added a bus ram mux and created the functionality to test two srams through wishbone with different address mappings
diff --git a/verilog/rtl/openram_testchip.v b/verilog/rtl/openram_testchip.v index 45016e1..e159acd 100644 --- a/verilog/rtl/openram_testchip.v +++ b/verilog/rtl/openram_testchip.v
@@ -31,6 +31,7 @@ input [31:0] wbs_dat_i, input [31:0] wbs_adr_i, input [`DATA_SIZE-1:0] wbs_sram8_data, + input [`DATA_SIZE-1:0] wbs_sram9_data, output wbs_ack_o, output [31:0] wbs_dat_o, // SRAM data outputs to be captured @@ -98,14 +99,38 @@ // SRAM input connections reg [`SELECT_SIZE-1:0] chip_select; -// Using the wishbone signals for enabling memories - wire ram_clk0; - wire ram_csb0; - wire ram_web0; - wire [`WMASK_SIZE-1:0] ram_wmask0; - wire [7:0] ram_addr0; - wire [31:0] ram_din0; - wire [31:0] ram_dout0; +// wires connecting sram8 wrapper to sram8 macro + wire ram8_clk0; + wire ram8_csb0; + wire ram8_web0; + wire [`WMASK_SIZE-1:0] ram8_wmask0; + wire [7:0] ram8_addr0; + wire [31:0] ram8_din0; + wire [31:0] ram8_dout0; +// wires connecting sram9 wrapper to sram9 macro + wire ram9_clk0; + wire ram9_csb0; + wire ram9_web0; + wire [`WMASK_SIZE-1:0] ram9_wmask0; + wire [7:0] ram9_addr0; + wire [31:0] ram9_din0; + wire [31:0] ram9_dout0; +// wires connecting between mux & sram8 + wire wbs_or8_stb; + wire wbs_or8_cyc; + wire wbs_or8_we; + wire [3:0] wbs_or8_sel; + wire [31:0] wbs_or8_dat_i; + wire wbs_or8_ack; + wire [31:0] wbs_or8_dat_o; +// wires connecting between mux & sram9 + wire wbs_or9_stb; + wire wbs_or9_cyc; + wire wbs_or9_we; + wire [3:0] wbs_or9_sel; + wire [31:0] wbs_or9_dat_i; + wire wbs_or9_ack; + wire [31:0] wbs_or9_dat_o; always @ (posedge clk) begin @@ -130,42 +155,114 @@ sram_register[`WMASK_SIZE+1:0]}; end end - wishbone_wrapper WRAPPER( + + wishbone_ram_mux WB_RAM_MUX( .wb_clk_i(wb_clk_i), .wb_rst_i(wb_rst_i), - .wbs_stb_i(wbs_stb_i), - .wbs_cyc_i(wbs_cyc_i), - .wbs_we_i(wbs_we_i), - .wbs_sel_i(wbs_sel_i), - .wbs_dat_i(wbs_dat_i), + // main wishbone signals coming here + .wbs_ufp_stb_i(wbs_stb_i), + .wbs_ufp_cyc_i(wbs_cyc_i), + .wbs_ufp_we_i(wbs_we_i), + .wbs_ufp_sel_i(wbs_sel_i), + .wbs_ufp_dat_i(wbs_dat_i), + .wbs_ufp_adr_i(wbs_adr_i), + .wbs_ufp_ack_o(wbs_ack_o), + .wbs_ufp_dat_o(wbs_dat_o), + // wishbone signals to sram 8 + .wbs_or8_stb_o(wbs_or8_stb), + .wbs_or8_cyc_o(wbs_or8_cyc), + .wbs_or8_we_o(wbs_or8_we), + .wbs_or8_sel_o(wbs_or8_sel), + .wbs_or8_dat_i(wbs_or8_dat_i), + .wbs_or8_ack_i(wbs_or8_ack), + .wbs_or8_dat_o(wbs_or8_dat_o), + // wishbone signals to sram 9 + .wbs_or9_stb_o(wbs_or9_stb), + .wbs_or9_cyc_o(wbs_or9_cyc), + .wbs_or9_we_o(wbs_or9_we), + .wbs_or9_sel_o(wbs_or9_sel), + .wbs_or9_dat_i(wbs_or9_dat_i), + .wbs_or9_ack_i(wbs_or9_ack), + .wbs_or9_dat_o(wbs_or9_dat_o) + ); + + wishbone_wrapper #(.BASE_ADDR(32'h3000_0000), .ADDR_WIDTH(8)) SRAM8_WRAPPER( + .wb_clk_i(wb_clk_i), + .wb_rst_i(wb_rst_i), + .wbs_stb_i(wbs_or8_stb), + .wbs_cyc_i(wbs_or8_cyc), + .wbs_we_i(wbs_or8_we), + .wbs_sel_i(wbs_or8_sel), + .wbs_dat_i(wbs_or8_dat_o), .wbs_adr_i(wbs_adr_i), - .wbs_ack_o(wbs_ack_o), - .wbs_dat_o(wbs_dat_o), + .wbs_ack_o(wbs_or8_ack), + .wbs_dat_o(wbs_or8_dat_i), // OpenRAM interface - .ram_clk0(ram_clk0), // (output) clock - .ram_csb0(ram_csb0), // (output) active low chip select - .ram_web0(ram_web0), // (output) active low write control - .ram_wmask0(ram_wmask0), // (output) write (byte) mask - .ram_addr0(ram_addr0), // (output) + .ram_clk0(ram8_clk0), // (output) clock + .ram_csb0(ram8_csb0), // (output) active low chip select + .ram_web0(ram8_web0), // (output) active low write control + .ram_wmask0(ram8_wmask0), // (output) write (byte) mask + .ram_addr0(ram8_addr0), // (output) .ram_din0(wbs_sram8_data), // (input) read from sram and sent through wb - .ram_dout0(ram_din0) // (output) read from wb and sent to sram + .ram_dout0(ram8_din0) // (output) read from wb and sent to sram + ); + + wishbone_wrapper #(.BASE_ADDR(32'h3000_0400), .ADDR_WIDTH(9)) SRAM9_WRAPPER( + .wb_clk_i(wb_clk_i), + .wb_rst_i(wb_rst_i), + .wbs_stb_i(wbs_or9_stb), + .wbs_cyc_i(wbs_or9_cyc), + .wbs_we_i(wbs_or9_we), + .wbs_sel_i(wbs_or9_sel), + .wbs_dat_i(wbs_or9_dat_o), + .wbs_adr_i(wbs_adr_i), + .wbs_ack_o(wbs_or9_ack), + .wbs_dat_o(wbs_or9_dat_i), + // OpenRAM interface + .ram_clk0(ram9_clk0), // (output) clock + .ram_csb0(ram9_csb0), // (output) active low chip select + .ram_web0(ram9_web0), // (output) active low write control + .ram_wmask0(ram9_wmask0), // (output) write (byte) mask + .ram_addr0(ram9_addr0), // (output) + .ram_din0(wbs_sram9_data), // (input) read from sram and sent through wb + .ram_dout0(ram9_din0) // (output) read from wb and sent to sram ); // Splitting register bits into fields always @(*) begin if(wbs_stb_i && wbs_cyc_i) begin - chip_select = 8; - csb0_temp = ram_csb0; - addr0 = ram_addr0; - din0 = ram_din0; - web0 = ram_web0; - wmask0 = ram_wmask0; - // dont cares for now since we are just testing single port for now - addr1 = sram_register[`PORT_SIZE-1:`DATA_SIZE+`WMASK_SIZE+2]; - din1 = sram_register[`DATA_SIZE+`WMASK_SIZE+1:`WMASK_SIZE+2]; - csb1_temp = global_csb | sram_register[`WMASK_SIZE+1]; - web1 = sram_register[`WMASK_SIZE]; - wmask1 = sram_register[`WMASK_SIZE-1:0]; + // select on the basis of strobe signals here + // for example: + // at any given time wbs_or8_stb or wbs_or9_stb will be active + // based on that take their values and provide to the sram control signals + chip_select = 0; + + if(wbs_or8_stb && !wbs_or9_stb) begin + csb0_temp = ram8_csb0; + addr0 = ram8_addr0; + din0 = ram8_din0; + web0 = ram8_web0; + wmask0 = ram8_wmask0; + // dont cares for now since we are just testing single port for now + addr1 = sram_register[`PORT_SIZE-1:`DATA_SIZE+`WMASK_SIZE+2]; + din1 = sram_register[`DATA_SIZE+`WMASK_SIZE+1:`WMASK_SIZE+2]; + csb1_temp = global_csb | sram_register[`WMASK_SIZE+1]; + web1 = sram_register[`WMASK_SIZE]; + wmask1 = sram_register[`WMASK_SIZE-1:0]; + end + else if(!wbs_or8_stb && wbs_or9_stb) begin + csb0_temp = ram9_csb0; + addr0 = ram9_addr0; + din0 = ram9_din0; + web0 = ram9_web0; + wmask0 = ram9_wmask0; + // dont cares for now since we are just testing single port for now + addr1 = sram_register[`PORT_SIZE-1:`DATA_SIZE+`WMASK_SIZE+2]; + din1 = sram_register[`DATA_SIZE+`WMASK_SIZE+1:`WMASK_SIZE+2]; + csb1_temp = global_csb | sram_register[`WMASK_SIZE+1]; + web1 = sram_register[`WMASK_SIZE]; + wmask1 = sram_register[`WMASK_SIZE-1:0]; + end end else begin chip_select = sram_register[`TOTAL_SIZE-1:`TOTAL_SIZE-`SELECT_SIZE]; @@ -187,8 +284,12 @@ // Apply the correct CSB always @(*) begin if(wbs_stb_i && wbs_cyc_i) begin -// ccsb0 = {16'b111111110111111, csb0_temp}; - csb0 = {7'b1111111, csb0_temp, 8'b11111111}; + if(wbs_or8_stb && !wbs_or9_stb) begin + csb0 = {7'b1111111, csb0_temp, 8'b11111111}; + end + else if(!wbs_or8_stb && wbs_or9_stb) begin + csb0 = {6'b111111, csb0_temp, 9'b111111111}; + end csb1 = 16'b1111111111111111; end else begin
diff --git a/verilog/rtl/uprj_netlists.v b/verilog/rtl/uprj_netlists.v index 3330e84..541dde9 100644 --- a/verilog/rtl/uprj_netlists.v +++ b/verilog/rtl/uprj_netlists.v
@@ -26,6 +26,7 @@ `include "user_project_wrapper.v" `include "openram_testchip.v" `include "wishbone_wrapper.v" + `include "wishbone_ram_mux.v" `include "sky130_sram_1kbyte_1rw1r_8x1024_8.v" `include "sky130_sram_1kbyte_1rw1r_32x256_8.v" `include "sky130_sram_2kbyte_1rw1r_32x512_8.v"
diff --git a/verilog/rtl/user_project_wrapper.v b/verilog/rtl/user_project_wrapper.v index 8a6fe42..cc54435 100644 --- a/verilog/rtl/user_project_wrapper.v +++ b/verilog/rtl/user_project_wrapper.v
@@ -159,6 +159,7 @@ .wbs_ack_o(wbs_ack_o), .wbs_dat_o(wbs_dat_o), .wbs_sram8_data(sram8_dout0), + .wbs_sram9_data(sram9_dout0), // Shared control/data to the SRAMs .addr0(addr0), .din0(din0),
diff --git a/verilog/rtl/wishbone_ram_mux.v b/verilog/rtl/wishbone_ram_mux.v new file mode 100644 index 0000000..df15428 --- /dev/null +++ b/verilog/rtl/wishbone_ram_mux.v
@@ -0,0 +1,79 @@ +`default_nettype none + +module wishbone_ram_mux +( +`ifdef USE_POWER_PINS + inout vccd1, // User area 1 1.8V supply + inout vssd1, // User area 1 digital ground +`endif + + // Wishbone UFP (Upward Facing Port) + input wb_clk_i, + input wb_rst_i, + input wbs_ufp_stb_i, + input wbs_ufp_cyc_i, + input wbs_ufp_we_i, + input [3:0] wbs_ufp_sel_i, + input [31:0] wbs_ufp_dat_i, + input [31:0] wbs_ufp_adr_i, + output wbs_ufp_ack_o, + output [31:0] wbs_ufp_dat_o, + + + // Wishbone OR (Downward Facing Port) - SRAM8 + output wbs_or8_stb_o, + output wbs_or8_cyc_o, + output wbs_or8_we_o, + output [3:0] wbs_or8_sel_o, + input [31:0] wbs_or8_dat_i, +// input [31:0] wbs_or_adr_i, // address connected directly from UFP + input wbs_or8_ack_i, + output [31:0] wbs_or8_dat_o, + + + // Wishbone OR (Downward Facing Port) - SRAM9 + output wbs_or9_stb_o, + output wbs_or9_cyc_o, + output wbs_or9_we_o, + output [3:0] wbs_or9_sel_o, + input [31:0] wbs_or9_dat_i, +// input [31:0] wbs_or_adr_i, // address connected directly from UFP + input wbs_or9_ack_i, + output [31:0] wbs_or9_dat_o + +); + +parameter SRAM8_BASE_ADDR = 32'h3000_0000; +parameter SRAM8_MASK = 32'hffff_ff00; + +parameter SRAM9_BASE_ADDR = 32'h3000_0400; +parameter SRAM9_MASK = 32'hffff_fe00; + + +wire sram8_select; +assign sram8_select = ((wbs_ufp_adr_i & SRAM8_MASK) == SRAM8_BASE_ADDR); + +wire sram9_select; +assign sram9_select = (((wbs_ufp_adr_i & SRAM9_MASK) == SRAM9_BASE_ADDR) && !sram8_select); + +// UFP -> SRAM 8 +assign wbs_or8_stb_o = wbs_ufp_stb_i & sram8_select; +assign wbs_or8_cyc_o = wbs_ufp_cyc_i; +assign wbs_or8_we_o = wbs_ufp_we_i & sram8_select; +assign wbs_or8_sel_o = wbs_ufp_sel_i & {4{sram8_select}}; +assign wbs_or8_dat_o = wbs_ufp_dat_i & {32{sram8_select}}; + +// UFP -> SRAM 9 +assign wbs_or9_stb_o = wbs_ufp_stb_i & sram9_select; +assign wbs_or9_cyc_o = wbs_ufp_cyc_i; +assign wbs_or9_we_o = wbs_ufp_we_i & sram9_select; +assign wbs_or9_sel_o = wbs_ufp_sel_i & {4{sram9_select}}; +assign wbs_or9_dat_o = wbs_ufp_dat_i & {32{sram9_select}}; + +// HyperRAM or OpenRAM -> UFP +assign wbs_ufp_ack_o = (wbs_or8_ack_i & sram8_select) | (wbs_or9_ack_i & sram9_select); +assign wbs_ufp_dat_o = (wbs_or8_dat_i & {32{sram8_select}}) | (wbs_or9_dat_i & {32{sram9_select}}); + +endmodule + +`default_nettype wire