From ad9193ad5a99c4645f41a27614a93df0aba61099 Mon Sep 17 00:00:00 2001 From: jsowash Date: Fri, 5 Jul 2019 15:08:59 -0700 Subject: [PATCH] Verified 1rw mask writing and changed verilog.py accordingly. --- compiler/base/verilog.py | 31 +++++--- compiler/tests/sram_1rw_wmask_tb.v | 110 +++++++++++++++++++++++++++++ 2 files changed, 132 insertions(+), 9 deletions(-) create mode 100644 compiler/tests/sram_1rw_wmask_tb.v diff --git a/compiler/base/verilog.py b/compiler/base/verilog.py index 435b6912..f1e5cd13 100644 --- a/compiler/base/verilog.py +++ b/compiler/base/verilog.py @@ -53,12 +53,12 @@ class verilog: if port != self.all_ports[-1]: self.vf.write(",\n") self.vf.write("\n );\n\n") - - self.vf.write(" parameter DATA_WIDTH = {0} ;\n".format(self.word_size)) - self.vf.write(" parameter ADDR_WIDTH = {0} ;\n".format(self.addr_size)) + if self.wmask_enabled: self.num_wmask = int(self.word_size/self.write_size) self.vf.write(" parameter NUM_WMASK = {0} ;\n".format(self.num_wmask)) + self.vf.write(" parameter DATA_WIDTH = {0} ;\n".format(self.word_size)) + self.vf.write(" parameter ADDR_WIDTH = {0} ;\n".format(self.addr_size)) self.vf.write(" parameter RAM_DEPTH = 1 << ADDR_WIDTH;\n") self.vf.write(" // FIXME: This delay is arbitrary.\n") self.vf.write(" parameter DELAY = 3 ;\n") @@ -100,6 +100,9 @@ class verilog: self.vf.write(" reg csb{0}_reg;\n".format(port)) if port in self.readwrite_ports: self.vf.write(" reg web{0}_reg;\n".format(port)) + if port in self.write_ports: + if self.wmask_enabled: + self.vf.write(" reg [NUM_WMASK-1:0] wmask{0}_reg;\n".format(port)) self.vf.write(" reg [ADDR_WIDTH-1:0] ADDR{0}_reg;\n".format(port)) if port in self.write_ports: self.vf.write(" reg [DATA_WIDTH-1:0] DIN{0}_reg;\n".format(port)) @@ -117,6 +120,9 @@ class verilog: self.vf.write(" csb{0}_reg = csb{0};\n".format(port)) if port in self.readwrite_ports: self.vf.write(" web{0}_reg = web{0};\n".format(port)) + if port in self.write_ports: + if self.wmask_enabled: + self.vf.write(" wmask{0}_reg = wmask{0};\n".format(port)) self.vf.write(" ADDR{0}_reg = ADDR{0};\n".format(port)) if port in self.write_ports: self.vf.write(" DIN{0}_reg = DIN{0};\n".format(port)) @@ -128,13 +134,19 @@ class verilog: elif port in self.read_ports: self.vf.write(" if ( !csb{0}_reg ) \n".format(port)) self.vf.write(" $display($time,\" Reading %m ADDR{0}=%b DOUT{0}=%b\",ADDR{0}_reg,mem[ADDR{0}_reg]);\n".format(port)) - if port in self.readwrite_ports: self.vf.write(" if ( !csb{0}_reg && !web{0}_reg )\n".format(port)) - self.vf.write(" $display($time,\" Writing %m ADDR{0}=%b DIN{0}=%b\",ADDR{0}_reg,DIN{0}_reg);\n".format(port)) + if self.wmask_enabled: + self.vf.write(" $display($time,\" Writing %m ADDR{0}=%b DIN{0}=%b wmask{0}=%b\",ADDR{0}_reg,DIN{0}_reg,wmask{0}_reg);\n".format(port)) + else: + self.vf.write(" $display($time,\" Writing %m ADDR{0}=%b DIN{0}=%b\",ADDR{0}_reg,DIN{0}_reg);\n".format(port)) elif port in self.write_ports: self.vf.write(" if ( !csb{0}_reg )\n".format(port)) - self.vf.write(" $display($time,\" Writing %m ADDR{0}=%b DIN{0}=%b\",ADDR{0}_reg,DIN{0}_reg);\n".format(port)) + if self.wmask_enabled: + self.vf.write(" $display($time,\" Writing %m ADDR{0}=%b DIN{0}=%b wmask{0}=%b\",ADDR{0}_reg,DIN{0}_reg,wmask{0}_reg);\n".format(port)) + else: + self.vf.write(" $display($time,\" Writing %m ADDR{0}=%b DIN{0}=%b\",ADDR{0}_reg,DIN{0}_reg);\n".format(port)) + self.vf.write(" end\n\n") @@ -165,18 +177,19 @@ class verilog: self.vf.write(" always @ (negedge clk{0})\n".format(port)) self.vf.write(" begin : MEM_WRITE{0}\n".format(port)) if port in self.readwrite_ports: - self.vf.write(" if ( !csb{0}_reg && !web{0}_reg )\n".format(port)) + self.vf.write(" if ( !csb{0}_reg && !web{0}_reg ) begin\n".format(port)) else: - self.vf.write(" if (!csb{0}_reg)\n".format(port)) + self.vf.write(" if (!csb{0}_reg) begin\n".format(port)) if self.wmask_enabled: for mask in range(0,self.num_wmask): lower = mask * self.write_size upper = lower + self.write_size-1 - self.vf.write(" if(wmask[{}])\n".format(mask)) + self.vf.write(" if (wmask{0}_reg[{1}])\n".format(port,mask)) self.vf.write(" mem[ADDR{0}_reg][{1}:{2}] = DIN{0}_reg[{1}:{2}];\n".format(port,upper,lower)) else: self.vf.write(" mem[ADDR{0}_reg] = DIN_reg{0};\n".format(port)) + self.vf.write(" end\n") self.vf.write(" end\n") def add_read_block(self, port): diff --git a/compiler/tests/sram_1rw_wmask_tb.v b/compiler/tests/sram_1rw_wmask_tb.v new file mode 100644 index 00000000..54aada6e --- /dev/null +++ b/compiler/tests/sram_1rw_wmask_tb.v @@ -0,0 +1,110 @@ +`define assert(signal, value) \ +if (!(signal === value)) begin \ + $display("ASSERTION FAILED in %m: signal != value"); \ + $finish;\ +end + +module sram_1rw_wmask_tb; + reg clk; + + reg [3:0] addr0; + reg [1:0] din0; + reg csb0; + reg web0; + reg [1:0] wmask0; + wire [1:0] dout0; + + sram_2b_16_1rw_freepdk45 U0 (.DIN0(din0), + .DOUT0(dout0), + .ADDR0(addr0), + .csb0(csb0), + .web0(web0), + .wmask0(wmask0), + .clk0(clk) + ); + + + initial + begin + //$monitor("%g addr0=%b din0=%b dout0=%b", + // $time, addr0, din0, dout0); + + + clk = 1; + csb0 = 1; + web0 = 1; + wmask0 = 2'b01; + addr0 = 0; + din0 = 0; + + // write + #10 din0=2'b10; + addr0=4'h1; + web0 = 0; + csb0 = 0; + wmask0 = 2'b10; + + // read + #10 din0=2'b11; + addr0=4'h1; + web0 = 1; + csb0 = 0; + + #10 `assert(dout0, 2'b1x) + + // write another + #10 din0=2'b01; + addr0=4'hC; + web0 = 0; + csb0 = 0; + wmask0 = 2'b01; + + // read undefined + #10 din0=2'b11; + addr0=4'h0; + web0 = 1; + csb0 = 0; + wmask0 = 2'b01; + + #10 `assert(dout0, 2'bxx) + + // read defined + din0=2'b11; + addr0=4'hC; + web0 = 1; + csb0 = 0; + wmask0 = 2'b01; + + #10 `assert(dout0, 2'bx1) + + // write another + din0=2'b01; + addr0=4'h1; + web0 = 0; + csb0 = 0; + + // read defined + #10 din0=2'b11; + addr0=4'h1; + web0 = 1; + csb0 = 0; + + + #10 `assert(dout0, 2'b11) + + // read undefined + din0=2'b11; + addr0=4'h0; + web0 = 1; + csb0 = 0; + + #10 `assert(dout0, 2'bxx) + + #10 $finish; + + end + + always + #5 clk = !clk; + +endmodule \ No newline at end of file