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)
|
# sys.exit(1)
|
||||||
|
|
||||||
#For debugging, skips characterization and returns dummy values.
|
#For debugging, skips characterization and returns dummy values.
|
||||||
# i = 1.0
|
char_data = self.char_data
|
||||||
# for slew in slews:
|
i = 1.0
|
||||||
# for load in loads:
|
for slew in slews:
|
||||||
# for k,v in char_data.items():
|
for load in loads:
|
||||||
# char_data[k].append(i)
|
for k,v in char_data.items():
|
||||||
# i+=1.0
|
char_data[k].append(i)
|
||||||
# char_data["min_period"] = i
|
i+=1.0
|
||||||
# char_data["leakage_power"] = i+1.0
|
char_data["min_period"] = i
|
||||||
# return char_data
|
char_data["leakage_power"] = i+1.0
|
||||||
|
return char_data
|
||||||
|
|
||||||
# 1) Find a feasible period and it's corresponding delays using the trimmed array.
|
# 1) Find a feasible period and it's corresponding delays using the trimmed array.
|
||||||
(feasible_delays_lh, feasible_delays_hl) = self.find_feasible_period()
|
(feasible_delays_lh, feasible_delays_hl) = self.find_feasible_period()
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,11 @@ class lib:
|
||||||
""" lib file generation."""
|
""" lib file generation."""
|
||||||
|
|
||||||
def __init__(self, out_dir, sram, sp_file, use_model=OPTS.analytical_delay):
|
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.out_dir = out_dir
|
||||||
self.sram = sram
|
self.sram = sram
|
||||||
self.sp_file = sp_file
|
self.sp_file = sp_file
|
||||||
|
|
@ -112,7 +117,7 @@ class lib:
|
||||||
self.write_addr_bus(port)
|
self.write_addr_bus(port)
|
||||||
self.write_control_pins(port) #need to split this into sram and port control signals
|
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()
|
self.write_footer()
|
||||||
|
|
||||||
|
|
@ -409,8 +414,7 @@ class lib:
|
||||||
self.write_FF_setuphold()
|
self.write_FF_setuphold()
|
||||||
self.lib.write(" }\n\n")
|
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):
|
||||||
def write_clk_timing_power(self, port):
|
|
||||||
""" Adds clk pin timing results."""
|
""" Adds clk pin timing results."""
|
||||||
|
|
||||||
self.lib.write(" pin(clk){\n")
|
self.lib.write(" pin(clk){\n")
|
||||||
|
|
@ -419,41 +423,10 @@ class lib:
|
||||||
# FIXME: This depends on the clock buffer size in the control logic
|
# FIXME: This depends on the clock buffer size in the control logic
|
||||||
self.lib.write(" capacitance : {0}; \n".format(tech.spice["dff_in_cap"]))
|
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
|
#Add power values for the ports. lib generated with this is not syntactically correct. TODO once
|
||||||
# Could make it a table, but this is fine for now.
|
#top level is done
|
||||||
avg_write_power = np.mean(self.char_results["write1_power{0}".format(port)] + self.char_results["write0_power{0}".format(port)])
|
for port in range(self.total_port_num):
|
||||||
avg_read_power = np.mean(self.char_results["read1_power{0}".format(port)] + self.char_results["read0_power{0}".format(port)])
|
self.add_clk_control_power(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")
|
|
||||||
|
|
||||||
min_pulse_width = round_time(self.char_results["min_period"])/2.0
|
min_pulse_width = round_time(self.char_results["min_period"])/2.0
|
||||||
min_period = round_time(self.char_results["min_period"])
|
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")
|
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):
|
def compute_delay(self):
|
||||||
""" Do the analysis if we haven't characterized the SRAM yet """
|
""" Do the analysis if we haven't characterized the SRAM yet """
|
||||||
if not hasattr(self,"d"):
|
if not hasattr(self,"d"):
|
||||||
|
|
@ -487,11 +504,6 @@ class lib:
|
||||||
if self.use_model:
|
if self.use_model:
|
||||||
self.char_results = self.d.analytical_delay(self.sram,self.slews,self.loads)
|
self.char_results = self.d.analytical_delay(self.sram,self.slews,self.loads)
|
||||||
else:
|
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_address = "1" * self.sram.addr_size
|
||||||
probe_data = self.sram.word_size - 1
|
probe_data = self.sram.word_size - 1
|
||||||
self.char_results = self.d.analyze(probe_address, probe_data, self.slews, self.loads)
|
self.char_results = self.d.analyze(probe_address, probe_data, self.slews, self.loads)
|
||||||
|
|
|
||||||
|
|
@ -278,21 +278,21 @@ class setup_hold():
|
||||||
HL_hold = []
|
HL_hold = []
|
||||||
|
|
||||||
#For debugging, skips characterization and returns dummy values.
|
#For debugging, skips characterization and returns dummy values.
|
||||||
# i = 1.0
|
i = 1.0
|
||||||
# for self.related_input_slew in related_slews:
|
for self.related_input_slew in related_slews:
|
||||||
# for self.constrained_input_slew in constrained_slews:
|
for self.constrained_input_slew in constrained_slews:
|
||||||
# LH_setup.append(i)
|
LH_setup.append(i)
|
||||||
# HL_setup.append(i+1.0)
|
HL_setup.append(i+1.0)
|
||||||
# LH_hold.append(i+2.0)
|
LH_hold.append(i+2.0)
|
||||||
# HL_hold.append(i+3.0)
|
HL_hold.append(i+3.0)
|
||||||
# i+=4.0
|
i+=4.0
|
||||||
|
|
||||||
# times = {"setup_times_LH": LH_setup,
|
times = {"setup_times_LH": LH_setup,
|
||||||
# "setup_times_HL": HL_setup,
|
"setup_times_HL": HL_setup,
|
||||||
# "hold_times_LH": LH_hold,
|
"hold_times_LH": LH_hold,
|
||||||
# "hold_times_HL": HL_hold
|
"hold_times_HL": HL_hold
|
||||||
# }
|
}
|
||||||
# return times
|
return times
|
||||||
|
|
||||||
|
|
||||||
for self.related_input_slew in related_slews:
|
for self.related_input_slew in related_slews:
|
||||||
|
|
|
||||||
|
|
@ -9,4 +9,3 @@ temperatures = [ 25 ]
|
||||||
|
|
||||||
output_path = "temp"
|
output_path = "temp"
|
||||||
output_name = "sram_{0}_{1}_{2}_{3}".format(word_size,num_words,num_banks,tech_name)
|
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
|
# 4. Check if remaining string matches
|
||||||
if line1 != line2:
|
if line1 != line2:
|
||||||
#Uncomment if you want to see all the individual chars of the two lines
|
#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 line1]))
|
||||||
print(str([i for i in line2]))
|
#print(str([i for i in line2]))
|
||||||
if mismatches==0:
|
if mismatches==0:
|
||||||
debug.error("Mismatching files:\nfile1={0}\nfile2={1}".format(filename1,filename2))
|
debug.error("Mismatching files:\nfile1={0}\nfile2={1}".format(filename1,filename2))
|
||||||
mismatches += 1
|
mismatches += 1
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue