Skip to content

Liberty updates for power char and bus deinjfiotn #80

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 17 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion compiler/characterizer/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
if OPTS.spice_exe=="" or OPTS.spice_exe==None:
debug.error("{0} not found. Unable to perform characterization.".format(OPTS.spice_name),1)
else:
(OPTS.spice_name,OPTS.spice_exe) = get_tool("spice",["hspice", "ngspice", "ngspice.exe", "xa"])
(OPTS.spice_name,OPTS.spice_exe) = get_tool("spice",["hspice", "ngspice", "ngspice.exe", "xa", "alps"])

# set the input dir for spice files if using ngspice
if OPTS.spice_name == "ngspice":
Expand Down
3 changes: 3 additions & 0 deletions compiler/characterizer/charutils.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ def parse_spice_list(filename, key):
if OPTS.spice_name == "xa" :
# customsim has a different output file name
full_filename="{0}xa.meas".format(OPTS.openram_temp)
elif OPTS.spice_name == "alps":
# alps using a .measure
full_filename="{0}{1}.measure".format(OPTS.openram_temp, filename)
else:
# ngspice/hspice using a .lis file
full_filename="{0}{1}.lis".format(OPTS.openram_temp, filename)
Expand Down
6 changes: 3 additions & 3 deletions compiler/characterizer/delay.py
Original file line number Diff line number Diff line change
Expand Up @@ -581,8 +581,8 @@ def get_power_measure_variants(self, port, power_obj, operation):
"""Get the measurement values that can either vary port to port (time delays)"""

# Return value is intended to match the power measure format: t_initial, t_final, port
t_initial = self.cycle_times[self.measure_cycles[port][power_obj.meta_str]]
t_final = self.cycle_times[self.measure_cycles[port][power_obj.meta_str]+1]
t_initial = self.cycle_times[self.measure_cycles[port][power_obj.meta_str]]-self.slew/2-self.period*0.05
t_final = self.cycle_times[self.measure_cycles[port][power_obj.meta_str]+1]-self.slew/2-self.period*0.05

return (t_initial, t_final, port)

Expand Down Expand Up @@ -666,7 +666,7 @@ def write_power_measures(self):
t_final = 2*self.period
self.stim.gen_meas_power(meas_name="leakage_power",
t_initial=t_initial,
t_final=t_final)
t_final=t_final, leakage=True)

def find_feasible_period_one_port(self, port):
"""
Expand Down
15 changes: 9 additions & 6 deletions compiler/characterizer/lib.py
Original file line number Diff line number Diff line change
Expand Up @@ -325,25 +325,28 @@ def write_bus(self):
self.lib.write(" base_type : array;\n")
self.lib.write(" data_type : bit;\n")
self.lib.write(" bit_width : {0};\n".format(self.sram.word_size))
self.lib.write(" bit_from : 0;\n")
self.lib.write(" bit_to : {0};\n".format(self.sram.word_size - 1))
self.lib.write(" bit_from : {0};\n".format(self.sram.word_size - 1))
self.lib.write(" bit_to : 0;\n")
self.lib.write(" downto : true;\n")
self.lib.write(" }\n\n")

self.lib.write(" type (addr){\n")
self.lib.write(" base_type : array;\n")
self.lib.write(" data_type : bit;\n")
self.lib.write(" bit_width : {0};\n".format(self.sram.addr_size))
self.lib.write(" bit_from : 0;\n")
self.lib.write(" bit_to : {0};\n".format(self.sram.addr_size - 1))
self.lib.write(" bit_from : {0};\n".format(self.sram.addr_size - 1))
self.lib.write(" bit_to : 0;\n")
self.lib.write(" downto : true;\n")
self.lib.write(" }\n\n")

if self.sram.write_size:
self.lib.write(" type (wmask){\n")
self.lib.write(" base_type : array;\n")
self.lib.write(" data_type : bit;\n")
self.lib.write(" bit_width : {0};\n".format(self.sram.num_wmasks))
self.lib.write(" bit_from : 0;\n")
self.lib.write(" bit_to : {0};\n".format(self.sram.num_wmasks - 1))
self.lib.write(" bit_from : {0};\n".format(self.sram.num_wmasks - 1))
self.lib.write(" bit_to : 0;\n")
self.lib.write(" downto : true;\n")
self.lib.write(" }\n\n")


Expand Down
39 changes: 30 additions & 9 deletions compiler/characterizer/stimuli.py
Original file line number Diff line number Diff line change
Expand Up @@ -192,18 +192,29 @@ def gen_meas_find_voltage_at_time(self, meas_name, targ_name, time_at):
targ_name,
time_at))

def gen_meas_power(self, meas_name, t_initial, t_final):
def gen_meas_power(self, meas_name, t_initial, t_final, leakage=False):
""" Creates the .meas statement for the measurement of avg power """
# power mea cmd is different in different spice:
if OPTS.spice_name == "hspice":
power_exp = "power"
else:
power_exp = "par('(-1*v(" + str(self.vdd_name) + ")*I(v" + str(self.vdd_name) + "))')"
self.sf.write(".meas tran {0} avg {1} from={2}n to={3}n\n\n".format(meas_name,
power_exp,
t_initial,
t_final))

if leakage:
self.sf.write(".meas tran {0} avg {1} from={2}n to={3}n\n".format(meas_name,
power_exp,
t_initial,
t_final))
else:
self.sf.write(".meas tran {0}_total avg {1} from={2}n to={3}n\n".format(meas_name,
power_exp,
t_initial,
t_final))
self.sf.write(".meas tran {0}_leakage avg {1} from={2}n to={3}n\n".format(meas_name,
power_exp,
t_final-0.05*(t_final-t_initial),
t_final))
self.sf.write(".meas tran {0} param='{0}_total - {0}_leakage'\n\n".format(meas_name))

def gen_meas_value(self, meas_name, dout, t_intital, t_final):
measure_string=".meas tran {0} AVG v({1}) FROM={2}n TO={3}n\n\n".format(meas_name, dout, t_intital, t_final)
self.sf.write(measure_string)
Expand All @@ -230,9 +241,11 @@ def write_control(self, end_time, runlvl=4):
# which is more accurate, but slower than the default trapezoid method
# Do not remove this or it may not converge due to some "pa_00" nodes
# unless you figure out what these are.
self.sf.write(".OPTIONS POST=1 RELTOL={0} PROBE method=gear\n".format(reltol))
self.sf.write(".OPTIONS POST={1} RELTOL={0} PROBE method=gear\n".format(reltol, 0 if OPTS.purge_temp else 1))
elif OPTS.spice_name == "alps":
self.sf.write(".OPTIONS POST={2} RUNLVL={0} RELTOL={1} PROBE LEAST_DISK_SPACE=2000\n".format(runlvl, reltol, 0 if OPTS.purge_temp else 1))
else:
self.sf.write(".OPTIONS POST=1 RUNLVL={0} PROBE\n".format(runlvl))
self.sf.write(".OPTIONS POST={1} RUNLVL={0} PROBE\n".format(runlvl, 0 if OPTS.purge_temp else 1))

# create plots for all signals
self.sf.write("* probe is used for hspice/xa, while plot is used in ngspice\n")
Expand Down Expand Up @@ -297,7 +310,15 @@ def run_sim(self):
valid_retcode=0
elif OPTS.spice_name == "hspice":
# TODO: Should make multithreading parameter a configuration option
cmd = "{0} -mt 2 -i {1} -o {2}timing".format(OPTS.spice_exe,
cmd = "{0} -mt {1} -i {2} -o {3}timing".format(OPTS.spice_exe,
OPTS.num_threads,
temp_stim,
OPTS.openram_temp)
valid_retcode=0
elif OPTS.spice_name == "alps":
# TODO: Should make multithreading parameter a configuration option
cmd = "{0} -mt {1} -i {2} -o {3}timing".format(OPTS.spice_exe,
OPTS.num_threads,
temp_stim,
OPTS.openram_temp)
valid_retcode=0
Expand Down
6 changes: 5 additions & 1 deletion compiler/globals.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,11 @@ def parse_args():
"--dontpurge",
action="store_false",
dest="purge_temp",
help="Don't purge the contents of the temp directory after a successful run")
help="Don't purge the contents of the temp directory after a successful run"),
optparse.make_option(
"--num_threads",
dest="num_threads",
help="Number of threads used by simulator. Default is 2")
# -h --help is implicit.
}

Expand Down
3 changes: 3 additions & 0 deletions compiler/options.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,9 @@ class options(optparse.Values):
spice_name = ""
# The spice executable being used which is derived from the user PATH.
spice_exe = ""

# Thread number for hspice and alps
num_threads = 2
# Variable to select the variant of drc, lvs, pex
drc_name = ""
lvs_name = ""
Expand Down
2 changes: 2 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
numpy
scipy