Fix merge of results.

This commit is contained in:
Matt Guthaus 2018-02-21 15:47:07 -08:00
commit a44346110b
7 changed files with 175 additions and 171 deletions

View File

@ -204,7 +204,7 @@ class delay():
trig_val = targ_val = 0.5 * self.vdd_voltage
# Delay the target to measure after the negative edge
self.stim.gen_meas_delay(meas_name="delay_hl",
self.stim.gen_meas_delay(meas_name="DELAY0",
trig_name=trig_name,
targ_name=targ_name,
trig_val=trig_val,
@ -214,7 +214,7 @@ class delay():
trig_td=self.cycle_times[self.read0_cycle],
targ_td=self.cycle_times[self.read0_cycle]+0.5*period)
self.stim.gen_meas_delay(meas_name="delay_lh",
self.stim.gen_meas_delay(meas_name="DELAY1",
trig_name=trig_name,
targ_name=targ_name,
trig_val=trig_val,
@ -224,7 +224,7 @@ class delay():
trig_td=self.cycle_times[self.read1_cycle],
targ_td=self.cycle_times[self.read1_cycle]+0.5*period)
self.stim.gen_meas_delay(meas_name="slew_hl",
self.stim.gen_meas_delay(meas_name="SLEW0",
trig_name=targ_name,
targ_name=targ_name,
trig_val=0.9*self.vdd_voltage,
@ -234,7 +234,7 @@ class delay():
trig_td=self.cycle_times[self.read0_cycle],
targ_td=self.cycle_times[self.read0_cycle]+0.5*period)
self.stim.gen_meas_delay(meas_name="slew_lh",
self.stim.gen_meas_delay(meas_name="SLEW1",
trig_name=targ_name,
targ_name=targ_name,
trig_val=0.1*self.vdd_voltage,
@ -247,25 +247,25 @@ class delay():
# add measure statements for power
t_initial = self.cycle_times[self.write0_cycle]
t_final = self.cycle_times[self.write0_cycle+1]
self.stim.gen_meas_power(meas_name="write0_power",
self.stim.gen_meas_power(meas_name="WRITE0_POWER",
t_initial=t_initial,
t_final=t_final)
t_initial = self.cycle_times[self.write1_cycle]
t_final = self.cycle_times[self.write1_cycle+1]
self.stim.gen_meas_power(meas_name="write1_power",
self.stim.gen_meas_power(meas_name="WRITE1_POWER",
t_initial=t_initial,
t_final=t_final)
t_initial = self.cycle_times[self.read0_cycle]
t_final = self.cycle_times[self.read0_cycle+1]
self.stim.gen_meas_power(meas_name="read0_power",
self.stim.gen_meas_power(meas_name="READ0_POWER",
t_initial=t_initial,
t_final=t_final)
t_initial = self.cycle_times[self.read1_cycle]
t_final = self.cycle_times[self.read1_cycle+1]
self.stim.gen_meas_power(meas_name="read1_power",
self.stim.gen_meas_power(meas_name="READ1_POWER",
t_initial=t_initial,
t_final=t_final)
@ -303,20 +303,20 @@ class delay():
debug.error("Timed out, could not find a feasible period.",2)
(success, results)=self.run_delay_simulation(feasible_period,load,slew)
feasible_delay1 = results["delay1"]
feasible_slew1 = results["slew1"]
feasible_delay0 = results["delay0"]
feasible_slew0 = results["slew0"]
if not success:
feasible_period = 2 * feasible_period
continue
feasible_delay_lh = results["delay_lh"]
feasible_slew_lh = results["slew_lh"]
feasible_delay_hl = results["delay_hl"]
feasible_slew_hl = results["slew_hl"]
debug.info(1, "Found feasible_period: {0}ns feasible_delay_lh/0 {1}ns/{2}ns slew {3}ns/{4}ns".format(feasible_period,
feasible_delay_lh,
feasible_delay_hl,
feasible_slew_lh,
feasible_slew_hl))
return (feasible_period, feasible_delay_lh, feasible_delay_hl)
debug.info(1, "Found feasible_period: {0}ns feasible_delay1/0 {1}ns/{2}ns slew {3}ns/{4}ns".format(feasible_period,
feasible_delay1,
feasible_delay0,
feasible_slew1,
feasible_slew0))
return (feasible_period, feasible_delay1, feasible_delay0)
def run_delay_simulation(self, period, load, slew):
@ -330,11 +330,11 @@ class delay():
# Checking from not data_value to data_value
self.write_delay_stimulus(period, load, slew)
self.stim.run_sim()
delay_hl = ch.parse_output("timing", "delay_hl")
delay_lh = ch.parse_output("timing", "delay_lh")
slew_hl = ch.parse_output("timing", "slew_hl")
slew_lh = ch.parse_output("timing", "slew_lh")
delays = (delay_hl, delay_lh, slew_hl, slew_lh)
delay0 = ch.parse_output("timing", "delay0")
delay1 = ch.parse_output("timing", "delay1")
slew0 = ch.parse_output("timing", "slew0")
slew1 = ch.parse_output("timing", "slew1")
delays = (delay0, delay1, slew0, slew1)
read0_power=ch.parse_output("timing", "read0_power")
write0_power=ch.parse_output("timing", "write0_power")
@ -348,10 +348,10 @@ class delay():
#key=raw_input("press return to continue")
# Scale results to ns and mw, respectively
result = { "delay_hl" : delay_hl*1e9,
"delay_lh" : delay_lh*1e9,
"slew_hl" : slew_hl*1e9,
"slew_lh" : slew_lh*1e9,
result = { "delay0" : delay0*1e9,
"delay1" : delay1*1e9,
"slew0" : slew0*1e9,
"slew1" : slew1*1e9,
"read0_power" : read0_power*1e3,
"read1_power" : read1_power*1e3,
"write0_power" : write0_power*1e3,
@ -382,46 +382,46 @@ class delay():
#key=raw_input("press return to continue")
return (leakage_power*1e3, trim_leakage_power*1e3)
def check_valid_delays(self, period, load, slew, (delay_hl, delay_lh, slew_hl, slew_lh)):
def check_valid_delays(self, period, load, slew, (delay0, delay1, slew0, slew1)):
""" Check if the measurements are defined and if they are valid. """
# if it failed or the read was longer than a period
if type(delay_hl)!=float or type(delay_lh)!=float or type(slew_lh)!=float or type(slew_hl)!=float:
debug.info(2,"Failed simulation: period {0} load {1} slew {2}, delay_hl={3} delay_lh={4} slew_hl={5} slew_lh={6}".format(period,
load,
slew,
delay_hl,
delay_lh,
slew_hl,
slew_lh))
if type(delay0)!=float or type(delay1)!=float or type(slew1)!=float or type(slew0)!=float:
debug.info(2,"Failed simulation: period {0} load {1} slew {2}, delay0={3}n delay1={4}ns slew0={5}n slew1={6}n".format(period,
load,
slew,
delay0,
delay1,
slew0,
slew1))
return False
# Scale delays to ns (they previously could have not been floats)
delay_hl *= 1e9
delay_lh *= 1e9
slew_hl *= 1e9
slew_lh *= 1e9
if delay_hl>period or delay_lh>period or slew_hl>period or slew_lh>period:
debug.info(2,"UNsuccessful simulation: period {0} load {1} slew {2}, delay_hl={3}n delay_lh={4}ns slew_hl={5}n slew_lh={6}n".format(period,
load,
slew,
delay_hl,
delay_lh,
slew_hl,
slew_lh))
delay0 *= 1e9
delay1 *= 1e9
slew0 *= 1e9
slew1 *= 1e9
if delay0>period or delay1>period or slew0>period or slew1>period:
debug.info(2,"UNsuccessful simulation: period {0} load {1} slew {2}, delay0={3}n delay1={4}ns slew0={5}n slew1={6}n".format(period,
load,
slew,
delay0,
delay1,
slew0,
slew1))
return False
else:
debug.info(2,"Successful simulation: period {0} load {1} slew {2}, delay_hl={3}n delay_lh={4}ns slew_hl={5}n slew_lh={6}n".format(period,
load,
slew,
delay_hl,
delay_lh,
slew_hl,
slew_lh))
debug.info(2,"Successful simulation: period {0} load {1} slew {2}, delay0={3}n delay1={4}ns slew0={5}n slew1={6}n".format(period,
load,
slew,
delay0,
delay1,
slew0,
slew1))
return True
def find_min_period(self,feasible_period, load, slew, feasible_delay_lh, feasible_delay_hl):
def find_min_period(self,feasible_period, load, slew, feasible_delay1, feasible_delay0):
"""
Searches for the smallest period with output delays being within 5% of
long period.
@ -442,7 +442,7 @@ class delay():
ub_period,
lb_period))
if self.try_period(target_period, load, slew, feasible_delay_lh, feasible_delay_hl):
if self.try_period(target_period, load, slew, feasible_delay1, feasible_delay0):
ub_period = target_period
else:
lb_period = target_period
@ -452,7 +452,7 @@ class delay():
return ub_period
def try_period(self, period, load, slew, feasible_delay_lh, feasible_delay_hl):
def try_period(self, period, load, slew, feasible_delay1, feasible_delay0):
"""
This tries to simulate a period and checks if the result
works. If it does and the delay is within 5% still, it returns True.
@ -461,45 +461,45 @@ class delay():
# Checking from not data_value to data_value
self.write_delay_stimulus(period,load,slew)
self.stim.run_sim()
delay_hl = ch.parse_output("timing", "delay_hl")
delay_lh = ch.parse_output("timing", "delay_lh")
slew_hl = ch.parse_output("timing", "slew_hl")
slew_lh = ch.parse_output("timing", "slew_lh")
delay0 = ch.parse_output("timing", "delay0")
delay1 = ch.parse_output("timing", "delay1")
slew0 = ch.parse_output("timing", "slew0")
slew1 = ch.parse_output("timing", "slew1")
# if it failed or the read was longer than a period
if type(delay_hl)!=float or type(delay_lh)!=float or type(slew_lh)!=float or type(slew_hl)!=float:
debug.info(2,"Invalid measures: Period {0}, delay_hl={1}ns, delay_lh={2}ns slew_hl={3}ns slew_lh={4}ns".format(period,
delay_hl,
delay_lh,
slew_hl,
slew_lh))
if type(delay0)!=float or type(delay1)!=float or type(slew1)!=float or type(slew0)!=float:
debug.info(2,"Invalid measures: Period {0}, delay0={1}ns, delay1={2}ns slew0={3}ns slew1={4}ns".format(period,
delay0,
delay1,
slew0,
slew1))
return False
delay_hl *= 1e9
delay_lh *= 1e9
slew_hl *= 1e9
slew_lh *= 1e9
if delay_hl>period or delay_lh>period or slew_hl>period or slew_lh>period:
debug.info(2,"Too long delay/slew: Period {0}, delay_hl={1}ns, delay_lh={2}ns slew_hl={3}ns slew_lh={4}ns".format(period,
delay_hl,
delay_lh,
slew_hl,
slew_lh))
delay0 *= 1e9
delay1 *= 1e9
slew0 *= 1e9
slew1 *= 1e9
if delay0>period or delay1>period or slew0>period or slew1>period:
debug.info(2,"Too long delay/slew: Period {0}, delay0={1}ns, delay1={2}ns slew0={3}ns slew1={4}ns".format(period,
delay0,
delay1,
slew0,
slew1))
return False
else:
if not ch.relative_compare(delay_lh,feasible_delay_lh,error_tolerance=0.05):
debug.info(2,"Delay too big {0} vs {1}".format(delay_lh,feasible_delay_lh))
if not ch.relative_compare(delay1,feasible_delay1,error_tolerance=0.05):
debug.info(2,"Delay too big {0} vs {1}".format(delay1,feasible_delay1))
return False
elif not ch.relative_compare(delay_hl,feasible_delay_hl,error_tolerance=0.05):
debug.info(2,"Delay too big {0} vs {1}".format(delay_hl,feasible_delay_hl))
elif not ch.relative_compare(delay0,feasible_delay0,error_tolerance=0.05):
debug.info(2,"Delay too big {0} vs {1}".format(delay0,feasible_delay0))
return False
#key=raw_input("press return to continue")
debug.info(2,"Successful period {0}, delay_hl={1}ns, delay_lh={2}ns slew_hl={3}ns slew_lh={4}ns".format(period,
delay_hl,
delay_lh,
slew_hl,
slew_lh))
debug.info(2,"Successful period {0}, delay0={1}ns, delay1={2}ns slew0={3}ns slew1={4}ns".format(period,
delay0,
delay1,
slew0,
slew1))
return True
def set_probe(self,probe_address, probe_data):
@ -544,23 +544,23 @@ class delay():
# This is for debugging a full simulation
# debug.info(0,"Debug simulation running...")
# target_period=50.0
# feasible_delay_lh=0.059083183
# feasible_delay_hl=0.17953789
# feasible_delay1=0.059083183
# feasible_delay0=0.17953789
# load=1.6728
# slew=0.04
# self.try_period(target_period, load, slew, feasible_delay_lh, feasible_delay_hl)
# self.try_period(target_period, load, slew, feasible_delay1, feasible_delay0)
# sys.exit(1)
# 1) Find a feasible period and it's corresponding delays using the trimmed array.
(feasible_period, feasible_delay_lh, feasible_delay_hl) = self.find_feasible_period(max(loads), max(slews))
debug.check(feasible_delay_lh>0,"Negative delay may not be possible")
debug.check(feasible_delay_hl>0,"Negative delay may not be possible")
(feasible_period, feasible_delay1, feasible_delay0) = self.find_feasible_period(max(loads), max(slews))
debug.check(feasible_delay1>0,"Negative delay may not be possible")
debug.check(feasible_delay0>0,"Negative delay may not be possible")
# 2) Measure the delay, slew and power for all slew/load pairs.
# Make a list for each type of measurement to append results to
char_data = {}
for m in ["delay_lh", "delay_hl", "slew_lh", "slew_hl", "read0_power",
for m in ["delay1", "delay0", "slew1", "slew0", "read0_power",
"read1_power", "write0_power", "write1_power", "leakage_power"]:
char_data[m]=[]
full_array_leakage = {}
@ -587,9 +587,9 @@ class delay():
# 3) Finds the minimum period without degrading the delays by X%
min_period = self.find_min_period(feasible_period, max(loads), max(slews), feasible_delay_lh, feasible_delay_hl)
min_period = self.find_min_period(feasible_period, max(loads), max(slews), feasible_delay1, feasible_delay0)
debug.check(type(min_period)==float,"Couldn't find minimum period.")
debug.info(1, "Min Period: {0}n with a delay of {1} / {2}".format(min_period, feasible_delay_lh, feasible_delay_hl))
debug.info(1, "Min Period: {0}n with a delay of {1} / {2}".format(min_period, feasible_delay1, feasible_delay0))
# 4) Pack up the final measurements
char_data["min_period"] = ch.round_time(min_period)
@ -706,16 +706,16 @@ class delay():
for load in loads:
bank_delay = sram.analytical_delay(slew,load)
# Convert from ps to ns
delay_lh.append(bank_delay.delay/1e3)
delay_hl.append(bank_delay.delay/1e3)
slew_lh.append(bank_delay.slew/1e3)
slew_hl.append(bank_delay.slew/1e3)
LH_delay.append(bank_delay.delay/1e3)
HL_delay.append(bank_delay.delay/1e3)
LH_slew.append(bank_delay.slew/1e3)
HL_slew.append(bank_delay.slew/1e3)
data = {"min_period": 0,
"delay_lh": delay_lh,
"delay_hl": delay_hl,
"slew_lh": slew_lh,
"slew_hl": slew_hl,
"delay1": LH_delay,
"delay0": HL_delay,
"slew1": LH_slew,
"slew0": HL_slew,
"read0_power": 0,
"read1_power": 0,
"write0_power": 0,

View File

@ -92,10 +92,10 @@ cell (sram_2_16_1_freepdk45){
internal_power(){
when : "OEb & !clk";
rise_power(scalar){
values("0.039688322");
values("0.0396585518889");
}
fall_power(scalar){
values("0.029868294");
values("0.029840953");
}
}
timing(){
@ -129,10 +129,10 @@ cell (sram_2_16_1_freepdk45){
internal_power(){
when : "!OEb & !clk";
rise_power(scalar){
values("0.049703133");
values("0.0495000442222");
}
fall_power(scalar){
values("0.055020041");
values("0.0549839213333");
}
}
timing(){
@ -140,24 +140,24 @@ cell (sram_2_16_1_freepdk45){
related_pin : "clk";
timing_type : falling_edge;
cell_rise(CELL_TABLE) {
values("0.055, 0.056, 0.063",\
"0.056, 0.057, 0.063",\
"0.061, 0.062, 0.069");
values("0.055, 0.056, 0.061",\
"0.056, 0.057, 0.062",\
"0.063, 0.063, 0.069");
}
cell_fall(CELL_TABLE) {
values("0.429, 0.43, 0.439",\
"0.429, 0.431, 0.439",\
"0.435, 0.436, 0.446");
values("0.429, 0.429, 0.435",\
"0.43, 0.431, 0.436",\
"0.439, 0.439, 0.446");
}
rise_transition(CELL_TABLE) {
values("0.013, 0.015, 0.026",\
"0.013, 0.015, 0.026",\
"0.013, 0.015, 0.026");
values("0.013, 0.013, 0.013",\
"0.015, 0.015, 0.015",\
"0.026, 0.026, 0.026");
}
fall_transition(CELL_TABLE) {
values("0.029, 0.031, 0.044",\
"0.029, 0.031, 0.044",\
"0.029, 0.031, 0.044");
values("0.029, 0.029, 0.029",\
"0.031, 0.031, 0.031",\
"0.044, 0.044, 0.044");
}
}
}

View File

@ -92,10 +92,10 @@ cell (sram_2_16_1_freepdk45){
internal_power(){
when : "OEb & !clk";
rise_power(scalar){
values("0.036463566");
values("0.03655734659");
}
fall_power(scalar){
values("0.026623993");
values("0.0267123544789");
}
}
timing(){
@ -129,10 +129,10 @@ cell (sram_2_16_1_freepdk45){
internal_power(){
when : "!OEb & !clk";
rise_power(scalar){
values("0.033688925");
values("0.0336039323678");
}
fall_power(scalar){
values("0.038865319");
values("0.03895461259");
}
}
timing(){
@ -140,24 +140,24 @@ cell (sram_2_16_1_freepdk45){
related_pin : "clk";
timing_type : falling_edge;
cell_rise(CELL_TABLE) {
values("0.054, 0.055, 0.061",\
"0.055, 0.055, 0.062",\
"0.06, 0.061, 0.067");
values("0.054, 0.055, 0.06",\
"0.055, 0.055, 0.061",\
"0.061, 0.062, 0.067");
}
cell_fall(CELL_TABLE) {
values("0.425, 0.426, 0.436",\
"0.426, 0.427, 0.436",\
"0.432, 0.433, 0.442");
values("0.425, 0.426, 0.432",\
"0.426, 0.427, 0.433",\
"0.436, 0.436, 0.442");
}
rise_transition(CELL_TABLE) {
values("0.013, 0.014, 0.026",\
"0.013, 0.014, 0.026",\
"0.013, 0.015, 0.026");
values("0.013, 0.013, 0.013",\
"0.014, 0.014, 0.015",\
"0.026, 0.026, 0.026");
}
fall_transition(CELL_TABLE) {
values("0.027, 0.029, 0.043",\
"0.027, 0.029, 0.043",\
"0.027, 0.029, 0.043");
values("0.027, 0.027, 0.027",\
"0.029, 0.029, 0.029",\
"0.043, 0.043, 0.043");
}
}
}

View File

@ -92,10 +92,10 @@ cell (sram_2_16_1_scn3me_subm){
internal_power(){
when : "OEb & !clk";
rise_power(scalar){
values("11.763876");
values("11.5567013333");
}
fall_power(scalar){
values("8.1710129");
values("8.11796563333");
}
}
timing(){
@ -129,10 +129,10 @@ cell (sram_2_16_1_scn3me_subm){
internal_power(){
when : "!OEb & !clk";
rise_power(scalar){
values("12.162858");
values("12.0236177778");
}
fall_power(scalar){
values("10.926647");
values("10.8690056667");
}
}
timing(){
@ -140,24 +140,24 @@ cell (sram_2_16_1_scn3me_subm){
related_pin : "clk";
timing_type : falling_edge;
cell_rise(CELL_TABLE) {
values("0.473, 0.519, 0.888",\
"0.476, 0.522, 0.891",\
"0.516, 0.56, 0.928");
values("0.473, 0.476, 0.516",\
"0.519, 0.522, 0.56",\
"0.888, 0.891, 0.928");
}
cell_fall(CELL_TABLE) {
values("0.582, 0.655, 1.256",\
"0.585, 0.658, 1.259",\
"0.625, 0.697, 1.295");
values("0.582, 0.585, 0.625",\
"0.655, 0.658, 0.697",\
"1.256, 1.259, 1.295");
}
rise_transition(CELL_TABLE) {
values("0.154, 0.233, 1.086",\
"0.155, 0.234, 1.086",\
"0.158, 0.237, 1.086");
values("0.154, 0.155, 0.158",\
"0.233, 0.234, 0.237",\
"1.086, 1.086, 1.086");
}
fall_transition(CELL_TABLE) {
values("0.278, 0.359, 1.499",\
"0.278, 0.361, 1.499",\
"0.28, 0.367, 1.5");
values("0.278, 0.278, 0.28",\
"0.359, 0.361, 0.367",\
"1.499, 1.499, 1.5");
}
}
}

View File

@ -92,10 +92,10 @@ cell (sram_2_16_1_scn3me_subm){
internal_power(){
when : "OEb & !clk";
rise_power(scalar){
values("10.4925");
values("10.4314073837");
}
fall_power(scalar){
values("7.1836643");
values("7.13119680587");
}
}
timing(){
@ -129,10 +129,10 @@ cell (sram_2_16_1_scn3me_subm){
internal_power(){
when : "!OEb & !clk";
rise_power(scalar){
values("10.203608");
values("9.93581495032");
}
fall_power(scalar){
values("10.057386");
values("10.0783428725");
}
}
timing(){
@ -140,24 +140,24 @@ cell (sram_2_16_1_scn3me_subm){
related_pin : "clk";
timing_type : falling_edge;
cell_rise(CELL_TABLE) {
values("0.458, 0.503, 0.87",\
"0.461, 0.505, 0.873",\
"0.5, 0.544, 0.911");
values("0.458, 0.461, 0.5",\
"0.503, 0.505, 0.544",\
"0.87, 0.873, 0.911");
}
cell_fall(CELL_TABLE) {
values("0.573, 0.645, 1.246",\
"0.576, 0.648, 1.249",\
"0.616, 0.687, 1.286");
values("0.573, 0.576, 0.616",\
"0.645, 0.648, 0.687",\
"1.246, 1.249, 1.286");
}
rise_transition(CELL_TABLE) {
values("0.153, 0.232, 1.084",\
"0.153, 0.233, 1.084",\
"0.156, 0.236, 1.084");
values("0.153, 0.153, 0.156",\
"0.232, 0.233, 0.236",\
"1.084, 1.084, 1.084");
}
fall_transition(CELL_TABLE) {
values("0.277, 0.36, 1.499",\
"0.277, 0.362, 1.499",\
"0.278, 0.37, 1.5");
values("0.277, 0.277, 0.278",\
"0.36, 0.362, 0.37",\
"1.499, 1.499, 1.5");
}
}
}

View File

@ -1,6 +1,8 @@
CUR_DIR = $(shell pwd)
TEST_DIR = ${CUR_DIR}/tests
MAKEFLAGS += -j 2
CONFIG_DIR = configs
OUT_DIRS = sp lib lef gds verilog
$(shell mkdir -p $(OUT_DIRS))
@ -12,7 +14,7 @@ all : $(SPICES)
# Characterize and perform DRC/LVS
OPTS = -c
# Do not characterize or perform DRC/LVS
OPTS += -n
#OPTS = -n
%.sp : %.py
$(eval bname=$(basename $(notdir $<)))
openram.py $(OPTS) $< 2>&1 > $(bname).log

View File

@ -1,6 +1,8 @@
CUR_DIR = $(shell pwd)
TEST_DIR = ${CUR_DIR}/tests
MAKEFLAGS += -j 2
CONFIG_DIR = configs
OUT_DIRS = sp lib lef gds verilog
$(shell mkdir -p $(OUT_DIRS))
@ -12,7 +14,7 @@ all : $(SPICES)
# Characterize and perform DRC/LVS
OPTS = -c
# Do not characterize or perform DRC/LVS
OPTS += -n
#OPTS = -n
%.sp : %.py
$(eval bname=$(basename $(notdir $<)))
openram.py $(OPTS) $< 2>&1 > $(bname).log