Change characterizer to be one data structure. Add approximate diff for lib file.

This commit is contained in:
Matt Guthaus 2016-11-23 17:18:48 -08:00
parent 233acc3fcc
commit 841532a52f
5 changed files with 102 additions and 27 deletions

View File

@ -386,15 +386,15 @@ class delay():
debug.info(1, "Min Period for high_to_low transistion: {0}n with a delay of {1}".format(min_period0, delay0))
read_power=ch.convert_to_float(ch.parse_output("timing", "power_read"))
write_power=ch.convert_to_float(ch.parse_output("timing", "power_write"))
data = {"min_period1": min_period1, # period in ns
"delay1": delay1, # delay in s
"min_period0": min_period0,
"delay0": delay0
"delay0": delay0,
"read_power": read_power,
"write_power": write_power
}
power = {"Read_Power": read_power,
"Write_Power": write_power
}
return data, power
return data
def obtain_cycle_times(self, slow_period, fast_period):

View File

@ -61,12 +61,14 @@ class lib:
probe_address = "1" * self.addr_size
probe_data = self.word_size - 1
data , power = self.d.analyze(probe_address, probe_data)
data = self.d.analyze(probe_address, probe_data)
for i in data.keys():
if i == "read_power" or i == "write_power":
continue
data[i] = ch.round_time(data[i])
self.write_data_bus(data, power, times)
self.write_data_bus(data, times)
self.write_addr_bus(times)
self.write_control_pins(times)
self.write_clk(data)
@ -199,7 +201,7 @@ class lib:
def write_data_bus(self, data, power, times):
def write_data_bus(self, data, times):
""" Adds data bus timing results."""
self.lib.write(" bus(DATA){\n")
self.lib.write(" bus_type : DATA; \n")
@ -217,10 +219,10 @@ class lib:
self.lib.write(" internal_power(){\n")
self.lib.write(" when : \"OEb & !clk\"; \n")
self.lib.write(" rise_power(INPUT_BY_TRANS_FOR_SIGNAL){\n")
self.lib.write(" values(\"{0}\");\n".format(power["Write_Power"]* 1e3))
self.lib.write(" values(\"{0}\");\n".format(data["write_power"]* 1e3))
self.lib.write(" }\n")
self.lib.write(" fall_power(INPUT_BY_TRANS_FOR_SIGNAL){\n")
self.lib.write(" values(\"{0}\");\n".format(power["Write_Power"]* 1e3))
self.lib.write(" values(\"{0}\");\n".format(data["write_power"]* 1e3))
self.lib.write(" }\n")
self.lib.write(" }\n")
self.write_timing(times)
@ -231,10 +233,10 @@ class lib:
self.lib.write(" internal_power(){\n")
self.lib.write(" when : \"!OEb & !clk\"; \n")
self.lib.write(" rise_power(INPUT_BY_TRANS_FOR_SIGNAL){\n")
self.lib.write(" values(\"{0}\");\n".format(power["Read_Power"]* 1e3))
self.lib.write(" values(\"{0}\");\n".format(data["read_power"]* 1e3))
self.lib.write(" }\n")
self.lib.write(" fall_power(INPUT_BY_TRANS_FOR_SIGNAL){\n")
self.lib.write(" values(\"{0}\");\n".format(power["Read_Power"]* 1e3))
self.lib.write(" values(\"{0}\");\n".format(data["read_power"]* 1e3))
self.lib.write(" }\n")
self.lib.write(" }\n")
self.lib.write(" timing(){ \n")

View File

@ -4,7 +4,7 @@ Check the .lib file for an SRAM
"""
import unittest
from testutils import header,isdiff
from testutils import header,isapproxdiff
import sys,os
sys.path.append(os.path.join(sys.path[0],".."))
import globals
@ -40,7 +40,8 @@ class lib_test(unittest.TestCase):
# let's diff the result with a golden model
golden = "{0}/golden/{1}".format(os.path.dirname(os.path.realpath(__file__)),filename)
self.assertEqual(isdiff(libname,golden),True)
# Randomly decided 10% difference between spice simulators is ok.
self.assertEqual(isapproxdiff(libname,golden,0.10),True)
os.system("rm {0}".format(libname))

View File

@ -124,10 +124,10 @@ cell (sram_2_16_1_freepdk45){
internal_power(){
when : "OEb & !clk";
rise_power(INPUT_BY_TRANS_FOR_SIGNAL){
values("0.6942568");
values("0.66109");
}
fall_power(INPUT_BY_TRANS_FOR_SIGNAL){
values("0.6942568");
values("0.66109");
}
}
timing(){
@ -156,10 +156,10 @@ cell (sram_2_16_1_freepdk45){
internal_power(){
when : "!OEb & !clk";
rise_power(INPUT_BY_TRANS_FOR_SIGNAL){
values("0.0290396");
values("0.027754");
}
fall_power(INPUT_BY_TRANS_FOR_SIGNAL){
values("0.0290396");
values("0.027754");
}
}
timing(){
@ -167,16 +167,16 @@ cell (sram_2_16_1_freepdk45){
related_pin : "clk";
timing_type : rising_edge;
cell_rise(CELL_UP_FOR_CLOCK) {
values("0.061");
values("0.042");
}
cell_fall(CELL_DN_FOR_CLOCK) {
values("0.24");
values("0.241");
}
rise_transition(TRAN) {
values("0.061");
values("0.042");
}
fall_transition(TRAN) {
values("0.24");
values("0.241");
}
}
}
@ -294,20 +294,20 @@ cell (sram_2_16_1_freepdk45){
timing_type :"min_pulse_width";
related_pin : clk;
rise_constraint(CLK_TRAN) {
values("0.1745");
values("0.174");
}
fall_constraint(CLK_TRAN) {
values("0.1745");
values("0.174");
}
}
timing(){
timing_type :"minimum_period";
related_pin : clk;
rise_constraint(CLK_TRAN) {
values("0.349");
values("0.348");
}
fall_constraint(CLK_TRAN) {
values("0.349");
values("0.348");
}
}
}

View File

@ -1,5 +1,4 @@
def isclose(value1,value2,error_tolerance=1e-2):
""" This is used to compare relative values. """
import debug
@ -11,6 +10,79 @@ def isclose(value1,value2,error_tolerance=1e-2):
debug.info(2,"CLOSE {0} {1} relative diff={2}".format(value1,value2,relative_diff))
return (check)
def relative_compare(value1,value2,error_tolerance):
""" This is used to compare relative values. """
if (value1==value2): # if we don't need a relative comparison!
return True
return (abs(value1 - value2) / max(value1,value2) <= error_tolerance)
def isapproxdiff(f1, f2, error_tolerance=0.001):
"""Compare two files.
Arguments:
f1 -- First file name
f2 -- Second file name
Return value:
True if the files are the same, False otherwise.
"""
import re
import debug
with open(f1, 'rb') as fp1, open(f2, 'rb') as fp2:
while True:
b1 = fp1.readline()
b2 = fp2.readline()
#print "b1:",b1,
#print "b2:",b2,
# 1. Find all of the floats using a regex
numeric_const_pattern = r"""
[-+]? # optional sign
(?:
(?: \d* \. \d+ ) # .1 .12 .123 etc 9.1 etc 98.1 etc
|
(?: \d+ \.? ) # 1. 12. 123. etc 1 12 123 etc
)
# followed by optional exponent part if desired
(?: [Ee] [+-]? \d+ ) ?
"""
rx = re.compile(numeric_const_pattern, re.VERBOSE)
b1_floats=rx.findall(b1)
b2_floats=rx.findall(b2)
debug.info(3,"b1_floats: "+str(b1_floats))
debug.info(3,"b2_floats: "+str(b2_floats))
# 2. Remove the floats from the string
for f in b1_floats:
b1=b1.replace(str(f),"")
for f in b2_floats:
b2=b2.replace(str(f),"")
#print "b1:",b1,
#print "b2:",b2,
# 3. Check if remaining string matches
if b1 != b2:
debug.info(2,"Line: {0}\n!=\nLine: {1}".format(b1,b2))
return False
# 4. Now compare that the floats match
if len(b1_floats)!=len(b2_floats):
debug.info(2,"Len {0} != {1}".format(len(b1_floats),len(b2_floats)))
return False
for (f1,f2) in zip(b1_floats,b2_floats):
if not relative_compare(float(f1),float(f2),error_tolerance):
debug.info(2, "Float {0} != {1}".format(f1,f2))
return False
if not b1:
return True
def isdiff(file1,file2):
""" This is used to compare two files and display the diff if they are different.. """
import debug