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) self.add_mod(self.cell)
# We increase it by a well enclosure so the precharges don't overlap our wells # 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.height = self.row_size*self.cell.height + drc["well_enclosure_active"] + self.m1_width
self.width = self.column_size*self.cell.width self.width = self.column_size*self.cell.width + self.m1_width
self.add_pins() self.add_pins()
self.create_layout() self.create_layout()
@ -76,28 +76,7 @@ class bitcell_array(design.design):
def add_layout_pins(self): def add_layout_pins(self):
""" Add the layout pins """
# 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
offset = vector(0.0, 0.0) offset = vector(0.0, 0.0)
for col in range(self.column_size): for col in range(self.column_size):
@ -108,24 +87,12 @@ class bitcell_array(design.design):
layer="metal2", layer="metal2",
offset=bl_pin.ll(), offset=bl_pin.ll(),
width=bl_pin.width(), width=bl_pin.width(),
height=full_height) height=self.height)
self.add_layout_pin(text="br[{0}]".format(col), self.add_layout_pin(text="br[{0}]".format(col),
layer="metal2", layer="metal2",
offset=br_pin.ll(), offset=br_pin.ll(),
width=br_pin.width(), width=br_pin.width(),
height=full_height) height=self.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)
# increments to the next column width # increments to the next column width
offset.x += self.cell.width offset.x += self.cell.width
@ -133,37 +100,50 @@ class bitcell_array(design.design):
offset.x = 0.0 offset.x = 0.0
for row in range(self.row_size): for row in range(self.row_size):
wl_pin = self.cell_inst[row,0].get_pin("WL") 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), self.add_layout_pin(text="wl[{0}]".format(row),
layer="metal1", layer="metal1",
offset=wl_pin.ll(), offset=wl_pin.ll(),
width=full_width, width=self.width,
height=wl_pin.height()) height=wl_pin.height())
# increments to the next row height # increments to the next row height
offset.y += self.cell.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): def analytical_delay(self, slew, load=0):
from tech import drc from tech import drc
wl_wire = self.gen_wl_wire() 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"), self.add_via_center(layers=("metal1","via1","metal2"),
offset=rail_pos, offset=rail_pos,
rotate=90) 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): def add_dffs(self):
@ -568,6 +571,7 @@ class control_logic(design.design):
def connect_output(self, inst, pin_name, out_name): def connect_output(self, inst, pin_name, out_name):
""" Create an output pin on the right side from the pin of a given instance. """ """ Create an output pin on the right side from the pin of a given instance. """
out_pin = inst.get_pin(pin_name) out_pin = inst.get_pin(pin_name)
right_pos=out_pin.center() + vector(self.width-out_pin.cx(),0) right_pos=out_pin.center() + vector(self.width-out_pin.cx(),0)
self.add_layout_pin_segment_center(text=out_name, self.add_layout_pin_segment_center(text=out_name,
@ -582,7 +586,7 @@ class control_logic(design.design):
rows_start = 0 rows_start = 0
rows_end = self.width rows_end = self.width
well_width = drc["minwidth_well"] #well_width = drc["minwidth_well"]
for i in range(8): for i in range(8):
if i%2: if i%2:
@ -598,7 +602,7 @@ class control_logic(design.design):
layer="metal1", layer="metal1",
start=vector(rows_start,yoffset), start=vector(rows_start,yoffset),
end=vector(rows_end,yoffset)) end=vector(rows_end,yoffset))
# # also add a well +- around the rail # # also add a well +- around the rail
# well_offset = vector(rows_start,yoffset-0.5*well_width) # well_offset = vector(rows_start,yoffset-0.5*well_width)
# self.add_rect(layer=well_type, # 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 # are not recomputed using instance placement. So, place the control logic such that it aligns
# with the top of the SRAM. # with the top of the SRAM.
control_pos = vector(-self.control_logic.width - self.m3_pitch, 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) self.add_control_logic(position=control_pos)
# Leave room for the control routes to the left of the flops # Leave room for the control routes to the left of the flops
addr_pos = vector(self.control_logic_inst.lx() + 4*self.m2_pitch, 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) 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.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): def route_shared_banks(self):
@ -230,7 +231,7 @@ class sram(design.design):
# create the input control pins # create the input control pins
for n in self.control_logic_inputs + ["clk"]: 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 # connect the control logic to the control bus
for n in self.control_logic_outputs + ["vdd", "gnd"]: 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) # Create the address and control flops (but not the clk)
dff_size = self.addr_size 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) self.add_mod(self.addr_dff)
# Create the bank module (up to four are instantiated) # Create the bank module (up to four are instantiated)
@ -1069,7 +1070,7 @@ class sram(design.design):
# Connect the control pins as inputs # Connect the control pins as inputs
for n in self.control_logic_inputs + ["clk"]: 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 # Connect the clock between the flops and control module
flop_pin = self.addr_dff_inst.get_pin("clk") flop_pin = self.addr_dff_inst.get_pin("clk")
@ -1099,16 +1100,6 @@ class sram(design.design):
size = (1,self.supply_vias), size = (1,self.supply_vias),
rotate=90) 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): def route_single_bank_gnd(self):
@ -1128,16 +1119,6 @@ class sram(design.design):
size = (1,self.supply_vias), size = (1,self.supply_vias),
rotate=90) 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): def sp_write(self, sp_name):

Binary file not shown.

View File

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

View File

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