mirror of https://github.com/VLSIDA/OpenRAM.git
Change pbuf/pinv to pdriver in control logic.
This commit is contained in:
parent
23718b952f
commit
b58fd03083
|
|
@ -1253,20 +1253,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()
|
||||
|
|
|
|||
|
|
@ -14,20 +14,22 @@ 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.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_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.
|
||||
|
|
@ -82,33 +84,44 @@ class control_logic(design.design):
|
|||
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 = factory.create(module_type="pbuf",
|
||||
size=clock_driver_size,
|
||||
# clk_buf drives a flop for every address and control bit
|
||||
clock_fanout = math.log(self.num_words,2) + math.log(self.words_per_row,2) + self.num_control_signals
|
||||
|
||||
self.clkbuf = factory.create(module_type="pdriver",
|
||||
fanout=clock_fanout,
|
||||
height=dff_height)
|
||||
|
||||
self.add_mod(self.clkbuf)
|
||||
|
||||
self.buf16 = factory.create(module_type="pbuf",
|
||||
size=16,
|
||||
height=dff_height)
|
||||
self.add_mod(self.buf16)
|
||||
# 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)
|
||||
|
||||
self.buf8 = factory.create(module_type="pbuf",
|
||||
size=8,
|
||||
height=dff_height)
|
||||
self.add_mod(self.buf8)
|
||||
|
||||
self.inv = self.inv1 = factory.create(module_type="pinv",
|
||||
# w_en drives every write driver
|
||||
self.w_en_driver = factory.create(module_type="pbuf",
|
||||
size=self.word_size,
|
||||
height=dff_height)
|
||||
self.add_mod(self.w_en_driver)
|
||||
|
||||
# s_en drives every sense amp
|
||||
self.s_en_driver = factory.create(module_type="pbuf",
|
||||
size=8,
|
||||
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.inv1)
|
||||
|
||||
self.inv8 = factory.create(module_type="pinv",
|
||||
size=8,
|
||||
height=dff_height)
|
||||
self.add_mod(self.inv8)
|
||||
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",
|
||||
fanout=8,
|
||||
height=dff_height)
|
||||
self.add_mod(self.p_en_bar_driver)
|
||||
|
||||
if (self.port_type == "rw") or (self.port_type == "r"):
|
||||
delay_stages_heuristic, delay_fanout_heuristic = self.get_heuristic_delay_chain_size()
|
||||
|
|
@ -510,7 +523,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):
|
||||
|
|
@ -580,7 +593,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"])
|
||||
|
||||
|
||||
|
|
@ -620,7 +633,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):
|
||||
|
|
@ -657,7 +670,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"])
|
||||
|
||||
|
||||
|
|
@ -814,7 +827,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.clkbuf.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)
|
||||
|
|
@ -845,17 +858,17 @@ 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
|
||||
|
|
|
|||
|
|
@ -230,7 +230,7 @@ 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
|
||||
|
||||
|
|
|
|||
|
|
@ -614,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
|
||||
|
|
|
|||
|
|
@ -224,11 +224,11 @@ 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)
|
||||
stage2 = self.inv.get_stage_effort(external_cout, last_stage_is_rise)
|
||||
stage_effort_list.append(stage2)
|
||||
|
||||
return stage_effort_list
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -130,3 +130,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)
|
||||
|
|
|
|||
|
|
@ -113,15 +113,15 @@ class pand2(pgate.pgate):
|
|||
inv_delay = self.inv.analytical_delay(slew=nand_delay.slew, load=load)
|
||||
return nand_delay + inv_delay
|
||||
|
||||
def get_output_stage_efforts(self, external_cout, inp_is_rise=False):
|
||||
def get_stage_efforts(self, external_cout, inp_is_rise=False):
|
||||
"""Get the stage efforts of the A or B -> Z path"""
|
||||
stage_effort_list = []
|
||||
stage1_cout = self.inv.get_cin()
|
||||
stage1 = self.nand.get_effort_stage(stage1_cout, inp_is_rise)
|
||||
stage1 = self.nand.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)
|
||||
stage2 = self.inv.get_stage_effort(external_cout, last_stage_is_rise)
|
||||
stage_effort_list.append(stage2)
|
||||
|
||||
return stage_effort_list
|
||||
|
|
|
|||
|
|
@ -115,15 +115,15 @@ class pbuf(pgate.pgate):
|
|||
inv2_delay = self.inv2.analytical_delay(slew=inv1_delay.slew, load=load)
|
||||
return inv1_delay + inv2_delay
|
||||
|
||||
def get_output_stage_efforts(self, external_cout, inp_is_rise=False):
|
||||
def get_stage_efforts(self, external_cout, inp_is_rise=False):
|
||||
"""Get the stage efforts of the A -> Z path"""
|
||||
stage_effort_list = []
|
||||
stage1_cout = self.inv2.get_cin()
|
||||
stage1 = self.inv1.get_effort_stage(stage1_cout, inp_is_rise)
|
||||
stage1 = self.inv1.get_stage_effort(stage1_cout, inp_is_rise)
|
||||
stage_effort_list.append(stage1)
|
||||
last_stage_is_rise = stage1.is_rise
|
||||
|
||||
stage2 = self.inv2.get_effort_stage(external_cout, last_stage_is_rise)
|
||||
stage2 = self.inv2.get_stage_effort(external_cout, last_stage_is_rise)
|
||||
stage_effort_list.append(stage2)
|
||||
|
||||
return stage_effort_list
|
||||
|
|
|
|||
|
|
@ -11,16 +11,16 @@ class pdriver(pgate.pgate):
|
|||
"""
|
||||
This instantiates an even or odd number of inverters sized for driving a load.
|
||||
"""
|
||||
def __init__(self, name, neg_polarity=False, fanout_size=8, size_list = [], height=None):
|
||||
def __init__(self, name, neg_polarity=False, fanout=0, size_list=None, height=None):
|
||||
|
||||
self.stage_effort = 4
|
||||
self.height = height
|
||||
self.neg_polarity = neg_polarity
|
||||
self.size_list = size_list
|
||||
self.fanout_size = fanout_size
|
||||
self.fanout = fanout
|
||||
|
||||
if len(self.size_list) > 0 and (self.fanout_size != 8 or self.neg_polarity):
|
||||
debug.error("Cannot specify both size_list and neg_polarity or fanout_size.", -1)
|
||||
if self.size_list and (self.fanout != 0 or self.neg_polarity):
|
||||
debug.error("Cannot specify both size_list and neg_polarity or fanout.", -1)
|
||||
|
||||
pgate.pgate.__init__(self, name, height)
|
||||
debug.info(1, "Creating {}".format(self.name))
|
||||
|
|
@ -33,14 +33,14 @@ class pdriver(pgate.pgate):
|
|||
|
||||
def compute_sizes(self):
|
||||
# size_list specified
|
||||
if len(self.size_list) > 0:
|
||||
if self.size_list:
|
||||
if not len(self.size_list) % 2:
|
||||
neg_polarity = True
|
||||
self.num_inv = len(self.size_list)
|
||||
else:
|
||||
# find the number of stages
|
||||
#fanout_size is a unit inverter fanout, not a capacitance so c_in=1
|
||||
num_stages = max(1,int(round(log(self.fanout_size)/log(4))))
|
||||
#fanout is a unit inverter fanout, not a capacitance so c_in=1
|
||||
num_stages = max(1,int(round(log(self.fanout)/log(4))))
|
||||
|
||||
# find inv_num and compute sizes
|
||||
if self.neg_polarity:
|
||||
|
|
@ -53,42 +53,42 @@ class pdriver(pgate.pgate):
|
|||
self.same_polarity(num_stages=num_stages)
|
||||
else:
|
||||
self.diff_polarity(num_stages=num_stages)
|
||||
|
||||
|
||||
|
||||
def same_polarity(self, num_stages):
|
||||
self.calc_size_list = []
|
||||
self.size_list = []
|
||||
self.num_inv = num_stages
|
||||
# compute sizes
|
||||
fanout_size_prev = self.fanout_size
|
||||
fanout_prev = self.fanout
|
||||
for x in range(self.num_inv-1,-1,-1):
|
||||
fanout_size_prev = int(round(fanout_size_prev/self.stage_effort))
|
||||
self.calc_size_list.append(fanout_size_prev)
|
||||
fanout_prev = max(round(fanout_prev/self.stage_effort),1)
|
||||
self.size_list.append(fanout_prev)
|
||||
self.size_list.reverse()
|
||||
|
||||
|
||||
def diff_polarity(self, num_stages):
|
||||
self.calc_size_list = []
|
||||
self.size_list = []
|
||||
# find which delay is smaller
|
||||
if (num_stages > 1):
|
||||
delay_below = ((num_stages-1)*(self.fanout_size**(1/num_stages-1))) + num_stages-1
|
||||
delay_above = ((num_stages+1)*(self.fanout_size**(1/num_stages+1))) + num_stages+1
|
||||
delay_below = ((num_stages-1)*(self.fanout**(1/num_stages-1))) + num_stages-1
|
||||
delay_above = ((num_stages+1)*(self.fanout**(1/num_stages+1))) + num_stages+1
|
||||
if (delay_above < delay_below):
|
||||
# recompute stage_effort for this delay
|
||||
self.num_inv = num_stages+1
|
||||
polarity_stage_effort = self.fanout_size**(1/self.num_inv)
|
||||
polarity_stage_effort = self.fanout**(1/self.num_inv)
|
||||
else:
|
||||
self.num_inv = num_stages-1
|
||||
polarity_stage_effort = self.fanout_size**(1/self.num_inv)
|
||||
polarity_stage_effort = self.fanout**(1/self.num_inv)
|
||||
else: # num_stages is 1, can't go to 0
|
||||
self.num_inv = num_stages+1
|
||||
polarity_stage_effort = self.fanout_size**(1/self.num_inv)
|
||||
polarity_stage_effort = self.fanout**(1/self.num_inv)
|
||||
|
||||
|
||||
# compute sizes
|
||||
fanout_size_prev = self.fanout_size
|
||||
fanout_prev = self.fanout
|
||||
for x in range(self.num_inv-1,-1,-1):
|
||||
fanout_size_prev = int(round(fanout_size_prev/polarity_stage_effort))
|
||||
self.calc_size_list.append(fanout_size_prev)
|
||||
|
||||
fanout_prev = round(fanout_prev/polarity_stage_effort)
|
||||
self.size_list.append(fanout_prev)
|
||||
self.size_list.reverse()
|
||||
|
||||
def create_netlist(self):
|
||||
inv_list = []
|
||||
|
|
@ -115,16 +115,10 @@ class pdriver(pgate.pgate):
|
|||
|
||||
def add_modules(self):
|
||||
self.inv_list = []
|
||||
if len(self.size_list) > 0: # size list specified
|
||||
for x in range(len(self.size_list)):
|
||||
temp_inv = factory.create(module_type="pinv", size=self.size_list[x], height=self.height)
|
||||
self.inv_list.append(temp_inv)
|
||||
self.add_mod(self.inv_list[x])
|
||||
else: # find inv sizes
|
||||
for x in range(len(self.calc_size_list)):
|
||||
temp_inv = factory.create(module_type="pinv", size=self.calc_size_list[x], height=self.height)
|
||||
self.inv_list.append(temp_inv)
|
||||
self.add_mod(self.inv_list[x])
|
||||
for size in self.size_list:
|
||||
temp_inv = factory.create(module_type="pinv", size=size, height=self.height)
|
||||
self.inv_list.append(temp_inv)
|
||||
self.add_mod(temp_inv)
|
||||
|
||||
|
||||
def create_insts(self):
|
||||
|
|
@ -226,3 +220,24 @@ class pdriver(pgate.pgate):
|
|||
return delay
|
||||
|
||||
|
||||
def get_stage_efforts(self, external_cout, inp_is_rise=False):
|
||||
"""Get the stage efforts of the A -> Z path"""
|
||||
|
||||
cout_list = {}
|
||||
for prev_inv,inv in zip(self.inv_list, self.inv_list[1:]):
|
||||
cout_list[prev_inv]=inv.get_cin()
|
||||
|
||||
cout_list[self.inv_list[-1]]=external_cout
|
||||
|
||||
stage_effort_list = []
|
||||
last_inp_is_rise = inp_is_rise
|
||||
for inv in self.inv_list:
|
||||
stage = inv.get_stage_effort(cout_list[inv], last_inp_is_rise)
|
||||
stage_effort_list.append(stage)
|
||||
last_inp_is_rise = stage.is_rise
|
||||
|
||||
return stage_effort_list
|
||||
|
||||
def get_cin(self):
|
||||
"""Returns the relative capacitance of the input"""
|
||||
return self.inv_list[0].get_cin()
|
||||
|
|
|
|||
|
|
@ -286,7 +286,7 @@ class pinv(pgate.pgate):
|
|||
"""Return the capacitance of the gate connection in generic capacitive units relative to the minimum width of a transistor"""
|
||||
return self.nmos_size + self.pmos_size
|
||||
|
||||
def get_effort_stage(self, cout, inp_is_rise=True):
|
||||
def get_stage_effort(self, cout, inp_is_rise=True):
|
||||
"""Returns an object representing the parameters for delay in tau units.
|
||||
Optional is_rise refers to the input direction rise/fall. Input inverted by this stage.
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -186,11 +186,11 @@ class pinvbuf(design.design):
|
|||
"""Get the stage efforts of the clk -> clk_buf path"""
|
||||
stage_effort_list = []
|
||||
stage1_cout = self.inv1.get_cin() + self.inv2.get_cin()
|
||||
stage1 = self.inv.get_effort_stage(stage1_cout, inp_is_rise)
|
||||
stage1 = self.inv.get_stage_effort(stage1_cout, inp_is_rise)
|
||||
stage_effort_list.append(stage1)
|
||||
last_stage_is_rise = stage1.is_rise
|
||||
|
||||
stage2 = self.inv2.get_effort_stage(external_cout, last_stage_is_rise)
|
||||
stage2 = self.inv2.get_stage_effort(external_cout, last_stage_is_rise)
|
||||
stage_effort_list.append(stage2)
|
||||
|
||||
return stage_effort_list
|
||||
|
|
@ -200,16 +200,16 @@ class pinvbuf(design.design):
|
|||
#After (almost) every stage, the direction of the signal inverts.
|
||||
stage_effort_list = []
|
||||
stage1_cout = self.inv1.get_cin() + self.inv2.get_cin()
|
||||
stage1 = self.inv.get_effort_stage(stage1_cout, inp_is_rise)
|
||||
stage1 = self.inv.get_stage_effort(stage1_cout, inp_is_rise)
|
||||
stage_effort_list.append(stage1)
|
||||
last_stage_is_rise = stage_effort_list[-1].is_rise
|
||||
|
||||
stage2_cout = self.inv2.get_cin()
|
||||
stage2 = self.inv1.get_effort_stage(stage2_cout, last_stage_is_rise)
|
||||
stage2 = self.inv1.get_stage_effort(stage2_cout, last_stage_is_rise)
|
||||
stage_effort_list.append(stage2)
|
||||
last_stage_is_rise = stage_effort_list[-1].is_rise
|
||||
|
||||
stage3 = self.inv2.get_effort_stage(external_cout, last_stage_is_rise)
|
||||
stage3 = self.inv2.get_stage_effort(external_cout, last_stage_is_rise)
|
||||
stage_effort_list.append(stage3)
|
||||
|
||||
return stage_effort_list
|
||||
|
|
|
|||
|
|
@ -252,7 +252,7 @@ class pnand2(pgate.pgate):
|
|||
"""Return the relative input capacitance of a single input"""
|
||||
return self.nmos_size+self.pmos_size
|
||||
|
||||
def get_effort_stage(self, cout, inp_is_rise=True):
|
||||
def get_stage_effort(self, cout, inp_is_rise=True):
|
||||
"""Returns an object representing the parameters for delay in tau units.
|
||||
Optional is_rise refers to the input direction rise/fall. Input inverted by this stage.
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -264,7 +264,7 @@ class pnand3(pgate.pgate):
|
|||
"""Return the relative input capacitance of a single input"""
|
||||
return self.nmos_size+self.pmos_size
|
||||
|
||||
def get_effort_stage(self, cout, inp_is_rise=True):
|
||||
def get_stage_effort(self, cout, inp_is_rise=True):
|
||||
"""Returns an object representing the parameters for delay in tau units.
|
||||
Optional is_rise refers to the input direction rise/fall. Input inverted by this stage.
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -279,20 +279,23 @@ class sram_base(design, verilog, lef):
|
|||
|
||||
# Create the control logic module for each port type
|
||||
if len(self.readwrite_ports)>0:
|
||||
self.control_logic_rw = self.mod_control_logic(num_rows=self.num_rows,
|
||||
self.control_logic_rw = self.mod_control_logic(num_rows=self.num_rows,
|
||||
words_per_row=self.words_per_row,
|
||||
word_size=self.word_size,
|
||||
sram=self,
|
||||
port_type="rw")
|
||||
self.add_mod(self.control_logic_rw)
|
||||
if len(self.writeonly_ports)>0:
|
||||
self.control_logic_w = self.mod_control_logic(num_rows=self.num_rows,
|
||||
words_per_row=self.words_per_row,
|
||||
word_size=self.word_size,
|
||||
sram=self,
|
||||
port_type="w")
|
||||
self.add_mod(self.control_logic_w)
|
||||
if len(self.readonly_ports)>0:
|
||||
self.control_logic_r = self.mod_control_logic(num_rows=self.num_rows,
|
||||
words_per_row=self.words_per_row,
|
||||
word_size=self.word_size,
|
||||
sram=self,
|
||||
port_type="r")
|
||||
self.add_mod(self.control_logic_r)
|
||||
|
|
@ -512,25 +515,30 @@ class sram_base(design, verilog, lef):
|
|||
|
||||
def get_wl_en_cin(self):
|
||||
"""Gets the capacitive load the of clock (clk_buf) for the sram"""
|
||||
#As clk_buf is an output of the control logic. The cap for that module is not determined here.
|
||||
#Only the wordline drivers within the bank use this signal
|
||||
bank_clk_cin = self.bank.get_wl_en_cin()
|
||||
|
||||
return bank_clk_cin
|
||||
|
||||
return self.bank.get_wl_en_cin()
|
||||
|
||||
def get_w_en_cin(self):
|
||||
"""Gets the capacitive load the of write enable (w_en) for the sram"""
|
||||
#Only the write drivers within the bank use this signal
|
||||
return self.bank.get_w_en_cin()
|
||||
|
||||
|
||||
def get_p_en_bar_cin(self):
|
||||
"""Gets the capacitive load the of precharge enable (p_en_bar) for the sram"""
|
||||
#Only the precharges within the bank use this signal
|
||||
return self.bank.get_p_en_bar_cin()
|
||||
|
||||
def get_clk_bar_cin(self):
|
||||
"""Gets the capacitive load the of clock (clk_buf_bar) for the sram"""
|
||||
#As clk_buf_bar is an output of the control logic. The cap for that module is not determined here.
|
||||
#Only the precharge cells use this signal (other than the control logic)
|
||||
bank_clk_cin = self.bank.get_clk_bar_cin()
|
||||
return bank_clk_cin
|
||||
return self.bank.get_clk_bar_cin()
|
||||
|
||||
def get_sen_cin(self):
|
||||
"""Gets the capacitive load the of sense amp enable for the sram"""
|
||||
#As clk_buf_bar is an output of the control logic. The cap for that module is not determined here.
|
||||
#Only the sense_amps use this signal (other than the control logic)
|
||||
bank_sen_cin = self.bank.get_sen_cin()
|
||||
return bank_sen_cin
|
||||
return self.bank.get_sen_cin()
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -22,22 +22,22 @@ class pdriver_test(openram_test):
|
|||
|
||||
debug.info(2, "Testing inverter/buffer 4x 8x")
|
||||
# a tests the error message for specifying conflicting conditions
|
||||
#a = pdriver.pdriver(fanout_size = 4,size_list = [1,2,4,8])
|
||||
#a = pdriver.pdriver(fanout = 4,size_list = [1,2,4,8])
|
||||
#self.local_check(a)
|
||||
|
||||
b = pdriver.pdriver(name="pdriver1", size_list = [1,2,4,8])
|
||||
self.local_check(b)
|
||||
|
||||
c = pdriver.pdriver(name="pdriver2", fanout_size = 50)
|
||||
c = pdriver.pdriver(name="pdriver2", fanout = 50)
|
||||
self.local_check(c)
|
||||
|
||||
d = pdriver.pdriver(name="pdriver3", fanout_size = 50, neg_polarity = True)
|
||||
d = pdriver.pdriver(name="pdriver3", fanout = 50, neg_polarity = True)
|
||||
self.local_check(d)
|
||||
|
||||
e = pdriver.pdriver(name="pdriver4", fanout_size = 64)
|
||||
e = pdriver.pdriver(name="pdriver4", fanout = 64)
|
||||
self.local_check(e)
|
||||
|
||||
f = pdriver.pdriver(name="pdriver5", fanout_size = 64, neg_polarity = True)
|
||||
f = pdriver.pdriver(name="pdriver5", fanout = 64, neg_polarity = True)
|
||||
self.local_check(f)
|
||||
|
||||
globals.end_openram()
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ class control_logic_test(openram_test):
|
|||
|
||||
# check control logic for single port
|
||||
debug.info(1, "Testing sample for control_logic")
|
||||
a = control_logic.control_logic(num_rows=128, words_per_row=1)
|
||||
a = control_logic.control_logic(num_rows=128, words_per_row=1, word_size=32)
|
||||
self.local_check(a)
|
||||
|
||||
# check control logic for multi-port
|
||||
|
|
@ -31,7 +31,7 @@ class control_logic_test(openram_test):
|
|||
OPTS.num_r_ports = 0
|
||||
|
||||
debug.info(1, "Testing sample for control_logic for multiport")
|
||||
a = control_logic.control_logic(num_rows=128, words_per_row=1)
|
||||
a = control_logic.control_logic(num_rows=128, words_per_row=1, word_size=8)
|
||||
self.local_check(a)
|
||||
|
||||
# Check port specific control logic
|
||||
|
|
@ -40,15 +40,15 @@ class control_logic_test(openram_test):
|
|||
OPTS.num_r_ports = 1
|
||||
|
||||
debug.info(1, "Testing sample for control_logic for multiport, only write control logic")
|
||||
a = control_logic.control_logic(num_rows=128, words_per_row=1, port_type="rw")
|
||||
a = control_logic.control_logic(num_rows=128, words_per_row=1, word_size=8, port_type="rw")
|
||||
self.local_check(a)
|
||||
|
||||
debug.info(1, "Testing sample for control_logic for multiport, only write control logic")
|
||||
a = control_logic.control_logic(num_rows=128, words_per_row=1, port_type="w")
|
||||
a = control_logic.control_logic(num_rows=128, words_per_row=1, word_size=8, port_type="w")
|
||||
self.local_check(a)
|
||||
|
||||
debug.info(1, "Testing sample for control_logic for multiport, only read control logic")
|
||||
a = control_logic.control_logic(num_rows=128, words_per_row=1, port_type="r")
|
||||
a = control_logic.control_logic(num_rows=128, words_per_row=1, word_size=8, port_type="r")
|
||||
self.local_check(a)
|
||||
|
||||
globals.end_openram()
|
||||
|
|
|
|||
Loading…
Reference in New Issue