mirror of https://github.com/VLSIDA/OpenRAM.git
fix pin/net dictionary deepcopy-ing
This commit is contained in:
parent
09aa395174
commit
bfabe64f33
|
|
@ -292,19 +292,25 @@ class instance(geometry):
|
|||
to both of their respective objects
|
||||
nets_list must be the same length as self.spice_pins
|
||||
"""
|
||||
if len(nets_list) == 0 and len(self.spice_pins) == 0:
|
||||
# this is the only valid case to skip the following debug check
|
||||
# because this with no pins are often connected arbitrarily
|
||||
self.connected = True
|
||||
return
|
||||
debug.check(not self.connected,
|
||||
"instance {} has already been connected".format(self.name))
|
||||
debug.check(len(self.spice_pins) == len(nets_list),
|
||||
"must provide list of nets the same length as pin list\
|
||||
when connecting an instance")
|
||||
for i in range(len(self.spice_pins)):
|
||||
self.spice_pins[i].set_inst_net(nets_list[i])
|
||||
nets_list[i].connect_pin(self.spice_pins[i])
|
||||
for pin in self.spice_pins.values():
|
||||
net = nets_list.pop(0)
|
||||
pin.set_inst_net(net)
|
||||
net.connect_pin(pin)
|
||||
self.connected = True
|
||||
|
||||
def get_connections(self):
|
||||
conns = []
|
||||
for pin in self.spice_pins:
|
||||
for pin in self.spice_pins.values():
|
||||
conns.append(pin.inst_net.name)
|
||||
return conns
|
||||
|
||||
|
|
|
|||
|
|
@ -629,7 +629,7 @@ class layout():
|
|||
"""
|
||||
Return a pin list of all pins
|
||||
"""
|
||||
return self.pins
|
||||
return list(self.pins)
|
||||
|
||||
def copy_layout_pin(self, instance, pin_name, new_name="", relative_offset=vector(0, 0)):
|
||||
"""
|
||||
|
|
@ -1523,6 +1523,7 @@ class layout():
|
|||
""" Return the pin shapes as blockages for non-top-level blocks. """
|
||||
# FIXME: We don't have a body contact in ptx, so just ignore it for now
|
||||
import copy
|
||||
# FIXME: this may not work now that self.pins is a dict as defined in hierarchy_spice
|
||||
pin_names = copy.deepcopy(self.pins)
|
||||
if self.name.startswith("pmos") or self.name.startswith("nmos"):
|
||||
pin_names.remove("B")
|
||||
|
|
|
|||
|
|
@ -90,13 +90,13 @@ class spice():
|
|||
def add_pin(self, name, pin_type="INOUT"):
|
||||
""" Adds a pin to the pins list. Default type is INOUT signal. """
|
||||
debug.check(name not in self.pins, "cannot add duplicate spice pin {}".format(name))
|
||||
self.pins[name] = pin_spice(name, pin_type)
|
||||
self.pins[name] = pin_spice(name, pin_type, self)
|
||||
|
||||
def add_pin_list(self, pin_list, pin_type="INOUT"):
|
||||
""" Adds a pin_list to the pins list """
|
||||
# The pin type list can be a single type for all pins
|
||||
# or a list that is the same length as the pin list.
|
||||
if type(pin_type) == str:
|
||||
if isinstance(pin_type, str):
|
||||
for pin in pin_list:
|
||||
self.add_pin(pin, pin_type)
|
||||
|
||||
|
|
@ -124,7 +124,7 @@ class spice():
|
|||
"{} 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)
|
||||
pin.set_type(type)
|
||||
|
||||
def get_pin_type(self, name):
|
||||
""" Returns the type of the signal pin. """
|
||||
|
|
@ -212,7 +212,7 @@ class spice():
|
|||
for name in names_list:
|
||||
# setdefault adds to the dict if it doesn't find the net in it already
|
||||
# then it returns the net it found or created, a net_spice object
|
||||
net = self.nets.setdefault(name, net_spice(name))
|
||||
net = self.nets.setdefault(name, net_spice(name, self))
|
||||
nets.append(net)
|
||||
return nets
|
||||
|
||||
|
|
@ -764,9 +764,10 @@ class pin_spice():
|
|||
self.inst = inst
|
||||
|
||||
def set_inst_net(self, net):
|
||||
debug.check(self.inst_net is None,
|
||||
"pin {} is already connected to net {} so it cannot also be connected to net {}\
|
||||
".format(self.name, self.inst_net.name, net.name))
|
||||
if self.inst_net is not None:
|
||||
debug.error("pin {} is already connected to net {}\
|
||||
so it cannot also be connected to net {}\
|
||||
".format(self.name, self.inst_net.name, net.name), 1)
|
||||
debug.check(isinstance(net, net_spice), "net must be a net_spice object")
|
||||
self.inst_net = net
|
||||
|
||||
|
|
@ -789,6 +790,23 @@ class pin_spice():
|
|||
"""
|
||||
return self._hash
|
||||
|
||||
def __deepcopy__(original, memo):
|
||||
"""
|
||||
This function is defined so that instances of modules can make deep
|
||||
copies of their parent module's pins dictionary. It is only expected
|
||||
to be called by the instance class __init__ function. Mod and mod_net
|
||||
should not be deep copies but references to the existing mod and net
|
||||
objects they refer to in the original. If inst is already defined this
|
||||
function will throw an error because that means it was called on a pin
|
||||
from an instance, which is not defined behavior.
|
||||
"""
|
||||
debug.check(original.inst is None,
|
||||
"cannot make a deepcopy of a spice pin from an inst")
|
||||
pin = pin_spice(original.name, original.type, original.mod)
|
||||
if original.mod_net is not None:
|
||||
pin.set_mod_net(original.mod_net)
|
||||
return pin
|
||||
|
||||
|
||||
class net_spice():
|
||||
"""
|
||||
|
|
@ -797,9 +815,10 @@ class net_spice():
|
|||
inst is the instance this net is a part of, if any.
|
||||
"""
|
||||
|
||||
def __init__(self, name):
|
||||
def __init__(self, name, mod):
|
||||
self.name = name
|
||||
self.pins = []
|
||||
self.mod = mod
|
||||
self.inst = None
|
||||
|
||||
# TODO: evaluate if this makes sense... and works
|
||||
|
|
@ -812,9 +831,12 @@ class net_spice():
|
|||
else:
|
||||
self.pins.append(pin)
|
||||
|
||||
def set_inst(self, inst):
|
||||
self.inst = inst
|
||||
|
||||
def __str__(self):
|
||||
""" override print function output """
|
||||
return "(pin_name={} type={})".format(self.name, self.type)
|
||||
return "(net_name={} type={})".format(self.name, self.type)
|
||||
|
||||
def __repr__(self):
|
||||
""" override repr function output """
|
||||
|
|
@ -830,3 +852,21 @@ class net_spice():
|
|||
Provides a speedup if pin_spice is used as a key for dicts.
|
||||
"""
|
||||
return self._hash
|
||||
|
||||
def __deepcopy__(original, memo):
|
||||
"""
|
||||
This function is defined so that instances of modules can make deep
|
||||
copies of their parent module's nets dictionary. It is only expected
|
||||
to be called by the instance class __init__ function. Mod and mod_net
|
||||
should not be deep copies but references to the existing mod and net
|
||||
objects they refer to in the original. If inst is already defined this
|
||||
function will throw an error because that means it was called on a pin
|
||||
from an instance, which is not defined behavior.
|
||||
"""
|
||||
debug.check(original.inst is None,
|
||||
"cannot make a deepcopy of a spice net from an inst")
|
||||
net = net_spice(original.name, original.mod)
|
||||
if original.pins != []:
|
||||
# TODO: honestly I'm not sure if this is right but we'll see...
|
||||
net.pins = original.pins
|
||||
return net
|
||||
|
|
|
|||
Loading…
Reference in New Issue