mirror of
https://github.com/VLSIDA/OpenRAM.git
synced 2026-08-29 17:39:02 +02:00
First draft of sram_factory code
This commit is contained in:
+34
-38
@@ -6,9 +6,7 @@ import math
|
||||
from math import log,sqrt,ceil
|
||||
import contact
|
||||
import pgates
|
||||
from pinv import pinv
|
||||
from pnand2 import pnand2
|
||||
from pnor2 import pnor2
|
||||
from sram_factory import factory
|
||||
from vector import vector
|
||||
|
||||
from globals import OPTS
|
||||
@@ -396,25 +394,14 @@ class bank(design.design):
|
||||
def add_modules(self):
|
||||
""" Add all the modules using the class loader """
|
||||
|
||||
mod_list = ["bitcell", "decoder", "wordline_driver",
|
||||
"bitcell_array", "sense_amp_array", "precharge_array",
|
||||
"column_mux_array", "write_driver_array",
|
||||
"dff", "bank_select"]
|
||||
from importlib import reload
|
||||
for mod_name in mod_list:
|
||||
config_mod_name = getattr(OPTS, mod_name)
|
||||
class_file = reload(__import__(config_mod_name))
|
||||
mod_class = getattr(class_file , config_mod_name)
|
||||
setattr (self, "mod_"+mod_name, mod_class)
|
||||
|
||||
|
||||
|
||||
self.bitcell_array = self.mod_bitcell_array(cols=self.num_cols,
|
||||
rows=self.num_rows)
|
||||
self.bitcell_array = factory.create(module_type="bitcell_array",
|
||||
cols=self.num_cols,
|
||||
rows=self.num_rows)
|
||||
self.add_mod(self.bitcell_array)
|
||||
|
||||
# create arrays of bitline and bitline_bar names for read, write, or all ports
|
||||
self.bitcell = self.mod_bitcell()
|
||||
self.bitcell = factory.create(module_type="bitcell")
|
||||
self.bl_names = self.bitcell.list_all_bl_names()
|
||||
self.br_names = self.bitcell.list_all_br_names()
|
||||
self.wl_names = self.bitcell.list_all_wl_names()
|
||||
@@ -423,7 +410,11 @@ class bank(design.design):
|
||||
self.precharge_array = []
|
||||
for port in self.all_ports:
|
||||
if port in self.read_ports:
|
||||
self.precharge_array.append(self.mod_precharge_array(columns=self.num_cols, bitcell_bl=self.bl_names[port], bitcell_br=self.br_names[port]))
|
||||
temp_pre = factory.create(module_type="precharge_array",
|
||||
columns=self.num_cols,
|
||||
bitcell_bl=self.bl_names[port],
|
||||
bitcell_br=self.br_names[port])
|
||||
self.precharge_array.append(temp_pre)
|
||||
self.add_mod(self.precharge_array[port])
|
||||
else:
|
||||
self.precharge_array.append(None)
|
||||
@@ -431,32 +422,38 @@ class bank(design.design):
|
||||
if self.col_addr_size > 0:
|
||||
self.column_mux_array = []
|
||||
for port in self.all_ports:
|
||||
self.column_mux_array.append(self.mod_column_mux_array(columns=self.num_cols,
|
||||
word_size=self.word_size,
|
||||
bitcell_bl=self.bl_names[port],
|
||||
bitcell_br=self.br_names[port]))
|
||||
temp_col = factory.create(module_type="column_mux_array",
|
||||
columns=self.num_cols,
|
||||
word_size=self.word_size,
|
||||
bitcell_bl=self.bl_names[port],
|
||||
bitcell_br=self.br_names[port])
|
||||
self.column_mux_array.append(temp_col)
|
||||
self.add_mod(self.column_mux_array[port])
|
||||
|
||||
|
||||
self.sense_amp_array = self.mod_sense_amp_array(word_size=self.word_size,
|
||||
words_per_row=self.words_per_row)
|
||||
self.sense_amp_array = factory.create(module_type="sense_amp_array",
|
||||
word_size=self.word_size,
|
||||
words_per_row=self.words_per_row)
|
||||
self.add_mod(self.sense_amp_array)
|
||||
|
||||
self.write_driver_array = self.mod_write_driver_array(columns=self.num_cols,
|
||||
word_size=self.word_size)
|
||||
self.write_driver_array = factory.create(module_type="write_driver_array",
|
||||
columns=self.num_cols,
|
||||
word_size=self.word_size)
|
||||
self.add_mod(self.write_driver_array)
|
||||
|
||||
self.row_decoder = self.mod_decoder(rows=self.num_rows)
|
||||
self.row_decoder = factory.create(module_type="decoder",
|
||||
rows=self.num_rows)
|
||||
self.add_mod(self.row_decoder)
|
||||
|
||||
self.wordline_driver = self.mod_wordline_driver(rows=self.num_rows)
|
||||
self.wordline_driver = factory.create(module_type="wordline_driver",
|
||||
rows=self.num_rows)
|
||||
self.add_mod(self.wordline_driver)
|
||||
|
||||
self.inv = pinv()
|
||||
self.inv = factory.create(module_type="pinv")
|
||||
self.add_mod(self.inv)
|
||||
|
||||
if(self.num_banks > 1):
|
||||
self.bank_select = self.mod_bank_select()
|
||||
self.bank_select = factory.create(module_type="bank_select")
|
||||
self.add_mod(self.bank_select)
|
||||
|
||||
|
||||
@@ -693,18 +690,17 @@ class bank(design.design):
|
||||
"""
|
||||
Create a 2:4 or 3:8 column address decoder.
|
||||
"""
|
||||
|
||||
dff = factory.create(module_type="dff")
|
||||
|
||||
if self.col_addr_size == 0:
|
||||
return
|
||||
elif self.col_addr_size == 1:
|
||||
from pinvbuf import pinvbuf
|
||||
self.column_decoder = pinvbuf(height=self.mod_dff.height)
|
||||
self.column_decoder = factory.create(module_type="pinvbuf", height=dff.height)
|
||||
elif self.col_addr_size == 2:
|
||||
from hierarchical_predecode2x4 import hierarchical_predecode2x4 as pre2x4
|
||||
self.column_decoder = pre2x4(height=self.mod_dff.height)
|
||||
self.column_decoder = factory.create(module_type="hierarchical_predecode2x4", height=dff.height)
|
||||
elif self.col_addr_size == 3:
|
||||
from hierarchical_predecode3x8 import hierarchical_predecode3x8 as pre3x8
|
||||
self.column_decoder = pre3x8(height=self.mod_dff.height)
|
||||
self.column_decoder = factory.create(module_type="hierarchical_predecode3x8", height=dff.height)
|
||||
else:
|
||||
# No error checking before?
|
||||
debug.error("Invalid column decoder?",-1)
|
||||
@@ -1273,4 +1269,4 @@ class bank(design.design):
|
||||
"""Get the relative capacitance of all the sense amp enable connections in the bank"""
|
||||
#Current bank only uses sen as an enable for the sense amps.
|
||||
total_sen_cin = self.sense_amp_array.get_en_cin()
|
||||
return total_sen_cin
|
||||
return total_sen_cin
|
||||
|
||||
@@ -7,6 +7,7 @@ from pinv import pinv
|
||||
from pnand2 import pnand2
|
||||
from pnor2 import pnor2
|
||||
from vector import vector
|
||||
from sram_factory import factory
|
||||
from globals import OPTS
|
||||
|
||||
class bank_select(design.design):
|
||||
@@ -62,28 +63,25 @@ class bank_select(design.design):
|
||||
|
||||
def add_modules(self):
|
||||
""" Create modules for later instantiation """
|
||||
from importlib import reload
|
||||
c = reload(__import__(OPTS.bitcell))
|
||||
self.mod_bitcell = getattr(c, OPTS.bitcell)
|
||||
self.bitcell = self.mod_bitcell()
|
||||
self.bitcell = factory.create(module_type="bitcell")
|
||||
|
||||
height = self.bitcell.height + drc("poly_to_active")
|
||||
|
||||
# 1x Inverter
|
||||
self.inv_sel = pinv(height=height)
|
||||
self.inv_sel = factory.create(module_type="pinv", height=height)
|
||||
self.add_mod(self.inv_sel)
|
||||
|
||||
# 4x Inverter
|
||||
self.inv = self.inv4x = pinv(4)
|
||||
self.inv4x = factory.create(module_type="pinv", height=height, size=4)
|
||||
self.add_mod(self.inv4x)
|
||||
|
||||
self.nor2 = pnor2(height=height)
|
||||
self.nor2 = factory.create(module_type="pnor2", height=height)
|
||||
self.add_mod(self.nor2)
|
||||
|
||||
self.inv4x_nor = pinv(size=4, height=height)
|
||||
self.inv4x_nor = factory.create(module_type="pinv", height=height, size=4)
|
||||
self.add_mod(self.inv4x_nor)
|
||||
|
||||
self.nand2 = pnand2()
|
||||
self.nand2 = factory.create(module_type="pnand2")
|
||||
self.add_mod(self.nand2)
|
||||
|
||||
def calculate_module_offsets(self):
|
||||
@@ -94,7 +92,7 @@ class bank_select(design.design):
|
||||
self.xoffset_bank_sel_inv = 0
|
||||
self.xoffset_inputs = 0
|
||||
|
||||
self.yoffset_maxpoint = self.num_control_lines * self.inv.height
|
||||
self.yoffset_maxpoint = self.num_control_lines * self.inv4x.height
|
||||
# Include the M1 pitches for the supply rails and spacing
|
||||
self.height = self.yoffset_maxpoint + 2*self.m1_pitch
|
||||
self.width = self.xoffset_inv + self.inv4x.width
|
||||
@@ -170,10 +168,10 @@ class bank_select(design.design):
|
||||
if i == 0:
|
||||
y_offset = 0
|
||||
else:
|
||||
y_offset = self.inv4x_nor.height + self.inv.height * (i-1)
|
||||
y_offset = self.inv4x_nor.height + self.inv4x.height * (i-1)
|
||||
|
||||
if i%2:
|
||||
y_offset += self.inv.height
|
||||
y_offset += self.inv4x.height
|
||||
mirror = "MX"
|
||||
else:
|
||||
mirror = ""
|
||||
@@ -223,7 +221,7 @@ class bank_select(design.design):
|
||||
self.add_label_pin(text="bank_sel_bar",
|
||||
layer="metal2",
|
||||
offset=vector(xoffset_bank_sel_bar, 0),
|
||||
height=self.inv.height)
|
||||
height=self.inv4x.height)
|
||||
self.add_via_center(layers=("metal1","via1","metal2"),
|
||||
offset=bank_sel_bar_pin.rc())
|
||||
|
||||
|
||||
@@ -3,8 +3,7 @@ import design
|
||||
from tech import drc, spice
|
||||
from vector import vector
|
||||
from globals import OPTS
|
||||
|
||||
unique_id = 1
|
||||
from sram_factory import factory
|
||||
|
||||
class bitcell_array(design.design):
|
||||
"""
|
||||
@@ -12,13 +11,7 @@ class bitcell_array(design.design):
|
||||
and word line is connected by abutment.
|
||||
Connects the word lines and bit lines.
|
||||
"""
|
||||
unique_id = 1
|
||||
|
||||
def __init__(self, cols, rows, name=""):
|
||||
|
||||
if name == "":
|
||||
name = "bitcell_array_{0}x{1}_{2}".format(rows,cols,bitcell_array.unique_id)
|
||||
bitcell_array.unique_id += 1
|
||||
def __init__(self, cols, rows, name):
|
||||
design.design.__init__(self, name)
|
||||
debug.info(1, "Creating {0} {1} x {2}".format(self.name, rows, cols))
|
||||
|
||||
@@ -83,11 +76,7 @@ class bitcell_array(design.design):
|
||||
|
||||
def add_modules(self):
|
||||
""" Add the modules used in this design """
|
||||
|
||||
from importlib import reload
|
||||
c = reload(__import__(OPTS.bitcell))
|
||||
self.mod_bitcell = getattr(c, OPTS.bitcell)
|
||||
self.cell = self.mod_bitcell()
|
||||
self.cell = factory.create(module_type="bitcell")
|
||||
self.add_mod(self.cell)
|
||||
|
||||
def create_instances(self):
|
||||
@@ -210,4 +199,4 @@ class bitcell_array(design.design):
|
||||
#A single wordline is connected to all the bitcells in a single row meaning the capacitance depends on the # of columns
|
||||
bitcell_wl_cin = self.cell.get_wl_cin()
|
||||
total_cin = bitcell_wl_cin * self.column_size
|
||||
return total_cin
|
||||
return total_cin
|
||||
|
||||
@@ -3,13 +3,7 @@ import design
|
||||
from tech import drc, parameter
|
||||
import debug
|
||||
import contact
|
||||
from pinv import pinv
|
||||
from pbuf import pbuf
|
||||
from pand2 import pand2
|
||||
from pnand2 import pnand2
|
||||
from pinvbuf import pinvbuf
|
||||
from dff_buf import dff_buf
|
||||
from dff_buf_array import dff_buf_array
|
||||
from sram_factory import factory
|
||||
import math
|
||||
from vector import vector
|
||||
from globals import OPTS
|
||||
@@ -73,46 +67,56 @@ class control_logic(design.design):
|
||||
def add_modules(self):
|
||||
""" Add all the required modules """
|
||||
|
||||
dff = dff_buf()
|
||||
dff = factory.create(module_type="dff_buf")
|
||||
dff_height = dff.height
|
||||
|
||||
self.ctrl_dff_array = dff_buf_array(rows=self.num_control_signals,columns=1)
|
||||
self.ctrl_dff_array = factory.create(module_type="dff_buf_array",
|
||||
rows=self.num_control_signals,
|
||||
columns=1)
|
||||
|
||||
self.add_mod(self.ctrl_dff_array)
|
||||
|
||||
self.and2 = pand2(size=4,height=dff_height)
|
||||
self.and2 = factory.create(module_type="pand2",
|
||||
size=4,
|
||||
height=dff_height)
|
||||
self.add_mod(self.and2)
|
||||
|
||||
# Special gates: inverters for buffering
|
||||
# Size the clock for the number of rows (fanout)
|
||||
clock_driver_size = max(1,int(self.num_rows/4))
|
||||
self.clkbuf = pbuf(size=clock_driver_size, height=dff_height)
|
||||
self.clkbuf = factory.create(module_type="pbuf",
|
||||
size=clock_driver_size,
|
||||
height=dff_height)
|
||||
|
||||
self.add_mod(self.clkbuf)
|
||||
|
||||
self.buf16 = pbuf(size=16, height=dff_height)
|
||||
self.buf16 = factory.create(module_type="pbuf",
|
||||
size=16,
|
||||
height=dff_height)
|
||||
self.add_mod(self.buf16)
|
||||
|
||||
self.buf8 = pbuf(size=8, height=dff_height)
|
||||
self.buf8 = factory.create(module_type="pbuf",
|
||||
size=8,
|
||||
height=dff_height)
|
||||
self.add_mod(self.buf8)
|
||||
|
||||
self.inv = self.inv1 = pinv(size=1, height=dff_height)
|
||||
self.inv = self.inv1 = factory.create(module_type="pinv",
|
||||
size=1,
|
||||
height=dff_height)
|
||||
self.add_mod(self.inv1)
|
||||
|
||||
self.inv8 = pinv(size=8, height=dff_height)
|
||||
self.inv8 = factory.create(module_type="pinv",
|
||||
size=8,
|
||||
height=dff_height)
|
||||
self.add_mod(self.inv8)
|
||||
|
||||
# self.inv2 = pinv(size=4, height=dff_height)
|
||||
# self.add_mod(self.inv2)
|
||||
#self.inv16 = pinv(size=16, height=dff_height)
|
||||
#self.add_mod(self.inv16)
|
||||
|
||||
if (self.port_type == "rw") or (self.port_type == "r"):
|
||||
from importlib import reload
|
||||
c = reload(__import__(OPTS.replica_bitline))
|
||||
replica_bitline = getattr(c, OPTS.replica_bitline)
|
||||
|
||||
delay_stages_heuristic, delay_fanout_heuristic = self.get_heuristic_delay_chain_size()
|
||||
bitcell_loads = int(math.ceil(self.num_rows / 2.0))
|
||||
self.replica_bitline = replica_bitline([delay_fanout_heuristic]*delay_stages_heuristic, bitcell_loads, name="replica_bitline_"+self.port_type)
|
||||
self.replica_bitline = factory.create(module_type="replica_bitline",
|
||||
delay_fanout_list=[delay_fanout_heuristic]*delay_stages_heuristic,
|
||||
bitcell_loads=bitcell_loads)
|
||||
|
||||
|
||||
if self.sram != None:
|
||||
self.set_sen_wl_delays()
|
||||
@@ -124,8 +128,10 @@ class control_logic(design.design):
|
||||
|
||||
#This resizes based on total delay.
|
||||
delay_stages, delay_fanout = self.get_dynamic_delay_chain_size(delay_stages_heuristic, delay_fanout_heuristic)
|
||||
self.replica_bitline = replica_bitline([delay_fanout]*delay_stages, bitcell_loads, name="replica_bitline_resized_"+self.port_type)
|
||||
|
||||
self.replica_bitline = factory.create(module_type="replica_bitline",
|
||||
delay_fanout_list=[delay_fanout]*delay_stages,
|
||||
bitcell_loads=bitcell_loads)
|
||||
|
||||
self.sen_delay_rise,self.sen_delay_fall = self.get_delays_to_sen() #get the new timing
|
||||
|
||||
self.add_mod(self.replica_bitline)
|
||||
@@ -853,4 +859,4 @@ class control_logic(design.design):
|
||||
last_stage_rise = stage_effort_list[-1].is_rise
|
||||
|
||||
return stage_effort_list
|
||||
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import debug
|
||||
import design
|
||||
from tech import drc
|
||||
from pinv import pinv
|
||||
from contact import contact
|
||||
from vector import vector
|
||||
from globals import OPTS
|
||||
from sram_factory import factory
|
||||
|
||||
class delay_chain(design.design):
|
||||
"""
|
||||
@@ -13,12 +13,8 @@ class delay_chain(design.design):
|
||||
Usually, this will be constant, but it could have varied fanout.
|
||||
"""
|
||||
|
||||
unique_id = 1
|
||||
|
||||
def __init__(self, fanout_list, name="delay_chain"):
|
||||
def __init__(self, name, fanout_list):
|
||||
"""init function"""
|
||||
name = name+"_{}".format(delay_chain.unique_id)
|
||||
delay_chain.unique_id += 1
|
||||
design.design.__init__(self, name)
|
||||
|
||||
# Two fanouts are needed so that we can route the vdd/gnd connections
|
||||
@@ -57,7 +53,7 @@ class delay_chain(design.design):
|
||||
self.add_pin("gnd")
|
||||
|
||||
def add_modules(self):
|
||||
self.inv = pinv(route_output=False)
|
||||
self.inv = factory.create(module_type="pinv", route_output=False)
|
||||
self.add_mod(self.inv)
|
||||
|
||||
def create_inverters(self):
|
||||
@@ -238,4 +234,4 @@ class delay_chain(design.design):
|
||||
stage_effort_list.append(stage)
|
||||
last_stage_is_rise = stage.is_rise
|
||||
|
||||
return stage_effort_list
|
||||
return stage_effort_list
|
||||
|
||||
@@ -3,6 +3,7 @@ import design
|
||||
from tech import drc
|
||||
from math import log
|
||||
from vector import vector
|
||||
from sram_factory import factory
|
||||
from globals import OPTS
|
||||
|
||||
class dff_array(design.design):
|
||||
@@ -38,10 +39,7 @@ class dff_array(design.design):
|
||||
self.DRC_LVS()
|
||||
|
||||
def add_modules(self):
|
||||
from importlib import reload
|
||||
c = reload(__import__(OPTS.dff))
|
||||
self.mod_dff = getattr(c, OPTS.dff)
|
||||
self.dff = self.mod_dff("dff")
|
||||
self.dff = factory.create(module_type="dff")
|
||||
self.add_mod(self.dff)
|
||||
|
||||
def add_pins(self):
|
||||
@@ -61,7 +59,7 @@ class dff_array(design.design):
|
||||
for col in range(self.columns):
|
||||
name = "dff_r{0}_c{1}".format(row,col)
|
||||
self.dff_insts[row,col]=self.add_inst(name=name,
|
||||
mod=self.dff)
|
||||
mod=self.dff)
|
||||
self.connect_inst([self.get_din_name(row,col),
|
||||
self.get_dout_name(row,col),
|
||||
"clk",
|
||||
@@ -162,4 +160,4 @@ class dff_array(design.design):
|
||||
"""Return the total capacitance (in relative units) that the clock is loaded by in the dff array"""
|
||||
dff_clk_cin = self.dff.get_clk_cin()
|
||||
total_cin = dff_clk_cin * self.rows * self.columns
|
||||
return total_cin
|
||||
return total_cin
|
||||
|
||||
@@ -4,7 +4,7 @@ from tech import drc,parameter
|
||||
from math import log
|
||||
from vector import vector
|
||||
from globals import OPTS
|
||||
from pinv import pinv
|
||||
from sram_factory import factory
|
||||
|
||||
class dff_buf(design.design):
|
||||
"""
|
||||
@@ -50,16 +50,17 @@ class dff_buf(design.design):
|
||||
self.DRC_LVS()
|
||||
|
||||
def add_modules(self):
|
||||
from importlib import reload
|
||||
c = reload(__import__(OPTS.dff))
|
||||
self.mod_dff = getattr(c, OPTS.dff)
|
||||
self.dff = self.mod_dff("dff")
|
||||
self.dff = factory.create(module_type="dff")
|
||||
self.add_mod(self.dff)
|
||||
|
||||
self.inv1 = pinv(size=self.inv1_size,height=self.dff.height)
|
||||
self.inv1 = factory.create(module_type="pinv",
|
||||
size=self.inv1_size,
|
||||
height=self.dff.height)
|
||||
self.add_mod(self.inv1)
|
||||
|
||||
self.inv2 = pinv(size=self.inv2_size,height=self.dff.height)
|
||||
self.inv2 = factory.create(module_type="pinv",
|
||||
size=self.inv2_size,
|
||||
height=self.dff.height)
|
||||
self.add_mod(self.inv2)
|
||||
|
||||
|
||||
@@ -182,4 +183,4 @@ class dff_buf(design.design):
|
||||
#This is a handmade cell so the value must be entered in the tech.py file or estimated.
|
||||
#Calculated in the tech file by summing the widths of all the gates and dividing by the minimum width.
|
||||
#FIXME: Dff changed in a past commit. The parameter need to be updated.
|
||||
return parameter["dff_clk_cin"]
|
||||
return parameter["dff_clk_cin"]
|
||||
|
||||
@@ -4,7 +4,7 @@ from tech import drc
|
||||
from math import log
|
||||
from vector import vector
|
||||
from globals import OPTS
|
||||
import dff_buf
|
||||
from sram_factory import factory
|
||||
|
||||
class dff_buf_array(design.design):
|
||||
"""
|
||||
@@ -54,7 +54,9 @@ class dff_buf_array(design.design):
|
||||
self.add_pin("gnd")
|
||||
|
||||
def add_modules(self):
|
||||
self.dff = dff_buf.dff_buf(self.inv1_size, self.inv2_size)
|
||||
self.dff = factory.create(module_type="dff_buf",
|
||||
inv1_size=self.inv1_size,
|
||||
inv2_size=self.inv2_size)
|
||||
self.add_mod(self.dff)
|
||||
|
||||
def create_dff_array(self):
|
||||
@@ -189,4 +191,4 @@ class dff_buf_array(design.design):
|
||||
"""Return the total capacitance (in relative units) that the clock is loaded by in the dff array"""
|
||||
dff_clk_cin = self.dff.get_clk_cin()
|
||||
total_cin = dff_clk_cin * self.rows * self.columns
|
||||
return total_cin
|
||||
return total_cin
|
||||
|
||||
@@ -55,13 +55,12 @@ class dff_inv(design.design):
|
||||
self.add_pin("gnd")
|
||||
|
||||
def add_modules(self):
|
||||
from importlib import reload
|
||||
c = reload(__import__(OPTS.dff))
|
||||
self.mod_dff = getattr(c, OPTS.dff)
|
||||
self.dff = self.mod_dff("dff")
|
||||
self.dff = dff_inv.dff_inv(self.inv_size)
|
||||
self.add_mod(self.dff)
|
||||
|
||||
self.inv1 = pinv(size=self.inv_size,height=self.dff.height)
|
||||
self.inv1 = factory.create(module_type="pinv",
|
||||
size=self.inv_size,
|
||||
height=self.dff.height)
|
||||
self.add_mod(self.inv1)
|
||||
|
||||
def create_modules(self):
|
||||
@@ -152,4 +151,4 @@ class dff_inv(design.design):
|
||||
|
||||
def get_clk_cin(self):
|
||||
"""Return the total capacitance (in relative units) that the clock is loaded by in the dff"""
|
||||
return self.dff.get_clk_cin()
|
||||
return self.dff.get_clk_cin()
|
||||
|
||||
@@ -42,7 +42,7 @@ class dff_inv_array(design.design):
|
||||
self.DRC_LVS()
|
||||
|
||||
def add_modules(self):
|
||||
self.dff = dff_inv.dff_inv(self.inv_size)
|
||||
self.dff = factory.create(module_type="dff")
|
||||
self.add_mod(self.dff)
|
||||
|
||||
def add_pins(self):
|
||||
@@ -189,4 +189,4 @@ class dff_inv_array(design.design):
|
||||
"""Return the total capacitance (in relative units) that the clock is loaded by in the dff array"""
|
||||
dff_clk_cin = self.dff.get_clk_cin()
|
||||
total_cin = dff_clk_cin * self.rows * self.columns
|
||||
return total_cin
|
||||
return total_cin
|
||||
|
||||
@@ -4,12 +4,8 @@ import design
|
||||
from math import log
|
||||
from math import sqrt
|
||||
import math
|
||||
import contact
|
||||
from pnand2 import pnand2
|
||||
from pnand3 import pnand3
|
||||
from pinv import pinv
|
||||
from hierarchical_predecode2x4 import hierarchical_predecode2x4 as pre2x4
|
||||
from hierarchical_predecode3x8 import hierarchical_predecode3x8 as pre3x8
|
||||
import contact
|
||||
from sram_factory import factory
|
||||
from vector import vector
|
||||
from globals import OPTS
|
||||
|
||||
@@ -17,11 +13,8 @@ class hierarchical_decoder(design.design):
|
||||
"""
|
||||
Dynamically generated hierarchical decoder.
|
||||
"""
|
||||
unique_id = 1
|
||||
|
||||
def __init__(self, rows, height=None):
|
||||
design.design.__init__(self, "hierarchical_decoder_{0}rows_{1}".format(rows,hierarchical_decoder.unique_id))
|
||||
hierarchical_decoder.unique_id += 1
|
||||
def __init__(self, name, rows, height=None):
|
||||
design.design.__init__(self, name)
|
||||
|
||||
self.NAND_FORMAT = "DEC_NAND_{0}"
|
||||
self.INV_FORMAT = "DEC_INV_{0}"
|
||||
@@ -57,21 +50,26 @@ class hierarchical_decoder(design.design):
|
||||
self.DRC_LVS()
|
||||
|
||||
def add_modules(self):
|
||||
self.inv = pinv(height=self.cell_height)
|
||||
self.inv = factory.create(module_type="pinv",
|
||||
height=self.cell_height)
|
||||
self.add_mod(self.inv)
|
||||
self.nand2 = pnand2(height=self.cell_height)
|
||||
self.nand2 = factory.create(module_type="pnand2",
|
||||
height=self.cell_height)
|
||||
self.add_mod(self.nand2)
|
||||
self.nand3 = pnand3(height=self.cell_height)
|
||||
self.nand3 = factory.create(module_type="pnand3",
|
||||
height=self.cell_height)
|
||||
self.add_mod(self.nand3)
|
||||
|
||||
self.add_decoders()
|
||||
|
||||
def add_decoders(self):
|
||||
""" Create the decoders based on the number of pre-decodes """
|
||||
self.pre2_4 = pre2x4(height=self.cell_height)
|
||||
self.pre2_4 = factory.create(module_type="hierarchical_predecode2x4",
|
||||
height=self.cell_height)
|
||||
self.add_mod(self.pre2_4)
|
||||
|
||||
self.pre3_8 = pre3x8(height=self.cell_height)
|
||||
self.pre3_8 = factory.create(module_type="hierarchical_predecode3x8",
|
||||
height=self.cell_height)
|
||||
self.add_mod(self.pre3_8)
|
||||
|
||||
def determine_predecodes(self,num_inputs):
|
||||
|
||||
@@ -3,24 +3,19 @@ import design
|
||||
import math
|
||||
from tech import drc
|
||||
import contact
|
||||
from pinv import pinv
|
||||
from vector import vector
|
||||
from globals import OPTS
|
||||
from pnand2 import pnand2
|
||||
from pnand3 import pnand3
|
||||
from sram_factory import factory
|
||||
|
||||
class hierarchical_predecode(design.design):
|
||||
"""
|
||||
Pre 2x4 and 3x8 decoder shared code.
|
||||
"""
|
||||
unique_id = 1
|
||||
|
||||
def __init__(self, input_number, height=None):
|
||||
def __init__(self, name, input_number, height=None):
|
||||
self.number_of_inputs = input_number
|
||||
self.cell_height = height
|
||||
self.number_of_outputs = int(math.pow(2, self.number_of_inputs))
|
||||
design.design.__init__(self, name="pre{0}x{1}_{2}".format(self.number_of_inputs,self.number_of_outputs,hierarchical_predecode.unique_id))
|
||||
hierarchical_predecode.unique_id += 1
|
||||
design.design.__init__(self, name)
|
||||
|
||||
def add_pins(self):
|
||||
for k in range(self.number_of_inputs):
|
||||
@@ -33,7 +28,8 @@ class hierarchical_predecode(design.design):
|
||||
def add_modules(self):
|
||||
""" Add the INV and NAND gate modules """
|
||||
|
||||
self.inv = pinv(height=self.cell_height)
|
||||
self.inv = factory.create(module_type="pinv",
|
||||
height=self.cell_height)
|
||||
self.add_mod(self.inv)
|
||||
|
||||
self.add_nand(self.number_of_inputs)
|
||||
@@ -42,9 +38,11 @@ class hierarchical_predecode(design.design):
|
||||
def add_nand(self,inputs):
|
||||
""" Create the NAND for the predecode input stage """
|
||||
if inputs==2:
|
||||
self.nand = pnand2(height=self.cell_height)
|
||||
self.nand = factory.create(module_type="pnand2",
|
||||
height=self.cell_height)
|
||||
elif inputs==3:
|
||||
self.nand = pnand3(height=self.cell_height)
|
||||
self.nand = factory.create(module_type="pnand3",
|
||||
height=self.cell_height)
|
||||
else:
|
||||
debug.error("Invalid number of predecode inputs: {}".format(inputs),-1)
|
||||
|
||||
|
||||
@@ -9,8 +9,8 @@ class hierarchical_predecode2x4(hierarchical_predecode):
|
||||
"""
|
||||
Pre 2x4 decoder used in hierarchical_decoder.
|
||||
"""
|
||||
def __init__(self, height=None):
|
||||
hierarchical_predecode.__init__(self, 2, height)
|
||||
def __init__(self, name, height=None):
|
||||
hierarchical_predecode.__init__(self, name, 2, height)
|
||||
|
||||
self.create_netlist()
|
||||
if not OPTS.netlist_only:
|
||||
|
||||
@@ -9,8 +9,8 @@ class hierarchical_predecode3x8(hierarchical_predecode):
|
||||
"""
|
||||
Pre 3x8 decoder used in hierarchical_decoder.
|
||||
"""
|
||||
def __init__(self, height=None):
|
||||
hierarchical_predecode.__init__(self, 3, height)
|
||||
def __init__(self, name, height=None):
|
||||
hierarchical_predecode.__init__(self, name, 3, height)
|
||||
|
||||
self.create_netlist()
|
||||
if not OPTS.netlist_only:
|
||||
|
||||
@@ -5,12 +5,8 @@ import design
|
||||
import math
|
||||
from math import log,sqrt,ceil
|
||||
import contact
|
||||
from pinv import pinv
|
||||
from pnand2 import pnand2
|
||||
from pnor2 import pnor2
|
||||
from vector import vector
|
||||
from pinvbuf import pinvbuf
|
||||
|
||||
from sram_factory import factory
|
||||
from globals import OPTS
|
||||
|
||||
class multibank(design.design):
|
||||
@@ -21,21 +17,8 @@ class multibank(design.design):
|
||||
This module includes the tristate and bank select logic.
|
||||
"""
|
||||
|
||||
def __init__(self, word_size, num_words, words_per_row, num_banks=1, name=""):
|
||||
def __init__(self, name, word_size, num_words, words_per_row, num_banks=1):
|
||||
|
||||
mod_list = ["tri_gate", "bitcell", "decoder", "wordline_driver",
|
||||
"bitcell_array", "sense_amp_array", "precharge_array",
|
||||
"column_mux_array", "write_driver_array", "tri_gate_array",
|
||||
"dff", "bank_select"]
|
||||
from importlib import reload
|
||||
for mod_name in mod_list:
|
||||
config_mod_name = getattr(OPTS, mod_name)
|
||||
class_file = reload(__import__(config_mod_name))
|
||||
mod_class = getattr(class_file , config_mod_name)
|
||||
setattr (self, "mod_"+mod_name, mod_class)
|
||||
|
||||
if name == "":
|
||||
name = "bank_{0}_{1}".format(word_size, num_words)
|
||||
design.design.__init__(self, name)
|
||||
debug.info(2, "create sram of size {0} with {1} words".format(word_size,num_words))
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ import design
|
||||
import debug
|
||||
from tech import drc
|
||||
from vector import vector
|
||||
from precharge import precharge
|
||||
from sram_factory import factory
|
||||
from globals import OPTS
|
||||
|
||||
class precharge_array(design.design):
|
||||
@@ -11,11 +11,7 @@ class precharge_array(design.design):
|
||||
of bit line columns, height is the height of the bit-cell array.
|
||||
"""
|
||||
|
||||
unique_id = 1
|
||||
|
||||
def __init__(self, columns, size=1, bitcell_bl="bl", bitcell_br="br"):
|
||||
name = "precharge_array_{}".format(precharge_array.unique_id)
|
||||
precharge_array.unique_id += 1
|
||||
def __init__(self, name, columns, size=1, bitcell_bl="bl", bitcell_br="br"):
|
||||
design.design.__init__(self, name)
|
||||
debug.info(1, "Creating {0}".format(self.name))
|
||||
|
||||
@@ -50,10 +46,12 @@ class precharge_array(design.design):
|
||||
self.DRC_LVS()
|
||||
|
||||
def add_modules(self):
|
||||
self.pc_cell = precharge(name="precharge",
|
||||
size=self.size,
|
||||
bitcell_bl=self.bitcell_bl,
|
||||
bitcell_br=self.bitcell_br)
|
||||
self.pc_cell = factory.create(module_type="precharge",
|
||||
size=self.size,
|
||||
bitcell_bl=self.bitcell_bl,
|
||||
bitcell_br=self.bitcell_br)
|
||||
|
||||
|
||||
self.add_mod(self.pc_cell)
|
||||
|
||||
|
||||
@@ -107,4 +105,4 @@ class precharge_array(design.design):
|
||||
"""Get the relative capacitance of all the clk connections in the precharge array"""
|
||||
#Assume single port
|
||||
precharge_en_cin = self.pc_cell.get_en_cin()
|
||||
return precharge_en_cin*self.columns
|
||||
return precharge_en_cin*self.columns
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
import debug
|
||||
import design
|
||||
from tech import drc
|
||||
from pinv import pinv
|
||||
import contact
|
||||
from bitcell_array import bitcell_array
|
||||
from ptx import ptx
|
||||
from sram_factory import factory
|
||||
from vector import vector
|
||||
from globals import OPTS
|
||||
|
||||
@@ -15,7 +13,7 @@ class replica_bitline(design.design):
|
||||
line and rows is the height of the replica bit loads.
|
||||
"""
|
||||
|
||||
def __init__(self, delay_fanout_list, bitcell_loads, name="replica_bitline"):
|
||||
def __init__(self, name, delay_fanout_list, bitcell_loads):
|
||||
design.design.__init__(self, name)
|
||||
|
||||
self.bitcell_loads = bitcell_loads
|
||||
@@ -78,29 +76,25 @@ class replica_bitline(design.design):
|
||||
def add_modules(self):
|
||||
""" Add the modules for later usage """
|
||||
|
||||
from importlib import reload
|
||||
#g = reload(__import__(OPTS.delay_chain))
|
||||
#self.mod_delay_chain = getattr(g, OPTS.delay_chain)
|
||||
|
||||
g = reload(__import__(OPTS.replica_bitcell))
|
||||
self.mod_replica_bitcell = getattr(g, OPTS.replica_bitcell)
|
||||
|
||||
self.bitcell = self.replica_bitcell = self.mod_replica_bitcell()
|
||||
self.add_mod(self.bitcell)
|
||||
self.replica_bitcell = factory.create(module_type="replica_bitcell")
|
||||
self.add_mod(self.replica_bitcell)
|
||||
|
||||
# This is the replica bitline load column that is the height of our array
|
||||
self.rbl = bitcell_array(cols=1, rows=self.bitcell_loads)
|
||||
self.rbl = factory.create(module_type="bitcell_array",
|
||||
cols=1,
|
||||
rows=self.bitcell_loads)
|
||||
self.add_mod(self.rbl)
|
||||
|
||||
# FIXME: The FO and depth of this should be tuned
|
||||
from delay_chain import delay_chain
|
||||
self.delay_chain = delay_chain(self.delay_fanout_list)
|
||||
self.delay_chain = factory.create(module_type="delay_chain",
|
||||
fanout_list=self.delay_fanout_list)
|
||||
self.add_mod(self.delay_chain)
|
||||
|
||||
self.inv = pinv()
|
||||
self.inv = factory.create(module_type="pinv")
|
||||
self.add_mod(self.inv)
|
||||
|
||||
self.access_tx = ptx(tx_type="pmos")
|
||||
self.access_tx = factory.create(module_type="ptx",
|
||||
tx_type="pmos")
|
||||
self.add_mod(self.access_tx)
|
||||
|
||||
def create_instances(self):
|
||||
@@ -132,7 +126,6 @@ class replica_bitline(design.design):
|
||||
temp.append("vdd")
|
||||
temp.append("gnd")
|
||||
self.connect_inst(temp)
|
||||
#self.connect_inst(["bl_0", "br_0", "delayed_en", "vdd", "gnd"])
|
||||
|
||||
self.rbl_inst=self.add_inst(name="load",
|
||||
mod=self.rbl)
|
||||
@@ -631,4 +624,4 @@ class replica_bitline(design.design):
|
||||
access_tx_cin = self.access_tx.get_cin()
|
||||
rbc_cin = self.replica_bitcell.get_wl_cin()
|
||||
return access_tx_cin + rbc_cin
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import design
|
||||
from tech import drc
|
||||
from vector import vector
|
||||
from sram_factory import factory
|
||||
import debug
|
||||
from globals import OPTS
|
||||
|
||||
@@ -10,8 +11,8 @@ class sense_amp_array(design.design):
|
||||
Dynamically generated sense amp array for all bitlines.
|
||||
"""
|
||||
|
||||
def __init__(self, word_size, words_per_row):
|
||||
design.design.__init__(self, "sense_amp_array")
|
||||
def __init__(self, name, word_size, words_per_row):
|
||||
design.design.__init__(self, name)
|
||||
debug.info(1, "Creating {0}".format(self.name))
|
||||
|
||||
self.word_size = word_size
|
||||
@@ -51,17 +52,13 @@ class sense_amp_array(design.design):
|
||||
self.add_pin("gnd")
|
||||
|
||||
def add_modules(self):
|
||||
from importlib import reload
|
||||
c = reload(__import__(OPTS.sense_amp))
|
||||
self.mod_sense_amp = getattr(c, OPTS.sense_amp)
|
||||
self.amp = self.mod_sense_amp("sense_amp")
|
||||
self.amp = factory.create(module_type="sense_amp")
|
||||
|
||||
self.add_mod(self.amp)
|
||||
|
||||
# This is just used for measurements,
|
||||
# so don't add the module
|
||||
c = reload(__import__(OPTS.bitcell))
|
||||
self.mod_bitcell = getattr(c, OPTS.bitcell)
|
||||
self.bitcell = self.mod_bitcell()
|
||||
self.bitcell = factory.create(module_type="bitcell")
|
||||
|
||||
def create_sense_amp_array(self):
|
||||
self.local_insts = []
|
||||
@@ -143,4 +140,4 @@ class sense_amp_array(design.design):
|
||||
def get_en_cin(self):
|
||||
"""Get the relative capacitance of all the sense amp enable connections in the array"""
|
||||
sense_amp_en_cin = self.amp.get_en_cin()
|
||||
return sense_amp_en_cin * self.words_per_row
|
||||
return sense_amp_en_cin * self.words_per_row
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
from math import log
|
||||
import design
|
||||
from single_level_column_mux import single_level_column_mux
|
||||
import contact
|
||||
from tech import drc
|
||||
import debug
|
||||
import math
|
||||
from vector import vector
|
||||
from sram_factory import factory
|
||||
from globals import OPTS
|
||||
|
||||
class single_level_column_mux_array(design.design):
|
||||
@@ -14,11 +14,7 @@ class single_level_column_mux_array(design.design):
|
||||
Array of column mux to read the bitlines through the 6T.
|
||||
"""
|
||||
|
||||
unique_id = 1
|
||||
|
||||
def __init__(self, columns, word_size, bitcell_bl="bl", bitcell_br="br"):
|
||||
name="single_level_column_mux_array_{}".format(single_level_column_mux_array.unique_id)
|
||||
single_level_column_mux_array.unique_id += 1
|
||||
def __init__(self, name, columns, word_size, bitcell_bl="bl", bitcell_br="br"):
|
||||
design.design.__init__(self, name)
|
||||
debug.info(1, "Creating {0}".format(self.name))
|
||||
self.columns = columns
|
||||
@@ -61,7 +57,9 @@ class single_level_column_mux_array(design.design):
|
||||
|
||||
|
||||
def add_modules(self):
|
||||
self.mux = single_level_column_mux(bitcell_bl=self.bitcell_bl, bitcell_br=self.bitcell_br)
|
||||
self.mux = factory.create(module_type="single_level_column_mux",
|
||||
bitcell_bl=self.bitcell_bl,
|
||||
bitcell_br=self.bitcell_br)
|
||||
self.add_mod(self.mux)
|
||||
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ import debug
|
||||
from tech import drc
|
||||
import design
|
||||
from vector import vector
|
||||
from sram_factory import factory
|
||||
from globals import OPTS
|
||||
|
||||
class tri_gate_array(design.design):
|
||||
@@ -36,10 +37,7 @@ class tri_gate_array(design.design):
|
||||
self.DRC_LVS()
|
||||
|
||||
def add_modules(self):
|
||||
from importlib import reload
|
||||
c = reload(__import__(OPTS.tri_gate))
|
||||
self.mod_tri_gate = getattr(c, OPTS.tri_gate)
|
||||
self.tri = self.mod_tri_gate("tri_gate")
|
||||
self.tri = factory.create(module_type="tri_gate")
|
||||
self.add_mod(self.tri)
|
||||
|
||||
def add_pins(self):
|
||||
|
||||
@@ -5,9 +5,8 @@ import contact
|
||||
from math import log
|
||||
from math import sqrt
|
||||
import math
|
||||
from pinv import pinv
|
||||
from pnand2 import pnand2
|
||||
from vector import vector
|
||||
from sram_factory import factory
|
||||
from globals import OPTS
|
||||
|
||||
class wordline_driver(design.design):
|
||||
@@ -16,8 +15,8 @@ class wordline_driver(design.design):
|
||||
Generates the wordline-driver to drive the bitcell
|
||||
"""
|
||||
|
||||
def __init__(self, rows):
|
||||
design.design.__init__(self, "wordline_driver")
|
||||
def __init__(self, name, rows):
|
||||
design.design.__init__(self, name)
|
||||
|
||||
self.rows = rows
|
||||
|
||||
@@ -53,13 +52,14 @@ class wordline_driver(design.design):
|
||||
# This is just used for measurements,
|
||||
# so don't add the module
|
||||
|
||||
self.inv = pinv()
|
||||
self.inv = factory.create(module_type="pinv")
|
||||
self.add_mod(self.inv)
|
||||
|
||||
self.inv_no_output = pinv(route_output=False)
|
||||
self.inv_no_output = factory.create(module_type="pinv",
|
||||
route_output=False)
|
||||
self.add_mod(self.inv_no_output)
|
||||
|
||||
self.nand2 = pnand2()
|
||||
self.nand2 = factory.create(module_type="pnand2")
|
||||
self.add_mod(self.nand2)
|
||||
|
||||
|
||||
@@ -237,4 +237,4 @@ class wordline_driver(design.design):
|
||||
"""Get the relative capacitance of all the enable connections in the bank"""
|
||||
#The enable is connected to a nand2 for every row.
|
||||
total_cin = self.nand2.get_cin() * self.rows
|
||||
return total_cin
|
||||
return total_cin
|
||||
|
||||
@@ -2,6 +2,7 @@ from math import log
|
||||
import design
|
||||
from tech import drc
|
||||
import debug
|
||||
from sram_factory import factory
|
||||
from vector import vector
|
||||
from globals import OPTS
|
||||
|
||||
@@ -11,8 +12,8 @@ class write_driver_array(design.design):
|
||||
Dynamically generated write driver array of all bitlines.
|
||||
"""
|
||||
|
||||
def __init__(self, columns, word_size):
|
||||
design.design.__init__(self, "write_driver_array")
|
||||
def __init__(self, name, columns, word_size):
|
||||
design.design.__init__(self, name)
|
||||
debug.info(1, "Creating {0}".format(self.name))
|
||||
|
||||
self.columns = columns
|
||||
@@ -53,17 +54,12 @@ class write_driver_array(design.design):
|
||||
self.add_pin("gnd")
|
||||
|
||||
def add_modules(self):
|
||||
from importlib import reload
|
||||
c = reload(__import__(OPTS.write_driver))
|
||||
self.mod_write_driver = getattr(c, OPTS.write_driver)
|
||||
self.driver = self.mod_write_driver("write_driver")
|
||||
self.driver = factory.create(module_type="write_driver")
|
||||
self.add_mod(self.driver)
|
||||
|
||||
# This is just used for measurements,
|
||||
# so don't add the module
|
||||
c = reload(__import__(OPTS.bitcell))
|
||||
self.mod_bitcell = getattr(c, OPTS.bitcell)
|
||||
self.bitcell = self.mod_bitcell()
|
||||
self.bitcell = factory.create(module_type="bitcell")
|
||||
|
||||
def create_write_array(self):
|
||||
self.driver_insts = {}
|
||||
|
||||
Reference in New Issue
Block a user