From 9ffba4b0529d3a50140810b75a0453b668a1cd0d Mon Sep 17 00:00:00 2001 From: Matt Guthaus Date: Mon, 13 Aug 2018 09:57:10 -0700 Subject: [PATCH 1/7] Add +x permissions on precharge and pbitcell tests --- compiler/tests/04_precharge_test.py | 0 compiler/tests/05_pbitcell_array_test.py | 0 2 files changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 compiler/tests/04_precharge_test.py mode change 100644 => 100755 compiler/tests/05_pbitcell_array_test.py diff --git a/compiler/tests/04_precharge_test.py b/compiler/tests/04_precharge_test.py old mode 100644 new mode 100755 diff --git a/compiler/tests/05_pbitcell_array_test.py b/compiler/tests/05_pbitcell_array_test.py old mode 100644 new mode 100755 From 49bee6a96eb459c64c30a571fb20a67d44338086 Mon Sep 17 00:00:00 2001 From: Matt Guthaus Date: Mon, 13 Aug 2018 14:09:49 -0700 Subject: [PATCH 2/7] Remove OEB signal since we split DIN/DOUT ports --- compiler/characterizer/delay.py | 6 ------ compiler/modules/control_logic.py | 21 ++++++++++----------- compiler/tests/21_ngspice_delay_test.py | 20 ++++++++++---------- technology/freepdk45/tech/tech.py | 2 +- technology/scn3me_subm/tech/tech.py | 2 +- 5 files changed, 22 insertions(+), 29 deletions(-) diff --git a/compiler/characterizer/delay.py b/compiler/characterizer/delay.py index 2c639ee9..55a3bc06 100644 --- a/compiler/characterizer/delay.py +++ b/compiler/characterizer/delay.py @@ -166,7 +166,6 @@ class delay(): self.sf.write("\n* Generation of control signals\n") self.stim.gen_constant(sig_name="CSb", v_val=self.vdd_voltage) self.stim.gen_constant(sig_name="WEb", v_val=self.vdd_voltage) - self.stim.gen_constant(sig_name="OEb", v_val=self.vdd_voltage) self.sf.write("\n* Generation of global clock signal\n") self.stim.gen_constant(sig_name="CLK", v_val=0) @@ -621,7 +620,6 @@ class delay(): self.cycle_times.append(self.t_current) self.t_current += self.period self.web_values.append(1) - self.oeb_values.append(1) self.csb_values.append(1) self.add_data(data) @@ -637,7 +635,6 @@ class delay(): self.t_current += self.period self.web_values.append(1) - self.oeb_values.append(0) self.csb_values.append(0) self.add_data(data) @@ -654,7 +651,6 @@ class delay(): self.t_current += self.period self.web_values.append(0) - self.oeb_values.append(1) self.csb_values.append(0) self.add_data(data) @@ -674,7 +670,6 @@ class delay(): # Control logic signals each cycle self.web_values = [] - self.oeb_values = [] self.csb_values = [] # Address and data values for each address/data bit @@ -798,4 +793,3 @@ class delay(): """ Generates the control signals """ self.stim.gen_pwl("csb", self.cycle_times, self.csb_values, self.period, self.slew, 0.05) self.stim.gen_pwl("web", self.cycle_times, self.web_values, self.period, self.slew, 0.05) - self.stim.gen_pwl("oeb", self.cycle_times, self.oeb_values, self.period, self.slew, 0.05) diff --git a/compiler/modules/control_logic.py b/compiler/modules/control_logic.py index 99018a9a..d9f12589 100644 --- a/compiler/modules/control_logic.py +++ b/compiler/modules/control_logic.py @@ -52,7 +52,7 @@ class control_logic(design.design): dff = dff_inv() dff_height = dff.height - self.ctrl_dff_array = dff_inv_array(rows=3,columns=1) + self.ctrl_dff_array = dff_inv_array(rows=2,columns=1) self.add_mod(self.ctrl_dff_array) self.nand2 = pnand2(height=dff_height) @@ -93,10 +93,10 @@ class control_logic(design.design): #self.cell_gap = max(self.m2_pitch,drc["pwell_to_nwell"]) # List of input control signals - self.input_list =["csb","web","oeb"] - self.dff_output_list =["cs_bar", "cs", "we_bar", "we", "oe_bar", "oe"] + self.input_list =["csb","web"] + self.dff_output_list =["cs_bar", "cs", "we_bar", "we"] # list of output control signals (for making a vertical bus) - self.internal_bus_list = ["clk_buf", "clk_buf_bar", "we", "cs", "oe"] + self.internal_bus_list = ["clk_buf", "clk_buf_bar", "we", "cs"] # leave space for the bus plus one extra space self.internal_bus_width = (len(self.internal_bus_list)+1)*self.m2_pitch # Ooutputs to the bank @@ -190,14 +190,14 @@ class control_logic(design.design): (y_off,mirror)=self.get_offset(row) - # input: OE, clk_buf_bar,CS output: rbl_in_bar + # input: clk_buf_bar,CS output: rbl_in_bar self.rbl_in_bar_offset = vector(x_off, y_off) self.rbl_in_bar_inst=self.add_inst(name="nand3_rbl_in_bar", - mod=self.nand3, + mod=self.nand2, offset=self.rbl_in_bar_offset, mirror=mirror) - self.connect_inst(["clk_buf_bar", "oe", "cs", "rbl_in_bar", "vdd", "gnd"]) - x_off += self.nand3.width + self.connect_inst(["clk_buf_bar", "cs", "rbl_in_bar", "vdd", "gnd"]) + x_off += self.nand2.width # input: rbl_in_bar, output: rbl_in self.rbl_in_offset = vector(x_off, y_off) @@ -306,7 +306,7 @@ class control_logic(design.design): def route_dffs(self): """ Route the input inverters """ - dff_out_map = zip(["dout_bar[{}]".format(i) for i in range(3)], ["cs", "we", "oe"]) + dff_out_map = zip(["dout_bar[{}]".format(i) for i in range(3)], ["cs", "we"]) self.connect_vertical_bus(dff_out_map, self.ctrl_dff_inst, self.rail_offsets) # Connect the clock rail to the other clock rail @@ -320,7 +320,6 @@ class control_logic(design.design): self.copy_layout_pin(self.ctrl_dff_inst, "din[0]", "csb") self.copy_layout_pin(self.ctrl_dff_inst, "din[1]", "web") - self.copy_layout_pin(self.ctrl_dff_inst, "din[2]", "oeb") def add_dffs(self): @@ -388,7 +387,7 @@ class control_logic(design.design): def route_rbl_in(self): """ Connect the logic for the rbl_in generation """ - rbl_in_map = zip(["A", "B", "C"], ["clk_buf_bar", "oe", "cs"]) + rbl_in_map = zip(["A", "B"], ["clk_buf_bar", "cs"]) self.connect_vertical_bus(rbl_in_map, self.rbl_in_bar_inst, self.rail_offsets) # Connect the NAND3 output to the inverter diff --git a/compiler/tests/21_ngspice_delay_test.py b/compiler/tests/21_ngspice_delay_test.py index 72bdbc65..33fb0e9c 100755 --- a/compiler/tests/21_ngspice_delay_test.py +++ b/compiler/tests/21_ngspice_delay_test.py @@ -61,16 +61,16 @@ class timing_sram_test(openram_test): 'write0_power': [0.04765188], 'write1_power': [0.04434999]} elif OPTS.tech_name == "scn3me_subm": - golden_data = {'delay_hl': [11.69536], - 'delay_lh': [1.260921], - 'leakage_power': 0.00039469710000000004, - 'min_period': 20.0, - 'read0_power': [4.40238], - 'read1_power': [4.126633], - 'slew_hl': [1.259555], - 'slew_lh': [0.9150649], - 'write0_power': [4.988347], - 'write1_power': [4.473887]} + golden_data = {'delay_hl': [3.8551919999999997], + 'delay_lh': [2.649183], + 'leakage_power': 0.001692146, + 'min_period': 4.688, + 'read0_power': [17.34118], + 'read1_power': [16.63607], + 'slew_hl': [1.257066], + 'slew_lh': [1.211681], + 'write0_power': [21.73913], + 'write1_power': [18.39621]} else: self.assertTrue(False) # other techs fail diff --git a/technology/freepdk45/tech/tech.py b/technology/freepdk45/tech/tech.py index 98e0fab3..f232a2a7 100644 --- a/technology/freepdk45/tech/tech.py +++ b/technology/freepdk45/tech/tech.py @@ -261,7 +261,7 @@ spice["nom_temperature"] = 25 # Nominal temperature (celcius) #FIXME: We don't use these everywhere... spice["vdd_name"] = "vdd" spice["gnd_name"] = "gnd" -spice["control_signals"] = ["CSb", "WEb", "OEb"] +spice["control_signals"] = ["CSB", "WEB"] spice["data_name"] = "DATA" spice["addr_name"] = "ADDR" spice["minwidth_tx"] = drc["minwidth_tx"] diff --git a/technology/scn3me_subm/tech/tech.py b/technology/scn3me_subm/tech/tech.py index 0bba8754..18ec5bca 100755 --- a/technology/scn3me_subm/tech/tech.py +++ b/technology/scn3me_subm/tech/tech.py @@ -224,7 +224,7 @@ spice["nom_temperature"] = 25 # Nominal temperature (celcius) #FIXME: We don't use these everywhere... spice["vdd_name"] = "vdd" spice["gnd_name"] = "gnd" -spice["control_signals"] = ["CSb", "WEb", "OEb"] +spice["control_signals"] = ["CSB", "WEB"] spice["data_name"] = "DATA" spice["addr_name"] = "ADDR" spice["minwidth_tx"] = drc["minwidth_tx"] From f7f318d72e699a9b4e9d13927e261374263cf1c9 Mon Sep 17 00:00:00 2001 From: Matt Guthaus Date: Mon, 13 Aug 2018 14:47:03 -0700 Subject: [PATCH 3/7] Remove tri_en signals from bank control logic. --- compiler/modules/bank.py | 77 +++--------------- compiler/modules/bank_select.py | 8 +- compiler/modules/control_logic.py | 105 ------------------------- compiler/sram_base.py | 5 +- compiler/tests/21_hspice_delay_test.py | 20 ++--- 5 files changed, 25 insertions(+), 190 deletions(-) diff --git a/compiler/modules/bank.py b/compiler/modules/bank.py index 74730f8b..d4ab62e5 100644 --- a/compiler/modules/bank.py +++ b/compiler/modules/bank.py @@ -22,9 +22,9 @@ class bank(design.design): def __init__(self, word_size, num_words, words_per_row, num_banks=1, name=""): - mod_list = ["tri_gate", "bitcell", "decoder", "ms_flop_array", "wordline_driver", + mod_list = ["bitcell", "decoder", "ms_flop_array", "wordline_driver", "bitcell_array", "sense_amp_array", "precharge_array", - "column_mux_array", "write_driver_array", "tri_gate_array", + "column_mux_array", "write_driver_array", "dff", "bank_select"] from importlib import reload for mod_name in mod_list: @@ -84,8 +84,7 @@ class bank(design.design): # the signals gated_*. if self.num_banks > 1: self.add_pin("bank_sel","INPUT") - for pin in ["s_en","w_en","tri_en_bar","tri_en", - "clk_buf_bar","clk_buf"]: + for pin in ["s_en","w_en","clk_buf_bar","clk_buf"]: self.add_pin(pin,"INPUT") self.add_pin("vdd","POWER") self.add_pin("gnd","GROUND") @@ -96,8 +95,6 @@ class bank(design.design): self.route_precharge_to_bitcell_array() self.route_col_mux_to_bitcell_array() self.route_sense_amp_to_col_mux_or_bitcell_array() - #self.route_sense_amp_to_trigate() - #self.route_tri_gate_out() self.route_sense_amp_out() self.route_wordline_driver() self.route_write_driver() @@ -121,8 +118,6 @@ class bank(design.design): self.add_column_mux_array() self.add_sense_amp_array() self.add_write_driver_array() - # Not needed for single bank - #self.add_tri_gate_array() # To the left of the bitcell array self.add_row_decoder() @@ -150,9 +145,9 @@ class bank(design.design): self.supply_rail_pitch = self.supply_rail_width + 4*self.m2_space # Number of control lines in the bus - self.num_control_lines = 6 + self.num_control_lines = 4 # The order of the control signals on the control bus: - self.input_control_signals = ["clk_buf", "tri_en_bar", "tri_en", "clk_buf_bar", "w_en", "s_en"] + self.input_control_signals = ["clk_buf", "clk_buf_bar", "w_en", "s_en"] # These will be outputs of the gaters if this is multibank, if not, normal signals. if self.num_banks > 1: self.control_signals = ["gated_"+str for str in self.input_control_signals] @@ -176,7 +171,6 @@ class bank(design.design): def create_modules(self): """ Create all the modules using the class loader """ - self.tri = self.mod_tri_gate() self.bitcell = self.mod_bitcell() self.bitcell_array = self.mod_bitcell_array(cols=self.num_cols, @@ -203,10 +197,6 @@ class bank(design.design): self.row_decoder = self.mod_decoder(rows=self.num_rows) self.add_mod(self.row_decoder) - self.tri_gate_array = self.mod_tri_gate_array(columns=self.num_cols, - word_size=self.word_size) - self.add_mod(self.tri_gate_array) - self.wordline_driver = self.mod_wordline_driver(rows=self.num_rows) self.add_mod(self.wordline_driver) @@ -316,22 +306,6 @@ class bank(design.design): temp.extend([self.prefix+"w_en", "vdd", "gnd"]) self.connect_inst(temp) - def add_tri_gate_array(self): - """ data tri gate to drive the data bus """ - y_offset = self.sense_amp_array.height+self.column_mux_height \ - + self.m2_gap + self.tri_gate_array.height - self.tri_gate_array_inst=self.add_inst(name="tri_gate_array", - mod=self.tri_gate_array, - offset=vector(0,y_offset).scale(-1,-1)) - - temp = [] - for i in range(self.word_size): - temp.append("sa_out[{0}]".format(i)) - for i in range(self.word_size): - temp.append("dout[{0}]".format(i)) - temp.extend([self.prefix+"tri_en", self.prefix+"tri_en_bar", "vdd", "gnd"]) - self.connect_inst(temp) - def add_row_decoder(self): """ Add the hierarchical row decoder """ @@ -447,7 +421,6 @@ class bank(design.design): self.precharge_array_inst, self.sense_amp_array_inst, self.write_driver_array_inst, -# self.tri_gate_array_inst, self.row_decoder_inst, self.wordline_driver_inst] # Add these if we use the part... @@ -493,10 +466,7 @@ class bank(design.design): control bus, power ring, etc. """ #The minimum point is either the bottom of the address flops, - #the column decoder (if there is one) or the tristate output - #driver. - # Leave room for the output below the tri gate. - #tri_gate_min_y_offset = self.tri_gate_array_inst.by() - 3*self.m2_pitch + #the column decoder (if there is one). write_driver_min_y_offset = self.write_driver_array_inst.by() - 3*self.m2_pitch row_decoder_min_y_offset = self.row_decoder_inst.by() if self.col_addr_size > 0: @@ -506,10 +476,10 @@ class bank(design.design): if self.num_banks>1: # The control gating logic is below the decoder - # Min of the control gating logic and tri gate. + # Min of the control gating logic and write driver. self.min_y_offset = min(col_decoder_min_y_offset - self.bank_select.height, write_driver_min_y_offset) else: - # Just the min of the decoder logic logic and tri gate. + # Just the min of the decoder logic logic and write driver. self.min_y_offset = min(col_decoder_min_y_offset, write_driver_min_y_offset) # The max point is always the top of the precharge bitlines @@ -603,20 +573,6 @@ class bank(design.design): self.add_path("metal2",[sense_amp_br, vector(sense_amp_br.x,yoffset), vector(connect_br.x,yoffset), connect_br]) - def route_sense_amp_to_trigate(self): - """ Routing of sense amp output to tri_gate input """ - - for i in range(self.word_size): - # Connection of data_out of sense amp to data_in - tri_gate_in = self.tri_gate_array_inst.get_pin("in[{}]".format(i)).lc() - sa_data_out = self.sense_amp_array_inst.get_pin("data[{}]".format(i)).bc() - - self.add_via_center(layers=("metal2", "via2", "metal3"), - offset=tri_gate_in) - self.add_via_center(layers=("metal2", "via2", "metal3"), - offset=sa_data_out) - self.add_path("metal3",[sa_data_out,tri_gate_in]) - def route_sense_amp_out(self): """ Add pins for the sense amp output """ for i in range(self.word_size): @@ -627,17 +583,6 @@ class bank(design.design): height=data_pin.height(), width=data_pin.width()), - def route_tri_gate_out(self): - """ Metal 3 routing of tri_gate output data """ - for i in range(self.word_size): - data_pin = self.tri_gate_array_inst.get_pin("out[{}]".format(i)) - self.add_layout_pin_rect_center(text="dout[{}]".format(i), - layer=data_pin.layer, - offset=data_pin.center(), - height=data_pin.height(), - width=data_pin.width()), - - def route_row_decoder(self): """ Routes the row decoder inputs and supplies """ @@ -782,8 +727,6 @@ class bank(design.design): # Connection from the central bus to the main control block crosses # pre-decoder and this connection is in metal3 connection = [] - #connection.append((self.prefix+"tri_en_bar", self.tri_gate_array_inst.get_pin("en_bar").lc())) - #connection.append((self.prefix+"tri_en", self.tri_gate_array_inst.get_pin("en").lc())) connection.append((self.prefix+"clk_buf_bar", self.precharge_array_inst.get_pin("en").lc())) connection.append((self.prefix+"w_en", self.write_driver_array_inst.get_pin("en").lc())) connection.append((self.prefix+"s_en", self.sense_amp_array_inst.get_pin("en").lc())) @@ -866,8 +809,6 @@ class bank(design.design): self.bitcell_array.output_load()) # output load of bitcell_array is set to be only small part of bl for sense amp. - data_t_DATA_delay = self.tri_gate_array.analytical_delay(bl_t_data_out_delay.slew, load) - - result = decoder_delay + word_driver_delay + bitcell_array_delay + bl_t_data_out_delay + data_t_DATA_delay + result = decoder_delay + word_driver_delay + bitcell_array_delay + bl_t_data_out_delay return result diff --git a/compiler/modules/bank_select.py b/compiler/modules/bank_select.py index 2abfb3c6..9a4b193e 100644 --- a/compiler/modules/bank_select.py +++ b/compiler/modules/bank_select.py @@ -19,9 +19,9 @@ class bank_select(design.design): design.design.__init__(self, name) # Number of control lines in the bus - self.num_control_lines = 6 + self.num_control_lines = 4 # The order of the control signals on the control bus: - self.input_control_signals = ["clk_buf", "tri_en_bar", "tri_en", "clk_buf_bar", "w_en", "s_en"] + self.input_control_signals = ["clk_buf", "clk_buf_bar", "w_en", "s_en"] # These will be outputs of the gaters if this is multibank self.control_signals = ["gated_"+str for str in self.input_control_signals] @@ -96,7 +96,7 @@ class bank_select(design.design): # These require OR (nor2+inv) gates since they are active low. # (writes occur on clk low) - if input_name in ("clk_buf", "tri_en_bar"): + if input_name in ("clk_buf"): self.logic_inst.append(self.add_inst(name=name_nor, mod=self.nor2, @@ -173,7 +173,7 @@ class bank_select(design.design): input_name = self.input_control_signals[i] gated_name = self.control_signals[i] - if input_name in ("clk_buf", "tri_en_bar"): + if input_name in ("clk_buf"): xoffset_bank_signal = xoffset_bank_sel_bar else: xoffset_bank_signal = xoffset_bank_sel diff --git a/compiler/modules/control_logic.py b/compiler/modules/control_logic.py index d9f12589..cf62851f 100644 --- a/compiler/modules/control_logic.py +++ b/compiler/modules/control_logic.py @@ -101,8 +101,6 @@ class control_logic(design.design): self.internal_bus_width = (len(self.internal_bus_list)+1)*self.m2_pitch # Ooutputs to the bank self.output_list = ["s_en", "w_en", "clk_buf_bar", "clk_buf"] - # # with tri/tri_en - # self.output_list = ["s_en", "w_en", "tri_en", "tri_en_bar", "clk_buf_bar", "clk_buf"] self.supply_list = ["vdd", "gnd"] @@ -237,71 +235,6 @@ class control_logic(design.design): self.row_end_inst.append(self.s_en_inst) - def add_trien_row(self, row): - x_off = self.ctrl_dff_array.width + self.internal_bus_width - (y_off,mirror)=self.get_offset(row) - - - x_off += self.nand2.width - - # BUFFER INVERTERS FOR TRI_EN - tri_en_offset = vector(x_off, y_off) - self.tri_en_inst=self.add_inst(name="inv_tri_en1", - mod=self.inv2, - offset=tri_en_offset, - mirror=mirror) - self.connect_inst(["pre_tri_en_bar", "pre_tri_en1", "vdd", "gnd"]) - x_off += self.inv2.width - - tri_en_buf1_offset = vector(x_off, y_off) - self.tri_en_buf1_inst=self.add_inst(name="tri_en_buf1", - mod=self.inv2, - offset=tri_en_buf1_offset, - mirror=mirror) - self.connect_inst(["pre_tri_en1", "pre_tri_en_bar1", "vdd", "gnd"]) - x_off += self.inv2.width - - tri_en_buf2_offset = vector(x_off, y_off) - self.tri_en_buf2_inst=self.add_inst(name="tri_en_buf2", - mod=self.inv8, - offset=tri_en_buf2_offset, - mirror=mirror) - self.connect_inst(["pre_tri_en_bar1", "tri_en", "vdd", "gnd"]) - - self.row_end_inst.append(self.tri_en_inst) - - def add_trien_bar_row(self, row): - x_off = self.ctrl_dff_array.width + self.internal_bus_width - (y_off,mirror)=self.get_offset(row) - - - # input: OE, clk_buf_bar output: tri_en_bar - tri_en_bar_offset = vector(x_off,y_off) - self.tri_en_bar_inst=self.add_inst(name="nand2_tri_en", - mod=self.nand2, - offset=tri_en_bar_offset, - mirror=mirror) - self.connect_inst(["clk_buf_bar", "oe", "pre_tri_en_bar", "vdd", "gnd"]) - x_off += self.nand2.width - - # BUFFER INVERTERS FOR TRI_EN - tri_en_bar_buf1_offset = vector(x_off, y_off) - self.tri_en_bar_buf1_inst=self.add_inst(name="tri_en_bar_buf1", - mod=self.inv2, - offset=tri_en_bar_buf1_offset, - mirror=mirror) - self.connect_inst(["pre_tri_en_bar", "pre_tri_en2", "vdd", "gnd"]) - x_off += self.inv2.width - - tri_en_bar_buf2_offset = vector(x_off, y_off) - self.tri_en_bar_buf2_inst=self.add_inst(name="tri_en_bar_buf2", - mod=self.inv8, - offset=tri_en_bar_buf2_offset, - mirror=mirror) - self.connect_inst(["pre_tri_en2", "tri_en_bar", "vdd", "gnd"]) - x_off += self.inv8.width - - self.row_end_inst.append(self.tri_en_bar_buf2_inst) def route_dffs(self): """ Route the input inverters """ @@ -474,44 +407,6 @@ class control_logic(design.design): self.connect_output(self.w_en_inst, "Z", "w_en") - def route_trien(self): - - # Connect the NAND2 output to the buffer - tri_en_bar_pos = self.tri_en_bar_inst.get_pin("Z").center() - inv_in_pos = self.tri_en_inst.get_pin("A").center() - mid1 = vector(tri_en_bar_pos.x,inv_in_pos.y) - self.add_wire(("metal1","via1","metal2"),[tri_en_bar_pos,mid1,inv_in_pos]) - - # Connect the INV output to the buffer - tri_en_pos = self.tri_en_inst.get_pin("Z").center() - inv_in_pos = self.tri_en_buf1_inst.get_pin("A").center() - mid_xoffset = 0.5*(tri_en_pos.x + inv_in_pos.x) - mid1 = vector(mid_xoffset,tri_en_pos.y) - mid2 = vector(mid_xoffset,inv_in_pos.y) - self.add_path("metal1",[tri_en_pos,mid1,mid2,inv_in_pos]) - - self.add_path("metal1",[self.tri_en_buf1_ist.get_pin("Z").center(), self.tri_en_buf2_inst.get_pin("A").center()]) - - self.connect_output(self.tri_en_buf2_inst, "Z", "tri_en") - - def route_trien_bar(self): - - trien_map = zip(["A", "B"], ["clk_buf_bar", "oe"]) - self.connect_vertical_bus(trien_map, self.tri_en_bar_inst, self.rail_offsets) - - # Connect the NAND2 output to the buffer - tri_en_bar_pos = self.tri_en_bar_inst.get_pin("Z").center() - inv_in_pos = self.tri_en_bar_buf1_inst.get_pin("A").center() - mid_xoffset = 0.5*(tri_en_bar_pos.x + inv_in_pos.x) - mid1 = vector(mid_xoffset,tri_en_bar_pos.y) - mid2 = vector(mid_xoffset,inv_in_pos.y) - self.add_path("metal1",[tri_en_bar_pos,mid1,mid2,inv_in_pos]) - - self.add_path("metal1",[self.tri_en_bar_buf1_inst.get_pin("Z").center(), self.tri_en_bar_buf2_inst.get_pin("A").center()]) - - self.connect_output(self.tri_en_bar_buf2_inst, "Z", "tri_en_bar") - - def route_sen(self): rbl_out_pos = self.rbl_inst.get_pin("out").bc() in_pos = self.pre_s_en_bar_inst.get_pin("A").lc() diff --git a/compiler/sram_base.py b/compiler/sram_base.py index c7044d61..812c0950 100644 --- a/compiler/sram_base.py +++ b/compiler/sram_base.py @@ -150,7 +150,7 @@ class sram_base(design): """ Add the horizontal and vertical busses """ # Vertical bus # The order of the control signals on the control bus: - self.control_bus_names = ["clk_buf", "tri_en_bar", "tri_en", "clk_buf_bar", "w_en", "s_en"] + self.control_bus_names = ["clk_buf", "clk_buf_bar", "w_en", "s_en"] self.vert_control_bus_positions = self.create_vertical_bus(layer="metal2", pitch=self.m2_pitch, offset=self.vertical_bus_offset, @@ -328,8 +328,7 @@ class sram_base(design): temp.append("A[{0}]".format(i)) if(self.num_banks > 1): temp.append("bank_sel[{0}]".format(bank_num)) - temp.extend(["s_en", "w_en", "tri_en_bar", "tri_en", - "clk_buf_bar","clk_buf" , "vdd", "gnd"]) + temp.extend(["s_en", "w_en", "clk_buf_bar","clk_buf" , "vdd", "gnd"]) self.connect_inst(temp) return bank_inst diff --git a/compiler/tests/21_hspice_delay_test.py b/compiler/tests/21_hspice_delay_test.py index 0d256c5b..9b9eb2bd 100755 --- a/compiler/tests/21_hspice_delay_test.py +++ b/compiler/tests/21_hspice_delay_test.py @@ -62,16 +62,16 @@ class timing_sram_test(openram_test): 'write0_power': [0.0494321], 'write1_power': [0.0457268]} elif OPTS.tech_name == "scn3me_subm": - golden_data = {'delay_hl': [6.0052], - 'delay_lh': [2.2886], - 'leakage_power': 0.025629199999999998, - 'min_period': 9.375, - 'read0_power': [8.8721], - 'read1_power': [8.3179], - 'slew_hl': [1.0746], - 'slew_lh': [0.413426], - 'write0_power': [8.6601], - 'write1_power': [8.0397]} + golden_data = {'delay_hl': [3.6602], + 'delay_lh': [2.2651], + 'leakage_power': 0.026040400000000002, + 'min_period': 4.688, + 'read0_power': [15.8985], + 'read1_power': [14.9719], + 'slew_hl': [1.1001], + 'slew_lh': [0.4111598], + 'write0_power': [19.4539], + 'write1_power': [16.8561]} else: self.assertTrue(False) # other techs fail # Check if no too many or too few results From 5ff49d322d282ff51201729e3b910dcec10a7431 Mon Sep 17 00:00:00 2001 From: Matt Guthaus Date: Mon, 13 Aug 2018 15:14:52 -0700 Subject: [PATCH 4/7] bank_sel_bar only used for clk now --- compiler/modules/bank_select.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/modules/bank_select.py b/compiler/modules/bank_select.py index 9a4b193e..f89f16be 100644 --- a/compiler/modules/bank_select.py +++ b/compiler/modules/bank_select.py @@ -161,7 +161,7 @@ class bank_select(design.design): self.add_label_pin(text="bank_sel_bar", layer="metal2", offset=vector(xoffset_bank_sel_bar, 0), - height=2*self.inv.height) + height=self.inv.height) self.add_via_center(layers=("metal1","via1","metal2"), offset=bank_sel_bar_pin.rc()) From 3420b1002c37ba79d7a878256fd0d79b5f7a8cbe Mon Sep 17 00:00:00 2001 From: Matt Guthaus Date: Tue, 14 Aug 2018 10:09:41 -0700 Subject: [PATCH 5/7] Connect data and column DFF clocks in 1 bank. --- compiler/modules/bank.py | 62 ++++------------------------ compiler/modules/control_logic.py | 9 ++-- compiler/modules/dff_array.py | 37 +++++++---------- compiler/modules/replica_bitline.py | 6 +-- compiler/sram_1bank.py | 44 +++++++++++++++----- compiler/sram_base.py | 6 +-- compiler/tests/20_sram_1bank_test.py | 2 +- 7 files changed, 69 insertions(+), 97 deletions(-) diff --git a/compiler/modules/bank.py b/compiler/modules/bank.py index d4ab62e5..ea7881ed 100644 --- a/compiler/modules/bank.py +++ b/compiler/modules/bank.py @@ -101,7 +101,6 @@ class bank(design.design): self.route_row_decoder() self.route_column_address_lines() self.route_control_lines() - self.add_control_pins() if self.num_banks > 1: self.route_bank_select() @@ -505,13 +504,15 @@ class bank(design.design): # and control lines. # The bank is at (0,0), so this is to the left of the y-axis. # 2 pitches on the right for vias/jogs to access the inputs - control_bus_offset = vector(-self.m2_pitch * self.num_control_lines - self.m2_width, 0) - control_bus_length = self.bitcell_array_inst.uy() - self.bus_xoffset = self.create_vertical_bus(layer="metal2", - pitch=self.m2_pitch, - offset=control_bus_offset, - names=self.control_signals, - length=control_bus_length) + control_bus_offset = vector(-self.m2_pitch * self.num_control_lines - self.m2_width, self.min_y_offset) + control_bus_length = self.max_y_offset - self.min_y_offset + self.bus_xoffset = self.create_bus(layer="metal2", + pitch=self.m2_pitch, + offset=control_bus_offset, + names=self.control_signals, + length=control_bus_length, + vertical=True, + make_pins=(self.num_banks==1)) @@ -750,52 +751,7 @@ class bank(design.design): offset=control_via_pos, rotate=90) - def add_control_pins(self): - """ Add the control signal input pins """ - for ctrl in self.control_signals: - # xoffsets are the center of the rail - x_offset = self.bus_xoffset[ctrl].x - 0.5*self.m2_width - if self.num_banks > 1: - # it's not an input pin if we have multiple banks - self.add_label_pin(text=ctrl, - layer="metal2", - offset=vector(x_offset, self.min_y_offset), - width=self.m2_width, - height=self.max_y_offset-self.min_y_offset) - else: - self.add_layout_pin(text=ctrl, - layer="metal2", - offset=vector(x_offset, self.min_y_offset), - width=self.m2_width, - height=self.max_y_offset-self.min_y_offset) - - - def connect_rail_from_right(self,inst, pin, rail): - """ Helper routine to connect an unrotated/mirrored oriented instance to the rails """ - in_pin = inst.get_pin(pin).lc() - rail_pos = vector(self.rail_1_x_offsets[rail], in_pin.y) - self.add_wire(("metal3","via2","metal2"),[in_pin, rail_pos, rail_pos - vector(0,self.m2_pitch)]) - # Bring it up to M2 for M2/M3 routing - self.add_via(layers=("metal1","via1","metal2"), - offset=in_pin + contact.m1m2.offset, - rotate=90) - self.add_via(layers=("metal2","via2","metal3"), - offset=in_pin + self.m2m3_via_offset, - rotate=90) - - - def connect_rail_from_left(self,inst, pin, rail): - """ Helper routine to connect an unrotated/mirrored oriented instance to the rails """ - in_pin = inst.get_pin(pin).rc() - rail_pos = vector(self.rail_1_x_offsets[rail], in_pin.y) - self.add_wire(("metal3","via2","metal2"),[in_pin, rail_pos, rail_pos - vector(0,self.m2_pitch)]) - self.add_via(layers=("metal1","via1","metal2"), - offset=in_pin + contact.m1m2.offset, - rotate=90) - self.add_via(layers=("metal2","via2","metal3"), - offset=in_pin + self.m2m3_via_offset, - rotate=90) def analytical_delay(self, slew, load): """ return analytical delay of the bank""" diff --git a/compiler/modules/control_logic.py b/compiler/modules/control_logic.py index cf62851f..5e744bfa 100644 --- a/compiler/modules/control_logic.py +++ b/compiler/modules/control_logic.py @@ -99,7 +99,7 @@ class control_logic(design.design): self.internal_bus_list = ["clk_buf", "clk_buf_bar", "we", "cs"] # leave space for the bus plus one extra space self.internal_bus_width = (len(self.internal_bus_list)+1)*self.m2_pitch - # Ooutputs to the bank + # Outputs to the bank self.output_list = ["s_en", "w_en", "clk_buf_bar", "clk_buf"] self.supply_list = ["vdd", "gnd"] @@ -137,10 +137,11 @@ class control_logic(design.design): # This offset is used for placement of the control logic in # the SRAM level. self.control_logic_center = vector(self.ctrl_dff_inst.rx(), self.rbl_inst.by()) - - self.height = self.rbl_inst.uy() + + # Extra pitch on top and right + self.height = self.rbl_inst.uy() + self.m3_pitch # Max of modules or logic rows - self.width = max(self.rbl_inst.rx(), max([inst.rx() for inst in self.row_end_inst])) + self.width = max(self.rbl_inst.rx(), max([inst.rx() for inst in self.row_end_inst])) + self.m2_pitch def add_routing(self): diff --git a/compiler/modules/dff_array.py b/compiler/modules/dff_array.py index 5a09ae33..ef59f8a6 100644 --- a/compiler/modules/dff_array.py +++ b/compiler/modules/dff_array.py @@ -125,28 +125,21 @@ class dff_array(design.design): # Create vertical spines to a single horizontal rail clk_pin = self.dff_insts[0,0].get_pin("clk") debug.check(clk_pin.layer=="metal2","DFF clk pin not on metal2") - if self.columns==1: - self.add_layout_pin(text="clk", - layer="metal2", - offset=clk_pin.ll().scale(1,0), - width=self.m2_width, - height=self.height) - else: - self.add_layout_pin_segment_center(text="clk", - layer="metal3", - start=vector(0,self.m3_pitch+self.m3_width), - end=vector(self.width,self.m3_pitch+self.m3_width)) - for col in range(self.columns): - clk_pin = self.dff_insts[0,col].get_pin("clk") - # Make a vertical strip for each column - self.add_rect(layer="metal2", - offset=clk_pin.ll().scale(1,0), - width=self.m2_width, - height=self.height) - # Drop a via to the M3 pin - self.add_via_center(layers=("metal2","via2","metal3"), - offset=vector(clk_pin.cx(),self.m3_pitch+self.m3_width)) - + self.add_layout_pin_segment_center(text="clk", + layer="metal3", + start=vector(0,self.m3_pitch+self.m3_width), + end=vector(self.width,self.m3_pitch+self.m3_width)) + for col in range(self.columns): + clk_pin = self.dff_insts[0,col].get_pin("clk") + # Make a vertical strip for each column + self.add_rect(layer="metal2", + offset=clk_pin.ll().scale(1,0), + width=self.m2_width, + height=self.height) + # Drop a via to the M3 pin + self.add_via_center(layers=("metal2","via2","metal3"), + offset=vector(clk_pin.cx(),self.m3_pitch+self.m3_width)) + def analytical_delay(self, slew, load=0.0): diff --git a/compiler/modules/replica_bitline.py b/compiler/modules/replica_bitline.py index bf6b8f92..941304e8 100644 --- a/compiler/modules/replica_bitline.py +++ b/compiler/modules/replica_bitline.py @@ -42,9 +42,9 @@ class replica_bitline(design.design): #self.add_lvs_correspondence_points() - # Plus a pitch for the WL contacts on the RBL - self.width = self.rbl_inst.rx() - self.dc_inst.lx() + self.m1_pitch - self.height = max(self.rbl_inst.uy(), self.dc_inst.uy()) + # Extra pitch on top and right + self.width = self.rbl_inst.rx() - self.dc_inst.lx() + self.m2_pitch + self.height = max(self.rbl_inst.uy(), self.dc_inst.uy()) + self.m3_pitch self.DRC_LVS() diff --git a/compiler/sram_1bank.py b/compiler/sram_1bank.py index 7d99299d..d58bcc85 100644 --- a/compiler/sram_1bank.py +++ b/compiler/sram_1bank.py @@ -29,26 +29,29 @@ class sram_1bank(sram_base): # No orientation or offset self.bank_inst = self.add_bank(0, [0, 0], 1, 1) + # The control logic is placed such that the center (between the delay/RBL and + # the actual control logic is aligned with the center of the bank (between + # the sense amps/column mux and cell array) control_pos = vector(-self.control_logic.width - self.m3_pitch, self.bank.bank_center.y - self.control_logic.control_logic_center.y) self.add_control_logic(position=control_pos) - # Leave room for the control routes to the left of the flops + # The row address bits are placed above the control logic aligned on the right. row_addr_pos = vector(self.control_logic_inst.rx() - self.row_addr_dff.width, - control_pos.y + self.control_logic.height + self.m1_pitch) + self.control_logic_inst.uy()) self.add_row_addr_dff(row_addr_pos) # This is M2 pitch even though it is on M1 to help stem via spacings on the trunk data_gap = -self.m2_pitch*(self.word_size+1) # Add the column address below the bank under the control - # Keep it aligned with the data flops + # The column address flops are aligned with the data flops if self.col_addr_dff: col_addr_pos = vector(self.bank.bank_center.x - self.col_addr_dff.width - self.bank.central_bus_width, data_gap - self.col_addr_dff.height) self.add_col_addr_dff(col_addr_pos) - # Add the data flops below the bank + # Add the data flops below the bank to the right of the center of bank: # This relies on the center point of the bank: # decoder in upper left, bank in upper right, sensing in lower right. # These flops go below the sensing and leave a gap to channel route to the @@ -104,13 +107,34 @@ class sram_1bank(sram_base): def route_clk(self): """ Route the clock network """ - debug.warning("Clock is top-level must connect.") - # For now, just have four clock pins for the address (x2), data, and control - if self.col_addr_dff: - self.copy_layout_pin(self.col_addr_dff_inst, "clk") - self.copy_layout_pin(self.row_addr_dff_inst, "clk") - self.copy_layout_pin(self.data_dff_inst, "clk") + + # This is the actual input to the SRAM self.copy_layout_pin(self.control_logic_inst, "clk") + + debug.warning("Clock is top-level must connect.") + + # Connect all of these clock pins to the clock in the central bus + # This is something like a "spine" clock distribution. The two spines + # are clk_buf and clk_buf_bar + bank_clk_buf_pin = self.bank_inst.get_pin("clk_buf") + bank_clk_buf_pos = bank_clk_buf_pin.center() + bank_clk_buf_bar_pin = self.bank_inst.get_pin("clk_buf_bar") + bank_clk_buf_bar_pos = bank_clk_buf_bar_pin.center() + + if self.col_addr_dff: + dff_clk_pin = self.col_addr_dff_inst.get_pin("clk") + dff_clk_pos = dff_clk_pin.center() + mid_pos = vector(bank_clk_buf_pos.x, dff_clk_pos.y) + self.add_wire(("metal3","via2","metal2"),[dff_clk_pos, mid_pos, bank_clk_buf_pos]) + + self.copy_layout_pin(self.row_addr_dff_inst, "clk") + #self.copy_layout_pin(self.data_dff_inst, "clk") + + data_dff_clk_pin = self.data_dff_inst.get_pin("clk") + data_dff_clk_pos = data_dff_clk_pin.center() + mid_pos = vector(bank_clk_buf_pos.x, data_dff_clk_pos.y) + self.add_wire(("metal3","via2","metal2"),[data_dff_clk_pos, mid_pos, bank_clk_buf_pos]) + def route_vdd_gnd(self): """ Propagate all vdd/gnd pins up to this level for all modules """ diff --git a/compiler/sram_base.py b/compiler/sram_base.py index 812c0950..c10019ff 100644 --- a/compiler/sram_base.py +++ b/compiler/sram_base.py @@ -362,8 +362,7 @@ class sram_base(design): inputs.append("ADDR[{}]".format(i)) outputs.append("A[{}]".format(i)) - # FIXME clk->clk_buf - self.connect_inst(inputs + outputs + ["clk", "vdd", "gnd"]) + self.connect_inst(inputs + outputs + ["clk_buf", "vdd", "gnd"]) def add_data_dff(self, position): """ Add and place all data flops """ @@ -377,8 +376,7 @@ class sram_base(design): inputs.append("DIN[{}]".format(i)) outputs.append("BANK_DIN[{}]".format(i)) - # FIXME clk->clk_buf_bar - self.connect_inst(inputs + outputs + ["clk", "vdd", "gnd"]) + self.connect_inst(inputs + outputs + ["clk_buf", "vdd", "gnd"]) def add_control_logic(self, position): """ Add and place control logic """ diff --git a/compiler/tests/20_sram_1bank_test.py b/compiler/tests/20_sram_1bank_test.py index 4b929e87..8b83f54a 100755 --- a/compiler/tests/20_sram_1bank_test.py +++ b/compiler/tests/20_sram_1bank_test.py @@ -35,7 +35,7 @@ class sram_1bank_test(openram_test): debug.info(1, "Single bank, eight way column mux with control logic") a = sram(word_size=2, num_words=128, num_banks=1, name="sram4") self.local_check(a, final_verification=True) - + globals.end_openram() # instantiate a copy of the class to actually run the test From 8900edbe121eedfd1c8b809f664747f22db40805 Mon Sep 17 00:00:00 2001 From: Matt Guthaus Date: Tue, 14 Aug 2018 10:36:35 -0700 Subject: [PATCH 6/7] Finalize single bank clock routing. --- compiler/sram_1bank.py | 28 ++++++++++++++++++++-------- compiler/sram_base.py | 3 +-- 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/compiler/sram_1bank.py b/compiler/sram_1bank.py index d58bcc85..4d2d72eb 100644 --- a/compiler/sram_1bank.py +++ b/compiler/sram_1bank.py @@ -29,10 +29,12 @@ class sram_1bank(sram_base): # No orientation or offset self.bank_inst = self.add_bank(0, [0, 0], 1, 1) - # The control logic is placed such that the center (between the delay/RBL and - # the actual control logic is aligned with the center of the bank (between + # The control logic is placed such that the vertical center (between the delay/RBL and + # the actual control logic is aligned with the vertical center of the bank (between # the sense amps/column mux and cell array) - control_pos = vector(-self.control_logic.width - self.m3_pitch, + # The x-coordinate is placed to allow a single clock wire (plus an extra pitch) + # up to the row address DFFs. + control_pos = vector(-self.control_logic.width - 2*self.m2_pitch, self.bank.bank_center.y - self.control_logic.control_logic_center.y) self.add_control_logic(position=control_pos) @@ -111,11 +113,10 @@ class sram_1bank(sram_base): # This is the actual input to the SRAM self.copy_layout_pin(self.control_logic_inst, "clk") - debug.warning("Clock is top-level must connect.") - # Connect all of these clock pins to the clock in the central bus # This is something like a "spine" clock distribution. The two spines # are clk_buf and clk_buf_bar + bank_clk_buf_pin = self.bank_inst.get_pin("clk_buf") bank_clk_buf_pos = bank_clk_buf_pin.center() bank_clk_buf_bar_pin = self.bank_inst.get_pin("clk_buf_bar") @@ -126,14 +127,25 @@ class sram_1bank(sram_base): dff_clk_pos = dff_clk_pin.center() mid_pos = vector(bank_clk_buf_pos.x, dff_clk_pos.y) self.add_wire(("metal3","via2","metal2"),[dff_clk_pos, mid_pos, bank_clk_buf_pos]) - - self.copy_layout_pin(self.row_addr_dff_inst, "clk") - #self.copy_layout_pin(self.data_dff_inst, "clk") data_dff_clk_pin = self.data_dff_inst.get_pin("clk") data_dff_clk_pos = data_dff_clk_pin.center() mid_pos = vector(bank_clk_buf_pos.x, data_dff_clk_pos.y) self.add_wire(("metal3","via2","metal2"),[data_dff_clk_pos, mid_pos, bank_clk_buf_pos]) + + # This uses a metal2 track to the right of the control/row addr DFF + # to route vertically. + control_clk_buf_pin = self.control_logic_inst.get_pin("clk_buf") + control_clk_buf_pos = control_clk_buf_pin.rc() + row_addr_clk_pin = self.row_addr_dff_inst.get_pin("clk") + row_addr_clk_pos = row_addr_clk_pin.rc() + mid1_pos = vector(self.row_addr_dff_inst.rx() + self.m2_pitch, + row_addr_clk_pos.y) + mid2_pos = vector(mid1_pos.x, + control_clk_buf_pos.y) + # Note, the via to the control logic is taken care of when we route + # the control logic to the bank + self.add_wire(("metal3","via2","metal2"),[row_addr_clk_pos, mid1_pos, mid2_pos, control_clk_buf_pos]) def route_vdd_gnd(self): diff --git a/compiler/sram_base.py b/compiler/sram_base.py index c10019ff..a11b0984 100644 --- a/compiler/sram_base.py +++ b/compiler/sram_base.py @@ -346,8 +346,7 @@ class sram_base(design): inputs.append("ADDR[{}]".format(i+self.col_addr_size)) outputs.append("A[{}]".format(i+self.col_addr_size)) - # FIXME clk->clk_buf - self.connect_inst(inputs + outputs + ["clk", "vdd", "gnd"]) + self.connect_inst(inputs + outputs + ["clk_buf", "vdd", "gnd"]) def add_col_addr_dff(self, position): From 36bfd2932a484fc21a47f173c1df53316e48f37a Mon Sep 17 00:00:00 2001 From: Matt Guthaus Date: Tue, 14 Aug 2018 10:51:02 -0700 Subject: [PATCH 7/7] Update delay results with new clock routing --- compiler/tests/21_hspice_delay_test.py | 36 +++++++++++------------ compiler/tests/21_ngspice_delay_test.py | 38 ++++++++++++------------- 2 files changed, 37 insertions(+), 37 deletions(-) diff --git a/compiler/tests/21_hspice_delay_test.py b/compiler/tests/21_hspice_delay_test.py index 9b9eb2bd..dd2d14de 100755 --- a/compiler/tests/21_hspice_delay_test.py +++ b/compiler/tests/21_hspice_delay_test.py @@ -51,27 +51,27 @@ class timing_sram_test(openram_test): data = d.analyze(probe_address, probe_data, slews, loads) if OPTS.tech_name == "freepdk45": - golden_data = {'delay_hl': [2.5614], - 'delay_lh': [0.22929839999999999], - 'leakage_power': 0.0020326, + golden_data = {'delay_hl': [2.5829000000000004], + 'delay_lh': [0.2255964], + 'leakage_power': 0.0019498999999999996, 'min_period': 4.844, - 'read0_power': [0.0497676], - 'read1_power': [0.0463576], - 'slew_hl': [0.1119293], - 'slew_lh': [0.0237043], - 'write0_power': [0.0494321], - 'write1_power': [0.0457268]} + 'read0_power': [0.055371399999999994], + 'read1_power': [0.0520225], + 'slew_hl': [0.0794261], + 'slew_lh': [0.0236264], + 'write0_power': [0.06545659999999999], + 'write1_power': [0.057846299999999996]} elif OPTS.tech_name == "scn3me_subm": - golden_data = {'delay_hl': [3.6602], - 'delay_lh': [2.2651], - 'leakage_power': 0.026040400000000002, + golden_data = {'delay_hl': [4.0249], + 'delay_lh': [2.2611], + 'leakage_power': 0.0257389, 'min_period': 4.688, - 'read0_power': [15.8985], - 'read1_power': [14.9719], - 'slew_hl': [1.1001], - 'slew_lh': [0.4111598], - 'write0_power': [19.4539], - 'write1_power': [16.8561]} + 'read0_power': [24.9279], + 'read1_power': [24.0219], + 'slew_hl': [0.8500753999999999], + 'slew_lh': [0.4122653], + 'write0_power': [28.197600000000005], + 'write1_power': [25.685]} else: self.assertTrue(False) # other techs fail # Check if no too many or too few results diff --git a/compiler/tests/21_ngspice_delay_test.py b/compiler/tests/21_ngspice_delay_test.py index 33fb0e9c..cd41c798 100755 --- a/compiler/tests/21_ngspice_delay_test.py +++ b/compiler/tests/21_ngspice_delay_test.py @@ -50,27 +50,27 @@ class timing_sram_test(openram_test): data = d.analyze(probe_address, probe_data, slews, loads) if OPTS.tech_name == "freepdk45": - golden_data = {'delay_hl': [2.562671], - 'delay_lh': [0.2320771], - 'leakage_power': 0.00102373, + golden_data = {'delay_hl': [2.584251], + 'delay_lh': [0.22870469999999998], + 'leakage_power': 0.0009567935, 'min_period': 4.844, - 'read0_power': [0.047404110000000006], - 'read1_power': [0.0438884], - 'slew_hl': [0.1140206], - 'slew_lh': [0.02492785], - 'write0_power': [0.04765188], - 'write1_power': [0.04434999]} + 'read0_power': [0.0547588], + 'read1_power': [0.051159970000000006], + 'slew_hl': [0.08164099999999999], + 'slew_lh': [0.025474979999999998], + 'write0_power': [0.06513271999999999], + 'write1_power': [0.058057000000000004]} elif OPTS.tech_name == "scn3me_subm": - golden_data = {'delay_hl': [3.8551919999999997], - 'delay_lh': [2.649183], - 'leakage_power': 0.001692146, - 'min_period': 4.688, - 'read0_power': [17.34118], - 'read1_power': [16.63607], - 'slew_hl': [1.257066], - 'slew_lh': [1.211681], - 'write0_power': [21.73913], - 'write1_power': [18.39621]} + golden_data = {'delay_hl': [4.221382999999999], + 'delay_lh': [2.6459520000000003], + 'leakage_power': 0.0013865260000000001, + 'min_period': 4.688, + 'read0_power': [26.699669999999998], + 'read1_power': [26.13123], + 'slew_hl': [0.9821776000000001], + 'slew_lh': [1.5791520000000001], + 'write0_power': [30.71939], + 'write1_power': [27.44753]} else: self.assertTrue(False) # other techs fail