Changed power logic in lib file writing. Syntax incorrect still for multiport. To be changed when top-level is done.

This commit is contained in:
Hunter Nichols 2018-09-10 19:33:59 -07:00
parent 5dfa8bc2c6
commit da6843af5b
5 changed files with 81 additions and 69 deletions

View File

@ -658,15 +658,16 @@ class delay():
# sys.exit(1)
#For debugging, skips characterization and returns dummy values.
# i = 1.0
# for slew in slews:
# for load in loads:
# for k,v in char_data.items():
# char_data[k].append(i)
# i+=1.0
# char_data["min_period"] = i
# char_data["leakage_power"] = i+1.0
# return char_data
char_data = self.char_data
i = 1.0
for slew in slews:
for load in loads:
for k,v in char_data.items():
char_data[k].append(i)
i+=1.0
char_data["min_period"] = i
char_data["leakage_power"] = i+1.0
return char_data
# 1) Find a feasible period and it's corresponding delays using the trimmed array.
(feasible_delays_lh, feasible_delays_hl) = self.find_feasible_period()

View File

@ -12,6 +12,11 @@ class lib:
""" lib file generation."""
def __init__(self, out_dir, sram, sp_file, use_model=OPTS.analytical_delay):
#Temporary Workaround to here to set num of ports. Crashes if set in config file.
OPTS.num_rw_ports = 2
#OPTS.num_r_ports = 1
#OPTS.num_w_ports = 1
self.out_dir = out_dir
self.sram = sram
self.sp_file = sp_file
@ -112,7 +117,7 @@ class lib:
self.write_addr_bus(port)
self.write_control_pins(port) #need to split this into sram and port control signals
self.write_clk_timing_power(port)
self.write_clk_timing_power()
self.write_footer()
@ -409,8 +414,7 @@ class lib:
self.write_FF_setuphold()
self.lib.write(" }\n\n")
#Port is a temporary input here. I do need a way to dynamically write the control signal here though.
def write_clk_timing_power(self, port):
def write_clk_timing_power(self):
""" Adds clk pin timing results."""
self.lib.write(" pin(clk){\n")
@ -419,41 +423,10 @@ class lib:
# FIXME: This depends on the clock buffer size in the control logic
self.lib.write(" capacitance : {0}; \n".format(tech.spice["dff_in_cap"]))
# Find the average power of 1 and 0 bits for writes and reads over all loads/slews
# Could make it a table, but this is fine for now.
avg_write_power = np.mean(self.char_results["write1_power{0}".format(port)] + self.char_results["write0_power{0}".format(port)])
avg_read_power = np.mean(self.char_results["read1_power{0}".format(port)] + self.char_results["read0_power{0}".format(port)])
# Equally divide read/write power between first and second half of clock period
self.lib.write(" internal_power(){\n")
self.lib.write(" when : \"!CSb{0} & clk & !WEb{0}\"; \n".format(port))
self.lib.write(" rise_power(scalar){\n")
self.lib.write(" values(\"{0}\");\n".format(avg_write_power/2.0))
self.lib.write(" }\n")
self.lib.write(" fall_power(scalar){\n")
self.lib.write(" values(\"{0}\");\n".format(avg_write_power/2.0))
self.lib.write(" }\n")
self.lib.write(" }\n")
self.lib.write(" internal_power(){\n")
self.lib.write(" when : \"!CSb{0} & !clk & WEb{0}\"; \n".format(port))
self.lib.write(" rise_power(scalar){\n")
self.lib.write(" values(\"{0}\");\n".format(avg_read_power/2.0))
self.lib.write(" }\n")
self.lib.write(" fall_power(scalar){\n")
self.lib.write(" values(\"{0}\");\n".format(avg_read_power/2.0))
self.lib.write(" }\n")
self.lib.write(" }\n")
# Have 0 internal power when disabled, this will be represented as leakage power.
self.lib.write(" internal_power(){\n")
self.lib.write(" when : \"CSb{0}\"; \n".format(port))
self.lib.write(" rise_power(scalar){\n")
self.lib.write(" values(\"0\");\n")
self.lib.write(" }\n")
self.lib.write(" fall_power(scalar){\n")
self.lib.write(" values(\"0\");\n")
self.lib.write(" }\n")
self.lib.write(" }\n")
#Add power values for the ports. lib generated with this is not syntactically correct. TODO once
#top level is done
for port in range(self.total_port_num):
self.add_clk_control_power(port)
min_pulse_width = round_time(self.char_results["min_period"])/2.0
min_period = round_time(self.char_results["min_period"])
@ -479,7 +452,51 @@ class lib:
self.lib.write(" }\n")
self.lib.write(" }\n")
self.lib.write(" }\n")
def add_clk_control_power(self, port):
"""Writes powers under the clock pin group for a specified port"""
#Web added to read/write ports. Likely to change when control logic finished.
web_name = ""
if port in self.write_ports:
if port in self.read_ports:
web_name = " & !WEb{0}".format(port)
avg_write_power = np.mean(self.char_results["write1_power{0}".format(port)] + self.char_results["write0_power{0}".format(port)])
self.lib.write(" internal_power(){\n")
self.lib.write(" when : \"!CSb{0} & clk{1}\"; \n".format(port, web_name))
self.lib.write(" rise_power(scalar){\n")
self.lib.write(" values(\"{0}\");\n".format(avg_write_power/2.0))
self.lib.write(" }\n")
self.lib.write(" fall_power(scalar){\n")
self.lib.write(" values(\"{0}\");\n".format(avg_write_power/2.0))
self.lib.write(" }\n")
self.lib.write(" }\n")
if port in self.read_ports:
if port in self.write_ports:
web_name = " & WEb{0}".format(port)
avg_read_power = np.mean(self.char_results["read1_power{0}".format(port)] + self.char_results["read0_power{0}".format(port)])
self.lib.write(" internal_power(){\n")
self.lib.write(" when : \"!CSb{0} & !clk{1}\"; \n".format(port, web_name))
self.lib.write(" rise_power(scalar){\n")
self.lib.write(" values(\"{0}\");\n".format(avg_read_power/2.0))
self.lib.write(" }\n")
self.lib.write(" fall_power(scalar){\n")
self.lib.write(" values(\"{0}\");\n".format(avg_read_power/2.0))
self.lib.write(" }\n")
self.lib.write(" }\n")
# Have 0 internal power when disabled, this will be represented as leakage power.
self.lib.write(" internal_power(){\n")
self.lib.write(" when : \"CSb{0}\"; \n".format(port))
self.lib.write(" rise_power(scalar){\n")
self.lib.write(" values(\"0\");\n")
self.lib.write(" }\n")
self.lib.write(" fall_power(scalar){\n")
self.lib.write(" values(\"0\");\n")
self.lib.write(" }\n")
self.lib.write(" }\n")
def compute_delay(self):
""" Do the analysis if we haven't characterized the SRAM yet """
if not hasattr(self,"d"):
@ -487,11 +504,6 @@ class lib:
if self.use_model:
self.char_results = self.d.analytical_delay(self.sram,self.slews,self.loads)
else:
#Temporary Workaround to here to set # of ports. Crashes if set in config file.
#OPTS.num_rw_ports = 0
#OPTS.num_r_ports = 1
#OPTS.num_w_ports = 1
probe_address = "1" * self.sram.addr_size
probe_data = self.sram.word_size - 1
self.char_results = self.d.analyze(probe_address, probe_data, self.slews, self.loads)

View File

@ -278,21 +278,21 @@ class setup_hold():
HL_hold = []
#For debugging, skips characterization and returns dummy values.
# i = 1.0
# for self.related_input_slew in related_slews:
# for self.constrained_input_slew in constrained_slews:
# LH_setup.append(i)
# HL_setup.append(i+1.0)
# LH_hold.append(i+2.0)
# HL_hold.append(i+3.0)
# i+=4.0
i = 1.0
for self.related_input_slew in related_slews:
for self.constrained_input_slew in constrained_slews:
LH_setup.append(i)
HL_setup.append(i+1.0)
LH_hold.append(i+2.0)
HL_hold.append(i+3.0)
i+=4.0
# times = {"setup_times_LH": LH_setup,
# "setup_times_HL": HL_setup,
# "hold_times_LH": LH_hold,
# "hold_times_HL": HL_hold
# }
# return times
times = {"setup_times_LH": LH_setup,
"setup_times_HL": HL_setup,
"hold_times_LH": LH_hold,
"hold_times_HL": HL_hold
}
return times
for self.related_input_slew in related_slews:

View File

@ -9,4 +9,3 @@ temperatures = [ 25 ]
output_path = "temp"
output_name = "sram_{0}_{1}_{2}_{3}".format(word_size,num_words,num_banks,tech_name)

View File

@ -184,8 +184,8 @@ class openram_test(unittest.TestCase):
# 4. Check if remaining string matches
if line1 != line2:
#Uncomment if you want to see all the individual chars of the two lines
print(str([i for i in line1]))
print(str([i for i in line2]))
#print(str([i for i in line1]))
#print(str([i for i in line2]))
if mismatches==0:
debug.error("Mismatching files:\nfile1={0}\nfile2={1}".format(filename1,filename2))
mismatches += 1