Skip to content

Commit 7581df2

Browse files
committed
change pins to OrderedDict
1 parent c8c43f7 commit 7581df2

File tree

3 files changed

+45
-57
lines changed

3 files changed

+45
-57
lines changed

compiler/base/design.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,8 @@ def __init__(self, name, cell_name=None, prop=None):
4141
if prop and prop.hard_cell:
4242
# The pins get added from the spice file, so just check
4343
# that they matched here
44-
debug.check(prop.port_names == self.pins,
45-
"Custom cell pin names do not match spice file:\n{0} vs {1}".format(prop.port_names, self.pins))
44+
debug.check(prop.port_names == list(self.pins),
45+
"Custom cell pin names do not match spice file:\n{0} vs {1}".format(prop.port_names, list(self.pins)))
4646
self.add_pin_indices(prop.port_indices)
4747
self.add_pin_names(prop.port_map)
4848
self.update_pin_types(prop.port_types)
@@ -51,7 +51,7 @@ def __init__(self, name, cell_name=None, prop=None):
5151
(width, height) = utils.get_libcell_size(self.cell_name,
5252
GDS["unit"],
5353
layer[prop.boundary_layer])
54-
self.pin_map = utils.get_libcell_pins(self.pins,
54+
self.pin_map = utils.get_libcell_pins(list(self.pins),
5555
self.cell_name,
5656
GDS["unit"])
5757

compiler/base/hierarchy_design.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -135,9 +135,9 @@ def build_graph(self, graph, inst_name, port_nets):
135135
# Translate port names to external nets
136136
if len(port_nets) != len(self.pins):
137137
debug.error("Port length mismatch:\nExt nets={}, Ports={}".format(port_nets,
138-
self.pins),
138+
list(self.pins)),
139139
1)
140-
port_dict = {pin: port for pin, port in zip(self.pins, port_nets)}
140+
port_dict = {pin: port for pin, port in zip(list(self.pins), port_nets)}
141141
debug.info(3, "Instance name={}".format(inst_name))
142142
for subinst, conns in zip(self.insts, self.conns):
143143
if subinst in self.graph_inst_exclude:
@@ -153,9 +153,9 @@ def build_names(self, name_dict, inst_name, port_nets):
153153
# Translate port names to external nets
154154
if len(port_nets) != len(self.pins):
155155
debug.error("Port length mismatch:\nExt nets={}, Ports={}".format(port_nets,
156-
self.pins),
156+
list(self.pins)),
157157
1)
158-
port_dict = {pin: port for pin, port in zip(self.pins, port_nets)}
158+
port_dict = {pin: port for pin, port in zip(list(self.pins), port_nets)}
159159
debug.info(3, "Instance name={}".format(inst_name))
160160
for subinst, conns in zip(self.insts, self.conns):
161161
subinst_name = inst_name + "{}x".format(OPTS.hier_seperator) + subinst.name
@@ -186,7 +186,7 @@ def add_graph_edges(self, graph, port_nets):
186186
"""
187187
# The final pin names will depend on the spice hierarchy, so
188188
# they are passed as an input.
189-
pin_dict = {pin: port for pin, port in zip(self.pins, port_nets)}
189+
pin_dict = {pin: port for pin, port in zip(list(self.pins), port_nets)}
190190
input_pins = self.get_inputs()
191191
output_pins = self.get_outputs()
192192
inout_pins = self.get_inouts()
@@ -197,7 +197,7 @@ def add_graph_edges(self, graph, port_nets):
197197

198198
def __str__(self):
199199
""" override print function output """
200-
pins = ",".join(self.pins)
200+
pins = ",".join(list(self.pins))
201201
insts = [" {}".format(x) for x in self.insts]
202202
objs = [" {}".format(x) for x in self.objs]
203203
s = "********** design {0} **********".format(self.cell_name)
@@ -208,7 +208,7 @@ def __str__(self):
208208

209209
def __repr__(self):
210210
""" override print function output """
211-
text="( design: " + self.name + " pins=" + str(self.pins) + " " + str(self.width) + "x" + str(self.height) + " )\n"
211+
text="( design: " + self.name + " pins=" + str(list(self.pins)) + " " + str(self.width) + "x" + str(self.height) + " )\n"
212212
for i in self.objs:
213213
text+=str(i) + ",\n"
214214
for i in self.insts:

compiler/base/hierarchy_spice.py

Lines changed: 35 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,13 @@
1313
from openram import debug
1414
from openram import tech
1515
from openram import OPTS
16-
17-
from compiler.base.net_spice import net_spice
16+
from collections import OrderedDict
1817
from .delay_data import delay_data
1918
from .wire_spice_model import wire_spice_model
2019
from .power_data import power_data
2120
from .logical_effort import convert_relative_c_to_farad, convert_farad_to_relative_c
2221
from .pin_spice import pin_spice
22+
from .net_spice import net_spice
2323

2424

2525
class spice():
@@ -55,14 +55,15 @@ def __init__(self, name, cell_name):
5555
# Holds subckts/mods for this module
5656
self.mods = set()
5757
# Holds the pins for this module (in order)
58-
self.pins = []
58+
# on Python3.7+ regular dictionaries guarantee order too, but we allow use of v3.5+
59+
self.pins = OrderedDict()
5960
# An (optional) list of indices to reorder the pins to match the spice.
6061
self.pin_indices = []
6162
# THE CONNECTIONS MUST MATCH THE ORDER OF THE PINS (restriction imposed by the
6263
# Spice format)
6364
# internal nets, which may or may not be connected to pins of the same name
64-
self.nets = []
65-
# If this is set, it will out output subckt or isntances of this (for row/col caps etc.)
65+
self.nets = {}
66+
# If this is set, it will not output subckt or instances of this (for row/col caps etc.)
6667
self.no_instances = False
6768
# If we are doing a trimmed netlist, these are the instance that will be filtered
6869
self.trim_insts = set()
@@ -90,9 +91,8 @@ def add_comment(self, comment):
9091

9192
def add_pin(self, name, pin_type="INOUT"):
9293
""" Adds a pin to the pins list. Default type is INOUT signal. """
93-
new_pin = pin_spice(name, pin_type)
94-
debug.check(new_pin not in self.pins, "cannot add duplicate spice pin")
95-
self.pins.append(new_pin)
94+
debug.check(name not in self.pins, "cannot add duplicate spice pin {}".format(name))
95+
self.pins[name] = pin_spice(name, pin_type)
9696

9797
def add_pin_list(self, pin_list, pin_type="INOUT"):
9898
""" Adds a pin_list to the pins list """
@@ -122,20 +122,17 @@ def get_ordered_inputs(self, input_list):
122122

123123
def update_pin_types(self, type_list):
124124
""" Change pin types for all the cell's pins. """
125-
if len(type_list) != len(self.pins):
126-
debug.error("{} spice subcircuit number of port types does not match number of pins\
127-
\n SPICE names={}\
128-
\n Module names={}\
129-
".format(self.name, self.pins, type_list), 1)
130-
for pin, type in zip(self.pins, type_list):
125+
debug.check(len(type_list) == len(self.pins),
126+
"{} spice subcircuit number of port types does not match number of pins\
127+
\n pin names={}\n port types={}".format(self.name, list(self.pins), type_list))
128+
for pin, type in zip(self.pins.values(), type_list):
131129
pin.set_pin_type(type)
132130

133131
def get_pin_type(self, name):
134132
""" Returns the type of the signal pin. """
135-
for pin in self.pins:
136-
if pin.name == name:
137-
return pin.type
138-
debug.error("Spice pin {} not found".format(name))
133+
pin = self.pins.get(name)
134+
debug.check(pin is not None, "Spice pin {} not found".format(name))
135+
return pin.type
139136

140137
def get_pin_dir(self, name):
141138
""" Returns the direction of the pin. (Supply/ground are INOUT). """
@@ -148,45 +145,47 @@ def get_pin_dir(self, name):
148145
def get_inputs(self):
149146
"""
150147
These use pin types to determine pin lists.
151-
Returns names only to maintain historical interface.
148+
Returns names only, to maintain historical interface.
152149
"""
153150
input_list = []
154-
for pin in self.pins:
151+
for pin in self.pins.values():
155152
if pin.type == "INPUT":
156153
input_list.append(pin.name)
157154
return input_list
158155

159156
def get_outputs(self):
160157
"""
161158
These use pin types to determine pin lists.
162-
Returns names only to maintain historical interface.
159+
Returns names only, to maintain historical interface.
163160
"""
164161
output_list = []
165-
for pin in self.pins:
162+
for pin in self.pins.values():
166163
if pin.type == "OUTPUT":
167164
output_list.append(pin.name)
168165
return output_list
169166

170167
def get_inouts(self):
171-
""" These use pin types to determine pin lists. These
172-
may be over-ridden by submodules that didn't use pin directions yet."""
168+
"""
169+
These use pin types to determine pin lists.
170+
Returns names only, to maintain historical interface.
171+
"""
173172
inout_list = []
174-
for pin in self.pins:
173+
for pin in self.pins.values():
175174
if pin.type == "INOUT":
176175
inout_list.append(pin.name)
177176
return inout_list
178177

179178
def copy_pins(self, other_module, suffix=""):
180179
""" This will copy all of the pins from the other module and add an optional suffix."""
181-
for pin in other_module.pins:
180+
for pin in other_module.pins.values():
182181
self.add_pin(pin.name + suffix, pin.type)
183182

184183
def connect_inst(self, args):
185184
"""
186185
Connects the pins of the last instance added
187186
"""
188187

189-
spice_pins = self.insts[-1].spice_pins
188+
spice_pins = list(self.insts[-1].spice_pins)
190189
num_pins = len(spice_pins)
191190
num_args = len(args)
192191

@@ -241,8 +240,7 @@ def sp_read(self):
241240
subckt = re.compile("^.subckt {}".format(self.cell_name), re.IGNORECASE)
242241
subckt_line = list(filter(subckt.search, self.spice))[0]
243242
# parses line into ports and remove subckt
244-
# FIXME: needs to use new pins interface
245-
self.pins = subckt_line.split(" ")[2:]
243+
self.add_pin_list(subckt_line.split(" ")[2:])
246244
else:
247245
debug.info(4, "no spfile {0}".format(self.sp_file))
248246
self.spice = []
@@ -263,10 +261,10 @@ def sp_read(self):
263261
subckt_line = list(filter(subckt.search, self.lvs))[0]
264262
# parses line into ports and remove subckt
265263
lvs_pins = subckt_line.split(" ")[2:]
266-
debug.check(lvs_pins == self.pins,
264+
debug.check(lvs_pins == list(self.pins),
267265
"Spice netlists for LVS and simulation have port mismatches:\n{0} (LVS {1})\nvs\n{2} (sim {3})".format(lvs_pins,
268266
self.lvs_file,
269-
self.pins,
267+
list(self.pins),
270268
self.sp_file))
271269

272270
def check_net_in_spice(self, net_name):
@@ -299,6 +297,8 @@ def contains(self, mod, modlist):
299297
return False
300298

301299
def sp_write_file(self, sp, usedMODS, lvs=False, trim=False):
300+
# FIXME: this function refers to conns for connections but that no longer exists.
301+
# it should be possible to just query the instances themselves for their connections.
302302
"""
303303
Recursive spice subcircuit write;
304304
Writes the spice subcircuit from the library or the dynamically generated one.
@@ -319,29 +319,17 @@ def sp_write_file(self, sp, usedMODS, lvs=False, trim=False):
319319

320320
if len(self.insts) == 0:
321321
return
322-
if self.pins == []:
322+
if len(self.pins) == 0:
323323
return
324324

325325
# write out the first spice line (the subcircuit)
326-
wrapped_pins = "\n+ ".join(tr.wrap(" ".join(self.pins)))
326+
wrapped_pins = "\n+ ".join(tr.wrap(" ".join(list(self.pins))))
327327
sp.write("\n.SUBCKT {0}\n+ {1}\n".format(self.cell_name,
328328
wrapped_pins))
329329

330-
# write a PININFO line
331-
if False:
332-
pin_info = "*.PININFO"
333-
for pin in self.pins:
334-
if self.pin_type[pin] == "INPUT":
335-
pin_info += " {0}:I".format(pin)
336-
elif self.pin_type[pin] == "OUTPUT":
337-
pin_info += " {0}:O".format(pin)
338-
else:
339-
pin_info += " {0}:B".format(pin)
340-
sp.write(pin_info + "\n")
341-
342330
# Also write pins as comments
343-
for pin in self.pins:
344-
sp.write("* {1:6}: {0} \n".format(pin, pin.type))
331+
for pin in self.pins.values():
332+
sp.write("* {1:6}: {0} \n".format(pin.name, pin.type))
345333

346334
for line in self.comments:
347335
sp.write("* {}\n".format(line))

0 commit comments

Comments
 (0)