mirror of
https://github.com/VLSIDA/OpenRAM.git
synced 2026-08-30 01:48:33 +02:00
PR from mithro + other changable GDS file names
This commit is contained in:
@@ -34,7 +34,7 @@ class contact(hierarchy_design.hierarchy_design):
|
||||
# This will ignore the name parameter since
|
||||
# we can guarantee a unique name here
|
||||
|
||||
super().__init__(name)
|
||||
super().__init__(name, name)
|
||||
debug.info(4, "create contact object {0}".format(name))
|
||||
|
||||
self.add_comment("layers: {0}".format(layer_stack))
|
||||
|
||||
@@ -20,8 +20,10 @@ class design(hierarchy_design):
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, name):
|
||||
super().__init__(name)
|
||||
def __init__(self, name, cell_name=None):
|
||||
if not cell_name:
|
||||
cell_name = name
|
||||
super().__init__(name, cell_name)
|
||||
|
||||
self.setup_multiport_constants()
|
||||
|
||||
|
||||
@@ -227,7 +227,7 @@ class instance(geometry):
|
||||
self.mod.gds_write_file(self.gds)
|
||||
# now write an instance of my module/structure
|
||||
new_layout.addInstance(self.gds,
|
||||
self.mod.name,
|
||||
self.mod.cell_name,
|
||||
offsetInMicrons=self.offset,
|
||||
mirror=self.mirror,
|
||||
rotate=self.rotate)
|
||||
@@ -402,11 +402,11 @@ class instance(geometry):
|
||||
|
||||
def __str__(self):
|
||||
""" override print function output """
|
||||
return "( inst: " + self.name + " @" + str(self.offset) + " mod=" + self.mod.name + " " + self.mirror + " R=" + str(self.rotate) + ")"
|
||||
return "( inst: " + self.name + " @" + str(self.offset) + " mod=" + self.mod.cell_name + " " + self.mirror + " R=" + str(self.rotate) + ")"
|
||||
|
||||
def __repr__(self):
|
||||
""" override print function output """
|
||||
return "( inst: " + self.name + " @" + str(self.offset) + " mod=" + self.mod.name + " " + self.mirror + " R=" + str(self.rotate) + ")"
|
||||
return "( inst: " + self.name + " @" + str(self.offset) + " mod=" + self.mod.cell_name + " " + self.mirror + " R=" + str(self.rotate) + ")"
|
||||
|
||||
|
||||
class path(geometry):
|
||||
|
||||
@@ -20,9 +20,9 @@ class hierarchy_design(hierarchy_spice.spice, hierarchy_layout.layout):
|
||||
"""
|
||||
name_map = []
|
||||
|
||||
def __init__(self, name):
|
||||
self.gds_file = OPTS.openram_tech + "gds_lib/" + name + ".gds"
|
||||
self.sp_file = OPTS.openram_tech + "sp_lib/" + name + ".sp"
|
||||
def __init__(self, name, cell_name):
|
||||
self.gds_file = OPTS.openram_tech + "gds_lib/" + cell_name + ".gds"
|
||||
self.sp_file = OPTS.openram_tech + "sp_lib/" + cell_name + ".sp"
|
||||
|
||||
# If we have a separate lvs directory, then all the lvs files
|
||||
# should be in there (all or nothing!)
|
||||
@@ -41,8 +41,9 @@ class hierarchy_design(hierarchy_spice.spice, hierarchy_layout.layout):
|
||||
self.lvs_errors = "skipped"
|
||||
|
||||
self.name = name
|
||||
hierarchy_spice.spice.__init__(self, name)
|
||||
hierarchy_layout.layout.__init__(self, name)
|
||||
self.cell_name = cell_name
|
||||
hierarchy_spice.spice.__init__(self, name, cell_name)
|
||||
hierarchy_layout.layout.__init__(self, name, cell_name)
|
||||
self.init_graph_params()
|
||||
|
||||
def get_layout_pins(self, inst):
|
||||
@@ -76,17 +77,17 @@ class hierarchy_design(hierarchy_spice.spice, hierarchy_layout.layout):
|
||||
self.lvs_write(tempspice)
|
||||
self.gds_write(tempgds)
|
||||
# Final verification option does not allow nets to be connected by label.
|
||||
self.drc_errors = verify.run_drc(self.name, tempgds, extract=True, final_verification=final_verification)
|
||||
self.lvs_errors = verify.run_lvs(self.name, tempgds, tempspice, final_verification=final_verification)
|
||||
self.drc_errors = verify.run_drc(self.cell_name, tempgds, extract=True, 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
|
||||
# if that flag is set
|
||||
if OPTS.inline_lvsdrc and not force_check:
|
||||
debug.check(self.drc_errors == 0,
|
||||
"DRC failed for {0} with {1} error(s)".format(self.name,
|
||||
"DRC failed for {0} with {1} error(s)".format(self.cell_name,
|
||||
self.drc_errors))
|
||||
debug.check(self.lvs_errors == 0,
|
||||
"LVS failed for {0} with {1} errors(s)".format(self.name,
|
||||
"LVS failed for {0} with {1} errors(s)".format(self.cell_name,
|
||||
self.lvs_errors))
|
||||
|
||||
if OPTS.purge_temp:
|
||||
@@ -104,11 +105,11 @@ class hierarchy_design(hierarchy_spice.spice, hierarchy_layout.layout):
|
||||
if OPTS.netlist_only:
|
||||
return
|
||||
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.name)
|
||||
tempgds = "{0}/{1}.gds".format(OPTS.openram_temp, self.cell_name)
|
||||
self.gds_write(tempgds)
|
||||
num_errors = verify.run_drc(self.name, tempgds, final_verification=final_verification)
|
||||
num_errors = verify.run_drc(self.cell_name, tempgds, final_verification=final_verification)
|
||||
debug.check(num_errors == 0,
|
||||
"DRC failed for {0} with {1} error(s)".format(self.name,
|
||||
"DRC failed for {0} with {1} error(s)".format(self.cell_name,
|
||||
num_errors))
|
||||
|
||||
if OPTS.purge_temp:
|
||||
@@ -125,13 +126,13 @@ class hierarchy_design(hierarchy_spice.spice, hierarchy_layout.layout):
|
||||
if OPTS.netlist_only:
|
||||
return
|
||||
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.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.gds_write(tempgds)
|
||||
num_errors = verify.run_lvs(self.name, tempgds, tempspice, final_verification=final_verification)
|
||||
debug.check(num_errors == 0,
|
||||
"LVS failed for {0} with {1} error(s)".format(self.name,
|
||||
"LVS failed for {0} with {1} error(s)".format(self.cell_name,
|
||||
num_errors))
|
||||
if OPTS.purge_temp:
|
||||
os.remove(tempspice)
|
||||
@@ -217,7 +218,7 @@ class hierarchy_design(hierarchy_spice.spice, hierarchy_layout.layout):
|
||||
pins = ",".join(self.pins)
|
||||
insts = [" {}".format(x) for x in self.insts]
|
||||
objs = [" {}".format(x) for x in self.objs]
|
||||
s = "********** design {0} **********".format(self.name)
|
||||
s = "********** design {0} **********".format(self.cell_name)
|
||||
s += "\n pins ({0})={1}\n".format(len(self.pins), pins)
|
||||
s += "\n objs ({0})=\n{1}\n".format(len(self.objs), "\n".join(objs))
|
||||
s += "\n insts ({0})=\n{1}\n".format(len(self.insts), "\n".join(insts))
|
||||
|
||||
@@ -30,8 +30,9 @@ class layout():
|
||||
layout/netlist and perform LVS/DRC.
|
||||
"""
|
||||
|
||||
def __init__(self, name):
|
||||
def __init__(self, name, cell_name):
|
||||
self.name = name
|
||||
self.cell_name = cell_name
|
||||
self.width = None
|
||||
self.height = None
|
||||
self.bounding_box = None
|
||||
@@ -214,7 +215,7 @@ class layout():
|
||||
# Contacts are not really instances, so skip them
|
||||
if "contact" not in mod.name:
|
||||
# Check that the instance name is unique
|
||||
debug.check(name not in self.inst_names, "Duplicate named instance in {0}: {1}".format(self.name, name))
|
||||
debug.check(name not in self.inst_names, "Duplicate named instance in {0}: {1}".format(self.cell_name, name))
|
||||
|
||||
self.inst_names.add(name)
|
||||
self.insts.append(geometry.instance(name, mod, offset, mirror, rotate))
|
||||
@@ -315,7 +316,7 @@ class layout():
|
||||
return any_pin
|
||||
except Exception:
|
||||
self.gds_write("missing_pin.gds")
|
||||
debug.error("No pin found with name {0} on {1}. Saved as missing_pin.gds.".format(text, self.name), -1)
|
||||
debug.error("No pin found with name {0} on {1}. Saved as missing_pin.gds.".format(text, self.cell_name), -1)
|
||||
|
||||
def get_pins(self, text):
|
||||
"""
|
||||
|
||||
@@ -10,6 +10,7 @@ import re
|
||||
import os
|
||||
import math
|
||||
import tech
|
||||
from pprint import pformat
|
||||
from delay_data import delay_data
|
||||
from wire_spice_model import wire_spice_model
|
||||
from power_data import power_data
|
||||
@@ -26,8 +27,9 @@ class spice():
|
||||
Class consisting of a set of modules and instances of these modules
|
||||
"""
|
||||
|
||||
def __init__(self, name):
|
||||
def __init__(self, name, cell_name):
|
||||
self.name = name
|
||||
self.cell_name = cell_name
|
||||
|
||||
self.valid_signal_types = ["INOUT", "INPUT", "OUTPUT", "POWER", "GROUND"]
|
||||
# Holds subckts/mods for this module
|
||||
@@ -164,7 +166,6 @@ class spice():
|
||||
num_pins = len(self.insts[-1].mod.pins)
|
||||
num_args = len(args)
|
||||
if (check and num_pins != num_args):
|
||||
from pprint import pformat
|
||||
if num_pins < num_args:
|
||||
mod_pins = self.insts[-1].mod.pins + [""] * (num_args - num_pins)
|
||||
arg_pins = args
|
||||
@@ -181,7 +182,6 @@ class spice():
|
||||
self.conns.append(args)
|
||||
|
||||
if check and (len(self.insts)!=len(self.conns)):
|
||||
from pprint import pformat
|
||||
insts_string=pformat(self.insts)
|
||||
conns_string=pformat(self.conns)
|
||||
|
||||
@@ -214,7 +214,7 @@ class spice():
|
||||
f.close()
|
||||
|
||||
# find the correct subckt line in the file
|
||||
subckt = re.compile("^.subckt {}".format(self.name), re.IGNORECASE)
|
||||
subckt = re.compile("^.subckt {}".format(self.cell_name), re.IGNORECASE)
|
||||
subckt_line = list(filter(subckt.search, self.spice))[0]
|
||||
# parses line into ports and remove subckt
|
||||
self.pins = subckt_line.split(" ")[2:]
|
||||
@@ -234,7 +234,7 @@ class spice():
|
||||
|
||||
# pins and subckt should be the same
|
||||
# find the correct subckt line in the file
|
||||
subckt = re.compile("^.subckt {}".format(self.name), re.IGNORECASE)
|
||||
subckt = re.compile("^.subckt {}".format(self.cell_name), re.IGNORECASE)
|
||||
subckt_line = list(filter(subckt.search, self.lvs))[0]
|
||||
# parses line into ports and remove subckt
|
||||
lvs_pins = subckt_line.split(" ")[2:]
|
||||
@@ -293,7 +293,7 @@ class spice():
|
||||
return
|
||||
|
||||
# write out the first spice line (the subcircuit)
|
||||
sp.write("\n.SUBCKT {0} {1}\n".format(self.name,
|
||||
sp.write("\n.SUBCKT {0} {1}\n".format(self.cell_name,
|
||||
" ".join(self.pins)))
|
||||
|
||||
for pin in self.pins:
|
||||
@@ -304,7 +304,7 @@ class spice():
|
||||
|
||||
# every instance must have a set of connections, even if it is empty.
|
||||
if len(self.insts) != len(self.conns):
|
||||
debug.error("{0} : Not all instance pins ({1}) are connected ({2}).".format(self.name,
|
||||
debug.error("{0} : Not all instance pins ({1}) are connected ({2}).".format(self.cell_name,
|
||||
len(self.insts),
|
||||
len(self.conns)))
|
||||
debug.error("Instances: \n" + str(self.insts))
|
||||
@@ -330,9 +330,9 @@ class spice():
|
||||
else:
|
||||
sp.write("X{0} {1} {2}\n".format(self.insts[i].name,
|
||||
" ".join(self.conns[i]),
|
||||
self.insts[i].mod.name))
|
||||
self.insts[i].mod.cell_name))
|
||||
|
||||
sp.write(".ENDS {0}\n".format(self.name))
|
||||
sp.write(".ENDS {0}\n".format(self.cell_name))
|
||||
|
||||
else:
|
||||
# If spice is a hard module, output the spice file contents.
|
||||
@@ -390,7 +390,7 @@ class spice():
|
||||
.format(self.__class__.__name__))
|
||||
debug.warning("Class {0} name {1}"
|
||||
.format(self.__class__.__name__,
|
||||
self.name))
|
||||
self.cell_name))
|
||||
return None
|
||||
|
||||
def get_cin(self):
|
||||
@@ -408,7 +408,7 @@ class spice():
|
||||
.format(self.__class__.__name__))
|
||||
debug.warning("Class {0} name {1}"
|
||||
.format(self.__class__.__name__,
|
||||
self.name))
|
||||
self.cell_name))
|
||||
return 0
|
||||
|
||||
def cal_delay_with_rc(self, corner, r, c, slew, swing=0.5):
|
||||
|
||||
@@ -95,6 +95,7 @@ def _get_gds_reader(units, gds_filename):
|
||||
|
||||
_GDS_SIZE_CACHE = {}
|
||||
|
||||
|
||||
def get_gds_size(name, gds_filename, units, lpp):
|
||||
"""
|
||||
Open a GDS file and return the size from either the
|
||||
@@ -129,6 +130,7 @@ def get_libcell_size(name, units, lpp):
|
||||
|
||||
_GDS_PINS_CACHE = {}
|
||||
|
||||
|
||||
def get_gds_pins(pin_names, name, gds_filename, units):
|
||||
"""
|
||||
Open a GDS file and find the pins in pin_names as text on a given layer.
|
||||
|
||||
Reference in New Issue
Block a user