Refactor run scripts.

Run DRC, LVS, and PEX share a run_*.sh script.
This commit is contained in:
Matt Guthaus 2019-04-26 15:43:46 -07:00
parent 946a0aca86
commit 978ba9d2f2
3 changed files with 93 additions and 142 deletions

View File

@ -7,61 +7,13 @@
# #
""" """
This is a DRC/LVS interface for calibre. It implements completely This is a DRC/LVS interface for calibre. It implements completely
independently two functions: run_drc and run_lvs, that perform these independently three functions: run_drc, run_lvs, run_pex, that perform these
functions in batch mode and will return true/false if the result functions in batch mode and will return true/false if the result
passes. All of the setup (the rules, temp dirs, etc.) should be passes. All of the setup (the rules, temp dirs, etc.) should be
contained in this file. Replacing with another DRC/LVS tool involves contained in this file. Replacing with another DRC/LVS tool involves
rewriting this code to work properly. Porting to a new technology in rewriting this code to work properly. Porting to a new technology in
Calibre means pointing the code to the proper DRC and LVS rule files. Calibre means pointing the code to the proper DRC and LVS rule files.
A calibre DRC runset file contains, at the minimum, the following information:
*drcRulesFile: /mada/software/techfiles/FreePDK45/ncsu_basekit/techfile/calibre/calibreDRC.rul
*drcRunDir: .
*drcLayoutPaths: ./cell_6t.gds
*drcLayoutPrimary: cell_6t
*drcLayoutSystem: GDSII
*drcResultsformat: ASCII
*drcResultsFile: cell_6t.drc.results
*drcSummaryFile: cell_6t.drc.summary
*cmnFDILayerMapFile: ./layer.map
*cmnFDIUseLayerMap: 1
This can be executed in "batch" mode with the following command:
calibre -gui -drc example_drc_runset -batch
To open the results, you can do this:
calibredrv cell_6t.gds
Select Verification->Start RVE.
Select the cell_6t.drc.results file.
Click on the errors and they will highlight in the design layout viewer.
For LVS:
*lvsRulesFile: /mada/software/techfiles/FreePDK45/ncsu_basekit/techfile/calibre/calibreLVS.rul
*lvsRunDir: .
*lvsLayoutPaths: ./cell_6t.gds
*lvsLayoutPrimary: cell_6t
*lvsSourcePath: ./cell_6t.sp
*lvsSourcePrimary: cell_6t
*lvsSourceSystem: SPICE
*lvsSpiceFile: extracted.sp
*lvsPowerNames: vdd
*lvsGroundNames: vss
*lvsIgnorePorts: 1
*lvsERCDatabase: cell_6t.erc.results
*lvsERCSummaryFile: cell_6t.erc.summary
*lvsReportFile: cell_6t.lvs.report
*lvsMaskDBFile: cell_6t.maskdb
*cmnFDILayerMapFile: ./layer.map
*cmnFDIUseLayerMap: 1
To run and see results:
calibre -gui -lvs example_lvs_runset -batch
more cell_6t.lvs.report
""" """
@ -71,7 +23,7 @@ import re
import time import time
import debug import debug
from globals import OPTS from globals import OPTS
import subprocess from run_script import *
# Keep track of statistics # Keep track of statistics
num_drc_runs = 0 num_drc_runs = 0
@ -178,6 +130,51 @@ def write_calibre_lvs_script(cell_name, final_verification):
return lvs_runset return lvs_runset
def write_calibre_pex_script(cell_name, extract, output, final_verification):
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(cell_name + ".lvs.report"):
run_drc(cell_name, gds_name)
run_lvs(cell_name, gds_name, sp_name)
pex_rules = drc["xrc_rules"]
pex_runset = {
'pexRulesFile': pex_rules,
'pexRunDir': OPTS.openram_temp,
'pexLayoutPaths': cell_name + ".gds",
'pexLayoutPrimary': cell_name,
#'pexSourcePath' : OPTS.openram_temp+"extracted.sp",
'pexSourcePath': cell_name + ".sp",
'pexSourcePrimary': cell_name,
'pexReportFile': cell_name + ".lvs.report",
'pexPexNetlistFile': cell_name + ".pex.netlist",
'pexPexReportFile': cell_name + ".pex.report",
'pexMaskDBFile': cell_name + ".maskdb",
'cmnFDIDEFLayoutPath': cell_name + ".def",
}
# write the runset file
f = open(OPTS.openram_temp + "pex_runset", "w")
for k in sorted(iter(pex_runset.keys())):
f.write("*{0}: {1}\n".format(k, pex_runset[k]))
f.close()
# Create an auxiliary script to run calibre with the runset
run_file = OPTS.openram_temp + "run_pex.sh"
f = open(run_file, "w")
f.write("#!/bin/sh\n")
cmd = "{0} -gui -pex {1}pex_runset -batch".format(OPTS.pex_exe[1],
OPTS.openram_temp)
f.write(cmd)
f.write("\n")
f.close()
os.system("chmod u+x {}".format(run_file))
return pex_runset
def run_drc(cell_name, gds_name, extract=False, final_verification=False): def run_drc(cell_name, gds_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
@ -192,16 +189,7 @@ def run_drc(cell_name, gds_name, extract=False, final_verification=False):
drc_runset = write_calibre_drc_script(cell_name, extract, final_verification) drc_runset = write_calibre_drc_script(cell_name, extract, final_verification)
# run drc (outfile, errfile, resultsfile) = run_script(cell_name, "drc")
cwd = os.getcwd()
os.chdir(OPTS.openram_temp)
errfile = "{0}{1}.drc.err".format(OPTS.openram_temp, cell_name)
outfile = "{0}{1}.drc.out".format(OPTS.openram_temp, cell_name)
cmd = "run_drc.sh 2> {0} 1> {1}".format(errfile, outfile)
debug.info(2, cmd)
os.system(cmd)
os.chdir(cwd)
# check the result for these lines in the summary: # check the result for these lines in the summary:
# TOTAL Original Layer Geometries: 106 (157) # TOTAL Original Layer Geometries: 106 (157)
@ -249,16 +237,7 @@ def run_lvs(cell_name, gds_name, sp_name, final_verification=False):
if os.path.dirname(sp_name)!=OPTS.openram_temp.rstrip('/'): if os.path.dirname(sp_name)!=OPTS.openram_temp.rstrip('/'):
shutil.copy(sp_name, OPTS.openram_temp) shutil.copy(sp_name, OPTS.openram_temp)
# run lvs (outfile, errfile, resultsfile) = run_script(cell_name, "lvs")
cwd = os.getcwd()
os.chdir(OPTS.openram_temp)
errfile = "{0}{1}.lvs.err".format(OPTS.openram_temp, cell_name)
outfile = "{0}{1}.lvs.out".format(OPTS.openram_temp, cell_name)
cmd = "run_lvs.sh 2> {0} 1> {1}".format(errfile, outfile)
debug.info(2, cmd)
os.system(cmd)
os.chdir(cwd)
# check the result for these lines in the summary: # check the result for these lines in the summary:
f = open(OPTS.openram_temp + lvs_runset['lvsReportFile'], "r") f = open(OPTS.openram_temp + lvs_runset['lvsReportFile'], "r")
@ -338,51 +317,10 @@ def run_pex(cell_name, gds_name, sp_name, output=None, final_verification=False)
global num_pex_runs global num_pex_runs
num_pex_runs += 1 num_pex_runs += 1
from tech import drc write_calibre_pex_script()
if output == None:
output = name + ".pex.netlist"
# check if lvs report has been done (outfile, errfile, resultsfile) = run_script(cell_name, "pex")
# if not run drc and lvs
if not os.path.isfile(cell_name + ".lvs.report"):
run_drc(cell_name, gds_name)
run_lvs(cell_name, gds_name, sp_name)
pex_rules = drc["xrc_rules"]
pex_runset = {
'pexRulesFile': pex_rules,
'pexRunDir': OPTS.openram_temp,
'pexLayoutPaths': gds_name,
'pexLayoutPrimary': cell_name,
#'pexSourcePath' : OPTS.openram_temp+"extracted.sp",
'pexSourcePath': sp_name,
'pexSourcePrimary': cell_name,
'pexReportFile': cell_name + ".lvs.report",
'pexPexNetlistFile': output,
'pexPexReportFile': cell_name + ".pex.report",
'pexMaskDBFile': cell_name + ".maskdb",
'cmnFDIDEFLayoutPath': cell_name + ".def",
}
# write the runset file
f = open(OPTS.openram_temp + "pex_runset", "w")
for k in sorted(iter(pex_runset.keys())):
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, cell_name)
outfile = "{0}{1}.pex.out".format(OPTS.openram_temp, cell_name)
cmd = "{0} -gui -pex {1}pex_runset -batch 2> {2} 1> {3}".format(OPTS.pex_exe[1],
OPTS.openram_temp,
errfile,
outfile)
debug.info(2, cmd)
os.system(cmd)
os.chdir(cwd)
# also check the output file # also check the output file
f = open(outfile, "r") f = open(outfile, "r")

View File

@ -8,7 +8,7 @@
""" """
This is a DRC/LVS/PEX interface file for magic + netgen. This is a DRC/LVS/PEX interface file for magic + netgen.
We include the tech file for SCN3ME_SUBM in the tech directory, We include the tech file for SCN4M_SUBM in the tech directory,
that is included in OpenRAM during DRC. that is included in OpenRAM during DRC.
You can use this interactively by appending the magic system path in You can use this interactively by appending the magic system path in
your .magicrc file your .magicrc file
@ -26,13 +26,14 @@ import time
import shutil import shutil
import debug import debug
from globals import OPTS from globals import OPTS
import subprocess from run_script import *
# Keep track of statistics # Keep track of statistics
num_drc_runs = 0 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, 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. """
@ -92,6 +93,7 @@ def write_magic_script(cell_name, extract=False, final_verification=False):
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): def write_netgen_script(cell_name):
""" Write a netgen script to perform LVS. """ """ Write a netgen script to perform LVS. """
@ -137,18 +139,7 @@ def run_drc(cell_name, gds_name, extract=True, final_verification=False):
write_magic_script(cell_name, extract, final_verification) write_magic_script(cell_name, extract, final_verification)
# run drc (outfile, errfile, resultsfile) = run_script(cell_name, "drc")
cwd = os.getcwd()
os.chdir(OPTS.openram_temp)
errfile = "{0}{1}.drc.err".format(OPTS.openram_temp, cell_name)
outfile = "{0}{1}.drc.summary".format(OPTS.openram_temp, cell_name)
cmd = "{0}run_drc.sh 2> {1} 1> {2}".format(OPTS.openram_temp,
errfile,
outfile)
debug.info(2, cmd)
os.system(cmd)
os.chdir(cwd)
# Check the result for these lines in the summary: # Check the result for these lines in the summary:
# Total DRC errors found: 0 # Total DRC errors found: 0
@ -201,19 +192,7 @@ def run_lvs(cell_name, gds_name, sp_name, final_verification=False):
write_netgen_script(cell_name) write_netgen_script(cell_name)
# run LVS (outfile, errfile, resultsfile) = run_script(cell_name, "lvs")
cwd = os.getcwd()
os.chdir(OPTS.openram_temp)
errfile = "{0}{1}.lvs.err".format(OPTS.openram_temp, cell_name)
outfile = "{0}{1}.lvs.out".format(OPTS.openram_temp, cell_name)
resultsfile = "{0}{1}.lvs.report".format(OPTS.openram_temp, cell_name)
cmd = "{0}run_lvs.sh lvs 2> {1} 1> {2}".format(OPTS.openram_temp,
errfile,
outfile)
debug.info(2, cmd)
os.system(cmd)
os.chdir(cwd)
total_errors = 0 total_errors = 0

View File

@ -0,0 +1,34 @@
# See LICENSE for licensing information.
#
#Copyright (c) 2019 Regents of the University of California and The Board
#of Regents for the Oklahoma Agricultural and Mechanical College
#(acting for and on behalf of Oklahoma State University)
#All rights reserved.
#
"""
Some baseline functions to run scripts.
"""
import os
import debug
from globals import OPTS
def run_script(cell_name, script="lvs"):
""" Run script and create output files. """
cwd = os.getcwd()
os.chdir(OPTS.openram_temp)
errfile = "{0}{1}.{2}.err".format(OPTS.openram_temp, cell_name, script)
outfile = "{0}{1}.{2}.out".format(OPTS.openram_temp, cell_name, script)
resultsfile = "{0}{1}.{2}.report".format(OPTS.openram_temp, cell_name, script)
cmd = "{0}run_{1}.sh 2> {2} 1> {3}".format(OPTS.openram_temp,
script,
errfile,
outfile)
debug.info(2, cmd)
os.system(cmd)
os.chdir(cwd)
return (outfile,errfile,resultsfile)