Fixed some delay model bugs.

This commit is contained in:
Hunter Nichols 2019-02-05 21:15:12 -08:00
parent e3d003d410
commit 5f01a52113
5 changed files with 23 additions and 14 deletions

View File

@ -889,7 +889,8 @@ class delay(simulation):
"""
if OPTS.num_rw_ports > 1 or OPTS.num_w_ports > 0 and OPTS.num_r_ports > 0:
debug.warning("Analytical characterization results are not supported for multiport.")
self.create_signal_names()
self.create_measurement_names()
power = self.analytical_power(slews, loads)
port_data = self.get_empty_measure_data_dict()
for slew in slews:
@ -907,7 +908,8 @@ class delay(simulation):
else:
debug.error("Measurement name not recognized: {}".format(mname),1)
period_margin = 0.1
sram_data = { "min_period": bank_delay[0]*2*period_margin,
risefall_delay = bank_delay[self.read_ports[0]].delay/1e3
sram_data = { "min_period":risefall_delay*2*period_margin,
"leakage_power": power.leakage}
return (sram_data,port_data)

View File

@ -154,10 +154,8 @@ class control_logic(design.design):
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: #Calculate delays for potential re-sizing
self.set_sen_wl_delays()
#Resize if necessary, condition depends on resizing method
if self.sram != None and self.enable_delay_chain_resizing and not self.does_sen_total_timing_match():
if self.sram != None and self.enable_delay_chain_resizing and not self.does_sen_rise_fall_timing_match():
#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)
self.replica_bitline = factory.create(module_type="replica_bitline",
@ -177,7 +175,8 @@ class control_logic(design.design):
def get_heuristic_delay_chain_size(self):
"""Use a basic heuristic to determine the size of the delay chain used for the Sense Amp Enable """
delay_fanout = 2 # This can be anything >=2
#FIXME: The minimum was 2 fanout, now it will not pass DRC unless it is 3. Why?
delay_fanout = 3 # This can be anything >=3
# Delay stages Must be non-inverting
if self.words_per_row >= 2:
delay_stages = 4
@ -246,15 +245,23 @@ class control_logic(design.design):
#If the fanout is different between rise/fall by this amount. Stage algorithm is made more pessimistic.
WARNING_FANOUT_DIFF = 5
stages_close = False
#The stages need to be equal (or at least a even number of stages with matching rise/fall delays)
while True:
stages_fall = self.calculate_stages_with_fixed_fanout(required_delay_fall,fanout_fall)
stages_rise = self.calculate_stages_with_fixed_fanout(required_delay_rise,fanout_rise)
debug.info(1,"Fall stages={}, rise stages={}".format(stages_fall,stages_rise))
if abs(stages_fall-stages_rise) == 1 and not stages_close:
stages_close = True
safe_fanout_rise = fanout_rise
safe_fanout_fall = fanout_fall
if stages_fall == stages_rise:
break
elif abs(stages_fall-stages_rise) == 1 and WARNING_FANOUT_DIFF < abs(fanout_fall-fanout_rise):
debug.info(1, "Delay chain fanouts between stages are large. Making chain size larger for safety.")
fanout_rise = safe_fanout_rise
fanout_fall = safe_fanout_fall
break
#There should also be a condition to make sure the fanout does not get too large.
#Otherwise, increase the fanout of delay with the most stages, calculate new stages

View File

@ -48,4 +48,5 @@ class sense_amp(design.design):
"""Get the relative capacitance of sense amp enable gate cin"""
pmos_cin = parameter["sa_en_pmos_size"]/drc("minwidth_tx")
nmos_cin = parameter["sa_en_nmos_size"]/drc("minwidth_tx")
#sen is connected to 2 pmos isolation TX and 1 nmos per sense amp.
return 2*pmos_cin + nmos_cin

View File

@ -142,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.word_size

View File

@ -196,17 +196,16 @@ class pdriver(pgate.pgate):
def get_stage_efforts(self, external_cout, inp_is_rise=False):
"""Get the stage efforts of the A -> Z path"""
cout_list = {}
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
cout_list.append(inv.get_cin())
cout_list.append(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)
for inv,cout in zip(self.inv_list,cout_list):
stage = inv.get_stage_effort(cout, last_inp_is_rise)
stage_effort_list.append(stage)
last_inp_is_rise = stage.is_rise