mirror of
https://github.com/VLSIDA/OpenRAM.git
synced 2026-09-07 11:21:14 +02:00
Convert entire OpenRAM to use python3. Works with Python 3.6.
Major changes: Remove mpmath library and use numpy instead. Convert bytes to new bytearrays. Fix class name check for duplicate gds instances. Add explicit integer conversion from floats. Fix importlib reload from importlib library Fix new key/index syntax issues. Fix filter and map conversion to lists. Fix deprecation warnings. Fix Circuits vs Netlist in Magic LVS results. Fix file closing warnings.
This commit is contained in:
@@ -1,9 +1,9 @@
|
||||
import os
|
||||
import debug
|
||||
from globals import OPTS,find_exe,get_tool
|
||||
import lib
|
||||
import delay
|
||||
import setup_hold
|
||||
from .lib import *
|
||||
from .delay import *
|
||||
from .setup_hold import *
|
||||
|
||||
|
||||
debug.info(2,"Initializing characterizer...")
|
||||
|
||||
@@ -2,9 +2,9 @@ import sys,re,shutil
|
||||
import debug
|
||||
import tech
|
||||
import math
|
||||
import stimuli
|
||||
from trim_spice import trim_spice
|
||||
import charutils as ch
|
||||
from .stimuli import *
|
||||
from .trim_spice import *
|
||||
from .charutils import *
|
||||
import utils
|
||||
from globals import OPTS
|
||||
|
||||
@@ -101,7 +101,7 @@ class delay():
|
||||
self.sf.write("* Delay stimulus for period of {0}n load={1}fF slew={2}ns\n\n".format(self.period,
|
||||
self.load,
|
||||
self.slew))
|
||||
self.stim = stimuli.stimuli(self.sf, self.corner)
|
||||
self.stim = stimuli(self.sf, self.corner)
|
||||
# include files in stimulus file
|
||||
self.stim.write_include(self.trim_sp_file)
|
||||
|
||||
@@ -339,16 +339,16 @@ class delay():
|
||||
# Checking from not data_value to data_value
|
||||
self.write_delay_stimulus()
|
||||
self.stim.run_sim()
|
||||
delay_hl = ch.parse_output("timing", "delay_hl")
|
||||
delay_lh = ch.parse_output("timing", "delay_lh")
|
||||
slew_hl = ch.parse_output("timing", "slew_hl")
|
||||
slew_lh = ch.parse_output("timing", "slew_lh")
|
||||
delay_hl = parse_output("timing", "delay_hl")
|
||||
delay_lh = parse_output("timing", "delay_lh")
|
||||
slew_hl = parse_output("timing", "slew_hl")
|
||||
slew_lh = parse_output("timing", "slew_lh")
|
||||
delays = (delay_hl, delay_lh, slew_hl, slew_lh)
|
||||
|
||||
read0_power=ch.parse_output("timing", "read0_power")
|
||||
write0_power=ch.parse_output("timing", "write0_power")
|
||||
read1_power=ch.parse_output("timing", "read1_power")
|
||||
write1_power=ch.parse_output("timing", "write1_power")
|
||||
read0_power=parse_output("timing", "read0_power")
|
||||
write0_power=parse_output("timing", "write0_power")
|
||||
read1_power=parse_output("timing", "read1_power")
|
||||
write1_power=parse_output("timing", "write1_power")
|
||||
|
||||
if not self.check_valid_delays(delays):
|
||||
return (False,{})
|
||||
@@ -378,22 +378,24 @@ class delay():
|
||||
|
||||
self.write_power_stimulus(trim=False)
|
||||
self.stim.run_sim()
|
||||
leakage_power=ch.parse_output("timing", "leakage_power")
|
||||
leakage_power=parse_output("timing", "leakage_power")
|
||||
debug.check(leakage_power!="Failed","Could not measure leakage power.")
|
||||
|
||||
|
||||
self.write_power_stimulus(trim=True)
|
||||
self.stim.run_sim()
|
||||
trim_leakage_power=ch.parse_output("timing", "leakage_power")
|
||||
trim_leakage_power=parse_output("timing", "leakage_power")
|
||||
debug.check(trim_leakage_power!="Failed","Could not measure leakage power.")
|
||||
|
||||
# For debug, you sometimes want to inspect each simulation.
|
||||
#key=raw_input("press return to continue")
|
||||
return (leakage_power*1e3, trim_leakage_power*1e3)
|
||||
|
||||
def check_valid_delays(self, (delay_hl, delay_lh, slew_hl, slew_lh)):
|
||||
def check_valid_delays(self, delay_tuple):
|
||||
""" Check if the measurements are defined and if they are valid. """
|
||||
|
||||
(delay_hl, delay_lh, slew_hl, slew_lh) = delay_tuple
|
||||
|
||||
# if it failed or the read was longer than a period
|
||||
if type(delay_hl)!=float or type(delay_lh)!=float or type(slew_lh)!=float or type(slew_hl)!=float:
|
||||
debug.info(2,"Failed simulation: period {0} load {1} slew {2}, delay_hl={3}n delay_lh={4}ns slew_hl={5}n slew_lh={6}n".format(self.period,
|
||||
@@ -457,7 +459,7 @@ class delay():
|
||||
else:
|
||||
lb_period = target_period
|
||||
|
||||
if ch.relative_compare(ub_period, lb_period, error_tolerance=0.05):
|
||||
if relative_compare(ub_period, lb_period, error_tolerance=0.05):
|
||||
# ub_period is always feasible
|
||||
return ub_period
|
||||
|
||||
@@ -471,10 +473,10 @@ class delay():
|
||||
# Checking from not data_value to data_value
|
||||
self.write_delay_stimulus()
|
||||
self.stim.run_sim()
|
||||
delay_hl = ch.parse_output("timing", "delay_hl")
|
||||
delay_lh = ch.parse_output("timing", "delay_lh")
|
||||
slew_hl = ch.parse_output("timing", "slew_hl")
|
||||
slew_lh = ch.parse_output("timing", "slew_lh")
|
||||
delay_hl = parse_output("timing", "delay_hl")
|
||||
delay_lh = parse_output("timing", "delay_lh")
|
||||
slew_hl = parse_output("timing", "slew_hl")
|
||||
slew_lh = parse_output("timing", "slew_lh")
|
||||
# if it failed or the read was longer than a period
|
||||
if type(delay_hl)!=float or type(delay_lh)!=float or type(slew_lh)!=float or type(slew_hl)!=float:
|
||||
debug.info(2,"Invalid measures: Period {0}, delay_hl={1}ns, delay_lh={2}ns slew_hl={3}ns slew_lh={4}ns".format(self.period,
|
||||
@@ -495,10 +497,10 @@ class delay():
|
||||
slew_lh))
|
||||
return False
|
||||
else:
|
||||
if not ch.relative_compare(delay_lh,feasible_delay_lh,error_tolerance=0.05):
|
||||
if not relative_compare(delay_lh,feasible_delay_lh,error_tolerance=0.05):
|
||||
debug.info(2,"Delay too big {0} vs {1}".format(delay_lh,feasible_delay_lh))
|
||||
return False
|
||||
elif not ch.relative_compare(delay_hl,feasible_delay_hl,error_tolerance=0.05):
|
||||
elif not relative_compare(delay_hl,feasible_delay_hl,error_tolerance=0.05):
|
||||
debug.info(2,"Delay too big {0} vs {1}".format(delay_hl,feasible_delay_hl))
|
||||
return False
|
||||
|
||||
@@ -602,7 +604,7 @@ class delay():
|
||||
debug.info(1, "Min Period: {0}n with a delay of {1} / {2}".format(min_period, feasible_delay_lh, feasible_delay_hl))
|
||||
|
||||
# 4) Pack up the final measurements
|
||||
char_data["min_period"] = ch.round_time(min_period)
|
||||
char_data["min_period"] = round_time(min_period)
|
||||
|
||||
return char_data
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import os,sys,re
|
||||
import debug
|
||||
import math
|
||||
import setup_hold
|
||||
import delay
|
||||
import charutils as ch
|
||||
from .setup_hold import *
|
||||
from .delay import *
|
||||
from .charutils import *
|
||||
import tech
|
||||
import numpy as np
|
||||
from globals import OPTS
|
||||
@@ -186,9 +186,9 @@ class lib:
|
||||
""" Helper function to create quoted, line wrapped array with each row of given length """
|
||||
# check that the length is a multiple or give an error!
|
||||
debug.check(len(values)%length == 0,"Values are not a multiple of the length. Cannot make a full array.")
|
||||
rounded_values = map(ch.round_time,values)
|
||||
rounded_values = list(map(round_time,values))
|
||||
split_values = [rounded_values[i:i+length] for i in range(0, len(rounded_values), length)]
|
||||
formatted_rows = map(self.create_list,split_values)
|
||||
formatted_rows = list(map(self.create_list,split_values))
|
||||
formatted_array = ",\\\n".join(formatted_rows)
|
||||
return formatted_array
|
||||
|
||||
@@ -274,11 +274,11 @@ class lib:
|
||||
self.lib.write(" timing_type : setup_rising; \n")
|
||||
self.lib.write(" related_pin : \"clk\"; \n")
|
||||
self.lib.write(" rise_constraint(CONSTRAINT_TABLE) {\n")
|
||||
rounded_values = map(ch.round_time,self.times["setup_times_LH"])
|
||||
rounded_values = list(map(round_time,self.times["setup_times_LH"]))
|
||||
self.write_values(rounded_values,len(self.slews)," ")
|
||||
self.lib.write(" }\n")
|
||||
self.lib.write(" fall_constraint(CONSTRAINT_TABLE) {\n")
|
||||
rounded_values = map(ch.round_time,self.times["setup_times_HL"])
|
||||
rounded_values = list(map(round_time,self.times["setup_times_HL"]))
|
||||
self.write_values(rounded_values,len(self.slews)," ")
|
||||
self.lib.write(" }\n")
|
||||
self.lib.write(" }\n")
|
||||
@@ -286,11 +286,11 @@ class lib:
|
||||
self.lib.write(" timing_type : hold_rising; \n")
|
||||
self.lib.write(" related_pin : \"clk\"; \n")
|
||||
self.lib.write(" rise_constraint(CONSTRAINT_TABLE) {\n")
|
||||
rounded_values = map(ch.round_time,self.times["hold_times_LH"])
|
||||
rounded_values = list(map(round_time,self.times["hold_times_LH"]))
|
||||
self.write_values(rounded_values,len(self.slews)," ")
|
||||
self.lib.write(" }\n")
|
||||
self.lib.write(" fall_constraint(CONSTRAINT_TABLE) {\n")
|
||||
rounded_values = map(ch.round_time,self.times["hold_times_HL"])
|
||||
rounded_values = list(map(round_time,self.times["hold_times_HL"]))
|
||||
self.write_values(rounded_values,len(self.slews)," ")
|
||||
self.lib.write(" }\n")
|
||||
self.lib.write(" }\n")
|
||||
@@ -413,8 +413,8 @@ class lib:
|
||||
self.lib.write(" }\n")
|
||||
self.lib.write(" }\n")
|
||||
|
||||
min_pulse_width = ch.round_time(self.char_results["min_period"])/2.0
|
||||
min_period = ch.round_time(self.char_results["min_period"])
|
||||
min_pulse_width = round_time(self.char_results["min_period"])/2.0
|
||||
min_period = round_time(self.char_results["min_period"])
|
||||
self.lib.write(" timing(){ \n")
|
||||
self.lib.write(" timing_type :\"min_pulse_width\"; \n")
|
||||
self.lib.write(" related_pin : clk; \n")
|
||||
@@ -443,7 +443,7 @@ class lib:
|
||||
try:
|
||||
self.d
|
||||
except AttributeError:
|
||||
self.d = delay.delay(self.sram, self.sp_file, self.corner)
|
||||
self.d = delay(self.sram, self.sp_file, self.corner)
|
||||
if self.use_model:
|
||||
self.char_results = self.d.analytical_delay(self.sram,self.slews,self.loads)
|
||||
else:
|
||||
@@ -458,7 +458,7 @@ class lib:
|
||||
try:
|
||||
self.sh
|
||||
except AttributeError:
|
||||
self.sh = setup_hold.setup_hold(self.corner)
|
||||
self.sh = setup_hold(self.corner)
|
||||
if self.use_model:
|
||||
self.times = self.sh.analytical_setuphold(self.slews,self.loads)
|
||||
else:
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import sys
|
||||
import tech
|
||||
import stimuli
|
||||
from .stimuli import *
|
||||
import debug
|
||||
import charutils as ch
|
||||
from .charutils import *
|
||||
import ms_flop
|
||||
from globals import OPTS
|
||||
|
||||
@@ -38,7 +38,7 @@ class setup_hold():
|
||||
# creates and opens the stimulus file for writing
|
||||
temp_stim = OPTS.openram_temp + "stim.sp"
|
||||
self.sf = open(temp_stim, "w")
|
||||
self.stim = stimuli.stimuli(self.sf, self.corner)
|
||||
self.stim = stimuli(self.sf, self.corner)
|
||||
|
||||
self.write_header(correct_value)
|
||||
|
||||
@@ -186,8 +186,8 @@ class setup_hold():
|
||||
target_time=feasible_bound,
|
||||
correct_value=correct_value)
|
||||
self.stim.run_sim()
|
||||
ideal_clk_to_q = ch.convert_to_float(ch.parse_output("timing", "clk2q_delay"))
|
||||
setuphold_time = ch.convert_to_float(ch.parse_output("timing", "setup_hold_time"))
|
||||
ideal_clk_to_q = convert_to_float(parse_output("timing", "clk2q_delay"))
|
||||
setuphold_time = convert_to_float(parse_output("timing", "setup_hold_time"))
|
||||
debug.info(2,"*** {0} CHECK: {1} Ideal Clk-to-Q: {2} Setup/Hold: {3}".format(mode, correct_value,ideal_clk_to_q,setuphold_time))
|
||||
|
||||
if type(ideal_clk_to_q)!=float or type(setuphold_time)!=float:
|
||||
@@ -219,8 +219,8 @@ class setup_hold():
|
||||
|
||||
|
||||
self.stim.run_sim()
|
||||
clk_to_q = ch.convert_to_float(ch.parse_output("timing", "clk2q_delay"))
|
||||
setuphold_time = ch.convert_to_float(ch.parse_output("timing", "setup_hold_time"))
|
||||
clk_to_q = convert_to_float(parse_output("timing", "clk2q_delay"))
|
||||
setuphold_time = convert_to_float(parse_output("timing", "setup_hold_time"))
|
||||
if type(clk_to_q)==float and (clk_to_q<1.1*ideal_clk_to_q) and type(setuphold_time)==float:
|
||||
if mode == "SETUP": # SETUP is clk-din, not din-clk
|
||||
setuphold_time *= -1e9
|
||||
@@ -235,7 +235,7 @@ class setup_hold():
|
||||
infeasible_bound = target_time
|
||||
|
||||
#raw_input("Press Enter to continue...")
|
||||
if ch.relative_compare(feasible_bound, infeasible_bound, error_tolerance=0.001):
|
||||
if relative_compare(feasible_bound, infeasible_bound, error_tolerance=0.001):
|
||||
debug.info(3,"CONVERGE {0} vs {1}".format(feasible_bound,infeasible_bound))
|
||||
break
|
||||
|
||||
|
||||
Reference in New Issue
Block a user