diff --git a/compiler/tests/diff b/compiler/tests/diff deleted file mode 100644 index 4d294794..00000000 --- a/compiler/tests/diff +++ /dev/null @@ -1,1166 +0,0 @@ -diff --git a/compiler/base/geometry.py b/compiler/base/geometry.py -index 32af7ee9..99490eb3 100644 ---- a/compiler/base/geometry.py -+++ b/compiler/base/geometry.py -@@ -12,6 +12,8 @@ import debug - from vector import vector - import tech - import math -+import copy -+import numpy as np - from globals import OPTS - from utils import round_to_grid - -@@ -269,6 +271,134 @@ class instance(geometry): - p.transform(self.offset, self.mirror, self.rotate) - new_pins.append(p) - return new_pins -+ -+ def calculate_transform(self, node): -+ #set up the rotation matrix -+ angle = math.radians(float(node.rotate)) -+ mRotate = np.array([[math.cos(angle),-math.sin(angle),0.0], -+ [math.sin(angle),math.cos(angle),0.0], -+ [0.0,0.0,1.0]]) -+ -+ #set up translation matrix -+ translateX = float(node.offset[0]) -+ translateY = float(node.offset[1]) -+ mTranslate = np.array([[1.0,0.0,translateX], -+ [0.0,1.0,translateY], -+ [0.0,0.0,1.0]]) -+ -+ #set up the scale matrix (handles mirror X) -+ scaleX = 1.0 -+ if(node.mirror == 'MX'): -+ scaleY = -1.0 -+ else: -+ scaleY = 1.0 -+ mScale = np.array([[scaleX,0.0,0.0], -+ [0.0,scaleY,0.0], -+ [0.0,0.0,1.0]]) -+ -+ return (mRotate, mScale, mTranslate) -+ -+ def apply_transform(self, mtransforms, uVector, vVector, origin): -+ origin = np.dot(mtransforms[0], origin) #rotate -+ uVector = np.dot(mtransforms[0], uVector) #rotate -+ vVector = np.dot(mtransforms[0], vVector) #rotate -+ origin = np.dot(mtransforms[1], origin) #scale -+ uVector = np.dot(mtransforms[1], uVector) #scale -+ vVector = np.dot(mtransforms[1], vVector) #scale -+ origin = np.dot(mtransforms[2], origin) -+ -+ return(uVector, vVector, origin) -+ -+ def apply_path_transform(self, path): -+ uVector = np.array([[1.0],[0.0],[0.0]]) -+ vVector = np.array([[0.0],[1.0],[0.0]]) -+ origin = np.array([[0.0],[0.0],[1.0]]) -+ -+ while(path): -+ instance = path.pop(-1) -+ mtransforms = self.calculate_transform(instance) -+ (uVector, vVector, origin) = self.apply_transform(mtransforms, uVector, vVector, origin) -+ -+ return (uVector, vVector, origin) -+ -+ def reverse_transformation_bitcell(self, cell_name): -+ path = [] # path currently follwed in bitcell search -+ cell_paths = [] # saved paths to bitcells -+ origin_offsets = [] # cell to bank offset -+ Q_offsets = [] # Q to cell offet -+ Q_bar_offsets = [] # Q_bar to cell offset -+ bl_offsets = [] # bl to cell offset -+ br_offsets = [] # br to cell offset -+ bl_meta = [] # bl offset metadata (row,col,name) -+ br_meta = [] #br offset metadata (row,col,name) -+ -+ def walk_subtree(node): -+ path.append(node) -+ -+ if node.mod.name == cell_name: -+ cell_paths.append(copy.copy(path)) -+ -+ inst_name = path[-1].name -+ -+ # get the row and col names from the path -+ row = int(path[-1].name.split('_')[-2][1:]) -+ col = int(path[-1].name.split('_')[-1][1:]) -+ -+ cell_bl_meta = [] -+ cell_br_meta = [] -+ -+ normalized_storage_nets = node.mod.get_normalized_storage_nets_offset() -+ (normalized_bl_offsets, normalized_br_offsets, bl_names, br_names) = node.mod.get_normalized_bitline_offset() -+ -+ for offset in range(len(normalized_bl_offsets)): -+ for port in range(len(bl_names)): -+ cell_bl_meta.append([bl_names[offset], row, col, port]) -+ -+ for offset in range(len(normalized_br_offsets)): -+ for port in range(len(br_names)): -+ cell_br_meta.append([br_names[offset], row, col, port]) -+ -+ Q_x = normalized_storage_nets[0][0] -+ Q_y = normalized_storage_nets[0][1] -+ -+ Q_bar_x = normalized_storage_nets[1][0] -+ Q_bar_y = normalized_storage_nets[1][1] -+ -+ if node.mirror == 'MX': -+ Q_y = -1 * Q_y -+ Q_bar_y = -1 * Q_bar_y -+ -+ for pair in range(len(normalized_bl_offsets)): -+ normalized_bl_offsets[pair] = (normalized_bl_offsets[pair][0], -+ -1 * normalized_bl_offsets[pair][1]) -+ -+ for pair in range(len(normalized_br_offsets)): -+ normalized_br_offsets[pair] = (normalized_br_offsets[pair][0], -+ -1 * normalized_br_offsets[pair][1]) -+ -+ -+ Q_offsets.append([Q_x, Q_y]) -+ Q_bar_offsets.append([Q_bar_x, Q_bar_y]) -+ -+ -+ bl_offsets.append(normalized_bl_offsets) -+ br_offsets.append(normalized_br_offsets) -+ -+ bl_meta.append(cell_bl_meta) -+ br_meta.append(cell_br_meta) -+ -+ elif node.mod.insts is not []: -+ for instance in node.mod.insts: -+ walk_subtree(instance) -+ path.pop(-1) -+ -+ walk_subtree(self) -+ for path in cell_paths: -+ vector_spaces = self.apply_path_transform(path) -+ origin = vector_spaces[2] -+ origin_offsets.append([origin[0], origin[1]]) -+ -+ return(origin_offsets, Q_offsets, Q_bar_offsets, bl_offsets, br_offsets, bl_meta, br_meta) - - def __str__(self): - """ override print function output """ -diff --git a/compiler/base/hierarchy_layout.py b/compiler/base/hierarchy_layout.py -index 8995488a..40f56263 100644 ---- a/compiler/base/hierarchy_layout.py -+++ b/compiler/base/hierarchy_layout.py -@@ -1324,6 +1324,8 @@ class layout(): - pdf.drawLayout() - pdf.writeToFile(pdf_name) - -+ -+ - def print_attr(self): - """Prints a list of attributes for the current layout object""" - debug.info(0, -diff --git a/compiler/bitcells/bitcell.py b/compiler/bitcells/bitcell.py -index e91d8c2f..c0aac690 100644 ---- a/compiler/bitcells/bitcell.py -+++ b/compiler/bitcells/bitcell.py -@@ -51,7 +51,7 @@ class bitcell(bitcell_base.bitcell_base): - self.add_pin_types(self.type_list) - self.nets_match = self.do_nets_exist(self.storage_nets) - -- debug.check(OPTS.tech_name != "sky130", "sky130 does not yet support single port cells") -+# debug.check(OPTS.tech_name != "sky130", "sky130 does not yet support single port cells") - - def get_all_wl_names(self): - """ Creates a list of all wordline pin names """ -diff --git a/compiler/bitcells/bitcell_base.py b/compiler/bitcells/bitcell_base.py -index 5265904b..58f7bdcb 100644 ---- a/compiler/bitcells/bitcell_base.py -+++ b/compiler/bitcells/bitcell_base.py -@@ -8,8 +8,9 @@ - - import debug - import design -+from globals import OPTS - import logical_effort --from tech import parameter, drc -+from tech import parameter, drc, layer - - - class bitcell_base(design.design): -@@ -78,7 +79,85 @@ class bitcell_base(design.design): - fmt_str = "Storage nodes={} not found in spice file." - debug.info(1, fmt_str.format(self.storage_nets)) - return None -- -+ -+ def get_storage_net_offset(self): -+ """ -+ Gets the location of the storage net labels to add top level -+ labels for pex simulation. -+ """ -+ # If we generated the bitcell, we already know where Q and Q_bar are -+ if OPTS.bitcell is not "pbitcell": -+ self.storage_net_offsets = [] -+ for i in range(len(self.get_storage_net_names())): -+ for text in self.gds.getTexts(layer["metal1"]): -+ if self.storage_nets[i] == text.textString.rstrip('\x00'): -+ self.storage_net_offsets.append(text.coordinates[0]) -+ -+ for i in range(len(self.storage_net_offsets)): -+ self.storage_net_offsets[i] = tuple([self.gds.info["units"][0] * x for x in self.storage_net_offsets[i]]) -+ -+ -+ return(self.storage_net_offsets) -+ -+ def get_bitline_offset(self): -+ -+ bl_names = self.get_all_bl_names() -+ br_names = self.get_all_br_names() -+ -+ found_bl = [] -+ found_br = [] -+ -+ self.bl_offsets = [] -+ self.br_offsets = [] -+ -+ for i in range(len(bl_names)): -+ for text in self.gds.getTexts(layer["metal2"]): -+ if not bl_names[i] in found_bl: -+ if bl_names[i] == text.textString.rstrip('\x00'): -+ self.bl_offsets.append(text.coordinates[0]) -+ found_bl.append(bl_names[i]) -+ -+ continue -+ -+ for i in range(len(br_names)): -+ for text in self.gds.getTexts(layer["metal2"]): -+ if not br_names[i] in found_br: -+ if br_names[i] == text.textString.rstrip('\x00'): -+ self.br_offsets.append(text.coordinates[0]) -+ found_br.append(br_names[i]) -+ continue -+ -+ for i in range(len(self.bl_offsets)): -+ self.bl_offsets[i] = tuple([self.gds.info["units"][0] * x for x in self.bl_offsets[i]]) -+ -+ for i in range(len(self.br_offsets)): -+ self.br_offsets[i] = tuple([self.gds.info["units"][0] * x for x in self.br_offsets[i]]) -+ -+ return(self.bl_offsets, self.br_offsets, found_bl, found_br) -+ -+ def get_normalized_storage_nets_offset(self): -+ """ -+ Convert storage net offset to be relative to the bottom left corner -+ of the bitcell. This is useful for making sense of offsets outside -+ of the bitcell. -+ """ -+ if OPTS.bitcell is not "pbitcell": -+ normalized_storage_net_offset = self.get_storage_net_offset() -+ -+ else: -+ net_offset = self.get_storage_net_offset() -+ Q_x = net_offset[0][0] - self.leftmost_xpos -+ Q_y = net_offset[0][1] - self.botmost_ypos -+ Q_bar_x = net_offset[1][0] - self.leftmost_xpos -+ Q_bar_y = net_offset[1][1] - self.botmost_ypos -+ -+ normalized_storage_net_offset = [[Q_x,Q_y],[Q_bar_x,Q_bar_y]] -+ -+ return normalized_storage_net_offset -+ -+ def get_normalized_bitline_offset(self): -+ return self.get_bitline_offset() -+ - def build_graph(self, graph, inst_name, port_nets): - """ - By default, bitcells won't be part of the graph. -diff --git a/compiler/bitcells/pbitcell.py b/compiler/bitcells/pbitcell.py -index aea7a6dc..98e477d8 100644 ---- a/compiler/bitcells/pbitcell.py -+++ b/compiler/bitcells/pbitcell.py -@@ -26,7 +26,7 @@ class pbitcell(bitcell_base.bitcell_base): - self.num_w_ports = OPTS.num_w_ports - self.num_r_ports = OPTS.num_r_ports - self.total_ports = self.num_rw_ports + self.num_w_ports + self.num_r_ports -- -+ - self.replica_bitcell = replica_bitcell - self.dummy_bitcell = dummy_bitcell - -@@ -152,7 +152,7 @@ class pbitcell(bitcell_base.bitcell_base): - self.Q_bar = "Q_bar" - self.Q = "Q" - self.storage_nets = [self.Q, self.Q_bar] -- -+ - def add_modules(self): - """ Determine size of transistors and add ptx modules """ - # if there are any read/write ports, -@@ -352,6 +352,11 @@ class pbitcell(bitcell_base.bitcell_base): - self.right_building_edge = right_inverter_xpos \ - + self.inverter_nmos.active_width - -+ def add_pex_labels(self, left_inverter_offset, right_inverter_offset): -+ self.add_label("Q", "metal1", left_inverter_offset) -+ self.add_label("Q_bar", "metal1", right_inverter_offset) -+ self.storage_net_offsets = [left_inverter_offset, right_inverter_offset] -+ - def route_storage(self): - """ Routes inputs and outputs of inverters to cross couple them """ - # connect input (gate) of inverters -@@ -397,6 +402,16 @@ class pbitcell(bitcell_base.bitcell_base): - contact_offset_right.y) - self.add_path("poly", [contact_offset_right, gate_offset_left]) - -+ # add labels to cross couple inverter for extracted simulation -+ contact_offset_left_output = vector(self.inverter_nmos_left.get_pin("D").rc().x \ -+ + 0.5 * contact.poly.height, -+ self.cross_couple_upper_ypos) -+ -+ contact_offset_right_output = vector(self.inverter_nmos_right.get_pin("S").lc().x \ -+ - 0.5*contact.poly.height, -+ self.cross_couple_lower_ypos) -+ self.add_pex_labels(contact_offset_left_output, contact_offset_right_output) -+ - def route_rails(self): - """ Adds gnd and vdd rails and connects them to the inverters """ - # Add rails for vdd and gnd -diff --git a/compiler/characterizer/delay.py b/compiler/characterizer/delay.py -index b7faaec3..21355b0e 100644 ---- a/compiler/characterizer/delay.py -+++ b/compiler/characterizer/delay.py -@@ -136,19 +136,18 @@ class delay(simulation): - """ - - self.bitline_volt_meas = [] -- - self.bitline_volt_meas.append(voltage_at_measure("v_bl_READ_ZERO", -- self.bl_name)) -+ self.bl_name)) - self.bitline_volt_meas[-1].meta_str = sram_op.READ_ZERO - self.bitline_volt_meas.append(voltage_at_measure("v_br_READ_ZERO", -- self.br_name)) -+ self.br_name)) - self.bitline_volt_meas[-1].meta_str = sram_op.READ_ZERO - - self.bitline_volt_meas.append(voltage_at_measure("v_bl_READ_ONE", -- self.bl_name)) -+ self.bl_name)) - self.bitline_volt_meas[-1].meta_str = sram_op.READ_ONE - self.bitline_volt_meas.append(voltage_at_measure("v_br_READ_ONE", -- self.br_name)) -+ self.br_name)) - self.bitline_volt_meas[-1].meta_str = sram_op.READ_ONE - return self.bitline_volt_meas - -@@ -229,8 +228,13 @@ class delay(simulation): - storage_names = cell_inst.mod.get_storage_net_names() - debug.check(len(storage_names) == 2, ("Only inverting/non-inverting storage nodes" - "supported for characterization. Storage nets={}").format(storage_names)) -- q_name = cell_name+'.'+str(storage_names[0]) -- qbar_name = cell_name+'.'+str(storage_names[1]) -+ if not OPTS.use_pex: -+ q_name = cell_name+'.'+str(storage_names[0]) -+ qbar_name = cell_name+'.'+str(storage_names[1]) -+ else: -+ bank_num = self.sram.get_bank_num(self.sram.name, bit_row, bit_col) -+ q_name = "bitcell_Q_b{0}_r{1}_c{2}".format(bank_num, bit_row, bit_col) -+ qbar_name = "bitcell_Q_bar_b{0}_r{1}_c{2}".format(bank_num, bit_row, bit_col) - - # Bit measures, measurements times to be defined later. The measurement names must be unique - # but they is enforced externally. {} added to names to differentiate between ports allow the -@@ -272,37 +276,50 @@ class delay(simulation): - """Sets important names for characterization such as Sense amp enable and internal bit nets.""" - - port = self.read_ports[0] -- self.graph.get_all_paths('{}{}'.format("clk", port), -- '{}{}_{}'.format(self.dout_name, port, self.probe_data)) -- -- sen_with_port = self.get_sen_name(self.graph.all_paths) -- if sen_with_port.endswith(str(port)): -- self.sen_name = sen_with_port[:-len(str(port))] -- else: -- self.sen_name = sen_with_port -- debug.warning("Error occurred while determining SEN name. Can cause faults in simulation.") -+ if not OPTS.use_pex: -+ self.graph.get_all_paths('{}{}'.format("clk", port), -+ '{}{}_{}'.format(self.dout_name, port, self.probe_data)) - -- debug.info(2,"s_en name = {}".format(self.sen_name)) -- -- bl_name_port, br_name_port = self.get_bl_name(self.graph.all_paths, port) -- port_pos = -1-len(str(self.probe_data))-len(str(port)) -- -- if bl_name_port.endswith(str(port)+"_"+str(self.probe_data)): -- self.bl_name = bl_name_port[:port_pos] +"{}"+ bl_name_port[port_pos+len(str(port)):] -- elif not bl_name_port[port_pos].isdigit(): # single port SRAM case, bl will not be numbered eg bl_0 -- self.bl_name = bl_name_port -- else: -- self.bl_name = bl_name_port -- debug.warning("Error occurred while determining bitline names. Can cause faults in simulation.") -+ sen_with_port = self.get_sen_name(self.graph.all_paths) -+ if sen_with_port.endswith(str(port)): -+ self.sen_name = sen_with_port[:-len(str(port))] -+ else: -+ self.sen_name = sen_with_port -+ debug.warning("Error occurred while determining SEN name. Can cause faults in simulation.") -+ -+ debug.info(2,"s_en name = {}".format(self.sen_name)) -+ -+ bl_name_port, br_name_port = self.get_bl_name(self.graph.all_paths, port) -+ port_pos = -1-len(str(self.probe_data))-len(str(port)) - -- if br_name_port.endswith(str(port)+"_"+str(self.probe_data)): -- self.br_name = br_name_port[:port_pos] +"{}"+ br_name_port[port_pos+len(str(port)):] -- elif not br_name_port[port_pos].isdigit(): # single port SRAM case, bl will not be numbered eg bl_0 -- self.br_name = br_name_port -+ if bl_name_port.endswith(str(port)+"_"+str(self.probe_data)): -+ self.bl_name = bl_name_port[:port_pos] +"{}"+ bl_name_port[port_pos+len(str(port)):] -+ elif not bl_name_port[port_pos].isdigit(): # single port SRAM case, bl will not be numbered eg bl_0 -+ self.bl_name = bl_name_port -+ else: -+ self.bl_name = bl_name_port -+ debug.warning("Error occurred while determining bitline names. Can cause faults in simulation.") -+ -+ if br_name_port.endswith(str(port)+"_"+str(self.probe_data)): -+ self.br_name = br_name_port[:port_pos] +"{}"+ br_name_port[port_pos+len(str(port)):] -+ elif not br_name_port[port_pos].isdigit(): # single port SRAM case, bl will not be numbered eg bl_0 -+ self.br_name = br_name_port -+ else: -+ self.br_name = br_name_port -+ debug.warning("Error occurred while determining bitline names. Can cause faults in simulation.") -+ debug.info(2,"bl name={}, br name={}".format(self.bl_name,self.br_name)) - else: -- self.br_name = br_name_port -- debug.warning("Error occurred while determining bitline names. Can cause faults in simulation.") -- debug.info(2,"bl name={}, br name={}".format(self.bl_name,self.br_name)) -+ self.graph.get_all_paths('{}{}'.format("clk", port), -+ '{}{}_{}'.format(self.dout_name, port, self.probe_data)) -+ -+ self.sen_name = self.get_sen_name(self.graph.all_paths) -+ debug.info(2,"s_en name = {}".format(self.sen_name)) -+ -+ -+ self.bl_name = "bl{0}_{1}".format(port, OPTS.word_size-1) -+ self.br_name = "br{0}_{1}".format(port, OPTS.word_size-1) -+ debug.info(2,"bl name={}, br name={}".format(self.bl_name,self.br_name)) -+ - - def get_sen_name(self, paths, assumed_port=None): - """ -@@ -316,7 +333,8 @@ class delay(simulation): - debug.check(len(sa_mods) == 1, "Only expected one type of Sense Amp. Cannot perform s_en checks.") - enable_name = sa_mods[0].get_enable_name() - sen_name = self.get_alias_in_path(paths, enable_name, sa_mods[0]) -- -+ if OPTS.use_pex: -+ sen_name = sen_name.split('.')[-1] - return sen_name - - def get_bl_name(self, paths, port): -@@ -332,7 +350,9 @@ class delay(simulation): - exclude_set = self.get_bl_name_search_exclusions() - for int_net in [cell_bl, cell_br]: - bl_names.append(self.get_alias_in_path(paths, int_net, cell_mod, exclude_set)) -- -+ if OPTS.use_pex: -+ for i in range(len(bl_names)): -+ bl_names[i] = bl_names[i].split('.')[-1] - return bl_names[0], bl_names[1] - - -@@ -423,8 +443,13 @@ class delay(simulation): - - # instantiate the sram - self.sf.write("\n* Instantiation of the SRAM\n") -- self.stim.inst_model(pins=self.pins, -- model_name=self.sram.name) -+ if not OPTS.use_pex: -+ self.stim.inst_model(pins=self.pins, -+ model_name=self.sram.name) -+ else: -+ self.stim.inst_sram_pex(pins=self.pins, -+ model_name=self.sram.name) -+ - self.sf.write("\n* SRAM output loads\n") - for port in self.read_ports: - for i in range(self.word_size): -diff --git a/compiler/characterizer/stimuli.py b/compiler/characterizer/stimuli.py -index 11dc449a..90fd6213 100644 ---- a/compiler/characterizer/stimuli.py -+++ b/compiler/characterizer/stimuli.py -@@ -56,7 +56,30 @@ class stimuli(): - for pin in pins: - self.sf.write("{0} ".format(pin)) - self.sf.write("{0}\n".format(model_name)) -- -+ -+ def inst_sram_pex(self, pins, model_name): -+ self.sf.write("X{0} ".format(model_name)) -+ for pin in pins: -+ self.sf.write("{0} ".format(pin)) -+ for bank in range(OPTS.num_banks): -+ row = int(OPTS.num_words / OPTS.words_per_row) - 1 -+ col = int(OPTS.word_size * OPTS.words_per_row) - 1 -+ self.sf.write("bitcell_Q_b{0}_r{1}_c{2} ".format(bank,row,col)) -+ self.sf.write("bitcell_Q_bar_b{0}_r{1}_c{2} ".format(bank,row,col)) -+ # can't add all bitcells to top level due to ngspice max port count of 1005 -+ # for row in range(int(OPTS.num_words / OPTS.words_per_row)): -+ # for col in range(int(OPTS.word_size * OPTS.words_per_row)): -+ # self.sf.write("bitcell_Q_b{0}_r{1}_c{2} ".format(bank,row,col)) -+ # self.sf.write("bitcell_Q_bar_b{0}_r{1}_c{2} ".format(bank,row,col)) -+ for bank in range(OPTS.num_banks): -+ for col in range(OPTS.word_size * OPTS.words_per_row): -+ for port in range(OPTS.num_r_ports + OPTS.num_w_ports + OPTS.num_rw_ports): -+ self.sf.write("bl{0}_{1} ".format(port, col)) -+ self.sf.write("br{0}_{1} ".format(port, col)) -+ -+ -+ self.sf.write("s_en{0} ".format(bank)) -+ self.sf.write("{0}\n".format(model_name)) - - def create_inverter(self, size=1, beta=2.5): - """ Generates inverter for the top level signals (only for sim purposes) """ -diff --git a/compiler/example_configs/example_config_1w_1r_scn4m_subm.py b/compiler/example_configs/example_config_1w_1r_scn4m_subm.py -index 55ac4016..7698f1a3 100644 ---- a/compiler/example_configs/example_config_1w_1r_scn4m_subm.py -+++ b/compiler/example_configs/example_config_1w_1r_scn4m_subm.py -@@ -1,9 +1,9 @@ - word_size = 2 - num_words = 16 - --num_rw_ports = 1 -+num_rw_ports = 0 - num_r_ports = 1 --num_w_ports = 0 -+num_w_ports = 1 - - tech_name = "scn4m_subm" - nominal_corners_only = False -diff --git a/compiler/modules/bank.py b/compiler/modules/bank.py -index 158ac37b..1efc3b13 100644 ---- a/compiler/modules/bank.py -+++ b/compiler/modules/bank.py -@@ -74,7 +74,6 @@ class bank(design.design): - self.bank_array_ll = self.offset_all_coordinates().scale(-1, -1) - self.bank_array_ur = self.bitcell_array_inst.ur() - self.bank_array_ul = self.bitcell_array_inst.ul() -- - self.DRC_LVS() - - def add_pins(self): -@@ -1022,7 +1021,7 @@ class bank(design.design): - inp_is_rise) - - return stage_effort_list -- -+ - def get_wl_en_cin(self): - """Get the relative capacitance of all the clk connections in the bank""" - # wl_en only used in the wordline driver. -diff --git a/compiler/modules/control_logic.py b/compiler/modules/control_logic.py -index a4e26a6f..8c037ef1 100644 ---- a/compiler/modules/control_logic.py -+++ b/compiler/modules/control_logic.py -@@ -869,7 +869,6 @@ class control_logic(design.design): - offset=pin.ll(), - height=pin.height(), - width=pin.width()) -- - def get_delays_to_wl(self): - """Get the delay (in delay units) of the clk to a wordline in the bitcell array""" - debug.check(self.sram.all_mods_except_control_done, "Cannot calculate sense amp enable delay unless all module have been added.") -diff --git a/compiler/sram/sram_1bank.py b/compiler/sram/sram_1bank.py -index 18f3414c..42fc3646 100644 ---- a/compiler/sram/sram_1bank.py -+++ b/compiler/sram/sram_1bank.py -@@ -579,5 +579,8 @@ class sram_1bank(sram_base): - """Gets the spice name of the target bitcell.""" - # Sanity check in case it was forgotten - if inst_name.find('x') != 0: -- inst_name = 'x' + inst_name -- return self.bank_inst.mod.get_cell_name(inst_name + '.x' + self.bank_inst.name, row, col) -+ inst_name = 'x'+inst_name -+ return self.bank_inst.mod.get_cell_name(inst_name+'.x'+self.bank_inst.name, row, col) -+ -+ def get_bank_num(self, inst_name, row, col): -+ return 0; -diff --git a/compiler/sram/sram_base.py b/compiler/sram/sram_base.py -index 12af7cf6..6dc98835 100644 ---- a/compiler/sram/sram_base.py -+++ b/compiler/sram/sram_base.py -@@ -15,6 +15,9 @@ from design import design - from verilog import verilog - from lef import lef - from sram_factory import factory -+from tech import drc -+import numpy as np -+import logical_effort - - - class sram_base(design, verilog, lef): -@@ -84,8 +87,71 @@ class sram_base(design, verilog, lef): - for bit in range(self.word_size + self.num_spare_cols): - self.add_pin("dout{0}[{1}]".format(port, bit), "OUTPUT") - -- self.add_pin("vdd", "POWER") -- self.add_pin("gnd", "GROUND") -+ self.add_pin("vdd","POWER") -+ self.add_pin("gnd","GROUND") -+ -+ def add_global_pex_labels(self): -+ """ -+ Add pex labels at the sram level for spice analysis -+ """ -+ -+ # add pex labels for bitcells -+ for bank_num in range(len(self.bank_insts)): -+ bank = self.bank_insts[bank_num] -+ pex_data = bank.reverse_transformation_bitcell(bank.mod.bitcell.name) -+ -+ bank_offset = pex_data[0] # offset bank relative to sram -+ Q_offset = pex_data[1] # offset of storage relative to bank -+ Q_bar_offset = pex_data[2] # offset of storage relative to bank -+ bl_offsets = pex_data[3] -+ br_offsets = pex_data[4] -+ bl_meta = pex_data[5] -+ br_meta = pex_data[6] -+ -+ bl = [] -+ br = [] -+ -+ storage_layer_name = "metal1" -+ bitline_layer_name = "metal2" -+ -+ for cell in range(len(bank_offset)): -+ Q = [bank_offset[cell][0] + Q_offset[cell][0], bank_offset[cell][1] + Q_offset[cell][1]] -+ Q_bar = [bank_offset[cell][0] + Q_bar_offset[cell][0], bank_offset[cell][1] + Q_bar_offset[cell][1]] -+ OPTS.words_per_row = self.words_per_row -+ self.add_layout_pin_rect_center("bitcell_Q_b{0}_r{1}_c{2}".format(bank_num, int(cell % (OPTS.num_words / self.words_per_row)), int(cell / (OPTS.word_size * self.words_per_row))) , storage_layer_name, Q) -+ self.add_layout_pin_rect_center("bitcell_Q_bar_b{0}_r{1}_c{2}".format(bank_num, int(cell % (OPTS.num_words / self.words_per_row)), int(cell / (OPTS.word_size * self.words_per_row))), storage_layer_name, Q_bar) -+ -+ for cell in range(len(bl_offsets)): -+ col = bl_meta[cell][0][2] -+ for bitline in range(len(bl_offsets[cell])): -+ bitline_location = [float(bank_offset[cell][0]) + bl_offsets[cell][bitline][0], float(bank_offset[cell][1]) + bl_offsets[cell][bitline][1]] -+ bl.append([bitline_location, bl_meta[cell][bitline][3], col]) -+ -+ for cell in range(len(br_offsets)): -+ col = br_meta[cell][0][2] -+ for bitline in range(len(br_offsets[cell])): -+ bitline_location = [float(bank_offset[cell][0]) + br_offsets[cell][bitline][0], float(bank_offset[cell][1]) + br_offsets[cell][bitline][1]] -+ br.append([bitline_location, br_meta[cell][bitline][3], col]) -+ -+ for i in range(len(bl)): -+ self.add_layout_pin_rect_center("bl{0}_{1}".format(bl[i][1], bl[i][2]), bitline_layer_name, bl[i][0]) -+ -+ for i in range(len(br)): -+ self.add_layout_pin_rect_center("br{0}_{1}".format(br[i][1], br[i][2]), bitline_layer_name, br[i][0]) -+ -+ # add pex labels for control logic -+ for i in range (len(self.control_logic_insts)): -+ instance = self.control_logic_insts[i] -+ control_logic_offset = instance.offset -+ for output in instance.mod.output_list: -+ pin = instance.mod.get_pin(output) -+ pin.transform([0,0], instance.mirror, instance.rotate) -+ offset = [control_logic_offset[0] + pin.center()[0], control_logic_offset[1] + pin.center()[1]] -+ self.add_layout_pin_rect_center("{0}{1}".format(pin.name,i), storage_layer_name, offset) -+ -+ -+ -+ - - def create_netlist(self): - """ Netlist creation """ -@@ -124,6 +190,8 @@ class sram_base(design, verilog, lef): - highest_coord = self.find_highest_coords() - self.width = highest_coord[0] - self.height = highest_coord[1] -+ if OPTS.use_pex: -+ self.add_global_pex_labels() - self.add_boundary(ll=vector(0, 0), - ur=vector(self.width, self.height)) - -diff --git a/compiler/tests/06_hierarchical_decoder_test.py b/compiler/tests/06_hierarchical_decoder_test.py -index e2b34cba..452ddeb8 100755 ---- a/compiler/tests/06_hierarchical_decoder_test.py -+++ b/compiler/tests/06_hierarchical_decoder_test.py -@@ -22,19 +22,19 @@ class hierarchical_decoder_test(openram_test): - globals.init_openram(config_file) - - # Checks 2x4 and 2-input NAND decoder -- debug.info(1, "Testing 16 row sample for hierarchical_decoder") -- a = factory.create(module_type="hierarchical_decoder", num_outputs=16) -- self.local_check(a) -+ #debug.info(1, "Testing 16 row sample for hierarchical_decoder") -+ #a = factory.create(module_type="hierarchical_decoder", num_outputs=16) -+ #self.local_check(a) - - # Checks 2x4 and 2-input NAND decoder with non-power-of-two -- debug.info(1, "Testing 17 row sample for hierarchical_decoder") -- a = factory.create(module_type="hierarchical_decoder", num_outputs=17) -- self.local_check(a) -+ #debug.info(1, "Testing 17 row sample for hierarchical_decoder") -+ #a = factory.create(module_type="hierarchical_decoder", num_outputs=17) -+ #self.local_check(a) - - # Checks 2x4 with 3x8 and 2-input NAND decoder -- debug.info(1, "Testing 32 row sample for hierarchical_decoder") -- a = factory.create(module_type="hierarchical_decoder", num_outputs=32) -- self.local_check(a) -+ #debug.info(1, "Testing 32 row sample for hierarchical_decoder") -+ #a = factory.create(module_type="hierarchical_decoder", num_outputs=32) -+ #self.local_check(a) - - # Checks 3 x 2x4 and 3-input NAND decoder - debug.info(1, "Testing 64 row sample for hierarchical_decoder") -diff --git a/compiler/verify/magic.py b/compiler/verify/magic.py -index ef98a09b..1be2f2cd 100644 ---- a/compiler/verify/magic.py -+++ b/compiler/verify/magic.py -@@ -107,21 +107,21 @@ def write_magic_script(cell_name, extract=False, final_verification=False): - # f.write(pre + "ext2spice hierarchy on\n") - # f.write(pre + "ext2spice scale off\n") - # lvs exists in 8.2.79, but be backword compatible for now -- # f.write(pre + "ext2spice lvs\n") -- f.write(pre + "ext2spice hierarchy on\n") -- f.write(pre + "ext2spice format ngspice\n") -- f.write(pre + "ext2spice cthresh infinite\n") -- f.write(pre + "ext2spice rthresh infinite\n") -- f.write(pre + "ext2spice renumber off\n") -- f.write(pre + "ext2spice scale off\n") -- f.write(pre + "ext2spice blackbox on\n") -- f.write(pre + "ext2spice subcircuit top auto\n") -- f.write(pre + "ext2spice global off\n") -+ #f.write(pre+"ext2spice lvs\n") -+ f.write(pre+"ext2spice hierarchy on\n") -+ f.write(pre+"ext2spice format ngspice\n") -+ f.write(pre+"ext2spice cthresh infinite\n") -+ f.write(pre+"ext2spice rthresh infinite\n") -+ f.write(pre+"ext2spice renumber off\n") -+ f.write(pre+"ext2spice scale off\n") -+ f.write(pre+"ext2spice blackbox on\n") -+ f.write(pre+"ext2spice subcircuit top on\n") -+ f.write(pre+"ext2spice global off\n") - - # Can choose hspice, ngspice, or spice3, - # but they all seem compatible enough. -- #f.write(pre + "ext2spice format ngspice\n") -- f.write(pre + "ext2spice {}\n".format(cell_name)) -+ f.write(pre+"ext2spice format ngspice\n") -+ f.write(pre+"ext2spice {}\n".format(cell_name)) - f.write("quit -noprompt\n") - f.write("EOF\n") - -@@ -411,13 +411,13 @@ def write_script_pex_rule(gds_name,cell_name,output): - else: - pre = "" - f.write(pre+"extract\n".format(cell_name)) -- #f.write(pre+"ext2spice hierarchy on\n") -- #f.write(pre+"ext2spice format ngspice\n") -- #f.write(pre+"ext2spice renumber off\n") -- #f.write(pre+"ext2spice scale off\n") -- #f.write(pre+"ext2spice blackbox on\n") -+ f.write(pre+"ext2spice hierarchy off\n") -+ f.write(pre+"ext2spice format ngspice\n") -+ f.write(pre+"ext2spice renumber off\n") -+ f.write(pre+"ext2spice scale off\n") -+ f.write(pre+"ext2spice blackbox on\n") - f.write(pre+"ext2spice subcircuit top on\n") -- #f.write(pre+"ext2spice global off\n") -+ f.write(pre+"ext2spice global off\n") - f.write(pre+"ext2spice {}\n".format(cell_name)) - f.write("quit -noprompt\n") - f.write("eof\n") -@@ -440,31 +440,48 @@ def correct_port(name, output_file_name, ref_file_name): - pex_file = open(output_file_name, "r") - contents = pex_file.read() - # locate the start of circuit definition line -- match = re.search(".subckt " + str(name) + ".*", contents) -+ match = re.search(r'^\.subckt+[^M]*', contents, re.MULTILINE) - match_index_start = match.start() -- pex_file.seek(match_index_start) -- rest_text = pex_file.read() -- # locate the end of circuit definition line -- match = re.search(r'\n', rest_text) -- match_index_end = match.start() -+ match_index_end = match.end() - # store the unchanged part of pex file in memory - pex_file.seek(0) - part1 = pex_file.read(match_index_start) -- pex_file.seek(match_index_start + match_index_end) -+ pex_file.seek(match_index_end) - part2 = pex_file.read() -+ -+ bitcell_list = "+ " -+ for bank in range(OPTS.num_banks): -+ for bank in range(OPTS.num_banks): -+ row = int(OPTS.num_words / OPTS.words_per_row) - 1 -+ col = int(OPTS.word_size * OPTS.words_per_row) - 1 -+ bitcell_list += "bitcell_Q_b{0}_r{1}_c{2} ".format(bank,row,col) -+ bitcell_list += "bitcell_Q_bar_b{0}_r{1}_c{2} ".format(bank,row,col) -+ for col in range(OPTS.word_size * OPTS.words_per_row): -+ for port in range(OPTS.num_r_ports + OPTS.num_w_ports + OPTS.num_rw_ports): -+ bitcell_list += "bl{0}_{1} ".format(bank, col) -+ bitcell_list += "br{0}_{1} ".format(bank, col) -+ bitcell_list += "\n" -+ -+ control_list = "+ " -+ for bank in range(OPTS.num_banks): -+ control_list += "s_en{0}".format(bank) -+ control_list += '\n' -+ -+ part2 = bitcell_list + control_list + part2 -+ - pex_file.close() - - # obtain the correct definition line from the original spice file - sp_file = open(ref_file_name, "r") - contents = sp_file.read() -- circuit_title = re.search(".SUBCKT " + str(name) + ".*\n", contents) -+ circuit_title = re.search(".SUBCKT " + str(name) + ".*", contents) - circuit_title = circuit_title.group() - sp_file.close() - - # write the new pex file with info in the memory - output_file = open(output_file_name, "w") - output_file.write(part1) -- output_file.write(circuit_title) -+ output_file.write(circuit_title+'\n') - output_file.write(part2) - output_file.close() - -@@ -473,4 +490,4 @@ def print_drc_stats(): - def print_lvs_stats(): - debug.info(1,"LVS runs: {0}".format(num_lvs_runs)) - def print_pex_stats(): -- debug.info(1,"PEX runs: {0}".format(num_pex_runs)) -+ debug.info(1,"PEX runs: {0}".format(num_pex_runs)) -\ No newline at end of file -diff --git a/technology/scn4m_subm/gds_lib/cell_1w_1r.gds b/technology/scn4m_subm/gds_lib/cell_1w_1r.gds -index 782c43dc..06f79ba5 100644 -Binary files a/technology/scn4m_subm/gds_lib/cell_1w_1r.gds and b/technology/scn4m_subm/gds_lib/cell_1w_1r.gds differ -diff --git a/technology/scn4m_subm/gds_lib/cell_6t.gds b/technology/scn4m_subm/gds_lib/cell_6t.gds -index 14d6ab7e..6bfc4431 100644 -Binary files a/technology/scn4m_subm/gds_lib/cell_6t.gds and b/technology/scn4m_subm/gds_lib/cell_6t.gds differ -diff --git a/technology/scn4m_subm/gds_lib/dff.gds b/technology/scn4m_subm/gds_lib/dff.gds -index 7825c3bc..ca6d2b6d 100644 -Binary files a/technology/scn4m_subm/gds_lib/dff.gds and b/technology/scn4m_subm/gds_lib/dff.gds differ -diff --git a/technology/scn4m_subm/gds_lib/replica_cell_6t.gds b/technology/scn4m_subm/gds_lib/replica_cell_6t.gds -index 191f1206..30f5a37e 100644 -Binary files a/technology/scn4m_subm/gds_lib/replica_cell_6t.gds and b/technology/scn4m_subm/gds_lib/replica_cell_6t.gds differ -diff --git a/technology/scn4m_subm/gds_lib/sense_amp.gds b/technology/scn4m_subm/gds_lib/sense_amp.gds -index cf5fa587..5ffbb0d5 100644 -Binary files a/technology/scn4m_subm/gds_lib/sense_amp.gds and b/technology/scn4m_subm/gds_lib/sense_amp.gds differ -diff --git a/technology/scn4m_subm/gds_lib/tri_gate.gds b/technology/scn4m_subm/gds_lib/tri_gate.gds -index ad83f4c6..088e8870 100644 -Binary files a/technology/scn4m_subm/gds_lib/tri_gate.gds and b/technology/scn4m_subm/gds_lib/tri_gate.gds differ -diff --git a/technology/scn4m_subm/gds_lib/write_driver.gds b/technology/scn4m_subm/gds_lib/write_driver.gds -index 8223c795..9e201f24 100644 -Binary files a/technology/scn4m_subm/gds_lib/write_driver.gds and b/technology/scn4m_subm/gds_lib/write_driver.gds differ -diff --git a/technology/scn4m_subm/mag_lib/cell_1rw_1r.mag b/technology/scn4m_subm/mag_lib/cell_1rw_1r.mag -index 9aec1c5d..0484df70 100644 ---- a/technology/scn4m_subm/mag_lib/cell_1rw_1r.mag -+++ b/technology/scn4m_subm/mag_lib/cell_1rw_1r.mag -@@ -1,6 +1,6 @@ - magic - tech scmos --timestamp 1542220294 -+timestamp 1577066542 - << nwell >> - rect 0 46 54 75 - << pwell >> -@@ -47,12 +47,17 @@ rect 17 33 21 37 - rect 25 29 29 37 - rect 33 33 37 37 - rect 41 33 45 37 -+rect 9 17 13 21 - rect 25 17 29 23 -+rect 41 17 45 21 - << pdcontact >> - rect 17 54 21 58 -+rect 25 54 29 58 - rect 33 54 37 58 - << psubstratepcontact >> - rect 25 9 29 13 -+<< nsubstratencontact >> -+rect 25 68 29 72 - << polysilicon >> - rect 22 57 24 60 - rect 30 57 32 60 -@@ -103,19 +108,16 @@ rect 0 2 16 6 - rect 20 2 34 6 - rect 38 2 54 6 - << m2contact >> -+rect 25 68 29 72 -+rect 25 54 29 58 - rect 2 33 6 37 - rect 48 33 52 37 - rect 16 24 20 28 - rect 34 24 38 28 --rect 16 2 20 6 --rect 34 2 38 6 --<< pdm12contact >> --rect 25 54 29 58 --<< ndm12contact >> - rect 9 17 13 21 - rect 41 17 45 21 --<< nsm12contact >> --rect 25 68 29 72 -+rect 16 2 20 6 -+rect 34 2 38 6 - << metal2 >> - rect 2 37 6 72 - rect 2 0 6 33 -@@ -139,4 +141,6 @@ rlabel metal2 4 7 4 7 2 bl0 - rlabel metal2 11 7 11 7 1 bl1 - rlabel metal2 43 7 43 7 1 br1 - rlabel metal2 50 7 50 7 8 br0 -+rlabel polycontact 29 49 29 49 1 Q -+rlabel polycontact 25 42 25 42 1 Q_bar - << end >> -diff --git a/technology/scn4m_subm/mag_lib/cell_1w_1r.mag b/technology/scn4m_subm/mag_lib/cell_1w_1r.mag -index 9aec1c5d..71a3b1bc 100644 ---- a/technology/scn4m_subm/mag_lib/cell_1w_1r.mag -+++ b/technology/scn4m_subm/mag_lib/cell_1w_1r.mag -@@ -1,6 +1,6 @@ - magic - tech scmos --timestamp 1542220294 -+timestamp 1577067400 - << nwell >> - rect 0 46 54 75 - << pwell >> -@@ -47,12 +47,17 @@ rect 17 33 21 37 - rect 25 29 29 37 - rect 33 33 37 37 - rect 41 33 45 37 -+rect 9 17 13 21 - rect 25 17 29 23 -+rect 41 17 45 21 - << pdcontact >> - rect 17 54 21 58 -+rect 25 54 29 58 - rect 33 54 37 58 - << psubstratepcontact >> - rect 25 9 29 13 -+<< nsubstratencontact >> -+rect 25 68 29 72 - << polysilicon >> - rect 22 57 24 60 - rect 30 57 32 60 -@@ -103,19 +108,16 @@ rect 0 2 16 6 - rect 20 2 34 6 - rect 38 2 54 6 - << m2contact >> -+rect 25 68 29 72 -+rect 25 54 29 58 - rect 2 33 6 37 - rect 48 33 52 37 - rect 16 24 20 28 - rect 34 24 38 28 --rect 16 2 20 6 --rect 34 2 38 6 --<< pdm12contact >> --rect 25 54 29 58 --<< ndm12contact >> - rect 9 17 13 21 - rect 41 17 45 21 --<< nsm12contact >> --rect 25 68 29 72 -+rect 16 2 20 6 -+rect 34 2 38 6 - << metal2 >> - rect 2 37 6 72 - rect 2 0 6 33 -@@ -139,4 +141,6 @@ rlabel metal2 4 7 4 7 2 bl0 - rlabel metal2 11 7 11 7 1 bl1 - rlabel metal2 43 7 43 7 1 br1 - rlabel metal2 50 7 50 7 8 br0 -+rlabel polycontact 29 49 29 49 1 Q -+rlabel polycontact 25 42 25 42 1 Q_bar - << end >> -diff --git a/technology/scn4m_subm/mag_lib/cell_6t.mag b/technology/scn4m_subm/mag_lib/cell_6t.mag -index bb9d943d..e8c16eff 100644 ---- a/technology/scn4m_subm/mag_lib/cell_6t.mag -+++ b/technology/scn4m_subm/mag_lib/cell_6t.mag -@@ -1,6 +1,6 @@ - magic - tech scmos --timestamp 1560809302 -+timestamp 1577163318 - << nwell >> - rect -8 35 42 57 - << pwell >> -@@ -115,4 +115,6 @@ rlabel m2contact 17 52 17 52 5 vdd - rlabel metal2 8 49 8 49 1 bl - rlabel metal2 26 49 26 49 1 br - rlabel metal1 4 13 4 13 1 wl -+rlabel polycontact 17 37 17 37 1 Q -+rlabel polycontact 23 28 23 28 1 Q_bar - << end >> -diff --git a/technology/scn4m_subm/mag_lib/dummy_cell_1rw_1r.mag b/technology/scn4m_subm/mag_lib/dummy_cell_1rw_1r.mag -index 60e24aca..1931485f 100644 ---- a/technology/scn4m_subm/mag_lib/dummy_cell_1rw_1r.mag -+++ b/technology/scn4m_subm/mag_lib/dummy_cell_1rw_1r.mag -@@ -1,6 +1,6 @@ - magic - tech scmos --timestamp 1562188987 -+timestamp 1577067400 - << nwell >> - rect 0 46 54 75 - << pwell >> -@@ -133,4 +133,6 @@ rlabel metal2 4 7 4 7 2 bl0 - rlabel metal2 11 7 11 7 1 bl1 - rlabel metal2 43 7 43 7 1 br1 - rlabel metal2 50 7 50 7 8 br0 -+rlabel polycontact 29 49 29 49 1 Q -+rlabel polycontact 25 42 25 42 1 Q_bar - << end >> -diff --git a/technology/scn4m_subm/mag_lib/dummy_cell_1w_1r.mag b/technology/scn4m_subm/mag_lib/dummy_cell_1w_1r.mag -index 03e49f03..1931485f 100644 ---- a/technology/scn4m_subm/mag_lib/dummy_cell_1w_1r.mag -+++ b/technology/scn4m_subm/mag_lib/dummy_cell_1w_1r.mag -@@ -1,6 +1,6 @@ - magic - tech scmos --timestamp 1562189027 -+timestamp 1577067400 - << nwell >> - rect 0 46 54 75 - << pwell >> -@@ -133,4 +133,6 @@ rlabel metal2 4 7 4 7 2 bl0 - rlabel metal2 11 7 11 7 1 bl1 - rlabel metal2 43 7 43 7 1 br1 - rlabel metal2 50 7 50 7 8 br0 -+rlabel polycontact 29 49 29 49 1 Q -+rlabel polycontact 25 42 25 42 1 Q_bar - << end >> -diff --git a/technology/scn4m_subm/mag_lib/dummy_cell_6t.mag b/technology/scn4m_subm/mag_lib/dummy_cell_6t.mag -index 74562f15..515ef682 100644 ---- a/technology/scn4m_subm/mag_lib/dummy_cell_6t.mag -+++ b/technology/scn4m_subm/mag_lib/dummy_cell_6t.mag -@@ -1,6 +1,6 @@ - magic - tech scmos --timestamp 1560809362 -+timestamp 1577067400 - << nwell >> - rect -8 35 42 57 - << pwell >> -@@ -112,4 +112,6 @@ rlabel m2contact 17 52 17 52 5 vdd - rlabel metal2 8 49 8 49 1 bl - rlabel metal2 26 49 26 49 1 br - rlabel metal1 4 13 4 13 1 wl -+rlabel polycontact 17 37 17 37 1 Q -+rlabel polycontact 23 28 23 28 1 Q_bar - << end >> -diff --git a/technology/scn4m_subm/mag_lib/replica_cell_1rw_1r.mag b/technology/scn4m_subm/mag_lib/replica_cell_1rw_1r.mag -index f215ff04..982e1630 100644 ---- a/technology/scn4m_subm/mag_lib/replica_cell_1rw_1r.mag -+++ b/technology/scn4m_subm/mag_lib/replica_cell_1rw_1r.mag -@@ -1,6 +1,6 @@ - magic - tech scmos --timestamp 1542221056 -+timestamp 1577067400 - << nwell >> - rect 0 46 54 75 - << pwell >> -@@ -142,4 +142,6 @@ rlabel metal2 4 7 4 7 2 bl0 - rlabel metal2 11 7 11 7 1 bl1 - rlabel metal2 43 7 43 7 1 br1 - rlabel metal2 50 7 50 7 8 br0 -+rlabel polycontact 29 49 29 49 1 Q -+rlabel polycontact 25 42 25 42 1 Q_bar - << end >> -diff --git a/technology/scn4m_subm/mag_lib/replica_cell_1w_1r.mag b/technology/scn4m_subm/mag_lib/replica_cell_1w_1r.mag -index f215ff04..61add325 100644 ---- a/technology/scn4m_subm/mag_lib/replica_cell_1w_1r.mag -+++ b/technology/scn4m_subm/mag_lib/replica_cell_1w_1r.mag -@@ -1,6 +1,6 @@ - magic - tech scmos --timestamp 1542221056 -+timestamp 1577067446 - << nwell >> - rect 0 46 54 75 - << pwell >> -@@ -142,4 +142,6 @@ rlabel metal2 4 7 4 7 2 bl0 - rlabel metal2 11 7 11 7 1 bl1 - rlabel metal2 43 7 43 7 1 br1 - rlabel metal2 50 7 50 7 8 br0 -+rlabel polycontact 29 49 29 49 1 Q -+rlabel polycontact 25 42 25 42 1 Q_bar - << end >> -diff --git a/technology/scn4m_subm/mag_lib/replica_cell_6t.mag b/technology/scn4m_subm/mag_lib/replica_cell_6t.mag -index b5a5f7b8..61a7646e 100644 ---- a/technology/scn4m_subm/mag_lib/replica_cell_6t.mag -+++ b/technology/scn4m_subm/mag_lib/replica_cell_6t.mag -@@ -1,6 +1,6 @@ - magic - tech scmos --timestamp 1560809329 -+timestamp 1577067503 - << nwell >> - rect -8 35 42 57 - << pwell >> -@@ -116,4 +116,6 @@ rlabel m2contact 17 52 17 52 5 vdd - rlabel metal2 8 49 8 49 1 bl - rlabel metal2 26 49 26 49 1 br - rlabel metal1 4 13 4 13 1 wl -+rlabel polycontact 17 37 17 37 1 Q -+rlabel polycontact 23 28 23 28 1 Q_bar - << end >> -diff --git a/technology/scn4m_subm/sp_lib/cell_6t.sp b/technology/scn4m_subm/sp_lib/cell_6t.sp -index bb430893..dc724007 100644 ---- a/technology/scn4m_subm/sp_lib/cell_6t.sp -+++ b/technology/scn4m_subm/sp_lib/cell_6t.sp -@@ -4,15 +4,15 @@ - * SPICE3 file created from cell_6t.ext - technology: scmos - - * Inverter 1 --M1000 Q Qbar vdd vdd p w=0.6u l=0.8u --M1002 Q Qbar gnd gnd n w=1.6u l=0.4u -+M1000 Q Q_bar vdd vdd p w=0.6u l=0.8u -+M1002 Q Q_bar gnd gnd n w=1.6u l=0.4u - - * Inverter 2 --M1001 vdd Q Qbar vdd p w=0.6u l=0.8u --M1003 gnd Q Qbar gnd n w=1.6u l=0.4u -+M1001 vdd Q Q_bar vdd p w=0.6u l=0.8u -+M1003 gnd Q Q_bar gnd n w=1.6u l=0.4u - - * Access transistors - M1004 Q wl bl gnd n w=0.8u l=0.4u --M1005 Qbar wl br gnd n w=0.8u l=0.4u -+M1005 Q_bar wl br gnd n w=0.8u l=0.4u - - .ENDS -diff --git a/technology/scn4m_subm/sp_lib/dummy_cell_6t.sp b/technology/scn4m_subm/sp_lib/dummy_cell_6t.sp -index 3b0584df..c5b6ff9d 100644 ---- a/technology/scn4m_subm/sp_lib/dummy_cell_6t.sp -+++ b/technology/scn4m_subm/sp_lib/dummy_cell_6t.sp -@@ -3,15 +3,15 @@ - .SUBCKT dummy_cell_6t bl br wl vdd gnd - - * Inverter 1 --M1000 Q Qbar vdd vdd p w=0.6u l=0.8u --M1002 Q Qbar gnd gnd n w=1.6u l=0.4u -+M1000 Q Q_bar vdd vdd p w=0.6u l=0.8u -+M1002 Q Q_bar gnd gnd n w=1.6u l=0.4u - - * Inverter 2 --M1001 vdd Q Qbar vdd p w=0.6u l=0.8u --M1003 gnd Q Qbar gnd n w=1.6u l=0.4u -+M1001 vdd Q Q_bar vdd p w=0.6u l=0.8u -+M1003 gnd Q Q_bar gnd n w=1.6u l=0.4u - - * Access transistors - M1004 Q wl bl_noconn gnd n w=0.8u l=0.4u --M1005 Qbar wl br_noconn gnd n w=0.8u l=0.4u -+M1005 Q_bar wl br_noconn gnd n w=0.8u l=0.4u - - .ENDS