From 5ceefc8da9b57c9688a2a047afa976cbc3f6f17a Mon Sep 17 00:00:00 2001 From: Fischer Moseley <42497969+fischermoseley@users.noreply.github.com> Date: Wed, 12 Apr 2023 18:15:50 -0400 Subject: [PATCH] this bram core has taken my soul --- src/manta/__init__.py | 8 ---- src/manta/block_memory_tmpl.v | 48 ++++++------------- .../block_memory_tb/block_memory.v | 48 ++++++------------- .../block_memory_tb/block_memory_tb.sv | 22 ++++++--- 4 files changed, 45 insertions(+), 81 deletions(-) diff --git a/src/manta/__init__.py b/src/manta/__init__.py index 2ee5e3c..284c7e9 100644 --- a/src/manta/__init__.py +++ b/src/manta/__init__.py @@ -673,8 +673,6 @@ class BlockMemoryCore: from math import ceil, floor, log2 self.addr_width = ceil(log2(self.depth)) self.n_brams = ceil(self.width / 16) - self.n_full_width_brams = floor(self.width / 16) - self.partial_bram_width = self.width - (16 * self.n_full_width_brams) self.max_addr = self.base_addr + (self.depth * self.n_brams) def hdl_inst(self): @@ -687,12 +685,6 @@ class BlockMemoryCore: def hdl_def(self): bram_core = VerilogManipulator("block_memory_tmpl.v") bram_core.sub(self.name, "/* NAME */") - bram_core.sub(self.width, "/* WIDTH */") - bram_core.sub(self.depth, "/* DEPTH */") - bram_core.sub(self.max_addr, "/* MAX_ADDR */") - bram_core.sub(self.n_brams, "/* N_BRAMS */") - bram_core.sub(self.n_full_width_brams, "/* N_FULL_WIDTH_BRAMS */") - bram_core.sub(self.partial_bram_width, "/* PARTIAL_BRAM_WIDTH */") return bram_core.get_hdl() diff --git a/src/manta/block_memory_tmpl.v b/src/manta/block_memory_tmpl.v index c4d52a8..7f4cd0f 100644 --- a/src/manta/block_memory_tmpl.v +++ b/src/manta/block_memory_tmpl.v @@ -26,25 +26,28 @@ module /* NAME */ ( input wire user_we); parameter BASE_ADDR = 0; - localparam BRAM_WIDTH = /* WIDTH */; - localparam BRAM_DEPTH = /* DEPTH */; + parameter BRAM_WIDTH = 0; + parameter BRAM_DEPTH = 0; localparam ADDR_WIDTH = $clog2(BRAM_DEPTH); - localparam MAX_ADDR = /* MAX_ADDR */; - localparam N_BRAMS = /* N_BRAMS */; - localparam N_FULL_WIDTH_BRAMS = /* N_FULL_WIDTH_BRAMS */; - localparam PARTIAL_BRAM_WIDTH = /* PARTIAL_BRAM_WIDTH */; + localparam N_BRAMS = int'($ceil(real'(BRAM_WIDTH) / 16.0)); + localparam MAX_ADDR = BASE_ADDR + (BRAM_DEPTH * N_BRAMS); - // Bus-Controlled side of BRAMs + // Port A of BRAMs reg [N_BRAMS-1:0][ADDR_WIDTH-1:0] addra = 0; reg [N_BRAMS-1:0][15:0] dina = 0; reg [N_BRAMS-1:0][15:0] douta; reg [N_BRAMS-1:0] wea = 0; - // User-Controlled Side of BRAMs - reg [N_BRAMS-1:0][15:0] dinb = 0; + // Port B of BRAMs + reg [N_BRAMS-1:0][15:0] dinb; reg [N_BRAMS-1:0][15:0] doutb; - assign dout = {doutb[1], doutb[0]}; + assign dinb = user_din; + + // kind of a hack to part select from a 2d array that's been flattened to 1d + reg [(N_BRAMS*16)-1:0] doutb_flattened; + assign doutb_flattened = doutb; + assign user_dout = doutb_flattened[BRAM_WIDTH-1:0]; // Pipelining reg [3:0][15:0] addr_pipe = 0; @@ -88,10 +91,10 @@ module /* NAME */ ( end end - // generate the full-width BRAMs + // generate the BRAMs genvar i; generate - for(i=0; i 0) begin - dual_port_bram #( - .RAM_WIDTH(PARTIAL_BRAM_WIDTH), - .RAM_DEPTH(BRAM_DEPTH) - ) bram_partial_width ( - - // port A is controlled by the bus - .clka(clk), - .addra(addra[N_BRAMS-1]), - .dina(dina[N_BRAMS-1][PARTIAL_BRAM_WIDTH-1:0]), - .douta(douta[N_BRAMS-1]), - .wea(wea[N_BRAMS-1]), - - // port B is exposed to the user - .clkb(user_clk), - .addrb(user_addr), - .dinb(dinb[N_BRAMS-1][PARTIAL_BRAM_WIDTH-1:0]), - .doutb(doutb[N_BRAMS-1]), - .web(user_we)); - end endgenerate endmodule `default_nettype wire \ No newline at end of file diff --git a/test/functional_sim/block_memory_tb/block_memory.v b/test/functional_sim/block_memory_tb/block_memory.v index 93ee5fa..0d607ca 100644 --- a/test/functional_sim/block_memory_tb/block_memory.v +++ b/test/functional_sim/block_memory_tb/block_memory.v @@ -23,25 +23,28 @@ module my_bram ( input wire user_we); parameter BASE_ADDR = 0; - localparam BRAM_WIDTH = 18; - localparam BRAM_DEPTH = 256; + parameter BRAM_WIDTH = 0; + parameter BRAM_DEPTH = 0; localparam ADDR_WIDTH = $clog2(BRAM_DEPTH); - localparam MAX_ADDR = 512; - localparam N_BRAMS = 2; - localparam N_FULL_WIDTH_BRAMS = 1; - localparam PARTIAL_BRAM_WIDTH = 2; + localparam MAX_ADDR = BASE_ADDR + (BRAM_DEPTH * N_BRAMS); + localparam N_BRAMS = int'($ceil(real'(BRAM_WIDTH) / 16.0)); - // Bus-Controlled side of BRAMs + // Port A of BRAMs reg [N_BRAMS-1:0][ADDR_WIDTH-1:0] addra = 0; reg [N_BRAMS-1:0][15:0] dina = 0; reg [N_BRAMS-1:0][15:0] douta; reg [N_BRAMS-1:0] wea = 0; - // User-Controlled Side of BRAMs - reg [N_BRAMS-1:0][15:0] dinb = 0; + // Port B of BRAMs + reg [N_BRAMS-1:0][15:0] dinb; reg [N_BRAMS-1:0][15:0] doutb; - assign dout = {doutb[1], doutb[0]}; + assign dinb = user_din; + + // kind of a hack to part select from a 2d array that's been flattened to 1d + reg [(N_BRAMS*16)-1:0] doutb_flattened; + assign doutb_flattened = doutb; + assign user_dout = doutb_flattened[BRAM_WIDTH-1:0]; // Pipelining reg [3:0][15:0] addr_pipe = 0; @@ -85,10 +88,10 @@ module my_bram ( end end - // generate the full-width BRAMs + // generate the BRAMs genvar i; generate - for(i=0; i 0) begin - dual_port_bram #( - .RAM_WIDTH(PARTIAL_BRAM_WIDTH), - .RAM_DEPTH(BRAM_DEPTH) - ) bram_partial_width ( - - // port A is controlled by the bus - .clka(clk), - .addra(addra[N_BRAMS-1]), - .dina(dina[N_BRAMS-1][PARTIAL_BRAM_WIDTH-1:0]), - .douta(douta[N_BRAMS-1]), - .wea(wea[N_BRAMS-1]), - - // port B is exposed to the user - .clkb(user_clk), - .addrb(user_addr), - .dinb(dinb[N_BRAMS-1][PARTIAL_BRAM_WIDTH-1:0]), - .doutb(doutb[N_BRAMS-1]), - .web(user_we)); - end endgenerate endmodule \ No newline at end of file diff --git a/test/functional_sim/block_memory_tb/block_memory_tb.sv b/test/functional_sim/block_memory_tb/block_memory_tb.sv index 2ec8e8b..ff08f17 100644 --- a/test/functional_sim/block_memory_tb/block_memory_tb.sv +++ b/test/functional_sim/block_memory_tb/block_memory_tb.sv @@ -74,12 +74,15 @@ module block_memory_tb; logic bc_tb_valid; // bram itself - logic [7:0] bram_user_addr = 0; - logic [17:0] bram_user_din = 0; - logic [17:0] bram_user_dout; + localparam BRAM_DEPTH = 256; + localparam BRAM_WIDTH = 33; + localparam ADDR_WIDTH = $clog2(BRAM_WIDTH); + logic [ADDR_WIDTH-1:0] bram_user_addr = 0; + logic [BRAM_WIDTH-1:0] bram_user_din = 0; + logic [BRAM_WIDTH-1:0] bram_user_dout; logic bram_user_we = 0; - my_bram my_bram_inst( + my_bram #(.BRAM_DEPTH(BRAM_DEPTH), .BRAM_WIDTH(BRAM_WIDTH)) my_bram_inst( .clk(clk), .addr_i(tb_bc_addr), @@ -109,6 +112,8 @@ module block_memory_tb; $dumpfile("block_memory_tb.vcd"); $dumpvars(0, block_memory_tb); + $display("i am going to vomit %d", my_bram_inst.N_BRAMS); + // setup and reset clk = 0; test_num = 0; @@ -132,11 +137,14 @@ module block_memory_tb; /* ==== Test 1 Begin ==== */ $display("\n=== test 1: read/write from BRAM, verify ==="); test_num = 1; - //read_reg(0, read_value, "lmao"); - write_and_verify(0, 4, "larry_op"); - write_and_verify(1, 3, "larry_op"); + write_and_verify(3, 'h1234, ""); + write_and_verify(4, 'h5678, ""); + write_and_verify(5, 'h0001, ""); // now query what's on the the user side at address 0 + bram_user_addr = 1; + #(3*`CP); + $display("Found 0x%h on the other side", bram_user_dout); #(10*`CP);