mirror of https://github.com/VLSIDA/OpenRAM.git
Fix single finger ptx bugs.
This commit is contained in:
parent
6207f2157c
commit
0214cfb48e
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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 """
|
||||
|
|
|
|||
|
|
@ -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)]
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
Loading…
Reference in New Issue