From 79391b84da278637106cd04843e4747fb5aa4889 Mon Sep 17 00:00:00 2001 From: mrg Date: Thu, 30 Jan 2020 01:45:33 +0000 Subject: [PATCH] Cleanup and rename vias. --- compiler/base/contact.py | 12 +++++-- compiler/base/design.py | 6 +++- compiler/bitcells/bitcell.py | 17 ++++++++-- .../custom_cell_properties.py | 12 ++++--- compiler/bitcells/pbitcell.py | 34 +++++++++---------- compiler/modules/bank_select.py | 2 +- compiler/modules/bitcell_array.py | 16 +++------ .../{base_array.py => bitcell_base_array.py} | 0 compiler/modules/hierarchical_predecode.py | 2 +- compiler/modules/module_type.py | 2 +- compiler/modules/multibank.py | 4 +-- compiler/modules/wordline_driver.py | 4 +-- compiler/pgates/pgate.py | 10 +++--- compiler/pgates/pinv.py | 7 ++-- compiler/pgates/pnand2.py | 14 ++++---- compiler/pgates/pnand3.py | 8 ++--- compiler/pgates/pnor2.py | 12 +++---- compiler/pgates/precharge.py | 6 ++-- compiler/pgates/ptristate_inv.py | 6 ++-- compiler/sram/sram_1bank.py | 6 ++-- technology/freepdk45/tech/tech.py | 7 ++-- technology/scn4m_subm/tech/tech.py | 6 ++-- 22 files changed, 106 insertions(+), 87 deletions(-) rename compiler/{modules => bitcells}/custom_cell_properties.py (66%) rename compiler/modules/{base_array.py => bitcell_base_array.py} (100%) diff --git a/compiler/base/contact.py b/compiler/base/contact.py index 1a5785aa..51efc498 100644 --- a/compiler/base/contact.py +++ b/compiler/base/contact.py @@ -36,6 +36,7 @@ class contact(hierarchy_design.hierarchy_design): hierarchy_design.hierarchy_design.__init__(self, name) debug.info(4, "create contact object {0}".format(name)) + self.add_comment("layers: {0}".format(layer_stack)) self.add_comment("dimensions: {0}".format(dimensions)) if implant_type or well_type: @@ -243,14 +244,19 @@ class contact(hierarchy_design.hierarchy_design): """ Get total power of a module """ return self.return_power() - + # Set up a static for each layer to be used for measurements for layer_stack in tech.layer_stacks: (layer1, via, layer2) = layer_stack cont = factory.create(module_type="contact", layer_stack=layer_stack) module = sys.modules[__name__] - # Create the contact as just the concat of the layer names - setattr(module, layer1 + layer2, cont) + # Also create a contact that is just the first layer + if layer1 == "poly" or layer1 == "active": + setattr(module, layer1 + "_contact", cont) + else: + setattr(module, layer1 + "_via", cont) + + diff --git a/compiler/base/design.py b/compiler/base/design.py index 9b595b5f..9db68877 100644 --- a/compiler/base/design.py +++ b/compiler/base/design.py @@ -61,8 +61,12 @@ class design(hierarchy_design): """ (layer1, via, layer2) = layer_stack - contact1 = getattr(contact, layer1 + layer2) + if layer1 == "poly" or layer1 == "active": + contact1 = getattr(contact, layer1 + "_contact") + else: + contact1 = getattr(contact, layer1 + "_via") max_contact = max(contact1.width, contact1.height) + layer1_space = getattr(self, layer1 + "_space") layer2_space = getattr(self, layer2 + "_space") pitch = max_contact + max(layer1_space, layer2_space) diff --git a/compiler/bitcells/bitcell.py b/compiler/bitcells/bitcell.py index b22c9a46..5b552832 100644 --- a/compiler/bitcells/bitcell.py +++ b/compiler/bitcells/bitcell.py @@ -7,7 +7,8 @@ # import debug import utils -from tech import GDS, layer +from tech import GDS, layer, parameter +from tech import cell_properties import bitcell_base @@ -19,7 +20,14 @@ class bitcell(bitcell_base.bitcell_base): library. """ - pin_names = ["bl", "br", "wl", "vdd", "gnd"] + # If we have a split WL bitcell, if not be backwards + # compatible in the tech file + + if cell_properties.bitcell.split_wl: + pin_names = ["bl", "br", "wl0", "wl1", "vdd", "gnd"] + else: + pin_names = ["bl", "br", "wl", "vdd", "gnd"] + storage_nets = ['Q', 'Qbar'] type_list = ["OUTPUT", "OUTPUT", "INPUT", "POWER", "GROUND"] (width, height) = utils.get_libcell_size("cell_6t", @@ -40,7 +48,10 @@ class bitcell(bitcell_base.bitcell_base): def get_all_wl_names(self): """ Creates a list of all wordline pin names """ - row_pins = ["wl"] + if cell_properties.bitcell.split_wl: + row_pins = ["wl0", "wl1"] + else: + row_pins = ["wl"] return row_pins def get_all_bitline_names(self): diff --git a/compiler/modules/custom_cell_properties.py b/compiler/bitcells/custom_cell_properties.py similarity index 66% rename from compiler/modules/custom_cell_properties.py rename to compiler/bitcells/custom_cell_properties.py index 085527fc..e795f6d7 100644 --- a/compiler/modules/custom_cell_properties.py +++ b/compiler/bitcells/custom_cell_properties.py @@ -6,22 +6,24 @@ # All rights reserved. # -class _MirrorAxis: +class _mirror_axis: def __init__(self, x, y): self.x = x self.y = y -class _Bitcell: - def __init__(self, mirror): +class _bitcell: + def __init__(self, mirror, split_wl): self.mirror = mirror + self.split_wl = split_wl -class CellProperties(): +class cell_properties(): """ TODO """ def __init__(self): self.names = {} - self._bitcell = _Bitcell(_MirrorAxis(True, False)) + self._bitcell = _bitcell(mirror = _mirror_axis(True, False), + split_wl = False) @property def bitcell(self): diff --git a/compiler/bitcells/pbitcell.py b/compiler/bitcells/pbitcell.py index 4f19c489..61bd9710 100644 --- a/compiler/bitcells/pbitcell.py +++ b/compiler/bitcells/pbitcell.py @@ -212,20 +212,20 @@ class pbitcell(bitcell_base.bitcell_base): # y-offset for the access transistor's gate contact self.gate_contact_yoffset = max_contact_extension + self.m2_space \ - + 0.5 * max(contact.polym1.height, contact.m1m2.height) + + 0.5 * max(contact.poly_contact.height, contact.m1_via.height) # y-position of access transistors - self.port_ypos = self.m1_space + 0.5 * contact.m1m2.height + self.gate_contact_yoffset + self.port_ypos = self.m1_space + 0.5 * contact.m1_via.height + self.gate_contact_yoffset # y-position of inverter nmos self.inverter_nmos_ypos = self.port_ypos # spacing between ports (same for read/write and write ports) self.bitline_offset = -0.5 * self.readwrite_nmos.active_width \ - + 0.5 * contact.m1m2.height \ + + 0.5 * contact.m1_via.height \ + self.m2_space + self.m2_width m2_constraint = self.bitline_offset + self.m2_space \ - + 0.5 * contact.m1m2.height \ + + 0.5 * contact.m1_via.height \ - 0.5 * self.readwrite_nmos.active_width self.write_port_spacing = max(self.active_space, self.m1_space, @@ -233,7 +233,7 @@ class pbitcell(bitcell_base.bitcell_base): self.read_port_spacing = self.bitline_offset + self.m2_space # spacing between cross coupled inverters - self.inverter_to_inverter_spacing = contact.polym1.width + self.m1_space + self.inverter_to_inverter_spacing = contact.poly_contact.width + self.m1_space # calculations related to inverter connections inverter_pmos_contact_extension = 0.5 * \ @@ -242,19 +242,19 @@ class pbitcell(bitcell_base.bitcell_base): (self.inverter_nmos.active_contact.height - self.inverter_nmos.active_height) self.inverter_gap = max(self.poly_to_active, self.m1_space + inverter_nmos_contact_extension) \ - + self.poly_to_contact + 2 * contact.polym1.width \ + + self.poly_to_contact + 2 * contact.poly_contact.width \ + self.m1_space + inverter_pmos_contact_extension self.cross_couple_lower_ypos = self.inverter_nmos_ypos \ + self.inverter_nmos.active_height \ + max(self.poly_to_active, self.m1_space + inverter_nmos_contact_extension) \ - + 0.5 * contact.polym1.width + + 0.5 * contact.poly_contact.width self.cross_couple_upper_ypos = self.inverter_nmos_ypos \ + self.inverter_nmos.active_height \ + max(self.poly_to_active, self.m1_space + inverter_nmos_contact_extension) \ + self.poly_to_contact \ - + 1.5 * contact.polym1.width + + 1.5 * contact.poly_contact.width # spacing between wordlines (and gnd) self.m1_offset = -0.5 * self.m1_width @@ -290,7 +290,7 @@ class pbitcell(bitcell_base.bitcell_base): (self.write_nmos.active_width + self.write_port_spacing) \ - self.num_r_ports * \ (self.read_port_width + self.read_port_spacing) \ - - self.bitline_offset - 0.5 * contact.m1m2.width + - self.bitline_offset - 0.5 * contact.m1_via.width self.width = -2 * self.leftmost_xpos self.height = self.topmost_ypos - self.botmost_ypos @@ -375,14 +375,14 @@ class pbitcell(bitcell_base.bitcell_base): # add contacts to connect gate poly to drain/source # metal1 (to connect Q to Q_bar) contact_offset_left = vector(self.inverter_nmos_left.get_pin("D").rc().x \ - + 0.5 * contact.polym1.height, + + 0.5 * contact.poly_contact.height, self.cross_couple_upper_ypos) self.add_via_center(layers=self.poly_stack, offset=contact_offset_left) contact_offset_right = vector(self.inverter_nmos_right.get_pin("S").lc().x \ - - 0.5*contact.polym1.height, + - 0.5*contact.poly_contact.height, self.cross_couple_lower_ypos) self.add_via_center(layers=self.poly_stack, offset=contact_offset_right) @@ -824,7 +824,7 @@ class pbitcell(bitcell_base.bitcell_base): offset=port_contact_offest) self.add_path("m2", - [port_contact_offest, bl_offset], width=contact.m1m2.height) + [port_contact_offest, bl_offset], width=contact.m1_via.height) for k in range(self.total_ports): port_contact_offest = right_port_transistors[k].get_pin("D").center() @@ -836,7 +836,7 @@ class pbitcell(bitcell_base.bitcell_base): offset=port_contact_offest) self.add_path("m2", - [port_contact_offest, br_offset], width=contact.m1m2.height) + [port_contact_offest, br_offset], width=contact.m1_via.height) def route_supply(self): """ Route inverter nmos and read-access nmos to gnd. Route inverter pmos to vdd. """ @@ -853,9 +853,9 @@ class pbitcell(bitcell_base.bitcell_base): offset=position) if position.x > 0: - contact_correct = 0.5 * contact.m1m2.height + contact_correct = 0.5 * contact.m1_via.height else: - contact_correct = -0.5 * contact.m1m2.height + contact_correct = -0.5 * contact.m1_via.height supply_offset = vector(position.x + contact_correct, self.gnd_position.y) self.add_via_center(layers=self.m1_stack, @@ -921,13 +921,13 @@ class pbitcell(bitcell_base.bitcell_base): """ # add poly to metal1 contacts for gates of the inverters left_storage_contact = vector(self.inverter_nmos_left.get_pin("G").lc().x \ - - self.poly_to_contact - 0.5*contact.polym1.width, + - self.poly_to_contact - 0.5*contact.poly_contact.width, self.cross_couple_upper_ypos) self.add_via_center(layers=self.poly_stack, offset=left_storage_contact) right_storage_contact = vector(self.inverter_nmos_right.get_pin("G").rc().x \ - + self.poly_to_contact + 0.5*contact.polym1.width, + + self.poly_to_contact + 0.5*contact.poly_contact.width, self.cross_couple_upper_ypos) self.add_via_center(layers=self.poly_stack, offset=right_storage_contact) diff --git a/compiler/modules/bank_select.py b/compiler/modules/bank_select.py index 0c15401e..c3307ece 100644 --- a/compiler/modules/bank_select.py +++ b/compiler/modules/bank_select.py @@ -256,7 +256,7 @@ class bank_select(design.design): # Connect the logic B input to bank_sel/bank_sel_bar - logic_pos = logic_inst.get_pin("B").lc() - vector(0.5*contact.m1m2.height,0) + logic_pos = logic_inst.get_pin("B").lc() - vector(0.5*contact.m1_via.height,0) input_pos = vector(xoffset_bank_signal, logic_pos.y) self.add_path("m2",[logic_pos, input_pos]) self.add_via_center(layers=self.m1_stack, diff --git a/compiler/modules/bitcell_array.py b/compiler/modules/bitcell_array.py index 636408df..60461724 100644 --- a/compiler/modules/bitcell_array.py +++ b/compiler/modules/bitcell_array.py @@ -5,14 +5,11 @@ # (acting for and on behalf of Oklahoma State University) # All rights reserved. # -import debug -import design -from base_array import bitcell_base_array +from bitcell_base_array import bitcell_base_array from tech import drc, spice -from vector import vector from globals import OPTS from sram_factory import factory -import logical_effort + class bitcell_array(bitcell_base_array): """ @@ -29,7 +26,7 @@ class bitcell_array(bitcell_base_array): # We don't offset this because we need to align # the replica bitcell in the control logic - #self.offset_all_coordinates() + # self.offset_all_coordinates() def create_netlist(self): @@ -48,13 +45,11 @@ class bitcell_array(bitcell_base_array): self.DRC_LVS() - def add_modules(self): """ Add the modules used in this design """ self.cell = factory.create(module_type="bitcell") self.add_mod(self.cell) - def create_instances(self): """ Create the module instances used in this design """ self.cell_inst = {} @@ -65,7 +60,6 @@ class bitcell_array(bitcell_base_array): mod=self.cell) self.connect_inst(self.get_bitcell_pins(col, row)) - def analytical_power(self, corner, load): """Power of Bitcell array and bitline in nW.""" from tech import drc, parameter @@ -77,10 +71,10 @@ class bitcell_array(bitcell_base_array): freq = spice["default_event_frequency"] bitline_dynamic = self.calc_dynamic_power(corner, cell_load, freq, swing=bl_swing) - #Calculate the bitcell power which currently only includes leakage + # Calculate the bitcell power which currently only includes leakage cell_power = self.cell.analytical_power(corner, load) - #Leakage power grows with entire array and bitlines. + # Leakage power grows with entire array and bitlines. total_power = self.return_power(cell_power.dynamic + bitline_dynamic * self.column_size, cell_power.leakage * self.column_size * self.row_size) return total_power diff --git a/compiler/modules/base_array.py b/compiler/modules/bitcell_base_array.py similarity index 100% rename from compiler/modules/base_array.py rename to compiler/modules/bitcell_base_array.py diff --git a/compiler/modules/hierarchical_predecode.py b/compiler/modules/hierarchical_predecode.py index dec04073..78e9af7f 100644 --- a/compiler/modules/hierarchical_predecode.py +++ b/compiler/modules/hierarchical_predecode.py @@ -178,7 +178,7 @@ class hierarchical_predecode(design.design): # route one signal next to each vdd/gnd rail since this is # typically where the p/n devices are and there are no # pins in the nand gates. - y_offset = (num+self.number_of_inputs) * self.inv.height + contact.m1m2.width + self.m1_space + y_offset = (num+self.number_of_inputs) * self.inv.height + contact.m1_via.width + self.m1_space in_pin = "in_{}".format(num) a_pin = "A_{}".format(num) in_pos = vector(self.input_rails[in_pin].x,y_offset) diff --git a/compiler/modules/module_type.py b/compiler/modules/module_type.py index 1d8d0cba..419e6041 100644 --- a/compiler/modules/module_type.py +++ b/compiler/modules/module_type.py @@ -6,7 +6,7 @@ # All rights reserved. # -class ModuleType(): +class module_type(): """ This is a class that maps cell names to python classes implementing them. """ diff --git a/compiler/modules/multibank.py b/compiler/modules/multibank.py index 33076bfb..bf19954b 100644 --- a/compiler/modules/multibank.py +++ b/compiler/modules/multibank.py @@ -810,7 +810,7 @@ class multibank(design.design): self.add_wire(("m3","via2","m2"),[in_pin, rail_pos, rail_pos - vector(0,self.m2_pitch)]) # Bring it up to M2 for M2/M3 routing self.add_via(layers=self.m1_stack, - offset=in_pin + contact.m1m2.offset, + offset=in_pin + contact.m1_via.offset, rotate=90) self.add_via(layers=self.m2_stack, offset=in_pin + self.m2m3_via_offset, @@ -823,7 +823,7 @@ class multibank(design.design): rail_pos = vector(self.rail_1_x_offsets[rail], in_pin.y) self.add_wire(("m3","via2","m2"),[in_pin, rail_pos, rail_pos - vector(0,self.m2_pitch)]) self.add_via(layers=self.m1_stack, - offset=in_pin + contact.m1m2.offset, + offset=in_pin + contact.m1_via.offset, rotate=90) self.add_via(layers=self.m2_stack, offset=in_pin + self.m2m3_via_offset, diff --git a/compiler/modules/wordline_driver.py b/compiler/modules/wordline_driver.py index 2af2c8c9..cac2eea5 100644 --- a/compiler/modules/wordline_driver.py +++ b/compiler/modules/wordline_driver.py @@ -177,7 +177,7 @@ class wordline_driver(design.design): up_or_down = self.m2_space if row % 2 else -self.m2_space input_offset = vector(0, b_pos.y + up_or_down) base_offset = vector(clk_offset.x, input_offset.y) - contact_offset = vector(0.5 * self.m2_width + self.m2_space + 0.5 * contact.m1m2.width, 0) + contact_offset = vector(0.5 * self.m2_width + self.m2_space + 0.5 * contact.m1_via.width, 0) mid_via_offset = base_offset + contact_offset # must under the clk line in M1 @@ -191,7 +191,7 @@ class wordline_driver(design.design): # now connect to the nand2 B self.add_path("m2", [mid_via_offset, b_pos]) - contact_offset = b_pos - vector(0.5 * contact.m1m2.height, 0) + contact_offset = b_pos - vector(0.5 * contact.m1_via.height, 0) self.add_via_center(layers=self.m1_stack, offset=contact_offset, directions=("H", "H")) diff --git a/compiler/pgates/pgate.py b/compiler/pgates/pgate.py index e009d1bb..43fc1c8c 100644 --- a/compiler/pgates/pgate.py +++ b/compiler/pgates/pgate.py @@ -87,16 +87,16 @@ class pgate(design.design): left_gate_offset = vector(nmos_gate_pin.lx(), ypos) # Center is completely symmetric. - contact_width = contact.polym1.width - contact_m1_width = contact.polym1.second_layer_width - contact_m1_height = contact.polym1.second_layer_height + contact_width = contact.poly_contact.width + contact_m1_width = contact.poly_contact.second_layer_width + contact_m1_height = contact.poly_contact.second_layer_height if position == "center": contact_offset = left_gate_offset \ + vector(0.5 * self.poly_width, 0) elif position == "farleft": contact_offset = left_gate_offset \ - - vector(0.5 * contact.polym1.width, 0) + - vector(0.5 * contact.poly_contact.width, 0) elif position == "left": contact_offset = left_gate_offset \ - vector(0.5 * contact_width - 0.5 * self.poly_width, 0) @@ -120,7 +120,7 @@ class pgate(design.design): + left_gate_offset.scale(0.5, 0) self.add_rect_center(layer="poly", offset=mid_point, - height=contact.polym1.first_layer_width, + height=contact.poly_contact.first_layer_width, width=left_gate_offset.x - contact_offset.x) def extend_wells(self, middle_position): diff --git a/compiler/pgates/pinv.py b/compiler/pgates/pinv.py index 8a3a8326..8da648b0 100644 --- a/compiler/pgates/pinv.py +++ b/compiler/pgates/pinv.py @@ -89,14 +89,15 @@ class pinv(pgate.pgate): # Assume we need 3 metal 1 pitches (2 power rails, one # between the tx for the drain) # plus the tx height - nmos = factory.create(module_type="ptx", tx_type="nmos") + nmos = factory.create(module_type="ptx", + tx_type="nmos") pmos = factory.create(module_type="ptx", width=drc("minwidth_tx"), tx_type="pmos") tx_height = nmos.poly_height + pmos.poly_height # rotated m1 pitch or poly to active spacing - min_channel = max(contact.polym1.width + self.m1_space, - contact.polym1.width + 2 * self.poly_to_active) + min_channel = max(contact.poly_contact.width + self.m1_space, + contact.poly_contact.width + 2 * self.poly_to_active) # This is the extra space needed to ensure DRC rules # to the active contacts diff --git a/compiler/pgates/pnand2.py b/compiler/pgates/pnand2.py index 8d3605a2..f5abdaaa 100644 --- a/compiler/pgates/pnand2.py +++ b/compiler/pgates/pnand2.py @@ -85,10 +85,10 @@ class pnand2(pgate.pgate): """ Pre-compute some handy layout parameters. """ # metal spacing to allow contacts on any layer - self.input_spacing = max(self.poly_space + contact.polym1.first_layer_width, - self.m1_space + contact.m1m2.first_layer_width, - self.m2_space + contact.m2m3.first_layer_width, - self.m3_space + contact.m2m3.second_layer_width) + self.input_spacing = max(self.poly_space + contact.poly_contact.first_layer_width, + self.m1_space + contact.m1_via.first_layer_width, + self.m2_space + contact.m2_via.first_layer_width, + self.m3_space + contact.m2_via.second_layer_width) # Compute the other pmos2 location, @@ -98,7 +98,7 @@ class pnand2(pgate.pgate): # Two PMOS devices and a well contact. Separation between each. # Enclosure space on the sides. - self.well_width = 2 * self.pmos.active_width + contact.activem1.width \ + self.well_width = 2 * self.pmos.active_width + contact.active_contact.width \ + 2 * self.active_space \ + 2 * self.nwell_enclose_active @@ -245,8 +245,8 @@ class pnand2(pgate.pgate): self.add_layout_pin_rect_center(text="Z", layer="m1", offset=out_offset, - width=contact.m1m2.first_layer_height, - height=contact.m1m2.first_layer_width) + width=contact.m1_via.first_layer_height, + height=contact.m1_via.first_layer_width) def analytical_power(self, corner, load): """Returns dynamic and leakage power. Results in nW""" diff --git a/compiler/pgates/pnand3.py b/compiler/pgates/pnand3.py index bb379db7..5c1e0db5 100644 --- a/compiler/pgates/pnand3.py +++ b/compiler/pgates/pnand3.py @@ -202,10 +202,10 @@ class pnand3(pgate.pgate): # wire space or wire and one contact space metal_spacing = max(self.m1_space + self.m1_width, self.m2_space + self.m2_width, - self.m1_space + 0.5 *contact.polym1.width + 0.5 * self.m1_width) + self.m1_space + 0.5 *contact.poly_contact.width + 0.5 * self.m1_width) active_spacing = max(self.m1_space, - 0.5 * contact.polym1.first_layer_width + self.poly_to_active) + 0.5 * contact.poly_contact.first_layer_width + self.poly_to_active) inputC_yoffset = self.nmos3_pos.y + self.nmos.active_height + active_spacing self.route_input_gate(self.pmos3_inst, self.nmos3_inst, @@ -256,8 +256,8 @@ class pnand3(pgate.pgate): self.add_layout_pin_rect_center(text="Z", layer="m1", offset=mid_offset, - width=contact.m1m2.first_layer_width, - height=contact.m1m2.first_layer_height) + width=contact.m1_via.first_layer_width, + height=contact.m1_via.first_layer_height) def analytical_power(self, corner, load): """Returns dynamic and leakage power. Results in nW""" diff --git a/compiler/pgates/pnor2.py b/compiler/pgates/pnor2.py index 9895e9d9..e28b6fc8 100644 --- a/compiler/pgates/pnor2.py +++ b/compiler/pgates/pnor2.py @@ -84,10 +84,10 @@ class pnor2(pgate.pgate): """ Pre-compute some handy layout parameters. """ # metal spacing to allow contacts on any layer - self.input_spacing = max(self.poly_space + contact.polym1.first_layer_width, - self.m1_space + contact.m1m2.first_layer_width, - self.m2_space + contact.m2m3.first_layer_width, - self.m3_space + contact.m2m3.second_layer_width) + self.input_spacing = max(self.poly_space + contact.poly_contact.first_layer_width, + self.m1_space + contact.m1_via.first_layer_width, + self.m2_space + contact.m2_via.first_layer_width, + self.m3_space + contact.m2_via.second_layer_width) # Compute the other pmos2 location, but determining # offset to overlap the source and drain pins @@ -234,8 +234,8 @@ class pnor2(pgate.pgate): self.add_layout_pin_rect_center(text="Z", layer="m1", offset=mid3_offset, - width=contact.m1m2.first_layer_height, - height=contact.m1m2.first_layer_width) + width=contact.m1_via.first_layer_height, + height=contact.m1_via.first_layer_width) def analytical_power(self, corner, load): """Returns dynamic and leakage power. Results in nW""" diff --git a/compiler/pgates/precharge.py b/compiler/pgates/precharge.py index d1e2f3af..888304ce 100644 --- a/compiler/pgates/precharge.py +++ b/compiler/pgates/precharge.py @@ -121,7 +121,7 @@ class precharge(design.design): self.lower_pmos_inst.place(self.lower_pmos_position) # adds the upper pmos(s) to layout - ydiff = self.pmos.height + 2 * self.m1_space + contact.polym1.width + ydiff = self.pmos.height + 2 * self.m1_space + contact.poly_contact.width self.upper_pmos1_pos = self.lower_pmos_position + vector(0, ydiff) self.upper_pmos1_inst.place(self.upper_pmos1_pos) @@ -175,7 +175,7 @@ class precharge(design.design): # adds the contact from active to metal1 well_contact_pos = self.upper_pmos1_inst.get_pin("D").center().scale(1, 0) \ - + vector(0, self.upper_pmos1_inst.uy() + contact.activem1.height / 2 \ + + vector(0, self.upper_pmos1_inst.uy() + contact.active_contact.height / 2 \ + self.nwell_extend_active) self.add_via_center(layers=self.active_stack, offset=well_contact_pos, @@ -183,7 +183,7 @@ class precharge(design.design): well_type="n") # leave an extra pitch for the height - self.height = well_contact_pos.y + contact.activem1.height + self.m1_pitch + self.height = well_contact_pos.y + contact.active_contact.height + self.m1_pitch # nwell should span the whole design since it is pmos only self.add_rect(layer="nwell", diff --git a/compiler/pgates/ptristate_inv.py b/compiler/pgates/ptristate_inv.py index 764b87c0..9586e72b 100644 --- a/compiler/pgates/ptristate_inv.py +++ b/compiler/pgates/ptristate_inv.py @@ -79,7 +79,7 @@ class ptristate_inv(pgate.pgate): # Height is an input parameter, so it is not recomputed. # Make sure we can put a well above and below - self.top_bottom_space = max(contact.activem1.width, contact.activem1.height) + self.top_bottom_space = max(contact.active_contact.width, contact.active_contact.height) def add_ptx(self): """ Create the PMOS and NMOS transistors. """ @@ -135,8 +135,8 @@ class ptristate_inv(pgate.pgate): """ pmos_yoff = self.height - self.pmos.active_height \ - - self.top_bottom_space - 0.5 * contact.activem1.height - nmos_yoff = self.top_bottom_space + 0.5 * contact.activem1.height + - self.top_bottom_space - 0.5 * contact.active_contact.height + nmos_yoff = self.top_bottom_space + 0.5 * contact.active_contact.height # Tristate transistors pmos1_pos = vector(self.pmos.active_offset.x, pmos_yoff) diff --git a/compiler/sram/sram_1bank.py b/compiler/sram/sram_1bank.py index 151c8a70..93247fc1 100644 --- a/compiler/sram/sram_1bank.py +++ b/compiler/sram/sram_1bank.py @@ -17,7 +17,7 @@ from globals import OPTS, print_time from sram_base import sram_base from bank import bank -from contact import m2m3 +from contact import m2_via from dff_buf_array import dff_buf_array from dff_array import dff_array @@ -280,7 +280,7 @@ class sram_1bank(sram_base): mid_pos = vector(clk_steiner_pos.x, data_dff_clk_pos.y) # In some designs, the steiner via will be too close to the mid_pos via # so make the wire as wide as the contacts - self.add_path("m2",[mid_pos, clk_steiner_pos], width=max(m2m3.width,m2m3.height)) + self.add_path("m2",[mid_pos, clk_steiner_pos], width=max(m2_via.width,m2_via.height)) self.add_wire(("m3","via2","m2"),[data_dff_clk_pos, mid_pos, clk_steiner_pos]) if self.write_size: @@ -289,7 +289,7 @@ class sram_1bank(sram_base): mid_pos = vector(clk_steiner_pos.x, wmask_dff_clk_pos.y) # In some designs, the steiner via will be too close to the mid_pos via # so make the wire as wide as the contacts - self.add_path("m2", [mid_pos, clk_steiner_pos], width=max(m2m3.width, m2m3.height)) + self.add_path("m2", [mid_pos, clk_steiner_pos], width=max(m2_via.width, m2_via.height)) self.add_wire(("m3", "via2", "m2"), [wmask_dff_clk_pos, mid_pos, clk_steiner_pos]) diff --git a/technology/freepdk45/tech/tech.py b/technology/freepdk45/tech/tech.py index ffc981b8..c60abeb5 100644 --- a/technology/freepdk45/tech/tech.py +++ b/technology/freepdk45/tech/tech.py @@ -8,7 +8,7 @@ import os from design_rules import * from module_type import * -from custom_cell_properties import CellProperties +from custom_cell_properties import cell_properties """ File containing the process technology parameters for FreePDK 45nm. @@ -23,15 +23,16 @@ File containing the process technology parameters for FreePDK 45nm. # Using tech_modules['cellname'] you can override each class by providing a custom # implementation in '$OPENRAM_TECHDIR/modules/' # For example: tech_modules['contact'] = 'contact_freepdk45' -tech_modules = ModuleType() +tech_modules = module_type() ################################################### # Custom cell properties ################################################### -cell_properties = CellProperties() +cell_properties = cell_properties() cell_properties.bitcell.mirror.x = True cell_properties.bitcell.mirror.y = False + ################################################### # GDS file info ################################################### diff --git a/technology/scn4m_subm/tech/tech.py b/technology/scn4m_subm/tech/tech.py index 965306a3..7c360d38 100644 --- a/technology/scn4m_subm/tech/tech.py +++ b/technology/scn4m_subm/tech/tech.py @@ -8,7 +8,7 @@ import os from design_rules import * from module_type import * -from custom_cell_properties import CellProperties +from custom_cell_properties import cell_properties """ File containing the process technology parameters for SCMOS 4m, 0.35um @@ -23,12 +23,12 @@ File containing the process technology parameters for SCMOS 4m, 0.35um # Using tech_modules['cellname'] you can override each class by providing a custom # implementation in '$OPENRAM_TECHDIR/modules/' # For example: tech_modules['contact'] = 'contact_scn4m' -tech_modules = ModuleType() +tech_modules = module_type() ################################################### # Custom cell properties ################################################### -cell_properties = CellProperties() +cell_properties = cell_properties() cell_properties.bitcell.mirror.x = True cell_properties.bitcell.mirror.y = False