mirror of https://github.com/VLSIDA/OpenRAM.git
Skeleton code for indirect DRC/LVS/PEX tools.
This commit is contained in:
parent
29c5ab48f0
commit
3e0f39cd8e
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
@ -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 """
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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.")
|
||||
|
||||
|
|
@ -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
|
||||
###################################################
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
###################################################
|
||||
|
|
|
|||
Loading…
Reference in New Issue