mirror of https://github.com/VLSIDA/OpenRAM.git
get connections from spice objects in instances
This commit is contained in:
parent
8a441bc68b
commit
478c76c1ca
|
|
@ -176,6 +176,8 @@ class instance(geometry):
|
||||||
self.rotate = rotate
|
self.rotate = rotate
|
||||||
self.offset = vector(offset).snap_to_grid()
|
self.offset = vector(offset).snap_to_grid()
|
||||||
self.mirror = mirror
|
self.mirror = mirror
|
||||||
|
# track if the instance's spice pin connections have been made
|
||||||
|
self.connected = False
|
||||||
|
|
||||||
# deepcopy because this instance needs to
|
# deepcopy because this instance needs to
|
||||||
# change attributes in these spice objects
|
# change attributes in these spice objects
|
||||||
|
|
@ -290,12 +292,21 @@ class instance(geometry):
|
||||||
to both of their respective objects
|
to both of their respective objects
|
||||||
nets_list must be the same length as self.spice_pins
|
nets_list must be the same length as self.spice_pins
|
||||||
"""
|
"""
|
||||||
|
debug.check(not self.connected,
|
||||||
|
"instance {} has already been connected".format(self.name))
|
||||||
debug.check(len(self.spice_pins) == len(nets_list),
|
debug.check(len(self.spice_pins) == len(nets_list),
|
||||||
"must provide list of nets the same length as pin list\
|
"must provide list of nets the same length as pin list\
|
||||||
when connecting an instance")
|
when connecting an instance")
|
||||||
for i in range(len(self.spice_pins)):
|
for i in range(len(self.spice_pins)):
|
||||||
self.spice_pins[i].set_inst_net(nets_list[i])
|
self.spice_pins[i].set_inst_net(nets_list[i])
|
||||||
nets_list[i].connect_pin(self.spice_pins[i])
|
nets_list[i].connect_pin(self.spice_pins[i])
|
||||||
|
self.connected = True
|
||||||
|
|
||||||
|
def get_connections(self):
|
||||||
|
conns = []
|
||||||
|
for pin in self.spice_pins:
|
||||||
|
conns.append(pin.inst_net.name)
|
||||||
|
return conns
|
||||||
|
|
||||||
def calculate_transform(self, node):
|
def calculate_transform(self, node):
|
||||||
#set up the rotation matrix
|
#set up the rotation matrix
|
||||||
|
|
|
||||||
|
|
@ -139,7 +139,7 @@ class hierarchy_design(spice, layout):
|
||||||
1)
|
1)
|
||||||
port_dict = {pin: port for pin, port in zip(list(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))
|
debug.info(3, "Instance name={}".format(inst_name))
|
||||||
for subinst, conns in zip(self.insts, self.conns):
|
for subinst, conns in zip(self.insts, self.get_instance_connections()):
|
||||||
if subinst in self.graph_inst_exclude:
|
if subinst in self.graph_inst_exclude:
|
||||||
continue
|
continue
|
||||||
subinst_name = inst_name + "{}x".format(OPTS.hier_seperator) + subinst.name
|
subinst_name = inst_name + "{}x".format(OPTS.hier_seperator) + subinst.name
|
||||||
|
|
@ -157,7 +157,7 @@ class hierarchy_design(spice, layout):
|
||||||
1)
|
1)
|
||||||
port_dict = {pin: port for pin, port in zip(list(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))
|
debug.info(3, "Instance name={}".format(inst_name))
|
||||||
for subinst, conns in zip(self.insts, self.conns):
|
for subinst, conns in zip(self.insts, self.get_instance_connections()):
|
||||||
subinst_name = inst_name + "{}x".format(OPTS.hier_seperator) + subinst.name
|
subinst_name = inst_name + "{}x".format(OPTS.hier_seperator) + subinst.name
|
||||||
subinst_ports = self.translate_nets(conns, port_dict, inst_name)
|
subinst_ports = self.translate_nets(conns, port_dict, inst_name)
|
||||||
for si_port, conn in zip(subinst_ports, conns):
|
for si_port, conn in zip(subinst_ports, conns):
|
||||||
|
|
|
||||||
|
|
@ -209,8 +209,6 @@ class spice():
|
||||||
ordered_nets = self.create_nets(ordered_args)
|
ordered_nets = self.create_nets(ordered_args)
|
||||||
self.insts[-1].connect_spice_pins(ordered_nets)
|
self.insts[-1].connect_spice_pins(ordered_nets)
|
||||||
|
|
||||||
# TODO: replace functionality that checked if user forgot to connect an inst before connecting the next
|
|
||||||
|
|
||||||
def create_nets(self, names_list):
|
def create_nets(self, names_list):
|
||||||
nets = []
|
nets = []
|
||||||
for name in names_list:
|
for name in names_list:
|
||||||
|
|
@ -294,8 +292,6 @@ class spice():
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def sp_write_file(self, sp, usedMODS, lvs=False, trim=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;
|
Recursive spice subcircuit write;
|
||||||
Writes the spice subcircuit from the library or the dynamically generated one.
|
Writes the spice subcircuit from the library or the dynamically generated one.
|
||||||
|
|
@ -308,11 +304,11 @@ class spice():
|
||||||
# If spice isn't defined, we dynamically generate one.
|
# If spice isn't defined, we dynamically generate one.
|
||||||
|
|
||||||
# recursively write the modules
|
# recursively write the modules
|
||||||
for i in self.mods:
|
for mod in self.mods:
|
||||||
if self.contains(i, usedMODS):
|
if self.contains(mod, usedMODS):
|
||||||
continue
|
continue
|
||||||
usedMODS.append(i)
|
usedMODS.append(mod)
|
||||||
i.sp_write_file(sp, usedMODS, lvs, trim)
|
mod.sp_write_file(sp, usedMODS, lvs, trim)
|
||||||
|
|
||||||
if len(self.insts) == 0:
|
if len(self.insts) == 0:
|
||||||
return
|
return
|
||||||
|
|
@ -331,43 +327,44 @@ class spice():
|
||||||
for line in self.comments:
|
for line in self.comments:
|
||||||
sp.write("* {}\n".format(line))
|
sp.write("* {}\n".format(line))
|
||||||
|
|
||||||
# every instance must have a set of connections, even if it is empty.
|
# every instance must be connected with the connect_inst function
|
||||||
if len(self.insts) != len(self.conns):
|
# TODO: may run into empty pin lists edge case, not sure yet
|
||||||
debug.error("{0} : Not all instance pins ({1}) are connected ({2}).".format(self.cell_name,
|
connected = True
|
||||||
len(self.insts),
|
for inst in self.insts:
|
||||||
len(self.conns)))
|
if inst.connected:
|
||||||
debug.error("Instances: \n" + str(self.insts))
|
continue
|
||||||
debug.error("-----")
|
debug.error("Instance {} spice pins not connected".format(str(inst)))
|
||||||
debug.error("Connections: \n" + str(self.conns), 1)
|
connected = False
|
||||||
|
debug.check(connected, "{0} : Not all instance spice pins are connected.".format(self.cell_name))
|
||||||
|
|
||||||
for i in range(len(self.insts)):
|
for inst in self.insts:
|
||||||
# we don't need to output connections of empty instances.
|
# we don't need to output connections of empty instances.
|
||||||
# these are wires and paths
|
# these are wires and paths
|
||||||
if self.conns[i] == []:
|
if len(inst.spice_pins) == 0:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# Instance with no devices in it needs no subckt/instance
|
# Instance with no devices in it needs no subckt/instance
|
||||||
if self.insts[i].mod.no_instances:
|
if inst.mod.no_instances:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# If this is a trimmed netlist, skip it by adding comment char
|
# If this is a trimmed netlist, skip it by adding comment char
|
||||||
if trim and self.insts[i].name in self.trim_insts:
|
if trim and inst.name in self.trim_insts:
|
||||||
sp.write("* ")
|
sp.write("* ")
|
||||||
|
|
||||||
if lvs and hasattr(self.insts[i].mod, "lvs_device"):
|
if lvs and hasattr(inst.mod, "lvs_device"):
|
||||||
sp.write(self.insts[i].mod.lvs_device.format(self.insts[i].name,
|
sp.write(inst.mod.lvs_device.format(inst.name,
|
||||||
" ".join(self.conns[i])))
|
" ".join(inst.get_connections())))
|
||||||
sp.write("\n")
|
sp.write("\n")
|
||||||
elif hasattr(self.insts[i].mod, "spice_device"):
|
elif hasattr(inst.mod, "spice_device"):
|
||||||
sp.write(self.insts[i].mod.spice_device.format(self.insts[i].name,
|
sp.write(inst.mod.spice_device.format(inst.name,
|
||||||
" ".join(self.conns[i])))
|
" ".join(inst.get_connections())))
|
||||||
sp.write("\n")
|
sp.write("\n")
|
||||||
else:
|
else:
|
||||||
wrapped_connections = "\n+ ".join(tr.wrap(" ".join(self.conns[i])))
|
wrapped_connections = "\n+ ".join(tr.wrap(" ".join(inst.get_connections())))
|
||||||
|
|
||||||
sp.write("X{0}\n+ {1}\n+ {2}\n".format(self.insts[i].name,
|
sp.write("X{0}\n+ {1}\n+ {2}\n".format(inst.name,
|
||||||
wrapped_connections,
|
wrapped_connections,
|
||||||
self.insts[i].mod.cell_name))
|
inst.mod.cell_name))
|
||||||
|
|
||||||
sp.write(".ENDS {0}\n".format(self.cell_name))
|
sp.write(".ENDS {0}\n".format(self.cell_name))
|
||||||
|
|
||||||
|
|
@ -696,6 +693,12 @@ class spice():
|
||||||
aliases.append(net)
|
aliases.append(net)
|
||||||
return aliases
|
return aliases
|
||||||
|
|
||||||
|
def get_instance_connections(self):
|
||||||
|
conns = []
|
||||||
|
for inst in self.instances:
|
||||||
|
conns.append(inst.get_connections())
|
||||||
|
return conns
|
||||||
|
|
||||||
def is_net_alias(self, known_net, net_alias, mod, exclusion_set):
|
def is_net_alias(self, known_net, net_alias, mod, exclusion_set):
|
||||||
"""
|
"""
|
||||||
Checks if the alias_net in input mod is the same as the input net for this mod (self).
|
Checks if the alias_net in input mod is the same as the input net for this mod (self).
|
||||||
|
|
@ -708,7 +711,7 @@ class spice():
|
||||||
return True
|
return True
|
||||||
# Check connections of all other subinsts
|
# Check connections of all other subinsts
|
||||||
mod_set = set()
|
mod_set = set()
|
||||||
for subinst, inst_conns in zip(self.insts, self.conns):
|
for subinst, inst_conns in zip(self.insts, self.get_instance_connections()):
|
||||||
for inst_conn, mod_pin in zip(inst_conns, subinst.mod.pins):
|
for inst_conn, mod_pin in zip(inst_conns, subinst.mod.pins):
|
||||||
if self.is_net_alias_name_check(known_net, inst_conn, net_alias, mod):
|
if self.is_net_alias_name_check(known_net, inst_conn, net_alias, mod):
|
||||||
return True
|
return True
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue