Simplify DRC and LVS run scripts.

Modified run scripts to work on local only files in the temp
directory. This assumes the files and subckts are named the
same as the clel name. Script now copies library files
to the temp directory as well.
This commit is contained in:
Matt Guthaus 2019-04-26 15:17:39 -07:00
parent 51a97979b9
commit 946a0aca86
2 changed files with 47 additions and 36 deletions

View File

@ -66,6 +66,7 @@ more cell_6t.lvs.report
import os import os
import shutil
import re import re
import time import time
import debug import debug
@ -77,7 +78,7 @@ num_drc_runs = 0
num_lvs_runs = 0 num_lvs_runs = 0
num_pex_runs = 0 num_pex_runs = 0
def write_calibre_drc_script(cell_name, gds_name, extract, final_verification): def write_calibre_drc_script(cell_name, extract, final_verification):
""" 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
from tech import drc from tech import drc
@ -86,12 +87,12 @@ def write_calibre_drc_script(cell_name, gds_name, extract, final_verification):
drc_runset = { drc_runset = {
'drcRulesFile': drc_rules, 'drcRulesFile': drc_rules,
'drcRunDir': OPTS.openram_temp, 'drcRunDir': OPTS.openram_temp,
'drcLayoutPaths': gds_name, 'drcLayoutPaths': cell_name + ".gds",
'drcLayoutPrimary': cell_name, 'drcLayoutPrimary': cell_name,
'drcLayoutSystem': 'GDSII', 'drcLayoutSystem': 'GDSII',
'drcResultsformat': 'ASCII', 'drcResultsformat': 'ASCII',
'drcResultsFile': OPTS.openram_temp + cell_name + ".drc.results", 'drcResultsFile': cell_name + ".drc.results",
'drcSummaryFile': OPTS.openram_temp + cell_name + ".drc.summary", 'drcSummaryFile': cell_name + ".drc.summary",
'cmnFDILayerMapFile': drc["layer_map"], 'cmnFDILayerMapFile': drc["layer_map"],
'cmnFDIUseLayerMap': 1 'cmnFDIUseLayerMap': 1
} }
@ -114,7 +115,7 @@ def write_calibre_drc_script(cell_name, gds_name, extract, final_verification):
os.system("chmod u+x {}".format(run_file)) os.system("chmod u+x {}".format(run_file))
return drc_runset return drc_runset
def write_calibre_lvs_script(cell_name, gds_name, sp_name, final_verification): def write_calibre_lvs_script(cell_name, final_verification):
""" Write a Calibre runset file and script to run LVS """ """ Write a Calibre runset file and script to run LVS """
from tech import drc from tech import drc
@ -122,20 +123,20 @@ def write_calibre_lvs_script(cell_name, gds_name, sp_name, final_verification):
lvs_runset = { lvs_runset = {
'lvsRulesFile': lvs_rules, 'lvsRulesFile': lvs_rules,
'lvsRunDir': OPTS.openram_temp, 'lvsRunDir': OPTS.openram_temp,
'lvsLayoutPaths': gds_name, 'lvsLayoutPaths': cell_name + ".gds",
'lvsLayoutPrimary': cell_name, 'lvsLayoutPrimary': cell_name,
'lvsSourcePath': sp_name, 'lvsSourcePath': cell_name + ".sp",
'lvsSourcePrimary': cell_name, 'lvsSourcePrimary': cell_name,
'lvsSourceSystem': 'SPICE', 'lvsSourceSystem': 'SPICE',
'lvsSpiceFile': OPTS.openram_temp + "extracted.sp", 'lvsSpiceFile': "extracted.sp",
'lvsPowerNames': 'vdd', 'lvsPowerNames': 'vdd',
'lvsGroundNames': 'gnd', 'lvsGroundNames': 'gnd',
'lvsIncludeSVRFCmds': 1, 'lvsIncludeSVRFCmds': 1,
'lvsIgnorePorts': 1, 'lvsIgnorePorts': 1,
'lvsERCDatabase': OPTS.openram_temp + cell_name + ".erc.results", 'lvsERCDatabase': cell_name + ".erc.results",
'lvsERCSummaryFile': OPTS.openram_temp + cell_name + ".erc.summary", 'lvsERCSummaryFile': cell_name + ".erc.summary",
'lvsReportFile': OPTS.openram_temp + cell_name + ".lvs.report", 'lvsReportFile': cell_name + ".lvs.report",
'lvsMaskDBFile': OPTS.openram_temp + cell_name + ".maskdb", 'lvsMaskDBFile': cell_name + ".maskdb",
'cmnFDILayerMapFile': drc["layer_map"], 'cmnFDILayerMapFile': drc["layer_map"],
'cmnFDIUseLayerMap': 1, 'cmnFDIUseLayerMap': 1,
'cmnTranscriptFile': './lvs.log', 'cmnTranscriptFile': './lvs.log',
@ -185,7 +186,11 @@ def run_drc(cell_name, gds_name, extract=False, final_verification=False):
global num_drc_runs global num_drc_runs
num_drc_runs += 1 num_drc_runs += 1
drc_runset = write_calibre_drc_script(cell_name, gds_name, extract, final_verification) # Copy file to local dir if it isn't already
if os.path.dirname(gds_name)!=OPTS.openram_temp.rstrip('/'):
shutil.copy(gds_name, OPTS.openram_temp)
drc_runset = write_calibre_drc_script(cell_name, extract, final_verification)
# run drc # run drc
cwd = os.getcwd() cwd = os.getcwd()
@ -193,9 +198,7 @@ def run_drc(cell_name, gds_name, extract=False, final_verification=False):
errfile = "{0}{1}.drc.err".format(OPTS.openram_temp, cell_name) errfile = "{0}{1}.drc.err".format(OPTS.openram_temp, cell_name)
outfile = "{0}{1}.drc.out".format(OPTS.openram_temp, cell_name) outfile = "{0}{1}.drc.out".format(OPTS.openram_temp, cell_name)
cmd = "{0}run_drc.sh 2> {1} 1> {2}".format(OPTS.openram_temp, cmd = "run_drc.sh 2> {0} 1> {1}".format(errfile, outfile)
errfile,
outfile)
debug.info(2, cmd) debug.info(2, cmd)
os.system(cmd) os.system(cmd)
os.chdir(cwd) os.chdir(cwd)
@ -205,7 +208,7 @@ def run_drc(cell_name, gds_name, extract=False, final_verification=False):
# TOTAL DRC RuleChecks Executed: 156 # TOTAL DRC RuleChecks Executed: 156
# TOTAL DRC Results Generated: 0 (0) # TOTAL DRC Results Generated: 0 (0)
try: try:
f = open(drc_runset['drcSummaryFile'], "r") f = open(OPTS.openram_temp + drc_runset['drcSummaryFile'], "r")
except: except:
debug.error("Unable to retrieve DRC results file. Is calibre set up?",1) debug.error("Unable to retrieve DRC results file. Is calibre set up?",1)
results = f.readlines() results = f.readlines()
@ -238,23 +241,27 @@ 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
lvs_runset = write_calibre_lvs_script(cell_name, gds_name, sp_name, final_verification) lvs_runset = write_calibre_lvs_script(cell_name, final_verification)
# Copy file to local dir if it isn't already
if os.path.dirname(gds_name)!=OPTS.openram_temp.rstrip('/'):
shutil.copy(gds_name, OPTS.openram_temp)
if os.path.dirname(sp_name)!=OPTS.openram_temp.rstrip('/'):
shutil.copy(sp_name, OPTS.openram_temp)
# run lvs # run lvs
cwd = os.getcwd() cwd = os.getcwd()
os.chdir(OPTS.openram_temp) os.chdir(OPTS.openram_temp)
errfile = "{0}{1}.lvs.err".format(OPTS.openram_temp, cell_name) errfile = "{0}{1}.lvs.err".format(OPTS.openram_temp, cell_name)
outfile = "{0}{1}.lvs.out".format(OPTS.openram_temp, cell_name) outfile = "{0}{1}.lvs.out".format(OPTS.openram_temp, cell_name)
cmd = "{0}run_lvs.sh 2> {1} 1> {2}".format(OPTS.openram_temp, cmd = "run_lvs.sh 2> {0} 1> {1}".format(errfile, outfile)
errfile,
outfile)
debug.info(2, cmd) debug.info(2, cmd)
os.system(cmd) os.system(cmd)
os.chdir(cwd) os.chdir(cwd)
# check the result for these lines in the summary: # check the result for these lines in the summary:
f = open(lvs_runset['lvsReportFile'], "r") f = open(OPTS.openram_temp + lvs_runset['lvsReportFile'], "r")
results = f.readlines() results = f.readlines()
f.close() f.close()
@ -277,7 +284,7 @@ def run_lvs(cell_name, gds_name, sp_name, final_verification=False):
summary_errors = len(notcompared) + len(incorrect) + len(errors) summary_errors = len(notcompared) + len(incorrect) + len(errors)
# also check the extraction summary file # also check the extraction summary file
f = open(lvs_runset['lvsReportFile'] + ".ext", "r") f = open(OPTS.openram_temp + lvs_runset['lvsReportFile'] + ".ext", "r")
results = f.readlines() results = f.readlines()
f.close() f.close()

View File

@ -33,7 +33,7 @@ num_drc_runs = 0
num_lvs_runs = 0 num_lvs_runs = 0
num_pex_runs = 0 num_pex_runs = 0
def write_magic_script(cell_name, gds_name, extract=False, final_verification=False): def write_magic_script(cell_name, extract=False, final_verification=False):
""" Write a magic script to perform DRC and optionally extraction. """ """ Write a magic script to perform DRC and optionally extraction. """
global OPTS global OPTS
@ -44,7 +44,7 @@ def write_magic_script(cell_name, gds_name, extract=False, final_verification=Fa
f.write("{} -dnull -noconsole << EOF\n".format(OPTS.drc_exe[1])) f.write("{} -dnull -noconsole << EOF\n".format(OPTS.drc_exe[1]))
f.write("gds polygon subcell true\n") f.write("gds polygon subcell true\n")
f.write("gds warning default\n") f.write("gds warning default\n")
f.write("gds read {}\n".format(gds_name)) f.write("gds read {}.gds\n".format(cell_name))
f.write("load {}\n".format(cell_name)) f.write("load {}\n".format(cell_name))
# Flatten the cell to get rid of DRCs spanning multiple layers # Flatten the cell to get rid of DRCs spanning multiple layers
# (e.g. with routes) # (e.g. with routes)
@ -92,7 +92,7 @@ def write_magic_script(cell_name, gds_name, extract=False, final_verification=Fa
f.close() f.close()
os.system("chmod u+x {}".format(run_file)) os.system("chmod u+x {}".format(run_file))
def write_netgen_script(cell_name, sp_name): def write_netgen_script(cell_name):
""" Write a netgen script to perform LVS. """ """ Write a netgen script to perform LVS. """
global OPTS global OPTS
@ -110,14 +110,8 @@ def write_netgen_script(cell_name, sp_name):
f.write("#!/bin/sh\n") f.write("#!/bin/sh\n")
f.write("{} -noconsole << EOF\n".format(OPTS.lvs_exe[1])) f.write("{} -noconsole << EOF\n".format(OPTS.lvs_exe[1]))
f.write("readnet spice {0}.spice\n".format(cell_name)) f.write("readnet spice {0}.spice\n".format(cell_name))
f.write("readnet spice {0}\n".format(sp_name)) f.write("readnet spice {0}.sp\n".format(cell_name))
# Allow some flexibility in W size because magic will snap to a lambda grid f.write("lvs {{{0}.spice {0}}} {{{0}.sp {0}}} {1} {0}.lvs.report\n".format(cell_name, setup_file))
# This can also cause disconnects unfortunately!
# f.write("property {{{0}{1}.spice nfet}} tolerance {{w 0.1}}\n".format(OPTS.openram_temp,
# cell_name))
# f.write("property {{{0}{1}.spice pfet}} tolerance {{w 0.1}}\n".format(OPTS.openram_temp,
# cell_name))
f.write("lvs {{{0}.spice {0}}} {{{1} {0}}} {2} {0}.lvs.report\n".format(cell_name, sp_name, setup_file))
f.write("quit\n") f.write("quit\n")
f.write("EOF\n") f.write("EOF\n")
f.close() f.close()
@ -130,6 +124,10 @@ def run_drc(cell_name, gds_name, extract=True, final_verification=False):
global num_drc_runs global num_drc_runs
num_drc_runs += 1 num_drc_runs += 1
# Copy file to local dir if it isn't already
if os.path.dirname(gds_name)!=OPTS.openram_temp.rstrip('/'):
shutil.copy(gds_name, OPTS.openram_temp)
# Copy .magicrc file into temp dir # Copy .magicrc file into temp dir
magic_file = OPTS.openram_tech + "mag_lib/.magicrc" magic_file = OPTS.openram_tech + "mag_lib/.magicrc"
if os.path.exists(magic_file): if os.path.exists(magic_file):
@ -137,7 +135,7 @@ def run_drc(cell_name, gds_name, extract=True, final_verification=False):
else: else:
debug.warning("Could not locate .magicrc file: {}".format(magic_file)) debug.warning("Could not locate .magicrc file: {}".format(magic_file))
write_magic_script(cell_name, gds_name, extract, final_verification) write_magic_script(cell_name, extract, final_verification)
# run drc # run drc
cwd = os.getcwd() cwd = os.getcwd()
@ -194,8 +192,14 @@ 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 os.path.dirname(gds_name)!=OPTS.openram_temp.rstrip('/'):
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_netgen_script(cell_name, sp_name) write_netgen_script(cell_name)
# run LVS # run LVS
cwd = os.getcwd() cwd = os.getcwd()