From 53cb4e7f5eb8a7874b8c9c26c683675a6366b09f Mon Sep 17 00:00:00 2001 From: Hunter Nichols Date: Mon, 22 Oct 2018 19:04:42 -0700 Subject: [PATCH] Fixed lib files to be syntactically correct with multiport. Fixed issue in geometry.py that prevented netlist_only option from working. --- compiler/base/geometry.py | 5 +- .../{modules => bitcells}/bitcell_1rw_1r.py | 0 compiler/characterizer/lib.py | 46 +++++++++---------- compiler/example_config_freepdk45.py | 1 - compiler/example_config_scn4m_subm.py | 9 +++- compiler/tests/04_bitcell_1rw_1r_test.py | 2 +- 6 files changed, 33 insertions(+), 30 deletions(-) rename compiler/{modules => bitcells}/bitcell_1rw_1r.py (100%) diff --git a/compiler/base/geometry.py b/compiler/base/geometry.py index 8f0edb29..1de435f1 100644 --- a/compiler/base/geometry.py +++ b/compiler/base/geometry.py @@ -143,8 +143,9 @@ class instance(geometry): self.rotate = rotate self.offset = vector(offset).snap_to_grid() self.mirror = mirror - self.width = round_to_grid(mod.width) - self.height = round_to_grid(mod.height) + if not OPTS.netlist_only: + self.width = round_to_grid(mod.width) + self.height = round_to_grid(mod.height) self.compute_boundary(offset,mirror,rotate) debug.info(4, "creating instance: " + self.name) diff --git a/compiler/modules/bitcell_1rw_1r.py b/compiler/bitcells/bitcell_1rw_1r.py similarity index 100% rename from compiler/modules/bitcell_1rw_1r.py rename to compiler/bitcells/bitcell_1rw_1r.py diff --git a/compiler/characterizer/lib.py b/compiler/characterizer/lib.py index 436ee301..741515e3 100644 --- a/compiler/characterizer/lib.py +++ b/compiler/characterizer/lib.py @@ -108,21 +108,21 @@ class lib: self.write_header() - #Loop over all readwrite ports. This is debugging. Will change later. + #Loop over all ports. for port in range(self.total_port_num): #set the read and write port as inputs. self.write_data_bus(port) self.write_addr_bus(port) self.write_control_pins(port) #need to split this into sram and port control signals - - self.write_clk_timing_power() + self.write_clk_timing_power(port) self.write_footer() def write_footer(self): """ Write the footer """ - self.lib.write("}\n") + self.lib.write("}\n") #Closing brace for the cell + self.lib.write("}\n") #Closing brace for the library def write_header(self): """ Write the header information """ @@ -151,7 +151,7 @@ class lib: self.lib.write(" dont_touch : true;\n") self.lib.write(" area : {};\n\n".format(self.sram.width * self.sram.height)) - #Build string of all control signals. This is subject to change once control signals finalized. + #Build string of all control signals. control_str = 'CSb0' #assume at least 1 port for i in range(1, self.total_port_num): control_str += ' & CSb{0}'.format(i) @@ -296,12 +296,12 @@ class lib: self.lib.write(" }\n\n") - def write_FF_setuphold(self): + def write_FF_setuphold(self, port): """ Adds Setup and Hold timing results""" self.lib.write(" timing(){ \n") self.lib.write(" timing_type : setup_rising; \n") - self.lib.write(" related_pin : \"clk\"; \n") + self.lib.write(" related_pin : \"clk{0}\"; \n".format(port)) self.lib.write(" rise_constraint(CONSTRAINT_TABLE) {\n") rounded_values = list(map(round_time,self.times["setup_times_LH"])) self.write_values(rounded_values,len(self.slews)," ") @@ -313,7 +313,7 @@ class lib: self.lib.write(" }\n") self.lib.write(" timing(){ \n") self.lib.write(" timing_type : hold_rising; \n") - self.lib.write(" related_pin : \"clk\"; \n") + self.lib.write(" related_pin : \"clk{0}\"; \n".format(port)) self.lib.write(" rise_constraint(CONSTRAINT_TABLE) {\n") rounded_values = list(map(round_time,self.times["hold_times_LH"])) self.write_values(rounded_values,len(self.slews)," ") @@ -339,10 +339,10 @@ class lib: self.lib.write(" pin(DOUT{1}[{0}:0]){{\n".format(self.sram.word_size - 1, read_port)) - self.write_FF_setuphold() + self.write_FF_setuphold(read_port) self.lib.write(" timing(){ \n") self.lib.write(" timing_sense : non_unate; \n") - self.lib.write(" related_pin : \"clk\"; \n") + self.lib.write(" related_pin : \"clk{0}\"; \n".format(read_port)) self.lib.write(" timing_type : rising_edge; \n") self.lib.write(" cell_rise(CELL_TABLE) {\n") self.write_values(self.char_port_results[read_port]["delay_lh"],len(self.loads)," ") @@ -370,7 +370,7 @@ class lib: self.lib.write(" capacitance : {0}; \n".format(tech.spice["dff_in_cap"])) self.lib.write(" memory_write(){ \n") self.lib.write(" address : ADDR{0}; \n".format(write_port)) - self.lib.write(" clocked_on : clk; \n") + self.lib.write(" clocked_on : clk{0}; \n".format(write_port)) self.lib.write(" }\n") self.lib.write(" }\n") @@ -392,7 +392,7 @@ class lib: self.lib.write(" pin(ADDR{1}[{0}:0])".format(self.sram.addr_size - 1, port)) self.lib.write("{\n") - self.write_FF_setuphold() + self.write_FF_setuphold(port) self.lib.write(" }\n") self.lib.write(" }\n\n") @@ -409,28 +409,25 @@ class lib: self.lib.write("{\n") self.lib.write(" direction : input; \n") self.lib.write(" capacitance : {0}; \n".format(tech.spice["dff_in_cap"])) - self.write_FF_setuphold() + self.write_FF_setuphold(port) self.lib.write(" }\n\n") - def write_clk_timing_power(self): + def write_clk_timing_power(self, port): """ Adds clk pin timing results.""" - self.lib.write(" pin(clk){\n") + self.lib.write(" pin(clk{0}){{\n".format(port)) self.lib.write(" clock : true;\n") self.lib.write(" direction : input; \n") # FIXME: This depends on the clock buffer size in the control logic self.lib.write(" capacitance : {0}; \n".format(tech.spice["dff_in_cap"])) - #Add power values for the ports. lib generated with this is not syntactically correct. TODO once - #top level is done. - for port in range(self.total_port_num): - self.add_clk_control_power(port) + self.add_clk_control_power(port) min_pulse_width = round_time(self.char_sram_results["min_period"])/2.0 min_period = round_time(self.char_sram_results["min_period"]) self.lib.write(" timing(){ \n") self.lib.write(" timing_type :\"min_pulse_width\"; \n") - self.lib.write(" related_pin : clk; \n") + self.lib.write(" related_pin : clk{0}; \n".format(port)) self.lib.write(" rise_constraint(scalar) {\n") self.lib.write(" values(\"{0}\"); \n".format(min_pulse_width)) self.lib.write(" }\n") @@ -440,7 +437,7 @@ class lib: self.lib.write(" }\n") self.lib.write(" timing(){ \n") self.lib.write(" timing_type :\"minimum_period\"; \n") - self.lib.write(" related_pin : clk; \n") + self.lib.write(" related_pin : clk{0}; \n".format(port)) self.lib.write(" rise_constraint(scalar) {\n") self.lib.write(" values(\"{0}\"); \n".format(min_period)) self.lib.write(" }\n") @@ -448,8 +445,7 @@ class lib: self.lib.write(" values(\"{0}\"); \n".format(min_period)) self.lib.write(" }\n") self.lib.write(" }\n") - self.lib.write(" }\n") - self.lib.write(" }\n") + self.lib.write(" }\n\n") def add_clk_control_power(self, port): """Writes powers under the clock pin group for a specified port""" @@ -461,7 +457,7 @@ class lib: web_name = " & !WEb{0}".format(port) avg_write_power = np.mean(self.char_port_results[port]["write1_power"] + self.char_port_results[port]["write0_power"]) self.lib.write(" internal_power(){\n") - self.lib.write(" when : \"!CSb{0} & clk{1}\"; \n".format(port, web_name)) + self.lib.write(" when : \"!CSb{0} & clk{0}{1}\"; \n".format(port, web_name)) self.lib.write(" rise_power(scalar){\n") self.lib.write(" values(\"{0}\");\n".format(avg_write_power/2.0)) self.lib.write(" }\n") @@ -475,7 +471,7 @@ class lib: web_name = " & WEb{0}".format(port) avg_read_power = np.mean(self.char_port_results[port]["read1_power"] + self.char_port_results[port]["read0_power"]) self.lib.write(" internal_power(){\n") - self.lib.write(" when : \"!CSb{0} & !clk{1}\"; \n".format(port, web_name)) + self.lib.write(" when : \"!CSb{0} & !clk{0}{1}\"; \n".format(port, web_name)) self.lib.write(" rise_power(scalar){\n") self.lib.write(" values(\"{0}\");\n".format(avg_read_power/2.0)) self.lib.write(" }\n") diff --git a/compiler/example_config_freepdk45.py b/compiler/example_config_freepdk45.py index e9e753b9..5e7a689f 100644 --- a/compiler/example_config_freepdk45.py +++ b/compiler/example_config_freepdk45.py @@ -1,6 +1,5 @@ word_size = 2 num_words = 16 -num_banks = 1 tech_name = "freepdk45" process_corners = ["TT"] diff --git a/compiler/example_config_scn4m_subm.py b/compiler/example_config_scn4m_subm.py index 9aa8e498..9306ae20 100644 --- a/compiler/example_config_scn4m_subm.py +++ b/compiler/example_config_scn4m_subm.py @@ -1,6 +1,5 @@ word_size = 2 num_words = 16 -num_banks = 1 tech_name = "scn4m_subm" process_corners = ["TT"] @@ -9,3 +8,11 @@ temperatures = [ 25 ] output_path = "temp" output_name = "sram_{0}_{1}_{2}".format(word_size,num_words,tech_name) + +#Setting for multiport +# netlist_only = True +# bitcell = "pbitcell" +# replica_bitcell="replica_pbitcell" +# num_rw_ports = 1 +# num_r_ports = 1 +# num_w_ports = 1 \ No newline at end of file diff --git a/compiler/tests/04_bitcell_1rw_1r_test.py b/compiler/tests/04_bitcell_1rw_1r_test.py index 567cd291..67db3710 100755 --- a/compiler/tests/04_bitcell_1rw_1r_test.py +++ b/compiler/tests/04_bitcell_1rw_1r_test.py @@ -13,7 +13,7 @@ import debug OPTS = globals.OPTS -#@unittest.skip("SKIPPING 04_bitcell_1rw_1r_test") +@unittest.skip("SKIPPING 04_bitcell_1rw_1r_test") class bitcell_1rw_1r_test(openram_test): def runTest(self):