mirror of https://github.com/VLSIDA/OpenRAM.git
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:
parent
5dfa8bc2c6
commit
da6843af5b
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue