Mostly working for 1 bank.

This commit is contained in:
Matt Guthaus 2018-03-21 15:23:32 -07:00
parent 97c08bce95
commit a0bf5345f8
10 changed files with 83 additions and 116 deletions

View File

@ -27,8 +27,8 @@ class bitcell_array(design.design):
self.add_mod(self.cell)
# We increase it by a well enclosure so the precharges don't overlap our wells
self.height = self.row_size*self.cell.height + drc["well_enclosure_active"]
self.width = self.column_size*self.cell.width
self.height = self.row_size*self.cell.height + drc["well_enclosure_active"] + self.m1_width
self.width = self.column_size*self.cell.width + self.m1_width
self.add_pins()
self.create_layout()
@ -76,28 +76,7 @@ class bitcell_array(design.design):
def add_layout_pins(self):
# Our cells have multiple gnd pins for now.
# FIXME: fix for multiple vdd too
vdd_pin = self.cell.get_pin("vdd")
# shift it up by the overlap amount (gnd_pin) too
# must find the lower gnd pin to determine this overlap
lower_y = self.cell.height
gnd_pins = self.cell.get_pins("gnd")
for gnd_pin in gnd_pins:
if gnd_pin.layer=="metal2" and gnd_pin.by()<lower_y:
lower_y=gnd_pin.by()
# lower_y is negative, so subtract off double this amount for each pair of
# overlapping cells
full_height = self.height - 2*lower_y
vdd_pin = self.cell.get_pin("vdd")
lower_x = vdd_pin.lx()
# lower_x is negative, so subtract off double this amount for each pair of
# overlapping cells
full_width = self.width - 2*lower_x
""" Add the layout pins """
offset = vector(0.0, 0.0)
for col in range(self.column_size):
@ -108,24 +87,12 @@ class bitcell_array(design.design):
layer="metal2",
offset=bl_pin.ll(),
width=bl_pin.width(),
height=full_height)
height=self.height)
self.add_layout_pin(text="br[{0}]".format(col),
layer="metal2",
offset=br_pin.ll(),
width=br_pin.width(),
height=full_height)
# gnd offset is 0 in our cell, but it be non-zero
gnd_pins = self.cell_inst[0,col].get_pins("gnd")
for gnd_pin in gnd_pins:
# avoid duplicates by only doing even rows
# also skip if it isn't the pin that spans the entire cell down to the bottom
if gnd_pin.layer=="metal2" and gnd_pin.by()==lower_y:
self.add_layout_pin(text="gnd",
layer="metal2",
offset=gnd_pin.ll(),
width=gnd_pin.width(),
height=full_height)
height=self.height)
# increments to the next column width
offset.x += self.cell.width
@ -133,37 +100,50 @@ class bitcell_array(design.design):
offset.x = 0.0
for row in range(self.row_size):
wl_pin = self.cell_inst[row,0].get_pin("WL")
vdd_pins = self.cell_inst[row,0].get_pins("vdd")
gnd_pins = self.cell_inst[row,0].get_pins("gnd")
for gnd_pin in gnd_pins:
if gnd_pin.layer=="metal1":
self.add_layout_pin(text="gnd",
layer="metal1",
offset=gnd_pin.ll(),
width=full_width,
height=drc["minwidth_metal1"])
# add vdd label and offset
# only add to even rows to avoid duplicates
for vdd_pin in vdd_pins:
if row % 2 == 0 and vdd_pin.layer=="metal1":
self.add_layout_pin(text="vdd",
layer="metal1",
offset=vdd_pin.ll(),
width=full_width,
height=drc["minwidth_metal1"])
# add wl label and offset
self.add_layout_pin(text="wl[{0}]".format(row),
layer="metal1",
offset=wl_pin.ll(),
width=full_width,
width=self.width,
height=wl_pin.height())
# increments to the next row height
offset.y += self.cell.height
# For every second row and column, add a via for vdd
for row in range(self.row_size):
for col in range(self.column_size):
inst = self.cell_inst[row,col]
for vdd_pin in inst.get_pins("vdd"):
# Drop to M1 if needed
if vdd_pin.layer == "metal1":
self.add_via_center(layers=("metal1", "via1", "metal2"),
offset=vdd_pin.center(),
rotate=90)
# Always drop to M2
self.add_via_center(layers=("metal2", "via2", "metal3"),
offset=vdd_pin.center())
self.add_layout_pin_rect_center(text="vdd",
layer="metal3",
offset=vdd_pin.center())
# For every second row and column (+1), add a via for gnd
for row in range(self.row_size):
for col in range(self.column_size):
inst = self.cell_inst[row,col]
for gnd_pin in inst.get_pins("gnd"):
# Drop to M1 if needed
if gnd_pin.layer == "metal1":
self.add_via_center(layers=("metal1", "via1", "metal2"),
offset=gnd_pin.center(),
rotate=90)
# Always drop to M2
self.add_via_center(layers=("metal2", "via2", "metal3"),
offset=gnd_pin.center())
self.add_layout_pin_rect_center(text="gnd",
layer="metal3",
offset=gnd_pin.center())
def analytical_delay(self, slew, load=0):
from tech import drc
wl_wire = self.gen_wl_wire()

View File

@ -350,7 +350,10 @@ class control_logic(design.design):
self.add_via_center(layers=("metal1","via1","metal2"),
offset=rail_pos,
rotate=90)
self.copy_layout_pin(self.ctrl_dff_inst, "din[0]", "csb")
self.copy_layout_pin(self.ctrl_dff_inst, "din[1]", "web")
self.copy_layout_pin(self.ctrl_dff_inst, "din[2]", "oeb")
def add_dffs(self):
@ -568,6 +571,7 @@ class control_logic(design.design):
def connect_output(self, inst, pin_name, out_name):
""" 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_segment_center(text=out_name,
@ -582,7 +586,7 @@ class control_logic(design.design):
rows_start = 0
rows_end = self.width
well_width = drc["minwidth_well"]
#well_width = drc["minwidth_well"]
for i in range(8):
if i%2:
@ -598,7 +602,7 @@ class control_logic(design.design):
layer="metal1",
start=vector(rows_start,yoffset),
end=vector(rows_end,yoffset))
# # also add a well +- around the rail
# well_offset = vector(rows_start,yoffset-0.5*well_width)
# self.add_rect(layer=well_type,

View File

@ -213,16 +213,17 @@ class sram(design.design):
# are not recomputed using instance placement. So, place the control logic such that it aligns
# with the top of the SRAM.
control_pos = vector(-self.control_logic.width - self.m3_pitch,
self.bank.height - self.control_logic.height - 3*self.supply_rail_width)
3*self.supply_rail_width)
self.add_control_logic(position=control_pos)
# Leave room for the control routes to the left of the flops
addr_pos = vector(self.control_logic_inst.lx() + 4*self.m2_pitch,
3*self.supply_rail_pitch)
control_pos.y + self.control_logic.height + self.m1_pitch)
self.add_addr_dff(addr_pos)
# two supply rails are already included in the bank, so just 2 here.
self.width = self.bank.width + self.control_logic.width + 2*self.supply_rail_pitch
self.height = self.bank.height + 2*self.supply_rail_pitch
self.height = self.bank.height
def route_shared_banks(self):
@ -230,7 +231,7 @@ class sram(design.design):
# create the input control pins
for n in self.control_logic_inputs + ["clk"]:
self.copy_layout_pin(self.control_logic_inst, n.lower(), n)
self.copy_layout_pin(self.control_logic_inst, n)
# connect the control logic to the control bus
for n in self.control_logic_outputs + ["vdd", "gnd"]:
@ -820,7 +821,7 @@ class sram(design.design):
# Create the address and control flops (but not the clk)
dff_size = self.addr_size
self.addr_dff = self.dff_array(name="dff_array", rows=dff_size, columns=1)
self.addr_dff = 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)
@ -1069,7 +1070,7 @@ class sram(design.design):
# Connect the control pins as inputs
for n in self.control_logic_inputs + ["clk"]:
self.copy_layout_pin(self.control_logic_inst, n.lower(), n)
self.copy_layout_pin(self.control_logic_inst, n)
# Connect the clock between the flops and control module
flop_pin = self.addr_dff_inst.get_pin("clk")
@ -1099,16 +1100,6 @@ class sram(design.design):
size = (1,self.supply_vias),
rotate=90)
# Route the vdd rails to the TOP
for vdd_pin in self.control_logic_inst.get_pins("vdd"):
if vdd_pin.layer != "metal2":
continue
vdd_pos = vdd_pin.uc()
top_rail_pos = vector(vdd_pos.x, self.top_vdd_y_center)
self.add_path("metal2", [top_rail_pos, vdd_pos])
self.add_via_center(layers=("metal1", "via1", "metal2"),
offset=top_rail_pos,
size = (1,self.supply_vias))
def route_single_bank_gnd(self):
@ -1128,16 +1119,6 @@ class sram(design.design):
size = (1,self.supply_vias),
rotate=90)
# Route the vdd rails to the TOP
for gnd_pin in self.control_logic_inst.get_pins("gnd"):
if gnd_pin.layer != "metal2":
continue
gnd_pos = gnd_pin.uc()
top_rail_pos = vector(gnd_pos.x, self.top_gnd_y_center)
self.add_path("metal2", [top_rail_pos, gnd_pos])
self.add_via_center(layers=("metal1", "via1", "metal2"),
offset=top_rail_pos,
size = (1,self.supply_vias))
def sp_write(self, sp_name):

Binary file not shown.

View File

@ -1,6 +1,6 @@
magic
tech scmos
timestamp 1517870584
timestamp 1521677056
<< nwell >>
rect -8 29 42 51
<< pwell >>
@ -73,7 +73,8 @@ rect 15 29 19 33
rect 21 20 25 24
rect 17 6 21 10
<< metal1 >>
rect -2 44 32 48
rect -2 44 15 48
rect 19 44 32 48
rect -2 40 2 44
rect 32 40 36 44
rect 11 36 12 40
@ -92,6 +93,7 @@ rect -2 6 17 9
rect 21 6 36 9
rect -2 5 36 6
<< m2contact >>
rect 15 44 19 48
rect -2 29 2 33
rect 32 29 36 33
rect 6 -2 10 2
@ -99,17 +101,17 @@ rect 20 -2 24 2
<< metal2 >>
rect -2 33 2 48
rect -2 -2 2 29
rect 10 -2 14 48
rect 20 2 24 48
rect 6 2 10 48
rect 24 -2 28 48
rect 32 33 36 48
rect 32 -2 36 29
<< m3p >>
rect 0 0 34 46
<< labels >>
rlabel metal1 2 6 2 6 3 WL
rlabel metal2 -1 28 -1 28 1 gnd
rlabel metal2 33 28 33 28 1 gnd
rlabel metal1 17 46 17 46 5 vdd
rlabel metal2 11 43 11 43 1 BL
rlabel metal2 21 43 21 43 1 BR
rlabel metal2 0 0 0 0 1 gnd
rlabel metal2 34 0 34 0 1 gnd
rlabel m2contact 17 46 17 46 5 vdd
rlabel metal1 4 7 4 7 1 WL
rlabel metal2 8 43 8 43 1 BL
rlabel metal2 26 43 26 43 1 BR
<< end >>

View File

@ -1,6 +1,6 @@
magic
tech scmos
timestamp 1517870621
timestamp 1521677136
<< nwell >>
rect -8 29 42 51
<< pwell >>
@ -73,19 +73,18 @@ rect 15 29 19 33
rect 21 20 25 24
rect 17 6 21 10
<< metal1 >>
rect -2 44 32 48
rect -2 44 15 48
rect 19 44 32 48
rect -2 40 2 44
rect 32 40 36 44
rect 11 36 12 40
rect 26 36 27 40
rect -2 26 2 29
rect 11 25 15 36
rect 2 22 15 25
rect 11 22 15 36
rect 23 24 27 36
rect -2 21 15 22
rect -2 16 2 21
rect 11 18 15 21
rect -2 18 15 22
rect 25 20 27 24
rect -2 16 2 18
rect 14 14 15 18
rect 23 18 27 20
rect 32 26 36 29
@ -95,6 +94,7 @@ rect -2 6 17 9
rect 21 6 36 9
rect -2 5 36 6
<< m2contact >>
rect 15 44 19 48
rect -2 29 2 33
rect 32 29 36 33
rect 6 -2 10 2
@ -102,17 +102,17 @@ rect 20 -2 24 2
<< metal2 >>
rect -2 33 2 48
rect -2 -2 2 29
rect 10 -2 14 48
rect 20 2 24 48
rect 6 2 10 48
rect 24 -2 28 48
rect 32 33 36 48
rect 32 -2 36 29
<< m3p >>
rect 0 0 34 46
<< labels >>
rlabel metal1 2 6 2 6 3 WL
rlabel metal2 -1 28 -1 28 1 gnd
rlabel metal2 33 28 33 28 1 gnd
rlabel metal1 17 46 17 46 5 vdd
rlabel metal2 11 43 11 43 1 BL
rlabel metal2 21 43 21 43 1 BR
rlabel metal2 0 0 0 0 1 gnd
rlabel metal2 34 0 34 0 1 gnd
rlabel m2contact 17 46 17 46 5 vdd
rlabel metal1 4 7 4 7 1 WL
rlabel metal2 8 43 8 43 1 BL
rlabel metal2 26 43 26 43 1 BR
<< end >>