najaeda 0.1.13__cp39-cp39-macosx_11_0_arm64.whl → 0.1.14__cp39-cp39-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.

Binary file
File without changes
@@ -0,0 +1,341 @@
1
+ # SPDX-FileCopyrightText: 2024 The Naja authors <https://github.com/najaeda/naja/blob/main/AUTHORS>
2
+ #
3
+ # SPDX-License-Identifier: Apache-2.0
4
+
5
+ import logging
6
+ import os
7
+ from naja import snl
8
+
9
+
10
+ class DesignsStats:
11
+ def __init__(self):
12
+ self.blackboxes = dict()
13
+ self.hier_designs = dict()
14
+
15
+
16
+ class DesignStats:
17
+ def __init__(self):
18
+ self.name = ""
19
+ self.assigns = 0
20
+ self.flat_assigns = 0
21
+ self.basic_primitives = dict()
22
+ self.primitives = dict()
23
+ self.flat_basic_primitives = dict()
24
+ self.flat_primitives = dict()
25
+ self.blackboxes = dict()
26
+ self.flat_blackboxes = dict()
27
+ self.ins = dict()
28
+ self.flat_ins = dict()
29
+ self.terms = dict()
30
+ self.bit_terms = dict()
31
+ self.net_stats = dict()
32
+
33
+ def add_ins_stats(self, ins_stats):
34
+ self.flat_assigns += ins_stats.flat_assigns
35
+ for ins, nb in ins_stats.flat_ins.items():
36
+ self.flat_ins[ins] = self.flat_ins.get(ins, 0) + nb
37
+ for ins, nb in ins_stats.flat_blackboxes.items():
38
+ self.flat_blackboxes[ins] = self.flat_blackboxes.get(ins, 0) + nb
39
+ for primitive, nb in ins_stats.flat_primitives.items():
40
+ self.flat_primitives[primitive] = (
41
+ self.flat_primitives.get(primitive, 0) + nb
42
+ )
43
+ for primitive, nb in ins_stats.flat_basic_primitives.items():
44
+ self.flat_basic_primitives[primitive] = (
45
+ self.flat_basic_primitives.get(primitive, 0) + nb
46
+ )
47
+
48
+
49
+ def isBasicPrimitive(design):
50
+ return design.isConst0() or design.isConst1() or design.isBuf() or design.isInv()
51
+
52
+
53
+ def compute_design_stats(design, designs_stats):
54
+ if design in designs_stats.hier_designs:
55
+ return designs_stats.hier_designs.get(design)
56
+ design_stats = DesignStats()
57
+ design_stats.name = design.getName()
58
+ for ins in design.getInstances():
59
+ model = ins.getModel()
60
+ if model.isAssign():
61
+ design_stats.assigns += 1
62
+ design_stats.flat_assigns += 1
63
+ elif model.isPrimitive():
64
+ if isBasicPrimitive(model):
65
+ design_stats.basic_primitives[model] = (
66
+ design_stats.basic_primitives.get(model, 0) + 1
67
+ )
68
+ design_stats.flat_basic_primitives[model] = (
69
+ design_stats.flat_basic_primitives.get(model, 0) + 1
70
+ )
71
+ else:
72
+ design_stats.primitives[model] = (
73
+ design_stats.primitives.get(model, 0) + 1
74
+ )
75
+ design_stats.flat_primitives[model] = (
76
+ design_stats.flat_primitives.get(model, 0) + 1
77
+ )
78
+ elif model.isBlackBox():
79
+ design_stats.blackboxes[model] = design_stats.blackboxes.get(model, 0) + 1
80
+ design_stats.flat_blackboxes[model] = (
81
+ design_stats.flat_blackboxes.get(model, 0) + 1
82
+ )
83
+ if model not in designs_stats.blackboxes:
84
+ designs_stats.blackboxes[model] = dict()
85
+ compute_design_terms(model, designs_stats.blackboxes[model])
86
+ else:
87
+ if model in designs_stats.hier_designs:
88
+ model_stats = designs_stats.hier_designs[model]
89
+ else:
90
+ model_stats = compute_design_stats(model, designs_stats)
91
+ design_stats.ins[model] = design_stats.ins.get(model, 0) + 1
92
+ design_stats.flat_ins[model] = design_stats.flat_ins.get(model, 0) + 1
93
+ design_stats.add_ins_stats(model_stats)
94
+ compute_design_terms(design, design_stats)
95
+ compute_design_net_stats(design, design_stats)
96
+ designs_stats.hier_designs[design] = design_stats
97
+ return design_stats
98
+
99
+
100
+ def compute_design_terms(design, design_stats):
101
+ for term in design.getTerms():
102
+ if term.getDirection() == snl.SNLTerm.Direction.Input:
103
+ design_stats.terms["inputs"] = design_stats.terms.get("inputs", 0) + 1
104
+ bit_terms = sum(1 for _ in term.getBits())
105
+ design_stats.bit_terms["inputs"] = (
106
+ design_stats.bit_terms.get("inputs", 0) + bit_terms
107
+ )
108
+ elif term.getDirection() == snl.SNLTerm.Direction.Output:
109
+ design_stats.terms["outputs"] = design_stats.terms.get("outputs", 0) + 1
110
+ bit_terms = sum(1 for _ in term.getBits())
111
+ design_stats.bit_terms["outputs"] = (
112
+ design_stats.bit_terms.get("outputs", 0) + bit_terms
113
+ )
114
+ elif term.getDirection() == snl.SNLTerm.Direction.InOut:
115
+ design_stats.terms["inouts"] = design_stats.terms.get("inouts", 0) + 1
116
+ bit_terms = sum(1 for _ in term.getBits())
117
+ design_stats.bit_terms["inouts"] = (
118
+ design_stats.bit_terms.get("inouts", 0) + bit_terms
119
+ )
120
+ else:
121
+ design_stats.terms["unknowns"] = design_stats.terms.get("unknowns", 0) + 1
122
+ bit_terms = sum(1 for _ in term.getBits())
123
+ design_stats.bit_terms["unknowns"] = (
124
+ design_stats.bit_terms.get("unknowns", 0) + bit_terms
125
+ )
126
+
127
+
128
+ def compute_design_net_stats(design, design_stats):
129
+ for net in design.getBitNets():
130
+ if net.isConstant():
131
+ pass
132
+ nb_components = sum(1 for c in net.getComponents())
133
+ design_stats.net_stats[nb_components] = (
134
+ design_stats.net_stats.get(nb_components, 0) + 1
135
+ )
136
+ design_stats.net_stats = dict(sorted(design_stats.net_stats.items()))
137
+
138
+
139
+ def dump_instances(stats_file, title, instances):
140
+ if len(instances) == 0:
141
+ return
142
+ sorted_instances = sorted(instances.items(), key=lambda item: item[0].getName())
143
+ stats_file.write(title + " " + str(sum(j for i, j in sorted_instances)) + "\n")
144
+ line_char = 0
145
+ for instance in sorted_instances:
146
+ if line_char != 0:
147
+ stats_file.write(",")
148
+ line_char += 1
149
+ if line_char > 80:
150
+ stats_file.write("\n")
151
+ line_char = 0
152
+ elif line_char != 0:
153
+ stats_file.write(" ")
154
+ line_char += 1
155
+ instance_char = instance[0].getName() + ":" + str(instance[1])
156
+ line_char += len(instance_char)
157
+ stats_file.write(instance_char)
158
+ stats_file.write("\n\n")
159
+
160
+
161
+ def dump_blackboxes_stats(stats_file, design_stats):
162
+ if len(design_stats.blackboxes) > 0:
163
+ stats_file.write("*** BlackBoxes ***\n")
164
+ for bbox in design_stats.blackboxes.items():
165
+ design = bbox[0]
166
+ design_terms = bbox[1]
167
+ stats_file.write("*** " + design.getName() + " ***\n")
168
+ if len(design_terms) > 0:
169
+ stats_file.write("Terms: ")
170
+ first = True
171
+ for terms in design_terms.items():
172
+ if not first:
173
+ stats_file.write(", ")
174
+ else:
175
+ first = False
176
+ stats_file.write(terms[0] + ":" + str(terms[1]))
177
+ stats_file.write("\n")
178
+ stats_file.write("\n")
179
+
180
+
181
+ def dump_stats(design, stats_file, designs_stats, dumped_models):
182
+ if design.isPrimitive() or design.isBlackBox():
183
+ return
184
+ if design in dumped_models:
185
+ return
186
+ dumped_models.add(design)
187
+ stats_file.write("*** " + design.getName() + " ***\n")
188
+ design_stats = designs_stats.hier_designs.get(design)
189
+ if design_stats is None:
190
+ print("Cannot find " + str(design) + " in design_stats")
191
+ raise
192
+ if len(design_stats.terms) > 0:
193
+ stats_file.write("Terms: ")
194
+ first = True
195
+ for terms in design_stats.terms.items():
196
+ if not first:
197
+ stats_file.write(", ")
198
+ else:
199
+ first = False
200
+ stats_file.write(terms[0] + ":" + str(terms[1]))
201
+ stats_file.write("\n")
202
+
203
+ dump_instances(stats_file, "Instances:", design_stats.ins)
204
+ nb_primitives = sum(design_stats.basic_primitives.values()) + sum(
205
+ design_stats.primitives.values()
206
+ )
207
+ if nb_primitives > 1:
208
+ stats_file.write("Primitives: " + str(nb_primitives) + "\n")
209
+ dump_instances(stats_file, "Simple Primitives:", design_stats.basic_primitives)
210
+ dump_instances(stats_file, "Other Primitives:", design_stats.primitives)
211
+ dump_instances(stats_file, "Blackboxes:", design_stats.blackboxes)
212
+ if design_stats.assigns > 0:
213
+ stats_file.write("Assigns: " + str(design_stats.assigns) + "\n")
214
+ dump_instances(stats_file, "Flat Instances:", design_stats.flat_ins)
215
+ dump_instances(stats_file, "Flat Blackboxes:", design_stats.flat_blackboxes)
216
+ nb_primitives = sum(design_stats.flat_basic_primitives.values()) + sum(
217
+ design_stats.flat_primitives.values()
218
+ )
219
+ if nb_primitives > 1:
220
+ stats_file.write("Flat Primitives: " + str(nb_primitives) + "\n")
221
+ dump_instances(
222
+ stats_file, "Flat Simple Primitives:", design_stats.flat_basic_primitives
223
+ )
224
+ dump_instances(stats_file, "Flat Other Primitives:", design_stats.flat_primitives)
225
+ if design_stats.flat_assigns > 0:
226
+ stats_file.write("Flat Assigns: " + str(design_stats.flat_assigns) + "\n")
227
+ stats_file.write("\n")
228
+ for ins in design.getInstances():
229
+ model = ins.getModel()
230
+ dump_stats(model, stats_file, designs_stats, dumped_models)
231
+
232
+
233
+ def dump_pandas(designs_stats):
234
+ import pandas
235
+ import matplotlib.pyplot as plt
236
+
237
+ # create a figures directory erase the previous one
238
+ if os.path.exists("figures"):
239
+ import shutil
240
+
241
+ shutil.rmtree("figures")
242
+ os.makedirs("figures")
243
+
244
+ data = []
245
+ for design, design_stats in designs_stats.hier_designs.items():
246
+ data.append(
247
+ [
248
+ design.getName(),
249
+ sum(design_stats.terms.values()),
250
+ sum(design_stats.bit_terms.values()),
251
+ sum(design_stats.basic_primitives.values()),
252
+ sum(design_stats.primitives.values()),
253
+ sum(design_stats.blackboxes.values()),
254
+ sum(design_stats.ins.values()),
255
+ sum(design_stats.flat_ins.values()),
256
+ sum(design_stats.flat_blackboxes.values()),
257
+ sum(design_stats.flat_basic_primitives.values()),
258
+ sum(design_stats.flat_primitives.values()),
259
+ ]
260
+ )
261
+ df = pandas.DataFrame(
262
+ data,
263
+ columns=[
264
+ "Design",
265
+ "Terms",
266
+ "Bit Terms",
267
+ "Basic Primitives",
268
+ "Primitives",
269
+ "Blackboxes",
270
+ "Instances",
271
+ "Flat Instances",
272
+ "Flat Blackboxes",
273
+ "Flat Basic Primitives",
274
+ "Flat Primitives",
275
+ ],
276
+ )
277
+ df.to_csv("figures/designs_stats.csv", index=False)
278
+
279
+ net_series = pandas.Series(design_stats.net_stats)
280
+ nets_plot = net_series.plot(
281
+ kind="bar",
282
+ title="Number of nets with a given number of components for\n"
283
+ + design.getName(),
284
+ xlabel="number of components",
285
+ ylabel="number of nets",
286
+ )
287
+ nets_plot.set_yscale("log")
288
+ nets_plot.xaxis.set_major_locator(plt.MaxNLocator(100))
289
+ nets_figure = nets_plot.get_figure()
290
+ nets_figure.tight_layout()
291
+ nets_figure.savefig("figures/nets_" + design.getName() + ".png")
292
+
293
+ flat_primitives_series = pandas.Series(design_stats.flat_primitives)
294
+ primitives_plot = flat_primitives_series.plot(
295
+ kind="bar",
296
+ title="Number of primitives for\n" + design.getName(),
297
+ xlabel="primitive",
298
+ ylabel="number of flat instances",
299
+ )
300
+ primitives_plot.set_yscale("log")
301
+ primitives_figure = primitives_plot.get_figure()
302
+ primitives_figure.tight_layout()
303
+ primitives_figure.savefig("figures/flat_primitives_" + design.getName() + ".png")
304
+
305
+
306
+ def compute_and_dump_design_stats(design, stats_file, with_pandas=False):
307
+ designs_stats = DesignsStats()
308
+ compute_design_stats(design, designs_stats)
309
+ dumped_models = set()
310
+ dump_stats(design, stats_file, designs_stats, dumped_models)
311
+ dump_blackboxes_stats(stats_file, designs_stats)
312
+ if with_pandas:
313
+ dump_pandas(designs_stats)
314
+
315
+
316
+ def dump_constants(design, analyzed_models):
317
+ if design.isPrimitive():
318
+ return
319
+ if design in analyzed_models:
320
+ return
321
+ analyzed_models.add(design)
322
+ for bitnet in design.getBitNets():
323
+ if bitnet.isConstant():
324
+ logging.info(
325
+ "In design "
326
+ + design.getName()
327
+ + ", constant net "
328
+ + bitnet.getName()
329
+ + " of type "
330
+ + bitnet.getTypeAsString()
331
+ )
332
+ if all(False for _ in bitnet.getComponents()):
333
+ logging.info(" with zero connections\n")
334
+ else:
335
+ logging.info(" connected to:\n")
336
+ for component in bitnet.getComponents():
337
+ logging.info(str(component) + "\n")
338
+
339
+ for ins in design.getInstances():
340
+ model = ins.getModel()
341
+ dump_constants(model, analyzed_models)
najaeda/netlist.py CHANGED
@@ -1352,6 +1352,13 @@ class Instance:
1352
1352
  """
1353
1353
  self.__get_snl_model().dumpVerilog(path, name)
1354
1354
 
1355
+ def get_truth_table(self):
1356
+ """
1357
+ :return: the truth table of the instance.
1358
+ :rtype: list[str]
1359
+ """
1360
+ return self.__get_snl_model().getTruthTable()
1361
+
1355
1362
 
1356
1363
  def get_top_db() -> snl.SNLDB:
1357
1364
  if snl.SNLUniverse.get() is None:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: najaeda
3
- Version: 0.1.13
3
+ Version: 0.1.14
4
4
  Summary: Naja EDA Python package
5
5
  Author-Email: Naja Authors <contact@keplertech.io>
6
6
  License: Apache License 2.0
@@ -1,10 +1,5 @@
1
- najaeda-0.1.13.dist-info/RECORD,,
2
- najaeda-0.1.13.dist-info/WHEEL,sha256=Qmm8uWPQTspuPJ9tUBLJdmqmcf0_LWu4zzBSlc_SSWo,112
3
- najaeda-0.1.13.dist-info/METADATA,sha256=_MF_KzBJGkauW1DVSxFnM0A-0BmFqz1L3vr0WyDBeVA,2475
4
- najaeda-0.1.13.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
5
- najaeda-0.1.13.dist-info/licenses/AUTHORS,sha256=7NYEGDAX_1QZvCCHfq8YVXC5ZbwH_pbNI8DcSmm70GU,377
6
- najaeda/netlist.py,sha256=8HvicL1VCsozjMZ8Fl0SS8OQyI4XREEhSwMQ5xKqVBc,49050
7
- najaeda/libnaja_snl_python.dylib,sha256=NtiGh5TqGliix5VPpSntF8FKNJqnqwuxa64_hhCHuew,887360
1
+ najaeda/netlist.py,sha256=FadEyKqZMS5cGzDt-WOZRmDcDc3dFFvQSw2iJusW7Y0,49236
2
+ najaeda/libnaja_snl_python.dylib,sha256=dAp7m7-J4VhsihmGCfwLQ_IN3tdaOrBs-4MhInlcsKM,887680
8
3
  najaeda/pandas_stats.py,sha256=yOb4ka965U7rN4D6AwvSGmRyeT_O7Ed-5cmT8BFbfeo,1070
9
4
  najaeda/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
5
  najaeda/net_visitor.py,sha256=P_esjibYb-wBDuF-AyF7es9sJYw1Ha8RhTPu-qKe7G4,1940
@@ -12,6 +7,8 @@ najaeda/libnaja_snl.dylib,sha256=_W6nRABcp6q9xoBF0hTOBDWwHBUB6-n8anUoTyNkn-s,574
12
7
  najaeda/snl.so,sha256=lRUMHy2TG1HRdV65DPiLny314jNElZWEWcHgkg6k0co,98272
13
8
  najaeda/stats.py,sha256=wackXsf0x24ic9v-UifECHj4t5yveUWssMDZp2B057A,16187
14
9
  najaeda/instance_visitor.py,sha256=JMsPSQaWNiDjxS05rxg83a0PIsrOIuTi9G35hkwdibs,1530
10
+ najaeda/native/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11
+ najaeda/native/stats.py,sha256=3iIPr-jitdMhbHthA4BauaTXwx1ijYIQuXwtoDyCf-A,13056
15
12
  najaeda/docs/requirements.txt,sha256=1XIBGTIplm2arC9HhDCfLuAjozGdVSXkqmOj8ybuT6U,121
16
13
  najaeda/docs/.readthedocs.yaml,sha256=nN_Psro-YdfPcIiueZkJcZepts68g23rqVThhKnmVRw,790
17
14
  najaeda/docs/source/index.rst,sha256=80VMfeEGHObnOUXRBxIzISQsG_HNkgT-pUpsDZsCfOY,387
@@ -31,3 +28,8 @@ najaeda/.dylibs/libcapnp-1.1.0.dylib,sha256=l9SvRdxPrCI2mB_UitO7QjsaC7I5mq2R3rZj
31
28
  najaeda/.dylibs/libkj-1.1.0.dylib,sha256=pB7dMks8b8ybJ6xKWqFR_hHjKsmpf7wzbcunZaS7gO4,578320
32
29
  najaeda/primitives/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
33
30
  najaeda/primitives/xilinx.py,sha256=_VPQfWAp3oc4EgOzW-gy96BXdFZK6E4C7aOSdCn4JRU,26008
31
+ najaeda-0.1.14.dist-info/RECORD,,
32
+ najaeda-0.1.14.dist-info/WHEEL,sha256=Qmm8uWPQTspuPJ9tUBLJdmqmcf0_LWu4zzBSlc_SSWo,112
33
+ najaeda-0.1.14.dist-info/METADATA,sha256=80hWLRV3mUTPKIbrne0o4kPXICFNFUO9oPtLN6zpA7o,2475
34
+ najaeda-0.1.14.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
35
+ najaeda-0.1.14.dist-info/licenses/AUTHORS,sha256=7NYEGDAX_1QZvCCHfq8YVXC5ZbwH_pbNI8DcSmm70GU,377