mirror of https://github.com/VLSIDA/OpenRAM.git
change pins to OrderedDict
This commit is contained in:
parent
c8c43f75d9
commit
7581df2255
|
|
@ -41,8 +41,8 @@ class design(hierarchy_design):
|
|||
if prop and prop.hard_cell:
|
||||
# The pins get added from the spice file, so just check
|
||||
# that they matched here
|
||||
debug.check(prop.port_names == self.pins,
|
||||
"Custom cell pin names do not match spice file:\n{0} vs {1}".format(prop.port_names, self.pins))
|
||||
debug.check(prop.port_names == list(self.pins),
|
||||
"Custom cell pin names do not match spice file:\n{0} vs {1}".format(prop.port_names, list(self.pins)))
|
||||
self.add_pin_indices(prop.port_indices)
|
||||
self.add_pin_names(prop.port_map)
|
||||
self.update_pin_types(prop.port_types)
|
||||
|
|
@ -51,7 +51,7 @@ class design(hierarchy_design):
|
|||
(width, height) = utils.get_libcell_size(self.cell_name,
|
||||
GDS["unit"],
|
||||
layer[prop.boundary_layer])
|
||||
self.pin_map = utils.get_libcell_pins(self.pins,
|
||||
self.pin_map = utils.get_libcell_pins(list(self.pins),
|
||||
self.cell_name,
|
||||
GDS["unit"])
|
||||
|
||||
|
|
|
|||
|
|
@ -135,9 +135,9 @@ class hierarchy_design(spice, layout):
|
|||
# Translate port names to external nets
|
||||
if len(port_nets) != len(self.pins):
|
||||
debug.error("Port length mismatch:\nExt nets={}, Ports={}".format(port_nets,
|
||||
self.pins),
|
||||
list(self.pins)),
|
||||
1)
|
||||
port_dict = {pin: port for pin, port in zip(self.pins, port_nets)}
|
||||
port_dict = {pin: port for pin, port in zip(list(self.pins), port_nets)}
|
||||
debug.info(3, "Instance name={}".format(inst_name))
|
||||
for subinst, conns in zip(self.insts, self.conns):
|
||||
if subinst in self.graph_inst_exclude:
|
||||
|
|
@ -153,9 +153,9 @@ class hierarchy_design(spice, layout):
|
|||
# Translate port names to external nets
|
||||
if len(port_nets) != len(self.pins):
|
||||
debug.error("Port length mismatch:\nExt nets={}, Ports={}".format(port_nets,
|
||||
self.pins),
|
||||
list(self.pins)),
|
||||
1)
|
||||
port_dict = {pin: port for pin, port in zip(self.pins, port_nets)}
|
||||
port_dict = {pin: port for pin, port in zip(list(self.pins), port_nets)}
|
||||
debug.info(3, "Instance name={}".format(inst_name))
|
||||
for subinst, conns in zip(self.insts, self.conns):
|
||||
subinst_name = inst_name + "{}x".format(OPTS.hier_seperator) + subinst.name
|
||||
|
|
@ -186,7 +186,7 @@ class hierarchy_design(spice, layout):
|
|||
"""
|
||||
# The final pin names will depend on the spice hierarchy, so
|
||||
# they are passed as an input.
|
||||
pin_dict = {pin: port for pin, port in zip(self.pins, port_nets)}
|
||||
pin_dict = {pin: port for pin, port in zip(list(self.pins), port_nets)}
|
||||
input_pins = self.get_inputs()
|
||||
output_pins = self.get_outputs()
|
||||
inout_pins = self.get_inouts()
|
||||
|
|
@ -197,7 +197,7 @@ class hierarchy_design(spice, layout):
|
|||
|
||||
def __str__(self):
|
||||
""" override print function output """
|
||||
pins = ",".join(self.pins)
|
||||
pins = ",".join(list(self.pins))
|
||||
insts = [" {}".format(x) for x in self.insts]
|
||||
objs = [" {}".format(x) for x in self.objs]
|
||||
s = "********** design {0} **********".format(self.cell_name)
|
||||
|
|
@ -208,7 +208,7 @@ class hierarchy_design(spice, layout):
|
|||
|
||||
def __repr__(self):
|
||||
""" override print function output """
|
||||
text="( design: " + self.name + " pins=" + str(self.pins) + " " + str(self.width) + "x" + str(self.height) + " )\n"
|
||||
text="( design: " + self.name + " pins=" + str(list(self.pins)) + " " + str(self.width) + "x" + str(self.height) + " )\n"
|
||||
for i in self.objs:
|
||||
text+=str(i) + ",\n"
|
||||
for i in self.insts:
|
||||
|
|
|
|||
|
|
@ -13,13 +13,13 @@ from pprint import pformat
|
|||
from openram import debug
|
||||
from openram import tech
|
||||
from openram import OPTS
|
||||
|
||||
from compiler.base.net_spice import net_spice
|
||||
from collections import OrderedDict
|
||||
from .delay_data import delay_data
|
||||
from .wire_spice_model import wire_spice_model
|
||||
from .power_data import power_data
|
||||
from .logical_effort import convert_relative_c_to_farad, convert_farad_to_relative_c
|
||||
from .pin_spice import pin_spice
|
||||
from .net_spice import net_spice
|
||||
|
||||
|
||||
class spice():
|
||||
|
|
@ -55,14 +55,15 @@ class spice():
|
|||
# Holds subckts/mods for this module
|
||||
self.mods = set()
|
||||
# Holds the pins for this module (in order)
|
||||
self.pins = []
|
||||
# on Python3.7+ regular dictionaries guarantee order too, but we allow use of v3.5+
|
||||
self.pins = OrderedDict()
|
||||
# An (optional) list of indices to reorder the pins to match the spice.
|
||||
self.pin_indices = []
|
||||
# THE CONNECTIONS MUST MATCH THE ORDER OF THE PINS (restriction imposed by the
|
||||
# Spice format)
|
||||
# internal nets, which may or may not be connected to pins of the same name
|
||||
self.nets = []
|
||||
# If this is set, it will out output subckt or isntances of this (for row/col caps etc.)
|
||||
self.nets = {}
|
||||
# If this is set, it will not output subckt or instances of this (for row/col caps etc.)
|
||||
self.no_instances = False
|
||||
# If we are doing a trimmed netlist, these are the instance that will be filtered
|
||||
self.trim_insts = set()
|
||||
|
|
@ -90,9 +91,8 @@ class spice():
|
|||
|
||||
def add_pin(self, name, pin_type="INOUT"):
|
||||
""" Adds a pin to the pins list. Default type is INOUT signal. """
|
||||
new_pin = pin_spice(name, pin_type)
|
||||
debug.check(new_pin not in self.pins, "cannot add duplicate spice pin")
|
||||
self.pins.append(new_pin)
|
||||
debug.check(name not in self.pins, "cannot add duplicate spice pin {}".format(name))
|
||||
self.pins[name] = pin_spice(name, pin_type)
|
||||
|
||||
def add_pin_list(self, pin_list, pin_type="INOUT"):
|
||||
""" Adds a pin_list to the pins list """
|
||||
|
|
@ -122,20 +122,17 @@ class spice():
|
|||
|
||||
def update_pin_types(self, type_list):
|
||||
""" Change pin types for all the cell's pins. """
|
||||
if len(type_list) != len(self.pins):
|
||||
debug.error("{} spice subcircuit number of port types does not match number of pins\
|
||||
\n SPICE names={}\
|
||||
\n Module names={}\
|
||||
".format(self.name, self.pins, type_list), 1)
|
||||
for pin, type in zip(self.pins, type_list):
|
||||
debug.check(len(type_list) == len(self.pins),
|
||||
"{} spice subcircuit number of port types does not match number of pins\
|
||||
\n pin names={}\n port types={}".format(self.name, list(self.pins), type_list))
|
||||
for pin, type in zip(self.pins.values(), type_list):
|
||||
pin.set_pin_type(type)
|
||||
|
||||
def get_pin_type(self, name):
|
||||
""" Returns the type of the signal pin. """
|
||||
for pin in self.pins:
|
||||
if pin.name == name:
|
||||
return pin.type
|
||||
debug.error("Spice pin {} not found".format(name))
|
||||
pin = self.pins.get(name)
|
||||
debug.check(pin is not None, "Spice pin {} not found".format(name))
|
||||
return pin.type
|
||||
|
||||
def get_pin_dir(self, name):
|
||||
""" Returns the direction of the pin. (Supply/ground are INOUT). """
|
||||
|
|
@ -148,10 +145,10 @@ class spice():
|
|||
def get_inputs(self):
|
||||
"""
|
||||
These use pin types to determine pin lists.
|
||||
Returns names only to maintain historical interface.
|
||||
Returns names only, to maintain historical interface.
|
||||
"""
|
||||
input_list = []
|
||||
for pin in self.pins:
|
||||
for pin in self.pins.values():
|
||||
if pin.type == "INPUT":
|
||||
input_list.append(pin.name)
|
||||
return input_list
|
||||
|
|
@ -159,26 +156,28 @@ class spice():
|
|||
def get_outputs(self):
|
||||
"""
|
||||
These use pin types to determine pin lists.
|
||||
Returns names only to maintain historical interface.
|
||||
Returns names only, to maintain historical interface.
|
||||
"""
|
||||
output_list = []
|
||||
for pin in self.pins:
|
||||
for pin in self.pins.values():
|
||||
if pin.type == "OUTPUT":
|
||||
output_list.append(pin.name)
|
||||
return output_list
|
||||
|
||||
def get_inouts(self):
|
||||
""" These use pin types to determine pin lists. These
|
||||
may be over-ridden by submodules that didn't use pin directions yet."""
|
||||
"""
|
||||
These use pin types to determine pin lists.
|
||||
Returns names only, to maintain historical interface.
|
||||
"""
|
||||
inout_list = []
|
||||
for pin in self.pins:
|
||||
for pin in self.pins.values():
|
||||
if pin.type == "INOUT":
|
||||
inout_list.append(pin.name)
|
||||
return inout_list
|
||||
|
||||
def copy_pins(self, other_module, suffix=""):
|
||||
""" This will copy all of the pins from the other module and add an optional suffix."""
|
||||
for pin in other_module.pins:
|
||||
for pin in other_module.pins.values():
|
||||
self.add_pin(pin.name + suffix, pin.type)
|
||||
|
||||
def connect_inst(self, args):
|
||||
|
|
@ -186,7 +185,7 @@ class spice():
|
|||
Connects the pins of the last instance added
|
||||
"""
|
||||
|
||||
spice_pins = self.insts[-1].spice_pins
|
||||
spice_pins = list(self.insts[-1].spice_pins)
|
||||
num_pins = len(spice_pins)
|
||||
num_args = len(args)
|
||||
|
||||
|
|
@ -241,8 +240,7 @@ class spice():
|
|||
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
|
||||
# FIXME: needs to use new pins interface
|
||||
self.pins = subckt_line.split(" ")[2:]
|
||||
self.add_pin_list(subckt_line.split(" ")[2:])
|
||||
else:
|
||||
debug.info(4, "no spfile {0}".format(self.sp_file))
|
||||
self.spice = []
|
||||
|
|
@ -263,10 +261,10 @@ class spice():
|
|||
subckt_line = list(filter(subckt.search, self.lvs))[0]
|
||||
# parses line into ports and remove subckt
|
||||
lvs_pins = subckt_line.split(" ")[2:]
|
||||
debug.check(lvs_pins == self.pins,
|
||||
debug.check(lvs_pins == list(self.pins),
|
||||
"Spice netlists for LVS and simulation have port mismatches:\n{0} (LVS {1})\nvs\n{2} (sim {3})".format(lvs_pins,
|
||||
self.lvs_file,
|
||||
self.pins,
|
||||
list(self.pins),
|
||||
self.sp_file))
|
||||
|
||||
def check_net_in_spice(self, net_name):
|
||||
|
|
@ -299,6 +297,8 @@ class spice():
|
|||
return False
|
||||
|
||||
def sp_write_file(self, sp, usedMODS, lvs=False, trim=False):
|
||||
# FIXME: this function refers to conns for connections but that no longer exists.
|
||||
# it should be possible to just query the instances themselves for their connections.
|
||||
"""
|
||||
Recursive spice subcircuit write;
|
||||
Writes the spice subcircuit from the library or the dynamically generated one.
|
||||
|
|
@ -319,29 +319,17 @@ class spice():
|
|||
|
||||
if len(self.insts) == 0:
|
||||
return
|
||||
if self.pins == []:
|
||||
if len(self.pins) == 0:
|
||||
return
|
||||
|
||||
# write out the first spice line (the subcircuit)
|
||||
wrapped_pins = "\n+ ".join(tr.wrap(" ".join(self.pins)))
|
||||
wrapped_pins = "\n+ ".join(tr.wrap(" ".join(list(self.pins))))
|
||||
sp.write("\n.SUBCKT {0}\n+ {1}\n".format(self.cell_name,
|
||||
wrapped_pins))
|
||||
|
||||
# write a PININFO line
|
||||
if False:
|
||||
pin_info = "*.PININFO"
|
||||
for pin in self.pins:
|
||||
if self.pin_type[pin] == "INPUT":
|
||||
pin_info += " {0}:I".format(pin)
|
||||
elif self.pin_type[pin] == "OUTPUT":
|
||||
pin_info += " {0}:O".format(pin)
|
||||
else:
|
||||
pin_info += " {0}:B".format(pin)
|
||||
sp.write(pin_info + "\n")
|
||||
|
||||
# Also write pins as comments
|
||||
for pin in self.pins:
|
||||
sp.write("* {1:6}: {0} \n".format(pin, pin.type))
|
||||
for pin in self.pins.values():
|
||||
sp.write("* {1:6}: {0} \n".format(pin.name, pin.type))
|
||||
|
||||
for line in self.comments:
|
||||
sp.write("* {}\n".format(line))
|
||||
|
|
|
|||
Loading…
Reference in New Issue