mirror of https://github.com/VLSIDA/OpenRAM.git
Changed s_en delay calculation based recent control logic changes.
This commit is contained in:
parent
0c3c58011b
commit
ea55bda493
|
|
@ -19,7 +19,7 @@ class logical_effort():
|
||||||
self.is_rise = out_is_rise
|
self.is_rise = out_is_rise
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "g = " + str(self.logical_effort) + ", h = " + str(self.eletrical_effort) + ", p = " + str(self.parasitic_scale)+"*pinv"
|
return "g=" + str(self.logical_effort) + ", h=" + str(self.eletrical_effort) + ", p=" + str(self.parasitic_scale)+"*pinv, rise_delay="+str(self.is_rise)
|
||||||
|
|
||||||
def get_stage_effort(self):
|
def get_stage_effort(self):
|
||||||
return self.logical_effort*self.eletrical_effort
|
return self.logical_effort*self.eletrical_effort
|
||||||
|
|
@ -37,8 +37,10 @@ def calculate_relative_delay(stage_effort_list, pinv=parameter["min_inv_para_del
|
||||||
|
|
||||||
def calculate_relative_rise_fall_delays(stage_effort_list, pinv=parameter["min_inv_para_delay"]):
|
def calculate_relative_rise_fall_delays(stage_effort_list, pinv=parameter["min_inv_para_delay"]):
|
||||||
"""Calculates the rise/fall delays of a given delay path made of a list of logical effort objects."""
|
"""Calculates the rise/fall delays of a given delay path made of a list of logical effort objects."""
|
||||||
|
debug.info(2, "Calculating rise/fall relative delays")
|
||||||
total_rise_delay, total_fall_delay = 0,0
|
total_rise_delay, total_fall_delay = 0,0
|
||||||
for stage in stage_effort_list:
|
for stage in stage_effort_list:
|
||||||
|
debug.info(3, stage)
|
||||||
if stage.is_rise:
|
if stage.is_rise:
|
||||||
total_rise_delay += stage.get_stage_delay(pinv)
|
total_rise_delay += stage.get_stage_delay(pinv)
|
||||||
else:
|
else:
|
||||||
|
|
|
||||||
|
|
@ -1254,10 +1254,10 @@ class bank(design.design):
|
||||||
|
|
||||||
return stage_effort_list
|
return stage_effort_list
|
||||||
|
|
||||||
def get_clk_cin(self):
|
def get_wl_en_cin(self):
|
||||||
"""Get the relative capacitance of all the clk connections in the bank"""
|
"""Get the relative capacitance of all the clk connections in the bank"""
|
||||||
#Current bank only uses clock (clk_buf) as an enable for the wordline driver.
|
#wl_en only used in the wordline driver.
|
||||||
total_clk_cin = self.wordline_driver.get_clk_cin()
|
total_clk_cin = self.wordline_driver.get_wl_en_cin()
|
||||||
return total_clk_cin
|
return total_clk_cin
|
||||||
|
|
||||||
def get_clk_bar_cin(self):
|
def get_clk_bar_cin(self):
|
||||||
|
|
|
||||||
|
|
@ -30,9 +30,11 @@ class control_logic(design.design):
|
||||||
self.words_per_row = words_per_row
|
self.words_per_row = words_per_row
|
||||||
self.port_type = port_type
|
self.port_type = port_type
|
||||||
|
|
||||||
|
self.enable_delay_chain_resizing = False
|
||||||
|
|
||||||
#This is needed to resize the delay chain. Likely to be changed at some point.
|
#This is needed to resize the delay chain. Likely to be changed at some point.
|
||||||
#self.sram=sram
|
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.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.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.
|
self.parasitic_inv_delay = parameter["min_inv_para_delay"] #Keeping 0 for now until further testing.
|
||||||
|
|
||||||
|
|
@ -112,7 +114,9 @@ class control_logic(design.design):
|
||||||
bitcell_loads = int(math.ceil(self.num_rows / 2.0))
|
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 = replica_bitline([delay_fanout_heuristic]*delay_stages_heuristic, bitcell_loads, name="replica_bitline_"+self.port_type)
|
||||||
|
|
||||||
if self.sram != None and not self.does_sen_total_timing_match(): #check condition based on resizing method
|
self.set_sen_wl_delays()
|
||||||
|
|
||||||
|
if self.sram != None and self.enable_delay_chain_resizing and not self.does_sen_total_timing_match(): #check condition based on resizing method
|
||||||
#This resizes to match fall and rise delays, can make the delay chain weird sizes.
|
#This resizes to match fall and rise delays, can make the delay chain weird sizes.
|
||||||
# stage_list = self.get_dynamic_delay_fanout_list(delay_stages_heuristic, delay_fanout_heuristic)
|
# stage_list = self.get_dynamic_delay_fanout_list(delay_stages_heuristic, delay_fanout_heuristic)
|
||||||
# self.replica_bitline = replica_bitline(stage_list, bitcell_loads, name="replica_bitline_resized_"+self.port_type)
|
# self.replica_bitline = replica_bitline(stage_list, bitcell_loads, name="replica_bitline_resized_"+self.port_type)
|
||||||
|
|
@ -794,17 +798,16 @@ class control_logic(design.design):
|
||||||
|
|
||||||
|
|
||||||
def determine_wordline_stage_efforts(self):
|
def determine_wordline_stage_efforts(self):
|
||||||
"""Follows the clock signal to the clk_buf signal to the wordline signal for the total path efforts"""
|
"""Follows the gated_clk_bar -> wl_en -> wordline signal for the total path efforts"""
|
||||||
stage_effort_list = []
|
stage_effort_list = []
|
||||||
|
|
||||||
#Initial direction of clock signal for this path
|
#Initial direction of gated_clk_bar signal for this path
|
||||||
is_clk_rise = False
|
is_clk_bar_rise = True
|
||||||
|
|
||||||
#Calculate the load on clk_buf within the module and add it to external load
|
#Calculate the load on wl_en within the module and add it to external load
|
||||||
internal_cout = self.ctrl_dff_array.get_clk_cin()
|
external_cout = self.sram.get_wl_en_cin()
|
||||||
external_cout = self.sram.get_clk_cin()
|
|
||||||
#First stage is the clock buffer
|
#First stage is the clock buffer
|
||||||
stage_effort_list += self.clkbuf.determine_z_stage_efforts(internal_cout+external_cout, is_clk_rise)
|
stage_effort_list += self.clkbuf.get_output_stage_efforts(external_cout, is_clk_bar_rise)
|
||||||
last_stage_is_rise = stage_effort_list[-1].is_rise
|
last_stage_is_rise = stage_effort_list[-1].is_rise
|
||||||
|
|
||||||
#Then ask the sram for the other path delays (from the bank)
|
#Then ask the sram for the other path delays (from the bank)
|
||||||
|
|
@ -824,56 +827,28 @@ class control_logic(design.design):
|
||||||
return clk_to_sen_rise, clk_to_sen_fall
|
return clk_to_sen_rise, clk_to_sen_fall
|
||||||
|
|
||||||
def determine_sa_enable_stage_efforts(self):
|
def determine_sa_enable_stage_efforts(self):
|
||||||
"""Follows the clock signal to the sense amp enable signal adding each stages stage effort to a list"""
|
"""Follows the gated_clk_bar signal to the sense amp enable signal adding each stages stage effort to a list"""
|
||||||
stage_effort_list = []
|
stage_effort_list = []
|
||||||
#Calculate the load on clk_buf_bar
|
#Calculate the load on clk_buf_bar
|
||||||
int_clk_buf_cout = self.get_clk_buf_bar_cin()
|
|
||||||
ext_clk_buf_cout = self.sram.get_clk_bar_cin()
|
ext_clk_buf_cout = self.sram.get_clk_bar_cin()
|
||||||
|
|
||||||
#Initial direction of clock signal for this path
|
#Initial direction of clock signal for this path
|
||||||
is_clk_rise = False
|
is_clk_bar_rise = True
|
||||||
|
|
||||||
#First stage is the clock buffer
|
#First stage, gated_clk_bar -(and2)-> rbl_in
|
||||||
stage1 = self.clkbuf.determine_clk_buf_bar_stage_efforts(int_clk_buf_cout+ext_clk_buf_cout, is_clk_rise)
|
stage1_cout = self.replica_bitline.get_en_cin()
|
||||||
stage_effort_list += stage1
|
stage_effort_list += self.and2.get_output_stage_efforts(stage1_cout, is_clk_bar_rise)
|
||||||
last_stage_rise = stage_effort_list[-1].is_rise
|
last_stage_rise = stage_effort_list[-1].is_rise
|
||||||
|
|
||||||
#nand2 stage
|
#Replica bitline stage, rbl_in -(rbl)-> pre_s_en
|
||||||
stage2_cout = self.inv1.get_cin()
|
stage2_cout = self.buf8.get_cin()
|
||||||
stage2 = self.nand2.get_effort_stage(stage2_cout, last_stage_rise)
|
stage_effort_list += self.replica_bitline.determine_sen_stage_efforts(stage2_cout, last_stage_rise)
|
||||||
stage_effort_list.append(stage2)
|
|
||||||
last_stage_rise = stage_effort_list[-1].is_rise
|
last_stage_rise = stage_effort_list[-1].is_rise
|
||||||
|
|
||||||
#inverter stage
|
#buffer stage, pre_s_en -(buffer)-> s_en
|
||||||
stage3_cout = self.replica_bitline.get_en_cin()
|
stage3_cout = self.sram.get_sen_cin()
|
||||||
stage3 = self.inv1.get_effort_stage(stage3_cout, last_stage_rise)
|
stage_effort_list += self.buf8.get_output_stage_efforts(stage3_cout, last_stage_rise)
|
||||||
stage_effort_list.append(stage3)
|
|
||||||
last_stage_rise = stage_effort_list[-1].is_rise
|
last_stage_rise = stage_effort_list[-1].is_rise
|
||||||
|
|
||||||
#Replica bitline stage
|
|
||||||
stage4_cout = self.inv2.get_cin()
|
|
||||||
stage4 = self.replica_bitline.determine_sen_stage_efforts(stage4_cout, last_stage_rise)
|
|
||||||
stage_effort_list += stage4
|
|
||||||
last_stage_rise = stage_effort_list[-1].is_rise
|
|
||||||
|
|
||||||
#inverter (inv2) stage
|
|
||||||
stage5_cout = self.inv8.get_cin()
|
|
||||||
stage5 = self.inv2.get_effort_stage(stage5_cout, last_stage_rise)
|
|
||||||
stage_effort_list.append(stage5)
|
|
||||||
last_stage_rise = stage_effort_list[-1].is_rise
|
|
||||||
|
|
||||||
#inverter (inv8) stage, s_en output
|
|
||||||
clk_sen_cout = self.sram.get_sen_cin()
|
|
||||||
stage6 = self.inv8.get_effort_stage(clk_sen_cout, last_stage_rise)
|
|
||||||
stage_effort_list.append(stage6)
|
|
||||||
return stage_effort_list
|
return stage_effort_list
|
||||||
|
|
||||||
def get_clk_buf_bar_cin(self):
|
|
||||||
"""Get the relative capacitance off the clk_buf_bar signal internal to the control logic"""
|
|
||||||
we_nand_cin = self.nand2.get_cin()
|
|
||||||
if self.port_type == "rw":
|
|
||||||
nand_mod = self.nand3
|
|
||||||
else:
|
|
||||||
nand_mod = self.nand2
|
|
||||||
sen_nand_cin = nand_mod.get_cin()
|
|
||||||
return we_nand_cin + sen_nand_cin
|
|
||||||
|
|
@ -627,6 +627,8 @@ class replica_bitline(design.design):
|
||||||
return stage_effort_list
|
return stage_effort_list
|
||||||
|
|
||||||
def get_delayed_en_cin(self):
|
def get_delayed_en_cin(self):
|
||||||
|
"""Get the fanout capacitance (relative) of the delayed enable from the delay chain."""
|
||||||
access_tx_cin = self.access_tx.get_cin()
|
access_tx_cin = self.access_tx.get_cin()
|
||||||
rbc_cin = self.replica_bitcell.get_wl_cin()
|
rbc_cin = self.replica_bitcell.get_wl_cin()
|
||||||
return access_tx_cin + rbc_cin
|
return access_tx_cin + rbc_cin
|
||||||
|
|
||||||
|
|
@ -222,23 +222,19 @@ class wordline_driver(design.design):
|
||||||
def determine_wordline_stage_efforts(self, external_cout, inp_is_rise=True):
|
def determine_wordline_stage_efforts(self, external_cout, inp_is_rise=True):
|
||||||
"""Follows the clk_buf to a wordline signal adding each stages stage effort to a list"""
|
"""Follows the clk_buf to a wordline signal adding each stages stage effort to a list"""
|
||||||
stage_effort_list = []
|
stage_effort_list = []
|
||||||
stage1_cout = self.nand2.get_cin()
|
|
||||||
stage1 = self.inv_no_output.get_effort_stage(stage1_cout, inp_is_rise)
|
stage1_cout = self.inv.get_cin()
|
||||||
|
stage1 = self.nand2.get_effort_stage(stage1_cout, inp_is_rise)
|
||||||
stage_effort_list.append(stage1)
|
stage_effort_list.append(stage1)
|
||||||
last_stage_is_rise = stage1.is_rise
|
last_stage_is_rise = stage1.is_rise
|
||||||
|
|
||||||
stage2_cout = self.inv.get_cin()
|
stage2 = self.inv.get_effort_stage(external_cout, last_stage_is_rise)
|
||||||
stage2 = self.nand2.get_effort_stage(stage2_cout, last_stage_is_rise)
|
|
||||||
stage_effort_list.append(stage2)
|
stage_effort_list.append(stage2)
|
||||||
last_stage_is_rise = stage2.is_rise
|
|
||||||
|
|
||||||
stage3 = self.inv.get_effort_stage(external_cout, last_stage_is_rise)
|
|
||||||
stage_effort_list.append(stage3)
|
|
||||||
|
|
||||||
return stage_effort_list
|
return stage_effort_list
|
||||||
|
|
||||||
def get_clk_cin(self):
|
def get_wl_en_cin(self):
|
||||||
"""Get the relative capacitance of all the clk connections in the bank"""
|
"""Get the relative capacitance of all the enable connections in the bank"""
|
||||||
#Clock is connected as an input to 1 inverter per row
|
#The enable is connected to a nand2 for every row.
|
||||||
total_cin = self.inv_no_output.get_cin() * self.rows
|
total_cin = self.nand2.get_cin() * self.rows
|
||||||
return total_cin
|
return total_cin
|
||||||
|
|
@ -125,4 +125,15 @@ class pand2(pgate.pgate):
|
||||||
inv_delay = self.inv.analytical_delay(slew=nand_delay.slew, load=load)
|
inv_delay = self.inv.analytical_delay(slew=nand_delay.slew, load=load)
|
||||||
return nand_delay + inv_delay
|
return nand_delay + inv_delay
|
||||||
|
|
||||||
|
def get_output_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)
|
||||||
|
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)
|
||||||
|
|
||||||
|
return stage_effort_list
|
||||||
|
|
|
||||||
|
|
@ -125,7 +125,7 @@ class pbuf(pgate.pgate):
|
||||||
inv2_delay = self.inv2.analytical_delay(slew=inv1_delay.slew, load=load)
|
inv2_delay = self.inv2.analytical_delay(slew=inv1_delay.slew, load=load)
|
||||||
return inv1_delay + inv2_delay
|
return inv1_delay + inv2_delay
|
||||||
|
|
||||||
def determine_z_stage_efforts(self, external_cout, inp_is_rise=False):
|
def get_output_stage_efforts(self, external_cout, inp_is_rise=False):
|
||||||
"""Get the stage efforts of the A -> Z path"""
|
"""Get the stage efforts of the A -> Z path"""
|
||||||
stage_effort_list = []
|
stage_effort_list = []
|
||||||
stage1_cout = self.inv2.get_cin()
|
stage1_cout = self.inv2.get_cin()
|
||||||
|
|
@ -137,3 +137,8 @@ class pbuf(pgate.pgate):
|
||||||
stage_effort_list.append(stage2)
|
stage_effort_list.append(stage2)
|
||||||
|
|
||||||
return stage_effort_list
|
return stage_effort_list
|
||||||
|
|
||||||
|
def get_cin(self):
|
||||||
|
"""Returns the relative capacitance of the input"""
|
||||||
|
input_cin = self.inv1.get_cin()
|
||||||
|
return input_cin
|
||||||
|
|
@ -491,17 +491,13 @@ class sram_base(design):
|
||||||
|
|
||||||
return stage_effort_list
|
return stage_effort_list
|
||||||
|
|
||||||
def get_clk_cin(self):
|
def get_wl_en_cin(self):
|
||||||
"""Gets the capacitive load the of clock (clk_buf) for the sram"""
|
"""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.
|
#As clk_buf is an output of the control logic. The cap for that module is not determined here.
|
||||||
row_addr_clk_cin = self.row_addr_dff.get_clk_cin()
|
#Only the wordline drivers within the bank use this signal
|
||||||
data_clk_cin = self.data_dff.get_clk_cin()
|
bank_clk_cin = self.bank.get_wl_en_cin()
|
||||||
col_addr_clk_cin = 0
|
|
||||||
if self.col_addr_size > 0:
|
|
||||||
col_addr_clk_cin = self.col_addr_dff.get_clk_cin()
|
|
||||||
bank_clk_cin = self.bank.get_clk_cin()
|
|
||||||
|
|
||||||
return row_addr_clk_cin + data_clk_cin + col_addr_clk_cin + bank_clk_cin
|
return bank_clk_cin
|
||||||
|
|
||||||
def get_clk_bar_cin(self):
|
def get_clk_bar_cin(self):
|
||||||
"""Gets the capacitive load the of clock (clk_buf_bar) for the sram"""
|
"""Gets the capacitive load the of clock (clk_buf_bar) for the sram"""
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ import globals
|
||||||
from globals import OPTS
|
from globals import OPTS
|
||||||
import debug
|
import debug
|
||||||
|
|
||||||
@unittest.skip("SKIPPING 22_psram_1bank_2mux_1rw_1r_1w_func_test, third port reads are broken?")
|
#@unittest.skip("SKIPPING 22_psram_1bank_2mux_1rw_1r_1w_func_test, third port reads are broken?")
|
||||||
class psram_1bank_2mux_1rw_1r_1w_func_test(openram_test):
|
class psram_1bank_2mux_1rw_1r_1w_func_test(openram_test):
|
||||||
|
|
||||||
def runTest(self):
|
def runTest(self):
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ import globals
|
||||||
from globals import OPTS
|
from globals import OPTS
|
||||||
import debug
|
import debug
|
||||||
|
|
||||||
@unittest.skip("SKIPPING 22_psram_1bank_4mux_func_test, third port reads are broken?")
|
#@unittest.skip("SKIPPING 22_psram_1bank_4mux_func_test, third port reads are broken?")
|
||||||
class psram_1bank_4mux_func_test(openram_test):
|
class psram_1bank_4mux_func_test(openram_test):
|
||||||
|
|
||||||
def runTest(self):
|
def runTest(self):
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue