Fixed merge conflicts

This commit is contained in:
Hunter Nichols
2019-01-28 22:33:08 -08:00
121 changed files with 1245 additions and 1419 deletions
+47 -48
View File
@@ -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,39 @@ 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,
cols=self.num_cols)
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 +691,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)
@@ -1071,8 +1068,8 @@ class bank(design.design):
# The mid guarantees we exit the input cell to the right.
driver_wl_pos = self.wordline_driver_inst[port].get_pin("wl_{}".format(row)).rc()
bitcell_wl_pos = self.bitcell_array_inst.get_pin(self.wl_names[port]+"_{}".format(row)).lc()
mid1 = driver_wl_pos.scale(0.5,1)+bitcell_wl_pos.scale(0.5,0)
mid2 = driver_wl_pos.scale(0.5,0)+bitcell_wl_pos.scale(0.5,1)
mid1 = driver_wl_pos.scale(0,1) + vector(0.5*self.wordline_driver_inst[port].rx() + 0.5*self.bitcell_array_inst.lx(),0)
mid2 = mid1.scale(1,0)+bitcell_wl_pos.scale(0.5,1)
self.add_path("metal1", [driver_wl_pos, mid1, mid2, bitcell_wl_pos])
@@ -1090,8 +1087,8 @@ class bank(design.design):
# The mid guarantees we exit the input cell to the right.
driver_wl_pos = self.wordline_driver_inst[port].get_pin("wl_{}".format(row)).lc()
bitcell_wl_pos = self.bitcell_array_inst.get_pin(self.wl_names[port]+"_{}".format(row)).rc()
mid1 = driver_wl_pos.scale(0.5,1)+bitcell_wl_pos.scale(0.5,0)
mid2 = driver_wl_pos.scale(0.5,0)+bitcell_wl_pos.scale(0.5,1)
mid1 = driver_wl_pos.scale(0,1) + vector(0.5*self.wordline_driver_inst[port].lx() + 0.5*self.bitcell_array_inst.rx(),0)
mid2 = mid1.scale(1,0)+bitcell_wl_pos.scale(0,1)
self.add_path("metal1", [driver_wl_pos, mid1, mid2, bitcell_wl_pos])
def route_column_address_lines(self, port):
@@ -1257,20 +1254,22 @@ class bank(design.design):
def get_wl_en_cin(self):
"""Get the relative capacitance of all the clk connections in the bank"""
#wl_en only used in the wordline driver.
total_clk_cin = self.wordline_driver.get_wl_en_cin()
return total_clk_cin
return self.wordline_driver.get_wl_en_cin()
def get_w_en_cin(self):
"""Get the relative capacitance of all the clk connections in the bank"""
#wl_en only used in the wordline driver.
return self.write_driver.get_w_en_cin()
def get_clk_bar_cin(self):
"""Get the relative capacitance of all the clk_bar connections in the bank"""
#Current bank only uses clock bar (clk_buf_bar) as an enable for the precharge array.
#Precharges are the all the same in Mulitport, one is picked
port = self.read_ports[0]
total_clk_bar_cin = self.precharge_array[port].get_en_cin()
return total_clk_bar_cin
return self.precharge_array[port].get_en_cin()
def get_sen_cin(self):
"""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 self.sense_amp_array.get_en_cin()
+11 -13
View File
@@ -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())
+5 -16
View File
@@ -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,16 +11,10 @@ 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))
self.add_comment("rows: {0} cols: {1}".format(rows, cols))
self.column_size = cols
self.row_size = rows
@@ -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
+84 -57
View File
@@ -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
@@ -20,20 +14,26 @@ class control_logic(design.design):
Dynamically generated Control logic for the total SRAM circuit.
"""
def __init__(self, num_rows, words_per_row, sram=None, port_type="rw"):
def __init__(self, num_rows, words_per_row, word_size, sram=None, port_type="rw"):
""" Constructor """
name = "control_logic_" + port_type
design.design.__init__(self, name)
debug.info(1, "Creating {}".format(name))
self.add_comment("num_rows: {0}".format(num_rows))
self.add_comment("words_per_row: {0}".format(words_per_row))
self.add_comment("word_size {0}".format(word_size))
self.sram=sram
self.num_rows = num_rows
self.words_per_row = words_per_row
self.word_size = word_size
self.port_type = port_type
self.num_cols = word_size*words_per_row
self.num_words = num_rows * words_per_row
self.enable_delay_chain_resizing = False
#This is needed to resize the delay chain. Likely to be changed at some point.
self.sram=sram
#self.sram=None #disable re-sizing for debugging, FIXME: resizing is not working, needs to be adjusted for new control logic.
self.wl_timing_tolerance = 1 #Determines how much larger the sen delay should be. Accounts for possible error in model.
self.parasitic_inv_delay = parameter["min_inv_para_delay"] #Keeping 0 for now until further testing.
@@ -75,38 +75,62 @@ 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.add_mod(self.clkbuf)
self.buf16 = pbuf(size=16, height=dff_height)
self.add_mod(self.buf16)
self.buf8 = pbuf(size=8, height=dff_height)
self.add_mod(self.buf8)
# clk_buf drives a flop for every address and control bit
# plus about 5 fanouts for the control logic
# each flop internally has a FO 4 approximately
clock_fanout = 4*(math.log(self.num_words,2) + math.log(self.words_per_row,2) \
+ self.num_control_signals) + 5
self.clk_buf_driver = factory.create(module_type="pdriver",
fanout=clock_fanout,
height=dff_height)
self.inv = self.inv1 = pinv(size=1, height=dff_height)
self.add_mod(self.inv1)
self.inv8 = 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)
self.add_mod(self.clk_buf_driver)
# wl_en drives every row in the bank
self.wl_en_driver = factory.create(module_type="pdriver",
fanout=self.num_rows,
height=dff_height)
self.add_mod(self.wl_en_driver)
# w_en drives every write driver
self.w_en_driver = factory.create(module_type="pdriver",
fanout=self.word_size+8,
height=dff_height)
self.add_mod(self.w_en_driver)
# s_en drives every sense amp
self.s_en_driver = factory.create(module_type="pdriver",
fanout=self.word_size,
height=dff_height)
self.add_mod(self.s_en_driver)
# used to generate inverted signals with low fanout
self.inv = factory.create(module_type="pinv",
size=1,
height=dff_height)
self.add_mod(self.inv)
# p_en_bar drives every column in the bicell array
self.p_en_bar_driver = factory.create(module_type="pdriver",
neg_polarity=True,
fanout=self.num_cols,
height=dff_height)
self.add_mod(self.p_en_bar_driver)
if (self.port_type == "rw") or (self.port_type == "r"):
from importlib import reload
c = reload(__import__(OPTS.replica_bitline))
@@ -126,9 +150,9 @@ class control_logic(design.design):
else: #Otherwise, use a heuristic and/or model based sizing.
#First use a heuristic
delay_stages_heuristic, delay_fanout_heuristic = self.get_heuristic_delay_chain_size()
self.replica_bitline = replica_bitline([delay_fanout_heuristic]*delay_stages_heuristic,
bitcell_loads,
name="replica_bitline_"+self.port_type)
self.replica_bitline = replica_bitline("replica_bitline_"+self.port_type,
[delay_fanout_heuristic]*delay_stages_heuristic,
bitcell_loads)
if self.sram != None: #Calculate delays for potential re-sizing
self.set_sen_wl_delays()
#Resize if necessary, condition depends on resizing method
@@ -412,8 +436,8 @@ class control_logic(design.design):
def create_clk_buf_row(self):
""" Create the multistage and gated clock buffer """
self.clkbuf_inst = self.add_inst(name="clkbuf",
mod=self.clkbuf)
self.clk_buf_inst = self.add_inst(name="clkbuf",
mod=self.clk_buf_driver)
self.connect_inst(["clk","clk_buf","vdd","gnd"])
def place_clk_buf_row(self,row):
@@ -422,12 +446,12 @@ class control_logic(design.design):
(y_off,mirror)=self.get_offset(row)
offset = vector(x_off,y_off)
self.clkbuf_inst.place(offset, mirror)
self.clk_buf_inst.place(offset, mirror)
self.row_end_inst.append(self.clkbuf_inst)
self.row_end_inst.append(self.clk_buf_inst)
def route_clk_buf(self):
clk_pin = self.clkbuf_inst.get_pin("A")
clk_pin = self.clk_buf_inst.get_pin("A")
clk_pos = clk_pin.center()
self.add_layout_pin_segment_center(text="clk",
layer="metal2",
@@ -437,14 +461,17 @@ class control_logic(design.design):
offset=clk_pos)
clkbuf_map = zip(["Z"], ["clk_buf"])
self.connect_vertical_bus(clkbuf_map, self.clkbuf_inst, self.rail_offsets, ("metal3", "via2", "metal2"))
# Connect this at the bottom of the buffer
out_pos = self.clk_buf_inst.get_pin("Z").center()
mid1 = vector(out_pos.x,2*self.m2_pitch)
mid2 = vector(self.rail_offsets["clk_buf"].x, mid1.y)
bus_pos = self.rail_offsets["clk_buf"]
self.add_wire(("metal3","via2","metal2"),[out_pos, mid1, mid2, bus_pos])
# The pin is on M1, so we need another via as well
self.add_via_center(layers=("metal1","via1","metal2"),
offset=self.clkbuf_inst.get_pin("Z").center())
offset=self.clk_buf_inst.get_pin("Z").center())
self.connect_output(self.clkbuf_inst, "Z", "clk_buf")
self.connect_output(self.clk_buf_inst, "Z", "clk_buf")
def create_gated_clk_bar_row(self):
self.clk_bar_inst = self.add_inst(name="inv_clk_bar",
@@ -523,7 +550,7 @@ class control_logic(design.design):
def create_wlen_row(self):
# input pre_p_en, output: wl_en
self.wl_en_inst=self.add_inst(name="buf_wl_en",
mod=self.buf16)
mod=self.wl_en_driver)
self.connect_inst(["gated_clk_bar", "wl_en", "vdd", "gnd"])
def place_wlen_row(self, row):
@@ -593,7 +620,7 @@ class control_logic(design.design):
# input: pre_p_en, output: p_en_bar
self.p_en_bar_inst=self.add_inst(name="inv_p_en_bar",
mod=self.inv8)
mod=self.p_en_bar_driver)
self.connect_inst([input_name, "p_en_bar", "vdd", "gnd"])
@@ -633,7 +660,7 @@ class control_logic(design.design):
# BUFFER FOR S_EN
# input: pre_s_en, output: s_en
self.s_en_inst=self.add_inst(name="buf_s_en",
mod=self.buf8)
mod=self.s_en_driver)
self.connect_inst(["pre_s_en", "s_en", "vdd", "gnd"])
def place_sen_row(self,row):
@@ -670,7 +697,7 @@ class control_logic(design.design):
# BUFFER FOR W_EN
self.w_en_inst = self.add_inst(name="buf_w_en_buf",
mod=self.buf8)
mod=self.w_en_driver)
self.connect_inst([input_name, "w_en", "vdd", "gnd"])
@@ -827,7 +854,7 @@ class control_logic(design.design):
#Calculate the load on wl_en within the module and add it to external load
external_cout = self.sram.get_wl_en_cin()
#First stage is the clock buffer
stage_effort_list += self.clkbuf.get_output_stage_efforts(external_cout, is_clk_bar_rise)
stage_effort_list += self.clk_buf_driver.get_stage_efforts(external_cout, is_clk_bar_rise)
last_stage_is_rise = stage_effort_list[-1].is_rise
#Then ask the sram for the other path delays (from the bank)
@@ -858,21 +885,21 @@ class control_logic(design.design):
#First stage, gated_clk_bar -(and2)-> rbl_in. Only for RW ports.
if self.port_type == "rw":
stage1_cout = self.replica_bitline.get_en_cin()
stage_effort_list += self.and2.get_output_stage_efforts(stage1_cout, last_stage_rise)
stage_effort_list += self.and2.get_stage_efforts(stage1_cout, last_stage_rise)
last_stage_rise = stage_effort_list[-1].is_rise
#Replica bitline stage, rbl_in -(rbl)-> pre_s_en
stage2_cout = self.buf8.get_cin()
stage2_cout = self.s_en_driver.get_cin()
stage_effort_list += self.replica_bitline.determine_sen_stage_efforts(stage2_cout, last_stage_rise)
last_stage_rise = stage_effort_list[-1].is_rise
#buffer stage, pre_s_en -(buffer)-> s_en
stage3_cout = self.sram.get_sen_cin()
stage_effort_list += self.buf8.get_output_stage_efforts(stage3_cout, last_stage_rise)
stage_effort_list += self.s_en_driver.get_stage_efforts(stage3_cout, last_stage_rise)
last_stage_rise = stage_effort_list[-1].is_rise
return stage_effort_list
def get_wl_sen_delays(self):
"""Gets a list of the stages and delays in order of their path."""
if self.sen_stage_efforts == None or self.wl_stage_efforts == None:
@@ -880,4 +907,4 @@ class control_logic(design.design):
wl_delays = logical_effort.calculate_delays(self.wl_stage_efforts, self.parasitic_inv_delay)
sen_delays = logical_effort.calculate_delays(self.sen_stage_efforts, self.parasitic_inv_delay)
return wl_delays, sen_delays
+8 -10
View File
@@ -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,14 +13,12 @@ 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)
debug.info(1, "creating delay chain {0}".format(str(fanout_list)))
self.add_comment("fanouts: {0}".format(str(fanout_list)))
# Two fanouts are needed so that we can route the vdd/gnd connections
for f in fanout_list:
debug.check(f>=2,"Must have >=2 fanouts for each stage.")
@@ -57,7 +55,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):
@@ -234,8 +232,8 @@ class delay_chain(design.design):
stage_cout = self.inv.get_cin()*(stage_fanout+1)
if len(stage_effort_list) == len(self.fanout_list)-1: #last stage
stage_cout+=ext_delayed_en_cout
stage = self.inv.get_effort_stage(stage_cout, last_stage_is_rise)
stage = self.inv.get_stage_effort(stage_cout, last_stage_is_rise)
stage_effort_list.append(stage)
last_stage_is_rise = stage.is_rise
return stage_effort_list
return stage_effort_list
+7 -8
View File
@@ -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):
@@ -11,7 +12,7 @@ class dff_array(design.design):
Unlike the data flops, these are never spaced out.
"""
def __init__(self, rows, columns, inv1_size=2, inv2_size=4, name=""):
def __init__(self, rows, columns, name=""):
self.rows = rows
self.columns = columns
@@ -19,7 +20,8 @@ class dff_array(design.design):
name = "dff_array_{0}x{1}".format(rows, columns)
design.design.__init__(self, name)
debug.info(1, "Creating {0} rows={1} cols={2}".format(self.name, self.rows, self.columns))
self.add_comment("rows: {0} cols: {1}".format(rows, columns))
self.create_netlist()
if not OPTS.netlist_only:
self.create_layout()
@@ -38,10 +40,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 +60,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 +161,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
+11 -9
View File
@@ -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):
"""
@@ -21,7 +21,8 @@ class dff_buf(design.design):
dff_buf.unique_id += 1
design.design.__init__(self, name)
debug.info(1, "Creating {}".format(self.name))
self.add_comment("inv1: {0} inv2: {1}".format(inv1_size, inv2_size))
# This is specifically for SCMOS where the DFF vdd/gnd rails are more than min width.
# This causes a DRC in the pinv which assumes min width rails. This ensures the output
# contact does not violate spacing to the rail in the NMOS.
@@ -50,16 +51,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 +184,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"]
+8 -3
View File
@@ -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):
"""
@@ -22,6 +22,9 @@ class dff_buf_array(design.design):
dff_buf_array.unique_id += 1
design.design.__init__(self, name)
debug.info(1, "Creating {}".format(self.name))
self.add_comment("rows: {0} cols: {1}".format(rows, columns))
self.add_comment("inv1: {0} inv2: {1}".format(inv1_size, inv2_size))
self.inv1_size = inv1_size
self.inv2_size = inv2_size
@@ -54,7 +57,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 +194,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
+7 -6
View File
@@ -20,6 +20,8 @@ class dff_inv(design.design):
dff_inv.unique_id += 1
design.design.__init__(self, name)
debug.info(1, "Creating {}".format(self.name))
self.add_comment("inv: {0}".format(inv_size))
self.inv_size = inv_size
# This is specifically for SCMOS where the DFF vdd/gnd rails are more than min width.
@@ -55,13 +57,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 +153,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()
+5 -2
View File
@@ -22,6 +22,9 @@ class dff_inv_array(design.design):
dff_inv_array.unique_id += 1
design.design.__init__(self, name)
debug.info(1, "Creating {}".format(self.name))
self.add_comment("rows: {0} cols: {1}".format(rows, columns))
self.add_comment("inv1: {0}".format(inv1_size))
self.inv_size = inv_size
self.create_netlist()
@@ -42,7 +45,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 +192,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
+14 -16
View File
@@ -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):
+9 -11
View File
@@ -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:
+2 -19
View File
@@ -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))
+11 -12
View File
@@ -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,14 +11,11 @@ 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))
self.add_comment("cols: {0} size: {1} bl: {2} br: {3}".format(columns, size, bitcell_bl, bitcell_br))
self.columns = columns
self.size = size
self.bitcell_bl = bitcell_bl
@@ -50,10 +47,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 +106,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
+14 -21
View File
@@ -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)
@@ -621,7 +614,7 @@ class replica_bitline(design.design):
#The delay chain triggers the enable on the replica bitline (rbl). This is used to track the bitline delay whereas this
#model is intended to track every but that. Therefore, the next stage is the inverter after the rbl.
stage2 = self.inv.get_effort_stage(ext_cout, last_stage_is_rise)
stage2 = self.inv.get_stage_effort(ext_cout, last_stage_is_rise)
stage_effort_list.append(stage2)
return stage_effort_list
@@ -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
+9 -10
View File
@@ -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,9 +11,11 @@ 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.add_comment("word_size {0}".format(word_size))
self.add_comment("words_per_row: {0}".format(words_per_row))
self.word_size = word_size
self.words_per_row = words_per_row
@@ -51,17 +54,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 +142,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,13 +14,11 @@ 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.add_comment("cols: {0} word_size: {1} bl: {2} br: {3}".format(columns, word_size, bitcell_bl, bitcell_br))
self.columns = columns
self.word_size = word_size
self.words_per_row = int(self.columns / self.word_size)
@@ -61,7 +59,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 -4
View File
@@ -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):
+17 -12
View File
@@ -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,10 +15,13 @@ 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, cols):
design.design.__init__(self, name)
debug.info(1, "Creating {0}".format(self.name))
self.add_comment("rows: {0} cols: {1}".format(rows, cols))
self.rows = rows
self.cols = cols
self.create_netlist()
if not OPTS.netlist_only:
@@ -53,13 +55,16 @@ 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="pdriver",
fanout=self.cols,
neg_polarity=True)
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)
@@ -224,12 +229,12 @@ class wordline_driver(design.design):
stage_effort_list = []
stage1_cout = self.inv.get_cin()
stage1 = self.nand2.get_effort_stage(stage1_cout, inp_is_rise)
stage1 = self.nand2.get_stage_effort(stage1_cout, inp_is_rise)
stage_effort_list.append(stage1)
last_stage_is_rise = stage1.is_rise
stage2 = self.inv.get_effort_stage(external_cout, last_stage_is_rise)
stage_effort_list.append(stage2)
stage2 = self.inv.get_stage_efforts(external_cout, last_stage_is_rise)
stage_effort_list.extend(stage2)
return stage_effort_list
@@ -237,4 +242,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
+5
View File
@@ -23,3 +23,8 @@ class write_driver(design.design):
self.height = write_driver.height
self.pin_map = write_driver.pin_map
def get_w_en_cin(self):
"""Get the relative capacitance of a single input"""
# This is approximated from SCMOS. It has roughly 5 3x transistor gates.
return 5*3
+11 -9
View File
@@ -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,9 +12,11 @@ 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.add_comment("columns: {0}".format(columns))
self.add_comment("word_size {0}".format(word_size))
self.columns = columns
self.word_size = word_size
@@ -53,17 +56,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 = {}
@@ -134,3 +132,7 @@ class write_driver_array(design.design):
def get_w_en_cin(self):
"""Get the relative capacitance of all the enable connections in the bank"""
#The enable is connected to a nand2 for every row.
return self.driver.get_w_en_cin() * len(self.driver_insts)