From e3aba49e7170a63828bf52b9879d806ef4b5063e Mon Sep 17 00:00:00 2001 From: Pedro Antunes Date: Wed, 9 Aug 2023 14:29:12 +0100 Subject: [PATCH 01/27] _boot.c, OS, ext_mem.v: alteration to make it simillar to how it was when it run the Linux OS --- hardware/src/ext_mem.v | 121 ++++++++++++++++++++ software/src/iob_soc_opencryptolinux_boot.c | 8 +- submodules/OS | 2 +- 3 files changed, 125 insertions(+), 6 deletions(-) create mode 100644 hardware/src/ext_mem.v diff --git a/hardware/src/ext_mem.v b/hardware/src/ext_mem.v new file mode 100644 index 00000000..b640e81a --- /dev/null +++ b/hardware/src/ext_mem.v @@ -0,0 +1,121 @@ +`timescale 1 ns / 1 ps + +`include "iob_utils.vh" + +module ext_mem #( + parameter ADDR_W = 0, + parameter DATA_W = 0, + parameter FIRM_ADDR_W = 0, + parameter MEM_ADDR_W = 0, + parameter DDR_ADDR_W = 0, + parameter DDR_DATA_W = 0, + parameter AXI_ID_W = 0, + parameter AXI_LEN_W = 0, + parameter AXI_ADDR_W = 0, + parameter AXI_DATA_W = 0 +) ( + // Instruction bus + input [1+FIRM_ADDR_W-2+`WRITE_W-1:0] i_req, + output [ `RESP_W-1:0] i_resp, + + // Data bus + input [1+1+MEM_ADDR_W-2+`WRITE_W-1:0] d_req, + output [ `RESP_W-1:0] d_resp, + + // AXI interface + `include "axi_m_port.vs" + `include "clk_en_rst_port.vs" +); + + // + // INSTRUCTION CACHE + // + + wire [1+MEM_ADDR_W+`WRITE_W-1:0] icache_req; + wire [1+MEM_ADDR_W+`WRITE_W-1:0] dcache_req; + + //l2 cache interface signals + wire [1+MEM_ADDR_W+`WRITE_W-1:0] l2cache_req; + wire [`RESP_W-1:0] l2cache_resp; + + //ext_mem control signals + wire l2_wtb_empty; + wire invalidate; + reg invalidate_reg; + wire l2_avalid = l2cache_req[1+MEM_ADDR_W+`WRITE_W-1]; + //Necessary logic to avoid invalidating L2 while it's being accessed by a request + always @(posedge clk_i, posedge arst_i) + if (arst_i) invalidate_reg <= 1'b0; + else if (invalidate) invalidate_reg <= 1'b1; + else if (~l2_avalid) invalidate_reg <= 1'b0; + else invalidate_reg <= invalidate_reg; + + assign icache_req = {i_req[1+FIRM_ADDR_W-2+`WRITE_W-1], {(MEM_ADDR_W-FIRM_ADDR_W){1'b0}}, i_req[`ADDRESS(0, FIRM_ADDR_W-2)], 2'b00, i_req[`WRITE_W-1:0]}; + assign dcache_req = {d_req[2+MEM_ADDR_W-2+`WRITE_W-1], d_req[`ADDRESS(0,MEM_ADDR_W-2)], 2'b00, d_req[`WRITE_W-1:0]}; + + // Merge cache back-ends + iob_merge #( + .ADDR_W (MEM_ADDR_W), + .N_MASTERS(2) + ) merge_i_d_buses_into_l2 ( + .clk_i (clk_i), + .arst_i (arst_i), + // masters + .m_req_i ({icache_req, dcache_req}), + .m_resp_o({i_resp, d_resp}), + // slave + .s_req_o (l2cache_req), + .s_resp_i(l2cache_resp) + ); + + wire l2cache_valid; + wire [MEM_ADDR_W-3:0] l2cache_addr; + wire [ DATA_W-1:0] l2cache_wdata; + wire [ DATA_W/8-1:0] l2cache_wstrb; + wire [ DATA_W-1:0] l2cache_rdata; + wire l2cache_rvalid; + wire l2cache_ready; + + assign l2cache_valid = l2cache_req[1+MEM_ADDR_W+`WRITE_W-1]; + assign l2cache_addr = l2cache_req[`ADDRESS(0, MEM_ADDR_W)-2]; + assign l2cache_wdata = l2cache_req[`WDATA(0)]; + assign l2cache_wstrb = l2cache_req[`WSTRB(0)]; + assign l2cache_resp[`RDATA(0)] = l2cache_rdata; + assign l2cache_resp[`RVALID(0)] = l2cache_rvalid; + assign l2cache_resp[`READY(0)] = l2cache_ready; + + // L2 cache instance + iob_cache_axi #( + .AXI_ID_W (AXI_ID_W), + .AXI_LEN_W (AXI_LEN_W), + .FE_ADDR_W (MEM_ADDR_W), + .BE_ADDR_W (DDR_ADDR_W), + .BE_DATA_W (DDR_DATA_W), + .NWAYS_W (2), //Number of Ways + .NLINES_W (7), //Cache Line Offset (number of lines) + .WORD_OFFSET_W(3), //Word Offset (number of words per line) + .WTBUF_DEPTH_W(5), //FIFO's depth -- 5 minimum for BRAM implementation + .USE_CTRL (0), //Cache-Control can't be accessed + .USE_CTRL_CNT (0) //Remove counters + ) l2cache ( + // Native interface + .avalid (l2cache_valid), + .addr (l2cache_addr), + .wdata (l2cache_wdata), + .wstrb (l2cache_wstrb), + .rdata (l2cache_rdata), + .rvalid (l2cache_rvalid), + .ready (l2cache_ready), + //Control IO + .invalidate_in (invalidate_reg & ~l2_avalid), + .invalidate_out(), + .wtb_empty_in (1'b1), + .wtb_empty_out (l2_wtb_empty), + // AXI interface + `include "axi_m_m_portmap.vs" + .clk_i (clk_i), + .cke_i (cke_i), + .arst_i (arst_i) + ); + +endmodule diff --git a/software/src/iob_soc_opencryptolinux_boot.c b/software/src/iob_soc_opencryptolinux_boot.c index 71dd6a59..851f3412 100644 --- a/software/src/iob_soc_opencryptolinux_boot.c +++ b/software/src/iob_soc_opencryptolinux_boot.c @@ -63,8 +63,6 @@ while(uart16550_getc() != ACK){ uart16550_puts (PROGNAME); uart16550_puts (": Loading firmware...\n"); } - - uart16550_putc((char) DC1); #else //receive firmware from host @@ -81,7 +79,9 @@ while(uart16550_getc() != ACK){ uart16550_puts (": ERROR loading firmware\n"); } #endif - +#endif + + uart16550_putc((char) DC1); // Clear CPU registers, to not pass arguments to the next asm volatile("and a0,a0,zero"); asm volatile("and a1,a1,zero"); @@ -92,8 +92,6 @@ while(uart16550_getc() != ACK){ asm volatile("and a6,a6,zero"); asm volatile("and a7,a7,zero"); -#endif - //run firmware uart16550_puts (PROGNAME); uart16550_puts (": Restart CPU to run user program...\n"); diff --git a/submodules/OS b/submodules/OS index 1afb8184..f29cb1b2 160000 --- a/submodules/OS +++ b/submodules/OS @@ -1 +1 @@ -Subproject commit 1afb8184a6817db1db78d96cb8820acb69a10633 +Subproject commit f29cb1b2f14ecd6a3958e48c5a7b59679d54f1ef From d6b612932fe9ea00573bba10404092326091003c Mon Sep 17 00:00:00 2001 From: Pedro Antunes Date: Wed, 9 Aug 2023 14:37:50 +0100 Subject: [PATCH 02/27] ext_mem.v: fix merge conflits. --- hardware/src/ext_mem.v | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/hardware/src/ext_mem.v b/hardware/src/ext_mem.v index b640e81a..439f214d 100644 --- a/hardware/src/ext_mem.v +++ b/hardware/src/ext_mem.v @@ -24,7 +24,7 @@ module ext_mem #( // AXI interface `include "axi_m_port.vs" - `include "clk_en_rst_port.vs" + `include "clk_en_rst_s_port.vs" ); // @@ -99,18 +99,18 @@ module ext_mem #( .USE_CTRL_CNT (0) //Remove counters ) l2cache ( // Native interface - .avalid (l2cache_valid), - .addr (l2cache_addr), - .wdata (l2cache_wdata), - .wstrb (l2cache_wstrb), - .rdata (l2cache_rdata), - .rvalid (l2cache_rvalid), - .ready (l2cache_ready), + .avalid_i (l2cache_valid), + .addr_i (l2cache_addr), + .wdata_i (l2cache_wdata), + .wstrb_i (l2cache_wstrb), + .rdata_o (l2cache_rdata), + .rvalid_o (l2cache_rvalid), + .ready_o (l2cache_ready), //Control IO - .invalidate_in (invalidate_reg & ~l2_avalid), - .invalidate_out(), - .wtb_empty_in (1'b1), - .wtb_empty_out (l2_wtb_empty), + .invalidate_i (invalidate_reg & ~l2_avalid), + .invalidate_o(), + .wtb_empty_i (1'b1), + .wtb_empty_o (l2_wtb_empty), // AXI interface `include "axi_m_m_portmap.vs" .clk_i (clk_i), From 9ef5455d30acb8238057854ed29b99b8eee23f68 Mon Sep 17 00:00:00 2001 From: Pedro Antunes Date: Thu, 10 Aug 2023 14:50:51 +0100 Subject: [PATCH 03/27] submodules/SPI: added. --- .gitmodules | 3 +++ submodules/SPI | 1 + 2 files changed, 4 insertions(+) create mode 160000 submodules/SPI diff --git a/.gitmodules b/.gitmodules index 109432ce..336d0db7 100644 --- a/.gitmodules +++ b/.gitmodules @@ -19,3 +19,6 @@ [submodule "submodules/IOBSOC"] path = submodules/IOBSOC url = git@github.com:IObundle/iob-soc.git +[submodule "submodules/SPI"] + path = submodules/SPI + url = git@github.com:IObundle/iob-spi.git diff --git a/submodules/SPI b/submodules/SPI new file mode 160000 index 00000000..94928c01 --- /dev/null +++ b/submodules/SPI @@ -0,0 +1 @@ +Subproject commit 94928c01643178fac6724d59e10c74557405c5b5 From 13e6463f1fb4b1405946b43c093a3960c49017ca Mon Sep 17 00:00:00 2001 From: Pedro Antunes Date: Thu, 10 Aug 2023 15:09:05 +0100 Subject: [PATCH 04/27] iob_soc_opencryptolinux.py: add SPI peripheral to SoC. - SPI IOs which should only be used if defined "RUN_FLASH" appear in the SoC IOs. (needs fixing) --- iob_soc_opencryptolinux.py | 4 ++++ submodules/SPI | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/iob_soc_opencryptolinux.py b/iob_soc_opencryptolinux.py index fc9c89b3..d8ee5081 100755 --- a/iob_soc_opencryptolinux.py +++ b/iob_soc_opencryptolinux.py @@ -11,6 +11,7 @@ from iob_plic import iob_plic from iob_clint import iob_clint from iob_uart import iob_uart +from iob_spi import iob_spi class iob_soc_opencryptolinux(iob_soc): @@ -38,6 +39,8 @@ def _create_instances(cls): ) if iob_clint in cls.submodule_list: cls.peripherals.append(iob_clint("CLINT0", "CLINT peripheral")) + if iob_spi in cls.submodule_list: + cls.peripherals.append(iob_spi("SPI0", "SPI master peripheral")) @classmethod def _create_submodules_list(cls, extra_submodules=[]): @@ -48,6 +51,7 @@ def _create_submodules_list(cls, extra_submodules=[]): iob_uart16550, iob_clint, iob_plic, + iob_spi, (iob_uart, {"purpose": "simulation"}), ] + extra_submodules diff --git a/submodules/SPI b/submodules/SPI index 94928c01..4b2448c9 160000 --- a/submodules/SPI +++ b/submodules/SPI @@ -1 +1 @@ -Subproject commit 94928c01643178fac6724d59e10c74557405c5b5 +Subproject commit 4b2448c9941df0eea4c769c91febb64077e537ed From 8344eb87b2280c1ed15e7ce89596159b4a95c22e Mon Sep 17 00:00:00 2001 From: Pedro Antunes Date: Tue, 5 Sep 2023 17:09:23 +0100 Subject: [PATCH 05/27] iob_soc_opencryptolinux.v: change CPU used. --- hardware/src/iob_soc_opencryptolinux.v | 13 ++-- iob_soc_opencryptolinux.py | 4 +- software/src/iob_soc_opencryptolinux_boot.c | 21 +++--- .../src/iob_soc_opencryptolinux_firmware.c | 71 ------------------- 4 files changed, 16 insertions(+), 93 deletions(-) diff --git a/hardware/src/iob_soc_opencryptolinux.v b/hardware/src/iob_soc_opencryptolinux.v index 30fd9a09..cc1a74cb 100644 --- a/hardware/src/iob_soc_opencryptolinux.v +++ b/hardware/src/iob_soc_opencryptolinux.v @@ -40,8 +40,6 @@ module iob_soc_opencryptolinux #( wire [ `REQ_W-1:0] cpu_d_req; wire [ `RESP_W-1:0] cpu_d_resp; - assign PLIC0_src = {{31{1'b0}}, UART_interrupt}; - assign CLINT0_rt_clk = 1'b0; assign cpu_trap_o = 1'b0; //instantiate the cpu @@ -55,16 +53,17 @@ module iob_soc_opencryptolinux #( .arst_i (arst_i), .cpu_reset_i (cpu_reset), .boot_i (boot), + .clint_req({`REQ_W{1'b0}}), + .clint_resp(), + .plic_req({`REQ_W{1'b0}}), + .plic_resp(), + .plicInterrupts(32'd0), //instruction bus .ibus_req (cpu_i_req), .ibus_resp (cpu_i_resp), //data bus .dbus_req (cpu_d_req), - .dbus_resp (cpu_d_resp), - // interupts - .timerInterrupt (CLINT0_mtip[0]), - .softwareInterrupt (CLINT0_msip[0]), - .externalInterrupts(PLIC0_irq[1:0]) + .dbus_resp (cpu_d_resp) ); diff --git a/iob_soc_opencryptolinux.py b/iob_soc_opencryptolinux.py index d8ee5081..96b082d6 100755 --- a/iob_soc_opencryptolinux.py +++ b/iob_soc_opencryptolinux.py @@ -49,9 +49,7 @@ def _create_submodules_list(cls, extra_submodules=[]): [ iob_vexriscv, iob_uart16550, - iob_clint, - iob_plic, - iob_spi, + # iob_spi, (iob_uart, {"purpose": "simulation"}), ] + extra_submodules diff --git a/software/src/iob_soc_opencryptolinux_boot.c b/software/src/iob_soc_opencryptolinux_boot.c index 851f3412..440e55f3 100644 --- a/software/src/iob_soc_opencryptolinux_boot.c +++ b/software/src/iob_soc_opencryptolinux_boot.c @@ -83,22 +83,19 @@ while(uart16550_getc() != ACK){ uart16550_putc((char) DC1); // Clear CPU registers, to not pass arguments to the next - asm volatile("and a0,a0,zero"); - asm volatile("and a1,a1,zero"); - asm volatile("and a2,a2,zero"); - asm volatile("and a3,a3,zero"); - asm volatile("and a4,a4,zero"); - asm volatile("and a5,a5,zero"); - asm volatile("and a6,a6,zero"); - asm volatile("and a7,a7,zero"); + asm volatile("li a0,0"); + asm volatile("li a1,0"); + asm volatile("li a2,0"); + asm volatile("li a3,0"); + asm volatile("li a4,0"); + asm volatile("li a5,0"); + asm volatile("li a6,0"); + asm volatile("li a7,0"); //run firmware uart16550_puts (PROGNAME); uart16550_puts (": Restart CPU to run user program...\n"); uart16550_txwait(); -#ifdef USE_EXTMEM - while( !cache_wtb_empty() ); -#endif - + while( !cache_wtb_empty() ); } diff --git a/software/src/iob_soc_opencryptolinux_firmware.c b/software/src/iob_soc_opencryptolinux_firmware.c index 2b046ad7..2bea92c0 100644 --- a/software/src/iob_soc_opencryptolinux_firmware.c +++ b/software/src/iob_soc_opencryptolinux_firmware.c @@ -4,14 +4,6 @@ #include "iob_soc_opencryptolinux_periphs.h" #include "iob_soc_opencryptolinux_system.h" #include "printf.h" -#include "iob-plic.h" -#include "iob-clint.h" - -#include "riscv-csr.h" -#include "riscv-interrupts.h" - -// Machine mode interrupt service routine -static void irq_entry(void) __attribute__ ((interrupt ("machine"))); // Global to hold current timestamp static volatile uint64_t timestamp = 0; @@ -19,74 +11,11 @@ static volatile uint64_t timestamp = 0; int main() { //init uart uart16550_init(UART0_BASE, FREQ/(16*BAUD)); - clint_init(CLINT0_BASE); - plic_init(PLIC0_BASE); printf_init(&uart16550_putc); printf("\n\n\nHello world!\n\n\n"); - // Global interrupt disable - csr_clr_bits_mstatus(MSTATUS_MIE_BIT_MASK); - csr_write_mie(0); - csr_clr_bits_mcause(MCAUSE_INTERRUPT_ALL_SET_MASK); - csr_write_mcause(0); - - // Setup timer for 1 second interval - timestamp = mtimer_get_raw_time(); - mtimer_set_raw_time_cmp(MTIMER_SECONDS_TO_CLOCKS(0.002)); - - // Setup the IRQ handler entry point - csr_write_mtvec((uint_xlen_t) irq_entry); - - // Enable MIE.MTI and MIE.MEI - csr_set_bits_mie(MIE_MTI_BIT_MASK); - csr_set_bits_mie(MIE_MEI_BIT_MASK); - - // Global interrupt enable - csr_set_bits_mstatus(MSTATUS_MIE_BIT_MASK); - - // Enable PLIC interrupt for UART - printf("Enabling external interrupt source 0 with ID = 1.\n"); - int target; - target = plic_enable_interrupt(0); - - printf("HART id %d, waiting for timer interrupt...\n", target); - // Wait for interrupt - __asm__ volatile ("wfi"); - printf("Exit...\n"); uart16550_finish(); return 0; } - -#pragma GCC push_options -// Force the alignment for mtvec.BASE. A 'C' extension program could be aligned to to bytes. -#pragma GCC optimize ("align-functions=4") -static void irq_entry(void) { - printf("Entered IRQ.\n"); - uint_xlen_t this_cause = csr_read_mcause(); - if (this_cause & MCAUSE_INTERRUPT_BIT_MASK) { - this_cause &= 0xFF; - // Known exceptions - switch (this_cause) { - case RISCV_INT_POS_MTI : - printf("Time interrupt.\n"); - // Timer exception, keep up the one second tick. - mtimer_set_raw_time_cmp(MTIMER_SECONDS_TO_CLOCKS(1)); - timestamp = mtimer_get_raw_time(); - float aux = (float)timestamp/MTIME_FREQ_HZ; - printf("Current time passed: %.3f seconds.\n", aux); - printf("MTIMER register value: %lld.\n", timestamp); - break; - case RISCV_INT_POS_MEI : - printf("External interrupt.\n"); - int source_id = 0; - source_id = plic_claim_interrupt(); - printf("External interrupt ID received was: %d.\n", source_id); - plic_complete_interrupt(source_id); - plic_disable_interrupt(source_id); - break; - } - } -} -#pragma GCC pop_options From d41f00a168226c0f6637eda65e1553cfcaa48244 Mon Sep 17 00:00:00 2001 From: Pedro Antunes Date: Tue, 5 Sep 2023 17:30:40 +0100 Subject: [PATCH 06/27] submodules/*: update. --- submodules/IOBSOC | 2 +- submodules/LIB | 2 +- submodules/VEXRISCV | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/submodules/IOBSOC b/submodules/IOBSOC index 02731ffb..3e401e72 160000 --- a/submodules/IOBSOC +++ b/submodules/IOBSOC @@ -1 +1 @@ -Subproject commit 02731ffb0907300ff2156d671ed118e4a0c8148e +Subproject commit 3e401e72b4e8e9e5d257f479bfa751764efb409d diff --git a/submodules/LIB b/submodules/LIB index ff75030d..c39bcd67 160000 --- a/submodules/LIB +++ b/submodules/LIB @@ -1 +1 @@ -Subproject commit ff75030d5b75ebaf3251108428fa98a335626ca2 +Subproject commit c39bcd67c2b5b7c15bebb2190ffdf53023902c6c diff --git a/submodules/VEXRISCV b/submodules/VEXRISCV index d4b2152b..d7b36b14 160000 --- a/submodules/VEXRISCV +++ b/submodules/VEXRISCV @@ -1 +1 @@ -Subproject commit d4b2152b7fb9fac426412b8de5b90f81538cdb49 +Subproject commit d7b36b140a53775d96120080688271f783456648 From 19a7d62aefe75213ebf7336b9db1da3f6f814288 Mon Sep 17 00:00:00 2001 From: Pedro Antunes Date: Fri, 8 Sep 2023 18:39:07 +0100 Subject: [PATCH 07/27] iob_soc_opencryptolinux.v: aparently cke_i is no longer an input; fix signals missing or duplicated. --- .../simulation/src/iob_soc_opencryptolinux_sim_wrapper.v | 3 +-- hardware/src/iob_soc_opencryptolinux.v | 5 ++--- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/hardware/simulation/src/iob_soc_opencryptolinux_sim_wrapper.v b/hardware/simulation/src/iob_soc_opencryptolinux_sim_wrapper.v index f82e0cbb..cada5155 100644 --- a/hardware/simulation/src/iob_soc_opencryptolinux_sim_wrapper.v +++ b/hardware/simulation/src/iob_soc_opencryptolinux_sim_wrapper.v @@ -40,7 +40,7 @@ module iob_soc_opencryptolinux_sim_wrapper ( initial begin `ifdef VCD $dumpfile("uut.vcd"); - $dumpvars(); + $dumpvars(0, iob_soc_opencryptolinux_sim_wrapper.soc0.cpu_0.CPU); `endif end @@ -59,7 +59,6 @@ module iob_soc_opencryptolinux_sim_wrapper ( ) soc0 ( `include "iob_soc_opencryptolinux_pportmaps.vs" .clk_i (clk), - .cke_i (cke), .arst_i(rst), .trap_o(trap_o) ); diff --git a/hardware/src/iob_soc_opencryptolinux.v b/hardware/src/iob_soc_opencryptolinux.v index 61efe673..94078030 100644 --- a/hardware/src/iob_soc_opencryptolinux.v +++ b/hardware/src/iob_soc_opencryptolinux.v @@ -15,6 +15,7 @@ module iob_soc_opencryptolinux #( localparam integer Bbit = `IOB_SOC_OPENCRYPTOLINUX_B; localparam integer AddrMsb = `REQ_W - 2; + localparam integer MEM_ADDR_OFFSET = 0; `include "iob_soc_opencryptolinux_pwires.vs" @@ -24,6 +25,7 @@ module iob_soc_opencryptolinux #( wire boot; wire cpu_reset; + wire cke_i = 1'b1; // // CPU @@ -189,9 +191,6 @@ module iob_soc_opencryptolinux #( ext_mem_d_req[`WRITE(0)] }; - wire [AXI_ADDR_W-1:0] internal_axi_awaddr_o; - wire [AXI_ADDR_W-1:0] internal_axi_araddr_o; - ext_mem #( .ADDR_W (ADDR_W), .DATA_W (DATA_W), From b91cb9ef0bee25d0cf7180cb0bd5fceab21bab4b Mon Sep 17 00:00:00 2001 From: Pedro Antunes Date: Mon, 11 Sep 2023 17:47:56 +0100 Subject: [PATCH 08/27] *: simulation executes until Waiting for Console ACK. --- .../src/iob_soc_opencryptolinux_sim_wrapper.v | 2 +- software/src/iob_soc_opencryptolinux_boot.c | 97 +++++++++---------- submodules/VEXRISCV | 2 +- 3 files changed, 48 insertions(+), 53 deletions(-) diff --git a/hardware/simulation/src/iob_soc_opencryptolinux_sim_wrapper.v b/hardware/simulation/src/iob_soc_opencryptolinux_sim_wrapper.v index cada5155..7aea12aa 100644 --- a/hardware/simulation/src/iob_soc_opencryptolinux_sim_wrapper.v +++ b/hardware/simulation/src/iob_soc_opencryptolinux_sim_wrapper.v @@ -40,7 +40,7 @@ module iob_soc_opencryptolinux_sim_wrapper ( initial begin `ifdef VCD $dumpfile("uut.vcd"); - $dumpvars(0, iob_soc_opencryptolinux_sim_wrapper.soc0.cpu_0.CPU); + $dumpvars(0, iob_soc_opencryptolinux_sim_wrapper.soc0); `endif end diff --git a/software/src/iob_soc_opencryptolinux_boot.c b/software/src/iob_soc_opencryptolinux_boot.c index 2bd52a70..0c856f33 100644 --- a/software/src/iob_soc_opencryptolinux_boot.c +++ b/software/src/iob_soc_opencryptolinux_boot.c @@ -1,15 +1,12 @@ #include "bsp.h" -#include "iob_soc_opencryptolinux_system.h" -#include "iob_soc_opencryptolinux_conf.h" #include "iob-uart16550.h" - -#ifdef USE_EXTMEM +#include "iob_soc_opencryptolinux_conf.h" +#include "iob_soc_opencryptolinux_system.h" #include "iob-cache.h" -#endif -//defined here (and not in periphs.h) because it is the only peripheral used -//by the bootloader -#define UART0_BASE (UART0 << (31 - N_SLAVES_W)) +// defined here (and not in periphs.h) because it is the only peripheral used +// by the bootloader +#define UART0_BASE (UART0 << (31 - N_SLAVES_W - 4))|0xf0000000 #define PROGNAME "IOb-Bootloader" @@ -18,45 +15,41 @@ int main() { - //init uart - uart16550_init(UART0_BASE, FREQ/(16*BAUD)); - -#ifdef USE_EXTMEM - cache_init(1< Date: Tue, 12 Sep 2023 20:11:11 +0100 Subject: [PATCH 09/27] software/*: iverilog runs bootloader; set custom peripheral addresses. --- software/src/iob_soc_opencryptolinux_boot.c | 4 ++-- .../src/iob_soc_opencryptolinux_firmware.c | 21 +++++++++++-------- submodules/LIB | 2 +- submodules/OS | 2 +- submodules/VEXRISCV | 2 +- 5 files changed, 17 insertions(+), 14 deletions(-) diff --git a/software/src/iob_soc_opencryptolinux_boot.c b/software/src/iob_soc_opencryptolinux_boot.c index 0c856f33..a0380be9 100644 --- a/software/src/iob_soc_opencryptolinux_boot.c +++ b/software/src/iob_soc_opencryptolinux_boot.c @@ -1,12 +1,12 @@ #include "bsp.h" +#include "iob-cache.h" #include "iob-uart16550.h" #include "iob_soc_opencryptolinux_conf.h" #include "iob_soc_opencryptolinux_system.h" -#include "iob-cache.h" // defined here (and not in periphs.h) because it is the only peripheral used // by the bootloader -#define UART0_BASE (UART0 << (31 - N_SLAVES_W - 4))|0xf0000000 +#define UART0_BASE (UART0 << (31 - N_SLAVES_W - 4)) | 0xf0000000 #define PROGNAME "IOb-Bootloader" diff --git a/software/src/iob_soc_opencryptolinux_firmware.c b/software/src/iob_soc_opencryptolinux_firmware.c index f44865bf..934472db 100644 --- a/software/src/iob_soc_opencryptolinux_firmware.c +++ b/software/src/iob_soc_opencryptolinux_firmware.c @@ -1,24 +1,27 @@ #include "bsp.h" #include "iob-uart16550.h" #include "iob_soc_opencryptolinux_conf.h" -#include "iob_soc_opencryptolinux_periphs.h" #include "iob_soc_opencryptolinux_system.h" #include "iob_str.h" #include "printf.h" +#define UART0_BASE 0xf2000000 +#define PLIC0_BASE 0xf4000000 +#define CLINT0_BASE 0xf6000000 + // Global to hold current timestamp static volatile uint64_t timestamp = 0; int main() { - char pass_string[] = "Test passed!"; + char pass_string[] = "Test passed!"; - //init uart - uart16550_init(UART0_BASE, FREQ/(16*BAUD)); - printf_init(&uart16550_putc); + // init uart + uart16550_init(UART0_BASE, FREQ / (16 * BAUD)); + printf_init(&uart16550_putc); - printf("\n\n\nHello world!\n\n\n"); + printf("\n\n\nHello world!\n\n\n"); - printf("Exit...\n"); - uart16550_finish(); - return 0; + printf("Exit...\n"); + uart16550_finish(); + return 0; } diff --git a/submodules/LIB b/submodules/LIB index c39bcd67..1c3a1894 160000 --- a/submodules/LIB +++ b/submodules/LIB @@ -1 +1 @@ -Subproject commit c39bcd67c2b5b7c15bebb2190ffdf53023902c6c +Subproject commit 1c3a1894f85bae33791b76fdb5ae7c7b496bd816 diff --git a/submodules/OS b/submodules/OS index f29cb1b2..ff805dab 160000 --- a/submodules/OS +++ b/submodules/OS @@ -1 +1 @@ -Subproject commit f29cb1b2f14ecd6a3958e48c5a7b59679d54f1ef +Subproject commit ff805dab4e30db733af0c84db2d0cc14b200d663 diff --git a/submodules/VEXRISCV b/submodules/VEXRISCV index 5d42c4e9..7c95c8c5 160000 --- a/submodules/VEXRISCV +++ b/submodules/VEXRISCV @@ -1 +1 @@ -Subproject commit 5d42c4e9a5001e29cd527771e0d527ca34c5da69 +Subproject commit 7c95c8c5833773e46c1c73592a03e1082fa956b8 From 193241cdb11d3812bc4748446f8081916b730209 Mon Sep 17 00:00:00 2001 From: Pedro Antunes Date: Thu, 14 Sep 2023 00:45:46 +0100 Subject: [PATCH 10/27] iob2axi.v: create and add to extmem. --- hardware/src/ext_mem.v | 146 ++++++----------- hardware/src/iob2axi.v | 210 +++++++++++++++++++++++++ hardware/src/iob_soc_opencryptolinux.v | 19 +-- 3 files changed, 258 insertions(+), 117 deletions(-) create mode 100644 hardware/src/iob2axi.v diff --git a/hardware/src/ext_mem.v b/hardware/src/ext_mem.v index 439f214d..e23a95b5 100644 --- a/hardware/src/ext_mem.v +++ b/hardware/src/ext_mem.v @@ -3,119 +3,65 @@ `include "iob_utils.vh" module ext_mem #( - parameter ADDR_W = 0, - parameter DATA_W = 0, - parameter FIRM_ADDR_W = 0, - parameter MEM_ADDR_W = 0, - parameter DDR_ADDR_W = 0, - parameter DDR_DATA_W = 0, - parameter AXI_ID_W = 0, - parameter AXI_LEN_W = 0, - parameter AXI_ADDR_W = 0, - parameter AXI_DATA_W = 0 + parameter ADDR_W = 0, + parameter DATA_W = 0, + parameter FIRM_ADDR_W = 0, + parameter MEM_ADDR_W = 0, + parameter DDR_ADDR_W = 0, + parameter DDR_DATA_W = 0, + parameter AXI_ID_W = 0, + parameter AXI_LEN_W = 0, + parameter AXI_ADDR_W = 0, + parameter AXI_DATA_W = 0 ) ( - // Instruction bus - input [1+FIRM_ADDR_W-2+`WRITE_W-1:0] i_req, - output [ `RESP_W-1:0] i_resp, + // Instruction bus + input [ `REQ_W-1:0] i_req, + output [`RESP_W-1:0] i_resp, - // Data bus - input [1+1+MEM_ADDR_W-2+`WRITE_W-1:0] d_req, - output [ `RESP_W-1:0] d_resp, + // Data bus + input [ `REQ_W-1:0] d_req, + output [`RESP_W-1:0] d_resp, - // AXI interface - `include "axi_m_port.vs" - `include "clk_en_rst_s_port.vs" + // AXI interface + `include "axi_m_port.vs" + `include "clk_en_rst_s_port.vs" ); - // - // INSTRUCTION CACHE - // + // External memory interface signals + wire [ `REQ_W-1:0] ext_mem_req; + wire [`RESP_W-1:0] ext_mem_resp; - wire [1+MEM_ADDR_W+`WRITE_W-1:0] icache_req; - wire [1+MEM_ADDR_W+`WRITE_W-1:0] dcache_req; - - //l2 cache interface signals - wire [1+MEM_ADDR_W+`WRITE_W-1:0] l2cache_req; - wire [`RESP_W-1:0] l2cache_resp; - - //ext_mem control signals - wire l2_wtb_empty; - wire invalidate; - reg invalidate_reg; - wire l2_avalid = l2cache_req[1+MEM_ADDR_W+`WRITE_W-1]; - //Necessary logic to avoid invalidating L2 while it's being accessed by a request - always @(posedge clk_i, posedge arst_i) - if (arst_i) invalidate_reg <= 1'b0; - else if (invalidate) invalidate_reg <= 1'b1; - else if (~l2_avalid) invalidate_reg <= 1'b0; - else invalidate_reg <= invalidate_reg; - - assign icache_req = {i_req[1+FIRM_ADDR_W-2+`WRITE_W-1], {(MEM_ADDR_W-FIRM_ADDR_W){1'b0}}, i_req[`ADDRESS(0, FIRM_ADDR_W-2)], 2'b00, i_req[`WRITE_W-1:0]}; - assign dcache_req = {d_req[2+MEM_ADDR_W-2+`WRITE_W-1], d_req[`ADDRESS(0,MEM_ADDR_W-2)], 2'b00, d_req[`WRITE_W-1:0]}; - - // Merge cache back-ends - iob_merge #( - .ADDR_W (MEM_ADDR_W), + // Merge cache back-ends + iob_merge #( + .ADDR_W (ADDR_W), .N_MASTERS(2) - ) merge_i_d_buses_into_l2 ( + ) merge_i_d_buses_into_l2 ( .clk_i (clk_i), .arst_i (arst_i), // masters - .m_req_i ({icache_req, dcache_req}), + .m_req_i ({i_req, d_req}), .m_resp_o({i_resp, d_resp}), // slave - .s_req_o (l2cache_req), - .s_resp_i(l2cache_resp) - ); - - wire l2cache_valid; - wire [MEM_ADDR_W-3:0] l2cache_addr; - wire [ DATA_W-1:0] l2cache_wdata; - wire [ DATA_W/8-1:0] l2cache_wstrb; - wire [ DATA_W-1:0] l2cache_rdata; - wire l2cache_rvalid; - wire l2cache_ready; - - assign l2cache_valid = l2cache_req[1+MEM_ADDR_W+`WRITE_W-1]; - assign l2cache_addr = l2cache_req[`ADDRESS(0, MEM_ADDR_W)-2]; - assign l2cache_wdata = l2cache_req[`WDATA(0)]; - assign l2cache_wstrb = l2cache_req[`WSTRB(0)]; - assign l2cache_resp[`RDATA(0)] = l2cache_rdata; - assign l2cache_resp[`RVALID(0)] = l2cache_rvalid; - assign l2cache_resp[`READY(0)] = l2cache_ready; + .s_req_o (ext_mem_req), + .s_resp_i(ext_mem_resp) + ); - // L2 cache instance - iob_cache_axi #( - .AXI_ID_W (AXI_ID_W), - .AXI_LEN_W (AXI_LEN_W), - .FE_ADDR_W (MEM_ADDR_W), - .BE_ADDR_W (DDR_ADDR_W), - .BE_DATA_W (DDR_DATA_W), - .NWAYS_W (2), //Number of Ways - .NLINES_W (7), //Cache Line Offset (number of lines) - .WORD_OFFSET_W(3), //Word Offset (number of words per line) - .WTBUF_DEPTH_W(5), //FIFO's depth -- 5 minimum for BRAM implementation - .USE_CTRL (0), //Cache-Control can't be accessed - .USE_CTRL_CNT (0) //Remove counters - ) l2cache ( - // Native interface - .avalid_i (l2cache_valid), - .addr_i (l2cache_addr), - .wdata_i (l2cache_wdata), - .wstrb_i (l2cache_wstrb), - .rdata_o (l2cache_rdata), - .rvalid_o (l2cache_rvalid), - .ready_o (l2cache_ready), - //Control IO - .invalidate_i (invalidate_reg & ~l2_avalid), - .invalidate_o(), - .wtb_empty_i (1'b1), - .wtb_empty_o (l2_wtb_empty), - // AXI interface + // AXI interface + iob2axi #( + .ADDR_W(MEM_ADDR_W), + .DATA_W(DATA_W) + ) ext_mem_iob2axi ( + .iob_avalid_i(ext_mem_req[`AVALID(0)]), + .iob_addr_i (ext_mem_req[`ADDRESS(0, MEM_ADDR_W)]), + .iob_wdata_i (ext_mem_req[`WDATA(0)]), + .iob_wstrb_i (ext_mem_req[`WSTRB(0)]), + .iob_rdata_o (ext_mem_resp[`RVALID(0)]), + .iob_rvalid_o(ext_mem_resp[`RDATA(0)]), + .iob_rready_o(ext_mem_resp[`READY(0)]), `include "axi_m_m_portmap.vs" - .clk_i (clk_i), - .cke_i (cke_i), - .arst_i (arst_i) - ); + .clk_i (clk_i), + .cke_i (cke_i), + .arst_i (arst_i) + ); endmodule diff --git a/hardware/src/iob2axi.v b/hardware/src/iob2axi.v new file mode 100644 index 00000000..de9a40b8 --- /dev/null +++ b/hardware/src/iob2axi.v @@ -0,0 +1,210 @@ +`timescale 1ns / 1ps + +module iob2axi #( + // Width of address bus in bits + parameter ADDR_WIDTH = 32, + // Width of input (slave/master) AXI/IOb interface data bus in bits + parameter DATA_WIDTH = 32, + // Width of input (slave/master) AXI/IOb interface wstrb (width of data bus in words) + parameter STRB_WIDTH = (DATA_WIDTH / 8), + // Width of AXI ID signal + parameter AXI_ID_WIDTH = 8, + // Length of AXI read burst + parameter AXI_RLEN_W = 8'h00, + // Length of AXI write burst + parameter AXI_WLEN_W = 8'h00 +) ( + input wire clk_i, //System clock input + input wire cke_i, //System clock enable + input wire arst_i, //System reset, asynchronous and active high + /* + * IOb-bus slave interface + */ + input wire iob_avalid_i, + input wire [ ADDR_WIDTH-1:0] iob_addr_i, + input wire [ DATA_WIDTH-1:0] iob_wdata_i, + input wire [ STRB_WIDTH-1:0] iob_wstrb_i, + output wire [ DATA_WIDTH-1:0] iob_rdata_o, + output wire iob_rvalid_o, + output wire iob_ready_o, + /* + * AXI master interface + */ + output wire [AXI_ID_WIDTH-1:0] axi_awid_o, + output wire [ ADDR_WIDTH-1:0] axi_awaddr_o, + output wire [ 7:0] axi_awlen_o, + output wire [ 2:0] axi_awsize_o, + output wire [ 1:0] axi_awburst_o, + output wire axi_awlock_o, + output wire [ 3:0] axi_awcache_o, + output wire [ 2:0] axi_awprot_o, + output wire axi_awvalid_o, + input wire axi_awready_i, + output wire [ DATA_WIDTH-1:0] axi_wdata_o, + output wire [ STRB_WIDTH-1:0] axi_wstrb_o, + output wire axi_wlast_o, + output wire axi_wvalid_o, + input wire axi_wready_i, + input wire [AXI_ID_WIDTH-1:0] axi_bid_i, + input wire [ 1:0] axi_bresp_i, + input wire axi_bvalid_i, + output wire axi_bready_o, + output wire [AXI_ID_WIDTH-1:0] axi_arid_o, + output wire [ ADDR_WIDTH-1:0] axi_araddr_o, + output wire [ 7:0] axi_arlen_o, + output wire [ 2:0] axi_arsize_o, + output wire [ 1:0] axi_arburst_o, + output wire axi_arlock_o, + output wire [ 3:0] axi_arcache_o, + output wire [ 2:0] axi_arprot_o, + output wire axi_arvalid_o, + input wire axi_arready_i, + input wire [AXI_ID_WIDTH-1:0] axi_rid_i, + input wire [ DATA_WIDTH-1:0] axi_rdata_i, + input wire [ 1:0] axi_rresp_i, + input wire axi_rlast_i, + input wire axi_rvalid_i, + output wire axi_rready_o +); + + localparam AXI_RLEN = 2 ** AXI_RLEN_W; + localparam AXI_WLEN = 2 ** AXI_WLEN_W; + + // + // Input/Write bus FIFO + // + wire in_fifo_full; + wire in_fifo_wr; + wire [DATA_WIDTH-1:0] in_fifo_wdata; + + wire in_fifo_empty; + wire in_fifo_rd; + wire [DATA_WIDTH-1:0] in_fifo_rdata; + + wire [AXI_WLEN:0] in_fifo_level; + wire in_ext_mem_clk; + wire in_ext_mem_w_en; + wire [AXI_RLEN-1:0] in_ext_mem_w_addr; + wire [DATA_WIDTH-1:0] in_ext_mem_w_data; + wire in_ext_mem_r_en; + wire [AXI_RLEN-1:0] in_ext_mem_r_addr; + wire [DATA_WIDTH-1:0] in_ext_mem_r_data; + + // + // Output/Read bus FIFO + // + wire out_fifo_full; + wire out_fifo_wr; + wire [DATA_WIDTH-1:0] out_fifo_wdata; + + wire out_fifo_empty; + wire out_fifo_rd; + wire [DATA_WIDTH-1:0] out_fifo_rdata; + + wire [AXI_RLEN:0] out_fifo_level; + + wire out_ext_mem_clk; + wire out_ext_mem_w_en; + wire [AXI_RLEN-1:0] out_ext_mem_w_addr; + wire [DATA_WIDTH-1:0] out_ext_mem_w_data; + wire out_ext_mem_r_en; + wire [AXI_RLEN-1:0] out_ext_mem_r_addr; + wire [DATA_WIDTH-1:0] out_ext_mem_r_data; + + assign in_fifo_wr = s_valid_i & |s_wstrb_i & ~in_fifo_full; + assign in_fifo_wdata = {s_wdata_i, s_wstrb_i}; + assign in_fifo_rd = wr_valid; + // + // Output/Read bus FIFO + // + assign out_fifo_wr = rd_valid & |rd_wstrb & ~out_fifo_full; + assign out_fifo_wdata = rd_wdata; + assign out_fifo_rd = s_valid_i & ~|s_wstrb_i & ~out_fifo_empty; + + iob_fifo_sync #( + .W_DATA_W(DATA_WIDTH), + .R_DATA_W(DATA_WIDTH), + .ADDR_W (AXI_WLEN) + ) write_bus_iob_fifo_sync ( + .clk_i(clk_i), + .rst_i(rst_i), + + .w_en_i (in_fifo_wr), + .w_data_i(in_fifo_wdata), + .w_full_o(in_fifo_full), + + .r_en_i (in_fifo_rd), + .r_data_o (in_fifo_rdata), + .r_empty_o(in_fifo_empty), + + .ext_mem_clk_o(in_ext_mem_clk), + .ext_mem_w_en_o(in_ext_mem_w_en), + .ext_mem_w_addr_o(in_ext_mem_w_addr), + .ext_mem_w_data_o(in_ext_mem_w_data), + + .ext_mem_r_en_o (in_ext_mem_r_en), + .ext_mem_r_addr_o(in_ext_mem_r_addr), + .ext_mem_r_data_i(in_ext_mem_r_data), + + .level_o(in_fifo_level) + ); + + iob_ram_2p #( + .DATA_W(DATA_WIDTH), + .ADDR_W(AXI_WLEN) + ) write_bus_ram ( + .clk_i(in_ext_mem_clk), + + .w_en_i (in_ext_mem_w_en), + .w_addr_i(in_ext_mem_w_addr), + .w_data_i(in_ext_mem_w_data), + + .r_en_i (in_ext_mem_r_en), + .r_addr_i(in_ext_mem_r_addr), + .r_data_o(in_ext_mem_r_data) + ); + + iob_fifo_sync #( + .W_DATA_W(DATA_WIDTH), + .R_DATA_W(DATA_WIDTH), + .ADDR_W (AXI_RLEN) + ) read_bus_iob_fifo_sync ( + .clk_i(clk_i), + .rst_i(rst_i), + + .w_en_i (out_fifo_wr), + .w_data_i(out_fifo_wdata), + .w_full_o(out_fifo_full), + + .r_en_i (out_fifo_rd), + .r_data_o (out_fifo_rdata), + .r_empty_o(out_fifo_empty), + + .ext_mem_clk_o(out_ext_mem_clk), + .ext_mem_w_en_o(out_ext_mem_w_en), + .ext_mem_w_addr_o(out_ext_mem_w_addr), + .ext_mem_w_data_o(out_ext_mem_w_data), + + .ext_mem_r_en_o (out_ext_mem_r_en), + .ext_mem_r_addr_o(out_ext_mem_r_addr), + .ext_mem_r_data_i(out_ext_mem_r_data), + + .level_o(out_fifo_level) + ); + + iob_ram_2p #( + .DATA_W(DATA_WIDTH), + .ADDR_W(AXI_RLEN) + ) read_bus_ram ( + .clk_i(out_ext_mem_clk), + + .w_en_i (out_ext_mem_w_en), + .w_addr_i(out_ext_mem_w_addr), + .w_data_i(out_ext_mem_w_data), + + .r_en_i (out_ext_mem_r_en), + .r_addr_i(out_ext_mem_r_addr), + .r_data_o(out_ext_mem_r_data) + ); + +endmodule diff --git a/hardware/src/iob_soc_opencryptolinux.v b/hardware/src/iob_soc_opencryptolinux.v index 94078030..a92358ee 100644 --- a/hardware/src/iob_soc_opencryptolinux.v +++ b/hardware/src/iob_soc_opencryptolinux.v @@ -176,21 +176,6 @@ module iob_soc_opencryptolinux #( // // EXTERNAL DDR MEMORY // - - wire [ 1+SRAM_ADDR_W-2+DATA_W+DATA_W/8-1:0] ext_mem0_i_req; - wire [1+MEM_ADDR_W+1-2+DATA_W+DATA_W/8-1:0] ext_mem0_d_req; - - assign ext_mem0_i_req = { - ext_mem_i_req[`AVALID(0)], - ext_mem_i_req[`ADDRESS(0, `IOB_SOC_OPENCRYPTOLINUX_SRAM_ADDR_W)-2], - ext_mem_i_req[`WRITE(0)] - }; - assign ext_mem0_d_req = { - ext_mem_d_req[`AVALID(0)], - ext_mem_d_req[`ADDRESS(0, MEM_ADDR_W+1)-2], - ext_mem_d_req[`WRITE(0)] - }; - ext_mem #( .ADDR_W (ADDR_W), .DATA_W (DATA_W), @@ -204,11 +189,11 @@ module iob_soc_opencryptolinux #( .AXI_DATA_W (AXI_DATA_W) ) ext_mem0 ( // instruction bus - .i_req (ext_mem0_i_req), + .i_req (ext_mem_i_req), .i_resp(ext_mem_i_resp), //data bus - .d_req (ext_mem0_d_req), + .d_req (ext_mem_d_req), .d_resp(ext_mem_d_resp), //AXI INTERFACE From cdac4b9e0e8e7c4d87068d52e368406c1d04a683 Mon Sep 17 00:00:00 2001 From: Pedro Antunes Date: Thu, 14 Sep 2023 18:28:35 +0100 Subject: [PATCH 11/27] iob2axi.v: read FSM made (not tested). --- hardware/src/ext_mem.v | 15 +- hardware/src/iob2axi.v | 407 ++++++++++++++++++++++++++++++----------- 2 files changed, 305 insertions(+), 117 deletions(-) diff --git a/hardware/src/ext_mem.v b/hardware/src/ext_mem.v index e23a95b5..d065cb15 100644 --- a/hardware/src/ext_mem.v +++ b/hardware/src/ext_mem.v @@ -5,14 +5,8 @@ module ext_mem #( parameter ADDR_W = 0, parameter DATA_W = 0, - parameter FIRM_ADDR_W = 0, parameter MEM_ADDR_W = 0, - parameter DDR_ADDR_W = 0, - parameter DDR_DATA_W = 0, - parameter AXI_ID_W = 0, - parameter AXI_LEN_W = 0, - parameter AXI_ADDR_W = 0, - parameter AXI_DATA_W = 0 + parameter AXI_ID_W = 0 ) ( // Instruction bus input [ `REQ_W-1:0] i_req, @@ -48,8 +42,11 @@ module ext_mem #( // AXI interface iob2axi #( - .ADDR_W(MEM_ADDR_W), - .DATA_W(DATA_W) + .ADDR_WIDTH(MEM_ADDR_W), + .DATA_WIDTH(DATA_W), + .AXI_ID_WIDTH(AXI_ID_W), + .AXI_RLEN(8'h0f), + .AXI_WLEN(8'h00) ) ext_mem_iob2axi ( .iob_avalid_i(ext_mem_req[`AVALID(0)]), .iob_addr_i (ext_mem_req[`ADDRESS(0, MEM_ADDR_W)]), diff --git a/hardware/src/iob2axi.v b/hardware/src/iob2axi.v index de9a40b8..08be8d1c 100644 --- a/hardware/src/iob2axi.v +++ b/hardware/src/iob2axi.v @@ -2,17 +2,17 @@ module iob2axi #( // Width of address bus in bits - parameter ADDR_WIDTH = 32, + parameter ADDR_WIDTH = 32, // Width of input (slave/master) AXI/IOb interface data bus in bits - parameter DATA_WIDTH = 32, + parameter DATA_WIDTH = 32, // Width of input (slave/master) AXI/IOb interface wstrb (width of data bus in words) - parameter STRB_WIDTH = (DATA_WIDTH / 8), + parameter STRB_WIDTH = (DATA_WIDTH / 8), // Width of AXI ID signal parameter AXI_ID_WIDTH = 8, - // Length of AXI read burst - parameter AXI_RLEN_W = 8'h00, - // Length of AXI write burst - parameter AXI_WLEN_W = 8'h00 + // Length of AXI read burst (Burst_Length = AxLEN[7:0] + 1) + parameter AXI_RLEN = 8'h00, + // Length of AXI write burst (Burst_Length = AxLEN[7:0] + 1) + parameter AXI_WLEN = 8'h00 ) ( input wire clk_i, //System clock input input wire cke_i, //System clock enable @@ -24,8 +24,8 @@ module iob2axi #( input wire [ ADDR_WIDTH-1:0] iob_addr_i, input wire [ DATA_WIDTH-1:0] iob_wdata_i, input wire [ STRB_WIDTH-1:0] iob_wstrb_i, - output wire [ DATA_WIDTH-1:0] iob_rdata_o, - output wire iob_rvalid_o, + output reg [ DATA_WIDTH-1:0] iob_rdata_o, + output reg iob_rvalid_o, output wire iob_ready_o, /* * AXI master interface @@ -67,144 +67,335 @@ module iob2axi #( output wire axi_rready_o ); - localparam AXI_RLEN = 2 ** AXI_RLEN_W; - localparam AXI_WLEN = 2 ** AXI_WLEN_W; + localparam integer BurstRLEN = AXI_RLEN + 1; + localparam integer BurstWLEN = AXI_WLEN + 1; + localparam integer IDLE = 0, WriteFIFO = 1, ReadFIFO = 2; + + wire iob_we; + // Write bus + wire w_fifo_full; + wire w_fifo_wr; + wire [DATA_WIDTH+STRB_WIDTH-1:0] w_fifo_wdata; + wire w_fifo_empty; + wire w_fifo_rd; + wire [DATA_WIDTH+STRB_WIDTH-1:0] w_fifo_rdata; + wire [ AXI_WLEN:0] w_fifo_level; + wire w_ext_mem_clk; + wire w_ext_mem_w_en; + wire [ AXI_WLEN-1:0] w_ext_mem_w_addr; + wire [DATA_WIDTH+STRB_WIDTH-1:0] w_ext_mem_w_data; + wire w_ext_mem_r_en; + wire [ AXI_WLEN-1:0] w_ext_mem_r_addr; + wire [DATA_WIDTH+STRB_WIDTH-1:0] w_ext_mem_r_data; + wire iob_wvalid; + wire iob_waddr_q; + wire iob_wready; + wire w_state_q; + reg w_state_next; + // Read bus + wire r_fifo_full; + wire r_fifo_wr; + wire [ DATA_WIDTH-1:0] r_fifo_wdata; + wire r_fifo_empty; + wire r_fifo_rd; + wire [ DATA_WIDTH-1:0] r_fifo_rdata; + wire [ AXI_RLEN:0] r_fifo_level; + wire r_ext_mem_clk; + wire r_ext_mem_w_en; + wire [ AXI_RLEN-1:0] r_ext_mem_w_addr; + wire [ DATA_WIDTH-1:0] r_ext_mem_w_data; + wire r_ext_mem_r_en; + wire [ AXI_RLEN-1:0] r_ext_mem_r_addr; + wire [ DATA_WIDTH-1:0] r_ext_mem_r_data; + wire iob_arvalid; + wire iob_arready; + wire iob_raddr_q; + reg iob_rvalid_next; + wire r_state_q; + reg r_state_next; + + assign iob_we = |iob_wstrb_i; + assign iob_rready_o = iob_we ? iob_wready : iob_arready; + // Write bus + // // IOb-bus + assign iob_wvalid = iob_we & iob_avalid_i; + assign iob_wready = axi_awready_i; + assign iob_wready = axi_wready_i; + // // AXI + assign axi_awid_o = {AXI_ID_WIDTH{1'b0}}; + assign axi_awaddr_o = iob_wvalid ? iob_addr_i : iob_waddr_q; + assign axi_awlen_o = AXI_WLEN; + assign axi_awsize_o = 3'b010; + assign axi_awburst_o = 2'b01; + assign axi_awlock_o = 1'b0; + assign axi_awcache_o = 4'hf; + assign axi_awprot_o = 3'b010; + assign axi_awvalid_o = iob_wvalid; + assign axi_wdata_o = iob_wdata_i; + assign axi_wstrb_o = iob_wstrb_i; + assign axi_wlast_o = 1'b1; + assign axi_wvalid_o = iob_wvalid; + assign axi_bid_i = {AXI_ID_WIDTH{1'b0}}; + assign axi_bresp_i = 2'b00; + assign axi_bvalid_i = 1'b0; + assign axi_bready_o = 1'b1; + // Read bus + // // IOb-bus + assign iob_arvalid = ~iob_we & iob_avalid_i; + // // AXI + assign axi_arid_o = {AXI_ID_WIDTH{1'b0}}; + assign axi_araddr_o = iob_arvalid ? iob_addr_i : iob_raddr_q; + assign axi_arlen_o = AXI_RLEN; + assign axi_arsize_o = 3'b010; + assign axi_arburst_o = 2'b01; + assign axi_arlock_o = 1'b0; + assign axi_arcache_o = 4'hf; + assign axi_arprot_o = 3'b010; + assign axi_rready_o = 1'b1; + + + // Write bus FSM + always @(*) begin + axi_awvalid_o = 1'b0; + axi_wvalid_o = 1'b0; + case (w_state_q) + default: begin + iob_wready = 1'b1; + if (iob_wvalid) begin + r_state_next = WriteFIFO; + w_fifo_wr = 1'b1; + w_fifo_wdata = {iob_wdata_i, iob_wstrb_i}; + end else begin + r_state_next = IDLE; + end + end + WriteFIFO: begin + w_fifo_wr = 1'b0; + if (w_fifo_full) begin + w_state_next = IDLE; + iob_wready = 1'b0; + end else begin + w_state_next = WriteFIFO; + if (iob_wvalid) begin + w_fifo_wr = 1'b1; + w_fifo_wdata = {iob_wdata_i, iob_wstrb_i}; + end + end + end + ReadFIFO: begin + if (w_fifo_empty) begin + w_state_next = IDLE; + iob_wready = 1'b1; + end else begin + w_state_next = ReadFIFO; + end + end + endcase + end + + // Read bus FSM + always @(*) begin + iob_rvalid_next = 1'b0; + iob_arready = 1'b0; + r_fifo_wr = 1'b0; + case (r_state_q) + default: begin + iob_arready = axi_arready_i; + if (iob_arvalid & axi_arready_i) begin + r_state_next = WriteFIFO; + axi_arvalid_o = 1'b1; + end else begin + r_state_next = IDLE; + end + end + WriteFIFO: begin + if (r_fifo_full) begin + r_state_next = ReadFIFO; + r_fifo_rd = 1'b1; + iob_rvalid_next = 1'b1; + end else begin + r_state_next = WriteFIFO; + if(axi_rvalid_i) begin + r_fifo_wr = 1'b1; + r_fifo_wdata = axi_rdata_i; + end + end + end + ReadFIFO: begin + iob_arready = 1'b1; + if (r_fifo_empty) begin + r_state_next = IDLE; + r_fifo_rd = 1'b0; + iob_rvalid_o = 1'b0; + iob_rdata_o = {DATA_WIDTH{1'b0}}; + end else begin + r_state_next = ReadFIFO; + iob_rdata_o = r_fifo_rdata; + if (iob_arvalid) begin + r_fifo_rd = 1'b1; + iob_rvalid_next = 1'b1; + end + end + end + endcase + end - // - // Input/Write bus FIFO - // - wire in_fifo_full; - wire in_fifo_wr; - wire [DATA_WIDTH-1:0] in_fifo_wdata; - - wire in_fifo_empty; - wire in_fifo_rd; - wire [DATA_WIDTH-1:0] in_fifo_rdata; - - wire [AXI_WLEN:0] in_fifo_level; - wire in_ext_mem_clk; - wire in_ext_mem_w_en; - wire [AXI_RLEN-1:0] in_ext_mem_w_addr; - wire [DATA_WIDTH-1:0] in_ext_mem_w_data; - wire in_ext_mem_r_en; - wire [AXI_RLEN-1:0] in_ext_mem_r_addr; - wire [DATA_WIDTH-1:0] in_ext_mem_r_data; // - // Output/Read bus FIFO - // - wire out_fifo_full; - wire out_fifo_wr; - wire [DATA_WIDTH-1:0] out_fifo_wdata; - - wire out_fifo_empty; - wire out_fifo_rd; - wire [DATA_WIDTH-1:0] out_fifo_rdata; - - wire [AXI_RLEN:0] out_fifo_level; - - wire out_ext_mem_clk; - wire out_ext_mem_w_en; - wire [AXI_RLEN-1:0] out_ext_mem_w_addr; - wire [DATA_WIDTH-1:0] out_ext_mem_w_data; - wire out_ext_mem_r_en; - wire [AXI_RLEN-1:0] out_ext_mem_r_addr; - wire [DATA_WIDTH-1:0] out_ext_mem_r_data; - - assign in_fifo_wr = s_valid_i & |s_wstrb_i & ~in_fifo_full; - assign in_fifo_wdata = {s_wdata_i, s_wstrb_i}; - assign in_fifo_rd = wr_valid; - // - // Output/Read bus FIFO + // Write bus FIFO // - assign out_fifo_wr = rd_valid & |rd_wstrb & ~out_fifo_full; - assign out_fifo_wdata = rd_wdata; - assign out_fifo_rd = s_valid_i & ~|s_wstrb_i & ~out_fifo_empty; - iob_fifo_sync #( - .W_DATA_W(DATA_WIDTH), - .R_DATA_W(DATA_WIDTH), - .ADDR_W (AXI_WLEN) + .W_DATA_W(DATA_WIDTH + STRB_WIDTH), + .R_DATA_W(DATA_WIDTH + STRB_WIDTH), + .ADDR_W (BurstWLEN) ) write_bus_iob_fifo_sync ( .clk_i(clk_i), .rst_i(rst_i), - .w_en_i (in_fifo_wr), - .w_data_i(in_fifo_wdata), - .w_full_o(in_fifo_full), + .w_en_i (w_fifo_wr), + .w_data_i(w_fifo_wdata), + .w_full_o(w_fifo_full), - .r_en_i (in_fifo_rd), - .r_data_o (in_fifo_rdata), - .r_empty_o(in_fifo_empty), + .r_en_i (w_fifo_rd), + .r_data_o (w_fifo_rdata), + .r_empty_o(w_fifo_empty), - .ext_mem_clk_o(in_ext_mem_clk), - .ext_mem_w_en_o(in_ext_mem_w_en), - .ext_mem_w_addr_o(in_ext_mem_w_addr), - .ext_mem_w_data_o(in_ext_mem_w_data), + .ext_mem_clk_o(w_ext_mem_clk), + .ext_mem_w_en_o(w_ext_mem_w_en), + .ext_mem_w_addr_o(w_ext_mem_w_addr), + .ext_mem_w_data_o(w_ext_mem_w_data), - .ext_mem_r_en_o (in_ext_mem_r_en), - .ext_mem_r_addr_o(in_ext_mem_r_addr), - .ext_mem_r_data_i(in_ext_mem_r_data), + .ext_mem_r_en_o (w_ext_mem_r_en), + .ext_mem_r_addr_o(w_ext_mem_r_addr), + .ext_mem_r_data_i(w_ext_mem_r_data), - .level_o(in_fifo_level) + .level_o(w_fifo_level) ); iob_ram_2p #( - .DATA_W(DATA_WIDTH), - .ADDR_W(AXI_WLEN) + .DATA_W(DATA_WIDTH + STRB_WIDTH), + .ADDR_W(BurstWLEN) ) write_bus_ram ( - .clk_i(in_ext_mem_clk), + .clk_i(w_ext_mem_clk), - .w_en_i (in_ext_mem_w_en), - .w_addr_i(in_ext_mem_w_addr), - .w_data_i(in_ext_mem_w_data), + .w_en_i (w_ext_mem_w_en), + .w_addr_i(w_ext_mem_w_addr), + .w_data_i(w_ext_mem_w_data), - .r_en_i (in_ext_mem_r_en), - .r_addr_i(in_ext_mem_r_addr), - .r_data_o(in_ext_mem_r_data) + .r_en_i (w_ext_mem_r_en), + .r_addr_i(w_ext_mem_r_addr), + .r_data_o(w_ext_mem_r_data) ); + iob_reg_re #( + .DATA_W (ADDR_WIDTH), + .RST_VAL(0) + ) iob_reg_iob_waddr ( + .clk_i (clk_i), + .arst_i(arst_i), + .cke_i (cke_i), + .rst_i (1'b0), + .en_i (iob_wvalid), + .data_i(iob_addr_i), + .data_o(iob_waddr_q) + ); + + iob_reg_re #( + .DATA_W (1), + .RST_VAL(0) + ) iob_reg_w_state ( + .clk_i (clk_i), + .arst_i(arst_i), + .cke_i (cke_i), + .rst_i (1'b0), + .en_i (1'b1), + .data_i(w_state_next), + .data_o(w_state_q) + ); + + // + // Read bus FIFO + // iob_fifo_sync #( .W_DATA_W(DATA_WIDTH), .R_DATA_W(DATA_WIDTH), - .ADDR_W (AXI_RLEN) + .ADDR_W (BurstRLEN) ) read_bus_iob_fifo_sync ( .clk_i(clk_i), .rst_i(rst_i), - .w_en_i (out_fifo_wr), - .w_data_i(out_fifo_wdata), - .w_full_o(out_fifo_full), + .w_en_i (r_fifo_wr), + .w_data_i(r_fifo_wdata), + .w_full_o(r_fifo_full), - .r_en_i (out_fifo_rd), - .r_data_o (out_fifo_rdata), - .r_empty_o(out_fifo_empty), + .r_en_i (r_fifo_rd), + .r_data_o (r_fifo_rdata), + .r_empty_o(r_fifo_empty), - .ext_mem_clk_o(out_ext_mem_clk), - .ext_mem_w_en_o(out_ext_mem_w_en), - .ext_mem_w_addr_o(out_ext_mem_w_addr), - .ext_mem_w_data_o(out_ext_mem_w_data), + .ext_mem_clk_o(r_ext_mem_clk), + .ext_mem_w_en_o(r_ext_mem_w_en), + .ext_mem_w_addr_o(r_ext_mem_w_addr), + .ext_mem_w_data_o(r_ext_mem_w_data), - .ext_mem_r_en_o (out_ext_mem_r_en), - .ext_mem_r_addr_o(out_ext_mem_r_addr), - .ext_mem_r_data_i(out_ext_mem_r_data), + .ext_mem_r_en_o (r_ext_mem_r_en), + .ext_mem_r_addr_o(r_ext_mem_r_addr), + .ext_mem_r_data_i(r_ext_mem_r_data), - .level_o(out_fifo_level) + .level_o(r_fifo_level) ); iob_ram_2p #( .DATA_W(DATA_WIDTH), - .ADDR_W(AXI_RLEN) + .ADDR_W(BurstRLEN) ) read_bus_ram ( - .clk_i(out_ext_mem_clk), + .clk_i(r_ext_mem_clk), - .w_en_i (out_ext_mem_w_en), - .w_addr_i(out_ext_mem_w_addr), - .w_data_i(out_ext_mem_w_data), + .w_en_i (r_ext_mem_w_en), + .w_addr_i(r_ext_mem_w_addr), + .w_data_i(r_ext_mem_w_data), + + .r_en_i (r_ext_mem_r_en), + .r_addr_i(r_ext_mem_r_addr), + .r_data_o(r_ext_mem_r_data) + ); + + iob_reg_re #( + .DATA_W (ADDR_WIDTH), + .RST_VAL(0) + ) iob_reg_iob_raddr ( + .clk_i (clk_i), + .arst_i(arst_i), + .cke_i (cke_i), + .rst_i (1'b0), + .en_i (iob_arvalid), + .data_i(iob_addr_i), + .data_o(iob_raddr_q) + ); + + iob_reg_re #( + .DATA_W (1), + .RST_VAL(0) + ) iob_reg_r_state ( + .clk_i (clk_i), + .arst_i(arst_i), + .cke_i (cke_i), + .rst_i (1'b0), + .en_i (1'b1), + .data_i(r_state_next), + .data_o(r_state_q) + ); - .r_en_i (out_ext_mem_r_en), - .r_addr_i(out_ext_mem_r_addr), - .r_data_o(out_ext_mem_r_data) + iob_reg_re #( + .DATA_W (1), + .RST_VAL(0) + ) iob_reg_iob_rvalid ( + .clk_i (clk_i), + .arst_i(arst_i), + .cke_i (cke_i), + .rst_i (1'b0), + .en_i (1'b1), + .data_i(iob_rvalid_next), + .data_o(iob_rvalid_o) ); endmodule From c37f11a2b4b6782d74f6e11b999591afee2ad5d1 Mon Sep 17 00:00:00 2001 From: Pedro Antunes Date: Thu, 14 Sep 2023 18:59:31 +0100 Subject: [PATCH 12/27] iob2axi.v: write FSM made (not tested). --- hardware/src/iob2axi.v | 68 ++++++++++++++++++++---------------------- 1 file changed, 33 insertions(+), 35 deletions(-) diff --git a/hardware/src/iob2axi.v b/hardware/src/iob2axi.v index 08be8d1c..a9bffe36 100644 --- a/hardware/src/iob2axi.v +++ b/hardware/src/iob2axi.v @@ -38,12 +38,12 @@ module iob2axi #( output wire axi_awlock_o, output wire [ 3:0] axi_awcache_o, output wire [ 2:0] axi_awprot_o, - output wire axi_awvalid_o, + output reg axi_awvalid_o, input wire axi_awready_i, - output wire [ DATA_WIDTH-1:0] axi_wdata_o, - output wire [ STRB_WIDTH-1:0] axi_wstrb_o, - output wire axi_wlast_o, - output wire axi_wvalid_o, + output reg [ DATA_WIDTH-1:0] axi_wdata_o, + output reg [ STRB_WIDTH-1:0] axi_wstrb_o, + output reg axi_wlast_o, + output reg axi_wvalid_o, input wire axi_wready_i, input wire [AXI_ID_WIDTH-1:0] axi_bid_i, input wire [ 1:0] axi_bresp_i, @@ -57,7 +57,7 @@ module iob2axi #( output wire axi_arlock_o, output wire [ 3:0] axi_arcache_o, output wire [ 2:0] axi_arprot_o, - output wire axi_arvalid_o, + output reg axi_arvalid_o, input wire axi_arready_i, input wire [AXI_ID_WIDTH-1:0] axi_rid_i, input wire [ DATA_WIDTH-1:0] axi_rdata_i, @@ -74,10 +74,10 @@ module iob2axi #( wire iob_we; // Write bus wire w_fifo_full; - wire w_fifo_wr; - wire [DATA_WIDTH+STRB_WIDTH-1:0] w_fifo_wdata; + reg w_fifo_wr; + reg [DATA_WIDTH+STRB_WIDTH-1:0] w_fifo_wdata; wire w_fifo_empty; - wire w_fifo_rd; + reg w_fifo_rd; wire [DATA_WIDTH+STRB_WIDTH-1:0] w_fifo_rdata; wire [ AXI_WLEN:0] w_fifo_level; wire w_ext_mem_clk; @@ -89,15 +89,15 @@ module iob2axi #( wire [DATA_WIDTH+STRB_WIDTH-1:0] w_ext_mem_r_data; wire iob_wvalid; wire iob_waddr_q; - wire iob_wready; + reg iob_wready; wire w_state_q; reg w_state_next; // Read bus wire r_fifo_full; - wire r_fifo_wr; - wire [ DATA_WIDTH-1:0] r_fifo_wdata; + reg r_fifo_wr; + reg [ DATA_WIDTH-1:0] r_fifo_wdata; wire r_fifo_empty; - wire r_fifo_rd; + reg r_fifo_rd; wire [ DATA_WIDTH-1:0] r_fifo_rdata; wire [ AXI_RLEN:0] r_fifo_level; wire r_ext_mem_clk; @@ -108,7 +108,7 @@ module iob2axi #( wire [ AXI_RLEN-1:0] r_ext_mem_r_addr; wire [ DATA_WIDTH-1:0] r_ext_mem_r_data; wire iob_arvalid; - wire iob_arready; + reg iob_arready; wire iob_raddr_q; reg iob_rvalid_next; wire r_state_q; @@ -119,8 +119,6 @@ module iob2axi #( // Write bus // // IOb-bus assign iob_wvalid = iob_we & iob_avalid_i; - assign iob_wready = axi_awready_i; - assign iob_wready = axi_wready_i; // // AXI assign axi_awid_o = {AXI_ID_WIDTH{1'b0}}; assign axi_awaddr_o = iob_wvalid ? iob_addr_i : iob_waddr_q; @@ -130,14 +128,6 @@ module iob2axi #( assign axi_awlock_o = 1'b0; assign axi_awcache_o = 4'hf; assign axi_awprot_o = 3'b010; - assign axi_awvalid_o = iob_wvalid; - assign axi_wdata_o = iob_wdata_i; - assign axi_wstrb_o = iob_wstrb_i; - assign axi_wlast_o = 1'b1; - assign axi_wvalid_o = iob_wvalid; - assign axi_bid_i = {AXI_ID_WIDTH{1'b0}}; - assign axi_bresp_i = 2'b00; - assign axi_bvalid_i = 1'b0; assign axi_bready_o = 1'b1; // Read bus // // IOb-bus @@ -157,23 +147,25 @@ module iob2axi #( // Write bus FSM always @(*) begin axi_awvalid_o = 1'b0; - axi_wvalid_o = 1'b0; + axi_wvalid_o = 1'b0; + iob_wready = 1'b0; + w_fifo_rd = 1'b0; case (w_state_q) default: begin iob_wready = 1'b1; if (iob_wvalid) begin - r_state_next = WriteFIFO; + w_state_next = WriteFIFO; w_fifo_wr = 1'b1; w_fifo_wdata = {iob_wdata_i, iob_wstrb_i}; end else begin - r_state_next = IDLE; + w_state_next = IDLE; end end WriteFIFO: begin w_fifo_wr = 1'b0; if (w_fifo_full) begin - w_state_next = IDLE; - iob_wready = 1'b0; + w_state_next = ReadFIFO; + w_fifo_rd = 1'b1; end else begin w_state_next = WriteFIFO; if (iob_wvalid) begin @@ -183,11 +175,17 @@ module iob2axi #( end end ReadFIFO: begin - if (w_fifo_empty) begin - w_state_next = IDLE; - iob_wready = 1'b1; - end else begin - w_state_next = ReadFIFO; + w_state_next = ReadFIFO; + if (axi_awready_i & axi_wready_i) begin + w_fifo_rd = 1'b1; + axi_awvalid_o = 1'b1; + axi_wvalid_o = 1'b1; + {axi_wdata_o, axi_wstrb_o} = w_fifo_rdata; + if (w_fifo_empty) begin + w_state_next = IDLE; + iob_wready = 1'b1; + axi_wlast_o = 1'b1; + end end end endcase @@ -215,7 +213,7 @@ module iob2axi #( iob_rvalid_next = 1'b1; end else begin r_state_next = WriteFIFO; - if(axi_rvalid_i) begin + if (axi_rvalid_i) begin r_fifo_wr = 1'b1; r_fifo_wdata = axi_rdata_i; end From df209cdb263c2707a08cf743aed04a24fbf11d69 Mon Sep 17 00:00:00 2001 From: Pedro Antunes Date: Thu, 14 Sep 2023 21:59:19 +0100 Subject: [PATCH 13/27] iob2axi.v: fix errors detected by simulators. --- hardware/src/ext_mem.v | 24 ++++--- hardware/src/iob2axi.v | 96 ++++++++++++++------------ hardware/src/iob_soc_opencryptolinux.v | 8 +-- 3 files changed, 64 insertions(+), 64 deletions(-) diff --git a/hardware/src/ext_mem.v b/hardware/src/ext_mem.v index d065cb15..47b951e9 100644 --- a/hardware/src/ext_mem.v +++ b/hardware/src/ext_mem.v @@ -3,10 +3,12 @@ `include "iob_utils.vh" module ext_mem #( - parameter ADDR_W = 0, - parameter DATA_W = 0, - parameter MEM_ADDR_W = 0, - parameter AXI_ID_W = 0 + parameter ADDR_W = 0, + parameter DATA_W = 0, + parameter AXI_ID_W = 0, + parameter AXI_LEN_W = 8, + parameter AXI_ADDR_W = ADDR_W, + parameter AXI_DATA_W = DATA_W ) ( // Instruction bus input [ `REQ_W-1:0] i_req, @@ -42,19 +44,19 @@ module ext_mem #( // AXI interface iob2axi #( - .ADDR_WIDTH(MEM_ADDR_W), - .DATA_WIDTH(DATA_W), + .ADDR_WIDTH(AXI_ADDR_W), + .DATA_WIDTH(AXI_DATA_W), .AXI_ID_WIDTH(AXI_ID_W), - .AXI_RLEN(8'h0f), + .AXI_RLEN(8'h00), .AXI_WLEN(8'h00) ) ext_mem_iob2axi ( .iob_avalid_i(ext_mem_req[`AVALID(0)]), - .iob_addr_i (ext_mem_req[`ADDRESS(0, MEM_ADDR_W)]), + .iob_addr_i (ext_mem_req[`ADDRESS(0, AXI_ADDR_W)]), .iob_wdata_i (ext_mem_req[`WDATA(0)]), .iob_wstrb_i (ext_mem_req[`WSTRB(0)]), - .iob_rdata_o (ext_mem_resp[`RVALID(0)]), - .iob_rvalid_o(ext_mem_resp[`RDATA(0)]), - .iob_rready_o(ext_mem_resp[`READY(0)]), + .iob_rdata_o (ext_mem_resp[`RDATA(0)]), + .iob_rvalid_o(ext_mem_resp[`RVALID(0)]), + .iob_ready_o (ext_mem_resp[`READY(0)]), `include "axi_m_m_portmap.vs" .clk_i (clk_i), .cke_i (cke_i), diff --git a/hardware/src/iob2axi.v b/hardware/src/iob2axi.v index a9bffe36..e95c72f3 100644 --- a/hardware/src/iob2axi.v +++ b/hardware/src/iob2axi.v @@ -25,7 +25,7 @@ module iob2axi #( input wire [ DATA_WIDTH-1:0] iob_wdata_i, input wire [ STRB_WIDTH-1:0] iob_wstrb_i, output reg [ DATA_WIDTH-1:0] iob_rdata_o, - output reg iob_rvalid_o, + output wire iob_rvalid_o, output wire iob_ready_o, /* * AXI master interface @@ -35,9 +35,10 @@ module iob2axi #( output wire [ 7:0] axi_awlen_o, output wire [ 2:0] axi_awsize_o, output wire [ 1:0] axi_awburst_o, - output wire axi_awlock_o, + output wire [ 1:0] axi_awlock_o, output wire [ 3:0] axi_awcache_o, output wire [ 2:0] axi_awprot_o, + output wire [ 3:0] axi_awqos_o, output reg axi_awvalid_o, input wire axi_awready_i, output reg [ DATA_WIDTH-1:0] axi_wdata_o, @@ -54,9 +55,10 @@ module iob2axi #( output wire [ 7:0] axi_arlen_o, output wire [ 2:0] axi_arsize_o, output wire [ 1:0] axi_arburst_o, - output wire axi_arlock_o, + output wire [ 1:0] axi_arlock_o, output wire [ 3:0] axi_arcache_o, output wire [ 2:0] axi_arprot_o, + output wire [ 3:0] axi_arqos_o, output reg axi_arvalid_o, input wire axi_arready_i, input wire [AXI_ID_WIDTH-1:0] axi_rid_i, @@ -79,16 +81,16 @@ module iob2axi #( wire w_fifo_empty; reg w_fifo_rd; wire [DATA_WIDTH+STRB_WIDTH-1:0] w_fifo_rdata; - wire [ AXI_WLEN:0] w_fifo_level; + wire [ BurstWLEN:0] w_fifo_level; wire w_ext_mem_clk; wire w_ext_mem_w_en; - wire [ AXI_WLEN-1:0] w_ext_mem_w_addr; + wire [ BurstWLEN-1:0] w_ext_mem_w_addr; wire [DATA_WIDTH+STRB_WIDTH-1:0] w_ext_mem_w_data; wire w_ext_mem_r_en; - wire [ AXI_WLEN-1:0] w_ext_mem_r_addr; + wire [ BurstWLEN-1:0] w_ext_mem_r_addr; wire [DATA_WIDTH+STRB_WIDTH-1:0] w_ext_mem_r_data; wire iob_wvalid; - wire iob_waddr_q; + wire [ ADDR_WIDTH-1:0] iob_waddr_q; reg iob_wready; wire w_state_q; reg w_state_next; @@ -99,23 +101,23 @@ module iob2axi #( wire r_fifo_empty; reg r_fifo_rd; wire [ DATA_WIDTH-1:0] r_fifo_rdata; - wire [ AXI_RLEN:0] r_fifo_level; + wire [ BurstRLEN:0] r_fifo_level; wire r_ext_mem_clk; wire r_ext_mem_w_en; - wire [ AXI_RLEN-1:0] r_ext_mem_w_addr; + wire [ BurstRLEN-1:0] r_ext_mem_w_addr; wire [ DATA_WIDTH-1:0] r_ext_mem_w_data; wire r_ext_mem_r_en; - wire [ AXI_RLEN-1:0] r_ext_mem_r_addr; + wire [ BurstRLEN-1:0] r_ext_mem_r_addr; wire [ DATA_WIDTH-1:0] r_ext_mem_r_data; wire iob_arvalid; reg iob_arready; - wire iob_raddr_q; + wire [ ADDR_WIDTH-1:0] iob_araddr_q; reg iob_rvalid_next; wire r_state_q; reg r_state_next; assign iob_we = |iob_wstrb_i; - assign iob_rready_o = iob_we ? iob_wready : iob_arready; + assign iob_ready_o = iob_we ? iob_wready : iob_arready; // Write bus // // IOb-bus assign iob_wvalid = iob_we & iob_avalid_i; @@ -125,22 +127,24 @@ module iob2axi #( assign axi_awlen_o = AXI_WLEN; assign axi_awsize_o = 3'b010; assign axi_awburst_o = 2'b01; - assign axi_awlock_o = 1'b0; + assign axi_awlock_o = 2'b00; assign axi_awcache_o = 4'hf; assign axi_awprot_o = 3'b010; + assign axi_awqos_o = 4'h0; assign axi_bready_o = 1'b1; // Read bus // // IOb-bus assign iob_arvalid = ~iob_we & iob_avalid_i; // // AXI assign axi_arid_o = {AXI_ID_WIDTH{1'b0}}; - assign axi_araddr_o = iob_arvalid ? iob_addr_i : iob_raddr_q; + assign axi_araddr_o = iob_arvalid ? iob_addr_i : iob_araddr_q; assign axi_arlen_o = AXI_RLEN; assign axi_arsize_o = 3'b010; assign axi_arburst_o = 2'b01; - assign axi_arlock_o = 1'b0; + assign axi_arlock_o = 2'b00; assign axi_arcache_o = 4'hf; assign axi_arprot_o = 3'b010; + assign axi_arqos_o = 4'h0; assign axi_rready_o = 1'b1; @@ -148,8 +152,14 @@ module iob2axi #( always @(*) begin axi_awvalid_o = 1'b0; axi_wvalid_o = 1'b0; + axi_wdata_o = {DATA_WIDTH{1'b0}}; + axi_wstrb_o = {STRB_WIDTH{1'b0}}; + axi_wlast_o = 1'b0; iob_wready = 1'b0; + w_fifo_wr = 1'b0; w_fifo_rd = 1'b0; + w_fifo_wdata = {DATA_WIDTH{1'b0}}; + w_state_next = w_state_q; case (w_state_q) default: begin iob_wready = 1'b1; @@ -157,25 +167,18 @@ module iob2axi #( w_state_next = WriteFIFO; w_fifo_wr = 1'b1; w_fifo_wdata = {iob_wdata_i, iob_wstrb_i}; - end else begin - w_state_next = IDLE; end end WriteFIFO: begin - w_fifo_wr = 1'b0; if (w_fifo_full) begin w_state_next = ReadFIFO; w_fifo_rd = 1'b1; - end else begin - w_state_next = WriteFIFO; - if (iob_wvalid) begin - w_fifo_wr = 1'b1; - w_fifo_wdata = {iob_wdata_i, iob_wstrb_i}; - end + end else if (iob_wvalid) begin + w_fifo_wr = 1'b1; + w_fifo_wdata = {iob_wdata_i, iob_wstrb_i}; end end ReadFIFO: begin - w_state_next = ReadFIFO; if (axi_awready_i & axi_wready_i) begin w_fifo_rd = 1'b1; axi_awvalid_o = 1'b1; @@ -183,7 +186,6 @@ module iob2axi #( {axi_wdata_o, axi_wstrb_o} = w_fifo_rdata; if (w_fifo_empty) begin w_state_next = IDLE; - iob_wready = 1'b1; axi_wlast_o = 1'b1; end end @@ -193,17 +195,20 @@ module iob2axi #( // Read bus FSM always @(*) begin - iob_rvalid_next = 1'b0; iob_arready = 1'b0; + axi_arvalid_o = 1'b0; + iob_rvalid_next = 1'b0; + iob_rdata_o = {DATA_WIDTH{1'b0}}; r_fifo_wr = 1'b0; + r_fifo_rd = 1'b0; + r_fifo_wdata = {DATA_WIDTH{1'b0}}; + r_state_next = r_state_q; case (r_state_q) default: begin iob_arready = axi_arready_i; if (iob_arvalid & axi_arready_i) begin r_state_next = WriteFIFO; axi_arvalid_o = 1'b1; - end else begin - r_state_next = IDLE; end end WriteFIFO: begin @@ -211,24 +216,17 @@ module iob2axi #( r_state_next = ReadFIFO; r_fifo_rd = 1'b1; iob_rvalid_next = 1'b1; - end else begin - r_state_next = WriteFIFO; - if (axi_rvalid_i) begin - r_fifo_wr = 1'b1; - r_fifo_wdata = axi_rdata_i; - end + end else if (axi_rvalid_i) begin + r_fifo_wr = 1'b1; + r_fifo_wdata = axi_rdata_i; end end ReadFIFO: begin - iob_arready = 1'b1; + iob_arready = axi_arready_i; if (r_fifo_empty) begin r_state_next = IDLE; - r_fifo_rd = 1'b0; - iob_rvalid_o = 1'b0; - iob_rdata_o = {DATA_WIDTH{1'b0}}; end else begin - r_state_next = ReadFIFO; - iob_rdata_o = r_fifo_rdata; + iob_rdata_o = r_fifo_rdata; if (iob_arvalid) begin r_fifo_rd = 1'b1; iob_rvalid_next = 1'b1; @@ -247,8 +245,11 @@ module iob2axi #( .R_DATA_W(DATA_WIDTH + STRB_WIDTH), .ADDR_W (BurstWLEN) ) write_bus_iob_fifo_sync ( - .clk_i(clk_i), - .rst_i(rst_i), + .clk_i (clk_i), + .cke_i (cke_i), + .arst_i(arst_i), + + .rst_i(1'b0), .w_en_i (w_fifo_wr), .w_data_i(w_fifo_wdata), @@ -319,8 +320,11 @@ module iob2axi #( .R_DATA_W(DATA_WIDTH), .ADDR_W (BurstRLEN) ) read_bus_iob_fifo_sync ( - .clk_i(clk_i), - .rst_i(rst_i), + .clk_i (clk_i), + .cke_i (cke_i), + .arst_i(arst_i), + + .rst_i(1'b0), .w_en_i (r_fifo_wr), .w_data_i(r_fifo_wdata), @@ -367,7 +371,7 @@ module iob2axi #( .rst_i (1'b0), .en_i (iob_arvalid), .data_i(iob_addr_i), - .data_o(iob_raddr_q) + .data_o(iob_araddr_q) ); iob_reg_re #( diff --git a/hardware/src/iob_soc_opencryptolinux.v b/hardware/src/iob_soc_opencryptolinux.v index a92358ee..1f44b3fa 100644 --- a/hardware/src/iob_soc_opencryptolinux.v +++ b/hardware/src/iob_soc_opencryptolinux.v @@ -179,14 +179,8 @@ module iob_soc_opencryptolinux #( ext_mem #( .ADDR_W (ADDR_W), .DATA_W (DATA_W), - .FIRM_ADDR_W(SRAM_ADDR_W), - .MEM_ADDR_W (MEM_ADDR_W), - .DDR_ADDR_W (`DDR_ADDR_W), - .DDR_DATA_W (`DDR_DATA_W), .AXI_ID_W (AXI_ID_W), - .AXI_LEN_W (AXI_LEN_W), - .AXI_ADDR_W (AXI_ADDR_W), - .AXI_DATA_W (AXI_DATA_W) + .AXI_ADDR_W (MEM_ADDR_W) ) ext_mem0 ( // instruction bus .i_req (ext_mem_i_req), From 23d22b1266390ec9c0817014d20cd1658d90ac3d Mon Sep 17 00:00:00 2001 From: Pedro Antunes Date: Fri, 15 Sep 2023 14:26:12 +0100 Subject: [PATCH 14/27] iob2axi.v, ext_mem.v: small fixes to interface converter. --- .../src/iob_soc_opencryptolinux_sim_wrapper.v | 2 +- hardware/src/ext_mem.v | 2 +- hardware/src/iob2axi.v | 21 +- hardware/src/iob_soc_opencryptolinux.v | 184 +++++++++--------- software/src/iob_soc_opencryptolinux_boot.c | 5 - 5 files changed, 107 insertions(+), 107 deletions(-) diff --git a/hardware/simulation/src/iob_soc_opencryptolinux_sim_wrapper.v b/hardware/simulation/src/iob_soc_opencryptolinux_sim_wrapper.v index 7aea12aa..6c954fe1 100644 --- a/hardware/simulation/src/iob_soc_opencryptolinux_sim_wrapper.v +++ b/hardware/simulation/src/iob_soc_opencryptolinux_sim_wrapper.v @@ -40,7 +40,7 @@ module iob_soc_opencryptolinux_sim_wrapper ( initial begin `ifdef VCD $dumpfile("uut.vcd"); - $dumpvars(0, iob_soc_opencryptolinux_sim_wrapper.soc0); + $dumpvars(); `endif end diff --git a/hardware/src/ext_mem.v b/hardware/src/ext_mem.v index 47b951e9..84ff4820 100644 --- a/hardware/src/ext_mem.v +++ b/hardware/src/ext_mem.v @@ -31,7 +31,7 @@ module ext_mem #( iob_merge #( .ADDR_W (ADDR_W), .N_MASTERS(2) - ) merge_i_d_buses_into_l2 ( + ) merge_i_d_buses ( .clk_i (clk_i), .arst_i (arst_i), // masters diff --git a/hardware/src/iob2axi.v b/hardware/src/iob2axi.v index e95c72f3..7c73f2ac 100644 --- a/hardware/src/iob2axi.v +++ b/hardware/src/iob2axi.v @@ -92,8 +92,8 @@ module iob2axi #( wire iob_wvalid; wire [ ADDR_WIDTH-1:0] iob_waddr_q; reg iob_wready; - wire w_state_q; - reg w_state_next; + wire [ 1:0] w_state_q; + reg [ 1:0] w_state_next; // Read bus wire r_fifo_full; reg r_fifo_wr; @@ -113,8 +113,8 @@ module iob2axi #( reg iob_arready; wire [ ADDR_WIDTH-1:0] iob_araddr_q; reg iob_rvalid_next; - wire r_state_q; - reg r_state_next; + wire [ 1:0] r_state_q; + reg [ 1:0] r_state_next; assign iob_we = |iob_wstrb_i; assign iob_ready_o = iob_we ? iob_wready : iob_arready; @@ -158,7 +158,7 @@ module iob2axi #( iob_wready = 1'b0; w_fifo_wr = 1'b0; w_fifo_rd = 1'b0; - w_fifo_wdata = {DATA_WIDTH{1'b0}}; + w_fifo_wdata = {DATA_WIDTH + STRB_WIDTH{1'b0}}; w_state_next = w_state_q; case (w_state_q) default: begin @@ -170,6 +170,7 @@ module iob2axi #( end end WriteFIFO: begin + iob_wready = ~w_fifo_full; if (w_fifo_full) begin w_state_next = ReadFIFO; w_fifo_rd = 1'b1; @@ -206,9 +207,11 @@ module iob2axi #( case (r_state_q) default: begin iob_arready = axi_arready_i; - if (iob_arvalid & axi_arready_i) begin - r_state_next = WriteFIFO; + if (iob_arvalid) begin axi_arvalid_o = 1'b1; + if (axi_arready_i) begin + r_state_next = WriteFIFO; + end end end WriteFIFO: begin @@ -300,7 +303,7 @@ module iob2axi #( ); iob_reg_re #( - .DATA_W (1), + .DATA_W (2), .RST_VAL(0) ) iob_reg_w_state ( .clk_i (clk_i), @@ -375,7 +378,7 @@ module iob2axi #( ); iob_reg_re #( - .DATA_W (1), + .DATA_W (2), .RST_VAL(0) ) iob_reg_r_state ( .clk_i (clk_i), diff --git a/hardware/src/iob_soc_opencryptolinux.v b/hardware/src/iob_soc_opencryptolinux.v index 1f44b3fa..1bf8dfdc 100644 --- a/hardware/src/iob_soc_opencryptolinux.v +++ b/hardware/src/iob_soc_opencryptolinux.v @@ -8,82 +8,82 @@ `include "iob_soc_opencryptolinux_periphs_swreg_def.vs" module iob_soc_opencryptolinux #( - `include "iob_soc_opencryptolinux_params.vs" + `include "iob_soc_opencryptolinux_params.vs" ) ( - `include "iob_soc_opencryptolinux_io.vs" + `include "iob_soc_opencryptolinux_io.vs" ); - localparam integer Bbit = `IOB_SOC_OPENCRYPTOLINUX_B; - localparam integer AddrMsb = `REQ_W - 2; - localparam integer MEM_ADDR_OFFSET = 0; + localparam integer Bbit = `IOB_SOC_OPENCRYPTOLINUX_B; + localparam integer AddrMsb = `REQ_W - 2; + localparam integer MEM_ADDR_OFFSET = 0; - `include "iob_soc_opencryptolinux_pwires.vs" + `include "iob_soc_opencryptolinux_pwires.vs" - // - // SYSTEM RESET - // + // + // SYSTEM RESET + // - wire boot; - wire cpu_reset; - wire cke_i = 1'b1; + wire boot; + wire cpu_reset; + wire cke_i = 1'b1; - // - // CPU - // + // + // CPU + // - // instruction bus - wire [ `REQ_W-1:0] cpu_i_req; - wire [ `RESP_W-1:0] cpu_i_resp; + // instruction bus + wire [ `REQ_W-1:0] cpu_i_req; + wire [`RESP_W-1:0] cpu_i_resp; - // data cat bus - wire [ `REQ_W-1:0] cpu_d_req; - wire [ `RESP_W-1:0] cpu_d_resp; + // data cat bus + wire [ `REQ_W-1:0] cpu_d_req; + wire [`RESP_W-1:0] cpu_d_resp; - assign cpu_trap_o = 1'b0; + assign cpu_trap_o = 1'b0; - //instantiate the cpu - iob_VexRiscv #( + //instantiate the cpu + iob_VexRiscv #( .ADDR_W (ADDR_W), .DATA_W (DATA_W), .USE_EXTMEM(1) - ) cpu_0 ( - .clk_i (clk_i), - .cke_i (cke_i), - .arst_i (arst_i), - .cpu_reset_i (cpu_reset), - .boot_i (boot), - .clint_req({`REQ_W{1'b0}}), - .clint_resp(), - .plic_req({`REQ_W{1'b0}}), - .plic_resp(), + ) cpu_0 ( + .clk_i (clk_i), + .cke_i (cke_i), + .arst_i (arst_i), + .cpu_reset_i (cpu_reset), + .boot_i (boot), + .clint_req ({`REQ_W{1'b0}}), + .clint_resp (), + .plic_req ({`REQ_W{1'b0}}), + .plic_resp (), .plicInterrupts(32'd0), //instruction bus - .ibus_req (cpu_i_req), - .ibus_resp (cpu_i_resp), + .ibus_req (cpu_i_req), + .ibus_resp (cpu_i_resp), //data bus - .dbus_req (cpu_d_req), - .dbus_resp (cpu_d_resp) - ); + .dbus_req (cpu_d_req), + .dbus_resp (cpu_d_resp) + ); - // - // SPLIT CPU BUSES TO ACCESS INTERNAL OR EXTERNAL MEMORY - // + // + // SPLIT CPU BUSES TO ACCESS INTERNAL OR EXTERNAL MEMORY + // - //internal memory instruction bus - wire [ `REQ_W-1:0] int_mem_i_req; - wire [`RESP_W-1:0] int_mem_i_resp; - //external memory instruction bus - wire [ `REQ_W-1:0] ext_mem_i_req; - wire [`RESP_W-1:0] ext_mem_i_resp; + //internal memory instruction bus + wire [ `REQ_W-1:0] int_mem_i_req; + wire [`RESP_W-1:0] int_mem_i_resp; + //external memory instruction bus + wire [ `REQ_W-1:0] ext_mem_i_req; + wire [`RESP_W-1:0] ext_mem_i_resp; - // INSTRUCTION BUS - iob_split #( + // INSTRUCTION BUS + iob_split #( .ADDR_W (ADDR_W), .DATA_W (DATA_W), .N_SLAVES(2), .P_SLAVES(AddrMsb) - ) ibus_split ( + ) ibus_split ( .clk_i (clk_i), .arst_i (arst_i), // master interface @@ -92,24 +92,24 @@ module iob_soc_opencryptolinux #( // slaves interface .s_req_o ({ext_mem_i_req, int_mem_i_req}), .s_resp_i({ext_mem_i_resp, int_mem_i_resp}) - ); + ); - // DATA BUS + // DATA BUS - //internal data bus - wire [ `REQ_W-1:0] int_d_req; - wire [`RESP_W-1:0] int_d_resp; - //external memory data bus - wire [ `REQ_W-1:0] ext_mem_d_req; - wire [`RESP_W-1:0] ext_mem_d_resp; + //internal data bus + wire [ `REQ_W-1:0] int_d_req; + wire [`RESP_W-1:0] int_d_resp; + //external memory data bus + wire [ `REQ_W-1:0] ext_mem_d_req; + wire [`RESP_W-1:0] ext_mem_d_resp; - iob_split #( + iob_split #( .ADDR_W (ADDR_W), .DATA_W (DATA_W), .N_SLAVES(2), //E,{P,I} .P_SLAVES(AddrMsb) - ) dbus_split ( + ) dbus_split ( .clk_i (clk_i), .arst_i (arst_i), // master interface @@ -118,22 +118,22 @@ module iob_soc_opencryptolinux #( // slaves interface .s_req_o ({ext_mem_d_req, int_d_req}), .s_resp_i({ext_mem_d_resp, int_d_resp}) - ); + ); - // - // SPLIT INTERNAL MEMORY AND PERIPHERALS BUS - // + // + // SPLIT INTERNAL MEMORY AND PERIPHERALS BUS + // - //slaves bus (includes internal memory + periphrals) - wire [ (`IOB_SOC_OPENCRYPTOLINUX_N_SLAVES)*`REQ_W-1:0] slaves_req; - wire [(`IOB_SOC_OPENCRYPTOLINUX_N_SLAVES)*`RESP_W-1:0] slaves_resp; + //slaves bus (includes internal memory + periphrals) + wire [ (`IOB_SOC_OPENCRYPTOLINUX_N_SLAVES)*`REQ_W-1:0] slaves_req; + wire [(`IOB_SOC_OPENCRYPTOLINUX_N_SLAVES)*`RESP_W-1:0] slaves_resp; - iob_split #( + iob_split #( .ADDR_W (ADDR_W), .DATA_W (DATA_W), .N_SLAVES(`IOB_SOC_OPENCRYPTOLINUX_N_SLAVES), .P_SLAVES(AddrMsb - 1) - ) pbus_split ( + ) pbus_split ( .clk_i (clk_i), .arst_i (arst_i), // master interface @@ -142,14 +142,14 @@ module iob_soc_opencryptolinux #( // slaves interface .s_req_o (slaves_req), .s_resp_i(slaves_resp) - ); + ); - // - // INTERNAL SRAM MEMORY - // + // + // INTERNAL SRAM MEMORY + // - int_mem #( + int_mem #( .ADDR_W (ADDR_W), .DATA_W (DATA_W), .HEXFILE ("iob_soc_opencryptolinux_firmware"), @@ -157,7 +157,7 @@ module iob_soc_opencryptolinux #( .SRAM_ADDR_W (SRAM_ADDR_W), .BOOTROM_ADDR_W(BOOTROM_ADDR_W), .B_BIT (`B_BIT) - ) int_mem0 ( + ) int_mem0 ( .clk_i (clk_i), .arst_i (arst_i), .cke_i (cke_i), @@ -171,17 +171,19 @@ module iob_soc_opencryptolinux #( //data bus .d_req (slaves_req[0+:`REQ_W]), .d_resp(slaves_resp[0+:`RESP_W]) - ); - - // - // EXTERNAL DDR MEMORY - // - ext_mem #( - .ADDR_W (ADDR_W), - .DATA_W (DATA_W), - .AXI_ID_W (AXI_ID_W), - .AXI_ADDR_W (MEM_ADDR_W) - ) ext_mem0 ( + ); + + // + // EXTERNAL DDR MEMORY + // + ext_mem #( + .ADDR_W (ADDR_W), + .DATA_W (DATA_W), + .AXI_ID_W (AXI_ID_W), + .AXI_LEN_W (AXI_LEN_W), + .AXI_ADDR_W(MEM_ADDR_W), + .AXI_DATA_W(DATA_W) + ) ext_mem0 ( // instruction bus .i_req (ext_mem_i_req), .i_resp(ext_mem_i_resp), @@ -237,11 +239,11 @@ module iob_soc_opencryptolinux #( .clk_i (clk_i), .cke_i (cke_i), .arst_i(arst_i) - ); + ); - assign axi_awaddr_o[AXI_ADDR_W-1:0] = internal_axi_awaddr_o + MEM_ADDR_OFFSET; - assign axi_araddr_o[AXI_ADDR_W-1:0] = internal_axi_araddr_o + MEM_ADDR_OFFSET; + assign axi_awaddr_o[AXI_ADDR_W-1:0] = internal_axi_awaddr_o + MEM_ADDR_OFFSET; + assign axi_araddr_o[AXI_ADDR_W-1:0] = internal_axi_araddr_o + MEM_ADDR_OFFSET; - `include "iob_soc_opencryptolinux_periphs_inst.vs" + `include "iob_soc_opencryptolinux_periphs_inst.vs" endmodule diff --git a/software/src/iob_soc_opencryptolinux_boot.c b/software/src/iob_soc_opencryptolinux_boot.c index a0380be9..bdcd652f 100644 --- a/software/src/iob_soc_opencryptolinux_boot.c +++ b/software/src/iob_soc_opencryptolinux_boot.c @@ -1,5 +1,4 @@ #include "bsp.h" -#include "iob-cache.h" #include "iob-uart16550.h" #include "iob_soc_opencryptolinux_conf.h" #include "iob_soc_opencryptolinux_system.h" @@ -17,7 +16,6 @@ int main() { // init uart uart16550_init(UART0_BASE, FREQ / (16 * BAUD)); - cache_init(1 << E, MEM_ADDR_W); // connect with console do { @@ -94,7 +92,4 @@ int main() { uart16550_puts(PROGNAME); uart16550_puts(": Restart CPU to run user program...\n"); uart16550_txwait(); - - while (!cache_wtb_empty()) - ; } From 71678b61a23222706c63cfa0b96df838630dcd71 Mon Sep 17 00:00:00 2001 From: Pedro Antunes Date: Sat, 16 Sep 2023 00:05:49 +0100 Subject: [PATCH 15/27] *: runs part of the firmware. --- hardware/src/ext_mem.v | 2 +- hardware/src/iob2axi.v | 133 +++++++++++++++--- .../src/iob_soc_opencryptolinux_firmware.c | 2 +- submodules/LIB | 2 +- submodules/VEXRISCV | 2 +- 5 files changed, 119 insertions(+), 22 deletions(-) diff --git a/hardware/src/ext_mem.v b/hardware/src/ext_mem.v index 84ff4820..458e37d9 100644 --- a/hardware/src/ext_mem.v +++ b/hardware/src/ext_mem.v @@ -47,7 +47,7 @@ module ext_mem #( .ADDR_WIDTH(AXI_ADDR_W), .DATA_WIDTH(AXI_DATA_W), .AXI_ID_WIDTH(AXI_ID_W), - .AXI_RLEN(8'h00), + .AXI_RLEN(8'h0f), .AXI_WLEN(8'h00) ) ext_mem_iob2axi ( .iob_avalid_i(ext_mem_req[`AVALID(0)]), diff --git a/hardware/src/iob2axi.v b/hardware/src/iob2axi.v index 7c73f2ac..536f9fbc 100644 --- a/hardware/src/iob2axi.v +++ b/hardware/src/iob2axi.v @@ -39,12 +39,12 @@ module iob2axi #( output wire [ 3:0] axi_awcache_o, output wire [ 2:0] axi_awprot_o, output wire [ 3:0] axi_awqos_o, - output reg axi_awvalid_o, + output wire axi_awvalid_o, input wire axi_awready_i, output reg [ DATA_WIDTH-1:0] axi_wdata_o, output reg [ STRB_WIDTH-1:0] axi_wstrb_o, output reg axi_wlast_o, - output reg axi_wvalid_o, + output wire axi_wvalid_o, input wire axi_wready_i, input wire [AXI_ID_WIDTH-1:0] axi_bid_i, input wire [ 1:0] axi_bresp_i, @@ -72,6 +72,7 @@ module iob2axi #( localparam integer BurstRLEN = AXI_RLEN + 1; localparam integer BurstWLEN = AXI_WLEN + 1; localparam integer IDLE = 0, WriteFIFO = 1, ReadFIFO = 2; + localparam integer WaitForValid = 0, WaitForAWValid = 1, WaitForWValid = 2, ExecuteWrite = 3; wire iob_we; // Write bus @@ -92,8 +93,12 @@ module iob2axi #( wire iob_wvalid; wire [ ADDR_WIDTH-1:0] iob_waddr_q; reg iob_wready; + reg axi_awvalid_next; + reg axi_wvalid_next; wire [ 1:0] w_state_q; reg [ 1:0] w_state_next; + wire [ 1:0] w_readFifo_state; + reg [ 1:0] w_readFifo_state_next; // Read bus wire r_fifo_full; reg r_fifo_wr; @@ -117,7 +122,7 @@ module iob2axi #( reg [ 1:0] r_state_next; assign iob_we = |iob_wstrb_i; - assign iob_ready_o = iob_we ? iob_wready : iob_arready; + assign iob_ready_o = iob_wready & iob_arready; // Write bus // // IOb-bus assign iob_wvalid = iob_we & iob_avalid_i; @@ -150,8 +155,8 @@ module iob2axi #( // Write bus FSM always @(*) begin - axi_awvalid_o = 1'b0; - axi_wvalid_o = 1'b0; + axi_awvalid_next = axi_awvalid_o; + axi_wvalid_next = axi_wvalid_o; axi_wdata_o = {DATA_WIDTH{1'b0}}; axi_wstrb_o = {STRB_WIDTH{1'b0}}; axi_wlast_o = 1'b0; @@ -160,6 +165,7 @@ module iob2axi #( w_fifo_rd = 1'b0; w_fifo_wdata = {DATA_WIDTH + STRB_WIDTH{1'b0}}; w_state_next = w_state_q; + w_readFifo_state_next = w_readFifo_state; case (w_state_q) default: begin iob_wready = 1'b1; @@ -170,26 +176,78 @@ module iob2axi #( end end WriteFIFO: begin - iob_wready = ~w_fifo_full; - if (w_fifo_full) begin + iob_wready = 1'b1; + if (w_fifo_level > AXI_WLEN) begin w_state_next = ReadFIFO; + iob_wready = 1'b0; w_fifo_rd = 1'b1; + axi_awvalid_next = 1'b1; + axi_wvalid_next = 1'b1; end else if (iob_wvalid) begin w_fifo_wr = 1'b1; w_fifo_wdata = {iob_wdata_i, iob_wstrb_i}; end end ReadFIFO: begin - if (axi_awready_i & axi_wready_i) begin - w_fifo_rd = 1'b1; - axi_awvalid_o = 1'b1; - axi_wvalid_o = 1'b1; - {axi_wdata_o, axi_wstrb_o} = w_fifo_rdata; - if (w_fifo_empty) begin - w_state_next = IDLE; - axi_wlast_o = 1'b1; + case (w_readFifo_state) + WaitForValid: begin + if (axi_awready_i & axi_wready_i) begin + axi_awvalid_next = 1'b0; + axi_wvalid_next = 1'b0; + w_fifo_rd = 1'b1; + {axi_wdata_o, axi_wstrb_o} = w_fifo_rdata; + if (w_fifo_empty) begin + w_state_next = IDLE; + axi_wlast_o = 1'b1; + end else begin + w_readFifo_state_next = ExecuteWrite; + end + end else if (axi_awready_i) begin + axi_awvalid_next = 1'b0; + w_readFifo_state_next = WaitForWValid; + end else if (axi_wready_i) begin + axi_wvalid_next = 1'b0; + w_readFifo_state_next = WaitForAWValid; + end end - end + WaitForAWValid: begin + if (axi_awready_i) begin + axi_awvalid_next = 1'b0; + w_fifo_rd = 1'b1; + {axi_wdata_o, axi_wstrb_o} = w_fifo_rdata; + if (w_fifo_empty) begin + w_readFifo_state_next = WaitForValid; + w_state_next = IDLE; + axi_wlast_o = 1'b1; + end else begin + w_readFifo_state_next = ExecuteWrite; + end + end + end + WaitForWValid: begin + if (axi_wready_i) begin + axi_wvalid_next = 1'b0; + w_fifo_rd = 1'b1; + {axi_wdata_o, axi_wstrb_o} = w_fifo_rdata; + if (w_fifo_empty) begin + w_readFifo_state_next = WaitForValid; + w_state_next = IDLE; + axi_wlast_o = 1'b1; + end else begin + w_readFifo_state_next = ExecuteWrite; + end + end + end + default: begin + w_fifo_rd = 1'b1; + {axi_wdata_o, axi_wstrb_o} = w_fifo_rdata; + if (w_fifo_empty) begin + w_readFifo_state_next = WaitForValid; + w_state_next = IDLE; + axi_wlast_o = 1'b1; + end + end + endcase end endcase end @@ -215,7 +273,7 @@ module iob2axi #( end end WriteFIFO: begin - if (r_fifo_full) begin + if (r_fifo_level > AXI_RLEN) begin r_state_next = ReadFIFO; r_fifo_rd = 1'b1; iob_rvalid_next = 1'b1; @@ -225,10 +283,10 @@ module iob2axi #( end end ReadFIFO: begin - iob_arready = axi_arready_i; if (r_fifo_empty) begin r_state_next = IDLE; end else begin + iob_arready = 1'b1; iob_rdata_o = r_fifo_rdata; if (iob_arvalid) begin r_fifo_rd = 1'b1; @@ -302,6 +360,19 @@ module iob2axi #( .data_o(iob_waddr_q) ); + iob_reg_re #( + .DATA_W (2), + .RST_VAL(0) + ) iob_reg_w_readFifo_state ( + .clk_i (clk_i), + .arst_i(arst_i), + .cke_i (cke_i), + .rst_i (1'b0), + .en_i (1'b1), + .data_i(w_readFifo_state_next), + .data_o(w_readFifo_state) + ); + iob_reg_re #( .DATA_W (2), .RST_VAL(0) @@ -315,6 +386,32 @@ module iob2axi #( .data_o(w_state_q) ); + iob_reg_re #( + .DATA_W (1), + .RST_VAL(0) + ) iob_reg_axi_awvalid ( + .clk_i (clk_i), + .arst_i(arst_i), + .cke_i (cke_i), + .rst_i (1'b0), + .en_i (1'b1), + .data_i(axi_awvalid_next), + .data_o(axi_awvalid_o) + ); + + iob_reg_re #( + .DATA_W (1), + .RST_VAL(0) + ) iob_reg_axi_wvalid ( + .clk_i (clk_i), + .arst_i(arst_i), + .cke_i (cke_i), + .rst_i (1'b0), + .en_i (1'b1), + .data_i(axi_wvalid_next), + .data_o(axi_wvalid_o) + ); + // // Read bus FIFO // diff --git a/software/src/iob_soc_opencryptolinux_firmware.c b/software/src/iob_soc_opencryptolinux_firmware.c index 934472db..8facc61a 100644 --- a/software/src/iob_soc_opencryptolinux_firmware.c +++ b/software/src/iob_soc_opencryptolinux_firmware.c @@ -5,7 +5,7 @@ #include "iob_str.h" #include "printf.h" -#define UART0_BASE 0xf2000000 +#define UART0_BASE 0xf4000000 #define PLIC0_BASE 0xf4000000 #define CLINT0_BASE 0xf6000000 diff --git a/submodules/LIB b/submodules/LIB index 1c3a1894..83331602 160000 --- a/submodules/LIB +++ b/submodules/LIB @@ -1 +1 @@ -Subproject commit 1c3a1894f85bae33791b76fdb5ae7c7b496bd816 +Subproject commit 833316020080d1e5dc78909fe17bf97655adce39 diff --git a/submodules/VEXRISCV b/submodules/VEXRISCV index 7c95c8c5..a4957a61 160000 --- a/submodules/VEXRISCV +++ b/submodules/VEXRISCV @@ -1 +1 @@ -Subproject commit 7c95c8c5833773e46c1c73592a03e1082fa956b8 +Subproject commit a4957a616773e8123ead5073db2daf7ff0a40588 From f88de024fc1357ac3b53248cadada54bc1d42c44 Mon Sep 17 00:00:00 2001 From: Pedro Antunes Date: Mon, 18 Sep 2023 21:43:28 +0100 Subject: [PATCH 16/27] opencryptolinux.py: add axi interfaces. --- iob_soc_opencryptolinux.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/iob_soc_opencryptolinux.py b/iob_soc_opencryptolinux.py index 3852ce7e..ee3cf4b8 100755 --- a/iob_soc_opencryptolinux.py +++ b/iob_soc_opencryptolinux.py @@ -47,6 +47,16 @@ def _create_submodules_list(cls, extra_submodules=[]): """Create submodules list with dependencies of this module""" super()._create_submodules_list( [ + {"interface": "peripheral_axi_wire"}, + {"interface": "iBus_intmem_axi_wire"}, + {"interface": "dBus_extmem_axi_wire"}, + {"interface": "iBus_extmem_axi_wire"}, + {"interface": "dBus_axi_wire"}, + {"interface": "iBus_axi_wire"}, + {"interface": "dBus_axi_m_port"}, + {"interface": "iBus_axi_m_port"}, + {"interface": "dBus_axi_m_portmap"}, + {"interface": "iBus_axi_m_portmap"}, iob_vexriscv, iob_uart16550, # iob_spi, From fb72c8cb5d03f148db7a306c46f2a38b8bccc7e8 Mon Sep 17 00:00:00 2001 From: Pedro Antunes Date: Mon, 18 Sep 2023 21:55:39 +0100 Subject: [PATCH 17/27] *: baremetal simulation runs. --- hardware/simulation/bsp.vh | 2 +- hardware/src/axi2iob.v | 530 +++++++++++++ hardware/src/axi_interconnect.v | 981 +++++++++++++++++++++++++ hardware/src/ext_mem.v | 66 -- hardware/src/iob2axil.v | 74 ++ hardware/src/iob_soc_opencryptolinux.v | 613 +++++++++++---- submodules/LIB | 2 +- submodules/VEXRISCV | 2 +- 8 files changed, 2064 insertions(+), 206 deletions(-) create mode 100644 hardware/src/axi2iob.v create mode 100644 hardware/src/axi_interconnect.v delete mode 100644 hardware/src/ext_mem.v create mode 100644 hardware/src/iob2axil.v diff --git a/hardware/simulation/bsp.vh b/hardware/simulation/bsp.vh index a2f3c43d..c1773d23 100644 --- a/hardware/simulation/bsp.vh +++ b/hardware/simulation/bsp.vh @@ -1,4 +1,4 @@ -`define BAUD 115200 +`define BAUD 1000000 `define FREQ 100000000 `define DDR_DATA_W 32 `define DDR_ADDR_W 26 diff --git a/hardware/src/axi2iob.v b/hardware/src/axi2iob.v new file mode 100644 index 00000000..229c359f --- /dev/null +++ b/hardware/src/axi2iob.v @@ -0,0 +1,530 @@ +// Language: Verilog 2001 +`timescale 1ns / 1ps + +/* + * AXI4 to IOb adapter + */ +module axi2iob #( + // Width of address bus in bits + parameter ADDR_WIDTH = 32, + // Width of input (slave/master) AXI/IOb interface data bus in bits + parameter DATA_WIDTH = 32, + // Width of input (slave/master) AXI/IOb interface wstrb (width of data bus in words) + parameter STRB_WIDTH = (DATA_WIDTH / 8), + // Width of AXI ID signal + parameter AXI_ID_WIDTH = 8 +) ( + input wire clk_i, + input wire arst_i, + + /* + * AXI slave interface + */ + input wire [AXI_ID_WIDTH-1:0] s_axi_awid, + input wire [ ADDR_WIDTH-1:0] s_axi_awaddr, + input wire [ 7:0] s_axi_awlen, + input wire [ 2:0] s_axi_awsize, + input wire [ 1:0] s_axi_awburst, + input wire s_axi_awlock, + input wire [ 3:0] s_axi_awcache, + input wire [ 2:0] s_axi_awprot, + input wire s_axi_awvalid, + output wire s_axi_awready, + input wire [ DATA_WIDTH-1:0] s_axi_wdata, + input wire [ STRB_WIDTH-1:0] s_axi_wstrb, + input wire s_axi_wlast, + input wire s_axi_wvalid, + output wire s_axi_wready, + output wire [AXI_ID_WIDTH-1:0] s_axi_bid, + output wire [ 1:0] s_axi_bresp, + output wire s_axi_bvalid, + input wire s_axi_bready, + input wire [AXI_ID_WIDTH-1:0] s_axi_arid, + input wire [ ADDR_WIDTH-1:0] s_axi_araddr, + input wire [ 7:0] s_axi_arlen, + input wire [ 2:0] s_axi_arsize, + input wire [ 1:0] s_axi_arburst, + input wire s_axi_arlock, + input wire [ 3:0] s_axi_arcache, + input wire [ 2:0] s_axi_arprot, + input wire s_axi_arvalid, + output wire s_axi_arready, + output wire [AXI_ID_WIDTH-1:0] s_axi_rid, + output wire [ DATA_WIDTH-1:0] s_axi_rdata, + output wire [ 1:0] s_axi_rresp, + output wire s_axi_rlast, + output wire s_axi_rvalid, + input wire s_axi_rready, + + /* + * IOb-bus master interface + */ + output wire iob_avalid_o, + output wire [ADDR_WIDTH-1:0] iob_addr_o, + output wire [DATA_WIDTH-1:0] iob_wdata_o, + output wire [STRB_WIDTH-1:0] iob_wstrb_o, + input wire iob_rvalid_i, + input wire [DATA_WIDTH-1:0] iob_rdata_i, + input wire iob_ready_i +); + + localparam [1:0] STATE_IDLE = 2'd0, STATE_DATA = 2'd1, STATE_RESP = 2'd2; + + /* + * AXI lite master interface (used as a middle ground from AXI4 to IOb) + */ + wire [ADDR_WIDTH-1:0] m_axil_awaddr; + wire [ 2:0] m_axil_awprot; + wire m_axil_awvalid; + wire m_axil_awready; + wire [DATA_WIDTH-1:0] m_axil_wdata; + wire [STRB_WIDTH-1:0] m_axil_wstrb; + wire m_axil_wvalid; + wire m_axil_wready; + wire [ 1:0] m_axil_bresp; + wire m_axil_bvalid; + wire m_axil_bready; + wire [ADDR_WIDTH-1:0] m_axil_araddr; + wire [ 2:0] m_axil_arprot; + wire m_axil_arvalid; + wire m_axil_arready; + wire [DATA_WIDTH-1:0] m_axil_rdata; + wire [ 1:0] m_axil_rresp; + wire m_axil_rvalid; + wire m_axil_rready; + + // + // AXI4-Lite interface to IOb + // + wire iob_rvalid_q; + wire iob_rvalid_e; + wire write_enable; + wire [ADDR_WIDTH-1:0] m_axil_awaddr_q; + wire m_axil_bvalid_n; + wire m_axil_bvalid_e; + + assign write_enable = |m_axil_wstrb; + assign m_axil_bvalid_n = m_axil_wvalid; + assign m_axil_bvalid_e = m_axil_bvalid_n | m_axil_bready; + assign iob_rvalid_e = iob_rvalid_i | m_axil_rready; + + // COMPUTE AXIL OUTPUTS + // // write address + assign m_axil_awready = iob_ready_i; + // // write + assign m_axil_wready = iob_ready_i; + // // write response + assign m_axil_bresp = 2'b0; + // // read address + assign m_axil_arready = iob_ready_i; + // // read + assign m_axil_rdata = iob_rdata_i; + assign m_axil_rresp = 2'b0; + assign m_axil_rvalid = iob_rvalid_i ? 1'b1 : iob_rvalid_q; + + // COMPUTE IOb OUTPUTS + assign iob_avalid_o = (m_axil_bvalid_n & write_enable) | m_axil_arvalid; + assign iob_addr_o = m_axil_arvalid ? m_axil_araddr : (m_axil_awvalid ? m_axil_awaddr : m_axil_awaddr_q); + assign iob_wdata_o = m_axil_wdata; + assign iob_wstrb_o = m_axil_arvalid ? {STRB_WIDTH{1'b0}} : m_axil_wstrb; + + iob_reg_re #( + .DATA_W (ADDR_WIDTH), + .RST_VAL(0) + ) iob_reg_awaddr ( + .clk_i (clk_i), + .arst_i(arst_i), + .cke_i (1'b1), + .rst_i (1'b0), + .en_i (m_axil_awvalid), + .data_i(m_axil_awaddr), + .data_o(m_axil_awaddr_q) + ); + + iob_reg_re #( + .DATA_W (1), + .RST_VAL(0) + ) iob_reg_rvalid ( + .clk_i (clk_i), + .arst_i(arst_i), + .cke_i (1'b1), + .rst_i (1'b0), + .en_i (iob_rvalid_e), + .data_i(iob_rvalid_i), + .data_o(iob_rvalid_q) + ); + + iob_reg_re #( + .DATA_W (1), + .RST_VAL(0) + ) iob_reg_bvalid ( + .clk_i (clk_i), + .arst_i(arst_i), + .cke_i (1'b1), + .rst_i (1'b0), + .en_i (m_axil_bvalid_e), + .data_i(m_axil_bvalid_n), + .data_o(m_axil_bvalid) + ); + + // + // AXI4 write interface conversion to AXI4-Lite + // + reg [1:0] w_state_reg, w_state_next; + + reg [AXI_ID_WIDTH-1:0] w_id_reg, w_id_next; + reg [ADDR_WIDTH-1:0] w_addr_reg, w_addr_next; + reg [DATA_WIDTH-1:0] w_data_reg, w_data_next; + reg [STRB_WIDTH-1:0] w_strb_reg, w_strb_next; + reg [7:0] w_burst_reg, w_burst_next; + reg [2:0] w_burst_size_reg, w_burst_size_next; + reg [2:0] w_master_burst_size_reg, w_master_burst_size_next; + reg w_burst_active_reg, w_burst_active_next; + reg w_first_transfer_reg, w_first_transfer_next; + reg w_last_segment_reg, w_last_segment_next; + + reg s_axi_awready_reg, s_axi_awready_next; + reg s_axi_wready_reg, s_axi_wready_next; + reg [AXI_ID_WIDTH-1:0] s_axi_bid_reg, s_axi_bid_next; + reg [1:0] s_axi_bresp_reg, s_axi_bresp_next; + reg s_axi_bvalid_reg, s_axi_bvalid_next; + + reg [ADDR_WIDTH-1:0] m_axil_awaddr_reg, m_axil_awaddr_next; + reg [2:0] m_axil_awprot_reg, m_axil_awprot_next; + reg m_axil_awvalid_reg, m_axil_awvalid_next; + reg [DATA_WIDTH-1:0] m_axil_wdata_reg, m_axil_wdata_next; + reg [STRB_WIDTH-1:0] m_axil_wstrb_reg, m_axil_wstrb_next; + reg m_axil_wvalid_reg, m_axil_wvalid_next; + reg m_axil_bready_reg, m_axil_bready_next; + + assign s_axi_awready = s_axi_awready_reg; + assign s_axi_wready = s_axi_wready_reg; + assign s_axi_bid = s_axi_bid_reg; + assign s_axi_bresp = s_axi_bresp_reg; + assign s_axi_bvalid = s_axi_bvalid_reg; + + assign m_axil_awaddr = m_axil_awaddr_reg; + assign m_axil_awprot = m_axil_awprot_reg; + assign m_axil_awvalid = m_axil_awvalid_reg; + assign m_axil_wdata = m_axil_wdata_reg; + assign m_axil_wstrb = m_axil_wstrb_reg; + assign m_axil_wvalid = m_axil_wvalid_reg; + assign m_axil_bready = m_axil_bready_reg; + + integer i; + + always @* begin + w_state_next = STATE_IDLE; + + w_id_next = w_id_reg; + w_addr_next = w_addr_reg; + w_data_next = w_data_reg; + w_strb_next = w_strb_reg; + w_burst_next = w_burst_reg; + w_burst_size_next = w_burst_size_reg; + w_master_burst_size_next = w_master_burst_size_reg; + w_burst_active_next = w_burst_active_reg; + w_first_transfer_next = w_first_transfer_reg; + w_last_segment_next = w_last_segment_reg; + + s_axi_awready_next = 1'b0; + s_axi_wready_next = 1'b0; + s_axi_bid_next = s_axi_bid_reg; + s_axi_bresp_next = s_axi_bresp_reg; + s_axi_bvalid_next = s_axi_bvalid_reg & ~s_axi_bready; + m_axil_awaddr_next = m_axil_awaddr_reg; + m_axil_awprot_next = m_axil_awprot_reg; + m_axil_awvalid_next = m_axil_awvalid_reg & ~m_axil_awready; + m_axil_wdata_next = m_axil_wdata_reg; + m_axil_wstrb_next = m_axil_wstrb_reg; + m_axil_wvalid_next = m_axil_wvalid_reg & ~m_axil_wready; + m_axil_bready_next = 1'b0; + + case (w_state_reg) + default: begin // STATE_IDLE + // idle state; wait for new burst + s_axi_awready_next = ~m_axil_awvalid; + w_first_transfer_next = 1'b1; + + if (s_axi_awready & s_axi_awvalid) begin + s_axi_awready_next = 1'b0; + w_id_next = s_axi_awid; + m_axil_awaddr_next = s_axi_awaddr; + w_addr_next = s_axi_awaddr; + w_burst_next = s_axi_awlen; + w_burst_size_next = s_axi_awsize; + w_burst_active_next = 1'b1; + m_axil_awprot_next = s_axi_awprot; + m_axil_awvalid_next = 1'b1; + s_axi_wready_next = ~m_axil_wvalid; + w_state_next = STATE_DATA; + end else begin + w_state_next = STATE_IDLE; + end + end + STATE_DATA: begin + // data state; transfer write data + s_axi_wready_next = ~m_axil_wvalid; + + if (s_axi_wready & s_axi_wvalid) begin + m_axil_wdata_next = s_axi_wdata; + m_axil_wstrb_next = s_axi_wstrb; + m_axil_wvalid_next = 1'b1; + w_burst_next = w_burst_reg - 1; + w_burst_active_next = w_burst_reg != 0; + w_addr_next = w_addr_reg + (1 << w_burst_size_reg); + s_axi_wready_next = 1'b0; + m_axil_bready_next = ~s_axi_bvalid & ~m_axil_awvalid; + w_state_next = STATE_RESP; + end else begin + w_state_next = STATE_DATA; + end + end + STATE_RESP: begin + // resp state; transfer write response + m_axil_bready_next = ~s_axi_bvalid & ~m_axil_awvalid; + + if (m_axil_bready & m_axil_bvalid) begin + m_axil_bready_next = 1'b0; + s_axi_bid_next = w_id_reg; + w_first_transfer_next = 1'b0; + if (w_first_transfer_reg | (m_axil_bresp != 0)) begin + s_axi_bresp_next = m_axil_bresp; + end + if (w_burst_active_reg) begin + // burst on slave interface still active; start new AXI lite write + m_axil_awaddr_next = w_addr_reg; + m_axil_awvalid_next = 1'b1; + s_axi_wready_next = ~m_axil_wvalid; + w_state_next = STATE_DATA; + end else begin + // burst on slave interface finished; return to idle + s_axi_bvalid_next = 1'b1; + s_axi_awready_next = ~m_axil_awvalid; + w_state_next = STATE_IDLE; + end + end else begin + w_state_next = STATE_RESP; + end + end + endcase + end + + always @(posedge clk_i, posedge arst_i) begin + if (arst_i) begin + w_state_reg <= STATE_IDLE; + s_axi_awready_reg <= 1'b0; + s_axi_wready_reg <= 1'b0; + s_axi_bvalid_reg <= 1'b0; + m_axil_awvalid_reg <= 1'b0; + m_axil_wvalid_reg <= 1'b0; + m_axil_bready_reg <= 1'b0; + + w_id_reg <= {AXI_ID_WIDTH{1'b0}}; + w_addr_reg <= {ADDR_WIDTH{1'b0}}; + w_data_reg <= {DATA_WIDTH{1'b0}}; + w_strb_reg <= {STRB_WIDTH{1'b0}}; + w_burst_reg <= 8'd0; + w_burst_size_reg <= 3'd0; + w_master_burst_size_reg <= 3'd0; + w_burst_active_reg <= 1'b0; + w_first_transfer_reg <= 1'b0; + w_last_segment_reg <= 1'b0; + + s_axi_bid_reg <= {AXI_ID_WIDTH{1'b0}}; + s_axi_bresp_reg <= 2'd0; + m_axil_awaddr_reg <= {ADDR_WIDTH{1'b0}}; + m_axil_awprot_reg <= 3'd0; + m_axil_wdata_reg <= {DATA_WIDTH{1'b0}}; + m_axil_wstrb_reg <= {STRB_WIDTH{1'b0}}; + end else begin + w_state_reg <= w_state_next; + s_axi_awready_reg <= s_axi_awready_next; + s_axi_wready_reg <= s_axi_wready_next; + s_axi_bvalid_reg <= s_axi_bvalid_next; + m_axil_awvalid_reg <= m_axil_awvalid_next; + m_axil_wvalid_reg <= m_axil_wvalid_next; + m_axil_bready_reg <= m_axil_bready_next; + + w_id_reg <= w_id_next; + w_addr_reg <= w_addr_next; + w_data_reg <= w_data_next; + w_strb_reg <= w_strb_next; + w_burst_reg <= w_burst_next; + w_burst_size_reg <= w_burst_size_next; + w_master_burst_size_reg <= w_master_burst_size_next; + w_burst_active_reg <= w_burst_active_next; + w_first_transfer_reg <= w_first_transfer_next; + w_last_segment_reg <= w_last_segment_next; + + s_axi_bid_reg <= s_axi_bid_next; + s_axi_bresp_reg <= s_axi_bresp_next; + m_axil_awaddr_reg <= m_axil_awaddr_next; + m_axil_awprot_reg <= m_axil_awprot_next; + m_axil_wdata_reg <= m_axil_wdata_next; + m_axil_wstrb_reg <= m_axil_wstrb_next; + end + end + + // + // AXI4 read interface conversion to AXI4-Lite + // + reg [1:0] r_state_reg, r_state_next; + + reg [AXI_ID_WIDTH-1:0] r_id_reg, r_id_next; + reg [ADDR_WIDTH-1:0] r_addr_reg, r_addr_next; + reg [DATA_WIDTH-1:0] r_data_reg, r_data_next; + reg [1:0] r_resp_reg, r_resp_next; + reg [7:0] r_burst_reg, r_burst_next; + reg [2:0] r_burst_size_reg, r_burst_size_next; + reg [7:0] r_master_burst_reg, r_master_burst_next; + reg [2:0] r_master_burst_size_reg, r_master_burst_size_next; + + reg s_axi_arready_reg, s_axi_arready_next; + reg [AXI_ID_WIDTH-1:0] s_axi_rid_reg, s_axi_rid_next; + reg [DATA_WIDTH-1:0] s_axi_rdata_reg, s_axi_rdata_next; + reg [1:0] s_axi_rresp_reg, s_axi_rresp_next; + reg s_axi_rlast_reg, s_axi_rlast_next; + reg s_axi_rvalid_reg, s_axi_rvalid_next; + + reg [ADDR_WIDTH-1:0] m_axil_araddr_reg, m_axil_araddr_next; + reg [2:0] m_axil_arprot_reg, m_axil_arprot_next; + reg m_axil_arvalid_reg, m_axil_arvalid_next; + reg m_axil_rready_reg, m_axil_rready_next; + + assign s_axi_arready = s_axi_arready_reg; + assign s_axi_rid = s_axi_rid_reg; + assign s_axi_rdata = s_axi_rdata_reg; + assign s_axi_rresp = s_axi_rresp_reg; + assign s_axi_rlast = s_axi_rlast_reg; + assign s_axi_rvalid = s_axi_rvalid_reg; + + assign m_axil_araddr = m_axil_araddr_reg; + assign m_axil_arprot = m_axil_arprot_reg; + assign m_axil_arvalid = m_axil_arvalid_reg; + assign m_axil_rready = m_axil_rready_reg; + + always @* begin + r_state_next = STATE_IDLE; + + r_id_next = r_id_reg; + r_addr_next = r_addr_reg; + r_data_next = r_data_reg; + r_resp_next = r_resp_reg; + r_burst_next = r_burst_reg; + r_burst_size_next = r_burst_size_reg; + r_master_burst_next = r_master_burst_reg; + r_master_burst_size_next = r_master_burst_size_reg; + + s_axi_arready_next = 1'b0; + s_axi_rid_next = s_axi_rid_reg; + s_axi_rdata_next = s_axi_rdata_reg; + s_axi_rresp_next = s_axi_rresp_reg; + s_axi_rlast_next = s_axi_rlast_reg; + s_axi_rvalid_next = s_axi_rvalid_reg & ~s_axi_rready; + m_axil_araddr_next = m_axil_araddr_reg; + m_axil_arprot_next = m_axil_arprot_reg; + m_axil_arvalid_next = m_axil_arvalid_reg & ~m_axil_arready; + m_axil_rready_next = 1'b0; + + case (r_state_reg) + default: begin // STATE_IDLE + // idle state; wait for new burst + s_axi_arready_next = ~m_axil_arvalid; + + if (s_axi_arready & s_axi_arvalid) begin + s_axi_arready_next = 1'b0; + r_id_next = s_axi_arid; + m_axil_araddr_next = s_axi_araddr; + r_addr_next = s_axi_araddr; + r_burst_next = s_axi_arlen; + r_burst_size_next = s_axi_arsize; + m_axil_arprot_next = s_axi_arprot; + m_axil_arvalid_next = 1'b1; + m_axil_rready_next = 1'b0; + r_state_next = STATE_DATA; + end else begin + r_state_next = STATE_IDLE; + end + end + STATE_DATA: begin + // data state; transfer read data + m_axil_rready_next = ~s_axi_rvalid & ~m_axil_arvalid; + + if (m_axil_rready & m_axil_rvalid) begin + s_axi_rid_next = r_id_reg; + s_axi_rdata_next = m_axil_rdata; + s_axi_rresp_next = m_axil_rresp; + s_axi_rlast_next = 1'b0; + s_axi_rvalid_next = 1'b1; + r_burst_next = r_burst_reg - 1; + r_addr_next = r_addr_reg + (1 << r_burst_size_reg); + if (r_burst_reg == 0) begin + // last data word, return to idle + m_axil_rready_next = 1'b0; + s_axi_rlast_next = 1'b1; + s_axi_arready_next = ~m_axil_arvalid; + r_state_next = STATE_IDLE; + end else begin + // start new AXI lite read + m_axil_araddr_next = r_addr_next; + m_axil_arvalid_next = 1'b1; + m_axil_rready_next = 1'b0; + r_state_next = STATE_DATA; + end + end else begin + r_state_next = STATE_DATA; + end + end + endcase + end + + always @(posedge clk_i, posedge arst_i) begin + if (arst_i) begin + r_state_reg <= STATE_IDLE; + s_axi_arready_reg <= 1'b0; + s_axi_rvalid_reg <= 1'b0; + m_axil_arvalid_reg <= 1'b0; + m_axil_rready_reg <= 1'b0; + + r_id_reg <= {AXI_ID_WIDTH{1'b0}}; + r_addr_reg <= {ADDR_WIDTH{1'b0}}; + r_data_reg <= {DATA_WIDTH{1'b0}}; + r_resp_reg <= 2'd0; + r_burst_reg <= 8'd0; + r_burst_size_reg <= 3'd0; + r_master_burst_reg <= 8'd0; + r_master_burst_size_reg <= 3'd0; + + s_axi_rid_reg <= {AXI_ID_WIDTH{1'b0}}; + s_axi_rdata_reg <= {DATA_WIDTH{1'b0}}; + s_axi_rresp_reg <= 2'd0; + s_axi_rlast_reg <= 1'b0; + m_axil_araddr_reg <= {ADDR_WIDTH{1'b0}}; + m_axil_arprot_reg <= 3'd0; + end else begin + r_state_reg <= r_state_next; + s_axi_arready_reg <= s_axi_arready_next; + s_axi_rvalid_reg <= s_axi_rvalid_next; + m_axil_arvalid_reg <= m_axil_arvalid_next; + m_axil_rready_reg <= m_axil_rready_next; + + r_id_reg <= r_id_next; + r_addr_reg <= r_addr_next; + r_data_reg <= r_data_next; + r_resp_reg <= r_resp_next; + r_burst_reg <= r_burst_next; + r_burst_size_reg <= r_burst_size_next; + r_master_burst_reg <= r_master_burst_next; + r_master_burst_size_reg <= r_master_burst_size_next; + + s_axi_rid_reg <= s_axi_rid_next; + s_axi_rdata_reg <= s_axi_rdata_next; + s_axi_rresp_reg <= s_axi_rresp_next; + s_axi_rlast_reg <= s_axi_rlast_next; + m_axil_araddr_reg <= m_axil_araddr_next; + m_axil_arprot_reg <= m_axil_arprot_next; + end + end + +endmodule diff --git a/hardware/src/axi_interconnect.v b/hardware/src/axi_interconnect.v new file mode 100644 index 00000000..a72a9a78 --- /dev/null +++ b/hardware/src/axi_interconnect.v @@ -0,0 +1,981 @@ +/* + +Copyright (c) 2018 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ + +// Language: Verilog 2001 + +`timescale 1ns / 1ps + +/* + * AXI4 interconnect + */ +module axi_interconnect #( + // Number of AXI inputs (slave interfaces) + parameter S_COUNT = 4, + // Number of AXI outputs (master interfaces) + parameter M_COUNT = 4, + // Width of data bus in bits + parameter DATA_WIDTH = 32, + // Width of address bus in bits + parameter ADDR_WIDTH = 32, + // Width of wstrb (width of data bus in words) + parameter STRB_WIDTH = (DATA_WIDTH / 8), + // Width of ID signal + parameter ID_WIDTH = 8, + // Propagate awuser signal + parameter AWUSER_ENABLE = 0, + // Width of awuser signal + parameter AWUSER_WIDTH = 1, + // Propagate wuser signal + parameter WUSER_ENABLE = 0, + // Width of wuser signal + parameter WUSER_WIDTH = 1, + // Propagate buser signal + parameter BUSER_ENABLE = 0, + // Width of buser signal + parameter BUSER_WIDTH = 1, + // Propagate aruser signal + parameter ARUSER_ENABLE = 0, + // Width of aruser signal + parameter ARUSER_WIDTH = 1, + // Propagate ruser signal + parameter RUSER_ENABLE = 0, + // Width of ruser signal + parameter RUSER_WIDTH = 1, + // Propagate ID field + parameter FORWARD_ID = 0, + // Number of regions per master interface + parameter M_REGIONS = 1, + // Master interface base addresses + // M_COUNT concatenated fields of M_REGIONS concatenated fields of ADDR_WIDTH bits + // set to zero for default addressing based on M_ADDR_WIDTH + parameter M_BASE_ADDR = 0, + // Master interface address widths + // M_COUNT concatenated fields of M_REGIONS concatenated fields of 32 bits + parameter M_ADDR_WIDTH = {M_COUNT{{M_REGIONS{32'd24}}}}, + // Read connections between interfaces + // M_COUNT concatenated fields of S_COUNT bits + parameter M_CONNECT_READ = {M_COUNT{{S_COUNT{1'b1}}}}, + // Write connections between interfaces + // M_COUNT concatenated fields of S_COUNT bits + parameter M_CONNECT_WRITE = {M_COUNT{{S_COUNT{1'b1}}}}, + // Secure master (fail operations based on awprot/arprot) + // M_COUNT bits + parameter M_SECURE = {M_COUNT{1'b0}} +) ( + input wire clk, + input wire rst, + + /* + * AXI slave interfaces + */ + input wire [ S_COUNT*ID_WIDTH-1:0] s_axi_awid, + input wire [ S_COUNT*ADDR_WIDTH-1:0] s_axi_awaddr, + input wire [ S_COUNT*8-1:0] s_axi_awlen, + input wire [ S_COUNT*3-1:0] s_axi_awsize, + input wire [ S_COUNT*2-1:0] s_axi_awburst, + input wire [ S_COUNT-1:0] s_axi_awlock, + input wire [ S_COUNT*4-1:0] s_axi_awcache, + input wire [ S_COUNT*3-1:0] s_axi_awprot, + input wire [ S_COUNT*4-1:0] s_axi_awqos, + input wire [S_COUNT*AWUSER_WIDTH-1:0] s_axi_awuser, + input wire [ S_COUNT-1:0] s_axi_awvalid, + output wire [ S_COUNT-1:0] s_axi_awready, + input wire [ S_COUNT*DATA_WIDTH-1:0] s_axi_wdata, + input wire [ S_COUNT*STRB_WIDTH-1:0] s_axi_wstrb, + input wire [ S_COUNT-1:0] s_axi_wlast, + input wire [ S_COUNT*WUSER_WIDTH-1:0] s_axi_wuser, + input wire [ S_COUNT-1:0] s_axi_wvalid, + output wire [ S_COUNT-1:0] s_axi_wready, + output wire [ S_COUNT*ID_WIDTH-1:0] s_axi_bid, + output wire [ S_COUNT*2-1:0] s_axi_bresp, + output wire [ S_COUNT*BUSER_WIDTH-1:0] s_axi_buser, + output wire [ S_COUNT-1:0] s_axi_bvalid, + input wire [ S_COUNT-1:0] s_axi_bready, + input wire [ S_COUNT*ID_WIDTH-1:0] s_axi_arid, + input wire [ S_COUNT*ADDR_WIDTH-1:0] s_axi_araddr, + input wire [ S_COUNT*8-1:0] s_axi_arlen, + input wire [ S_COUNT*3-1:0] s_axi_arsize, + input wire [ S_COUNT*2-1:0] s_axi_arburst, + input wire [ S_COUNT-1:0] s_axi_arlock, + input wire [ S_COUNT*4-1:0] s_axi_arcache, + input wire [ S_COUNT*3-1:0] s_axi_arprot, + input wire [ S_COUNT*4-1:0] s_axi_arqos, + input wire [S_COUNT*ARUSER_WIDTH-1:0] s_axi_aruser, + input wire [ S_COUNT-1:0] s_axi_arvalid, + output wire [ S_COUNT-1:0] s_axi_arready, + output wire [ S_COUNT*ID_WIDTH-1:0] s_axi_rid, + output wire [ S_COUNT*DATA_WIDTH-1:0] s_axi_rdata, + output wire [ S_COUNT*2-1:0] s_axi_rresp, + output wire [ S_COUNT-1:0] s_axi_rlast, + output wire [ S_COUNT*RUSER_WIDTH-1:0] s_axi_ruser, + output wire [ S_COUNT-1:0] s_axi_rvalid, + input wire [ S_COUNT-1:0] s_axi_rready, + + /* + * AXI master interfaces + */ + output wire [ M_COUNT*ID_WIDTH-1:0] m_axi_awid, + output wire [ M_COUNT*ADDR_WIDTH-1:0] m_axi_awaddr, + output wire [ M_COUNT*8-1:0] m_axi_awlen, + output wire [ M_COUNT*3-1:0] m_axi_awsize, + output wire [ M_COUNT*2-1:0] m_axi_awburst, + output wire [ M_COUNT-1:0] m_axi_awlock, + output wire [ M_COUNT*4-1:0] m_axi_awcache, + output wire [ M_COUNT*3-1:0] m_axi_awprot, + output wire [ M_COUNT*4-1:0] m_axi_awqos, + output wire [ M_COUNT*4-1:0] m_axi_awregion, + output wire [M_COUNT*AWUSER_WIDTH-1:0] m_axi_awuser, + output wire [ M_COUNT-1:0] m_axi_awvalid, + input wire [ M_COUNT-1:0] m_axi_awready, + output wire [ M_COUNT*DATA_WIDTH-1:0] m_axi_wdata, + output wire [ M_COUNT*STRB_WIDTH-1:0] m_axi_wstrb, + output wire [ M_COUNT-1:0] m_axi_wlast, + output wire [ M_COUNT*WUSER_WIDTH-1:0] m_axi_wuser, + output wire [ M_COUNT-1:0] m_axi_wvalid, + input wire [ M_COUNT-1:0] m_axi_wready, + input wire [ M_COUNT*ID_WIDTH-1:0] m_axi_bid, + input wire [ M_COUNT*2-1:0] m_axi_bresp, + input wire [ M_COUNT*BUSER_WIDTH-1:0] m_axi_buser, + input wire [ M_COUNT-1:0] m_axi_bvalid, + output wire [ M_COUNT-1:0] m_axi_bready, + output wire [ M_COUNT*ID_WIDTH-1:0] m_axi_arid, + output wire [ M_COUNT*ADDR_WIDTH-1:0] m_axi_araddr, + output wire [ M_COUNT*8-1:0] m_axi_arlen, + output wire [ M_COUNT*3-1:0] m_axi_arsize, + output wire [ M_COUNT*2-1:0] m_axi_arburst, + output wire [ M_COUNT-1:0] m_axi_arlock, + output wire [ M_COUNT*4-1:0] m_axi_arcache, + output wire [ M_COUNT*3-1:0] m_axi_arprot, + output wire [ M_COUNT*4-1:0] m_axi_arqos, + output wire [ M_COUNT*4-1:0] m_axi_arregion, + output wire [M_COUNT*ARUSER_WIDTH-1:0] m_axi_aruser, + output wire [ M_COUNT-1:0] m_axi_arvalid, + input wire [ M_COUNT-1:0] m_axi_arready, + input wire [ M_COUNT*ID_WIDTH-1:0] m_axi_rid, + input wire [ M_COUNT*DATA_WIDTH-1:0] m_axi_rdata, + input wire [ M_COUNT*2-1:0] m_axi_rresp, + input wire [ M_COUNT-1:0] m_axi_rlast, + input wire [ M_COUNT*RUSER_WIDTH-1:0] m_axi_ruser, + input wire [ M_COUNT-1:0] m_axi_rvalid, + output wire [ M_COUNT-1:0] m_axi_rready +); + + parameter CL_S_COUNT = $clog2(S_COUNT); + parameter CL_M_COUNT = $clog2(M_COUNT); + + parameter AUSER_WIDTH = AWUSER_WIDTH > ARUSER_WIDTH ? AWUSER_WIDTH : ARUSER_WIDTH; + + // default address computation + function automatic [M_COUNT*M_REGIONS*ADDR_WIDTH-1:0] calcBaseAddrs(input integer dummy); + integer i; + reg [ADDR_WIDTH-1:0] base; + begin + calcBaseAddrs = {M_COUNT * M_REGIONS * ADDR_WIDTH{1'b0}}; + base = 0; + for (i = 1; i < M_COUNT * M_REGIONS; i = i + 1) begin + if (M_ADDR_WIDTH[i*32+:32]) begin + base = base + 2 ** M_ADDR_WIDTH[(i-1)*32+:32]; // increment + base = base - (base % 2 ** M_ADDR_WIDTH[i*32+:32]); // align + calcBaseAddrs[i*ADDR_WIDTH+:ADDR_WIDTH] = base; + end + end + end + endfunction + + parameter M_BASE_ADDR_INT = M_BASE_ADDR ? M_BASE_ADDR : calcBaseAddrs(0); + + integer i, j; + + // check configuration + initial begin + if (M_REGIONS < 1 || M_REGIONS > 16) begin + $error("Error: M_REGIONS must be between 1 and 16 (instance %m)"); + $finish(); + end + + for (i = 0; i < M_COUNT * M_REGIONS; i = i + 1) begin + if (M_ADDR_WIDTH[i*32 +: 32] && (M_ADDR_WIDTH[i*32 +: 32] < 12 || M_ADDR_WIDTH[i*32 +: 32] > ADDR_WIDTH)) begin + $error("Error: address width out of range (instance %m)"); + $finish(); + end + end + + $display("Addressing configuration for axi_interconnect instance %m"); + for (i = 0; i < M_COUNT * M_REGIONS; i = i + 1) begin + if (M_ADDR_WIDTH[i*32+:32]) begin + $display( + "%2d (%2d): %x / %2d -- %x-%x", i / M_REGIONS, i % M_REGIONS, + M_BASE_ADDR_INT[i*ADDR_WIDTH+:ADDR_WIDTH], M_ADDR_WIDTH[i*32+:32], + M_BASE_ADDR_INT[i*ADDR_WIDTH+:ADDR_WIDTH] & ({ADDR_WIDTH{1'b1}} << M_ADDR_WIDTH[i*32+:32]), + M_BASE_ADDR_INT[i*ADDR_WIDTH+:ADDR_WIDTH] | ({ADDR_WIDTH{1'b1}} >> (ADDR_WIDTH - M_ADDR_WIDTH[i*32+:32]))); + end + end + + for (i = 0; i < M_COUNT * M_REGIONS; i = i + 1) begin + for (j = i + 1; j < M_COUNT * M_REGIONS; j = j + 1) begin + if (M_ADDR_WIDTH[i*32+:32] && M_ADDR_WIDTH[j*32+:32]) begin + if (((M_BASE_ADDR_INT[i*ADDR_WIDTH +: ADDR_WIDTH] & ({ADDR_WIDTH{1'b1}} << M_ADDR_WIDTH[i*32 +: 32])) <= (M_BASE_ADDR_INT[j*ADDR_WIDTH +: ADDR_WIDTH] | ({ADDR_WIDTH{1'b1}} >> (ADDR_WIDTH - M_ADDR_WIDTH[j*32 +: 32])))) && ((M_BASE_ADDR_INT[j*ADDR_WIDTH +: ADDR_WIDTH] & ({ADDR_WIDTH{1'b1}} << M_ADDR_WIDTH[j*32 +: 32])) <= (M_BASE_ADDR_INT[i*ADDR_WIDTH +: ADDR_WIDTH] | ({ADDR_WIDTH{1'b1}} >> (ADDR_WIDTH - M_ADDR_WIDTH[i*32 +: 32]))))) begin + $display("Overlapping regions:"); + $display( + "%2d (%2d): %x / %2d -- %x-%x", i / M_REGIONS, i % M_REGIONS, + M_BASE_ADDR_INT[i*ADDR_WIDTH+:ADDR_WIDTH], M_ADDR_WIDTH[i*32+:32], + M_BASE_ADDR_INT[i*ADDR_WIDTH+:ADDR_WIDTH] & ({ADDR_WIDTH{1'b1}} << M_ADDR_WIDTH[i*32+:32]), + M_BASE_ADDR_INT[i*ADDR_WIDTH+:ADDR_WIDTH] | ({ADDR_WIDTH{1'b1}} >> (ADDR_WIDTH - M_ADDR_WIDTH[i*32+:32]))); + $display( + "%2d (%2d): %x / %2d -- %x-%x", j / M_REGIONS, j % M_REGIONS, + M_BASE_ADDR_INT[j*ADDR_WIDTH+:ADDR_WIDTH], M_ADDR_WIDTH[j*32+:32], + M_BASE_ADDR_INT[j*ADDR_WIDTH+:ADDR_WIDTH] & ({ADDR_WIDTH{1'b1}} << M_ADDR_WIDTH[j*32+:32]), + M_BASE_ADDR_INT[j*ADDR_WIDTH+:ADDR_WIDTH] | ({ADDR_WIDTH{1'b1}} >> (ADDR_WIDTH - M_ADDR_WIDTH[j*32+:32]))); + $error("Error: address ranges overlap (instance %m)"); + $finish(); + end + end + end + end + end + + localparam [2:0] + STATE_IDLE = 3'd0, + STATE_DECODE = 3'd1, + STATE_WRITE = 3'd2, + STATE_WRITE_RESP = 3'd3, + STATE_WRITE_DROP = 3'd4, + STATE_READ = 3'd5, + STATE_READ_DROP = 3'd6, + STATE_WAIT_IDLE = 3'd7; + + reg [2:0] state_reg, state_next; + + reg match; + + reg [CL_M_COUNT-1:0] m_select_reg, m_select_next; + reg [ID_WIDTH-1:0] axi_id_reg, axi_id_next; + reg [ADDR_WIDTH-1:0] axi_addr_reg, axi_addr_next; + reg axi_addr_valid_reg, axi_addr_valid_next; + reg [7:0] axi_len_reg, axi_len_next; + reg [2:0] axi_size_reg, axi_size_next; + reg [1:0] axi_burst_reg, axi_burst_next; + reg axi_lock_reg, axi_lock_next; + reg [3:0] axi_cache_reg, axi_cache_next; + reg [2:0] axi_prot_reg, axi_prot_next; + reg [3:0] axi_qos_reg, axi_qos_next; + reg [3:0] axi_region_reg, axi_region_next; + reg [AUSER_WIDTH-1:0] axi_auser_reg, axi_auser_next; + reg [1:0] axi_bresp_reg, axi_bresp_next; + reg [BUSER_WIDTH-1:0] axi_buser_reg, axi_buser_next; + + reg [S_COUNT-1:0] s_axi_awready_reg, s_axi_awready_next; + reg [S_COUNT-1:0] s_axi_wready_reg, s_axi_wready_next; + reg [S_COUNT-1:0] s_axi_bvalid_reg, s_axi_bvalid_next; + reg [S_COUNT-1:0] s_axi_arready_reg, s_axi_arready_next; + + reg [M_COUNT-1:0] m_axi_awvalid_reg, m_axi_awvalid_next; + reg [M_COUNT-1:0] m_axi_bready_reg, m_axi_bready_next; + reg [M_COUNT-1:0] m_axi_arvalid_reg, m_axi_arvalid_next; + reg [M_COUNT-1:0] m_axi_rready_reg, m_axi_rready_next; + + // internal datapath + reg [ ID_WIDTH-1:0] s_axi_rid_int; + reg [ DATA_WIDTH-1:0] s_axi_rdata_int; + reg [ 1:0] s_axi_rresp_int; + reg s_axi_rlast_int; + reg [RUSER_WIDTH-1:0] s_axi_ruser_int; + reg s_axi_rvalid_int; + reg s_axi_rready_int_reg = 1'b0; + wire s_axi_rready_int_early; + + reg [ DATA_WIDTH-1:0] m_axi_wdata_int; + reg [ STRB_WIDTH-1:0] m_axi_wstrb_int; + reg m_axi_wlast_int; + reg [WUSER_WIDTH-1:0] m_axi_wuser_int; + reg m_axi_wvalid_int; + reg m_axi_wready_int_reg = 1'b0; + wire m_axi_wready_int_early; + + assign s_axi_awready = s_axi_awready_reg; + assign s_axi_wready = s_axi_wready_reg; + assign s_axi_bid = {S_COUNT{axi_id_reg}}; + assign s_axi_bresp = {S_COUNT{axi_bresp_reg}}; + assign s_axi_buser = {S_COUNT{BUSER_ENABLE ? axi_buser_reg : {BUSER_WIDTH{1'b0}}}}; + assign s_axi_bvalid = s_axi_bvalid_reg; + assign s_axi_arready = s_axi_arready_reg; + + assign m_axi_awid = {M_COUNT{FORWARD_ID ? axi_id_reg : {ID_WIDTH{1'b0}}}}; + assign m_axi_awaddr = {M_COUNT{axi_addr_reg}}; + assign m_axi_awlen = {M_COUNT{axi_len_reg}}; + assign m_axi_awsize = {M_COUNT{axi_size_reg}}; + assign m_axi_awburst = {M_COUNT{axi_burst_reg}}; + assign m_axi_awlock = {M_COUNT{axi_lock_reg}}; + assign m_axi_awcache = {M_COUNT{axi_cache_reg}}; + assign m_axi_awprot = {M_COUNT{axi_prot_reg}}; + assign m_axi_awqos = {M_COUNT{axi_qos_reg}}; + assign m_axi_awregion = {M_COUNT{axi_region_reg}}; + assign m_axi_awuser = {M_COUNT{AWUSER_ENABLE ? axi_auser_reg[AWUSER_WIDTH-1:0] : {AWUSER_WIDTH{1'b0}}}}; + assign m_axi_awvalid = m_axi_awvalid_reg; + assign m_axi_bready = m_axi_bready_reg; + assign m_axi_arid = {M_COUNT{FORWARD_ID ? axi_id_reg : {ID_WIDTH{1'b0}}}}; + assign m_axi_araddr = {M_COUNT{axi_addr_reg}}; + assign m_axi_arlen = {M_COUNT{axi_len_reg}}; + assign m_axi_arsize = {M_COUNT{axi_size_reg}}; + assign m_axi_arburst = {M_COUNT{axi_burst_reg}}; + assign m_axi_arlock = {M_COUNT{axi_lock_reg}}; + assign m_axi_arcache = {M_COUNT{axi_cache_reg}}; + assign m_axi_arprot = {M_COUNT{axi_prot_reg}}; + assign m_axi_arqos = {M_COUNT{axi_qos_reg}}; + assign m_axi_arregion = {M_COUNT{axi_region_reg}}; + assign m_axi_aruser = {M_COUNT{ARUSER_ENABLE ? axi_auser_reg[ARUSER_WIDTH-1:0] : {ARUSER_WIDTH{1'b0}}}}; + assign m_axi_arvalid = m_axi_arvalid_reg; + assign m_axi_rready = m_axi_rready_reg; + + // slave side mux + wire [(CL_S_COUNT > 0 ? CL_S_COUNT-1 : 0):0] s_select; + + wire [ID_WIDTH-1:0] current_s_axi_awid = s_axi_awid[s_select*ID_WIDTH+:ID_WIDTH]; + wire [ADDR_WIDTH-1:0] current_s_axi_awaddr = s_axi_awaddr[s_select*ADDR_WIDTH+:ADDR_WIDTH]; + wire [7:0] current_s_axi_awlen = s_axi_awlen[s_select*8+:8]; + wire [2:0] current_s_axi_awsize = s_axi_awsize[s_select*3+:3]; + wire [1:0] current_s_axi_awburst = s_axi_awburst[s_select*2+:2]; + wire current_s_axi_awlock = s_axi_awlock[s_select]; + wire [3:0] current_s_axi_awcache = s_axi_awcache[s_select*4+:4]; + wire [2:0] current_s_axi_awprot = s_axi_awprot[s_select*3+:3]; + wire [3:0] current_s_axi_awqos = s_axi_awqos[s_select*4+:4]; + wire [AWUSER_WIDTH-1:0] current_s_axi_awuser = s_axi_awuser[s_select*AWUSER_WIDTH+:AWUSER_WIDTH]; + wire current_s_axi_awvalid = s_axi_awvalid[s_select]; + wire current_s_axi_awready = s_axi_awready[s_select]; + wire [DATA_WIDTH-1:0] current_s_axi_wdata = s_axi_wdata[s_select*DATA_WIDTH+:DATA_WIDTH]; + wire [STRB_WIDTH-1:0] current_s_axi_wstrb = s_axi_wstrb[s_select*STRB_WIDTH+:STRB_WIDTH]; + wire current_s_axi_wlast = s_axi_wlast[s_select]; + wire [WUSER_WIDTH-1:0] current_s_axi_wuser = s_axi_wuser[s_select*WUSER_WIDTH+:WUSER_WIDTH]; + wire current_s_axi_wvalid = s_axi_wvalid[s_select]; + wire current_s_axi_wready = s_axi_wready[s_select]; + wire [ID_WIDTH-1:0] current_s_axi_bid = s_axi_bid[s_select*ID_WIDTH+:ID_WIDTH]; + wire [1:0] current_s_axi_bresp = s_axi_bresp[s_select*2+:2]; + wire [BUSER_WIDTH-1:0] current_s_axi_buser = s_axi_buser[s_select*BUSER_WIDTH+:BUSER_WIDTH]; + wire current_s_axi_bvalid = s_axi_bvalid[s_select]; + wire current_s_axi_bready = s_axi_bready[s_select]; + wire [ID_WIDTH-1:0] current_s_axi_arid = s_axi_arid[s_select*ID_WIDTH+:ID_WIDTH]; + wire [ADDR_WIDTH-1:0] current_s_axi_araddr = s_axi_araddr[s_select*ADDR_WIDTH+:ADDR_WIDTH]; + wire [7:0] current_s_axi_arlen = s_axi_arlen[s_select*8+:8]; + wire [2:0] current_s_axi_arsize = s_axi_arsize[s_select*3+:3]; + wire [1:0] current_s_axi_arburst = s_axi_arburst[s_select*2+:2]; + wire current_s_axi_arlock = s_axi_arlock[s_select]; + wire [3:0] current_s_axi_arcache = s_axi_arcache[s_select*4+:4]; + wire [2:0] current_s_axi_arprot = s_axi_arprot[s_select*3+:3]; + wire [3:0] current_s_axi_arqos = s_axi_arqos[s_select*4+:4]; + wire [ARUSER_WIDTH-1:0] current_s_axi_aruser = s_axi_aruser[s_select*ARUSER_WIDTH+:ARUSER_WIDTH]; + wire current_s_axi_arvalid = s_axi_arvalid[s_select]; + wire current_s_axi_arready = s_axi_arready[s_select]; + wire [ID_WIDTH-1:0] current_s_axi_rid = s_axi_rid[s_select*ID_WIDTH+:ID_WIDTH]; + wire [DATA_WIDTH-1:0] current_s_axi_rdata = s_axi_rdata[s_select*DATA_WIDTH+:DATA_WIDTH]; + wire [1:0] current_s_axi_rresp = s_axi_rresp[s_select*2+:2]; + wire current_s_axi_rlast = s_axi_rlast[s_select]; + wire [RUSER_WIDTH-1:0] current_s_axi_ruser = s_axi_ruser[s_select*RUSER_WIDTH+:RUSER_WIDTH]; + wire current_s_axi_rvalid = s_axi_rvalid[s_select]; + wire current_s_axi_rready = s_axi_rready[s_select]; + + // master side mux + wire [ID_WIDTH-1:0] current_m_axi_awid = m_axi_awid[m_select_reg*ID_WIDTH+:ID_WIDTH]; + wire [ADDR_WIDTH-1:0] current_m_axi_awaddr = m_axi_awaddr[m_select_reg*ADDR_WIDTH+:ADDR_WIDTH]; + wire [7:0] current_m_axi_awlen = m_axi_awlen[m_select_reg*8+:8]; + wire [2:0] current_m_axi_awsize = m_axi_awsize[m_select_reg*3+:3]; + wire [1:0] current_m_axi_awburst = m_axi_awburst[m_select_reg*2+:2]; + wire current_m_axi_awlock = m_axi_awlock[m_select_reg]; + wire [3:0] current_m_axi_awcache = m_axi_awcache[m_select_reg*4+:4]; + wire [2:0] current_m_axi_awprot = m_axi_awprot[m_select_reg*3+:3]; + wire [3:0] current_m_axi_awqos = m_axi_awqos[m_select_reg*4+:4]; + wire [3:0] current_m_axi_awregion = m_axi_awregion[m_select_reg*4+:4]; + wire [AWUSER_WIDTH-1:0] current_m_axi_awuser = m_axi_awuser[m_select_reg*AWUSER_WIDTH +: AWUSER_WIDTH]; + wire current_m_axi_awvalid = m_axi_awvalid[m_select_reg]; + wire current_m_axi_awready = m_axi_awready[m_select_reg]; + wire [DATA_WIDTH-1:0] current_m_axi_wdata = m_axi_wdata[m_select_reg*DATA_WIDTH+:DATA_WIDTH]; + wire [STRB_WIDTH-1:0] current_m_axi_wstrb = m_axi_wstrb[m_select_reg*STRB_WIDTH+:STRB_WIDTH]; + wire current_m_axi_wlast = m_axi_wlast[m_select_reg]; + wire [WUSER_WIDTH-1:0] current_m_axi_wuser = m_axi_wuser[m_select_reg*WUSER_WIDTH+:WUSER_WIDTH]; + wire current_m_axi_wvalid = m_axi_wvalid[m_select_reg]; + wire current_m_axi_wready = m_axi_wready[m_select_reg]; + wire [ID_WIDTH-1:0] current_m_axi_bid = m_axi_bid[m_select_reg*ID_WIDTH+:ID_WIDTH]; + wire [1:0] current_m_axi_bresp = m_axi_bresp[m_select_reg*2+:2]; + wire [BUSER_WIDTH-1:0] current_m_axi_buser = m_axi_buser[m_select_reg*BUSER_WIDTH+:BUSER_WIDTH]; + wire current_m_axi_bvalid = m_axi_bvalid[m_select_reg]; + wire current_m_axi_bready = m_axi_bready[m_select_reg]; + wire [ID_WIDTH-1:0] current_m_axi_arid = m_axi_arid[m_select_reg*ID_WIDTH+:ID_WIDTH]; + wire [ADDR_WIDTH-1:0] current_m_axi_araddr = m_axi_araddr[m_select_reg*ADDR_WIDTH+:ADDR_WIDTH]; + wire [7:0] current_m_axi_arlen = m_axi_arlen[m_select_reg*8+:8]; + wire [2:0] current_m_axi_arsize = m_axi_arsize[m_select_reg*3+:3]; + wire [1:0] current_m_axi_arburst = m_axi_arburst[m_select_reg*2+:2]; + wire current_m_axi_arlock = m_axi_arlock[m_select_reg]; + wire [3:0] current_m_axi_arcache = m_axi_arcache[m_select_reg*4+:4]; + wire [2:0] current_m_axi_arprot = m_axi_arprot[m_select_reg*3+:3]; + wire [3:0] current_m_axi_arqos = m_axi_arqos[m_select_reg*4+:4]; + wire [3:0] current_m_axi_arregion = m_axi_arregion[m_select_reg*4+:4]; + wire [ARUSER_WIDTH-1:0] current_m_axi_aruser = m_axi_aruser[m_select_reg*ARUSER_WIDTH +: ARUSER_WIDTH]; + wire current_m_axi_arvalid = m_axi_arvalid[m_select_reg]; + wire current_m_axi_arready = m_axi_arready[m_select_reg]; + wire [ID_WIDTH-1:0] current_m_axi_rid = m_axi_rid[m_select_reg*ID_WIDTH+:ID_WIDTH]; + wire [DATA_WIDTH-1:0] current_m_axi_rdata = m_axi_rdata[m_select_reg*DATA_WIDTH+:DATA_WIDTH]; + wire [1:0] current_m_axi_rresp = m_axi_rresp[m_select_reg*2+:2]; + wire current_m_axi_rlast = m_axi_rlast[m_select_reg]; + wire [RUSER_WIDTH-1:0] current_m_axi_ruser = m_axi_ruser[m_select_reg*RUSER_WIDTH+:RUSER_WIDTH]; + wire current_m_axi_rvalid = m_axi_rvalid[m_select_reg]; + wire current_m_axi_rready = m_axi_rready[m_select_reg]; + + // arbiter instance + wire [S_COUNT*2-1:0] request; + wire [S_COUNT*2-1:0] acknowledge; + wire [S_COUNT*2-1:0] grant; + wire grant_valid; + wire [CL_S_COUNT:0] grant_encoded; + + wire read = grant_encoded[0]; + assign s_select = grant_encoded >> 1; + + arbiter #( + .PORTS (S_COUNT * 2), + .TYPE ("ROUND_ROBIN"), + .BLOCK ("ACKNOWLEDGE"), + .LSB_PRIORITY("HIGH") + ) arb_inst ( + .clk (clk), + .rst (rst), + .request (request), + .acknowledge (acknowledge), + .grant (grant), + .grant_valid (grant_valid), + .grant_encoded(grant_encoded) + ); + + genvar n; + + // request generation + generate + for (n = 0; n < S_COUNT; n = n + 1) begin : req_gen + assign request[2*n] = s_axi_awvalid[n]; + assign request[2*n+1] = s_axi_arvalid[n]; + end + endgenerate + + // acknowledge generation + generate + for (n = 0; n < S_COUNT; n = n + 1) begin : ack_gen + assign acknowledge[2*n] = grant[2*n] && s_axi_bvalid[n] && s_axi_bready[n]; + assign acknowledge[2*n+1] = grant[2*n+1] && s_axi_rvalid[n] && s_axi_rready[n] && s_axi_rlast[n]; + end + endgenerate + + always @* begin + state_next = STATE_IDLE; + + match = 1'b0; + + m_select_next = m_select_reg; + axi_id_next = axi_id_reg; + axi_addr_next = axi_addr_reg; + axi_addr_valid_next = axi_addr_valid_reg; + axi_len_next = axi_len_reg; + axi_size_next = axi_size_reg; + axi_burst_next = axi_burst_reg; + axi_lock_next = axi_lock_reg; + axi_cache_next = axi_cache_reg; + axi_prot_next = axi_prot_reg; + axi_qos_next = axi_qos_reg; + axi_region_next = axi_region_reg; + axi_auser_next = axi_auser_reg; + axi_bresp_next = axi_bresp_reg; + axi_buser_next = axi_buser_reg; + + s_axi_awready_next = 0; + s_axi_wready_next = 0; + s_axi_bvalid_next = s_axi_bvalid_reg & ~s_axi_bready; + s_axi_arready_next = 0; + + m_axi_awvalid_next = m_axi_awvalid_reg & ~m_axi_awready; + m_axi_bready_next = 0; + m_axi_arvalid_next = m_axi_arvalid_reg & ~m_axi_arready; + m_axi_rready_next = 0; + + s_axi_rid_int = axi_id_reg; + s_axi_rdata_int = current_m_axi_rdata; + s_axi_rresp_int = current_m_axi_rresp; + s_axi_rlast_int = current_m_axi_rlast; + s_axi_ruser_int = current_m_axi_ruser; + s_axi_rvalid_int = 1'b0; + + m_axi_wdata_int = current_s_axi_wdata; + m_axi_wstrb_int = current_s_axi_wstrb; + m_axi_wlast_int = current_s_axi_wlast; + m_axi_wuser_int = current_s_axi_wuser; + m_axi_wvalid_int = 1'b0; + + case (state_reg) + STATE_IDLE: begin + // idle state; wait for arbitration + + if (grant_valid) begin + + axi_addr_valid_next = 1'b1; + + if (read) begin + // reading + axi_addr_next = current_s_axi_araddr; + axi_prot_next = current_s_axi_arprot; + axi_id_next = current_s_axi_arid; + axi_addr_next = current_s_axi_araddr; + axi_len_next = current_s_axi_arlen; + axi_size_next = current_s_axi_arsize; + axi_burst_next = current_s_axi_arburst; + axi_lock_next = current_s_axi_arlock; + axi_cache_next = current_s_axi_arcache; + axi_prot_next = current_s_axi_arprot; + axi_qos_next = current_s_axi_arqos; + axi_auser_next = current_s_axi_aruser; + s_axi_arready_next[s_select] = 1'b1; + end else begin + // writing + axi_addr_next = current_s_axi_awaddr; + axi_prot_next = current_s_axi_awprot; + axi_id_next = current_s_axi_awid; + axi_addr_next = current_s_axi_awaddr; + axi_len_next = current_s_axi_awlen; + axi_size_next = current_s_axi_awsize; + axi_burst_next = current_s_axi_awburst; + axi_lock_next = current_s_axi_awlock; + axi_cache_next = current_s_axi_awcache; + axi_prot_next = current_s_axi_awprot; + axi_qos_next = current_s_axi_awqos; + axi_auser_next = current_s_axi_awuser; + s_axi_awready_next[s_select] = 1'b1; + end + + state_next = STATE_DECODE; + end else begin + state_next = STATE_IDLE; + end + end + STATE_DECODE: begin + // decode state; determine master interface + + match = 1'b0; + for (i = 0; i < M_COUNT; i = i + 1) begin + for (j = 0; j < M_REGIONS; j = j + 1) begin + if (M_ADDR_WIDTH[(i*M_REGIONS+j)*32 +: 32] && (!M_SECURE[i] || !axi_prot_reg[1]) && ((read ? M_CONNECT_READ : M_CONNECT_WRITE) & (1 << (s_select+i*S_COUNT))) && (axi_addr_reg >> M_ADDR_WIDTH[(i*M_REGIONS+j)*32 +: 32]) == (M_BASE_ADDR_INT[(i*M_REGIONS+j)*ADDR_WIDTH +: ADDR_WIDTH] >> M_ADDR_WIDTH[(i*M_REGIONS+j)*32 +: 32])) begin + m_select_next = i; + axi_region_next = j; + match = 1'b1; + end + end + end + + if (match) begin + if (read) begin + // reading + m_axi_rready_next[m_select_reg] = s_axi_rready_int_early; + state_next = STATE_READ; + end else begin + // writing + s_axi_wready_next[s_select] = m_axi_wready_int_early; + state_next = STATE_WRITE; + end + end else begin + // no match; return decode error + if (read) begin + // reading + state_next = STATE_READ_DROP; + end else begin + // writing + axi_bresp_next = 2'b11; + s_axi_wready_next[s_select] = 1'b1; + state_next = STATE_WRITE_DROP; + end + end + end + STATE_WRITE: begin + // write state; store and forward write data + s_axi_wready_next[s_select] = m_axi_wready_int_early; + + if (axi_addr_valid_reg) begin + m_axi_awvalid_next[m_select_reg] = 1'b1; + end + axi_addr_valid_next = 1'b0; + + if (current_s_axi_wready && current_s_axi_wvalid) begin + m_axi_wdata_int = current_s_axi_wdata; + m_axi_wstrb_int = current_s_axi_wstrb; + m_axi_wlast_int = current_s_axi_wlast; + m_axi_wuser_int = current_s_axi_wuser; + m_axi_wvalid_int = 1'b1; + + if (current_s_axi_wlast) begin + s_axi_wready_next[s_select] = 1'b0; + m_axi_bready_next[m_select_reg] = 1'b1; + state_next = STATE_WRITE_RESP; + end else begin + state_next = STATE_WRITE; + end + end else begin + state_next = STATE_WRITE; + end + end + STATE_WRITE_RESP: begin + // write response state; store and forward write response + m_axi_bready_next[m_select_reg] = 1'b1; + + if (current_m_axi_bready && current_m_axi_bvalid) begin + m_axi_bready_next[m_select_reg] = 1'b0; + axi_bresp_next = current_m_axi_bresp; + s_axi_bvalid_next[s_select] = 1'b1; + state_next = STATE_WAIT_IDLE; + end else begin + state_next = STATE_WRITE_RESP; + end + end + STATE_WRITE_DROP: begin + // write drop state; drop write data + s_axi_wready_next[s_select] = 1'b1; + + axi_addr_valid_next = 1'b0; + + if (current_s_axi_wready && current_s_axi_wvalid) begin + s_axi_wready_next[s_select] = 1'b0; + s_axi_bvalid_next[s_select] = 1'b1; + state_next = STATE_WAIT_IDLE; + end else begin + state_next = STATE_WRITE_DROP; + end + end + STATE_READ: begin + // read state; store and forward read response + m_axi_rready_next[m_select_reg] = s_axi_rready_int_early; + + if (axi_addr_valid_reg) begin + m_axi_arvalid_next[m_select_reg] = 1'b1; + end + axi_addr_valid_next = 1'b0; + + if (current_m_axi_rready && current_m_axi_rvalid) begin + s_axi_rid_int = axi_id_reg; + s_axi_rdata_int = current_m_axi_rdata; + s_axi_rresp_int = current_m_axi_rresp; + s_axi_rlast_int = current_m_axi_rlast; + s_axi_ruser_int = current_m_axi_ruser; + s_axi_rvalid_int = 1'b1; + + if (current_m_axi_rlast) begin + m_axi_rready_next[m_select_reg] = 1'b0; + state_next = STATE_WAIT_IDLE; + end else begin + state_next = STATE_READ; + end + end else begin + state_next = STATE_READ; + end + end + STATE_READ_DROP: begin + // read drop state; generate decode error read response + + s_axi_rid_int = axi_id_reg; + s_axi_rdata_int = {DATA_WIDTH{1'b0}}; + s_axi_rresp_int = 2'b11; + s_axi_rlast_int = axi_len_reg == 0; + s_axi_ruser_int = {RUSER_WIDTH{1'b0}}; + s_axi_rvalid_int = 1'b1; + + if (s_axi_rready_int_reg) begin + axi_len_next = axi_len_reg - 1; + if (axi_len_reg == 0) begin + state_next = STATE_WAIT_IDLE; + end else begin + state_next = STATE_READ_DROP; + end + end else begin + state_next = STATE_READ_DROP; + end + end + STATE_WAIT_IDLE: begin + // wait for idle state; wait untl grant valid is deasserted + + if (!grant_valid || acknowledge) begin + state_next = STATE_IDLE; + end else begin + state_next = STATE_WAIT_IDLE; + end + end + default: ; // Do nothing + endcase + end + + always @(posedge clk, posedge rst) begin + if (rst) begin + state_reg <= STATE_IDLE; + + s_axi_awready_reg <= 0; + s_axi_wready_reg <= 0; + s_axi_bvalid_reg <= 0; + s_axi_arready_reg <= 0; + + m_axi_awvalid_reg <= 0; + m_axi_bready_reg <= 0; + m_axi_arvalid_reg <= 0; + m_axi_rready_reg <= 0; + + m_select_reg <= 2'd0; + axi_id_reg <= {ID_WIDTH{1'b0}}; + axi_addr_reg <= {ADDR_WIDTH{1'b0}}; + axi_addr_valid_reg <= 1'b0; + axi_len_reg <= {8{1'b0}}; + axi_size_reg <= {3{1'b0}}; + axi_burst_reg <= {2{1'b0}}; + axi_lock_reg <= 1'b0; + axi_cache_reg <= {4{1'b0}}; + axi_prot_reg <= {3{1'b0}}; + axi_qos_reg <= {4{1'b0}}; + axi_region_reg <= {4{1'b0}}; + axi_auser_reg <= {ARUSER_WIDTH{1'b0}}; + axi_bresp_reg <= {2{1'b0}}; + axi_buser_reg <= {BUSER_WIDTH{1'b0}}; + end else begin + state_reg <= state_next; + + s_axi_awready_reg <= s_axi_awready_next; + s_axi_wready_reg <= s_axi_wready_next; + s_axi_bvalid_reg <= s_axi_bvalid_next; + s_axi_arready_reg <= s_axi_arready_next; + + m_axi_awvalid_reg <= m_axi_awvalid_next; + m_axi_bready_reg <= m_axi_bready_next; + m_axi_arvalid_reg <= m_axi_arvalid_next; + m_axi_rready_reg <= m_axi_rready_next; + + m_select_reg <= m_select_next; + axi_id_reg <= axi_id_next; + axi_addr_reg <= axi_addr_next; + axi_addr_valid_reg <= axi_addr_valid_next; + axi_len_reg <= axi_len_next; + axi_size_reg <= axi_size_next; + axi_burst_reg <= axi_burst_next; + axi_lock_reg <= axi_lock_next; + axi_cache_reg <= axi_cache_next; + axi_prot_reg <= axi_prot_next; + axi_qos_reg <= axi_qos_next; + axi_region_reg <= axi_region_next; + axi_auser_reg <= axi_auser_next; + axi_bresp_reg <= axi_bresp_next; + axi_buser_reg <= axi_buser_next; + end + end + + // output datapath logic (R channel) + reg [ ID_WIDTH-1:0] s_axi_rid_reg = {ID_WIDTH{1'b0}}; + reg [ DATA_WIDTH-1:0] s_axi_rdata_reg = {DATA_WIDTH{1'b0}}; + reg [ 1:0] s_axi_rresp_reg = 2'd0; + reg s_axi_rlast_reg = 1'b0; + reg [RUSER_WIDTH-1:0] s_axi_ruser_reg = 1'b0; + reg [S_COUNT-1:0] s_axi_rvalid_reg, s_axi_rvalid_next; + + reg [ ID_WIDTH-1:0] temp_s_axi_rid_reg = {ID_WIDTH{1'b0}}; + reg [ DATA_WIDTH-1:0] temp_s_axi_rdata_reg = {DATA_WIDTH{1'b0}}; + reg [ 1:0] temp_s_axi_rresp_reg = 2'd0; + reg temp_s_axi_rlast_reg = 1'b0; + reg [RUSER_WIDTH-1:0] temp_s_axi_ruser_reg = 1'b0; + reg temp_s_axi_rvalid_reg, temp_s_axi_rvalid_next; + + // datapath control + reg store_axi_r_int_to_output; + reg store_axi_r_int_to_temp; + reg store_axi_r_temp_to_output; + + assign s_axi_rid = {S_COUNT{s_axi_rid_reg}}; + assign s_axi_rdata = {S_COUNT{s_axi_rdata_reg}}; + assign s_axi_rresp = {S_COUNT{s_axi_rresp_reg}}; + assign s_axi_rlast = {S_COUNT{s_axi_rlast_reg}}; + assign s_axi_ruser = {S_COUNT{RUSER_ENABLE ? s_axi_ruser_reg : {RUSER_WIDTH{1'b0}}}}; + assign s_axi_rvalid = s_axi_rvalid_reg; + + // enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) + assign s_axi_rready_int_early = current_s_axi_rready | (~temp_s_axi_rvalid_reg & (~current_s_axi_rvalid | ~s_axi_rvalid_int)); + + always @* begin + // transfer sink ready state to source + s_axi_rvalid_next = s_axi_rvalid_reg; + temp_s_axi_rvalid_next = temp_s_axi_rvalid_reg; + + store_axi_r_int_to_output = 1'b0; + store_axi_r_int_to_temp = 1'b0; + store_axi_r_temp_to_output = 1'b0; + + if (s_axi_rready_int_reg) begin + // input is ready + if (current_s_axi_rready | ~current_s_axi_rvalid) begin + // output is ready or currently not valid, transfer data to output + s_axi_rvalid_next[s_select] = s_axi_rvalid_int; + store_axi_r_int_to_output = 1'b1; + end else begin + // output is not ready, store input in temp + temp_s_axi_rvalid_next = s_axi_rvalid_int; + store_axi_r_int_to_temp = 1'b1; + end + end else if (current_s_axi_rready) begin + // input is not ready, but output is ready + s_axi_rvalid_next[s_select] = temp_s_axi_rvalid_reg; + temp_s_axi_rvalid_next = 1'b0; + store_axi_r_temp_to_output = 1'b1; + end + end + + always @(posedge clk, posedge rst) begin + if (rst) begin + s_axi_rvalid_reg <= 1'b0; + s_axi_rready_int_reg <= 1'b0; + temp_s_axi_rvalid_reg <= 1'b0; + s_axi_rid_reg <= {ID_WIDTH{1'b0}}; + s_axi_rdata_reg <= {DATA_WIDTH{1'b0}}; + s_axi_rresp_reg <= 2'd0; + s_axi_rlast_reg <= 1'b0; + s_axi_ruser_reg <= {RUSER_WIDTH{1'b0}}; + temp_s_axi_rid_reg <= {ID_WIDTH{1'b0}}; + temp_s_axi_rdata_reg <= {DATA_WIDTH{1'b0}}; + temp_s_axi_rresp_reg <= 2'd0; + temp_s_axi_rlast_reg <= 1'b0; + temp_s_axi_ruser_reg <= {RUSER_WIDTH{1'b0}}; + end else begin + s_axi_rvalid_reg <= s_axi_rvalid_next; + s_axi_rready_int_reg <= s_axi_rready_int_early; + temp_s_axi_rvalid_reg <= temp_s_axi_rvalid_next; + // datapath + if (store_axi_r_int_to_output) begin + s_axi_rid_reg <= s_axi_rid_int; + s_axi_rdata_reg <= s_axi_rdata_int; + s_axi_rresp_reg <= s_axi_rresp_int; + s_axi_rlast_reg <= s_axi_rlast_int; + s_axi_ruser_reg <= s_axi_ruser_int; + end else if (store_axi_r_temp_to_output) begin + s_axi_rid_reg <= temp_s_axi_rid_reg; + s_axi_rdata_reg <= temp_s_axi_rdata_reg; + s_axi_rresp_reg <= temp_s_axi_rresp_reg; + s_axi_rlast_reg <= temp_s_axi_rlast_reg; + s_axi_ruser_reg <= temp_s_axi_ruser_reg; + end + if (store_axi_r_int_to_temp) begin + temp_s_axi_rid_reg <= s_axi_rid_int; + temp_s_axi_rdata_reg <= s_axi_rdata_int; + temp_s_axi_rresp_reg <= s_axi_rresp_int; + temp_s_axi_rlast_reg <= s_axi_rlast_int; + temp_s_axi_ruser_reg <= s_axi_ruser_int; + end + end + end + + // output datapath logic (W channel) + reg [ DATA_WIDTH-1:0] m_axi_wdata_reg = {DATA_WIDTH{1'b0}}; + reg [ STRB_WIDTH-1:0] m_axi_wstrb_reg = {STRB_WIDTH{1'b0}}; + reg m_axi_wlast_reg = 1'b0; + reg [WUSER_WIDTH-1:0] m_axi_wuser_reg = 1'b0; + reg [M_COUNT-1:0] m_axi_wvalid_reg, m_axi_wvalid_next; + + reg [ DATA_WIDTH-1:0] temp_m_axi_wdata_reg = {DATA_WIDTH{1'b0}}; + reg [ STRB_WIDTH-1:0] temp_m_axi_wstrb_reg = {STRB_WIDTH{1'b0}}; + reg temp_m_axi_wlast_reg = 1'b0; + reg [WUSER_WIDTH-1:0] temp_m_axi_wuser_reg = 1'b0; + reg temp_m_axi_wvalid_reg, temp_m_axi_wvalid_next; + + // datapath control + reg store_axi_w_int_to_output; + reg store_axi_w_int_to_temp; + reg store_axi_w_temp_to_output; + + assign m_axi_wdata = {M_COUNT{m_axi_wdata_reg}}; + assign m_axi_wstrb = {M_COUNT{m_axi_wstrb_reg}}; + assign m_axi_wlast = {M_COUNT{m_axi_wlast_reg}}; + assign m_axi_wuser = {M_COUNT{WUSER_ENABLE ? m_axi_wuser_reg : {WUSER_WIDTH{1'b0}}}}; + assign m_axi_wvalid = m_axi_wvalid_reg; + + // enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) + assign m_axi_wready_int_early = current_m_axi_wready | (~temp_m_axi_wvalid_reg & (~current_m_axi_wvalid | ~m_axi_wvalid_int)); + + always @* begin + // transfer sink ready state to source + m_axi_wvalid_next = m_axi_wvalid_reg; + temp_m_axi_wvalid_next = temp_m_axi_wvalid_reg; + + store_axi_w_int_to_output = 1'b0; + store_axi_w_int_to_temp = 1'b0; + store_axi_w_temp_to_output = 1'b0; + + if (m_axi_wready_int_reg) begin + // input is ready + if (current_m_axi_wready | ~current_m_axi_wvalid) begin + // output is ready or currently not valid, transfer data to output + m_axi_wvalid_next[m_select_reg] = m_axi_wvalid_int; + store_axi_w_int_to_output = 1'b1; + end else begin + // output is not ready, store input in temp + temp_m_axi_wvalid_next = m_axi_wvalid_int; + store_axi_w_int_to_temp = 1'b1; + end + end else if (current_m_axi_wready) begin + // input is not ready, but output is ready + m_axi_wvalid_next[m_select_reg] = temp_m_axi_wvalid_reg; + temp_m_axi_wvalid_next = 1'b0; + store_axi_w_temp_to_output = 1'b1; + end + end + + always @(posedge clk, posedge rst) begin + if (rst) begin + m_axi_wvalid_reg <= 1'b0; + m_axi_wready_int_reg <= 1'b0; + temp_m_axi_wvalid_reg <= 1'b0; + m_axi_wdata_reg <= {DATA_WIDTH{1'b0}}; + m_axi_wstrb_reg <= {STRB_WIDTH{1'b0}}; + m_axi_wlast_reg <= 1'b0; + m_axi_wuser_reg <= {WUSER_WIDTH{1'b0}}; + temp_m_axi_wdata_reg <= {DATA_WIDTH{1'b0}}; + temp_m_axi_wstrb_reg <= {STRB_WIDTH{1'b0}}; + temp_m_axi_wlast_reg <= 1'b0; + temp_m_axi_wuser_reg <= {WUSER_WIDTH{1'b0}}; + end else begin + m_axi_wvalid_reg <= m_axi_wvalid_next; + m_axi_wready_int_reg <= m_axi_wready_int_early; + temp_m_axi_wvalid_reg <= temp_m_axi_wvalid_next; + // datapath + if (store_axi_w_int_to_output) begin + m_axi_wdata_reg <= m_axi_wdata_int; + m_axi_wstrb_reg <= m_axi_wstrb_int; + m_axi_wlast_reg <= m_axi_wlast_int; + m_axi_wuser_reg <= m_axi_wuser_int; + end else if (store_axi_w_temp_to_output) begin + m_axi_wdata_reg <= temp_m_axi_wdata_reg; + m_axi_wstrb_reg <= temp_m_axi_wstrb_reg; + m_axi_wlast_reg <= temp_m_axi_wlast_reg; + m_axi_wuser_reg <= temp_m_axi_wuser_reg; + end + if (store_axi_w_int_to_temp) begin + temp_m_axi_wdata_reg <= m_axi_wdata_int; + temp_m_axi_wstrb_reg <= m_axi_wstrb_int; + temp_m_axi_wlast_reg <= m_axi_wlast_int; + temp_m_axi_wuser_reg <= m_axi_wuser_int; + end + end + end + +endmodule diff --git a/hardware/src/ext_mem.v b/hardware/src/ext_mem.v deleted file mode 100644 index 458e37d9..00000000 --- a/hardware/src/ext_mem.v +++ /dev/null @@ -1,66 +0,0 @@ -`timescale 1 ns / 1 ps - -`include "iob_utils.vh" - -module ext_mem #( - parameter ADDR_W = 0, - parameter DATA_W = 0, - parameter AXI_ID_W = 0, - parameter AXI_LEN_W = 8, - parameter AXI_ADDR_W = ADDR_W, - parameter AXI_DATA_W = DATA_W -) ( - // Instruction bus - input [ `REQ_W-1:0] i_req, - output [`RESP_W-1:0] i_resp, - - // Data bus - input [ `REQ_W-1:0] d_req, - output [`RESP_W-1:0] d_resp, - - // AXI interface - `include "axi_m_port.vs" - `include "clk_en_rst_s_port.vs" -); - - // External memory interface signals - wire [ `REQ_W-1:0] ext_mem_req; - wire [`RESP_W-1:0] ext_mem_resp; - - // Merge cache back-ends - iob_merge #( - .ADDR_W (ADDR_W), - .N_MASTERS(2) - ) merge_i_d_buses ( - .clk_i (clk_i), - .arst_i (arst_i), - // masters - .m_req_i ({i_req, d_req}), - .m_resp_o({i_resp, d_resp}), - // slave - .s_req_o (ext_mem_req), - .s_resp_i(ext_mem_resp) - ); - - // AXI interface - iob2axi #( - .ADDR_WIDTH(AXI_ADDR_W), - .DATA_WIDTH(AXI_DATA_W), - .AXI_ID_WIDTH(AXI_ID_W), - .AXI_RLEN(8'h0f), - .AXI_WLEN(8'h00) - ) ext_mem_iob2axi ( - .iob_avalid_i(ext_mem_req[`AVALID(0)]), - .iob_addr_i (ext_mem_req[`ADDRESS(0, AXI_ADDR_W)]), - .iob_wdata_i (ext_mem_req[`WDATA(0)]), - .iob_wstrb_i (ext_mem_req[`WSTRB(0)]), - .iob_rdata_o (ext_mem_resp[`RDATA(0)]), - .iob_rvalid_o(ext_mem_resp[`RVALID(0)]), - .iob_ready_o (ext_mem_resp[`READY(0)]), - `include "axi_m_m_portmap.vs" - .clk_i (clk_i), - .cke_i (cke_i), - .arst_i (arst_i) - ); - -endmodule diff --git a/hardware/src/iob2axil.v b/hardware/src/iob2axil.v new file mode 100644 index 00000000..a5b0ae74 --- /dev/null +++ b/hardware/src/iob2axil.v @@ -0,0 +1,74 @@ +`timescale 1ns / 1ps + + + +module iob2axil #( + parameter AXIL_ADDR_W = 21, // AXI Lite address bus width in bits + parameter AXIL_DATA_W = 21, // AXI Lite data bus width in bits + parameter ADDR_W = AXIL_ADDR_W, // IOb address bus width in bits + parameter DATA_W = AXIL_DATA_W // IOb data bus width in bits +) ( + // AXI4 Lite master interface + output wire axil_awvalid_o, + input wire axil_awready_i, + output wire [ AXIL_ADDR_W-1:0] axil_awaddr_o, + output wire [ 2:0] axil_awprot_o, + output wire axil_wvalid_o, + input wire axil_wready_i, + output wire [ AXIL_DATA_W-1:0] axil_wdata_o, + output wire [AXIL_DATA_W/8-1:0] axil_wstrb_o, + input wire axil_bvalid_i, + output wire axil_bready_o, + input wire [ 1:0] axil_bresp_i, + output wire axil_arvalid_o, + input wire axil_arready_i, + output wire [ AXIL_ADDR_W-1:0] axil_araddr_o, + output wire [ 2:0] axil_arprot_o, + input wire axil_rvalid_i, + output wire axil_rready_o, + input wire [ AXIL_DATA_W-1:0] axil_rdata_i, + input wire [ 1:0] axil_rresp_i, + + // IOb slave interface + input wire iob_avalid_i, + input wire [ ADDR_W-1:0] iob_addr_i, + input wire [ DATA_W-1:0] iob_wdata_i, + input wire [DATA_W/8-1:0] iob_wstrb_i, + output wire iob_rvalid_o, + output wire [ DATA_W-1:0] iob_rdata_o, + output wire iob_ready_o +); + + // + // COMPUTE IOb OUTPUTS + // + assign iob_rvalid_o = axil_rvalid_i; + assign iob_rdata_o = axil_rdata_i; + assign iob_ready_o = (iob_wstrb_i != {(DATA_W / 8) {1'b0}}) ? axil_wready_i : axil_arready_i; + + // + // COMPUTE AXIL OUTPUTS + // + + // write address + assign axil_awvalid_o = iob_avalid_i & |iob_wstrb_i; + assign axil_awaddr_o = iob_addr_i; + assign axil_awprot_o = 3'd2; + + // write + assign axil_wvalid_o = iob_avalid_i & |iob_wstrb_i; + assign axil_wdata_o = iob_wdata_i; + assign axil_wstrb_o = iob_wstrb_i; + + // write response + assign axil_bready_o = 1'b1; + + // read address + assign axil_arvalid_o = iob_avalid_i & ~|iob_wstrb_i; + assign axil_araddr_o = iob_addr_i; + assign axil_arprot_o = 3'd2; + + // read + assign axil_rready_o = 1'b1; + +endmodule diff --git a/hardware/src/iob_soc_opencryptolinux.v b/hardware/src/iob_soc_opencryptolinux.v index 1bf8dfdc..ef1204e6 100644 --- a/hardware/src/iob_soc_opencryptolinux.v +++ b/hardware/src/iob_soc_opencryptolinux.v @@ -16,28 +16,66 @@ module iob_soc_opencryptolinux #( localparam integer Bbit = `IOB_SOC_OPENCRYPTOLINUX_B; localparam integer AddrMsb = `REQ_W - 2; localparam integer MEM_ADDR_OFFSET = 0; + localparam IBUS_AXI_ID_W = 1; + localparam IBUS_AXI_LEN_W = 8; + localparam IBUS_AXI_ADDR_W = 32; + localparam IBUS_AXI_DATA_W = 32; + localparam DBUS_AXI_ID_W = 1; + localparam DBUS_AXI_LEN_W = 8; + localparam DBUS_AXI_ADDR_W = 32; + localparam DBUS_AXI_DATA_W = 32; + localparam PERIPHERAL_AXI_ID_W = 1; + localparam PERIPHERAL_AXI_LEN_W = 8; + localparam PERIPHERAL_AXI_ADDR_W = 32; + localparam PERIPHERAL_AXI_DATA_W = 32; + localparam IBUS_INTMEM_AXI_ID_W = 1; + localparam IBUS_INTMEM_AXI_LEN_W = 8; + localparam IBUS_INTMEM_AXI_ADDR_W = 32; + localparam IBUS_INTMEM_AXI_DATA_W = 32; + localparam IBUS_EXTMEM_AXI_ID_W = 1; + localparam IBUS_EXTMEM_AXI_LEN_W = 8; + localparam IBUS_EXTMEM_AXI_ADDR_W = 32; + localparam IBUS_EXTMEM_AXI_DATA_W = 32; + localparam DBUS_EXTMEM_AXI_ID_W = 1; + localparam DBUS_EXTMEM_AXI_LEN_W = 8; + localparam DBUS_EXTMEM_AXI_ADDR_W = 32; + localparam DBUS_EXTMEM_AXI_DATA_W = 32; + `include "iob_soc_opencryptolinux_pwires.vs" + + wire iBus_intmem_iob_avalid; + wire [ADDR_W-1:0] iBus_intmem_iob_addr; + wire [DATA_W-1:0] iBus_intmem_iob_wdata; + wire [DATA_W/8-1:0] iBus_intmem_iob_wstrb; + wire iBus_intmem_iob_rvalid; + wire [DATA_W-1:0] iBus_intmem_iob_rdata; + wire iBus_intmem_iob_ready; + + wire peripheral_iob_avalid; + wire [ADDR_W-1:0] peripheral_iob_addr; + wire [DATA_W-1:0] peripheral_iob_wdata; + wire [DATA_W/8-1:0] peripheral_iob_wstrb; + wire peripheral_iob_rvalid; + wire [DATA_W-1:0] peripheral_iob_rdata; + wire peripheral_iob_ready; + // // SYSTEM RESET // - wire boot; - wire cpu_reset; - wire cke_i = 1'b1; + wire boot; + wire cpu_reset; + wire cke_i = 1'b1; // // CPU // - - // instruction bus - wire [ `REQ_W-1:0] cpu_i_req; - wire [`RESP_W-1:0] cpu_i_resp; - - // data cat bus - wire [ `REQ_W-1:0] cpu_d_req; - wire [`RESP_W-1:0] cpu_d_resp; + // Axi instruction bus + `include "iBus_axi_wire.vs" + // Axi data bus + `include "dBus_axi_wire.vs" assign cpu_trap_o = 1'b0; @@ -51,18 +89,16 @@ module iob_soc_opencryptolinux #( .cke_i (cke_i), .arst_i (arst_i), .cpu_reset_i (cpu_reset), - .boot_i (boot), .clint_req ({`REQ_W{1'b0}}), .clint_resp (), .plic_req ({`REQ_W{1'b0}}), .plic_resp (), .plicInterrupts(32'd0), - //instruction bus - .ibus_req (cpu_i_req), - .ibus_resp (cpu_i_resp), - //data bus - .dbus_req (cpu_d_req), - .dbus_resp (cpu_d_resp) + // Axi instruction bus + `include "iBus_axi_m_portmap.vs" + // Axi data bus + `include "dBus_axi_m_portmap.vs" + .boot_i (boot) ); @@ -70,60 +106,319 @@ module iob_soc_opencryptolinux #( // SPLIT CPU BUSES TO ACCESS INTERNAL OR EXTERNAL MEMORY // - //internal memory instruction bus - wire [ `REQ_W-1:0] int_mem_i_req; - wire [`RESP_W-1:0] int_mem_i_resp; - //external memory instruction bus - wire [ `REQ_W-1:0] ext_mem_i_req; - wire [`RESP_W-1:0] ext_mem_i_resp; - - // INSTRUCTION BUS - iob_split #( - .ADDR_W (ADDR_W), - .DATA_W (DATA_W), - .N_SLAVES(2), - .P_SLAVES(AddrMsb) - ) ibus_split ( - .clk_i (clk_i), - .arst_i (arst_i), - // master interface - .m_req_i (cpu_i_req), - .m_resp_o(cpu_i_resp), - // slaves interface - .s_req_o ({ext_mem_i_req, int_mem_i_req}), - .s_resp_i({ext_mem_i_resp, int_mem_i_resp}) + // Intructions intmem AXI bus + `include "iBus_intmem_axi_wire.vs" + // Intructions intmem AXI bus + `include "iBus_extmem_axi_wire.vs" + // Data internal AXI bus + `include "peripheral_axi_wire.vs" + // Data extmem AXI bus + `include "dBus_extmem_axi_wire.vs" + + // Instructions bus interconnect {I, D} -> {internal, external} + axi_interconnect #( + .ID_WIDTH (1), + .DATA_WIDTH(DATA_W), + .ADDR_WIDTH(ADDR_W), + .M_ADDR_WIDTH({2{32'd31}}), + .S_COUNT (1), + .M_COUNT (2) + ) iBus_axi_interconnect ( + .clk(clk_i), + .rst(arst_i), + + .s_axi_awid(iBus_axi_awid), + .s_axi_awaddr(iBus_axi_awaddr), + .s_axi_awlen(iBus_axi_awlen), + .s_axi_awsize(iBus_axi_awsize), + .s_axi_awburst(iBus_axi_awburst), + .s_axi_awlock(iBus_axi_awlock[0]), + .s_axi_awcache(iBus_axi_awcache), + .s_axi_awprot(iBus_axi_awprot), + .s_axi_awqos(iBus_axi_awqos), + .s_axi_awvalid(iBus_axi_awvalid), + .s_axi_awready(iBus_axi_awready), + .s_axi_wdata(iBus_axi_wdata), + .s_axi_wstrb(iBus_axi_wstrb), + .s_axi_wlast(iBus_axi_wlast), + .s_axi_wvalid(iBus_axi_wvalid), + .s_axi_wready(iBus_axi_wready), + .s_axi_bid(iBus_axi_bid), + .s_axi_bresp(iBus_axi_bresp), + .s_axi_bvalid(iBus_axi_bvalid), + .s_axi_bready(iBus_axi_bready), + .s_axi_arid(iBus_axi_arid), + .s_axi_araddr(iBus_axi_araddr), + .s_axi_arlen(iBus_axi_arlen), + .s_axi_arsize(iBus_axi_arsize), + .s_axi_arburst(iBus_axi_arburst), + .s_axi_arlock(iBus_axi_arlock[0]), + .s_axi_arcache(iBus_axi_arcache), + .s_axi_arprot(iBus_axi_arprot), + .s_axi_arqos(iBus_axi_arqos), + .s_axi_arvalid(iBus_axi_arvalid), + .s_axi_arready(iBus_axi_arready), + .s_axi_rid(iBus_axi_rid), + .s_axi_rdata(iBus_axi_rdata), + .s_axi_rresp(iBus_axi_rresp), + .s_axi_rlast(iBus_axi_rlast), + .s_axi_rvalid(iBus_axi_rvalid), + .s_axi_rready(iBus_axi_rready), + + .m_axi_awid({iBus_intmem_axi_awid, iBus_extmem_axi_awid}), + .m_axi_awaddr({iBus_intmem_axi_awaddr, iBus_extmem_axi_awaddr}), + .m_axi_awlen({iBus_intmem_axi_awlen, iBus_extmem_axi_awlen}), + .m_axi_awsize({iBus_intmem_axi_awsize, iBus_extmem_axi_awsize}), + .m_axi_awburst({iBus_intmem_axi_awburst, iBus_extmem_axi_awburst}), + .m_axi_awlock({iBus_intmem_axi_awlock[0], iBus_extmem_axi_awlock[0]}), + .m_axi_awcache({iBus_intmem_axi_awcache, iBus_extmem_axi_awcache}), + .m_axi_awprot({iBus_intmem_axi_awprot, iBus_extmem_axi_awprot}), + .m_axi_awqos({iBus_intmem_axi_awqos, iBus_extmem_axi_awqos}), + .m_axi_awvalid({iBus_intmem_axi_awvalid, iBus_extmem_axi_awvalid}), + .m_axi_awready({iBus_intmem_axi_awready, iBus_extmem_axi_awready}), + .m_axi_wdata({iBus_intmem_axi_wdata, iBus_extmem_axi_wdata}), + .m_axi_wstrb({iBus_intmem_axi_wstrb, iBus_extmem_axi_wstrb}), + .m_axi_wlast({iBus_intmem_axi_wlast, iBus_extmem_axi_wlast}), + .m_axi_wvalid({iBus_intmem_axi_wvalid, iBus_extmem_axi_wvalid}), + .m_axi_wready({iBus_intmem_axi_wready, iBus_extmem_axi_wready}), + .m_axi_bid({iBus_intmem_axi_bid, iBus_extmem_axi_bid}), + .m_axi_bresp({iBus_intmem_axi_bresp, iBus_extmem_axi_bresp}), + .m_axi_bvalid({iBus_intmem_axi_bvalid, iBus_extmem_axi_bvalid}), + .m_axi_bready({iBus_intmem_axi_bready, iBus_extmem_axi_bready}), + .m_axi_arid({iBus_intmem_axi_arid, iBus_extmem_axi_arid}), + .m_axi_araddr({iBus_intmem_axi_araddr, iBus_extmem_axi_araddr}), + .m_axi_arlen({iBus_intmem_axi_arlen, iBus_extmem_axi_arlen}), + .m_axi_arsize({iBus_intmem_axi_arsize, iBus_extmem_axi_arsize}), + .m_axi_arburst({iBus_intmem_axi_arburst, iBus_extmem_axi_arburst}), + .m_axi_arlock({iBus_intmem_axi_arlock[0], iBus_extmem_axi_arlock[0]}), + .m_axi_arcache({iBus_intmem_axi_arcache, iBus_extmem_axi_arcache}), + .m_axi_arprot({iBus_intmem_axi_arprot, iBus_extmem_axi_arprot}), + .m_axi_arqos({iBus_intmem_axi_arqos, iBus_extmem_axi_arqos}), + .m_axi_arvalid({iBus_intmem_axi_arvalid, iBus_extmem_axi_arvalid}), + .m_axi_arready({iBus_intmem_axi_arready, iBus_extmem_axi_arready}), + .m_axi_rid({iBus_intmem_axi_rid, iBus_extmem_axi_rid}), + .m_axi_rdata({iBus_intmem_axi_rdata, iBus_extmem_axi_rdata}), + .m_axi_rresp({iBus_intmem_axi_rresp, iBus_extmem_axi_rresp}), + .m_axi_rlast({iBus_intmem_axi_rlast, iBus_extmem_axi_rlast}), + .m_axi_rvalid({iBus_intmem_axi_rvalid, iBus_extmem_axi_rvalid}), + .m_axi_rready({iBus_intmem_axi_rready, iBus_extmem_axi_rready}), + + //optional signals + .s_axi_awuser(1'b0), + .s_axi_wuser (1'b0), + .s_axi_aruser(1'b0), + .m_axi_buser (2'b00), + .m_axi_ruser (2'b00) ); - - // DATA BUS - - //internal data bus - wire [ `REQ_W-1:0] int_d_req; - wire [`RESP_W-1:0] int_d_resp; - //external memory data bus - wire [ `REQ_W-1:0] ext_mem_d_req; - wire [`RESP_W-1:0] ext_mem_d_resp; - - iob_split #( - .ADDR_W (ADDR_W), - .DATA_W (DATA_W), - .N_SLAVES(2), //E,{P,I} - .P_SLAVES(AddrMsb) - ) dbus_split ( - .clk_i (clk_i), - .arst_i (arst_i), - // master interface - .m_req_i (cpu_d_req), - .m_resp_o(cpu_d_resp), - // slaves interface - .s_req_o ({ext_mem_d_req, int_d_req}), - .s_resp_i({ext_mem_d_resp, int_d_resp}) + // instantiate axi2iob CPU data + axi2iob #( + .ADDR_WIDTH (ADDR_W), + .DATA_WIDTH (DATA_W), + .STRB_WIDTH ((DATA_W / 8)), + .AXI_ID_WIDTH(1) + ) iBus_intmem_axi2iob ( + .clk_i(clk_i), + .arst_i(arst_i), + .s_axi_awid(iBus_intmem_axi_awid), + .s_axi_awaddr(iBus_intmem_axi_awaddr), + .s_axi_awlen(iBus_intmem_axi_awlen), + .s_axi_awsize(iBus_intmem_axi_awsize), + .s_axi_awburst(iBus_intmem_axi_awburst), + .s_axi_awlock(iBus_intmem_axi_awlock[0]), + .s_axi_awcache(iBus_intmem_axi_awcache), + .s_axi_awprot(iBus_intmem_axi_awprot), + .s_axi_awvalid(iBus_intmem_axi_awvalid), + .s_axi_awready(iBus_intmem_axi_awready), + .s_axi_wdata(iBus_intmem_axi_wdata), + .s_axi_wstrb(iBus_intmem_axi_wstrb), + .s_axi_wlast(iBus_intmem_axi_wlast), + .s_axi_wvalid(iBus_intmem_axi_wvalid), + .s_axi_wready(iBus_intmem_axi_wready), + .s_axi_bid(iBus_intmem_axi_bid), + .s_axi_bresp(iBus_intmem_axi_bresp), + .s_axi_bvalid(iBus_intmem_axi_bvalid), + .s_axi_bready(iBus_intmem_axi_bready), + .s_axi_arid(iBus_intmem_axi_arid), + .s_axi_araddr(iBus_intmem_axi_araddr), + .s_axi_arlen(iBus_intmem_axi_arlen), + .s_axi_arsize(iBus_intmem_axi_arsize), + .s_axi_arburst(iBus_intmem_axi_arburst), + .s_axi_arlock(iBus_intmem_axi_arlock[0]), + .s_axi_arcache(iBus_intmem_axi_arcache), + .s_axi_arprot(iBus_intmem_axi_arprot), + .s_axi_arvalid(iBus_intmem_axi_arvalid), + .s_axi_arready(iBus_intmem_axi_arready), + .s_axi_rid(iBus_intmem_axi_rid), + .s_axi_rdata(iBus_intmem_axi_rdata), + .s_axi_rresp(iBus_intmem_axi_rresp), + .s_axi_rlast(iBus_intmem_axi_rlast), + .s_axi_rvalid(iBus_intmem_axi_rvalid), + .s_axi_rready(iBus_intmem_axi_rready), + // IOb-bus signals + .iob_avalid_o(iBus_intmem_iob_avalid), + .iob_addr_o(iBus_intmem_iob_addr), + .iob_wdata_o(iBus_intmem_iob_wdata), + .iob_wstrb_o(iBus_intmem_iob_wstrb), + .iob_rvalid_i(iBus_intmem_iob_rvalid), + .iob_rdata_i(iBus_intmem_iob_rdata), + .iob_ready_i(iBus_intmem_iob_ready) ); // // SPLIT INTERNAL MEMORY AND PERIPHERALS BUS // + // Data bus interconnect {I, D} -> {internal, external} + axi_interconnect #( + .ID_WIDTH (1), + .DATA_WIDTH(DATA_W), + .ADDR_WIDTH(ADDR_W), + .M_ADDR_WIDTH({2{32'd31}}), + .S_COUNT (1), + .M_COUNT (2) + ) dBus_axi_interconnect ( + .clk(clk_i), + .rst(arst_i), + + .s_axi_awid(dBus_axi_awid), + .s_axi_awaddr(dBus_axi_awaddr), + .s_axi_awlen(dBus_axi_awlen), + .s_axi_awsize(dBus_axi_awsize), + .s_axi_awburst(dBus_axi_awburst), + .s_axi_awlock(dBus_axi_awlock[0]), + .s_axi_awcache(dBus_axi_awcache), + .s_axi_awprot(dBus_axi_awprot), + .s_axi_awqos(dBus_axi_awqos), + .s_axi_awvalid(dBus_axi_awvalid), + .s_axi_awready(dBus_axi_awready), + .s_axi_wdata(dBus_axi_wdata), + .s_axi_wstrb(dBus_axi_wstrb), + .s_axi_wlast(dBus_axi_wlast), + .s_axi_wvalid(dBus_axi_wvalid), + .s_axi_wready(dBus_axi_wready), + .s_axi_bid(dBus_axi_bid), + .s_axi_bresp(dBus_axi_bresp), + .s_axi_bvalid(dBus_axi_bvalid), + .s_axi_bready(dBus_axi_bready), + .s_axi_arid(dBus_axi_arid), + .s_axi_araddr(dBus_axi_araddr), + .s_axi_arlen(dBus_axi_arlen), + .s_axi_arsize(dBus_axi_arsize), + .s_axi_arburst(dBus_axi_arburst), + .s_axi_arlock(dBus_axi_arlock[0]), + .s_axi_arcache(dBus_axi_arcache), + .s_axi_arprot(dBus_axi_arprot), + .s_axi_arqos(dBus_axi_arqos), + .s_axi_arvalid(dBus_axi_arvalid), + .s_axi_arready(dBus_axi_arready), + .s_axi_rid(dBus_axi_rid), + .s_axi_rdata(dBus_axi_rdata), + .s_axi_rresp(dBus_axi_rresp), + .s_axi_rlast(dBus_axi_rlast), + .s_axi_rvalid(dBus_axi_rvalid), + .s_axi_rready(dBus_axi_rready), + + .m_axi_awid({peripheral_axi_awid, dBus_extmem_axi_awid}), + .m_axi_awaddr({peripheral_axi_awaddr, dBus_extmem_axi_awaddr}), + .m_axi_awlen({peripheral_axi_awlen, dBus_extmem_axi_awlen}), + .m_axi_awsize({peripheral_axi_awsize, dBus_extmem_axi_awsize}), + .m_axi_awburst({peripheral_axi_awburst, dBus_extmem_axi_awburst}), + .m_axi_awlock({peripheral_axi_awlock[0], dBus_extmem_axi_awlock[0]}), + .m_axi_awcache({peripheral_axi_awcache, dBus_extmem_axi_awcache}), + .m_axi_awprot({peripheral_axi_awprot, dBus_extmem_axi_awprot}), + .m_axi_awqos({peripheral_axi_awqos, dBus_extmem_axi_awqos}), + .m_axi_awvalid({peripheral_axi_awvalid, dBus_extmem_axi_awvalid}), + .m_axi_awready({peripheral_axi_awready, dBus_extmem_axi_awready}), + .m_axi_wdata({peripheral_axi_wdata, dBus_extmem_axi_wdata}), + .m_axi_wstrb({peripheral_axi_wstrb, dBus_extmem_axi_wstrb}), + .m_axi_wlast({peripheral_axi_wlast, dBus_extmem_axi_wlast}), + .m_axi_wvalid({peripheral_axi_wvalid, dBus_extmem_axi_wvalid}), + .m_axi_wready({peripheral_axi_wready, dBus_extmem_axi_wready}), + .m_axi_bid({peripheral_axi_bid, dBus_extmem_axi_bid}), + .m_axi_bresp({peripheral_axi_bresp, dBus_extmem_axi_bresp}), + .m_axi_bvalid({peripheral_axi_bvalid, dBus_extmem_axi_bvalid}), + .m_axi_bready({peripheral_axi_bready, dBus_extmem_axi_bready}), + .m_axi_arid({peripheral_axi_arid, dBus_extmem_axi_arid}), + .m_axi_araddr({peripheral_axi_araddr, dBus_extmem_axi_araddr}), + .m_axi_arlen({peripheral_axi_arlen, dBus_extmem_axi_arlen}), + .m_axi_arsize({peripheral_axi_arsize, dBus_extmem_axi_arsize}), + .m_axi_arburst({peripheral_axi_arburst, dBus_extmem_axi_arburst}), + .m_axi_arlock({peripheral_axi_arlock[0], dBus_extmem_axi_arlock[0]}), + .m_axi_arcache({peripheral_axi_arcache, dBus_extmem_axi_arcache}), + .m_axi_arprot({peripheral_axi_arprot, dBus_extmem_axi_arprot}), + .m_axi_arqos({peripheral_axi_arqos, dBus_extmem_axi_arqos}), + .m_axi_arvalid({peripheral_axi_arvalid, dBus_extmem_axi_arvalid}), + .m_axi_arready({peripheral_axi_arready, dBus_extmem_axi_arready}), + .m_axi_rid({peripheral_axi_rid, dBus_extmem_axi_rid}), + .m_axi_rdata({peripheral_axi_rdata, dBus_extmem_axi_rdata}), + .m_axi_rresp({peripheral_axi_rresp, dBus_extmem_axi_rresp}), + .m_axi_rlast({peripheral_axi_rlast, dBus_extmem_axi_rlast}), + .m_axi_rvalid({peripheral_axi_rvalid, dBus_extmem_axi_rvalid}), + .m_axi_rready({peripheral_axi_rready, dBus_extmem_axi_rready}), + + //optional signals + .s_axi_awuser(1'b0), + .s_axi_wuser (1'b0), + .s_axi_aruser(1'b0), + .m_axi_buser (2'b00), + .m_axi_ruser (2'b00) + ); + + // instantiate axi2iob CPU data + axi2iob #( + .ADDR_WIDTH (ADDR_W), + .DATA_WIDTH (DATA_W), + .STRB_WIDTH ((DATA_W / 8)), + .AXI_ID_WIDTH(1) + ) dBus_axi2iob ( + .clk_i(clk_i), + .arst_i(arst_i), + .s_axi_awid(peripheral_axi_awid), + .s_axi_awaddr(peripheral_axi_awaddr), + .s_axi_awlen(peripheral_axi_awlen), + .s_axi_awsize(peripheral_axi_awsize), + .s_axi_awburst(peripheral_axi_awburst), + .s_axi_awlock(peripheral_axi_awlock[0]), + .s_axi_awcache(peripheral_axi_awcache), + .s_axi_awprot(peripheral_axi_awprot), + .s_axi_awvalid(peripheral_axi_awvalid), + .s_axi_awready(peripheral_axi_awready), + .s_axi_wdata(peripheral_axi_wdata), + .s_axi_wstrb(peripheral_axi_wstrb), + .s_axi_wlast(peripheral_axi_wlast), + .s_axi_wvalid(peripheral_axi_wvalid), + .s_axi_wready(peripheral_axi_wready), + .s_axi_bid(peripheral_axi_bid), + .s_axi_bresp(peripheral_axi_bresp), + .s_axi_bvalid(peripheral_axi_bvalid), + .s_axi_bready(peripheral_axi_bready), + .s_axi_arid(peripheral_axi_arid), + .s_axi_araddr(peripheral_axi_araddr), + .s_axi_arlen(peripheral_axi_arlen), + .s_axi_arsize(peripheral_axi_arsize), + .s_axi_arburst(peripheral_axi_arburst), + .s_axi_arlock(peripheral_axi_arlock[0]), + .s_axi_arcache(peripheral_axi_arcache), + .s_axi_arprot(peripheral_axi_arprot), + .s_axi_arvalid(peripheral_axi_arvalid), + .s_axi_arready(peripheral_axi_arready), + .s_axi_rid(peripheral_axi_rid), + .s_axi_rdata(peripheral_axi_rdata), + .s_axi_rresp(peripheral_axi_rresp), + .s_axi_rlast(peripheral_axi_rlast), + .s_axi_rvalid(peripheral_axi_rvalid), + .s_axi_rready(peripheral_axi_rready), + // IOb-bus signals + .iob_avalid_o(peripheral_iob_avalid), + .iob_addr_o(peripheral_iob_addr), + .iob_wdata_o(peripheral_iob_wdata), + .iob_wstrb_o(peripheral_iob_wstrb), + .iob_rvalid_i(peripheral_iob_rvalid), + .iob_rdata_i(peripheral_iob_rdata), + .iob_ready_i(peripheral_iob_ready) + ); + //slaves bus (includes internal memory + periphrals) wire [ (`IOB_SOC_OPENCRYPTOLINUX_N_SLAVES)*`REQ_W-1:0] slaves_req; wire [(`IOB_SOC_OPENCRYPTOLINUX_N_SLAVES)*`RESP_W-1:0] slaves_resp; @@ -134,13 +429,15 @@ module iob_soc_opencryptolinux #( .N_SLAVES(`IOB_SOC_OPENCRYPTOLINUX_N_SLAVES), .P_SLAVES(AddrMsb - 1) ) pbus_split ( - .clk_i (clk_i), - .arst_i (arst_i), + .clk_i(clk_i), + .arst_i(arst_i), // master interface - .m_req_i (int_d_req), - .m_resp_o(int_d_resp), + .m_req_i({ + peripheral_iob_avalid, peripheral_iob_addr, peripheral_iob_wdata, peripheral_iob_wstrb + }), + .m_resp_o({peripheral_iob_rdata, peripheral_iob_rvalid, peripheral_iob_ready}), // slaves interface - .s_req_o (slaves_req), + .s_req_o(slaves_req), .s_resp_i(slaves_resp) ); @@ -165,80 +462,122 @@ module iob_soc_opencryptolinux #( .cpu_reset(cpu_reset), // instruction bus - .i_req (int_mem_i_req), - .i_resp(int_mem_i_resp), + .i_req({ + iBus_intmem_iob_avalid, iBus_intmem_iob_addr, iBus_intmem_iob_wdata, iBus_intmem_iob_wstrb + }), + .i_resp({iBus_intmem_iob_rdata, iBus_intmem_iob_rvalid, iBus_intmem_iob_ready}), //data bus .d_req (slaves_req[0+:`REQ_W]), .d_resp(slaves_resp[0+:`RESP_W]) ); - // - // EXTERNAL DDR MEMORY - // - ext_mem #( - .ADDR_W (ADDR_W), - .DATA_W (DATA_W), - .AXI_ID_W (AXI_ID_W), - .AXI_LEN_W (AXI_LEN_W), - .AXI_ADDR_W(MEM_ADDR_W), - .AXI_DATA_W(DATA_W) - ) ext_mem0 ( - // instruction bus - .i_req (ext_mem_i_req), - .i_resp(ext_mem_i_resp), - - //data bus - .d_req (ext_mem_d_req), - .d_resp(ext_mem_d_resp), - - //AXI INTERFACE - //address write - .axi_awid_o (axi_awid_o[0+:AXI_ID_W]), - .axi_awaddr_o (internal_axi_awaddr_o[0+:AXI_ADDR_W]), - .axi_awlen_o (axi_awlen_o[0+:AXI_LEN_W]), - .axi_awsize_o (axi_awsize_o[0+:3]), - .axi_awburst_o(axi_awburst_o[0+:2]), - .axi_awlock_o (axi_awlock_o[0+:2]), - .axi_awcache_o(axi_awcache_o[0+:4]), - .axi_awprot_o (axi_awprot_o[0+:3]), - .axi_awqos_o (axi_awqos_o[0+:4]), - .axi_awvalid_o(axi_awvalid_o[0+:1]), - .axi_awready_i(axi_awready_i[0+:1]), - //write - .axi_wdata_o (axi_wdata_o[0+:AXI_DATA_W]), - .axi_wstrb_o (axi_wstrb_o[0+:(AXI_DATA_W/8)]), - .axi_wlast_o (axi_wlast_o[0+:1]), - .axi_wvalid_o (axi_wvalid_o[0+:1]), - .axi_wready_i (axi_wready_i[0+:1]), - //write response - .axi_bid_i (axi_bid_i[0+:AXI_ID_W]), - .axi_bresp_i (axi_bresp_i[0+:2]), - .axi_bvalid_i (axi_bvalid_i[0+:1]), - .axi_bready_o (axi_bready_o[0+:1]), - //address read - .axi_arid_o (axi_arid_o[0+:AXI_ID_W]), - .axi_araddr_o (internal_axi_araddr_o[0+:AXI_ADDR_W]), - .axi_arlen_o (axi_arlen_o[0+:AXI_LEN_W]), - .axi_arsize_o (axi_arsize_o[0+:3]), - .axi_arburst_o(axi_arburst_o[0+:2]), - .axi_arlock_o (axi_arlock_o[0+:2]), - .axi_arcache_o(axi_arcache_o[0+:4]), - .axi_arprot_o (axi_arprot_o[0+:3]), - .axi_arqos_o (axi_arqos_o[0+:4]), - .axi_arvalid_o(axi_arvalid_o[0+:1]), - .axi_arready_i(axi_arready_i[0+:1]), - //read - .axi_rid_i (axi_rid_i[0+:AXI_ID_W]), - .axi_rdata_i (axi_rdata_i[0+:AXI_DATA_W]), - .axi_rresp_i (axi_rresp_i[0+:2]), - .axi_rlast_i (axi_rlast_i[0+:1]), - .axi_rvalid_i (axi_rvalid_i[0+:1]), - .axi_rready_o (axi_rready_o[0+:1]), - - .clk_i (clk_i), - .cke_i (cke_i), - .arst_i(arst_i) + wire extmem_axi_arlock; + wire extmem_axi_awlock; + wire [7:0] extmem_axi_bid; + wire [7:0] extmem_axi_rid; + assign axi_awlock_o = {1'B0, extmem_axi_awlock}; + assign axi_arlock_o = {1'B0, extmem_axi_arlock}; + assign {iBus_extmem_axi_bid, dBus_extmem_axi_bid} = {extmem_axi_bid[4], extmem_axi_bid[0]}; + assign {iBus_extmem_axi_rid, dBus_extmem_axi_rid} = {extmem_axi_rid[4], extmem_axi_rid[0]}; + // Instructions bus interconnect {I, D} -> {internal, external} + axi_interconnect #( + .ID_WIDTH (AXI_ID_W), + .DATA_WIDTH(DATA_W), + .ADDR_WIDTH(MEM_ADDR_W), + .M_ADDR_WIDTH(MEM_ADDR_W), + .S_COUNT (2), + .M_COUNT (1) + ) extmem_axi_interconnect ( + .clk(clk_i), + .rst(arst_i), + + .s_axi_awid({3'b000, iBus_extmem_axi_awid, 3'b000, dBus_extmem_axi_awid}), + .s_axi_awaddr({ + iBus_extmem_axi_awaddr[MEM_ADDR_W-1:0], dBus_extmem_axi_awaddr[MEM_ADDR_W-1:0] + }), + .s_axi_awlen({iBus_extmem_axi_awlen, dBus_extmem_axi_awlen}), + .s_axi_awsize({iBus_extmem_axi_awsize, dBus_extmem_axi_awsize}), + .s_axi_awburst({iBus_extmem_axi_awburst, dBus_extmem_axi_awburst}), + .s_axi_awlock({iBus_extmem_axi_awlock[0], dBus_extmem_axi_awlock[0]}), + .s_axi_awcache({iBus_extmem_axi_awcache, dBus_extmem_axi_awcache}), + .s_axi_awprot({iBus_extmem_axi_awprot, dBus_extmem_axi_awprot}), + .s_axi_awqos({iBus_extmem_axi_awqos, dBus_extmem_axi_awqos}), + .s_axi_awvalid({iBus_extmem_axi_awvalid, dBus_extmem_axi_awvalid}), + .s_axi_awready({iBus_extmem_axi_awready, dBus_extmem_axi_awready}), + .s_axi_wdata({iBus_extmem_axi_wdata, dBus_extmem_axi_wdata}), + .s_axi_wstrb({iBus_extmem_axi_wstrb, dBus_extmem_axi_wstrb}), + .s_axi_wlast({iBus_extmem_axi_wlast, dBus_extmem_axi_wlast}), + .s_axi_wvalid({iBus_extmem_axi_wvalid, dBus_extmem_axi_wvalid}), + .s_axi_wready({iBus_extmem_axi_wready, dBus_extmem_axi_wready}), + .s_axi_bid(extmem_axi_bid), + .s_axi_bresp({iBus_extmem_axi_bresp, dBus_extmem_axi_bresp}), + .s_axi_bvalid({iBus_extmem_axi_bvalid, dBus_extmem_axi_bvalid}), + .s_axi_bready({iBus_extmem_axi_bready, dBus_extmem_axi_bready}), + .s_axi_arid({3'b000, iBus_extmem_axi_arid, 3'b000, dBus_extmem_axi_arid}), + .s_axi_araddr({ + iBus_extmem_axi_araddr[MEM_ADDR_W-1:0], dBus_extmem_axi_araddr[MEM_ADDR_W-1:0] + }), + .s_axi_arlen({iBus_extmem_axi_arlen, dBus_extmem_axi_arlen}), + .s_axi_arsize({iBus_extmem_axi_arsize, dBus_extmem_axi_arsize}), + .s_axi_arburst({iBus_extmem_axi_arburst, dBus_extmem_axi_arburst}), + .s_axi_arlock({iBus_extmem_axi_arlock[0], dBus_extmem_axi_arlock[0]}), + .s_axi_arcache({iBus_extmem_axi_arcache, dBus_extmem_axi_arcache}), + .s_axi_arprot({iBus_extmem_axi_arprot, dBus_extmem_axi_arprot}), + .s_axi_arqos({iBus_extmem_axi_arqos, dBus_extmem_axi_arqos}), + .s_axi_arvalid({iBus_extmem_axi_arvalid, dBus_extmem_axi_arvalid}), + .s_axi_arready({iBus_extmem_axi_arready, dBus_extmem_axi_arready}), + .s_axi_rid(extmem_axi_rid), + .s_axi_rdata({iBus_extmem_axi_rdata, dBus_extmem_axi_rdata}), + .s_axi_rresp({iBus_extmem_axi_rresp, dBus_extmem_axi_rresp}), + .s_axi_rlast({iBus_extmem_axi_rlast, dBus_extmem_axi_rlast}), + .s_axi_rvalid({iBus_extmem_axi_rvalid, dBus_extmem_axi_rvalid}), + .s_axi_rready({iBus_extmem_axi_rready, dBus_extmem_axi_rready}), + + .m_axi_awid(axi_awid_o), + .m_axi_awaddr(internal_axi_awaddr_o), + .m_axi_awlen(axi_awlen_o), + .m_axi_awsize(axi_awsize_o), + .m_axi_awburst(axi_awburst_o), + .m_axi_awlock(extmem_axi_awlock), + .m_axi_awcache(axi_awcache_o), + .m_axi_awprot(axi_awprot_o), + .m_axi_awqos(axi_awqos_o), + .m_axi_awvalid(axi_awvalid_o), + .m_axi_awready(axi_awready_i), + .m_axi_wdata(axi_wdata_o), + .m_axi_wstrb(axi_wstrb_o), + .m_axi_wlast(axi_wlast_o), + .m_axi_wvalid(axi_wvalid_o), + .m_axi_wready(axi_wready_i), + .m_axi_bid(axi_bid_i), + .m_axi_bresp(axi_bresp_i), + .m_axi_bvalid(axi_bvalid_i), + .m_axi_bready(axi_bready_o), + .m_axi_arid(axi_arid_o), + .m_axi_araddr(internal_axi_araddr_o), + .m_axi_arlen(axi_arlen_o), + .m_axi_arsize(axi_arsize_o), + .m_axi_arburst(axi_arburst_o), + .m_axi_arlock(extmem_axi_arlock), + .m_axi_arcache(axi_arcache_o), + .m_axi_arprot(axi_arprot_o), + .m_axi_arqos(axi_arqos_o), + .m_axi_arvalid(axi_arvalid_o), + .m_axi_arready(axi_arready_i), + .m_axi_rid(axi_rid_i), + .m_axi_rdata(axi_rdata_i), + .m_axi_rresp(axi_rresp_i), + .m_axi_rlast(axi_rlast_i), + .m_axi_rvalid(axi_rvalid_i), + .m_axi_rready(axi_rready_o), + + //optional signals + .s_axi_awuser(2'b00), + .s_axi_wuser (2'b00), + .s_axi_aruser(2'b00), + .m_axi_buser (1'b0), + .m_axi_ruser (1'b0) ); assign axi_awaddr_o[AXI_ADDR_W-1:0] = internal_axi_awaddr_o + MEM_ADDR_OFFSET; diff --git a/submodules/LIB b/submodules/LIB index 83331602..832d78df 160000 --- a/submodules/LIB +++ b/submodules/LIB @@ -1 +1 @@ -Subproject commit 833316020080d1e5dc78909fe17bf97655adce39 +Subproject commit 832d78dfcd1383be33d5d4aea2335a370ff341a4 diff --git a/submodules/VEXRISCV b/submodules/VEXRISCV index a4957a61..88a6af07 160000 --- a/submodules/VEXRISCV +++ b/submodules/VEXRISCV @@ -1 +1 @@ -Subproject commit a4957a616773e8123ead5073db2daf7ff0a40588 +Subproject commit 88a6af07d7589c69e519e850d513177af1b7f3db From 23a09d1114f2d0345c3ed1aac08ddcc7b5428ea0 Mon Sep 17 00:00:00 2001 From: Pedro Antunes Date: Mon, 18 Sep 2023 23:47:00 +0100 Subject: [PATCH 18/27] software/*: testing interrupts in baremetal. --- software/src/iob-clint.c | 89 + software/src/iob-clint.h | 39 + software/src/iob-plic.c | 63 + software/src/iob-plic.h | 60 + software/src/iob_soc_opencryptolinux_boot.c | 2 +- .../src/iob_soc_opencryptolinux_firmware.c | 95 +- software/src/riscv-csr.h | 3784 +++++++++++++++++ software/src/riscv-interrupts.h | 56 + 8 files changed, 4176 insertions(+), 12 deletions(-) create mode 100644 software/src/iob-clint.c create mode 100644 software/src/iob-clint.h create mode 100644 software/src/iob-plic.c create mode 100644 software/src/iob-plic.h create mode 100644 software/src/riscv-csr.h create mode 100644 software/src/riscv-interrupts.h diff --git a/software/src/iob-clint.c b/software/src/iob-clint.c new file mode 100644 index 00000000..25aa2607 --- /dev/null +++ b/software/src/iob-clint.c @@ -0,0 +1,89 @@ +#include "iob-clint.h" + +void clint_init(int base_address){ + clint_base = base_address; +} + +void clint_set_timer(unsigned long long time){ + (*(volatile uint32_t *) (clint_base + MTIME_BASE)) = (uint32_t)(time & 0x0FFFFFFFFUL); + (*(volatile uint32_t *) (clint_base + MTIME_BASE + 4)) = (uint32_t)(time >> 32); +} + +uint64_t clint_get_timer(){ + uint64_t read_time; + + read_time = (uint64_t)(*(volatile uint32_t *) (clint_base + MTIME_BASE)); + read_time |= (uint64_t)(*(volatile uint32_t *) (clint_base + MTIME_BASE + 4)) << 32; + + return read_time; +} + +void clint_set_timercmp(unsigned long long time, int hart){ + (*(volatile uint32_t *) (clint_base + MTIMECMP_BASE + 8*hart + 4)) = 0xFFFFFFFF; + (*(volatile uint32_t *) (clint_base + MTIMECMP_BASE + 8*hart)) = (uint32_t)(time & 0x0FFFFFFFFUL); + (*(volatile uint32_t *) (clint_base + MTIMECMP_BASE + 8*hart + 4)) = (uint32_t)(time >> 32); +} + +uint64_t clint_get_timercmp(int hart){ + uint64_t read_time; + + read_time = (uint64_t)(*(volatile uint32_t *) (clint_base + MTIMECMP_BASE + 8*hart)); + read_time |= (uint64_t)(*(volatile uint32_t *) (clint_base + MTIMECMP_BASE + 8*hart + 4)) << 32; + + return read_time; +} + +void clint_set_msip(unsigned long msip_value, int hart){ + (*(volatile uint32_t *) (clint_base + MSIP_BASE + 4*hart)) = msip_value; +} + +uint32_t clint_get_msip(int hart){ + uint32_t msip_value; + + msip_value = (*(volatile uint32_t *) (clint_base + MSIP_BASE + 4*hart)); + + return msip_value; +} + +void mtimer_set_raw_time_cmp(uint64_t clock_offset) { + // First of all set + uint64_t new_mtimecmp = mtimer_get_raw_time() + clock_offset; +#if (__riscv_xlen == 64) + // Single bus access + volatile uint64_t *mtimecmp = (volatile uint64_t*)(clint_base+MTIMECMP_BASE); + *mtimecmp = new_mtimecmp; +#else + volatile uint32_t *mtimecmpl = (volatile uint32_t *)(clint_base+MTIMECMP_BASE); + volatile uint32_t *mtimecmph = (volatile uint32_t *)(clint_base+MTIMECMP_BASE+4); + // AS we are doing 32 bit writes, an intermediate mtimecmp value may cause spurious interrupts. + // Prevent that by first setting the dummy MSB to an unacheivable value + *mtimecmph = 0xFFFFFFFF; // cppcheck-suppress redundantAssignment + // set the LSB + *mtimecmpl = (uint32_t)(new_mtimecmp & 0x0FFFFFFFFUL); + // Set the correct MSB + *mtimecmph = (uint32_t)(new_mtimecmp >> 32); // cppcheck-suppress redundantAssignment +#endif +} + +/** Read the raw time of the system timer in system timer clocks + */ +uint64_t mtimer_get_raw_time(void) { +#if ( __riscv_xlen == 64) + // Directly read 64 bit value + volatile uint64_t *mtime = (volatile uint64_t *)(clint_base+MTIME_BASE); + return *mtime; +#else + volatile uint32_t * mtimel = (volatile uint32_t *)(clint_base+MTIME_BASE); + volatile uint32_t * mtimeh = (volatile uint32_t *)(clint_base+MTIME_BASE+4); + uint32_t mtimeh_val; + uint32_t mtimel_val; + do { + // There is a small risk the mtimeh will tick over after reading mtimel + mtimeh_val = *mtimeh; + mtimel_val = *mtimel; + // Poll mtimeh to ensure it's consistent after reading mtimel + // The frequency of mtimeh ticking over is low + } while (mtimeh_val != *mtimeh); + return (uint64_t) ( ( ((uint64_t)mtimeh_val)<<32) | mtimel_val); +#endif +} diff --git a/software/src/iob-clint.h b/software/src/iob-clint.h new file mode 100644 index 00000000..6871fe92 --- /dev/null +++ b/software/src/iob-clint.h @@ -0,0 +1,39 @@ +#ifndef CLINT_H +#define CLINT_H + +#include + +#define MSIP_BASE 0 +#define MTIMECMP_BASE 0x4000 +#define MTIME_BASE 0xBFF8 + +#define MTIME_FREQ_HZ 100000 + +#define MTIMER_SECONDS_TO_CLOCKS(SEC) \ + ((uint64_t)(((SEC)*(MTIME_FREQ_HZ)))) + +//Functions +static int clint_base; +void clint_init(int); + +void clint_set_timer(unsigned long long); +void clint_set_timercmp(unsigned long long, int); +void clint_set_msip(unsigned long, int); + +uint64_t clint_get_timer(); +uint64_t clint_get_timercmp(int); +uint32_t clint_get_msip(int); + +/** Set the raw time compare point in system timer clocks. + * @param clock_offset Time relative to current mtime when + * @note The time range of the 64 bit timer is large enough not to consider a wrap around of mtime. + * An interrupt will be generated at mtime + clock_offset. + * See http://five-embeddev.com/riscv-isa-manual/latest/machine.html#machine-timer-registers-mtime-and-mtimecmp + */ +void mtimer_set_raw_time_cmp(uint64_t clock_offset); + +/** Read the raw time of the system timer in system timer clocks + */ +uint64_t mtimer_get_raw_time(void); + +#endif // #ifdef CLINT_H diff --git a/software/src/iob-plic.c b/software/src/iob-plic.c new file mode 100644 index 00000000..ebff46e6 --- /dev/null +++ b/software/src/iob-plic.c @@ -0,0 +1,63 @@ +#include + +#include "iob-plic.h" +#include "riscv-csr.h" + +void plic_init(int base_address){ + base = base_address; + + int i = 0; + //clear all EL + for (i=0; i < EDGE_LEVEL_REGS; i++) + plic_write((EL_BASE_ADDRESS+i)*DATA_W/8, 0); + //set priority for all sources to '1'; '0' means 'never interrupt' + int write_pr = write_pr_regs(); + for (i=0; i < PRIORITY_REGS; i++) + plic_write((PR_BASE_ADDRESS+i)*DATA_W/8, write_pr); + //clear all IE + for (i=0; i < IE_REGS; i++) + plic_write((IE_BASE_ADDRESS+i)*DATA_W/8, 0); + //set all threshold to '0' + for (i=0; i < PTHRESHOLD_REGS; i++) + plic_write((TH_BASE_ADDRESS+i)*DATA_W/8, 0); +} +void plic_write(int address, int data){ + (*(volatile uint32_t *) (base+address)) = (uint32_t)(data); +} +int plic_read(int address){ + return (uint64_t)(*(volatile uint32_t *) (base+address)); +} + +int plic_enable_interrupt(int source){ + int target; + target = csr_read_mhartid(); + plic_write((IE_BASE_ADDRESS+(target*EDGE_LEVEL_REGS)+(source/DATA_W))*DATA_W/8, 1 << (source % DATA_W)); + return target; +} +int plic_disable_interrupt(int source){ + int target; + target = csr_read_mhartid(); + plic_write((IE_BASE_ADDRESS+(target*EDGE_LEVEL_REGS)+(source/DATA_W))*DATA_W/8, 0); + return target; +} +/* Returns interrupt ID */ +int plic_claim_interrupt(){ + int target; + target = csr_read_mhartid(); + return plic_read((ID_BASE_ADDRESS + target) * DATA_W/8); +} +/* Sends complete signal to PLIC */ +void plic_complete_interrupt(int source_id){ + int target; + target = csr_read_mhartid(); + plic_write((ID_BASE_ADDRESS + target) * DATA_W/8, 1 << (source_id % DATA_W)); +} + +int write_pr_regs(){ + int res = 0; + int i = 0; + for (i = 0; i < PRIORITY_FIELDS_PER_REG; i++) { + res = (res << (DATA_W/8)*PRIORITY_NIBBLES) | 0x01; + } + return res; +} diff --git a/software/src/iob-plic.h b/software/src/iob-plic.h new file mode 100644 index 00000000..4b4573f2 --- /dev/null +++ b/software/src/iob-plic.h @@ -0,0 +1,60 @@ +#pragma once + +#define DATA_W 32 + +#ifndef N_SOURCES +#define N_SOURCES 32 +#endif + +#ifndef N_TARGETS +#define N_TARGETS 1 +#endif + +#define PRIORITY_BITS 3 //$clog2(PRIORITIES); PRIORITIES = 8; +#define HAS_THRESHOLD 1 +#define HAS_CONFIG_REG 1 +//Configuration Bits +#define MAX_SOURCES_BITS 16 +#define MAX_TARGETS_BITS 16 +#define MAX_PRIORITY_BITS MAX_SOURCES_BITS +#define HAS_THRESHOLD_BITS 1 +//How many CONFIG registers are there (only 1) +#define CONFIG_REGS (HAS_CONFIG_REG == 0 ? 0 : ((MAX_SOURCES_BITS + MAX_TARGETS_BITS + MAX_PRIORITY_BITS + HAS_THRESHOLD_BITS + DATA_W -1)/DATA_W)) +//Amount of Edge/Level registers +#define EDGE_LEVEL_REGS ((N_SOURCES + DATA_W -1) / DATA_W) +//Amount of Interrupt Enable registers +#define IE_REGS (EDGE_LEVEL_REGS * N_TARGETS) +//Each PRIORITY field starts at a new nibble boundary +//Get the number of nibbles in 'PRIORITY_BITS' ? +#define PRIORITY_NIBBLES ((PRIORITY_BITS +3 -1) / 4) +//How many PRIORITY fields fit in 1 register? +#define PRIORITY_FIELDS_PER_REG (DATA_W / (PRIORITY_NIBBLES*4)) +//Amount of Priority registers +#define PRIORITY_REGS ((N_SOURCES + PRIORITY_FIELDS_PER_REG -1) / PRIORITY_FIELDS_PER_REG) +//Amount of Threshold registers +#define PTHRESHOLD_REGS (HAS_THRESHOLD == 0 ? 0 : N_TARGETS) +//Amount of ID registers +#define ID_REGS N_TARGETS +//Total amount of registers +#define TOTAL_REGS (CONFIG_REGS + EDGE_LEVEL_REGS + IE_REGS + PRIORITY_REGS + PTHRESHOLD_REGS + ID_REGS) + + +//Set base register addresses ... +#define EL_BASE_ADDRESS CONFIG_REGS +#define PR_BASE_ADDRESS (EL_BASE_ADDRESS+EDGE_LEVEL_REGS) +#define IE_BASE_ADDRESS (PR_BASE_ADDRESS+PRIORITY_REGS) +#define TH_BASE_ADDRESS (IE_BASE_ADDRESS+IE_REGS) +#define ID_BASE_ADDRESS (TH_BASE_ADDRESS+PTHRESHOLD_REGS) + +//Functions +static int base; +void plic_init(int); +void plic_write(int, int); +int plic_read(int); + +int plic_enable_interrupt(int); +int plic_disable_interrupt(int); +int plic_claim_interrupt(); +void plic_complete_interrupt(int); + +int write_pr_regs(); diff --git a/software/src/iob_soc_opencryptolinux_boot.c b/software/src/iob_soc_opencryptolinux_boot.c index bdcd652f..d741a7e9 100644 --- a/software/src/iob_soc_opencryptolinux_boot.c +++ b/software/src/iob_soc_opencryptolinux_boot.c @@ -5,7 +5,7 @@ // defined here (and not in periphs.h) because it is the only peripheral used // by the bootloader -#define UART0_BASE (UART0 << (31 - N_SLAVES_W - 4)) | 0xf0000000 +#define UART0_BASE 0xfa000000 #define PROGNAME "IOb-Bootloader" diff --git a/software/src/iob_soc_opencryptolinux_firmware.c b/software/src/iob_soc_opencryptolinux_firmware.c index 8facc61a..5e04e032 100644 --- a/software/src/iob_soc_opencryptolinux_firmware.c +++ b/software/src/iob_soc_opencryptolinux_firmware.c @@ -4,24 +4,97 @@ #include "iob_soc_opencryptolinux_system.h" #include "iob_str.h" #include "printf.h" +#include "iob-plic.h" +#include "iob-clint.h" -#define UART0_BASE 0xf4000000 -#define PLIC0_BASE 0xf4000000 -#define CLINT0_BASE 0xf6000000 +#include "riscv-csr.h" +#include "riscv-interrupts.h" + +#define UART0_BASE 0xfa000000 +#define PLIC0_BASE 0xfc000000 +#define CLINT0_BASE 0xfe000000 + +// Machine mode interrupt service routine +static void irq_entry(void) __attribute__ ((interrupt ("machine"))); // Global to hold current timestamp static volatile uint64_t timestamp = 0; int main() { - char pass_string[] = "Test passed!"; + char pass_string[] = "Test passed!"; + + //init uart + uart16550_init(UART0_BASE, FREQ/(16*BAUD)); + clint_init(CLINT0_BASE); + plic_init(PLIC0_BASE); + printf_init(&uart16550_putc); + + printf("\n\n\nHello world!\n\n\n"); + + // Global interrupt disable + csr_clr_bits_mstatus(MSTATUS_MIE_BIT_MASK); + csr_write_mie(0); + csr_clr_bits_mcause(MCAUSE_INTERRUPT_ALL_SET_MASK); + csr_write_mcause(0); + + // Setup timer for 1 second interval + timestamp = mtimer_get_raw_time(); + mtimer_set_raw_time_cmp(MTIMER_SECONDS_TO_CLOCKS(0.03)); - // init uart - uart16550_init(UART0_BASE, FREQ / (16 * BAUD)); - printf_init(&uart16550_putc); + // Setup the IRQ handler entry point + csr_write_mtvec((uint_xlen_t) irq_entry); - printf("\n\n\nHello world!\n\n\n"); + // Enable MIE.MTI and MIE.MEI + csr_set_bits_mie(MIE_MTI_BIT_MASK); + csr_set_bits_mie(MIE_MEI_BIT_MASK); + + // Global interrupt enable + csr_set_bits_mstatus(MSTATUS_MIE_BIT_MASK); + + // Enable PLIC interrupt for UART + printf("Enabling external interrupt source 0 with ID = 1.\n"); + int target; + target = plic_enable_interrupt(0); + + printf("HART id %d, waiting for timer interrupt...\n", target); + // Wait for interrupt + __asm__ volatile ("wfi"); + + uart16550_sendfile("test.log", iob_strlen(pass_string), pass_string); + + printf("Exit...\n"); + uart16550_finish(); + return 0; +} - printf("Exit...\n"); - uart16550_finish(); - return 0; +#pragma GCC push_options +// Force the alignment for mtvec.BASE. A 'C' extension program could be aligned to to bytes. +#pragma GCC optimize ("align-functions=4") +static void irq_entry(void) { + printf("Entered IRQ.\n"); + uint_xlen_t this_cause = csr_read_mcause(); + if (this_cause & MCAUSE_INTERRUPT_BIT_MASK) { + this_cause &= 0xFF; + // Known exceptions + switch (this_cause) { + case RISCV_INT_POS_MTI : + printf("Time interrupt.\n"); + // Timer exception, keep up the one second tick. + mtimer_set_raw_time_cmp(MTIMER_SECONDS_TO_CLOCKS(1)); + timestamp = mtimer_get_raw_time(); + float aux = (float)timestamp/MTIME_FREQ_HZ; + printf("Current time passed: %.3f seconds.\n", aux); + printf("MTIMER register value: %lld.\n", timestamp); + break; + case RISCV_INT_POS_MEI : + printf("External interrupt.\n"); + int source_id = 0; + source_id = plic_claim_interrupt(); + printf("External interrupt ID received was: %d.\n", source_id); + plic_complete_interrupt(source_id); + plic_disable_interrupt(source_id); + break; + } + } } +#pragma GCC pop_options \ No newline at end of file diff --git a/software/src/riscv-csr.h b/software/src/riscv-csr.h new file mode 100644 index 00000000..1dc58bf1 --- /dev/null +++ b/software/src/riscv-csr.h @@ -0,0 +1,3784 @@ +/* + Register access functions for RISC-V system registers. + SPDX-License-Identifier: Unlicense + + https://five-embeddev.com/ + +*/ + +#ifndef RISCV_CSR_H +#define RISCV_CSR_H + +#include + +#if __riscv_xlen==32 +typedef uint32_t uint_xlen_t; +typedef uint32_t uint_csr32_t; +typedef uint32_t uint_csr64_t; +#elif __riscv_xlen==64 +typedef uint64_t uint_xlen_t; +typedef uint32_t uint_csr32_t; +typedef uint64_t uint_csr64_t; +#else +#error "Unknown XLEN" +#endif + +/******************************************* + * misa - MRW - Machine ISA + */ +static inline uint_xlen_t csr_read_misa(void) { + uint_xlen_t value; + __asm__ volatile ("csrr %0, misa" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} +static inline void csr_write_misa(uint_xlen_t value) { + __asm__ volatile ("csrw misa, %0" + : /* output: none */ + : "r" (value) /* input : from register */ + : /* clobbers: none */); +} +static inline uint_xlen_t csr_read_write_misa(uint_xlen_t new_value) { + uint_xlen_t prev_value; + __asm__ volatile ("csrrw %0, misa, %1" + : "=r" (prev_value) /* output: register %0 */ + : "r" (new_value) /* input : register */ + : /* clobbers: none */); + return prev_value; +} + +/******************************************* + * mvendorid - MRO - Machine Vendor ID + */ +static inline uint32_t csr_read_mvendorid(void) { + uint_csr32_t value; + __asm__ volatile ("csrr %0, mvendorid" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} + +/******************************************* + * marchid - MRO - Machine Architecture ID + */ +static inline uint_xlen_t csr_read_marchid(void) { + uint_xlen_t value; + __asm__ volatile ("csrr %0, marchid" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} + +/******************************************* + * mimpid - MRO - Machine Implementation ID + */ +static inline uint_xlen_t csr_read_mimpid(void) { + uint_xlen_t value; + __asm__ volatile ("csrr %0, mimpid" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} + +/******************************************* + * mhartid - MRO - Hardware Thread ID + */ +static inline uint_xlen_t csr_read_mhartid(void) { + uint_xlen_t value; + __asm__ volatile ("csrr %0, mhartid" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} + +/******************************************* + * mstatus - MRW - Machine Status + */ +static inline uint_xlen_t csr_read_mstatus(void) { + uint_xlen_t value; + __asm__ volatile ("csrr %0, mstatus" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} +static inline void csr_write_mstatus(uint_xlen_t value) { + __asm__ volatile ("csrw mstatus, %0" + : /* output: none */ + : "r" (value) /* input : from register */ + : /* clobbers: none */); +} +static inline uint_xlen_t csr_read_write_mstatus(uint_xlen_t new_value) { + uint_xlen_t prev_value; + __asm__ volatile ("csrrw %0, mstatus, %1" + : "=r" (prev_value) /* output: register %0 */ + : "r" (new_value) /* input : register */ + : /* clobbers: none */); + return prev_value; +} +/* Register CSR bit set and clear instructions */ +static inline void csr_set_bits_mstatus(uint_xlen_t mask) { + __asm__ volatile ("csrrs zero, mstatus, %0" + : /* output: none */ + : "r" (mask) /* input : register */ + : /* clobbers: none */); +} +static inline void csr_clr_bits_mstatus(uint_xlen_t mask) { + __asm__ volatile ("csrrc zero, mstatus, %0" + : /* output: none */ + : "r" (mask) /* input : register */ + : /* clobbers: none */); +} +static inline uint_xlen_t csr_read_set_bits_mstatus(uint_xlen_t mask) { + uint_xlen_t value; + __asm__ volatile ("csrrs %0, mstatus, %1" + : "=r" (value) /* output: register %0 */ + : "r" (mask) /* input : register */ + : /* clobbers: none */); + return value; +} +static inline uint_xlen_t csr_read_clr_bits_mstatus(uint_xlen_t mask) { + uint_xlen_t value; + __asm__ volatile ("csrrc %0, mstatus, %1" + : "=r" (value) /* output: register %0 */ + : "r" (mask) /* input : register */ + : /* clobbers: none */); + return value; +} +/* mstatus, CSR write value via immediate value (only up to 5 bits) */ +#define CSR_WRITE_IMM_MSTATUS(VALUE) \ + __asm__ volatile ("csrrwi zero, mstatus, %0" \ + : /* output: none */ \ + : "i" (VALUE) /* input : immediate */ \ + : /* clobbers: none */) + +/* mstatus, CSR set bits via immediate value mask (only up to 5 bits) */ +#define CSR_SET_BITS_IMM_MSTATUS(MASK) \ + __asm__ volatile ("csrrsi zero, mstatus, %0" \ + : /* output: none */ \ + : "i" (MASK) /* input : immediate */ \ + : /* clobbers: none */) + +/* mstatus, CSR clear bits via immediate value mask (only up to 5 bits) */ +#define CSR_CLR_BITS_IMM_MSTATUS(MASK) \ + __asm__ volatile ("csrrci zero, mstatus, %0" \ + : /* output: none */ \ + : "i" (MASK) /* input : immediate */ \ + : /* clobbers: none */) +#define MSTATUS_MIE_BIT_OFFSET 3 +#define MSTATUS_MIE_BIT_WIDTH 1 +#define MSTATUS_MIE_BIT_MASK 0x8 +#define MSTATUS_MIE_ALL_SET_MASK 0x1 +#define MSTATUS_SIE_BIT_OFFSET 2 +#define MSTATUS_SIE_BIT_WIDTH 1 +#define MSTATUS_SIE_BIT_MASK 0x4 +#define MSTATUS_SIE_ALL_SET_MASK 0x1 +#define MSTATUS_MPIE_BIT_OFFSET 7 +#define MSTATUS_MPIE_BIT_WIDTH 1 +#define MSTATUS_MPIE_BIT_MASK 0x80 +#define MSTATUS_MPIE_ALL_SET_MASK 0x1 +#define MSTATUS_SPIE_BIT_OFFSET 5 +#define MSTATUS_SPIE_BIT_WIDTH 1 +#define MSTATUS_SPIE_BIT_MASK 0x20 +#define MSTATUS_SPIE_ALL_SET_MASK 0x1 +#define MSTATUS_MPRV_BIT_OFFSET 17 +#define MSTATUS_MPRV_BIT_WIDTH 1 +#define MSTATUS_MPRV_BIT_MASK 0x20000 +#define MSTATUS_MPRV_ALL_SET_MASK 0x1 +#define MSTATUS_MPP_BIT_OFFSET 11 +#define MSTATUS_MPP_BIT_WIDTH 2 +#define MSTATUS_MPP_BIT_MASK 0x1800 +#define MSTATUS_MPP_ALL_SET_MASK 0x3 +#define MSTATUS_SPP_BIT_OFFSET 8 +#define MSTATUS_SPP_BIT_WIDTH 1 +#define MSTATUS_SPP_BIT_MASK 0x100 +#define MSTATUS_SPP_ALL_SET_MASK 0x1 + +/******************************************* + * mstatush - MRW - Additional machine status register, RV32 only. + */ +static inline uint_xlen_t csr_read_mstatush(void) { + uint_xlen_t value; + __asm__ volatile ("csrr %0, mstatush" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} +static inline void csr_write_mstatush(uint_xlen_t value) { + __asm__ volatile ("csrw mstatush, %0" + : /* output: none */ + : "r" (value) /* input : from register */ + : /* clobbers: none */); +} +static inline uint_xlen_t csr_read_write_mstatush(uint_xlen_t new_value) { + uint_xlen_t prev_value; + __asm__ volatile ("csrrw %0, mstatush, %1" + : "=r" (prev_value) /* output: register %0 */ + : "r" (new_value) /* input : register */ + : /* clobbers: none */); + return prev_value; +} + +/******************************************* + * mtvec - MRW - Machine Trap Vector Base Address + */ +static inline uint_xlen_t csr_read_mtvec(void) { + uint_xlen_t value; + __asm__ volatile ("csrr %0, mtvec" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} +static inline void csr_write_mtvec(uint_xlen_t value) { + __asm__ volatile ("csrw mtvec, %0" + : /* output: none */ + : "r" (value) /* input : from register */ + : /* clobbers: none */); +} +static inline uint_xlen_t csr_read_write_mtvec(uint_xlen_t new_value) { + uint_xlen_t prev_value; + __asm__ volatile ("csrrw %0, mtvec, %1" + : "=r" (prev_value) /* output: register %0 */ + : "r" (new_value) /* input : register */ + : /* clobbers: none */); + return prev_value; +} +/* Register CSR bit set and clear instructions */ +static inline void csr_set_bits_mtvec(uint_xlen_t mask) { + __asm__ volatile ("csrrs zero, mtvec, %0" + : /* output: none */ + : "r" (mask) /* input : register */ + : /* clobbers: none */); +} +static inline void csr_clr_bits_mtvec(uint_xlen_t mask) { + __asm__ volatile ("csrrc zero, mtvec, %0" + : /* output: none */ + : "r" (mask) /* input : register */ + : /* clobbers: none */); +} +static inline uint_xlen_t csr_read_set_bits_mtvec(uint_xlen_t mask) { + uint_xlen_t value; + __asm__ volatile ("csrrs %0, mtvec, %1" + : "=r" (value) /* output: register %0 */ + : "r" (mask) /* input : register */ + : /* clobbers: none */); + return value; +} +static inline uint_xlen_t csr_read_clr_bits_mtvec(uint_xlen_t mask) { + uint_xlen_t value; + __asm__ volatile ("csrrc %0, mtvec, %1" + : "=r" (value) /* output: register %0 */ + : "r" (mask) /* input : register */ + : /* clobbers: none */); + return value; +} +/* mtvec, CSR write value via immediate value (only up to 5 bits) */ +#define CSR_WRITE_IMM_MTVEC(VALUE) \ + __asm__ volatile ("csrrwi zero, mtvec, %0" \ + : /* output: none */ \ + : "i" (VALUE) /* input : immediate */ \ + : /* clobbers: none */) + +/* mtvec, CSR set bits via immediate value mask (only up to 5 bits) */ +#define CSR_SET_BITS_IMM_MTVEC(MASK) \ + __asm__ volatile ("csrrsi zero, mtvec, %0" \ + : /* output: none */ \ + : "i" (MASK) /* input : immediate */ \ + : /* clobbers: none */) + +/* mtvec, CSR clear bits via immediate value mask (only up to 5 bits) */ +#define CSR_CLR_BITS_IMM_MTVEC(MASK) \ + __asm__ volatile ("csrrci zero, mtvec, %0" \ + : /* output: none */ \ + : "i" (MASK) /* input : immediate */ \ + : /* clobbers: none */) +#define MTVEC_BASE_BIT_OFFSET 2 +#define MTVEC_BASE_BIT_WIDTH ((__riscv_xlen-1)-(2) + 1) +#define MTVEC_BASE_BIT_MASK ((1UL<<(((__riscv_xlen-1)-(2) + 1)-1)) << (2)) +#define MTVEC_BASE_ALL_SET_MASK ((1UL<<(((__riscv_xlen-1)-(2) + 1)-1)) << (0)) +#define MTVEC_MODE_BIT_OFFSET 0 +#define MTVEC_MODE_BIT_WIDTH 2 +#define MTVEC_MODE_BIT_MASK 0x3 +#define MTVEC_MODE_ALL_SET_MASK 0x3 + +/******************************************* + * medeleg - MRW - Machine Exception Delegation + */ +static inline uint_xlen_t csr_read_medeleg(void) { + uint_xlen_t value; + __asm__ volatile ("csrr %0, medeleg" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} +static inline void csr_write_medeleg(uint_xlen_t value) { + __asm__ volatile ("csrw medeleg, %0" + : /* output: none */ + : "r" (value) /* input : from register */ + : /* clobbers: none */); +} +static inline uint_xlen_t csr_read_write_medeleg(uint_xlen_t new_value) { + uint_xlen_t prev_value; + __asm__ volatile ("csrrw %0, medeleg, %1" + : "=r" (prev_value) /* output: register %0 */ + : "r" (new_value) /* input : register */ + : /* clobbers: none */); + return prev_value; +} + +/******************************************* + * mideleg - MRW - Machine Interrupt Delegation + */ +static inline uint_xlen_t csr_read_mideleg(void) { + uint_xlen_t value; + __asm__ volatile ("csrr %0, mideleg" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} +static inline void csr_write_mideleg(uint_xlen_t value) { + __asm__ volatile ("csrw mideleg, %0" + : /* output: none */ + : "r" (value) /* input : from register */ + : /* clobbers: none */); +} +static inline uint_xlen_t csr_read_write_mideleg(uint_xlen_t new_value) { + uint_xlen_t prev_value; + __asm__ volatile ("csrrw %0, mideleg, %1" + : "=r" (prev_value) /* output: register %0 */ + : "r" (new_value) /* input : register */ + : /* clobbers: none */); + return prev_value; +} + +/******************************************* + * mip - MRW - Machine Interrupt Pending + */ +static inline uint_xlen_t csr_read_mip(void) { + uint_xlen_t value; + __asm__ volatile ("csrr %0, mip" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} +static inline void csr_write_mip(uint_xlen_t value) { + __asm__ volatile ("csrw mip, %0" + : /* output: none */ + : "r" (value) /* input : from register */ + : /* clobbers: none */); +} +static inline uint_xlen_t csr_read_write_mip(uint_xlen_t new_value) { + uint_xlen_t prev_value; + __asm__ volatile ("csrrw %0, mip, %1" + : "=r" (prev_value) /* output: register %0 */ + : "r" (new_value) /* input : register */ + : /* clobbers: none */); + return prev_value; +} +/* Register CSR bit set and clear instructions */ +static inline void csr_set_bits_mip(uint_xlen_t mask) { + __asm__ volatile ("csrrs zero, mip, %0" + : /* output: none */ + : "r" (mask) /* input : register */ + : /* clobbers: none */); +} +static inline void csr_clr_bits_mip(uint_xlen_t mask) { + __asm__ volatile ("csrrc zero, mip, %0" + : /* output: none */ + : "r" (mask) /* input : register */ + : /* clobbers: none */); +} +static inline uint_xlen_t csr_read_set_bits_mip(uint_xlen_t mask) { + uint_xlen_t value; + __asm__ volatile ("csrrs %0, mip, %1" + : "=r" (value) /* output: register %0 */ + : "r" (mask) /* input : register */ + : /* clobbers: none */); + return value; +} +static inline uint_xlen_t csr_read_clr_bits_mip(uint_xlen_t mask) { + uint_xlen_t value; + __asm__ volatile ("csrrc %0, mip, %1" + : "=r" (value) /* output: register %0 */ + : "r" (mask) /* input : register */ + : /* clobbers: none */); + return value; +} +/* mip, CSR write value via immediate value (only up to 5 bits) */ +#define CSR_WRITE_IMM_MIP(VALUE) \ + __asm__ volatile ("csrrwi zero, mip, %0" \ + : /* output: none */ \ + : "i" (VALUE) /* input : immediate */ \ + : /* clobbers: none */) + +/* mip, CSR set bits via immediate value mask (only up to 5 bits) */ +#define CSR_SET_BITS_IMM_MIP(MASK) \ + __asm__ volatile ("csrrsi zero, mip, %0" \ + : /* output: none */ \ + : "i" (MASK) /* input : immediate */ \ + : /* clobbers: none */) + +/* mip, CSR clear bits via immediate value mask (only up to 5 bits) */ +#define CSR_CLR_BITS_IMM_MIP(MASK) \ + __asm__ volatile ("csrrci zero, mip, %0" \ + : /* output: none */ \ + : "i" (MASK) /* input : immediate */ \ + : /* clobbers: none */) +#define MIP_MSI_BIT_OFFSET 3 +#define MIP_MSI_BIT_WIDTH 1 +#define MIP_MSI_BIT_MASK 0x8 +#define MIP_MSI_ALL_SET_MASK 0x1 +#define MIP_MTI_BIT_OFFSET 7 +#define MIP_MTI_BIT_WIDTH 1 +#define MIP_MTI_BIT_MASK 0x80 +#define MIP_MTI_ALL_SET_MASK 0x1 +#define MIP_MEI_BIT_OFFSET 11 +#define MIP_MEI_BIT_WIDTH 1 +#define MIP_MEI_BIT_MASK 0x800 +#define MIP_MEI_ALL_SET_MASK 0x1 +#define MIP_SSI_BIT_OFFSET 1 +#define MIP_SSI_BIT_WIDTH 1 +#define MIP_SSI_BIT_MASK 0x2 +#define MIP_SSI_ALL_SET_MASK 0x1 +#define MIP_STI_BIT_OFFSET 5 +#define MIP_STI_BIT_WIDTH 1 +#define MIP_STI_BIT_MASK 0x20 +#define MIP_STI_ALL_SET_MASK 0x1 +#define MIP_SEI_BIT_OFFSET 9 +#define MIP_SEI_BIT_WIDTH 1 +#define MIP_SEI_BIT_MASK 0x200 +#define MIP_SEI_ALL_SET_MASK 0x1 +#define MIP_USI_BIT_OFFSET 0 +#define MIP_USI_BIT_WIDTH 1 +#define MIP_USI_BIT_MASK 0x1 +#define MIP_USI_ALL_SET_MASK 0x1 +#define MIP_UTI_BIT_OFFSET 4 +#define MIP_UTI_BIT_WIDTH 1 +#define MIP_UTI_BIT_MASK 0x10 +#define MIP_UTI_ALL_SET_MASK 0x1 +#define MIP_UEI_BIT_OFFSET 8 +#define MIP_UEI_BIT_WIDTH 1 +#define MIP_UEI_BIT_MASK 0x100 +#define MIP_UEI_ALL_SET_MASK 0x1 +#define MIP_PLATFORM_DEFINED_BIT_OFFSET 16 +#define MIP_PLATFORM_DEFINED_BIT_WIDTH ((__riscv_xlen)-(16) + 1) +#define MIP_PLATFORM_DEFINED_BIT_MASK ((1UL<<(((__riscv_xlen)-(16) + 1)-1)) << (16)) +#define MIP_PLATFORM_DEFINED_ALL_SET_MASK ((1UL<<(((__riscv_xlen)-(16) + 1)-1)) << (0)) + +/******************************************* + * mie - MRW - Machine Interrupt Enable + */ +static inline uint_xlen_t csr_read_mie(void) { + uint_xlen_t value; + __asm__ volatile ("csrr %0, mie" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} +static inline void csr_write_mie(uint_xlen_t value) { + __asm__ volatile ("csrw mie, %0" + : /* output: none */ + : "r" (value) /* input : from register */ + : /* clobbers: none */); +} +static inline uint_xlen_t csr_read_write_mie(uint_xlen_t new_value) { + uint_xlen_t prev_value; + __asm__ volatile ("csrrw %0, mie, %1" + : "=r" (prev_value) /* output: register %0 */ + : "r" (new_value) /* input : register */ + : /* clobbers: none */); + return prev_value; +} +/* Register CSR bit set and clear instructions */ +static inline void csr_set_bits_mie(uint_xlen_t mask) { + __asm__ volatile ("csrrs zero, mie, %0" + : /* output: none */ + : "r" (mask) /* input : register */ + : /* clobbers: none */); +} +static inline void csr_clr_bits_mie(uint_xlen_t mask) { + __asm__ volatile ("csrrc zero, mie, %0" + : /* output: none */ + : "r" (mask) /* input : register */ + : /* clobbers: none */); +} +static inline uint_xlen_t csr_read_set_bits_mie(uint_xlen_t mask) { + uint_xlen_t value; + __asm__ volatile ("csrrs %0, mie, %1" + : "=r" (value) /* output: register %0 */ + : "r" (mask) /* input : register */ + : /* clobbers: none */); + return value; +} +static inline uint_xlen_t csr_read_clr_bits_mie(uint_xlen_t mask) { + uint_xlen_t value; + __asm__ volatile ("csrrc %0, mie, %1" + : "=r" (value) /* output: register %0 */ + : "r" (mask) /* input : register */ + : /* clobbers: none */); + return value; +} +/* mie, CSR write value via immediate value (only up to 5 bits) */ +#define CSR_WRITE_IMM_MIE(VALUE) \ + __asm__ volatile ("csrrwi zero, mie, %0" \ + : /* output: none */ \ + : "i" (VALUE) /* input : immediate */ \ + : /* clobbers: none */) + +/* mie, CSR set bits via immediate value mask (only up to 5 bits) */ +#define CSR_SET_BITS_IMM_MIE(MASK) \ + __asm__ volatile ("csrrsi zero, mie, %0" \ + : /* output: none */ \ + : "i" (MASK) /* input : immediate */ \ + : /* clobbers: none */) + +/* mie, CSR clear bits via immediate value mask (only up to 5 bits) */ +#define CSR_CLR_BITS_IMM_MIE(MASK) \ + __asm__ volatile ("csrrci zero, mie, %0" \ + : /* output: none */ \ + : "i" (MASK) /* input : immediate */ \ + : /* clobbers: none */) +#define MIE_MSI_BIT_OFFSET 3 +#define MIE_MSI_BIT_WIDTH 1 +#define MIE_MSI_BIT_MASK 0x8 +#define MIE_MSI_ALL_SET_MASK 0x1 +#define MIE_MTI_BIT_OFFSET 7 +#define MIE_MTI_BIT_WIDTH 1 +#define MIE_MTI_BIT_MASK 0x80 +#define MIE_MTI_ALL_SET_MASK 0x1 +#define MIE_MEI_BIT_OFFSET 11 +#define MIE_MEI_BIT_WIDTH 1 +#define MIE_MEI_BIT_MASK 0x800 +#define MIE_MEI_ALL_SET_MASK 0x1 +#define MIE_SSI_BIT_OFFSET 1 +#define MIE_SSI_BIT_WIDTH 1 +#define MIE_SSI_BIT_MASK 0x2 +#define MIE_SSI_ALL_SET_MASK 0x1 +#define MIE_STI_BIT_OFFSET 5 +#define MIE_STI_BIT_WIDTH 1 +#define MIE_STI_BIT_MASK 0x20 +#define MIE_STI_ALL_SET_MASK 0x1 +#define MIE_SEI_BIT_OFFSET 9 +#define MIE_SEI_BIT_WIDTH 1 +#define MIE_SEI_BIT_MASK 0x200 +#define MIE_SEI_ALL_SET_MASK 0x1 +#define MIE_USI_BIT_OFFSET 0 +#define MIE_USI_BIT_WIDTH 1 +#define MIE_USI_BIT_MASK 0x1 +#define MIE_USI_ALL_SET_MASK 0x1 +#define MIE_UTI_BIT_OFFSET 4 +#define MIE_UTI_BIT_WIDTH 1 +#define MIE_UTI_BIT_MASK 0x10 +#define MIE_UTI_ALL_SET_MASK 0x1 +#define MIE_UEI_BIT_OFFSET 8 +#define MIE_UEI_BIT_WIDTH 1 +#define MIE_UEI_BIT_MASK 0x100 +#define MIE_UEI_ALL_SET_MASK 0x1 +#define MIE_PLATFORM_DEFINED_BIT_OFFSET 16 +#define MIE_PLATFORM_DEFINED_BIT_WIDTH ((__riscv_xlen)-(16) + 1) +#define MIE_PLATFORM_DEFINED_BIT_MASK ((1UL<<(((__riscv_xlen)-(16) + 1)-1)) << (16)) +#define MIE_PLATFORM_DEFINED_ALL_SET_MASK ((1UL<<(((__riscv_xlen)-(16) + 1)-1)) << (0)) + +/******************************************* + * mcountinhibit - MRW - Machine Counter Inhibit + */ +static inline uint32_t csr_read_mcountinhibit(void) { + uint_csr32_t value; + __asm__ volatile ("csrr %0, mcountinhibit" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} +static inline void csr_write_mcountinhibit(uint_csr32_t value) { + __asm__ volatile ("csrw mcountinhibit, %0" + : /* output: none */ + : "r" (value) /* input : from register */ + : /* clobbers: none */); +} +static inline uint32_t csr_read_write_mcountinhibit(uint32_t new_value) { + uint_csr32_t prev_value; + __asm__ volatile ("csrrw %0, mcountinhibit, %1" + : "=r" (prev_value) /* output: register %0 */ + : "r" (new_value) /* input : register */ + : /* clobbers: none */); + return prev_value; +} +/* Register CSR bit set and clear instructions */ +static inline void csr_set_bits_mcountinhibit(uint32_t mask) { + __asm__ volatile ("csrrs zero, mcountinhibit, %0" + : /* output: none */ + : "r" (mask) /* input : register */ + : /* clobbers: none */); +} +static inline void csr_clr_bits_mcountinhibit(uint32_t mask) { + __asm__ volatile ("csrrc zero, mcountinhibit, %0" + : /* output: none */ + : "r" (mask) /* input : register */ + : /* clobbers: none */); +} +static inline uint32_t csr_read_set_bits_mcountinhibit(uint32_t mask) { + uint_csr32_t value; + __asm__ volatile ("csrrs %0, mcountinhibit, %1" + : "=r" (value) /* output: register %0 */ + : "r" (mask) /* input : register */ + : /* clobbers: none */); + return value; +} +static inline uint32_t csr_read_clr_bits_mcountinhibit(uint32_t mask) { + uint_csr32_t value; + __asm__ volatile ("csrrc %0, mcountinhibit, %1" + : "=r" (value) /* output: register %0 */ + : "r" (mask) /* input : register */ + : /* clobbers: none */); + return value; +} +/* mcountinhibit, CSR write value via immediate value (only up to 5 bits) */ +#define CSR_WRITE_IMM_MCOUNTINHIBIT(VALUE) \ + __asm__ volatile ("csrrwi zero, mcountinhibit, %0" \ + : /* output: none */ \ + : "i" (VALUE) /* input : immediate */ \ + : /* clobbers: none */) + +/* mcountinhibit, CSR set bits via immediate value mask (only up to 5 bits) */ +#define CSR_SET_BITS_IMM_MCOUNTINHIBIT(MASK) \ + __asm__ volatile ("csrrsi zero, mcountinhibit, %0" \ + : /* output: none */ \ + : "i" (MASK) /* input : immediate */ \ + : /* clobbers: none */) + +/* mcountinhibit, CSR clear bits via immediate value mask (only up to 5 bits) */ +#define CSR_CLR_BITS_IMM_MCOUNTINHIBIT(MASK) \ + __asm__ volatile ("csrrci zero, mcountinhibit, %0" \ + : /* output: none */ \ + : "i" (MASK) /* input : immediate */ \ + : /* clobbers: none */) +#define MCOUNTINHIBIT_CY_BIT_OFFSET 0 +#define MCOUNTINHIBIT_CY_BIT_WIDTH 1 +#define MCOUNTINHIBIT_CY_BIT_MASK 0x1 +#define MCOUNTINHIBIT_CY_ALL_SET_MASK 0x1 +#define MCOUNTINHIBIT_IR_BIT_OFFSET 2 +#define MCOUNTINHIBIT_IR_BIT_WIDTH 1 +#define MCOUNTINHIBIT_IR_BIT_MASK 0x4 +#define MCOUNTINHIBIT_IR_ALL_SET_MASK 0x1 +#define MCOUNTINHIBIT_HPM_BIT_OFFSET 3 +#define MCOUNTINHIBIT_HPM_BIT_WIDTH 29 +#define MCOUNTINHIBIT_HPM_BIT_MASK 0xfffffff8 +#define MCOUNTINHIBIT_HPM_ALL_SET_MASK 0x1fffffff + +/******************************************* + * mcycle - MRW - Clock Cycles Executed Counter + */ +static inline uint64_t csr_read_mcycle(void) { + uint_csr64_t value; + __asm__ volatile ("csrr %0, mcycle" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} +static inline void csr_write_mcycle(uint_csr64_t value) { + __asm__ volatile ("csrw mcycle, %0" + : /* output: none */ + : "r" (value) /* input : from register */ + : /* clobbers: none */); +} +static inline uint64_t csr_read_write_mcycle(uint64_t new_value) { + uint_csr64_t prev_value; + __asm__ volatile ("csrrw %0, mcycle, %1" + : "=r" (prev_value) /* output: register %0 */ + : "r" (new_value) /* input : register */ + : /* clobbers: none */); + return prev_value; +} + +/******************************************* + * minstret - MRW - Number of Instructions Retired Counter + */ +static inline uint64_t csr_read_minstret(void) { + uint_csr64_t value; + __asm__ volatile ("csrr %0, minstret" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} +static inline void csr_write_minstret(uint_csr64_t value) { + __asm__ volatile ("csrw minstret, %0" + : /* output: none */ + : "r" (value) /* input : from register */ + : /* clobbers: none */); +} +static inline uint64_t csr_read_write_minstret(uint64_t new_value) { + uint_csr64_t prev_value; + __asm__ volatile ("csrrw %0, minstret, %1" + : "=r" (prev_value) /* output: register %0 */ + : "r" (new_value) /* input : register */ + : /* clobbers: none */); + return prev_value; +} + +/******************************************* + * mhpmcounter3 - MRW - Event Counters + */ +static inline uint64_t csr_read_mhpmcounter3(void) { + uint_csr64_t value; + __asm__ volatile ("csrr %0, mhpmcounter3" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} +static inline void csr_write_mhpmcounter3(uint_csr64_t value) { + __asm__ volatile ("csrw mhpmcounter3, %0" + : /* output: none */ + : "r" (value) /* input : from register */ + : /* clobbers: none */); +} +static inline uint64_t csr_read_write_mhpmcounter3(uint64_t new_value) { + uint_csr64_t prev_value; + __asm__ volatile ("csrrw %0, mhpmcounter3, %1" + : "=r" (prev_value) /* output: register %0 */ + : "r" (new_value) /* input : register */ + : /* clobbers: none */); + return prev_value; +} + +/******************************************* + * mhpmevent3 - MRW - Event Counter Event Select + */ +static inline uint_xlen_t csr_read_mhpmevent3(void) { + uint_xlen_t value; + __asm__ volatile ("csrr %0, mhpmevent3" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} +static inline void csr_write_mhpmevent3(uint_xlen_t value) { + __asm__ volatile ("csrw mhpmevent3, %0" + : /* output: none */ + : "r" (value) /* input : from register */ + : /* clobbers: none */); +} +static inline uint_xlen_t csr_read_write_mhpmevent3(uint_xlen_t new_value) { + uint_xlen_t prev_value; + __asm__ volatile ("csrrw %0, mhpmevent3, %1" + : "=r" (prev_value) /* output: register %0 */ + : "r" (new_value) /* input : register */ + : /* clobbers: none */); + return prev_value; +} + +/******************************************* + * mcounteren - MRW - Counter Enable + */ +static inline uint32_t csr_read_mcounteren(void) { + uint_csr32_t value; + __asm__ volatile ("csrr %0, mcounteren" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} +static inline void csr_write_mcounteren(uint_csr32_t value) { + __asm__ volatile ("csrw mcounteren, %0" + : /* output: none */ + : "r" (value) /* input : from register */ + : /* clobbers: none */); +} +static inline uint32_t csr_read_write_mcounteren(uint32_t new_value) { + uint_csr32_t prev_value; + __asm__ volatile ("csrrw %0, mcounteren, %1" + : "=r" (prev_value) /* output: register %0 */ + : "r" (new_value) /* input : register */ + : /* clobbers: none */); + return prev_value; +} +/* Register CSR bit set and clear instructions */ +static inline void csr_set_bits_mcounteren(uint32_t mask) { + __asm__ volatile ("csrrs zero, mcounteren, %0" + : /* output: none */ + : "r" (mask) /* input : register */ + : /* clobbers: none */); +} +static inline void csr_clr_bits_mcounteren(uint32_t mask) { + __asm__ volatile ("csrrc zero, mcounteren, %0" + : /* output: none */ + : "r" (mask) /* input : register */ + : /* clobbers: none */); +} +static inline uint32_t csr_read_set_bits_mcounteren(uint32_t mask) { + uint_csr32_t value; + __asm__ volatile ("csrrs %0, mcounteren, %1" + : "=r" (value) /* output: register %0 */ + : "r" (mask) /* input : register */ + : /* clobbers: none */); + return value; +} +static inline uint32_t csr_read_clr_bits_mcounteren(uint32_t mask) { + uint_csr32_t value; + __asm__ volatile ("csrrc %0, mcounteren, %1" + : "=r" (value) /* output: register %0 */ + : "r" (mask) /* input : register */ + : /* clobbers: none */); + return value; +} +/* mcounteren, CSR write value via immediate value (only up to 5 bits) */ +#define CSR_WRITE_IMM_MCOUNTEREN(VALUE) \ + __asm__ volatile ("csrrwi zero, mcounteren, %0" \ + : /* output: none */ \ + : "i" (VALUE) /* input : immediate */ \ + : /* clobbers: none */) + +/* mcounteren, CSR set bits via immediate value mask (only up to 5 bits) */ +#define CSR_SET_BITS_IMM_MCOUNTEREN(MASK) \ + __asm__ volatile ("csrrsi zero, mcounteren, %0" \ + : /* output: none */ \ + : "i" (MASK) /* input : immediate */ \ + : /* clobbers: none */) + +/* mcounteren, CSR clear bits via immediate value mask (only up to 5 bits) */ +#define CSR_CLR_BITS_IMM_MCOUNTEREN(MASK) \ + __asm__ volatile ("csrrci zero, mcounteren, %0" \ + : /* output: none */ \ + : "i" (MASK) /* input : immediate */ \ + : /* clobbers: none */) +#define MCOUNTEREN_CY_BIT_OFFSET 0 +#define MCOUNTEREN_CY_BIT_WIDTH 1 +#define MCOUNTEREN_CY_BIT_MASK 0x1 +#define MCOUNTEREN_CY_ALL_SET_MASK 0x1 +#define MCOUNTEREN_TM_BIT_OFFSET 1 +#define MCOUNTEREN_TM_BIT_WIDTH 1 +#define MCOUNTEREN_TM_BIT_MASK 0x2 +#define MCOUNTEREN_TM_ALL_SET_MASK 0x1 +#define MCOUNTEREN_IR_BIT_OFFSET 2 +#define MCOUNTEREN_IR_BIT_WIDTH 1 +#define MCOUNTEREN_IR_BIT_MASK 0x4 +#define MCOUNTEREN_IR_ALL_SET_MASK 0x1 +#define MCOUNTEREN_HPM_BIT_OFFSET 3 +#define MCOUNTEREN_HPM_BIT_WIDTH 29 +#define MCOUNTEREN_HPM_BIT_MASK 0xfffffff8 +#define MCOUNTEREN_HPM_ALL_SET_MASK 0x1fffffff + +/******************************************* + * scounteren - SRW - Counter Enable + */ +static inline uint_xlen_t csr_read_scounteren(void) { + uint_xlen_t value; + __asm__ volatile ("csrr %0, scounteren" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} +static inline void csr_write_scounteren(uint_xlen_t value) { + __asm__ volatile ("csrw scounteren, %0" + : /* output: none */ + : "r" (value) /* input : from register */ + : /* clobbers: none */); +} +static inline uint_xlen_t csr_read_write_scounteren(uint_xlen_t new_value) { + uint_xlen_t prev_value; + __asm__ volatile ("csrrw %0, scounteren, %1" + : "=r" (prev_value) /* output: register %0 */ + : "r" (new_value) /* input : register */ + : /* clobbers: none */); + return prev_value; +} + +/******************************************* + * mscratch - MRW - Machine Mode Scratch Register + */ +static inline uint_xlen_t csr_read_mscratch(void) { + uint_xlen_t value; + __asm__ volatile ("csrr %0, mscratch" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} +static inline void csr_write_mscratch(uint_xlen_t value) { + __asm__ volatile ("csrw mscratch, %0" + : /* output: none */ + : "r" (value) /* input : from register */ + : /* clobbers: none */); +} +static inline uint_xlen_t csr_read_write_mscratch(uint_xlen_t new_value) { + uint_xlen_t prev_value; + __asm__ volatile ("csrrw %0, mscratch, %1" + : "=r" (prev_value) /* output: register %0 */ + : "r" (new_value) /* input : register */ + : /* clobbers: none */); + return prev_value; +} + +/******************************************* + * mepc - MRW - Machine Exception Program Counter + */ +static inline uint_xlen_t csr_read_mepc(void) { + uint_xlen_t value; + __asm__ volatile ("csrr %0, mepc" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} +static inline void csr_write_mepc(uint_xlen_t value) { + __asm__ volatile ("csrw mepc, %0" + : /* output: none */ + : "r" (value) /* input : from register */ + : /* clobbers: none */); +} +static inline uint_xlen_t csr_read_write_mepc(uint_xlen_t new_value) { + uint_xlen_t prev_value; + __asm__ volatile ("csrrw %0, mepc, %1" + : "=r" (prev_value) /* output: register %0 */ + : "r" (new_value) /* input : register */ + : /* clobbers: none */); + return prev_value; +} + +/******************************************* + * mcause - MRW - Machine Exception Cause + */ +static inline uint_xlen_t csr_read_mcause(void) { + uint_xlen_t value; + __asm__ volatile ("csrr %0, mcause" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} +static inline void csr_write_mcause(uint_xlen_t value) { + __asm__ volatile ("csrw mcause, %0" + : /* output: none */ + : "r" (value) /* input : from register */ + : /* clobbers: none */); +} +static inline uint_xlen_t csr_read_write_mcause(uint_xlen_t new_value) { + uint_xlen_t prev_value; + __asm__ volatile ("csrrw %0, mcause, %1" + : "=r" (prev_value) /* output: register %0 */ + : "r" (new_value) /* input : register */ + : /* clobbers: none */); + return prev_value; +} +/* Register CSR bit set and clear instructions */ +static inline void csr_set_bits_mcause(uint_xlen_t mask) { + __asm__ volatile ("csrrs zero, mcause, %0" + : /* output: none */ + : "r" (mask) /* input : register */ + : /* clobbers: none */); +} +static inline void csr_clr_bits_mcause(uint_xlen_t mask) { + __asm__ volatile ("csrrc zero, mcause, %0" + : /* output: none */ + : "r" (mask) /* input : register */ + : /* clobbers: none */); +} +static inline uint_xlen_t csr_read_set_bits_mcause(uint_xlen_t mask) { + uint_xlen_t value; + __asm__ volatile ("csrrs %0, mcause, %1" + : "=r" (value) /* output: register %0 */ + : "r" (mask) /* input : register */ + : /* clobbers: none */); + return value; +} +static inline uint_xlen_t csr_read_clr_bits_mcause(uint_xlen_t mask) { + uint_xlen_t value; + __asm__ volatile ("csrrc %0, mcause, %1" + : "=r" (value) /* output: register %0 */ + : "r" (mask) /* input : register */ + : /* clobbers: none */); + return value; +} +/* mcause, CSR write value via immediate value (only up to 5 bits) */ +#define CSR_WRITE_IMM_MCAUSE(VALUE) \ + __asm__ volatile ("csrrwi zero, mcause, %0" \ + : /* output: none */ \ + : "i" (VALUE) /* input : immediate */ \ + : /* clobbers: none */) + +/* mcause, CSR set bits via immediate value mask (only up to 5 bits) */ +#define CSR_SET_BITS_IMM_MCAUSE(MASK) \ + __asm__ volatile ("csrrsi zero, mcause, %0" \ + : /* output: none */ \ + : "i" (MASK) /* input : immediate */ \ + : /* clobbers: none */) + +/* mcause, CSR clear bits via immediate value mask (only up to 5 bits) */ +#define CSR_CLR_BITS_IMM_MCAUSE(MASK) \ + __asm__ volatile ("csrrci zero, mcause, %0" \ + : /* output: none */ \ + : "i" (MASK) /* input : immediate */ \ + : /* clobbers: none */) +#define MCAUSE_INTERRUPT_BIT_OFFSET (__riscv_xlen-1) +#define MCAUSE_INTERRUPT_BIT_WIDTH 1 +#define MCAUSE_INTERRUPT_BIT_MASK (0x1UL << ((__riscv_xlen-1))) +#define MCAUSE_INTERRUPT_ALL_SET_MASK 0x1 +#define MCAUSE_EXCEPTION_CODE_BIT_OFFSET 0 +#define MCAUSE_EXCEPTION_CODE_BIT_WIDTH ((__riscv_xlen-2)-(0) + 1) +#define MCAUSE_EXCEPTION_CODE_BIT_MASK ((1UL<<(((__riscv_xlen-2)-(0) + 1)-1)) << (0)) +#define MCAUSE_EXCEPTION_CODE_ALL_SET_MASK ((1UL<<(((__riscv_xlen-2)-(0) + 1)-1)) << (0)) + +/******************************************* + * mtval - MRW - Machine Trap Value + */ +static inline uint_xlen_t csr_read_mtval(void) { + uint_xlen_t value; + __asm__ volatile ("csrr %0, mtval" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} +static inline void csr_write_mtval(uint_xlen_t value) { + __asm__ volatile ("csrw mtval, %0" + : /* output: none */ + : "r" (value) /* input : from register */ + : /* clobbers: none */); +} +static inline uint_xlen_t csr_read_write_mtval(uint_xlen_t new_value) { + uint_xlen_t prev_value; + __asm__ volatile ("csrrw %0, mtval, %1" + : "=r" (prev_value) /* output: register %0 */ + : "r" (new_value) /* input : register */ + : /* clobbers: none */); + return prev_value; +} + +/******************************************* + * sscratch - SRW - Supervisor Mode Scratch Register + */ +static inline uint_xlen_t csr_read_sscratch(void) { + uint_xlen_t value; + __asm__ volatile ("csrr %0, sscratch" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} +static inline void csr_write_sscratch(uint_xlen_t value) { + __asm__ volatile ("csrw sscratch, %0" + : /* output: none */ + : "r" (value) /* input : from register */ + : /* clobbers: none */); +} +static inline uint_xlen_t csr_read_write_sscratch(uint_xlen_t new_value) { + uint_xlen_t prev_value; + __asm__ volatile ("csrrw %0, sscratch, %1" + : "=r" (prev_value) /* output: register %0 */ + : "r" (new_value) /* input : register */ + : /* clobbers: none */); + return prev_value; +} + +/******************************************* + * sepc - SRW - Supervisor Exception Program Counter + */ +static inline uint_xlen_t csr_read_sepc(void) { + uint_xlen_t value; + __asm__ volatile ("csrr %0, sepc" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} +static inline void csr_write_sepc(uint_xlen_t value) { + __asm__ volatile ("csrw sepc, %0" + : /* output: none */ + : "r" (value) /* input : from register */ + : /* clobbers: none */); +} +static inline uint_xlen_t csr_read_write_sepc(uint_xlen_t new_value) { + uint_xlen_t prev_value; + __asm__ volatile ("csrrw %0, sepc, %1" + : "=r" (prev_value) /* output: register %0 */ + : "r" (new_value) /* input : register */ + : /* clobbers: none */); + return prev_value; +} + +/******************************************* + * scause - SRW - Supervisor Exception Cause + */ +static inline uint_xlen_t csr_read_scause(void) { + uint_xlen_t value; + __asm__ volatile ("csrr %0, scause" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} +static inline void csr_write_scause(uint_xlen_t value) { + __asm__ volatile ("csrw scause, %0" + : /* output: none */ + : "r" (value) /* input : from register */ + : /* clobbers: none */); +} +static inline uint_xlen_t csr_read_write_scause(uint_xlen_t new_value) { + uint_xlen_t prev_value; + __asm__ volatile ("csrrw %0, scause, %1" + : "=r" (prev_value) /* output: register %0 */ + : "r" (new_value) /* input : register */ + : /* clobbers: none */); + return prev_value; +} +/* Register CSR bit set and clear instructions */ +static inline void csr_set_bits_scause(uint_xlen_t mask) { + __asm__ volatile ("csrrs zero, scause, %0" + : /* output: none */ + : "r" (mask) /* input : register */ + : /* clobbers: none */); +} +static inline void csr_clr_bits_scause(uint_xlen_t mask) { + __asm__ volatile ("csrrc zero, scause, %0" + : /* output: none */ + : "r" (mask) /* input : register */ + : /* clobbers: none */); +} +static inline uint_xlen_t csr_read_set_bits_scause(uint_xlen_t mask) { + uint_xlen_t value; + __asm__ volatile ("csrrs %0, scause, %1" + : "=r" (value) /* output: register %0 */ + : "r" (mask) /* input : register */ + : /* clobbers: none */); + return value; +} +static inline uint_xlen_t csr_read_clr_bits_scause(uint_xlen_t mask) { + uint_xlen_t value; + __asm__ volatile ("csrrc %0, scause, %1" + : "=r" (value) /* output: register %0 */ + : "r" (mask) /* input : register */ + : /* clobbers: none */); + return value; +} +/* scause, CSR write value via immediate value (only up to 5 bits) */ +#define CSR_WRITE_IMM_SCAUSE(VALUE) \ + __asm__ volatile ("csrrwi zero, scause, %0" \ + : /* output: none */ \ + : "i" (VALUE) /* input : immediate */ \ + : /* clobbers: none */) + +/* scause, CSR set bits via immediate value mask (only up to 5 bits) */ +#define CSR_SET_BITS_IMM_SCAUSE(MASK) \ + __asm__ volatile ("csrrsi zero, scause, %0" \ + : /* output: none */ \ + : "i" (MASK) /* input : immediate */ \ + : /* clobbers: none */) + +/* scause, CSR clear bits via immediate value mask (only up to 5 bits) */ +#define CSR_CLR_BITS_IMM_SCAUSE(MASK) \ + __asm__ volatile ("csrrci zero, scause, %0" \ + : /* output: none */ \ + : "i" (MASK) /* input : immediate */ \ + : /* clobbers: none */) +#define SCAUSE_INTERRUPT_BIT_OFFSET (__riscv_xlen-1) +#define SCAUSE_INTERRUPT_BIT_WIDTH 1 +#define SCAUSE_INTERRUPT_BIT_MASK (0x1UL << ((__riscv_xlen-1))) +#define SCAUSE_INTERRUPT_ALL_SET_MASK 0x1 +#define SCAUSE_EXCEPTION_CODE_BIT_OFFSET 0 +#define SCAUSE_EXCEPTION_CODE_BIT_WIDTH ((__riscv_xlen-2)-(0) + 1) +#define SCAUSE_EXCEPTION_CODE_BIT_MASK ((1UL<<(((__riscv_xlen-2)-(0) + 1)-1)) << (0)) +#define SCAUSE_EXCEPTION_CODE_ALL_SET_MASK ((1UL<<(((__riscv_xlen-2)-(0) + 1)-1)) << (0)) + +/******************************************* + * sstatus - SRW - Supervisor Status + */ +static inline uint_xlen_t csr_read_sstatus(void) { + uint_xlen_t value; + __asm__ volatile ("csrr %0, sstatus" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} +static inline void csr_write_sstatus(uint_xlen_t value) { + __asm__ volatile ("csrw sstatus, %0" + : /* output: none */ + : "r" (value) /* input : from register */ + : /* clobbers: none */); +} +static inline uint_xlen_t csr_read_write_sstatus(uint_xlen_t new_value) { + uint_xlen_t prev_value; + __asm__ volatile ("csrrw %0, sstatus, %1" + : "=r" (prev_value) /* output: register %0 */ + : "r" (new_value) /* input : register */ + : /* clobbers: none */); + return prev_value; +} +/* Register CSR bit set and clear instructions */ +static inline void csr_set_bits_sstatus(uint_xlen_t mask) { + __asm__ volatile ("csrrs zero, sstatus, %0" + : /* output: none */ + : "r" (mask) /* input : register */ + : /* clobbers: none */); +} +static inline void csr_clr_bits_sstatus(uint_xlen_t mask) { + __asm__ volatile ("csrrc zero, sstatus, %0" + : /* output: none */ + : "r" (mask) /* input : register */ + : /* clobbers: none */); +} +static inline uint_xlen_t csr_read_set_bits_sstatus(uint_xlen_t mask) { + uint_xlen_t value; + __asm__ volatile ("csrrs %0, sstatus, %1" + : "=r" (value) /* output: register %0 */ + : "r" (mask) /* input : register */ + : /* clobbers: none */); + return value; +} +static inline uint_xlen_t csr_read_clr_bits_sstatus(uint_xlen_t mask) { + uint_xlen_t value; + __asm__ volatile ("csrrc %0, sstatus, %1" + : "=r" (value) /* output: register %0 */ + : "r" (mask) /* input : register */ + : /* clobbers: none */); + return value; +} +/* sstatus, CSR write value via immediate value (only up to 5 bits) */ +#define CSR_WRITE_IMM_SSTATUS(VALUE) \ + __asm__ volatile ("csrrwi zero, sstatus, %0" \ + : /* output: none */ \ + : "i" (VALUE) /* input : immediate */ \ + : /* clobbers: none */) + +/* sstatus, CSR set bits via immediate value mask (only up to 5 bits) */ +#define CSR_SET_BITS_IMM_SSTATUS(MASK) \ + __asm__ volatile ("csrrsi zero, sstatus, %0" \ + : /* output: none */ \ + : "i" (MASK) /* input : immediate */ \ + : /* clobbers: none */) + +/* sstatus, CSR clear bits via immediate value mask (only up to 5 bits) */ +#define CSR_CLR_BITS_IMM_SSTATUS(MASK) \ + __asm__ volatile ("csrrci zero, sstatus, %0" \ + : /* output: none */ \ + : "i" (MASK) /* input : immediate */ \ + : /* clobbers: none */) +#define SSTATUS_SIE_BIT_OFFSET 2 +#define SSTATUS_SIE_BIT_WIDTH 1 +#define SSTATUS_SIE_BIT_MASK 0x4 +#define SSTATUS_SIE_ALL_SET_MASK 0x1 +#define SSTATUS_SPIE_BIT_OFFSET 5 +#define SSTATUS_SPIE_BIT_WIDTH 1 +#define SSTATUS_SPIE_BIT_MASK 0x20 +#define SSTATUS_SPIE_ALL_SET_MASK 0x1 +#define SSTATUS_SPP_BIT_OFFSET 8 +#define SSTATUS_SPP_BIT_WIDTH 1 +#define SSTATUS_SPP_BIT_MASK 0x100 +#define SSTATUS_SPP_ALL_SET_MASK 0x1 + +/******************************************* + * stvec - SRW - Supervisor Trap Vector Base Address + */ +static inline uint_xlen_t csr_read_stvec(void) { + uint_xlen_t value; + __asm__ volatile ("csrr %0, stvec" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} +static inline void csr_write_stvec(uint_xlen_t value) { + __asm__ volatile ("csrw stvec, %0" + : /* output: none */ + : "r" (value) /* input : from register */ + : /* clobbers: none */); +} +static inline uint_xlen_t csr_read_write_stvec(uint_xlen_t new_value) { + uint_xlen_t prev_value; + __asm__ volatile ("csrrw %0, stvec, %1" + : "=r" (prev_value) /* output: register %0 */ + : "r" (new_value) /* input : register */ + : /* clobbers: none */); + return prev_value; +} +/* Register CSR bit set and clear instructions */ +static inline void csr_set_bits_stvec(uint_xlen_t mask) { + __asm__ volatile ("csrrs zero, stvec, %0" + : /* output: none */ + : "r" (mask) /* input : register */ + : /* clobbers: none */); +} +static inline void csr_clr_bits_stvec(uint_xlen_t mask) { + __asm__ volatile ("csrrc zero, stvec, %0" + : /* output: none */ + : "r" (mask) /* input : register */ + : /* clobbers: none */); +} +static inline uint_xlen_t csr_read_set_bits_stvec(uint_xlen_t mask) { + uint_xlen_t value; + __asm__ volatile ("csrrs %0, stvec, %1" + : "=r" (value) /* output: register %0 */ + : "r" (mask) /* input : register */ + : /* clobbers: none */); + return value; +} +static inline uint_xlen_t csr_read_clr_bits_stvec(uint_xlen_t mask) { + uint_xlen_t value; + __asm__ volatile ("csrrc %0, stvec, %1" + : "=r" (value) /* output: register %0 */ + : "r" (mask) /* input : register */ + : /* clobbers: none */); + return value; +} +/* stvec, CSR write value via immediate value (only up to 5 bits) */ +#define CSR_WRITE_IMM_STVEC(VALUE) \ + __asm__ volatile ("csrrwi zero, stvec, %0" \ + : /* output: none */ \ + : "i" (VALUE) /* input : immediate */ \ + : /* clobbers: none */) + +/* stvec, CSR set bits via immediate value mask (only up to 5 bits) */ +#define CSR_SET_BITS_IMM_STVEC(MASK) \ + __asm__ volatile ("csrrsi zero, stvec, %0" \ + : /* output: none */ \ + : "i" (MASK) /* input : immediate */ \ + : /* clobbers: none */) + +/* stvec, CSR clear bits via immediate value mask (only up to 5 bits) */ +#define CSR_CLR_BITS_IMM_STVEC(MASK) \ + __asm__ volatile ("csrrci zero, stvec, %0" \ + : /* output: none */ \ + : "i" (MASK) /* input : immediate */ \ + : /* clobbers: none */) +#define STVEC_BASE_BIT_OFFSET 2 +#define STVEC_BASE_BIT_WIDTH ((__riscv_xlen-1)-(2) + 1) +#define STVEC_BASE_BIT_MASK ((1UL<<(((__riscv_xlen-1)-(2) + 1)-1)) << (2)) +#define STVEC_BASE_ALL_SET_MASK ((1UL<<(((__riscv_xlen-1)-(2) + 1)-1)) << (0)) +#define STVEC_MODE_BIT_OFFSET 0 +#define STVEC_MODE_BIT_WIDTH 2 +#define STVEC_MODE_BIT_MASK 0x3 +#define STVEC_MODE_ALL_SET_MASK 0x3 + +/******************************************* + * sideleg - SRW - Supervisor Interrupt Delegation + */ +static inline uint_xlen_t csr_read_sideleg(void) { + uint_xlen_t value; + __asm__ volatile ("csrr %0, sideleg" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} +static inline void csr_write_sideleg(uint_xlen_t value) { + __asm__ volatile ("csrw sideleg, %0" + : /* output: none */ + : "r" (value) /* input : from register */ + : /* clobbers: none */); +} +static inline uint_xlen_t csr_read_write_sideleg(uint_xlen_t new_value) { + uint_xlen_t prev_value; + __asm__ volatile ("csrrw %0, sideleg, %1" + : "=r" (prev_value) /* output: register %0 */ + : "r" (new_value) /* input : register */ + : /* clobbers: none */); + return prev_value; +} + +/******************************************* + * sedeleg - SRW - Supervisor Exception Delegation + */ +static inline uint_xlen_t csr_read_sedeleg(void) { + uint_xlen_t value; + __asm__ volatile ("csrr %0, sedeleg" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} +static inline void csr_write_sedeleg(uint_xlen_t value) { + __asm__ volatile ("csrw sedeleg, %0" + : /* output: none */ + : "r" (value) /* input : from register */ + : /* clobbers: none */); +} +static inline uint_xlen_t csr_read_write_sedeleg(uint_xlen_t new_value) { + uint_xlen_t prev_value; + __asm__ volatile ("csrrw %0, sedeleg, %1" + : "=r" (prev_value) /* output: register %0 */ + : "r" (new_value) /* input : register */ + : /* clobbers: none */); + return prev_value; +} + +/******************************************* + * sip - SRW - Supervisor Interrupt Pending + */ +static inline uint_xlen_t csr_read_sip(void) { + uint_xlen_t value; + __asm__ volatile ("csrr %0, sip" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} +static inline void csr_write_sip(uint_xlen_t value) { + __asm__ volatile ("csrw sip, %0" + : /* output: none */ + : "r" (value) /* input : from register */ + : /* clobbers: none */); +} +static inline uint_xlen_t csr_read_write_sip(uint_xlen_t new_value) { + uint_xlen_t prev_value; + __asm__ volatile ("csrrw %0, sip, %1" + : "=r" (prev_value) /* output: register %0 */ + : "r" (new_value) /* input : register */ + : /* clobbers: none */); + return prev_value; +} +/* Register CSR bit set and clear instructions */ +static inline void csr_set_bits_sip(uint_xlen_t mask) { + __asm__ volatile ("csrrs zero, sip, %0" + : /* output: none */ + : "r" (mask) /* input : register */ + : /* clobbers: none */); +} +static inline void csr_clr_bits_sip(uint_xlen_t mask) { + __asm__ volatile ("csrrc zero, sip, %0" + : /* output: none */ + : "r" (mask) /* input : register */ + : /* clobbers: none */); +} +static inline uint_xlen_t csr_read_set_bits_sip(uint_xlen_t mask) { + uint_xlen_t value; + __asm__ volatile ("csrrs %0, sip, %1" + : "=r" (value) /* output: register %0 */ + : "r" (mask) /* input : register */ + : /* clobbers: none */); + return value; +} +static inline uint_xlen_t csr_read_clr_bits_sip(uint_xlen_t mask) { + uint_xlen_t value; + __asm__ volatile ("csrrc %0, sip, %1" + : "=r" (value) /* output: register %0 */ + : "r" (mask) /* input : register */ + : /* clobbers: none */); + return value; +} +/* sip, CSR write value via immediate value (only up to 5 bits) */ +#define CSR_WRITE_IMM_SIP(VALUE) \ + __asm__ volatile ("csrrwi zero, sip, %0" \ + : /* output: none */ \ + : "i" (VALUE) /* input : immediate */ \ + : /* clobbers: none */) + +/* sip, CSR set bits via immediate value mask (only up to 5 bits) */ +#define CSR_SET_BITS_IMM_SIP(MASK) \ + __asm__ volatile ("csrrsi zero, sip, %0" \ + : /* output: none */ \ + : "i" (MASK) /* input : immediate */ \ + : /* clobbers: none */) + +/* sip, CSR clear bits via immediate value mask (only up to 5 bits) */ +#define CSR_CLR_BITS_IMM_SIP(MASK) \ + __asm__ volatile ("csrrci zero, sip, %0" \ + : /* output: none */ \ + : "i" (MASK) /* input : immediate */ \ + : /* clobbers: none */) +#define SIP_SSI_BIT_OFFSET 1 +#define SIP_SSI_BIT_WIDTH 1 +#define SIP_SSI_BIT_MASK 0x2 +#define SIP_SSI_ALL_SET_MASK 0x1 +#define SIP_STI_BIT_OFFSET 5 +#define SIP_STI_BIT_WIDTH 1 +#define SIP_STI_BIT_MASK 0x20 +#define SIP_STI_ALL_SET_MASK 0x1 +#define SIP_SEI_BIT_OFFSET 9 +#define SIP_SEI_BIT_WIDTH 1 +#define SIP_SEI_BIT_MASK 0x200 +#define SIP_SEI_ALL_SET_MASK 0x1 +#define SIP_USI_BIT_OFFSET 0 +#define SIP_USI_BIT_WIDTH 1 +#define SIP_USI_BIT_MASK 0x1 +#define SIP_USI_ALL_SET_MASK 0x1 +#define SIP_UTI_BIT_OFFSET 4 +#define SIP_UTI_BIT_WIDTH 1 +#define SIP_UTI_BIT_MASK 0x10 +#define SIP_UTI_ALL_SET_MASK 0x1 +#define SIP_UEI_BIT_OFFSET 8 +#define SIP_UEI_BIT_WIDTH 1 +#define SIP_UEI_BIT_MASK 0x100 +#define SIP_UEI_ALL_SET_MASK 0x1 + +/******************************************* + * sie - SRW - Supervisor Interrupt Enable + */ +static inline uint_xlen_t csr_read_sie(void) { + uint_xlen_t value; + __asm__ volatile ("csrr %0, sie" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} +static inline void csr_write_sie(uint_xlen_t value) { + __asm__ volatile ("csrw sie, %0" + : /* output: none */ + : "r" (value) /* input : from register */ + : /* clobbers: none */); +} +static inline uint_xlen_t csr_read_write_sie(uint_xlen_t new_value) { + uint_xlen_t prev_value; + __asm__ volatile ("csrrw %0, sie, %1" + : "=r" (prev_value) /* output: register %0 */ + : "r" (new_value) /* input : register */ + : /* clobbers: none */); + return prev_value; +} +/* Register CSR bit set and clear instructions */ +static inline void csr_set_bits_sie(uint_xlen_t mask) { + __asm__ volatile ("csrrs zero, sie, %0" + : /* output: none */ + : "r" (mask) /* input : register */ + : /* clobbers: none */); +} +static inline void csr_clr_bits_sie(uint_xlen_t mask) { + __asm__ volatile ("csrrc zero, sie, %0" + : /* output: none */ + : "r" (mask) /* input : register */ + : /* clobbers: none */); +} +static inline uint_xlen_t csr_read_set_bits_sie(uint_xlen_t mask) { + uint_xlen_t value; + __asm__ volatile ("csrrs %0, sie, %1" + : "=r" (value) /* output: register %0 */ + : "r" (mask) /* input : register */ + : /* clobbers: none */); + return value; +} +static inline uint_xlen_t csr_read_clr_bits_sie(uint_xlen_t mask) { + uint_xlen_t value; + __asm__ volatile ("csrrc %0, sie, %1" + : "=r" (value) /* output: register %0 */ + : "r" (mask) /* input : register */ + : /* clobbers: none */); + return value; +} +/* sie, CSR write value via immediate value (only up to 5 bits) */ +#define CSR_WRITE_IMM_SIE(VALUE) \ + __asm__ volatile ("csrrwi zero, sie, %0" \ + : /* output: none */ \ + : "i" (VALUE) /* input : immediate */ \ + : /* clobbers: none */) + +/* sie, CSR set bits via immediate value mask (only up to 5 bits) */ +#define CSR_SET_BITS_IMM_SIE(MASK) \ + __asm__ volatile ("csrrsi zero, sie, %0" \ + : /* output: none */ \ + : "i" (MASK) /* input : immediate */ \ + : /* clobbers: none */) + +/* sie, CSR clear bits via immediate value mask (only up to 5 bits) */ +#define CSR_CLR_BITS_IMM_SIE(MASK) \ + __asm__ volatile ("csrrci zero, sie, %0" \ + : /* output: none */ \ + : "i" (MASK) /* input : immediate */ \ + : /* clobbers: none */) +#define SIE_SSI_BIT_OFFSET 1 +#define SIE_SSI_BIT_WIDTH 1 +#define SIE_SSI_BIT_MASK 0x2 +#define SIE_SSI_ALL_SET_MASK 0x1 +#define SIE_STI_BIT_OFFSET 5 +#define SIE_STI_BIT_WIDTH 1 +#define SIE_STI_BIT_MASK 0x20 +#define SIE_STI_ALL_SET_MASK 0x1 +#define SIE_SEI_BIT_OFFSET 9 +#define SIE_SEI_BIT_WIDTH 1 +#define SIE_SEI_BIT_MASK 0x200 +#define SIE_SEI_ALL_SET_MASK 0x1 +#define SIE_USI_BIT_OFFSET 0 +#define SIE_USI_BIT_WIDTH 1 +#define SIE_USI_BIT_MASK 0x1 +#define SIE_USI_ALL_SET_MASK 0x1 +#define SIE_UTI_BIT_OFFSET 4 +#define SIE_UTI_BIT_WIDTH 1 +#define SIE_UTI_BIT_MASK 0x10 +#define SIE_UTI_ALL_SET_MASK 0x1 +#define SIE_UEI_BIT_OFFSET 8 +#define SIE_UEI_BIT_WIDTH 1 +#define SIE_UEI_BIT_MASK 0x100 +#define SIE_UEI_ALL_SET_MASK 0x1 + +/******************************************* + * ustatus - URW - User mode restricted view of mstatus + */ +static inline uint_xlen_t csr_read_ustatus(void) { + uint_xlen_t value; + __asm__ volatile ("csrr %0, ustatus" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} +static inline void csr_write_ustatus(uint_xlen_t value) { + __asm__ volatile ("csrw ustatus, %0" + : /* output: none */ + : "r" (value) /* input : from register */ + : /* clobbers: none */); +} +static inline uint_xlen_t csr_read_write_ustatus(uint_xlen_t new_value) { + uint_xlen_t prev_value; + __asm__ volatile ("csrrw %0, ustatus, %1" + : "=r" (prev_value) /* output: register %0 */ + : "r" (new_value) /* input : register */ + : /* clobbers: none */); + return prev_value; +} +/* Register CSR bit set and clear instructions */ +static inline void csr_set_bits_ustatus(uint_xlen_t mask) { + __asm__ volatile ("csrrs zero, ustatus, %0" + : /* output: none */ + : "r" (mask) /* input : register */ + : /* clobbers: none */); +} +static inline void csr_clr_bits_ustatus(uint_xlen_t mask) { + __asm__ volatile ("csrrc zero, ustatus, %0" + : /* output: none */ + : "r" (mask) /* input : register */ + : /* clobbers: none */); +} +static inline uint_xlen_t csr_read_set_bits_ustatus(uint_xlen_t mask) { + uint_xlen_t value; + __asm__ volatile ("csrrs %0, ustatus, %1" + : "=r" (value) /* output: register %0 */ + : "r" (mask) /* input : register */ + : /* clobbers: none */); + return value; +} +static inline uint_xlen_t csr_read_clr_bits_ustatus(uint_xlen_t mask) { + uint_xlen_t value; + __asm__ volatile ("csrrc %0, ustatus, %1" + : "=r" (value) /* output: register %0 */ + : "r" (mask) /* input : register */ + : /* clobbers: none */); + return value; +} +/* ustatus, CSR write value via immediate value (only up to 5 bits) */ +#define CSR_WRITE_IMM_USTATUS(VALUE) \ + __asm__ volatile ("csrrwi zero, ustatus, %0" \ + : /* output: none */ \ + : "i" (VALUE) /* input : immediate */ \ + : /* clobbers: none */) + +/* ustatus, CSR set bits via immediate value mask (only up to 5 bits) */ +#define CSR_SET_BITS_IMM_USTATUS(MASK) \ + __asm__ volatile ("csrrsi zero, ustatus, %0" \ + : /* output: none */ \ + : "i" (MASK) /* input : immediate */ \ + : /* clobbers: none */) + +/* ustatus, CSR clear bits via immediate value mask (only up to 5 bits) */ +#define CSR_CLR_BITS_IMM_USTATUS(MASK) \ + __asm__ volatile ("csrrci zero, ustatus, %0" \ + : /* output: none */ \ + : "i" (MASK) /* input : immediate */ \ + : /* clobbers: none */) +#define USTATUS_UIE_BIT_OFFSET 1 +#define USTATUS_UIE_BIT_WIDTH 1 +#define USTATUS_UIE_BIT_MASK 0x2 +#define USTATUS_UIE_ALL_SET_MASK 0x1 +#define USTATUS_UPIE_BIT_OFFSET 3 +#define USTATUS_UPIE_BIT_WIDTH 1 +#define USTATUS_UPIE_BIT_MASK 0x8 +#define USTATUS_UPIE_ALL_SET_MASK 0x1 + +/******************************************* + * uip - URW - User Interrupt Pending + */ +static inline uint_xlen_t csr_read_uip(void) { + uint_xlen_t value; + __asm__ volatile ("csrr %0, uip" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} +static inline void csr_write_uip(uint_xlen_t value) { + __asm__ volatile ("csrw uip, %0" + : /* output: none */ + : "r" (value) /* input : from register */ + : /* clobbers: none */); +} +static inline uint_xlen_t csr_read_write_uip(uint_xlen_t new_value) { + uint_xlen_t prev_value; + __asm__ volatile ("csrrw %0, uip, %1" + : "=r" (prev_value) /* output: register %0 */ + : "r" (new_value) /* input : register */ + : /* clobbers: none */); + return prev_value; +} +/* Register CSR bit set and clear instructions */ +static inline void csr_set_bits_uip(uint_xlen_t mask) { + __asm__ volatile ("csrrs zero, uip, %0" + : /* output: none */ + : "r" (mask) /* input : register */ + : /* clobbers: none */); +} +static inline void csr_clr_bits_uip(uint_xlen_t mask) { + __asm__ volatile ("csrrc zero, uip, %0" + : /* output: none */ + : "r" (mask) /* input : register */ + : /* clobbers: none */); +} +static inline uint_xlen_t csr_read_set_bits_uip(uint_xlen_t mask) { + uint_xlen_t value; + __asm__ volatile ("csrrs %0, uip, %1" + : "=r" (value) /* output: register %0 */ + : "r" (mask) /* input : register */ + : /* clobbers: none */); + return value; +} +static inline uint_xlen_t csr_read_clr_bits_uip(uint_xlen_t mask) { + uint_xlen_t value; + __asm__ volatile ("csrrc %0, uip, %1" + : "=r" (value) /* output: register %0 */ + : "r" (mask) /* input : register */ + : /* clobbers: none */); + return value; +} +/* uip, CSR write value via immediate value (only up to 5 bits) */ +#define CSR_WRITE_IMM_UIP(VALUE) \ + __asm__ volatile ("csrrwi zero, uip, %0" \ + : /* output: none */ \ + : "i" (VALUE) /* input : immediate */ \ + : /* clobbers: none */) + +/* uip, CSR set bits via immediate value mask (only up to 5 bits) */ +#define CSR_SET_BITS_IMM_UIP(MASK) \ + __asm__ volatile ("csrrsi zero, uip, %0" \ + : /* output: none */ \ + : "i" (MASK) /* input : immediate */ \ + : /* clobbers: none */) + +/* uip, CSR clear bits via immediate value mask (only up to 5 bits) */ +#define CSR_CLR_BITS_IMM_UIP(MASK) \ + __asm__ volatile ("csrrci zero, uip, %0" \ + : /* output: none */ \ + : "i" (MASK) /* input : immediate */ \ + : /* clobbers: none */) +#define UIP_USI_BIT_OFFSET 0 +#define UIP_USI_BIT_WIDTH 1 +#define UIP_USI_BIT_MASK 0x1 +#define UIP_USI_ALL_SET_MASK 0x1 +#define UIP_UTI_BIT_OFFSET 4 +#define UIP_UTI_BIT_WIDTH 1 +#define UIP_UTI_BIT_MASK 0x10 +#define UIP_UTI_ALL_SET_MASK 0x1 +#define UIP_UEI_BIT_OFFSET 8 +#define UIP_UEI_BIT_WIDTH 1 +#define UIP_UEI_BIT_MASK 0x100 +#define UIP_UEI_ALL_SET_MASK 0x1 + +/******************************************* + * uie - URW - User Interrupt Enable + */ +static inline uint_xlen_t csr_read_uie(void) { + uint_xlen_t value; + __asm__ volatile ("csrr %0, uie" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} +static inline void csr_write_uie(uint_xlen_t value) { + __asm__ volatile ("csrw uie, %0" + : /* output: none */ + : "r" (value) /* input : from register */ + : /* clobbers: none */); +} +static inline uint_xlen_t csr_read_write_uie(uint_xlen_t new_value) { + uint_xlen_t prev_value; + __asm__ volatile ("csrrw %0, uie, %1" + : "=r" (prev_value) /* output: register %0 */ + : "r" (new_value) /* input : register */ + : /* clobbers: none */); + return prev_value; +} +/* Register CSR bit set and clear instructions */ +static inline void csr_set_bits_uie(uint_xlen_t mask) { + __asm__ volatile ("csrrs zero, uie, %0" + : /* output: none */ + : "r" (mask) /* input : register */ + : /* clobbers: none */); +} +static inline void csr_clr_bits_uie(uint_xlen_t mask) { + __asm__ volatile ("csrrc zero, uie, %0" + : /* output: none */ + : "r" (mask) /* input : register */ + : /* clobbers: none */); +} +static inline uint_xlen_t csr_read_set_bits_uie(uint_xlen_t mask) { + uint_xlen_t value; + __asm__ volatile ("csrrs %0, uie, %1" + : "=r" (value) /* output: register %0 */ + : "r" (mask) /* input : register */ + : /* clobbers: none */); + return value; +} +static inline uint_xlen_t csr_read_clr_bits_uie(uint_xlen_t mask) { + uint_xlen_t value; + __asm__ volatile ("csrrc %0, uie, %1" + : "=r" (value) /* output: register %0 */ + : "r" (mask) /* input : register */ + : /* clobbers: none */); + return value; +} +/* uie, CSR write value via immediate value (only up to 5 bits) */ +#define CSR_WRITE_IMM_UIE(VALUE) \ + __asm__ volatile ("csrrwi zero, uie, %0" \ + : /* output: none */ \ + : "i" (VALUE) /* input : immediate */ \ + : /* clobbers: none */) + +/* uie, CSR set bits via immediate value mask (only up to 5 bits) */ +#define CSR_SET_BITS_IMM_UIE(MASK) \ + __asm__ volatile ("csrrsi zero, uie, %0" \ + : /* output: none */ \ + : "i" (MASK) /* input : immediate */ \ + : /* clobbers: none */) + +/* uie, CSR clear bits via immediate value mask (only up to 5 bits) */ +#define CSR_CLR_BITS_IMM_UIE(MASK) \ + __asm__ volatile ("csrrci zero, uie, %0" \ + : /* output: none */ \ + : "i" (MASK) /* input : immediate */ \ + : /* clobbers: none */) +#define UIE_USI_BIT_OFFSET 0 +#define UIE_USI_BIT_WIDTH 1 +#define UIE_USI_BIT_MASK 0x1 +#define UIE_USI_ALL_SET_MASK 0x1 +#define UIE_UTI_BIT_OFFSET 4 +#define UIE_UTI_BIT_WIDTH 1 +#define UIE_UTI_BIT_MASK 0x10 +#define UIE_UTI_ALL_SET_MASK 0x1 +#define UIE_UEI_BIT_OFFSET 8 +#define UIE_UEI_BIT_WIDTH 1 +#define UIE_UEI_BIT_MASK 0x100 +#define UIE_UEI_ALL_SET_MASK 0x1 + +/******************************************* + * uscratch - URW - User Mode Scratch Register + */ +static inline uint_xlen_t csr_read_uscratch(void) { + uint_xlen_t value; + __asm__ volatile ("csrr %0, uscratch" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} +static inline void csr_write_uscratch(uint_xlen_t value) { + __asm__ volatile ("csrw uscratch, %0" + : /* output: none */ + : "r" (value) /* input : from register */ + : /* clobbers: none */); +} +static inline uint_xlen_t csr_read_write_uscratch(uint_xlen_t new_value) { + uint_xlen_t prev_value; + __asm__ volatile ("csrrw %0, uscratch, %1" + : "=r" (prev_value) /* output: register %0 */ + : "r" (new_value) /* input : register */ + : /* clobbers: none */); + return prev_value; +} + +/******************************************* + * uepc - URW - User Exception Program Counter + */ +static inline uint_xlen_t csr_read_uepc(void) { + uint_xlen_t value; + __asm__ volatile ("csrr %0, uepc" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} +static inline void csr_write_uepc(uint_xlen_t value) { + __asm__ volatile ("csrw uepc, %0" + : /* output: none */ + : "r" (value) /* input : from register */ + : /* clobbers: none */); +} +static inline uint_xlen_t csr_read_write_uepc(uint_xlen_t new_value) { + uint_xlen_t prev_value; + __asm__ volatile ("csrrw %0, uepc, %1" + : "=r" (prev_value) /* output: register %0 */ + : "r" (new_value) /* input : register */ + : /* clobbers: none */); + return prev_value; +} + +/******************************************* + * ucause - URW - User Exception Cause + */ +static inline uint_xlen_t csr_read_ucause(void) { + uint_xlen_t value; + __asm__ volatile ("csrr %0, ucause" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} +static inline void csr_write_ucause(uint_xlen_t value) { + __asm__ volatile ("csrw ucause, %0" + : /* output: none */ + : "r" (value) /* input : from register */ + : /* clobbers: none */); +} +static inline uint_xlen_t csr_read_write_ucause(uint_xlen_t new_value) { + uint_xlen_t prev_value; + __asm__ volatile ("csrrw %0, ucause, %1" + : "=r" (prev_value) /* output: register %0 */ + : "r" (new_value) /* input : register */ + : /* clobbers: none */); + return prev_value; +} +/* Register CSR bit set and clear instructions */ +static inline void csr_set_bits_ucause(uint_xlen_t mask) { + __asm__ volatile ("csrrs zero, ucause, %0" + : /* output: none */ + : "r" (mask) /* input : register */ + : /* clobbers: none */); +} +static inline void csr_clr_bits_ucause(uint_xlen_t mask) { + __asm__ volatile ("csrrc zero, ucause, %0" + : /* output: none */ + : "r" (mask) /* input : register */ + : /* clobbers: none */); +} +static inline uint_xlen_t csr_read_set_bits_ucause(uint_xlen_t mask) { + uint_xlen_t value; + __asm__ volatile ("csrrs %0, ucause, %1" + : "=r" (value) /* output: register %0 */ + : "r" (mask) /* input : register */ + : /* clobbers: none */); + return value; +} +static inline uint_xlen_t csr_read_clr_bits_ucause(uint_xlen_t mask) { + uint_xlen_t value; + __asm__ volatile ("csrrc %0, ucause, %1" + : "=r" (value) /* output: register %0 */ + : "r" (mask) /* input : register */ + : /* clobbers: none */); + return value; +} +/* ucause, CSR write value via immediate value (only up to 5 bits) */ +#define CSR_WRITE_IMM_UCAUSE(VALUE) \ + __asm__ volatile ("csrrwi zero, ucause, %0" \ + : /* output: none */ \ + : "i" (VALUE) /* input : immediate */ \ + : /* clobbers: none */) + +/* ucause, CSR set bits via immediate value mask (only up to 5 bits) */ +#define CSR_SET_BITS_IMM_UCAUSE(MASK) \ + __asm__ volatile ("csrrsi zero, ucause, %0" \ + : /* output: none */ \ + : "i" (MASK) /* input : immediate */ \ + : /* clobbers: none */) + +/* ucause, CSR clear bits via immediate value mask (only up to 5 bits) */ +#define CSR_CLR_BITS_IMM_UCAUSE(MASK) \ + __asm__ volatile ("csrrci zero, ucause, %0" \ + : /* output: none */ \ + : "i" (MASK) /* input : immediate */ \ + : /* clobbers: none */) +#define UCAUSE_INTERRUPT_BIT_OFFSET (__riscv_xlen-1) +#define UCAUSE_INTERRUPT_BIT_WIDTH 1 +#define UCAUSE_INTERRUPT_BIT_MASK (0x1UL << ((__riscv_xlen-1))) +#define UCAUSE_INTERRUPT_ALL_SET_MASK 0x1 +#define UCAUSE_EXCEPTION_CODE_BIT_OFFSET 0 +#define UCAUSE_EXCEPTION_CODE_BIT_WIDTH ((__riscv_xlen-2)-(0) + 1) +#define UCAUSE_EXCEPTION_CODE_BIT_MASK ((1UL<<(((__riscv_xlen-2)-(0) + 1)-1)) << (0)) +#define UCAUSE_EXCEPTION_CODE_ALL_SET_MASK ((1UL<<(((__riscv_xlen-2)-(0) + 1)-1)) << (0)) + +/******************************************* + * utvec - URW - User Trap Vector Base Address + */ +static inline uint_xlen_t csr_read_utvec(void) { + uint_xlen_t value; + __asm__ volatile ("csrr %0, utvec" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} +static inline void csr_write_utvec(uint_xlen_t value) { + __asm__ volatile ("csrw utvec, %0" + : /* output: none */ + : "r" (value) /* input : from register */ + : /* clobbers: none */); +} +static inline uint_xlen_t csr_read_write_utvec(uint_xlen_t new_value) { + uint_xlen_t prev_value; + __asm__ volatile ("csrrw %0, utvec, %1" + : "=r" (prev_value) /* output: register %0 */ + : "r" (new_value) /* input : register */ + : /* clobbers: none */); + return prev_value; +} +/* Register CSR bit set and clear instructions */ +static inline void csr_set_bits_utvec(uint_xlen_t mask) { + __asm__ volatile ("csrrs zero, utvec, %0" + : /* output: none */ + : "r" (mask) /* input : register */ + : /* clobbers: none */); +} +static inline void csr_clr_bits_utvec(uint_xlen_t mask) { + __asm__ volatile ("csrrc zero, utvec, %0" + : /* output: none */ + : "r" (mask) /* input : register */ + : /* clobbers: none */); +} +static inline uint_xlen_t csr_read_set_bits_utvec(uint_xlen_t mask) { + uint_xlen_t value; + __asm__ volatile ("csrrs %0, utvec, %1" + : "=r" (value) /* output: register %0 */ + : "r" (mask) /* input : register */ + : /* clobbers: none */); + return value; +} +static inline uint_xlen_t csr_read_clr_bits_utvec(uint_xlen_t mask) { + uint_xlen_t value; + __asm__ volatile ("csrrc %0, utvec, %1" + : "=r" (value) /* output: register %0 */ + : "r" (mask) /* input : register */ + : /* clobbers: none */); + return value; +} +/* utvec, CSR write value via immediate value (only up to 5 bits) */ +#define CSR_WRITE_IMM_UTVEC(VALUE) \ + __asm__ volatile ("csrrwi zero, utvec, %0" \ + : /* output: none */ \ + : "i" (VALUE) /* input : immediate */ \ + : /* clobbers: none */) + +/* utvec, CSR set bits via immediate value mask (only up to 5 bits) */ +#define CSR_SET_BITS_IMM_UTVEC(MASK) \ + __asm__ volatile ("csrrsi zero, utvec, %0" \ + : /* output: none */ \ + : "i" (MASK) /* input : immediate */ \ + : /* clobbers: none */) + +/* utvec, CSR clear bits via immediate value mask (only up to 5 bits) */ +#define CSR_CLR_BITS_IMM_UTVEC(MASK) \ + __asm__ volatile ("csrrci zero, utvec, %0" \ + : /* output: none */ \ + : "i" (MASK) /* input : immediate */ \ + : /* clobbers: none */) +#define UTVEC_BASE_BIT_OFFSET 2 +#define UTVEC_BASE_BIT_WIDTH ((__riscv_xlen-1)-(2) + 1) +#define UTVEC_BASE_BIT_MASK ((1UL<<(((__riscv_xlen-1)-(2) + 1)-1)) << (2)) +#define UTVEC_BASE_ALL_SET_MASK ((1UL<<(((__riscv_xlen-1)-(2) + 1)-1)) << (0)) +#define UTVEC_MODE_BIT_OFFSET 0 +#define UTVEC_MODE_BIT_WIDTH 2 +#define UTVEC_MODE_BIT_MASK 0x3 +#define UTVEC_MODE_ALL_SET_MASK 0x3 + +/******************************************* + * utval - URW - User Trap Value + */ +static inline uint_xlen_t csr_read_utval(void) { + uint_xlen_t value; + __asm__ volatile ("csrr %0, utval" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} +static inline void csr_write_utval(uint_xlen_t value) { + __asm__ volatile ("csrw utval, %0" + : /* output: none */ + : "r" (value) /* input : from register */ + : /* clobbers: none */); +} +static inline uint_xlen_t csr_read_write_utval(uint_xlen_t new_value) { + uint_xlen_t prev_value; + __asm__ volatile ("csrrw %0, utval, %1" + : "=r" (prev_value) /* output: register %0 */ + : "r" (new_value) /* input : register */ + : /* clobbers: none */); + return prev_value; +} + +/******************************************* + * fflags - URW - Floating-Point Accrued Exceptions. + */ +static inline uint_xlen_t csr_read_fflags(void) { + uint_xlen_t value; + __asm__ volatile ("csrr %0, fflags" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} +static inline void csr_write_fflags(uint_xlen_t value) { + __asm__ volatile ("csrw fflags, %0" + : /* output: none */ + : "r" (value) /* input : from register */ + : /* clobbers: none */); +} +static inline uint_xlen_t csr_read_write_fflags(uint_xlen_t new_value) { + uint_xlen_t prev_value; + __asm__ volatile ("csrrw %0, fflags, %1" + : "=r" (prev_value) /* output: register %0 */ + : "r" (new_value) /* input : register */ + : /* clobbers: none */); + return prev_value; +} + +/******************************************* + * frm - URW - Floating-Point Dynamic Rounding Mode. + */ +static inline uint_xlen_t csr_read_frm(void) { + uint_xlen_t value; + __asm__ volatile ("csrr %0, frm" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} +static inline void csr_write_frm(uint_xlen_t value) { + __asm__ volatile ("csrw frm, %0" + : /* output: none */ + : "r" (value) /* input : from register */ + : /* clobbers: none */); +} +static inline uint_xlen_t csr_read_write_frm(uint_xlen_t new_value) { + uint_xlen_t prev_value; + __asm__ volatile ("csrrw %0, frm, %1" + : "=r" (prev_value) /* output: register %0 */ + : "r" (new_value) /* input : register */ + : /* clobbers: none */); + return prev_value; +} + +/******************************************* + * fcsr - URW - Floating-Point Control and Status + */ +static inline uint_xlen_t csr_read_fcsr(void) { + uint_xlen_t value; + __asm__ volatile ("csrr %0, fcsr" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} +static inline void csr_write_fcsr(uint_xlen_t value) { + __asm__ volatile ("csrw fcsr, %0" + : /* output: none */ + : "r" (value) /* input : from register */ + : /* clobbers: none */); +} +static inline uint_xlen_t csr_read_write_fcsr(uint_xlen_t new_value) { + uint_xlen_t prev_value; + __asm__ volatile ("csrrw %0, fcsr, %1" + : "=r" (prev_value) /* output: register %0 */ + : "r" (new_value) /* input : register */ + : /* clobbers: none */); + return prev_value; +} + +/******************************************* + * cycle - URO - Cycle counter for RDCYCLE instruction. + */ +static inline uint_xlen_t csr_read_cycle(void) { + uint_xlen_t value; + __asm__ volatile ("csrr %0, cycle" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} + +/******************************************* + * time - URO - Timer for RDTIME instruction. + */ +static inline uint_xlen_t csr_read_time(void) { + uint_xlen_t value; + __asm__ volatile ("csrr %0, time" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} + +/******************************************* + * instret - URO - Instructions-retired counter for RDINSTRET instruction. + */ +static inline uint_xlen_t csr_read_instret(void) { + uint_xlen_t value; + __asm__ volatile ("csrr %0, instret" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} + +/******************************************* + * hpmcounter3 - URO - Performance-monitoring counter. + */ +static inline uint_xlen_t csr_read_hpmcounter3(void) { + uint_xlen_t value; + __asm__ volatile ("csrr %0, hpmcounter3" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} + +/******************************************* + * hpmcounter4 - URO - Performance-monitoring counter. + */ +static inline uint_xlen_t csr_read_hpmcounter4(void) { + uint_xlen_t value; + __asm__ volatile ("csrr %0, hpmcounter4" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} + +/******************************************* + * hpmcounter31 - URO - Performance-monitoring counter. + */ +static inline uint_xlen_t csr_read_hpmcounter31(void) { + uint_xlen_t value; + __asm__ volatile ("csrr %0, hpmcounter31" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} + +/******************************************* + * cycleh - URO - Upper 32 bits of cycle, RV32I only. + */ +static inline uint_xlen_t csr_read_cycleh(void) { + uint_xlen_t value; + __asm__ volatile ("csrr %0, cycleh" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} + +/******************************************* + * timeh - URO - Upper 32 bits of time, RV32I only. + */ +static inline uint_xlen_t csr_read_timeh(void) { + uint_xlen_t value; + __asm__ volatile ("csrr %0, timeh" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} + +/******************************************* + * instreth - URO - Upper 32 bits of instret, RV32I only. + */ +static inline uint_xlen_t csr_read_instreth(void) { + uint_xlen_t value; + __asm__ volatile ("csrr %0, instreth" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} + +/******************************************* + * hpmcounter3h - URO - Upper 32 bits of hpmcounter3, RV32I only. + */ +static inline uint_xlen_t csr_read_hpmcounter3h(void) { + uint_xlen_t value; + __asm__ volatile ("csrr %0, hpmcounter3h" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} + +/******************************************* + * hpmcounter4h - URO - Upper 32 bits of hpmcounter4, RV32I only. + */ +static inline uint_xlen_t csr_read_hpmcounter4h(void) { + uint_xlen_t value; + __asm__ volatile ("csrr %0, hpmcounter4h" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} + +/******************************************* + * hpmcounter31h - URO - Upper 32 bits of hpmcounter31, RV32I only. + */ +static inline uint_xlen_t csr_read_hpmcounter31h(void) { + uint_xlen_t value; + __asm__ volatile ("csrr %0, hpmcounter31h" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} + +/******************************************* + * stval - SRW - Supervisor bad address or instruction. + */ +static inline uint_xlen_t csr_read_stval(void) { + uint_xlen_t value; + __asm__ volatile ("csrr %0, stval" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} +static inline void csr_write_stval(uint_xlen_t value) { + __asm__ volatile ("csrw stval, %0" + : /* output: none */ + : "r" (value) /* input : from register */ + : /* clobbers: none */); +} +static inline uint_xlen_t csr_read_write_stval(uint_xlen_t new_value) { + uint_xlen_t prev_value; + __asm__ volatile ("csrrw %0, stval, %1" + : "=r" (prev_value) /* output: register %0 */ + : "r" (new_value) /* input : register */ + : /* clobbers: none */); + return prev_value; +} + +/******************************************* + * satp - SRW - Supervisor address translation and protection. + */ +static inline uint_xlen_t csr_read_satp(void) { + uint_xlen_t value; + __asm__ volatile ("csrr %0, satp" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} +static inline void csr_write_satp(uint_xlen_t value) { + __asm__ volatile ("csrw satp, %0" + : /* output: none */ + : "r" (value) /* input : from register */ + : /* clobbers: none */); +} +static inline uint_xlen_t csr_read_write_satp(uint_xlen_t new_value) { + uint_xlen_t prev_value; + __asm__ volatile ("csrrw %0, satp, %1" + : "=r" (prev_value) /* output: register %0 */ + : "r" (new_value) /* input : register */ + : /* clobbers: none */); + return prev_value; +} + +/******************************************* + * hstatus - HRW - Hypervisor status register. + */ +static inline uint_xlen_t csr_read_hstatus(void) { + uint_xlen_t value; + __asm__ volatile ("csrr %0, hstatus" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} +static inline void csr_write_hstatus(uint_xlen_t value) { + __asm__ volatile ("csrw hstatus, %0" + : /* output: none */ + : "r" (value) /* input : from register */ + : /* clobbers: none */); +} +static inline uint_xlen_t csr_read_write_hstatus(uint_xlen_t new_value) { + uint_xlen_t prev_value; + __asm__ volatile ("csrrw %0, hstatus, %1" + : "=r" (prev_value) /* output: register %0 */ + : "r" (new_value) /* input : register */ + : /* clobbers: none */); + return prev_value; +} + +/******************************************* + * hedeleg - HRW - Hypervisor exception delegation register. + */ +static inline uint_xlen_t csr_read_hedeleg(void) { + uint_xlen_t value; + __asm__ volatile ("csrr %0, hedeleg" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} +static inline void csr_write_hedeleg(uint_xlen_t value) { + __asm__ volatile ("csrw hedeleg, %0" + : /* output: none */ + : "r" (value) /* input : from register */ + : /* clobbers: none */); +} +static inline uint_xlen_t csr_read_write_hedeleg(uint_xlen_t new_value) { + uint_xlen_t prev_value; + __asm__ volatile ("csrrw %0, hedeleg, %1" + : "=r" (prev_value) /* output: register %0 */ + : "r" (new_value) /* input : register */ + : /* clobbers: none */); + return prev_value; +} + +/******************************************* + * hideleg - HRW - Hypervisor interrupt delegation register. + */ +static inline uint_xlen_t csr_read_hideleg(void) { + uint_xlen_t value; + __asm__ volatile ("csrr %0, hideleg" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} +static inline void csr_write_hideleg(uint_xlen_t value) { + __asm__ volatile ("csrw hideleg, %0" + : /* output: none */ + : "r" (value) /* input : from register */ + : /* clobbers: none */); +} +static inline uint_xlen_t csr_read_write_hideleg(uint_xlen_t new_value) { + uint_xlen_t prev_value; + __asm__ volatile ("csrrw %0, hideleg, %1" + : "=r" (prev_value) /* output: register %0 */ + : "r" (new_value) /* input : register */ + : /* clobbers: none */); + return prev_value; +} + +/******************************************* + * hcounteren - HRW - Hypervisor counter enable. + */ +static inline uint_xlen_t csr_read_hcounteren(void) { + uint_xlen_t value; + __asm__ volatile ("csrr %0, hcounteren" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} +static inline void csr_write_hcounteren(uint_xlen_t value) { + __asm__ volatile ("csrw hcounteren, %0" + : /* output: none */ + : "r" (value) /* input : from register */ + : /* clobbers: none */); +} +static inline uint_xlen_t csr_read_write_hcounteren(uint_xlen_t new_value) { + uint_xlen_t prev_value; + __asm__ volatile ("csrrw %0, hcounteren, %1" + : "=r" (prev_value) /* output: register %0 */ + : "r" (new_value) /* input : register */ + : /* clobbers: none */); + return prev_value; +} + +/******************************************* + * hgatp - HRW - Hypervisor guest address translation and protection. + */ +static inline uint_xlen_t csr_read_hgatp(void) { + uint_xlen_t value; + __asm__ volatile ("csrr %0, hgatp" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} +static inline void csr_write_hgatp(uint_xlen_t value) { + __asm__ volatile ("csrw hgatp, %0" + : /* output: none */ + : "r" (value) /* input : from register */ + : /* clobbers: none */); +} +static inline uint_xlen_t csr_read_write_hgatp(uint_xlen_t new_value) { + uint_xlen_t prev_value; + __asm__ volatile ("csrrw %0, hgatp, %1" + : "=r" (prev_value) /* output: register %0 */ + : "r" (new_value) /* input : register */ + : /* clobbers: none */); + return prev_value; +} + +/******************************************* + * htimedelta - HRW - Delta for VS/VU-mode timer. + */ +static inline uint_xlen_t csr_read_htimedelta(void) { + uint_xlen_t value; + __asm__ volatile ("csrr %0, htimedelta" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} +static inline void csr_write_htimedelta(uint_xlen_t value) { + __asm__ volatile ("csrw htimedelta, %0" + : /* output: none */ + : "r" (value) /* input : from register */ + : /* clobbers: none */); +} +static inline uint_xlen_t csr_read_write_htimedelta(uint_xlen_t new_value) { + uint_xlen_t prev_value; + __asm__ volatile ("csrrw %0, htimedelta, %1" + : "=r" (prev_value) /* output: register %0 */ + : "r" (new_value) /* input : register */ + : /* clobbers: none */); + return prev_value; +} + +/******************************************* + * htimedeltah - HRW - Upper 32 bits of htimedelta, RV32I only. + */ +static inline uint_xlen_t csr_read_htimedeltah(void) { + uint_xlen_t value; + __asm__ volatile ("csrr %0, htimedeltah" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} +static inline void csr_write_htimedeltah(uint_xlen_t value) { + __asm__ volatile ("csrw htimedeltah, %0" + : /* output: none */ + : "r" (value) /* input : from register */ + : /* clobbers: none */); +} +static inline uint_xlen_t csr_read_write_htimedeltah(uint_xlen_t new_value) { + uint_xlen_t prev_value; + __asm__ volatile ("csrrw %0, htimedeltah, %1" + : "=r" (prev_value) /* output: register %0 */ + : "r" (new_value) /* input : register */ + : /* clobbers: none */); + return prev_value; +} + +/******************************************* + * vsstatus - HRW - Virtual supervisor status register. + */ +static inline uint_xlen_t csr_read_vsstatus(void) { + uint_xlen_t value; + __asm__ volatile ("csrr %0, vsstatus" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} +static inline void csr_write_vsstatus(uint_xlen_t value) { + __asm__ volatile ("csrw vsstatus, %0" + : /* output: none */ + : "r" (value) /* input : from register */ + : /* clobbers: none */); +} +static inline uint_xlen_t csr_read_write_vsstatus(uint_xlen_t new_value) { + uint_xlen_t prev_value; + __asm__ volatile ("csrrw %0, vsstatus, %1" + : "=r" (prev_value) /* output: register %0 */ + : "r" (new_value) /* input : register */ + : /* clobbers: none */); + return prev_value; +} + +/******************************************* + * vsie - HRW - Virtual supervisor interrupt-enable register. + */ +static inline uint_xlen_t csr_read_vsie(void) { + uint_xlen_t value; + __asm__ volatile ("csrr %0, vsie" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} +static inline void csr_write_vsie(uint_xlen_t value) { + __asm__ volatile ("csrw vsie, %0" + : /* output: none */ + : "r" (value) /* input : from register */ + : /* clobbers: none */); +} +static inline uint_xlen_t csr_read_write_vsie(uint_xlen_t new_value) { + uint_xlen_t prev_value; + __asm__ volatile ("csrrw %0, vsie, %1" + : "=r" (prev_value) /* output: register %0 */ + : "r" (new_value) /* input : register */ + : /* clobbers: none */); + return prev_value; +} + +/******************************************* + * vstvec - HRW - Virtual supervisor trap handler base address. + */ +static inline uint_xlen_t csr_read_vstvec(void) { + uint_xlen_t value; + __asm__ volatile ("csrr %0, vstvec" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} +static inline void csr_write_vstvec(uint_xlen_t value) { + __asm__ volatile ("csrw vstvec, %0" + : /* output: none */ + : "r" (value) /* input : from register */ + : /* clobbers: none */); +} +static inline uint_xlen_t csr_read_write_vstvec(uint_xlen_t new_value) { + uint_xlen_t prev_value; + __asm__ volatile ("csrrw %0, vstvec, %1" + : "=r" (prev_value) /* output: register %0 */ + : "r" (new_value) /* input : register */ + : /* clobbers: none */); + return prev_value; +} + +/******************************************* + * vsscratch - HRW - Virtual supervisor scratch register. + */ +static inline uint_xlen_t csr_read_vsscratch(void) { + uint_xlen_t value; + __asm__ volatile ("csrr %0, vsscratch" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} +static inline void csr_write_vsscratch(uint_xlen_t value) { + __asm__ volatile ("csrw vsscratch, %0" + : /* output: none */ + : "r" (value) /* input : from register */ + : /* clobbers: none */); +} +static inline uint_xlen_t csr_read_write_vsscratch(uint_xlen_t new_value) { + uint_xlen_t prev_value; + __asm__ volatile ("csrrw %0, vsscratch, %1" + : "=r" (prev_value) /* output: register %0 */ + : "r" (new_value) /* input : register */ + : /* clobbers: none */); + return prev_value; +} + +/******************************************* + * vsepc - HRW - Virtual supervisor exception program counter. + */ +static inline uint_xlen_t csr_read_vsepc(void) { + uint_xlen_t value; + __asm__ volatile ("csrr %0, vsepc" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} +static inline void csr_write_vsepc(uint_xlen_t value) { + __asm__ volatile ("csrw vsepc, %0" + : /* output: none */ + : "r" (value) /* input : from register */ + : /* clobbers: none */); +} +static inline uint_xlen_t csr_read_write_vsepc(uint_xlen_t new_value) { + uint_xlen_t prev_value; + __asm__ volatile ("csrrw %0, vsepc, %1" + : "=r" (prev_value) /* output: register %0 */ + : "r" (new_value) /* input : register */ + : /* clobbers: none */); + return prev_value; +} + +/******************************************* + * vscause - HRW - Virtual supervisor trap cause. + */ +static inline uint_xlen_t csr_read_vscause(void) { + uint_xlen_t value; + __asm__ volatile ("csrr %0, vscause" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} +static inline void csr_write_vscause(uint_xlen_t value) { + __asm__ volatile ("csrw vscause, %0" + : /* output: none */ + : "r" (value) /* input : from register */ + : /* clobbers: none */); +} +static inline uint_xlen_t csr_read_write_vscause(uint_xlen_t new_value) { + uint_xlen_t prev_value; + __asm__ volatile ("csrrw %0, vscause, %1" + : "=r" (prev_value) /* output: register %0 */ + : "r" (new_value) /* input : register */ + : /* clobbers: none */); + return prev_value; +} + +/******************************************* + * vstval - HRW - Virtual supervisor bad address or instruction. + */ +static inline uint_xlen_t csr_read_vstval(void) { + uint_xlen_t value; + __asm__ volatile ("csrr %0, vstval" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} +static inline void csr_write_vstval(uint_xlen_t value) { + __asm__ volatile ("csrw vstval, %0" + : /* output: none */ + : "r" (value) /* input : from register */ + : /* clobbers: none */); +} +static inline uint_xlen_t csr_read_write_vstval(uint_xlen_t new_value) { + uint_xlen_t prev_value; + __asm__ volatile ("csrrw %0, vstval, %1" + : "=r" (prev_value) /* output: register %0 */ + : "r" (new_value) /* input : register */ + : /* clobbers: none */); + return prev_value; +} + +/******************************************* + * vsip - HRW - Virtual supervisor interrupt pending. + */ +static inline uint_xlen_t csr_read_vsip(void) { + uint_xlen_t value; + __asm__ volatile ("csrr %0, vsip" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} +static inline void csr_write_vsip(uint_xlen_t value) { + __asm__ volatile ("csrw vsip, %0" + : /* output: none */ + : "r" (value) /* input : from register */ + : /* clobbers: none */); +} +static inline uint_xlen_t csr_read_write_vsip(uint_xlen_t new_value) { + uint_xlen_t prev_value; + __asm__ volatile ("csrrw %0, vsip, %1" + : "=r" (prev_value) /* output: register %0 */ + : "r" (new_value) /* input : register */ + : /* clobbers: none */); + return prev_value; +} + +/******************************************* + * vsatp - HRW - Virtual supervisor address translation and protection. + */ +static inline uint_xlen_t csr_read_vsatp(void) { + uint_xlen_t value; + __asm__ volatile ("csrr %0, vsatp" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} +static inline void csr_write_vsatp(uint_xlen_t value) { + __asm__ volatile ("csrw vsatp, %0" + : /* output: none */ + : "r" (value) /* input : from register */ + : /* clobbers: none */); +} +static inline uint_xlen_t csr_read_write_vsatp(uint_xlen_t new_value) { + uint_xlen_t prev_value; + __asm__ volatile ("csrrw %0, vsatp, %1" + : "=r" (prev_value) /* output: register %0 */ + : "r" (new_value) /* input : register */ + : /* clobbers: none */); + return prev_value; +} + +/******************************************* + * mbase - MRW - Base register. + */ +static inline uint_xlen_t csr_read_mbase(void) { + uint_xlen_t value; + __asm__ volatile ("csrr %0, mbase" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} +static inline void csr_write_mbase(uint_xlen_t value) { + __asm__ volatile ("csrw mbase, %0" + : /* output: none */ + : "r" (value) /* input : from register */ + : /* clobbers: none */); +} +static inline uint_xlen_t csr_read_write_mbase(uint_xlen_t new_value) { + uint_xlen_t prev_value; + __asm__ volatile ("csrrw %0, mbase, %1" + : "=r" (prev_value) /* output: register %0 */ + : "r" (new_value) /* input : register */ + : /* clobbers: none */); + return prev_value; +} + +/******************************************* + * mbound - MRW - Bound register. + */ +static inline uint_xlen_t csr_read_mbound(void) { + uint_xlen_t value; + __asm__ volatile ("csrr %0, mbound" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} +static inline void csr_write_mbound(uint_xlen_t value) { + __asm__ volatile ("csrw mbound, %0" + : /* output: none */ + : "r" (value) /* input : from register */ + : /* clobbers: none */); +} +static inline uint_xlen_t csr_read_write_mbound(uint_xlen_t new_value) { + uint_xlen_t prev_value; + __asm__ volatile ("csrrw %0, mbound, %1" + : "=r" (prev_value) /* output: register %0 */ + : "r" (new_value) /* input : register */ + : /* clobbers: none */); + return prev_value; +} + +/******************************************* + * mibase - MRW - Instruction base register. + */ +static inline uint_xlen_t csr_read_mibase(void) { + uint_xlen_t value; + __asm__ volatile ("csrr %0, mibase" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} +static inline void csr_write_mibase(uint_xlen_t value) { + __asm__ volatile ("csrw mibase, %0" + : /* output: none */ + : "r" (value) /* input : from register */ + : /* clobbers: none */); +} +static inline uint_xlen_t csr_read_write_mibase(uint_xlen_t new_value) { + uint_xlen_t prev_value; + __asm__ volatile ("csrrw %0, mibase, %1" + : "=r" (prev_value) /* output: register %0 */ + : "r" (new_value) /* input : register */ + : /* clobbers: none */); + return prev_value; +} + +/******************************************* + * mibound - MRW - Instruction bound register. + */ +static inline uint_xlen_t csr_read_mibound(void) { + uint_xlen_t value; + __asm__ volatile ("csrr %0, mibound" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} +static inline void csr_write_mibound(uint_xlen_t value) { + __asm__ volatile ("csrw mibound, %0" + : /* output: none */ + : "r" (value) /* input : from register */ + : /* clobbers: none */); +} +static inline uint_xlen_t csr_read_write_mibound(uint_xlen_t new_value) { + uint_xlen_t prev_value; + __asm__ volatile ("csrrw %0, mibound, %1" + : "=r" (prev_value) /* output: register %0 */ + : "r" (new_value) /* input : register */ + : /* clobbers: none */); + return prev_value; +} + +/******************************************* + * mdbase - MRW - Data base register. + */ +static inline uint_xlen_t csr_read_mdbase(void) { + uint_xlen_t value; + __asm__ volatile ("csrr %0, mdbase" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} +static inline void csr_write_mdbase(uint_xlen_t value) { + __asm__ volatile ("csrw mdbase, %0" + : /* output: none */ + : "r" (value) /* input : from register */ + : /* clobbers: none */); +} +static inline uint_xlen_t csr_read_write_mdbase(uint_xlen_t new_value) { + uint_xlen_t prev_value; + __asm__ volatile ("csrrw %0, mdbase, %1" + : "=r" (prev_value) /* output: register %0 */ + : "r" (new_value) /* input : register */ + : /* clobbers: none */); + return prev_value; +} + +/******************************************* + * mdbound - MRW - Data bound register. + */ +static inline uint_xlen_t csr_read_mdbound(void) { + uint_xlen_t value; + __asm__ volatile ("csrr %0, mdbound" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} +static inline void csr_write_mdbound(uint_xlen_t value) { + __asm__ volatile ("csrw mdbound, %0" + : /* output: none */ + : "r" (value) /* input : from register */ + : /* clobbers: none */); +} +static inline uint_xlen_t csr_read_write_mdbound(uint_xlen_t new_value) { + uint_xlen_t prev_value; + __asm__ volatile ("csrrw %0, mdbound, %1" + : "=r" (prev_value) /* output: register %0 */ + : "r" (new_value) /* input : register */ + : /* clobbers: none */); + return prev_value; +} + +/******************************************* + * pmpcfg0 - MRW - Physical memory protection configuration. + */ +static inline uint_xlen_t csr_read_pmpcfg0(void) { + uint_xlen_t value; + __asm__ volatile ("csrr %0, pmpcfg0" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} +static inline void csr_write_pmpcfg0(uint_xlen_t value) { + __asm__ volatile ("csrw pmpcfg0, %0" + : /* output: none */ + : "r" (value) /* input : from register */ + : /* clobbers: none */); +} +static inline uint_xlen_t csr_read_write_pmpcfg0(uint_xlen_t new_value) { + uint_xlen_t prev_value; + __asm__ volatile ("csrrw %0, pmpcfg0, %1" + : "=r" (prev_value) /* output: register %0 */ + : "r" (new_value) /* input : register */ + : /* clobbers: none */); + return prev_value; +} + +/******************************************* + * pmpcfg1 - MRW - Physical memory protection configuration, RV32 only. + */ +static inline uint_xlen_t csr_read_pmpcfg1(void) { + uint_xlen_t value; + __asm__ volatile ("csrr %0, pmpcfg1" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} +static inline void csr_write_pmpcfg1(uint_xlen_t value) { + __asm__ volatile ("csrw pmpcfg1, %0" + : /* output: none */ + : "r" (value) /* input : from register */ + : /* clobbers: none */); +} +static inline uint_xlen_t csr_read_write_pmpcfg1(uint_xlen_t new_value) { + uint_xlen_t prev_value; + __asm__ volatile ("csrrw %0, pmpcfg1, %1" + : "=r" (prev_value) /* output: register %0 */ + : "r" (new_value) /* input : register */ + : /* clobbers: none */); + return prev_value; +} + +/******************************************* + * pmpcfg2 - MRW - Physical memory protection configuration. + */ +static inline uint_xlen_t csr_read_pmpcfg2(void) { + uint_xlen_t value; + __asm__ volatile ("csrr %0, pmpcfg2" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} +static inline void csr_write_pmpcfg2(uint_xlen_t value) { + __asm__ volatile ("csrw pmpcfg2, %0" + : /* output: none */ + : "r" (value) /* input : from register */ + : /* clobbers: none */); +} +static inline uint_xlen_t csr_read_write_pmpcfg2(uint_xlen_t new_value) { + uint_xlen_t prev_value; + __asm__ volatile ("csrrw %0, pmpcfg2, %1" + : "=r" (prev_value) /* output: register %0 */ + : "r" (new_value) /* input : register */ + : /* clobbers: none */); + return prev_value; +} + +/******************************************* + * pmpcfg3 - MRW - Physical memory protection configuration, RV32 only. + */ +static inline uint_xlen_t csr_read_pmpcfg3(void) { + uint_xlen_t value; + __asm__ volatile ("csrr %0, pmpcfg3" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} +static inline void csr_write_pmpcfg3(uint_xlen_t value) { + __asm__ volatile ("csrw pmpcfg3, %0" + : /* output: none */ + : "r" (value) /* input : from register */ + : /* clobbers: none */); +} +static inline uint_xlen_t csr_read_write_pmpcfg3(uint_xlen_t new_value) { + uint_xlen_t prev_value; + __asm__ volatile ("csrrw %0, pmpcfg3, %1" + : "=r" (prev_value) /* output: register %0 */ + : "r" (new_value) /* input : register */ + : /* clobbers: none */); + return prev_value; +} + +/******************************************* + * pmpaddr0 - MRW - Physical memory protection address register. + */ +static inline uint_xlen_t csr_read_pmpaddr0(void) { + uint_xlen_t value; + __asm__ volatile ("csrr %0, pmpaddr0" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} +static inline void csr_write_pmpaddr0(uint_xlen_t value) { + __asm__ volatile ("csrw pmpaddr0, %0" + : /* output: none */ + : "r" (value) /* input : from register */ + : /* clobbers: none */); +} +static inline uint_xlen_t csr_read_write_pmpaddr0(uint_xlen_t new_value) { + uint_xlen_t prev_value; + __asm__ volatile ("csrrw %0, pmpaddr0, %1" + : "=r" (prev_value) /* output: register %0 */ + : "r" (new_value) /* input : register */ + : /* clobbers: none */); + return prev_value; +} + +/******************************************* + * pmpaddr1 - MRW - Physical memory protection address register. + */ +static inline uint_xlen_t csr_read_pmpaddr1(void) { + uint_xlen_t value; + __asm__ volatile ("csrr %0, pmpaddr1" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} +static inline void csr_write_pmpaddr1(uint_xlen_t value) { + __asm__ volatile ("csrw pmpaddr1, %0" + : /* output: none */ + : "r" (value) /* input : from register */ + : /* clobbers: none */); +} +static inline uint_xlen_t csr_read_write_pmpaddr1(uint_xlen_t new_value) { + uint_xlen_t prev_value; + __asm__ volatile ("csrrw %0, pmpaddr1, %1" + : "=r" (prev_value) /* output: register %0 */ + : "r" (new_value) /* input : register */ + : /* clobbers: none */); + return prev_value; +} + +/******************************************* + * pmpaddr15 - MRW - Physical memory protection address register. + */ +static inline uint_xlen_t csr_read_pmpaddr15(void) { + uint_xlen_t value; + __asm__ volatile ("csrr %0, pmpaddr15" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} +static inline void csr_write_pmpaddr15(uint_xlen_t value) { + __asm__ volatile ("csrw pmpaddr15, %0" + : /* output: none */ + : "r" (value) /* input : from register */ + : /* clobbers: none */); +} +static inline uint_xlen_t csr_read_write_pmpaddr15(uint_xlen_t new_value) { + uint_xlen_t prev_value; + __asm__ volatile ("csrrw %0, pmpaddr15, %1" + : "=r" (prev_value) /* output: register %0 */ + : "r" (new_value) /* input : register */ + : /* clobbers: none */); + return prev_value; +} + +/******************************************* + * mhpmcounter4 - MRW - Machine performance-monitoring counter. + */ +static inline uint_xlen_t csr_read_mhpmcounter4(void) { + uint_xlen_t value; + __asm__ volatile ("csrr %0, mhpmcounter4" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} +static inline void csr_write_mhpmcounter4(uint_xlen_t value) { + __asm__ volatile ("csrw mhpmcounter4, %0" + : /* output: none */ + : "r" (value) /* input : from register */ + : /* clobbers: none */); +} +static inline uint_xlen_t csr_read_write_mhpmcounter4(uint_xlen_t new_value) { + uint_xlen_t prev_value; + __asm__ volatile ("csrrw %0, mhpmcounter4, %1" + : "=r" (prev_value) /* output: register %0 */ + : "r" (new_value) /* input : register */ + : /* clobbers: none */); + return prev_value; +} + +/******************************************* + * mhpmcounter31 - MRW - Machine performance-monitoring counter. + */ +static inline uint_xlen_t csr_read_mhpmcounter31(void) { + uint_xlen_t value; + __asm__ volatile ("csrr %0, mhpmcounter31" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} +static inline void csr_write_mhpmcounter31(uint_xlen_t value) { + __asm__ volatile ("csrw mhpmcounter31, %0" + : /* output: none */ + : "r" (value) /* input : from register */ + : /* clobbers: none */); +} +static inline uint_xlen_t csr_read_write_mhpmcounter31(uint_xlen_t new_value) { + uint_xlen_t prev_value; + __asm__ volatile ("csrrw %0, mhpmcounter31, %1" + : "=r" (prev_value) /* output: register %0 */ + : "r" (new_value) /* input : register */ + : /* clobbers: none */); + return prev_value; +} + +/******************************************* + * mcycleh - MRW - Upper 32 bits of mcycle, RV32I only. + */ +static inline uint32_t csr_read_mcycleh(void) { + uint_csr32_t value; + __asm__ volatile ("csrr %0, mcycleh" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} +static inline void csr_write_mcycleh(uint_csr32_t value) { + __asm__ volatile ("csrw mcycleh, %0" + : /* output: none */ + : "r" (value) /* input : from register */ + : /* clobbers: none */); +} +static inline uint32_t csr_read_write_mcycleh(uint32_t new_value) { + uint_csr32_t prev_value; + __asm__ volatile ("csrrw %0, mcycleh, %1" + : "=r" (prev_value) /* output: register %0 */ + : "r" (new_value) /* input : register */ + : /* clobbers: none */); + return prev_value; +} + +/******************************************* + * minstreth - MRW - Upper 32 bits of minstret, RV32I only. + */ +static inline uint32_t csr_read_minstreth(void) { + uint_csr32_t value; + __asm__ volatile ("csrr %0, minstreth" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} +static inline void csr_write_minstreth(uint_csr32_t value) { + __asm__ volatile ("csrw minstreth, %0" + : /* output: none */ + : "r" (value) /* input : from register */ + : /* clobbers: none */); +} +static inline uint32_t csr_read_write_minstreth(uint32_t new_value) { + uint_csr32_t prev_value; + __asm__ volatile ("csrrw %0, minstreth, %1" + : "=r" (prev_value) /* output: register %0 */ + : "r" (new_value) /* input : register */ + : /* clobbers: none */); + return prev_value; +} + +/******************************************* + * mhpmcounter3h - MRW - Upper 32 bits of mhpmcounter3, RV32I only. + */ +static inline uint32_t csr_read_mhpmcounter3h(void) { + uint_csr32_t value; + __asm__ volatile ("csrr %0, mhpmcounter3h" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} +static inline void csr_write_mhpmcounter3h(uint_csr32_t value) { + __asm__ volatile ("csrw mhpmcounter3h, %0" + : /* output: none */ + : "r" (value) /* input : from register */ + : /* clobbers: none */); +} +static inline uint32_t csr_read_write_mhpmcounter3h(uint32_t new_value) { + uint_csr32_t prev_value; + __asm__ volatile ("csrrw %0, mhpmcounter3h, %1" + : "=r" (prev_value) /* output: register %0 */ + : "r" (new_value) /* input : register */ + : /* clobbers: none */); + return prev_value; +} + +/******************************************* + * mhpmcounter4h - MRW - Upper 32 bits of mhpmcounter4, RV32I only. + */ +static inline uint32_t csr_read_mhpmcounter4h(void) { + uint_csr32_t value; + __asm__ volatile ("csrr %0, mhpmcounter4h" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} +static inline void csr_write_mhpmcounter4h(uint_csr32_t value) { + __asm__ volatile ("csrw mhpmcounter4h, %0" + : /* output: none */ + : "r" (value) /* input : from register */ + : /* clobbers: none */); +} +static inline uint32_t csr_read_write_mhpmcounter4h(uint32_t new_value) { + uint_csr32_t prev_value; + __asm__ volatile ("csrrw %0, mhpmcounter4h, %1" + : "=r" (prev_value) /* output: register %0 */ + : "r" (new_value) /* input : register */ + : /* clobbers: none */); + return prev_value; +} + +/******************************************* + * mhpmcounter31h - MRW - Upper 32 bits of mhpmcounter31, RV32I only. + */ +static inline uint32_t csr_read_mhpmcounter31h(void) { + uint_csr32_t value; + __asm__ volatile ("csrr %0, mhpmcounter31h" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} +static inline void csr_write_mhpmcounter31h(uint_csr32_t value) { + __asm__ volatile ("csrw mhpmcounter31h, %0" + : /* output: none */ + : "r" (value) /* input : from register */ + : /* clobbers: none */); +} +static inline uint32_t csr_read_write_mhpmcounter31h(uint32_t new_value) { + uint_csr32_t prev_value; + __asm__ volatile ("csrrw %0, mhpmcounter31h, %1" + : "=r" (prev_value) /* output: register %0 */ + : "r" (new_value) /* input : register */ + : /* clobbers: none */); + return prev_value; +} + +/******************************************* + * mhpmevent4 - MRW - Machine performance-monitoring event selector. + */ +static inline uint_xlen_t csr_read_mhpmevent4(void) { + uint_xlen_t value; + __asm__ volatile ("csrr %0, mhpmevent4" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} +static inline void csr_write_mhpmevent4(uint_xlen_t value) { + __asm__ volatile ("csrw mhpmevent4, %0" + : /* output: none */ + : "r" (value) /* input : from register */ + : /* clobbers: none */); +} +static inline uint_xlen_t csr_read_write_mhpmevent4(uint_xlen_t new_value) { + uint_xlen_t prev_value; + __asm__ volatile ("csrrw %0, mhpmevent4, %1" + : "=r" (prev_value) /* output: register %0 */ + : "r" (new_value) /* input : register */ + : /* clobbers: none */); + return prev_value; +} + +/******************************************* + * mhpmevent31 - MRW - Machine performance-monitoring event selector. + */ +static inline uint_xlen_t csr_read_mhpmevent31(void) { + uint_xlen_t value; + __asm__ volatile ("csrr %0, mhpmevent31" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} +static inline void csr_write_mhpmevent31(uint_xlen_t value) { + __asm__ volatile ("csrw mhpmevent31, %0" + : /* output: none */ + : "r" (value) /* input : from register */ + : /* clobbers: none */); +} +static inline uint_xlen_t csr_read_write_mhpmevent31(uint_xlen_t new_value) { + uint_xlen_t prev_value; + __asm__ volatile ("csrrw %0, mhpmevent31, %1" + : "=r" (prev_value) /* output: register %0 */ + : "r" (new_value) /* input : register */ + : /* clobbers: none */); + return prev_value; +} + +/******************************************* + * tselect - MRW - Debug/Trace trigger register select. + */ +static inline uint_xlen_t csr_read_tselect(void) { + uint_xlen_t value; + __asm__ volatile ("csrr %0, tselect" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} +static inline void csr_write_tselect(uint_xlen_t value) { + __asm__ volatile ("csrw tselect, %0" + : /* output: none */ + : "r" (value) /* input : from register */ + : /* clobbers: none */); +} +static inline uint_xlen_t csr_read_write_tselect(uint_xlen_t new_value) { + uint_xlen_t prev_value; + __asm__ volatile ("csrrw %0, tselect, %1" + : "=r" (prev_value) /* output: register %0 */ + : "r" (new_value) /* input : register */ + : /* clobbers: none */); + return prev_value; +} + +/******************************************* + * tdata1 - MRW - First Debug/Trace trigger data register. + */ +static inline uint_xlen_t csr_read_tdata1(void) { + uint_xlen_t value; + __asm__ volatile ("csrr %0, tdata1" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} +static inline void csr_write_tdata1(uint_xlen_t value) { + __asm__ volatile ("csrw tdata1, %0" + : /* output: none */ + : "r" (value) /* input : from register */ + : /* clobbers: none */); +} +static inline uint_xlen_t csr_read_write_tdata1(uint_xlen_t new_value) { + uint_xlen_t prev_value; + __asm__ volatile ("csrrw %0, tdata1, %1" + : "=r" (prev_value) /* output: register %0 */ + : "r" (new_value) /* input : register */ + : /* clobbers: none */); + return prev_value; +} + +/******************************************* + * tdata2 - MRW - Second Debug/Trace trigger data register. + */ +static inline uint_xlen_t csr_read_tdata2(void) { + uint_xlen_t value; + __asm__ volatile ("csrr %0, tdata2" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} +static inline void csr_write_tdata2(uint_xlen_t value) { + __asm__ volatile ("csrw tdata2, %0" + : /* output: none */ + : "r" (value) /* input : from register */ + : /* clobbers: none */); +} +static inline uint_xlen_t csr_read_write_tdata2(uint_xlen_t new_value) { + uint_xlen_t prev_value; + __asm__ volatile ("csrrw %0, tdata2, %1" + : "=r" (prev_value) /* output: register %0 */ + : "r" (new_value) /* input : register */ + : /* clobbers: none */); + return prev_value; +} + +/******************************************* + * tdata3 - MRW - Third Debug/Trace trigger data register. + */ +static inline uint_xlen_t csr_read_tdata3(void) { + uint_xlen_t value; + __asm__ volatile ("csrr %0, tdata3" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} +static inline void csr_write_tdata3(uint_xlen_t value) { + __asm__ volatile ("csrw tdata3, %0" + : /* output: none */ + : "r" (value) /* input : from register */ + : /* clobbers: none */); +} +static inline uint_xlen_t csr_read_write_tdata3(uint_xlen_t new_value) { + uint_xlen_t prev_value; + __asm__ volatile ("csrrw %0, tdata3, %1" + : "=r" (prev_value) /* output: register %0 */ + : "r" (new_value) /* input : register */ + : /* clobbers: none */); + return prev_value; +} + +/******************************************* + * dcsr - DRW - Debug control and status register. + */ +static inline uint_xlen_t csr_read_dcsr(void) { + uint_xlen_t value; + __asm__ volatile ("csrr %0, dcsr" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} +static inline void csr_write_dcsr(uint_xlen_t value) { + __asm__ volatile ("csrw dcsr, %0" + : /* output: none */ + : "r" (value) /* input : from register */ + : /* clobbers: none */); +} +static inline uint_xlen_t csr_read_write_dcsr(uint_xlen_t new_value) { + uint_xlen_t prev_value; + __asm__ volatile ("csrrw %0, dcsr, %1" + : "=r" (prev_value) /* output: register %0 */ + : "r" (new_value) /* input : register */ + : /* clobbers: none */); + return prev_value; +} + +/******************************************* + * dpc - DRW - Debug PC. + */ +static inline uint_xlen_t csr_read_dpc(void) { + uint_xlen_t value; + __asm__ volatile ("csrr %0, dpc" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} +static inline void csr_write_dpc(uint_xlen_t value) { + __asm__ volatile ("csrw dpc, %0" + : /* output: none */ + : "r" (value) /* input : from register */ + : /* clobbers: none */); +} +static inline uint_xlen_t csr_read_write_dpc(uint_xlen_t new_value) { + uint_xlen_t prev_value; + __asm__ volatile ("csrrw %0, dpc, %1" + : "=r" (prev_value) /* output: register %0 */ + : "r" (new_value) /* input : register */ + : /* clobbers: none */); + return prev_value; +} + +/******************************************* + * dscratch0 - DRW - Debug scratch register 0. + */ +static inline uint_xlen_t csr_read_dscratch0(void) { + uint_xlen_t value; + __asm__ volatile ("csrr %0, dscratch0" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} +static inline void csr_write_dscratch0(uint_xlen_t value) { + __asm__ volatile ("csrw dscratch0, %0" + : /* output: none */ + : "r" (value) /* input : from register */ + : /* clobbers: none */); +} +static inline uint_xlen_t csr_read_write_dscratch0(uint_xlen_t new_value) { + uint_xlen_t prev_value; + __asm__ volatile ("csrrw %0, dscratch0, %1" + : "=r" (prev_value) /* output: register %0 */ + : "r" (new_value) /* input : register */ + : /* clobbers: none */); + return prev_value; +} + +/******************************************* + * dscratch1 - DRW - Debug scratch register 1. + */ +static inline uint_xlen_t csr_read_dscratch1(void) { + uint_xlen_t value; + __asm__ volatile ("csrr %0, dscratch1" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} +static inline void csr_write_dscratch1(uint_xlen_t value) { + __asm__ volatile ("csrw dscratch1, %0" + : /* output: none */ + : "r" (value) /* input : from register */ + : /* clobbers: none */); +} +static inline uint_xlen_t csr_read_write_dscratch1(uint_xlen_t new_value) { + uint_xlen_t prev_value; + __asm__ volatile ("csrrw %0, dscratch1, %1" + : "=r" (prev_value) /* output: register %0 */ + : "r" (new_value) /* input : register */ + : /* clobbers: none */); + return prev_value; +} + +/******************************************* + * hie - HRW - Hypervisor interrupt-enable register. + */ +static inline uint_xlen_t csr_read_hie(void) { + uint_xlen_t value; + __asm__ volatile ("csrr %0, hie" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} +static inline void csr_write_hie(uint_xlen_t value) { + __asm__ volatile ("csrw hie, %0" + : /* output: none */ + : "r" (value) /* input : from register */ + : /* clobbers: none */); +} +static inline uint_xlen_t csr_read_write_hie(uint_xlen_t new_value) { + uint_xlen_t prev_value; + __asm__ volatile ("csrrw %0, hie, %1" + : "=r" (prev_value) /* output: register %0 */ + : "r" (new_value) /* input : register */ + : /* clobbers: none */); + return prev_value; +} + +/******************************************* + * hgeie - HRW - Hypervisor guest external interrupt-enable register. + */ +static inline uint_xlen_t csr_read_hgeie(void) { + uint_xlen_t value; + __asm__ volatile ("csrr %0, hgeie" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} +static inline void csr_write_hgeie(uint_xlen_t value) { + __asm__ volatile ("csrw hgeie, %0" + : /* output: none */ + : "r" (value) /* input : from register */ + : /* clobbers: none */); +} +static inline uint_xlen_t csr_read_write_hgeie(uint_xlen_t new_value) { + uint_xlen_t prev_value; + __asm__ volatile ("csrrw %0, hgeie, %1" + : "=r" (prev_value) /* output: register %0 */ + : "r" (new_value) /* input : register */ + : /* clobbers: none */); + return prev_value; +} + +/******************************************* + * htval - HRW - Hypervisor bad guest physical address. + */ +static inline uint_xlen_t csr_read_htval(void) { + uint_xlen_t value; + __asm__ volatile ("csrr %0, htval" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} +static inline void csr_write_htval(uint_xlen_t value) { + __asm__ volatile ("csrw htval, %0" + : /* output: none */ + : "r" (value) /* input : from register */ + : /* clobbers: none */); +} +static inline uint_xlen_t csr_read_write_htval(uint_xlen_t new_value) { + uint_xlen_t prev_value; + __asm__ volatile ("csrrw %0, htval, %1" + : "=r" (prev_value) /* output: register %0 */ + : "r" (new_value) /* input : register */ + : /* clobbers: none */); + return prev_value; +} + +/******************************************* + * hip - HRW - Hypervisor interrupt pending. + */ +static inline uint_xlen_t csr_read_hip(void) { + uint_xlen_t value; + __asm__ volatile ("csrr %0, hip" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} +static inline void csr_write_hip(uint_xlen_t value) { + __asm__ volatile ("csrw hip, %0" + : /* output: none */ + : "r" (value) /* input : from register */ + : /* clobbers: none */); +} +static inline uint_xlen_t csr_read_write_hip(uint_xlen_t new_value) { + uint_xlen_t prev_value; + __asm__ volatile ("csrrw %0, hip, %1" + : "=r" (prev_value) /* output: register %0 */ + : "r" (new_value) /* input : register */ + : /* clobbers: none */); + return prev_value; +} + +/******************************************* + * htinst - HRW - Hypervisor trap instruction (transformed). + */ +static inline uint_xlen_t csr_read_htinst(void) { + uint_xlen_t value; + __asm__ volatile ("csrr %0, htinst" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} +static inline void csr_write_htinst(uint_xlen_t value) { + __asm__ volatile ("csrw htinst, %0" + : /* output: none */ + : "r" (value) /* input : from register */ + : /* clobbers: none */); +} +static inline uint_xlen_t csr_read_write_htinst(uint_xlen_t new_value) { + uint_xlen_t prev_value; + __asm__ volatile ("csrrw %0, htinst, %1" + : "=r" (prev_value) /* output: register %0 */ + : "r" (new_value) /* input : register */ + : /* clobbers: none */); + return prev_value; +} + +/******************************************* + * hgeip - HRO - Hypervisor guest external interrupt pending. + */ +static inline uint_xlen_t csr_read_hgeip(void) { + uint_xlen_t value; + __asm__ volatile ("csrr %0, hgeip" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} + +/******************************************* + * mtinst - MRW - Machine trap instruction (transformed). + */ +static inline uint_xlen_t csr_read_mtinst(void) { + uint_xlen_t value; + __asm__ volatile ("csrr %0, mtinst" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} +static inline void csr_write_mtinst(uint_xlen_t value) { + __asm__ volatile ("csrw mtinst, %0" + : /* output: none */ + : "r" (value) /* input : from register */ + : /* clobbers: none */); +} +static inline uint_xlen_t csr_read_write_mtinst(uint_xlen_t new_value) { + uint_xlen_t prev_value; + __asm__ volatile ("csrrw %0, mtinst, %1" + : "=r" (prev_value) /* output: register %0 */ + : "r" (new_value) /* input : register */ + : /* clobbers: none */); + return prev_value; +} + +/******************************************* + * mtval2 - MRW - Machine bad guest physical address. + */ +static inline uint_xlen_t csr_read_mtval2(void) { + uint_xlen_t value; + __asm__ volatile ("csrr %0, mtval2" + : "=r" (value) /* output : register */ + : /* input : none */ + : /* clobbers: none */); + return value; +} +static inline void csr_write_mtval2(uint_xlen_t value) { + __asm__ volatile ("csrw mtval2, %0" + : /* output: none */ + : "r" (value) /* input : from register */ + : /* clobbers: none */); +} +static inline uint_xlen_t csr_read_write_mtval2(uint_xlen_t new_value) { + uint_xlen_t prev_value; + __asm__ volatile ("csrrw %0, mtval2, %1" + : "=r" (prev_value) /* output: register %0 */ + : "r" (new_value) /* input : register */ + : /* clobbers: none */); + return prev_value; +} + + +#endif // #define RISCV_CSR_H \ No newline at end of file diff --git a/software/src/riscv-interrupts.h b/software/src/riscv-interrupts.h new file mode 100644 index 00000000..2e58fe2b --- /dev/null +++ b/software/src/riscv-interrupts.h @@ -0,0 +1,56 @@ +/* + RISC-V machine interrupts. + SPDX-License-Identifier: Unlicense + + https://five-embeddev.com/ + +*/ + +#ifndef RISCV_INTERRUPTS_H +#define RISCV_INTERRUPTS_H + +enum { + RISCV_INT_POS_MSI = 3, + RISCV_INT_POS_MTI = 7, + RISCV_INT_POS_MEI = 11, + RISCV_INT_POS_SSI = 1, + RISCV_INT_POS_STI = 5, + RISCV_INT_POS_SEI = 9, + RISCV_INT_POS_USI = 0, + RISCV_INT_POS_UTI = 4, + RISCV_INT_POS_UEI = 8, +}; + +enum { + RISCV_INT_MASK_MSI = (1UL< Date: Mon, 18 Sep 2023 23:47:50 +0100 Subject: [PATCH 19/27] iob_soc_opencryptolinux.v: pass PLIC and CLINT slave bus to CPU. --- hardware/src/iob_soc_opencryptolinux.v | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/hardware/src/iob_soc_opencryptolinux.v b/hardware/src/iob_soc_opencryptolinux.v index ef1204e6..c4464d94 100644 --- a/hardware/src/iob_soc_opencryptolinux.v +++ b/hardware/src/iob_soc_opencryptolinux.v @@ -16,6 +16,7 @@ module iob_soc_opencryptolinux #( localparam integer Bbit = `IOB_SOC_OPENCRYPTOLINUX_B; localparam integer AddrMsb = `REQ_W - 2; localparam integer MEM_ADDR_OFFSET = 0; + localparam IBUS_AXI_ID_W = 1; localparam IBUS_AXI_LEN_W = 8; localparam IBUS_AXI_ADDR_W = 32; @@ -41,6 +42,8 @@ module iob_soc_opencryptolinux #( localparam DBUS_EXTMEM_AXI_ADDR_W = 32; localparam DBUS_EXTMEM_AXI_DATA_W = 32; + localparam N_SLAVES = `IOB_SOC_OPENCRYPTOLINUX_N_SLAVES; + `include "iob_soc_opencryptolinux_pwires.vs" @@ -61,6 +64,10 @@ module iob_soc_opencryptolinux #( wire [DATA_W-1:0] peripheral_iob_rdata; wire peripheral_iob_ready; + //slaves bus (includes internal memory + periphrals) + wire [(N_SLAVES+2)*`REQ_W-1:0] slaves_req; + wire [(N_SLAVES+2)*`RESP_W-1:0] slaves_resp; + // // SYSTEM RESET // @@ -89,10 +96,10 @@ module iob_soc_opencryptolinux #( .cke_i (cke_i), .arst_i (arst_i), .cpu_reset_i (cpu_reset), - .clint_req ({`REQ_W{1'b0}}), - .clint_resp (), - .plic_req ({`REQ_W{1'b0}}), - .plic_resp (), + .clint_req (slaves_req[(N_SLAVES)*69+:`REQ_W]), + .clint_resp (slaves_resp[(N_SLAVES)*34+:`RESP_W]), + .plic_req (slaves_req[(N_SLAVES+1)*69+:`REQ_W]), + .plic_resp (slaves_resp[(N_SLAVES+1)*34+:`RESP_W]), .plicInterrupts(32'd0), // Axi instruction bus `include "iBus_axi_m_portmap.vs" @@ -419,14 +426,10 @@ module iob_soc_opencryptolinux #( .iob_ready_i(peripheral_iob_ready) ); - //slaves bus (includes internal memory + periphrals) - wire [ (`IOB_SOC_OPENCRYPTOLINUX_N_SLAVES)*`REQ_W-1:0] slaves_req; - wire [(`IOB_SOC_OPENCRYPTOLINUX_N_SLAVES)*`RESP_W-1:0] slaves_resp; - iob_split #( .ADDR_W (ADDR_W), .DATA_W (DATA_W), - .N_SLAVES(`IOB_SOC_OPENCRYPTOLINUX_N_SLAVES), + .N_SLAVES(N_SLAVES + 2), .P_SLAVES(AddrMsb - 1) ) pbus_split ( .clk_i(clk_i), From 84a5c0201dbb1ff020bb7269ab02f8bcb536e910 Mon Sep 17 00:00:00 2001 From: Pedro Antunes Date: Thu, 21 Sep 2023 18:55:06 +0100 Subject: [PATCH 20/27] *: test CLINT firmware. --- hardware/src/iob2axil.v | 2 +- hardware/src/iob_soc_opencryptolinux.v | 33 +++--- iob_soc_opencryptolinux.py | 6 +- software/Makefile | 102 ++++++++++++++++++ software/src/iob-plic.c | 6 +- software/src/iob-plic.h | 2 +- .../src/iob_soc_opencryptolinux_firmware.c | 44 +++----- submodules/VEXRISCV | 2 +- 8 files changed, 144 insertions(+), 53 deletions(-) create mode 100644 software/Makefile diff --git a/hardware/src/iob2axil.v b/hardware/src/iob2axil.v index a5b0ae74..57cb0220 100644 --- a/hardware/src/iob2axil.v +++ b/hardware/src/iob2axil.v @@ -44,7 +44,7 @@ module iob2axil #( // assign iob_rvalid_o = axil_rvalid_i; assign iob_rdata_o = axil_rdata_i; - assign iob_ready_o = (iob_wstrb_i != {(DATA_W / 8) {1'b0}}) ? axil_wready_i : axil_arready_i; + assign iob_ready_o = (|iob_wstrb_i) ? axil_wready_i : axil_arready_i; // // COMPUTE AXIL OUTPUTS diff --git a/hardware/src/iob_soc_opencryptolinux.v b/hardware/src/iob_soc_opencryptolinux.v index c4464d94..6f9c6c1e 100644 --- a/hardware/src/iob_soc_opencryptolinux.v +++ b/hardware/src/iob_soc_opencryptolinux.v @@ -42,7 +42,7 @@ module iob_soc_opencryptolinux #( localparam DBUS_EXTMEM_AXI_ADDR_W = 32; localparam DBUS_EXTMEM_AXI_DATA_W = 32; - localparam N_SLAVES = `IOB_SOC_OPENCRYPTOLINUX_N_SLAVES; + localparam N_SLAVES = `IOB_SOC_OPENCRYPTOLINUX_N_SLAVES; // add 2 if using CPU PLIC and CLINT `include "iob_soc_opencryptolinux_pwires.vs" @@ -65,8 +65,8 @@ module iob_soc_opencryptolinux #( wire peripheral_iob_ready; //slaves bus (includes internal memory + periphrals) - wire [(N_SLAVES+2)*`REQ_W-1:0] slaves_req; - wire [(N_SLAVES+2)*`RESP_W-1:0] slaves_resp; + wire [(N_SLAVES)*`REQ_W-1:0] slaves_req; + wire [(N_SLAVES)*`RESP_W-1:0] slaves_resp; // // SYSTEM RESET @@ -84,7 +84,10 @@ module iob_soc_opencryptolinux #( // Axi data bus `include "dBus_axi_wire.vs" - assign cpu_trap_o = 1'b0; + assign cpu_trap_o = 1'b0; + + assign PLIC0_src = {{31{1'b0}}, uart_interrupt_o}; + assign CLINT0_rt_clk = 1'b0; //instantiate the cpu iob_VexRiscv #( @@ -92,20 +95,20 @@ module iob_soc_opencryptolinux #( .DATA_W (DATA_W), .USE_EXTMEM(1) ) cpu_0 ( - .clk_i (clk_i), - .cke_i (cke_i), - .arst_i (arst_i), - .cpu_reset_i (cpu_reset), - .clint_req (slaves_req[(N_SLAVES)*69+:`REQ_W]), - .clint_resp (slaves_resp[(N_SLAVES)*34+:`RESP_W]), - .plic_req (slaves_req[(N_SLAVES+1)*69+:`REQ_W]), - .plic_resp (slaves_resp[(N_SLAVES+1)*34+:`RESP_W]), - .plicInterrupts(32'd0), + .clk_i (clk_i), + .cke_i (cke_i), + .arst_i (arst_i), + .cpu_reset_i (cpu_reset), + // interupts + .timerInterrupt (CLINT0_mtip[0]), + .softwareInterrupt (CLINT0_msip[0]), + .externalInterrupt (PLIC0_irq[0]), + .externalInterruptS(PLIC0_irq[1]), // Axi instruction bus `include "iBus_axi_m_portmap.vs" // Axi data bus `include "dBus_axi_m_portmap.vs" - .boot_i (boot) + .boot_i (boot) ); @@ -429,7 +432,7 @@ module iob_soc_opencryptolinux #( iob_split #( .ADDR_W (ADDR_W), .DATA_W (DATA_W), - .N_SLAVES(N_SLAVES + 2), + .N_SLAVES(N_SLAVES), .P_SLAVES(AddrMsb - 1) ) pbus_split ( .clk_i(clk_i), diff --git a/iob_soc_opencryptolinux.py b/iob_soc_opencryptolinux.py index ee3cf4b8..0dfeb5f4 100755 --- a/iob_soc_opencryptolinux.py +++ b/iob_soc_opencryptolinux.py @@ -29,6 +29,8 @@ def _create_instances(cls): # Instantiate OpenCryptoLinux peripherals if iob_uart16550 in cls.submodule_list: cls.peripherals.append(iob_uart16550("UART0", "Default UART interface")) + if iob_clint in cls.submodule_list: + cls.peripherals.append(iob_clint("CLINT0", "CLINT peripheral")) if iob_plic in cls.submodule_list: cls.peripherals.append( iob_plic( @@ -37,8 +39,6 @@ def _create_instances(cls): parameters={"N_SOURCES": "32", "N_TARGETS": "2"}, ) ) - if iob_clint in cls.submodule_list: - cls.peripherals.append(iob_clint("CLINT0", "CLINT peripheral")) if iob_spi in cls.submodule_list: cls.peripherals.append(iob_spi("SPI0", "SPI master peripheral")) @@ -59,6 +59,8 @@ def _create_submodules_list(cls, extra_submodules=[]): {"interface": "iBus_axi_m_portmap"}, iob_vexriscv, iob_uart16550, + iob_clint, + iob_plic, # iob_spi, (iob_uart, {"purpose": "simulation"}), ] diff --git a/software/Makefile b/software/Makefile new file mode 100644 index 00000000..1a0b1e2a --- /dev/null +++ b/software/Makefile @@ -0,0 +1,102 @@ +# (c) 2022-Present IObundle, Lda, all rights reserved +# +# This makefile is used at build-time in $(BUILD_DIR)/software/Makefile +# + +include ../config_build.mk + +######################################### +# Embedded settings # +######################################### + +TEMPLATE_LDS ?=template.lds + +MFLAGS=rv32imac + +#default compiler settings +TOOLCHAIN_PREFIX ?=riscv64-unknown-elf- +CFLAGS ?=-Os -nostdlib -march=$(MFLAGS) -mabi=ilp32 --specs=nano.specs -Wcast-align=strict +LFLAGS ?= -Wl,-Bstatic,-T,$(TEMPLATE_LDS),--strip-debug +LLIBS ?=-lgcc -lc -lnosys +INCLUDES ?=-I. -Isrc + +######################################### +# PC emulation settings # +######################################### + +# compiler flags +EMUL_CFLAGS=-Os -std=gnu99 -Wl,--strip-debug + +CONSOLE_CMD=rm -f soc2cnsl cnsl2soc; ../scripts/console.py -L + +EMUL_INCLUDES=-I. -Isrc + +EMUL_HDR+=$(wildcard src/*_emul.h) + +EMUL_SRC+=$(wildcard src/*_emul.c) + +######################################### +# General settings # +######################################### + +# include local build segment +# all previously defined variables can be overwritten in this file +ifneq ($(wildcard sw_build.mk),) +include sw_build.mk +endif + +######################################### +# Embedded targets # +######################################### + +build: $(UTARGETS) +%.elf: $(TEMPLATE_LDS) $(HDR) $(SRC) + $(TOOLCHAIN_PREFIX)gcc -o $@ $(CFLAGS) $(LFLAGS) $(INCLUDES) $(SRC) $(LLIBS) + $(TOOLCHAIN_PREFIX)objcopy -O binary $@ $(*F).bin + +ifneq ($(BOARD),) +FPGA_TOOL:=$(shell find ../hardware/fpga -name $(BOARD) | cut -d"/" -f5) +endif + +debug: + @echo $(TEMPLATE_LDS) + @echo $(FW_SRC) + @echo $(BOOT_SRC) + @echo $(HDR) + +.PHONY: build debug + +######################################### +# PC emulation targets # +######################################### + +fw_emul: $(EMUL_HDR) $(EMUL_SRC) + gcc -o $@ $(EMUL_CFLAGS) $(EMUL_INCLUDES) $(EMUL_SRC) -lgcc -lc + +build_emul: fw_emul + @echo "build" + +#board client command +BOARD_GRAB_CMD=../scripts/board_client.py grab 300 + +run_emul: build_emul + $(BOARD_GRAB_CMD) -s './fw_emul' -c '$(CONSOLE_CMD)' + +test_emul: clean $(EMUL_TEST_LIST) + test "$$(cat test.log)" = "Test passed!" + +.PHONY: build_emul run_emul test_emul + +######################################### +# General targets # +######################################### + +# TODO add to iob-soc custom clean list +# CLEAN_LIST+= + +clean: $(CLEAN_LIST) + @rm -rf *.bin *.elf *.map *.hex + @rm -rf fw_emul test.log soc2cnsl cnsl2soc + @rm -rf *.txt + +.PHONY: clean diff --git a/software/src/iob-plic.c b/software/src/iob-plic.c index ebff46e6..9088a452 100644 --- a/software/src/iob-plic.c +++ b/software/src/iob-plic.c @@ -4,7 +4,7 @@ #include "riscv-csr.h" void plic_init(int base_address){ - base = base_address; + plic_base = base_address; int i = 0; //clear all EL @@ -22,10 +22,10 @@ void plic_init(int base_address){ plic_write((TH_BASE_ADDRESS+i)*DATA_W/8, 0); } void plic_write(int address, int data){ - (*(volatile uint32_t *) (base+address)) = (uint32_t)(data); + (*(volatile uint32_t *) (plic_base+address)) = (uint32_t)(data); } int plic_read(int address){ - return (uint64_t)(*(volatile uint32_t *) (base+address)); + return (uint64_t)(*(volatile uint32_t *) (plic_base+address)); } int plic_enable_interrupt(int source){ diff --git a/software/src/iob-plic.h b/software/src/iob-plic.h index 4b4573f2..3aa7434c 100644 --- a/software/src/iob-plic.h +++ b/software/src/iob-plic.h @@ -47,7 +47,7 @@ #define ID_BASE_ADDRESS (TH_BASE_ADDRESS+PTHRESHOLD_REGS) //Functions -static int base; +static int plic_base; void plic_init(int); void plic_write(int, int); int plic_read(int); diff --git a/software/src/iob_soc_opencryptolinux_firmware.c b/software/src/iob_soc_opencryptolinux_firmware.c index 5e04e032..78436acc 100644 --- a/software/src/iob_soc_opencryptolinux_firmware.c +++ b/software/src/iob_soc_opencryptolinux_firmware.c @@ -1,21 +1,21 @@ #include "bsp.h" -#include "iob-uart16550.h" #include "iob_soc_opencryptolinux_conf.h" #include "iob_soc_opencryptolinux_system.h" +#include "iob-clint.h" +#include "iob-plic.h" +#include "iob-uart16550.h" #include "iob_str.h" #include "printf.h" -#include "iob-plic.h" -#include "iob-clint.h" #include "riscv-csr.h" #include "riscv-interrupts.h" #define UART0_BASE 0xfa000000 -#define PLIC0_BASE 0xfc000000 -#define CLINT0_BASE 0xfe000000 +#define CLINT0_BASE 0xfc000000 +#define PLIC0_BASE 0xfe000000 // Machine mode interrupt service routine -static void irq_entry(void) __attribute__ ((interrupt ("machine"))); +static void irq_entry(void) __attribute__((interrupt("machine"))); // Global to hold current timestamp static volatile uint64_t timestamp = 0; @@ -26,7 +26,7 @@ int main() { //init uart uart16550_init(UART0_BASE, FREQ/(16*BAUD)); clint_init(CLINT0_BASE); - plic_init(PLIC0_BASE); + //plic_init(PLIC0_BASE); printf_init(&uart16550_putc); printf("\n\n\nHello world!\n\n\n"); @@ -39,32 +39,27 @@ int main() { // Setup timer for 1 second interval timestamp = mtimer_get_raw_time(); - mtimer_set_raw_time_cmp(MTIMER_SECONDS_TO_CLOCKS(0.03)); + mtimer_set_raw_time_cmp(MTIMER_SECONDS_TO_CLOCKS(0.001)); // Setup the IRQ handler entry point csr_write_mtvec((uint_xlen_t) irq_entry); - // Enable MIE.MTI and MIE.MEI + // Enable MIE.MTI csr_set_bits_mie(MIE_MTI_BIT_MASK); - csr_set_bits_mie(MIE_MEI_BIT_MASK); + printf("\nBUGED\n"); // Global interrupt enable csr_set_bits_mstatus(MSTATUS_MIE_BIT_MASK); + printf("\nBUGED\n"); - // Enable PLIC interrupt for UART - printf("Enabling external interrupt source 0 with ID = 1.\n"); - int target; - target = plic_enable_interrupt(0); - - printf("HART id %d, waiting for timer interrupt...\n", target); + printf("Waiting...\n"); // Wait for interrupt __asm__ volatile ("wfi"); - uart16550_sendfile("test.log", iob_strlen(pass_string), pass_string); - printf("Exit...\n"); uart16550_finish(); return 0; + } #pragma GCC push_options @@ -82,19 +77,8 @@ static void irq_entry(void) { // Timer exception, keep up the one second tick. mtimer_set_raw_time_cmp(MTIMER_SECONDS_TO_CLOCKS(1)); timestamp = mtimer_get_raw_time(); - float aux = (float)timestamp/MTIME_FREQ_HZ; - printf("Current time passed: %.3f seconds.\n", aux); - printf("MTIMER register value: %lld.\n", timestamp); - break; - case RISCV_INT_POS_MEI : - printf("External interrupt.\n"); - int source_id = 0; - source_id = plic_claim_interrupt(); - printf("External interrupt ID received was: %d.\n", source_id); - plic_complete_interrupt(source_id); - plic_disable_interrupt(source_id); break; } } } -#pragma GCC pop_options \ No newline at end of file +#pragma GCC pop_options diff --git a/submodules/VEXRISCV b/submodules/VEXRISCV index 88a6af07..2252e7d2 160000 --- a/submodules/VEXRISCV +++ b/submodules/VEXRISCV @@ -1 +1 @@ -Subproject commit 88a6af07d7589c69e519e850d513177af1b7f3db +Subproject commit 2252e7d2d6a24929f49201c7c87e73045474539e From 0b7f393d7f1256f45804f95f8b6124f89b9d4064 Mon Sep 17 00:00:00 2001 From: Pedro Antunes Date: Tue, 10 Oct 2023 19:10:26 +0100 Subject: [PATCH 21/27] software/src/*: use SpinalHDL PLIC and CLINT firmware. --- hardware/simulation/bsp.vh | 3 +- hardware/src/iob_soc_opencryptolinux.v | 27 +++--- iob_soc_opencryptolinux.py | 2 - software/src/clint.h | 37 ++++++++ software/src/io.h | 34 +++++++ software/src/iob-clint.c | 89 ------------------- software/src/iob-clint.h | 39 -------- software/src/iob-plic.c | 63 ------------- software/src/iob-plic.h | 60 ------------- .../src/iob_soc_opencryptolinux_firmware.c | 23 ++--- software/src/plic.h | 40 +++++++++ software/src/riscv-csr.h | 8 -- software/src/soc.h | 45 ++++++++++ software/src/type.h | 51 +++++++++++ submodules/LIB | 2 +- 15 files changed, 233 insertions(+), 290 deletions(-) create mode 100644 software/src/clint.h create mode 100644 software/src/io.h delete mode 100644 software/src/iob-clint.c delete mode 100644 software/src/iob-clint.h delete mode 100644 software/src/iob-plic.c delete mode 100644 software/src/iob-plic.h create mode 100644 software/src/plic.h create mode 100644 software/src/soc.h create mode 100644 software/src/type.h diff --git a/hardware/simulation/bsp.vh b/hardware/simulation/bsp.vh index c1773d23..8fc823e8 100644 --- a/hardware/simulation/bsp.vh +++ b/hardware/simulation/bsp.vh @@ -1,4 +1,5 @@ -`define BAUD 1000000 +//`define BAUD 115200 +`define BAUD 2000000 `define FREQ 100000000 `define DDR_DATA_W 32 `define DDR_ADDR_W 26 diff --git a/hardware/src/iob_soc_opencryptolinux.v b/hardware/src/iob_soc_opencryptolinux.v index 6f9c6c1e..e1df1dd8 100644 --- a/hardware/src/iob_soc_opencryptolinux.v +++ b/hardware/src/iob_soc_opencryptolinux.v @@ -42,7 +42,7 @@ module iob_soc_opencryptolinux #( localparam DBUS_EXTMEM_AXI_ADDR_W = 32; localparam DBUS_EXTMEM_AXI_DATA_W = 32; - localparam N_SLAVES = `IOB_SOC_OPENCRYPTOLINUX_N_SLAVES; // add 2 if using CPU PLIC and CLINT + localparam N_SLAVES = `IOB_SOC_OPENCRYPTOLINUX_N_SLAVES+2; // add 2 if using CPU PLIC and CLINT `include "iob_soc_opencryptolinux_pwires.vs" @@ -84,31 +84,26 @@ module iob_soc_opencryptolinux #( // Axi data bus `include "dBus_axi_wire.vs" - assign cpu_trap_o = 1'b0; - - assign PLIC0_src = {{31{1'b0}}, uart_interrupt_o}; - assign CLINT0_rt_clk = 1'b0; - //instantiate the cpu iob_VexRiscv #( .ADDR_W (ADDR_W), .DATA_W (DATA_W), .USE_EXTMEM(1) ) cpu_0 ( - .clk_i (clk_i), - .cke_i (cke_i), - .arst_i (arst_i), - .cpu_reset_i (cpu_reset), - // interupts - .timerInterrupt (CLINT0_mtip[0]), - .softwareInterrupt (CLINT0_msip[0]), - .externalInterrupt (PLIC0_irq[0]), - .externalInterruptS(PLIC0_irq[1]), + .clk_i (clk_i), + .cke_i (cke_i), + .arst_i (arst_i), + .cpu_reset_i (cpu_reset), + .clint_req (slaves_req[(N_SLAVES-2)*69+:`REQ_W]), + .clint_resp (slaves_resp[(N_SLAVES-2)*34+:`RESP_W]), + .plic_req (slaves_req[(N_SLAVES-1)*69+:`REQ_W]), + .plic_resp (slaves_resp[(N_SLAVES-1)*34+:`RESP_W]), + .plicInterrupts(32'd0), // Axi instruction bus `include "iBus_axi_m_portmap.vs" // Axi data bus `include "dBus_axi_m_portmap.vs" - .boot_i (boot) + .boot_i (boot) ); diff --git a/iob_soc_opencryptolinux.py b/iob_soc_opencryptolinux.py index 0dfeb5f4..a2659f97 100755 --- a/iob_soc_opencryptolinux.py +++ b/iob_soc_opencryptolinux.py @@ -59,8 +59,6 @@ def _create_submodules_list(cls, extra_submodules=[]): {"interface": "iBus_axi_m_portmap"}, iob_vexriscv, iob_uart16550, - iob_clint, - iob_plic, # iob_spi, (iob_uart, {"purpose": "simulation"}), ] diff --git a/software/src/clint.h b/software/src/clint.h new file mode 100644 index 00000000..31ae74c1 --- /dev/null +++ b/software/src/clint.h @@ -0,0 +1,37 @@ +#pragma once + +#include "io.h" +#include "type.h" + +#define CLINT_IPI_ADDR 0x0000 +#define CLINT_CMP_ADDR 0x4000 +#define CLINT_TIME_ADDR 0xBFF8 + +readReg_u32(clint_getTimeLow, CLINT_TIME_ADDR) +readReg_u32(clint_getTimeHigh, CLINT_TIME_ADDR + 4) + +static void clint_setCmp(u32 p, u64 cmp, u32 hart_id) { + p += CLINT_CMP_ADDR + hart_id * 8; + write_u32(0xFFFFFFFF, p + 4); + write_u32(cmp, p + 0); + write_u32(cmp >> 32, p + 4); +} + +static u64 clint_getTime(u32 p) { + u32 lo, hi; + + /* Likewise, must guard against rollover when reading */ + do { + hi = clint_getTimeHigh(p); + lo = clint_getTimeLow(p); + } while (clint_getTimeHigh(p) != hi); + + return (((u64)hi) << 32) | lo; +} + +static void clint_uDelay(u32 usec, u32 hz, u32 reg) { + u32 mTimePerUsec = hz / 1000000; + u32 limit = clint_getTimeLow(reg) + usec * mTimePerUsec; + while ((int32_t)(limit - (clint_getTimeLow(reg))) >= 0) + ; +} \ No newline at end of file diff --git a/software/src/io.h b/software/src/io.h new file mode 100644 index 00000000..f6f165a9 --- /dev/null +++ b/software/src/io.h @@ -0,0 +1,34 @@ +#pragma once + +#include "soc.h" +#include "type.h" + +static inline u32 read_u32(u32 address) { return *((volatile u32 *)address); } + +static inline void write_u32(u32 data, u32 address) { + *((volatile u32 *)address) = data; +} + +static inline u16 read_u16(u32 address) { return *((volatile u16 *)address); } + +static inline void write_u16(u16 data, u32 address) { + *((volatile u16 *)address) = data; +} + +static inline u8 read_u8(u32 address) { return *((volatile u8 *)address); } + +static inline void write_u8(u8 data, u32 address) { + *((volatile u8 *)address) = data; +} + +static inline void write_u32_ad(u32 address, u32 data) { + *((volatile u32 *)address) = data; +} + +#define writeReg_u32(name, offset) \ + static inline void name(u32 reg, u32 value) { \ + write_u32(value, reg + offset); \ + } + +#define readReg_u32(name, offset) \ + static inline u32 name(u32 reg) { return read_u32(reg + offset); }\ diff --git a/software/src/iob-clint.c b/software/src/iob-clint.c deleted file mode 100644 index 25aa2607..00000000 --- a/software/src/iob-clint.c +++ /dev/null @@ -1,89 +0,0 @@ -#include "iob-clint.h" - -void clint_init(int base_address){ - clint_base = base_address; -} - -void clint_set_timer(unsigned long long time){ - (*(volatile uint32_t *) (clint_base + MTIME_BASE)) = (uint32_t)(time & 0x0FFFFFFFFUL); - (*(volatile uint32_t *) (clint_base + MTIME_BASE + 4)) = (uint32_t)(time >> 32); -} - -uint64_t clint_get_timer(){ - uint64_t read_time; - - read_time = (uint64_t)(*(volatile uint32_t *) (clint_base + MTIME_BASE)); - read_time |= (uint64_t)(*(volatile uint32_t *) (clint_base + MTIME_BASE + 4)) << 32; - - return read_time; -} - -void clint_set_timercmp(unsigned long long time, int hart){ - (*(volatile uint32_t *) (clint_base + MTIMECMP_BASE + 8*hart + 4)) = 0xFFFFFFFF; - (*(volatile uint32_t *) (clint_base + MTIMECMP_BASE + 8*hart)) = (uint32_t)(time & 0x0FFFFFFFFUL); - (*(volatile uint32_t *) (clint_base + MTIMECMP_BASE + 8*hart + 4)) = (uint32_t)(time >> 32); -} - -uint64_t clint_get_timercmp(int hart){ - uint64_t read_time; - - read_time = (uint64_t)(*(volatile uint32_t *) (clint_base + MTIMECMP_BASE + 8*hart)); - read_time |= (uint64_t)(*(volatile uint32_t *) (clint_base + MTIMECMP_BASE + 8*hart + 4)) << 32; - - return read_time; -} - -void clint_set_msip(unsigned long msip_value, int hart){ - (*(volatile uint32_t *) (clint_base + MSIP_BASE + 4*hart)) = msip_value; -} - -uint32_t clint_get_msip(int hart){ - uint32_t msip_value; - - msip_value = (*(volatile uint32_t *) (clint_base + MSIP_BASE + 4*hart)); - - return msip_value; -} - -void mtimer_set_raw_time_cmp(uint64_t clock_offset) { - // First of all set - uint64_t new_mtimecmp = mtimer_get_raw_time() + clock_offset; -#if (__riscv_xlen == 64) - // Single bus access - volatile uint64_t *mtimecmp = (volatile uint64_t*)(clint_base+MTIMECMP_BASE); - *mtimecmp = new_mtimecmp; -#else - volatile uint32_t *mtimecmpl = (volatile uint32_t *)(clint_base+MTIMECMP_BASE); - volatile uint32_t *mtimecmph = (volatile uint32_t *)(clint_base+MTIMECMP_BASE+4); - // AS we are doing 32 bit writes, an intermediate mtimecmp value may cause spurious interrupts. - // Prevent that by first setting the dummy MSB to an unacheivable value - *mtimecmph = 0xFFFFFFFF; // cppcheck-suppress redundantAssignment - // set the LSB - *mtimecmpl = (uint32_t)(new_mtimecmp & 0x0FFFFFFFFUL); - // Set the correct MSB - *mtimecmph = (uint32_t)(new_mtimecmp >> 32); // cppcheck-suppress redundantAssignment -#endif -} - -/** Read the raw time of the system timer in system timer clocks - */ -uint64_t mtimer_get_raw_time(void) { -#if ( __riscv_xlen == 64) - // Directly read 64 bit value - volatile uint64_t *mtime = (volatile uint64_t *)(clint_base+MTIME_BASE); - return *mtime; -#else - volatile uint32_t * mtimel = (volatile uint32_t *)(clint_base+MTIME_BASE); - volatile uint32_t * mtimeh = (volatile uint32_t *)(clint_base+MTIME_BASE+4); - uint32_t mtimeh_val; - uint32_t mtimel_val; - do { - // There is a small risk the mtimeh will tick over after reading mtimel - mtimeh_val = *mtimeh; - mtimel_val = *mtimel; - // Poll mtimeh to ensure it's consistent after reading mtimel - // The frequency of mtimeh ticking over is low - } while (mtimeh_val != *mtimeh); - return (uint64_t) ( ( ((uint64_t)mtimeh_val)<<32) | mtimel_val); -#endif -} diff --git a/software/src/iob-clint.h b/software/src/iob-clint.h deleted file mode 100644 index 6871fe92..00000000 --- a/software/src/iob-clint.h +++ /dev/null @@ -1,39 +0,0 @@ -#ifndef CLINT_H -#define CLINT_H - -#include - -#define MSIP_BASE 0 -#define MTIMECMP_BASE 0x4000 -#define MTIME_BASE 0xBFF8 - -#define MTIME_FREQ_HZ 100000 - -#define MTIMER_SECONDS_TO_CLOCKS(SEC) \ - ((uint64_t)(((SEC)*(MTIME_FREQ_HZ)))) - -//Functions -static int clint_base; -void clint_init(int); - -void clint_set_timer(unsigned long long); -void clint_set_timercmp(unsigned long long, int); -void clint_set_msip(unsigned long, int); - -uint64_t clint_get_timer(); -uint64_t clint_get_timercmp(int); -uint32_t clint_get_msip(int); - -/** Set the raw time compare point in system timer clocks. - * @param clock_offset Time relative to current mtime when - * @note The time range of the 64 bit timer is large enough not to consider a wrap around of mtime. - * An interrupt will be generated at mtime + clock_offset. - * See http://five-embeddev.com/riscv-isa-manual/latest/machine.html#machine-timer-registers-mtime-and-mtimecmp - */ -void mtimer_set_raw_time_cmp(uint64_t clock_offset); - -/** Read the raw time of the system timer in system timer clocks - */ -uint64_t mtimer_get_raw_time(void); - -#endif // #ifdef CLINT_H diff --git a/software/src/iob-plic.c b/software/src/iob-plic.c deleted file mode 100644 index 9088a452..00000000 --- a/software/src/iob-plic.c +++ /dev/null @@ -1,63 +0,0 @@ -#include - -#include "iob-plic.h" -#include "riscv-csr.h" - -void plic_init(int base_address){ - plic_base = base_address; - - int i = 0; - //clear all EL - for (i=0; i < EDGE_LEVEL_REGS; i++) - plic_write((EL_BASE_ADDRESS+i)*DATA_W/8, 0); - //set priority for all sources to '1'; '0' means 'never interrupt' - int write_pr = write_pr_regs(); - for (i=0; i < PRIORITY_REGS; i++) - plic_write((PR_BASE_ADDRESS+i)*DATA_W/8, write_pr); - //clear all IE - for (i=0; i < IE_REGS; i++) - plic_write((IE_BASE_ADDRESS+i)*DATA_W/8, 0); - //set all threshold to '0' - for (i=0; i < PTHRESHOLD_REGS; i++) - plic_write((TH_BASE_ADDRESS+i)*DATA_W/8, 0); -} -void plic_write(int address, int data){ - (*(volatile uint32_t *) (plic_base+address)) = (uint32_t)(data); -} -int plic_read(int address){ - return (uint64_t)(*(volatile uint32_t *) (plic_base+address)); -} - -int plic_enable_interrupt(int source){ - int target; - target = csr_read_mhartid(); - plic_write((IE_BASE_ADDRESS+(target*EDGE_LEVEL_REGS)+(source/DATA_W))*DATA_W/8, 1 << (source % DATA_W)); - return target; -} -int plic_disable_interrupt(int source){ - int target; - target = csr_read_mhartid(); - plic_write((IE_BASE_ADDRESS+(target*EDGE_LEVEL_REGS)+(source/DATA_W))*DATA_W/8, 0); - return target; -} -/* Returns interrupt ID */ -int plic_claim_interrupt(){ - int target; - target = csr_read_mhartid(); - return plic_read((ID_BASE_ADDRESS + target) * DATA_W/8); -} -/* Sends complete signal to PLIC */ -void plic_complete_interrupt(int source_id){ - int target; - target = csr_read_mhartid(); - plic_write((ID_BASE_ADDRESS + target) * DATA_W/8, 1 << (source_id % DATA_W)); -} - -int write_pr_regs(){ - int res = 0; - int i = 0; - for (i = 0; i < PRIORITY_FIELDS_PER_REG; i++) { - res = (res << (DATA_W/8)*PRIORITY_NIBBLES) | 0x01; - } - return res; -} diff --git a/software/src/iob-plic.h b/software/src/iob-plic.h deleted file mode 100644 index 3aa7434c..00000000 --- a/software/src/iob-plic.h +++ /dev/null @@ -1,60 +0,0 @@ -#pragma once - -#define DATA_W 32 - -#ifndef N_SOURCES -#define N_SOURCES 32 -#endif - -#ifndef N_TARGETS -#define N_TARGETS 1 -#endif - -#define PRIORITY_BITS 3 //$clog2(PRIORITIES); PRIORITIES = 8; -#define HAS_THRESHOLD 1 -#define HAS_CONFIG_REG 1 -//Configuration Bits -#define MAX_SOURCES_BITS 16 -#define MAX_TARGETS_BITS 16 -#define MAX_PRIORITY_BITS MAX_SOURCES_BITS -#define HAS_THRESHOLD_BITS 1 -//How many CONFIG registers are there (only 1) -#define CONFIG_REGS (HAS_CONFIG_REG == 0 ? 0 : ((MAX_SOURCES_BITS + MAX_TARGETS_BITS + MAX_PRIORITY_BITS + HAS_THRESHOLD_BITS + DATA_W -1)/DATA_W)) -//Amount of Edge/Level registers -#define EDGE_LEVEL_REGS ((N_SOURCES + DATA_W -1) / DATA_W) -//Amount of Interrupt Enable registers -#define IE_REGS (EDGE_LEVEL_REGS * N_TARGETS) -//Each PRIORITY field starts at a new nibble boundary -//Get the number of nibbles in 'PRIORITY_BITS' ? -#define PRIORITY_NIBBLES ((PRIORITY_BITS +3 -1) / 4) -//How many PRIORITY fields fit in 1 register? -#define PRIORITY_FIELDS_PER_REG (DATA_W / (PRIORITY_NIBBLES*4)) -//Amount of Priority registers -#define PRIORITY_REGS ((N_SOURCES + PRIORITY_FIELDS_PER_REG -1) / PRIORITY_FIELDS_PER_REG) -//Amount of Threshold registers -#define PTHRESHOLD_REGS (HAS_THRESHOLD == 0 ? 0 : N_TARGETS) -//Amount of ID registers -#define ID_REGS N_TARGETS -//Total amount of registers -#define TOTAL_REGS (CONFIG_REGS + EDGE_LEVEL_REGS + IE_REGS + PRIORITY_REGS + PTHRESHOLD_REGS + ID_REGS) - - -//Set base register addresses ... -#define EL_BASE_ADDRESS CONFIG_REGS -#define PR_BASE_ADDRESS (EL_BASE_ADDRESS+EDGE_LEVEL_REGS) -#define IE_BASE_ADDRESS (PR_BASE_ADDRESS+PRIORITY_REGS) -#define TH_BASE_ADDRESS (IE_BASE_ADDRESS+IE_REGS) -#define ID_BASE_ADDRESS (TH_BASE_ADDRESS+PTHRESHOLD_REGS) - -//Functions -static int plic_base; -void plic_init(int); -void plic_write(int, int); -int plic_read(int); - -int plic_enable_interrupt(int); -int plic_disable_interrupt(int); -int plic_claim_interrupt(); -void plic_complete_interrupt(int); - -int write_pr_regs(); diff --git a/software/src/iob_soc_opencryptolinux_firmware.c b/software/src/iob_soc_opencryptolinux_firmware.c index 78436acc..0179d25d 100644 --- a/software/src/iob_soc_opencryptolinux_firmware.c +++ b/software/src/iob_soc_opencryptolinux_firmware.c @@ -1,8 +1,8 @@ #include "bsp.h" #include "iob_soc_opencryptolinux_conf.h" #include "iob_soc_opencryptolinux_system.h" -#include "iob-clint.h" -#include "iob-plic.h" +#include "clint.h" +#include "plic.h" #include "iob-uart16550.h" #include "iob_str.h" #include "printf.h" @@ -22,11 +22,10 @@ static volatile uint64_t timestamp = 0; int main() { char pass_string[] = "Test passed!"; + uint_xlen_t irq_entry_copy; //init uart uart16550_init(UART0_BASE, FREQ/(16*BAUD)); - clint_init(CLINT0_BASE); - //plic_init(PLIC0_BASE); printf_init(&uart16550_putc); printf("\n\n\nHello world!\n\n\n"); @@ -38,19 +37,20 @@ int main() { csr_write_mcause(0); // Setup timer for 1 second interval - timestamp = mtimer_get_raw_time(); - mtimer_set_raw_time_cmp(MTIMER_SECONDS_TO_CLOCKS(0.001)); + timestamp = clint_getTime(CLINT0_BASE); + clint_setCmp(CLINT0_BASE, timestamp*2, 0); + printf("%x\n", (uint_xlen_t) irq_entry); // Setup the IRQ handler entry point csr_write_mtvec((uint_xlen_t) irq_entry); + irq_entry_copy = csr_read_mtvec(); + printf("%x\n", (uint_xlen_t) irq_entry_copy); // Enable MIE.MTI csr_set_bits_mie(MIE_MTI_BIT_MASK); - printf("\nBUGED\n"); // Global interrupt enable csr_set_bits_mstatus(MSTATUS_MIE_BIT_MASK); - printf("\nBUGED\n"); printf("Waiting...\n"); // Wait for interrupt @@ -67,7 +67,8 @@ int main() { #pragma GCC optimize ("align-functions=4") static void irq_entry(void) { printf("Entered IRQ.\n"); - uint_xlen_t this_cause = csr_read_mcause(); + uint32_t this_cause = csr_read_mcause(); + timestamp = clint_getTime(CLINT0_BASE); if (this_cause & MCAUSE_INTERRUPT_BIT_MASK) { this_cause &= 0xFF; // Known exceptions @@ -75,8 +76,8 @@ static void irq_entry(void) { case RISCV_INT_POS_MTI : printf("Time interrupt.\n"); // Timer exception, keep up the one second tick. - mtimer_set_raw_time_cmp(MTIMER_SECONDS_TO_CLOCKS(1)); - timestamp = mtimer_get_raw_time(); + clint_setCmp(CLINT0_BASE, timestamp*2, 0); + timestamp = clint_getTime(CLINT0_BASE); break; } } diff --git a/software/src/plic.h b/software/src/plic.h new file mode 100644 index 00000000..12c4a251 --- /dev/null +++ b/software/src/plic.h @@ -0,0 +1,40 @@ +#pragma once + +#include "io.h" +#include "type.h" + +#define PLIC_PRIORITY_BASE 0x0000 +#define PLIC_PENDING_BASE 0x1000 +#define PLIC_ENABLE_BASE 0x2000 +#define PLIC_THRESHOLD_BASE 0x200000 +#define PLIC_CLAIM_BASE 0x200004 + +#define PLIC_ENABLE_PER_HART 0x80 +#define PLIC_CONTEXT_PER_HART 0x1000 + +static void plic_set_priority(u32 plic, u32 gateway, u32 priority) { + write_u32(priority, plic + PLIC_PRIORITY_BASE + gateway * 4); +} + +static void plic_set_enable(u32 plic, u32 target, u32 gateway, u32 enable) { + u32 word = plic + PLIC_ENABLE_BASE + target * PLIC_ENABLE_PER_HART + + (gateway / 32 * 4); + u32 mask = 1 << (gateway % 32); + if (enable) + write_u32(read_u32(word) | mask, word); + else + write_u32(read_u32(word) & ~mask, word); +} + +static void plic_set_threshold(u32 plic, u32 target, u32 threshold) { + write_u32(threshold, + plic + PLIC_THRESHOLD_BASE + target * PLIC_CONTEXT_PER_HART); +} + +static u32 plic_claim(u32 plic, u32 target) { + return read_u32(plic + PLIC_CLAIM_BASE + target * PLIC_CONTEXT_PER_HART); +} + +static void plic_release(u32 plic, u32 target, u32 gateway) { + write_u32(gateway, plic + PLIC_CLAIM_BASE + target * PLIC_CONTEXT_PER_HART); +} \ No newline at end of file diff --git a/software/src/riscv-csr.h b/software/src/riscv-csr.h index 1dc58bf1..f0da41f6 100644 --- a/software/src/riscv-csr.h +++ b/software/src/riscv-csr.h @@ -11,17 +11,9 @@ #include -#if __riscv_xlen==32 typedef uint32_t uint_xlen_t; typedef uint32_t uint_csr32_t; typedef uint32_t uint_csr64_t; -#elif __riscv_xlen==64 -typedef uint64_t uint_xlen_t; -typedef uint32_t uint_csr32_t; -typedef uint64_t uint_csr64_t; -#else -#error "Unknown XLEN" -#endif /******************************************* * misa - MRW - Machine ISA diff --git a/software/src/soc.h b/software/src/soc.h new file mode 100644 index 00000000..b71e4fca --- /dev/null +++ b/software/src/soc.h @@ -0,0 +1,45 @@ +#ifndef SOC_H +#define SOC_H +#define SYSTEM_RAM_A_SIZE 4096 +#define SYSTEM_DPR_SIZE 1024 +#define SYSTEM__BUS16_SIZE 4096 +#define SYSTEM__BUS32_SIZE 4096 +#define SYSTEM_CLINT_HZ 19960000 +#define SYSTEM_UART_A_PARAMETER_UART_CTRL_CONFIG_DATA_WIDTH_MAX 8 +#define SYSTEM_UART_A_PARAMETER_UART_CTRL_CONFIG_CLOCK_DIVIDER_WIDTH 12 +#define SYSTEM_UART_A_PARAMETER_UART_CTRL_CONFIG_PRE_SAMPLING_SIZE 1 +#define SYSTEM_UART_A_PARAMETER_UART_CTRL_CONFIG_SAMPLING_SIZE 3 +#define SYSTEM_UART_A_PARAMETER_UART_CTRL_CONFIG_POST_SAMPLING_SIZE 1 +#define SYSTEM_UART_A_PARAMETER_UART_CTRL_CONFIG_CTS_GEN 0 +#define SYSTEM_UART_A_PARAMETER_UART_CTRL_CONFIG_RTS_GEN 0 +#define SYSTEM_UART_A_PARAMETER_UART_CTRL_CONFIG_RX_SAMPLE_PER_BIT 5 +#define SYSTEM_UART_A_PARAMETER_INIT_CONFIG_BAUDRATE 115200 +#define SYSTEM_UART_A_PARAMETER_INIT_CONFIG_DATA_LENGTH 7 +#define SYSTEM_UART_A_PARAMETER_INIT_CONFIG_PARITY NONE +#define SYSTEM_UART_A_PARAMETER_INIT_CONFIG_STOP ONE +#define SYSTEM_UART_A_PARAMETER_BUS_CAN_WRITE_CLOCK_DIVIDER_CONFIG 0 +#define SYSTEM_UART_A_PARAMETER_BUS_CAN_WRITE_FRAME_CONFIG 0 +#define SYSTEM_UART_A_PARAMETER_TX_FIFO_DEPTH 1 +#define SYSTEM_UART_A_PARAMETER_RX_FIFO_DEPTH 1 +#define SYSTEM_CPU_CFU 0 +#define SYSTEM_CPU_FPU 0 +#define SYSTEM_CPU_D_BUS 0x0 +#define SYSTEM_RAM_A_CTRL 0x8000 +#define SYSTEM_RAM_A_CTRL_SIZE 0x1000 +#define SYSTEM_PERIPH_BRIDGE_BMB 0x10000000 +#define SYSTEM_PERIPH_BRIDGE_BMB_SIZE 0x20000 +#define SYSTEM_CLINT_CTRL 0x10000000 +#define SYSTEM_CLINT_CTRL_SIZE 0x10000 +#define SYSTEM_GPIO_A_CTRL 0x10010000 +#define SYSTEM_GPIO_A_CTRL_SIZE 0x100 +#define SYSTEM_UART_A_CTRL 0x10010100 +#define SYSTEM_UART_A_CTRL_SIZE 0x40 +#define SYSTEM_D_BUS16_BMB 0x0 +#define SYSTEM_D_BUS16_BMB_SIZE 0x2000 +#define SYSTEM_DPR_CTRL 0x0 +#define SYSTEM_DPR_CTRL_SIZE 0x400 +#define SYSTEM__BUS16_CTRL 0x1000 +#define SYSTEM__BUS16_CTRL_SIZE 0x1000 +#define SYSTEM__BUS32_CTRL 0x2000 +#define SYSTEM__BUS32_CTRL_SIZE 0x1000 +#endif diff --git a/software/src/type.h b/software/src/type.h new file mode 100644 index 00000000..241bb92a --- /dev/null +++ b/software/src/type.h @@ -0,0 +1,51 @@ +#ifndef TYPE_H +#define TYPE_H + +#include + +typedef uint64_t u64; +typedef int64_t s64; + +typedef uint32_t u32; +typedef int32_t s32; + +typedef uint16_t u16; +typedef int16_t s16; + +typedef uint8_t u8; +typedef int8_t s8; + +#define BIT_0 (1 << 0) +#define BIT_1 (1 << 1) +#define BIT_2 (1 << 2) +#define BIT_3 (1 << 3) +#define BIT_4 (1 << 4) +#define BIT_5 (1 << 5) +#define BIT_6 (1 << 6) +#define BIT_7 (1 << 7) +#define BIT_8 (1 << 8) +#define BIT_9 (1 << 9) +#define BIT_10 (1 << 10) +#define BIT_11 (1 << 11) +#define BIT_12 (1 << 12) +#define BIT_13 (1 << 13) +#define BIT_14 (1 << 14) +#define BIT_15 (1 << 15) +#define BIT_16 (1 << 16) +#define BIT_17 (1 << 17) +#define BIT_18 (1 << 18) +#define BIT_19 (1 << 19) +#define BIT_20 (1 << 20) +#define BIT_21 (1 << 21) +#define BIT_22 (1 << 22) +#define BIT_23 (1 << 23) +#define BIT_24 (1 << 24) +#define BIT_25 (1 << 25) +#define BIT_26 (1 << 26) +#define BIT_27 (1 << 27) +#define BIT_28 (1 << 28) +#define BIT_29 (1 << 29) +#define BIT_30 (1 << 30) +#define BIT_31 (1 << 31) + +#endif diff --git a/submodules/LIB b/submodules/LIB index 832d78df..6077072d 160000 --- a/submodules/LIB +++ b/submodules/LIB @@ -1 +1 @@ -Subproject commit 832d78dfcd1383be33d5d4aea2335a370ff341a4 +Subproject commit 6077072d5fa6035aba8656ff59b8627ec6a8021a From 97ea48c3f1518cd9f2583f47db2b8fec3e7edd03 Mon Sep 17 00:00:00 2001 From: Pedro Antunes Date: Fri, 13 Oct 2023 14:05:48 +0100 Subject: [PATCH 22/27] software/*: firmware is compiled corectly. --- iob_soc_opencryptolinux.py | 8 ++ software/src/io.h | 2 +- software/src/iob_soc_opencryptolinux_boot.c | 2 + software/src/iob_soc_opencryptolinux_boot.lds | 12 +++ .../src/iob_soc_opencryptolinux_firmware.S | 30 +++--- .../src/iob_soc_opencryptolinux_firmware.c | 99 ++++++++++--------- .../src/iob_soc_opencryptolinux_firmware.lds | 36 +++++++ submodules/IOBSOC | 2 +- submodules/LIB | 2 +- submodules/VEXRISCV | 2 +- 10 files changed, 127 insertions(+), 68 deletions(-) create mode 100644 software/src/iob_soc_opencryptolinux_boot.lds create mode 100644 software/src/iob_soc_opencryptolinux_firmware.lds diff --git a/iob_soc_opencryptolinux.py b/iob_soc_opencryptolinux.py index a2659f97..84562019 100755 --- a/iob_soc_opencryptolinux.py +++ b/iob_soc_opencryptolinux.py @@ -131,6 +131,14 @@ def _setup_confs(cls, extra_confs=[]): "max": "32", "descr": "Boot ROM address width", }, + { + "name": "SRAM_ADDR_W", + "type": "P", + "val": "20", + "min": "1", + "max": "32", + "descr": "SRAM address width", + }, { "name": "MEM_ADDR_W", "type": "P", diff --git a/software/src/io.h b/software/src/io.h index f6f165a9..b123c4ec 100644 --- a/software/src/io.h +++ b/software/src/io.h @@ -31,4 +31,4 @@ static inline void write_u32_ad(u32 address, u32 data) { } #define readReg_u32(name, offset) \ - static inline u32 name(u32 reg) { return read_u32(reg + offset); }\ + static inline u32 name(u32 reg) { return read_u32(reg + offset); } diff --git a/software/src/iob_soc_opencryptolinux_boot.c b/software/src/iob_soc_opencryptolinux_boot.c index d741a7e9..1c7ed8b3 100644 --- a/software/src/iob_soc_opencryptolinux_boot.c +++ b/software/src/iob_soc_opencryptolinux_boot.c @@ -2,10 +2,12 @@ #include "iob-uart16550.h" #include "iob_soc_opencryptolinux_conf.h" #include "iob_soc_opencryptolinux_system.h" +#include "clint.h" // defined here (and not in periphs.h) because it is the only peripheral used // by the bootloader #define UART0_BASE 0xfa000000 +#define CLINT0_BASE 0xfc000000 #define PROGNAME "IOb-Bootloader" diff --git a/software/src/iob_soc_opencryptolinux_boot.lds b/software/src/iob_soc_opencryptolinux_boot.lds new file mode 100644 index 00000000..db07578b --- /dev/null +++ b/software/src/iob_soc_opencryptolinux_boot.lds @@ -0,0 +1,12 @@ +SECTIONS { + /* Program code */ + . = 0x00000000; + .memory : { + *(.init); + *(.text); + *(*); + } + . = ALIGN(4); + _heap_start = .; + end = .; +} diff --git a/software/src/iob_soc_opencryptolinux_firmware.S b/software/src/iob_soc_opencryptolinux_firmware.S index 9bb9091b..ad0b7082 100644 --- a/software/src/iob_soc_opencryptolinux_firmware.S +++ b/software/src/iob_soc_opencryptolinux_firmware.S @@ -2,25 +2,25 @@ #include "iob_soc_opencryptolinux_conf.h" .section .init -.global main -// The 'norelax' option is critical here. -// Without 'norelax' the global pointer will -// be loaded relative to the global pointer! +.globl _start +.type _start,@function + +_start: .option push .option norelax -la gp, 0x800 + la gp, __global_pointer$ .option pop -//set stack pointer -lui sp, %hi(1< Date: Fri, 13 Oct 2023 15:21:44 +0100 Subject: [PATCH 23/27] int_mem.v: use axi_ram. --- hardware/src/int_mem.v | 294 +++++++++++++++++++++++++++++++++++++ iob_soc_opencryptolinux.py | 2 + 2 files changed, 296 insertions(+) create mode 100644 hardware/src/int_mem.v diff --git a/hardware/src/int_mem.v b/hardware/src/int_mem.v new file mode 100644 index 00000000..5712e026 --- /dev/null +++ b/hardware/src/int_mem.v @@ -0,0 +1,294 @@ +`timescale 1 ns / 1 ps + +`include "iob_soc_conf.vh" +`include "iob_utils.vh" + +module int_mem #( + parameter ADDR_W = 0, + parameter DATA_W = 0, + parameter STRB_WIDTH = (DATA_W / 8), + parameter AXI_ID_WIDTH = 8, + parameter BOOT_HEXFILE = "none", + parameter BOOTROM_ADDR_W = 1, + parameter B_BIT = 2, + parameter SRAM_ADDR_W = (B_BIT - 1) +) ( + + output wire boot, + output wire cpu_reset, + /* + * AXI instruction bus interface + */ + input wire [AXI_ID_WIDTH-1:0] i_axi_awid, + input wire [ ADDR_W-1:0] i_axi_awaddr, + input wire [ 7:0] i_axi_awlen, + input wire [ 2:0] i_axi_awsize, + input wire [ 1:0] i_axi_awburst, + input wire i_axi_awlock, + input wire [ 3:0] i_axi_awcache, + input wire [ 2:0] i_axi_awprot, + input wire i_axi_awvalid, + output wire i_axi_awready, + input wire [ DATA_W-1:0] i_axi_wdata, + input wire [ STRB_WIDTH-1:0] i_axi_wstrb, + input wire i_axi_wlast, + input wire i_axi_wvalid, + output wire i_axi_wready, + output wire [AXI_ID_WIDTH-1:0] i_axi_bid, + output wire [ 1:0] i_axi_bresp, + output wire i_axi_bvalid, + input wire i_axi_bready, + input wire [AXI_ID_WIDTH-1:0] i_axi_arid, + input wire [ ADDR_W-1:0] i_axi_araddr, + input wire [ 7:0] i_axi_arlen, + input wire [ 2:0] i_axi_arsize, + input wire [ 1:0] i_axi_arburst, + input wire i_axi_arlock, + input wire [ 3:0] i_axi_arcache, + input wire [ 2:0] i_axi_arprot, + input wire i_axi_arvalid, + output wire i_axi_arready, + output wire [AXI_ID_WIDTH-1:0] i_axi_rid, + output wire [ DATA_W-1:0] i_axi_rdata, + output wire [ 1:0] i_axi_rresp, + output wire i_axi_rlast, + output wire i_axi_rvalid, + input wire i_axi_rready, + + /* + * AXI data bus interface + */ + input wire [AXI_ID_WIDTH-1:0] d_axi_awid, + input wire [ ADDR_W-1:0] d_axi_awaddr, + input wire [ 7:0] d_axi_awlen, + input wire [ 2:0] d_axi_awsize, + input wire [ 1:0] d_axi_awburst, + input wire d_axi_awlock, + input wire [ 3:0] d_axi_awcache, + input wire [ 2:0] d_axi_awprot, + input wire d_axi_awvalid, + output wire d_axi_awready, + input wire [ DATA_W-1:0] d_axi_wdata, + input wire [ STRB_WIDTH-1:0] d_axi_wstrb, + input wire d_axi_wlast, + input wire d_axi_wvalid, + output wire d_axi_wready, + output wire [AXI_ID_WIDTH-1:0] d_axi_bid, + output wire [ 1:0] d_axi_bresp, + output wire d_axi_bvalid, + input wire d_axi_bready, + input wire [AXI_ID_WIDTH-1:0] d_axi_arid, + input wire [ ADDR_W-1:0] d_axi_araddr, + input wire [ 7:0] d_axi_arlen, + input wire [ 2:0] d_axi_arsize, + input wire [ 1:0] d_axi_arburst, + input wire d_axi_arlock, + input wire [ 3:0] d_axi_arcache, + input wire [ 2:0] d_axi_arprot, + input wire d_axi_arvalid, + output wire d_axi_arready, + output wire [AXI_ID_WIDTH-1:0] d_axi_rid, + output wire [ DATA_W-1:0] d_axi_rdata, + output wire [ 1:0] d_axi_rresp, + output wire d_axi_rlast, + output wire d_axi_rvalid, + input wire d_axi_rready, + + `include "clk_en_rst_s_port.vs" +); + + wire mm_reg_enable; + wire int_d_axi_awvalid; + wire int_d_axi_wvalid; + //boot register: (1) load bootloader to sram and run it: (0) run program + wire boot_wr; + reg boot_nxt; + //create CPU reset pulse + wire cpu_rst_req; + + assign mm_reg_enable = d_axi_awaddr[B_BIT]; + assign boot_wr = mm_reg_enable & d_axi_wvalid & (|d_axi_wstrb); + assign cpu_rst_req = mm_reg_enable & d_axi_wvalid & (|d_axi_wstrb) & cpu_wdata[1]; + + assign int_d_axi_awvalid = (~mm_reg_enable) & d_axi_awvalid; + assign int_d_axi_wvalid = (~mm_reg_enable) & d_axi_wvalid; + + iob_reg_re #( + .DATA_W (1), + .RST_VAL(1) + ) bootnxt ( + .clk_i (clk_i), + .arst_i(arst_i), + .cke_i (cke_i), + .rst_i (1'b0), + .en_i (boot_wr), + .data_i(cpu_wdata[0]), + .data_o(boot_nxt) + ); + iob_reg_r #( + .DATA_W (1), + .RST_VAL(1) + ) bootreg ( + .clk_i (clk_i), + .arst_i(arst_i), + .cke_i (cke_i), + .rst_i (1'b0), + .data_i(boot_nxt), + .data_o(boot) + ); + iob_pulse_gen #( + .START (0), + .DURATION(100) + ) reset_pulse ( + .clk_i (clk_i), + .arst_i (arst_i), + .cke_i (cke_i), + .start_i(cpu_rst_req), + .pulse_o(cpu_rst) + ); + + axi_interconnect #( + .ID_WIDTH (AXI_ID_W), + .DATA_WIDTH(DATA_W), + .ADDR_WIDTH(SRAM_ADDR_W), + .M_ADDR_WIDTH(SRAM_ADDR_W), + .S_COUNT (2), + .M_COUNT (1) + ) extmem_axi_interconnect ( + .clk(clk_i), + .rst(arst_i), + + .s_axi_awid({3'b000, i_axi_awid, 3'b000, d_axi_awid}), + .s_axi_awaddr({i_axi_awaddr[SRAM_ADDR_W-1:0], d_axi_awaddr[SRAM_ADDR_W-1:0]}), + .s_axi_awlen({i_axi_awlen, d_axi_awlen}), + .s_axi_awsize({i_axi_awsize, d_axi_awsize}), + .s_axi_awburst({i_axi_awburst, d_axi_awburst}), + .s_axi_awlock({i_axi_awlock[0], d_axi_awlock[0]}), + .s_axi_awcache({i_axi_awcache, d_axi_awcache}), + .s_axi_awprot({i_axi_awprot, d_axi_awprot}), + .s_axi_awqos({i_axi_awqos, d_axi_awqos}), + .s_axi_awvalid({i_axi_awvalid, int_d_axi_awvalid}), + .s_axi_awready({i_axi_awready, d_axi_awready}), + .s_axi_wdata({i_axi_wdata, d_axi_wdata}), + .s_axi_wstrb({i_axi_wstrb, d_axi_wstrb}), + .s_axi_wlast({i_axi_wlast, d_axi_wlast}), + .s_axi_wvalid({i_axi_wvalid, int_d_axi_wvalid}), + .s_axi_wready({i_axi_wready, d_axi_wready}), + .s_axi_bid(extmem_axi_bid), + .s_axi_bresp({i_axi_bresp, d_axi_bresp}), + .s_axi_bvalid({i_axi_bvalid, d_axi_bvalid}), + .s_axi_bready({i_axi_bready, d_axi_bready}), + .s_axi_arid({3'b000, i_axi_arid, 3'b000, d_axi_arid}), + .s_axi_araddr({i_axi_araddr[SRAM_ADDR_W-1:0], d_axi_araddr[SRAM_ADDR_W-1:0]}), + .s_axi_arlen({i_axi_arlen, d_axi_arlen}), + .s_axi_arsize({i_axi_arsize, d_axi_arsize}), + .s_axi_arburst({i_axi_arburst, d_axi_arburst}), + .s_axi_arlock({i_axi_arlock[0], d_axi_arlock[0]}), + .s_axi_arcache({i_axi_arcache, d_axi_arcache}), + .s_axi_arprot({i_axi_arprot, d_axi_arprot}), + .s_axi_arqos({i_axi_arqos, d_axi_arqos}), + .s_axi_arvalid({i_axi_arvalid, d_axi_arvalid}), + .s_axi_arready({i_axi_arready, d_axi_arready}), + .s_axi_rid(extmem_axi_rid), + .s_axi_rdata({i_axi_rdata, d_axi_rdata}), + .s_axi_rresp({i_axi_rresp, d_axi_rresp}), + .s_axi_rlast({i_axi_rlast, d_axi_rlast}), + .s_axi_rvalid({i_axi_rvalid, d_axi_rvalid}), + .s_axi_rready({i_axi_rready, d_axi_rready}), + + .m_axi_awid(ram_axi_awid), + .m_axi_awaddr(ram_axi_awaddr), + .m_axi_awlen(ram_axi_awlen), + .m_axi_awsize(ram_axi_awsize), + .m_axi_awburst(ram_axi_awburst), + .m_axi_awlock(ram_axi_awlock), + .m_axi_awcache(ram_axi_awcache), + .m_axi_awprot(ram_axi_awprot), + .m_axi_awqos(ram_axi_awqos), + .m_axi_awvalid(ram_axi_awvalid), + .m_axi_awready(ram_axi_awready), + .m_axi_wdata(ram_axi_wdata), + .m_axi_wstrb(ram_axi_wstrb), + .m_axi_wlast(ram_axi_wlast), + .m_axi_wvalid(ram_axi_wvalid), + .m_axi_wready(ram_axi_wready), + .m_axi_bid(ram_axi_bid), + .m_axi_bresp(ram_axi_bresp), + .m_axi_bvalid(ram_axi_bvalid), + .m_axi_bready(ram_axi_bready), + .m_axi_arid(ram_axi_arid), + .m_axi_araddr(ram_axi_araddr), + .m_axi_arlen(ram_axi_arlen), + .m_axi_arsize(ram_axi_arsize), + .m_axi_arburst(ram_axi_arburst), + .m_axi_arlock(ram_axi_arlock), + .m_axi_arcache(ram_axi_arcache), + .m_axi_arprot(ram_axi_arprot), + .m_axi_arqos(ram_axi_arqos), + .m_axi_arvalid(ram_axi_arvalid), + .m_axi_arready(ram_axi_arready), + .m_axi_rid(ram_axi_rid), + .m_axi_rdata(ram_axi_rdata), + .m_axi_rresp(ram_axi_rresp), + .m_axi_rlast(ram_axi_rlast), + .m_axi_rvalid(ram_axi_rvalid), + .m_axi_rready(ram_axi_rready), + + //optional signals + .s_axi_awuser(2'b00), + .s_axi_wuser (2'b00), + .s_axi_aruser(2'b00), + .m_axi_buser (1'b0), + .m_axi_ruser (1'b0) + ); + + axi_ram #( + .DATA_WIDTH(ADDR_W), + .ADDR_WIDTH(ADDR_W), + .FILE(BOOT_HEXFILE), + .FILE_SIZE(BOOTROM_ADDR_W), + .HEX_DATA_W(B_BIT - 1) + ) boot_ram ( + .clk_i(clk_i), + .rst_i(arst_i), + + .axi_awid_i(ram_axi_awid), + .axi_awaddr_i(ram_axi_awaddr), + .axi_awlen_i(ram_axi_awlen), + .axi_awsize_i(ram_axi_awsize), + .axi_awburst_i(ram_axi_awburst), + .axi_awlock_i(ram_axi_awlock), + .axi_awcache_i(ram_axi_awcache), + .axi_awprot_i(ram_axi_awprot), + .axi_awqos_i(ram_axi_awqos), + .axi_awvalid_i(ram_axi_awvalid), + .axi_awready_o(ram_axi_awready), + .axi_wdata_i(ram_axi_wdata), + .axi_wstrb_i(ram_axi_wstrb), + .axi_wlast_i(ram_axi_wlast), + .axi_wvalid_i(ram_axi_wvalid), + .axi_wready_o(ram_axi_wready), + .axi_bid_o(ram_axi_bid), + .axi_bresp_o(ram_axi_bresp), + .axi_bvalid_o(ram_axi_bvalid), + .axi_bready_i(ram_axi_bready), + .axi_arid_i(ram_axi_arid), + .axi_araddr_i(ram_axi_araddr), + .axi_arlen_i(ram_axi_arlen), + .axi_arsize_i(ram_axi_arsize), + .axi_arburst_i(ram_axi_arburst), + .axi_arlock_i(ram_axi_arlock), + .axi_arcache_i(ram_axi_arcache), + .axi_arprot_i(ram_axi_arprot), + .axi_arqos_i(ram_axi_arqos), + .axi_arvalid_i(ram_axi_arvalid), + .axi_arready_o(ram_axi_arready), + .axi_rid_o(ram_axi_rid), + .axi_rdata_o(ram_axi_rdata), + .axi_rresp_o(ram_axi_rresp), + .axi_rlast_o(ram_axi_rlast), + .axi_rvalid_o(ram_axi_rvalid), + .axi_rready_i(ram_axi_rready) + ); + +endmodule diff --git a/iob_soc_opencryptolinux.py b/iob_soc_opencryptolinux.py index 84562019..bd0a35f6 100755 --- a/iob_soc_opencryptolinux.py +++ b/iob_soc_opencryptolinux.py @@ -12,6 +12,7 @@ from iob_clint import iob_clint from iob_uart import iob_uart from iob_spi import iob_spi +from axi_ram import axi_ram class iob_soc_opencryptolinux(iob_soc): @@ -59,6 +60,7 @@ def _create_submodules_list(cls, extra_submodules=[]): {"interface": "iBus_axi_m_portmap"}, iob_vexriscv, iob_uart16550, + axi_ram, # iob_spi, (iob_uart, {"purpose": "simulation"}), ] From 9d2575e910f91e2994cdd4483b0663327abc22b7 Mon Sep 17 00:00:00 2001 From: Pedro Antunes Date: Sat, 14 Oct 2023 01:03:49 +0100 Subject: [PATCH 24/27] hardware: compiles without errors. --- .../src/iob_soc_opencryptolinux_sim_wrapper.v | 11 +- hardware/src/axi2iob.v | 530 ------------------ hardware/src/int_mem.v | 195 ++++--- hardware/src/iob2axi.v | 503 ----------------- hardware/src/iob_soc_opencryptolinux.v | 318 +++++------ iob_soc_opencryptolinux.py | 6 +- software/src/iob_soc_opencryptolinux_boot.c | 4 +- .../src/iob_soc_opencryptolinux_firmware.c | 6 +- submodules/LIB | 2 +- 9 files changed, 279 insertions(+), 1296 deletions(-) delete mode 100644 hardware/src/axi2iob.v delete mode 100644 hardware/src/iob2axi.v diff --git a/hardware/simulation/src/iob_soc_opencryptolinux_sim_wrapper.v b/hardware/simulation/src/iob_soc_opencryptolinux_sim_wrapper.v index 6c954fe1..15bf479d 100644 --- a/hardware/simulation/src/iob_soc_opencryptolinux_sim_wrapper.v +++ b/hardware/simulation/src/iob_soc_opencryptolinux_sim_wrapper.v @@ -29,7 +29,7 @@ module iob_soc_opencryptolinux_sim_wrapper ( wire clk = clk_i; wire cke = 1'b1; - wire rst = rst_i; + wire arst = rst_i; `include "iob_soc_opencryptolinux_wrapper_pwires.vs" @@ -59,7 +59,8 @@ module iob_soc_opencryptolinux_sim_wrapper ( ) soc0 ( `include "iob_soc_opencryptolinux_pportmaps.vs" .clk_i (clk), - .arst_i(rst), + .cke_i (cke), + .arst_i(arst), .trap_o(trap_o) ); @@ -79,7 +80,7 @@ module iob_soc_opencryptolinux_sim_wrapper ( `include "iob_memory_axi_s_portmap.vs" .clk_i(clk), - .rst_i(rst) + .rst_i(arst) ); //finish simulation on trap @@ -120,7 +121,7 @@ always @(posedge trap[1]) begin iob_uart uart_tb ( .clk_i (clk), .cke_i (cke), - .arst_i(rst), + .arst_i(arst), .iob_avalid_i(uart_avalid), .iob_addr_i (uart_addr), @@ -155,7 +156,7 @@ always @(posedge trap[1]) begin //add core test module in testbench iob_eth_tb_gen eth_tb ( .clk (clk), - .reset(rst), + .reset(arst), // This module acts like a loopback .RX_CLK (ETHERNET0_TX_CLK), diff --git a/hardware/src/axi2iob.v b/hardware/src/axi2iob.v deleted file mode 100644 index 229c359f..00000000 --- a/hardware/src/axi2iob.v +++ /dev/null @@ -1,530 +0,0 @@ -// Language: Verilog 2001 -`timescale 1ns / 1ps - -/* - * AXI4 to IOb adapter - */ -module axi2iob #( - // Width of address bus in bits - parameter ADDR_WIDTH = 32, - // Width of input (slave/master) AXI/IOb interface data bus in bits - parameter DATA_WIDTH = 32, - // Width of input (slave/master) AXI/IOb interface wstrb (width of data bus in words) - parameter STRB_WIDTH = (DATA_WIDTH / 8), - // Width of AXI ID signal - parameter AXI_ID_WIDTH = 8 -) ( - input wire clk_i, - input wire arst_i, - - /* - * AXI slave interface - */ - input wire [AXI_ID_WIDTH-1:0] s_axi_awid, - input wire [ ADDR_WIDTH-1:0] s_axi_awaddr, - input wire [ 7:0] s_axi_awlen, - input wire [ 2:0] s_axi_awsize, - input wire [ 1:0] s_axi_awburst, - input wire s_axi_awlock, - input wire [ 3:0] s_axi_awcache, - input wire [ 2:0] s_axi_awprot, - input wire s_axi_awvalid, - output wire s_axi_awready, - input wire [ DATA_WIDTH-1:0] s_axi_wdata, - input wire [ STRB_WIDTH-1:0] s_axi_wstrb, - input wire s_axi_wlast, - input wire s_axi_wvalid, - output wire s_axi_wready, - output wire [AXI_ID_WIDTH-1:0] s_axi_bid, - output wire [ 1:0] s_axi_bresp, - output wire s_axi_bvalid, - input wire s_axi_bready, - input wire [AXI_ID_WIDTH-1:0] s_axi_arid, - input wire [ ADDR_WIDTH-1:0] s_axi_araddr, - input wire [ 7:0] s_axi_arlen, - input wire [ 2:0] s_axi_arsize, - input wire [ 1:0] s_axi_arburst, - input wire s_axi_arlock, - input wire [ 3:0] s_axi_arcache, - input wire [ 2:0] s_axi_arprot, - input wire s_axi_arvalid, - output wire s_axi_arready, - output wire [AXI_ID_WIDTH-1:0] s_axi_rid, - output wire [ DATA_WIDTH-1:0] s_axi_rdata, - output wire [ 1:0] s_axi_rresp, - output wire s_axi_rlast, - output wire s_axi_rvalid, - input wire s_axi_rready, - - /* - * IOb-bus master interface - */ - output wire iob_avalid_o, - output wire [ADDR_WIDTH-1:0] iob_addr_o, - output wire [DATA_WIDTH-1:0] iob_wdata_o, - output wire [STRB_WIDTH-1:0] iob_wstrb_o, - input wire iob_rvalid_i, - input wire [DATA_WIDTH-1:0] iob_rdata_i, - input wire iob_ready_i -); - - localparam [1:0] STATE_IDLE = 2'd0, STATE_DATA = 2'd1, STATE_RESP = 2'd2; - - /* - * AXI lite master interface (used as a middle ground from AXI4 to IOb) - */ - wire [ADDR_WIDTH-1:0] m_axil_awaddr; - wire [ 2:0] m_axil_awprot; - wire m_axil_awvalid; - wire m_axil_awready; - wire [DATA_WIDTH-1:0] m_axil_wdata; - wire [STRB_WIDTH-1:0] m_axil_wstrb; - wire m_axil_wvalid; - wire m_axil_wready; - wire [ 1:0] m_axil_bresp; - wire m_axil_bvalid; - wire m_axil_bready; - wire [ADDR_WIDTH-1:0] m_axil_araddr; - wire [ 2:0] m_axil_arprot; - wire m_axil_arvalid; - wire m_axil_arready; - wire [DATA_WIDTH-1:0] m_axil_rdata; - wire [ 1:0] m_axil_rresp; - wire m_axil_rvalid; - wire m_axil_rready; - - // - // AXI4-Lite interface to IOb - // - wire iob_rvalid_q; - wire iob_rvalid_e; - wire write_enable; - wire [ADDR_WIDTH-1:0] m_axil_awaddr_q; - wire m_axil_bvalid_n; - wire m_axil_bvalid_e; - - assign write_enable = |m_axil_wstrb; - assign m_axil_bvalid_n = m_axil_wvalid; - assign m_axil_bvalid_e = m_axil_bvalid_n | m_axil_bready; - assign iob_rvalid_e = iob_rvalid_i | m_axil_rready; - - // COMPUTE AXIL OUTPUTS - // // write address - assign m_axil_awready = iob_ready_i; - // // write - assign m_axil_wready = iob_ready_i; - // // write response - assign m_axil_bresp = 2'b0; - // // read address - assign m_axil_arready = iob_ready_i; - // // read - assign m_axil_rdata = iob_rdata_i; - assign m_axil_rresp = 2'b0; - assign m_axil_rvalid = iob_rvalid_i ? 1'b1 : iob_rvalid_q; - - // COMPUTE IOb OUTPUTS - assign iob_avalid_o = (m_axil_bvalid_n & write_enable) | m_axil_arvalid; - assign iob_addr_o = m_axil_arvalid ? m_axil_araddr : (m_axil_awvalid ? m_axil_awaddr : m_axil_awaddr_q); - assign iob_wdata_o = m_axil_wdata; - assign iob_wstrb_o = m_axil_arvalid ? {STRB_WIDTH{1'b0}} : m_axil_wstrb; - - iob_reg_re #( - .DATA_W (ADDR_WIDTH), - .RST_VAL(0) - ) iob_reg_awaddr ( - .clk_i (clk_i), - .arst_i(arst_i), - .cke_i (1'b1), - .rst_i (1'b0), - .en_i (m_axil_awvalid), - .data_i(m_axil_awaddr), - .data_o(m_axil_awaddr_q) - ); - - iob_reg_re #( - .DATA_W (1), - .RST_VAL(0) - ) iob_reg_rvalid ( - .clk_i (clk_i), - .arst_i(arst_i), - .cke_i (1'b1), - .rst_i (1'b0), - .en_i (iob_rvalid_e), - .data_i(iob_rvalid_i), - .data_o(iob_rvalid_q) - ); - - iob_reg_re #( - .DATA_W (1), - .RST_VAL(0) - ) iob_reg_bvalid ( - .clk_i (clk_i), - .arst_i(arst_i), - .cke_i (1'b1), - .rst_i (1'b0), - .en_i (m_axil_bvalid_e), - .data_i(m_axil_bvalid_n), - .data_o(m_axil_bvalid) - ); - - // - // AXI4 write interface conversion to AXI4-Lite - // - reg [1:0] w_state_reg, w_state_next; - - reg [AXI_ID_WIDTH-1:0] w_id_reg, w_id_next; - reg [ADDR_WIDTH-1:0] w_addr_reg, w_addr_next; - reg [DATA_WIDTH-1:0] w_data_reg, w_data_next; - reg [STRB_WIDTH-1:0] w_strb_reg, w_strb_next; - reg [7:0] w_burst_reg, w_burst_next; - reg [2:0] w_burst_size_reg, w_burst_size_next; - reg [2:0] w_master_burst_size_reg, w_master_burst_size_next; - reg w_burst_active_reg, w_burst_active_next; - reg w_first_transfer_reg, w_first_transfer_next; - reg w_last_segment_reg, w_last_segment_next; - - reg s_axi_awready_reg, s_axi_awready_next; - reg s_axi_wready_reg, s_axi_wready_next; - reg [AXI_ID_WIDTH-1:0] s_axi_bid_reg, s_axi_bid_next; - reg [1:0] s_axi_bresp_reg, s_axi_bresp_next; - reg s_axi_bvalid_reg, s_axi_bvalid_next; - - reg [ADDR_WIDTH-1:0] m_axil_awaddr_reg, m_axil_awaddr_next; - reg [2:0] m_axil_awprot_reg, m_axil_awprot_next; - reg m_axil_awvalid_reg, m_axil_awvalid_next; - reg [DATA_WIDTH-1:0] m_axil_wdata_reg, m_axil_wdata_next; - reg [STRB_WIDTH-1:0] m_axil_wstrb_reg, m_axil_wstrb_next; - reg m_axil_wvalid_reg, m_axil_wvalid_next; - reg m_axil_bready_reg, m_axil_bready_next; - - assign s_axi_awready = s_axi_awready_reg; - assign s_axi_wready = s_axi_wready_reg; - assign s_axi_bid = s_axi_bid_reg; - assign s_axi_bresp = s_axi_bresp_reg; - assign s_axi_bvalid = s_axi_bvalid_reg; - - assign m_axil_awaddr = m_axil_awaddr_reg; - assign m_axil_awprot = m_axil_awprot_reg; - assign m_axil_awvalid = m_axil_awvalid_reg; - assign m_axil_wdata = m_axil_wdata_reg; - assign m_axil_wstrb = m_axil_wstrb_reg; - assign m_axil_wvalid = m_axil_wvalid_reg; - assign m_axil_bready = m_axil_bready_reg; - - integer i; - - always @* begin - w_state_next = STATE_IDLE; - - w_id_next = w_id_reg; - w_addr_next = w_addr_reg; - w_data_next = w_data_reg; - w_strb_next = w_strb_reg; - w_burst_next = w_burst_reg; - w_burst_size_next = w_burst_size_reg; - w_master_burst_size_next = w_master_burst_size_reg; - w_burst_active_next = w_burst_active_reg; - w_first_transfer_next = w_first_transfer_reg; - w_last_segment_next = w_last_segment_reg; - - s_axi_awready_next = 1'b0; - s_axi_wready_next = 1'b0; - s_axi_bid_next = s_axi_bid_reg; - s_axi_bresp_next = s_axi_bresp_reg; - s_axi_bvalid_next = s_axi_bvalid_reg & ~s_axi_bready; - m_axil_awaddr_next = m_axil_awaddr_reg; - m_axil_awprot_next = m_axil_awprot_reg; - m_axil_awvalid_next = m_axil_awvalid_reg & ~m_axil_awready; - m_axil_wdata_next = m_axil_wdata_reg; - m_axil_wstrb_next = m_axil_wstrb_reg; - m_axil_wvalid_next = m_axil_wvalid_reg & ~m_axil_wready; - m_axil_bready_next = 1'b0; - - case (w_state_reg) - default: begin // STATE_IDLE - // idle state; wait for new burst - s_axi_awready_next = ~m_axil_awvalid; - w_first_transfer_next = 1'b1; - - if (s_axi_awready & s_axi_awvalid) begin - s_axi_awready_next = 1'b0; - w_id_next = s_axi_awid; - m_axil_awaddr_next = s_axi_awaddr; - w_addr_next = s_axi_awaddr; - w_burst_next = s_axi_awlen; - w_burst_size_next = s_axi_awsize; - w_burst_active_next = 1'b1; - m_axil_awprot_next = s_axi_awprot; - m_axil_awvalid_next = 1'b1; - s_axi_wready_next = ~m_axil_wvalid; - w_state_next = STATE_DATA; - end else begin - w_state_next = STATE_IDLE; - end - end - STATE_DATA: begin - // data state; transfer write data - s_axi_wready_next = ~m_axil_wvalid; - - if (s_axi_wready & s_axi_wvalid) begin - m_axil_wdata_next = s_axi_wdata; - m_axil_wstrb_next = s_axi_wstrb; - m_axil_wvalid_next = 1'b1; - w_burst_next = w_burst_reg - 1; - w_burst_active_next = w_burst_reg != 0; - w_addr_next = w_addr_reg + (1 << w_burst_size_reg); - s_axi_wready_next = 1'b0; - m_axil_bready_next = ~s_axi_bvalid & ~m_axil_awvalid; - w_state_next = STATE_RESP; - end else begin - w_state_next = STATE_DATA; - end - end - STATE_RESP: begin - // resp state; transfer write response - m_axil_bready_next = ~s_axi_bvalid & ~m_axil_awvalid; - - if (m_axil_bready & m_axil_bvalid) begin - m_axil_bready_next = 1'b0; - s_axi_bid_next = w_id_reg; - w_first_transfer_next = 1'b0; - if (w_first_transfer_reg | (m_axil_bresp != 0)) begin - s_axi_bresp_next = m_axil_bresp; - end - if (w_burst_active_reg) begin - // burst on slave interface still active; start new AXI lite write - m_axil_awaddr_next = w_addr_reg; - m_axil_awvalid_next = 1'b1; - s_axi_wready_next = ~m_axil_wvalid; - w_state_next = STATE_DATA; - end else begin - // burst on slave interface finished; return to idle - s_axi_bvalid_next = 1'b1; - s_axi_awready_next = ~m_axil_awvalid; - w_state_next = STATE_IDLE; - end - end else begin - w_state_next = STATE_RESP; - end - end - endcase - end - - always @(posedge clk_i, posedge arst_i) begin - if (arst_i) begin - w_state_reg <= STATE_IDLE; - s_axi_awready_reg <= 1'b0; - s_axi_wready_reg <= 1'b0; - s_axi_bvalid_reg <= 1'b0; - m_axil_awvalid_reg <= 1'b0; - m_axil_wvalid_reg <= 1'b0; - m_axil_bready_reg <= 1'b0; - - w_id_reg <= {AXI_ID_WIDTH{1'b0}}; - w_addr_reg <= {ADDR_WIDTH{1'b0}}; - w_data_reg <= {DATA_WIDTH{1'b0}}; - w_strb_reg <= {STRB_WIDTH{1'b0}}; - w_burst_reg <= 8'd0; - w_burst_size_reg <= 3'd0; - w_master_burst_size_reg <= 3'd0; - w_burst_active_reg <= 1'b0; - w_first_transfer_reg <= 1'b0; - w_last_segment_reg <= 1'b0; - - s_axi_bid_reg <= {AXI_ID_WIDTH{1'b0}}; - s_axi_bresp_reg <= 2'd0; - m_axil_awaddr_reg <= {ADDR_WIDTH{1'b0}}; - m_axil_awprot_reg <= 3'd0; - m_axil_wdata_reg <= {DATA_WIDTH{1'b0}}; - m_axil_wstrb_reg <= {STRB_WIDTH{1'b0}}; - end else begin - w_state_reg <= w_state_next; - s_axi_awready_reg <= s_axi_awready_next; - s_axi_wready_reg <= s_axi_wready_next; - s_axi_bvalid_reg <= s_axi_bvalid_next; - m_axil_awvalid_reg <= m_axil_awvalid_next; - m_axil_wvalid_reg <= m_axil_wvalid_next; - m_axil_bready_reg <= m_axil_bready_next; - - w_id_reg <= w_id_next; - w_addr_reg <= w_addr_next; - w_data_reg <= w_data_next; - w_strb_reg <= w_strb_next; - w_burst_reg <= w_burst_next; - w_burst_size_reg <= w_burst_size_next; - w_master_burst_size_reg <= w_master_burst_size_next; - w_burst_active_reg <= w_burst_active_next; - w_first_transfer_reg <= w_first_transfer_next; - w_last_segment_reg <= w_last_segment_next; - - s_axi_bid_reg <= s_axi_bid_next; - s_axi_bresp_reg <= s_axi_bresp_next; - m_axil_awaddr_reg <= m_axil_awaddr_next; - m_axil_awprot_reg <= m_axil_awprot_next; - m_axil_wdata_reg <= m_axil_wdata_next; - m_axil_wstrb_reg <= m_axil_wstrb_next; - end - end - - // - // AXI4 read interface conversion to AXI4-Lite - // - reg [1:0] r_state_reg, r_state_next; - - reg [AXI_ID_WIDTH-1:0] r_id_reg, r_id_next; - reg [ADDR_WIDTH-1:0] r_addr_reg, r_addr_next; - reg [DATA_WIDTH-1:0] r_data_reg, r_data_next; - reg [1:0] r_resp_reg, r_resp_next; - reg [7:0] r_burst_reg, r_burst_next; - reg [2:0] r_burst_size_reg, r_burst_size_next; - reg [7:0] r_master_burst_reg, r_master_burst_next; - reg [2:0] r_master_burst_size_reg, r_master_burst_size_next; - - reg s_axi_arready_reg, s_axi_arready_next; - reg [AXI_ID_WIDTH-1:0] s_axi_rid_reg, s_axi_rid_next; - reg [DATA_WIDTH-1:0] s_axi_rdata_reg, s_axi_rdata_next; - reg [1:0] s_axi_rresp_reg, s_axi_rresp_next; - reg s_axi_rlast_reg, s_axi_rlast_next; - reg s_axi_rvalid_reg, s_axi_rvalid_next; - - reg [ADDR_WIDTH-1:0] m_axil_araddr_reg, m_axil_araddr_next; - reg [2:0] m_axil_arprot_reg, m_axil_arprot_next; - reg m_axil_arvalid_reg, m_axil_arvalid_next; - reg m_axil_rready_reg, m_axil_rready_next; - - assign s_axi_arready = s_axi_arready_reg; - assign s_axi_rid = s_axi_rid_reg; - assign s_axi_rdata = s_axi_rdata_reg; - assign s_axi_rresp = s_axi_rresp_reg; - assign s_axi_rlast = s_axi_rlast_reg; - assign s_axi_rvalid = s_axi_rvalid_reg; - - assign m_axil_araddr = m_axil_araddr_reg; - assign m_axil_arprot = m_axil_arprot_reg; - assign m_axil_arvalid = m_axil_arvalid_reg; - assign m_axil_rready = m_axil_rready_reg; - - always @* begin - r_state_next = STATE_IDLE; - - r_id_next = r_id_reg; - r_addr_next = r_addr_reg; - r_data_next = r_data_reg; - r_resp_next = r_resp_reg; - r_burst_next = r_burst_reg; - r_burst_size_next = r_burst_size_reg; - r_master_burst_next = r_master_burst_reg; - r_master_burst_size_next = r_master_burst_size_reg; - - s_axi_arready_next = 1'b0; - s_axi_rid_next = s_axi_rid_reg; - s_axi_rdata_next = s_axi_rdata_reg; - s_axi_rresp_next = s_axi_rresp_reg; - s_axi_rlast_next = s_axi_rlast_reg; - s_axi_rvalid_next = s_axi_rvalid_reg & ~s_axi_rready; - m_axil_araddr_next = m_axil_araddr_reg; - m_axil_arprot_next = m_axil_arprot_reg; - m_axil_arvalid_next = m_axil_arvalid_reg & ~m_axil_arready; - m_axil_rready_next = 1'b0; - - case (r_state_reg) - default: begin // STATE_IDLE - // idle state; wait for new burst - s_axi_arready_next = ~m_axil_arvalid; - - if (s_axi_arready & s_axi_arvalid) begin - s_axi_arready_next = 1'b0; - r_id_next = s_axi_arid; - m_axil_araddr_next = s_axi_araddr; - r_addr_next = s_axi_araddr; - r_burst_next = s_axi_arlen; - r_burst_size_next = s_axi_arsize; - m_axil_arprot_next = s_axi_arprot; - m_axil_arvalid_next = 1'b1; - m_axil_rready_next = 1'b0; - r_state_next = STATE_DATA; - end else begin - r_state_next = STATE_IDLE; - end - end - STATE_DATA: begin - // data state; transfer read data - m_axil_rready_next = ~s_axi_rvalid & ~m_axil_arvalid; - - if (m_axil_rready & m_axil_rvalid) begin - s_axi_rid_next = r_id_reg; - s_axi_rdata_next = m_axil_rdata; - s_axi_rresp_next = m_axil_rresp; - s_axi_rlast_next = 1'b0; - s_axi_rvalid_next = 1'b1; - r_burst_next = r_burst_reg - 1; - r_addr_next = r_addr_reg + (1 << r_burst_size_reg); - if (r_burst_reg == 0) begin - // last data word, return to idle - m_axil_rready_next = 1'b0; - s_axi_rlast_next = 1'b1; - s_axi_arready_next = ~m_axil_arvalid; - r_state_next = STATE_IDLE; - end else begin - // start new AXI lite read - m_axil_araddr_next = r_addr_next; - m_axil_arvalid_next = 1'b1; - m_axil_rready_next = 1'b0; - r_state_next = STATE_DATA; - end - end else begin - r_state_next = STATE_DATA; - end - end - endcase - end - - always @(posedge clk_i, posedge arst_i) begin - if (arst_i) begin - r_state_reg <= STATE_IDLE; - s_axi_arready_reg <= 1'b0; - s_axi_rvalid_reg <= 1'b0; - m_axil_arvalid_reg <= 1'b0; - m_axil_rready_reg <= 1'b0; - - r_id_reg <= {AXI_ID_WIDTH{1'b0}}; - r_addr_reg <= {ADDR_WIDTH{1'b0}}; - r_data_reg <= {DATA_WIDTH{1'b0}}; - r_resp_reg <= 2'd0; - r_burst_reg <= 8'd0; - r_burst_size_reg <= 3'd0; - r_master_burst_reg <= 8'd0; - r_master_burst_size_reg <= 3'd0; - - s_axi_rid_reg <= {AXI_ID_WIDTH{1'b0}}; - s_axi_rdata_reg <= {DATA_WIDTH{1'b0}}; - s_axi_rresp_reg <= 2'd0; - s_axi_rlast_reg <= 1'b0; - m_axil_araddr_reg <= {ADDR_WIDTH{1'b0}}; - m_axil_arprot_reg <= 3'd0; - end else begin - r_state_reg <= r_state_next; - s_axi_arready_reg <= s_axi_arready_next; - s_axi_rvalid_reg <= s_axi_rvalid_next; - m_axil_arvalid_reg <= m_axil_arvalid_next; - m_axil_rready_reg <= m_axil_rready_next; - - r_id_reg <= r_id_next; - r_addr_reg <= r_addr_next; - r_data_reg <= r_data_next; - r_resp_reg <= r_resp_next; - r_burst_reg <= r_burst_next; - r_burst_size_reg <= r_burst_size_next; - r_master_burst_reg <= r_master_burst_next; - r_master_burst_size_reg <= r_master_burst_size_next; - - s_axi_rid_reg <= s_axi_rid_next; - s_axi_rdata_reg <= s_axi_rdata_next; - s_axi_rresp_reg <= s_axi_rresp_next; - s_axi_rlast_reg <= s_axi_rlast_next; - m_axil_araddr_reg <= m_axil_araddr_next; - m_axil_arprot_reg <= m_axil_arprot_next; - end - end - -endmodule diff --git a/hardware/src/int_mem.v b/hardware/src/int_mem.v index 5712e026..4d7f8a29 100644 --- a/hardware/src/int_mem.v +++ b/hardware/src/int_mem.v @@ -1,102 +1,107 @@ `timescale 1 ns / 1 ps -`include "iob_soc_conf.vh" +`include "iob_soc_opencryptolinux_conf.vh" `include "iob_utils.vh" module int_mem #( parameter ADDR_W = 0, parameter DATA_W = 0, - parameter STRB_WIDTH = (DATA_W / 8), - parameter AXI_ID_WIDTH = 8, + parameter STRB_W = (DATA_W / 8), + parameter AXI_ID_W = 1, parameter BOOT_HEXFILE = "none", parameter BOOTROM_ADDR_W = 1, parameter B_BIT = 2, parameter SRAM_ADDR_W = (B_BIT - 1) ) ( - output wire boot, - output wire cpu_reset, + output wire boot, + output wire cpu_reset, /* * AXI instruction bus interface */ - input wire [AXI_ID_WIDTH-1:0] i_axi_awid, - input wire [ ADDR_W-1:0] i_axi_awaddr, - input wire [ 7:0] i_axi_awlen, - input wire [ 2:0] i_axi_awsize, - input wire [ 1:0] i_axi_awburst, - input wire i_axi_awlock, - input wire [ 3:0] i_axi_awcache, - input wire [ 2:0] i_axi_awprot, - input wire i_axi_awvalid, - output wire i_axi_awready, - input wire [ DATA_W-1:0] i_axi_wdata, - input wire [ STRB_WIDTH-1:0] i_axi_wstrb, - input wire i_axi_wlast, - input wire i_axi_wvalid, - output wire i_axi_wready, - output wire [AXI_ID_WIDTH-1:0] i_axi_bid, - output wire [ 1:0] i_axi_bresp, - output wire i_axi_bvalid, - input wire i_axi_bready, - input wire [AXI_ID_WIDTH-1:0] i_axi_arid, - input wire [ ADDR_W-1:0] i_axi_araddr, - input wire [ 7:0] i_axi_arlen, - input wire [ 2:0] i_axi_arsize, - input wire [ 1:0] i_axi_arburst, - input wire i_axi_arlock, - input wire [ 3:0] i_axi_arcache, - input wire [ 2:0] i_axi_arprot, - input wire i_axi_arvalid, - output wire i_axi_arready, - output wire [AXI_ID_WIDTH-1:0] i_axi_rid, - output wire [ DATA_W-1:0] i_axi_rdata, - output wire [ 1:0] i_axi_rresp, - output wire i_axi_rlast, - output wire i_axi_rvalid, - input wire i_axi_rready, + input wire [AXI_ID_W-1:0] i_axi_awid, + input wire [ ADDR_W-1:0] i_axi_awaddr, + input wire [ 7:0] i_axi_awlen, + input wire [ 2:0] i_axi_awsize, + input wire [ 1:0] i_axi_awburst, + input wire i_axi_awlock, + input wire [ 3:0] i_axi_awcache, + input wire [ 2:0] i_axi_awprot, + input wire i_axi_awvalid, + output wire i_axi_awready, + input wire [ DATA_W-1:0] i_axi_wdata, + input wire [ STRB_W-1:0] i_axi_wstrb, + input wire i_axi_wlast, + input wire i_axi_wvalid, + output wire i_axi_wready, + output wire [AXI_ID_W-1:0] i_axi_bid, + output wire [ 1:0] i_axi_bresp, + output wire i_axi_bvalid, + input wire i_axi_bready, + input wire [AXI_ID_W-1:0] i_axi_arid, + input wire [ ADDR_W-1:0] i_axi_araddr, + input wire [ 7:0] i_axi_arlen, + input wire [ 2:0] i_axi_arsize, + input wire [ 1:0] i_axi_arburst, + input wire i_axi_arlock, + input wire [ 3:0] i_axi_arcache, + input wire [ 2:0] i_axi_arprot, + input wire i_axi_arvalid, + output wire i_axi_arready, + output wire [AXI_ID_W-1:0] i_axi_rid, + output wire [ DATA_W-1:0] i_axi_rdata, + output wire [ 1:0] i_axi_rresp, + output wire i_axi_rlast, + output wire i_axi_rvalid, + input wire i_axi_rready, /* * AXI data bus interface */ - input wire [AXI_ID_WIDTH-1:0] d_axi_awid, - input wire [ ADDR_W-1:0] d_axi_awaddr, - input wire [ 7:0] d_axi_awlen, - input wire [ 2:0] d_axi_awsize, - input wire [ 1:0] d_axi_awburst, - input wire d_axi_awlock, - input wire [ 3:0] d_axi_awcache, - input wire [ 2:0] d_axi_awprot, - input wire d_axi_awvalid, - output wire d_axi_awready, - input wire [ DATA_W-1:0] d_axi_wdata, - input wire [ STRB_WIDTH-1:0] d_axi_wstrb, - input wire d_axi_wlast, - input wire d_axi_wvalid, - output wire d_axi_wready, - output wire [AXI_ID_WIDTH-1:0] d_axi_bid, - output wire [ 1:0] d_axi_bresp, - output wire d_axi_bvalid, - input wire d_axi_bready, - input wire [AXI_ID_WIDTH-1:0] d_axi_arid, - input wire [ ADDR_W-1:0] d_axi_araddr, - input wire [ 7:0] d_axi_arlen, - input wire [ 2:0] d_axi_arsize, - input wire [ 1:0] d_axi_arburst, - input wire d_axi_arlock, - input wire [ 3:0] d_axi_arcache, - input wire [ 2:0] d_axi_arprot, - input wire d_axi_arvalid, - output wire d_axi_arready, - output wire [AXI_ID_WIDTH-1:0] d_axi_rid, - output wire [ DATA_W-1:0] d_axi_rdata, - output wire [ 1:0] d_axi_rresp, - output wire d_axi_rlast, - output wire d_axi_rvalid, - input wire d_axi_rready, + input wire [AXI_ID_W-1:0] d_axi_awid, + input wire [ ADDR_W-1:0] d_axi_awaddr, + input wire [ 7:0] d_axi_awlen, + input wire [ 2:0] d_axi_awsize, + input wire [ 1:0] d_axi_awburst, + input wire d_axi_awlock, + input wire [ 3:0] d_axi_awcache, + input wire [ 2:0] d_axi_awprot, + input wire d_axi_awvalid, + output wire d_axi_awready, + input wire [ DATA_W-1:0] d_axi_wdata, + input wire [ STRB_W-1:0] d_axi_wstrb, + input wire d_axi_wlast, + input wire d_axi_wvalid, + output wire d_axi_wready, + output wire [AXI_ID_W-1:0] d_axi_bid, + output wire [ 1:0] d_axi_bresp, + output wire d_axi_bvalid, + input wire d_axi_bready, + input wire [AXI_ID_W-1:0] d_axi_arid, + input wire [ ADDR_W-1:0] d_axi_araddr, + input wire [ 7:0] d_axi_arlen, + input wire [ 2:0] d_axi_arsize, + input wire [ 1:0] d_axi_arburst, + input wire d_axi_arlock, + input wire [ 3:0] d_axi_arcache, + input wire [ 2:0] d_axi_arprot, + input wire d_axi_arvalid, + output wire d_axi_arready, + output wire [AXI_ID_W-1:0] d_axi_rid, + output wire [ DATA_W-1:0] d_axi_rdata, + output wire [ 1:0] d_axi_rresp, + output wire d_axi_rlast, + output wire d_axi_rvalid, + input wire d_axi_rready, `include "clk_en_rst_s_port.vs" ); + localparam RAM_AXI_ID_W = 1; + localparam RAM_AXI_LEN_W = 8; + localparam RAM_AXI_ADDR_W = SRAM_ADDR_W; + localparam RAM_AXI_DATA_W = DATA_W; + wire mm_reg_enable; wire int_d_axi_awvalid; wire int_d_axi_wvalid; @@ -105,14 +110,18 @@ module int_mem #( reg boot_nxt; //create CPU reset pulse wire cpu_rst_req; + `include "ram_axi_wire.vs" assign mm_reg_enable = d_axi_awaddr[B_BIT]; assign boot_wr = mm_reg_enable & d_axi_wvalid & (|d_axi_wstrb); - assign cpu_rst_req = mm_reg_enable & d_axi_wvalid & (|d_axi_wstrb) & cpu_wdata[1]; + assign cpu_rst_req = mm_reg_enable & d_axi_wvalid & (|d_axi_wstrb) & d_axi_wdata[1]; assign int_d_axi_awvalid = (~mm_reg_enable) & d_axi_awvalid; assign int_d_axi_wvalid = (~mm_reg_enable) & d_axi_wvalid; + assign ram_axi_awlock[1] = 1'b0; + assign ram_axi_arlock[1] = 1'b0; + iob_reg_re #( .DATA_W (1), .RST_VAL(1) @@ -122,7 +131,7 @@ module int_mem #( .cke_i (cke_i), .rst_i (1'b0), .en_i (boot_wr), - .data_i(cpu_wdata[0]), + .data_i(d_axi_wdata[0]), .data_o(boot_nxt) ); iob_reg_r #( @@ -144,7 +153,7 @@ module int_mem #( .arst_i (arst_i), .cke_i (cke_i), .start_i(cpu_rst_req), - .pulse_o(cpu_rst) + .pulse_o(cpu_reset) ); axi_interconnect #( @@ -154,19 +163,19 @@ module int_mem #( .M_ADDR_WIDTH(SRAM_ADDR_W), .S_COUNT (2), .M_COUNT (1) - ) extmem_axi_interconnect ( + ) sram_axi_interconnect ( .clk(clk_i), .rst(arst_i), - .s_axi_awid({3'b000, i_axi_awid, 3'b000, d_axi_awid}), + .s_axi_awid({i_axi_awid, d_axi_awid}), .s_axi_awaddr({i_axi_awaddr[SRAM_ADDR_W-1:0], d_axi_awaddr[SRAM_ADDR_W-1:0]}), .s_axi_awlen({i_axi_awlen, d_axi_awlen}), .s_axi_awsize({i_axi_awsize, d_axi_awsize}), .s_axi_awburst({i_axi_awburst, d_axi_awburst}), - .s_axi_awlock({i_axi_awlock[0], d_axi_awlock[0]}), + .s_axi_awlock({i_axi_awlock, d_axi_awlock}), .s_axi_awcache({i_axi_awcache, d_axi_awcache}), .s_axi_awprot({i_axi_awprot, d_axi_awprot}), - .s_axi_awqos({i_axi_awqos, d_axi_awqos}), + .s_axi_awqos({4'h0, 4'h0}), .s_axi_awvalid({i_axi_awvalid, int_d_axi_awvalid}), .s_axi_awready({i_axi_awready, d_axi_awready}), .s_axi_wdata({i_axi_wdata, d_axi_wdata}), @@ -174,22 +183,22 @@ module int_mem #( .s_axi_wlast({i_axi_wlast, d_axi_wlast}), .s_axi_wvalid({i_axi_wvalid, int_d_axi_wvalid}), .s_axi_wready({i_axi_wready, d_axi_wready}), - .s_axi_bid(extmem_axi_bid), + .s_axi_bid({i_axi_bid, d_axi_bid}), .s_axi_bresp({i_axi_bresp, d_axi_bresp}), .s_axi_bvalid({i_axi_bvalid, d_axi_bvalid}), .s_axi_bready({i_axi_bready, d_axi_bready}), - .s_axi_arid({3'b000, i_axi_arid, 3'b000, d_axi_arid}), + .s_axi_arid({i_axi_arid, d_axi_arid}), .s_axi_araddr({i_axi_araddr[SRAM_ADDR_W-1:0], d_axi_araddr[SRAM_ADDR_W-1:0]}), .s_axi_arlen({i_axi_arlen, d_axi_arlen}), .s_axi_arsize({i_axi_arsize, d_axi_arsize}), .s_axi_arburst({i_axi_arburst, d_axi_arburst}), - .s_axi_arlock({i_axi_arlock[0], d_axi_arlock[0]}), + .s_axi_arlock({i_axi_arlock, d_axi_arlock}), .s_axi_arcache({i_axi_arcache, d_axi_arcache}), .s_axi_arprot({i_axi_arprot, d_axi_arprot}), - .s_axi_arqos({i_axi_arqos, d_axi_arqos}), + .s_axi_arqos({4'h0, 4'h0}), .s_axi_arvalid({i_axi_arvalid, d_axi_arvalid}), .s_axi_arready({i_axi_arready, d_axi_arready}), - .s_axi_rid(extmem_axi_rid), + .s_axi_rid({i_axi_rid, d_axi_rid}), .s_axi_rdata({i_axi_rdata, d_axi_rdata}), .s_axi_rresp({i_axi_rresp, d_axi_rresp}), .s_axi_rlast({i_axi_rlast, d_axi_rlast}), @@ -201,7 +210,7 @@ module int_mem #( .m_axi_awlen(ram_axi_awlen), .m_axi_awsize(ram_axi_awsize), .m_axi_awburst(ram_axi_awburst), - .m_axi_awlock(ram_axi_awlock), + .m_axi_awlock(ram_axi_awlock[1]), .m_axi_awcache(ram_axi_awcache), .m_axi_awprot(ram_axi_awprot), .m_axi_awqos(ram_axi_awqos), @@ -221,7 +230,7 @@ module int_mem #( .m_axi_arlen(ram_axi_arlen), .m_axi_arsize(ram_axi_arsize), .m_axi_arburst(ram_axi_arburst), - .m_axi_arlock(ram_axi_arlock), + .m_axi_arlock(ram_axi_arlock[1]), .m_axi_arcache(ram_axi_arcache), .m_axi_arprot(ram_axi_arprot), .m_axi_arqos(ram_axi_arqos), @@ -243,11 +252,11 @@ module int_mem #( ); axi_ram #( - .DATA_WIDTH(ADDR_W), - .ADDR_WIDTH(ADDR_W), + .DATA_WIDTH(DATA_W), + .ADDR_WIDTH(SRAM_ADDR_W), + .ID_WIDTH(AXI_ID_W), .FILE(BOOT_HEXFILE), - .FILE_SIZE(BOOTROM_ADDR_W), - .HEX_DATA_W(B_BIT - 1) + .FILE_SIZE(2**(BOOTROM_ADDR_W-2)) ) boot_ram ( .clk_i(clk_i), .rst_i(arst_i), diff --git a/hardware/src/iob2axi.v b/hardware/src/iob2axi.v deleted file mode 100644 index 536f9fbc..00000000 --- a/hardware/src/iob2axi.v +++ /dev/null @@ -1,503 +0,0 @@ -`timescale 1ns / 1ps - -module iob2axi #( - // Width of address bus in bits - parameter ADDR_WIDTH = 32, - // Width of input (slave/master) AXI/IOb interface data bus in bits - parameter DATA_WIDTH = 32, - // Width of input (slave/master) AXI/IOb interface wstrb (width of data bus in words) - parameter STRB_WIDTH = (DATA_WIDTH / 8), - // Width of AXI ID signal - parameter AXI_ID_WIDTH = 8, - // Length of AXI read burst (Burst_Length = AxLEN[7:0] + 1) - parameter AXI_RLEN = 8'h00, - // Length of AXI write burst (Burst_Length = AxLEN[7:0] + 1) - parameter AXI_WLEN = 8'h00 -) ( - input wire clk_i, //System clock input - input wire cke_i, //System clock enable - input wire arst_i, //System reset, asynchronous and active high - /* - * IOb-bus slave interface - */ - input wire iob_avalid_i, - input wire [ ADDR_WIDTH-1:0] iob_addr_i, - input wire [ DATA_WIDTH-1:0] iob_wdata_i, - input wire [ STRB_WIDTH-1:0] iob_wstrb_i, - output reg [ DATA_WIDTH-1:0] iob_rdata_o, - output wire iob_rvalid_o, - output wire iob_ready_o, - /* - * AXI master interface - */ - output wire [AXI_ID_WIDTH-1:0] axi_awid_o, - output wire [ ADDR_WIDTH-1:0] axi_awaddr_o, - output wire [ 7:0] axi_awlen_o, - output wire [ 2:0] axi_awsize_o, - output wire [ 1:0] axi_awburst_o, - output wire [ 1:0] axi_awlock_o, - output wire [ 3:0] axi_awcache_o, - output wire [ 2:0] axi_awprot_o, - output wire [ 3:0] axi_awqos_o, - output wire axi_awvalid_o, - input wire axi_awready_i, - output reg [ DATA_WIDTH-1:0] axi_wdata_o, - output reg [ STRB_WIDTH-1:0] axi_wstrb_o, - output reg axi_wlast_o, - output wire axi_wvalid_o, - input wire axi_wready_i, - input wire [AXI_ID_WIDTH-1:0] axi_bid_i, - input wire [ 1:0] axi_bresp_i, - input wire axi_bvalid_i, - output wire axi_bready_o, - output wire [AXI_ID_WIDTH-1:0] axi_arid_o, - output wire [ ADDR_WIDTH-1:0] axi_araddr_o, - output wire [ 7:0] axi_arlen_o, - output wire [ 2:0] axi_arsize_o, - output wire [ 1:0] axi_arburst_o, - output wire [ 1:0] axi_arlock_o, - output wire [ 3:0] axi_arcache_o, - output wire [ 2:0] axi_arprot_o, - output wire [ 3:0] axi_arqos_o, - output reg axi_arvalid_o, - input wire axi_arready_i, - input wire [AXI_ID_WIDTH-1:0] axi_rid_i, - input wire [ DATA_WIDTH-1:0] axi_rdata_i, - input wire [ 1:0] axi_rresp_i, - input wire axi_rlast_i, - input wire axi_rvalid_i, - output wire axi_rready_o -); - - localparam integer BurstRLEN = AXI_RLEN + 1; - localparam integer BurstWLEN = AXI_WLEN + 1; - localparam integer IDLE = 0, WriteFIFO = 1, ReadFIFO = 2; - localparam integer WaitForValid = 0, WaitForAWValid = 1, WaitForWValid = 2, ExecuteWrite = 3; - - wire iob_we; - // Write bus - wire w_fifo_full; - reg w_fifo_wr; - reg [DATA_WIDTH+STRB_WIDTH-1:0] w_fifo_wdata; - wire w_fifo_empty; - reg w_fifo_rd; - wire [DATA_WIDTH+STRB_WIDTH-1:0] w_fifo_rdata; - wire [ BurstWLEN:0] w_fifo_level; - wire w_ext_mem_clk; - wire w_ext_mem_w_en; - wire [ BurstWLEN-1:0] w_ext_mem_w_addr; - wire [DATA_WIDTH+STRB_WIDTH-1:0] w_ext_mem_w_data; - wire w_ext_mem_r_en; - wire [ BurstWLEN-1:0] w_ext_mem_r_addr; - wire [DATA_WIDTH+STRB_WIDTH-1:0] w_ext_mem_r_data; - wire iob_wvalid; - wire [ ADDR_WIDTH-1:0] iob_waddr_q; - reg iob_wready; - reg axi_awvalid_next; - reg axi_wvalid_next; - wire [ 1:0] w_state_q; - reg [ 1:0] w_state_next; - wire [ 1:0] w_readFifo_state; - reg [ 1:0] w_readFifo_state_next; - // Read bus - wire r_fifo_full; - reg r_fifo_wr; - reg [ DATA_WIDTH-1:0] r_fifo_wdata; - wire r_fifo_empty; - reg r_fifo_rd; - wire [ DATA_WIDTH-1:0] r_fifo_rdata; - wire [ BurstRLEN:0] r_fifo_level; - wire r_ext_mem_clk; - wire r_ext_mem_w_en; - wire [ BurstRLEN-1:0] r_ext_mem_w_addr; - wire [ DATA_WIDTH-1:0] r_ext_mem_w_data; - wire r_ext_mem_r_en; - wire [ BurstRLEN-1:0] r_ext_mem_r_addr; - wire [ DATA_WIDTH-1:0] r_ext_mem_r_data; - wire iob_arvalid; - reg iob_arready; - wire [ ADDR_WIDTH-1:0] iob_araddr_q; - reg iob_rvalid_next; - wire [ 1:0] r_state_q; - reg [ 1:0] r_state_next; - - assign iob_we = |iob_wstrb_i; - assign iob_ready_o = iob_wready & iob_arready; - // Write bus - // // IOb-bus - assign iob_wvalid = iob_we & iob_avalid_i; - // // AXI - assign axi_awid_o = {AXI_ID_WIDTH{1'b0}}; - assign axi_awaddr_o = iob_wvalid ? iob_addr_i : iob_waddr_q; - assign axi_awlen_o = AXI_WLEN; - assign axi_awsize_o = 3'b010; - assign axi_awburst_o = 2'b01; - assign axi_awlock_o = 2'b00; - assign axi_awcache_o = 4'hf; - assign axi_awprot_o = 3'b010; - assign axi_awqos_o = 4'h0; - assign axi_bready_o = 1'b1; - // Read bus - // // IOb-bus - assign iob_arvalid = ~iob_we & iob_avalid_i; - // // AXI - assign axi_arid_o = {AXI_ID_WIDTH{1'b0}}; - assign axi_araddr_o = iob_arvalid ? iob_addr_i : iob_araddr_q; - assign axi_arlen_o = AXI_RLEN; - assign axi_arsize_o = 3'b010; - assign axi_arburst_o = 2'b01; - assign axi_arlock_o = 2'b00; - assign axi_arcache_o = 4'hf; - assign axi_arprot_o = 3'b010; - assign axi_arqos_o = 4'h0; - assign axi_rready_o = 1'b1; - - - // Write bus FSM - always @(*) begin - axi_awvalid_next = axi_awvalid_o; - axi_wvalid_next = axi_wvalid_o; - axi_wdata_o = {DATA_WIDTH{1'b0}}; - axi_wstrb_o = {STRB_WIDTH{1'b0}}; - axi_wlast_o = 1'b0; - iob_wready = 1'b0; - w_fifo_wr = 1'b0; - w_fifo_rd = 1'b0; - w_fifo_wdata = {DATA_WIDTH + STRB_WIDTH{1'b0}}; - w_state_next = w_state_q; - w_readFifo_state_next = w_readFifo_state; - case (w_state_q) - default: begin - iob_wready = 1'b1; - if (iob_wvalid) begin - w_state_next = WriteFIFO; - w_fifo_wr = 1'b1; - w_fifo_wdata = {iob_wdata_i, iob_wstrb_i}; - end - end - WriteFIFO: begin - iob_wready = 1'b1; - if (w_fifo_level > AXI_WLEN) begin - w_state_next = ReadFIFO; - iob_wready = 1'b0; - w_fifo_rd = 1'b1; - axi_awvalid_next = 1'b1; - axi_wvalid_next = 1'b1; - end else if (iob_wvalid) begin - w_fifo_wr = 1'b1; - w_fifo_wdata = {iob_wdata_i, iob_wstrb_i}; - end - end - ReadFIFO: begin - case (w_readFifo_state) - WaitForValid: begin - if (axi_awready_i & axi_wready_i) begin - axi_awvalid_next = 1'b0; - axi_wvalid_next = 1'b0; - w_fifo_rd = 1'b1; - {axi_wdata_o, axi_wstrb_o} = w_fifo_rdata; - if (w_fifo_empty) begin - w_state_next = IDLE; - axi_wlast_o = 1'b1; - end else begin - w_readFifo_state_next = ExecuteWrite; - end - end else if (axi_awready_i) begin - axi_awvalid_next = 1'b0; - w_readFifo_state_next = WaitForWValid; - end else if (axi_wready_i) begin - axi_wvalid_next = 1'b0; - w_readFifo_state_next = WaitForAWValid; - end - end - WaitForAWValid: begin - if (axi_awready_i) begin - axi_awvalid_next = 1'b0; - w_fifo_rd = 1'b1; - {axi_wdata_o, axi_wstrb_o} = w_fifo_rdata; - if (w_fifo_empty) begin - w_readFifo_state_next = WaitForValid; - w_state_next = IDLE; - axi_wlast_o = 1'b1; - end else begin - w_readFifo_state_next = ExecuteWrite; - end - end - end - WaitForWValid: begin - if (axi_wready_i) begin - axi_wvalid_next = 1'b0; - w_fifo_rd = 1'b1; - {axi_wdata_o, axi_wstrb_o} = w_fifo_rdata; - if (w_fifo_empty) begin - w_readFifo_state_next = WaitForValid; - w_state_next = IDLE; - axi_wlast_o = 1'b1; - end else begin - w_readFifo_state_next = ExecuteWrite; - end - end - end - default: begin - w_fifo_rd = 1'b1; - {axi_wdata_o, axi_wstrb_o} = w_fifo_rdata; - if (w_fifo_empty) begin - w_readFifo_state_next = WaitForValid; - w_state_next = IDLE; - axi_wlast_o = 1'b1; - end - end - endcase - end - endcase - end - - // Read bus FSM - always @(*) begin - iob_arready = 1'b0; - axi_arvalid_o = 1'b0; - iob_rvalid_next = 1'b0; - iob_rdata_o = {DATA_WIDTH{1'b0}}; - r_fifo_wr = 1'b0; - r_fifo_rd = 1'b0; - r_fifo_wdata = {DATA_WIDTH{1'b0}}; - r_state_next = r_state_q; - case (r_state_q) - default: begin - iob_arready = axi_arready_i; - if (iob_arvalid) begin - axi_arvalid_o = 1'b1; - if (axi_arready_i) begin - r_state_next = WriteFIFO; - end - end - end - WriteFIFO: begin - if (r_fifo_level > AXI_RLEN) begin - r_state_next = ReadFIFO; - r_fifo_rd = 1'b1; - iob_rvalid_next = 1'b1; - end else if (axi_rvalid_i) begin - r_fifo_wr = 1'b1; - r_fifo_wdata = axi_rdata_i; - end - end - ReadFIFO: begin - if (r_fifo_empty) begin - r_state_next = IDLE; - end else begin - iob_arready = 1'b1; - iob_rdata_o = r_fifo_rdata; - if (iob_arvalid) begin - r_fifo_rd = 1'b1; - iob_rvalid_next = 1'b1; - end - end - end - endcase - end - - - // - // Write bus FIFO - // - iob_fifo_sync #( - .W_DATA_W(DATA_WIDTH + STRB_WIDTH), - .R_DATA_W(DATA_WIDTH + STRB_WIDTH), - .ADDR_W (BurstWLEN) - ) write_bus_iob_fifo_sync ( - .clk_i (clk_i), - .cke_i (cke_i), - .arst_i(arst_i), - - .rst_i(1'b0), - - .w_en_i (w_fifo_wr), - .w_data_i(w_fifo_wdata), - .w_full_o(w_fifo_full), - - .r_en_i (w_fifo_rd), - .r_data_o (w_fifo_rdata), - .r_empty_o(w_fifo_empty), - - .ext_mem_clk_o(w_ext_mem_clk), - .ext_mem_w_en_o(w_ext_mem_w_en), - .ext_mem_w_addr_o(w_ext_mem_w_addr), - .ext_mem_w_data_o(w_ext_mem_w_data), - - .ext_mem_r_en_o (w_ext_mem_r_en), - .ext_mem_r_addr_o(w_ext_mem_r_addr), - .ext_mem_r_data_i(w_ext_mem_r_data), - - .level_o(w_fifo_level) - ); - - iob_ram_2p #( - .DATA_W(DATA_WIDTH + STRB_WIDTH), - .ADDR_W(BurstWLEN) - ) write_bus_ram ( - .clk_i(w_ext_mem_clk), - - .w_en_i (w_ext_mem_w_en), - .w_addr_i(w_ext_mem_w_addr), - .w_data_i(w_ext_mem_w_data), - - .r_en_i (w_ext_mem_r_en), - .r_addr_i(w_ext_mem_r_addr), - .r_data_o(w_ext_mem_r_data) - ); - - iob_reg_re #( - .DATA_W (ADDR_WIDTH), - .RST_VAL(0) - ) iob_reg_iob_waddr ( - .clk_i (clk_i), - .arst_i(arst_i), - .cke_i (cke_i), - .rst_i (1'b0), - .en_i (iob_wvalid), - .data_i(iob_addr_i), - .data_o(iob_waddr_q) - ); - - iob_reg_re #( - .DATA_W (2), - .RST_VAL(0) - ) iob_reg_w_readFifo_state ( - .clk_i (clk_i), - .arst_i(arst_i), - .cke_i (cke_i), - .rst_i (1'b0), - .en_i (1'b1), - .data_i(w_readFifo_state_next), - .data_o(w_readFifo_state) - ); - - iob_reg_re #( - .DATA_W (2), - .RST_VAL(0) - ) iob_reg_w_state ( - .clk_i (clk_i), - .arst_i(arst_i), - .cke_i (cke_i), - .rst_i (1'b0), - .en_i (1'b1), - .data_i(w_state_next), - .data_o(w_state_q) - ); - - iob_reg_re #( - .DATA_W (1), - .RST_VAL(0) - ) iob_reg_axi_awvalid ( - .clk_i (clk_i), - .arst_i(arst_i), - .cke_i (cke_i), - .rst_i (1'b0), - .en_i (1'b1), - .data_i(axi_awvalid_next), - .data_o(axi_awvalid_o) - ); - - iob_reg_re #( - .DATA_W (1), - .RST_VAL(0) - ) iob_reg_axi_wvalid ( - .clk_i (clk_i), - .arst_i(arst_i), - .cke_i (cke_i), - .rst_i (1'b0), - .en_i (1'b1), - .data_i(axi_wvalid_next), - .data_o(axi_wvalid_o) - ); - - // - // Read bus FIFO - // - iob_fifo_sync #( - .W_DATA_W(DATA_WIDTH), - .R_DATA_W(DATA_WIDTH), - .ADDR_W (BurstRLEN) - ) read_bus_iob_fifo_sync ( - .clk_i (clk_i), - .cke_i (cke_i), - .arst_i(arst_i), - - .rst_i(1'b0), - - .w_en_i (r_fifo_wr), - .w_data_i(r_fifo_wdata), - .w_full_o(r_fifo_full), - - .r_en_i (r_fifo_rd), - .r_data_o (r_fifo_rdata), - .r_empty_o(r_fifo_empty), - - .ext_mem_clk_o(r_ext_mem_clk), - .ext_mem_w_en_o(r_ext_mem_w_en), - .ext_mem_w_addr_o(r_ext_mem_w_addr), - .ext_mem_w_data_o(r_ext_mem_w_data), - - .ext_mem_r_en_o (r_ext_mem_r_en), - .ext_mem_r_addr_o(r_ext_mem_r_addr), - .ext_mem_r_data_i(r_ext_mem_r_data), - - .level_o(r_fifo_level) - ); - - iob_ram_2p #( - .DATA_W(DATA_WIDTH), - .ADDR_W(BurstRLEN) - ) read_bus_ram ( - .clk_i(r_ext_mem_clk), - - .w_en_i (r_ext_mem_w_en), - .w_addr_i(r_ext_mem_w_addr), - .w_data_i(r_ext_mem_w_data), - - .r_en_i (r_ext_mem_r_en), - .r_addr_i(r_ext_mem_r_addr), - .r_data_o(r_ext_mem_r_data) - ); - - iob_reg_re #( - .DATA_W (ADDR_WIDTH), - .RST_VAL(0) - ) iob_reg_iob_raddr ( - .clk_i (clk_i), - .arst_i(arst_i), - .cke_i (cke_i), - .rst_i (1'b0), - .en_i (iob_arvalid), - .data_i(iob_addr_i), - .data_o(iob_araddr_q) - ); - - iob_reg_re #( - .DATA_W (2), - .RST_VAL(0) - ) iob_reg_r_state ( - .clk_i (clk_i), - .arst_i(arst_i), - .cke_i (cke_i), - .rst_i (1'b0), - .en_i (1'b1), - .data_i(r_state_next), - .data_o(r_state_q) - ); - - iob_reg_re #( - .DATA_W (1), - .RST_VAL(0) - ) iob_reg_iob_rvalid ( - .clk_i (clk_i), - .arst_i(arst_i), - .cke_i (cke_i), - .rst_i (1'b0), - .en_i (1'b1), - .data_i(iob_rvalid_next), - .data_o(iob_rvalid_o) - ); - -endmodule diff --git a/hardware/src/iob_soc_opencryptolinux.v b/hardware/src/iob_soc_opencryptolinux.v index e1df1dd8..409fbd19 100644 --- a/hardware/src/iob_soc_opencryptolinux.v +++ b/hardware/src/iob_soc_opencryptolinux.v @@ -15,7 +15,6 @@ module iob_soc_opencryptolinux #( localparam integer Bbit = `IOB_SOC_OPENCRYPTOLINUX_B; localparam integer AddrMsb = `REQ_W - 2; - localparam integer MEM_ADDR_OFFSET = 0; localparam IBUS_AXI_ID_W = 1; localparam IBUS_AXI_LEN_W = 8; @@ -37,12 +36,16 @@ module iob_soc_opencryptolinux #( localparam IBUS_EXTMEM_AXI_LEN_W = 8; localparam IBUS_EXTMEM_AXI_ADDR_W = 32; localparam IBUS_EXTMEM_AXI_DATA_W = 32; + localparam DBUS_INTMEM_AXI_ID_W = 1; + localparam DBUS_INTMEM_AXI_LEN_W = 8; + localparam DBUS_INTMEM_AXI_ADDR_W = 32; + localparam DBUS_INTMEM_AXI_DATA_W = 32; localparam DBUS_EXTMEM_AXI_ID_W = 1; localparam DBUS_EXTMEM_AXI_LEN_W = 8; localparam DBUS_EXTMEM_AXI_ADDR_W = 32; localparam DBUS_EXTMEM_AXI_DATA_W = 32; - localparam N_SLAVES = `IOB_SOC_OPENCRYPTOLINUX_N_SLAVES+2; // add 2 if using CPU PLIC and CLINT + localparam N_SLAVES = 3; // PLIC, UART and CLINT `include "iob_soc_opencryptolinux_pwires.vs" @@ -74,7 +77,6 @@ module iob_soc_opencryptolinux #( wire boot; wire cpu_reset; - wire cke_i = 1'b1; // // CPU @@ -94,10 +96,10 @@ module iob_soc_opencryptolinux #( .cke_i (cke_i), .arst_i (arst_i), .cpu_reset_i (cpu_reset), - .clint_req (slaves_req[(N_SLAVES-2)*69+:`REQ_W]), - .clint_resp (slaves_resp[(N_SLAVES-2)*34+:`RESP_W]), - .plic_req (slaves_req[(N_SLAVES-1)*69+:`REQ_W]), - .plic_resp (slaves_resp[(N_SLAVES-1)*34+:`RESP_W]), + .clint_req (slaves_req[(N_SLAVES-1)*69+:`REQ_W]), + .clint_resp (slaves_resp[(N_SLAVES-1)*34+:`RESP_W]), + .plic_req (slaves_req[0+:`REQ_W]), + .plic_resp (slaves_resp[0+:`RESP_W]), .plicInterrupts(32'd0), // Axi instruction bus `include "iBus_axi_m_portmap.vs" @@ -117,6 +119,8 @@ module iob_soc_opencryptolinux #( `include "iBus_extmem_axi_wire.vs" // Data internal AXI bus `include "peripheral_axi_wire.vs" + // Intructions intmem AXI bus + `include "dBus_intmem_axi_wire.vs" // Data extmem AXI bus `include "dBus_extmem_axi_wire.vs" @@ -125,7 +129,7 @@ module iob_soc_opencryptolinux #( .ID_WIDTH (1), .DATA_WIDTH(DATA_W), .ADDR_WIDTH(ADDR_W), - .M_ADDR_WIDTH({2{32'd31}}), + .M_ADDR_WIDTH({{32'd31}, {32'd31}}), .S_COUNT (1), .M_COUNT (2) ) iBus_axi_interconnect ( @@ -216,60 +220,6 @@ module iob_soc_opencryptolinux #( .m_axi_ruser (2'b00) ); - // instantiate axi2iob CPU data - axi2iob #( - .ADDR_WIDTH (ADDR_W), - .DATA_WIDTH (DATA_W), - .STRB_WIDTH ((DATA_W / 8)), - .AXI_ID_WIDTH(1) - ) iBus_intmem_axi2iob ( - .clk_i(clk_i), - .arst_i(arst_i), - .s_axi_awid(iBus_intmem_axi_awid), - .s_axi_awaddr(iBus_intmem_axi_awaddr), - .s_axi_awlen(iBus_intmem_axi_awlen), - .s_axi_awsize(iBus_intmem_axi_awsize), - .s_axi_awburst(iBus_intmem_axi_awburst), - .s_axi_awlock(iBus_intmem_axi_awlock[0]), - .s_axi_awcache(iBus_intmem_axi_awcache), - .s_axi_awprot(iBus_intmem_axi_awprot), - .s_axi_awvalid(iBus_intmem_axi_awvalid), - .s_axi_awready(iBus_intmem_axi_awready), - .s_axi_wdata(iBus_intmem_axi_wdata), - .s_axi_wstrb(iBus_intmem_axi_wstrb), - .s_axi_wlast(iBus_intmem_axi_wlast), - .s_axi_wvalid(iBus_intmem_axi_wvalid), - .s_axi_wready(iBus_intmem_axi_wready), - .s_axi_bid(iBus_intmem_axi_bid), - .s_axi_bresp(iBus_intmem_axi_bresp), - .s_axi_bvalid(iBus_intmem_axi_bvalid), - .s_axi_bready(iBus_intmem_axi_bready), - .s_axi_arid(iBus_intmem_axi_arid), - .s_axi_araddr(iBus_intmem_axi_araddr), - .s_axi_arlen(iBus_intmem_axi_arlen), - .s_axi_arsize(iBus_intmem_axi_arsize), - .s_axi_arburst(iBus_intmem_axi_arburst), - .s_axi_arlock(iBus_intmem_axi_arlock[0]), - .s_axi_arcache(iBus_intmem_axi_arcache), - .s_axi_arprot(iBus_intmem_axi_arprot), - .s_axi_arvalid(iBus_intmem_axi_arvalid), - .s_axi_arready(iBus_intmem_axi_arready), - .s_axi_rid(iBus_intmem_axi_rid), - .s_axi_rdata(iBus_intmem_axi_rdata), - .s_axi_rresp(iBus_intmem_axi_rresp), - .s_axi_rlast(iBus_intmem_axi_rlast), - .s_axi_rvalid(iBus_intmem_axi_rvalid), - .s_axi_rready(iBus_intmem_axi_rready), - // IOb-bus signals - .iob_avalid_o(iBus_intmem_iob_avalid), - .iob_addr_o(iBus_intmem_iob_addr), - .iob_wdata_o(iBus_intmem_iob_wdata), - .iob_wstrb_o(iBus_intmem_iob_wstrb), - .iob_rvalid_i(iBus_intmem_iob_rvalid), - .iob_rdata_i(iBus_intmem_iob_rdata), - .iob_ready_i(iBus_intmem_iob_ready) - ); - // // SPLIT INTERNAL MEMORY AND PERIPHERALS BUS // @@ -279,9 +229,9 @@ module iob_soc_opencryptolinux #( .ID_WIDTH (1), .DATA_WIDTH(DATA_W), .ADDR_WIDTH(ADDR_W), - .M_ADDR_WIDTH({2{32'd31}}), + .M_ADDR_WIDTH({{32'd31}, {32'd30}, {32'd30}}), .S_COUNT (1), - .M_COUNT (2) + .M_COUNT (3) ) dBus_axi_interconnect ( .clk(clk_i), .rst(arst_i), @@ -324,96 +274,84 @@ module iob_soc_opencryptolinux #( .s_axi_rvalid(dBus_axi_rvalid), .s_axi_rready(dBus_axi_rready), - .m_axi_awid({peripheral_axi_awid, dBus_extmem_axi_awid}), - .m_axi_awaddr({peripheral_axi_awaddr, dBus_extmem_axi_awaddr}), - .m_axi_awlen({peripheral_axi_awlen, dBus_extmem_axi_awlen}), - .m_axi_awsize({peripheral_axi_awsize, dBus_extmem_axi_awsize}), - .m_axi_awburst({peripheral_axi_awburst, dBus_extmem_axi_awburst}), - .m_axi_awlock({peripheral_axi_awlock[0], dBus_extmem_axi_awlock[0]}), - .m_axi_awcache({peripheral_axi_awcache, dBus_extmem_axi_awcache}), - .m_axi_awprot({peripheral_axi_awprot, dBus_extmem_axi_awprot}), - .m_axi_awqos({peripheral_axi_awqos, dBus_extmem_axi_awqos}), - .m_axi_awvalid({peripheral_axi_awvalid, dBus_extmem_axi_awvalid}), - .m_axi_awready({peripheral_axi_awready, dBus_extmem_axi_awready}), - .m_axi_wdata({peripheral_axi_wdata, dBus_extmem_axi_wdata}), - .m_axi_wstrb({peripheral_axi_wstrb, dBus_extmem_axi_wstrb}), - .m_axi_wlast({peripheral_axi_wlast, dBus_extmem_axi_wlast}), - .m_axi_wvalid({peripheral_axi_wvalid, dBus_extmem_axi_wvalid}), - .m_axi_wready({peripheral_axi_wready, dBus_extmem_axi_wready}), - .m_axi_bid({peripheral_axi_bid, dBus_extmem_axi_bid}), - .m_axi_bresp({peripheral_axi_bresp, dBus_extmem_axi_bresp}), - .m_axi_bvalid({peripheral_axi_bvalid, dBus_extmem_axi_bvalid}), - .m_axi_bready({peripheral_axi_bready, dBus_extmem_axi_bready}), - .m_axi_arid({peripheral_axi_arid, dBus_extmem_axi_arid}), - .m_axi_araddr({peripheral_axi_araddr, dBus_extmem_axi_araddr}), - .m_axi_arlen({peripheral_axi_arlen, dBus_extmem_axi_arlen}), - .m_axi_arsize({peripheral_axi_arsize, dBus_extmem_axi_arsize}), - .m_axi_arburst({peripheral_axi_arburst, dBus_extmem_axi_arburst}), - .m_axi_arlock({peripheral_axi_arlock[0], dBus_extmem_axi_arlock[0]}), - .m_axi_arcache({peripheral_axi_arcache, dBus_extmem_axi_arcache}), - .m_axi_arprot({peripheral_axi_arprot, dBus_extmem_axi_arprot}), - .m_axi_arqos({peripheral_axi_arqos, dBus_extmem_axi_arqos}), - .m_axi_arvalid({peripheral_axi_arvalid, dBus_extmem_axi_arvalid}), - .m_axi_arready({peripheral_axi_arready, dBus_extmem_axi_arready}), - .m_axi_rid({peripheral_axi_rid, dBus_extmem_axi_rid}), - .m_axi_rdata({peripheral_axi_rdata, dBus_extmem_axi_rdata}), - .m_axi_rresp({peripheral_axi_rresp, dBus_extmem_axi_rresp}), - .m_axi_rlast({peripheral_axi_rlast, dBus_extmem_axi_rlast}), - .m_axi_rvalid({peripheral_axi_rvalid, dBus_extmem_axi_rvalid}), - .m_axi_rready({peripheral_axi_rready, dBus_extmem_axi_rready}), + .m_axi_awid({dBus_intmem_axi_awid, peripheral_axi_awid, dBus_extmem_axi_awid}), + .m_axi_awaddr({dBus_intmem_axi_awaddr, peripheral_axi_awaddr, dBus_extmem_axi_awaddr}), + .m_axi_awlen({dBus_intmem_axi_awlen, peripheral_axi_awlen, dBus_extmem_axi_awlen}), + .m_axi_awsize({dBus_intmem_axi_awsize, peripheral_axi_awsize, dBus_extmem_axi_awsize}), + .m_axi_awburst({dBus_intmem_axi_awburst, peripheral_axi_awburst, dBus_extmem_axi_awburst}), + .m_axi_awlock({ + dBus_intmem_axi_awlock[0], peripheral_axi_awlock[0], dBus_extmem_axi_awlock[0] + }), + .m_axi_awcache({dBus_intmem_axi_awcache, peripheral_axi_awcache, dBus_extmem_axi_awcache}), + .m_axi_awprot({dBus_intmem_axi_awprot, peripheral_axi_awprot, dBus_extmem_axi_awprot}), + .m_axi_awqos({dBus_intmem_axi_awqos, peripheral_axi_awqos, dBus_extmem_axi_awqos}), + .m_axi_awvalid({dBus_intmem_axi_awvalid, peripheral_axi_awvalid, dBus_extmem_axi_awvalid}), + .m_axi_awready({dBus_intmem_axi_awready, peripheral_axi_awready, dBus_extmem_axi_awready}), + .m_axi_wdata({dBus_intmem_axi_wdata, peripheral_axi_wdata, dBus_extmem_axi_wdata}), + .m_axi_wstrb({dBus_intmem_axi_wstrb, peripheral_axi_wstrb, dBus_extmem_axi_wstrb}), + .m_axi_wlast({dBus_intmem_axi_wlast, peripheral_axi_wlast, dBus_extmem_axi_wlast}), + .m_axi_wvalid({dBus_intmem_axi_wvalid, peripheral_axi_wvalid, dBus_extmem_axi_wvalid}), + .m_axi_wready({dBus_intmem_axi_wready, peripheral_axi_wready, dBus_extmem_axi_wready}), + .m_axi_bid({dBus_intmem_axi_bid, peripheral_axi_bid, dBus_extmem_axi_bid}), + .m_axi_bresp({dBus_intmem_axi_bresp, peripheral_axi_bresp, dBus_extmem_axi_bresp}), + .m_axi_bvalid({dBus_intmem_axi_bvalid, peripheral_axi_bvalid, dBus_extmem_axi_bvalid}), + .m_axi_bready({dBus_intmem_axi_bready, peripheral_axi_bready, dBus_extmem_axi_bready}), + .m_axi_arid({dBus_intmem_axi_arid, peripheral_axi_arid, dBus_extmem_axi_arid}), + .m_axi_araddr({dBus_intmem_axi_araddr, peripheral_axi_araddr, dBus_extmem_axi_araddr}), + .m_axi_arlen({dBus_intmem_axi_arlen, peripheral_axi_arlen, dBus_extmem_axi_arlen}), + .m_axi_arsize({dBus_intmem_axi_arsize, peripheral_axi_arsize, dBus_extmem_axi_arsize}), + .m_axi_arburst({dBus_intmem_axi_arburst, peripheral_axi_arburst, dBus_extmem_axi_arburst}), + .m_axi_arlock({ + dBus_intmem_axi_arlock[0], peripheral_axi_arlock[0], dBus_extmem_axi_arlock[0] + }), + .m_axi_arcache({dBus_intmem_axi_arcache, peripheral_axi_arcache, dBus_extmem_axi_arcache}), + .m_axi_arprot({dBus_intmem_axi_arprot, peripheral_axi_arprot, dBus_extmem_axi_arprot}), + .m_axi_arqos({dBus_intmem_axi_arqos, peripheral_axi_arqos, dBus_extmem_axi_arqos}), + .m_axi_arvalid({dBus_intmem_axi_arvalid, peripheral_axi_arvalid, dBus_extmem_axi_arvalid}), + .m_axi_arready({dBus_intmem_axi_arready, peripheral_axi_arready, dBus_extmem_axi_arready}), + .m_axi_rid({dBus_intmem_axi_rid, peripheral_axi_rid, dBus_extmem_axi_rid}), + .m_axi_rdata({dBus_intmem_axi_rdata, peripheral_axi_rdata, dBus_extmem_axi_rdata}), + .m_axi_rresp({dBus_intmem_axi_rresp, peripheral_axi_rresp, dBus_extmem_axi_rresp}), + .m_axi_rlast({dBus_intmem_axi_rlast, peripheral_axi_rlast, dBus_extmem_axi_rlast}), + .m_axi_rvalid({dBus_intmem_axi_rvalid, peripheral_axi_rvalid, dBus_extmem_axi_rvalid}), + .m_axi_rready({dBus_intmem_axi_rready, peripheral_axi_rready, dBus_extmem_axi_rready}), //optional signals .s_axi_awuser(1'b0), .s_axi_wuser (1'b0), .s_axi_aruser(1'b0), - .m_axi_buser (2'b00), - .m_axi_ruser (2'b00) + .m_axi_buser (3'b000), + .m_axi_ruser (3'b000) ); // instantiate axi2iob CPU data - axi2iob #( - .ADDR_WIDTH (ADDR_W), - .DATA_WIDTH (DATA_W), - .STRB_WIDTH ((DATA_W / 8)), - .AXI_ID_WIDTH(1) - ) dBus_axi2iob ( + axil2iob #( + .AXIL_ADDR_W (ADDR_W), + .AXIL_DATA_W (DATA_W) + ) peripheral_axil2iob ( .clk_i(clk_i), + .cke_i(cke_i), .arst_i(arst_i), - .s_axi_awid(peripheral_axi_awid), - .s_axi_awaddr(peripheral_axi_awaddr), - .s_axi_awlen(peripheral_axi_awlen), - .s_axi_awsize(peripheral_axi_awsize), - .s_axi_awburst(peripheral_axi_awburst), - .s_axi_awlock(peripheral_axi_awlock[0]), - .s_axi_awcache(peripheral_axi_awcache), - .s_axi_awprot(peripheral_axi_awprot), - .s_axi_awvalid(peripheral_axi_awvalid), - .s_axi_awready(peripheral_axi_awready), - .s_axi_wdata(peripheral_axi_wdata), - .s_axi_wstrb(peripheral_axi_wstrb), - .s_axi_wlast(peripheral_axi_wlast), - .s_axi_wvalid(peripheral_axi_wvalid), - .s_axi_wready(peripheral_axi_wready), - .s_axi_bid(peripheral_axi_bid), - .s_axi_bresp(peripheral_axi_bresp), - .s_axi_bvalid(peripheral_axi_bvalid), - .s_axi_bready(peripheral_axi_bready), - .s_axi_arid(peripheral_axi_arid), - .s_axi_araddr(peripheral_axi_araddr), - .s_axi_arlen(peripheral_axi_arlen), - .s_axi_arsize(peripheral_axi_arsize), - .s_axi_arburst(peripheral_axi_arburst), - .s_axi_arlock(peripheral_axi_arlock[0]), - .s_axi_arcache(peripheral_axi_arcache), - .s_axi_arprot(peripheral_axi_arprot), - .s_axi_arvalid(peripheral_axi_arvalid), - .s_axi_arready(peripheral_axi_arready), - .s_axi_rid(peripheral_axi_rid), - .s_axi_rdata(peripheral_axi_rdata), - .s_axi_rresp(peripheral_axi_rresp), - .s_axi_rlast(peripheral_axi_rlast), - .s_axi_rvalid(peripheral_axi_rvalid), - .s_axi_rready(peripheral_axi_rready), + // AXI4 Lite slave interface + .axil_awaddr_i(peripheral_axi_awaddr), + .axil_awprot_i(peripheral_axi_awprot), + .axil_awvalid_i(peripheral_axi_awvalid), + .axil_awready_o(peripheral_axi_awready), + .axil_wdata_i(peripheral_axi_wdata), + .axil_wstrb_i(peripheral_axi_wstrb), + .axil_wvalid_i(peripheral_axi_wvalid), + .axil_wready_o(peripheral_axi_wready), + .axil_bresp_o(peripheral_axi_bresp), + .axil_bvalid_o(peripheral_axi_bvalid), + .axil_bready_i(peripheral_axi_bready), + .axil_araddr_i(peripheral_axi_araddr), + .axil_arprot_i(peripheral_axi_arprot), + .axil_arvalid_i(peripheral_axi_arvalid), + .axil_arready_o(peripheral_axi_arready), + .axil_rdata_o(peripheral_axi_rdata), + .axil_rresp_o(peripheral_axi_rresp), + .axil_rvalid_o(peripheral_axi_rvalid), + .axil_rready_i(peripheral_axi_rready), // IOb-bus signals .iob_avalid_o(peripheral_iob_avalid), .iob_addr_o(peripheral_iob_addr), @@ -446,15 +384,13 @@ module iob_soc_opencryptolinux #( // // INTERNAL SRAM MEMORY // - int_mem #( .ADDR_W (ADDR_W), .DATA_W (DATA_W), - .HEXFILE ("iob_soc_opencryptolinux_firmware"), - .BOOT_HEXFILE ("iob_soc_opencryptolinux_boot"), + .BOOT_HEXFILE ("iob_soc_opencryptolinux_boot.hex"), .SRAM_ADDR_W (SRAM_ADDR_W), .BOOTROM_ADDR_W(BOOTROM_ADDR_W), - .B_BIT (`B_BIT) + .B_BIT (Bbit) ) int_mem0 ( .clk_i (clk_i), .arst_i (arst_i), @@ -463,20 +399,86 @@ module iob_soc_opencryptolinux #( .cpu_reset(cpu_reset), // instruction bus - .i_req({ - iBus_intmem_iob_avalid, iBus_intmem_iob_addr, iBus_intmem_iob_wdata, iBus_intmem_iob_wstrb - }), - .i_resp({iBus_intmem_iob_rdata, iBus_intmem_iob_rvalid, iBus_intmem_iob_ready}), + .i_axi_awid(iBus_intmem_axi_awid), + .i_axi_awaddr(iBus_intmem_axi_awaddr), + .i_axi_awlen(iBus_intmem_axi_awlen), + .i_axi_awsize(iBus_intmem_axi_awsize), + .i_axi_awburst(iBus_intmem_axi_awburst), + .i_axi_awlock(iBus_intmem_axi_awlock[0]), + .i_axi_awcache(iBus_intmem_axi_awcache), + .i_axi_awprot(iBus_intmem_axi_awprot), + .i_axi_awvalid(iBus_intmem_axi_awvalid), + .i_axi_awready(iBus_intmem_axi_awready), + .i_axi_wdata(iBus_intmem_axi_wdata), + .i_axi_wstrb(iBus_intmem_axi_wstrb), + .i_axi_wlast(iBus_intmem_axi_wlast), + .i_axi_wvalid(iBus_intmem_axi_wvalid), + .i_axi_wready(iBus_intmem_axi_wready), + .i_axi_bid(iBus_intmem_axi_bid), + .i_axi_bresp(iBus_intmem_axi_bresp), + .i_axi_bvalid(iBus_intmem_axi_bvalid), + .i_axi_bready(iBus_intmem_axi_bready), + .i_axi_arid(iBus_intmem_axi_arid), + .i_axi_araddr(iBus_intmem_axi_araddr), + .i_axi_arlen(iBus_intmem_axi_arlen), + .i_axi_arsize(iBus_intmem_axi_arsize), + .i_axi_arburst(iBus_intmem_axi_arburst), + .i_axi_arlock(iBus_intmem_axi_arlock[0]), + .i_axi_arcache(iBus_intmem_axi_arcache), + .i_axi_arprot(iBus_intmem_axi_arprot), + .i_axi_arvalid(iBus_intmem_axi_arvalid), + .i_axi_arready(iBus_intmem_axi_arready), + .i_axi_rid(iBus_intmem_axi_rid), + .i_axi_rdata(iBus_intmem_axi_rdata), + .i_axi_rresp(iBus_intmem_axi_rresp), + .i_axi_rlast(iBus_intmem_axi_rlast), + .i_axi_rvalid(iBus_intmem_axi_rvalid), + .i_axi_rready(iBus_intmem_axi_rready), //data bus - .d_req (slaves_req[0+:`REQ_W]), - .d_resp(slaves_resp[0+:`RESP_W]) + .d_axi_awid(dBus_intmem_axi_awid), + .d_axi_awaddr(dBus_intmem_axi_awaddr), + .d_axi_awlen(dBus_intmem_axi_awlen), + .d_axi_awsize(dBus_intmem_axi_awsize), + .d_axi_awburst(dBus_intmem_axi_awburst), + .d_axi_awlock(dBus_intmem_axi_awlock[0]), + .d_axi_awcache(dBus_intmem_axi_awcache), + .d_axi_awprot(dBus_intmem_axi_awprot), + .d_axi_awvalid(dBus_intmem_axi_awvalid), + .d_axi_awready(dBus_intmem_axi_awready), + .d_axi_wdata(dBus_intmem_axi_wdata), + .d_axi_wstrb(dBus_intmem_axi_wstrb), + .d_axi_wlast(dBus_intmem_axi_wlast), + .d_axi_wvalid(dBus_intmem_axi_wvalid), + .d_axi_wready(dBus_intmem_axi_wready), + .d_axi_bid(dBus_intmem_axi_bid), + .d_axi_bresp(dBus_intmem_axi_bresp), + .d_axi_bvalid(dBus_intmem_axi_bvalid), + .d_axi_bready(dBus_intmem_axi_bready), + .d_axi_arid(dBus_intmem_axi_arid), + .d_axi_araddr(dBus_intmem_axi_araddr), + .d_axi_arlen(dBus_intmem_axi_arlen), + .d_axi_arsize(dBus_intmem_axi_arsize), + .d_axi_arburst(dBus_intmem_axi_arburst), + .d_axi_arlock(dBus_intmem_axi_arlock[0]), + .d_axi_arcache(dBus_intmem_axi_arcache), + .d_axi_arprot(dBus_intmem_axi_arprot), + .d_axi_arvalid(dBus_intmem_axi_arvalid), + .d_axi_arready(dBus_intmem_axi_arready), + .d_axi_rid(dBus_intmem_axi_rid), + .d_axi_rdata(dBus_intmem_axi_rdata), + .d_axi_rresp(dBus_intmem_axi_rresp), + .d_axi_rlast(dBus_intmem_axi_rlast), + .d_axi_rvalid(dBus_intmem_axi_rvalid), + .d_axi_rready(dBus_intmem_axi_rready) ); wire extmem_axi_arlock; wire extmem_axi_awlock; wire [7:0] extmem_axi_bid; wire [7:0] extmem_axi_rid; + wire [MEM_ADDR_W-1:0] internal_axi_awaddr; + wire [MEM_ADDR_W-1:0] internal_axi_araddr; assign axi_awlock_o = {1'B0, extmem_axi_awlock}; assign axi_arlock_o = {1'B0, extmem_axi_arlock}; assign {iBus_extmem_axi_bid, dBus_extmem_axi_bid} = {extmem_axi_bid[4], extmem_axi_bid[0]}; @@ -536,7 +538,7 @@ module iob_soc_opencryptolinux #( .s_axi_rready({iBus_extmem_axi_rready, dBus_extmem_axi_rready}), .m_axi_awid(axi_awid_o), - .m_axi_awaddr(internal_axi_awaddr_o), + .m_axi_awaddr(internal_axi_awaddr), .m_axi_awlen(axi_awlen_o), .m_axi_awsize(axi_awsize_o), .m_axi_awburst(axi_awburst_o), @@ -556,7 +558,7 @@ module iob_soc_opencryptolinux #( .m_axi_bvalid(axi_bvalid_i), .m_axi_bready(axi_bready_o), .m_axi_arid(axi_arid_o), - .m_axi_araddr(internal_axi_araddr_o), + .m_axi_araddr(internal_axi_araddr), .m_axi_arlen(axi_arlen_o), .m_axi_arsize(axi_arsize_o), .m_axi_arburst(axi_arburst_o), @@ -581,8 +583,8 @@ module iob_soc_opencryptolinux #( .m_axi_ruser (1'b0) ); - assign axi_awaddr_o[AXI_ADDR_W-1:0] = internal_axi_awaddr_o + MEM_ADDR_OFFSET; - assign axi_araddr_o[AXI_ADDR_W-1:0] = internal_axi_araddr_o + MEM_ADDR_OFFSET; + assign axi_awaddr_o[AXI_ADDR_W-1:0] = internal_axi_awaddr + MEM_ADDR_OFFSET; + assign axi_araddr_o[AXI_ADDR_W-1:0] = internal_axi_araddr + MEM_ADDR_OFFSET; `include "iob_soc_opencryptolinux_periphs_inst.vs" diff --git a/iob_soc_opencryptolinux.py b/iob_soc_opencryptolinux.py index bd0a35f6..f9b0973a 100755 --- a/iob_soc_opencryptolinux.py +++ b/iob_soc_opencryptolinux.py @@ -13,6 +13,7 @@ from iob_uart import iob_uart from iob_spi import iob_spi from axi_ram import axi_ram +from axil2iob import axil2iob class iob_soc_opencryptolinux(iob_soc): @@ -49,11 +50,13 @@ def _create_submodules_list(cls, extra_submodules=[]): super()._create_submodules_list( [ {"interface": "peripheral_axi_wire"}, + {"interface": "dBus_intmem_axi_wire"}, {"interface": "iBus_intmem_axi_wire"}, {"interface": "dBus_extmem_axi_wire"}, {"interface": "iBus_extmem_axi_wire"}, {"interface": "dBus_axi_wire"}, {"interface": "iBus_axi_wire"}, + {"interface": "ram_axi_wire"}, {"interface": "dBus_axi_m_port"}, {"interface": "iBus_axi_m_port"}, {"interface": "dBus_axi_m_portmap"}, @@ -61,6 +64,7 @@ def _create_submodules_list(cls, extra_submodules=[]): iob_vexriscv, iob_uart16550, axi_ram, + axil2iob, # iob_spi, (iob_uart, {"purpose": "simulation"}), ] @@ -128,7 +132,7 @@ def _setup_confs(cls, extra_confs=[]): { "name": "BOOTROM_ADDR_W", "type": "P", - "val": "13", + "val": "12", "min": "1", "max": "32", "descr": "Boot ROM address width", diff --git a/software/src/iob_soc_opencryptolinux_boot.c b/software/src/iob_soc_opencryptolinux_boot.c index 1c7ed8b3..289a1f9b 100644 --- a/software/src/iob_soc_opencryptolinux_boot.c +++ b/software/src/iob_soc_opencryptolinux_boot.c @@ -6,8 +6,8 @@ // defined here (and not in periphs.h) because it is the only peripheral used // by the bootloader -#define UART0_BASE 0xfa000000 -#define CLINT0_BASE 0xfc000000 +#define UART0_BASE 0xf4000000 +#define CLINT0_BASE 0xf8000000 #define PROGNAME "IOb-Bootloader" diff --git a/software/src/iob_soc_opencryptolinux_firmware.c b/software/src/iob_soc_opencryptolinux_firmware.c index af2ac722..9fce6196 100644 --- a/software/src/iob_soc_opencryptolinux_firmware.c +++ b/software/src/iob_soc_opencryptolinux_firmware.c @@ -10,9 +10,9 @@ #include "riscv-csr.h" #include "riscv-interrupts.h" -#define UART0_BASE 0xfa000000 -#define CLINT0_BASE 0xfc000000 -#define PLIC0_BASE 0xfe000000 +#define UART0_BASE 0xf4000000 +#define CLINT0_BASE 0xf8000000 +#define PLIC0_BASE 0xf0000000 #define MTIMER_SECONDS_TO_CLOCKS(SEC) \ ((uint64_t)(((SEC)*(FREQ)))) diff --git a/submodules/LIB b/submodules/LIB index cea0c7c3..17aaab87 160000 --- a/submodules/LIB +++ b/submodules/LIB @@ -1 +1 @@ -Subproject commit cea0c7c346ac0d29bc3c5351142057ea2016c9a5 +Subproject commit 17aaab878dc2916e5f6fb68c52f1a2a5fc749178 From 3cb47fca2703b9e9a1bb89be6ecc98d80810ca6e Mon Sep 17 00:00:00 2001 From: Pedro Antunes Date: Wed, 18 Oct 2023 00:28:19 +0100 Subject: [PATCH 25/27] iob_soc_opencryptolinux.v: simplify code. --- hardware/src/axi_interconnect.v | 24 +- hardware/src/axi_ram.v | 413 +++++++++++++ hardware/src/boot_ctr.v | 76 +++ hardware/src/int_mem.v | 303 ---------- hardware/src/iob_soc_opencryptolinux.v | 618 ++++++-------------- iob_soc_opencryptolinux.py | 10 +- software/src/iob_soc_opencryptolinux_boot.c | 1 - 7 files changed, 684 insertions(+), 761 deletions(-) create mode 100644 hardware/src/axi_ram.v create mode 100644 hardware/src/boot_ctr.v delete mode 100644 hardware/src/int_mem.v diff --git a/hardware/src/axi_interconnect.v b/hardware/src/axi_interconnect.v index a72a9a78..82de7f79 100644 --- a/hardware/src/axi_interconnect.v +++ b/hardware/src/axi_interconnect.v @@ -302,7 +302,7 @@ module axi_interconnect #( reg s_axi_rlast_int; reg [RUSER_WIDTH-1:0] s_axi_ruser_int; reg s_axi_rvalid_int; - reg s_axi_rready_int_reg = 1'b0; + reg s_axi_rready_int_reg; wire s_axi_rready_int_early; reg [ DATA_WIDTH-1:0] m_axi_wdata_int; @@ -310,7 +310,7 @@ module axi_interconnect #( reg m_axi_wlast_int; reg [WUSER_WIDTH-1:0] m_axi_wuser_int; reg m_axi_wvalid_int; - reg m_axi_wready_int_reg = 1'b0; + reg m_axi_wready_int_reg; wire m_axi_wready_int_early; assign s_axi_awready = s_axi_awready_reg; @@ -785,18 +785,18 @@ module axi_interconnect #( end // output datapath logic (R channel) - reg [ ID_WIDTH-1:0] s_axi_rid_reg = {ID_WIDTH{1'b0}}; - reg [ DATA_WIDTH-1:0] s_axi_rdata_reg = {DATA_WIDTH{1'b0}}; - reg [ 1:0] s_axi_rresp_reg = 2'd0; - reg s_axi_rlast_reg = 1'b0; - reg [RUSER_WIDTH-1:0] s_axi_ruser_reg = 1'b0; + reg [ ID_WIDTH-1:0] s_axi_rid_reg; + reg [ DATA_WIDTH-1:0] s_axi_rdata_reg; + reg [ 1:0] s_axi_rresp_reg; + reg s_axi_rlast_reg; + reg [RUSER_WIDTH-1:0] s_axi_ruser_reg; reg [S_COUNT-1:0] s_axi_rvalid_reg, s_axi_rvalid_next; - reg [ ID_WIDTH-1:0] temp_s_axi_rid_reg = {ID_WIDTH{1'b0}}; - reg [ DATA_WIDTH-1:0] temp_s_axi_rdata_reg = {DATA_WIDTH{1'b0}}; - reg [ 1:0] temp_s_axi_rresp_reg = 2'd0; - reg temp_s_axi_rlast_reg = 1'b0; - reg [RUSER_WIDTH-1:0] temp_s_axi_ruser_reg = 1'b0; + reg [ ID_WIDTH-1:0] temp_s_axi_rid_reg; + reg [ DATA_WIDTH-1:0] temp_s_axi_rdata_reg; + reg [ 1:0] temp_s_axi_rresp_reg; + reg temp_s_axi_rlast_reg; + reg [RUSER_WIDTH-1:0] temp_s_axi_ruser_reg; reg temp_s_axi_rvalid_reg, temp_s_axi_rvalid_next; // datapath control diff --git a/hardware/src/axi_ram.v b/hardware/src/axi_ram.v new file mode 100644 index 00000000..2c005fa5 --- /dev/null +++ b/hardware/src/axi_ram.v @@ -0,0 +1,413 @@ +/* + +Copyright (c) 2018 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ + +// Language: Verilog 2001 + +`timescale 1ns / 1ps + +/* + * AXI4 RAM + */ +module axi_ram #( + // Width of data bus in bits + parameter DATA_WIDTH = 32, + // Width of address bus in bits + parameter ADDR_WIDTH = 16, + // Width of wstrb (width of data bus in words) + parameter STRB_WIDTH = (DATA_WIDTH / 8), + // Width of ID signal + parameter ID_WIDTH = 8, + parameter LEN_WIDTH = 8, + // Extra pipeline register on output + parameter PIPELINE_OUTPUT = 0, + parameter FILE = "none", + parameter FILE_SIZE = 1, + parameter HEX_DATA_W = DATA_WIDTH +) ( + input wire clk_i, + input wire rst_i, + + input wire [ ID_WIDTH-1:0] axi_awid_i, + input wire [ADDR_WIDTH-1:0] axi_awaddr_i, + input wire [ LEN_WIDTH-1:0] axi_awlen_i, + input wire [ 2:0] axi_awsize_i, + input wire [ 1:0] axi_awburst_i, + input wire [ 1:0] axi_awlock_i, + input wire [ 3:0] axi_awcache_i, + input wire [ 2:0] axi_awprot_i, + input wire [ 3:0] axi_awqos_i, + input wire axi_awvalid_i, + output wire axi_awready_o, + + input wire [DATA_WIDTH-1:0] axi_wdata_i, + input wire [STRB_WIDTH-1:0] axi_wstrb_i, + input wire axi_wlast_i, + input wire axi_wvalid_i, + output wire axi_wready_o, + + output wire [ ID_WIDTH-1:0] axi_bid_o, + output wire [ 1:0] axi_bresp_o, + output wire axi_bvalid_o, + input wire axi_bready_i, + input wire [ ID_WIDTH-1:0] axi_arid_i, + input wire [ADDR_WIDTH-1:0] axi_araddr_i, + input wire [ LEN_WIDTH-1:0] axi_arlen_i, + input wire [ 2:0] axi_arsize_i, + input wire [ 1:0] axi_arburst_i, + input wire [ 1:0] axi_arlock_i, + input wire [ 3:0] axi_arcache_i, + input wire [ 2:0] axi_arprot_i, + input wire [ 3:0] axi_arqos_i, + input wire axi_arvalid_i, + output wire axi_arready_o, + output wire [ ID_WIDTH-1:0] axi_rid_o, + output wire [DATA_WIDTH-1:0] axi_rdata_o, + output wire [ 1:0] axi_rresp_o, + output wire axi_rlast_o, + output wire axi_rvalid_o, + input wire axi_rready_i +); + + localparam VALID_ADDR_WIDTH = ADDR_WIDTH - $clog2(STRB_WIDTH); + localparam WORD_WIDTH = STRB_WIDTH; + localparam WORD_SIZE = DATA_WIDTH / WORD_WIDTH; + + // bus width assertions + initial begin + if (WORD_SIZE * STRB_WIDTH != DATA_WIDTH) begin + $error("Error: AXI data width not evenly divisble (instance %m)"); + $finish(); + end + + if (2 ** $clog2(WORD_WIDTH) != WORD_WIDTH) begin + $error("Error: AXI word width must be even power of two (instance %m)"); + $finish(); + end + end + + localparam [0:0] READ_STATE_IDLE = 1'd0, READ_STATE_BURST = 1'd1; + + reg [0:0] read_state_reg, read_state_next; + + localparam [1:0] WRITE_STATE_IDLE = 2'd0, WRITE_STATE_BURST = 2'd1, WRITE_STATE_RESP = 2'd2; + + reg [1:0] write_state_reg, write_state_next; + + reg mem_wr_en; + reg mem_rd_en; + + reg [ID_WIDTH-1:0] read_id_reg, read_id_next; + reg [ADDR_WIDTH-1:0] read_addr_reg, read_addr_next; + reg [LEN_WIDTH-1:0] read_count_reg, read_count_next; + reg [2:0] read_size_reg, read_size_next; + reg [1:0] read_burst_reg, read_burst_next; + reg [ID_WIDTH-1:0] write_id_reg, write_id_next; + reg [ADDR_WIDTH-1:0] write_addr_reg, write_addr_next; + reg [LEN_WIDTH-1:0] write_count_reg, write_count_next; + reg [2:0] write_size_reg, write_size_next; + reg [1:0] write_burst_reg, write_burst_next; + + reg axi_awready_reg, axi_awready_next; + reg axi_wready_reg, axi_wready_next; + reg [ID_WIDTH-1:0] axi_bid_reg, axi_bid_next; + reg axi_bvalid_reg, axi_bvalid_next; + reg axi_arready_reg, axi_arready_next; + reg [ID_WIDTH-1:0] axi_rid_reg, axi_rid_next; + reg [DATA_WIDTH-1:0] axi_rdata_reg, axi_rdata_next; + reg axi_rlast_reg, axi_rlast_next; + reg axi_rvalid_reg, axi_rvalid_next; + reg [ID_WIDTH-1:0] axi_rid_pipe_reg; + reg [DATA_WIDTH-1:0] axi_rdata_pipe_reg; + reg axi_rlast_pipe_reg; + reg axi_rvalid_pipe_reg; + + // (* RAM_STYLE="BLOCK" *) + reg [DATA_WIDTH-1:0] mem[2**VALID_ADDR_WIDTH]; + + wire [VALID_ADDR_WIDTH-1:0] axi_awaddr_valid = axi_awaddr_i >> (ADDR_WIDTH - VALID_ADDR_WIDTH); + wire [VALID_ADDR_WIDTH-1:0] axi_araddr_valid = axi_araddr_i >> (ADDR_WIDTH - VALID_ADDR_WIDTH); + wire [VALID_ADDR_WIDTH-1:0] read_addr_valid = read_addr_reg >> (ADDR_WIDTH - VALID_ADDR_WIDTH); + wire [VALID_ADDR_WIDTH-1:0] write_addr_valid = write_addr_reg >> (ADDR_WIDTH - VALID_ADDR_WIDTH); + + assign axi_awready_o = axi_awready_reg; + assign axi_wready_o = axi_wready_reg; + assign axi_bid_o = axi_bid_reg; + assign axi_bresp_o = 2'b00; + assign axi_bvalid_o = axi_bvalid_reg; + assign axi_arready_o = axi_arready_reg; + assign axi_rid_o = PIPELINE_OUTPUT ? axi_rid_pipe_reg : axi_rid_reg; + assign axi_rdata_o = PIPELINE_OUTPUT ? axi_rdata_pipe_reg : axi_rdata_reg; + assign axi_rresp_o = 2'b00; + assign axi_rlast_o = PIPELINE_OUTPUT ? axi_rlast_pipe_reg : axi_rlast_reg; + assign axi_rvalid_o = PIPELINE_OUTPUT ? axi_rvalid_pipe_reg : axi_rvalid_reg; + + integer i, j; + localparam mem_init_file_int = FILE; + reg [HEX_DATA_W-1:0] mem_tmp[FILE_SIZE]; + reg [DATA_WIDTH-1:0] tmp; + + initial begin + // two nested loops for smaller number of iterations per loop + // workaround for synthesizer complaints about large loop counts + for (i = 0; i < 2 ** VALID_ADDR_WIDTH; i = i + 2 ** (VALID_ADDR_WIDTH / 2)) begin + for (j = i; j < i + 2 ** (VALID_ADDR_WIDTH / 2); j = j + 1) begin + mem[j] = 0; + end + end + if (mem_init_file_int != "none") begin + $readmemh(mem_init_file_int, mem_tmp, 0, FILE_SIZE - 1); + j = 0; + for (i = 0; i < FILE_SIZE; i = i + 1) begin + if (i % (DATA_WIDTH / HEX_DATA_W) == 0) tmp = 0; + + tmp[i%(DATA_WIDTH/HEX_DATA_W)*HEX_DATA_W+:HEX_DATA_W] = mem_tmp[i]; + + if (i % (DATA_WIDTH / HEX_DATA_W) == DATA_WIDTH / HEX_DATA_W - 1) begin + mem[j] = tmp; + j = j + 1; + end + end + end + end + + always_comb begin + write_state_next = WRITE_STATE_IDLE; + + mem_wr_en = 1'b0; + + write_id_next = write_id_reg; + write_addr_next = write_addr_reg; + write_count_next = write_count_reg; + write_size_next = write_size_reg; + write_burst_next = write_burst_reg; + + axi_awready_next = 1'b0; + axi_wready_next = 1'b0; + axi_bid_next = axi_bid_reg; + axi_bvalid_next = axi_bvalid_reg && !axi_bready_i; + + case (write_state_reg) + WRITE_STATE_IDLE: begin + axi_awready_next = 1'b1; + + if (axi_awready_o && axi_awvalid_i) begin + write_id_next = axi_awid_i; + write_addr_next = axi_awaddr_i; + write_count_next = axi_awlen_i; + write_size_next = axi_awsize_i < $clog2(STRB_WIDTH) ? axi_awsize_i : + $clog2(STRB_WIDTH); + write_burst_next = axi_awburst_i; + + axi_awready_next = 1'b0; + axi_wready_next = 1'b1; + write_state_next = WRITE_STATE_BURST; + end else begin + write_state_next = WRITE_STATE_IDLE; + end + end + WRITE_STATE_BURST: begin + axi_wready_next = 1'b1; + + if (axi_wready_o && axi_wvalid_i) begin + mem_wr_en = 1'b1; + if (write_burst_reg != 2'b00) begin + write_addr_next = write_addr_reg + (1 << write_size_reg); + end + write_count_next = write_count_reg - 1; + if (write_count_reg > 0) begin + write_state_next = WRITE_STATE_BURST; + end else begin + axi_wready_next = 1'b0; + if (axi_bready_i || !axi_bvalid_o) begin + axi_bid_next = write_id_reg; + axi_bvalid_next = 1'b1; + axi_awready_next = 1'b1; + write_state_next = WRITE_STATE_IDLE; + end else begin + write_state_next = WRITE_STATE_RESP; + end + end + end else begin + write_state_next = WRITE_STATE_BURST; + end + end + WRITE_STATE_RESP: begin + if (axi_bready_i || !axi_bvalid_o) begin + axi_bid_next = write_id_reg; + axi_bvalid_next = 1'b1; + axi_awready_next = 1'b1; + write_state_next = WRITE_STATE_IDLE; + end else begin + write_state_next = WRITE_STATE_RESP; + end + end + default: ; + endcase + end + + always @(posedge clk_i) begin + if (rst_i) begin + write_state_reg <= WRITE_STATE_IDLE; + axi_awready_reg <= 1'b0; + axi_wready_reg <= 1'b0; + axi_bvalid_reg <= 1'b0; + + write_id_reg <= {ID_WIDTH{1'b0}}; + write_addr_reg <= {ADDR_WIDTH{1'b0}}; + write_count_reg <= {LEN_WIDTH{1'b0}}; + write_size_reg <= 3'd0; + write_burst_reg <= 2'd0; + + axi_bid_reg <= {ID_WIDTH{1'b0}}; + end else begin + write_state_reg <= write_state_next; + axi_awready_reg <= axi_awready_next; + axi_wready_reg <= axi_wready_next; + axi_bvalid_reg <= axi_bvalid_next; + + write_id_reg <= write_id_next; + write_addr_reg <= write_addr_next; + write_count_reg <= write_count_next; + write_size_reg <= write_size_next; + write_burst_reg <= write_burst_next; + + axi_bid_reg <= axi_bid_next; + end + + for (i = 0; i < WORD_WIDTH; i = i + 1) begin + if (mem_wr_en & axi_wstrb_i[i]) begin + mem[write_addr_valid][WORD_SIZE*i+:WORD_SIZE] <= axi_wdata_i[WORD_SIZE*i+:WORD_SIZE]; + end + end + end + + always_comb begin + read_state_next = READ_STATE_IDLE; + + mem_rd_en = 1'b0; + + axi_rid_next = axi_rid_reg; + axi_rlast_next = axi_rlast_reg; + axi_rvalid_next = axi_rvalid_reg && !(axi_rready_i || (PIPELINE_OUTPUT && !axi_rvalid_pipe_reg)); + + read_id_next = read_id_reg; + read_addr_next = read_addr_reg; + read_count_next = read_count_reg; + read_size_next = read_size_reg; + read_burst_next = read_burst_reg; + + axi_arready_next = 1'b0; + + case (read_state_reg) + READ_STATE_IDLE: begin + axi_arready_next = 1'b1; + + if (axi_arready_o && axi_arvalid_i) begin + read_id_next = axi_arid_i; + read_addr_next = axi_araddr_i; + read_count_next = axi_arlen_i; + read_size_next = axi_arsize_i < $clog2(STRB_WIDTH) ? axi_arsize_i : + $clog2(STRB_WIDTH); + read_burst_next = axi_arburst_i; + + axi_arready_next = 1'b0; + read_state_next = READ_STATE_BURST; + end else begin + read_state_next = READ_STATE_IDLE; + end + end + READ_STATE_BURST: begin + if (axi_rready_i || (PIPELINE_OUTPUT && !axi_rvalid_pipe_reg) || !axi_rvalid_reg) begin + mem_rd_en = 1'b1; + axi_rvalid_next = 1'b1; + axi_rid_next = read_id_reg; + axi_rlast_next = read_count_reg == 0; + if (read_burst_reg != 2'b00) begin + read_addr_next = read_addr_reg + (1 << read_size_reg); + end + read_count_next = read_count_reg - 1; + if (read_count_reg > 0) begin + read_state_next = READ_STATE_BURST; + end else begin + axi_arready_next = 1'b1; + read_state_next = READ_STATE_IDLE; + end + end else begin + read_state_next = READ_STATE_BURST; + end + end // case: READ_STATE_BURST + default: ; + endcase + end + + always @(posedge clk_i) begin + if (rst_i) begin + read_state_reg <= READ_STATE_IDLE; + axi_arready_reg <= 1'b0; + axi_rvalid_reg <= 1'b0; + axi_rvalid_pipe_reg <= 1'b0; + + read_id_reg <= {ID_WIDTH{1'b0}}; + read_addr_reg <= {ADDR_WIDTH{1'b0}}; + read_count_reg <= 0; + read_size_reg <= 3'd0; + read_burst_reg <= 2'd0; + + axi_rid_reg <= {ID_WIDTH{1'b0}}; + axi_rlast_reg <= 1'b0; + axi_rdata_reg <= {DATA_WIDTH{1'b0}}; + axi_rid_pipe_reg <= {ID_WIDTH{1'b0}}; + axi_rdata_pipe_reg <= {DATA_WIDTH{1'b0}}; + axi_rlast_pipe_reg <= 1'b0; + end else begin + read_state_reg <= read_state_next; + axi_arready_reg <= axi_arready_next; + axi_rvalid_reg <= axi_rvalid_next; + + if (!axi_rvalid_pipe_reg || axi_rready_i) begin + axi_rvalid_pipe_reg <= axi_rvalid_reg; + end + + read_id_reg <= read_id_next; + read_addr_reg <= read_addr_next; + read_count_reg <= read_count_next; + read_size_reg <= read_size_next; + read_burst_reg <= read_burst_next; + + axi_rid_reg <= axi_rid_next; + axi_rlast_reg <= axi_rlast_next; + + if (mem_rd_en) begin + axi_rdata_reg <= mem[read_addr_valid]; + end + + if (!axi_rvalid_pipe_reg || axi_rready_i) begin + axi_rid_pipe_reg <= axi_rid_reg; + axi_rdata_pipe_reg <= axi_rdata_reg; + axi_rlast_pipe_reg <= axi_rlast_reg; + end + end + end + +endmodule diff --git a/hardware/src/boot_ctr.v b/hardware/src/boot_ctr.v new file mode 100644 index 00000000..577aa3ca --- /dev/null +++ b/hardware/src/boot_ctr.v @@ -0,0 +1,76 @@ +`timescale 1 ns / 1 ps + +module boot_ctr #( + parameter ADDR_W = 0, + parameter DATA_W = 0, + parameter STRB_W = (DATA_W / 8) +) ( + output wire boot, + output wire cpu_reset, + + input [ 1-1:0] iob_avalid_i, + input [ADDR_W-1:0] iob_addr_i, + input [DATA_W-1:0] iob_wdata_i, + input [STRB_W-1:0] iob_wstrb_i, + output [ 1-1:0] iob_rvalid_o, + output [DATA_W-1:0] iob_rdata_o, + output [ 1-1:0] iob_ready_o, + + `include "clk_en_rst_s_port.vs" +); + + //boot register: (1) load bootloader to sram and run it: (0) run program + wire boot_wr; + reg boot_nxt; + //create CPU reset pulse + wire cpu_rst_req; + wire rst_sync; + + assign boot_wr = iob_avalid_i & (|iob_wstrb_i); + assign cpu_rst_req = (iob_avalid_i & (|iob_wstrb_i) & iob_wdata_i[1]) | rst_sync; + + iob_reg_re #( + .DATA_W (1), + .RST_VAL(1) + ) bootnxt ( + .clk_i (clk_i), + .arst_i(arst_i), + .cke_i (cke_i), + .rst_i (1'b0), + .en_i (boot_wr), + .data_i(iob_wdata_i[0]), + .data_o(boot_nxt) + ); + iob_reg_r #( + .DATA_W (1), + .RST_VAL(1) + ) bootreg ( + .clk_i (clk_i), + .arst_i(arst_i), + .cke_i (cke_i), + .rst_i (1'b0), + .data_i(boot_nxt), + .data_o(boot) + ); + iob_reg #( + .DATA_W (1), + .RST_VAL(1) + ) sync_reset ( + .clk_i (clk_i), + .arst_i(arst_i), + .cke_i (cke_i), + .data_i(1'b0), + .data_o(rst_sync) + ); + iob_pulse_gen #( + .START (0), + .DURATION(100) + ) reset_pulse ( + .clk_i (clk_i), + .arst_i (arst_i), + .cke_i (cke_i), + .start_i(cpu_rst_req), + .pulse_o(cpu_reset) + ); + +endmodule diff --git a/hardware/src/int_mem.v b/hardware/src/int_mem.v deleted file mode 100644 index 4d7f8a29..00000000 --- a/hardware/src/int_mem.v +++ /dev/null @@ -1,303 +0,0 @@ -`timescale 1 ns / 1 ps - -`include "iob_soc_opencryptolinux_conf.vh" -`include "iob_utils.vh" - -module int_mem #( - parameter ADDR_W = 0, - parameter DATA_W = 0, - parameter STRB_W = (DATA_W / 8), - parameter AXI_ID_W = 1, - parameter BOOT_HEXFILE = "none", - parameter BOOTROM_ADDR_W = 1, - parameter B_BIT = 2, - parameter SRAM_ADDR_W = (B_BIT - 1) -) ( - - output wire boot, - output wire cpu_reset, - /* - * AXI instruction bus interface - */ - input wire [AXI_ID_W-1:0] i_axi_awid, - input wire [ ADDR_W-1:0] i_axi_awaddr, - input wire [ 7:0] i_axi_awlen, - input wire [ 2:0] i_axi_awsize, - input wire [ 1:0] i_axi_awburst, - input wire i_axi_awlock, - input wire [ 3:0] i_axi_awcache, - input wire [ 2:0] i_axi_awprot, - input wire i_axi_awvalid, - output wire i_axi_awready, - input wire [ DATA_W-1:0] i_axi_wdata, - input wire [ STRB_W-1:0] i_axi_wstrb, - input wire i_axi_wlast, - input wire i_axi_wvalid, - output wire i_axi_wready, - output wire [AXI_ID_W-1:0] i_axi_bid, - output wire [ 1:0] i_axi_bresp, - output wire i_axi_bvalid, - input wire i_axi_bready, - input wire [AXI_ID_W-1:0] i_axi_arid, - input wire [ ADDR_W-1:0] i_axi_araddr, - input wire [ 7:0] i_axi_arlen, - input wire [ 2:0] i_axi_arsize, - input wire [ 1:0] i_axi_arburst, - input wire i_axi_arlock, - input wire [ 3:0] i_axi_arcache, - input wire [ 2:0] i_axi_arprot, - input wire i_axi_arvalid, - output wire i_axi_arready, - output wire [AXI_ID_W-1:0] i_axi_rid, - output wire [ DATA_W-1:0] i_axi_rdata, - output wire [ 1:0] i_axi_rresp, - output wire i_axi_rlast, - output wire i_axi_rvalid, - input wire i_axi_rready, - - /* - * AXI data bus interface - */ - input wire [AXI_ID_W-1:0] d_axi_awid, - input wire [ ADDR_W-1:0] d_axi_awaddr, - input wire [ 7:0] d_axi_awlen, - input wire [ 2:0] d_axi_awsize, - input wire [ 1:0] d_axi_awburst, - input wire d_axi_awlock, - input wire [ 3:0] d_axi_awcache, - input wire [ 2:0] d_axi_awprot, - input wire d_axi_awvalid, - output wire d_axi_awready, - input wire [ DATA_W-1:0] d_axi_wdata, - input wire [ STRB_W-1:0] d_axi_wstrb, - input wire d_axi_wlast, - input wire d_axi_wvalid, - output wire d_axi_wready, - output wire [AXI_ID_W-1:0] d_axi_bid, - output wire [ 1:0] d_axi_bresp, - output wire d_axi_bvalid, - input wire d_axi_bready, - input wire [AXI_ID_W-1:0] d_axi_arid, - input wire [ ADDR_W-1:0] d_axi_araddr, - input wire [ 7:0] d_axi_arlen, - input wire [ 2:0] d_axi_arsize, - input wire [ 1:0] d_axi_arburst, - input wire d_axi_arlock, - input wire [ 3:0] d_axi_arcache, - input wire [ 2:0] d_axi_arprot, - input wire d_axi_arvalid, - output wire d_axi_arready, - output wire [AXI_ID_W-1:0] d_axi_rid, - output wire [ DATA_W-1:0] d_axi_rdata, - output wire [ 1:0] d_axi_rresp, - output wire d_axi_rlast, - output wire d_axi_rvalid, - input wire d_axi_rready, - - `include "clk_en_rst_s_port.vs" -); - - localparam RAM_AXI_ID_W = 1; - localparam RAM_AXI_LEN_W = 8; - localparam RAM_AXI_ADDR_W = SRAM_ADDR_W; - localparam RAM_AXI_DATA_W = DATA_W; - - wire mm_reg_enable; - wire int_d_axi_awvalid; - wire int_d_axi_wvalid; - //boot register: (1) load bootloader to sram and run it: (0) run program - wire boot_wr; - reg boot_nxt; - //create CPU reset pulse - wire cpu_rst_req; - `include "ram_axi_wire.vs" - - assign mm_reg_enable = d_axi_awaddr[B_BIT]; - assign boot_wr = mm_reg_enable & d_axi_wvalid & (|d_axi_wstrb); - assign cpu_rst_req = mm_reg_enable & d_axi_wvalid & (|d_axi_wstrb) & d_axi_wdata[1]; - - assign int_d_axi_awvalid = (~mm_reg_enable) & d_axi_awvalid; - assign int_d_axi_wvalid = (~mm_reg_enable) & d_axi_wvalid; - - assign ram_axi_awlock[1] = 1'b0; - assign ram_axi_arlock[1] = 1'b0; - - iob_reg_re #( - .DATA_W (1), - .RST_VAL(1) - ) bootnxt ( - .clk_i (clk_i), - .arst_i(arst_i), - .cke_i (cke_i), - .rst_i (1'b0), - .en_i (boot_wr), - .data_i(d_axi_wdata[0]), - .data_o(boot_nxt) - ); - iob_reg_r #( - .DATA_W (1), - .RST_VAL(1) - ) bootreg ( - .clk_i (clk_i), - .arst_i(arst_i), - .cke_i (cke_i), - .rst_i (1'b0), - .data_i(boot_nxt), - .data_o(boot) - ); - iob_pulse_gen #( - .START (0), - .DURATION(100) - ) reset_pulse ( - .clk_i (clk_i), - .arst_i (arst_i), - .cke_i (cke_i), - .start_i(cpu_rst_req), - .pulse_o(cpu_reset) - ); - - axi_interconnect #( - .ID_WIDTH (AXI_ID_W), - .DATA_WIDTH(DATA_W), - .ADDR_WIDTH(SRAM_ADDR_W), - .M_ADDR_WIDTH(SRAM_ADDR_W), - .S_COUNT (2), - .M_COUNT (1) - ) sram_axi_interconnect ( - .clk(clk_i), - .rst(arst_i), - - .s_axi_awid({i_axi_awid, d_axi_awid}), - .s_axi_awaddr({i_axi_awaddr[SRAM_ADDR_W-1:0], d_axi_awaddr[SRAM_ADDR_W-1:0]}), - .s_axi_awlen({i_axi_awlen, d_axi_awlen}), - .s_axi_awsize({i_axi_awsize, d_axi_awsize}), - .s_axi_awburst({i_axi_awburst, d_axi_awburst}), - .s_axi_awlock({i_axi_awlock, d_axi_awlock}), - .s_axi_awcache({i_axi_awcache, d_axi_awcache}), - .s_axi_awprot({i_axi_awprot, d_axi_awprot}), - .s_axi_awqos({4'h0, 4'h0}), - .s_axi_awvalid({i_axi_awvalid, int_d_axi_awvalid}), - .s_axi_awready({i_axi_awready, d_axi_awready}), - .s_axi_wdata({i_axi_wdata, d_axi_wdata}), - .s_axi_wstrb({i_axi_wstrb, d_axi_wstrb}), - .s_axi_wlast({i_axi_wlast, d_axi_wlast}), - .s_axi_wvalid({i_axi_wvalid, int_d_axi_wvalid}), - .s_axi_wready({i_axi_wready, d_axi_wready}), - .s_axi_bid({i_axi_bid, d_axi_bid}), - .s_axi_bresp({i_axi_bresp, d_axi_bresp}), - .s_axi_bvalid({i_axi_bvalid, d_axi_bvalid}), - .s_axi_bready({i_axi_bready, d_axi_bready}), - .s_axi_arid({i_axi_arid, d_axi_arid}), - .s_axi_araddr({i_axi_araddr[SRAM_ADDR_W-1:0], d_axi_araddr[SRAM_ADDR_W-1:0]}), - .s_axi_arlen({i_axi_arlen, d_axi_arlen}), - .s_axi_arsize({i_axi_arsize, d_axi_arsize}), - .s_axi_arburst({i_axi_arburst, d_axi_arburst}), - .s_axi_arlock({i_axi_arlock, d_axi_arlock}), - .s_axi_arcache({i_axi_arcache, d_axi_arcache}), - .s_axi_arprot({i_axi_arprot, d_axi_arprot}), - .s_axi_arqos({4'h0, 4'h0}), - .s_axi_arvalid({i_axi_arvalid, d_axi_arvalid}), - .s_axi_arready({i_axi_arready, d_axi_arready}), - .s_axi_rid({i_axi_rid, d_axi_rid}), - .s_axi_rdata({i_axi_rdata, d_axi_rdata}), - .s_axi_rresp({i_axi_rresp, d_axi_rresp}), - .s_axi_rlast({i_axi_rlast, d_axi_rlast}), - .s_axi_rvalid({i_axi_rvalid, d_axi_rvalid}), - .s_axi_rready({i_axi_rready, d_axi_rready}), - - .m_axi_awid(ram_axi_awid), - .m_axi_awaddr(ram_axi_awaddr), - .m_axi_awlen(ram_axi_awlen), - .m_axi_awsize(ram_axi_awsize), - .m_axi_awburst(ram_axi_awburst), - .m_axi_awlock(ram_axi_awlock[1]), - .m_axi_awcache(ram_axi_awcache), - .m_axi_awprot(ram_axi_awprot), - .m_axi_awqos(ram_axi_awqos), - .m_axi_awvalid(ram_axi_awvalid), - .m_axi_awready(ram_axi_awready), - .m_axi_wdata(ram_axi_wdata), - .m_axi_wstrb(ram_axi_wstrb), - .m_axi_wlast(ram_axi_wlast), - .m_axi_wvalid(ram_axi_wvalid), - .m_axi_wready(ram_axi_wready), - .m_axi_bid(ram_axi_bid), - .m_axi_bresp(ram_axi_bresp), - .m_axi_bvalid(ram_axi_bvalid), - .m_axi_bready(ram_axi_bready), - .m_axi_arid(ram_axi_arid), - .m_axi_araddr(ram_axi_araddr), - .m_axi_arlen(ram_axi_arlen), - .m_axi_arsize(ram_axi_arsize), - .m_axi_arburst(ram_axi_arburst), - .m_axi_arlock(ram_axi_arlock[1]), - .m_axi_arcache(ram_axi_arcache), - .m_axi_arprot(ram_axi_arprot), - .m_axi_arqos(ram_axi_arqos), - .m_axi_arvalid(ram_axi_arvalid), - .m_axi_arready(ram_axi_arready), - .m_axi_rid(ram_axi_rid), - .m_axi_rdata(ram_axi_rdata), - .m_axi_rresp(ram_axi_rresp), - .m_axi_rlast(ram_axi_rlast), - .m_axi_rvalid(ram_axi_rvalid), - .m_axi_rready(ram_axi_rready), - - //optional signals - .s_axi_awuser(2'b00), - .s_axi_wuser (2'b00), - .s_axi_aruser(2'b00), - .m_axi_buser (1'b0), - .m_axi_ruser (1'b0) - ); - - axi_ram #( - .DATA_WIDTH(DATA_W), - .ADDR_WIDTH(SRAM_ADDR_W), - .ID_WIDTH(AXI_ID_W), - .FILE(BOOT_HEXFILE), - .FILE_SIZE(2**(BOOTROM_ADDR_W-2)) - ) boot_ram ( - .clk_i(clk_i), - .rst_i(arst_i), - - .axi_awid_i(ram_axi_awid), - .axi_awaddr_i(ram_axi_awaddr), - .axi_awlen_i(ram_axi_awlen), - .axi_awsize_i(ram_axi_awsize), - .axi_awburst_i(ram_axi_awburst), - .axi_awlock_i(ram_axi_awlock), - .axi_awcache_i(ram_axi_awcache), - .axi_awprot_i(ram_axi_awprot), - .axi_awqos_i(ram_axi_awqos), - .axi_awvalid_i(ram_axi_awvalid), - .axi_awready_o(ram_axi_awready), - .axi_wdata_i(ram_axi_wdata), - .axi_wstrb_i(ram_axi_wstrb), - .axi_wlast_i(ram_axi_wlast), - .axi_wvalid_i(ram_axi_wvalid), - .axi_wready_o(ram_axi_wready), - .axi_bid_o(ram_axi_bid), - .axi_bresp_o(ram_axi_bresp), - .axi_bvalid_o(ram_axi_bvalid), - .axi_bready_i(ram_axi_bready), - .axi_arid_i(ram_axi_arid), - .axi_araddr_i(ram_axi_araddr), - .axi_arlen_i(ram_axi_arlen), - .axi_arsize_i(ram_axi_arsize), - .axi_arburst_i(ram_axi_arburst), - .axi_arlock_i(ram_axi_arlock), - .axi_arcache_i(ram_axi_arcache), - .axi_arprot_i(ram_axi_arprot), - .axi_arqos_i(ram_axi_arqos), - .axi_arvalid_i(ram_axi_arvalid), - .axi_arready_o(ram_axi_arready), - .axi_rid_o(ram_axi_rid), - .axi_rdata_o(ram_axi_rdata), - .axi_rresp_o(ram_axi_rresp), - .axi_rlast_o(ram_axi_rlast), - .axi_rvalid_o(ram_axi_rvalid), - .axi_rready_i(ram_axi_rready) - ); - -endmodule diff --git a/hardware/src/iob_soc_opencryptolinux.v b/hardware/src/iob_soc_opencryptolinux.v index 409fbd19..58dcdb6f 100644 --- a/hardware/src/iob_soc_opencryptolinux.v +++ b/hardware/src/iob_soc_opencryptolinux.v @@ -28,37 +28,17 @@ module iob_soc_opencryptolinux #( localparam PERIPHERAL_AXI_LEN_W = 8; localparam PERIPHERAL_AXI_ADDR_W = 32; localparam PERIPHERAL_AXI_DATA_W = 32; - localparam IBUS_INTMEM_AXI_ID_W = 1; - localparam IBUS_INTMEM_AXI_LEN_W = 8; - localparam IBUS_INTMEM_AXI_ADDR_W = 32; - localparam IBUS_INTMEM_AXI_DATA_W = 32; - localparam IBUS_EXTMEM_AXI_ID_W = 1; - localparam IBUS_EXTMEM_AXI_LEN_W = 8; - localparam IBUS_EXTMEM_AXI_ADDR_W = 32; - localparam IBUS_EXTMEM_AXI_DATA_W = 32; - localparam DBUS_INTMEM_AXI_ID_W = 1; - localparam DBUS_INTMEM_AXI_LEN_W = 8; - localparam DBUS_INTMEM_AXI_ADDR_W = 32; - localparam DBUS_INTMEM_AXI_DATA_W = 32; - localparam DBUS_EXTMEM_AXI_ID_W = 1; - localparam DBUS_EXTMEM_AXI_LEN_W = 8; - localparam DBUS_EXTMEM_AXI_ADDR_W = 32; - localparam DBUS_EXTMEM_AXI_DATA_W = 32; + localparam INTMEM_AXI_ID_W = 1; + localparam INTMEM_AXI_LEN_W = 8; + localparam INTMEM_AXI_ADDR_W = 32; + localparam INTMEM_AXI_DATA_W = 32; - localparam N_SLAVES = 3; // PLIC, UART and CLINT + localparam N_SLAVES = 4; // BOOT_CTR, UART, CLINT and PLIC `include "iob_soc_opencryptolinux_pwires.vs" - wire iBus_intmem_iob_avalid; - wire [ADDR_W-1:0] iBus_intmem_iob_addr; - wire [DATA_W-1:0] iBus_intmem_iob_wdata; - wire [DATA_W/8-1:0] iBus_intmem_iob_wstrb; - wire iBus_intmem_iob_rvalid; - wire [DATA_W-1:0] iBus_intmem_iob_rdata; - wire iBus_intmem_iob_ready; - wire peripheral_iob_avalid; wire [ADDR_W-1:0] peripheral_iob_addr; wire [DATA_W-1:0] peripheral_iob_wdata; @@ -78,15 +58,28 @@ module iob_soc_opencryptolinux #( wire boot; wire cpu_reset; - // - // CPU - // // Axi instruction bus `include "iBus_axi_wire.vs" // Axi data bus `include "dBus_axi_wire.vs" + // Internal memmory AXI bus + `include "intmem_axi_wire.vs" + // Periphrals AXI bus + `include "peripheral_axi_wire.vs" - //instantiate the cpu + wire [ADDR_W-1:0] extmem_axi_awaddr; + wire [ADDR_W-1:0] extmem_axi_araddr; + + assign axi_awlock_o[1] = 1'b0; + assign axi_arlock_o[1] = 1'b0; + assign axi_awid_o[AXI_ID_W-1:1] = {AXI_ID_W{1'b0}}; + assign axi_arid_o[AXI_ID_W-1:1] = {AXI_ID_W{1'b0}}; + assign axi_awaddr_o[AXI_ADDR_W-1:0] = extmem_axi_awaddr[MEM_ADDR_W-1:0] + MEM_ADDR_OFFSET; + assign axi_araddr_o[AXI_ADDR_W-1:0] = extmem_axi_araddr[MEM_ADDR_W-1:0] + MEM_ADDR_OFFSET; + + // + // CPU + // iob_VexRiscv #( .ADDR_W (ADDR_W), .DATA_W (DATA_W), @@ -96,10 +89,10 @@ module iob_soc_opencryptolinux #( .cke_i (cke_i), .arst_i (arst_i), .cpu_reset_i (cpu_reset), - .clint_req (slaves_req[(N_SLAVES-1)*69+:`REQ_W]), - .clint_resp (slaves_resp[(N_SLAVES-1)*34+:`RESP_W]), - .plic_req (slaves_req[0+:`REQ_W]), - .plic_resp (slaves_resp[0+:`RESP_W]), + .clint_req (slaves_req[(N_SLAVES-2)*69+:`REQ_W]), + .clint_resp (slaves_resp[(N_SLAVES-2)*34+:`RESP_W]), + .plic_req (slaves_req[(N_SLAVES-1)*69+:`REQ_W]), + .plic_resp (slaves_resp[(N_SLAVES-1)*34+:`RESP_W]), .plicInterrupts(32'd0), // Axi instruction bus `include "iBus_axi_m_portmap.vs" @@ -108,226 +101,163 @@ module iob_soc_opencryptolinux #( .boot_i (boot) ); - // - // SPLIT CPU BUSES TO ACCESS INTERNAL OR EXTERNAL MEMORY + // AXI interconnect {I, D} -> {peripheral, internal, external} // - - // Intructions intmem AXI bus - `include "iBus_intmem_axi_wire.vs" - // Intructions intmem AXI bus - `include "iBus_extmem_axi_wire.vs" - // Data internal AXI bus - `include "peripheral_axi_wire.vs" - // Intructions intmem AXI bus - `include "dBus_intmem_axi_wire.vs" - // Data extmem AXI bus - `include "dBus_extmem_axi_wire.vs" - - // Instructions bus interconnect {I, D} -> {internal, external} axi_interconnect #( .ID_WIDTH (1), .DATA_WIDTH(DATA_W), .ADDR_WIDTH(ADDR_W), - .M_ADDR_WIDTH({{32'd31}, {32'd31}}), - .S_COUNT (1), - .M_COUNT (2) - ) iBus_axi_interconnect ( + .M_ADDR_WIDTH({{32'd30}, {32'd30}, {32'd31}}), + .S_COUNT (2), + .M_COUNT (3) + ) dBus_axi_interconnect ( .clk(clk_i), .rst(arst_i), - .s_axi_awid(iBus_axi_awid), - .s_axi_awaddr(iBus_axi_awaddr), - .s_axi_awlen(iBus_axi_awlen), - .s_axi_awsize(iBus_axi_awsize), - .s_axi_awburst(iBus_axi_awburst), - .s_axi_awlock(iBus_axi_awlock[0]), - .s_axi_awcache(iBus_axi_awcache), - .s_axi_awprot(iBus_axi_awprot), - .s_axi_awqos(iBus_axi_awqos), - .s_axi_awvalid(iBus_axi_awvalid), - .s_axi_awready(iBus_axi_awready), - .s_axi_wdata(iBus_axi_wdata), - .s_axi_wstrb(iBus_axi_wstrb), - .s_axi_wlast(iBus_axi_wlast), - .s_axi_wvalid(iBus_axi_wvalid), - .s_axi_wready(iBus_axi_wready), - .s_axi_bid(iBus_axi_bid), - .s_axi_bresp(iBus_axi_bresp), - .s_axi_bvalid(iBus_axi_bvalid), - .s_axi_bready(iBus_axi_bready), - .s_axi_arid(iBus_axi_arid), - .s_axi_araddr(iBus_axi_araddr), - .s_axi_arlen(iBus_axi_arlen), - .s_axi_arsize(iBus_axi_arsize), - .s_axi_arburst(iBus_axi_arburst), - .s_axi_arlock(iBus_axi_arlock[0]), - .s_axi_arcache(iBus_axi_arcache), - .s_axi_arprot(iBus_axi_arprot), - .s_axi_arqos(iBus_axi_arqos), - .s_axi_arvalid(iBus_axi_arvalid), - .s_axi_arready(iBus_axi_arready), - .s_axi_rid(iBus_axi_rid), - .s_axi_rdata(iBus_axi_rdata), - .s_axi_rresp(iBus_axi_rresp), - .s_axi_rlast(iBus_axi_rlast), - .s_axi_rvalid(iBus_axi_rvalid), - .s_axi_rready(iBus_axi_rready), - - .m_axi_awid({iBus_intmem_axi_awid, iBus_extmem_axi_awid}), - .m_axi_awaddr({iBus_intmem_axi_awaddr, iBus_extmem_axi_awaddr}), - .m_axi_awlen({iBus_intmem_axi_awlen, iBus_extmem_axi_awlen}), - .m_axi_awsize({iBus_intmem_axi_awsize, iBus_extmem_axi_awsize}), - .m_axi_awburst({iBus_intmem_axi_awburst, iBus_extmem_axi_awburst}), - .m_axi_awlock({iBus_intmem_axi_awlock[0], iBus_extmem_axi_awlock[0]}), - .m_axi_awcache({iBus_intmem_axi_awcache, iBus_extmem_axi_awcache}), - .m_axi_awprot({iBus_intmem_axi_awprot, iBus_extmem_axi_awprot}), - .m_axi_awqos({iBus_intmem_axi_awqos, iBus_extmem_axi_awqos}), - .m_axi_awvalid({iBus_intmem_axi_awvalid, iBus_extmem_axi_awvalid}), - .m_axi_awready({iBus_intmem_axi_awready, iBus_extmem_axi_awready}), - .m_axi_wdata({iBus_intmem_axi_wdata, iBus_extmem_axi_wdata}), - .m_axi_wstrb({iBus_intmem_axi_wstrb, iBus_extmem_axi_wstrb}), - .m_axi_wlast({iBus_intmem_axi_wlast, iBus_extmem_axi_wlast}), - .m_axi_wvalid({iBus_intmem_axi_wvalid, iBus_extmem_axi_wvalid}), - .m_axi_wready({iBus_intmem_axi_wready, iBus_extmem_axi_wready}), - .m_axi_bid({iBus_intmem_axi_bid, iBus_extmem_axi_bid}), - .m_axi_bresp({iBus_intmem_axi_bresp, iBus_extmem_axi_bresp}), - .m_axi_bvalid({iBus_intmem_axi_bvalid, iBus_extmem_axi_bvalid}), - .m_axi_bready({iBus_intmem_axi_bready, iBus_extmem_axi_bready}), - .m_axi_arid({iBus_intmem_axi_arid, iBus_extmem_axi_arid}), - .m_axi_araddr({iBus_intmem_axi_araddr, iBus_extmem_axi_araddr}), - .m_axi_arlen({iBus_intmem_axi_arlen, iBus_extmem_axi_arlen}), - .m_axi_arsize({iBus_intmem_axi_arsize, iBus_extmem_axi_arsize}), - .m_axi_arburst({iBus_intmem_axi_arburst, iBus_extmem_axi_arburst}), - .m_axi_arlock({iBus_intmem_axi_arlock[0], iBus_extmem_axi_arlock[0]}), - .m_axi_arcache({iBus_intmem_axi_arcache, iBus_extmem_axi_arcache}), - .m_axi_arprot({iBus_intmem_axi_arprot, iBus_extmem_axi_arprot}), - .m_axi_arqos({iBus_intmem_axi_arqos, iBus_extmem_axi_arqos}), - .m_axi_arvalid({iBus_intmem_axi_arvalid, iBus_extmem_axi_arvalid}), - .m_axi_arready({iBus_intmem_axi_arready, iBus_extmem_axi_arready}), - .m_axi_rid({iBus_intmem_axi_rid, iBus_extmem_axi_rid}), - .m_axi_rdata({iBus_intmem_axi_rdata, iBus_extmem_axi_rdata}), - .m_axi_rresp({iBus_intmem_axi_rresp, iBus_extmem_axi_rresp}), - .m_axi_rlast({iBus_intmem_axi_rlast, iBus_extmem_axi_rlast}), - .m_axi_rvalid({iBus_intmem_axi_rvalid, iBus_extmem_axi_rvalid}), - .m_axi_rready({iBus_intmem_axi_rready, iBus_extmem_axi_rready}), + .s_axi_awid({iBus_axi_awid, dBus_axi_awid}), + .s_axi_awaddr({iBus_axi_awaddr, dBus_axi_awaddr}), + .s_axi_awlen({iBus_axi_awlen, dBus_axi_awlen}), + .s_axi_awsize({iBus_axi_awsize, dBus_axi_awsize}), + .s_axi_awburst({iBus_axi_awburst, dBus_axi_awburst}), + .s_axi_awlock({iBus_axi_awlock[0], dBus_axi_awlock[0]}), + .s_axi_awcache({iBus_axi_awcache, dBus_axi_awcache}), + .s_axi_awprot({iBus_axi_awprot, dBus_axi_awprot}), + .s_axi_awqos({iBus_axi_awqos, dBus_axi_awqos}), + .s_axi_awvalid({iBus_axi_awvalid, dBus_axi_awvalid}), + .s_axi_awready({iBus_axi_awready, dBus_axi_awready}), + .s_axi_wdata({iBus_axi_wdata, dBus_axi_wdata}), + .s_axi_wstrb({iBus_axi_wstrb, dBus_axi_wstrb}), + .s_axi_wlast({iBus_axi_wlast, dBus_axi_wlast}), + .s_axi_wvalid({iBus_axi_wvalid, dBus_axi_wvalid}), + .s_axi_wready({iBus_axi_wready, dBus_axi_wready}), + .s_axi_bid({iBus_axi_bid, dBus_axi_bid}), + .s_axi_bresp({iBus_axi_bresp, dBus_axi_bresp}), + .s_axi_bvalid({iBus_axi_bvalid, dBus_axi_bvalid}), + .s_axi_bready({iBus_axi_bready, dBus_axi_bready}), + .s_axi_arid({iBus_axi_arid, dBus_axi_arid}), + .s_axi_araddr({iBus_axi_araddr, dBus_axi_araddr}), + .s_axi_arlen({iBus_axi_arlen, dBus_axi_arlen}), + .s_axi_arsize({iBus_axi_arsize, dBus_axi_arsize}), + .s_axi_arburst({iBus_axi_arburst, dBus_axi_arburst}), + .s_axi_arlock({iBus_axi_arlock[0], dBus_axi_arlock[0]}), + .s_axi_arcache({iBus_axi_arcache, dBus_axi_arcache}), + .s_axi_arprot({iBus_axi_arprot, dBus_axi_arprot}), + .s_axi_arqos({iBus_axi_arqos, dBus_axi_arqos}), + .s_axi_arvalid({iBus_axi_arvalid, dBus_axi_arvalid}), + .s_axi_arready({iBus_axi_arready, dBus_axi_arready}), + .s_axi_rid({iBus_axi_rid, dBus_axi_rid}), + .s_axi_rdata({iBus_axi_rdata, dBus_axi_rdata}), + .s_axi_rresp({iBus_axi_rresp, dBus_axi_rresp}), + .s_axi_rlast({iBus_axi_rlast, dBus_axi_rlast}), + .s_axi_rvalid({iBus_axi_rvalid, dBus_axi_rvalid}), + .s_axi_rready({iBus_axi_rready, dBus_axi_rready}), + + .m_axi_awid({peripheral_axi_awid, intmem_axi_awid, axi_awid_o[0]}), + .m_axi_awaddr({peripheral_axi_awaddr, intmem_axi_awaddr, extmem_axi_awaddr}), + .m_axi_awlen({peripheral_axi_awlen, intmem_axi_awlen, axi_awlen_o}), + .m_axi_awsize({peripheral_axi_awsize, intmem_axi_awsize, axi_awsize_o}), + .m_axi_awburst({peripheral_axi_awburst, intmem_axi_awburst, axi_awburst_o}), + .m_axi_awlock({peripheral_axi_awlock[0], intmem_axi_awlock[0], axi_awlock_o[0]}), + .m_axi_awcache({peripheral_axi_awcache, intmem_axi_awcache, axi_awcache_o}), + .m_axi_awprot({peripheral_axi_awprot, intmem_axi_awprot, axi_awprot_o}), + .m_axi_awqos({peripheral_axi_awqos, intmem_axi_awqos, axi_awqos_o}), + .m_axi_awvalid({peripheral_axi_awvalid, intmem_axi_awvalid, axi_awvalid_o}), + .m_axi_awready({peripheral_axi_awready, intmem_axi_awready, axi_awready_i}), + .m_axi_wdata({peripheral_axi_wdata, intmem_axi_wdata, axi_wdata_o}), + .m_axi_wstrb({peripheral_axi_wstrb, intmem_axi_wstrb, axi_wstrb_o}), + .m_axi_wlast({peripheral_axi_wlast, intmem_axi_wlast, axi_wlast_o}), + .m_axi_wvalid({peripheral_axi_wvalid, intmem_axi_wvalid, axi_wvalid_o}), + .m_axi_wready({peripheral_axi_wready, intmem_axi_wready, axi_wready_i}), + .m_axi_bid({peripheral_axi_bid, intmem_axi_bid, axi_bid_i[0]}), + .m_axi_bresp({peripheral_axi_bresp, intmem_axi_bresp, axi_bresp_i}), + .m_axi_bvalid({peripheral_axi_bvalid, intmem_axi_bvalid, axi_bvalid_i}), + .m_axi_bready({peripheral_axi_bready, intmem_axi_bready, axi_bready_o}), + .m_axi_arid({peripheral_axi_arid, intmem_axi_arid, axi_arid_o[0]}), + .m_axi_araddr({peripheral_axi_araddr, intmem_axi_araddr, extmem_axi_araddr}), + .m_axi_arlen({peripheral_axi_arlen, intmem_axi_arlen, axi_arlen_o}), + .m_axi_arsize({peripheral_axi_arsize, intmem_axi_arsize, axi_arsize_o}), + .m_axi_arburst({peripheral_axi_arburst, intmem_axi_arburst, axi_arburst_o}), + .m_axi_arlock({peripheral_axi_arlock[0], intmem_axi_arlock[0], axi_arlock_o[0]}), + .m_axi_arcache({peripheral_axi_arcache, intmem_axi_arcache, axi_arcache_o}), + .m_axi_arprot({peripheral_axi_arprot, intmem_axi_arprot, axi_arprot_o}), + .m_axi_arqos({peripheral_axi_arqos, intmem_axi_arqos, axi_arqos_o}), + .m_axi_arvalid({peripheral_axi_arvalid, intmem_axi_arvalid, axi_arvalid_o}), + .m_axi_arready({peripheral_axi_arready, intmem_axi_arready, axi_arready_i}), + .m_axi_rid({peripheral_axi_rid, intmem_axi_rid, axi_rid_i[0]}), + .m_axi_rdata({peripheral_axi_rdata, intmem_axi_rdata, axi_rdata_i}), + .m_axi_rresp({peripheral_axi_rresp, intmem_axi_rresp, axi_rresp_i}), + .m_axi_rlast({peripheral_axi_rlast, intmem_axi_rlast, axi_rlast_i}), + .m_axi_rvalid({peripheral_axi_rvalid, intmem_axi_rvalid, axi_rvalid_i}), + .m_axi_rready({peripheral_axi_rready, intmem_axi_rready, axi_rready_o}), //optional signals - .s_axi_awuser(1'b0), - .s_axi_wuser (1'b0), - .s_axi_aruser(1'b0), - .m_axi_buser (2'b00), - .m_axi_ruser (2'b00) + .s_axi_awuser(2'b00), + .s_axi_wuser (2'b00), + .s_axi_aruser(2'b00), + .m_axi_buser (3'b000), + .m_axi_ruser (3'b000) ); + // - // SPLIT INTERNAL MEMORY AND PERIPHERALS BUS + // INTERNAL SRAM MEMORY // - - // Data bus interconnect {I, D} -> {internal, external} - axi_interconnect #( - .ID_WIDTH (1), + axi_ram #( .DATA_WIDTH(DATA_W), - .ADDR_WIDTH(ADDR_W), - .M_ADDR_WIDTH({{32'd31}, {32'd30}, {32'd30}}), - .S_COUNT (1), - .M_COUNT (3) - ) dBus_axi_interconnect ( - .clk(clk_i), - .rst(arst_i), - - .s_axi_awid(dBus_axi_awid), - .s_axi_awaddr(dBus_axi_awaddr), - .s_axi_awlen(dBus_axi_awlen), - .s_axi_awsize(dBus_axi_awsize), - .s_axi_awburst(dBus_axi_awburst), - .s_axi_awlock(dBus_axi_awlock[0]), - .s_axi_awcache(dBus_axi_awcache), - .s_axi_awprot(dBus_axi_awprot), - .s_axi_awqos(dBus_axi_awqos), - .s_axi_awvalid(dBus_axi_awvalid), - .s_axi_awready(dBus_axi_awready), - .s_axi_wdata(dBus_axi_wdata), - .s_axi_wstrb(dBus_axi_wstrb), - .s_axi_wlast(dBus_axi_wlast), - .s_axi_wvalid(dBus_axi_wvalid), - .s_axi_wready(dBus_axi_wready), - .s_axi_bid(dBus_axi_bid), - .s_axi_bresp(dBus_axi_bresp), - .s_axi_bvalid(dBus_axi_bvalid), - .s_axi_bready(dBus_axi_bready), - .s_axi_arid(dBus_axi_arid), - .s_axi_araddr(dBus_axi_araddr), - .s_axi_arlen(dBus_axi_arlen), - .s_axi_arsize(dBus_axi_arsize), - .s_axi_arburst(dBus_axi_arburst), - .s_axi_arlock(dBus_axi_arlock[0]), - .s_axi_arcache(dBus_axi_arcache), - .s_axi_arprot(dBus_axi_arprot), - .s_axi_arqos(dBus_axi_arqos), - .s_axi_arvalid(dBus_axi_arvalid), - .s_axi_arready(dBus_axi_arready), - .s_axi_rid(dBus_axi_rid), - .s_axi_rdata(dBus_axi_rdata), - .s_axi_rresp(dBus_axi_rresp), - .s_axi_rlast(dBus_axi_rlast), - .s_axi_rvalid(dBus_axi_rvalid), - .s_axi_rready(dBus_axi_rready), - - .m_axi_awid({dBus_intmem_axi_awid, peripheral_axi_awid, dBus_extmem_axi_awid}), - .m_axi_awaddr({dBus_intmem_axi_awaddr, peripheral_axi_awaddr, dBus_extmem_axi_awaddr}), - .m_axi_awlen({dBus_intmem_axi_awlen, peripheral_axi_awlen, dBus_extmem_axi_awlen}), - .m_axi_awsize({dBus_intmem_axi_awsize, peripheral_axi_awsize, dBus_extmem_axi_awsize}), - .m_axi_awburst({dBus_intmem_axi_awburst, peripheral_axi_awburst, dBus_extmem_axi_awburst}), - .m_axi_awlock({ - dBus_intmem_axi_awlock[0], peripheral_axi_awlock[0], dBus_extmem_axi_awlock[0] - }), - .m_axi_awcache({dBus_intmem_axi_awcache, peripheral_axi_awcache, dBus_extmem_axi_awcache}), - .m_axi_awprot({dBus_intmem_axi_awprot, peripheral_axi_awprot, dBus_extmem_axi_awprot}), - .m_axi_awqos({dBus_intmem_axi_awqos, peripheral_axi_awqos, dBus_extmem_axi_awqos}), - .m_axi_awvalid({dBus_intmem_axi_awvalid, peripheral_axi_awvalid, dBus_extmem_axi_awvalid}), - .m_axi_awready({dBus_intmem_axi_awready, peripheral_axi_awready, dBus_extmem_axi_awready}), - .m_axi_wdata({dBus_intmem_axi_wdata, peripheral_axi_wdata, dBus_extmem_axi_wdata}), - .m_axi_wstrb({dBus_intmem_axi_wstrb, peripheral_axi_wstrb, dBus_extmem_axi_wstrb}), - .m_axi_wlast({dBus_intmem_axi_wlast, peripheral_axi_wlast, dBus_extmem_axi_wlast}), - .m_axi_wvalid({dBus_intmem_axi_wvalid, peripheral_axi_wvalid, dBus_extmem_axi_wvalid}), - .m_axi_wready({dBus_intmem_axi_wready, peripheral_axi_wready, dBus_extmem_axi_wready}), - .m_axi_bid({dBus_intmem_axi_bid, peripheral_axi_bid, dBus_extmem_axi_bid}), - .m_axi_bresp({dBus_intmem_axi_bresp, peripheral_axi_bresp, dBus_extmem_axi_bresp}), - .m_axi_bvalid({dBus_intmem_axi_bvalid, peripheral_axi_bvalid, dBus_extmem_axi_bvalid}), - .m_axi_bready({dBus_intmem_axi_bready, peripheral_axi_bready, dBus_extmem_axi_bready}), - .m_axi_arid({dBus_intmem_axi_arid, peripheral_axi_arid, dBus_extmem_axi_arid}), - .m_axi_araddr({dBus_intmem_axi_araddr, peripheral_axi_araddr, dBus_extmem_axi_araddr}), - .m_axi_arlen({dBus_intmem_axi_arlen, peripheral_axi_arlen, dBus_extmem_axi_arlen}), - .m_axi_arsize({dBus_intmem_axi_arsize, peripheral_axi_arsize, dBus_extmem_axi_arsize}), - .m_axi_arburst({dBus_intmem_axi_arburst, peripheral_axi_arburst, dBus_extmem_axi_arburst}), - .m_axi_arlock({ - dBus_intmem_axi_arlock[0], peripheral_axi_arlock[0], dBus_extmem_axi_arlock[0] - }), - .m_axi_arcache({dBus_intmem_axi_arcache, peripheral_axi_arcache, dBus_extmem_axi_arcache}), - .m_axi_arprot({dBus_intmem_axi_arprot, peripheral_axi_arprot, dBus_extmem_axi_arprot}), - .m_axi_arqos({dBus_intmem_axi_arqos, peripheral_axi_arqos, dBus_extmem_axi_arqos}), - .m_axi_arvalid({dBus_intmem_axi_arvalid, peripheral_axi_arvalid, dBus_extmem_axi_arvalid}), - .m_axi_arready({dBus_intmem_axi_arready, peripheral_axi_arready, dBus_extmem_axi_arready}), - .m_axi_rid({dBus_intmem_axi_rid, peripheral_axi_rid, dBus_extmem_axi_rid}), - .m_axi_rdata({dBus_intmem_axi_rdata, peripheral_axi_rdata, dBus_extmem_axi_rdata}), - .m_axi_rresp({dBus_intmem_axi_rresp, peripheral_axi_rresp, dBus_extmem_axi_rresp}), - .m_axi_rlast({dBus_intmem_axi_rlast, peripheral_axi_rlast, dBus_extmem_axi_rlast}), - .m_axi_rvalid({dBus_intmem_axi_rvalid, peripheral_axi_rvalid, dBus_extmem_axi_rvalid}), - .m_axi_rready({dBus_intmem_axi_rready, peripheral_axi_rready, dBus_extmem_axi_rready}), - - //optional signals - .s_axi_awuser(1'b0), - .s_axi_wuser (1'b0), - .s_axi_aruser(1'b0), - .m_axi_buser (3'b000), - .m_axi_ruser (3'b000) + .ADDR_WIDTH(SRAM_ADDR_W), + .ID_WIDTH(INTMEM_AXI_ID_W), + .FILE("iob_soc_opencryptolinux_boot.hex"), + .FILE_SIZE(2 ** (BOOTROM_ADDR_W - 2)) + ) boot_ram ( + .clk_i(clk_i), + .rst_i(arst_i), + + .axi_awid_i(intmem_axi_awid), + .axi_awaddr_i(intmem_axi_awaddr[SRAM_ADDR_W-1:0]), + .axi_awlen_i(intmem_axi_awlen), + .axi_awsize_i(intmem_axi_awsize), + .axi_awburst_i(intmem_axi_awburst), + .axi_awlock_i(intmem_axi_awlock), + .axi_awcache_i(intmem_axi_awcache), + .axi_awprot_i(intmem_axi_awprot), + .axi_awqos_i(intmem_axi_awqos), + .axi_awvalid_i(intmem_axi_awvalid), + .axi_awready_o(intmem_axi_awready), + .axi_wdata_i(intmem_axi_wdata), + .axi_wstrb_i(intmem_axi_wstrb), + .axi_wlast_i(intmem_axi_wlast), + .axi_wvalid_i(intmem_axi_wvalid), + .axi_wready_o(intmem_axi_wready), + .axi_bid_o(intmem_axi_bid), + .axi_bresp_o(intmem_axi_bresp), + .axi_bvalid_o(intmem_axi_bvalid), + .axi_bready_i(intmem_axi_bready), + .axi_arid_i(intmem_axi_arid), + .axi_araddr_i(intmem_axi_araddr[SRAM_ADDR_W-1:0]), + .axi_arlen_i(intmem_axi_arlen), + .axi_arsize_i(intmem_axi_arsize), + .axi_arburst_i(intmem_axi_arburst), + .axi_arlock_i(intmem_axi_arlock), + .axi_arcache_i(intmem_axi_arcache), + .axi_arprot_i(intmem_axi_arprot), + .axi_arqos_i(intmem_axi_arqos), + .axi_arvalid_i(intmem_axi_arvalid), + .axi_arready_o(intmem_axi_arready), + .axi_rid_o(intmem_axi_rid), + .axi_rdata_o(intmem_axi_rdata), + .axi_rresp_o(intmem_axi_rresp), + .axi_rlast_o(intmem_axi_rlast), + .axi_rvalid_o(intmem_axi_rvalid), + .axi_rready_i(intmem_axi_rready) ); - // instantiate axi2iob CPU data + // + // Peripheral interface AXIL to IOb-bus + // axil2iob #( - .AXIL_ADDR_W (ADDR_W), - .AXIL_DATA_W (DATA_W) + .AXIL_ADDR_W(ADDR_W), + .AXIL_DATA_W(DATA_W) ) peripheral_axil2iob ( .clk_i(clk_i), .cke_i(cke_i), @@ -366,7 +296,7 @@ module iob_soc_opencryptolinux #( .ADDR_W (ADDR_W), .DATA_W (DATA_W), .N_SLAVES(N_SLAVES), - .P_SLAVES(AddrMsb - 1) + .P_SLAVES(AddrMsb - 4) ) pbus_split ( .clk_i(clk_i), .arst_i(arst_i), @@ -381,211 +311,25 @@ module iob_soc_opencryptolinux #( ); - // - // INTERNAL SRAM MEMORY - // - int_mem #( - .ADDR_W (ADDR_W), - .DATA_W (DATA_W), - .BOOT_HEXFILE ("iob_soc_opencryptolinux_boot.hex"), - .SRAM_ADDR_W (SRAM_ADDR_W), - .BOOTROM_ADDR_W(BOOTROM_ADDR_W), - .B_BIT (Bbit) - ) int_mem0 ( - .clk_i (clk_i), - .arst_i (arst_i), - .cke_i (cke_i), - .boot (boot), - .cpu_reset(cpu_reset), - - // instruction bus - .i_axi_awid(iBus_intmem_axi_awid), - .i_axi_awaddr(iBus_intmem_axi_awaddr), - .i_axi_awlen(iBus_intmem_axi_awlen), - .i_axi_awsize(iBus_intmem_axi_awsize), - .i_axi_awburst(iBus_intmem_axi_awburst), - .i_axi_awlock(iBus_intmem_axi_awlock[0]), - .i_axi_awcache(iBus_intmem_axi_awcache), - .i_axi_awprot(iBus_intmem_axi_awprot), - .i_axi_awvalid(iBus_intmem_axi_awvalid), - .i_axi_awready(iBus_intmem_axi_awready), - .i_axi_wdata(iBus_intmem_axi_wdata), - .i_axi_wstrb(iBus_intmem_axi_wstrb), - .i_axi_wlast(iBus_intmem_axi_wlast), - .i_axi_wvalid(iBus_intmem_axi_wvalid), - .i_axi_wready(iBus_intmem_axi_wready), - .i_axi_bid(iBus_intmem_axi_bid), - .i_axi_bresp(iBus_intmem_axi_bresp), - .i_axi_bvalid(iBus_intmem_axi_bvalid), - .i_axi_bready(iBus_intmem_axi_bready), - .i_axi_arid(iBus_intmem_axi_arid), - .i_axi_araddr(iBus_intmem_axi_araddr), - .i_axi_arlen(iBus_intmem_axi_arlen), - .i_axi_arsize(iBus_intmem_axi_arsize), - .i_axi_arburst(iBus_intmem_axi_arburst), - .i_axi_arlock(iBus_intmem_axi_arlock[0]), - .i_axi_arcache(iBus_intmem_axi_arcache), - .i_axi_arprot(iBus_intmem_axi_arprot), - .i_axi_arvalid(iBus_intmem_axi_arvalid), - .i_axi_arready(iBus_intmem_axi_arready), - .i_axi_rid(iBus_intmem_axi_rid), - .i_axi_rdata(iBus_intmem_axi_rdata), - .i_axi_rresp(iBus_intmem_axi_rresp), - .i_axi_rlast(iBus_intmem_axi_rlast), - .i_axi_rvalid(iBus_intmem_axi_rvalid), - .i_axi_rready(iBus_intmem_axi_rready), - - //data bus - .d_axi_awid(dBus_intmem_axi_awid), - .d_axi_awaddr(dBus_intmem_axi_awaddr), - .d_axi_awlen(dBus_intmem_axi_awlen), - .d_axi_awsize(dBus_intmem_axi_awsize), - .d_axi_awburst(dBus_intmem_axi_awburst), - .d_axi_awlock(dBus_intmem_axi_awlock[0]), - .d_axi_awcache(dBus_intmem_axi_awcache), - .d_axi_awprot(dBus_intmem_axi_awprot), - .d_axi_awvalid(dBus_intmem_axi_awvalid), - .d_axi_awready(dBus_intmem_axi_awready), - .d_axi_wdata(dBus_intmem_axi_wdata), - .d_axi_wstrb(dBus_intmem_axi_wstrb), - .d_axi_wlast(dBus_intmem_axi_wlast), - .d_axi_wvalid(dBus_intmem_axi_wvalid), - .d_axi_wready(dBus_intmem_axi_wready), - .d_axi_bid(dBus_intmem_axi_bid), - .d_axi_bresp(dBus_intmem_axi_bresp), - .d_axi_bvalid(dBus_intmem_axi_bvalid), - .d_axi_bready(dBus_intmem_axi_bready), - .d_axi_arid(dBus_intmem_axi_arid), - .d_axi_araddr(dBus_intmem_axi_araddr), - .d_axi_arlen(dBus_intmem_axi_arlen), - .d_axi_arsize(dBus_intmem_axi_arsize), - .d_axi_arburst(dBus_intmem_axi_arburst), - .d_axi_arlock(dBus_intmem_axi_arlock[0]), - .d_axi_arcache(dBus_intmem_axi_arcache), - .d_axi_arprot(dBus_intmem_axi_arprot), - .d_axi_arvalid(dBus_intmem_axi_arvalid), - .d_axi_arready(dBus_intmem_axi_arready), - .d_axi_rid(dBus_intmem_axi_rid), - .d_axi_rdata(dBus_intmem_axi_rdata), - .d_axi_rresp(dBus_intmem_axi_rresp), - .d_axi_rlast(dBus_intmem_axi_rlast), - .d_axi_rvalid(dBus_intmem_axi_rvalid), - .d_axi_rready(dBus_intmem_axi_rready) - ); - - wire extmem_axi_arlock; - wire extmem_axi_awlock; - wire [7:0] extmem_axi_bid; - wire [7:0] extmem_axi_rid; - wire [MEM_ADDR_W-1:0] internal_axi_awaddr; - wire [MEM_ADDR_W-1:0] internal_axi_araddr; - assign axi_awlock_o = {1'B0, extmem_axi_awlock}; - assign axi_arlock_o = {1'B0, extmem_axi_arlock}; - assign {iBus_extmem_axi_bid, dBus_extmem_axi_bid} = {extmem_axi_bid[4], extmem_axi_bid[0]}; - assign {iBus_extmem_axi_rid, dBus_extmem_axi_rid} = {extmem_axi_rid[4], extmem_axi_rid[0]}; - // Instructions bus interconnect {I, D} -> {internal, external} - axi_interconnect #( - .ID_WIDTH (AXI_ID_W), - .DATA_WIDTH(DATA_W), - .ADDR_WIDTH(MEM_ADDR_W), - .M_ADDR_WIDTH(MEM_ADDR_W), - .S_COUNT (2), - .M_COUNT (1) - ) extmem_axi_interconnect ( - .clk(clk_i), - .rst(arst_i), - - .s_axi_awid({3'b000, iBus_extmem_axi_awid, 3'b000, dBus_extmem_axi_awid}), - .s_axi_awaddr({ - iBus_extmem_axi_awaddr[MEM_ADDR_W-1:0], dBus_extmem_axi_awaddr[MEM_ADDR_W-1:0] - }), - .s_axi_awlen({iBus_extmem_axi_awlen, dBus_extmem_axi_awlen}), - .s_axi_awsize({iBus_extmem_axi_awsize, dBus_extmem_axi_awsize}), - .s_axi_awburst({iBus_extmem_axi_awburst, dBus_extmem_axi_awburst}), - .s_axi_awlock({iBus_extmem_axi_awlock[0], dBus_extmem_axi_awlock[0]}), - .s_axi_awcache({iBus_extmem_axi_awcache, dBus_extmem_axi_awcache}), - .s_axi_awprot({iBus_extmem_axi_awprot, dBus_extmem_axi_awprot}), - .s_axi_awqos({iBus_extmem_axi_awqos, dBus_extmem_axi_awqos}), - .s_axi_awvalid({iBus_extmem_axi_awvalid, dBus_extmem_axi_awvalid}), - .s_axi_awready({iBus_extmem_axi_awready, dBus_extmem_axi_awready}), - .s_axi_wdata({iBus_extmem_axi_wdata, dBus_extmem_axi_wdata}), - .s_axi_wstrb({iBus_extmem_axi_wstrb, dBus_extmem_axi_wstrb}), - .s_axi_wlast({iBus_extmem_axi_wlast, dBus_extmem_axi_wlast}), - .s_axi_wvalid({iBus_extmem_axi_wvalid, dBus_extmem_axi_wvalid}), - .s_axi_wready({iBus_extmem_axi_wready, dBus_extmem_axi_wready}), - .s_axi_bid(extmem_axi_bid), - .s_axi_bresp({iBus_extmem_axi_bresp, dBus_extmem_axi_bresp}), - .s_axi_bvalid({iBus_extmem_axi_bvalid, dBus_extmem_axi_bvalid}), - .s_axi_bready({iBus_extmem_axi_bready, dBus_extmem_axi_bready}), - .s_axi_arid({3'b000, iBus_extmem_axi_arid, 3'b000, dBus_extmem_axi_arid}), - .s_axi_araddr({ - iBus_extmem_axi_araddr[MEM_ADDR_W-1:0], dBus_extmem_axi_araddr[MEM_ADDR_W-1:0] - }), - .s_axi_arlen({iBus_extmem_axi_arlen, dBus_extmem_axi_arlen}), - .s_axi_arsize({iBus_extmem_axi_arsize, dBus_extmem_axi_arsize}), - .s_axi_arburst({iBus_extmem_axi_arburst, dBus_extmem_axi_arburst}), - .s_axi_arlock({iBus_extmem_axi_arlock[0], dBus_extmem_axi_arlock[0]}), - .s_axi_arcache({iBus_extmem_axi_arcache, dBus_extmem_axi_arcache}), - .s_axi_arprot({iBus_extmem_axi_arprot, dBus_extmem_axi_arprot}), - .s_axi_arqos({iBus_extmem_axi_arqos, dBus_extmem_axi_arqos}), - .s_axi_arvalid({iBus_extmem_axi_arvalid, dBus_extmem_axi_arvalid}), - .s_axi_arready({iBus_extmem_axi_arready, dBus_extmem_axi_arready}), - .s_axi_rid(extmem_axi_rid), - .s_axi_rdata({iBus_extmem_axi_rdata, dBus_extmem_axi_rdata}), - .s_axi_rresp({iBus_extmem_axi_rresp, dBus_extmem_axi_rresp}), - .s_axi_rlast({iBus_extmem_axi_rlast, dBus_extmem_axi_rlast}), - .s_axi_rvalid({iBus_extmem_axi_rvalid, dBus_extmem_axi_rvalid}), - .s_axi_rready({iBus_extmem_axi_rready, dBus_extmem_axi_rready}), - - .m_axi_awid(axi_awid_o), - .m_axi_awaddr(internal_axi_awaddr), - .m_axi_awlen(axi_awlen_o), - .m_axi_awsize(axi_awsize_o), - .m_axi_awburst(axi_awburst_o), - .m_axi_awlock(extmem_axi_awlock), - .m_axi_awcache(axi_awcache_o), - .m_axi_awprot(axi_awprot_o), - .m_axi_awqos(axi_awqos_o), - .m_axi_awvalid(axi_awvalid_o), - .m_axi_awready(axi_awready_i), - .m_axi_wdata(axi_wdata_o), - .m_axi_wstrb(axi_wstrb_o), - .m_axi_wlast(axi_wlast_o), - .m_axi_wvalid(axi_wvalid_o), - .m_axi_wready(axi_wready_i), - .m_axi_bid(axi_bid_i), - .m_axi_bresp(axi_bresp_i), - .m_axi_bvalid(axi_bvalid_i), - .m_axi_bready(axi_bready_o), - .m_axi_arid(axi_arid_o), - .m_axi_araddr(internal_axi_araddr), - .m_axi_arlen(axi_arlen_o), - .m_axi_arsize(axi_arsize_o), - .m_axi_arburst(axi_arburst_o), - .m_axi_arlock(extmem_axi_arlock), - .m_axi_arcache(axi_arcache_o), - .m_axi_arprot(axi_arprot_o), - .m_axi_arqos(axi_arqos_o), - .m_axi_arvalid(axi_arvalid_o), - .m_axi_arready(axi_arready_i), - .m_axi_rid(axi_rid_i), - .m_axi_rdata(axi_rdata_i), - .m_axi_rresp(axi_rresp_i), - .m_axi_rlast(axi_rlast_i), - .m_axi_rvalid(axi_rvalid_i), - .m_axi_rready(axi_rready_o), - //optional signals - .s_axi_awuser(2'b00), - .s_axi_wuser (2'b00), - .s_axi_aruser(2'b00), - .m_axi_buser (1'b0), - .m_axi_ruser (1'b0) + boot_ctr #( + .DATA_W(UART0_DATA_W), + .ADDR_W(UART0_ADDR_W) + ) boot_ctr ( + .boot(boot), + .cpu_reset(cpu_reset), + .iob_avalid_i(slaves_req[`AVALID(0)]), + .iob_addr_i(slaves_req[`ADDRESS(0, `IOB_UART16550_SWREG_ADDR_W)]), + .iob_wdata_i(slaves_req[`WDATA(0)]), + .iob_wstrb_i(slaves_req[`WSTRB(0)]), + .iob_rvalid_o(slaves_resp[`RVALID(0)]), + .iob_rdata_o(slaves_resp[`RDATA(0)]), + .iob_ready_o(slaves_resp[`READY(0)]), + .clk_i(clk_i), + .arst_i(arst_i), + .cke_i(cke_i) ); - assign axi_awaddr_o[AXI_ADDR_W-1:0] = internal_axi_awaddr + MEM_ADDR_OFFSET; - assign axi_araddr_o[AXI_ADDR_W-1:0] = internal_axi_araddr + MEM_ADDR_OFFSET; - `include "iob_soc_opencryptolinux_periphs_inst.vs" endmodule diff --git a/iob_soc_opencryptolinux.py b/iob_soc_opencryptolinux.py index f9b0973a..8a0735c6 100755 --- a/iob_soc_opencryptolinux.py +++ b/iob_soc_opencryptolinux.py @@ -12,7 +12,6 @@ from iob_clint import iob_clint from iob_uart import iob_uart from iob_spi import iob_spi -from axi_ram import axi_ram from axil2iob import axil2iob @@ -50,20 +49,15 @@ def _create_submodules_list(cls, extra_submodules=[]): super()._create_submodules_list( [ {"interface": "peripheral_axi_wire"}, - {"interface": "dBus_intmem_axi_wire"}, - {"interface": "iBus_intmem_axi_wire"}, - {"interface": "dBus_extmem_axi_wire"}, - {"interface": "iBus_extmem_axi_wire"}, + {"interface": "intmem_axi_wire"}, {"interface": "dBus_axi_wire"}, {"interface": "iBus_axi_wire"}, - {"interface": "ram_axi_wire"}, {"interface": "dBus_axi_m_port"}, {"interface": "iBus_axi_m_port"}, {"interface": "dBus_axi_m_portmap"}, {"interface": "iBus_axi_m_portmap"}, iob_vexriscv, iob_uart16550, - axi_ram, axil2iob, # iob_spi, (iob_uart, {"purpose": "simulation"}), @@ -140,7 +134,7 @@ def _setup_confs(cls, extra_confs=[]): { "name": "SRAM_ADDR_W", "type": "P", - "val": "20", + "val": "15", "min": "1", "max": "32", "descr": "SRAM address width", diff --git a/software/src/iob_soc_opencryptolinux_boot.c b/software/src/iob_soc_opencryptolinux_boot.c index 289a1f9b..3c4c0577 100644 --- a/software/src/iob_soc_opencryptolinux_boot.c +++ b/software/src/iob_soc_opencryptolinux_boot.c @@ -7,7 +7,6 @@ // defined here (and not in periphs.h) because it is the only peripheral used // by the bootloader #define UART0_BASE 0xf4000000 -#define CLINT0_BASE 0xf8000000 #define PROGNAME "IOb-Bootloader" From 29a887a1c29a64fd753cd92b8b3b5e94289f28e7 Mon Sep 17 00:00:00 2001 From: Pedro Antunes Date: Wed, 18 Oct 2023 16:57:54 +0100 Subject: [PATCH 26/27] *: SoC runs baremetal firmware. --- hardware/src/axi_ram.v | 6 +++-- hardware/src/boot_ctr.v | 25 +++++++++++-------- hardware/src/iob_soc_opencryptolinux.v | 4 +++ iob_soc_opencryptolinux.py | 5 ++++ software/src/iob_soc_opencryptolinux_boot.S | 2 +- .../src/iob_soc_opencryptolinux_firmware.S | 2 +- .../src/iob_soc_opencryptolinux_firmware.c | 4 +-- submodules/VEXRISCV | 2 +- 8 files changed, 32 insertions(+), 18 deletions(-) diff --git a/hardware/src/axi_ram.v b/hardware/src/axi_ram.v index 2c005fa5..02d805fc 100644 --- a/hardware/src/axi_ram.v +++ b/hardware/src/axi_ram.v @@ -266,7 +266,7 @@ module axi_ram #( endcase end - always @(posedge clk_i) begin + always @(posedge clk_i, posedge rst_i) begin if (rst_i) begin write_state_reg <= WRITE_STATE_IDLE; axi_awready_reg <= 1'b0; @@ -294,7 +294,9 @@ module axi_ram #( axi_bid_reg <= axi_bid_next; end + end + always @(posedge clk_i) begin for (i = 0; i < WORD_WIDTH; i = i + 1) begin if (mem_wr_en & axi_wstrb_i[i]) begin mem[write_addr_valid][WORD_SIZE*i+:WORD_SIZE] <= axi_wdata_i[WORD_SIZE*i+:WORD_SIZE]; @@ -361,7 +363,7 @@ module axi_ram #( endcase end - always @(posedge clk_i) begin + always @(posedge clk_i, posedge rst_i) begin if (rst_i) begin read_state_reg <= READ_STATE_IDLE; axi_arready_reg <= 1'b0; diff --git a/hardware/src/boot_ctr.v b/hardware/src/boot_ctr.v index 577aa3ca..a7779410 100644 --- a/hardware/src/boot_ctr.v +++ b/hardware/src/boot_ctr.v @@ -8,13 +8,13 @@ module boot_ctr #( output wire boot, output wire cpu_reset, - input [ 1-1:0] iob_avalid_i, - input [ADDR_W-1:0] iob_addr_i, - input [DATA_W-1:0] iob_wdata_i, - input [STRB_W-1:0] iob_wstrb_i, - output [ 1-1:0] iob_rvalid_o, - output [DATA_W-1:0] iob_rdata_o, - output [ 1-1:0] iob_ready_o, + input wire [ 1-1:0] iob_avalid_i, + input wire [ADDR_W-1:0] iob_addr_i, + input wire [DATA_W-1:0] iob_wdata_i, + input wire [STRB_W-1:0] iob_wstrb_i, + output wire [ 1-1:0] iob_rvalid_o, + output wire [DATA_W-1:0] iob_rdata_o, + output wire [ 1-1:0] iob_ready_o, `include "clk_en_rst_s_port.vs" ); @@ -23,11 +23,16 @@ module boot_ctr #( wire boot_wr; reg boot_nxt; //create CPU reset pulse - wire cpu_rst_req; + wire cpu_reset_req; wire rst_sync; assign boot_wr = iob_avalid_i & (|iob_wstrb_i); - assign cpu_rst_req = (iob_avalid_i & (|iob_wstrb_i) & iob_wdata_i[1]) | rst_sync; + assign cpu_reset_req = (iob_avalid_i & (|iob_wstrb_i) & iob_wdata_i[1]) | rst_sync; + + // IOb-Bus + assign iob_rvalid_o = 1'b0; // has no read registers + assign iob_rdata_o = {DATA_W{1'b0}}; + assign iob_ready_o = 1'b1; iob_reg_re #( .DATA_W (1), @@ -69,7 +74,7 @@ module boot_ctr #( .clk_i (clk_i), .arst_i (arst_i), .cke_i (cke_i), - .start_i(cpu_rst_req), + .start_i(cpu_reset_req), .pulse_o(cpu_reset) ); diff --git a/hardware/src/iob_soc_opencryptolinux.v b/hardware/src/iob_soc_opencryptolinux.v index 58dcdb6f..4b3b8d4f 100644 --- a/hardware/src/iob_soc_opencryptolinux.v +++ b/hardware/src/iob_soc_opencryptolinux.v @@ -77,6 +77,10 @@ module iob_soc_opencryptolinux #( assign axi_awaddr_o[AXI_ADDR_W-1:0] = extmem_axi_awaddr[MEM_ADDR_W-1:0] + MEM_ADDR_OFFSET; assign axi_araddr_o[AXI_ADDR_W-1:0] = extmem_axi_araddr[MEM_ADDR_W-1:0] + MEM_ADDR_OFFSET; + assign peripheral_axi_bid = {PERIPHERAL_AXI_ID_W{1'b0}}; + assign peripheral_axi_rid = {PERIPHERAL_AXI_ID_W{1'b0}}; + assign peripheral_axi_rlast = 1'b1; + // // CPU // diff --git a/iob_soc_opencryptolinux.py b/iob_soc_opencryptolinux.py index 8a0735c6..ee663407 100755 --- a/iob_soc_opencryptolinux.py +++ b/iob_soc_opencryptolinux.py @@ -70,6 +70,7 @@ def _create_submodules_list(cls, extra_submodules=[]): if type(cls.submodule_list[i]) == type and cls.submodule_list[i].name in [ "iob_picorv32", "iob_uart", + "axi_interconnect", ]: cls.submodule_list.pop(i) continue @@ -86,6 +87,10 @@ def _post_setup(cls): if os.path.isfile(src_file): shutil.copy2(src_file, dst) + dst = f"{cls.build_dir}/hardware/src" + src_file = f"{__class__.setup_dir}/hardware/src/axi_interconnect.v" + shutil.copy2(src_file, dst) + @classmethod def _setup_confs(cls, extra_confs=[]): # Append confs or override them if they exist diff --git a/software/src/iob_soc_opencryptolinux_boot.S b/software/src/iob_soc_opencryptolinux_boot.S index 0af6b0af..c056ab7d 100644 --- a/software/src/iob_soc_opencryptolinux_boot.S +++ b/software/src/iob_soc_opencryptolinux_boot.S @@ -13,7 +13,7 @@ jal ra, main //reboot to run firmware li s5, 2 //cpu_rst_req=1, boot=0 -li s6, BOOTCTR_BASE +li s6, 0xf0000000 sw s5, 0(s6) ebreak diff --git a/software/src/iob_soc_opencryptolinux_firmware.S b/software/src/iob_soc_opencryptolinux_firmware.S index ad0b7082..7d01bddf 100644 --- a/software/src/iob_soc_opencryptolinux_firmware.S +++ b/software/src/iob_soc_opencryptolinux_firmware.S @@ -20,7 +20,7 @@ _start: //reboot to run bootloader li s5, 3 //cpu_rst_req=1, boot=1 - li s6, BOOTCTR_BASE + li s6, 0xf0000000 sw s5, 0(s6)//cpu_rst_req=1, boot=1 ebreak diff --git a/software/src/iob_soc_opencryptolinux_firmware.c b/software/src/iob_soc_opencryptolinux_firmware.c index 9fce6196..9b039a85 100644 --- a/software/src/iob_soc_opencryptolinux_firmware.c +++ b/software/src/iob_soc_opencryptolinux_firmware.c @@ -12,7 +12,7 @@ #define UART0_BASE 0xf4000000 #define CLINT0_BASE 0xf8000000 -#define PLIC0_BASE 0xf0000000 +#define PLIC0_BASE 0xfc000000 #define MTIMER_SECONDS_TO_CLOCKS(SEC) \ ((uint64_t)(((SEC)*(FREQ)))) @@ -43,7 +43,6 @@ int main() { // Setup timer timestamp = clint_getTime(CLINT0_BASE); - printf("%x\n", (uint32_t)timestamp); clint_setCmp(CLINT0_BASE, MTIMER_SECONDS_TO_CLOCKS(0.001)+(uint32_t)timestamp, 0); // Enable MIE.MTI @@ -70,7 +69,6 @@ static void irq_entry(void) { printf("Entered IRQ.\n"); uint32_t this_cause = csr_read_mcause(); timestamp = clint_getTime(CLINT0_BASE); - printf("%x\n", (uint32_t)timestamp); if (this_cause & MCAUSE_INTERRUPT_BIT_MASK) { this_cause &= 0xFF; // Known exceptions diff --git a/submodules/VEXRISCV b/submodules/VEXRISCV index 5bfa235a..ad5ea7e4 160000 --- a/submodules/VEXRISCV +++ b/submodules/VEXRISCV @@ -1 +1 @@ -Subproject commit 5bfa235aeb3a3337728179979af434aa5d6696f1 +Subproject commit ad5ea7e4fe40f5b5748bbc4b0e615145a04a7473 From eb6988cd4f04d87c0c283d9b2326ee585ccda754 Mon Sep 17 00:00:00 2001 From: Pedro Antunes Date: Wed, 18 Oct 2023 18:53:27 +0100 Subject: [PATCH 27/27] submodules/*: update. --- hardware/src/iob_soc_opencryptolinux.v | 2 +- software/src/iob_soc_opencryptolinux_boot.c | 2 +- submodules/OS | 2 +- submodules/VEXRISCV | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/hardware/src/iob_soc_opencryptolinux.v b/hardware/src/iob_soc_opencryptolinux.v index 4b3b8d4f..270ecdc2 100644 --- a/hardware/src/iob_soc_opencryptolinux.v +++ b/hardware/src/iob_soc_opencryptolinux.v @@ -97,7 +97,7 @@ module iob_soc_opencryptolinux #( .clint_resp (slaves_resp[(N_SLAVES-2)*34+:`RESP_W]), .plic_req (slaves_req[(N_SLAVES-1)*69+:`REQ_W]), .plic_resp (slaves_resp[(N_SLAVES-1)*34+:`RESP_W]), - .plicInterrupts(32'd0), + .plicInterrupts({{31{1'b0}}, uart_interrupt_o}), // Axi instruction bus `include "iBus_axi_m_portmap.vs" // Axi data bus diff --git a/software/src/iob_soc_opencryptolinux_boot.c b/software/src/iob_soc_opencryptolinux_boot.c index 3c4c0577..a7a9058c 100644 --- a/software/src/iob_soc_opencryptolinux_boot.c +++ b/software/src/iob_soc_opencryptolinux_boot.c @@ -11,7 +11,7 @@ #define PROGNAME "IOb-Bootloader" #define DC1 17 // Device Control 1 (used to indicate end of bootloader) -#define EXT_MEM 0x80000000 +#define EXT_MEM 0x00000000 int main() { diff --git a/submodules/OS b/submodules/OS index ff805dab..f9fb7351 160000 --- a/submodules/OS +++ b/submodules/OS @@ -1 +1 @@ -Subproject commit ff805dab4e30db733af0c84db2d0cc14b200d663 +Subproject commit f9fb73519d370591ff6a6a06fefe8f1119f2b2e2 diff --git a/submodules/VEXRISCV b/submodules/VEXRISCV index ad5ea7e4..c5eee031 160000 --- a/submodules/VEXRISCV +++ b/submodules/VEXRISCV @@ -1 +1 @@ -Subproject commit ad5ea7e4fe40f5b5748bbc4b0e615145a04a7473 +Subproject commit c5eee03118a25e74d7051bdb610b0baed3f8b0f4