Fix single finger ptx bugs.

This commit is contained in:
Matt Guthaus 2017-11-30 11:56:40 -08:00
parent 6207f2157c
commit 0214cfb48e
6 changed files with 49 additions and 69 deletions

View File

@ -512,7 +512,7 @@ class bank(design.design):
bank_sel_line_pos = vector(xoffset_bank_sel + 0.5*self.m2_width, self.min_point)
bank_sel_pin_pos=vector(self.left_vdd_x_offset, self.min_point)
self.add_center_layout_pin_segment(text="bank_sel",
self.add_layout_pin_center_segment(text="bank_sel",
layer="metal3",
start=bank_sel_pin_pos,
end=bank_sel_line_pos)
@ -629,7 +629,7 @@ class bank(design.design):
offset=logic_pos,
rotate=90)
self.add_center_layout_pin_segment(text=input_name,
self.add_layout_pin_center_segment(text=input_name,
layer="metal3",
start=input_pos,
end=logic_pos)

View File

@ -148,7 +148,7 @@ class instance(geometry):
def __str__(self):
""" override print function output """
return "inst: " + self.name + " mod=" + self.mod.name
return "inst: " + self.name + " mod=" + self.mod.name
def __repr__(self):
""" override print function output """

View File

@ -174,7 +174,7 @@ class layout:
new_name = pin.name
self.add_layout_pin(new_name, pin.layer, pin.ll(), pin.width(), pin.height())
def add_center_layout_pin_segment(self, text, layer, start, end):
def add_layout_pin_center_segment(self, text, layer, start, end):
""" Creates a path like pin with center-line convention """
debug.check(start.x==end.x or start.y==end.y,"Cannot have a non-manhatten layout pin.")
@ -198,7 +198,7 @@ class layout:
return self.add_layout_pin(text, layer, ll_offset, width, height)
def add_center_layout_pin_rect(self, text, layer, offset, width=None, height=None):
def add_layout_pin_center_rect(self, text, layer, offset, width=None, height=None):
""" Creates a path like pin with center-line convention """
if width==None:
width=drc["minwidth_{0}".format(layer)]

View File

@ -142,6 +142,7 @@ class pinv(design.design):
connect_poly=True,
connect_active=True)
self.add_mod(self.nmos)
self.pmos = ptx(width=self.pmos_width,
mults=self.tx_mults,
tx_type="pmos",
@ -151,12 +152,12 @@ class pinv(design.design):
def add_supply_rails(self):
""" Add vdd/gnd rails to the top and bottom. """
self.add_center_layout_pin_rect(text="gnd",
self.add_layout_pin_center_rect(text="gnd",
layer="metal1",
offset=vector(0.5*self.width,0),
width=self.width)
self.add_center_layout_pin_rect(text="vdd",
self.add_layout_pin_center_rect(text="vdd",
layer="metal1",
offset=vector(0.5*self.width,self.height),
width=self.width)
@ -168,7 +169,6 @@ class pinv(design.design):
"""
# place PMOS so it is half a poly spacing down from the top
# Source should overlap rail if it is fingered!
pmos_position = vector(0,self.height-self.pmos.height-0.5*drc["poly_to_poly"])
self.pmos_inst=self.add_inst(name="pinv_pmos",
mod=self.pmos,
@ -176,7 +176,6 @@ class pinv(design.design):
self.connect_inst(["Z", "A", "vdd", "vdd"])
# place NMOS so that it is half a poly spacing up from the bottom
# Source should overlap rail if it is fingered!
nmos_position = vector(0,self.nmos.height+0.5*drc["poly_to_poly"])
self.nmos_inst=self.add_inst(name="pinv_nmos",
mod=self.nmos,
@ -256,28 +255,28 @@ class pinv(design.design):
nmos_gate_pin = self.nmos_inst.get_pin("G")
pmos_gate_pin = self.pmos_inst.get_pin("G")
# Pick point in center of NMOS and connect down to PMOS
# Pick point on the left of NMOS and connect down to PMOS
nmos_gate_pos = nmos_gate_pin.ll() + vector(0.5*drc["minwidth_poly"],0)
pmos_gate_pos = vector(nmos_gate_pos.x,pmos_gate_pin.bc().y)
self.add_path("poly",[nmos_gate_pos,pmos_gate_pos])
# The midpoint of the vertical poly gate
mid_gate_offset = vector(nmos_gate_pos.x,self.middle_position.y)
contact_offset = mid_gate_offset - vector(0.5*self.poly_contact.height,0)
# Add the via to the cell midpoint along the gate
left_gate_offset = vector(nmos_gate_pin.lx(),self.middle_position.y)
contact_offset = left_gate_offset - vector(0.5*self.poly_contact.height,0)
self.add_center_contact(layers=("poly", "contact", "metal1"),
offset=contact_offset,
rotate=90)
self.add_center_layout_pin_segment(text="A",
self.add_layout_pin_center_segment(text="A",
layer="metal1",
start=mid_gate_offset.scale(0,1),
end=mid_gate_offset)
start=left_gate_offset.scale(0,1),
end=left_gate_offset)
# This is to ensure that the contact is connected to the gate
mid_point = contact_offset.scale(0.5,1)+mid_gate_offset.scale(0.5,0)
mid_point = contact_offset.scale(0.5,1)+left_gate_offset.scale(0.5,0)
self.add_center_rect(layer="poly",
offset=mid_point,
height=self.poly_contact.first_layer_width,
width=mid_gate_offset.x-contact_offset.x)
width=left_gate_offset.x-contact_offset.x)
def route_output_drain(self):
@ -299,7 +298,7 @@ class pinv(design.design):
if self.route_output == True:
# This extends the output to the edge of the cell
output_offset = mid_drain_offset.scale(0,1) + vector(self.width,0)
self.add_center_layout_pin_segment(text="Z",
self.add_layout_pin_center_segment(text="Z",
layer="metal1",
start=mid_drain_offset,
end=output_offset)
@ -375,8 +374,8 @@ class pinv(design.design):
# Only if they don't overlap already
if gnd_pin.uy() < nmos_source_pin.by():
self.add_rect(layer="metal1",
offset=nmos__pin.ll(),
height=nmos_source_pin.by()-gnd_pin.uy(),
offset=nmos_source_pin.ll(),
height=-1*nmos_source_pin.by(),
width=nmos_source_pin.width())
pmos_source_pin = self.pmos_inst.get_pin("S")

View File

@ -47,9 +47,6 @@ class ptx(design.design):
# but this may be uncommented for debug purposes
#self.DRC()
def add_pins(self):
"""Adds pins for spice netlist"""
self.add_pin_list(["D", "G", "S", "B"])
def create_layout(self):
"""Calls all functions related to the generation of the layout"""
@ -60,7 +57,7 @@ class ptx(design.design):
self.add_active_contacts()
def create_spice(self):
self.add_pins()
self.add_pin_list(["D", "G", "S", "B"])
self.spice.append("\n.SUBCKT {0} {1}".format(self.name,
" ".join(self.pins)))
@ -160,7 +157,7 @@ class ptx(design.design):
and we will add a single horizontal connection.
"""
# Nothing to do if there's one poly gate
if len(poly_positions) == 1:
if len(poly_positions)<2:
return
# The width of the poly is from the left-most to right-most poly gate
@ -189,25 +186,25 @@ class ptx(design.design):
+ drc["metal1_to_metal1"] + 0.5*drc["minwidth_metal1"])
# This is the width of a contact to extend the ends of the pin
end_offset = vector(self.active_contact.second_layer_width/2,0)
if source_positions: # if not an empty set
if len(source_positions)>1:
self.remove_layout_pin("S") # remove the individual connections
# Add each vertical segment
for a in source_positions:
self.add_path(("metal1"), [a,a+pin_offset])
# Add a single horizontal pin
self.add_center_layout_pin_segment(text="S",
self.add_layout_pin_center_segment(text="S",
layer="metal1",
start=source_positions[0]+pin_offset-end_offset,
end=source_positions[-1]+pin_offset+end_offset)
if drain_positions: # if not an empty set
if len(drain_positions)>1:
self.remove_layout_pin("D") # remove the individual connections
# Add each vertical segment
for a in drain_positions:
self.add_path(("metal1"), [a,a-pin_offset])
# Add a single horizontal pin
self.add_center_layout_pin_segment(text="D",
self.add_layout_pin_center_segment(text="D",
layer="metal1",
start=drain_positions[0]-pin_offset-end_offset,
end=drain_positions[-1]-pin_offset+end_offset)
@ -223,18 +220,16 @@ class ptx(design.design):
poly_positions = []
for i in range(0, self.mults):
if self.connect_poly:
# Add the rectangle in case we remove the pin when joining fingers
self.add_center_rect(layer="poly",
offset=poly_offset,
height=self.poly_height,
width=self.poly_width)
else:
self.add_center_layout_pin_rect(text="G",
layer="poly",
offset=poly_offset,
height=self.poly_height,
width=self.poly_width)
# Add this duplicate rectangle in case we remove the pin when joining fingers
self.add_center_rect(layer="poly",
offset=poly_offset,
height=self.poly_height,
width=self.poly_width)
self.add_layout_pin_center_rect(text="G",
layer="poly",
offset=poly_offset,
height=self.poly_height,
width=self.poly_width)
poly_positions.append(poly_offset)
poly_offset = poly_offset + vector(self.poly_pitch,0)
@ -306,36 +301,22 @@ class ptx(design.design):
contact=self.add_center_contact(layers=("active", "contact", "metal1"),
offset=pos,
size=(1, self.num_contacts))
if self.connect_active:
# Add this in case the pins get removed when fingers joined
self.add_center_rect(layer="metal1",
offset=pos,
width=contact.second_layer_width,
height=contact.second_layer_height)
else:
self.add_center_layout_pin_rect(text="S",
layer="metal1",
offset=pos,
width=contact.second_layer_width,
height=contact.second_layer_height)
self.add_layout_pin_center_rect(text="S",
layer="metal1",
offset=pos,
width=contact.second_layer_width,
height=contact.second_layer_height)
for pos in drain_positions:
contact=self.add_center_contact(layers=("active", "contact", "metal1"),
offset=pos,
size=(1, self.num_contacts))
if self.connect_active:
# Add this in case the pins get removed when fingers joined
self.add_center_rect(layer="metal1",
offset=pos,
width=contact.second_layer_width,
height=contact.second_layer_height)
else:
self.add_center_layout_pin_rect(text="D",
layer="metal1",
offset=pos,
width=contact.second_layer_width,
height=contact.second_layer_height)
self.add_layout_pin_center_rect(text="D",
layer="metal1",
offset=pos,
width=contact.second_layer_width,
height=contact.second_layer_height)
if self.connect_active:
self.connect_fingered_active(drain_positions, source_positions)

View File

@ -167,7 +167,7 @@ class wordline_driver(design.design):
input_offset = vector(0,a_pos.y)
mid_via_offset = vector(clk_offset.x,a_pos.y) + vector(0.5*drc["minwidth_metal2"]+drc["metal2_to_metal2"]+0.5*m1m2_via.width,0)
# must under the clk line in M1
self.add_center_layout_pin_segment(text="in[{0}]".format(row),
self.add_layout_pin_center_segment(text="in[{0}]".format(row),
layer="metal1",
start=input_offset,
end=mid_via_offset)
@ -185,7 +185,7 @@ class wordline_driver(design.design):
# output each WL on the right
wl_offset = inv2_inst.get_pin("Z").rc()
self.add_center_layout_pin_segment(text="wl[{0}]".format(row),
self.add_layout_pin_center_segment(text="wl[{0}]".format(row),
layer="metal1",
start=wl_offset,
end=wl_offset-vector(drc["minwidth_metal1"],0))