digsim-logic-simulator 0.3.0__py3-none-any.whl → 0.5.0__py3-none-any.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 digsim-logic-simulator might be problematic. Click here for more details.
- digsim/__init__.py +1 -1
- digsim/app/__main__.py +1 -1
- digsim/app/gui/__init__.py +1 -1
- digsim/app/gui/_circuit_area.py +1 -6
- digsim/app/gui/_component_selection.py +1 -3
- digsim/app/gui/_main_window.py +1 -3
- digsim/app/gui/_top_bar.py +1 -4
- digsim/app/gui/_warning_dialog.py +1 -3
- digsim/app/gui_objects/__init__.py +1 -1
- digsim/app/gui_objects/_bus_bit_object.py +2 -5
- digsim/app/gui_objects/_buzzer_object.py +1 -1
- digsim/app/gui_objects/_component_context_menu.py +2 -2
- digsim/app/gui_objects/_component_object.py +8 -10
- digsim/app/gui_objects/_component_port_item.py +1 -1
- digsim/app/gui_objects/_dip_switch_object.py +2 -5
- digsim/app/gui_objects/_gui_note_object.py +1 -1
- digsim/app/gui_objects/_gui_object_factory.py +1 -1
- digsim/app/gui_objects/_hexdigit_object.py +1 -1
- digsim/app/gui_objects/_image_objects.py +2 -4
- digsim/app/gui_objects/_label_object.py +1 -1
- digsim/app/gui_objects/_logic_analyzer_object.py +1 -2
- digsim/app/gui_objects/_seven_segment_object.py +2 -4
- digsim/app/gui_objects/_shortcut_objects.py +2 -4
- digsim/app/gui_objects/_yosys_object.py +1 -1
- digsim/app/model/__init__.py +1 -1
- digsim/app/model/_model.py +15 -18
- digsim/app/model/_model_components.py +12 -15
- digsim/app/model/_model_objects.py +30 -26
- digsim/app/model/_model_settings.py +1 -5
- digsim/app/model/_model_shortcuts.py +3 -3
- digsim/app/settings/__init__.py +1 -1
- digsim/app/settings/_component_settings.py +5 -7
- digsim/app/settings/_gui_settings.py +1 -3
- digsim/app/settings/_shortcut_dialog.py +1 -3
- digsim/circuit/__init__.py +1 -1
- digsim/circuit/_circuit.py +21 -64
- digsim/circuit/_waves_writer.py +1 -4
- digsim/circuit/components/__init__.py +1 -1
- digsim/circuit/components/_bus_bits.py +2 -2
- digsim/circuit/components/_button.py +1 -1
- digsim/circuit/components/_buzzer.py +2 -2
- digsim/circuit/components/_clock.py +2 -2
- digsim/circuit/components/_dip_switch.py +2 -2
- digsim/circuit/components/_gates.py +7 -9
- digsim/circuit/components/_hexdigit.py +3 -3
- digsim/circuit/components/_ic.py +1 -0
- digsim/circuit/components/_label_wire.py +4 -4
- digsim/circuit/components/_led.py +1 -1
- digsim/circuit/components/_logic_analyzer.py +2 -2
- digsim/circuit/components/_note.py +1 -1
- digsim/circuit/components/_on_off_switch.py +1 -1
- digsim/circuit/components/_seven_segment.py +2 -1
- digsim/circuit/components/_static_level.py +1 -1
- digsim/circuit/components/_static_value.py +2 -2
- digsim/circuit/components/_yosys_atoms.py +1 -6
- digsim/circuit/components/_yosys_component.py +1 -4
- digsim/circuit/components/atoms/__init__.py +1 -1
- digsim/circuit/components/atoms/_component.py +2 -44
- digsim/circuit/components/atoms/_port.py +7 -18
- digsim/storage_model/__init__.py +7 -0
- digsim/storage_model/_app.py +53 -0
- digsim/storage_model/_circuit.py +118 -0
- digsim/synth/__init__.py +1 -1
- digsim/synth/__main__.py +1 -1
- digsim/synth/_synthesis.py +10 -2
- digsim/utils/__init__.py +1 -1
- {digsim_logic_simulator-0.3.0.dist-info → digsim_logic_simulator-0.5.0.dist-info}/METADATA +12 -7
- digsim_logic_simulator-0.5.0.dist-info/RECORD +105 -0
- {digsim_logic_simulator-0.3.0.dist-info → digsim_logic_simulator-0.5.0.dist-info}/WHEEL +1 -1
- digsim_logic_simulator-0.3.0.dist-info/RECORD +0 -102
- {digsim_logic_simulator-0.3.0.dist-info → digsim_logic_simulator-0.5.0.dist-info}/LICENSE.md +0 -0
- {digsim_logic_simulator-0.3.0.dist-info → digsim_logic_simulator-0.5.0.dist-info}/top_level.txt +0 -0
|
@@ -1,10 +1,8 @@
|
|
|
1
|
-
# Copyright (c) Fredrik Andersson, 2023
|
|
1
|
+
# Copyright (c) Fredrik Andersson, 2023-2024
|
|
2
2
|
# All rights reserved
|
|
3
3
|
|
|
4
4
|
"""The GUI settings dialog"""
|
|
5
5
|
|
|
6
|
-
# pylint: disable=too-few-public-methods
|
|
7
|
-
|
|
8
6
|
from PySide6.QtCore import Qt
|
|
9
7
|
from PySide6.QtWidgets import QCheckBox, QComboBox, QDialog, QDialogButtonBox, QGridLayout, QLabel
|
|
10
8
|
|
|
@@ -1,10 +1,8 @@
|
|
|
1
|
-
# Copyright (c) Fredrik Andersson, 2023
|
|
1
|
+
# Copyright (c) Fredrik Andersson, 2023-2024
|
|
2
2
|
# All rights reserved
|
|
3
3
|
|
|
4
4
|
"""The shurtcut dialog"""
|
|
5
5
|
|
|
6
|
-
# pylint: disable=too-few-public-methods
|
|
7
|
-
|
|
8
6
|
from PySide6.QtCore import Qt
|
|
9
7
|
from PySide6.QtWidgets import QComboBox, QDialog, QDialogButtonBox, QLabel, QVBoxLayout
|
|
10
8
|
|
digsim/circuit/__init__.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Copyright (c) Fredrik Andersson, 2023
|
|
2
2
|
# All rights reserved
|
|
3
3
|
|
|
4
|
-
"""
|
|
4
|
+
"""All classes within digsim.circuit namespace"""
|
|
5
5
|
|
|
6
6
|
from ._circuit import Circuit # noqa: F401
|
|
7
7
|
from .components import PortConnectionError # noqa: F401
|
digsim/circuit/_circuit.py
CHANGED
|
@@ -1,18 +1,16 @@
|
|
|
1
|
-
# Copyright (c) Fredrik Andersson, 2023
|
|
1
|
+
# Copyright (c) Fredrik Andersson, 2023-2024
|
|
2
2
|
# All rights reserved
|
|
3
3
|
|
|
4
4
|
"""
|
|
5
5
|
Module that handles the circuit simulation of components
|
|
6
6
|
"""
|
|
7
7
|
|
|
8
|
-
# pylint: disable=too-many-public-methods
|
|
9
|
-
# pylint: disable=too-many-arguments
|
|
10
|
-
|
|
11
|
-
import json
|
|
12
8
|
import os
|
|
13
9
|
|
|
10
|
+
from digsim.storage_model import CircuitDataClass, CircuitFileDataClass
|
|
11
|
+
|
|
14
12
|
from ._waves_writer import WavesWriter
|
|
15
|
-
from .components.atoms import
|
|
13
|
+
from .components.atoms import DigsimException
|
|
16
14
|
|
|
17
15
|
|
|
18
16
|
class CircuitError(DigsimException):
|
|
@@ -73,6 +71,11 @@ class Circuit:
|
|
|
73
71
|
else:
|
|
74
72
|
self._vcd = None
|
|
75
73
|
|
|
74
|
+
@property
|
|
75
|
+
def name(self):
|
|
76
|
+
"""Get the circuit name"""
|
|
77
|
+
return self._name
|
|
78
|
+
|
|
76
79
|
@property
|
|
77
80
|
def time_ns(self):
|
|
78
81
|
"""Get the current simulation time (ns)"""
|
|
@@ -246,65 +249,24 @@ class Circuit:
|
|
|
246
249
|
return comp
|
|
247
250
|
raise CircuitError(f"Component '{component_name}' not found")
|
|
248
251
|
|
|
249
|
-
def
|
|
250
|
-
source_component_name = source.split(".")[0]
|
|
251
|
-
source_port_name = source.split(".")[1]
|
|
252
|
-
dest_component_name = dest.split(".")[0]
|
|
253
|
-
dest_port_name = dest.split(".")[1]
|
|
254
|
-
|
|
255
|
-
source_component = self.get_component(source_component_name)
|
|
256
|
-
dest_componment = self.get_component(dest_component_name)
|
|
257
|
-
source_component.port(source_port_name).wire = dest_componment.port(dest_port_name)
|
|
258
|
-
|
|
259
|
-
def to_dict(self, folder=None):
|
|
252
|
+
def to_dataclass(self, folder=None):
|
|
260
253
|
"""Generate dict from circuit, used when storing circuit"""
|
|
261
254
|
if self._name is None:
|
|
262
255
|
raise CircuitError("Circuit must have a name")
|
|
263
|
-
|
|
264
256
|
self._folder = folder
|
|
265
|
-
|
|
266
|
-
for comp in self.get_toplevel_components():
|
|
267
|
-
components_list.append(comp.to_dict())
|
|
257
|
+
return CircuitDataClass.from_circuit(self)
|
|
268
258
|
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
for port in comp.ports:
|
|
272
|
-
port_conn_list = port.to_dict_list()
|
|
273
|
-
connection_list.extend(port_conn_list)
|
|
274
|
-
|
|
275
|
-
circuit_dict = {
|
|
276
|
-
"circuit": {
|
|
277
|
-
"name": self._name,
|
|
278
|
-
"components": components_list,
|
|
279
|
-
"wires": connection_list,
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
return circuit_dict
|
|
284
|
-
|
|
285
|
-
def from_dict(
|
|
286
|
-
self, circuit_dict, folder=None, component_exceptions=True, connect_exceptions=True
|
|
259
|
+
def from_dataclass(
|
|
260
|
+
self, circuit_dc, folder=None, component_exceptions=True, connect_exceptions=True
|
|
287
261
|
):
|
|
288
262
|
"""Clear circuit and add components from dict"""
|
|
289
263
|
self._folder = folder
|
|
290
264
|
self.clear()
|
|
291
|
-
if "circuit" not in circuit_dict:
|
|
292
|
-
raise CircuitError("No 'circuit' in JSON")
|
|
293
|
-
json_circuit = circuit_dict["circuit"]
|
|
294
|
-
if "name" not in json_circuit:
|
|
295
|
-
raise CircuitError("No 'circuit/name' in JSON")
|
|
296
|
-
self._name = json_circuit["name"]
|
|
297
|
-
if "components" not in json_circuit:
|
|
298
|
-
raise CircuitError("No 'circuit/components' in JSON")
|
|
299
|
-
json_components = json_circuit["components"]
|
|
300
|
-
if "wires" not in json_circuit:
|
|
301
|
-
raise CircuitError("No 'circuit/connections' in JSON")
|
|
302
|
-
json_connections = json_circuit["wires"]
|
|
303
265
|
|
|
304
266
|
exception_str_list = []
|
|
305
|
-
for
|
|
267
|
+
for component in circuit_dc.components:
|
|
306
268
|
try:
|
|
307
|
-
|
|
269
|
+
component.create(self)
|
|
308
270
|
except DigsimException as exc:
|
|
309
271
|
if component_exceptions:
|
|
310
272
|
raise exc
|
|
@@ -313,9 +275,9 @@ class Circuit:
|
|
|
313
275
|
if component_exceptions:
|
|
314
276
|
raise exc
|
|
315
277
|
exception_str_list.append(f"{str(exc.__class__.__name__)}:{str(exc)}")
|
|
316
|
-
for
|
|
278
|
+
for wire in circuit_dc.wires:
|
|
317
279
|
try:
|
|
318
|
-
|
|
280
|
+
wire.connect(self)
|
|
319
281
|
except DigsimException as exc:
|
|
320
282
|
if connect_exceptions:
|
|
321
283
|
raise exc
|
|
@@ -325,15 +287,10 @@ class Circuit:
|
|
|
325
287
|
|
|
326
288
|
def to_json_file(self, filename):
|
|
327
289
|
"""Store circuit in json file"""
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
with open(filename, mode="w", encoding="utf-8") as json_file:
|
|
332
|
-
json_file.write(json_object)
|
|
290
|
+
circuitfile_dc = CircuitFileDataClass(circuit=self.to_dataclass())
|
|
291
|
+
circuitfile_dc.save(filename)
|
|
333
292
|
|
|
334
293
|
def from_json_file(self, filename, folder=None):
|
|
335
294
|
"""Load circuit from json file"""
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
circuit_dict = json.load(json_file)
|
|
339
|
-
self.from_dict(circuit_dict, folder)
|
|
295
|
+
file_dc = CircuitFileDataClass.load(filename)
|
|
296
|
+
self.from_dataclass(file_dc.circuit, folder)
|
digsim/circuit/_waves_writer.py
CHANGED
|
@@ -1,13 +1,10 @@
|
|
|
1
|
-
# Copyright (c) Fredrik Andersson, 2023
|
|
1
|
+
# Copyright (c) Fredrik Andersson, 2023-2024
|
|
2
2
|
# All rights reserved
|
|
3
3
|
|
|
4
4
|
"""
|
|
5
5
|
Module that handles the creation of vcd files
|
|
6
6
|
"""
|
|
7
7
|
|
|
8
|
-
# pylint: disable=consider-using-with
|
|
9
|
-
# pylint: disable=import-error
|
|
10
|
-
|
|
11
8
|
from vcd import VCDWriter
|
|
12
9
|
|
|
13
10
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Copyright (c) Fredrik Andersson, 2023
|
|
2
2
|
# All rights reserved
|
|
3
3
|
|
|
4
|
-
"""
|
|
4
|
+
"""All classes within digsim.circuit.components namespace"""
|
|
5
5
|
|
|
6
6
|
from ._bus_bits import Bus2Wires, Wires2Bus # noqa: F401
|
|
7
7
|
from ._button import PushButton # noqa: F401
|
|
@@ -29,7 +29,7 @@ class Bus2Wires(Component):
|
|
|
29
29
|
def get_parameters(cls):
|
|
30
30
|
return {
|
|
31
31
|
"width": {
|
|
32
|
-
"type": int,
|
|
32
|
+
"type": "int",
|
|
33
33
|
"min": 2,
|
|
34
34
|
"max": 32,
|
|
35
35
|
"default": 2,
|
|
@@ -59,7 +59,7 @@ class Wires2Bus(Component):
|
|
|
59
59
|
def get_parameters(cls):
|
|
60
60
|
return {
|
|
61
61
|
"width": {
|
|
62
|
-
"type": int,
|
|
62
|
+
"type": "int",
|
|
63
63
|
"min": 2,
|
|
64
64
|
"max": 32,
|
|
65
65
|
"default": 2,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Copyright (c) Fredrik Andersson, 2023
|
|
2
2
|
# All rights reserved
|
|
3
3
|
|
|
4
|
-
"""
|
|
4
|
+
"""Module with the Buzzer component"""
|
|
5
5
|
|
|
6
6
|
from .atoms import CallbackComponent, PortIn
|
|
7
7
|
|
|
@@ -36,7 +36,7 @@ class Buzzer(CallbackComponent):
|
|
|
36
36
|
def get_parameters(cls):
|
|
37
37
|
return {
|
|
38
38
|
"tone": {
|
|
39
|
-
"type": list,
|
|
39
|
+
"type": "list",
|
|
40
40
|
"items": ["A", "B", "C", "D", "E", "F", "G"],
|
|
41
41
|
"default": "A",
|
|
42
42
|
"description": "Buzzer tone",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Copyright (c) Fredrik Andersson, 2023
|
|
2
2
|
# All rights reserved
|
|
3
3
|
|
|
4
|
-
"""
|
|
4
|
+
"""Clock component module"""
|
|
5
5
|
|
|
6
6
|
from .atoms import CallbackComponent, PortOutDelta, PortOutImmediate
|
|
7
7
|
|
|
@@ -44,7 +44,7 @@ class Clock(CallbackComponent):
|
|
|
44
44
|
def get_parameters(cls):
|
|
45
45
|
return {
|
|
46
46
|
"frequency": {
|
|
47
|
-
"type": int,
|
|
47
|
+
"type": "int",
|
|
48
48
|
"min": 1,
|
|
49
49
|
"max": 50,
|
|
50
50
|
"default": 1,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Copyright (c) Fredrik Andersson, 2023
|
|
2
2
|
# All rights reserved
|
|
3
3
|
|
|
4
|
-
"""
|
|
4
|
+
"""A Dip-switch component"""
|
|
5
5
|
|
|
6
6
|
from .atoms import CallbackComponent, PortOutImmediate
|
|
7
7
|
|
|
@@ -64,7 +64,7 @@ class DipSwitch(CallbackComponent):
|
|
|
64
64
|
def get_parameters(cls):
|
|
65
65
|
return {
|
|
66
66
|
"bits": {
|
|
67
|
-
"type": int,
|
|
67
|
+
"type": "int",
|
|
68
68
|
"min": 2,
|
|
69
69
|
"max": 8,
|
|
70
70
|
"default": 8,
|
|
@@ -1,9 +1,7 @@
|
|
|
1
|
-
# Copyright (c) Fredrik Andersson, 2023
|
|
1
|
+
# Copyright (c) Fredrik Andersson, 2023-2024
|
|
2
2
|
# All rights reserved
|
|
3
3
|
|
|
4
|
-
"""
|
|
5
|
-
|
|
6
|
-
# pylint: disable=too-many-arguments
|
|
4
|
+
"""Module with the basic logic gates"""
|
|
7
5
|
|
|
8
6
|
import math
|
|
9
7
|
|
|
@@ -46,7 +44,7 @@ class ConfigPortsComponent(Component):
|
|
|
46
44
|
def get_parameters(cls):
|
|
47
45
|
return {
|
|
48
46
|
"ports": {
|
|
49
|
-
"type": int,
|
|
47
|
+
"type": "int",
|
|
50
48
|
"min": 2,
|
|
51
49
|
"max": 8,
|
|
52
50
|
"default": 2,
|
|
@@ -163,17 +161,17 @@ class DFF(Component):
|
|
|
163
161
|
def get_parameters(cls):
|
|
164
162
|
return {
|
|
165
163
|
"async_reset": {
|
|
166
|
-
"type": bool,
|
|
164
|
+
"type": "bool",
|
|
167
165
|
"default": False,
|
|
168
166
|
"description": "Use asynchronous reset",
|
|
169
167
|
},
|
|
170
168
|
"clock_enable": {
|
|
171
|
-
"type": bool,
|
|
169
|
+
"type": "bool",
|
|
172
170
|
"default": False,
|
|
173
171
|
"description": "Use clock enable",
|
|
174
172
|
},
|
|
175
173
|
"width": {
|
|
176
|
-
"type": int,
|
|
174
|
+
"type": "int",
|
|
177
175
|
"min": 1,
|
|
178
176
|
"max": 32,
|
|
179
177
|
"default": 1,
|
|
@@ -217,7 +215,7 @@ class MUX(Component):
|
|
|
217
215
|
"description": "Number of input ports",
|
|
218
216
|
},
|
|
219
217
|
"width": {
|
|
220
|
-
"type": int,
|
|
218
|
+
"type": "int",
|
|
221
219
|
"min": 1,
|
|
222
220
|
"max": 32,
|
|
223
221
|
"default": 1,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Copyright (c) Fredrik Andersson, 2023
|
|
2
2
|
# All rights reserved
|
|
3
3
|
|
|
4
|
-
"""
|
|
4
|
+
"""HexDigit component module"""
|
|
5
5
|
|
|
6
6
|
from .atoms import CallbackComponent, PortIn
|
|
7
7
|
|
|
@@ -68,14 +68,14 @@ class HexDigit(CallbackComponent):
|
|
|
68
68
|
def get_parameters(cls):
|
|
69
69
|
return {
|
|
70
70
|
"digits": {
|
|
71
|
-
"type": int,
|
|
71
|
+
"type": "int",
|
|
72
72
|
"min": 1,
|
|
73
73
|
"max": 8,
|
|
74
74
|
"default": 1,
|
|
75
75
|
"description": "Number of digits",
|
|
76
76
|
},
|
|
77
77
|
"dot": {
|
|
78
|
-
"type": bool,
|
|
78
|
+
"type": "bool",
|
|
79
79
|
"default": False,
|
|
80
80
|
"description": "Use decimal dot",
|
|
81
81
|
},
|
digsim/circuit/components/_ic.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Copyright (c) Fredrik Andersson, 2023
|
|
2
2
|
# All rights reserved
|
|
3
3
|
|
|
4
|
-
"""
|
|
4
|
+
"""Label Wire components module"""
|
|
5
5
|
|
|
6
6
|
from .atoms import Component, DigsimException, PortWire
|
|
7
7
|
|
|
@@ -106,14 +106,14 @@ class LabelWireIn(Component):
|
|
|
106
106
|
|
|
107
107
|
return {
|
|
108
108
|
"label": {
|
|
109
|
-
"type": str,
|
|
109
|
+
"type": "str",
|
|
110
110
|
"single_line": True,
|
|
111
111
|
"default": "WireLabel",
|
|
112
112
|
"description": "Label name",
|
|
113
113
|
"invalid_list": label_list,
|
|
114
114
|
},
|
|
115
115
|
"width": {
|
|
116
|
-
"type": int,
|
|
116
|
+
"type": "int",
|
|
117
117
|
"min": 1,
|
|
118
118
|
"max": 32,
|
|
119
119
|
"default": 1,
|
|
@@ -160,7 +160,7 @@ class LabelWireOut(Component):
|
|
|
160
160
|
|
|
161
161
|
return {
|
|
162
162
|
"label": {
|
|
163
|
-
"type": list,
|
|
163
|
+
"type": "list",
|
|
164
164
|
"items": label_list,
|
|
165
165
|
"description": "Select label",
|
|
166
166
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Copyright (c) Fredrik Andersson, 2023
|
|
2
2
|
# All rights reserved
|
|
3
3
|
|
|
4
|
-
"""
|
|
4
|
+
"""Module with Logic Analyzer component"""
|
|
5
5
|
|
|
6
6
|
from .atoms import CallbackComponent, PortOutDelta, PortWire
|
|
7
7
|
|
|
@@ -50,7 +50,7 @@ class LogicAnalyzer(CallbackComponent):
|
|
|
50
50
|
def get_parameters(cls):
|
|
51
51
|
return {
|
|
52
52
|
"sample_rate": {
|
|
53
|
-
"type": int,
|
|
53
|
+
"type": "int",
|
|
54
54
|
"min": 10,
|
|
55
55
|
"max": 100,
|
|
56
56
|
"default": 20,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Copyright (c) Fredrik Andersson, 2023
|
|
2
2
|
# All rights reserved
|
|
3
3
|
|
|
4
|
-
"""
|
|
4
|
+
"""Module with the Static Leve component"""
|
|
5
5
|
|
|
6
6
|
from .atoms import Component, PortOutImmediate
|
|
7
7
|
|
|
@@ -35,7 +35,7 @@ class StaticValue(Component):
|
|
|
35
35
|
"reconfigurable": True,
|
|
36
36
|
},
|
|
37
37
|
"width": {
|
|
38
|
-
"type": int,
|
|
38
|
+
"type": "int",
|
|
39
39
|
"min": 1,
|
|
40
40
|
"max": 16,
|
|
41
41
|
"default": 1,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright (c) Fredrik Andersson, 2023
|
|
1
|
+
# Copyright (c) Fredrik Andersson, 2023-2024
|
|
2
2
|
# All rights reserved
|
|
3
3
|
|
|
4
4
|
"""
|
|
@@ -8,11 +8,6 @@ All components are implemented from the specification in:
|
|
|
8
8
|
https://github.com/YosysHQ/yosys/blob/master/techlibs/common/simcells.v
|
|
9
9
|
"""
|
|
10
10
|
|
|
11
|
-
# pylint: disable=too-many-arguments
|
|
12
|
-
# pylint: disable=consider-using-in
|
|
13
|
-
# pylint: disable=too-many-lines
|
|
14
|
-
# pylint: disable=too-many-branches
|
|
15
|
-
|
|
16
11
|
from .atoms import Component, DigsimException, PortIn, PortOutDelta, PortWire
|
|
17
12
|
|
|
18
13
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright (c) Fredrik Andersson, 2023
|
|
1
|
+
# Copyright (c) Fredrik Andersson, 2023-2024
|
|
2
2
|
# All rights reserved
|
|
3
3
|
|
|
4
4
|
"""
|
|
@@ -6,9 +6,6 @@ Module with classes to create a yosys component
|
|
|
6
6
|
from a yosys json netlist.
|
|
7
7
|
"""
|
|
8
8
|
|
|
9
|
-
# pylint: disable=protected-access
|
|
10
|
-
# pylint: disable=too-many-instance-attributes
|
|
11
|
-
|
|
12
9
|
import json
|
|
13
10
|
|
|
14
11
|
import digsim.circuit.components._yosys_atoms
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Copyright (c) Fredrik Andersson, 2023
|
|
2
2
|
# All rights reserved
|
|
3
3
|
|
|
4
|
-
"""
|
|
4
|
+
"""All classes within digsim.circuit.components.atoms namespace"""
|
|
5
5
|
|
|
6
6
|
from ._component import ( # noqa: F401
|
|
7
7
|
CallbackComponent,
|
|
@@ -1,14 +1,10 @@
|
|
|
1
|
-
# Copyright (c) Fredrik Andersson, 2023
|
|
1
|
+
# Copyright (c) Fredrik Andersson, 2023-2024
|
|
2
2
|
# All rights reserved
|
|
3
3
|
|
|
4
|
-
"""
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
# pylint: disable=too-many-public-methods
|
|
4
|
+
"""This module contains the base classes for all component types"""
|
|
8
5
|
|
|
9
6
|
import abc
|
|
10
7
|
import copy
|
|
11
|
-
import importlib
|
|
12
8
|
|
|
13
9
|
from ._digsim_exception import DigsimException
|
|
14
10
|
|
|
@@ -169,44 +165,6 @@ class Component(abc.ABC):
|
|
|
169
165
|
comp_str += f"\n - O:{port.name()}={port.value}"
|
|
170
166
|
return comp_str
|
|
171
167
|
|
|
172
|
-
def to_dict(self):
|
|
173
|
-
"""Return the component information as a dict, used when storing a circuit"""
|
|
174
|
-
component_dict = {
|
|
175
|
-
"name": self.name(),
|
|
176
|
-
"display_name": self.display_name(),
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
module_split = type(self).__module__.split(".")
|
|
180
|
-
type_str = ""
|
|
181
|
-
for module in module_split:
|
|
182
|
-
if not module.startswith("_"):
|
|
183
|
-
type_str += f"{module}."
|
|
184
|
-
type_str += type(self).__name__
|
|
185
|
-
component_dict["type"] = type_str
|
|
186
|
-
component_dict["settings"] = self.settings_to_dict()
|
|
187
|
-
return component_dict
|
|
188
|
-
|
|
189
|
-
@classmethod
|
|
190
|
-
def from_dict(cls, circuit, json_component):
|
|
191
|
-
"""Factory: Create a component from a dict"""
|
|
192
|
-
component_name = json_component["name"]
|
|
193
|
-
component_type = json_component["type"]
|
|
194
|
-
component_settings = json_component.get("settings", {})
|
|
195
|
-
if "path" in component_settings:
|
|
196
|
-
component_settings["path"] = circuit.load_path(component_settings["path"])
|
|
197
|
-
|
|
198
|
-
display_name = json_component.get("display_name")
|
|
199
|
-
py_module_name = ".".join(component_type.split(".")[0:-1])
|
|
200
|
-
py_class_name = component_type.split(".")[-1]
|
|
201
|
-
|
|
202
|
-
module = importlib.import_module(py_module_name)
|
|
203
|
-
class_ = getattr(module, py_class_name)
|
|
204
|
-
component = class_(circuit=circuit, **component_settings)
|
|
205
|
-
component.set_name(component_name)
|
|
206
|
-
if display_name is not None:
|
|
207
|
-
component.set_display_name(display_name)
|
|
208
|
-
return component
|
|
209
|
-
|
|
210
168
|
@property
|
|
211
169
|
def has_action(self):
|
|
212
170
|
"""Return True if this component is interactive"""
|
|
@@ -1,9 +1,7 @@
|
|
|
1
|
-
# Copyright (c) Fredrik Andersson, 2023
|
|
1
|
+
# Copyright (c) Fredrik Andersson, 2023-2024
|
|
2
2
|
# All rights reserved
|
|
3
3
|
|
|
4
|
-
"""
|
|
5
|
-
|
|
6
|
-
# pylint: disable=too-many-public-methods
|
|
4
|
+
"""This module contains the classes for all component ports"""
|
|
7
5
|
|
|
8
6
|
import abc
|
|
9
7
|
|
|
@@ -33,6 +31,11 @@ class Port(abc.ABC):
|
|
|
33
31
|
self._edge_detect_value = "X"
|
|
34
32
|
self.update_wires("X")
|
|
35
33
|
|
|
34
|
+
@property
|
|
35
|
+
def wired_ports(self):
|
|
36
|
+
"""Get wires from thisport"""
|
|
37
|
+
return self._wired_ports
|
|
38
|
+
|
|
36
39
|
@property
|
|
37
40
|
def value(self):
|
|
38
41
|
"""Get the value of the port, can be "X" """
|
|
@@ -176,20 +179,6 @@ class Port(abc.ABC):
|
|
|
176
179
|
def __str__(self):
|
|
177
180
|
return f"{self._parent.name()}:{self._name}={self.value}"
|
|
178
181
|
|
|
179
|
-
def to_dict_list(self):
|
|
180
|
-
"""Output port connections as a dict, used when storing a circuit"""
|
|
181
|
-
port_conn_list = []
|
|
182
|
-
for port in self._wired_ports:
|
|
183
|
-
# Only add port on top-level components
|
|
184
|
-
if port.parent().is_toplevel():
|
|
185
|
-
port_conn_list.append(
|
|
186
|
-
{
|
|
187
|
-
"src": f"{self.parent().name()}.{self.name()}",
|
|
188
|
-
"dst": f"{port.parent().name()}.{port.name()}",
|
|
189
|
-
}
|
|
190
|
-
)
|
|
191
|
-
return port_conn_list
|
|
192
|
-
|
|
193
182
|
|
|
194
183
|
class PortWire(Port):
|
|
195
184
|
"""
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# Copyright (c) Fredrik Andersson, 2024
|
|
2
|
+
# All rights reserved
|
|
3
|
+
|
|
4
|
+
"""All classes within digsim.storage_model namespace"""
|
|
5
|
+
|
|
6
|
+
from ._app import AppFileDataClass, GuiPositionDataClass, ModelDataClass
|
|
7
|
+
from ._circuit import CircuitDataClass, CircuitFileDataClass, ComponentDataClass, WireDataClass
|