def read_netlist(lef_file, def_file): # intialize the database db = odb.dbDatabase.create() # load the lef file try: odb.read_lef(db, lef_file) except Exception as e: logger.error("Problem loading the tech file!") return None # load the def file try: odb.read_def(db, def_file) except Exception as e: logger.error("Problem loading the design!") return None # parse the design into a DGL graph design = db.getChip() G = build_graph(design) print(str.format('Built a graph with %s nodes' % str(G.number_of_nodes()))) print(str.format('.... Added %s edges' % str(G.number_of_edges()))) return G
def read_netlist(lef_file, netlist_file, load_cache=True): logger = get_logger() if os.path.exists(netlist_file + '.dgl') and load_cache: graphs, _ = load_graphs(netlist_file + '.dgl') logger.info("Loaded a cached graph") return graphs[0] # intialize the database import opendbpy as odb db = odb.dbDatabase.create() # load the lef file try: odb.read_lef(db, lef_file) except Exception as e: logger.error("Problem loading the tech file!") return None # load the def file try: odb.read_def(db, netlist_file) except Exception as e: logger.error("Problem loading the design!") return None # parse the design into a DGL graph design = db.getChip() G = _build_graph(design) logger.info('Built a graph with %s nodes', str(G.number_of_nodes())) logger.info('.... Added %s edges', str(G.number_of_edges())) _save_g(netlist_file + '.dgl', G) return G
input_def_file_name = args.input_def input_lef_file_names = args.lef extra_mappings = args.map extra_mappings_pin_names = [tup[2] for tup in extra_mappings] if args.output is not None: output_def_file_name = args.output else: print("Warning: The input DEF file will be overwritten") output_def_file_name = input_def_file_name mapping_db = odb.dbDatabase.create() for lef in netlist_lef_file_names: odb.read_lef(mapping_db, lef) odb.read_def(mapping_db, netlist_def_file_name) # for later chip_db = odb.dbDatabase.create() for lef in input_lef_file_names: print(lef) odb.read_lef(chip_db, lef) odb.read_def(chip_db, input_def_file_name) mapping_chip = mapping_db.getChip() mapping_block = mapping_chip.getBlock() mapping_nets = mapping_block.getNets() pad_pin_map = {} for net in mapping_nets: iterms = net.getITerms()
import opendbpy as odb import os current_dir = os.path.dirname(os.path.realpath(__file__)) tests_dir = os.path.abspath(os.path.join(current_dir, os.pardir)) opendb_dir = os.path.abspath(os.path.join(tests_dir, os.pardir)) data_dir = os.path.join(tests_dir, "data") db = odb.dbDatabase.create() lib = odb.read_lef(db, os.path.join(data_dir, "gscl45nm.lef")) odb.read_def(db, os.path.join(data_dir, "design.def")) chip = db.getChip() block = chip.getBlock() result = odb.write_lef(lib, os.path.join(opendb_dir, "build", "lef.out")) assert result==1, "LEF not written"
import opendbpy as odb import os current_dir = os.path.dirname(os.path.realpath(__file__)) tests_dir = os.path.abspath(os.path.join(current_dir, os.pardir)) opendb_dir = os.path.abspath(os.path.join(tests_dir, os.pardir)) data_dir = os.path.join(tests_dir, "data") db = odb.dbDatabase.create() lib = odb.read_lef( db, os.path.join(data_dir, "Nangate45/NangateOpenCellLibrary.mod.lef")) odb.read_def(db, os.path.join(data_dir, "gcd/floorplan.def")) chip = db.getChip() tech = db.getTech() block = chip.getBlock() sites = lib.getSites() site = sites[0] rt = odb.dbRow_create(block, "ROW_TEST", site, 0, 380, "MX", "HORIZONTAL", 420, 380) assert rt.getName() == "ROW_TEST", "Rown name mismatch" assert rt.getOrigin() == [0, 380], "Row origin mismatch" assert rt.getSite().getName() == site.getName(), "Row Site name mismatch" assert rt.getDirection() == "HORIZONTAL", "Row diretion mismatch" assert rt.getOrient() == "MX", "Row orientation mismatch" assert rt.getSpacing() == 380, "Row spacing mismatch" assert rt.getSiteCount() == 420, "row site count mismatch" rt1 = odb.dbRow_create(block, "ROW_TEST", site, 0, 380, "R0", "HORIZONTAL", 420, 380)
parser.add_argument('--output-def', '-o', required=True, help='Output placed DEF file') args = parser.parse_args() input_lef_file_names = args.lef input_def_file_name = args.input_def output_def_file_name = args.output_def # Load db_design = odb.dbDatabase.create() for lef in input_lef_file_names: odb.read_lef(db_design, lef) odb.read_def(db_design, input_def_file_name) chip_design = db_design.getChip() block_design = chip_design.getBlock() top_design_name = block_design.getName() print("Design name:", top_design_name) cfg = { 'diode_cell_true': 'sky130_fd_sc_hd__diode_2', 'diode_cell_fake': 'sky130_ef_sc_hd__fakediode_2', 'diode_cell_pin': 'DIODE', } di = DiodeInserter(block_design, cfg) di.execute() # Write result
# top_def_new_file_name = os.path.join(os.path.dirname(macro_def_file_name), os.path.basename(macro_def_file_name) + ".top.def") # copy(os.path.normpath(top_lef_file_name), top_lef_new_file_name) # copy(os.path.normpath(top_def_file_name), top_def_new_file_name) # top_lef_file_name = top_lef_new_file_name # top_def_file_name = top_def_new_file_name db_macro = odb.dbDatabase.create() db_top = odb.dbDatabase.create() odb.read_lef(db_macro, top_lef_file_name ) # must read first to have consistent views with the top-level odb.read_lef( db_macro, macro_lef_file_name ) # rest of the macros that don't appear in the top-level are covered here odb.read_def(db_macro, macro_def_file_name) odb.read_lef(db_top, top_lef_file_name) odb.read_def(db_top, top_def_file_name) chip_macro = db_macro.getChip() block_macro = chip_macro.getBlock() macro_design_name = block_macro.getName() chip_top = db_top.getChip() block_top = chip_top.getBlock() top_design_name = block_top.getName() print("Block design name:", macro_design_name) print("Top-level design name:", top_design_name)
# distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import argparse import opendbpy as odb # overkill parser = argparse.ArgumentParser( description='gets the core dimensions from DEF/LEF') parser.add_argument('--input-def', '-d', required=True) parser.add_argument('--input-lef', '-l', required=True) args = parser.parse_args() input_lef_file_name = args.input_lef input_def_file_name = args.input_def db = odb.dbDatabase.create() odb.read_lef(db, input_lef_file_name) odb.read_def(db, input_def_file_name) chip = db.getChip() tech = db.getTech() block = chip.getBlock() r = block.getCoreArea() print(r.dx() / tech.getDbUnitsPerMicron(), r.dy() / tech.getDbUnitsPerMicron())
import opendbpy as odb import os current_dir = os.path.dirname(os.path.realpath(__file__)) tests_dir = os.path.abspath(os.path.join(current_dir, os.pardir)) opendb_dir = os.path.abspath(os.path.join(tests_dir, os.pardir)) data_dir = os.path.join(tests_dir, "data") db = odb.dbDatabase.create() odb.read_lef( db, os.path.join(data_dir, "Nangate45", "NangateOpenCellLibrary.mod.lef")) odb.read_lef(db, os.path.join(data_dir, "ICEWall", "dummy_pads.lef")) odb.read_def(db, os.path.join(data_dir, "ICEWall", "octilinear.def")) chip = db.getChip() if chip == None: exit("Read DEF Failed") result = odb.write_def( chip.getBlock(), os.path.join(opendb_dir, "build", "generated_octilinear.def")) assert result == 1, "DEF not written" db_file = os.path.join(opendb_dir, "build", "export_oct.db") export_result = odb.write_db(db, db_file) if export_result != 1: exit("Export DB Failed") new_db = odb.dbDatabase.create() new_db = odb.read_db(new_db, db_file) if odb.db_diff(db, new_db): exit("Error: Difference found between exported and imported DB")
if port.getSigType() == "POWER" or port.getName() == power_port_name: vdd_ports.append(port) elif port.getSigType() == "GROUND" or port.getName() == ground_port_name: gnd_ports.append(port) return (vdd_ports, gnd_ports) def find_power_ground_port(port_name, ports): for port in ports: if port.getName() == port_name: return port return None db = odb.dbDatabase.create() odb.read_lef(db, lef_file_name) odb.read_def(db, def_file_name) chip = db.getChip() block = chip.getBlock() design_name = block.getName() print("Top-level design name:", design_name) VDD_PORTS, GND_PORTS = get_power_ground_ports(block.getBTerms()) assert VDD_PORTS and GND_PORTS, "No power ports found at the top-level. "\ "Make sure that they exist and have the USE POWER|GROUND property or "\ "they match the arguments specified with --power-port and --ground-port." DEFAULT_VDD = VDD_PORTS[0].getNet() DEFAULT_GND = GND_PORTS[0].getNet()
}, ] else: gnd_pad_pin_map = [{ "pad_pin": mapping[0], "pad_name_substr": mapping[1] } for mapping in gnd_pad_pin_map] SPECIAL_NETS[VDD_NET_NAME]["map"] = vdd_pad_pin_map SPECIAL_NETS[GND_NET_NAME]["map"] = gnd_pad_pin_map ################## db_top = odb.dbDatabase.create() odb.read_lef(db_top, lef_file_name) odb.read_def(db_top, def_file_name) chip_top = db_top.getChip() block_top = chip_top.getBlock() top_design_name = block_top.getName() tech = db_top.getTech() via_rules = tech.getViaGenerateRules() print("Found", len(via_rules), "VIA GENERATE rules") # build dictionary of basic custom vias (ROW = COL = 1) custom_vias = {} for rule in via_rules: lower_rules = rule.getViaLayerRule(0) upper_rules = rule.getViaLayerRule(1) cut_rules = rule.getViaLayerRule(2)
import opendbpy as odb import os current_dir = os.path.dirname(os.path.realpath(__file__)) tests_dir = os.path.abspath(os.path.join(current_dir, os.pardir)) opendb_dir = os.path.abspath(os.path.join(tests_dir, os.pardir)) data_dir = os.path.join(tests_dir, "data") db = odb.dbDatabase.create() lib = odb.read_lef( db, os.path.join(data_dir, "Nangate45/NangateOpenCellLibrary.mod.lef")) odb.read_def(db, os.path.join(data_dir, "gcd/gcd_pdn.def")) chip = db.getChip() block = chip.getBlock() nets = block.getNets() tech = db.getTech() assert block.getName() == "gcd", "Block name mismatch" units = block.getDefUnits() assert units == 2000, "DEF units mismatch" assert len(block.getChildren()) == 0, "Number of children mismatch" assert len(block.getInsts()) == 0, "Number of instsances mismatch" assert len(block.getBTerms()) == 0, "Number of B terms mismatch" assert len(block.getObstructions()) == 0, "Number of obstructions mismatch" assert len(block.getBlockages()) == 0, "NUmber of blockages mismatch" assert len(block.getNets()) == 2, "Number of nets mismatch" assert len(block.getVias()) == 6, "Number of vias mismatch" assert len(block.getRows()) == 112, "Number of rows mismatch" bbox = block.getBBox() assert bbox.xMin() == 20140, "Bbox xMin mismatch"
parser.add_argument('--output-def', '-o', required=True, help='Output placed DEF file') db_design = odb.dbDatabase.create() args = parser.parse_args() input_lef_file_names = args.lef input_def_file_name = args.input_def output_def_file_name = args.output_def for lef in input_lef_file_names: odb.read_lef(db_design, lef) odb.read_def(db_design, input_def_file_name) chip_design = db_design.getChip() block_design = chip_design.getBlock() top_design_name = block_design.getName() print("Design name:", top_design_name) SRAMPower(block_design).process_all() odb.write_def(block_design, output_def_file_name) import sys sys.exit(0) import opendbpy as odb
print("STDERR:") print(output[1].strip()) print("openroad exit code:", p.returncode) assert p.returncode == 0 # TODO: check for errors else: assert def_netlist is not None working_def = def_netlist assert os.path.exists(working_def), "DEF file doesn't exist" db_top = odb.dbDatabase.create() # odb.read_db(db_top, f"{design}.pf.db") for lef in lefs: odb.read_lef(db_top, lef) odb.read_def(db_top, working_def) chip_top = db_top.getChip() block_top = chip_top.getBlock() top_design_name = block_top.getName() print("Top-level design name:", top_design_name) ## Step 2: create a simple data structure with pads from the library # types: corner, power, other pads = {} libs = db_top.getLibs() for lib in libs: masters = lib.getMasters() for m in masters: name = m.getName()
obs_list = [] for obs in obses: obs = obs.strip() m = re.match(RE_OBS, obs) assert m,\ "Incorrectly formatted input (%s).\n Format: layer llx lly urx ury, ..." % (obs) layer = m.group('layer') bbox = [float(x) for x in m.group('bbox').split()] obs_list.append((layer, bbox)) design_db = odb.dbDatabase.create() for lef in input_lef_file_names: odb.read_lef(design_db, lef) odb.read_def(design_db, input_def_file_name) design_chip = design_db.getChip() design_block = design_chip.getBlock() design_insts = design_block.getInsts() design_tech = design_db.getTech() for obs in obs_list: layer = obs[0] bbox = obs[1] dbu = design_tech.getDbUnitsPerMicron() bbox = [int(x * dbu) for x in bbox] print("Creating an obstruction on", layer, "at", *bbox, "(DBU)") odb.dbObstruction_create(design_block, design_tech.findLayer(layer), *bbox) odb.write_def(design_block, output_def_file_name)
args = parser.parse_args() def_file_name = args.input_def lef_file_name = args.input_lef power_port_name = args.power_port ground_port_name = args.ground_port ignore_missing_pins = args.ignore_missing_pins output_file_name = args.output db = odb.dbDatabase.create() odb.read_lef(db, lef_file_name) odb.read_def(db, def_file_name) chip = db.getChip() block = chip.getBlock() design_name = block.getName() print("Top-level design name:", design_name) VDD = None GND = None ports = block.getBTerms() for port in ports: if port.getSigType() == "POWER" or port.getName() == power_port_name: print("Found port", port.getName(), "of type", port.getSigType()) VDD = port