mirror of https://github.com/VLSIDA/OpenRAM.git
Mostly working for 1 bank.
This commit is contained in:
parent
97c08bce95
commit
a0bf5345f8
|
|
@ -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()
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -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 >>
|
||||||
|
|
|
||||||
|
|
@ -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 >>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue