diff --git a/compiler/characterizer/delay.py b/compiler/characterizer/delay.py index 14bdcd11..9230be55 100644 --- a/compiler/characterizer/delay.py +++ b/compiler/characterizer/delay.py @@ -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) diff --git a/compiler/modules/control_logic.py b/compiler/modules/control_logic.py index e81e44ea..9d022324 100644 --- a/compiler/modules/control_logic.py +++ b/compiler/modules/control_logic.py @@ -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 diff --git a/compiler/modules/sense_amp.py b/compiler/modules/sense_amp.py index 8553e42c..9601259c 100644 --- a/compiler/modules/sense_amp.py +++ b/compiler/modules/sense_amp.py @@ -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 \ No newline at end of file diff --git a/compiler/modules/sense_amp_array.py b/compiler/modules/sense_amp_array.py index ebf95c95..dc80a13b 100644 --- a/compiler/modules/sense_amp_array.py +++ b/compiler/modules/sense_amp_array.py @@ -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 diff --git a/compiler/pgates/pdriver.py b/compiler/pgates/pdriver.py index 3a0e4e78..23f3f4f8 100644 --- a/compiler/pgates/pdriver.py +++ b/compiler/pgates/pdriver.py @@ -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