mirror of https://github.com/VLSIDA/OpenRAM.git
Use readspice to define ports from sp netlist in Magic extract.
This commit is contained in:
parent
31ae56ff39
commit
03dad01e4c
|
|
@ -73,11 +73,11 @@ class hierarchy_design(hierarchy_spice.spice, hierarchy_layout.layout):
|
||||||
elif (OPTS.inline_lvsdrc or force_check or final_verification):
|
elif (OPTS.inline_lvsdrc or force_check or final_verification):
|
||||||
|
|
||||||
tempspice = "{0}/{1}.sp".format(OPTS.openram_temp, self.name)
|
tempspice = "{0}/{1}.sp".format(OPTS.openram_temp, self.name)
|
||||||
tempgds = "{0}/{1}.gds".format(OPTS.openram_temp, self.name)
|
|
||||||
self.lvs_write(tempspice)
|
self.lvs_write(tempspice)
|
||||||
|
tempgds = "{0}/{1}.gds".format(OPTS.openram_temp, self.name)
|
||||||
self.gds_write(tempgds)
|
self.gds_write(tempgds)
|
||||||
# Final verification option does not allow nets to be connected by label.
|
# Final verification option does not allow nets to be connected by label.
|
||||||
self.drc_errors = verify.run_drc(self.cell_name, tempgds, extract=True, final_verification=final_verification)
|
self.drc_errors = verify.run_drc(self.cell_name, tempgds, tempspice, extract=True, final_verification=final_verification)
|
||||||
self.lvs_errors = verify.run_lvs(self.cell_name, tempgds, tempspice, final_verification=final_verification)
|
self.lvs_errors = verify.run_lvs(self.cell_name, tempgds, tempspice, final_verification=final_verification)
|
||||||
|
|
||||||
# force_check is used to determine decoder height and other things, so we shouldn't fail
|
# force_check is used to determine decoder height and other things, so we shouldn't fail
|
||||||
|
|
@ -105,9 +105,11 @@ class hierarchy_design(hierarchy_spice.spice, hierarchy_layout.layout):
|
||||||
if OPTS.netlist_only:
|
if OPTS.netlist_only:
|
||||||
return
|
return
|
||||||
elif (not OPTS.is_unit_test and OPTS.check_lvsdrc and (OPTS.inline_lvsdrc or final_verification)):
|
elif (not OPTS.is_unit_test and OPTS.check_lvsdrc and (OPTS.inline_lvsdrc or final_verification)):
|
||||||
tempgds = "{0}/{1}.gds".format(OPTS.openram_temp, self.cell_name)
|
tempspice = "{0}{1}.sp".format(OPTS.openram_temp, self.name)
|
||||||
|
self.lvs_write(tempspice)
|
||||||
|
tempgds = "{0}{1}.gds".format(OPTS.openram_temp, self.cell_name)
|
||||||
self.gds_write(tempgds)
|
self.gds_write(tempgds)
|
||||||
num_errors = verify.run_drc(self.cell_name, tempgds, final_verification=final_verification)
|
num_errors = verify.run_drc(self.cell_name, tempgds, tempspice, final_verification=final_verification)
|
||||||
debug.check(num_errors == 0,
|
debug.check(num_errors == 0,
|
||||||
"DRC failed for {0} with {1} error(s)".format(self.cell_name,
|
"DRC failed for {0} with {1} error(s)".format(self.cell_name,
|
||||||
num_errors))
|
num_errors))
|
||||||
|
|
@ -126,9 +128,9 @@ class hierarchy_design(hierarchy_spice.spice, hierarchy_layout.layout):
|
||||||
if OPTS.netlist_only:
|
if OPTS.netlist_only:
|
||||||
return
|
return
|
||||||
elif (not OPTS.is_unit_test and OPTS.check_lvsdrc and (OPTS.inline_lvsdrc or final_verification)):
|
elif (not OPTS.is_unit_test and OPTS.check_lvsdrc and (OPTS.inline_lvsdrc or final_verification)):
|
||||||
tempspice = "{0}/{1}.sp".format(OPTS.openram_temp, self.cell_name)
|
tempspice = "{0}{1}.sp".format(OPTS.openram_temp, self.cell_name)
|
||||||
tempgds = "{0}/{1}.gds".format(OPTS.openram_temp, self.name)
|
|
||||||
self.lvs_write(tempspice)
|
self.lvs_write(tempspice)
|
||||||
|
tempgds = "{0}{1}.gds".format(OPTS.openram_temp, self.name)
|
||||||
self.gds_write(tempgds)
|
self.gds_write(tempgds)
|
||||||
num_errors = verify.run_lvs(self.name, tempgds, tempspice, final_verification=final_verification)
|
num_errors = verify.run_lvs(self.name, tempgds, tempspice, final_verification=final_verification)
|
||||||
debug.check(num_errors == 0,
|
debug.check(num_errors == 0,
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,7 @@ class openram_test(unittest.TestCase):
|
||||||
# Run both DRC and LVS even if DRC might fail
|
# Run both DRC and LVS even if DRC might fail
|
||||||
# Magic can still extract despite DRC failing, so it might be ok in some techs
|
# Magic can still extract despite DRC failing, so it might be ok in some techs
|
||||||
# if we ignore things like minimum metal area of pins
|
# if we ignore things like minimum metal area of pins
|
||||||
drc_result=verify.run_drc(a.name, tempgds, extract=True, final_verification=final_verification)
|
drc_result=verify.run_drc(a.name, tempgds, tempspice, extract=True, final_verification=final_verification)
|
||||||
|
|
||||||
# We can still run LVS even if DRC fails in Magic OR Calibre
|
# We can still run LVS even if DRC fails in Magic OR Calibre
|
||||||
lvs_result=verify.run_lvs(a.name, tempgds, tempspice, final_verification=final_verification)
|
lvs_result=verify.run_lvs(a.name, tempgds, tempspice, final_verification=final_verification)
|
||||||
|
|
|
||||||
|
|
@ -30,9 +30,13 @@ num_lvs_runs = 0
|
||||||
num_pex_runs = 0
|
num_pex_runs = 0
|
||||||
|
|
||||||
|
|
||||||
def write_drc_script(cell_name, gds_name, extract, final_verification, output_path):
|
def write_drc_script(cell_name, gds_name, extract, final_verification=False, output_path=None):
|
||||||
""" Write a Calibre runset file and script to run DRC """
|
""" Write a Calibre runset file and script to run DRC """
|
||||||
# the runset file contains all the options to run calibre
|
# the runset file contains all the options to run calibre
|
||||||
|
|
||||||
|
if not output_path:
|
||||||
|
output_path = OPTS.openram_temp
|
||||||
|
|
||||||
from tech import drc
|
from tech import drc
|
||||||
drc_rules = drc["drc_rules"]
|
drc_rules = drc["drc_rules"]
|
||||||
|
|
||||||
|
|
@ -68,9 +72,12 @@ def write_drc_script(cell_name, gds_name, extract, final_verification, output_pa
|
||||||
return drc_runset
|
return drc_runset
|
||||||
|
|
||||||
|
|
||||||
def write_lvs_script(cell_name, gds_name, sp_name, final_verification, output_path):
|
def write_lvs_script(cell_name, gds_name, sp_name, final_verification=False, output_path=None):
|
||||||
""" Write a Calibre runset file and script to run LVS """
|
""" Write a Calibre runset file and script to run LVS """
|
||||||
|
|
||||||
|
if not output_path:
|
||||||
|
output_path = OPTS.openram_temp
|
||||||
|
|
||||||
from tech import drc
|
from tech import drc
|
||||||
lvs_rules = drc["lvs_rules"]
|
lvs_rules = drc["lvs_rules"]
|
||||||
lvs_runset = {
|
lvs_runset = {
|
||||||
|
|
@ -132,8 +139,12 @@ def write_lvs_script(cell_name, gds_name, sp_name, final_verification, output_pa
|
||||||
return lvs_runset
|
return lvs_runset
|
||||||
|
|
||||||
|
|
||||||
def write_pex_script(cell_name, extract, output, final_verification, output_path):
|
def write_pex_script(cell_name, extract, output, final_verification=False, output_path=None):
|
||||||
""" Write a pex script that can either just extract the netlist or the netlist+parasitics """
|
""" Write a pex script that can either just extract the netlist or the netlist+parasitics """
|
||||||
|
|
||||||
|
if not output_path:
|
||||||
|
output_path = OPTS.openram_temp
|
||||||
|
|
||||||
if output == None:
|
if output == None:
|
||||||
output = cell_name + ".pex.sp"
|
output = cell_name + ".pex.sp"
|
||||||
|
|
||||||
|
|
@ -142,7 +153,7 @@ def write_pex_script(cell_name, extract, output, final_verification, output_path
|
||||||
if not os.path.isfile(output_path + cell_name + ".lvs.report"):
|
if not os.path.isfile(output_path + cell_name + ".lvs.report"):
|
||||||
gds_name = output_path +"/"+ cell_name + ".gds"
|
gds_name = output_path +"/"+ cell_name + ".gds"
|
||||||
sp_name = output_path +"/"+ cell_name + ".sp"
|
sp_name = output_path +"/"+ cell_name + ".sp"
|
||||||
run_drc(cell_name, gds_name)
|
run_drc(cell_name, gds_name, sp_name)
|
||||||
run_lvs(cell_name, gds_name, sp_name)
|
run_lvs(cell_name, gds_name, sp_name)
|
||||||
|
|
||||||
from tech import drc
|
from tech import drc
|
||||||
|
|
@ -181,7 +192,7 @@ def write_pex_script(cell_name, extract, output, final_verification, output_path
|
||||||
return pex_runset
|
return pex_runset
|
||||||
|
|
||||||
|
|
||||||
def run_drc(cell_name, gds_name, extract=False, final_verification=False):
|
def run_drc(cell_name, gds_name, sp_name, extract=False, final_verification=False):
|
||||||
"""Run DRC check on a given top-level name which is
|
"""Run DRC check on a given top-level name which is
|
||||||
implemented in gds_name."""
|
implemented in gds_name."""
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,7 @@ num_pex_runs = 0
|
||||||
# (outfile, errfile, resultsfile) = run_script(cell_name, "filter")
|
# (outfile, errfile, resultsfile) = run_script(cell_name, "filter")
|
||||||
|
|
||||||
|
|
||||||
def write_drc_script(cell_name, gds_name, extract, final_verification, output_path):
|
def write_drc_script(cell_name, gds_name, extract, final_verification, output_path, sp_name=None):
|
||||||
""" Write a magic script to perform DRC and optionally extraction. """
|
""" Write a magic script to perform DRC and optionally extraction. """
|
||||||
|
|
||||||
global OPTS
|
global OPTS
|
||||||
|
|
@ -102,35 +102,38 @@ def write_drc_script(cell_name, gds_name, extract, final_verification, output_pa
|
||||||
f.write("drc catchup\n")
|
f.write("drc catchup\n")
|
||||||
f.write("drc count total\n")
|
f.write("drc count total\n")
|
||||||
f.write("drc count\n")
|
f.write("drc count\n")
|
||||||
f.write("port makeall\n")
|
if not sp_name:
|
||||||
|
f.write("port makeall\n")
|
||||||
|
else:
|
||||||
|
f.write("readspice {}\n".format(sp_name))
|
||||||
if not extract:
|
if not extract:
|
||||||
pre = "#"
|
pre = "#"
|
||||||
else:
|
else:
|
||||||
pre = ""
|
pre = ""
|
||||||
if final_verification and OPTS.route_supplies:
|
if final_verification and OPTS.route_supplies:
|
||||||
f.write(pre + "extract unique all\n".format(cell_name))
|
f.write(pre + "extract unique all\n")
|
||||||
# Hack to work around unit scales in SkyWater
|
# Hack to work around unit scales in SkyWater
|
||||||
if OPTS.tech_name=="sky130":
|
if OPTS.tech_name=="sky130":
|
||||||
f.write(pre + "extract style ngspice(si)\n")
|
f.write(pre + "extract style ngspice(si)\n")
|
||||||
f.write(pre + "extract\n".format(cell_name))
|
f.write(pre + "extract\n")
|
||||||
# f.write(pre + "ext2spice hierarchy on\n")
|
# f.write(pre + "ext2spice hierarchy on\n")
|
||||||
# f.write(pre + "ext2spice scale off\n")
|
# f.write(pre + "ext2spice scale off\n")
|
||||||
# lvs exists in 8.2.79, but be backword compatible for now
|
# lvs exists in 8.2.79, but be backword compatible for now
|
||||||
#f.write(pre+"ext2spice lvs\n")
|
# f.write(pre + "ext2spice lvs\n")
|
||||||
f.write(pre+"ext2spice hierarchy on\n")
|
f.write(pre + "ext2spice hierarchy on\n")
|
||||||
f.write(pre+"ext2spice format ngspice\n")
|
f.write(pre + "ext2spice format ngspice\n")
|
||||||
f.write(pre+"ext2spice cthresh infinite\n")
|
f.write(pre + "ext2spice cthresh infinite\n")
|
||||||
f.write(pre+"ext2spice rthresh infinite\n")
|
f.write(pre + "ext2spice rthresh infinite\n")
|
||||||
f.write(pre+"ext2spice renumber off\n")
|
f.write(pre + "ext2spice renumber off\n")
|
||||||
f.write(pre+"ext2spice scale off\n")
|
f.write(pre + "ext2spice scale off\n")
|
||||||
f.write(pre+"ext2spice blackbox on\n")
|
f.write(pre + "ext2spice blackbox on\n")
|
||||||
f.write(pre+"ext2spice subcircuit top on\n")
|
f.write(pre + "ext2spice subcircuit top on\n")
|
||||||
f.write(pre+"ext2spice global off\n")
|
f.write(pre + "ext2spice global off\n")
|
||||||
|
|
||||||
# Can choose hspice, ngspice, or spice3,
|
# Can choose hspice, ngspice, or spice3,
|
||||||
# but they all seem compatible enough.
|
# but they all seem compatible enough.
|
||||||
f.write(pre+"ext2spice format ngspice\n")
|
f.write(pre + "ext2spice format ngspice\n")
|
||||||
f.write(pre+"ext2spice {}\n".format(cell_name))
|
f.write(pre + "ext2spice {}\n".format(cell_name))
|
||||||
f.write("quit -noprompt\n")
|
f.write("quit -noprompt\n")
|
||||||
f.write("EOF\n")
|
f.write("EOF\n")
|
||||||
|
|
||||||
|
|
@ -138,7 +141,7 @@ def write_drc_script(cell_name, gds_name, extract, final_verification, output_pa
|
||||||
os.system("chmod u+x {}".format(run_file))
|
os.system("chmod u+x {}".format(run_file))
|
||||||
|
|
||||||
|
|
||||||
def run_drc(cell_name, gds_name, extract=True, final_verification=False):
|
def run_drc(cell_name, gds_name, sp_name=None, extract=True, final_verification=False):
|
||||||
"""Run DRC check on a cell which is implemented in gds_name."""
|
"""Run DRC check on a cell which is implemented in gds_name."""
|
||||||
|
|
||||||
global num_drc_runs
|
global num_drc_runs
|
||||||
|
|
@ -148,7 +151,7 @@ def run_drc(cell_name, gds_name, extract=True, final_verification=False):
|
||||||
if os.path.dirname(gds_name)!=OPTS.openram_temp.rstrip('/'):
|
if os.path.dirname(gds_name)!=OPTS.openram_temp.rstrip('/'):
|
||||||
shutil.copy(gds_name, OPTS.openram_temp)
|
shutil.copy(gds_name, OPTS.openram_temp)
|
||||||
|
|
||||||
write_drc_script(cell_name, gds_name, extract, final_verification, OPTS.openram_temp)
|
write_drc_script(cell_name, gds_name, extract, final_verification, OPTS.openram_temp, sp_name=sp_name)
|
||||||
|
|
||||||
(outfile, errfile, resultsfile) = run_script(cell_name, "drc")
|
(outfile, errfile, resultsfile) = run_script(cell_name, "drc")
|
||||||
|
|
||||||
|
|
@ -161,7 +164,7 @@ def run_drc(cell_name, gds_name, extract=True, final_verification=False):
|
||||||
try:
|
try:
|
||||||
f = open(outfile, "r")
|
f = open(outfile, "r")
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
debug.error("Unable to load DRC results file from {}. Is magic set up?".format(outfile),1)
|
debug.error("Unable to load DRC results file from {}. Is magic set up?".format(outfile), 1)
|
||||||
|
|
||||||
results = f.readlines()
|
results = f.readlines()
|
||||||
f.close()
|
f.close()
|
||||||
|
|
@ -172,7 +175,7 @@ def run_drc(cell_name, gds_name, extract=True, final_verification=False):
|
||||||
errors = int(re.split(": ", line)[1])
|
errors = int(re.split(": ", line)[1])
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
debug.error("Unable to find the total error line in Magic output.",1)
|
debug.error("Unable to find the total error line in Magic output.", 1)
|
||||||
|
|
||||||
|
|
||||||
# always display this summary
|
# always display this summary
|
||||||
|
|
@ -180,7 +183,7 @@ def run_drc(cell_name, gds_name, extract=True, final_verification=False):
|
||||||
if errors > 0:
|
if errors > 0:
|
||||||
for line in results:
|
for line in results:
|
||||||
if "error tiles" in line:
|
if "error tiles" in line:
|
||||||
debug.info(1,line.rstrip("\n"))
|
debug.info(1, line.rstrip("\n"))
|
||||||
debug.warning(result_str)
|
debug.warning(result_str)
|
||||||
else:
|
else:
|
||||||
debug.info(1, result_str)
|
debug.info(1, result_str)
|
||||||
|
|
@ -188,11 +191,14 @@ def run_drc(cell_name, gds_name, extract=True, final_verification=False):
|
||||||
return errors
|
return errors
|
||||||
|
|
||||||
|
|
||||||
def write_lvs_script(cell_name, gds_name, sp_name, final_verification, output_path):
|
def write_lvs_script(cell_name, gds_name, sp_name, final_verification=False, output_path=None):
|
||||||
""" Write a netgen script to perform LVS. """
|
""" Write a netgen script to perform LVS. """
|
||||||
|
|
||||||
global OPTS
|
global OPTS
|
||||||
|
|
||||||
|
if not output_path:
|
||||||
|
output_path = OPTS.openram_temp
|
||||||
|
|
||||||
setup_file = "setup.tcl"
|
setup_file = "setup.tcl"
|
||||||
full_setup_file = OPTS.openram_tech + "tech/" + setup_file
|
full_setup_file = OPTS.openram_tech + "tech/" + setup_file
|
||||||
if os.path.exists(full_setup_file):
|
if os.path.exists(full_setup_file):
|
||||||
|
|
@ -214,7 +220,7 @@ def write_lvs_script(cell_name, gds_name, sp_name, final_verification, output_pa
|
||||||
os.system("chmod u+x {}".format(run_file))
|
os.system("chmod u+x {}".format(run_file))
|
||||||
|
|
||||||
|
|
||||||
def run_lvs(cell_name, gds_name, sp_name, final_verification=False):
|
def run_lvs(cell_name, gds_name, sp_name, final_verification=False, output_path=None):
|
||||||
"""Run LVS check on a given top-level name which is
|
"""Run LVS check on a given top-level name which is
|
||||||
implemented in gds_name and sp_name. Final verification will
|
implemented in gds_name and sp_name. Final verification will
|
||||||
ensure that there are no remaining virtual conections. """
|
ensure that there are no remaining virtual conections. """
|
||||||
|
|
@ -222,13 +228,16 @@ def run_lvs(cell_name, gds_name, sp_name, final_verification=False):
|
||||||
global num_lvs_runs
|
global num_lvs_runs
|
||||||
num_lvs_runs += 1
|
num_lvs_runs += 1
|
||||||
|
|
||||||
# Copy file to local dir if it isn't already
|
if not output_path:
|
||||||
if os.path.dirname(gds_name)!=OPTS.openram_temp.rstrip('/'):
|
output_path = OPTS.openram_temp
|
||||||
shutil.copy(gds_name, OPTS.openram_temp)
|
|
||||||
if os.path.dirname(sp_name)!=OPTS.openram_temp.rstrip('/'):
|
|
||||||
shutil.copy(sp_name, OPTS.openram_temp)
|
|
||||||
|
|
||||||
write_lvs_script(cell_name, gds_name, sp_name, final_verification, OPTS.openram_temp)
|
# Copy file to local dir if it isn't already
|
||||||
|
if os.path.dirname(gds_name) != output_path.rstrip('/'):
|
||||||
|
shutil.copy(gds_name, output_path)
|
||||||
|
if os.path.dirname(sp_name) != output_path.rstrip('/'):
|
||||||
|
shutil.copy(sp_name, output_path)
|
||||||
|
|
||||||
|
write_lvs_script(cell_name, gds_name, sp_name, final_verification)
|
||||||
|
|
||||||
(outfile, errfile, resultsfile) = run_script(cell_name, "lvs")
|
(outfile, errfile, resultsfile) = run_script(cell_name, "lvs")
|
||||||
|
|
||||||
|
|
@ -289,13 +298,17 @@ def run_lvs(cell_name, gds_name, sp_name, final_verification=False):
|
||||||
return total_errors
|
return total_errors
|
||||||
|
|
||||||
|
|
||||||
def run_pex(name, gds_name, sp_name, output=None, final_verification=False):
|
def run_pex(name, gds_name, sp_name, output=None, final_verification=False, output_path=None):
|
||||||
"""Run pex on a given top-level name which is
|
"""Run pex on a given top-level name which is
|
||||||
implemented in gds_name and sp_name. """
|
implemented in gds_name and sp_name. """
|
||||||
|
|
||||||
global num_pex_runs
|
global num_pex_runs
|
||||||
num_pex_runs += 1
|
num_pex_runs += 1
|
||||||
os.chdir(OPTS.openram_temp)
|
|
||||||
|
os.chdir(output_path)
|
||||||
|
|
||||||
|
if not output_path:
|
||||||
|
output_path = OPTS.openram_temp
|
||||||
|
|
||||||
if output == None:
|
if output == None:
|
||||||
output = name + ".pex.netlist"
|
output = name + ".pex.netlist"
|
||||||
|
|
@ -311,8 +324,8 @@ def run_pex(name, gds_name, sp_name, output=None, final_verification=False):
|
||||||
# the dev old code using batch mode does not run and is split into functions
|
# the dev old code using batch mode does not run and is split into functions
|
||||||
pex_runset = write_script_pex_rule(gds_name, name, output)
|
pex_runset = write_script_pex_rule(gds_name, name, output)
|
||||||
|
|
||||||
errfile = "{0}{1}.pex.err".format(OPTS.openram_temp, name)
|
errfile = "{0}{1}.pex.err".format(output_path, name)
|
||||||
outfile = "{0}{1}.pex.out".format(OPTS.openram_temp, name)
|
outfile = "{0}{1}.pex.out".format(output_path, name)
|
||||||
|
|
||||||
script_cmd = "{0} 2> {1} 1> {2}".format(pex_runset,
|
script_cmd = "{0} 2> {1} 1> {2}".format(pex_runset,
|
||||||
errfile,
|
errfile,
|
||||||
|
|
@ -387,7 +400,7 @@ def write_batch_pex_rule(gds_name, name, sp_name, output):
|
||||||
return file
|
return file
|
||||||
|
|
||||||
|
|
||||||
def write_script_pex_rule(gds_name, cell_name, output):
|
def write_script_pex_rule(gds_name, cell_name, sp_name, output):
|
||||||
global OPTS
|
global OPTS
|
||||||
run_file = OPTS.openram_temp + "run_pex.sh"
|
run_file = OPTS.openram_temp + "run_pex.sh"
|
||||||
f = open(run_file, "w")
|
f = open(run_file, "w")
|
||||||
|
|
@ -399,26 +412,24 @@ def write_script_pex_rule(gds_name, cell_name, output):
|
||||||
f.write("load {}\n".format(cell_name))
|
f.write("load {}\n".format(cell_name))
|
||||||
f.write("select top cell\n")
|
f.write("select top cell\n")
|
||||||
f.write("expand\n")
|
f.write("expand\n")
|
||||||
f.write("port makeall\n")
|
if not sp_name:
|
||||||
extract = True
|
f.write("port makeall\n")
|
||||||
if not extract:
|
|
||||||
pre = "#"
|
|
||||||
else:
|
else:
|
||||||
pre = ""
|
f.write("readspice {}\n".format(sp_name))
|
||||||
f.write(pre + "extract\n")
|
f.write("extract\n")
|
||||||
f.write(pre + "ext2sim labels on\n")
|
f.write("ext2sim labels on\n")
|
||||||
f.write(pre + "ext2sim\n")
|
f.write("ext2sim\n")
|
||||||
f.write(pre + "extresist simplify off\n")
|
f.write("extresist simplify off\n")
|
||||||
f.write(pre + "extresist all\n")
|
f.write("extresist all\n")
|
||||||
f.write(pre + "ext2spice hierarchy off\n")
|
f.write("ext2spice hierarchy off\n")
|
||||||
f.write(pre + "ext2spice format ngspice\n")
|
f.write("ext2spice format ngspice\n")
|
||||||
f.write(pre + "ext2spice renumber off\n")
|
f.write("ext2spice renumber off\n")
|
||||||
f.write(pre + "ext2spice scale off\n")
|
f.write("ext2spice scale off\n")
|
||||||
f.write(pre + "ext2spice blackbox on\n")
|
f.write("ext2spice blackbox on\n")
|
||||||
f.write(pre + "ext2spice subcircuit top on\n")
|
f.write("ext2spice subcircuit top on\n")
|
||||||
f.write(pre + "ext2spice global off\n")
|
f.write("ext2spice global off\n")
|
||||||
f.write(pre + "ext2spice extresist on\n")
|
f.write("ext2spice extresist on\n")
|
||||||
f.write(pre + "ext2spice {}\n".format(cell_name))
|
f.write("ext2spice {}\n".format(cell_name))
|
||||||
f.write("quit -noprompt\n")
|
f.write("quit -noprompt\n")
|
||||||
f.write("eof\n")
|
f.write("eof\n")
|
||||||
f.write("mv {0}.spice {1}\n".format(cell_name, output))
|
f.write("mv {0}.spice {1}\n".format(cell_name, output))
|
||||||
|
|
|
||||||
|
|
@ -17,11 +17,11 @@ lvs_warned = False
|
||||||
pex_warned = False
|
pex_warned = False
|
||||||
|
|
||||||
|
|
||||||
def write_drc_script(cell_name, gds_name, extract, final_verification, output_path):
|
def write_drc_script(cell_name, gds_name, extract, final_verification=False, output_path=None):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
def run_drc(cell_name, gds_name, extract=False, final_verification=False):
|
def run_drc(cell_name, gds_name, sp_name, extract=False, final_verification=False, output_path=None):
|
||||||
global drc_warned
|
global drc_warned
|
||||||
if not drc_warned:
|
if not drc_warned:
|
||||||
debug.error("DRC unable to run.", -1)
|
debug.error("DRC unable to run.", -1)
|
||||||
|
|
@ -30,11 +30,11 @@ def run_drc(cell_name, gds_name, extract=False, final_verification=False):
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
|
|
||||||
def write_lvs_script(cell_name, gds_name, sp_name, final_verification, output_path):
|
def write_lvs_script(cell_name, gds_name, sp_name, final_verification=False, output_path=None):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
def run_lvs(cell_name, gds_name, sp_name, final_verification=False):
|
def run_lvs(cell_name, gds_name, sp_name, final_verification=False, output_path=None):
|
||||||
global lvs_warned
|
global lvs_warned
|
||||||
if not lvs_warned:
|
if not lvs_warned:
|
||||||
debug.error("LVS unable to run.", -1)
|
debug.error("LVS unable to run.", -1)
|
||||||
|
|
@ -43,7 +43,7 @@ def run_lvs(cell_name, gds_name, sp_name, final_verification=False):
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
|
|
||||||
def run_pex(name, gds_name, sp_name, output=None, final_verification=False):
|
def run_pex(name, gds_name, sp_name, output=None, final_verification=False, output_path=None):
|
||||||
global pex_warned
|
global pex_warned
|
||||||
if not pex_warned:
|
if not pex_warned:
|
||||||
debug.error("PEX unable to run.", -1)
|
debug.error("PEX unable to run.", -1)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue