diff --git a/compiler/pgates/pnor2.py b/compiler/pgates/pnor2.py index 3d998d25..453a62b6 100644 --- a/compiler/pgates/pnor2.py +++ b/compiler/pgates/pnor2.py @@ -187,8 +187,7 @@ class pnor2(pgate.pgate): def route_inputs(self): """ Route the A and B inputs """ # Use M2 spaces so we can drop vias on the pins later! - inputB_yoffset = self.nmos2_pos.y + self.nmos.active_height \ - + self.m2_space + self.m2_width + inputB_yoffset = self.nmos2_inst.uy() + 0.5 * contact.poly_contact.height self.route_input_gate(self.pmos2_inst, self.nmos2_inst, inputB_yoffset, diff --git a/compiler/pgates/ptx.py b/compiler/pgates/ptx.py index 46726b37..ae20d586 100644 --- a/compiler/pgates/ptx.py +++ b/compiler/pgates/ptx.py @@ -27,15 +27,23 @@ class ptx(design.design): width=drc("minwidth_tx"), mults=1, tx_type="nmos", + add_source_contact=True, + add_drain_contact=True, + series_devices=False, connect_active=False, connect_poly=False, - series_devices=False, num_contacts=None): # We need to keep unique names because outputting to GDSII # will use the last record with a given name. I.e., you will # over-write a design in GDS if one has and the other doesn't # have poly connected, for example. name = "{0}_m{1}_w{2:.3f}".format(tx_type, mults, width) + if not add_source_contact: + name += "_ns" + if not add_drain_contact: + name += "_nd" + if series_devices: + name += "_sd" if connect_active: name += "_a" if connect_poly: @@ -52,6 +60,8 @@ class ptx(design.design): self.tx_width = width self.connect_active = connect_active self.connect_poly = connect_poly + self.add_source_contact = add_source_contact + self.add_drain_contact = add_drain_contact self.series_devices = series_devices self.num_contacts = num_contacts @@ -379,18 +389,24 @@ class ptx(design.design): # First one is always a SOURCE label = "S" pos = self.contact_offset - contact=self.add_via_center(layers=self.active_stack, - offset=pos, - size=(1, self.num_contacts), - directions=("V","V"), - implant_type=self.implant_type, - well_type=self.well_type) - self.add_layout_pin_rect_center(text=label, - layer="m1", + if self.add_source_contact: + contact=self.add_via_center(layers=self.active_stack, offset=pos, - width=contact.mod.second_layer_width, - height=contact.mod.second_layer_height) - self.source_contacts.append(contact) + size=(1, self.num_contacts), + directions=("V","V"), + implant_type=self.implant_type, + well_type=self.well_type) + self.source_contacts.append(contact) + if self.add_source_contact: + self.add_layout_pin_rect_center(text=label, + layer="m1", + offset=pos, + width=contact.mod.second_layer_width, + height=contact.mod.second_layer_height) + else: + self.add_layout_pin_rect_center(text=label, + layer="active", + offset=pos) source_positions.append(pos) # Skip these if they are going to be in series @@ -406,22 +422,26 @@ class ptx(design.design): label = "S" source_positions.append(pos) - contact=self.add_via_center(layers=self.active_stack, - offset=pos, - size=(1, self.num_contacts), - directions=("V","V"), - implant_type=self.implant_type, - well_type=self.well_type) - self.add_layout_pin_rect_center(text=label, - layer="m1", + if (label=="S" and self.add_source_contact) or (label=="D" and self.add_drain_contact): + contact=self.add_via_center(layers=self.active_stack, offset=pos, - width=contact.mod.second_layer_width, - height=contact.mod.second_layer_height) - - if label == "S": - self.source_contacts.append(contact) + size=(1, self.num_contacts), + directions=("V", "V"), + implant_type=self.implant_type, + well_type=self.well_type) + self.add_layout_pin_rect_center(text=label, + layer="m1", + offset=pos, + width=contact.mod.second_layer_width, + height=contact.mod.second_layer_height) + if label == "S": + self.source_contacts.append(contact) + else: + self.drain_contacts.append(contact) else: - self.drain_contacts.append(contact) + self.add_layout_pin_rect_center(text=label, + layer="active", + offset=pos) pos = vector(self.active_offset.x + self.active_width - 0.5 * self.active_contact.width, self.contact_offset.y) @@ -432,21 +452,28 @@ class ptx(design.design): else: label = "S" source_positions.append(pos) - contact=self.add_via_center(layers=self.active_stack, - offset=pos, - size=(1, self.num_contacts), - directions=("V","V"), - implant_type=self.implant_type, - well_type=self.well_type) - self.add_layout_pin_rect_center(text=label, - layer="m1", + + if (label=="S" and self.add_source_contact) or (label=="D" and self.add_drain_contact): + contact=self.add_via_center(layers=self.active_stack, offset=pos, - width=contact.mod.second_layer_width, - height=contact.mod.second_layer_height) - if label == "S": - self.source_contacts.append(contact) + size=(1, self.num_contacts), + directions=("V", "V"), + implant_type=self.implant_type, + well_type=self.well_type) + if label == "S": + self.source_contacts.append(contact) + else: + self.drain_contacts.append(contact) + if (label=="S" and self.add_source_contact) or (label=="D" and self.add_drain_contact): + self.add_layout_pin_rect_center(text=label, + layer="m1", + offset=pos, + width=contact.mod.second_layer_width, + height=contact.mod.second_layer_height) else: - self.drain_contacts.append(contact) + self.add_layout_pin_rect_center(text=label, + layer="active", + offset=pos) if self.connect_active: self.connect_fingered_active(drain_positions, source_positions) diff --git a/compiler/tests/03_ptx_1finger_nmos_test.py b/compiler/tests/03_ptx_1finger_nmos_test.py index ae323d90..0774af4a 100755 --- a/compiler/tests/03_ptx_1finger_nmos_test.py +++ b/compiler/tests/03_ptx_1finger_nmos_test.py @@ -15,6 +15,7 @@ from globals import OPTS from sram_factory import factory import debug + class ptx_1finger_nmos_test(openram_test): def runTest(self):