Skeleton code for indirect DRC/LVS/PEX tools.

This commit is contained in:
Matt Guthaus 2017-11-14 14:59:14 -08:00
parent 29c5ab48f0
commit 3e0f39cd8e
10 changed files with 490 additions and 93 deletions

View File

@ -97,11 +97,13 @@ def run_drc(name, gds_name):
# run drc
cwd = os.getcwd()
os.chdir(OPTS.openram_temp)
errfile = "%s%s.drc.err" % (OPTS.openram_temp, name)
outfile = "%s%s.drc.out" % (OPTS.openram_temp, name)
errfile = "{0}{1}.drc.err".format(OPTS.openram_temp, name)
outfile = "{0}{1}.drc.out".format(OPTS.openram_temp, name)
cmd = "{0} -gui -drc {1}drc_runset -batch 2> {2} 1> {3}".format(
OPTS.calibre_exe, OPTS.openram_temp, errfile, outfile)
cmd = "{0} -gui -drc {1}drc_runset -batch 2> {2} 1> {3}".format(OPTS.drc_exe,
OPTS.openram_temp,
errfile,
outfile)
debug.info(1, cmd)
os.system(cmd)
os.chdir(cwd)
@ -172,12 +174,14 @@ def run_lvs(name, gds_name, sp_name):
# run LVS
cwd = os.getcwd()
os.chdir(OPTS.openram_temp)
errfile = "%s%s.lvs.err" % (OPTS.openram_temp, name)
outfile = "%s%s.lvs.out" % (OPTS.openram_temp, name)
errfile = "{0}{1}.lvs.err".format(OPTS.openram_temp, name)
outfile = "{0}{1}.lvs.out".format(OPTS.openram_temp, name)
cmd = "calibre -gui -lvs %slvs_runset -batch 2> %s 1> %s" % (
OPTS.openram_temp, errfile, outfile)
debug.info(2, cmd)
cmd = "{0} -gui -lvs {1}lvs_runset -batch 2> {2} 1> {3}".format(OPTS.lvs_exe,
OPTS.openram_temp,
errfile,
outfile)
debug.info(1, cmd)
os.system(cmd)
os.chdir(cwd)
@ -283,7 +287,7 @@ def run_pex(name, gds_name, sp_name, output=None):
errfile = "{0}{1}.pex.err".format(OPTS.openram_temp, name)
outfile = "{0}{1}.pex.out".format(OPTS.openram_temp, name)
cmd = "{0} -gui -pex {1}pex_runset -batch 2> {2} 1> {3}".format(OPTS.calibre_exe,
cmd = "{0} -gui -pex {1}pex_runset -batch 2> {2} 1> {3}".format(OPTS.pex_exe,
OPTS.openram_temp,
errfile,
outfile)

View File

@ -1,7 +1,7 @@
import hierarchy_layout
import hierarchy_spice
import globals
import calibre
import verify
import debug
import os
@ -56,8 +56,8 @@ class design(hierarchy_spice.spice, hierarchy_layout.layout):
tempgds = OPTS.openram_temp + "/temp.gds"
self.sp_write(tempspice)
self.gds_write(tempgds)
debug.check(calibre.run_drc(self.name, tempgds) == 0,"DRC failed for {0}".format(self.name))
debug.check(calibre.run_lvs(self.name, tempgds, tempspice) == 0,"LVS failed for {0}".format(self.name))
debug.check(verify.run_drc(self.name, tempgds) == 0,"DRC failed for {0}".format(self.name))
debug.check(verify.run_lvs(self.name, tempgds, tempspice) == 0,"LVS failed for {0}".format(self.name))
os.remove(tempspice)
os.remove(tempgds)
@ -66,7 +66,7 @@ class design(hierarchy_spice.spice, hierarchy_layout.layout):
if OPTS.check_lvsdrc:
tempgds = OPTS.openram_temp + "/temp.gds"
self.gds_write(tempgds)
debug.check(calibre.run_drc(self.name, tempgds) == 0,"DRC failed for {0}".format(self.name))
debug.check(verify.run_drc(self.name, tempgds) == 0,"DRC failed for {0}".format(self.name))
os.remove(tempgds)
def LVS(self):
@ -76,7 +76,7 @@ class design(hierarchy_spice.spice, hierarchy_layout.layout):
tempgds = OPTS.openram_temp + "/temp.gds"
self.sp_write(tempspice)
self.gds_write(tempgds)
debug.check(calibre.run_lvs(self.name, tempgds, tempspice) == 0,"LVS failed for {0}".format(self.name))
debug.check(verify.run_lvs(self.name, tempgds, tempspice) == 0,"LVS failed for {0}".format(self.name))
os.remove(tempspice)
os.remove(tempgds)

View File

@ -115,8 +115,12 @@ def init_openram(config_file):
set_spice()
set_calibre()
set_drc()
set_lvs()
set_pex()
def read_config(config_file):
global OPTS
@ -154,30 +158,69 @@ def read_config(config_file):
debug.error("Unable to make output directory.",-1)
def find_exe(check_exe):
""" Check if the binary exists in the path and return the full path. """
# Check if the preferred spice option exists in the path
for path in os.environ["PATH"].split(os.pathsep):
exe = os.path.join(path, check_exe)
# if it is found, then break and use first version
if is_exe(exe):
return exe
return None
def set_calibre():
debug.info(2,"Finding calibre...")
def set_drc():
debug.info(2,"Finding DRC tool...")
global OPTS
# check if calibre is installed, if so, we should be running LVS/DRC on
# everything.
if not OPTS.check_lvsdrc:
# over-ride the check LVS/DRC option
debug.info(0,"Over-riding LVS/DRC. Not performing LVS/DRC.")
debug.info(1,"LVS/DRC/PEX disabled.")
return
else:
# see if calibre is in the path (extend to other tools later)
for path in os.environ["PATH"].split(os.pathsep):
OPTS.calibre_exe = os.path.join(path, "calibre")
# if it is found, do inline LVS/DRC
if is_exe(OPTS.calibre_exe):
OPTS.check_lvsdrc = True
debug.info(1, "Using calibre: " + OPTS.calibre_exe)
break
else:
# otherwise, give warning and procede
debug.warning("Calibre not found. Not performing LVS/DRC.")
OPTS.check_lvsdrc = False
import tech
if tech.drc_version != "":
OPTS.drc_exe=find_exe(tech.drc_version)
if OPTS.drc_exe==None:
debug.warning("{0} not found. Unable to perform DRC.".format(tech.drc_version))
OPTS.check_lvsdrc = False
else:
debug.info(1, "Using DRC: " + OPTS.drc_exe)
def set_lvs():
debug.info(2,"Finding LVS tool...")
global OPTS
if not OPTS.check_lvsdrc:
debug.info(1,"LVS/DRC/PEX disabled.")
return
else:
import tech
if tech.lvs_version != "":
OPTS.lvs_exe=find_exe(tech.lvs_version)
if OPTS.lvs_exe==None:
debug.warning("{0} not found. Unable to perform LVS.".format(tech.lvs_version))
OPTS.check_lvsdrc = False
else:
debug.info(1, "Using LVS: " + OPTS.lvs_exe)
def set_pex():
debug.info(2,"Finding PEX tool...")
global OPTS
if not OPTS.check_lvsdrc:
debug.info(1,"LVS/DRC/PEX disabled.")
return
else:
import tech
if tech.pex_version != "":
OPTS.pex_exe=find_exe(tech.pex_version)
if OPTS.pex_exe==None:
debug.warning("{0} not found. Unable to perform PEX.".format(tech.pex_version))
OPTS.check_lvsdrc = False
else:
debug.info(1, "Using PEX: " + OPTS.pex_exe)
def end_openram():
""" Clean up openram for a proper exit """
cleanup_paths()
@ -234,16 +277,6 @@ def setup_paths():
def find_spice(check_exe):
# Check if the preferred spice option exists in the path
for path in os.environ["PATH"].split(os.pathsep):
spice_exe = os.path.join(path, check_exe)
# if it is found, then break and use first version
if is_exe(spice_exe):
OPTS.spice_exe = spice_exe
return True
return False
def set_spice():
debug.info(2,"Finding spice...")
global OPTS
@ -252,13 +285,15 @@ def set_spice():
debug.info(1,"Using analytical delay models (no characterization)")
return
else:
spice_preferences = ["xa", "hspice", "ngspice", "ngspice.exe"]
if OPTS.spice_version != "":
if not find_spice(OPTS.spice_version):
OPTS.spice_exe=find_exe(OPTS.spice_version)
if OPTS.spice_exe==None:
debug.error("{0} not found. Unable to perform characterization.".format(OPTS.spice_version),1)
else:
spice_preferences = ["xa", "hspice", "ngspice", "ngspice.exe"]
for spice_name in spice_preferences:
if find_spice(spice_name):
OPTS.spice_exe = find_exe(spice_name)
if OPTS.spice_exe!=None:
OPTS.spice_version=spice_name
debug.info(1, "Using spice: " + OPTS.spice_exe)
break

306
compiler/magic.py Normal file
View File

@ -0,0 +1,306 @@
"""
This is a DRC/LVS/PEX interface file for magic + netgen.
1. magic can perform drc with the following:
#!/bin/sh
magic -dnull -noconsole << EOF
tech load SCN3ME_SUBM.30
** import gds file
load $1.mag -force
drc count
drc why
quit -noprompt
EOF
2. magic can perform extraction with the following:
#!/bin/sh
rm -f $1.ext
rm -f $1.spice
magic -dnull -noconsole << EOF
tech load SCN3ME_SUBM.30
** import gds file
load $1.mag -force
extract
ext2spice scale off
ext2spice
quit -noprompt
EOF
3. netgen can perform LVS with:
#!/bin/sh
netgen -noconsole <<EOF
readnet $1.spice
readnet $1.sp
ignore class c
permute transistors
compare hierarchical $1.spice {$1.sp $1}
permute
run converge
EOF
"""
import os
import re
import time
import debug
import globals
import subprocess
def run_drc(name, gds_name):
"""Run DRC check on a given top-level name which is
implemented in gds_name."""
debug.error("DRC using magic not implemented.",-1)
OPTS = globals.get_opts()
# the runset file contains all the options to run drc
from tech import drc
drc_rules = drc["drc_rules"]
drc_runset = {
'drcRulesFile': drc_rules,
'drcRunDir': OPTS.openram_temp,
'drcLayoutPaths': gds_name,
'drcLayoutPrimary': name,
'drcLayoutSystem': 'GDSII',
'drcResultsformat': 'ASCII',
'drcResultsFile': OPTS.openram_temp + name + ".drc.results",
'drcSummaryFile': OPTS.openram_temp + name + ".drc.summary",
'cmnFDILayerMapFile': drc["layer_map"],
'cmnFDIUseLayerMap': 1
}
# write the runset file
f = open(OPTS.openram_temp + "drc_runset", "w")
for k in sorted(drc_runset.iterkeys()):
f.write("*%s: %s\n" % (k, drc_runset[k]))
f.close()
# run drc
cwd = os.getcwd()
os.chdir(OPTS.openram_temp)
errfile = "{0}{1}.drc.err".format(OPTS.openram_temp, name)
outfile = "{0}{1}.drc.out".format(OPTS.openram_temp, name)
cmd = "{0} -gui -drc {1}drc_runset -batch 2> {2} 1> {3}".format(OPTS.drc_exe,
OPTS.openram_temp,
errfile,
outfile)
debug.info(1, cmd)
os.system(cmd)
os.chdir(cwd)
# check the result for these lines in the summary:
# TOTAL Original Layer Geometries: 106 (157)
# TOTAL DRC RuleChecks Executed: 156
# TOTAL DRC Results Generated: 0 (0)
try:
f = open(drc_runset['drcSummaryFile'], "r")
except:
debug.error("Unable to retrieve DRC results file. Is magic set up?",1)
results = f.readlines()
f.close()
# those lines should be the last 3
results = results[-3:]
geometries = int(re.split("\W+", results[0])[5])
rulechecks = int(re.split("\W+", results[1])[4])
errors = int(re.split("\W+", results[2])[5])
# always display this summary
if errors > 0:
debug.error("%-25s\tGeometries: %d\tChecks: %d\tErrors: %d" %
(name, geometries, rulechecks, errors))
else:
debug.info(1, "%-25s\tGeometries: %d\tChecks: %d\tErrors: %d" %
(name, geometries, rulechecks, errors))
return errors
def run_lvs(name, gds_name, sp_name):
"""Run LVS check on a given top-level name which is
implemented in gds_name and sp_name. """
debug.error("LVS using magic+netgen not implemented.",-1)
OPTS = globals.get_opts()
from tech import drc
lvs_rules = drc["lvs_rules"]
lvs_runset = {
'lvsRulesFile': lvs_rules,
'lvsRunDir': OPTS.openram_temp,
'lvsLayoutPaths': gds_name,
'lvsLayoutPrimary': name,
'lvsSourcePath': sp_name,
'lvsSourcePrimary': name,
'lvsSourceSystem': 'SPICE',
'lvsSpiceFile': OPTS.openram_temp + "extracted.sp",
'lvsPowerNames': 'vdd',
'lvsGroundNames': 'gnd',
'lvsIncludeSVRFCmds': 1,
'lvsSVRFCmds': '{VIRTUAL CONNECT NAME VDD? GND? ?}',
'lvsIgnorePorts': 1,
'lvsERCDatabase': OPTS.openram_temp + name + ".erc.results",
'lvsERCSummaryFile': OPTS.openram_temp + name + ".erc.summary",
'lvsReportFile': OPTS.openram_temp + name + ".lvs.report",
'lvsMaskDBFile': OPTS.openram_temp + name + ".maskdb",
'cmnFDILayerMapFile': drc["layer_map"],
'cmnFDIUseLayerMap': 1,
'cmnVConnectNames': 'vdd, gnd',
#'cmnVConnectNamesState' : 'ALL', #connects all nets with the same name
}
# write the runset file
f = open(OPTS.openram_temp + "lvs_runset", "w")
for k in sorted(lvs_runset.iterkeys()):
f.write("*%s: %s\n" % (k, lvs_runset[k]))
f.close()
# run LVS
cwd = os.getcwd()
os.chdir(OPTS.openram_temp)
errfile = "{0}{1}.lvs.err".format(OPTS.openram_temp, name)
outfile = "{0}{1}.lvs.out".format(OPTS.openram_temp, name)
cmd = "{0} -gui -lvs {1}lvs_runset -batch 2> {2} 1> {3}".format(OPTS.lvs_exe,
OPTS.openram_temp,
errfile,
outfile)
debug.info(1, cmd)
os.system(cmd)
os.chdir(cwd)
# check the result for these lines in the summary:
f = open(lvs_runset['lvsReportFile'], "r")
results = f.readlines()
f.close()
# NOT COMPARED
# CORRECT
# INCORRECT
test = re.compile("# CORRECT #")
correct = filter(test.search, results)
test = re.compile("NOT COMPARED")
notcompared = filter(test.search, results)
test = re.compile("# INCORRECT #")
incorrect = filter(test.search, results)
# Errors begin with "Error:"
test = re.compile("\s+Error:")
errors = filter(test.search, results)
for e in errors:
debug.error(e.strip("\n"))
summary_errors = len(notcompared) + len(incorrect) + len(errors)
# also check the extraction summary file
f = open(lvs_runset['lvsReportFile'] + ".ext", "r")
results = f.readlines()
f.close()
test = re.compile("ERROR:")
exterrors = filter(test.search, results)
for e in exterrors:
debug.error(e.strip("\n"))
test = re.compile("WARNING:")
extwarnings = filter(test.search, results)
for e in extwarnings:
debug.warning(e.strip("\n"))
# MRG - 9/26/17 - Change this to exclude warnings because of
# multiple labels on different pins in column mux.
ext_errors = len(exterrors)
ext_warnings = len(extwarnings)
# also check the output file
f = open(outfile, "r")
results = f.readlines()
f.close()
# Errors begin with "ERROR:"
test = re.compile("ERROR:")
stdouterrors = filter(test.search, results)
for e in stdouterrors:
debug.error(e.strip("\n"))
out_errors = len(stdouterrors)
total_errors = summary_errors + out_errors + ext_errors
return total_errors
def run_pex(name, gds_name, sp_name, output=None):
"""Run pex on a given top-level name which is
implemented in gds_name and sp_name. """
debug.error("PEX using magic not implemented.",-1)
OPTS = globals.get_opts()
from tech import drc
if output == None:
output = name + ".pex.netlist"
# check if lvs report has been done
# if not run drc and lvs
if not os.path.isfile(name + ".lvs.report"):
run_drc(name, gds_name)
run_lvs(name, gds_name, sp_name)
pex_rules = drc["xrc_rules"]
pex_runset = {
'pexRulesFile': pex_rules,
'pexRunDir': OPTS.openram_temp,
'pexLayoutPaths': gds_name,
'pexLayoutPrimary': name,
#'pexSourcePath' : OPTS.openram_temp+"extracted.sp",
'pexSourcePath': sp_name,
'pexSourcePrimary': name,
'pexReportFile': name + ".lvs.report",
'pexPexNetlistFile': output,
'pexPexReportFile': name + ".pex.report",
'pexMaskDBFile': name + ".maskdb",
'cmnFDIDEFLayoutPath': name + ".def",
}
# write the runset file
f = open(OPTS.openram_temp + "pex_runset", "w")
for k in sorted(pex_runset.iterkeys()):
f.write("*{0}: {1}\n".format(k, pex_runset[k]))
f.close()
# run pex
cwd = os.getcwd()
os.chdir(OPTS.openram_temp)
errfile = "{0}{1}.pex.err".format(OPTS.openram_temp, name)
outfile = "{0}{1}.pex.out".format(OPTS.openram_temp, name)
cmd = "{0} -gui -pex {1}pex_runset -batch 2> {2} 1> {3}".format(OPTS.pex_exe,
OPTS.openram_temp,
errfile,
outfile)
debug.info(2, cmd)
os.system(cmd)
os.chdir(cwd)
# also check the output file
f = open(outfile, "r")
results = f.readlines()
f.close()
# Errors begin with "ERROR:"
test = re.compile("ERROR:")
stdouterrors = filter(test.search, results)
for e in stdouterrors:
debug.error(e.strip("\n"))
out_errors = len(stdouterrors)
assert(os.path.isfile(output))
#correct_port(name, output, sp_name)
return out_errors

View File

@ -36,7 +36,7 @@ class nand_3(design.design):
self.add_pins()
self.create_layout()
self.DRC_LVS()
#self.DRC_LVS()
def add_pins(self):
""" add pics for this module """

View File

@ -10,12 +10,6 @@ a Liberty (.lib) file for timing analysis/optimization
"""
__author__ = "Matthew Guthaus (mrg@ucsc.edu) and numerous others"
__version__ = "$Revision: 0.9 $"
__copyright__ = "Copyright (c) 2015 UCSC and OSU"
__license__ = "This is not currently licensed for use outside of UCSC's VLSI-DA and OSU's VLSI group."
import sys,os
import datetime
import re
@ -72,17 +66,18 @@ print("Output files are " + OPTS.output_name + ".(sp|gds|v|lib|lef)")
print("Technology: {0}".format(OPTS.tech_name))
print("Word size: {0}\nWords: {1}\nBanks: {2}".format(word_size,num_words,num_banks))
if not OPTS.check_lvsdrc:
print("DRC/LVS/PEX checking is disabled.")
if OPTS.analytical_delay:
print("Using analytical delay models (no characterization)")
else:
print("Performing simulation-based characterization with {}".format(OPTS.spice_version))
if OPTS.trim_netlist:
print("Trimming netlist to speed up characterization (sacrificing some accuracy).")
if OPTS.trim_netlist:
print("Trimming netlist to speed up characterization (sacrificing some accuracy).")
# only start importing modules after we have the config file
import calibre
import verify
import sram
start_time = datetime.datetime.now()
@ -111,7 +106,7 @@ last_time=print_time("Spice writing", datetime.datetime.now(), last_time)
sram_file = spname
if OPTS.use_pex:
sram_file = OPTS.output_path + "temp_pex.sp"
calibre.run_pex(s.name, gdsname, spname, output=sram_file)
verify.run_pex(s.name, gdsname, spname, output=sram_file)
# Characterize the design
import lib

View File

@ -22,8 +22,10 @@ class options(optparse.Values):
spice_version = ""
# Should we print out the banner at startup
print_banner = True
# The Calibre executable being used which is derived from the user PATH.
calibre_exe = ""
# The DRC/LVS/PEX executable being used which is derived from the user PATH.
drc_exe = ""
lvs_exe = ""
pex_exe = ""
# The spice executable being used which is derived from the user PATH.
spice_exe = ""
# Run with extracted parasitics

35
compiler/verify.py Normal file
View File

@ -0,0 +1,35 @@
"""
This is a module that will import the correct DRC/LVS/PEX
module based on what tools are found. It is a layer of indirection
to enable multiple verification tool support.
Each DRC/LVS/PEX tool should implement the functions run_drc, run_lvs, and
run_pex, repsectively. If there is an error, they should abort and report the errors.
If not, OpenRAM will continue as if nothing happened!
"""
import debug
import tech
if tech.drc_version=="calibre":
from calibre import run_drc
elif tech.drc_version=="magic":
from magic import run_drc
else:
debug.warning("Did not find a supported DRC tool.")
if tech.lvs_version=="calibre":
from calibre import run_lvs
elif tech.lvs_version=="netgen":
from magic import run_lvs
else:
debug.warning("Did not find a supported LVS tool.")
if tech.pex_version=="calibre":
from calibre import run_pex
elif tech.pex_version=="magic":
from magic import run_pex
else:
debug.warning("Did not find a supported PEX tool.")

View File

@ -1,7 +1,7 @@
import os
"""
File containing the process technology parameters.
File containing the process technology parameters for FreePDK 45nm.
"""
info = {}
@ -17,9 +17,13 @@ GDS["unit"] = (0.0005,1e-9)
# default label zoom
GDS["zoom"] = 0.05
#####################################################################################################
##GDS Layer Map######################################################################################
#####################################################################################################
drc_version = "calibre"
lvs_version = "calibre"
pex_version = "calibre"
###################################################
##GDS Layer Map
###################################################
# create the GDS layer map
# FIXME: parse the gds layer map from the cadence map?
@ -56,13 +60,13 @@ layer["metal10"] = 29
layer["text"] = 239
layer["boundary"]= 239
#####################################################################################################
##END GDS Layer Map##################################################################################
#####################################################################################################
###################################################
##END GDS Layer Map
###################################################
#####################################################################################################
##DRC/LVS Rules Setup################################################################################
#####################################################################################################
###################################################
##DRC/LVS Rules Setup
###################################################
#technology parameter
parameter={}
@ -243,13 +247,13 @@ drc["metal10_to_metal10"] = 0.14
drc["metal10_extend_via9"] = 0
drc["metal10_enclosure_via9"] = 0
#####################################################################################################
##END DRC/LVS Rules##################################################################################
#####################################################################################################
###################################################
##END DRC/LVS Rules
###################################################
#####################################################################################################
##Spice Simulation Parameters########################################################################
#####################################################################################################
###################################################
##Spice Simulation Parameters
###################################################
#spice info
spice = {}
@ -298,3 +302,9 @@ spice["msflop_setup"] = 9 # DFF setup time in ps
spice["msflop_hold"] = 1 # DFF hold time in ps
spice["msflop_delay"] = 20.5 # DFF Clk-to-q delay in ps
spice["msflop_slew"] = 13.1 # DFF output slew in ps w/ no load
###################################################
##END Spice Simulation Parameters
###################################################

View File

@ -1,8 +1,9 @@
import os
"""
Class containing the process technology parameters.
File containing the process technology parameters for SCMOS 3me, subm, 180nm.
"""
info={}
info["name"]="scn3me_subm"
info["body_tie_down"] = 0
@ -16,9 +17,14 @@ GDS["unit"]=(0.001,1e-6)
# default label zoom
GDS["zoom"] = 0.5
#####################################################################################################
##GDS Layer Map######################################################################################
#####################################################################################################
drc_version = "magic"
lvs_version = "netgen"
pex_version = "magic"
###################################################
##GDS Layer Map
###################################################
# create the GDS layer map
layer={}
@ -41,13 +47,13 @@ layer["metal3"] = 62
layer["text"] = 83
layer["boundary"] = 83
#####################################################################################################
##END GDS Layer Map##################################################################################
#####################################################################################################
###################################################
##END GDS Layer Map
###################################################
#####################################################################################################
##DRC/LVS Rules Setup################################################################################
#####################################################################################################
###################################################
##DRC/LVS Rules Setup
###################################################
#technology parameter
parameter={}
@ -163,13 +169,13 @@ drc["metal3_extend_via2"] = 0.6
drc["metal3_enclosure_via2"] = 0.6
drc["minarea_metal3"] = 0
#####################################################################################################
##END DRC/LVS Rules##################################################################################
#####################################################################################################
###################################################
##END DRC/LVS Rules
###################################################
#####################################################################################################
##Spice Simulation Parameters########################################################################
#####################################################################################################
###################################################
##Spice Simulation Parameters
###################################################
# spice model info
spice={}
@ -218,3 +224,7 @@ spice["msflop_hold"] = 1 # DFF hold time in ps
spice["msflop_delay"] = 20.5 # DFF Clk-to-q delay in ps
spice["msflop_slew"] = 13.1 # DFF output slew in ps w/ no load
###################################################
##END Spice Simulation Parameters
###################################################