From dde4d77360aab0d2b4bc69b3902e839ae5dfab25 Mon Sep 17 00:00:00 2001 From: Edw590 <40151365+Edw590@users.noreply.github.com> Date: Thu, 10 Aug 2023 03:42:54 +0100 Subject: [PATCH 1/2] Fixes in hardware compilation More files updated to work with the latest scripts. --- hardware/src/iob_soc.vh | 2 + hardware/src/iob_soc_ext_mem_if.v | 73 ++++++++++++++--------------- hardware/src/iob_soc_int_mem.v | 3 +- submodules/BOOT/boot.py | 8 ++++ submodules/BOOT/hardware/src/boot.v | 26 +++++----- 5 files changed, 60 insertions(+), 52 deletions(-) create mode 100644 hardware/src/iob_soc.vh diff --git a/hardware/src/iob_soc.vh b/hardware/src/iob_soc.vh new file mode 100644 index 000000000..519387046 --- /dev/null +++ b/hardware/src/iob_soc.vh @@ -0,0 +1,2 @@ +// data bus select bits +`define B_BIT (`REQ_W - (ADDR_W-Bbit+1)) //boot controller select bit diff --git a/hardware/src/iob_soc_ext_mem_if.v b/hardware/src/iob_soc_ext_mem_if.v index cbb70ca7d..d597f79b0 100644 --- a/hardware/src/iob_soc_ext_mem_if.v +++ b/hardware/src/iob_soc_ext_mem_if.v @@ -3,7 +3,8 @@ */ `timescale 1 ns / 1 ps -`include "iob_lib.vh" +`include "iob_soc_conf.vh" +`include "iob_utils.vh" module iob_soc_ext_mem_if #( @@ -35,8 +36,8 @@ module iob_soc_ext_mem_if output [INT_DATA_W-1:0] d_rdata_o, // AXI interface -`include "iob_axi_m_port.vh" -`include "iob_clkenrst_port.vh" +`include "axi_m_port.vs" +`include "clk_en_rst_s_port.vs" ); // @@ -57,13 +58,10 @@ module iob_soc_ext_mem_if .rd_o(i_wr_e) ); -clk_i, + iob_reg_e #(1,0) d_wr_e_reg (clk_i, arst_i, cke_i, i_req[1+FIRM_ADDR_W-2+`WRITE_W-1], {| i_req[`WSTRB(0)]}, i_wr_e); - -arst_i, cke_i, i_req[1+FIRM_ADDR_W-2+`WRITE_W-1], {| i_req[`wstrb(0)]}, i_wr_e); - - assign i_resp[`rvalid(0)] = i_wr_e? 1'b0 : i_ack; - assign i_resp[`ready(0)] = i_ack; + assign i_resp[`RVALID(0)] = i_wr_e? 1'b0 : i_ack; + assign i_resp[`READY(0)] = i_ack; // Back-end bus wire [1+DCACHE_ADDR_W+`WRITE_W-1:0] icache_be_req; @@ -71,8 +69,7 @@ arst_i, cke_i, i_req[1+FIRM_ADDR_W-2+`WRITE_W-1], {| i_req[`wstrb(0)]}, i_wr_e); // Instruction cache instance - iob_cache_iob - #( + iob_cache_iob #( .FE_ADDR_W(FIRM_ADDR_W), .BE_ADDR_W(DCACHE_ADDR_W), .NWAYS_W(2), //Number of ways @@ -89,10 +86,10 @@ arst_i, cke_i, i_req[1+FIRM_ADDR_W-2+`WRITE_W-1], {| i_req[`wstrb(0)]}, i_wr_e); // Front-end interface .req (i_req[1+FIRM_ADDR_W-2+`WRITE_W-1]), - .addr (i_req[`address(0, FIRM_ADDR_W-2)]), - .wdata (i_req[`wdata(0)]), - .wstrb (i_req[`wstrb(0)]), - .rdata (i_resp[`rdata(0)]), + .addr (i_req[`ADDRESS(0, FIRM_ADDR_W-2)]), + .wdata (i_req[`WDATA(0)]), + .wstrb (i_req[`WSTRB(0)]), + .rdata (i_resp[`RDATA(0)]), .ack (i_ack), //Control IO .invalidate_in(1'b0), @@ -101,11 +98,11 @@ arst_i, cke_i, i_req[1+FIRM_ADDR_W-2+`WRITE_W-1], {| i_req[`wstrb(0)]}, i_wr_e); .wtb_empty_out(), // Back-end interface .be_req (icache_be_req[1+DCACHE_ADDR_W+`WRITE_W-1]), - .be_addr (icache_be_req[`address(0, DCACHE_ADDR_W)]), - .be_wdata (icache_be_req[`wdata(0)]), - .be_wstrb (icache_be_req[`wstrb(0)]), - .be_rdata (icache_be_resp[`rdata(0)]), - .be_ack (icache_be_resp[`ready(0)]) + .be_addr (icache_be_req[`ADDRESS(0, DCACHE_ADDR_W)]), + .be_wdata (icache_be_req[`WDATA(0)]), + .be_wstrb (icache_be_req[`WSTRB(0)]), + .be_rdata (icache_be_resp[`RDATA(0)]), + .be_ack (icache_be_resp[`READY(0)]) ); //l2 cache interface signals @@ -138,10 +135,10 @@ arst_i, cke_i, i_req[1+FIRM_ADDR_W-2+`WRITE_W-1], {| i_req[`wstrb(0)]}, i_wr_e); wire d_ack; reg d_wr_e; // Instruction write enable register reg d_ready; - iob_reg_e #(1,0) d_wr_e_reg (clk_i, arst_i, cke_i, d_req[1+FIRM_ADDR_W-2+`WRITE_W-1], {| d_req[`wstrb(0)]}, d_wr_e); + iob_reg_e #(1,0) d_wr_e_reg (clk_i, arst_i, cke_i, d_req[1+FIRM_ADDR_W-2+`WRITE_W-1], {| d_req[`WSTRB(0)]}, d_wr_e); //iob_reg_e #(1,0) d_ready_reg (clk_i, arst_i, cke_i, d_ack | d_req[1+FIRM_ADDR_W-2+`WRITE_W-1], ~d_req[1+FIRM_ADDR_W-2+`WRITE_W-1], d_ready); - assign d_resp[`rvalid(0)] = i_wr_e? 1'b0 : d_ack; - assign d_resp[`ready(0)] = d_ack; + assign d_resp[`RVALID(0)] = i_wr_e? 1'b0 : d_ack; + assign d_resp[`READY(0)] = d_ack; // Back-end bus wire [1+DCACHE_ADDR_W+`WRITE_W-1:0] dcache_be_req; @@ -165,10 +162,10 @@ arst_i, cke_i, i_req[1+FIRM_ADDR_W-2+`WRITE_W-1], {| i_req[`wstrb(0)]}, i_wr_e); // Front-end interface .req (d_req[2+DCACHE_ADDR_W-2+`WRITE_W-1]), - .addr (d_req[`address(0,1+DCACHE_ADDR_W-2)]), - .wdata (d_req[`wdata(0)]), - .wstrb (d_req[`wstrb(0)]), - .rdata (d_resp[`rdata(0)]), + .addr (d_req[`ADDRESS(0,1+DCACHE_ADDR_W-2)]), + .wdata (d_req[`WDATA(0)]), + .wstrb (d_req[`WSTRB(0)]), + .rdata (d_resp[`RDATA(0)]), .ack (d_ack), //Control IO .invalidate_in(1'b0), @@ -177,11 +174,11 @@ arst_i, cke_i, i_req[1+FIRM_ADDR_W-2+`WRITE_W-1], {| i_req[`wstrb(0)]}, i_wr_e); .wtb_empty_out(), // Back-end interface .be_req (dcache_be_req[1+DCACHE_ADDR_W+`WRITE_W-1]), - .be_addr (dcache_be_req[`address(0,DCACHE_ADDR_W)]), - .be_wdata (dcache_be_req[`wdata(0)]), - .be_wstrb (dcache_be_req[`wstrb(0)]), - .be_rdata (dcache_be_resp[`rdata(0)]), - .be_ack (dcache_be_resp[`ready(0)]) + .be_addr (dcache_be_req[`ADDRESS(0,DCACHE_ADDR_W)]), + .be_wdata (dcache_be_req[`WDATA(0)]), + .be_wstrb (dcache_be_req[`WSTRB(0)]), + .be_rdata (dcache_be_resp[`RDATA(0)]), + .be_ack (dcache_be_resp[`READY(0)]) ); // Merge cache back-ends @@ -222,18 +219,18 @@ arst_i, cke_i, i_req[1+FIRM_ADDR_W-2+`WRITE_W-1], {| i_req[`wstrb(0)]}, i_wr_e); ( // Native interface .req (l2cache_req[1+DCACHE_ADDR_W+`WRITE_W-1]), - .addr (l2cache_req[`address(0, DCACHE_ADDR_W)-2]), - .wdata (l2cache_req[`wdata(0)]), - .wstrb (l2cache_req[`wstrb(0)]), - .rdata (l2cache_resp[`rdata(0)]), - .ack (l2cache_resp[`ready(0)]), + .addr (l2cache_req[`ADDRESS(0, DCACHE_ADDR_W)-2]), + .wdata (l2cache_req[`WDATA(0)]), + .wstrb (l2cache_req[`WSTRB(0)]), + .rdata (l2cache_resp[`RDATA(0)]), + .ack (l2cache_resp[`READY(0)]), //Control IO .invalidate_in(invalidate_reg & ~l2_avalid), .invalidate_out(), .wtb_empty_in(1'b1), .wtb_empty_out(l2_wtb_empty), // AXI interface - `include "iob_axi_m_m_portmap.vh" + `include "axi_m_m_portmap.vs" .clk_i(clk_i), .rst_i(arst_i) ); diff --git a/hardware/src/iob_soc_int_mem.v b/hardware/src/iob_soc_int_mem.v index 3bd9b9657..8c8c69637 100644 --- a/hardware/src/iob_soc_int_mem.v +++ b/hardware/src/iob_soc_int_mem.v @@ -4,7 +4,6 @@ */ `timescale 1ns / 1ps -`include "build_configuration.vh" `include "iob_soc_conf.vh" module iob_soc_int_mem @@ -30,7 +29,7 @@ module iob_soc_int_mem output reg d_rvalid_o, output reg d_ready_o, -`include "iob_clkenrst_port.vh" +`include "clk_en_rst_s_port.vs" ); //assign ready signals to 1 since RAM is always ready diff --git a/submodules/BOOT/boot.py b/submodules/BOOT/boot.py index b8e6c30de..0144cf0fb 100644 --- a/submodules/BOOT/boot.py +++ b/submodules/BOOT/boot.py @@ -49,6 +49,14 @@ def _setup_confs(cls): "max": "32", "descr": "Data bus width", }, + { + "name": "ADDR_W", + "type": "P", + "val": "`IOB_UART_SWREG_ADDR_W", + "min": "NA", + "max": "NA", + "descr": "Address bus width", + }, { "name": "HEXFILE", "type": "P", diff --git a/submodules/BOOT/hardware/src/boot.v b/submodules/BOOT/hardware/src/boot.v index c0e51b625..741e5ca3d 100644 --- a/submodules/BOOT/hardware/src/boot.v +++ b/submodules/BOOT/hardware/src/boot.v @@ -1,31 +1,33 @@ `timescale 1 ns / 1 ps -`include "iob_lib.vh" +`include "iob_utils.vh" +`include "boot_conf.vh" `include "boot_swreg_def.vh" +`include "iob_soc_conf.vh" module boot #( -`include "boot_params.vh" +`include "boot_params.vs" ) ( -`include "boot_io.vh" +`include "boot_io.vs" ); -`include "boot_swreg_inst.vh" +`include "boot_swreg_inst.vs" //cpu interface: rdata, rvalid and ready - assign iob_rdata = {{(DATA_W-1){1'b0}},boot_o}; - iob_reg #(1,0) rvalid_reg (clk_i, arst_i, cke_i, iob_avalid & ~(|iob_wstrb), iob_rvalid); - assign iob_ready = 1'b1; + assign iob_rdata_o = {{(DATA_W-1){1'b0}},boot_o}; + iob_reg #(1,0) rvalid_reg (clk_i, arst_i, cke_i, iob_avalid_i & ~(|iob_wstrb_i), iob_rvalid_o); + assign iob_ready_o = 1'b1; //boot control register: {cpu_reset, boot, preboot} - wire bootctr_wr = iob_avalid & (iob_addr_i == `BOOT_CTR_ADDR) |iob_wstrb; - iob_reg_e #(2,1) bootnxt (clk_i, arst_i, cke_i, boot_wr, iob_wdata[1:0], CTR); + wire bootctr_wr = iob_avalid_i & (iob_addr_i == `BOOT_CTR_ADDR) |iob_wstrb_i; + iob_reg_e #(2,1) bootnxt (clk_i, arst_i, cke_i, boot_wr, iob_wdata_i[1:0], CTR); //create CPU reset pulse wire cpu_rst_req; - assign cpu_rst_req = iob_avalid & (|iob_wstrb) & iob_wdata[2]; + assign cpu_rst_req = iob_avalid_i & (|iob_wstrb_i) & iob_wdata_i[2]; iob_pulse_gen #( .START(0), @@ -46,7 +48,7 @@ module boot // iob_rom_dp #( .DATA_W(DATA_W), - .ADDR_W(BOOTROM_ADDR_W-2), + .ADDR_W(`IOB_SOC_BOOTROM_ADDR_W-2), .HEXFILE(HEXFILE) ) sp_rom0 @@ -61,7 +63,7 @@ module boot //data memory interface .r_en_b_i(dbus_avalid_i), .addr_b_i(iob_addr_i), - .w_data_b_i(iob_wdata_i) + .r_data_b_o(iob_rdata_o) ); From 14902f69de42e7fac8846796f32e6f7b9a5713bc Mon Sep 17 00:00:00 2001 From: Edw590 <40151365+Edw590@users.noreply.github.com> Date: Thu, 10 Aug 2023 17:58:40 +0100 Subject: [PATCH 2/2] Full compilation fix List of changes: - To fix the full compilation, python-setup files were brought back, so the project is now compiling parts of (or completely) the python-setup files (some files in hardware/src and all in software/src). Still, the revamp files are here ready to be integrated. - BOOT module renamed from boot to iob_soc_boot - More iob_soc_rom.hex preparations --- hardware/simulation/sim_build.mk | 1 + hardware/src/boot_ctr.v | 151 +++++++++++++ hardware/src/ext_mem.v | 206 ++++++++++++++++++ hardware/src/int_mem.v | 193 ++++++++++++++++ hardware/src/iob_soc_ext_mem_if.v | 20 +- hardware/src/sram.v | 130 +++++++++++ iob_soc.py | 8 +- software/bootloader/iob_soc_boot.S | 21 ++ software/bootloader/iob_soc_boot.c | 2 +- .../{template.lds => iob_soc_boot.lds} | 0 software/firmware/iob_soc_firmware.S | 20 ++ software/firmware/iob_soc_firmware.c | 87 ++++++++ software/firmware/iob_soc_firmware.lds | 29 +++ software/firmware/iob_soc_system.h | 6 + .../{template.lds => iob_soc_preboot.lds} | 0 software/src/iob_soc_boot.S | 12 +- software/src/iob_soc_firmware.S | 18 +- software/sw_build.mk | 13 +- submodules/BOOT/Makefile | 2 +- submodules/BOOT/config_setup.mk | 2 +- .../hardware/src/{boot.v => iob_soc_boot.v} | 26 +-- submodules/BOOT/{boot.py => iob_soc_boot.py} | 16 +- 22 files changed, 905 insertions(+), 58 deletions(-) create mode 100644 hardware/src/boot_ctr.v create mode 100644 hardware/src/ext_mem.v create mode 100644 hardware/src/int_mem.v create mode 100644 hardware/src/sram.v create mode 100644 software/bootloader/iob_soc_boot.S rename software/bootloader/{template.lds => iob_soc_boot.lds} (100%) create mode 100644 software/firmware/iob_soc_firmware.S create mode 100644 software/firmware/iob_soc_firmware.c create mode 100644 software/firmware/iob_soc_firmware.lds create mode 100644 software/firmware/iob_soc_system.h rename software/preboot/{template.lds => iob_soc_preboot.lds} (100%) rename submodules/BOOT/hardware/src/{boot.v => iob_soc_boot.v} (69%) rename submodules/BOOT/{boot.py => iob_soc_boot.py} (93%) diff --git a/hardware/simulation/sim_build.mk b/hardware/simulation/sim_build.mk index a6085712f..00a7e7510 100644 --- a/hardware/simulation/sim_build.mk +++ b/hardware/simulation/sim_build.mk @@ -1,4 +1,5 @@ # Add iob-soc software as a build dependency +#HEX+=iob_soc_preboot.hex iob_soc_boot.hex iob_soc_firmware.hex iob_soc_rom.hex HEX+=iob_soc_boot.hex iob_soc_firmware.hex ROOT_DIR :=../.. diff --git a/hardware/src/boot_ctr.v b/hardware/src/boot_ctr.v new file mode 100644 index 000000000..fb31eebcf --- /dev/null +++ b/hardware/src/boot_ctr.v @@ -0,0 +1,151 @@ +`timescale 1 ns / 1 ps + +module boot_ctr #( + parameter HEXFILE = "iob_soc_boot.hex", + parameter DATA_W = 0, + parameter ADDR_W = 0, + parameter BOOTROM_ADDR_W = 0, + parameter SRAM_ADDR_W = 0 +) ( + output cpu_rst, + output boot, + + //cpu interface + input cpu_avalid, + input [ 1:0] cpu_wdata, + input [DATA_W/8-1:0] cpu_wstrb, + output [ DATA_W-1:0] cpu_rdata, + output reg cpu_rvalid, + output reg cpu_ready, + + + //sram master write interface + output reg sram_avalid, + output [ ADDR_W-1:0] sram_addr, + output [ DATA_W-1:0] sram_wdata, + output reg [DATA_W/8-1:0] sram_wstrb, + + `include "clk_en_rst_s_port.vs" +); + + + //cpu interface: rdata and ready + assign cpu_rdata = {{(DATA_W - 1) {1'b0}}, boot}; + iob_reg #( + .DATA_W (1), + .RST_VAL(0) + ) rvalid_reg ( + .clk_i (clk_i), + .arst_i(arst_i), + .cke_i (cke_i), + .data_i(cpu_avalid & ~(|cpu_wstrb)), + .data_o(cpu_rvalid) + ); + assign cpu_ready = 1'b1; + + //boot register: (1) load bootloader to sram and run it: (0) run program + wire boot_wr = cpu_avalid & |cpu_wstrb; + reg boot_nxt; + 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) + ); + + + //create CPU reset pulse + wire cpu_rst_req; + assign cpu_rst_req = cpu_avalid & (|cpu_wstrb) & cpu_wdata[1]; + wire cpu_rst_pulse; + + 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_pulse) + ); + + wire loading; + assign cpu_rst = loading | cpu_rst_pulse; + + // + // READ BOOT ROM + // + reg rom_r_avalid; + reg [BOOTROM_ADDR_W-3:0] rom_r_addr; + wire [ DATA_W-1:0] rom_r_rdata; + + always @(posedge clk_i, posedge arst_i) + if (arst_i) begin + rom_r_avalid <= 1'b1; + rom_r_addr <= {(BOOTROM_ADDR_W - 2) {1'b0}}; + end else if (boot && rom_r_addr != (2 ** (BOOTROM_ADDR_W - 2) - 1)) + rom_r_addr <= rom_r_addr + 1'b1; + else begin + rom_r_avalid <= 1'b0; + rom_r_addr <= {(BOOTROM_ADDR_W - 2) {1'b0}}; + end + + // + // WRITE SRAM + // + reg sram_w_avalid; + reg [SRAM_ADDR_W-2-1:0] sram_w_addr; + always @(posedge clk_i, posedge arst_i) + if (arst_i) begin + sram_w_avalid <= 1'b0; + sram_w_addr <= -{1'b1, {(BOOTROM_ADDR_W - 2) {1'b0}}}; + sram_wstrb <= {DATA_W / 8{1'b1}}; + end else if (boot) begin + sram_w_avalid <= rom_r_avalid; + sram_w_addr <= -{1'b1, {(BOOTROM_ADDR_W - 2) {1'b0}}} + rom_r_addr; + sram_wstrb <= {DATA_W / 8{rom_r_avalid}}; + end else begin + sram_w_avalid <= 1'b0; + sram_w_addr <= -{1'b1, {(BOOTROM_ADDR_W - 2) {1'b0}}}; + sram_wstrb <= {DATA_W / 8{1'b1}}; + end + + assign loading = rom_r_avalid | sram_w_avalid; + + assign sram_avalid = sram_w_avalid; + assign sram_addr = {sram_w_addr, 2'b00}; + assign sram_wdata = rom_r_rdata; + + // + //INSTANTIATE ROM + // + iob_rom_sp #( + .DATA_W (DATA_W), + .ADDR_W (BOOTROM_ADDR_W - 2), + .HEXFILE(HEXFILE) + ) sp_rom0 ( + .clk_i (clk_i), + .r_en_i (rom_r_avalid), + .addr_i (rom_r_addr), + .r_data_o(rom_r_rdata) + ); + +endmodule diff --git a/hardware/src/ext_mem.v b/hardware/src/ext_mem.v new file mode 100644 index 000000000..7b865962b --- /dev/null +++ b/hardware/src/ext_mem.v @@ -0,0 +1,206 @@ +`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_s_port.vs" +); + + // + // INSTRUCTION CACHE + // + + // Back-end bus + wire [1+MEM_ADDR_W+`WRITE_W-1:0] icache_be_req; + wire [ `RESP_W-1:0] icache_be_resp; + + + // Instruction cache instance + iob_cache_iob #( + .FE_ADDR_W (FIRM_ADDR_W), + .BE_ADDR_W (MEM_ADDR_W), + .NWAYS_W (1), //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 + ) icache ( + .clk_i (clk_i), + .cke_i (cke_i), + .arst_i(arst_i), + + // Front-end interface + .avalid_i (i_req[1+FIRM_ADDR_W-2+`WRITE_W-1]), + .addr_i (i_req[`ADDRESS(0, FIRM_ADDR_W-2)]), + .wdata_i (i_req[`WDATA(0)]), + .wstrb_i (i_req[`WSTRB(0)]), + .rdata_o (i_resp[`RDATA(0)]), + .rvalid_o (i_resp[`RVALID(0)]), + .ready_o (i_resp[`READY(0)]), + //Control IO + .invalidate_i (1'b0), + .invalidate_o(), + .wtb_empty_i (1'b1), + .wtb_empty_o (), + // Back-end interface + .be_avalid_o (icache_be_req[1+MEM_ADDR_W+`WRITE_W-1]), + .be_addr_o (icache_be_req[`ADDRESS(0, MEM_ADDR_W)]), + .be_wdata_o (icache_be_req[`WDATA(0)]), + .be_wstrb_o (icache_be_req[`WSTRB(0)]), + .be_rdata_i (icache_be_resp[`RDATA(0)]), + .be_rvalid_i (icache_be_resp[`RVALID(0)]), + .be_ready_i (icache_be_resp[`READY(0)]) + ); + + //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; + + // + // DATA CACHE + // + + // IOb ready and rvalid signals + + // Back-end bus + wire [1+MEM_ADDR_W+`WRITE_W-1:0] dcache_be_req; + wire [ `RESP_W-1:0] dcache_be_resp; + + // Data cache instance + iob_cache_iob #( + .FE_ADDR_W (MEM_ADDR_W), + .BE_ADDR_W (MEM_ADDR_W), + .NWAYS_W (1), //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 (1), //Either 1 to enable cache-control or 0 to disable + .USE_CTRL_CNT (1) //do not change (it's implementation depends on the previous) + ) dcache ( + .clk_i (clk_i), + .cke_i (cke_i), + .arst_i(arst_i), + + // Front-end interface + .avalid_i (d_req[2+MEM_ADDR_W-2+`WRITE_W-1]), + .addr_i (d_req[`ADDRESS(0, 1+MEM_ADDR_W-2)]), + .wdata_i (d_req[`WDATA(0)]), + .wstrb_i (d_req[`WSTRB(0)]), + .rdata_o (d_resp[`RDATA(0)]), + .rvalid_o (d_resp[`RVALID(0)]), + .ready_o (d_resp[`READY(0)]), + //Control IO + .invalidate_i (1'b0), + .invalidate_o(invalidate), + .wtb_empty_i (l2_wtb_empty), + .wtb_empty_o (), + // Back-end interface + .be_avalid_o (dcache_be_req[1+MEM_ADDR_W+`WRITE_W-1]), + .be_addr_o (dcache_be_req[`ADDRESS(0, MEM_ADDR_W)]), + .be_wdata_o (dcache_be_req[`WDATA(0)]), + .be_wstrb_o (dcache_be_req[`WSTRB(0)]), + .be_rdata_i (dcache_be_resp[`RDATA(0)]), + .be_rvalid_i (dcache_be_resp[`RVALID(0)]), + .be_ready_i (dcache_be_resp[`READY(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_be_req, dcache_be_req}), + .m_resp_o({icache_be_resp, dcache_be_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_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 + `include "axi_m_m_portmap.vs" + .clk_i (clk_i), + .cke_i (cke_i), + .arst_i (arst_i) + ); + +endmodule diff --git a/hardware/src/int_mem.v b/hardware/src/int_mem.v new file mode 100644 index 000000000..fe50accbb --- /dev/null +++ b/hardware/src/int_mem.v @@ -0,0 +1,193 @@ +`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 HEXFILE = "iob_soc_firmware", + parameter BOOT_HEXFILE = "iob_soc_boot", + parameter SRAM_ADDR_W = 0, + parameter BOOTROM_ADDR_W = 0, + parameter B_BIT = 0 +) ( + + output boot, + output cpu_reset, + + //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, + `include "clk_en_rst_s_port.vs" +); + + //sram data bus interface + wire [ `REQ_W-1:0] ram_d_req; + wire [ `RESP_W-1:0] ram_d_resp; + + //modified ram address during boot + wire [SRAM_ADDR_W-3:0] ram_d_addr; + + + //////////////////////////////////////////////////////// + // BOOT HARDWARE + // + //boot controller bus to write program in sram + wire [ `REQ_W-1:0] boot_ctr_req; + wire [ `RESP_W-1:0] boot_ctr_resp; + + // + // SPLIT DATA BUS BETWEEN SRAM AND BOOT CONTROLLER + // + iob_split #( + .ADDR_W (ADDR_W), + .DATA_W (DATA_W), + .N_SLAVES(2), + .P_SLAVES(B_BIT) + ) data_bootctr_split ( + .clk_i (clk_i), + .arst_i (arst_i), + // master interface + .m_req_i (d_req), + .m_resp_o(d_resp), + + // slaves interface + .s_req_o ({boot_ctr_req, ram_d_req}), + .s_resp_i({boot_ctr_resp, ram_d_resp}) + ); + + + // + // BOOT CONTROLLER + // + + //sram instruction write bus + wire [ `REQ_W-1:0] ram_w_req; + wire [`RESP_W-1:0] ram_w_resp; + + boot_ctr #( + .HEXFILE ({BOOT_HEXFILE, ".hex"}), + .DATA_W (DATA_W), + .ADDR_W (ADDR_W), + .BOOTROM_ADDR_W(BOOTROM_ADDR_W), + .SRAM_ADDR_W (SRAM_ADDR_W) + ) boot_ctr0 ( + .clk_i (clk_i), + .arst_i (arst_i), + .cke_i (cke_i), + .cpu_rst(cpu_reset), + .boot (boot), + + //cpu slave interface + //no address bus since single address + .cpu_avalid(boot_ctr_req[`AVALID(0)]), + .cpu_wdata (boot_ctr_req[`WDATA(0)-(DATA_W-2)]), + .cpu_wstrb (boot_ctr_req[`WSTRB(0)]), + .cpu_rdata (boot_ctr_resp[`RDATA(0)]), + .cpu_rvalid(boot_ctr_resp[`RVALID(0)]), + .cpu_ready (boot_ctr_resp[`READY(0)]), + + //sram write master interface + .sram_avalid(ram_w_req[`AVALID(0)]), + .sram_addr (ram_w_req[`ADDRESS(0, ADDR_W)]), + .sram_wdata (ram_w_req[`WDATA(0)]), + .sram_wstrb (ram_w_req[`WSTRB(0)]) + ); + + // + //MODIFY INSTRUCTION READ ADDRESS DURING BOOT + // + + //instruction read bus + wire [ `REQ_W-1:0] ram_r_req; + wire [ `RESP_W-1:0] ram_r_resp; + wire [ ADDR_W-1:0] ram_r_addr; + wire [ ADDR_W-1:0] boot_i_addr; + wire [ ADDR_W-1:0] i_addr; + wire [SRAM_ADDR_W-3:0] boot_ram_d_addr; + wire [SRAM_ADDR_W-3:0] ram_d_addr_int; + + // + //modify addresses to run boot program + // + localparam boot_offset = -('b1 << BOOTROM_ADDR_W); + + //instruction bus: connect directly but address + assign ram_r_req[`ADDRESS(0, ADDR_W)] = ram_r_addr; + assign boot_i_addr = i_req[`ADDRESS(0, ADDR_W)] + boot_offset; + assign i_addr = i_req[`ADDRESS(0, ADDR_W)]; + + assign ram_r_req[`AVALID(0)] = i_req[`AVALID(0)]; + assign ram_r_addr = boot ? boot_i_addr : i_addr; + assign ram_r_req[`WRITE(0)] = i_req[`WRITE(0)]; + assign i_resp[`RESP(0)] = ram_r_resp[`RESP(0)]; + + //data bus: just replace address + assign boot_ram_d_addr = ram_d_req[`ADDRESS(0, SRAM_ADDR_W)-2] + boot_offset[SRAM_ADDR_W-1:2]; + assign ram_d_addr_int = ram_d_req[`ADDRESS(0, SRAM_ADDR_W)-2]; + assign ram_d_addr = boot ? boot_ram_d_addr : ram_d_addr_int; + + // + //MERGE BOOT WRITE BUS AND CPU READ BUS + // + + //sram instruction bus + wire [ `REQ_W-1:0] ram_i_req; + wire [`RESP_W-1:0] ram_i_resp; + + iob_merge #( + .N_MASTERS(2) + ) ibus_merge ( + .clk_i (clk_i), + .arst_i(arst_i), + + //master + .m_req_i ({ram_w_req, ram_r_req}), + .m_resp_o({ram_w_resp, ram_r_resp}), + + //slave + .s_req_o (ram_i_req), + .s_resp_i(ram_i_resp) + ); + + // + // INSTANTIATE RAM + // + sram #( +`ifndef IOB_SOC_USE_EXTMEM +`ifdef IOB_SOC_INIT_MEM + .HEXFILE (HEXFILE), +`endif +`endif + .DATA_W (DATA_W), + .SRAM_ADDR_W(SRAM_ADDR_W) + ) int_sram ( + .clk_i (clk_i), + .cke_i (cke_i), + .arst_i(arst_i), + + //instruction bus + .i_avalid(ram_i_req[`AVALID(0)]), + .i_addr (ram_i_req[`ADDRESS(0, SRAM_ADDR_W)-2]), + .i_wdata (ram_i_req[`WDATA(0)]), + .i_wstrb (ram_i_req[`WSTRB(0)]), + .i_rdata (ram_i_resp[`RDATA(0)]), + .i_rvalid(ram_i_resp[`RVALID(0)]), + .i_ready (ram_i_resp[`READY(0)]), + + //data bus + .d_avalid(ram_d_req[`AVALID(0)]), + .d_addr (ram_d_addr), + .d_wdata (ram_d_req[`WDATA(0)]), + .d_wstrb (ram_d_req[`WSTRB(0)]), + .d_rdata (ram_d_resp[`RDATA(0)]), + .d_rvalid(ram_d_resp[`RVALID(0)]), + .d_ready (ram_d_resp[`READY(0)]) + ); + +endmodule diff --git a/hardware/src/iob_soc_ext_mem_if.v b/hardware/src/iob_soc_ext_mem_if.v index d597f79b0..bc40b0e77 100644 --- a/hardware/src/iob_soc_ext_mem_if.v +++ b/hardware/src/iob_soc_ext_mem_if.v @@ -49,16 +49,16 @@ module iob_soc_ext_mem_if reg i_wr_e; // Instruction write enable register reg i_ready; - iob_reg_e #(1,0) i_wr_e_reg - ( - .clk_i(clk_i), - .rst_i(rst_i), - .wr_i(i_avalid_i), - .wr_data_i(i_wstrb_i), - .rd_o(i_wr_e) - ); - - iob_reg_e #(1,0) d_wr_e_reg (clk_i, arst_i, cke_i, i_req[1+FIRM_ADDR_W-2+`WRITE_W-1], {| i_req[`WSTRB(0)]}, i_wr_e); + //iob_reg_e #(1,0) i_wr_e_reg + // ( + // .clk_i(clk_i), + // .rst_i(rst_i), + // .wr_i(i_avalid_i), + // .wr_data_i(i_wstrb_i), + // .rd_o(i_wr_e) + // ); + + iob_reg_e #(1,0) i_wr_e_reg (clk_i, arst_i, cke_i, i_req[1+FIRM_ADDR_W-2+`WRITE_W-1], {| i_req[`WSTRB(0)]}, i_wr_e); assign i_resp[`RVALID(0)] = i_wr_e? 1'b0 : i_ack; assign i_resp[`READY(0)] = i_ack; diff --git a/hardware/src/sram.v b/hardware/src/sram.v new file mode 100644 index 000000000..7a1da0ea8 --- /dev/null +++ b/hardware/src/sram.v @@ -0,0 +1,130 @@ +`timescale 1ns / 1ps +`include "iob_soc_conf.vh" +`include "bsp.vh" + +module sram #( + parameter DATA_W = `IOB_SOC_DATA_W, + parameter SRAM_ADDR_W = `IOB_SOC_SRAM_ADDR_W, + parameter HEXFILE = "none" +) ( + // intruction bus + input i_avalid, + input [SRAM_ADDR_W-3:0] i_addr, + input [ DATA_W-1:0] i_wdata, //used for booting + input [ DATA_W/8-1:0] i_wstrb, //used for booting + output [ DATA_W-1:0] i_rdata, + output reg i_rvalid, + output reg i_ready, + + // data bus + input d_avalid, + input [SRAM_ADDR_W-3:0] d_addr, + input [ DATA_W-1:0] d_wdata, + input [ DATA_W/8-1:0] d_wstrb, + output [ DATA_W-1:0] d_rdata, + output reg d_rvalid, + output reg d_ready, + + `include "clk_en_rst_s_port.vs" +); + +`ifdef USE_SPRAM + + wire d_avalid_int = i_avalid ? 1'b0 : d_avalid; + wire avalid = i_avalid ? i_avalid : d_avalid; + wire [SRAM_ADDR_W-3:0] addr = i_avalid ? i_addr : d_addr; + wire [DATA_W-1:0] wdata = i_avalid ? i_wdata : d_wdata; + wire [DATA_W/8-1:0] wstrb = i_avalid ? i_wstrb : d_wstrb; + wire [DATA_W-1:0] rdata; + assign d_rdata = rdata; + assign i_rdata = rdata; + + iob_ram_sp_be #( + .HEXFILE(HEXFILE), + .ADDR_W (SRAM_ADDR_W - 2), + .DATA_W (DATA_W) + ) main_mem_byte ( + .clk_i(clk_i), + + // data port + .en_i (avalid), + .addr_i(addr), + .we_i (wstrb), + .d_i (wdata), + .dt_o (rdata) + ); +`else // !`ifdef USE_SPRAM +`ifdef MEM_NO_READ_ON_WRITE + iob_ram_dp_be #( + .HEXFILE (HEXFILE), + .ADDR_W (SRAM_ADDR_W - 2), + .DATA_W (DATA_W), + .MEM_NO_READ_ON_WRITE(1) + ) main_mem_byte ( + .clk_i(clk_i), + + // data port + .enA_i (d_avalid), + .addrA_i(d_addr), + .weA_i (d_wstrb), + .dA_i (d_wdata), + .dA_o (d_rdata), + + // instruction port + .enB_i (i_avalid), + .addrB_i(i_addr), + .weB_i (i_wstrb), + .dB_i (i_wdata), + .dB_o (i_rdata) + ); +`else // !`ifdef MEM_NO_READ_ON_WRITE + iob_ram_dp_be_xil #( + .HEXFILE(HEXFILE), + .ADDR_W (SRAM_ADDR_W - 2), + .DATA_W (DATA_W) + ) main_mem_byte ( + .clk_i(clk_i), + + // data port + .enA_i (d_avalid), + .addrA_i(d_addr), + .weA_i (d_wstrb), + .dA_i (d_wdata), + .dA_o (d_rdata), + + // instruction port + .enB_i (i_avalid), + .addrB_i(i_addr), + .weB_i (i_wstrb), + .dB_i (i_wdata), + .dB_o (i_rdata) + ); +`endif +`endif + + // reply with ready + + iob_reg #( + .DATA_W (1), + .RST_VAL(0) + ) i_rvalid_reg ( + .clk_i (clk_i), + .arst_i(arst_i), + .cke_i (cke_i), + .data_i(i_avalid & ~(|i_wstrb)), + .data_o(i_rvalid) + ); + iob_reg #( + .DATA_W (1), + .RST_VAL(0) + ) d_rvalid_reg ( + .clk_i (clk_i), + .arst_i(arst_i), + .cke_i (cke_i), + .data_i(d_avalid & ~(|d_wstrb)), + .data_o(d_rvalid) + ); + assign i_ready = 1'b1; // SRAM ready is supposed to always be 1 since requests can be continuous + assign d_ready = 1'b1; + +endmodule diff --git a/iob_soc.py b/iob_soc.py index 7aded1851..903d16c6d 100755 --- a/iob_soc.py +++ b/iob_soc.py @@ -9,7 +9,7 @@ from mk_configuration import update_define # Submodules -from boot import boot +from iob_soc_boot import iob_soc_boot from iob_picorv32 import iob_picorv32 from iob_cache import iob_cache from iob_uart import iob_uart @@ -75,15 +75,15 @@ def _create_instances(cls): cls.ext_mem = iob_merge("iob_merge_1") if iob_uart in cls.submodule_list: cls.peripherals.append(iob_uart("UART0")) - if boot in cls.submodule_list: - cls.peripherals.append(boot("BOOT0")) + if iob_soc_boot in cls.submodule_list: + cls.peripherals.append(iob_soc_boot("BOOT0")) @classmethod def _create_submodules_list(cls, extra_submodules=[]): """Create submodules list with dependencies of this module""" super()._create_submodules_list( [ - boot, + iob_soc_boot, iob_picorv32, iob_cache, iob_uart, diff --git a/software/bootloader/iob_soc_boot.S b/software/bootloader/iob_soc_boot.S new file mode 100644 index 000000000..c15f3ac52 --- /dev/null +++ b/software/bootloader/iob_soc_boot.S @@ -0,0 +1,21 @@ +#include "iob_soc_conf.h" +#include "iob_soc_periphs.h" + +#define CTR_ADDR (BOOT0_BASE+(1<