mirror of https://github.com/VLSIDA/OpenRAM.git
Add multiple process corners. Unit tests use nominal corner only. Add fake SCMOS nominal models, but they are broken.
This commit is contained in:
parent
1795dc5677
commit
a12ebeed9f
|
|
@ -26,8 +26,7 @@ class stimuli():
|
||||||
|
|
||||||
self.sf = stim_file
|
self.sf = stim_file
|
||||||
|
|
||||||
(self.process, self.vdd_voltage, self.temperature) = corner
|
(self.process, self.voltage, self.temperature) = corner
|
||||||
self.gnd_voltage = 0
|
|
||||||
self.device_models = tech.spice["fet_models"][self.process]
|
self.device_models = tech.spice["fet_models"][self.process]
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -158,7 +157,7 @@ class stimuli():
|
||||||
|
|
||||||
# shift signal times earlier for setup time
|
# shift signal times earlier for setup time
|
||||||
times = np.array(clk_times) - setup*period
|
times = np.array(clk_times) - setup*period
|
||||||
values = np.array(data_values) * self.vdd_voltage
|
values = np.array(data_values) * self.voltage
|
||||||
half_slew = 0.5 * slew
|
half_slew = 0.5 * slew
|
||||||
self.sf.write("* (time, data): {}\n".format(zip(clk_times, data_values)))
|
self.sf.write("* (time, data): {}\n".format(zip(clk_times, data_values)))
|
||||||
self.sf.write("V{0} {0} 0 PWL (0n {1}v ".format(sig_name, values[0]))
|
self.sf.write("V{0} {0} 0 PWL (0n {1}v ".format(sig_name, values[0]))
|
||||||
|
|
@ -174,10 +173,10 @@ class stimuli():
|
||||||
self.sf.write("V{0} {0} 0 DC {1}\n".format(sig_name, v_val))
|
self.sf.write("V{0} {0} 0 DC {1}\n".format(sig_name, v_val))
|
||||||
|
|
||||||
def get_inverse_voltage(self, value):
|
def get_inverse_voltage(self, value):
|
||||||
if value > 0.5*self.vdd_voltage:
|
if value > 0.5*self.voltage:
|
||||||
return self.gnd_voltage
|
return 0
|
||||||
elif value <= 0.5*self.vdd_voltage:
|
elif value <= 0.5*self.voltage:
|
||||||
return self.vdd_voltage
|
return self.voltage
|
||||||
else:
|
else:
|
||||||
debug.error("Invalid value to get an inverse of: {0}".format(value))
|
debug.error("Invalid value to get an inverse of: {0}".format(value))
|
||||||
|
|
||||||
|
|
@ -256,11 +255,11 @@ class stimuli():
|
||||||
|
|
||||||
def write_supply(self):
|
def write_supply(self):
|
||||||
""" Writes supply voltage statements """
|
""" Writes supply voltage statements """
|
||||||
self.sf.write("V{0} {0} 0.0 {1}\n".format(self.vdd_name, self.vdd_voltage))
|
self.sf.write("V{0} {0} 0.0 {1}\n".format(self.vdd_name, self.voltage))
|
||||||
self.sf.write("V{0} {0} 0.0 {1}\n".format(self.gnd_name, self.gnd_voltage))
|
self.sf.write("V{0} {0} 0.0 {1}\n".format(self.gnd_name, 0))
|
||||||
# This is for the test power supply
|
# This is for the test power supply
|
||||||
self.sf.write("V{0} {0} 0.0 {1}\n".format("test"+self.vdd_name, self.vdd_voltage))
|
self.sf.write("V{0} {0} 0.0 {1}\n".format("test"+self.vdd_name, self.voltage))
|
||||||
self.sf.write("V{0} {0} 0.0 {1}\n".format("test"+self.gnd_name, self.gnd_voltage))
|
self.sf.write("V{0} {0} 0.0 {1}\n".format("test"+self.gnd_name, 0))
|
||||||
|
|
||||||
|
|
||||||
def run_sim(self):
|
def run_sim(self):
|
||||||
|
|
|
||||||
|
|
@ -291,11 +291,11 @@ def import_tech():
|
||||||
import tech
|
import tech
|
||||||
# Set some default options now based on the technology...
|
# Set some default options now based on the technology...
|
||||||
if (OPTS.process_corners == ""):
|
if (OPTS.process_corners == ""):
|
||||||
OPTS.process_corners = [tech.spice["nom_corner"][0]]
|
OPTS.process_corners = tech.spice["fet_models"].keys()
|
||||||
if (OPTS.supply_voltages == ""):
|
if (OPTS.supply_voltages == ""):
|
||||||
OPTS.supply_voltages = [tech.spice["nom_corner"][1]]
|
OPTS.supply_voltages = tech.spice["supply_voltages"]
|
||||||
if (OPTS.temperatures == ""):
|
if (OPTS.temperatures == ""):
|
||||||
OPTS.temperatures = [tech.spice["nom_corner"][2]]
|
OPTS.temperatures = tech.spice["temperatures"]
|
||||||
|
|
||||||
|
|
||||||
def print_time(name, now_time, last_time=None):
|
def print_time(name, now_time, last_time=None):
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,8 @@ class timing_sram_test(openram_test):
|
||||||
probe_data = s.word_size - 1
|
probe_data = s.word_size - 1
|
||||||
debug.info(1, "Probe address {0} probe data {1}".format(probe_address, probe_data))
|
debug.info(1, "Probe address {0} probe data {1}".format(probe_address, probe_data))
|
||||||
|
|
||||||
d = delay.delay(s,tempspice,tech.spice["nom_corner"])
|
corner = (OPTS.process_corners[0], OPTS.supply_voltages[0], OPTS.temperatures[0])
|
||||||
|
d = delay.delay(s,tempspice,corner)
|
||||||
import tech
|
import tech
|
||||||
loads = [tech.spice["msflop_in_cap"]*4]
|
loads = [tech.spice["msflop_in_cap"]*4]
|
||||||
slews = [tech.spice["rise_time"]*2]
|
slews = [tech.spice["rise_time"]*2]
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,8 @@ class timing_setup_test(openram_test):
|
||||||
import tech
|
import tech
|
||||||
slews = [tech.spice["rise_time"]*2]
|
slews = [tech.spice["rise_time"]*2]
|
||||||
|
|
||||||
sh = setup_hold.setup_hold(tech.spice["nom_corner"])
|
corner = (OPTS.process_corners[0], OPTS.supply_voltages[0], OPTS.temperatures[0])
|
||||||
|
sh = setup_hold.setup_hold(corner)
|
||||||
data = sh.analyze(slews,slews)
|
data = sh.analyze(slews,slews)
|
||||||
|
|
||||||
if OPTS.tech_name == "freepdk45":
|
if OPTS.tech_name == "freepdk45":
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,8 @@ class timing_sram_test(openram_test):
|
||||||
probe_data = s.word_size - 1
|
probe_data = s.word_size - 1
|
||||||
debug.info(1, "Probe address {0} probe data {1}".format(probe_address, probe_data))
|
debug.info(1, "Probe address {0} probe data {1}".format(probe_address, probe_data))
|
||||||
|
|
||||||
d = delay.delay(s,tempspice,tech.spice["nom_corner"])
|
corner = (OPTS.process_corners[0], OPTS.supply_voltages[0], OPTS.temperatures[0])
|
||||||
|
d = delay.delay(s,tempspice,corner)
|
||||||
import tech
|
import tech
|
||||||
loads = [tech.spice["msflop_in_cap"]*4]
|
loads = [tech.spice["msflop_in_cap"]*4]
|
||||||
slews = [tech.spice["rise_time"]*2]
|
slews = [tech.spice["rise_time"]*2]
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,8 @@ class timing_setup_test(openram_test):
|
||||||
import tech
|
import tech
|
||||||
slews = [tech.spice["rise_time"]*2]
|
slews = [tech.spice["rise_time"]*2]
|
||||||
|
|
||||||
sh = setup_hold.setup_hold(tech.spice["nom_corner"])
|
corner = (OPTS.process_corners[0], OPTS.supply_voltages[0], OPTS.temperatures[0])
|
||||||
|
sh = setup_hold.setup_hold(corner)
|
||||||
data = sh.analyze(slews,slews)
|
data = sh.analyze(slews,slews)
|
||||||
|
|
||||||
if OPTS.tech_name == "freepdk45":
|
if OPTS.tech_name == "freepdk45":
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,8 @@ class sram_func_test(openram_test):
|
||||||
probe_data = s.word_size - 1
|
probe_data = s.word_size - 1
|
||||||
debug.info(1, "Probe address {0} probe data {1}".format(probe_address, probe_data))
|
debug.info(1, "Probe address {0} probe data {1}".format(probe_address, probe_data))
|
||||||
|
|
||||||
d = delay.delay(s,tempspice,tech.spice["nom_corner"])
|
corner = (OPTS.process_corners[0], OPTS.supply_voltages[0], OPTS.temperatures[0])
|
||||||
|
d = delay.delay(s,tempspice,corner)
|
||||||
d.set_probe(probe_address,probe_data)
|
d.set_probe(probe_address,probe_data)
|
||||||
|
|
||||||
# This will exit if it doesn't find a feasible period
|
# This will exit if it doesn't find a feasible period
|
||||||
|
|
|
||||||
|
|
@ -3,5 +3,8 @@ num_words = 16
|
||||||
num_banks = 1
|
num_banks = 1
|
||||||
|
|
||||||
tech_name = "freepdk45"
|
tech_name = "freepdk45"
|
||||||
|
process_corners = ["TT"]
|
||||||
|
supply_voltages = [1.0]
|
||||||
|
temperatures = [25]
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,4 +3,7 @@ num_words = 16
|
||||||
num_banks = 1
|
num_banks = 1
|
||||||
|
|
||||||
tech_name = "scn3me_subm"
|
tech_name = "scn3me_subm"
|
||||||
|
process_corners = ["TT"]
|
||||||
|
supply_voltages = [5.0]
|
||||||
|
temperatures = [25]
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -239,16 +239,21 @@ spice["nmos"] = "nmos_vtg"
|
||||||
spice["pmos"] = "pmos_vtg"
|
spice["pmos"] = "pmos_vtg"
|
||||||
# This is a map of corners to model files
|
# This is a map of corners to model files
|
||||||
SPICE_MODEL_DIR=os.environ.get("SPICE_MODEL_DIR")
|
SPICE_MODEL_DIR=os.environ.get("SPICE_MODEL_DIR")
|
||||||
spice["fet_models"] = { "TT" : [SPICE_MODEL_DIR+"/NMOS_VTG.inc",SPICE_MODEL_DIR+"/PMOS_VTG.inc"]}
|
spice["fet_models"] = { "TT" : [SPICE_MODEL_DIR+"/models_nom/PMOS_VTG.inc",SPICE_MODEL_DIR+"/models_nom/NMOS_VTG.inc"],
|
||||||
|
"FF" : [SPICE_MODEL_DIR+"/models_ff/PMOS_VTG.inc",SPICE_MODEL_DIR+"/models_ff/NMOS_VTG.inc"],
|
||||||
|
"SF" : [SPICE_MODEL_DIR+"/models_ss/PMOS_VTG.inc",SPICE_MODEL_DIR+"/models_ff/NMOS_VTG.inc"],
|
||||||
|
"FS" : [SPICE_MODEL_DIR+"/models_ff/PMOS_VTG.inc",SPICE_MODEL_DIR+"/models_ss/NMOS_VTG.inc"],
|
||||||
|
"SS" : [SPICE_MODEL_DIR+"/models_ss/PMOS_VTG.inc",SPICE_MODEL_DIR+"/models_ss/NMOS_VTG.inc"]}
|
||||||
|
|
||||||
#spice stimulus related variables
|
#spice stimulus related variables
|
||||||
spice["feasible_period"] = 5 # estimated feasible period in ns
|
spice["feasible_period"] = 5 # estimated feasible period in ns
|
||||||
spice["supply_voltage"] = 1.0 # ideal vdd in [Volts]
|
spice["supply_voltages"] = [0.9, 1.0, 1.1] # Supply voltage corners in [Volts]
|
||||||
spice["rise_time"] = 0.005 # rise time in [Nano-seconds]
|
spice["rise_time"] = 0.005 # rise time in [Nano-seconds]
|
||||||
spice["fall_time"] = 0.005 # fall time in [Nano-seconds]
|
spice["fall_time"] = 0.005 # fall time in [Nano-seconds]
|
||||||
spice["nom_corner"] = ("TT", 1.0, 25) # Nominal process corner
|
spice["temperatures"] = [0, 25, 100] # Temperature corners (celcius)
|
||||||
|
|
||||||
#sram signal names
|
#sram signal names
|
||||||
|
#FIXME: We don't use these everywhere...
|
||||||
spice["vdd_name"] = "vdd"
|
spice["vdd_name"] = "vdd"
|
||||||
spice["gnd_name"] = "gnd"
|
spice["gnd_name"] = "gnd"
|
||||||
spice["control_signals"] = ["CSb", "WEb", "OEb"]
|
spice["control_signals"] = ["CSb", "WEb", "OEb"]
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
*********************************************
|
||||||
|
* Transistor Models
|
||||||
|
* Note: These models are approximate
|
||||||
|
* and should be substituted with actual
|
||||||
|
* models from MOSIS or SCN3ME
|
||||||
|
*********************************************
|
||||||
|
|
||||||
|
.MODEL NFET NMOS (LEVEL=3 VTO=0.669845 KP=113.7771E-6
|
||||||
|
+ NSUB=6E16 U0=458 VFB=-0.851 GAMMA=0.5705 TOX=13.9n
|
||||||
|
+ TNOM=27)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
*********************************************
|
||||||
|
* Transistor Models
|
||||||
|
* Note: These models are approximate
|
||||||
|
* and should be substituted with actual
|
||||||
|
* models from MOSIS or SCN3ME
|
||||||
|
*********************************************
|
||||||
|
|
||||||
|
.MODEL PFET PMOS (LEVEL=3 VTO=-0.921340 KP=366.0244-6
|
||||||
|
+ NSUB=6E16 U0=212 VFB=0.395 GAMMA=0.2370 TOX=13.9n
|
||||||
|
+ TNOM=27)
|
||||||
|
|
||||||
|
|
@ -199,16 +199,24 @@ spice["nmos"]="n"
|
||||||
spice["pmos"]="p"
|
spice["pmos"]="p"
|
||||||
# This is a map of corners to model files
|
# This is a map of corners to model files
|
||||||
SPICE_MODEL_DIR=os.environ.get("SPICE_MODEL_DIR")
|
SPICE_MODEL_DIR=os.environ.get("SPICE_MODEL_DIR")
|
||||||
spice["fet_models"] = { "TT" : [SPICE_MODEL_DIR+"/on_c5n.sp"] }
|
# FIXME: Uncomment when we have the new spice models
|
||||||
|
spice["fet_models"] = { "TT" : [SPICE_MODEL_DIR+"/nom/pmos.sp",SPICE_MODEL_DIR+"/nom/nmos.sp"] }
|
||||||
|
# spice["fet_models"] = { "TT" : [SPICE_MODEL_DIR+"/nom/pmos.sp",SPICE_MODEL_DIR+"/nom/nmos.sp"],
|
||||||
|
# "FF" : [SPICE_MODEL_DIR+"/ff/pmos.sp",SPICE_MODEL_DIR+"/ff/nmos.sp"],
|
||||||
|
# "FS" : [SPICE_MODEL_DIR+"/ff/pmos.sp",SPICE_MODEL_DIR+"/ss/nmos.sp"],
|
||||||
|
# "SF" : [SPICE_MODEL_DIR+"/ss/pmos.sp",SPICE_MODEL_DIR+"/ff/nmos.sp"],
|
||||||
|
# "SS" : [SPICE_MODEL_DIR+"/ss/pmos.sp",SPICE_MODEL_DIR+"/ss/nmos.sp"] }
|
||||||
|
|
||||||
|
|
||||||
#spice stimulus related variables
|
#spice stimulus related variables
|
||||||
spice["feasible_period"] = 5 # estimated feasible period in ns
|
spice["feasible_period"] = 5 # estimated feasible period in ns
|
||||||
spice["supply_voltage"] = 5.0 # ideal vdd in [Volts]
|
spice["supply_voltages"] = [4.5, 5.0, 5.5] # Supply voltage corners in [Volts]
|
||||||
spice["rise_time"] = 0.05 # rise time in [Nano-seconds]
|
spice["rise_time"] = 0.05 # rise time in [Nano-seconds]
|
||||||
spice["fall_time"] = 0.05 # fall time in [Nano-seconds]
|
spice["fall_time"] = 0.05 # fall time in [Nano-seconds]
|
||||||
spice["nom_corner"] = ("TT", 5.0, 25) # Nominal process corner
|
spice["temperatures"] = [0, 25, 100] # Temperature corners (celcius)
|
||||||
|
|
||||||
#sram signal names
|
#sram signal names
|
||||||
|
#FIXME: We don't use these everywhere...
|
||||||
spice["vdd_name"] = "vdd"
|
spice["vdd_name"] = "vdd"
|
||||||
spice["gnd_name"] = "gnd"
|
spice["gnd_name"] = "gnd"
|
||||||
spice["control_signals"] = ["CSb", "WEb", "OEb"]
|
spice["control_signals"] = ["CSb", "WEb", "OEb"]
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ os.environ["DRCLVS_HOME"] = DRCLVS_HOME
|
||||||
# SPICE_MODEL_DIR = os.path.abspath(os.environ.get("SPICE_MODEL_DIR"))
|
# SPICE_MODEL_DIR = os.path.abspath(os.environ.get("SPICE_MODEL_DIR"))
|
||||||
# except:
|
# except:
|
||||||
# Always use the one in the PDK dir for FreePDK45
|
# Always use the one in the PDK dir for FreePDK45
|
||||||
os.environ["SPICE_MODEL_DIR"] = PDK_DIR+"/ncsu_basekit/models/hspice/tran_models/models_nom"
|
os.environ["SPICE_MODEL_DIR"] = PDK_DIR+"/ncsu_basekit/models/hspice/tran_models"
|
||||||
|
|
||||||
##########################
|
##########################
|
||||||
#Paths required for OPENRAM to function
|
#Paths required for OPENRAM to function
|
||||||
|
|
|
||||||
|
|
@ -27,10 +27,10 @@ except:
|
||||||
DRCLVS_HOME=OPENRAM_TECH+"/scn3me_subm/tech"
|
DRCLVS_HOME=OPENRAM_TECH+"/scn3me_subm/tech"
|
||||||
os.environ["DRCLVS_HOME"] = DRCLVS_HOME
|
os.environ["DRCLVS_HOME"] = DRCLVS_HOME
|
||||||
|
|
||||||
try:
|
# try:
|
||||||
SPICE_MODEL_DIR = os.path.abspath(os.environ.get("SPICE_MODEL_DIR"))
|
# SPICE_MODEL_DIR = os.path.abspath(os.environ.get("SPICE_MODEL_DIR"))
|
||||||
except:
|
# except:
|
||||||
os.environ["SPICE_MODEL_DIR"] = "/mada/software/techfiles/scn3me_subm"
|
os.environ["SPICE_MODEL_DIR"] = OPENRAM_TECH+"/models"
|
||||||
|
|
||||||
##########################
|
##########################
|
||||||
# Paths required for OPENRAM to function
|
# Paths required for OPENRAM to function
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue