diff --git a/compiler/pgates/pnor2.py b/compiler/pgates/pnor2.py index 453a62b6..3efe542d 100644 --- a/compiler/pgates/pnor2.py +++ b/compiler/pgates/pnor2.py @@ -73,33 +73,43 @@ class pnor2(pgate.pgate): connect_active=True) self.add_mod(self.nmos) - self.pmos = factory.create(module_type="ptx", - width=self.pmos_width, - mults=self.tx_mults, - tx_type="pmos", - connect_poly=True, - connect_active=True) - self.add_mod(self.pmos) + self.pmos_nd = factory.create(module_type="ptx", + width=self.pmos_width, + mults=self.tx_mults, + tx_type="pmos", + add_drain_contact=False, + connect_poly=True, + connect_active=True) + self.add_mod(self.pmos_nd) + self.pmos_ns = factory.create(module_type="ptx", + width=self.pmos_width, + mults=self.tx_mults, + tx_type="pmos", + add_source_contact=False, + connect_poly=True, + connect_active=True) + self.add_mod(self.pmos_ns) + def setup_layout_constants(self): """ Pre-compute some handy layout parameters. """ # metal spacing to allow contacts on any layer 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.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 - self.overlap_offset = self.pmos.get_pin("D").ll() - self.pmos.get_pin("S").ll() + self.overlap_offset = self.pmos_ns.get_pin("D").ll() - self.pmos_nd.get_pin("S").ll() # Two PMOS devices and a well contact. Separation between each. # Enclosure space on the sides. - self.width = 2 * self.pmos.active_width \ - + self.pmos.active_contact.width \ - + 2 * self.active_space \ - + 0.5 * self.nwell_enclose_active + self.width = 2 * self.pmos_ns.active_width \ + + self.pmos_ns.active_contact.width \ + + 2 * self.active_space \ + + 0.5 * self.nwell_enclose_active self.well_width = self.width + 2 * self.nwell_enclose_active # Height is an input parameter, so it is not recomputed. @@ -107,7 +117,7 @@ class pnor2(pgate.pgate): # to the active contacts extra_contact_space = max(-self.nmos.get_pin("D").by(), 0) # This is a poly-to-poly of a flipped cell - self.top_bottom_space = max(0.5 * self.m1_width + self.m1_space + extra_contact_space, + self.top_bottom_space = max(0.5 * self.m1_width + self.m1_space + extra_contact_space, self.poly_extend_active, self.poly_space) @@ -130,11 +140,11 @@ class pnor2(pgate.pgate): """ self.pmos1_inst = self.add_inst(name="pnor2_pmos1", - mod=self.pmos) + mod=self.pmos_nd) self.connect_inst(["vdd", "A", "net1", "vdd"]) self.pmos2_inst = self.add_inst(name="pnor2_pmos2", - mod=self.pmos) + mod=self.pmos_ns) self.connect_inst(["net1", "B", "Z", "vdd"]) self.nmos1_inst = self.add_inst(name="pnor2_nmos1", @@ -151,15 +161,15 @@ class pnor2(pgate.pgate): to provide maximum routing in channel """ - pmos1_pos = vector(self.pmos.active_offset.x, - self.height - self.pmos.active_height \ + pmos1_pos = vector(self.pmos_ns.active_offset.x, + self.height - self.pmos_ns.active_height \ - self.top_bottom_space) self.pmos1_inst.place(pmos1_pos) self.pmos2_pos = pmos1_pos + self.overlap_offset self.pmos2_inst.place(self.pmos2_pos) - nmos1_pos = vector(self.pmos.active_offset.x, self.top_bottom_space) + nmos1_pos = vector(self.pmos_ns.active_offset.x, self.top_bottom_space) self.nmos1_inst.place(nmos1_pos) self.nmos2_pos = nmos1_pos + self.overlap_offset @@ -172,7 +182,7 @@ class pnor2(pgate.pgate): def add_well_contacts(self): """ Add n/p well taps to the layout and connect to supplies """ - self.add_nwell_contact(self.pmos, self.pmos2_pos) + self.add_nwell_contact(self.pmos_ns, self.pmos2_pos) self.add_pwell_contact(self.nmos, self.nmos2_pos) def connect_rails(self):