mirror of https://github.com/VLSIDA/OpenRAM.git
Fixed some delay model bugs.
This commit is contained in:
parent
e3d003d410
commit
5f01a52113
|
|
@ -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:
|
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.")
|
debug.warning("Analytical characterization results are not supported for multiport.")
|
||||||
|
self.create_signal_names()
|
||||||
|
self.create_measurement_names()
|
||||||
power = self.analytical_power(slews, loads)
|
power = self.analytical_power(slews, loads)
|
||||||
port_data = self.get_empty_measure_data_dict()
|
port_data = self.get_empty_measure_data_dict()
|
||||||
for slew in slews:
|
for slew in slews:
|
||||||
|
|
@ -907,7 +908,8 @@ class delay(simulation):
|
||||||
else:
|
else:
|
||||||
debug.error("Measurement name not recognized: {}".format(mname),1)
|
debug.error("Measurement name not recognized: {}".format(mname),1)
|
||||||
period_margin = 0.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}
|
"leakage_power": power.leakage}
|
||||||
|
|
||||||
return (sram_data,port_data)
|
return (sram_data,port_data)
|
||||||
|
|
|
||||||
|
|
@ -154,10 +154,8 @@ class control_logic(design.design):
|
||||||
self.replica_bitline = factory.create(module_type="replica_bitline",
|
self.replica_bitline = factory.create(module_type="replica_bitline",
|
||||||
delay_fanout_list=[delay_fanout_heuristic]*delay_stages_heuristic,
|
delay_fanout_list=[delay_fanout_heuristic]*delay_stages_heuristic,
|
||||||
bitcell_loads=bitcell_loads)
|
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
|
#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.
|
#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 = factory.create(module_type="replica_bitline",
|
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):
|
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 """
|
"""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
|
# Delay stages Must be non-inverting
|
||||||
if self.words_per_row >= 2:
|
if self.words_per_row >= 2:
|
||||||
delay_stages = 4
|
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.
|
#If the fanout is different between rise/fall by this amount. Stage algorithm is made more pessimistic.
|
||||||
WARNING_FANOUT_DIFF = 5
|
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)
|
#The stages need to be equal (or at least a even number of stages with matching rise/fall delays)
|
||||||
while True:
|
while True:
|
||||||
stages_fall = self.calculate_stages_with_fixed_fanout(required_delay_fall,fanout_fall)
|
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)
|
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))
|
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:
|
if stages_fall == stages_rise:
|
||||||
break
|
break
|
||||||
elif abs(stages_fall-stages_rise) == 1 and WARNING_FANOUT_DIFF < abs(fanout_fall-fanout_rise):
|
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.")
|
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
|
break
|
||||||
#There should also be a condition to make sure the fanout does not get too large.
|
#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
|
#Otherwise, increase the fanout of delay with the most stages, calculate new stages
|
||||||
|
|
|
||||||
|
|
@ -48,4 +48,5 @@ class sense_amp(design.design):
|
||||||
"""Get the relative capacitance of sense amp enable gate cin"""
|
"""Get the relative capacitance of sense amp enable gate cin"""
|
||||||
pmos_cin = parameter["sa_en_pmos_size"]/drc("minwidth_tx")
|
pmos_cin = parameter["sa_en_pmos_size"]/drc("minwidth_tx")
|
||||||
nmos_cin = parameter["sa_en_nmos_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
|
return 2*pmos_cin + nmos_cin
|
||||||
|
|
@ -142,4 +142,4 @@ class sense_amp_array(design.design):
|
||||||
def get_en_cin(self):
|
def get_en_cin(self):
|
||||||
"""Get the relative capacitance of all the sense amp enable connections in the array"""
|
"""Get the relative capacitance of all the sense amp enable connections in the array"""
|
||||||
sense_amp_en_cin = self.amp.get_en_cin()
|
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
|
||||||
|
|
|
||||||
|
|
@ -196,17 +196,16 @@ class pdriver(pgate.pgate):
|
||||||
|
|
||||||
def get_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"""
|
"""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:]):
|
for prev_inv,inv in zip(self.inv_list, self.inv_list[1:]):
|
||||||
cout_list[prev_inv]=inv.get_cin()
|
cout_list.append(inv.get_cin())
|
||||||
|
|
||||||
cout_list[self.inv_list[-1]]=external_cout
|
cout_list.append(external_cout)
|
||||||
|
|
||||||
stage_effort_list = []
|
stage_effort_list = []
|
||||||
last_inp_is_rise = inp_is_rise
|
last_inp_is_rise = inp_is_rise
|
||||||
for inv in self.inv_list:
|
for inv,cout in zip(self.inv_list,cout_list):
|
||||||
stage = inv.get_stage_effort(cout_list[inv], last_inp_is_rise)
|
stage = inv.get_stage_effort(cout, last_inp_is_rise)
|
||||||
stage_effort_list.append(stage)
|
stage_effort_list.append(stage)
|
||||||
last_inp_is_rise = stage.is_rise
|
last_inp_is_rise = stage.is_rise
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue