Add dffs to control logic. Rename layout pin segment/rect functions for consistency. Redo gnd/vdd pins in control.

Shift s_en buffers even with other cells.
This commit is contained in:
Matt Guthaus 2018-03-21 13:20:48 -07:00
parent 696433b1ec
commit 97c08bce95
20 changed files with 215 additions and 232 deletions

View File

@ -110,6 +110,14 @@ class geometry:
""" Return the right edge """
return self.boundary[1].x
def cx(self):
""" Return the center x """
return 0.5*(self.boundary[0].x + self.boundary[1].x)
def cy(self):
""" Return the center y """
return 0.5*(self.boundary[0].y + self.boundary[1].y)
class instance(geometry):
"""

View File

@ -204,7 +204,7 @@ class layout(lef.lef):
new_name = pin.name
self.add_layout_pin(new_name, pin.layer, pin.ll(), pin.width(), pin.height())
def add_layout_pin_center_segment(self, text, layer, start, end):
def add_layout_pin_segment_center(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.")
@ -228,7 +228,7 @@ class layout(lef.lef):
return self.add_layout_pin(text, layer, ll_offset, width, height)
def add_layout_pin_center_rect(self, text, layer, offset, width=None, height=None):
def add_layout_pin_rect_center(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

@ -458,7 +458,7 @@ class bank(design.design):
""" Route the bank select logic. """
for input_name in self.input_control_signals+["bank_sel"]:
in_pos = self.bank_select_inst.get_pin(input_name).lc()
self.add_layout_pin_center_segment(text=input_name,
self.add_layout_pin_segment_center(text=input_name,
layer="metal3",
start=vector(self.left_gnd_x_offset,in_pos.y),
end=in_pos)

View File

@ -151,7 +151,7 @@ class bank_select(design.design):
# Route the pin to the left edge as well
bank_sel_pin_pos=vector(0, 0)
bank_sel_pin_end=vector(bank_sel_line_pos.x, bank_sel_pin_pos.y)
self.add_layout_pin_center_segment(text="bank_sel",
self.add_layout_pin_segment_center(text="bank_sel",
layer="metal3",
start=bank_sel_pin_pos,
end=bank_sel_pin_end)
@ -208,7 +208,7 @@ class bank_select(design.design):
self.add_via_center(layers=("metal2", "via2", "metal3"),
offset=logic_pos,
rotate=90)
self.add_layout_pin_center_segment(text=input_name,
self.add_layout_pin_segment_center(text=input_name,
layer="metal3",
start=input_pos,
end=logic_pos)
@ -224,14 +224,14 @@ class bank_select(design.design):
# Add vdd/gnd supply rails
gnd_pin = inv_inst.get_pin("gnd")
left_gnd_pos = vector(0, gnd_pin.cy())
self.add_layout_pin_center_segment(text="gnd",
self.add_layout_pin_segment_center(text="gnd",
layer="metal1",
start=left_gnd_pos,
end=gnd_pin.rc())
vdd_pin = inv_inst.get_pin("vdd")
left_vdd_pos = vector(0, vdd_pin.cy())
self.add_layout_pin_center_segment(text="vdd",
self.add_layout_pin_segment_center(text="vdd",
layer="metal1",
start=left_vdd_pos,
end=vdd_pin.rc())

View File

@ -7,6 +7,8 @@ from pinv import pinv
from pnand2 import pnand2
from pnand3 import pnand3
from pinvbuf import pinvbuf
from dff_inv import dff_inv
from dff_inv_array import dff_inv_array
import math
from vector import vector
from globals import OPTS
@ -28,15 +30,15 @@ class control_logic(design.design):
def create_layout(self):
""" Create layout and route between modules """
self.setup_layout_offsets()
self.add_pins()
self.create_modules()
self.add_rails()
self.add_modules()
self.add_routing()
def create_modules(self):
""" add all the required modules """
def add_pins(self):
""" Add the pins to the control logic module. """
for pin in self.input_list + ["clk"]:
self.add_pin(pin,"INPUT")
for pin in self.output_list:
@ -44,19 +46,28 @@ class control_logic(design.design):
self.add_pin("vdd","POWER")
self.add_pin("gnd","GROUND")
self.nand2 = pnand2()
def create_modules(self):
""" add all the required modules """
dff = dff_inv()
dff_height = dff.height
self.ctrl_dff_array = dff_inv_array(rows=3,columns=1)
self.add_mod(self.ctrl_dff_array)
self.nand2 = pnand2(height=dff_height)
self.add_mod(self.nand2)
self.nand3 = pnand3()
self.nand3 = pnand3(height=dff_height)
self.add_mod(self.nand3)
# Special gates: inverters for buffering
self.clkbuf = pinvbuf(4,16)
self.clkbuf = pinvbuf(4,16,height=dff_height)
self.add_mod(self.clkbuf)
self.inv = self.inv1 = pinv(1)
self.inv = self.inv1 = pinv(size=1, height=dff_height)
self.add_mod(self.inv1)
self.inv2 = pinv(2)
self.inv2 = pinv(size=4, height=dff_height)
self.add_mod(self.inv2)
self.inv8 = pinv(8)
self.inv8 = pinv(size=16, height=dff_height)
self.add_mod(self.inv8)
c = reload(__import__(OPTS.replica_bitline))
@ -82,10 +93,13 @@ class control_logic(design.design):
# Some cells may have pwell/nwell spacing problems too when the wells are different heights.
#self.cell_gap = max(self.m2_pitch,drc["pwell_to_nwell"])
# List of input control signals
self.input_list =["csb","web","oeb"]
self.input_width = len(self.input_list)*self.m2_pitch
self.input_bar_list = ["clk_buf_bar", "we", "cs", "oe"]
self.input_bar_width = len(self.input_bar_list)*self.m2_pitch
self.dff_output_list =["cs_bar", "cs", "we_bar", "we", "oe_bar", "oe"]
# list of output control signals (for making a vertical bus)
self.internal_list = ["clk_buf", "clk_buf_bar", "we", "cs", "oe"]
self.internal_width = len(self.internal_list)*self.m2_pitch
# Ooutputs to the bank
self.output_list = ["s_en", "w_en", "tri_en", "tri_en_bar", "clk_buf_bar", "clk_buf"]
self.supply_list = ["vdd", "gnd"]
self.rail_width = len(self.input_list)*len(self.output_list)*self.m2_pitch
@ -95,22 +109,11 @@ class control_logic(design.design):
#self.replica_bitline_gap = 2*self.m2_pitch
def add_rails(self):
""" Add the input signal tracks and their inverted tracks """
height = 4*self.inv1.height - self.m2_pitch
for i in range(len(self.input_list)):
name = self.input_list[i]
offset = vector(i*self.m2_pitch,0)
self.add_layout_pin(text=name,
layer="metal2",
offset=offset,
width=drc["minwidth_metal2"],
height=height)
self.rail_x_offsets[name]=offset.x + 0.5*drc["minwidth_metal2"] # center offset
""" Add the input signal inverted tracks """
height = 6*self.inv1.height - self.m2_pitch
for i in range(len(self.input_bar_list)):
name = self.input_bar_list[i]
offset = vector(i*self.m2_pitch + self.input_width + self.inv1.width, 0)
for i in range(len(self.internal_list)):
name = self.internal_list[i]
offset = vector(i*self.m2_pitch + self.ctrl_dff_array.width, 0)
# just for LVS correspondence...
self.add_label_pin(text=name,
layer="metal2",
@ -122,8 +125,7 @@ class control_logic(design.design):
def add_modules(self):
""" Place all the modules """
self.add_input_inv()
self.add_dffs()
self.add_clk_buffer(row=0)
self.add_we_row(row=2)
self.add_trien_row(row=3)
@ -146,7 +148,7 @@ class control_logic(design.design):
def add_routing(self):
""" Routing between modules """
self.route_input_inv()
self.route_dffs()
self.route_trien()
self.route_trien_bar()
self.route_rblk()
@ -171,7 +173,7 @@ class control_logic(design.design):
def add_clk_buffer(self,row):
""" Add the multistage clock buffer below the control flops """
x_off = self.input_width + self.inv1.width + self.input_bar_width
x_off = self.ctrl_dff_array.width + self.internal_width
y_off = row*self.inv1.height
if row % 2:
y_off += self.clkbuf.height
@ -189,7 +191,7 @@ class control_logic(design.design):
def add_rblk_row(self,row):
x_off = self.input_width + self.inv1.width + self.input_bar_width
x_off = self.ctrl_dff_array.width + self.internal_width
y_off = row*self.inv1.height
if row % 2:
y_off += self.inv1.height
@ -221,7 +223,7 @@ class control_logic(design.design):
def add_sen_row(self,row):
""" The sense enable buffer gets placed to the far right of the
row. """
x_off = self.replica_bitline.width - self.inv8.width
x_off = self.ctrl_dff_array.width + self.internal_width
y_off = row*self.inv1.height
if row % 2:
y_off += self.inv1.height
@ -249,7 +251,7 @@ class control_logic(design.design):
self.row_sen_end_x = self.replica_bitline.width
def add_trien_row(self, row):
x_off = self.input_width + self.inv1.width + self.input_bar_width
x_off = self.ctrl_dff_array.width + self.internal_width
y_off = row*self.inv1.height
if row % 2:
y_off += self.inv1.height
@ -293,7 +295,7 @@ class control_logic(design.design):
def add_trien_bar_row(self, row):
x_off = self.input_width + self.inv1.width + self.input_bar_width
x_off = self.ctrl_dff_array.width + self.internal_width
y_off = row*self.inv1.height
if row % 2:
y_off += self.inv1.height
@ -334,55 +336,34 @@ class control_logic(design.design):
self.row_trien_bar_end_x = x_off
def route_input_inv(self):
def route_dffs(self):
""" Route the input inverters """
self.connect_rail_from_left(self.cs_inv,"A","csb")
self.connect_rail_from_left(self.we_inv,"A","web")
self.connect_rail_from_left(self.oe_inv,"A","oeb")
self.connect_rail_from_right(self.ctrl_dff_inst,"dout_bar[0]","cs")
self.connect_rail_from_right(self.ctrl_dff_inst,"dout_bar[1]","we")
self.connect_rail_from_right(self.ctrl_dff_inst,"dout_bar[2]","oe")
self.connect_rail_from_right(self.cs_inv,"Z","cs")
self.connect_rail_from_right(self.we_inv,"Z","we")
self.connect_rail_from_right(self.oe_inv,"Z","oe")
# Connect the clock rail to the other clock rail
in_pos = self.ctrl_dff_inst.get_pin("clk").uc()
mid_pos = in_pos + vector(0,self.m2_pitch)
rail_pos = vector(self.rail_x_offsets["clk_buf"], mid_pos.y)
self.add_wire(("metal1","via1","metal2"),[in_pos, mid_pos, rail_pos])
self.add_via_center(layers=("metal1","via1","metal2"),
offset=rail_pos,
rotate=90)
def add_input_inv(self):
""" Add the three input inverters """
y_off = 0
mirror = "R0"
# input: csb output: cs
self.cs_inv_offset = vector(self.input_width, y_off)
self.cs_inv=self.add_inst(name="cs_inv",
mod=self.inv1,
offset=self.cs_inv_offset,
mirror=mirror)
self.connect_inst(["csb", "cs", "vdd", "gnd"])
y_off += 2*self.inv1.height
mirror = "MX"
# input: oeb output: oe
self.oe_inv_offset = vector(self.input_width, y_off)
self.oe_inv=self.add_inst(name="oe_inv",
mod=self.inv1,
offset=self.oe_inv_offset,
mirror=mirror)
self.connect_inst(["oeb", "oe", "vdd", "gnd"])
def add_dffs(self):
""" Add the three input DFFs (with inverters) """
self.ctrl_dff_inst=self.add_inst(name="ctrl_dffs",
mod=self.ctrl_dff_array,
offset=vector(0,0))
# Skip a row to prevent via conflict
y_off += 2*self.inv1.height
mirror = "MX"
# input: web output: we
self.we_inv_offset = vector(self.input_width, y_off)
self.we_inv=self.add_inst(name="we_inv",
mod=self.inv1,
offset=self.we_inv_offset,
mirror=mirror)
self.connect_inst(["web", "we", "vdd", "gnd"])
self.connect_inst(self.input_list + self.dff_output_list + ["clk_buf"] + self.supply_list)
def add_we_row(self,row):
x_off = self.input_width + self.inv1.width + self.input_bar_width
x_off = self.ctrl_dff_inst.width + self.internal_width
y_off = row*self.inv1.height
if row % 2:
y_off += self.inv1.height
@ -575,11 +556,12 @@ class control_logic(design.design):
""" Route the clk and clk_buf_bar signal internally """
clk_pin = self.clkbuf.get_pin("A")
self.add_layout_pin_center_segment(text="clk",
self.add_layout_pin_segment_center(text="clk",
layer="metal2",
start=clk_pin.bc(),
end=clk_pin.bc().scale(1,0))
self.connect_rail_from_right_m2m3(self.clkbuf, "Z", "clk_buf")
self.connect_rail_from_right_m2m3(self.clkbuf, "Zb", "clk_buf_bar")
self.connect_output(self.clkbuf, "Z", "clk_buf")
self.connect_output(self.clkbuf, "Zb", "clk_buf_bar")
@ -588,7 +570,7 @@ class control_logic(design.design):
""" Create an output pin on the right side from the pin of a given instance. """
out_pin = inst.get_pin(pin_name)
right_pos=out_pin.center() + vector(self.width-out_pin.cx(),0)
self.add_layout_pin_center_segment(text=out_name,
self.add_layout_pin_segment_center(text=out_name,
layer="metal1",
start=out_pin.center(),
end=right_pos)
@ -612,7 +594,7 @@ class control_logic(design.design):
yoffset = i*self.inv1.height
self.add_layout_pin_center_segment(text=name,
self.add_layout_pin_segment_center(text=name,
layer="metal1",
start=vector(rows_start,yoffset),
end=vector(rows_end,yoffset))
@ -628,43 +610,10 @@ class control_logic(design.design):
# width=rows_end-rows_start,
# height=well_width)
for vdd_pin in self.rbl_inst.get_pins("vdd"):
if vdd_pin.layer != "metal1":
continue
left = vdd_pin.lc().scale(0,1)
right = left + vector(rows_end,0)
self.add_layout_pin_center_segment(text="vdd",
layer="metal1",
start=left,
end=right)
for gnd_pin in self.rbl_inst.get_pins("gnd"):
if gnd_pin.layer != "metal1":
continue
left = gnd_pin.lc().scale(0,1)
right = left + vector(rows_end,0)
self.add_layout_pin_center_segment(text="gnd",
layer="metal1",
start=left,
end=right)
for vdd_pin in self.rbl_inst.get_pins("vdd"):
if vdd_pin.layer != "metal2":
continue
self.add_layout_pin(text="vdd",
layer="metal2",
offset=vdd_pin.ll(),
height=vdd_pin.height(),
width=vdd_pin.width())
for gnd_pin in self.rbl_inst.get_pins("gnd"):
if gnd_pin.layer != "metal2":
continue
self.add_layout_pin(text="gnd",
layer="metal2",
offset=gnd_pin.ll(),
height=gnd_pin.height(),
width=gnd_pin.width())
self.copy_layout_pin(self.rbl_inst,"gnd")
self.copy_layout_pin(self.rbl_inst,"vdd")
def add_lvs_correspondence_points(self):

View File

@ -194,7 +194,7 @@ class delay_chain(design.design):
offset=a_pin.center())
mid_point = vector(a_pin.cx()+3*self.m2_width,a_pin.cy())
self.add_path("metal2",[a_pin.center(), mid_point, mid_point.scale(1,0)])
self.add_layout_pin_center_segment(text="out",
self.add_layout_pin_segment_center(text="out",
layer="metal2",
start=mid_point,
end=mid_point.scale(1,0))

View File

@ -74,13 +74,17 @@ class dff_buf(design.design):
# Route dff q to inv1 a
q_pin = self.dff_inst.get_pin("Q")
a1_pin = self.inv1_inst.get_pin("A")
mid_point = vector(a1_pin.cx(), q_pin.cy())
self.add_wire(("metal3","via2","metal2"),
[q_pin.center(), mid_point, a1_pin.center()])
self.add_via_center(("metal2","via2","metal3"),
q_pin.center())
self.add_via_center(("metal1","via1","metal2"),
a1_pin.center())
mid_x_offset = 0.5*(a1_pin.cx() + q_pin.cx())
mid1 = vector(mid_x_offset, q_pin.cy())
mid2 = vector(mid_x_offset, a1_pin.cy())
self.add_path("metal3",
[q_pin.center(), mid1, mid2, a1_pin.center()])
self.add_via_center(layers=("metal2","via2","metal3"),
offset=q_pin.center())
self.add_via_center(layers=("metal2","via2","metal3"),
offset=a1_pin.center())
self.add_via_center(layers=("metal1","via1","metal2"),
offset=a1_pin.center())
# Route inv1 z to inv2 a
z1_pin = self.inv1_inst.get_pin("Z")
@ -121,14 +125,14 @@ class dff_buf(design.design):
height=din_pin.height())
dout_pin = self.inv2_inst.get_pin("Z")
self.add_layout_pin_center_rect(text="Q",
self.add_layout_pin_rect_center(text="Q",
layer="metal2",
offset=dout_pin.center())
self.add_via_center(layers=("metal1","via1","metal2"),
offset=dout_pin.center())
dout_pin = self.inv2_inst.get_pin("A")
self.add_layout_pin_center_rect(text="Qb",
self.add_layout_pin_rect_center(text="Qb",
layer="metal2",
offset=dout_pin.center())
self.add_via_center(layers=("metal1","via1","metal2"),

View File

@ -65,13 +65,17 @@ class dff_inv(design.design):
# Route dff q to inv1 a
q_pin = self.dff_inst.get_pin("Q")
a1_pin = self.inv1_inst.get_pin("A")
mid_point = vector(a1_pin.cx(), q_pin.cy())
self.add_wire(("metal3","via2","metal2"),
[q_pin.center(), mid_point, a1_pin.center()])
self.add_via_center(("metal2","via2","metal3"),
q_pin.center())
self.add_via_center(("metal1","via1","metal2"),
a1_pin.center())
mid_x_offset = 0.5*(a1_pin.cx() + q_pin.cx())
mid1 = vector(mid_x_offset, q_pin.cy())
mid2 = vector(mid_x_offset, a1_pin.cy())
self.add_path("metal3",
[q_pin.center(), mid1, mid2, a1_pin.center()])
self.add_via_center(layers=("metal2","via2","metal3"),
offset=q_pin.center())
self.add_via_center(layers=("metal2","via2","metal3"),
offset=a1_pin.center())
self.add_via_center(layers=("metal1","via1","metal2"),
offset=a1_pin.center())
def add_layout_pins(self):
@ -107,12 +111,12 @@ class dff_inv(design.design):
height=din_pin.height())
dout_pin = self.dff_inst.get_pin("Q")
self.add_layout_pin_center_rect(text="Q",
self.add_layout_pin_rect_center(text="Q",
layer=dout_pin.layer,
offset=dout_pin.center())
dout_pin = self.inv1_inst.get_pin("Z")
self.add_layout_pin_center_rect(text="Qb",
self.add_layout_pin_rect_center(text="Qb",
layer="metal2",
offset=dout_pin.center())
self.add_via_center(layers=("metal1","via1","metal2"),

View File

@ -118,7 +118,7 @@ class precharge(pgate.pgate):
rotate=90)
# adds the en rail on metal1
self.add_layout_pin_center_segment(text="en",
self.add_layout_pin_segment_center(text="en",
layer="metal1",
start=offset.scale(0,1),
end=offset.scale(0,1)+vector(self.width,0))

View File

@ -133,8 +133,8 @@ class replica_bitline(design.design):
def route(self):
""" Connect all the signals together """
self.route_gnd()
self.route_vdd()
self.route_gnd()
self.route_access_tx()
@ -210,28 +210,25 @@ class replica_bitline(design.design):
# Route the vdd lines from left to right
# Add via for the delay chain
left_vdd_start = self.dc_inst.ll().scale(1,0)
left_vdd_start = self.dc_inst.ll().scale(1,0) - vector(self.m2_pitch,0)
left_vdd_end = vector(left_vdd_start.x, self.rbl_inst.uy())
self.left_vdd_pin=self.add_layout_pin_center_segment(text="vdd",
layer="metal2",
start=left_vdd_start,
end=left_vdd_end)
self.left_vdd_pin=self.add_segment_center(layer="metal2",
start=left_vdd_start,
end=left_vdd_end)
# Vdd line to the left of the replica bitline
center_vdd_start = self.rbc_inst.ll() - vector(3*self.m2_pitch,0)
center_vdd_end = vector(center_vdd_start.x, self.rbl_inst.uy())
self.center_vdd_pin=self.add_layout_pin_center_segment(text="vdd",
layer="metal2",
start=center_vdd_start,
end=center_vdd_end)
self.center_vdd_pin=self.add_segment_center(layer="metal2",
start=center_vdd_start,
end=center_vdd_end)
# Vdd line to the right of the replica bitline
right_vdd_start = self.rbc_inst.lr() + vector(2*self.m2_pitch,0)
right_vdd_end = vector(right_vdd_start.x, self.rbl_inst.uy())
self.right_vdd_pin=self.add_layout_pin_center_segment(text="vdd",
layer="metal2",
start=right_vdd_start,
end=right_vdd_end)
self.right_vdd_pin=self.add_segment_center(layer="metal2",
start=right_vdd_start,
end=right_vdd_end)
@ -243,9 +240,10 @@ class replica_bitline(design.design):
continue
start = vector(self.center_vdd_pin.cx(),pin.cy())
end = vector(self.right_vdd_pin.cx(),pin.cy())
self.add_segment_center(layer="metal1",
start=start,
end=end)
self.add_layout_pin_segment_center(text="vdd",
layer="metal1",
start=start,
end=end)
self.add_via_center(layers=("metal1", "via1", "metal2"),
offset=start,
rotate=90)
@ -265,9 +263,10 @@ class replica_bitline(design.design):
# with the RBL pins
#end = vector(center_vdd_pin.cx(),pin.cy())
end = pin.rc()
self.add_segment_center(layer="metal1",
start=start,
end=end)
self.add_layout_pin_segment_center(text="vdd",
layer="metal1",
start=start,
end=end)
self.add_via_center(layers=("metal1", "via1", "metal2"),
offset=start,
rotate=90)
@ -303,14 +302,24 @@ class replica_bitline(design.design):
# Create the RBL rails too
rbl_pins = self.rbl_inst.get_pins("vdd")
for pin in rbl_pins:
if pin.layer != "metal2":
if pin.layer != "metal1":
continue
start = vector(pin.cx(),self.right_vdd_pin.by())
end = vector(pin.cx(),self.right_vdd_pin.uy())
self.add_layout_pin_center_segment(text="vdd",
layer="metal2",
# If above the delay line, route the full width
left = vector(self.left_vdd_pin.cx(),pin.cy())
center = vector(self.center_vdd_pin.cx(),pin.cy())
if pin.cy() > self.dc_inst.uy() + self.m1_pitch:
start = left
self.add_via_center(layers=("metal1", "via1", "metal2"),
offset=left,
rotate=90)
else:
start = center
end = vector(self.right_vdd_pin.cx()+0.5*self.m1_width,pin.cy())
self.add_layout_pin_segment_center(text="vdd",
layer="metal1",
start=start,
end=end)
@ -322,28 +331,25 @@ class replica_bitline(design.design):
# Route the gnd lines from left to right
# Add via for the delay chain
left_gnd_start = self.dc_inst.ll().scale(1,0) - vector(self.m2_pitch,0)
left_gnd_start = self.dc_inst.ll().scale(1,0) - vector(2*self.m2_pitch,0)
left_gnd_end = vector(left_gnd_start.x, self.rbl_inst.uy()+self.m2_pitch)
self.left_gnd_pin=self.add_layout_pin_center_segment(text="gnd",
layer="metal2",
start=left_gnd_start,
end=left_gnd_end)
self.left_gnd_pin=self.add_segment_center(layer="metal2",
start=left_gnd_start,
end=left_gnd_end)
# Gnd line to the left of the replica bitline
center_gnd_start = self.rbc_inst.ll().scale(1,0) - vector(2*self.m2_pitch,0)
center_gnd_end = vector(center_gnd_start.x, self.rbl_inst.uy()+self.m2_pitch)
self.center_gnd_pin=self.add_layout_pin_center_segment(text="gnd",
layer="metal2",
start=center_gnd_start,
end=center_gnd_end)
self.center_gnd_pin=self.add_segment_center(layer="metal2",
start=center_gnd_start,
end=center_gnd_end)
# Gnd line to the right of the replica bitline
right_gnd_start = self.rbc_inst.lr().scale(1,0) + vector(self.m2_pitch,0)
right_gnd_end = vector(right_gnd_start.x, self.rbl_inst.uy()+self.m2_pitch)
self.right_gnd_pin=self.add_layout_pin_center_segment(text="gnd",
layer="metal2",
start=right_gnd_start,
end=right_gnd_end)
self.right_gnd_pin=self.add_segment_center(layer="metal2",
start=right_gnd_start,
end=right_gnd_end)
@ -353,13 +359,24 @@ class replica_bitline(design.design):
pin = self.rbl_inst.get_pin(wl)
if pin.layer != "metal1":
continue
start = vector(self.center_gnd_pin.cx(),pin.cy())
end = vector(self.right_gnd_pin.cx(),pin.cy())
self.add_segment_center(layer="metal1",
start=start,
end=end)
# If above the delay line, route the full width
left = vector(self.left_gnd_pin.cx(),pin.cy())
center = vector(self.center_gnd_pin.cx(),pin.cy())
if pin.cy() > self.dc_inst.uy() + self.m1_pitch:
start = left
else:
start = center
end = vector(self.right_gnd_pin.cx(),pin.cy())
self.add_layout_pin_segment_center(text="gnd",
layer="metal1",
start=start,
end=end)
if start == left:
self.add_via_center(layers=("metal1", "via1", "metal2"),
offset=left,
rotate=90)
self.add_via_center(layers=("metal1", "via1", "metal2"),
offset=start,
offset=center,
rotate=90)
self.add_via_center(layers=("metal1", "via1", "metal2"),
offset=end,
@ -371,13 +388,23 @@ class replica_bitline(design.design):
for pin in rbl_gnd_pins:
if pin.layer != "metal1":
continue
start = vector(self.center_gnd_pin.cx(),pin.cy())
# If above the delay line, route the full width
left = vector(self.left_gnd_pin.cx(),pin.cy())
center = vector(self.center_gnd_pin.cx(),pin.cy())
if pin.cy() > self.dc_inst.uy() + self.m1_pitch:
start = left
else:
start = center
end = vector(self.right_gnd_pin.cx(),pin.cy())
self.add_segment_center(layer="metal1",
start=start,
end=end)
if start == left:
self.add_via_center(layers=("metal1", "via1", "metal2"),
offset=left,
rotate=90)
self.add_via_center(layers=("metal1", "via1", "metal2"),
offset=start,
offset=center,
rotate=90)
self.add_via_center(layers=("metal1", "via1", "metal2"),
offset=end,
@ -430,7 +457,7 @@ class replica_bitline(design.design):
continue
start = vector(pin.cx(),self.right_gnd_pin.by())
end = vector(pin.cx(),self.right_gnd_pin.uy())
self.add_layout_pin_center_segment(text="gnd",
self.add_layout_pin_segment_center(text="gnd",
layer="metal2",
start=start,
end=end)
@ -440,13 +467,13 @@ class replica_bitline(design.design):
def add_layout_pins(self):
""" Route the input and output signal """
en_offset = self.dc_inst.get_pin("in").bc()
self.add_layout_pin_center_segment(text="en",
self.add_layout_pin_segment_center(text="en",
layer="metal2",
start=en_offset,
end=en_offset.scale(1,0))
out_offset = self.rbl_inv_inst.get_pin("Z").center()
self.add_layout_pin_center_segment(text="out",
self.add_layout_pin_segment_center(text="out",
layer="metal2",
start=out_offset,
end=out_offset.scale(1,0))

View File

@ -176,7 +176,7 @@ class wordline_driver(design.design):
input_offset = vector(0,b_pos.y + up_or_down)
mid_via_offset = vector(clk_offset.x,input_offset.y) + vector(0.5*self.m2_width+self.m2_space+0.5*contact.m1m2.width,0)
# must under the clk line in M1
self.add_layout_pin_center_segment(text="in[{0}]".format(row),
self.add_layout_pin_segment_center(text="in[{0}]".format(row),
layer="metal1",
start=input_offset,
end=mid_via_offset)
@ -192,7 +192,7 @@ class wordline_driver(design.design):
# output each WL on the right
wl_offset = inv2_inst.get_pin("Z").rc()
self.add_layout_pin_center_segment(text="wl[{0}]".format(row),
self.add_layout_pin_segment_center(text="wl[{0}]".format(row),
layer="metal1",
start=wl_offset,
end=wl_offset-vector(self.m1_width,0))

View File

@ -59,8 +59,6 @@ class options(optparse.Values):
ms_flop = "ms_flop"
ms_flop_array = "ms_flop_array"
dff = "dff"
dff_array = "dff_array"
dff_buf_array = "dff_buf_array"
control_logic = "control_logic"
bitcell_array = "bitcell_array"
sense_amp = "sense_amp"

View File

@ -76,11 +76,11 @@ class pgate(design.design):
self.add_contact_center(layers=("poly", "contact", "metal1"),
offset=contact_offset,
rotate=rotate)
# self.add_layout_pin_center_segment(text=name,
# self.add_layout_pin_segment_center(text=name,
# layer="metal1",
# start=left_gate_offset.scale(0,1),
# end=left_gate_offset)
self.add_layout_pin_center_rect(text=name,
self.add_layout_pin_rect_center(text=name,
layer="metal1",
offset=contact_offset,
width=contact_m1_width,

View File

@ -148,12 +148,12 @@ class pinv(pgate.pgate):
def add_supply_rails(self):
""" Add vdd/gnd rails to the top and bottom. """
self.add_layout_pin_center_rect(text="gnd",
self.add_layout_pin_rect_center(text="gnd",
layer="metal1",
offset=vector(0.5*self.width,0),
width=self.width)
self.add_layout_pin_center_rect(text="vdd",
self.add_layout_pin_rect_center(text="vdd",
layer="metal1",
offset=vector(0.5*self.width,self.height),
width=self.width)
@ -208,13 +208,13 @@ class pinv(pgate.pgate):
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_layout_pin_center_segment(text="Z",
self.add_layout_pin_segment_center(text="Z",
layer="metal1",
start=mid_drain_offset,
end=output_offset)
else:
# This leaves the output as an internal pin (min sized)
self.add_layout_pin_center_rect(text="Z",
self.add_layout_pin_rect_center(text="Z",
layer="metal1",
offset=mid_drain_offset + vector(0.5*self.m1_width,0))
@ -257,4 +257,4 @@ class pinv(pgate.pgate):
c_load = load
c_para = spice["min_tx_drain_c"]*(self.nmos_size/parameter["min_tx_size"])#ff
transistion_prob = spice["inv_transisition_prob"]
return transistion_prob*(c_load + c_para)
return transistion_prob*(c_load + c_para)

View File

@ -130,14 +130,14 @@ class pinvbuf(design.design):
height=vdd_pin.height())
z_pin = self.inv4_inst.get_pin("Z")
self.add_layout_pin_center_rect(text="Z",
self.add_layout_pin_rect_center(text="Z",
layer="metal2",
offset=z_pin.center())
self.add_via_center(layers=("metal1","via1","metal2"),
offset=z_pin.center())
zb_pin = self.inv3_inst.get_pin("Z")
self.add_layout_pin_center_rect(text="Zb",
self.add_layout_pin_rect_center(text="Zb",
layer="metal2",
offset=zb_pin.center())
self.add_via_center(layers=("metal1","via1","metal2"),
@ -145,7 +145,7 @@ class pinvbuf(design.design):
a_pin = self.inv1_inst.get_pin("A")
self.add_layout_pin_center_rect(text="A",
self.add_layout_pin_rect_center(text="A",
layer="metal2",
offset=a_pin.center())
self.add_via_center(layers=("metal1","via1","metal2"),

View File

@ -102,12 +102,12 @@ class pnand2(pgate.pgate):
def add_supply_rails(self):
""" Add vdd/gnd rails to the top and bottom. """
self.add_layout_pin_center_rect(text="gnd",
self.add_layout_pin_rect_center(text="gnd",
layer="metal1",
offset=vector(0.5*self.width,0),
width=self.width)
self.add_layout_pin_center_rect(text="vdd",
self.add_layout_pin_rect_center(text="vdd",
layer="metal1",
offset=vector(0.5*self.width,self.height),
width=self.width)
@ -197,7 +197,7 @@ class pnand2(pgate.pgate):
self.add_path("metal2",[pmos_pin.bc(), mid_offset, nmos_pin.uc()])
# This extends the output to the edge of the cell
self.add_layout_pin_center_rect(text="Z",
self.add_layout_pin_rect_center(text="Z",
layer="metal1",
offset=mid_offset,
width=contact.m1m2.first_layer_height,

View File

@ -100,12 +100,12 @@ class pnand3(pgate.pgate):
def add_supply_rails(self):
""" Add vdd/gnd rails to the top and bottom. """
self.add_layout_pin_center_rect(text="gnd",
self.add_layout_pin_rect_center(text="gnd",
layer="metal1",
offset=vector(0.5*self.width,0),
width=self.width)
self.add_layout_pin_center_rect(text="vdd",
self.add_layout_pin_rect_center(text="vdd",
layer="metal1",
offset=vector(0.5*self.width,self.height),
width=self.width)
@ -218,7 +218,7 @@ class pnand3(pgate.pgate):
# This extends the output to the edge of the cell
self.add_contact_center(layers=("metal1", "via1", "metal2"),
offset=mid_offset)
self.add_layout_pin_center_rect(text="Z",
self.add_layout_pin_rect_center(text="Z",
layer="metal1",
offset=mid_offset,
width=contact.m1m2.first_layer_width,

View File

@ -106,12 +106,12 @@ class pnor2(pgate.pgate):
def add_supply_rails(self):
""" Add vdd/gnd rails to the top and bottom. """
self.add_layout_pin_center_rect(text="gnd",
self.add_layout_pin_rect_center(text="gnd",
layer="metal1",
offset=vector(0.5*self.width,0),
width=self.width)
self.add_layout_pin_center_rect(text="vdd",
self.add_layout_pin_rect_center(text="vdd",
layer="metal1",
offset=vector(0.5*self.width,self.height),
width=self.width)
@ -208,7 +208,7 @@ class pnor2(pgate.pgate):
self.add_contact_center(layers=("metal1", "via1", "metal2"),
offset=mid3_offset,
rotate=90)
self.add_layout_pin_center_rect(text="Z",
self.add_layout_pin_rect_center(text="Z",
layer="metal1",
offset=mid3_offset,
width=contact.m1m2.first_layer_height,
@ -240,4 +240,4 @@ class pnor2(pgate.pgate):
c_para = spice["min_tx_drain_c"]*(self.nmos_size/parameter["min_tx_size"])#ff
transistion_prob = spice["nor2_transisition_prob"]
return transistion_prob*(c_load + c_para)

View File

@ -210,7 +210,7 @@ class ptx(design.design):
for a in source_positions:
self.add_path(("metal1"), [a,a+pin_offset.scale(source_dir,source_dir)])
# Add a single horizontal pin
self.add_layout_pin_center_segment(text="S",
self.add_layout_pin_segment_center(text="S",
layer="metal1",
start=source_positions[0]+source_offset-end_offset,
end=source_positions[-1]+source_offset+end_offset)
@ -222,7 +222,7 @@ class ptx(design.design):
for a in drain_positions:
self.add_path(("metal1"), [a,a+drain_offset])
# Add a single horizontal pin
self.add_layout_pin_center_segment(text="D",
self.add_layout_pin_segment_center(text="D",
layer="metal1",
start=drain_positions[0]+drain_offset-end_offset,
end=drain_positions[-1]+drain_offset+end_offset)
@ -246,7 +246,7 @@ class ptx(design.design):
offset=poly_offset,
height=self.poly_height,
width=self.poly_width)
self.add_layout_pin_center_rect(text="G",
self.add_layout_pin_rect_center(text="G",
layer="poly",
offset=poly_offset,
height=self.poly_height,
@ -329,7 +329,7 @@ class ptx(design.design):
size=(1, self.num_contacts),
implant_type=self.implant_type,
well_type=self.well_type)
self.add_layout_pin_center_rect(text="S",
self.add_layout_pin_rect_center(text="S",
layer="metal1",
offset=pos,
width=contact.mod.second_layer_width,
@ -342,7 +342,7 @@ class ptx(design.design):
size=(1, self.num_contacts),
implant_type=self.implant_type,
well_type=self.well_type)
self.add_layout_pin_center_rect(text="D",
self.add_layout_pin_rect_center(text="D",
layer="metal1",
offset=pos,
width=contact.mod.second_layer_width,

View File

@ -5,6 +5,8 @@ import design
from math import log,sqrt,ceil
import contact
from bank import bank
from dff_buf_array import dff_buf_array
from dff_array import dff_array
import datetime
import getpass
from vector import vector
@ -21,15 +23,6 @@ class sram(design.design):
c = reload(__import__(OPTS.control_logic))
self.mod_control_logic = getattr(c, OPTS.control_logic)
if num_banks>1:
# Use a buffered array for big arrays
# Also ensures we have Qbar when FF doesn't
c = reload(__import__(OPTS.dff_buf_array))
self.mod_dff_array = getattr(c, OPTS.dff_buf_array)
else:
c = reload(__import__(OPTS.dff_array))
self.mod_dff_array = getattr(c, OPTS.dff_array)
c = reload(__import__(OPTS.bitcell))
self.mod_bitcell = getattr(c, OPTS.bitcell)
self.bitcell = self.mod_bitcell()
@ -809,9 +802,9 @@ class sram(design.design):
def create_multi_bank_modules(self):
""" Create the multibank address flops and bank decoder """
self.msb_address = self.mod_dff_array(name="msb_address",
rows=1,
columns=self.num_banks/2)
self.msb_address = dff_buf_array(name="msb_address",
rows=1,
columns=self.num_banks/2)
self.add_mod(self.msb_address)
if self.num_banks>2:
@ -827,7 +820,7 @@ class sram(design.design):
# Create the address and control flops (but not the clk)
dff_size = self.addr_size
self.addr_dff = self.mod_dff_array(name="dff_array", rows=dff_size, columns=1)
self.addr_dff = self.dff_array(name="dff_array", rows=dff_size, columns=1)
self.add_mod(self.addr_dff)
# Create the bank module (up to four are instantiated)