This document describes integrating Kelvin as an AXI/TileLink peripheral in a bigger system.
We provide a scalar-only Kelvin configuration that can integrate with an AXI based system. The SystemVerilog can be generated with:
bazel build //hdl/chisel/src/kelvin:core_mini_axi_cc_library_emit_verilog
The interfaces to Kelvin are defined as follows:
Signal Bundle | Description |
---|---|
clk | The clock of the AXI Bus/Kelvin core. |
reset | The active-low reset signal for the AXI Bus/Kelvin core. |
s_axi | An AXI4 slave interface that can be used to write TCMs or touch Kelvin CSRs. |
m_axi | An AXI4 master interface used by Kelvin to read/write to memories/CSRs. |
irqn | Active-low interrupt to the Kelvin core. Can be triggered by peripherals or other host processor. |
wfi | Active-high signal from the Kelvin core, indicating that the core is waiting for an interrupt. While this is active, Kelvin is clock-gated. |
debug | Debug interface to monitor Kelvin instructions execution. This interface is typically only used for simulation. |
s_log | Debug interface to handle SLOG instruction. This interface is typically only used for simulation. |
halted | Output interface informing if the Core is running or not. Can be ignored. |
fault | Output interface to determine if the Core hit a fault. These signals should be connected to a system control CPU interrupt-line or status register for notification when Kelvin faults or is halted. |
AR / AW channel | Signal | Behaviour | | ------ | --------- | | addr | Address Kelvin wishes to read/write | | prot | Always 2 (unprivileged, insecure, data) | | id | Always 0 | | len | (Count of beats in the burst) - 1 | | size | Bytes-per-beat (1, 2, or 4) | | burst | Always 1 (INCR) | | lock | Always 0 (normal access) | | cache | Always 0 (Device non-bufferable) | | qos | Always 0 | | region | Always 0 |
R channel | Signal | Behaviour | | ------ | --------- | | data | Response data from the slave | | id | Ignored, but should be 0 as Kelvin only emits txns with an id of 0 | | resp | Response code | | last | Whether the beat is the last in the burst |
W channel | Signal | Behaviour | | ------ | --------- | | data | Data Kelvin wishes to write | | last | Whether the beat is the last in the burst | | strb | Which bytes in the data are valid |
B channel | Signal | Behaviour | | ------ | --------- | | id | Ignored, but should be 0 as Kelvin only emits txns with an id of 0 (an RTL assertion exists for this) | | resp | Response code |
Note: the USER signal is not supported on any of the channels.
AR / AW channel | Signal | Behaviour | | ------ | --------- | | addr | Address the master wishes to read / write to | | prot | Ignored | | id | Transaction ID, should be reflected in the response beats | | len | (Count of beats in the burst) - 1 | | size | Bytes-per-beat (1,2,4,8,16) | | burst | 0, 1, or 2 (FIXED, INCR, WRAP) | | lock | Ignored | | cache | Ignored | | qos | Ignored | | region | Ignored |
R channel | Signal | Behaviour | | ------ | --------- | | data | Response data from Kelvin | | id | Transaction ID, should match with the id field from AR | | resp | Response code (0/OKAY or 2/SLVERR) | | last | Whether the beat is the last in the burst |
W channel | Signal | Behaviour | | ------ | --------- | | data | Data the master wishes to write to Kelvin | | last | Whether the beat is the last in the burst | | strb | Which bytes in data are valid |
B channel | Signal | Behaviour | | ------ | --------- | | id | Transaction ID, should match with the id field from AW | | resp | Response code (0/OKAY or 2/SLVERR)
Note: the USER signal is not supported on any of the channels.
Memory accesses to Kelvin are defined as follows:
Region | Range | Size | Alignment | Description |
---|---|---|---|---|
ITCM | 0x0000 - 0x1FFF | 8kB | 4 bytes | ITCM storage for code executed by Kelvin. |
DTCM | 0x10000 - 0x17FFF | 32kB | 1 byte | DTCM storage for data used by Kelvin. |
CSR | 0x30000 - TBD | TBD | 4 bytes | CSR interface used to query/control Kelvin. |
Kelvin uses a synchronous reset strategy -- to ensure proper reset behavior, ensure that the clock runs for a cycle with reset active, before enabling either the internal clock gate (via CSR) or gating externally.
A note first -- in these examples, Kelvin is located in the overall system memory map at 0x70000000.
volatile uint8_t* kelvin_itcm = (uint8_t*)0x70000000L; for (int i = 0; i < kelvin_binary_len; ++i) { kelvin_itcm[i] = kelvin_binary[i]; }
If something like a DMA engine is present in your system, that is probably a better option for initializing the ITCM.
volatile uint32_t* kelvin_pc_csr = (uint32_t*)0x70030004L; *kelvin_pc_csr = start_addr;
volatile uint32_t* kelvin_reset_csr = (uint32_t*)0x70030000L; *kelvin_reset_csr = 1;
After this, ensure you wait a cycle to allow Kelvin‘s reset to occur. If you want to configure something like an interrupt that is connected to Kelvin’s fault or halted outputs, this is a good time.
volatile uint32_t* kelvin_reset_csr = (uint32_t*)0x70030000L; *kelvin_reset_csr = 0;
At this point, Kelvin will begin executing at the PC programmed in step 2.
io_halted
The status of Kelvin's execution can be checked by reading the status CSR:volatile uint32_t* kelvin_status_csr = (uint32_t*)0x70030008L; uint32_t status = *kelvin_status_csr; bool halted = status & 1; bool fault = status & 2;