From 81d20ec2aab55b5a4ae06fccb873a6a08c7c795c Mon Sep 17 00:00:00 2001 From: mrg Date: Fri, 18 Jun 2021 07:23:41 -0700 Subject: [PATCH] Add spare cols to behavioral Verilog model --- compiler/base/verilog.py | 55 +++++++++++++++++++++++++--------------- 1 file changed, 35 insertions(+), 20 deletions(-) diff --git a/compiler/base/verilog.py b/compiler/base/verilog.py index c2f9833a..6358103b 100644 --- a/compiler/base/verilog.py +++ b/compiler/base/verilog.py @@ -37,13 +37,13 @@ class verilog: self.gnd_name = spice["ground"] except KeyError: self.gnd_name = "gnd" - + self.vf.write("module {0}(\n".format(self.name)) self.vf.write("`ifdef USE_POWER_PINS\n") self.vf.write(" {},\n".format(self.vdd_name)) self.vf.write(" {},\n".format(self.gnd_name)) self.vf.write("`endif\n") - + for port in self.all_ports: if port in self.readwrite_ports: self.vf.write("// Port {0}: RW\n".format(port)) @@ -55,11 +55,15 @@ class verilog: self.vf.write(" clk{0},csb{0},web{0},".format(port)) if self.write_size: self.vf.write("wmask{},".format(port)) + if self.num_spare_cols > 0: + self.vf.write(" spare_wen{0},".format(port)) self.vf.write("addr{0},din{0},dout{0}".format(port)) elif port in self.write_ports: self.vf.write(" clk{0},csb{0},".format(port)) if self.write_size: self.vf.write("wmask{},".format(port)) + if self.num_spare_cols > 0: + self.vf.write(" spare_wen{0},".format(port)) self.vf.write("addr{0},din{0}".format(port)) elif port in self.read_ports: self.vf.write(" clk{0},csb{0},addr{0},dout{0}".format(port)) @@ -71,7 +75,7 @@ class verilog: if self.write_size: self.num_wmasks = int(math.ceil(self.word_size / self.write_size)) self.vf.write(" parameter NUM_WMASKS = {0} ;\n".format(self.num_wmasks)) - self.vf.write(" parameter DATA_WIDTH = {0} ;\n".format(self.word_size)) + self.vf.write(" parameter DATA_WIDTH = {0} ;\n".format(self.word_size + self.num_spare_cols)) 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") @@ -84,7 +88,7 @@ class verilog: self.vf.write(" inout {};\n".format(self.vdd_name)) self.vf.write(" inout {};\n".format(self.gnd_name)) self.vf.write("`endif\n") - + for port in self.all_ports: self.add_inputs_outputs(port) @@ -123,6 +127,10 @@ class verilog: if port in self.write_ports: if self.write_size: self.vf.write(" reg [NUM_WMASKS-1:0] wmask{0}_reg;\n".format(port)) + if self.num_spare_cols > 1: + self.vf.write(" reg [{1}:0] spare_wen{0}_reg;".format(port, self.num_spare_cols - 1)) + elif self.num_spare_cols == 1: + self.vf.write(" reg spare_wen{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)) @@ -143,7 +151,9 @@ class verilog: if port in self.write_ports: if self.write_size: self.vf.write(" wmask{0}_reg = wmask{0};\n".format(port)) - self.vf.write(" addr{0}_reg = addr{0};\n".format(port)) + if self.num_spare_cols: + self.vf.write(" spare_wen{0}_reg = spare_wen{0};\n".format(port)) + self.vf.write(" addr{0}_reg = addr{0};\n".format(port)) if port in self.read_ports: self.add_write_read_checks(port) @@ -182,6 +192,11 @@ class verilog: self.vf.write(" input web{0}; // active low write control\n".format(port)) if self.write_size: self.vf.write(" input [NUM_WMASKS-1:0] wmask{0}; // write mask\n".format(port)) + if self.num_spare_cols > 1: + self.vf.write(" input [{1}:0] spare_wen{0}; // write mask\n".format(port, self.num_spare_cols-1)) + else: + self.vf.write(" input spare_wen{0}; // write mask\n".format(port)) + self.vf.write(" input [ADDR_WIDTH-1:0] addr{0};\n".format(port)) if port in self.write_ports: self.vf.write(" input [DATA_WIDTH-1:0] din{0};\n".format(port)) @@ -199,29 +214,29 @@ 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: - if self.write_size: - self.vf.write(" if ( !csb{0}_reg && !web{0}_reg ) begin\n".format(port)) - else: - 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: - if self.write_size: - self.vf.write(" if (!csb{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.write_size: - remainder_bits = self.word_size % self.write_size for mask in range(0, self.num_wmasks): lower = mask * self.write_size - if (remainder_bits and mask == self.num_wmasks - 1): - upper = lower + remainder_bits - 1 - else: - upper = lower + self.write_size - 1 + upper = lower + self.write_size - 1 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)) - self.vf.write(" end\n") else: - self.vf.write(" mem[addr{0}_reg] = din{0}_reg;\n".format(port)) + upper = self.word_size - self.num_spare_cols - 1 + self.vf.write(" mem[addr{0}_reg][{1}:0] = din{0}_reg[{1}:0];\n".format(port, upper)) + + if self.num_spare_cols == 1: + self.vf.write(" if (spare_wen{0}_reg)\n".format(port)) + self.vf.write(" mem[addr{0}_reg][{1}] = din{0}_reg[{1}];\n".format(port, self.word_size + num)) + else: + for num in range(self.num_spare_cols): + self.vf.write(" if (spare_wen{0}_reg[{1}])\n".format(port, num)) + self.vf.write(" mem[addr{0}_reg][{1}] = din{0}_reg[{1}];\n".format(port, self.word_size + num)) + + self.vf.write(" end\n") self.vf.write(" end\n") def add_read_block(self, port):