diff --git a/compiler/base/hierarchy_layout.py b/compiler/base/hierarchy_layout.py index e3864b81..9843dcef 100644 --- a/compiler/base/hierarchy_layout.py +++ b/compiler/base/hierarchy_layout.py @@ -926,22 +926,30 @@ class layout(lef.lef): - def add_power_pin(self, name, loc, rotate=90, m1_too=True): + def add_power_pin(self, name, loc, rotate=90, start_layer="metal1"): """ - Add a single power pin from M3 down to M1 at the given center location + Add a single power pin from M3 down to M1 at the given center location. + The starting layer is specified to determine which vias are needed. """ - if m1_too: + + if start_layer=="metal1": self.add_via_center(layers=("metal1", "via1", "metal2"), offset=loc, rotate=float(rotate)) - via=self.add_via_center(layers=("metal2", "via2", "metal3"), - offset=loc, - rotate=float(rotate)) - self.add_layout_pin_rect_center(text=name, - layer="metal3", - offset=loc, - width=via.width, - height=via.height) + if start_layer=="metal1" or start_layer=="metal2": + via=self.add_via_center(layers=("metal2", "via2", "metal3"), + offset=loc, + rotate=float(rotate)) + if start_layer=="metal3": + self.add_layout_pin_rect_center(text=name, + layer="metal3", + offset=loc) + else: + self.add_layout_pin_rect_center(text=name, + layer="metal3", + offset=loc, + width=via.width, + height=via.height) def add_power_ring(self, bbox): """ diff --git a/compiler/bitcells/pbitcell.py b/compiler/bitcells/pbitcell.py index d858b609..d9d2ef7a 100644 --- a/compiler/bitcells/pbitcell.py +++ b/compiler/bitcells/pbitcell.py @@ -80,7 +80,7 @@ class pbitcell(design.design): self.offset_all_coordinates() gnd_overlap = vector(0, 0.5*contact.well.width) self.translate_all(gnd_overlap) - self.DRC_LVS() + def add_pins(self): """ add pins and set names for bitlines and wordlines """ @@ -323,20 +323,21 @@ class pbitcell(design.design): # Add rails for vdd and gnd gnd_ypos = self.rowline_offset - self.total_ports*self.rowline_spacing self.gnd_position = vector(0, gnd_ypos) - self.gnd = self.add_layout_pin_rect_center(text="gnd", - layer="metal1", - offset=self.gnd_position, - width=self.width, - height=self.m1_width) - + self.add_rect_center(layer="metal1", + offset=self.gnd_position, + width=self.width, + height=self.m1_width) + self.add_power_pin("gnd", vector(0,gnd_ypos)) + + vdd_ypos = self.inverter_nmos_ypos + self.inverter_nmos.active_height + self.inverter_gap + self.inverter_pmos.active_height + self.vdd_offset self.vdd_position = vector(0, vdd_ypos) - self.vdd = self.add_layout_pin_rect_center(text="vdd", - layer="metal1", - offset=self.vdd_position, - width=self.width, - height=self.m1_width) - + self.add_rect_center(layer="metal1", + offset=self.vdd_position, + width=self.width, + height=self.m1_width) + self.add_power_pin("vdd", vector(0,vdd_ypos)) + def create_readwrite_ports(self): """ Creates read/write ports to the bit cell. A differential pair of transistor can both read and write, like in a 6T cell. diff --git a/compiler/modules/bitcell_array.py b/compiler/modules/bitcell_array.py index e9d9446d..792fd9ae 100644 --- a/compiler/modules/bitcell_array.py +++ b/compiler/modules/bitcell_array.py @@ -138,7 +138,8 @@ class bitcell_array(design.design): inst = self.cell_inst[row,col] for pin_name in ["vdd", "gnd"]: for pin in inst.get_pins(pin_name): - self.add_power_pin(pin_name, pin.center(), 0, pin.layer=="metal1") + self.add_power_pin(pin_name, pin.center(), 0, pin.layer) + def analytical_delay(self, slew, load=0): from tech import drc diff --git a/compiler/modules/replica_bitline.py b/compiler/modules/replica_bitline.py index e349fa89..dcbc53d4 100644 --- a/compiler/modules/replica_bitline.py +++ b/compiler/modules/replica_bitline.py @@ -265,15 +265,8 @@ class replica_bitline(design.design): pin = self.rbl_inv_inst.get_pin("vdd") self.add_power_pin("vdd", pin.lc()) - # Replica bitcell needs to be routed up to M3 pin=self.rbc_inst.get_pin("vdd") - # Don't rotate this via to vit in FreePDK45. In the custom cell, the pin cannot be placed - # directly on vdd or there will be a drc error with a wordline. Place the pin slightly farther - # away then route to it. A better solution would be to rotate the m1 in the via or move the pin - # a m1_pitch below the entire cell. - pin_extension = pin.center() - vector(0,self.m1_pitch) - self.add_power_pin("vdd", pin_extension, rotate=0) - self.add_path("metal1", [pin.center(), pin_extension]) + self.add_power_pin("vdd", pin.center(), 0, pin.layer) for pin in self.rbc_inst.get_pins("gnd"): self.add_power_pin("gnd", pin.center()) diff --git a/technology/freepdk45/gds_lib/cell_1rw_1r.gds b/technology/freepdk45/gds_lib/cell_1rw_1r.gds index fe12fc72..00dc1855 100644 Binary files a/technology/freepdk45/gds_lib/cell_1rw_1r.gds and b/technology/freepdk45/gds_lib/cell_1rw_1r.gds differ diff --git a/technology/freepdk45/gds_lib/replica_cell_1rw_1r.gds b/technology/freepdk45/gds_lib/replica_cell_1rw_1r.gds index 8bc45cbb..96bf3d75 100644 Binary files a/technology/freepdk45/gds_lib/replica_cell_1rw_1r.gds and b/technology/freepdk45/gds_lib/replica_cell_1rw_1r.gds differ