najaeda 0.3.3__cp314-cp314-win_amd64.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.
- najaeda/__init__.py +20 -0
- najaeda/_version.py +16 -0
- najaeda/docs/.readthedocs.yaml +26 -0
- najaeda/docs/requirements.txt +7 -0
- najaeda/docs/source/api.rst +7 -0
- najaeda/docs/source/common_classes.rst +11 -0
- najaeda/docs/source/conf.py +57 -0
- najaeda/docs/source/equipotential.rst +15 -0
- najaeda/docs/source/examples.rst.in +66 -0
- najaeda/docs/source/index.rst +17 -0
- najaeda/docs/source/instance.rst +34 -0
- najaeda/docs/source/introduction.rst +68 -0
- najaeda/docs/source/net.rst +20 -0
- najaeda/docs/source/netlist_classes.rst +11 -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 +43 -0
- najaeda/naja.pyd +0 -0
- najaeda/naja_bne.dll +0 -0
- najaeda/naja_dnl.dll +0 -0
- najaeda/naja_metrics.dll +0 -0
- najaeda/naja_nl.dll +0 -0
- najaeda/naja_opt.dll +0 -0
- najaeda/naja_python.dll +0 -0
- najaeda/native/__init__.py +0 -0
- najaeda/native/stats.py +341 -0
- najaeda/net_visitor.py +53 -0
- najaeda/netlist.py +1990 -0
- najaeda/pandas_stats.py +32 -0
- najaeda/primitives/__init__.py +0 -0
- najaeda/primitives/utils.py +19 -0
- najaeda/primitives/xilinx.py +541 -0
- najaeda/primitives/yosys.py +288 -0
- najaeda/stats.py +410 -0
- najaeda-0.3.3.dist-info/DELVEWHEEL +2 -0
- najaeda-0.3.3.dist-info/METADATA +108 -0
- najaeda-0.3.3.dist-info/RECORD +44 -0
- najaeda-0.3.3.dist-info/WHEEL +5 -0
- najaeda-0.3.3.dist-info/licenses/AUTHORS +7 -0
- najaeda-0.3.3.dist-info/licenses/LICENSE +201 -0
- najaeda.libs/msvcp140.dll +0 -0
- najaeda.libs/tbb12.dll +0 -0
- najaeda.libs/tbbmalloc.dll +0 -0
najaeda/stats.py
ADDED
|
@@ -0,0 +1,410 @@
|
|
|
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 json
|
|
7
|
+
|
|
8
|
+
from najaeda import netlist
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class InstancesStats:
|
|
12
|
+
def __init__(self):
|
|
13
|
+
self.blackboxes = dict()
|
|
14
|
+
self.hier_instances = dict()
|
|
15
|
+
|
|
16
|
+
def dump_instance_stats_text(self, instance, stats_files):
|
|
17
|
+
dumped_models = set()
|
|
18
|
+
self.__dump_instance_stats_text(instance, stats_files, dumped_models)
|
|
19
|
+
|
|
20
|
+
def __dump_stats(self, file, value_name, value):
|
|
21
|
+
file.write(f"{value_name}: {value} \n")
|
|
22
|
+
|
|
23
|
+
def __dump_terms_stats_text(self, instance_stats, file):
|
|
24
|
+
file.write("Terms: ")
|
|
25
|
+
first = True
|
|
26
|
+
for terms in instance_stats.terms.items():
|
|
27
|
+
if not first:
|
|
28
|
+
file.write(", ")
|
|
29
|
+
else:
|
|
30
|
+
first = False
|
|
31
|
+
file.write(terms[0] + ":" + str(terms[1]))
|
|
32
|
+
file.write("\n")
|
|
33
|
+
|
|
34
|
+
def __dump_instances(self, stats_file, title, instances):
|
|
35
|
+
if len(instances) == 0:
|
|
36
|
+
return
|
|
37
|
+
sorted_instances = sorted(
|
|
38
|
+
instances.items(), key=lambda item: netlist.get_model_name(item[0])
|
|
39
|
+
)
|
|
40
|
+
stats_file.write(title + " " + str(sum(j for i, j in sorted_instances)) + "\n")
|
|
41
|
+
line_char = 0
|
|
42
|
+
for instance in sorted_instances:
|
|
43
|
+
model_name = netlist.get_model_name(instance[0])
|
|
44
|
+
if line_char != 0:
|
|
45
|
+
stats_file.write(",")
|
|
46
|
+
line_char += 1
|
|
47
|
+
if line_char > 80:
|
|
48
|
+
stats_file.write("\n")
|
|
49
|
+
line_char = 0
|
|
50
|
+
elif line_char != 0:
|
|
51
|
+
stats_file.write(" ")
|
|
52
|
+
line_char += 1
|
|
53
|
+
instance_char = model_name + ":" + str(instance[1])
|
|
54
|
+
line_char += len(instance_char)
|
|
55
|
+
stats_file.write(instance_char)
|
|
56
|
+
stats_file.write("\n\n")
|
|
57
|
+
|
|
58
|
+
def __dump_instance_stats_text(self, instance, file, dumped_models):
|
|
59
|
+
if instance.is_primitive() or instance.is_blackbox():
|
|
60
|
+
return
|
|
61
|
+
# Only dump once each model
|
|
62
|
+
model_id = instance.get_model_id()
|
|
63
|
+
if model_id in dumped_models:
|
|
64
|
+
return
|
|
65
|
+
dumped_models.add(model_id)
|
|
66
|
+
|
|
67
|
+
file.write("*** " + instance.get_name() + " ***\n")
|
|
68
|
+
|
|
69
|
+
instance_stats = self.hier_instances.get(model_id)
|
|
70
|
+
if instance_stats is None:
|
|
71
|
+
print(
|
|
72
|
+
"Cannot find " + str(instance.get_model_name()) + " in instance_stats"
|
|
73
|
+
)
|
|
74
|
+
raise
|
|
75
|
+
|
|
76
|
+
if len(instance_stats.terms) > 0:
|
|
77
|
+
self.__dump_terms_stats_text(instance_stats, file)
|
|
78
|
+
|
|
79
|
+
# self.__dump_instances(stats_file, "Instances:", design_stats.ins)
|
|
80
|
+
nb_primitives = sum(instance_stats.basic_primitives.values()) + sum(
|
|
81
|
+
instance_stats.primitives.values()
|
|
82
|
+
)
|
|
83
|
+
if nb_primitives > 1:
|
|
84
|
+
self.__dump_stats(file, "Primitives", nb_primitives)
|
|
85
|
+
|
|
86
|
+
self.__dump_instances(
|
|
87
|
+
file, "Simple Primitives:", instance_stats.basic_primitives
|
|
88
|
+
)
|
|
89
|
+
self.__dump_instances(file, "Other Primitives:", instance_stats.primitives)
|
|
90
|
+
self.__dump_instances(file, "Blackboxes:", instance_stats.blackboxes)
|
|
91
|
+
|
|
92
|
+
if instance_stats.assigns > 0:
|
|
93
|
+
self.__dump_stats(file, "Assigns", instance_stats.assigns)
|
|
94
|
+
|
|
95
|
+
self.__dump_instances(file, "Flat Instances:", instance_stats.flat_ins)
|
|
96
|
+
self.__dump_instances(file, "Flat Blackboxes:", instance_stats.flat_blackboxes)
|
|
97
|
+
|
|
98
|
+
nb_primitives = sum(instance_stats.flat_basic_primitives.values()) + sum(
|
|
99
|
+
instance_stats.flat_primitives.values()
|
|
100
|
+
)
|
|
101
|
+
if nb_primitives > 1:
|
|
102
|
+
self.__dump_stats(file, "Flat Primitives", nb_primitives)
|
|
103
|
+
|
|
104
|
+
self.__dump_instances(
|
|
105
|
+
file, "Flat Simple Primitives:", instance_stats.flat_basic_primitives
|
|
106
|
+
)
|
|
107
|
+
self.__dump_instances(
|
|
108
|
+
file, "Flat Other Primitives:", instance_stats.flat_primitives
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
if instance_stats.flat_assigns > 0:
|
|
112
|
+
self.__dump_stats(file, "Flat Assigns", instance_stats.flat_assigns)
|
|
113
|
+
|
|
114
|
+
file.write("\n")
|
|
115
|
+
|
|
116
|
+
for child_instance in instance.get_child_instances():
|
|
117
|
+
self.__dump_instance_stats_text(child_instance, file, dumped_models)
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
class InstanceStats:
|
|
121
|
+
def __init__(self):
|
|
122
|
+
self.name = ""
|
|
123
|
+
self.assigns = 0
|
|
124
|
+
self.flat_assigns = 0
|
|
125
|
+
self.basic_primitives = dict()
|
|
126
|
+
self.primitives = dict()
|
|
127
|
+
self.flat_basic_primitives = dict()
|
|
128
|
+
self.flat_primitives = dict()
|
|
129
|
+
self.blackboxes = dict()
|
|
130
|
+
self.flat_blackboxes = dict()
|
|
131
|
+
self.ins = dict()
|
|
132
|
+
self.flat_ins = dict()
|
|
133
|
+
self.terms = dict()
|
|
134
|
+
self.bit_terms = dict()
|
|
135
|
+
self.net_stats = dict()
|
|
136
|
+
|
|
137
|
+
def add_ins_stats(self, ins_stats):
|
|
138
|
+
self.flat_assigns += ins_stats.flat_assigns
|
|
139
|
+
for ins, nb in ins_stats.flat_ins.items():
|
|
140
|
+
self.flat_ins[ins] = self.flat_ins.get(ins, 0) + nb
|
|
141
|
+
for ins, nb in ins_stats.flat_blackboxes.items():
|
|
142
|
+
self.flat_blackboxes[ins] = self.flat_blackboxes.get(ins, 0) + nb
|
|
143
|
+
for primitive, nb in ins_stats.flat_primitives.items():
|
|
144
|
+
self.flat_primitives[primitive] = (
|
|
145
|
+
self.flat_primitives.get(primitive, 0) + nb
|
|
146
|
+
)
|
|
147
|
+
for primitive, nb in ins_stats.flat_basic_primitives.items():
|
|
148
|
+
self.flat_basic_primitives[primitive] = (
|
|
149
|
+
self.flat_basic_primitives.get(primitive, 0) + nb
|
|
150
|
+
)
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
def is_basic_primitive(instance):
|
|
154
|
+
return instance.is_const() or instance.is_buf() or instance.is_inv()
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
def compute_instance_stats(instance, instances_stats):
|
|
158
|
+
if instance.get_model_id() in instances_stats.hier_instances:
|
|
159
|
+
return instances_stats.hier_instances.get(instance.get_model_id())
|
|
160
|
+
instance_stats = InstanceStats()
|
|
161
|
+
instance_stats.name = instance.get_model_name()
|
|
162
|
+
for ins in instance.get_child_instances():
|
|
163
|
+
model_id = ins.get_model_id()
|
|
164
|
+
if ins.is_assign():
|
|
165
|
+
instance_stats.assigns += 1
|
|
166
|
+
instance_stats.flat_assigns += 1
|
|
167
|
+
elif ins.is_primitive():
|
|
168
|
+
if is_basic_primitive(ins):
|
|
169
|
+
instance_stats.basic_primitives[model_id] = (
|
|
170
|
+
instance_stats.basic_primitives.get(model_id, 0) + 1
|
|
171
|
+
)
|
|
172
|
+
instance_stats.flat_basic_primitives[model_id] = (
|
|
173
|
+
instance_stats.flat_basic_primitives.get(model_id, 0) + 1
|
|
174
|
+
)
|
|
175
|
+
else:
|
|
176
|
+
instance_stats.primitives[model_id] = (
|
|
177
|
+
instance_stats.primitives.get(model_id, 0) + 1
|
|
178
|
+
)
|
|
179
|
+
instance_stats.flat_primitives[model_id] = (
|
|
180
|
+
instance_stats.flat_primitives.get(model_id, 0) + 1
|
|
181
|
+
)
|
|
182
|
+
elif ins.is_blackbox():
|
|
183
|
+
instance_stats.blackboxes[model_id] = (
|
|
184
|
+
instance_stats.blackboxes.get(model_id, 0) + 1
|
|
185
|
+
)
|
|
186
|
+
instance_stats.flat_blackboxes[model_id] = (
|
|
187
|
+
instance_stats.flat_blackboxes.get(model_id, 0) + 1
|
|
188
|
+
)
|
|
189
|
+
if model_id not in instance_stats.blackboxes:
|
|
190
|
+
instance_stats.blackboxes[model_id] = dict()
|
|
191
|
+
compute_instance_terms(model_id, instance_stats.blackboxes[model_id])
|
|
192
|
+
else:
|
|
193
|
+
if model_id in instances_stats.hier_instances:
|
|
194
|
+
model_stats = instances_stats.hier_instances[model_id]
|
|
195
|
+
else:
|
|
196
|
+
model_stats = compute_instance_stats(ins, instances_stats)
|
|
197
|
+
instance_stats.ins[model_id] = instance_stats.ins.get(model_id, 0) + 1
|
|
198
|
+
instance_stats.flat_ins[model_id] = (
|
|
199
|
+
instance_stats.flat_ins.get(model_id, 0) + 1
|
|
200
|
+
)
|
|
201
|
+
instance_stats.add_ins_stats(model_stats)
|
|
202
|
+
compute_instance_terms(instance, instance_stats)
|
|
203
|
+
compute_instance_net_stats(instance, instance_stats)
|
|
204
|
+
instances_stats.hier_instances[instance.get_model_id()] = instance_stats
|
|
205
|
+
return instance_stats
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
def compute_instance_terms(instance, instance_stats):
|
|
209
|
+
for term in instance.get_terms():
|
|
210
|
+
if term.get_direction() == netlist.Term.Direction.INPUT:
|
|
211
|
+
instance_stats.terms["inputs"] = instance_stats.terms.get("inputs", 0) + 1
|
|
212
|
+
bit_terms = sum(1 for _ in term.get_bits())
|
|
213
|
+
instance_stats.bit_terms["inputs"] = (
|
|
214
|
+
instance_stats.bit_terms.get("inputs", 0) + bit_terms
|
|
215
|
+
)
|
|
216
|
+
elif term.get_direction() == netlist.Term.Direction.OUTPUT:
|
|
217
|
+
instance_stats.terms["outputs"] = instance_stats.terms.get("outputs", 0) + 1
|
|
218
|
+
bit_terms = sum(1 for _ in term.get_bits())
|
|
219
|
+
instance_stats.bit_terms["outputs"] = (
|
|
220
|
+
instance_stats.bit_terms.get("outputs", 0) + bit_terms
|
|
221
|
+
)
|
|
222
|
+
elif term.get_direction() == netlist.Term.Direction.INOUT:
|
|
223
|
+
instance_stats.terms["inouts"] = instance_stats.terms.get("inouts", 0) + 1
|
|
224
|
+
bit_terms = sum(1 for _ in term.get_bits())
|
|
225
|
+
instance_stats.bit_terms["inouts"] = (
|
|
226
|
+
instance_stats.bit_terms.get("inouts", 0) + bit_terms
|
|
227
|
+
)
|
|
228
|
+
else:
|
|
229
|
+
instance_stats.terms["unknowns"] = (
|
|
230
|
+
instance_stats.terms.get("unknowns", 0) + 1
|
|
231
|
+
)
|
|
232
|
+
bit_terms = sum(1 for _ in term.get_bits())
|
|
233
|
+
instance_stats.bit_terms["unknowns"] = (
|
|
234
|
+
instance_stats.bit_terms.get("unknowns", 0) + bit_terms
|
|
235
|
+
)
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
def compute_instance_net_stats(instance, instance_stats):
|
|
239
|
+
for net in instance.get_bit_nets():
|
|
240
|
+
if net.is_const():
|
|
241
|
+
pass
|
|
242
|
+
nb_components = sum(1 for c in net.get_terms())
|
|
243
|
+
instance_stats.net_stats[nb_components] = (
|
|
244
|
+
instance_stats.net_stats.get(nb_components, 0) + 1
|
|
245
|
+
)
|
|
246
|
+
instance_stats.net_stats = dict(sorted(instance_stats.net_stats.items()))
|
|
247
|
+
|
|
248
|
+
|
|
249
|
+
def dump_instances(stats_file, title, instances):
|
|
250
|
+
if len(instances) == 0:
|
|
251
|
+
return
|
|
252
|
+
sorted_instances = sorted(
|
|
253
|
+
instances.items(), key=lambda item: netlist.get_model_name(item[0])
|
|
254
|
+
)
|
|
255
|
+
stats_file.write(title + " " + str(sum(j for i, j in sorted_instances)) + "\n")
|
|
256
|
+
line_char = 0
|
|
257
|
+
for instance in sorted_instances:
|
|
258
|
+
model_name = netlist.get_model_name(instance[0])
|
|
259
|
+
if line_char != 0:
|
|
260
|
+
stats_file.write(",")
|
|
261
|
+
line_char += 1
|
|
262
|
+
if line_char > 80:
|
|
263
|
+
stats_file.write("\n")
|
|
264
|
+
line_char = 0
|
|
265
|
+
elif line_char != 0:
|
|
266
|
+
stats_file.write(" ")
|
|
267
|
+
line_char += 1
|
|
268
|
+
instance_char = model_name + ":" + str(instance[1])
|
|
269
|
+
line_char += len(instance_char)
|
|
270
|
+
stats_file.write(instance_char)
|
|
271
|
+
stats_file.write("\n\n")
|
|
272
|
+
|
|
273
|
+
|
|
274
|
+
def dump_blackboxes_stats(stats_file, design_stats):
|
|
275
|
+
if len(design_stats.blackboxes) > 0:
|
|
276
|
+
stats_file.write("*** BlackBoxes ***\n")
|
|
277
|
+
for bbox in design_stats.blackboxes.items():
|
|
278
|
+
design = bbox[0]
|
|
279
|
+
design_terms = bbox[1]
|
|
280
|
+
stats_file.write("*** " + design.getName() + " ***\n")
|
|
281
|
+
if len(design_terms) > 0:
|
|
282
|
+
stats_file.write("Terms: ")
|
|
283
|
+
first = True
|
|
284
|
+
for terms in design_terms.items():
|
|
285
|
+
if not first:
|
|
286
|
+
stats_file.write(", ")
|
|
287
|
+
else:
|
|
288
|
+
first = False
|
|
289
|
+
stats_file.write(terms[0] + ":" + str(terms[1]))
|
|
290
|
+
stats_file.write("\n")
|
|
291
|
+
stats_file.write("\n")
|
|
292
|
+
|
|
293
|
+
|
|
294
|
+
# def dump_pandas(designs_stats):
|
|
295
|
+
# import pandas
|
|
296
|
+
# import matplotlib.pyplot as plt
|
|
297
|
+
#
|
|
298
|
+
# #create a figures directory erase the previous one
|
|
299
|
+
# if os.path.exists('figures'):
|
|
300
|
+
# import shutil
|
|
301
|
+
# shutil.rmtree('figures')
|
|
302
|
+
# os.makedirs('figures')
|
|
303
|
+
#
|
|
304
|
+
# data = []
|
|
305
|
+
# for design, design_stats in designs_stats.hier_designs.items():
|
|
306
|
+
# data.append([
|
|
307
|
+
# design.getName(),
|
|
308
|
+
# sum(design_stats.terms.values()),
|
|
309
|
+
# sum(design_stats.bit_terms.values()),
|
|
310
|
+
# sum(design_stats.basic_primitives.values()),
|
|
311
|
+
# sum(design_stats.primitives.values()),
|
|
312
|
+
# sum(design_stats.blackboxes.values()),
|
|
313
|
+
# sum(design_stats.ins.values()),
|
|
314
|
+
# sum(design_stats.flat_ins.values()),
|
|
315
|
+
# sum(design_stats.flat_blackboxes.values()),
|
|
316
|
+
# sum(design_stats.flat_basic_primitives.values()),
|
|
317
|
+
# sum(design_stats.flat_primitives.values())])
|
|
318
|
+
# df = pandas.DataFrame(data, columns=[
|
|
319
|
+
# 'Design', 'Terms', 'Bit Terms',
|
|
320
|
+
# 'Basic Primitives', 'Primitives', 'Blackboxes', 'Instances',
|
|
321
|
+
# 'Flat Instances', 'Flat Blackboxes',
|
|
322
|
+
# 'Flat Basic Primitives', 'Flat Primitives'])
|
|
323
|
+
# df.to_csv('figures/designs_stats.csv', index=False)
|
|
324
|
+
#
|
|
325
|
+
# net_series = pandas.Series(design_stats.net_stats)
|
|
326
|
+
# nets_plot = net_series.plot(kind='bar',
|
|
327
|
+
# title='Number of nets with a given number of components for\n' + design.getName(),
|
|
328
|
+
# xlabel='number of components', ylabel='number of nets')
|
|
329
|
+
# nets_plot.set_yscale('log')
|
|
330
|
+
# nets_plot.xaxis.set_major_locator(plt.MaxNLocator(100))
|
|
331
|
+
# nets_figure = nets_plot.get_figure()
|
|
332
|
+
# nets_figure.tight_layout()
|
|
333
|
+
# nets_figure.savefig('figures/nets_' + design.getName() + '.png')
|
|
334
|
+
#
|
|
335
|
+
# flat_primitives_series = pandas.Series(design_stats.flat_primitives)
|
|
336
|
+
# primitives_plot = flat_primitives_series.plot(kind='bar',
|
|
337
|
+
# title='Number of primitives for\n' + design.getName(),
|
|
338
|
+
# xlabel='primitive', ylabel='number of flat instances')
|
|
339
|
+
# primitives_plot.set_yscale('log')
|
|
340
|
+
# primitives_figure = primitives_plot.get_figure()
|
|
341
|
+
# primitives_figure.tight_layout()
|
|
342
|
+
# primitives_figure.savefig('figures/flat_primitives_' + design.getName() + '.png')
|
|
343
|
+
|
|
344
|
+
|
|
345
|
+
def convert_instance_stats_to_json(instance_stats):
|
|
346
|
+
json_top = list()
|
|
347
|
+
for _, value in instance_stats.hier_instances.items():
|
|
348
|
+
nb_primitives = sum(value.basic_primitives.values())
|
|
349
|
+
+sum(value.primitives.values())
|
|
350
|
+
nb_terms = sum(value.terms.values())
|
|
351
|
+
nb_nets = sum(value.net_stats.keys())
|
|
352
|
+
nb_ins = sum(value.ins.values()) + nb_primitives
|
|
353
|
+
json_top.append(
|
|
354
|
+
{
|
|
355
|
+
"Name": value.name,
|
|
356
|
+
"primitives": nb_primitives,
|
|
357
|
+
"instances": nb_ins,
|
|
358
|
+
"terms": nb_terms,
|
|
359
|
+
"nets": nb_nets,
|
|
360
|
+
# "primitives": value.primitives,
|
|
361
|
+
# "flat_basic_primitives": value.flat_basic_primitives,
|
|
362
|
+
# "flat_primitives": value.flat_primitives,
|
|
363
|
+
# "blackboxes": value.blackboxes,
|
|
364
|
+
# "flat_blackboxes": value.flat_blackboxes,
|
|
365
|
+
# "ins": value.ins,
|
|
366
|
+
# "flat_ins": value.flat_ins,
|
|
367
|
+
# "terms": value.terms,
|
|
368
|
+
# "bit_terms": value.bit_terms,
|
|
369
|
+
# "net_stats": value.net_stats,
|
|
370
|
+
}
|
|
371
|
+
)
|
|
372
|
+
return json_top
|
|
373
|
+
|
|
374
|
+
|
|
375
|
+
def dump_instance_stats_json(instance, path: str):
|
|
376
|
+
instances_stats = InstancesStats()
|
|
377
|
+
compute_instance_stats(instance, instances_stats)
|
|
378
|
+
json_dict = convert_instance_stats_to_json(instances_stats)
|
|
379
|
+
with open(path, "w") as f:
|
|
380
|
+
json.dump(json_dict, f, indent=4)
|
|
381
|
+
|
|
382
|
+
|
|
383
|
+
def dump_instance_stats_text(instance, path: str):
|
|
384
|
+
instances_stats = InstancesStats()
|
|
385
|
+
compute_instance_stats(instance, instances_stats)
|
|
386
|
+
instances_stats.dump_instance_stats_text(instance, path)
|
|
387
|
+
|
|
388
|
+
|
|
389
|
+
def dump_constants(design, analyzed_models):
|
|
390
|
+
if design.isPrimitive():
|
|
391
|
+
return
|
|
392
|
+
if design in analyzed_models:
|
|
393
|
+
return
|
|
394
|
+
analyzed_models.add(design)
|
|
395
|
+
for bitnet in design.getBitNets():
|
|
396
|
+
if bitnet.isConstant():
|
|
397
|
+
message = f"In design {design.getName()}, \
|
|
398
|
+
constant net {bitnet.getName()} \
|
|
399
|
+
of type {bitnet.getTypeAsString()}"
|
|
400
|
+
logging.info(message)
|
|
401
|
+
if all(False for _ in bitnet.getComponents()):
|
|
402
|
+
logging.info(" with zero connections\n")
|
|
403
|
+
else:
|
|
404
|
+
logging.info(" connected to:\n")
|
|
405
|
+
for component in bitnet.getComponents():
|
|
406
|
+
logging.info(str(component) + "\n")
|
|
407
|
+
|
|
408
|
+
for ins in design.getInstances():
|
|
409
|
+
model = ins.getModel()
|
|
410
|
+
dump_constants(model, analyzed_models)
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
Version: 1.11.2
|
|
2
|
+
Arguments: ['C:\\hostedtoolcache\\windows\\Python\\3.11.9\\x64\\Scripts\\delvewheel', 'repair', '-v', '--ignore-existing', '--analyze-existing', '--include-imports', '--add-path', 'C:\\Users\\runneradmin\\vcpkg\\installed\\x64-windows\\bin', '-w', 'C:\\Users\\runneradmin\\AppData\\Local\\Temp\\cibw-run-g372w1d8\\cp314-win_amd64\\repaired_wheel', 'C:\\Users\\runneradmin\\AppData\\Local\\Temp\\cibw-run-g372w1d8\\cp314-win_amd64\\built_wheel\\najaeda-0.3.3-cp314-cp314-win_amd64.whl']
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
Metadata-Version: 2.2
|
|
2
|
+
Name: najaeda
|
|
3
|
+
Version: 0.3.3
|
|
4
|
+
Summary: Naja EDA Python package
|
|
5
|
+
Author-Email: Naja Authors <contact@keplertech.io>
|
|
6
|
+
License: Apache License 2.0
|
|
7
|
+
Classifier: Development Status :: 4 - Beta
|
|
8
|
+
Classifier: Intended Audience :: Developers
|
|
9
|
+
Classifier: License :: OSI Approved :: Apache Software License
|
|
10
|
+
Classifier: Operating System :: MacOS
|
|
11
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
12
|
+
Classifier: Operating System :: Microsoft :: Windows
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
19
|
+
Classifier: Topic :: Scientific/Engineering :: Electronic Design Automation (EDA)
|
|
20
|
+
Project-URL: Homepage, https://github.com/najaeda/naja
|
|
21
|
+
Requires-Python: >=3.8
|
|
22
|
+
Description-Content-Type: text/x-rst
|
|
23
|
+
|
|
24
|
+
najaeda Python Package
|
|
25
|
+
=======================
|
|
26
|
+
|
|
27
|
+
najaeda is a Python package that provides data structures and APIs for developing post-synthesis Electronic Design Automation (EDA) algorithms.
|
|
28
|
+
|
|
29
|
+
najaeda provides a powerful yet simple framework designed to help software
|
|
30
|
+
and hardware developers efficiently navigate and manipulate electronic
|
|
31
|
+
design automation (EDA) workflows.
|
|
32
|
+
|
|
33
|
+
With najaeda, you can:
|
|
34
|
+
|
|
35
|
+
* Explore Netlists with Ease:
|
|
36
|
+
|
|
37
|
+
* Navigate netlist hierarchy and connectivity effortlessly.
|
|
38
|
+
* Browse at multiple levels of detail:
|
|
39
|
+
|
|
40
|
+
* Bit-level or bus-level granularity.
|
|
41
|
+
* Instance-by-instance exploration or flattened views at the primitives level.
|
|
42
|
+
* Localized per-instance connections or comprehensive equipotential views.
|
|
43
|
+
|
|
44
|
+
* Perform ECO (Engineering Change Order) Transformations:
|
|
45
|
+
|
|
46
|
+
* Seamlessly apply and manage changes to your designs.
|
|
47
|
+
|
|
48
|
+
* Prototype EDA Ideas Quickly:
|
|
49
|
+
|
|
50
|
+
* Use an intuitive API to experiment with new EDA concepts and workflows.
|
|
51
|
+
|
|
52
|
+
* Develop Custom EDA Tools:
|
|
53
|
+
|
|
54
|
+
* Build fast, tailored tools for solving specific challenges without relying on costly, proprietary EDA software.
|
|
55
|
+
|
|
56
|
+
najaeda empowers developers to innovate, adapt, and accelerate their EDA
|
|
57
|
+
processes with minimal overhead.
|
|
58
|
+
|
|
59
|
+
najaeda is the Python counterpart of the `Naja C++ project <https://github.com/najaeda/naja>`_.
|
|
60
|
+
|
|
61
|
+
If you find this project useful, please consider `starring it on GitHub <https://github.com/najaeda/naja>`_ to show your support.
|
|
62
|
+
|
|
63
|
+
Feel free to reach out to us anytime at `contact@keplertech.io <mailto:contact@keplertech.io>`_.
|
|
64
|
+
|
|
65
|
+
Installation
|
|
66
|
+
------------
|
|
67
|
+
|
|
68
|
+
Install Naja EDA using pip:
|
|
69
|
+
|
|
70
|
+
.. code-block:: bash
|
|
71
|
+
|
|
72
|
+
pip install najaeda
|
|
73
|
+
|
|
74
|
+
Quick Start
|
|
75
|
+
-----------
|
|
76
|
+
|
|
77
|
+
To quickly explore what **najaeda** can do, launch the interactive tutorial notebook on Google Colab:
|
|
78
|
+
|
|
79
|
+
.. image:: https://colab.research.google.com/assets/colab-badge.svg
|
|
80
|
+
:target: https://colab.research.google.com/github/najaeda/najaeda-tutorials/blob/main/notebooks/01_getting_started.ipynb
|
|
81
|
+
:alt: Open in Colab
|
|
82
|
+
|
|
83
|
+
Documentation
|
|
84
|
+
-------------
|
|
85
|
+
|
|
86
|
+
Naja EDA online documentation is available `here <https://najaeda.readthedocs.io/en/latest/index.html>`_.
|
|
87
|
+
|
|
88
|
+
Examples
|
|
89
|
+
--------
|
|
90
|
+
|
|
91
|
+
A list of examples can be found in this
|
|
92
|
+
documentation `section <https://najaeda.readthedocs.io/en/latest/examples.html>`_.
|
|
93
|
+
|
|
94
|
+
Support
|
|
95
|
+
-------
|
|
96
|
+
If you encounter any issues or have questions, please report them on the
|
|
97
|
+
`Naja issue tracker <https://github.com/najaeda/naja/issues>`_.
|
|
98
|
+
|
|
99
|
+
You’re also welcome to join the discussion on Matrix:
|
|
100
|
+
|
|
101
|
+
.. image:: https://img.shields.io/badge/Matrix-Join%20Chat-success?logo=matrix
|
|
102
|
+
:target: https://matrix.to/#/#naja:fossi-chat.org
|
|
103
|
+
:alt: Join the Matrix chat
|
|
104
|
+
|
|
105
|
+
License
|
|
106
|
+
-------
|
|
107
|
+
This project is licensed under the Apache License 2.0. \
|
|
108
|
+
See the `LICENSE <https://github.com/najaeda/naja/blob/main/LICENSE>`_ file for details.
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
najaeda/instance_visitor.py,sha256=vwymIJ3_-iIUKdcRt-ZXPcDwmp0UKsNCyDP6Z0ue7zA,1573
|
|
2
|
+
najaeda/naja.pyd,sha256=EekzDdcxLeEUs2lqRl1opncouJb8y_c_vqHZdKzd0wc,210944
|
|
3
|
+
najaeda/naja_bne.dll,sha256=eijuKTpU_tLgQF6ZDsc2-zCsuc2yO9iv1R9SfDocPVs,115200
|
|
4
|
+
najaeda/naja_dnl.dll,sha256=CjvDZZOb9VHcbjf99-lZLyMQxQPHNyvDxY4X_b8VCC4,128000
|
|
5
|
+
najaeda/naja_metrics.dll,sha256=fw3zXBI7c8-_zHKGmYa8yuLxS_3FSWi1hDmSCRrqk6U,198656
|
|
6
|
+
najaeda/naja_nl.dll,sha256=RB6FsB60tSPRkrLUrlqng9g8LM88ZOL9Xr5RhXIh8UA,970752
|
|
7
|
+
najaeda/naja_opt.dll,sha256=6wk2beYaAxX3sNQ9u6RzwBAjBFmFEspbgxsrvBH-yIs,238080
|
|
8
|
+
najaeda/naja_python.dll,sha256=mFdpJQ9GoHtMjx2ij8erOVRXob7VJ70BMSUXGacjqas,976384
|
|
9
|
+
najaeda/netlist.py,sha256=RMdEgQH3n9fXID7No5MAGRK4RATjJtRi3dF9Sg-ZIPk,69191
|
|
10
|
+
najaeda/net_visitor.py,sha256=XrGiT1JKIF8MYc2R-SgUVqxQqIBQgtcfIyYU2yURz6M,1993
|
|
11
|
+
najaeda/pandas_stats.py,sha256=vA3o45sDJ4xNq37fCjofH03aCPjxjuaE2XmT-vbYaAA,1102
|
|
12
|
+
najaeda/stats.py,sha256=pzPNyxxa8H2pwjj9ACN3F7r6OT7OMokNWYAvSCa965E,16517
|
|
13
|
+
najaeda/_version.py,sha256=DzMRseGe_crufJHgXzWOEYnrxnrQJFpBxtvlf17Ey0A,348
|
|
14
|
+
najaeda/__init__.py,sha256=tt9IOQGlxFk3SznR2IKoghuQC9DYxZeWHz2uhFnhaFQ,550
|
|
15
|
+
najaeda/docs/.readthedocs.yaml,sha256=HNNsm-hz7lPVHfsKyEPbMWUHwRVxz9BQp0wIvNVGXQc,815
|
|
16
|
+
najaeda/docs/requirements.txt,sha256=whi2b4ITj5RHuTa9o-63dBlNZS97dflaMwqWdMgEtDs,128
|
|
17
|
+
najaeda/docs/source/api.rst,sha256=XrEya-N-4puXDjhlBcduvVH6Kc4jZWmXxRotv2U0v18,157
|
|
18
|
+
najaeda/docs/source/common_classes.rst,sha256=GYpUAoF9p85dFUaaKhADNA5un2SqsAlsisrzhy-DDCc,191
|
|
19
|
+
najaeda/docs/source/conf.py,sha256=Od3yuAs4UOmwew4ZD9ot7fDt5kkGG64H8vcQruaTzXM,2077
|
|
20
|
+
najaeda/docs/source/equipotential.rst,sha256=9DsSzfqWGC4NPqHoiitMXS6d1cNG2eAPeOkhof6A2NM,349
|
|
21
|
+
najaeda/docs/source/examples.rst.in,sha256=oPIRgGLmDRHbIiShWeM1P_aI5xj18DeLatP1IrdHrho,2156
|
|
22
|
+
najaeda/docs/source/index.rst,sha256=GXd3weCxyOblxj4TCXr43WbH2cRutE7MI0Q4T9Tgbj4,403
|
|
23
|
+
najaeda/docs/source/instance.rst,sha256=11GnhzjTc9ihDrZFXyqV9EbDsP3CM8VO02bCg8xiomo,1043
|
|
24
|
+
najaeda/docs/source/introduction.rst,sha256=fM47hKcMFoNfZoa6i6rfO9hdduSgKjSwCGBCjc1Y9hs,2723
|
|
25
|
+
najaeda/docs/source/net.rst,sha256=mTdZpKhEMAkaZBZXN2rDWJvyiZmlWBJbjlwdwmAEwCk,751
|
|
26
|
+
najaeda/docs/source/netlist_classes.rst,sha256=SsbBoE4z-MxWwJgU5T_iOKK_GKJ29jyYWSd7yhF0F14,142
|
|
27
|
+
najaeda/docs/source/preprocessor.py,sha256=JG_sHgCINp4IJzewz75_fckDMbESTcHrcLWOaL6UM0I,2697
|
|
28
|
+
najaeda/docs/source/term.rst,sha256=y48_Fdert0YCC5Kjoe98t2fczH-w20JfIL9iHzT_MAM,709
|
|
29
|
+
najaeda/docs/source/visitors.rst,sha256=FWcXKVNNjMGjFJR8QHnv1duVpmib2gnXC9HNPM1G6wk,239
|
|
30
|
+
najaeda/native/stats.py,sha256=sTEx4u2QYIrcgZllL2SjQvPXGVhqQERsshOvHWwwLng,13404
|
|
31
|
+
najaeda/native/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
32
|
+
najaeda/primitives/utils.py,sha256=oC4zRs-RVwghZxNccJCaNFWKvyb46z53AikKWdcSe0U,680
|
|
33
|
+
najaeda/primitives/xilinx.py,sha256=NriL16J52-sSvL8zAqUK4oVYDQ7nadN7JvRVTz10_Pc,31473
|
|
34
|
+
najaeda/primitives/yosys.py,sha256=vDo9e5nPBUKP3B0kUqVKbp4_m-WgdPWFspv4YgaLUYU,13840
|
|
35
|
+
najaeda/primitives/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
36
|
+
najaeda-0.3.3.dist-info/DELVEWHEEL,sha256=BI9ImydNgL0KSuyh-QfNNFRJYe08mbtRn9IE3f3XrVk,502
|
|
37
|
+
najaeda-0.3.3.dist-info/METADATA,sha256=1jmkb34z4w5HBU-FKEjNgLbf-M9pLT93J8Te2aDKzP0,3759
|
|
38
|
+
najaeda-0.3.3.dist-info/RECORD,,
|
|
39
|
+
najaeda-0.3.3.dist-info/WHEEL,sha256=gWMs92Yhbl9pSGNRFWCXG1mfeuNl7HhxcJG5aLu4nQc,106
|
|
40
|
+
najaeda-0.3.3.dist-info/licenses/AUTHORS,sha256=CCabv7V3a2ngY1f3faiauRBtE9Dp0ba_kGg4-v-E0mw,384
|
|
41
|
+
najaeda-0.3.3.dist-info/licenses/LICENSE,sha256=HrhfyXIkWY2tGFK11kg7vPCqhgh5DcxleloqdhrpyMY,11558
|
|
42
|
+
najaeda.libs/msvcp140.dll,sha256=pMIim9wqKmMKzcCVtNhgCOXD47x3cxdDVPPaT1vrnN4,575056
|
|
43
|
+
najaeda.libs/tbb12.dll,sha256=iYd4NxYqMA8TnJF__A0o_0kguotJbkbidsBB7yH70iA,347136
|
|
44
|
+
najaeda.libs/tbbmalloc.dll,sha256=7eYciyWpgXZGYhylXyyMkzVCkRsy5OwqAlrlIAnqlaY,113664
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# This is the list of Naja authors for copyright purposes.
|
|
2
|
+
#
|
|
3
|
+
# This does not necessarily list everyone who has contributed code, since in
|
|
4
|
+
# some cases, their employer may be the copyright holder. To see the full list
|
|
5
|
+
# of contributors, see the revision history in source control.
|
|
6
|
+
Christophe Alexandre <christophe.alexandre@keplertech.io>
|
|
7
|
+
Noam Cohen <noam.cohen@keplertech.io>
|