diff --git a/compiler/base/hierarchy_layout.py b/compiler/base/hierarchy_layout.py index 2e0bf755..6b1ca3fd 100644 --- a/compiler/base/hierarchy_layout.py +++ b/compiler/base/hierarchy_layout.py @@ -517,12 +517,12 @@ class layout(): self.connect_inst([]) return inst - def add_via_stack(self, offset, direction, from_layer, to_layer, - size=[1,1]): + def add_via_stack(self, offset, from_layer, to_layer, + direction=None, + size=[1, 1]): """ Punch a stack of vias from a start layer to a target layer. """ - return self.__add_via_stack_internal(offset=offset, direction=direction, from_layer=from_layer, @@ -531,8 +531,9 @@ class layout(): last_via=None, size=size) - def add_via_stack_center(self, offset, direction, from_layer, to_layer, - size=[1,1]): + def add_via_stack_center(self, offset, from_layer, to_layer, + direction=None, + size=[1, 1]): """ Punch a stack of vias from a start layer to a target layer by the center coordinate accounting for mirroring and rotation. @@ -545,7 +546,6 @@ class layout(): last_via=None, size=size) - def __add_via_stack_internal(self, offset, direction, from_layer, to_layer, via_func, last_via, size): """ @@ -581,7 +581,6 @@ class layout(): last_via=via, size=size) - def add_ptx(self, offset, mirror="R0", rotate=0, width=1, mults=1, tx_type="nmos"): """Adds a ptx module to the design.""" import ptx diff --git a/compiler/modules/hierarchical_decoder.py b/compiler/modules/hierarchical_decoder.py index 7d625b75..f9c21619 100644 --- a/compiler/modules/hierarchical_decoder.py +++ b/compiler/modules/hierarchical_decoder.py @@ -521,7 +521,7 @@ class hierarchical_decoder(design.design): """ Add a pin for each row of vdd/gnd which are must-connects next level up. """ # The vias will be placed in the center and right of the cells, respectively. - xoffset = self.nand_inst[0].cx() + xoffset = self.nand_inst[0].rx() for num in range(0, self.rows): for pin_name in ["vdd", "gnd"]: # The nand and inv are the same height rows... diff --git a/compiler/modules/wordline_driver.py b/compiler/modules/wordline_driver.py index 27671fd2..35a2b8bf 100644 --- a/compiler/modules/wordline_driver.py +++ b/compiler/modules/wordline_driver.py @@ -75,8 +75,7 @@ class wordline_driver(design.design): """ # Find the x offsets for where the vias/pins should be placed - a_xoffset = self.nand_inst[0].rx() - b_xoffset = self.inv2_inst[0].lx() + a_xoffset = self.nand_inst[0].lx() for num in range(self.rows): # this will result in duplicate polygons for rails, but who cares @@ -90,7 +89,7 @@ class wordline_driver(design.design): supply_pin = self.inv2_inst[num].get_pin(name) # Add pins in two locations - for xoffset in [a_xoffset, b_xoffset]: + for xoffset in [a_xoffset]: pin_pos = vector(xoffset, supply_pin.cy()) self.add_power_pin(name, pin_pos) diff --git a/compiler/pgates/pgate.py b/compiler/pgates/pgate.py index a6a11a28..7693fa07 100644 --- a/compiler/pgates/pgate.py +++ b/compiler/pgates/pgate.py @@ -267,8 +267,8 @@ class pgate(design.design): def determine_width(self): """ Determine the width based on the well contacts (assumed to be on the right side) """ - # Width is determined by well contact and spacing - self.width = max(self.nwell_contact.rx(), self.pwell_contact.rx()) + self.m1_space + # Width is determined by well contact and spacing and allowing a supply via between each cell + self.width = max(self.nwell_contact.rx(), self.pwell_contact.rx()) + self.m1_space + 0.5 * contact.m1_via.width self.well_width = self.width + 2 * self.nwell_enclose_active # Height is an input parameter, so it is not recomputed. diff --git a/compiler/pgates/precharge.py b/compiler/pgates/precharge.py index acb2062f..4a494763 100644 --- a/compiler/pgates/precharge.py +++ b/compiler/pgates/precharge.py @@ -12,7 +12,7 @@ from tech import parameter from vector import vector from globals import OPTS from sram_factory import factory - +from tech import drc class precharge(design.design): """ @@ -30,7 +30,10 @@ class precharge(design.design): self.width = self.bitcell.width self.bitcell_bl = bitcell_bl self.bitcell_br = bitcell_br - + self.bitcell_bl_pin =self.bitcell.get_pin(self.bitcell_bl) + self.bitcell_br_pin =self.bitcell.get_pin(self.bitcell_br) + print(self.bitcell_bl_pin) + print(self.bitcell_br_pin) # Creates the netlist and layout # Since it has variable height, it is not a pgate. self.create_netlist() @@ -50,6 +53,7 @@ class precharge(design.design): self.create_ptx() def create_layout(self): + self.place_ptx() self.connect_poly() self.route_en() @@ -120,17 +124,18 @@ class precharge(design.design): contact_xdiff = self.pmos.get_pin("S").lx() # adds the lower pmos to layout - bl_xoffset = self.bitcell.get_pin(self.bitcell_bl).lx() + bl_xoffset = self.bitcell_bl_pin.lx() self.lower_pmos_position = vector(max(bl_xoffset - contact_xdiff, self.nwell_enclose_active), self.pmos.active_offset.y) 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.poly_contact.width + ydiff = self.pmos.height + 4 * self.m2_space self.upper_pmos1_pos = self.lower_pmos_position + vector(0, ydiff) self.upper_pmos1_inst.place(self.upper_pmos1_pos) + # Second pmos to the right of the first upper_pmos2_pos = self.upper_pmos1_pos + overlap_offset self.upper_pmos2_inst.place(upper_pmos2_pos) @@ -161,16 +166,25 @@ class precharge(design.design): """ Adds the en input rail, en contact/vias, and connects to the pmos """ - + + if self.bitcell_bl_pin.layer == "m1": + layer = "m2" + else: + layer = "m1" + # adds the en contact to connect the gates to the en rail on metal1 offset = self.lower_pmos_inst.get_pin("G").ul() \ - + vector(0, 0.5 * self.poly_space) + + vector(0, self.m2_pitch) self.add_via_center(layers=self.poly_stack, offset=offset) + if layer == "m2": + self.add_via_center(layers=self.m1_stack, + offset=offset) + # adds the en rail on metal1 self.add_layout_pin_segment_center(text="en_bar", - layer="m1", + layer=layer, start=offset.scale(0, 1), end=offset.scale(0, 1) + vector(self.width, 0)) @@ -201,20 +215,21 @@ class precharge(design.design): """ Adds both bit-line and bit-line-bar to the module """ - + layer_width = drc("minwidth_" + self.bitcell_br_pin.layer) + layer_space = drc("{0}_to_{0}".format(self.bitcell_br_pin.layer)) + layer = self.bitcell_bl_pin.layer + # adds the BL on metal 2 - offset = vector(self.bitcell.get_pin(self.bitcell_bl).cx(), 0) \ - - vector(0.5 * self.m2_width, 0) + offset = vector(layer_space - 0.5 * layer_width, 0) self.bl_pin = self.add_layout_pin(text="bl", - layer="m2", + layer=layer, offset=offset, height=self.height) # adds the BR on metal 2 - offset = vector(self.bitcell.get_pin(self.bitcell_br).cx(), 0) \ - - vector(0.5 * self.m2_width, 0) + offset = vector(self.width - layer_space - 0.5 * layer_width, 0) self.br_pin = self.add_layout_pin(text="br", - layer="m2", + layer=layer, offset=offset, height=self.height) @@ -225,11 +240,12 @@ class precharge(design.design): self.add_bitline_contacts() self.connect_pmos_m2(self.lower_pmos_inst.get_pin("S"), self.get_pin("bl")) + self.connect_pmos_m2(self.lower_pmos_inst.get_pin("D"), + self.get_pin("br")) + self.connect_pmos_m2(self.upper_pmos1_inst.get_pin("S"), self.get_pin("bl")) - self.connect_pmos_m1(self.lower_pmos_inst.get_pin("D"), - self.get_pin("br")) - self.connect_pmos_m1(self.upper_pmos2_inst.get_pin("D"), + self.connect_pmos_m2(self.upper_pmos2_inst.get_pin("D"), self.get_pin("br")) def add_bitline_contacts(self): @@ -237,34 +253,28 @@ class precharge(design.design): Adds contacts/via from metal1 to metal2 for bit-lines """ - upper_pin = self.upper_pmos1_inst.get_pin("S") - lower_pin = self.lower_pmos_inst.get_pin("S") - # BL goes up to M2 at the transistor - self.bl_contact =self.add_via_center(layers=self.m1_stack, - offset=upper_pin.center(), + # BL + lower_pin = self.lower_pmos_inst.get_pin("S") + self.lower_via = self.add_via_center(layers=self.m1_stack, + offset=lower_pin.center(), directions=("V", "V")) - self.add_via_center(layers=self.m1_stack, - offset=lower_pin.center(), - directions=("V", "V")) - # BR routes over on M1 first - self.add_via_center(layers=self.m1_stack, - offset=vector(self.br_pin.cx(), upper_pin.cy()), - directions=("V", "V")) - self.add_via_center(layers=self.m1_stack, - offset=vector(self.br_pin.cx(), lower_pin.cy()), - directions=("V", "V")) + lower_pin = self.lower_pmos_inst.get_pin("D") + self.lower_via = self.add_via_center(layers=self.m1_stack, + offset=lower_pin.center(), + directions=("V", "V")) + + # BR + upper_pin = self.upper_pmos1_inst.get_pin("S") + self.upper_via2 = self.add_via_center(layers=self.m1_stack, + offset=upper_pin.center(), + directions=("V", "V")) - def connect_pmos_m1(self, pmos_pin, bit_pin): - """ - Connect a pmos pin to bitline pin - """ - - left_pos = vector(min(pmos_pin.cx(), bit_pin.cx()), pmos_pin.cy()) - right_pos = vector(max(pmos_pin.cx(), bit_pin.cx()), pmos_pin.cy()) - - self.add_path("m1", [left_pos, right_pos] ) + upper_pin = self.upper_pmos2_inst.get_pin("D") + self.upper_via2 = self.add_via_center(layers=self.m1_stack, + offset=upper_pin.center(), + directions=("V", "V")) def connect_pmos_m2(self, pmos_pin, bit_pin): """ @@ -274,7 +284,7 @@ class precharge(design.design): left_pos = vector(min(pmos_pin.cx(), bit_pin.cx()), pmos_pin.cy()) right_pos = vector(max(pmos_pin.cx(), bit_pin.cx()), pmos_pin.cy()) - self.add_path("m2", [left_pos, right_pos], self.bl_contact.height) + self.add_path("m2", [left_pos, right_pos]) def get_en_cin(self): """Get the relative capacitance of the enable in the precharge cell"""