Add magic filter before calibre for sky130

This commit is contained in:
mrg 2020-06-15 13:58:26 -07:00
parent abb5ff7bae
commit 7dfc462ef6
4 changed files with 62 additions and 21 deletions

View File

@ -110,6 +110,8 @@ class options(optparse.Values):
drc_exe = None drc_exe = None
lvs_exe = None lvs_exe = None
pex_exe = None pex_exe = None
# For sky130, we need magic for filtering.
magic_exe = None
# Should we print out the banner at startup # Should we print out the banner at startup
print_banner = True print_banner = True

View File

@ -18,27 +18,27 @@ If not, OpenRAM will continue as if nothing happened!
import os import os
import debug import debug
from globals import OPTS from globals import OPTS
from globals import find_exe
from globals import get_tool from globals import get_tool
from tech import drc_name from tech import drc_name
from tech import lvs_name from tech import lvs_name
from tech import pex_name from tech import pex_name
import sys
debug.info(1,"Initializing verify...") debug.info(1, "Initializing verify...")
if not OPTS.check_lvsdrc: if not OPTS.check_lvsdrc:
debug.info(1,"LVS/DRC/PEX disabled.") debug.info(1, "LVS/DRC/PEX disabled.")
OPTS.drc_exe = None OPTS.drc_exe = None
OPTS.lvs_exe = None OPTS.lvs_exe = None
OPTS.pex_exe = None OPTS.pex_exe = None
else: else:
debug.info(1, "Finding DRC/LVS/PEX tools.") debug.info(1, "Finding DRC/LVS/PEX tools.")
OPTS.drc_exe = get_tool("DRC", ["calibre","assura","magic"], drc_name) OPTS.drc_exe = get_tool("DRC", ["calibre", "assura", "magic"], drc_name)
OPTS.lvs_exe = get_tool("LVS", ["calibre","assura","netgen"], lvs_name) OPTS.lvs_exe = get_tool("LVS", ["calibre", "assura", "netgen"], lvs_name)
OPTS.pex_exe = get_tool("PEX", ["calibre","magic"], pex_name) OPTS.pex_exe = get_tool("PEX", ["calibre", "magic"], pex_name)
if OPTS.tech_name == "sky130":
OPTS.magic_exe = get_tool("GDS", ["magic"], None)
if OPTS.drc_exe == None: if not OPTS.drc_exe:
from .none import run_drc, print_drc_stats from .none import run_drc, print_drc_stats
elif "calibre"==OPTS.drc_exe[0]: elif "calibre"==OPTS.drc_exe[0]:
from .calibre import run_drc, print_drc_stats from .calibre import run_drc, print_drc_stats
@ -49,7 +49,7 @@ elif "magic"==OPTS.drc_exe[0]:
else: else:
debug.warning("Did not find a supported DRC tool.") debug.warning("Did not find a supported DRC tool.")
if OPTS.lvs_exe == None: if not OPTS.lvs_exe:
from .none import run_lvs, print_lvs_stats from .none import run_lvs, print_lvs_stats
elif "calibre"==OPTS.lvs_exe[0]: elif "calibre"==OPTS.lvs_exe[0]:
from .calibre import run_lvs, print_lvs_stats from .calibre import run_lvs, print_lvs_stats
@ -61,7 +61,7 @@ else:
debug.warning("Did not find a supported LVS tool.") debug.warning("Did not find a supported LVS tool.")
if OPTS.pex_exe == None: if not OPTS.pex_exe:
from .none import run_pex,print_pex_stats from .none import run_pex,print_pex_stats
elif "calibre"==OPTS.pex_exe[0]: elif "calibre"==OPTS.pex_exe[0]:
from .calibre import run_pex,print_pex_stats from .calibre import run_pex,print_pex_stats
@ -69,4 +69,10 @@ elif "magic"==OPTS.pex_exe[0]:
from .magic import run_pex,print_pex_stats from .magic import run_pex,print_pex_stats
else: else:
debug.warning("Did not find a supported PEX tool.") debug.warning("Did not find a supported PEX tool.")
if OPTS.tech_name == "sky130":
if "magic"==OPTS.magic_exe[0]:
from .magic import filter_gds
else:
debug.warning("Did not find Magic.")

View File

@ -20,16 +20,16 @@ Calibre means pointing the code to the proper DRC and LVS rule files.
import os import os
import shutil import shutil
import re import re
import time
import debug import debug
from globals import OPTS from globals import OPTS
from run_script import * from run_script import run_script
# 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_calibre_drc_script(cell_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
@ -67,6 +67,7 @@ def write_calibre_drc_script(cell_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, 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 """
@ -80,7 +81,7 @@ def write_calibre_lvs_script(cell_name, final_verification):
'lvsSourcePath': cell_name + ".sp", 'lvsSourcePath': cell_name + ".sp",
'lvsSourcePrimary': cell_name, 'lvsSourcePrimary': cell_name,
'lvsSourceSystem': 'SPICE', 'lvsSourceSystem': 'SPICE',
'lvsSpiceFile': "extracted.sp", 'lvsSpiceFile': "{}.spice".format(cell_name),
'lvsPowerNames': 'vdd', 'lvsPowerNames': 'vdd',
'lvsGroundNames': 'gnd', 'lvsGroundNames': 'gnd',
'lvsIncludeSVRFCmds': 1, 'lvsIncludeSVRFCmds': 1,
@ -130,8 +131,9 @@ 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):
def write_calibre_pex_script(cell_name, extract, output, final_verification):
""" Write a pex script that can either just extract the netlist or the netlist+parasitics """
if output == None: if output == None:
output = name + ".pex.netlist" output = name + ".pex.netlist"
@ -150,10 +152,9 @@ def write_calibre_pex_script(cell_name, extract, output, final_verification):
'pexRunDir': OPTS.openram_temp, 'pexRunDir': OPTS.openram_temp,
'pexLayoutPaths': cell_name + ".gds", 'pexLayoutPaths': cell_name + ".gds",
'pexLayoutPrimary': cell_name, 'pexLayoutPrimary': cell_name,
#'pexSourcePath' : OPTS.openram_temp+"extracted.sp",
'pexSourcePath': cell_name + ".sp", 'pexSourcePath': cell_name + ".sp",
'pexSourcePrimary': cell_name, 'pexSourcePrimary': cell_name,
'pexReportFile': cell_name + ".lvs.report", 'pexReportFile': cell_name + ".pex.report",
'pexPexNetlistFile': cell_name + ".pex.netlist", 'pexPexNetlistFile': cell_name + ".pex.netlist",
'pexPexReportFile': cell_name + ".pex.report", 'pexPexReportFile': cell_name + ".pex.report",
'pexMaskDBFile': cell_name + ".maskdb", 'pexMaskDBFile': cell_name + ".maskdb",
@ -179,6 +180,7 @@ def write_calibre_pex_script(cell_name, extract, output, final_verification):
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, 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."""
@ -186,9 +188,15 @@ 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
# Copy file to local dir if it isn't already # Filter the layouts through magic as a GDS filter for nsdm/psdm/nwell merging
if os.path.dirname(gds_name)!=OPTS.openram_temp.rstrip('/'): if OPTS.tech_name == "sky130":
shutil.copy(gds_name, OPTS.openram_temp) shutil.copy(gds_name, OPTS.openram_temp + "temp.gds")
from magic import filter_gds
filter_gds(cell_name, OPTS.openram_temp + "temp.gds", gds_name)
else:
# 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) drc_runset = write_calibre_drc_script(cell_name, extract, final_verification)

View File

@ -33,6 +33,31 @@ num_lvs_runs = 0
num_pex_runs = 0 num_pex_runs = 0
def filter_gds(cell_name, input_gds, output_gds):
""" Run the gds through magic for any layer processing """
global OPTS
run_file = OPTS.openram_temp + "run_filter.sh"
f = open(run_file, "w")
f.write("#!/bin/sh\n")
f.write("{} -dnull -noconsole << EOF\n".format(OPTS.magic_exe[1]))
f.write("gds polygon subcell true\n")
f.write("gds warning default\n")
f.write("gds read {}\n".format(input_gds))
f.write("load {}\n".format(cell_name))
f.write("cellname delete \\(UNNAMED\\)\n")
#f.write("writeall force\n")
f.write("select top cell\n")
f.write("gds write {}\n".format(output_gds))
f.write("quit -noprompt\n")
f.write("EOF\n")
f.close()
os.system("chmod u+x {}".format(run_file))
(outfile, errfile, resultsfile) = run_script(cell_name, "filter")
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. """