najaeda 0.1.8__cp312-cp312-macosx_11_0_arm64.whl → 0.1.11__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 +2 -7
- najaeda/docs/source/api.rst +2 -2
- najaeda/docs/source/conf.py +21 -4
- najaeda/docs/source/equipotential.rst +0 -5
- najaeda/docs/source/examples.rst.in +66 -0
- najaeda/docs/source/index.rst +3 -1
- najaeda/docs/source/instance.rst +4 -8
- najaeda/docs/source/introduction.rst +53 -0
- najaeda/docs/source/net.rst +6 -6
- najaeda/docs/source/preprocessor.py +73 -0
- najaeda/docs/source/term.rst +6 -6
- najaeda/docs/source/visitors.rst +13 -0
- najaeda/instance_visitor.py +12 -20
- najaeda/libnaja_snl.dylib +0 -0
- najaeda/libnaja_snl_python.dylib +0 -0
- najaeda/netlist.py +473 -109
- najaeda/pandas_stats.py +32 -0
- najaeda/snl.so +0 -0
- najaeda/stats.py +211 -116
- {najaeda-0.1.8.dist-info → najaeda-0.1.11.dist-info}/METADATA +13 -7
- najaeda-0.1.11.dist-info/RECORD +28 -0
- najaeda/docs/Makefile +0 -20
- najaeda/docs/make.bat +0 -35
- najaeda-0.1.8.dist-info/RECORD +0 -25
- {najaeda-0.1.8.dist-info → najaeda-0.1.11.dist-info}/WHEEL +0 -0
- {najaeda-0.1.8.dist-info → najaeda-0.1.11.dist-info}/licenses/AUTHORS +0 -0
- {najaeda-0.1.8.dist-info → najaeda-0.1.11.dist-info}/licenses/LICENSE +0 -0
najaeda/netlist.py
CHANGED
|
@@ -7,9 +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
|
|
11
|
+
from enum import Enum
|
|
12
|
+
|
|
13
|
+
from najaeda import snl
|
|
13
14
|
|
|
14
15
|
|
|
15
16
|
def consistent_hash(obj):
|
|
@@ -23,15 +24,16 @@ def consistent_hash(obj):
|
|
|
23
24
|
|
|
24
25
|
def hash_value(value):
|
|
25
26
|
if isinstance(value, int):
|
|
26
|
-
return struct.pack(
|
|
27
|
+
return struct.pack("!q", value)
|
|
27
28
|
else:
|
|
28
29
|
raise TypeError(f"Unsupported type: {type(value)}")
|
|
29
30
|
|
|
30
31
|
def hash_object(o):
|
|
31
32
|
if isinstance(o, (list, tuple)):
|
|
32
|
-
return b
|
|
33
|
+
return b"".join(hash_object(i) for i in o)
|
|
33
34
|
else:
|
|
34
35
|
return hash_value(o)
|
|
36
|
+
|
|
35
37
|
serialized_obj = default_serializer(obj)
|
|
36
38
|
obj_bytes = hash_object(serialized_obj)
|
|
37
39
|
return int(hashlib.sha256(obj_bytes).hexdigest(), 16)
|
|
@@ -88,8 +90,7 @@ class Equipotential:
|
|
|
88
90
|
inst_term = term
|
|
89
91
|
path = get_snl_path_from_id_list(inst_term.pathIDs)
|
|
90
92
|
ito = snl.SNLNetComponentOccurrence(
|
|
91
|
-
path.getHeadPath(),
|
|
92
|
-
path.getTailInstance().getInstTerm(snl_term)
|
|
93
|
+
path.getHeadPath(), path.getTailInstance().getInstTerm(snl_term)
|
|
93
94
|
)
|
|
94
95
|
self.equi = snl.SNLEquipotential(ito)
|
|
95
96
|
|
|
@@ -97,9 +98,15 @@ class Equipotential:
|
|
|
97
98
|
return self.equi == value.equi
|
|
98
99
|
|
|
99
100
|
def dump_dot(self, path: str):
|
|
101
|
+
"""Dump the dot file of this equipotential."""
|
|
100
102
|
self.equi.dumpDotFile(path)
|
|
101
103
|
|
|
102
104
|
def get_inst_terms(self):
|
|
105
|
+
"""Iterate over the instance terminals of this equipotential.
|
|
106
|
+
|
|
107
|
+
:return: an iterator over the instance terminals of this equipotential.
|
|
108
|
+
:rtype: Iterator[Term]
|
|
109
|
+
"""
|
|
103
110
|
if self.equi is not None:
|
|
104
111
|
for term in self.equi.getInstTermOccurrences():
|
|
105
112
|
yield Term(
|
|
@@ -108,6 +115,11 @@ class Equipotential:
|
|
|
108
115
|
)
|
|
109
116
|
|
|
110
117
|
def get_top_terms(self):
|
|
118
|
+
"""Iterate over the top terminals of this equipotential.
|
|
119
|
+
|
|
120
|
+
:return: an iterator over the top terminals of this equipotential.
|
|
121
|
+
:rtype: Iterator[Term]
|
|
122
|
+
"""
|
|
111
123
|
if self.equi is not None:
|
|
112
124
|
for term in self.equi.getTerms():
|
|
113
125
|
yield Term([], term)
|
|
@@ -119,7 +131,9 @@ class Equipotential:
|
|
|
119
131
|
if direction != snl.SNLTerm.Direction.Output:
|
|
120
132
|
if term.getInstTerm().getInstance().getModel().isLeaf():
|
|
121
133
|
yield Term(
|
|
122
|
-
snl.SNLPath(
|
|
134
|
+
snl.SNLPath(
|
|
135
|
+
term.getPath(), term.getInstTerm().getInstance()
|
|
136
|
+
),
|
|
123
137
|
term.getInstTerm().getBitTerm(),
|
|
124
138
|
)
|
|
125
139
|
|
|
@@ -130,7 +144,9 @@ class Equipotential:
|
|
|
130
144
|
if direction != snl.SNLTerm.Direction.Input:
|
|
131
145
|
if term.getInstTerm().getInstance().getModel().isLeaf():
|
|
132
146
|
yield Term(
|
|
133
|
-
snl.SNLPath(
|
|
147
|
+
snl.SNLPath(
|
|
148
|
+
term.getPath(), term.getInstTerm().getInstance()
|
|
149
|
+
),
|
|
134
150
|
term.getInstTerm().getBitTerm(),
|
|
135
151
|
)
|
|
136
152
|
|
|
@@ -150,6 +166,13 @@ class Equipotential:
|
|
|
150
166
|
|
|
151
167
|
|
|
152
168
|
class Net:
|
|
169
|
+
class Type(Enum):
|
|
170
|
+
STANDARD = snl.SNLNet.Type.Standard
|
|
171
|
+
ASSIGN0 = snl.SNLNet.Type.Assign0
|
|
172
|
+
ASSIGN1 = snl.SNLNet.Type.Assign1
|
|
173
|
+
SUPPLY0 = snl.SNLNet.Type.Supply0
|
|
174
|
+
SUPPLY1 = snl.SNLNet.Type.Supply1
|
|
175
|
+
|
|
153
176
|
def __init__(self, path, net=None, net_concat=None):
|
|
154
177
|
if net is not None and net_concat is not None:
|
|
155
178
|
raise ValueError(
|
|
@@ -189,59 +212,105 @@ class Net:
|
|
|
189
212
|
return net_str
|
|
190
213
|
|
|
191
214
|
def get_name(self) -> str:
|
|
192
|
-
"""
|
|
215
|
+
"""
|
|
216
|
+
:return: the name of this Net.
|
|
217
|
+
:rtype: str
|
|
218
|
+
"""
|
|
193
219
|
if hasattr(self, "net"):
|
|
194
220
|
return self.net.getName()
|
|
195
221
|
return "{" + ",".join(map(str, self.net_concat)) + "}"
|
|
196
222
|
|
|
197
223
|
def get_msb(self) -> int:
|
|
198
|
-
"""
|
|
224
|
+
"""
|
|
225
|
+
:return: the most significant bit of the net if it is a bus.
|
|
226
|
+
:rtype: int
|
|
227
|
+
"""
|
|
199
228
|
if hasattr(self, "net") and isinstance(self.net, snl.SNLBusNet):
|
|
200
229
|
return self.net.getMSB()
|
|
201
230
|
return None
|
|
202
231
|
|
|
203
232
|
def get_lsb(self) -> int:
|
|
204
|
-
"""
|
|
233
|
+
"""
|
|
234
|
+
:return: the least significant bit of the net if it is a bus.
|
|
235
|
+
:rtype: int
|
|
236
|
+
"""
|
|
205
237
|
if hasattr(self, "net") and isinstance(self.net, snl.SNLBusNet):
|
|
206
238
|
return self.net.getLSB()
|
|
207
239
|
return None
|
|
208
240
|
|
|
209
241
|
def is_bus(self) -> bool:
|
|
210
|
-
"""
|
|
242
|
+
"""
|
|
243
|
+
:return: True if the net is a bus.
|
|
244
|
+
:rtype: bool
|
|
245
|
+
"""
|
|
211
246
|
return hasattr(self, "net") and isinstance(self.net, snl.SNLBusNet)
|
|
212
247
|
|
|
213
248
|
def is_bus_bit(self) -> bool:
|
|
214
|
-
"""
|
|
249
|
+
"""
|
|
250
|
+
:return: True if the net is a bit of a bus.
|
|
251
|
+
:rtype: bool
|
|
252
|
+
"""
|
|
215
253
|
return hasattr(self, "net") and isinstance(self.net, snl.SNLBusNetBit)
|
|
216
254
|
|
|
217
255
|
def is_scalar(self) -> bool:
|
|
218
|
-
"""
|
|
256
|
+
"""
|
|
257
|
+
:return: True if the net is a scalar.
|
|
258
|
+
:rtype: bool
|
|
259
|
+
"""
|
|
219
260
|
return hasattr(self, "net") and isinstance(self.net, snl.SNLScalarNet)
|
|
220
261
|
|
|
221
262
|
def is_bit(self) -> bool:
|
|
222
|
-
"""
|
|
263
|
+
"""
|
|
264
|
+
:return: True if the net is a bit.
|
|
265
|
+
:rtype: bool
|
|
266
|
+
"""
|
|
223
267
|
return self.is_scalar() or self.is_bus_bit()
|
|
224
268
|
|
|
225
269
|
def is_concat(self) -> bool:
|
|
226
|
-
"""
|
|
270
|
+
"""
|
|
271
|
+
:return: True if the net is a concatenation.
|
|
272
|
+
:rtype: bool
|
|
273
|
+
"""
|
|
227
274
|
return hasattr(self, "net_concat")
|
|
228
275
|
|
|
229
276
|
def is_const(self) -> bool:
|
|
230
|
-
"""
|
|
277
|
+
"""
|
|
278
|
+
:return: True if the net is a constant generator.
|
|
279
|
+
:rtype: bool
|
|
280
|
+
"""
|
|
231
281
|
if hasattr(self, "net"):
|
|
232
282
|
return self.net.isConstant()
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
283
|
+
else:
|
|
284
|
+
for net in self.net_concat:
|
|
285
|
+
if not net.isConstant():
|
|
286
|
+
return False
|
|
287
|
+
return True
|
|
288
|
+
|
|
289
|
+
def set_type(self, net_type: Type):
|
|
290
|
+
"""
|
|
291
|
+
:param Type net_type: the type of the net.
|
|
292
|
+
"""
|
|
293
|
+
if hasattr(self, "net"):
|
|
294
|
+
self.net.setType(net_type.value)
|
|
295
|
+
else:
|
|
296
|
+
for net in self.net_concat:
|
|
297
|
+
net.setType(net_type.value)
|
|
237
298
|
|
|
238
299
|
def get_width(self) -> int:
|
|
239
|
-
"""
|
|
300
|
+
"""
|
|
301
|
+
:return: the width of the net.
|
|
302
|
+
:rtype: int
|
|
303
|
+
"""
|
|
240
304
|
if hasattr(self, "net"):
|
|
241
305
|
return self.net.getWidth()
|
|
242
306
|
return sum(1 for _ in self.net_concat)
|
|
243
307
|
|
|
244
308
|
def get_bits(self):
|
|
309
|
+
"""Iterate over the bits of this Net.
|
|
310
|
+
The iterator will return itself if the Net is scalar.
|
|
311
|
+
:return: an iterator over the bits of this Net.
|
|
312
|
+
:rtype: Iterator[Net]
|
|
313
|
+
"""
|
|
245
314
|
if hasattr(self, "net"):
|
|
246
315
|
if isinstance(self.net, snl.SNLBusNet):
|
|
247
316
|
for bit in self.net.getBits():
|
|
@@ -250,9 +319,14 @@ class Net:
|
|
|
250
319
|
yield self
|
|
251
320
|
else:
|
|
252
321
|
for net in self.net_concat:
|
|
253
|
-
yield net
|
|
322
|
+
yield Net(net)
|
|
254
323
|
|
|
255
324
|
def get_bit(self, index: int):
|
|
325
|
+
"""
|
|
326
|
+
:param int index: the index of the bit to get.
|
|
327
|
+
:return: the Net bit at the given index or None if it does not exist.
|
|
328
|
+
:rtype: Net
|
|
329
|
+
"""
|
|
256
330
|
if hasattr(self, "net"):
|
|
257
331
|
if isinstance(self.net, snl.SNLBusNet):
|
|
258
332
|
return Net(self.pathIDs, self.net.getBit(index))
|
|
@@ -263,6 +337,10 @@ class Net:
|
|
|
263
337
|
return None
|
|
264
338
|
|
|
265
339
|
def get_inst_terms(self):
|
|
340
|
+
"""
|
|
341
|
+
:return: an iterator over the instance terminals of the net.
|
|
342
|
+
:rtype: Iterator[Term]
|
|
343
|
+
"""
|
|
266
344
|
if hasattr(self, "net_concat"):
|
|
267
345
|
raise ValueError("Cannot get inst terms from a net_concat")
|
|
268
346
|
for term in self.net.getInstTerms():
|
|
@@ -271,12 +349,20 @@ class Net:
|
|
|
271
349
|
yield Term(path, term.getBitTerm())
|
|
272
350
|
|
|
273
351
|
def get_design_terms(self):
|
|
352
|
+
"""
|
|
353
|
+
:return: an iterator over the design terminals of the net.
|
|
354
|
+
:rtype: Iterator[Term]
|
|
355
|
+
"""
|
|
274
356
|
if hasattr(self, "net_concat"):
|
|
275
357
|
raise ValueError("Cannot get terms from a net_concat")
|
|
276
358
|
for term in self.net.getBitTerms():
|
|
277
359
|
yield Term(self.pathIDs, term)
|
|
278
360
|
|
|
279
361
|
def get_terms(self):
|
|
362
|
+
"""
|
|
363
|
+
:return: an iterator over the terminals of the net.
|
|
364
|
+
:rtype: Iterator[Term]
|
|
365
|
+
"""
|
|
280
366
|
for term in itertools.chain(self.get_design_terms(), self.get_inst_terms()):
|
|
281
367
|
yield term
|
|
282
368
|
|
|
@@ -352,7 +438,9 @@ class Term:
|
|
|
352
438
|
if path.size() == 0:
|
|
353
439
|
return get_snl_term_for_ids(self.pathIDs, self.termIDs).getName()
|
|
354
440
|
else:
|
|
355
|
-
return
|
|
441
|
+
return (
|
|
442
|
+
f"{path}/{get_snl_term_for_ids(self.pathIDs, self.termIDs).getName()}"
|
|
443
|
+
)
|
|
356
444
|
|
|
357
445
|
def __repr__(self) -> str:
|
|
358
446
|
path = get_snl_path_from_id_list(self.pathIDs)
|
|
@@ -365,43 +453,76 @@ class Term:
|
|
|
365
453
|
snl.SNLUniquifier(path)
|
|
366
454
|
|
|
367
455
|
def is_bus(self) -> bool:
|
|
368
|
-
"""
|
|
369
|
-
return
|
|
456
|
+
"""
|
|
457
|
+
:return: True if the term is a bus.
|
|
458
|
+
:rtype: bool
|
|
459
|
+
"""
|
|
460
|
+
return isinstance(
|
|
461
|
+
get_snl_term_for_ids(self.pathIDs, self.termIDs), snl.SNLBusTerm
|
|
462
|
+
)
|
|
370
463
|
|
|
371
464
|
def is_bus_bit(self) -> bool:
|
|
372
|
-
"""
|
|
373
|
-
return
|
|
465
|
+
"""
|
|
466
|
+
:return: True if the term is a bit of a bus.
|
|
467
|
+
:rtype: bool
|
|
468
|
+
"""
|
|
469
|
+
return isinstance(
|
|
470
|
+
get_snl_term_for_ids(self.pathIDs, self.termIDs), snl.SNLBusTermBit
|
|
471
|
+
)
|
|
374
472
|
|
|
375
473
|
def is_scalar(self) -> bool:
|
|
376
|
-
"""
|
|
377
|
-
return
|
|
474
|
+
"""
|
|
475
|
+
:return: True if the term is a scalar.
|
|
476
|
+
:rtype: bool
|
|
477
|
+
"""
|
|
478
|
+
return isinstance(
|
|
479
|
+
get_snl_term_for_ids(self.pathIDs, self.termIDs), snl.SNLScalarTerm
|
|
480
|
+
)
|
|
378
481
|
|
|
379
482
|
def is_bit(self) -> bool:
|
|
380
|
-
"""
|
|
483
|
+
"""
|
|
484
|
+
:return: True if the term is a bit.
|
|
485
|
+
:rtype: bool
|
|
486
|
+
"""
|
|
381
487
|
return self.is_scalar() or self.is_bus_bit()
|
|
382
488
|
|
|
383
489
|
def get_msb(self) -> int:
|
|
384
|
-
"""
|
|
490
|
+
"""
|
|
491
|
+
:return: the most significant bit of the term if it is a bus.
|
|
492
|
+
:rtype: int or None
|
|
493
|
+
"""
|
|
385
494
|
if isinstance(get_snl_term_for_ids(self.pathIDs, self.termIDs), snl.SNLBusTerm):
|
|
386
495
|
return get_snl_term_for_ids(self.pathIDs, self.termIDs).getMSB()
|
|
387
496
|
return None
|
|
388
497
|
|
|
389
498
|
def get_lsb(self) -> int:
|
|
390
|
-
"""
|
|
499
|
+
"""
|
|
500
|
+
:return: the least significant bit of the term if it is a bus.
|
|
501
|
+
:rtype: int or None
|
|
502
|
+
"""
|
|
391
503
|
if isinstance(get_snl_term_for_ids(self.pathIDs, self.termIDs), snl.SNLBusTerm):
|
|
392
504
|
return get_snl_term_for_ids(self.pathIDs, self.termIDs).getLSB()
|
|
393
505
|
return None
|
|
394
506
|
|
|
395
507
|
def get_width(self) -> int:
|
|
396
|
-
"""
|
|
508
|
+
"""
|
|
509
|
+
:return: the width of the term. 1 if scalar.
|
|
510
|
+
:rtype: int
|
|
511
|
+
"""
|
|
397
512
|
return get_snl_term_for_ids(self.pathIDs, self.termIDs).getWidth()
|
|
398
513
|
|
|
399
514
|
def get_name(self) -> str:
|
|
400
|
-
"""
|
|
515
|
+
"""
|
|
516
|
+
:return: the name of the term.
|
|
517
|
+
:rtype: str
|
|
518
|
+
"""
|
|
401
519
|
return get_snl_term_for_ids(self.pathIDs, self.termIDs).getName()
|
|
402
520
|
|
|
403
521
|
def get_direction(self) -> snl.SNLTerm.Direction:
|
|
404
|
-
"""
|
|
522
|
+
"""
|
|
523
|
+
:return: the direction of the term.
|
|
524
|
+
:rtype: snl.SNLTerm.Direction
|
|
525
|
+
"""
|
|
405
526
|
snlterm = get_snl_term_for_ids(self.pathIDs, self.termIDs)
|
|
406
527
|
if snlterm.getDirection() == snl.SNLTerm.Direction.Input:
|
|
407
528
|
return Term.INPUT
|
|
@@ -454,17 +575,25 @@ class Term:
|
|
|
454
575
|
if all(element is not None for element in snl_nets):
|
|
455
576
|
return Net(path, net_concat=snl_nets)
|
|
456
577
|
else:
|
|
457
|
-
snl_net = snl_term_net_accessor(
|
|
578
|
+
snl_net = snl_term_net_accessor(
|
|
579
|
+
get_snl_term_for_ids(self.pathIDs, self.termIDs)
|
|
580
|
+
)
|
|
458
581
|
if snl_net is not None:
|
|
459
582
|
return Net(path, snl_net)
|
|
460
583
|
return None
|
|
461
584
|
|
|
462
585
|
def get_lower_net(self) -> Net:
|
|
463
|
-
"""
|
|
586
|
+
"""
|
|
587
|
+
:return: the lower net of the term.
|
|
588
|
+
:rtype: Net
|
|
589
|
+
"""
|
|
464
590
|
return self.__get_net(self.pathIDs, self.__get_snl_lower_bitnet)
|
|
465
591
|
|
|
466
592
|
def get_net(self) -> Net:
|
|
467
|
-
"""
|
|
593
|
+
"""
|
|
594
|
+
:return: the net of the term.
|
|
595
|
+
:rtype: Net
|
|
596
|
+
"""
|
|
468
597
|
head_path = self.pathIDs.copy()
|
|
469
598
|
if len(head_path) == 0:
|
|
470
599
|
return None
|
|
@@ -473,7 +602,10 @@ class Term:
|
|
|
473
602
|
return self.__get_net(head_path, self.__get_snl_bitnet)
|
|
474
603
|
|
|
475
604
|
def get_instance(self):
|
|
476
|
-
"""
|
|
605
|
+
"""
|
|
606
|
+
:return: the instance of this Term.
|
|
607
|
+
:rtype: Instance
|
|
608
|
+
"""
|
|
477
609
|
return Instance(self.pathIDs)
|
|
478
610
|
|
|
479
611
|
def get_flat_fanout(self):
|
|
@@ -483,16 +615,27 @@ class Term:
|
|
|
483
615
|
return Equipotential(self)
|
|
484
616
|
|
|
485
617
|
def is_input(self) -> bool:
|
|
486
|
-
"""
|
|
618
|
+
"""
|
|
619
|
+
:return: True if the term is an input.
|
|
620
|
+
:rtype: bool
|
|
621
|
+
"""
|
|
487
622
|
snlterm = get_snl_term_for_ids(self.pathIDs, self.termIDs)
|
|
488
623
|
return snlterm.getDirection() == snl.SNLTerm.Direction.Input
|
|
489
624
|
|
|
490
625
|
def is_output(self) -> bool:
|
|
491
|
-
"""
|
|
626
|
+
"""
|
|
627
|
+
:return: True if the term is an output.
|
|
628
|
+
:rtype: bool
|
|
629
|
+
"""
|
|
492
630
|
snlterm = get_snl_term_for_ids(self.pathIDs, self.termIDs)
|
|
493
631
|
return snlterm.getDirection() == snl.SNLTerm.Direction.Output
|
|
494
632
|
|
|
495
633
|
def get_bits(self):
|
|
634
|
+
"""
|
|
635
|
+
:return: an iterator over the bits of the term.
|
|
636
|
+
If the term is scalar, it will return an iterator over itself.
|
|
637
|
+
:rtype: Iterator[Term]
|
|
638
|
+
"""
|
|
496
639
|
if isinstance(get_snl_term_for_ids(self.pathIDs, self.termIDs), snl.SNLBusTerm):
|
|
497
640
|
for bit in get_snl_term_for_ids(self.pathIDs, self.termIDs).getBits():
|
|
498
641
|
yield Term(self.pathIDs, bit)
|
|
@@ -500,12 +643,20 @@ class Term:
|
|
|
500
643
|
yield self
|
|
501
644
|
|
|
502
645
|
def get_bit(self, index: int):
|
|
646
|
+
"""
|
|
647
|
+
:param int index: the index of the bit to get.
|
|
648
|
+
:return: the Term bit at the given index or None if it does not exist.
|
|
649
|
+
:rtype: Term or None
|
|
650
|
+
"""
|
|
503
651
|
if isinstance(get_snl_term_for_ids(self.pathIDs, self.termIDs), snl.SNLBusTerm):
|
|
504
|
-
return Term(
|
|
505
|
-
|
|
652
|
+
return Term(
|
|
653
|
+
self.pathIDs,
|
|
654
|
+
get_snl_term_for_ids(self.pathIDs, self.termIDs).getBit(index),
|
|
655
|
+
)
|
|
506
656
|
return None
|
|
507
657
|
|
|
508
658
|
def disconnect(self):
|
|
659
|
+
"""Disconnect this term from its net."""
|
|
509
660
|
path = get_snl_path_from_id_list(self.pathIDs)
|
|
510
661
|
self.__make_unique()
|
|
511
662
|
inst = path.getTailInstance()
|
|
@@ -514,21 +665,27 @@ class Term:
|
|
|
514
665
|
iterm.setNet(None)
|
|
515
666
|
|
|
516
667
|
def connect(self, net: Net):
|
|
668
|
+
"""Connect this term to the given Net.
|
|
669
|
+
|
|
670
|
+
:param Net net: the Net to connect to.
|
|
671
|
+
"""
|
|
517
672
|
if self.get_width() != net.get_width():
|
|
518
673
|
raise ValueError("Width mismatch")
|
|
519
674
|
if self.get_instance().is_top():
|
|
520
|
-
for bterm, bnet in zip(
|
|
521
|
-
|
|
522
|
-
|
|
675
|
+
for bterm, bnet in zip(
|
|
676
|
+
get_snl_term_for_ids(self.pathIDs, self.termIDs).getBits(),
|
|
677
|
+
net.net.getBits(),
|
|
678
|
+
):
|
|
523
679
|
logging.debug(f"Connecting {bterm} to {bnet}")
|
|
524
680
|
bterm.setNet(bnet)
|
|
525
681
|
else:
|
|
526
682
|
self.__make_unique()
|
|
527
683
|
path = get_snl_path_from_id_list(self.pathIDs)
|
|
528
684
|
inst = path.getTailInstance()
|
|
529
|
-
for bterm, bnet in zip(
|
|
530
|
-
|
|
531
|
-
|
|
685
|
+
for bterm, bnet in zip(
|
|
686
|
+
get_snl_term_for_ids(self.pathIDs, self.termIDs).getBits(),
|
|
687
|
+
net.net.getBits(),
|
|
688
|
+
):
|
|
532
689
|
iterm = inst.getInstTerm(bterm)
|
|
533
690
|
iterm.setNet(bnet)
|
|
534
691
|
|
|
@@ -547,19 +704,36 @@ def get_instance_by_path(names: list):
|
|
|
547
704
|
return Instance(path)
|
|
548
705
|
|
|
549
706
|
|
|
550
|
-
def refresh_path(path: snl.SNLPath):
|
|
551
|
-
pathlist = path.getPathIDs()
|
|
552
|
-
assert len(pathlist) > 0
|
|
553
|
-
path = snl.SNLPath()
|
|
554
|
-
instance = None
|
|
555
|
-
top = snl.SNLUniverse.get().getTopDesign()
|
|
556
|
-
design = top
|
|
557
|
-
for id in pathlist:
|
|
558
|
-
path = snl.SNLPath(path, design.getInstanceByID(id))
|
|
559
|
-
instance = design.getInstanceByID(id)
|
|
560
|
-
assert instance is not None
|
|
561
|
-
design = instance.getModel()
|
|
562
|
-
return path
|
|
707
|
+
# def refresh_path(path: snl.SNLPath):
|
|
708
|
+
# pathlist = path.getPathIDs()
|
|
709
|
+
# assert len(pathlist) > 0
|
|
710
|
+
# path = snl.SNLPath()
|
|
711
|
+
# instance = None
|
|
712
|
+
# top = snl.SNLUniverse.get().getTopDesign()
|
|
713
|
+
# design = top
|
|
714
|
+
# for id in pathlist:
|
|
715
|
+
# path = snl.SNLPath(path, design.getInstanceByID(id))
|
|
716
|
+
# instance = design.getInstanceByID(id)
|
|
717
|
+
# assert instance is not None
|
|
718
|
+
# design = instance.getModel()
|
|
719
|
+
# return path
|
|
720
|
+
|
|
721
|
+
|
|
722
|
+
class Attribute:
|
|
723
|
+
def __init__(self, snlAttribute):
|
|
724
|
+
self.snlAttribute = snlAttribute
|
|
725
|
+
|
|
726
|
+
def __str__(self):
|
|
727
|
+
return str(self.snlAttribute)
|
|
728
|
+
|
|
729
|
+
def get_name(self):
|
|
730
|
+
return self.snlAttribute.getName()
|
|
731
|
+
|
|
732
|
+
def has_value(self):
|
|
733
|
+
return self.snlAttribute.hasValue()
|
|
734
|
+
|
|
735
|
+
def get_value(self):
|
|
736
|
+
return self.snlAttribute.getValue()
|
|
563
737
|
|
|
564
738
|
|
|
565
739
|
class Instance:
|
|
@@ -598,6 +772,11 @@ class Instance:
|
|
|
598
772
|
return consistent_hash(self.pathIDs)
|
|
599
773
|
|
|
600
774
|
def get_leaf_children(self):
|
|
775
|
+
"""Iterate over the leaf children of this Instance.
|
|
776
|
+
Equivalent to the underlying leaves of the instanciation tree.
|
|
777
|
+
:return: an iterator over the leaf children Instance of this Instance.
|
|
778
|
+
:rtype: Iterator[Instance]
|
|
779
|
+
"""
|
|
601
780
|
initial_path = get_snl_path_from_id_list(self.pathIDs)
|
|
602
781
|
for inst in self.__get_snl_model().getInstances():
|
|
603
782
|
if inst.getModel().isLeaf():
|
|
@@ -615,47 +794,82 @@ class Instance:
|
|
|
615
794
|
stack.append([inst_child, path_child])
|
|
616
795
|
|
|
617
796
|
def is_top(self) -> bool:
|
|
618
|
-
"""
|
|
797
|
+
"""
|
|
798
|
+
:return: True if this is the top design.
|
|
799
|
+
:rtype: bool
|
|
800
|
+
"""
|
|
619
801
|
return len(self.pathIDs) == 0
|
|
620
802
|
|
|
621
803
|
def is_assign(self) -> bool:
|
|
804
|
+
"""Example: (assign a=b) will create an instance of assign connecting
|
|
805
|
+
the wire a to the output of the assign and b to the input.
|
|
806
|
+
|
|
807
|
+
:return: True if this is an assign. Assigns are represented with
|
|
808
|
+
anonymous Assign instances.
|
|
809
|
+
:rtype: bool
|
|
810
|
+
"""
|
|
622
811
|
return self.__get_snl_model().isAssign()
|
|
623
812
|
|
|
624
813
|
def is_blackbox(self) -> bool:
|
|
625
|
-
"""
|
|
814
|
+
"""
|
|
815
|
+
:return: True if this is a blackbox.
|
|
816
|
+
:rtype: bool
|
|
817
|
+
"""
|
|
626
818
|
return self.__get_snl_model().isBlackBox()
|
|
627
819
|
|
|
628
820
|
def is_leaf(self) -> bool:
|
|
629
|
-
"""
|
|
821
|
+
"""
|
|
822
|
+
:return: True if this is a leaf.
|
|
823
|
+
:rtype: bool
|
|
824
|
+
"""
|
|
630
825
|
return self.__get_snl_model().isLeaf()
|
|
631
826
|
|
|
632
827
|
def is_const0(self) -> bool:
|
|
633
|
-
"""
|
|
828
|
+
"""
|
|
829
|
+
:return: True if this is a constant 0 generator.
|
|
830
|
+
:rtype: bool
|
|
831
|
+
"""
|
|
634
832
|
return self.__get_snl_model().isConst0()
|
|
635
833
|
|
|
636
834
|
def is_const1(self) -> bool:
|
|
637
|
-
"""
|
|
835
|
+
"""
|
|
836
|
+
:return: True if this is a constant 1 generator.
|
|
837
|
+
:rtype: bool
|
|
838
|
+
"""
|
|
638
839
|
return self.__get_snl_model().isConst1()
|
|
639
840
|
|
|
640
841
|
def is_const(self) -> bool:
|
|
641
|
-
"""
|
|
842
|
+
"""
|
|
843
|
+
:return: True if this is a constant generator.
|
|
844
|
+
:rtype: bool
|
|
845
|
+
"""
|
|
642
846
|
return self.__get_snl_model().isConst()
|
|
643
847
|
|
|
644
848
|
def is_buf(self) -> bool:
|
|
645
|
-
"""
|
|
849
|
+
"""
|
|
850
|
+
:return: True if this is a buffer.
|
|
851
|
+
:rtype: bool
|
|
852
|
+
"""
|
|
646
853
|
return self.__get_snl_model().isBuf()
|
|
647
854
|
|
|
648
855
|
def is_inv(self) -> bool:
|
|
649
|
-
"""
|
|
856
|
+
"""
|
|
857
|
+
:return: True if this is an inverter.
|
|
858
|
+
:rtype: bool
|
|
859
|
+
"""
|
|
650
860
|
return self.__get_snl_model().isInv()
|
|
651
861
|
|
|
652
862
|
def __get_snl_model(self):
|
|
653
|
-
"""Return the model of the instance."""
|
|
654
863
|
if self.is_top():
|
|
655
864
|
return snl.SNLUniverse.get().getTopDesign()
|
|
656
865
|
instance = get_snl_instance_from_id_list(self.pathIDs)
|
|
657
866
|
return instance.getModel()
|
|
658
867
|
|
|
868
|
+
def __get_leaf_snl_object(self):
|
|
869
|
+
if self.is_top():
|
|
870
|
+
return snl.SNLUniverse.get().getTopDesign()
|
|
871
|
+
return get_snl_instance_from_id_list(self.pathIDs)
|
|
872
|
+
|
|
659
873
|
def __find_snl_model(self, name: str) -> snl.SNLDesign:
|
|
660
874
|
u = snl.SNLUniverse.get()
|
|
661
875
|
for db in u.getUserDBs():
|
|
@@ -673,7 +887,11 @@ class Instance:
|
|
|
673
887
|
self.__get_snl_model().dumpContextDotFile(path)
|
|
674
888
|
|
|
675
889
|
def get_child_instance(self, name: str):
|
|
676
|
-
"""
|
|
890
|
+
"""
|
|
891
|
+
:param str name: the name of the child Instance to get.
|
|
892
|
+
:return: the child Instance with the given name or None if it does not exist.
|
|
893
|
+
:rtype: Instance or None
|
|
894
|
+
"""
|
|
677
895
|
childInst = self.__get_snl_model().getInstance(name)
|
|
678
896
|
if childInst is None:
|
|
679
897
|
return None
|
|
@@ -682,12 +900,22 @@ class Instance:
|
|
|
682
900
|
return Instance(path)
|
|
683
901
|
|
|
684
902
|
def get_child_instances(self):
|
|
903
|
+
"""Iterate over the child instances of this instance.
|
|
904
|
+
Equivalent to go down one level in hierarchy.
|
|
905
|
+
|
|
906
|
+
:return: an iterator over the child instances of this instance.
|
|
907
|
+
:rtype: Iterator[Instance]
|
|
908
|
+
"""
|
|
685
909
|
for inst in self.__get_snl_model().getInstances():
|
|
686
910
|
path = self.pathIDs.copy()
|
|
687
911
|
path.append(inst.getID())
|
|
688
912
|
yield Instance(path)
|
|
689
913
|
|
|
690
914
|
def get_number_of_child_instances(self) -> int:
|
|
915
|
+
"""
|
|
916
|
+
:return: the number of child instances of this instance.
|
|
917
|
+
:rtype: int
|
|
918
|
+
"""
|
|
691
919
|
return sum(1 for _ in self.__get_snl_model().getInstances())
|
|
692
920
|
|
|
693
921
|
# def get_flat_primitive_instances(self):
|
|
@@ -707,15 +935,19 @@ class Instance:
|
|
|
707
935
|
# stack.append([inst_child, path_child])
|
|
708
936
|
|
|
709
937
|
def get_nets(self):
|
|
710
|
-
"""
|
|
711
|
-
|
|
938
|
+
"""Iterate over all scalar nets and bus nets.
|
|
939
|
+
|
|
940
|
+
:return: an iterator over the nets of this Instance.
|
|
941
|
+
:rtype: Iterator[Net]
|
|
712
942
|
"""
|
|
713
943
|
for net in self.__get_snl_model().getNets():
|
|
714
944
|
yield Net(self.pathIDs, net)
|
|
715
945
|
|
|
716
946
|
def get_flat_nets(self):
|
|
717
|
-
"""
|
|
718
|
-
|
|
947
|
+
"""Iterate over all scalar nets and bus net bits.
|
|
948
|
+
|
|
949
|
+
:return: an iterator over the flat nets of this Instance.
|
|
950
|
+
:rtype: Iterator[Net]
|
|
719
951
|
"""
|
|
720
952
|
for net in self.__get_snl_model().getNets():
|
|
721
953
|
if isinstance(net, snl.SNLBusNet):
|
|
@@ -725,48 +957,69 @@ class Instance:
|
|
|
725
957
|
yield Net(self.pathIDs, net)
|
|
726
958
|
|
|
727
959
|
def get_net(self, name: str) -> Net:
|
|
728
|
-
"""
|
|
960
|
+
"""
|
|
961
|
+
:param str name: the name of the Net to get.
|
|
962
|
+
:return: the Net with the given name or None if it does not exist.
|
|
963
|
+
:rtype: Net or None
|
|
964
|
+
"""
|
|
729
965
|
net = self.__get_snl_model().getNet(name)
|
|
730
966
|
if net is not None:
|
|
731
967
|
return Net(self.pathIDs, net)
|
|
732
968
|
return None
|
|
733
969
|
|
|
734
970
|
def is_primitive(self) -> bool:
|
|
735
|
-
"""
|
|
971
|
+
"""
|
|
972
|
+
:return: True if this is a primitive.
|
|
973
|
+
:rtype: bool
|
|
974
|
+
"""
|
|
736
975
|
return self.__get_snl_model().isPrimitive()
|
|
737
976
|
|
|
738
977
|
def get_terms(self):
|
|
739
|
-
"""
|
|
740
|
-
|
|
978
|
+
"""Iterate over all scalar terms and bus terms of this Instance.
|
|
979
|
+
|
|
980
|
+
:return: the terms of this Instance.
|
|
981
|
+
:rtype: Iterator[Term]
|
|
741
982
|
"""
|
|
742
983
|
for term in self.__get_snl_model().getTerms():
|
|
743
984
|
yield Term(self.pathIDs, term)
|
|
744
985
|
|
|
745
986
|
def get_flat_terms(self):
|
|
746
|
-
"""
|
|
747
|
-
|
|
987
|
+
"""Iterate over all scalar terms and bus term bits.
|
|
988
|
+
|
|
989
|
+
:return: the flat terms of this Instance.
|
|
990
|
+
:rtype: Iterator[Term]
|
|
748
991
|
"""
|
|
749
992
|
for term in self.__get_snl_model().getBitTerms():
|
|
750
993
|
yield Term(self.pathIDs, term)
|
|
751
994
|
|
|
752
995
|
def get_term(self, name: str) -> Term:
|
|
753
|
-
"""
|
|
996
|
+
"""
|
|
997
|
+
:param str name: the name of the Term to get.
|
|
998
|
+
:return: the Term with the given name.
|
|
999
|
+
:rtype: Term or None
|
|
1000
|
+
"""
|
|
754
1001
|
term = self.__get_snl_model().getTerm(name)
|
|
755
1002
|
if term is not None:
|
|
756
1003
|
return Term(self.pathIDs, self.__get_snl_model().getTerm(name))
|
|
757
1004
|
return None
|
|
758
1005
|
|
|
759
1006
|
def get_input_terms(self):
|
|
760
|
-
"""
|
|
761
|
-
|
|
1007
|
+
"""Iterate over all scalar input terms and bus input terms
|
|
1008
|
+
of this Instance.
|
|
1009
|
+
|
|
1010
|
+
:return: the input terms of this Instance.
|
|
1011
|
+
:rtype: Iterator[Term]
|
|
762
1012
|
"""
|
|
763
1013
|
for term in self.__get_snl_model().getTerms():
|
|
764
1014
|
if term.getDirection() != snl.SNLTerm.Direction.Output:
|
|
765
1015
|
yield Term(self.pathIDs, term)
|
|
766
1016
|
|
|
767
1017
|
def get_flat_input_terms(self):
|
|
768
|
-
"""
|
|
769
|
-
|
|
1018
|
+
"""Iterate over all scalar input terms and bus input term bits
|
|
1019
|
+
of this Instance.
|
|
1020
|
+
|
|
1021
|
+
:return: the flat input terms of this Instance.
|
|
1022
|
+
:rtype: Iterator[Term]
|
|
770
1023
|
"""
|
|
771
1024
|
for term in self.__get_snl_model().getTerms():
|
|
772
1025
|
if term.getDirection() != snl.SNLTerm.Direction.Output:
|
|
@@ -777,8 +1030,11 @@ class Instance:
|
|
|
777
1030
|
yield Term(self.pathIDs, term)
|
|
778
1031
|
|
|
779
1032
|
def get_output_terms(self):
|
|
780
|
-
"""
|
|
781
|
-
|
|
1033
|
+
"""Iterate over all scalar output terms and bus output terms
|
|
1034
|
+
of this Instance.
|
|
1035
|
+
|
|
1036
|
+
:return: the output terms of this Instance.
|
|
1037
|
+
:rtype: Iterator[Term]
|
|
782
1038
|
"""
|
|
783
1039
|
for term in self.__get_snl_model().getTerms():
|
|
784
1040
|
if term.getDirection() != snl.SNLTerm.Direction.Input:
|
|
@@ -796,6 +1052,11 @@ class Instance:
|
|
|
796
1052
|
else:
|
|
797
1053
|
yield Term(self.pathIDs, term)
|
|
798
1054
|
|
|
1055
|
+
def get_attributes(self):
|
|
1056
|
+
leaf_object = self.__get_leaf_snl_object()
|
|
1057
|
+
for attribute in leaf_object.getAttributes():
|
|
1058
|
+
yield Attribute(attribute)
|
|
1059
|
+
|
|
799
1060
|
def delete_instance(self, name: str):
|
|
800
1061
|
"""Delete the child instance with the given name."""
|
|
801
1062
|
if name == "":
|
|
@@ -810,7 +1071,10 @@ class Instance:
|
|
|
810
1071
|
self.__get_snl_model().getInstance(name).destroy()
|
|
811
1072
|
|
|
812
1073
|
def delete_instance_by_id(self, id: str):
|
|
813
|
-
"""Delete the child instance with the given ID.
|
|
1074
|
+
"""Delete the child instance with the given ID.
|
|
1075
|
+
|
|
1076
|
+
:param str id: the ID of the Instance to delete.
|
|
1077
|
+
"""
|
|
814
1078
|
init_path = get_snl_path_from_id_list(self.pathIDs)
|
|
815
1079
|
path = snl.SNLPath(init_path, self.__get_snl_model().getInstanceByID(id))
|
|
816
1080
|
snl.SNLUniquifier(path)
|
|
@@ -818,7 +1082,10 @@ class Instance:
|
|
|
818
1082
|
self.__get_snl_model().getInstanceByID(id).destroy()
|
|
819
1083
|
|
|
820
1084
|
def get_design(self):
|
|
821
|
-
"""
|
|
1085
|
+
"""
|
|
1086
|
+
:return: the Instance containing this instance.
|
|
1087
|
+
:rtype: Instance
|
|
1088
|
+
"""
|
|
822
1089
|
path = self.pathIDs.copy()
|
|
823
1090
|
if len(self.pathIDs) == 1:
|
|
824
1091
|
return get_top()
|
|
@@ -832,7 +1099,10 @@ class Instance:
|
|
|
832
1099
|
self.get_design().delete_instance_by_id(path.getTailInstance().getID())
|
|
833
1100
|
|
|
834
1101
|
def get_name(self) -> str:
|
|
835
|
-
"""
|
|
1102
|
+
"""
|
|
1103
|
+
:return: the name of the instance or name of the top is this is the top.
|
|
1104
|
+
:rtype: str
|
|
1105
|
+
"""
|
|
836
1106
|
path = get_snl_path_from_id_list(self.pathIDs)
|
|
837
1107
|
if self.is_top():
|
|
838
1108
|
return self.get_model_name()
|
|
@@ -840,16 +1110,29 @@ class Instance:
|
|
|
840
1110
|
return path.getTailInstance().getName()
|
|
841
1111
|
|
|
842
1112
|
def get_model_name(self) -> str:
|
|
843
|
-
"""
|
|
1113
|
+
"""
|
|
1114
|
+
:return: the name of the model of the instance
|
|
1115
|
+
or name of the top is this is the top.
|
|
1116
|
+
:rtype: str
|
|
1117
|
+
"""
|
|
844
1118
|
return self.__get_snl_model().getName()
|
|
845
1119
|
|
|
846
1120
|
def get_model_id(self) -> tuple[int, int, int]:
|
|
847
|
-
"""
|
|
1121
|
+
"""
|
|
1122
|
+
:return: the ID of the model of this Instance
|
|
1123
|
+
or ID of the top if this is the top.
|
|
1124
|
+
"""
|
|
848
1125
|
model = self.__get_snl_model()
|
|
849
1126
|
return model.getDB().getID(), model.getLibrary().getID(), model.getID()
|
|
850
1127
|
|
|
851
1128
|
def create_child_instance(self, model: str, name: str):
|
|
852
|
-
"""Create a child instance with the given model and name.
|
|
1129
|
+
"""Create a child instance with the given model and name.
|
|
1130
|
+
|
|
1131
|
+
:param str model: the name of the model of the instance to create.
|
|
1132
|
+
:param str name: the name of the instance to create.
|
|
1133
|
+
:return: the created Instance.
|
|
1134
|
+
:rtype: Instance
|
|
1135
|
+
"""
|
|
853
1136
|
path = get_snl_path_from_id_list(self.pathIDs)
|
|
854
1137
|
if path.size() > 0:
|
|
855
1138
|
snl.SNLUniquifier(path)
|
|
@@ -865,7 +1148,12 @@ class Instance:
|
|
|
865
1148
|
return Instance(path)
|
|
866
1149
|
|
|
867
1150
|
def create_term(self, name: str, direction: snl.SNLTerm.Direction) -> Term:
|
|
868
|
-
"""Create a Term
|
|
1151
|
+
"""Create a Term in this Instance with the given name and direction.
|
|
1152
|
+
|
|
1153
|
+
:param str name: the name of the Term to create.
|
|
1154
|
+
:param snl.SNLTerm.Direction direction: the direction of the Term to create.
|
|
1155
|
+
:return: the created Term.
|
|
1156
|
+
"""
|
|
869
1157
|
path = get_snl_path_from_id_list(self.pathIDs)
|
|
870
1158
|
if path.size() > 0:
|
|
871
1159
|
snl.SNLUniquifier(path)
|
|
@@ -875,19 +1163,40 @@ class Instance:
|
|
|
875
1163
|
return Term(path, newSNLTerm)
|
|
876
1164
|
|
|
877
1165
|
def create_output_term(self, name: str) -> Term:
|
|
878
|
-
"""Create an output Term in this Instance with the given name.
|
|
1166
|
+
"""Create an output Term in this Instance with the given name.
|
|
1167
|
+
|
|
1168
|
+
:param str name: the name of the Term to create.
|
|
1169
|
+
:return: the created Term.
|
|
1170
|
+
:rtype: Term
|
|
1171
|
+
"""
|
|
879
1172
|
return self.create_term(name, snl.SNLTerm.Direction.Output)
|
|
880
1173
|
|
|
881
1174
|
def create_input_term(self, name: str) -> Term:
|
|
882
|
-
"""Create an input Term in this Instance with the given name.
|
|
1175
|
+
"""Create an input Term in this Instance with the given name.
|
|
1176
|
+
|
|
1177
|
+
:param str name: the name of the Term to create.
|
|
1178
|
+
:return: the created Term.
|
|
1179
|
+
:rtype: Term
|
|
1180
|
+
"""
|
|
883
1181
|
return self.create_term(name, snl.SNLTerm.Direction.Input)
|
|
884
1182
|
|
|
885
1183
|
def create_inout_term(self, name: str) -> Term:
|
|
886
|
-
"""Create an inout Term in this Instance with the given name.
|
|
1184
|
+
"""Create an inout Term in this Instance with the given name.
|
|
1185
|
+
|
|
1186
|
+
:param str name: the name of the Term to create.
|
|
1187
|
+
:return: the created Term.
|
|
1188
|
+
:rtype: Term
|
|
1189
|
+
"""
|
|
887
1190
|
return self.create_term(name, snl.SNLTerm.Direction.InOut)
|
|
888
1191
|
|
|
889
1192
|
def create_bus_term(self, name: str, msb: int, lsb: int, direction) -> Term:
|
|
890
|
-
"""Create a bus Term in this Instance with the given name, msb, lsb and direction.
|
|
1193
|
+
"""Create a bus Term in this Instance with the given name, msb, lsb and direction.
|
|
1194
|
+
:param str name: the name of the Term to create.
|
|
1195
|
+
:param int msb: the most significant bit of the Term to create.
|
|
1196
|
+
:param int lsb: the least significant bit of the Term to create.
|
|
1197
|
+
:param snl.SNLTerm.Direction direction: the direction of the Term to create.
|
|
1198
|
+
:return: the created Term.
|
|
1199
|
+
"""
|
|
891
1200
|
path = get_snl_path_from_id_list(self.pathIDs)
|
|
892
1201
|
if path.size() > 0:
|
|
893
1202
|
snl.SNLUniquifier(path)
|
|
@@ -897,19 +1206,45 @@ class Instance:
|
|
|
897
1206
|
return Term(path, newSNLTerm)
|
|
898
1207
|
|
|
899
1208
|
def create_inout_bus_term(self, name: str, msb: int, lsb: int) -> Term:
|
|
900
|
-
"""Create an inout bus Term in this Instance with the given name, msb and lsb.
|
|
1209
|
+
"""Create an inout bus Term in this Instance with the given name, msb and lsb.
|
|
1210
|
+
|
|
1211
|
+
:param str name: the name of the Term to create.
|
|
1212
|
+
:param int msb: the most significant bit of the Term to create.
|
|
1213
|
+
:param int lsb: the least significant bit of the Term to create.
|
|
1214
|
+
:return: the created Term.
|
|
1215
|
+
:rtype: Term
|
|
1216
|
+
"""
|
|
901
1217
|
return self.create_bus_term(name, msb, lsb, snl.SNLTerm.Direction.InOut)
|
|
902
1218
|
|
|
903
1219
|
def create_output_bus_term(self, name: str, msb: int, lsb: int) -> Term:
|
|
904
|
-
"""Create an output bus Term in this Instance with the given name, msb and lsb.
|
|
1220
|
+
"""Create an output bus Term in this Instance with the given name, msb and lsb.
|
|
1221
|
+
|
|
1222
|
+
:param str name: the name of the Term to create.
|
|
1223
|
+
:param int msb: the most significant bit of the Term to create.
|
|
1224
|
+
:param int lsb: the least significant bit of the Term to create.
|
|
1225
|
+
:return: the created Term.
|
|
1226
|
+
:rtype: Term
|
|
1227
|
+
"""
|
|
905
1228
|
return self.create_bus_term(name, msb, lsb, snl.SNLTerm.Direction.Output)
|
|
906
1229
|
|
|
907
1230
|
def create_input_bus_term(self, name: str, msb: int, lsb: int) -> Term:
|
|
908
|
-
"""Create an input bus Term in this Instance with the given name, msb and lsb.
|
|
1231
|
+
"""Create an input bus Term in this Instance with the given name, msb and lsb.
|
|
1232
|
+
|
|
1233
|
+
:param str name: the name of the Term to create.
|
|
1234
|
+
:param int msb: the most significant bit of the Term to create.
|
|
1235
|
+
:param int lsb: the least significant bit of the Term to create.
|
|
1236
|
+
:return: the created Term.
|
|
1237
|
+
:rtype: Term
|
|
1238
|
+
"""
|
|
909
1239
|
return self.create_bus_term(name, msb, lsb, snl.SNLTerm.Direction.Input)
|
|
910
1240
|
|
|
911
1241
|
def create_net(self, name: str) -> Net:
|
|
912
|
-
"""Create a scalar Net in this Instance with the given name.
|
|
1242
|
+
"""Create a scalar Net in this Instance with the given name.
|
|
1243
|
+
|
|
1244
|
+
:param str name: the name of the Net to create.
|
|
1245
|
+
:return: the created Net.
|
|
1246
|
+
:rtype: Net
|
|
1247
|
+
"""
|
|
913
1248
|
path = get_snl_path_from_id_list(self.pathIDs)
|
|
914
1249
|
if path.size() > 0:
|
|
915
1250
|
snl.SNLUniquifier(path)
|
|
@@ -919,7 +1254,14 @@ class Instance:
|
|
|
919
1254
|
return Net(path, newSNLNet)
|
|
920
1255
|
|
|
921
1256
|
def create_bus_net(self, name: str, msb: int, lsb: int) -> Net:
|
|
922
|
-
"""Create a bus Net in this Instance with the given name, msb and lsb.
|
|
1257
|
+
"""Create a bus Net in this Instance with the given name, msb and lsb.
|
|
1258
|
+
|
|
1259
|
+
:param str name: the name of the Net to create.
|
|
1260
|
+
:param int msb: the most significant bit of the Net to create.
|
|
1261
|
+
:param int lsb: the least significant bit of the Net to create.
|
|
1262
|
+
:return: the created Net.
|
|
1263
|
+
:rtype: Net
|
|
1264
|
+
"""
|
|
923
1265
|
path = get_snl_path_from_id_list(self.pathIDs)
|
|
924
1266
|
if path.size() > 0:
|
|
925
1267
|
snl.SNLUniquifier(path)
|
|
@@ -929,7 +1271,11 @@ class Instance:
|
|
|
929
1271
|
return Net(path, newSNLNet)
|
|
930
1272
|
|
|
931
1273
|
def dump_verilog(self, path: str, name: str):
|
|
932
|
-
"""Dump the verilog of this instance.
|
|
1274
|
+
"""Dump the verilog of this instance.
|
|
1275
|
+
|
|
1276
|
+
:param str path: the path where to dump the verilog.
|
|
1277
|
+
:param str name: the name of the verilog file.
|
|
1278
|
+
"""
|
|
933
1279
|
self.__get_snl_model().dumpVerilog(path, name)
|
|
934
1280
|
|
|
935
1281
|
|
|
@@ -943,10 +1289,20 @@ def get_top_db() -> snl.SNLDB:
|
|
|
943
1289
|
|
|
944
1290
|
|
|
945
1291
|
def get_top():
|
|
1292
|
+
"""
|
|
1293
|
+
:return: the top Instance.
|
|
1294
|
+
:rtype: Instance
|
|
1295
|
+
"""
|
|
946
1296
|
return Instance(snl.SNLPath())
|
|
947
1297
|
|
|
948
1298
|
|
|
949
1299
|
def create_top(name: str) -> Instance:
|
|
1300
|
+
"""Create a top instance with the given name.
|
|
1301
|
+
|
|
1302
|
+
:param str name: the name of the top instance to create.
|
|
1303
|
+
:return: the created top Instance.
|
|
1304
|
+
:rtype: Instance
|
|
1305
|
+
"""
|
|
950
1306
|
# init
|
|
951
1307
|
db = get_top_db()
|
|
952
1308
|
# create top design
|
|
@@ -966,11 +1322,15 @@ def load_verilog(files: list):
|
|
|
966
1322
|
|
|
967
1323
|
|
|
968
1324
|
def load_liberty(files: list):
|
|
969
|
-
logging.info(f"Loading liberty: {', '.join(files)}")
|
|
1325
|
+
logging.info(f"Loading liberty files: {', '.join(files)}")
|
|
970
1326
|
get_top_db().loadLibertyPrimitives(files)
|
|
971
1327
|
|
|
972
1328
|
|
|
973
1329
|
def load_primitives(name: str):
|
|
1330
|
+
"""Loads a primitive library embedded in najaeda.
|
|
1331
|
+
Currently supported libraries are:
|
|
1332
|
+
- xilinx
|
|
1333
|
+
"""
|
|
974
1334
|
if name == "xilinx":
|
|
975
1335
|
logging.info("Loading xilinx primitives")
|
|
976
1336
|
from najaeda.primitives import xilinx
|
|
@@ -988,7 +1348,11 @@ def get_primitives_library() -> snl.SNLLibrary:
|
|
|
988
1348
|
|
|
989
1349
|
|
|
990
1350
|
def get_model_name(id: tuple[int, int, int]) -> str:
|
|
991
|
-
"""
|
|
1351
|
+
"""
|
|
1352
|
+
:param tuple[int, int, int] id: the id of the model.
|
|
1353
|
+
:return: the name of the model given its id or None if it does not exist.
|
|
1354
|
+
:rtype: str or None
|
|
1355
|
+
"""
|
|
992
1356
|
u = snl.SNLUniverse.get()
|
|
993
1357
|
if u:
|
|
994
1358
|
db = u.getDB(id[0])
|