najaeda 0.1.7__cp312-cp312-macosx_11_0_arm64.whl → 0.1.9__cp312-cp312-macosx_11_0_arm64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of najaeda might be problematic. Click here for more details.
- najaeda/docs/.readthedocs.yaml +3 -14
- najaeda/docs/requirements.txt +7 -0
- najaeda/docs/source/api.rst +2 -2
- najaeda/docs/source/conf.py +21 -4
- najaeda/docs/source/equipotential.rst +15 -0
- najaeda/docs/source/examples.rst.in +66 -0
- najaeda/docs/source/index.rst +7 -1
- najaeda/docs/source/instance.rst +19 -0
- najaeda/docs/source/introduction.rst +53 -0
- najaeda/docs/source/net.rst +20 -0
- najaeda/docs/source/preprocessor.py +73 -0
- najaeda/docs/source/term.rst +20 -0
- najaeda/docs/source/visitors.rst +13 -0
- najaeda/instance_visitor.py +12 -20
- najaeda/libnaja_snl_python.dylib +0 -0
- najaeda/netlist.py +489 -121
- najaeda/stats.py +320 -0
- {najaeda-0.1.7.dist-info → najaeda-0.1.9.dist-info}/METADATA +9 -4
- najaeda-0.1.9.dist-info/RECORD +27 -0
- najaeda/docs/Makefile +0 -20
- najaeda/docs/conf.py +0 -26
- najaeda/docs/make.bat +0 -35
- najaeda-0.1.7.dist-info/RECORD +0 -20
- {najaeda-0.1.7.dist-info → najaeda-0.1.9.dist-info}/WHEEL +0 -0
- {najaeda-0.1.7.dist-info → najaeda-0.1.9.dist-info}/licenses/AUTHORS +0 -0
- {najaeda-0.1.7.dist-info → najaeda-0.1.9.dist-info}/licenses/LICENSE +0 -0
najaeda/netlist.py
CHANGED
|
@@ -7,10 +7,10 @@ import itertools
|
|
|
7
7
|
import time
|
|
8
8
|
import logging
|
|
9
9
|
import hashlib
|
|
10
|
-
# import json
|
|
11
|
-
from najaeda import snl
|
|
12
10
|
import struct
|
|
13
11
|
|
|
12
|
+
from najaeda import snl
|
|
13
|
+
|
|
14
14
|
|
|
15
15
|
def consistent_hash(obj):
|
|
16
16
|
def default_serializer(o):
|
|
@@ -23,13 +23,13 @@ def consistent_hash(obj):
|
|
|
23
23
|
|
|
24
24
|
def hash_value(value):
|
|
25
25
|
if isinstance(value, int):
|
|
26
|
-
return struct.pack(
|
|
26
|
+
return struct.pack("!q", value)
|
|
27
27
|
else:
|
|
28
28
|
raise TypeError(f"Unsupported type: {type(value)}")
|
|
29
29
|
|
|
30
30
|
def hash_object(o):
|
|
31
31
|
if isinstance(o, (list, tuple)):
|
|
32
|
-
return b
|
|
32
|
+
return b"".join(hash_object(i) for i in o)
|
|
33
33
|
else:
|
|
34
34
|
return hash_value(o)
|
|
35
35
|
|
|
@@ -71,6 +71,7 @@ class Equipotential:
|
|
|
71
71
|
|
|
72
72
|
def __init__(self, term):
|
|
73
73
|
snl_term = get_snl_term_for_ids(term.pathIDs, term.termIDs)
|
|
74
|
+
inst_term = None
|
|
74
75
|
if isinstance(snl_term, snl.SNLBusTerm):
|
|
75
76
|
raise ValueError("Equipotential cannot be constructed on bus term")
|
|
76
77
|
if len(term.pathIDs) == 0:
|
|
@@ -82,20 +83,29 @@ class Equipotential:
|
|
|
82
83
|
if inst_term is None:
|
|
83
84
|
self.equi = None
|
|
84
85
|
return
|
|
86
|
+
else:
|
|
87
|
+
snl_term = get_snl_term_for_ids(inst_term.pathIDs, inst_term.termIDs)
|
|
85
88
|
else:
|
|
86
89
|
inst_term = term
|
|
87
90
|
path = get_snl_path_from_id_list(inst_term.pathIDs)
|
|
88
|
-
snl_term = get_snl_term_for_ids(inst_term.pathIDs, inst_term.termIDs)
|
|
89
91
|
ito = snl.SNLNetComponentOccurrence(
|
|
90
|
-
path.getHeadPath(),
|
|
91
|
-
path.getTailInstance().getInstTerm(snl_term)
|
|
92
|
+
path.getHeadPath(), path.getTailInstance().getInstTerm(snl_term)
|
|
92
93
|
)
|
|
93
94
|
self.equi = snl.SNLEquipotential(ito)
|
|
94
95
|
|
|
95
96
|
def __eq__(self, value):
|
|
96
97
|
return self.equi == value.equi
|
|
97
98
|
|
|
99
|
+
def dump_dot(self, path: str):
|
|
100
|
+
"""Dump the dot file of this equipotential."""
|
|
101
|
+
self.equi.dumpDotFile(path)
|
|
102
|
+
|
|
98
103
|
def get_inst_terms(self):
|
|
104
|
+
"""Iterate over the instance terminals of this equipotential.
|
|
105
|
+
|
|
106
|
+
:return: an iterator over the instance terminals of this equipotential.
|
|
107
|
+
:rtype: Iterator[Term]
|
|
108
|
+
"""
|
|
99
109
|
if self.equi is not None:
|
|
100
110
|
for term in self.equi.getInstTermOccurrences():
|
|
101
111
|
yield Term(
|
|
@@ -104,9 +114,14 @@ class Equipotential:
|
|
|
104
114
|
)
|
|
105
115
|
|
|
106
116
|
def get_top_terms(self):
|
|
117
|
+
"""Iterate over the top terminals of this equipotential.
|
|
118
|
+
|
|
119
|
+
:return: an iterator over the top terminals of this equipotential.
|
|
120
|
+
:rtype: Iterator[Term]
|
|
121
|
+
"""
|
|
107
122
|
if self.equi is not None:
|
|
108
123
|
for term in self.equi.getTerms():
|
|
109
|
-
yield Term(
|
|
124
|
+
yield Term([], term)
|
|
110
125
|
|
|
111
126
|
def get_leaf_readers(self):
|
|
112
127
|
if self.equi is not None:
|
|
@@ -115,7 +130,9 @@ class Equipotential:
|
|
|
115
130
|
if direction != snl.SNLTerm.Direction.Output:
|
|
116
131
|
if term.getInstTerm().getInstance().getModel().isLeaf():
|
|
117
132
|
yield Term(
|
|
118
|
-
snl.SNLPath(
|
|
133
|
+
snl.SNLPath(
|
|
134
|
+
term.getPath(), term.getInstTerm().getInstance()
|
|
135
|
+
),
|
|
119
136
|
term.getInstTerm().getBitTerm(),
|
|
120
137
|
)
|
|
121
138
|
|
|
@@ -126,7 +143,9 @@ class Equipotential:
|
|
|
126
143
|
if direction != snl.SNLTerm.Direction.Input:
|
|
127
144
|
if term.getInstTerm().getInstance().getModel().isLeaf():
|
|
128
145
|
yield Term(
|
|
129
|
-
snl.SNLPath(
|
|
146
|
+
snl.SNLPath(
|
|
147
|
+
term.getPath(), term.getInstTerm().getInstance()
|
|
148
|
+
),
|
|
130
149
|
term.getInstTerm().getBitTerm(),
|
|
131
150
|
)
|
|
132
151
|
|
|
@@ -151,10 +170,13 @@ class Net:
|
|
|
151
170
|
raise ValueError(
|
|
152
171
|
"Only one of `net` or `net_concat` should be provided, not both."
|
|
153
172
|
)
|
|
154
|
-
if path.
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
173
|
+
if isinstance(path, snl.SNLPath):
|
|
174
|
+
if path.size() > 0:
|
|
175
|
+
self.pathIDs = path.getPathIDs()
|
|
176
|
+
else:
|
|
177
|
+
self.pathIDs = []
|
|
178
|
+
elif isinstance(path, list):
|
|
179
|
+
self.pathIDs = path.copy()
|
|
158
180
|
if net is not None:
|
|
159
181
|
self.net = net
|
|
160
182
|
elif net_concat is not None:
|
|
@@ -182,45 +204,72 @@ class Net:
|
|
|
182
204
|
return net_str
|
|
183
205
|
|
|
184
206
|
def get_name(self) -> str:
|
|
185
|
-
"""
|
|
207
|
+
"""
|
|
208
|
+
:return: the name of this Net.
|
|
209
|
+
:rtype: str
|
|
210
|
+
"""
|
|
186
211
|
if hasattr(self, "net"):
|
|
187
212
|
return self.net.getName()
|
|
188
213
|
return "{" + ",".join(map(str, self.net_concat)) + "}"
|
|
189
214
|
|
|
190
215
|
def get_msb(self) -> int:
|
|
191
|
-
"""
|
|
216
|
+
"""
|
|
217
|
+
:return: the most significant bit of the net if it is a bus.
|
|
218
|
+
:rtype: int
|
|
219
|
+
"""
|
|
192
220
|
if hasattr(self, "net") and isinstance(self.net, snl.SNLBusNet):
|
|
193
221
|
return self.net.getMSB()
|
|
194
222
|
return None
|
|
195
223
|
|
|
196
224
|
def get_lsb(self) -> int:
|
|
197
|
-
"""
|
|
225
|
+
"""
|
|
226
|
+
:return: the least significant bit of the net if it is a bus.
|
|
227
|
+
:rtype: int
|
|
228
|
+
"""
|
|
198
229
|
if hasattr(self, "net") and isinstance(self.net, snl.SNLBusNet):
|
|
199
230
|
return self.net.getLSB()
|
|
200
231
|
return None
|
|
201
232
|
|
|
202
233
|
def is_bus(self) -> bool:
|
|
203
|
-
"""
|
|
234
|
+
"""
|
|
235
|
+
:return: True if the net is a bus.
|
|
236
|
+
:rtype: bool
|
|
237
|
+
"""
|
|
204
238
|
return hasattr(self, "net") and isinstance(self.net, snl.SNLBusNet)
|
|
205
239
|
|
|
206
240
|
def is_bus_bit(self) -> bool:
|
|
207
|
-
"""
|
|
241
|
+
"""
|
|
242
|
+
:return: True if the net is a bit of a bus.
|
|
243
|
+
:rtype: bool
|
|
244
|
+
"""
|
|
208
245
|
return hasattr(self, "net") and isinstance(self.net, snl.SNLBusNetBit)
|
|
209
246
|
|
|
210
247
|
def is_scalar(self) -> bool:
|
|
211
|
-
"""
|
|
248
|
+
"""
|
|
249
|
+
:return: True if the net is a scalar.
|
|
250
|
+
:rtype: bool
|
|
251
|
+
"""
|
|
212
252
|
return hasattr(self, "net") and isinstance(self.net, snl.SNLScalarNet)
|
|
213
253
|
|
|
214
254
|
def is_bit(self) -> bool:
|
|
215
|
-
"""
|
|
255
|
+
"""
|
|
256
|
+
:return: True if the net is a bit.
|
|
257
|
+
:rtype: bool
|
|
258
|
+
"""
|
|
216
259
|
return self.is_scalar() or self.is_bus_bit()
|
|
217
260
|
|
|
218
261
|
def is_concat(self) -> bool:
|
|
219
|
-
"""
|
|
262
|
+
"""
|
|
263
|
+
:return: True if the net is a concatenation.
|
|
264
|
+
:rtype: bool
|
|
265
|
+
"""
|
|
220
266
|
return hasattr(self, "net_concat")
|
|
221
267
|
|
|
222
268
|
def is_const(self) -> bool:
|
|
223
|
-
"""
|
|
269
|
+
"""
|
|
270
|
+
:return: True if the net is a constant generator.
|
|
271
|
+
:rtype: bool
|
|
272
|
+
"""
|
|
224
273
|
if hasattr(self, "net"):
|
|
225
274
|
return self.net.isConstant()
|
|
226
275
|
for net in self.net_concat:
|
|
@@ -229,17 +278,24 @@ class Net:
|
|
|
229
278
|
return True
|
|
230
279
|
|
|
231
280
|
def get_width(self) -> int:
|
|
232
|
-
"""
|
|
281
|
+
"""
|
|
282
|
+
:return: the width of the net.
|
|
283
|
+
:rtype: int
|
|
284
|
+
"""
|
|
233
285
|
if hasattr(self, "net"):
|
|
234
286
|
return self.net.getWidth()
|
|
235
287
|
return sum(1 for _ in self.net_concat)
|
|
236
288
|
|
|
237
289
|
def get_bits(self):
|
|
238
|
-
|
|
290
|
+
"""Iterate over the bits of this Net.
|
|
291
|
+
The iterator will return itself if the Net is scalar.
|
|
292
|
+
:return: an iterator over the bits of this Net.
|
|
293
|
+
:rtype: Iterator[Net]
|
|
294
|
+
"""
|
|
239
295
|
if hasattr(self, "net"):
|
|
240
296
|
if isinstance(self.net, snl.SNLBusNet):
|
|
241
297
|
for bit in self.net.getBits():
|
|
242
|
-
yield Net(
|
|
298
|
+
yield Net(self.pathIDs, bit)
|
|
243
299
|
else:
|
|
244
300
|
yield self
|
|
245
301
|
else:
|
|
@@ -247,32 +303,47 @@ class Net:
|
|
|
247
303
|
yield net
|
|
248
304
|
|
|
249
305
|
def get_bit(self, index: int):
|
|
250
|
-
|
|
306
|
+
"""
|
|
307
|
+
:param int index: the index of the bit to get.
|
|
308
|
+
:return: the Net bit at the given index or None if it does not exist.
|
|
309
|
+
:rtype: Net
|
|
310
|
+
"""
|
|
251
311
|
if hasattr(self, "net"):
|
|
252
312
|
if isinstance(self.net, snl.SNLBusNet):
|
|
253
|
-
return Net(
|
|
313
|
+
return Net(self.pathIDs, self.net.getBit(index))
|
|
254
314
|
else:
|
|
255
315
|
return None
|
|
256
316
|
if 0 <= index < len(self.net_concat):
|
|
257
|
-
return Net(
|
|
317
|
+
return Net(self.pathIDs, self.net_concat[index])
|
|
258
318
|
return None
|
|
259
319
|
|
|
260
320
|
def get_inst_terms(self):
|
|
261
|
-
|
|
321
|
+
"""
|
|
322
|
+
:return: an iterator over the instance terminals of the net.
|
|
323
|
+
:rtype: Iterator[Term]
|
|
324
|
+
"""
|
|
262
325
|
if hasattr(self, "net_concat"):
|
|
263
326
|
raise ValueError("Cannot get inst terms from a net_concat")
|
|
264
327
|
for term in self.net.getInstTerms():
|
|
265
|
-
path =
|
|
328
|
+
path = self.pathIDs.copy()
|
|
329
|
+
path.append(term.getInstance().getID())
|
|
266
330
|
yield Term(path, term.getBitTerm())
|
|
267
331
|
|
|
268
332
|
def get_design_terms(self):
|
|
269
|
-
|
|
333
|
+
"""
|
|
334
|
+
:return: an iterator over the design terminals of the net.
|
|
335
|
+
:rtype: Iterator[Term]
|
|
336
|
+
"""
|
|
270
337
|
if hasattr(self, "net_concat"):
|
|
271
338
|
raise ValueError("Cannot get terms from a net_concat")
|
|
272
339
|
for term in self.net.getBitTerms():
|
|
273
|
-
yield Term(
|
|
340
|
+
yield Term(self.pathIDs, term)
|
|
274
341
|
|
|
275
342
|
def get_terms(self):
|
|
343
|
+
"""
|
|
344
|
+
:return: an iterator over the terminals of the net.
|
|
345
|
+
:rtype: Iterator[Term]
|
|
346
|
+
"""
|
|
276
347
|
for term in itertools.chain(self.get_design_terms(), self.get_inst_terms()):
|
|
277
348
|
yield term
|
|
278
349
|
|
|
@@ -306,10 +377,13 @@ class Term:
|
|
|
306
377
|
else:
|
|
307
378
|
self.termIDs = [term.getID(), term.getBit()]
|
|
308
379
|
|
|
309
|
-
if path.
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
380
|
+
if isinstance(path, snl.SNLPath):
|
|
381
|
+
if path.size() > 0:
|
|
382
|
+
self.pathIDs = path.getPathIDs()
|
|
383
|
+
else:
|
|
384
|
+
self.pathIDs = []
|
|
385
|
+
elif isinstance(path, list):
|
|
386
|
+
self.pathIDs = path.copy()
|
|
313
387
|
|
|
314
388
|
def __eq__(self, other) -> bool:
|
|
315
389
|
return self.pathIDs == other.pathIDs and self.termIDs == other.termIDs
|
|
@@ -345,7 +419,9 @@ class Term:
|
|
|
345
419
|
if path.size() == 0:
|
|
346
420
|
return get_snl_term_for_ids(self.pathIDs, self.termIDs).getName()
|
|
347
421
|
else:
|
|
348
|
-
return
|
|
422
|
+
return (
|
|
423
|
+
f"{path}/{get_snl_term_for_ids(self.pathIDs, self.termIDs).getName()}"
|
|
424
|
+
)
|
|
349
425
|
|
|
350
426
|
def __repr__(self) -> str:
|
|
351
427
|
path = get_snl_path_from_id_list(self.pathIDs)
|
|
@@ -358,43 +434,76 @@ class Term:
|
|
|
358
434
|
snl.SNLUniquifier(path)
|
|
359
435
|
|
|
360
436
|
def is_bus(self) -> bool:
|
|
361
|
-
"""
|
|
362
|
-
return
|
|
437
|
+
"""
|
|
438
|
+
:return: True if the term is a bus.
|
|
439
|
+
:rtype: bool
|
|
440
|
+
"""
|
|
441
|
+
return isinstance(
|
|
442
|
+
get_snl_term_for_ids(self.pathIDs, self.termIDs), snl.SNLBusTerm
|
|
443
|
+
)
|
|
363
444
|
|
|
364
445
|
def is_bus_bit(self) -> bool:
|
|
365
|
-
"""
|
|
366
|
-
return
|
|
446
|
+
"""
|
|
447
|
+
:return: True if the term is a bit of a bus.
|
|
448
|
+
:rtype: bool
|
|
449
|
+
"""
|
|
450
|
+
return isinstance(
|
|
451
|
+
get_snl_term_for_ids(self.pathIDs, self.termIDs), snl.SNLBusTermBit
|
|
452
|
+
)
|
|
367
453
|
|
|
368
454
|
def is_scalar(self) -> bool:
|
|
369
|
-
"""
|
|
370
|
-
return
|
|
455
|
+
"""
|
|
456
|
+
:return: True if the term is a scalar.
|
|
457
|
+
:rtype: bool
|
|
458
|
+
"""
|
|
459
|
+
return isinstance(
|
|
460
|
+
get_snl_term_for_ids(self.pathIDs, self.termIDs), snl.SNLScalarTerm
|
|
461
|
+
)
|
|
371
462
|
|
|
372
463
|
def is_bit(self) -> bool:
|
|
373
|
-
"""
|
|
464
|
+
"""
|
|
465
|
+
:return: True if the term is a bit.
|
|
466
|
+
:rtype: bool
|
|
467
|
+
"""
|
|
374
468
|
return self.is_scalar() or self.is_bus_bit()
|
|
375
469
|
|
|
376
470
|
def get_msb(self) -> int:
|
|
377
|
-
"""
|
|
471
|
+
"""
|
|
472
|
+
:return: the most significant bit of the term if it is a bus.
|
|
473
|
+
:rtype: int or None
|
|
474
|
+
"""
|
|
378
475
|
if isinstance(get_snl_term_for_ids(self.pathIDs, self.termIDs), snl.SNLBusTerm):
|
|
379
476
|
return get_snl_term_for_ids(self.pathIDs, self.termIDs).getMSB()
|
|
380
477
|
return None
|
|
381
478
|
|
|
382
479
|
def get_lsb(self) -> int:
|
|
383
|
-
"""
|
|
480
|
+
"""
|
|
481
|
+
:return: the least significant bit of the term if it is a bus.
|
|
482
|
+
:rtype: int or None
|
|
483
|
+
"""
|
|
384
484
|
if isinstance(get_snl_term_for_ids(self.pathIDs, self.termIDs), snl.SNLBusTerm):
|
|
385
485
|
return get_snl_term_for_ids(self.pathIDs, self.termIDs).getLSB()
|
|
386
486
|
return None
|
|
387
487
|
|
|
388
488
|
def get_width(self) -> int:
|
|
389
|
-
"""
|
|
489
|
+
"""
|
|
490
|
+
:return: the width of the term. 1 if scalar.
|
|
491
|
+
:rtype: int
|
|
492
|
+
"""
|
|
390
493
|
return get_snl_term_for_ids(self.pathIDs, self.termIDs).getWidth()
|
|
391
494
|
|
|
392
495
|
def get_name(self) -> str:
|
|
393
|
-
"""
|
|
496
|
+
"""
|
|
497
|
+
:return: the name of the term.
|
|
498
|
+
:rtype: str
|
|
499
|
+
"""
|
|
394
500
|
return get_snl_term_for_ids(self.pathIDs, self.termIDs).getName()
|
|
395
501
|
|
|
396
502
|
def get_direction(self) -> snl.SNLTerm.Direction:
|
|
397
|
-
"""
|
|
503
|
+
"""
|
|
504
|
+
:return: the direction of the term.
|
|
505
|
+
:rtype: snl.SNLTerm.Direction
|
|
506
|
+
"""
|
|
398
507
|
snlterm = get_snl_term_for_ids(self.pathIDs, self.termIDs)
|
|
399
508
|
if snlterm.getDirection() == snl.SNLTerm.Direction.Input:
|
|
400
509
|
return Term.INPUT
|
|
@@ -447,29 +556,38 @@ class Term:
|
|
|
447
556
|
if all(element is not None for element in snl_nets):
|
|
448
557
|
return Net(path, net_concat=snl_nets)
|
|
449
558
|
else:
|
|
450
|
-
snl_net = snl_term_net_accessor(
|
|
559
|
+
snl_net = snl_term_net_accessor(
|
|
560
|
+
get_snl_term_for_ids(self.pathIDs, self.termIDs)
|
|
561
|
+
)
|
|
451
562
|
if snl_net is not None:
|
|
452
563
|
return Net(path, snl_net)
|
|
453
564
|
return None
|
|
454
565
|
|
|
455
566
|
def get_lower_net(self) -> Net:
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
567
|
+
"""
|
|
568
|
+
:return: the lower net of the term.
|
|
569
|
+
:rtype: Net
|
|
570
|
+
"""
|
|
571
|
+
return self.__get_net(self.pathIDs, self.__get_snl_lower_bitnet)
|
|
459
572
|
|
|
460
573
|
def get_net(self) -> Net:
|
|
461
|
-
"""
|
|
462
|
-
|
|
463
|
-
|
|
574
|
+
"""
|
|
575
|
+
:return: the net of the term.
|
|
576
|
+
:rtype: Net
|
|
577
|
+
"""
|
|
578
|
+
head_path = self.pathIDs.copy()
|
|
579
|
+
if len(head_path) == 0:
|
|
464
580
|
return None
|
|
465
581
|
# path is one level up
|
|
466
|
-
head_path
|
|
582
|
+
head_path.pop()
|
|
467
583
|
return self.__get_net(head_path, self.__get_snl_bitnet)
|
|
468
584
|
|
|
469
585
|
def get_instance(self):
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
586
|
+
"""
|
|
587
|
+
:return: the instance of this Term.
|
|
588
|
+
:rtype: Instance
|
|
589
|
+
"""
|
|
590
|
+
return Instance(self.pathIDs)
|
|
473
591
|
|
|
474
592
|
def get_flat_fanout(self):
|
|
475
593
|
return self.get_equipotential().get_leaf_readers()
|
|
@@ -478,30 +596,48 @@ class Term:
|
|
|
478
596
|
return Equipotential(self)
|
|
479
597
|
|
|
480
598
|
def is_input(self) -> bool:
|
|
481
|
-
"""
|
|
599
|
+
"""
|
|
600
|
+
:return: True if the term is an input.
|
|
601
|
+
:rtype: bool
|
|
602
|
+
"""
|
|
482
603
|
snlterm = get_snl_term_for_ids(self.pathIDs, self.termIDs)
|
|
483
604
|
return snlterm.getDirection() == snl.SNLTerm.Direction.Input
|
|
484
605
|
|
|
485
606
|
def is_output(self) -> bool:
|
|
486
|
-
"""
|
|
607
|
+
"""
|
|
608
|
+
:return: True if the term is an output.
|
|
609
|
+
:rtype: bool
|
|
610
|
+
"""
|
|
487
611
|
snlterm = get_snl_term_for_ids(self.pathIDs, self.termIDs)
|
|
488
612
|
return snlterm.getDirection() == snl.SNLTerm.Direction.Output
|
|
489
613
|
|
|
490
614
|
def get_bits(self):
|
|
491
|
-
|
|
615
|
+
"""
|
|
616
|
+
:return: an iterator over the bits of the term.
|
|
617
|
+
If the term is scalar, it will return an iterator over itself.
|
|
618
|
+
:rtype: Iterator[Term]
|
|
619
|
+
"""
|
|
492
620
|
if isinstance(get_snl_term_for_ids(self.pathIDs, self.termIDs), snl.SNLBusTerm):
|
|
493
621
|
for bit in get_snl_term_for_ids(self.pathIDs, self.termIDs).getBits():
|
|
494
|
-
yield Term(
|
|
622
|
+
yield Term(self.pathIDs, bit)
|
|
495
623
|
else:
|
|
496
624
|
yield self
|
|
497
625
|
|
|
498
626
|
def get_bit(self, index: int):
|
|
499
|
-
|
|
627
|
+
"""
|
|
628
|
+
:param int index: the index of the bit to get.
|
|
629
|
+
:return: the Term bit at the given index or None if it does not exist.
|
|
630
|
+
:rtype: Term or None
|
|
631
|
+
"""
|
|
500
632
|
if isinstance(get_snl_term_for_ids(self.pathIDs, self.termIDs), snl.SNLBusTerm):
|
|
501
|
-
return Term(
|
|
633
|
+
return Term(
|
|
634
|
+
self.pathIDs,
|
|
635
|
+
get_snl_term_for_ids(self.pathIDs, self.termIDs).getBit(index),
|
|
636
|
+
)
|
|
502
637
|
return None
|
|
503
638
|
|
|
504
639
|
def disconnect(self):
|
|
640
|
+
"""Disconnect this term from its net."""
|
|
505
641
|
path = get_snl_path_from_id_list(self.pathIDs)
|
|
506
642
|
self.__make_unique()
|
|
507
643
|
inst = path.getTailInstance()
|
|
@@ -510,21 +646,27 @@ class Term:
|
|
|
510
646
|
iterm.setNet(None)
|
|
511
647
|
|
|
512
648
|
def connect(self, net: Net):
|
|
649
|
+
"""Connect this term to the given Net.
|
|
650
|
+
|
|
651
|
+
:param Net net: the Net to connect to.
|
|
652
|
+
"""
|
|
513
653
|
if self.get_width() != net.get_width():
|
|
514
654
|
raise ValueError("Width mismatch")
|
|
515
655
|
if self.get_instance().is_top():
|
|
516
|
-
for bterm, bnet in zip(
|
|
517
|
-
|
|
518
|
-
|
|
656
|
+
for bterm, bnet in zip(
|
|
657
|
+
get_snl_term_for_ids(self.pathIDs, self.termIDs).getBits(),
|
|
658
|
+
net.net.getBits(),
|
|
659
|
+
):
|
|
519
660
|
logging.debug(f"Connecting {bterm} to {bnet}")
|
|
520
661
|
bterm.setNet(bnet)
|
|
521
662
|
else:
|
|
522
663
|
self.__make_unique()
|
|
523
664
|
path = get_snl_path_from_id_list(self.pathIDs)
|
|
524
665
|
inst = path.getTailInstance()
|
|
525
|
-
for bterm, bnet in zip(
|
|
526
|
-
|
|
527
|
-
|
|
666
|
+
for bterm, bnet in zip(
|
|
667
|
+
get_snl_term_for_ids(self.pathIDs, self.termIDs).getBits(),
|
|
668
|
+
net.net.getBits(),
|
|
669
|
+
):
|
|
528
670
|
iterm = inst.getInstTerm(bterm)
|
|
529
671
|
iterm.setNet(bnet)
|
|
530
672
|
|
|
@@ -564,10 +706,13 @@ class Instance:
|
|
|
564
706
|
"""
|
|
565
707
|
|
|
566
708
|
def __init__(self, path=snl.SNLPath()):
|
|
567
|
-
if path.
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
709
|
+
if isinstance(path, snl.SNLPath):
|
|
710
|
+
if path.size() > 0:
|
|
711
|
+
self.pathIDs = path.getPathIDs()
|
|
712
|
+
else:
|
|
713
|
+
self.pathIDs = []
|
|
714
|
+
elif isinstance(path, list):
|
|
715
|
+
self.pathIDs = path.copy()
|
|
571
716
|
|
|
572
717
|
def __eq__(self, other) -> bool:
|
|
573
718
|
return self.pathIDs == other.pathIDs
|
|
@@ -591,6 +736,11 @@ class Instance:
|
|
|
591
736
|
return consistent_hash(self.pathIDs)
|
|
592
737
|
|
|
593
738
|
def get_leaf_children(self):
|
|
739
|
+
"""Iterate over the leaf children of this Instance.
|
|
740
|
+
Equivalent to the underlying leaves of the instanciation tree.
|
|
741
|
+
:return: an iterator over the leaf children Instance of this Instance.
|
|
742
|
+
:rtype: Iterator[Instance]
|
|
743
|
+
"""
|
|
594
744
|
initial_path = get_snl_path_from_id_list(self.pathIDs)
|
|
595
745
|
for inst in self.__get_snl_model().getInstances():
|
|
596
746
|
if inst.getModel().isLeaf():
|
|
@@ -608,42 +758,72 @@ class Instance:
|
|
|
608
758
|
stack.append([inst_child, path_child])
|
|
609
759
|
|
|
610
760
|
def is_top(self) -> bool:
|
|
611
|
-
"""
|
|
761
|
+
"""
|
|
762
|
+
:return: True if this is the top design.
|
|
763
|
+
:rtype: bool
|
|
764
|
+
"""
|
|
612
765
|
return len(self.pathIDs) == 0
|
|
613
766
|
|
|
614
767
|
def is_assign(self) -> bool:
|
|
768
|
+
"""Example: (assign a=b) will create an instance of assign connecting
|
|
769
|
+
the wire a to the output of the assign and b to the input.
|
|
770
|
+
|
|
771
|
+
:return: True if this is an assign. Assigns are represented with
|
|
772
|
+
anonymous Assign instances.
|
|
773
|
+
:rtype: bool
|
|
774
|
+
"""
|
|
615
775
|
return self.__get_snl_model().isAssign()
|
|
616
776
|
|
|
617
777
|
def is_blackbox(self) -> bool:
|
|
618
|
-
"""
|
|
778
|
+
"""
|
|
779
|
+
:return: True if this is a blackbox.
|
|
780
|
+
:rtype: bool
|
|
781
|
+
"""
|
|
619
782
|
return self.__get_snl_model().isBlackBox()
|
|
620
783
|
|
|
621
784
|
def is_leaf(self) -> bool:
|
|
622
|
-
"""
|
|
785
|
+
"""
|
|
786
|
+
:return: True if this is a leaf.
|
|
787
|
+
:rtype: bool
|
|
788
|
+
"""
|
|
623
789
|
return self.__get_snl_model().isLeaf()
|
|
624
790
|
|
|
625
791
|
def is_const0(self) -> bool:
|
|
626
|
-
"""
|
|
792
|
+
"""
|
|
793
|
+
:return: True if this is a constant 0 generator.
|
|
794
|
+
:rtype: bool
|
|
795
|
+
"""
|
|
627
796
|
return self.__get_snl_model().isConst0()
|
|
628
797
|
|
|
629
798
|
def is_const1(self) -> bool:
|
|
630
|
-
"""
|
|
799
|
+
"""
|
|
800
|
+
:return: True if this is a constant 1 generator.
|
|
801
|
+
:rtype: bool
|
|
802
|
+
"""
|
|
631
803
|
return self.__get_snl_model().isConst1()
|
|
632
804
|
|
|
633
805
|
def is_const(self) -> bool:
|
|
634
|
-
"""
|
|
806
|
+
"""
|
|
807
|
+
:return: True if this is a constant generator.
|
|
808
|
+
:rtype: bool
|
|
809
|
+
"""
|
|
635
810
|
return self.__get_snl_model().isConst()
|
|
636
811
|
|
|
637
812
|
def is_buf(self) -> bool:
|
|
638
|
-
"""
|
|
813
|
+
"""
|
|
814
|
+
:return: True if this is a buffer.
|
|
815
|
+
:rtype: bool
|
|
816
|
+
"""
|
|
639
817
|
return self.__get_snl_model().isBuf()
|
|
640
818
|
|
|
641
819
|
def is_inv(self) -> bool:
|
|
642
|
-
"""
|
|
820
|
+
"""
|
|
821
|
+
:return: True if this is an inverter.
|
|
822
|
+
:rtype: bool
|
|
823
|
+
"""
|
|
643
824
|
return self.__get_snl_model().isInv()
|
|
644
825
|
|
|
645
826
|
def __get_snl_model(self):
|
|
646
|
-
"""Return the model of the instance."""
|
|
647
827
|
if self.is_top():
|
|
648
828
|
return snl.SNLUniverse.get().getTopDesign()
|
|
649
829
|
instance = get_snl_instance_from_id_list(self.pathIDs)
|
|
@@ -658,20 +838,43 @@ class Instance:
|
|
|
658
838
|
return found_model
|
|
659
839
|
return None
|
|
660
840
|
|
|
841
|
+
def dump_full_dot(self, path: str):
|
|
842
|
+
"""Dump the full dot file of this instance."""
|
|
843
|
+
self.__get_snl_model().dumpFullDotFile(path)
|
|
844
|
+
|
|
845
|
+
def dump_context_dot(self, path: str):
|
|
846
|
+
self.__get_snl_model().dumpContextDotFile(path)
|
|
847
|
+
|
|
661
848
|
def get_child_instance(self, name: str):
|
|
849
|
+
"""
|
|
850
|
+
:param str name: the name of the child Instance to get.
|
|
851
|
+
:return: the child Instance with the given name or None if it does not exist.
|
|
852
|
+
:rtype: Instance or None
|
|
853
|
+
"""
|
|
662
854
|
childInst = self.__get_snl_model().getInstance(name)
|
|
663
855
|
if childInst is None:
|
|
664
856
|
return None
|
|
665
|
-
path =
|
|
666
|
-
|
|
857
|
+
path = self.pathIDs.copy()
|
|
858
|
+
path.append(childInst.getID())
|
|
859
|
+
return Instance(path)
|
|
667
860
|
|
|
668
861
|
def get_child_instances(self):
|
|
862
|
+
"""Iterate over the child instances of this instance.
|
|
863
|
+
Equivalent to go down one level in hierarchy.
|
|
864
|
+
|
|
865
|
+
:return: an iterator over the child instances of this instance.
|
|
866
|
+
:rtype: Iterator[Instance]
|
|
867
|
+
"""
|
|
669
868
|
for inst in self.__get_snl_model().getInstances():
|
|
670
|
-
|
|
671
|
-
path
|
|
869
|
+
path = self.pathIDs.copy()
|
|
870
|
+
path.append(inst.getID())
|
|
672
871
|
yield Instance(path)
|
|
673
872
|
|
|
674
873
|
def get_number_of_child_instances(self) -> int:
|
|
874
|
+
"""
|
|
875
|
+
:return: the number of child instances of this instance.
|
|
876
|
+
:rtype: int
|
|
877
|
+
"""
|
|
675
878
|
return sum(1 for _ in self.__get_snl_model().getInstances())
|
|
676
879
|
|
|
677
880
|
# def get_flat_primitive_instances(self):
|
|
@@ -691,85 +894,130 @@ class Instance:
|
|
|
691
894
|
# stack.append([inst_child, path_child])
|
|
692
895
|
|
|
693
896
|
def get_nets(self):
|
|
694
|
-
|
|
897
|
+
"""Iterate over all scalar nets and bus nets.
|
|
898
|
+
|
|
899
|
+
:return: an iterator over the nets of this Instance.
|
|
900
|
+
:rtype: Iterator[Net]
|
|
901
|
+
"""
|
|
695
902
|
for net in self.__get_snl_model().getNets():
|
|
696
|
-
yield Net(
|
|
903
|
+
yield Net(self.pathIDs, net)
|
|
697
904
|
|
|
698
905
|
def get_flat_nets(self):
|
|
699
|
-
|
|
906
|
+
"""Iterate over all scalar nets and bus net bits.
|
|
907
|
+
|
|
908
|
+
:return: an iterator over the flat nets of this Instance.
|
|
909
|
+
:rtype: Iterator[Net]
|
|
910
|
+
"""
|
|
700
911
|
for net in self.__get_snl_model().getNets():
|
|
701
912
|
if isinstance(net, snl.SNLBusNet):
|
|
702
913
|
for bit in net.getBits():
|
|
703
|
-
yield Net(
|
|
914
|
+
yield Net(self.pathIDs, bit)
|
|
704
915
|
else:
|
|
705
|
-
yield Net(
|
|
916
|
+
yield Net(self.pathIDs, net)
|
|
706
917
|
|
|
707
918
|
def get_net(self, name: str) -> Net:
|
|
708
|
-
|
|
919
|
+
"""
|
|
920
|
+
:param str name: the name of the Net to get.
|
|
921
|
+
:return: the Net with the given name or None if it does not exist.
|
|
922
|
+
:rtype: Net or None
|
|
923
|
+
"""
|
|
709
924
|
net = self.__get_snl_model().getNet(name)
|
|
710
925
|
if net is not None:
|
|
711
|
-
return Net(
|
|
926
|
+
return Net(self.pathIDs, net)
|
|
712
927
|
return None
|
|
713
928
|
|
|
714
929
|
def is_primitive(self) -> bool:
|
|
715
|
-
"""
|
|
930
|
+
"""
|
|
931
|
+
:return: True if this is a primitive.
|
|
932
|
+
:rtype: bool
|
|
933
|
+
"""
|
|
716
934
|
return self.__get_snl_model().isPrimitive()
|
|
717
935
|
|
|
718
936
|
def get_terms(self):
|
|
719
|
-
|
|
937
|
+
"""Iterate over all scalar terms and bus terms of this Instance.
|
|
938
|
+
|
|
939
|
+
:return: the terms of this Instance.
|
|
940
|
+
:rtype: Iterator[Term]
|
|
941
|
+
"""
|
|
720
942
|
for term in self.__get_snl_model().getTerms():
|
|
721
|
-
yield Term(
|
|
943
|
+
yield Term(self.pathIDs, term)
|
|
722
944
|
|
|
723
945
|
def get_flat_terms(self):
|
|
724
|
-
|
|
946
|
+
"""Iterate over all scalar terms and bus term bits.
|
|
947
|
+
|
|
948
|
+
:return: the flat terms of this Instance.
|
|
949
|
+
:rtype: Iterator[Term]
|
|
950
|
+
"""
|
|
725
951
|
for term in self.__get_snl_model().getBitTerms():
|
|
726
|
-
yield Term(
|
|
952
|
+
yield Term(self.pathIDs, term)
|
|
727
953
|
|
|
728
954
|
def get_term(self, name: str) -> Term:
|
|
729
|
-
|
|
955
|
+
"""
|
|
956
|
+
:param str name: the name of the Term to get.
|
|
957
|
+
:return: the Term with the given name.
|
|
958
|
+
:rtype: Term or None
|
|
959
|
+
"""
|
|
730
960
|
term = self.__get_snl_model().getTerm(name)
|
|
731
961
|
if term is not None:
|
|
732
|
-
return Term(
|
|
962
|
+
return Term(self.pathIDs, self.__get_snl_model().getTerm(name))
|
|
733
963
|
return None
|
|
734
964
|
|
|
735
965
|
def get_input_terms(self):
|
|
736
|
-
|
|
966
|
+
"""Iterate over all scalar input terms and bus input terms
|
|
967
|
+
of this Instance.
|
|
968
|
+
|
|
969
|
+
:return: the input terms of this Instance.
|
|
970
|
+
:rtype: Iterator[Term]
|
|
971
|
+
"""
|
|
737
972
|
for term in self.__get_snl_model().getTerms():
|
|
738
973
|
if term.getDirection() != snl.SNLTerm.Direction.Output:
|
|
739
|
-
yield Term(
|
|
974
|
+
yield Term(self.pathIDs, term)
|
|
740
975
|
|
|
741
976
|
def get_flat_input_terms(self):
|
|
742
|
-
|
|
977
|
+
"""Iterate over all scalar input terms and bus input term bits
|
|
978
|
+
of this Instance.
|
|
979
|
+
|
|
980
|
+
:return: the flat input terms of this Instance.
|
|
981
|
+
:rtype: Iterator[Term]
|
|
982
|
+
"""
|
|
743
983
|
for term in self.__get_snl_model().getTerms():
|
|
744
984
|
if term.getDirection() != snl.SNLTerm.Direction.Output:
|
|
745
985
|
if isinstance(term, snl.SNLBusTerm):
|
|
746
986
|
for bit in term.getBits():
|
|
747
|
-
yield Term(
|
|
987
|
+
yield Term(self.pathIDs, bit)
|
|
748
988
|
else:
|
|
749
|
-
yield Term(
|
|
989
|
+
yield Term(self.pathIDs, term)
|
|
750
990
|
|
|
751
991
|
def get_output_terms(self):
|
|
752
|
-
|
|
992
|
+
"""Iterate over all scalar output terms and bus output terms
|
|
993
|
+
of this Instance.
|
|
994
|
+
|
|
995
|
+
:return: the output terms of this Instance.
|
|
996
|
+
:rtype: Iterator[Term]
|
|
997
|
+
"""
|
|
753
998
|
for term in self.__get_snl_model().getTerms():
|
|
754
999
|
if term.getDirection() != snl.SNLTerm.Direction.Input:
|
|
755
|
-
yield Term(
|
|
1000
|
+
yield Term(self.pathIDs, term)
|
|
756
1001
|
|
|
757
1002
|
def get_flat_output_terms(self):
|
|
758
|
-
|
|
1003
|
+
"""Return the flat output terms of the instance.
|
|
1004
|
+
This will iterate over all scalar output terms and bus output term bits.
|
|
1005
|
+
"""
|
|
759
1006
|
for term in self.__get_snl_model().getTerms():
|
|
760
1007
|
if term.getDirection() != snl.SNLTerm.Direction.Input:
|
|
761
1008
|
if isinstance(term, snl.SNLBusTerm):
|
|
762
1009
|
for bit in term.getBits():
|
|
763
|
-
yield Term(
|
|
1010
|
+
yield Term(self.pathIDs, bit)
|
|
764
1011
|
else:
|
|
765
|
-
yield Term(
|
|
1012
|
+
yield Term(self.pathIDs, term)
|
|
766
1013
|
|
|
767
1014
|
def delete_instance(self, name: str):
|
|
768
|
-
|
|
1015
|
+
"""Delete the child instance with the given name."""
|
|
769
1016
|
if name == "":
|
|
770
1017
|
raise ValueError(
|
|
771
1018
|
"Cannot delete instance with empty name. Try delete_instance_by_id instead."
|
|
772
1019
|
)
|
|
1020
|
+
init_path = get_snl_path_from_id_list(self.pathIDs)
|
|
773
1021
|
path = snl.SNLPath(init_path, self.__get_snl_model().getInstance(name))
|
|
774
1022
|
snl.SNLUniquifier(path)
|
|
775
1023
|
if init_path.size() > 0:
|
|
@@ -777,6 +1025,10 @@ class Instance:
|
|
|
777
1025
|
self.__get_snl_model().getInstance(name).destroy()
|
|
778
1026
|
|
|
779
1027
|
def delete_instance_by_id(self, id: str):
|
|
1028
|
+
"""Delete the child instance with the given ID.
|
|
1029
|
+
|
|
1030
|
+
:param str id: the ID of the Instance to delete.
|
|
1031
|
+
"""
|
|
780
1032
|
init_path = get_snl_path_from_id_list(self.pathIDs)
|
|
781
1033
|
path = snl.SNLPath(init_path, self.__get_snl_model().getInstanceByID(id))
|
|
782
1034
|
snl.SNLUniquifier(path)
|
|
@@ -784,33 +1036,57 @@ class Instance:
|
|
|
784
1036
|
self.__get_snl_model().getInstanceByID(id).destroy()
|
|
785
1037
|
|
|
786
1038
|
def get_design(self):
|
|
787
|
-
|
|
1039
|
+
"""
|
|
1040
|
+
:return: the Instance containing this instance.
|
|
1041
|
+
:rtype: Instance
|
|
1042
|
+
"""
|
|
1043
|
+
path = self.pathIDs.copy()
|
|
788
1044
|
if len(self.pathIDs) == 1:
|
|
789
1045
|
return get_top()
|
|
790
|
-
|
|
1046
|
+
path.pop()
|
|
1047
|
+
return Instance(path)
|
|
791
1048
|
|
|
792
1049
|
def delete(self):
|
|
1050
|
+
"""Delete this instance."""
|
|
793
1051
|
path = get_snl_path_from_id_list(self.pathIDs)
|
|
794
1052
|
snl.SNLUniquifier(path)
|
|
795
1053
|
self.get_design().delete_instance_by_id(path.getTailInstance().getID())
|
|
796
1054
|
|
|
797
1055
|
def get_name(self) -> str:
|
|
1056
|
+
"""
|
|
1057
|
+
:return: the name of the instance or name of the top is this is the top.
|
|
1058
|
+
:rtype: str
|
|
1059
|
+
"""
|
|
798
1060
|
path = get_snl_path_from_id_list(self.pathIDs)
|
|
799
|
-
"""Return the name of the instance or name of the top is this is the top."""
|
|
800
1061
|
if self.is_top():
|
|
801
1062
|
return self.get_model_name()
|
|
802
1063
|
else:
|
|
803
1064
|
return path.getTailInstance().getName()
|
|
804
1065
|
|
|
805
1066
|
def get_model_name(self) -> str:
|
|
806
|
-
"""
|
|
1067
|
+
"""
|
|
1068
|
+
:return: the name of the model of the instance
|
|
1069
|
+
or name of the top is this is the top.
|
|
1070
|
+
:rtype: str
|
|
1071
|
+
"""
|
|
807
1072
|
return self.__get_snl_model().getName()
|
|
808
1073
|
|
|
809
1074
|
def get_model_id(self) -> tuple[int, int, int]:
|
|
1075
|
+
"""
|
|
1076
|
+
:return: the ID of the model of this Instance
|
|
1077
|
+
or ID of the top if this is the top.
|
|
1078
|
+
"""
|
|
810
1079
|
model = self.__get_snl_model()
|
|
811
1080
|
return model.getDB().getID(), model.getLibrary().getID(), model.getID()
|
|
812
1081
|
|
|
813
1082
|
def create_child_instance(self, model: str, name: str):
|
|
1083
|
+
"""Create a child instance with the given model and name.
|
|
1084
|
+
|
|
1085
|
+
:param str model: the name of the model of the instance to create.
|
|
1086
|
+
:param str name: the name of the instance to create.
|
|
1087
|
+
:return: the created Instance.
|
|
1088
|
+
:rtype: Instance
|
|
1089
|
+
"""
|
|
814
1090
|
path = get_snl_path_from_id_list(self.pathIDs)
|
|
815
1091
|
if path.size() > 0:
|
|
816
1092
|
snl.SNLUniquifier(path)
|
|
@@ -826,6 +1102,12 @@ class Instance:
|
|
|
826
1102
|
return Instance(path)
|
|
827
1103
|
|
|
828
1104
|
def create_term(self, name: str, direction: snl.SNLTerm.Direction) -> Term:
|
|
1105
|
+
"""Create a Term in this Instance with the given name and direction.
|
|
1106
|
+
|
|
1107
|
+
:param str name: the name of the Term to create.
|
|
1108
|
+
:param snl.SNLTerm.Direction direction: the direction of the Term to create.
|
|
1109
|
+
:return: the created Term.
|
|
1110
|
+
"""
|
|
829
1111
|
path = get_snl_path_from_id_list(self.pathIDs)
|
|
830
1112
|
if path.size() > 0:
|
|
831
1113
|
snl.SNLUniquifier(path)
|
|
@@ -835,15 +1117,40 @@ class Instance:
|
|
|
835
1117
|
return Term(path, newSNLTerm)
|
|
836
1118
|
|
|
837
1119
|
def create_output_term(self, name: str) -> Term:
|
|
1120
|
+
"""Create an output Term in this Instance with the given name.
|
|
1121
|
+
|
|
1122
|
+
:param str name: the name of the Term to create.
|
|
1123
|
+
:return: the created Term.
|
|
1124
|
+
:rtype: Term
|
|
1125
|
+
"""
|
|
838
1126
|
return self.create_term(name, snl.SNLTerm.Direction.Output)
|
|
839
1127
|
|
|
840
1128
|
def create_input_term(self, name: str) -> Term:
|
|
1129
|
+
"""Create an input Term in this Instance with the given name.
|
|
1130
|
+
|
|
1131
|
+
:param str name: the name of the Term to create.
|
|
1132
|
+
:return: the created Term.
|
|
1133
|
+
:rtype: Term
|
|
1134
|
+
"""
|
|
841
1135
|
return self.create_term(name, snl.SNLTerm.Direction.Input)
|
|
842
1136
|
|
|
843
1137
|
def create_inout_term(self, name: str) -> Term:
|
|
1138
|
+
"""Create an inout Term in this Instance with the given name.
|
|
1139
|
+
|
|
1140
|
+
:param str name: the name of the Term to create.
|
|
1141
|
+
:return: the created Term.
|
|
1142
|
+
:rtype: Term
|
|
1143
|
+
"""
|
|
844
1144
|
return self.create_term(name, snl.SNLTerm.Direction.InOut)
|
|
845
1145
|
|
|
846
1146
|
def create_bus_term(self, name: str, msb: int, lsb: int, direction) -> Term:
|
|
1147
|
+
"""Create a bus Term in this Instance with the given name, msb, lsb and direction.
|
|
1148
|
+
:param str name: the name of the Term to create.
|
|
1149
|
+
:param int msb: the most significant bit of the Term to create.
|
|
1150
|
+
:param int lsb: the least significant bit of the Term to create.
|
|
1151
|
+
:param snl.SNLTerm.Direction direction: the direction of the Term to create.
|
|
1152
|
+
:return: the created Term.
|
|
1153
|
+
"""
|
|
847
1154
|
path = get_snl_path_from_id_list(self.pathIDs)
|
|
848
1155
|
if path.size() > 0:
|
|
849
1156
|
snl.SNLUniquifier(path)
|
|
@@ -853,15 +1160,45 @@ class Instance:
|
|
|
853
1160
|
return Term(path, newSNLTerm)
|
|
854
1161
|
|
|
855
1162
|
def create_inout_bus_term(self, name: str, msb: int, lsb: int) -> Term:
|
|
1163
|
+
"""Create an inout bus Term in this Instance with the given name, msb and lsb.
|
|
1164
|
+
|
|
1165
|
+
:param str name: the name of the Term to create.
|
|
1166
|
+
:param int msb: the most significant bit of the Term to create.
|
|
1167
|
+
:param int lsb: the least significant bit of the Term to create.
|
|
1168
|
+
:return: the created Term.
|
|
1169
|
+
:rtype: Term
|
|
1170
|
+
"""
|
|
856
1171
|
return self.create_bus_term(name, msb, lsb, snl.SNLTerm.Direction.InOut)
|
|
857
1172
|
|
|
858
1173
|
def create_output_bus_term(self, name: str, msb: int, lsb: int) -> Term:
|
|
1174
|
+
"""Create an output bus Term in this Instance with the given name, msb and lsb.
|
|
1175
|
+
|
|
1176
|
+
:param str name: the name of the Term to create.
|
|
1177
|
+
:param int msb: the most significant bit of the Term to create.
|
|
1178
|
+
:param int lsb: the least significant bit of the Term to create.
|
|
1179
|
+
:return: the created Term.
|
|
1180
|
+
:rtype: Term
|
|
1181
|
+
"""
|
|
859
1182
|
return self.create_bus_term(name, msb, lsb, snl.SNLTerm.Direction.Output)
|
|
860
1183
|
|
|
861
1184
|
def create_input_bus_term(self, name: str, msb: int, lsb: int) -> Term:
|
|
1185
|
+
"""Create an input bus Term in this Instance with the given name, msb and lsb.
|
|
1186
|
+
|
|
1187
|
+
:param str name: the name of the Term to create.
|
|
1188
|
+
:param int msb: the most significant bit of the Term to create.
|
|
1189
|
+
:param int lsb: the least significant bit of the Term to create.
|
|
1190
|
+
:return: the created Term.
|
|
1191
|
+
:rtype: Term
|
|
1192
|
+
"""
|
|
862
1193
|
return self.create_bus_term(name, msb, lsb, snl.SNLTerm.Direction.Input)
|
|
863
1194
|
|
|
864
1195
|
def create_net(self, name: str) -> Net:
|
|
1196
|
+
"""Create a scalar Net in this Instance with the given name.
|
|
1197
|
+
|
|
1198
|
+
:param str name: the name of the Net to create.
|
|
1199
|
+
:return: the created Net.
|
|
1200
|
+
:rtype: Net
|
|
1201
|
+
"""
|
|
865
1202
|
path = get_snl_path_from_id_list(self.pathIDs)
|
|
866
1203
|
if path.size() > 0:
|
|
867
1204
|
snl.SNLUniquifier(path)
|
|
@@ -871,6 +1208,14 @@ class Instance:
|
|
|
871
1208
|
return Net(path, newSNLNet)
|
|
872
1209
|
|
|
873
1210
|
def create_bus_net(self, name: str, msb: int, lsb: int) -> Net:
|
|
1211
|
+
"""Create a bus Net in this Instance with the given name, msb and lsb.
|
|
1212
|
+
|
|
1213
|
+
:param str name: the name of the Net to create.
|
|
1214
|
+
:param int msb: the most significant bit of the Net to create.
|
|
1215
|
+
:param int lsb: the least significant bit of the Net to create.
|
|
1216
|
+
:return: the created Net.
|
|
1217
|
+
:rtype: Net
|
|
1218
|
+
"""
|
|
874
1219
|
path = get_snl_path_from_id_list(self.pathIDs)
|
|
875
1220
|
if path.size() > 0:
|
|
876
1221
|
snl.SNLUniquifier(path)
|
|
@@ -880,6 +1225,11 @@ class Instance:
|
|
|
880
1225
|
return Net(path, newSNLNet)
|
|
881
1226
|
|
|
882
1227
|
def dump_verilog(self, path: str, name: str):
|
|
1228
|
+
"""Dump the verilog of this instance.
|
|
1229
|
+
|
|
1230
|
+
:param str path: the path where to dump the verilog.
|
|
1231
|
+
:param str name: the name of the verilog file.
|
|
1232
|
+
"""
|
|
883
1233
|
self.__get_snl_model().dumpVerilog(path, name)
|
|
884
1234
|
|
|
885
1235
|
|
|
@@ -893,10 +1243,20 @@ def get_top_db() -> snl.SNLDB:
|
|
|
893
1243
|
|
|
894
1244
|
|
|
895
1245
|
def get_top():
|
|
1246
|
+
"""
|
|
1247
|
+
:return: the top Instance.
|
|
1248
|
+
:rtype: Instance
|
|
1249
|
+
"""
|
|
896
1250
|
return Instance(snl.SNLPath())
|
|
897
1251
|
|
|
898
1252
|
|
|
899
1253
|
def create_top(name: str) -> Instance:
|
|
1254
|
+
"""Create a top instance with the given name.
|
|
1255
|
+
|
|
1256
|
+
:param str name: the name of the top instance to create.
|
|
1257
|
+
:return: the created top Instance.
|
|
1258
|
+
:rtype: Instance
|
|
1259
|
+
"""
|
|
900
1260
|
# init
|
|
901
1261
|
db = get_top_db()
|
|
902
1262
|
# create top design
|
|
@@ -916,11 +1276,15 @@ def load_verilog(files: list):
|
|
|
916
1276
|
|
|
917
1277
|
|
|
918
1278
|
def load_liberty(files: list):
|
|
919
|
-
logging.info(f"Loading liberty: {', '.join(files)}")
|
|
1279
|
+
logging.info(f"Loading liberty files: {', '.join(files)}")
|
|
920
1280
|
get_top_db().loadLibertyPrimitives(files)
|
|
921
1281
|
|
|
922
1282
|
|
|
923
1283
|
def load_primitives(name: str):
|
|
1284
|
+
"""Loads a primitive library embedded in najaeda.
|
|
1285
|
+
Currently supported libraries are:
|
|
1286
|
+
- xilinx
|
|
1287
|
+
"""
|
|
924
1288
|
if name == "xilinx":
|
|
925
1289
|
logging.info("Loading xilinx primitives")
|
|
926
1290
|
from najaeda.primitives import xilinx
|
|
@@ -938,7 +1302,11 @@ def get_primitives_library() -> snl.SNLLibrary:
|
|
|
938
1302
|
|
|
939
1303
|
|
|
940
1304
|
def get_model_name(id: tuple[int, int, int]) -> str:
|
|
941
|
-
"""
|
|
1305
|
+
"""
|
|
1306
|
+
:param tuple[int, int, int] id: the id of the model.
|
|
1307
|
+
:return: the name of the model given its id or None if it does not exist.
|
|
1308
|
+
:rtype: str or None
|
|
1309
|
+
"""
|
|
942
1310
|
u = snl.SNLUniverse.get()
|
|
943
1311
|
if u:
|
|
944
1312
|
db = u.getDB(id[0])
|