najaeda 0.2.3__cp312-cp312-macosx_11_0_arm64.whl → 0.2.4__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/libnaja_nl.dylib CHANGED
Binary file
Binary file
najaeda/naja.so CHANGED
Binary file
najaeda/netlist.py CHANGED
@@ -3,7 +3,6 @@
3
3
  #
4
4
  # SPDX-License-Identifier: Apache-2.0
5
5
 
6
- import itertools
7
6
  import time
8
7
  import logging
9
8
  import hashlib
@@ -133,27 +132,31 @@ class Equipotential:
133
132
  for term in self.equi.getTerms():
134
133
  yield Term([], term)
135
134
 
136
- def get_leaf_readers(self):
135
+ def get_leaf_readers(self, filter=None):
137
136
  if self.equi is not None:
138
137
  for term in self.equi.getInstTermOccurrences():
139
138
  direction = term.getInstTerm().getDirection()
140
- if direction != naja.SNLTerm.Direction.Output:
141
- if term.getInstTerm().getInstance().getModel().isLeaf():
142
- path = term.getPath().getPathIDs()
143
- path.append(term.getInstTerm().getInstance().getID())
144
- yield Term(path,
145
- term.getInstTerm().getBitTerm())
146
-
147
- def get_leaf_drivers(self):
139
+ if (
140
+ direction != naja.SNLTerm.Direction.Output and
141
+ term.getInstTerm().getInstance().getModel().isLeaf() and
142
+ (filter is None or filter(term))
143
+ ):
144
+ path = term.getPath().getPathIDs()
145
+ path.append(term.getInstTerm().getInstance().getID())
146
+ yield Term(path, term.getInstTerm().getBitTerm())
147
+
148
+ def get_leaf_drivers(self, filter=None):
148
149
  if self.equi is not None:
149
150
  for term in self.equi.getInstTermOccurrences():
150
151
  direction = term.getInstTerm().getDirection()
151
- if direction != naja.SNLTerm.Direction.Input:
152
- if term.getInstTerm().getInstance().getModel().isLeaf():
153
- path = term.getPath().getPathIDs()
154
- path.append(term.getInstTerm().getInstance().getID())
155
- yield Term(path,
156
- term.getInstTerm().getBitTerm())
152
+ if (
153
+ direction != naja.SNLTerm.Direction.Input and
154
+ term.getInstTerm().getInstance().getModel().isLeaf() and
155
+ (filter is None or filter(term))
156
+ ):
157
+ path = term.getPath().getPathIDs()
158
+ path.append(term.getInstTerm().getInstance().getID())
159
+ yield Term(path, term.getInstTerm().getBitTerm())
157
160
 
158
161
  def get_top_readers(self):
159
162
  if self.equi is not None:
@@ -241,6 +244,10 @@ class Net:
241
244
  "Use the bus net instead."
242
245
  )
243
246
  else:
247
+ # We need to uniquify until parent instance if parent instance is not top.
248
+ path = get_snl_path_from_id_list(self.pathIDs)
249
+ if path.size():
250
+ naja.SNLUniquifier(path.getHeadPath())
244
251
  self.net.setName(name)
245
252
 
246
253
  def get_msb(self) -> int:
@@ -304,10 +311,7 @@ class Net:
304
311
  if hasattr(self, "net"):
305
312
  return self.net.isConstant()
306
313
  else:
307
- for net in self.net_concat:
308
- if not net.isConstant():
309
- return False
310
- return True
314
+ return all(net.isConstant() for net in self.net_concat)
311
315
 
312
316
  def set_type(self, net_type: Type):
313
317
  """
@@ -342,7 +346,7 @@ class Net:
342
346
  yield self
343
347
  else:
344
348
  for net in self.net_concat:
345
- yield Net(net)
349
+ yield Net(self.pathIDs, net)
346
350
 
347
351
  def get_bit(self, index: int):
348
352
  """
@@ -409,8 +413,8 @@ class Net:
409
413
  :return: an iterator over the terminals of the net.
410
414
  :rtype: Iterator[Term]
411
415
  """
412
- for term in itertools.chain(self.get_design_terms(), self.get_inst_terms()):
413
- yield term
416
+ yield from self.get_design_terms()
417
+ yield from self.get_inst_terms()
414
418
 
415
419
 
416
420
  def get_snl_term_for_ids(pathIDs, termIDs):
@@ -552,6 +556,22 @@ class Term:
552
556
  """
553
557
  return self.is_scalar() or self.is_bus_bit()
554
558
 
559
+ def is_sequential(self) -> bool:
560
+ """
561
+ :return: True if the term is a sequential term.
562
+ :rtype: bool
563
+ """
564
+ for term in self.get_instance().get_flat_terms():
565
+ clockRelatedInputs = term.get_instance().get_clock_related_inputs(term)
566
+ if self in clockRelatedInputs:
567
+ return True
568
+ clockRelatedOutputs = term.get_instance().get_clock_related_outputs(term)
569
+ if self in clockRelatedOutputs:
570
+ return True
571
+ if (len(clockRelatedInputs) > 0 or len(clockRelatedOutputs) > 0) and (term == self):
572
+ return True
573
+ return False
574
+
555
575
  def get_bit_number(self):
556
576
  """
557
577
  :return: the bit index of the term if it is a bit.
@@ -618,7 +638,7 @@ class Term:
618
638
  def __get_snl_bitnet(self, bit) -> Net:
619
639
  # single bit
620
640
  path = get_snl_path_from_id_list(self.pathIDs)
621
- if path.size() > 0:
641
+ if path.size():
622
642
  instTerm = path.getTailInstance().getInstTerm(bit)
623
643
  return instTerm.getNet()
624
644
  else:
@@ -693,8 +713,11 @@ class Term:
693
713
  """
694
714
  return Instance(self.pathIDs)
695
715
 
696
- def get_flat_fanout(self):
697
- return self.get_equipotential().get_leaf_readers()
716
+ def get_flat_fanout(self, filter=None):
717
+ return self.get_equipotential().get_leaf_readers(filter=filter)
718
+
719
+ def count_flat_fanout(self, filter=None):
720
+ return sum(1 for _ in self.get_flat_fanout(filter=filter))
698
721
 
699
722
  def get_equipotential(self) -> Equipotential:
700
723
  """
@@ -863,9 +886,9 @@ class Instance:
863
886
  def __init__(self, path=naja.SNLPath()):
864
887
  self.inst = None
865
888
  self.revisionCount = 0
866
- self.SNLID = [0, 0, 0, 0, 0, 0]
889
+ self.SNLID = [0] * 6
867
890
  if isinstance(path, naja.SNLPath):
868
- if path.size() > 0:
891
+ if path.size():
869
892
  self.pathIDs = path.getPathIDs()
870
893
  self.revisionCount = path.getTailInstance().getModel().getRevisionCount()
871
894
  self.inst = path.getTailInstance()
@@ -873,10 +896,10 @@ class Instance:
873
896
  self.pathIDs = []
874
897
  elif isinstance(path, list):
875
898
  self.pathIDs = path.copy()
876
- if len(path) > 0:
899
+ if path:
877
900
  self.inst = get_snl_instance_from_id_list(path)
878
901
  self.revisionCount = self.inst.getModel().getRevisionCount()
879
- if self.inst is not None:
902
+ if self.inst:
880
903
  self.SNLID = self.inst.getModel().getNLID()
881
904
 
882
905
  def __eq__(self, other) -> bool:
@@ -989,12 +1012,6 @@ class Instance:
989
1012
  """
990
1013
  return self.__get_snl_model().isInv()
991
1014
 
992
- def is_basic_primitive(instance):
993
- design = instance.__get_snl_model()
994
- return (
995
- design.isConst0() or design.isConst1() or design.isBuf() or design.isInv()
996
- )
997
-
998
1015
  def __get_snl_model(self):
999
1016
  if self.is_top():
1000
1017
  return naja.NLUniverse.get().getTopDesign()
@@ -1142,6 +1159,13 @@ class Instance:
1142
1159
  """
1143
1160
  return self.__get_snl_model().isPrimitive()
1144
1161
 
1162
+ def is_sequential(self) -> bool:
1163
+ """
1164
+ :return: True if this is a sequential element.
1165
+ :rtype: bool
1166
+ """
1167
+ return self.__get_snl_model().isSequential()
1168
+
1145
1169
  def get_terms(self):
1146
1170
  """Iterate over all scalar terms and bus terms of this Instance.
1147
1171
 
@@ -1285,6 +1309,14 @@ class Instance:
1285
1309
  for attribute in leaf_object.getAttributes():
1286
1310
  yield Attribute(attribute)
1287
1311
 
1312
+ def count_attributes(self) -> int:
1313
+ """Count the attributes of this Instance.
1314
+
1315
+ :return: the number of attributes of this Instance.
1316
+ :rtype: int
1317
+ """
1318
+ return sum(1 for _ in self.get_attributes())
1319
+
1288
1320
  def delete_instance(self, name: str):
1289
1321
  """Delete the child instance with the given name."""
1290
1322
  if name == "":
@@ -1347,8 +1379,10 @@ class Instance:
1347
1379
  topSNLDesign.setName(name)
1348
1380
  else:
1349
1381
  path = get_snl_path_from_id_list(self.pathIDs)
1350
- if path.size() > 0:
1351
- naja.SNLUniquifier(path)
1382
+ # We need to uniquify until parent instance if parent instance
1383
+ # is not top. path.size == 1 for instance under top
1384
+ if path.size() > 1:
1385
+ naja.SNLUniquifier(path.getHeadPath())
1352
1386
  path = get_snl_path_from_id_list(self.pathIDs)
1353
1387
  inst = path.getTailInstance()
1354
1388
  inst.setName(name)
@@ -1537,6 +1571,87 @@ class Instance:
1537
1571
  """
1538
1572
  return self.__get_snl_model().getTruthTable()
1539
1573
 
1574
+ def add_clock_related_inputs(self, clock_term: Term, input_terms: List[Term]):
1575
+ """Add input terms that are related to the given clock term.
1576
+
1577
+ :param clock_term: the clock term to check for related inputs.
1578
+ :param input_terms: a list of input terms to add.
1579
+ :return: None
1580
+ """
1581
+ snlterms = [get_snl_term_for_ids(term.pathIDs, term.termIDs) for term in input_terms]
1582
+ self.__get_snl_model().addInputsToClockArcs(snlterms,
1583
+ get_snl_term_for_ids(clock_term.pathIDs,
1584
+ clock_term.termIDs))
1585
+
1586
+ def get_clock_related_inputs(self, clock_term: Term) -> List[Term]:
1587
+ """Get all input terms that are related to the given clock term.
1588
+
1589
+ :param clock_term: the clock term to check for related inputs.
1590
+ :return: a list of input terms that are related to the clock term.
1591
+ :rtype: List[Term]
1592
+ """
1593
+ terms = self.__get_snl_model().getClockRelatedInputs(
1594
+ get_snl_term_for_ids(clock_term.pathIDs, clock_term.termIDs))
1595
+ # Convert SNL terms to Term objects
1596
+ return [Term(clock_term.pathIDs, term) for term in terms]
1597
+
1598
+ def add_clock_related_outputs(self, clock_term: Term, output_terms: List[Term]):
1599
+ """Add output terms that are related to the given clock term.
1600
+
1601
+ :param clock_term: the clock term to check for related outputs.
1602
+ :param output_terms: a list of output terms to add.
1603
+ :return: None
1604
+ """
1605
+ # convert Term objects to SNL terms
1606
+ snlterms = [get_snl_term_for_ids(term.pathIDs, term.termIDs) for term in output_terms]
1607
+ self.__get_snl_model().addClockToOutputsArcs(
1608
+ get_snl_term_for_ids(clock_term.pathIDs, clock_term.termIDs), snlterms)
1609
+
1610
+ def get_clock_related_outputs(self, clock_term: Term) -> List[Term]:
1611
+ """Get all output terms that are related to the given clock term.
1612
+
1613
+ :param clock_term: the clock term to check for related outputs.
1614
+ :return: a list of output terms that are related to the clock term.
1615
+ :rtype: List[Term]
1616
+ """
1617
+ terms = self.__get_snl_model().getClockRelatedOutputs(
1618
+ get_snl_term_for_ids(clock_term.pathIDs, clock_term.termIDs))
1619
+ # Convert SNL terms to Term objects
1620
+ return [Term(clock_term.pathIDs, term) for term in terms]
1621
+
1622
+ def add_combinatorial_arcs(self, input_terms: List[Term], output_terms: List[Term]):
1623
+ """Add input terms that are combinatorial inputs for the given output term.
1624
+
1625
+ :param output_term: the output term to check for combinatorial inputs.
1626
+ :param input_terms: a list of input terms to add.
1627
+ :return: None
1628
+ """
1629
+ self.__get_snl_model().addCombinatorialArcs(
1630
+ [get_snl_term_for_ids(term.pathIDs, term.termIDs) for term in input_terms],
1631
+ [get_snl_term_for_ids(term.pathIDs, term.termIDs) for term in output_terms])
1632
+
1633
+ def get_combinatorial_inputs(self, output_term: Term) -> List[Term]:
1634
+ """Get all combinatorial input terms of this instance.
1635
+
1636
+ :return: a list of combinatorial input terms.
1637
+ :rtype: List[Term]
1638
+ """
1639
+ terms = self.__get_snl_model().getCombinatorialInputs(
1640
+ get_snl_term_for_ids(output_term.pathIDs, output_term.termIDs))
1641
+ # Convert SNL terms to Term objects
1642
+ return [Term(self.pathIDs, term) for term in terms]
1643
+
1644
+ def get_combinatorial_outputs(self, input_term: Term) -> List[Term]:
1645
+ """Get all combinatorial output terms of this instance.
1646
+
1647
+ :return: a list of combinatorial output terms.
1648
+ :rtype: List[Term]
1649
+ """
1650
+ terms = self.__get_snl_model().getCombinatorialOutputs(
1651
+ get_snl_term_for_ids(input_term.pathIDs, input_term.termIDs))
1652
+ # Convert SNL terms to Term objects
1653
+ return [Term(self.pathIDs, term) for term in terms]
1654
+
1540
1655
 
1541
1656
  def __get_top_db() -> naja.NLDB:
1542
1657
  if naja.NLUniverse.get() is None:
najaeda/stats.py CHANGED
@@ -151,7 +151,7 @@ class InstanceStats:
151
151
 
152
152
 
153
153
  def is_basic_primitive(instance):
154
- return instance.is_basic_primitive()
154
+ return instance.is_const() or instance.is_buf() or instance.is_inv()
155
155
 
156
156
 
157
157
  def compute_instance_stats(instance, instances_stats):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: najaeda
3
- Version: 0.2.3
3
+ Version: 0.2.4
4
4
  Summary: Naja EDA Python package
5
5
  Author-Email: Naja Authors <contact@keplertech.io>
6
6
  License: Apache License 2.0
@@ -1,18 +1,18 @@
1
- najaeda-0.2.3.dist-info/RECORD,,
2
- najaeda-0.2.3.dist-info/WHEEL,sha256=v7i1yNVEHWKlHHcCQ8SYkgpldhmAvPDAYWfI_XMFumo,114
3
- najaeda-0.2.3.dist-info/METADATA,sha256=Jx4ae_OoGfbOlrSqer4UwGLTOz5-CYwWQMeeKz3_mhM,3435
4
- najaeda-0.2.3.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
5
- najaeda-0.2.3.dist-info/licenses/AUTHORS,sha256=7NYEGDAX_1QZvCCHfq8YVXC5ZbwH_pbNI8DcSmm70GU,377
6
- najaeda/netlist.py,sha256=B2NwDDriuqf3Jy-J0w4bDJ4dwXIovSzwrWOEHLXjw6s,58509
7
- najaeda/libnaja_nl.dylib,sha256=X7Dfc_l443uGo5-5Rje2XV_axrx_kxuiHWdAr0Hlx4s,757376
1
+ najaeda-0.2.4.dist-info/RECORD,,
2
+ najaeda-0.2.4.dist-info/WHEEL,sha256=v7i1yNVEHWKlHHcCQ8SYkgpldhmAvPDAYWfI_XMFumo,114
3
+ najaeda-0.2.4.dist-info/METADATA,sha256=aGamxUDd_TKlccUOBxm-ooAbA3Ef-FwSlgP3lPTW09U,3435
4
+ najaeda-0.2.4.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
5
+ najaeda-0.2.4.dist-info/licenses/AUTHORS,sha256=7NYEGDAX_1QZvCCHfq8YVXC5ZbwH_pbNI8DcSmm70GU,377
6
+ najaeda/netlist.py,sha256=KdBQ77bMqYiUU_ecbDrR43L98FXk05_ahvj-8um-G5k,63866
7
+ najaeda/libnaja_nl.dylib,sha256=v773WRb6Pl9gpAtRNB8Z6YO0L0L1N121JPXRm9CjucI,757456
8
8
  najaeda/pandas_stats.py,sha256=yOb4ka965U7rN4D6AwvSGmRyeT_O7Ed-5cmT8BFbfeo,1070
9
9
  najaeda/_version.py,sha256=c-4hT20dyE-3BcdzOqR0vd92E7ydR5u2c-VmCc6oU8A,332
10
10
  najaeda/__init__.py,sha256=6QrOzlqTfd558FH9Zm6ve54IzkHaDJ8ZO8hTCaEwsL8,218
11
- najaeda/naja.so,sha256=E_DYv2PlULYrlFIC5Q_glJgMTmjdC6l5Vn--AAYFbnM,99440
11
+ najaeda/naja.so,sha256=KlZfhVxDYoHspfxoGy4yHuU8h9-r3y51IDlK9TSrjeQ,99440
12
12
  najaeda/net_visitor.py,sha256=P_esjibYb-wBDuF-AyF7es9sJYw1Ha8RhTPu-qKe7G4,1940
13
13
  najaeda/libnaja_opt.dylib,sha256=wIG2H5rnxbqGrwLSgklJjZ5wjOkx2Shhu2RsnYQwmuE,212720
14
- najaeda/libnaja_python.dylib,sha256=K9rhsJwvo28seQDE0VxTUWkRslo8Xl2lR2dzKihX8ME,944720
15
- najaeda/stats.py,sha256=SJ9rca0Z6ldNAFOjU7DPO2hfx1zq-9Bec0Rx_oLasJo,16217
14
+ najaeda/libnaja_python.dylib,sha256=soj2mTcuscVV3Frs3XmeiyekyUgWm5fmxGezO6ziJEQ,944848
15
+ najaeda/stats.py,sha256=W41fqyMiAN9o9ajXy1t-CGoxDaSmY0TyTT5epc6yz-I,16249
16
16
  najaeda/instance_visitor.py,sha256=JMsPSQaWNiDjxS05rxg83a0PIsrOIuTi9G35hkwdibs,1530
17
17
  najaeda/libnaja_bne.dylib,sha256=pLbGUnDr5PSGXbA8wKD-pqEyQIWHbiCb1icPpxRYrWE,136416
18
18
  najaeda/libnaja_dnl.dylib,sha256=qroDUAnl-eBJcdz-1YGC08Ngz4NEUctMiZ4W-gpT5mU,147088