From 45cb159d7f3ced59b0ee37ba803d68234445bfb3 Mon Sep 17 00:00:00 2001 From: jsowash Date: Fri, 19 Jul 2019 13:17:55 -0700 Subject: [PATCH] Connected wmask in the spice netlist. --- compiler/characterizer/functional.py | 12 ++++++++ compiler/characterizer/simulation.py | 22 +++++++++++++-- compiler/modules/bank.py | 12 ++++++++ compiler/modules/port_data.py | 34 +++++++++++++++++------ compiler/modules/write_driver_array.py | 23 +++++++++++---- compiler/modules/write_mask_and_array.py | 14 ++++++---- compiler/sram/sram_base.py | 12 ++++---- compiler/tests/22_sram_wmask_func_test.py | 4 ++- 8 files changed, 102 insertions(+), 31 deletions(-) diff --git a/compiler/characterizer/functional.py b/compiler/characterizer/functional.py index d49d307b..87ba0678 100644 --- a/compiler/characterizer/functional.py +++ b/compiler/characterizer/functional.py @@ -290,6 +290,18 @@ class functional(simulation): for port in self.readwrite_ports: self.stim.gen_pwl("WEB{}".format(port), self.cycle_times , self.web_values[port], self.period, self.slew, 0.05) + # Generate wmask bits + for port in self.write_ports: + self.sf.write("\n* Generation of wmask signals\n") + if (self.write_size != self.word_size): + num_wmask = int(self.word_size / self.write_size) + for bit in range(num_wmask): + sig_name = "WMASK{0}_{1} ".format(port, bit) + self.stim.gen_pwl(sig_name, self.cycle_times, self.data_values[port][bit], self.period, + self.slew, 0.05) + # self.stim.gen_pwl(sig_name, self.cycle_times, self.wmask_values[port][bit], self.period, + # self.slew, 0.05) + # Generate CLK signals for port in self.all_ports: self.stim.gen_pulse(sig_name="{0}{1}".format(tech.spice["clk"], port), diff --git a/compiler/characterizer/simulation.py b/compiler/characterizer/simulation.py index 5b34ce01..4dee96df 100644 --- a/compiler/characterizer/simulation.py +++ b/compiler/characterizer/simulation.py @@ -79,6 +79,7 @@ class simulation(): # Three dimensional list to handle each addr and data bits for wach port over the number of checks self.addr_values = [[[] for bit in range(self.addr_size)] for port in self.all_ports] self.data_values = [[[] for bit in range(self.word_size)] for port in self.write_ports] + self.wmask_values = [[[] for bit in range(self.num_wmask)] for port in self.write_ports] # For generating comments in SPICE stimulus self.cycle_comments = [] @@ -130,6 +131,20 @@ class simulation(): else: debug.error("Non-binary address string",1) bit -= 1 + + def add_wmask(self, wmask, port): + """ Add the array of address values """ + debug.check(len(wmask) == self.num_wmask, "Invalid wmask size.") + + bit = self.addr_size - 1 + for c in wmask: + if c == "0": + self.wmask_values[port][bit].append(0) + elif c == "1": + self.wmask_values[port][bit].append(1) + else: + debug.error("Non-binary address string", 1) + bit -= 1 def add_write(self, comment, address, data, port): """ Add the control values for a write cycle. """ @@ -281,13 +296,14 @@ class simulation(): for port in range(total_ports): if (port in read_index) and (port in write_index): pin_names.append("WEB{0}".format(port)) + + for port in range(total_ports): + pin_names.append("{0}{1}".format(tech.spice["clk"], port)) + if (self.write_size != self.word_size): num_wmask = int(self.word_size/self.write_size) for bit in range(num_wmask): pin_names.append("WMASK{0}_{1}".format(port,bit)) - - for port in range(total_ports): - pin_names.append("{0}{1}".format(tech.spice["clk"], port)) for read_output in read_index: for i in range(dbits): diff --git a/compiler/modules/bank.py b/compiler/modules/bank.py index c0f14a93..f62c9f8a 100644 --- a/compiler/modules/bank.py +++ b/compiler/modules/bank.py @@ -30,6 +30,8 @@ class bank(design.design): self.sram_config = sram_config sram_config.set_local_config(self) + if (self.word_size != self.write_size): + self.num_wmask = int(self.word_size/self.write_size) if name == "": name = "bank_{0}_{1}".format(self.word_size, self.num_words) @@ -98,6 +100,11 @@ class bank(design.design): self.add_pin("p_en_bar{0}".format(port), "INPUT") for port in self.write_ports: self.add_pin("w_en{0}".format(port), "INPUT") + if (self.word_size != self.write_size): + for bit in range(self.num_wmask): + self.add_pin("bank_wmask{0}_{1}".format(port,bit),"INPUT") + # for bit in range(self.num_wmask): + # self.add_pin("wdriver_sel{0}_{1}".format(port, bit),"INOUT") for port in self.all_ports: self.add_pin("wl_en{0}".format(port), "INPUT") self.add_pin("vdd","POWER") @@ -406,6 +413,11 @@ class bank(design.design): temp.append("p_en_bar{0}".format(port)) if port in self.write_ports: temp.append("w_en{0}".format(port)) + if (self.word_size != self.write_size): + for bit in range(self.num_wmask): + temp.append("bank_wmask{0}_{1}".format(port, bit)) + # for bit in range(self.num_wmask): + # temp.append("wdriver_sel_{0}_{1}".format(port, bit)) temp.extend(["vdd","gnd"]) self.connect_inst(temp) diff --git a/compiler/modules/port_data.py b/compiler/modules/port_data.py index 7f77652e..413922dd 100644 --- a/compiler/modules/port_data.py +++ b/compiler/modules/port_data.py @@ -21,7 +21,8 @@ class port_data(design.design): sram_config.set_local_config(self) self.port = port - self.num_wmask = int(self.word_size/self.write_size) + if (self.word_size != self.write_size): + self.num_wmask = int(self.word_size/self.write_size) if name == "": name = "port_data_{0}".format(self.port) @@ -96,6 +97,11 @@ class port_data(design.design): self.add_pin("p_en_bar", "INPUT") if self.port in self.write_ports: self.add_pin("w_en", "INPUT") + if (self.word_size != self.write_size): + for bit in range(self.num_wmask): + self.add_pin("bank_wmask_{}".format(bit),"INPUT") + # for bit in range(self.num_wmask): + # self.add_pin("wdriver_sel_{}".format(bit), "INOUT") self.add_pin("vdd","POWER") self.add_pin("gnd","GROUND") @@ -168,7 +174,8 @@ class port_data(design.design): if self.port in self.write_ports: self.write_driver_array = factory.create(module_type="write_driver_array", columns=self.num_cols, - word_size=self.word_size) + word_size=self.word_size, + write_size=self.write_size) self.add_mod(self.write_driver_array) if (self.word_size != self.write_size): self.write_mask_and_array = factory.create(module_type="write_mask_and_array", @@ -282,9 +289,8 @@ class port_data(design.design): mod=self.write_driver_array) temp = [] - m - for bit in range(self.word_size): - temp.append("din_{}".format(bit)) + for bit in range(self.word_size): + temp.append("din_{}".format(bit)) for bit in range(self.word_size): if (self.words_per_row == 1): @@ -293,7 +299,16 @@ class port_data(design.design): else: temp.append(self.bl_names[self.port]+"_out_{0}".format(bit)) temp.append(self.br_names[self.port]+"_out_{0}".format(bit)) - temp.extend(["w_en", "vdd", "gnd"]) + + if (self.write_size != self.word_size): + i = 0 + for bit in range(0,self.word_size,self.write_size): + for x in range(self.write_size): + temp.append("wdriver_sel_{}".format(i)) + i+=1 + else: + temp.append("w_en") + temp.extend(["vdd", "gnd"]) self.connect_inst(temp) @@ -304,8 +319,11 @@ class port_data(design.design): temp = [] for bit in range(self.num_wmask): - temp.append("write_mask_{}".format(bit)) - temp.extend(["w_en", "vdd", "gnd"]) + temp.append("bank_wmask_{}".format(bit)) + temp.extend(["w_en"]) + for bit in range(self.num_wmask): + temp.append("wdriver_sel_{}".format(bit)) + temp.extend(["vdd", "gnd"]) self.connect_inst(temp) diff --git a/compiler/modules/write_driver_array.py b/compiler/modules/write_driver_array.py index 599c4cd0..0a9f0f6b 100644 --- a/compiler/modules/write_driver_array.py +++ b/compiler/modules/write_driver_array.py @@ -19,7 +19,7 @@ class write_driver_array(design.design): Dynamically generated write driver array of all bitlines. """ - def __init__(self, name, columns, word_size): + def __init__(self, name, columns, word_size,write_size): design.design.__init__(self, name) debug.info(1, "Creating {0}".format(self.name)) self.add_comment("columns: {0}".format(columns)) @@ -27,6 +27,7 @@ class write_driver_array(design.design): self.columns = columns self.word_size = word_size + self.write_size = write_size self.words_per_row = int(columns / word_size) self.create_netlist() @@ -59,7 +60,11 @@ class write_driver_array(design.design): for i in range(self.word_size): self.add_pin("bl_{0}".format(i)) self.add_pin("br_{0}".format(i)) - self.add_pin("en") + if self.word_size != self.write_size: + for i in range(self.word_size): + self.add_pin("en_{}".format(i)) + else: + self.add_pin("en") self.add_pin("vdd") self.add_pin("gnd") @@ -79,10 +84,16 @@ class write_driver_array(design.design): self.driver_insts[index]=self.add_inst(name=name, mod=self.driver) - self.connect_inst(["data_{0}".format(index), - "bl_{0}".format(index), - "br_{0}".format(index), - "en", "vdd", "gnd"]) + if self.word_size != self.write_size: + self.connect_inst(["data_{0}".format(index), + "bl_{0}".format(index), + "br_{0}".format(index), + "en_{0}".format(index), "vdd", "gnd"]) + else: + self.connect_inst(["data_{0}".format(index), + "bl_{0}".format(index), + "br_{0}".format(index), + "en", "vdd", "gnd"]) def place_write_array(self): diff --git a/compiler/modules/write_mask_and_array.py b/compiler/modules/write_mask_and_array.py index f17f458c..04e5e21b 100644 --- a/compiler/modules/write_mask_and_array.py +++ b/compiler/modules/write_mask_and_array.py @@ -60,10 +60,12 @@ class write_mask_and_array(design.design): def add_pins(self): for bit in range(self.num_wmask): - self.add_pin("wdriver_sel_{}".format(bit)) - self.add_pin("en") - self.add_pin("vdd") - self.add_pin("gnd") + self.add_pin("wmask_in_{}".format(bit),"INPUT") + self.add_pin("en", "INPUT") + for bit in range(self.num_wmask): + self.add_pin("wmask_out_{}".format(bit),"OUTPUT") + self.add_pin("vdd","POWER") + self.add_pin("gnd","GROUND") def add_modules(self): self.wmask = factory.create(module_type="dff_buf") @@ -94,9 +96,9 @@ class write_mask_and_array(design.design): name = "and2_{}".format(bit) self.and2_insts[bit] = self.add_inst(name=name, mod=self.and2) - self.connect_inst(["bank_wmask_{}".format(bit), + self.connect_inst(["wmask_in_{}".format(bit), "en", - "wdriver_sel_{}".format(bit), + "wmask_out_{}".format(bit), "vdd", "gnd"]) diff --git a/compiler/sram/sram_base.py b/compiler/sram/sram_base.py index 6295f587..66dcdb0f 100644 --- a/compiler/sram/sram_base.py +++ b/compiler/sram/sram_base.py @@ -357,6 +357,11 @@ class sram_base(design, verilog, lef): temp.append("p_en_bar{0}".format(port)) for port in self.write_ports: temp.append("w_en{0}".format(port)) + if (self.word_size != self.write_size): + for bit in range(self.num_masks): + temp.append("bank_wmask{}[{}]".format(port, bit)) + # for bit in range(self.num_masks): + # temp.append("wdriver_sel{}[{}]".format(port, bit)) for port in self.all_ports: temp.append("wl_en{0}".format(port)) temp.extend(["vdd", "gnd"]) @@ -499,8 +504,6 @@ class sram_base(design, verilog, lef): if port in self.readwrite_ports: temp.append("web{}".format(port)) temp.append("clk{}".format(port)) - # if port in self.write_ports: - # temp.append("wmask{}".format(port)) # for port in self.all_ports: # self.add_pin("csb{}".format(port), "INPUT") @@ -508,11 +511,6 @@ class sram_base(design, verilog, lef): # self.add_pin("web{}".format(port), "INPUT") # for port in self.all_ports: # self.add_pin("clk{}".format(port), "INPUT") - # # add the optional write mask pins - # if self.word_size != self.write_size: - # for port in self.write_ports: - # print("write_ports", port) - # self.add_pin("wmask{0}".format(port), "INPUT") # Outputs if port in self.read_ports: diff --git a/compiler/tests/22_sram_wmask_func_test.py b/compiler/tests/22_sram_wmask_func_test.py index db239ccf..f76fdeef 100755 --- a/compiler/tests/22_sram_wmask_func_test.py +++ b/compiler/tests/22_sram_wmask_func_test.py @@ -15,7 +15,7 @@ from globals import OPTS from sram_factory import factory import debug -@unittest.skip("SKIPPING sram_wmask_func_test") +#@unittest.skip("SKIPPING sram_wmask_func_test") class sram_wmask_func_test(openram_test): def runTest(self): @@ -34,6 +34,8 @@ class sram_wmask_func_test(openram_test): num_words=16, write_size=4, num_banks=1) + c.words_per_row=1 + c.recompute_sizes_once() debug.info(1, "Functional test for sram with {} bit words, {} words, {} words per row, {} bit writes, {} banks".format(c.word_size, c.num_words, c.words_per_row,