digsim-logic-simulator 0.4.0__py3-none-any.whl → 0.6.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/app/gui_objects/_component_object.py +6 -3
- digsim/app/model/_model.py +13 -14
- digsim/app/model/_model_components.py +12 -15
- digsim/app/model/_model_objects.py +29 -23
- digsim/app/model/_model_settings.py +1 -5
- digsim/app/model/_model_shortcuts.py +3 -3
- digsim/app/settings/_component_settings.py +4 -4
- digsim/circuit/_circuit.py +20 -60
- digsim/circuit/components/_bus_bits.py +2 -2
- digsim/circuit/components/_buzzer.py +1 -1
- digsim/circuit/components/_clock.py +1 -1
- digsim/circuit/components/_dip_switch.py +1 -1
- digsim/circuit/components/_gates.py +5 -5
- digsim/circuit/components/_hexdigit.py +2 -2
- digsim/circuit/components/_label_wire.py +3 -3
- digsim/circuit/components/_logic_analyzer.py +1 -1
- digsim/circuit/components/_note.py +1 -1
- digsim/circuit/components/_static_value.py +1 -1
- digsim/circuit/components/atoms/_component.py +0 -39
- digsim/circuit/components/atoms/_port.py +5 -14
- digsim/storage_model/__init__.py +7 -0
- digsim/storage_model/_app.py +53 -0
- digsim/storage_model/_circuit.py +118 -0
- {digsim_logic_simulator-0.4.0.dist-info → digsim_logic_simulator-0.6.0.dist-info}/LICENSE.md +1 -1
- {digsim_logic_simulator-0.4.0.dist-info → digsim_logic_simulator-0.6.0.dist-info}/METADATA +13 -8
- {digsim_logic_simulator-0.4.0.dist-info → digsim_logic_simulator-0.6.0.dist-info}/RECORD +28 -25
- {digsim_logic_simulator-0.4.0.dist-info → digsim_logic_simulator-0.6.0.dist-info}/WHEEL +1 -1
- {digsim_logic_simulator-0.4.0.dist-info → digsim_logic_simulator-0.6.0.dist-info}/top_level.txt +0 -0
|
@@ -9,6 +9,8 @@ from PySide6.QtCore import QPoint, QRect, QSize, Qt
|
|
|
9
9
|
from PySide6.QtGui import QFont, QFontMetrics, QPen
|
|
10
10
|
from PySide6.QtWidgets import QGraphicsItem, QGraphicsRectItem
|
|
11
11
|
|
|
12
|
+
from digsim.storage_model import GuiPositionDataClass
|
|
13
|
+
|
|
12
14
|
from ._component_context_menu import ComponentContextMenu
|
|
13
15
|
from ._component_port_item import PortGraphicsItem
|
|
14
16
|
|
|
@@ -365,6 +367,7 @@ class ComponentObject(QGraphicsRectItem):
|
|
|
365
367
|
"""Set zlevel"""
|
|
366
368
|
self.setZValue(level)
|
|
367
369
|
|
|
368
|
-
def
|
|
369
|
-
|
|
370
|
-
|
|
370
|
+
def to_gui_dataclass(self):
|
|
371
|
+
return GuiPositionDataClass(
|
|
372
|
+
x=int(self._save_pos.x()), y=int(self._save_pos.y()), z=int(self.zlevel)
|
|
373
|
+
)
|
digsim/app/model/_model.py
CHANGED
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
|
|
4
4
|
"""An application model for a GUI simulated circuit"""
|
|
5
5
|
|
|
6
|
-
import json
|
|
7
6
|
import queue
|
|
8
7
|
import time
|
|
9
8
|
from pathlib import Path
|
|
@@ -12,6 +11,7 @@ from PySide6.QtCore import QThread, Signal
|
|
|
12
11
|
|
|
13
12
|
from digsim.app.gui_objects import ComponentObject
|
|
14
13
|
from digsim.circuit.components.atoms import Component
|
|
14
|
+
from digsim.storage_model import AppFileDataClass
|
|
15
15
|
|
|
16
16
|
from ._model_objects import ModelObjects
|
|
17
17
|
from ._model_settings import ModelSettings
|
|
@@ -155,28 +155,27 @@ class AppModel(QThread):
|
|
|
155
155
|
def save_circuit(self, path):
|
|
156
156
|
"""Save the circuit with GUI information"""
|
|
157
157
|
circuit_folder = str(Path(path).parent)
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
158
|
+
model_dataclass = self.objects.circuit_to_model(circuit_folder)
|
|
159
|
+
appfile_dataclass = AppFileDataClass(
|
|
160
|
+
circuit=model_dataclass.circuit,
|
|
161
|
+
gui=model_dataclass.gui,
|
|
162
|
+
shortcuts=self.shortcuts.to_dict(),
|
|
163
|
+
settings=self.settings.get_all(),
|
|
164
|
+
)
|
|
165
|
+
appfile_dataclass.save(path)
|
|
166
166
|
self._changed = False
|
|
167
167
|
self.sig_control_notify.emit()
|
|
168
168
|
|
|
169
169
|
def load_circuit(self, path):
|
|
170
170
|
"""Load a circuit with GUI information"""
|
|
171
171
|
self._model_clear()
|
|
172
|
-
|
|
173
|
-
circuit_dict = json.load(json_file)
|
|
172
|
+
app_file_dc = AppFileDataClass.load(path)
|
|
174
173
|
circuit_folder = str(Path(path).parent)
|
|
175
174
|
if len(circuit_folder) == 0:
|
|
176
175
|
circuit_folder = "."
|
|
177
|
-
exception_str_list = self.objects.
|
|
178
|
-
self.shortcuts.from_dict(
|
|
179
|
-
self.settings.from_dict(
|
|
176
|
+
exception_str_list = self.objects.model_to_circuit(app_file_dc, circuit_folder)
|
|
177
|
+
self.shortcuts.from_dict(app_file_dc.shortcuts)
|
|
178
|
+
self.settings.from_dict(app_file_dc.settings)
|
|
180
179
|
self.model_init()
|
|
181
180
|
self._changed = False
|
|
182
181
|
self.objects.reset_undo_stack()
|
|
@@ -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
|
"""Handle component objects in the model"""
|
|
@@ -7,6 +7,7 @@ import digsim.circuit.components
|
|
|
7
7
|
from digsim.app.gui_objects import ComponentObject
|
|
8
8
|
from digsim.circuit.components import Buzzer
|
|
9
9
|
from digsim.circuit.components.atoms import CallbackComponent
|
|
10
|
+
from digsim.storage_model import GuiPositionDataClass
|
|
10
11
|
|
|
11
12
|
|
|
12
13
|
class ModelComponents:
|
|
@@ -149,20 +150,16 @@ class ModelComponents:
|
|
|
149
150
|
self._circuit.delete_component(component_object.component)
|
|
150
151
|
self._app_model.sig_delete_component.emit(component_object)
|
|
151
152
|
|
|
152
|
-
def
|
|
153
|
+
def add_gui_positions(self, gui_dc_dict):
|
|
153
154
|
"""Create model components from circuit_dict"""
|
|
154
155
|
for comp in self._circuit.get_toplevel_components():
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
def get_circuit_dict(self):
|
|
164
|
-
"""Create model components dict"""
|
|
165
|
-
model_components_dict = {"gui": {}}
|
|
156
|
+
gui_dc = gui_dc_dict.get(comp.name(), GuiPositionDataClass())
|
|
157
|
+
component_object = self._add_object(comp, gui_dc.x, gui_dc.y)
|
|
158
|
+
component_object.zlevel = gui_dc.z
|
|
159
|
+
|
|
160
|
+
def get_gui_dict(self):
|
|
161
|
+
"""Return gui dict from component objects"""
|
|
162
|
+
gui_dict = {}
|
|
166
163
|
for comp, comp_object in self.get_dict().items():
|
|
167
|
-
|
|
168
|
-
return
|
|
164
|
+
gui_dict[comp.name()] = comp_object.to_gui_dataclass()
|
|
165
|
+
return gui_dict
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
from digsim.circuit import Circuit
|
|
7
7
|
from digsim.circuit.components.atoms import DigsimException
|
|
8
|
+
from digsim.storage_model import AppFileDataClass, ModelDataClass
|
|
8
9
|
|
|
9
10
|
from ._model_components import ModelComponents
|
|
10
11
|
from ._model_new_wire import NewWire
|
|
@@ -72,32 +73,37 @@ class ModelObjects:
|
|
|
72
73
|
self._app_model.model_changed()
|
|
73
74
|
self._app_model.sig_delete_wires.emit()
|
|
74
75
|
|
|
75
|
-
def
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
76
|
+
def model_to_circuit(self, model_dc, circuit_folder):
|
|
77
|
+
if isinstance(model_dc, AppFileDataClass):
|
|
78
|
+
# Loaded model
|
|
79
|
+
dc = ModelDataClass.from_app_file_dc(model_dc)
|
|
80
|
+
else:
|
|
81
|
+
dc = model_dc
|
|
81
82
|
|
|
82
|
-
def dict_to_circuit(self, circuit_dict, circuit_folder):
|
|
83
|
-
"""Convert dict to circuit and objects"""
|
|
84
|
-
exception_str_list = []
|
|
85
83
|
try:
|
|
86
|
-
|
|
87
|
-
|
|
84
|
+
# Create circuit
|
|
85
|
+
exception_str_list = self.circuit.from_dataclass(
|
|
86
|
+
dc.circuit,
|
|
87
|
+
circuit_folder,
|
|
88
|
+
component_exceptions=False,
|
|
89
|
+
connect_exceptions=False,
|
|
88
90
|
)
|
|
91
|
+
# Add component positions
|
|
92
|
+
self.components.add_gui_positions(dc.gui)
|
|
89
93
|
except DigsimException as exc:
|
|
90
94
|
self.sig_error.emit(f"Circuit error: {str(exc)}")
|
|
91
95
|
return exception_str_list
|
|
92
|
-
|
|
93
|
-
# Create GUI components
|
|
94
|
-
self.components.create_from_dict(circuit_dict)
|
|
95
|
-
|
|
96
96
|
return exception_str_list
|
|
97
97
|
|
|
98
|
-
def
|
|
98
|
+
def circuit_to_model(self, circuit_folder):
|
|
99
|
+
model_dc = ModelDataClass(
|
|
100
|
+
circuit=self.circuit.to_dataclass(circuit_folder), gui=self.components.get_gui_dict()
|
|
101
|
+
)
|
|
102
|
+
return model_dc
|
|
103
|
+
|
|
104
|
+
def _restore_state(self, model_dc):
|
|
99
105
|
self.clear()
|
|
100
|
-
exception_str_list = self.
|
|
106
|
+
exception_str_list = self.model_to_circuit(model_dc, None)
|
|
101
107
|
self._app_model.model_init()
|
|
102
108
|
self._app_model.model_changed()
|
|
103
109
|
if len(exception_str_list) > 0:
|
|
@@ -111,7 +117,7 @@ class ModelObjects:
|
|
|
111
117
|
|
|
112
118
|
def push_undo_state(self, clear_redo_stack=True):
|
|
113
119
|
"""Push undo state to stack"""
|
|
114
|
-
self._undo_stack.append(self.
|
|
120
|
+
self._undo_stack.append(self.circuit_to_model("/"))
|
|
115
121
|
if clear_redo_stack:
|
|
116
122
|
self._redo_stack = []
|
|
117
123
|
self._app_model.sig_control_notify.emit()
|
|
@@ -124,14 +130,14 @@ class ModelObjects:
|
|
|
124
130
|
|
|
125
131
|
def push_redo_state(self):
|
|
126
132
|
"""Push redo state to stack"""
|
|
127
|
-
self._redo_stack.append(self.
|
|
133
|
+
self._redo_stack.append(self.circuit_to_model("/"))
|
|
128
134
|
|
|
129
135
|
def undo(self):
|
|
130
136
|
"""Undo to last saved state"""
|
|
131
137
|
if len(self._undo_stack) > 0:
|
|
132
138
|
self.push_redo_state()
|
|
133
|
-
|
|
134
|
-
self._restore_state(
|
|
139
|
+
model_dc = self._undo_stack.pop()
|
|
140
|
+
self._restore_state(model_dc)
|
|
135
141
|
self._app_model.sig_control_notify.emit()
|
|
136
142
|
self._app_model.sig_synchronize_gui.emit()
|
|
137
143
|
|
|
@@ -139,8 +145,8 @@ class ModelObjects:
|
|
|
139
145
|
"""Undo to last saved state"""
|
|
140
146
|
if len(self._redo_stack) > 0:
|
|
141
147
|
self.push_undo_state(clear_redo_stack=False)
|
|
142
|
-
|
|
143
|
-
self._restore_state(
|
|
148
|
+
model_dc = self._redo_stack.pop()
|
|
149
|
+
self._restore_state(model_dc)
|
|
144
150
|
self._app_model.sig_control_notify.emit()
|
|
145
151
|
self._app_model.sig_synchronize_gui.emit()
|
|
146
152
|
|
|
@@ -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
|
"""Handle settings in the model"""
|
|
@@ -25,10 +25,6 @@ class ModelSettings:
|
|
|
25
25
|
"""Return settings dict"""
|
|
26
26
|
return self._settings
|
|
27
27
|
|
|
28
|
-
def to_dict(self):
|
|
29
|
-
"""Return settings dict to save"""
|
|
30
|
-
return {"settings": self._settings}
|
|
31
|
-
|
|
32
28
|
def from_dict(self, circuit_dict):
|
|
33
29
|
"""Get settings from circuit dict"""
|
|
34
30
|
for key, data in circuit_dict.get("settings", {}).items():
|
|
@@ -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
|
"""Handle shortcuts in the model"""
|
|
@@ -72,9 +72,9 @@ class ModelShortcuts:
|
|
|
72
72
|
|
|
73
73
|
def to_dict(self):
|
|
74
74
|
"""Generate dict from shortcuts"""
|
|
75
|
-
shortcuts_dict = {
|
|
75
|
+
shortcuts_dict = {}
|
|
76
76
|
for key, component in self._shortcut_component.items():
|
|
77
|
-
shortcuts_dict[
|
|
77
|
+
shortcuts_dict[key] = component.name()
|
|
78
78
|
return shortcuts_dict
|
|
79
79
|
|
|
80
80
|
def from_dict(self, model_dict):
|
|
@@ -358,9 +358,9 @@ class ComponentSettingsDialog(QDialog):
|
|
|
358
358
|
widget = ComponentSettingsCheckBoxWidthBool(
|
|
359
359
|
self, parameter, parameter_dict, self._settings
|
|
360
360
|
)
|
|
361
|
-
elif parameter_dict["type"] == int:
|
|
361
|
+
elif parameter_dict["type"] == "int":
|
|
362
362
|
widget = ComponentSettingsSlider(self, parameter, parameter_dict, self._settings)
|
|
363
|
-
elif parameter_dict["type"] == str:
|
|
363
|
+
elif parameter_dict["type"] == "str":
|
|
364
364
|
single_line = parameter_dict.get("single_line", False)
|
|
365
365
|
if single_line:
|
|
366
366
|
widget = ComponentSettingSingleLineText(
|
|
@@ -368,7 +368,7 @@ class ComponentSettingsDialog(QDialog):
|
|
|
368
368
|
)
|
|
369
369
|
else:
|
|
370
370
|
widget = ComponentSettingText(self, parameter, parameter_dict, self._settings)
|
|
371
|
-
elif parameter_dict["type"] == bool:
|
|
371
|
+
elif parameter_dict["type"] == "bool":
|
|
372
372
|
widget = ComponentSettingsCheckBox(self, parameter, parameter_dict, self._settings)
|
|
373
373
|
elif parameter_dict["type"] == "intrange":
|
|
374
374
|
widget = ComponentSettingsIntRangeSlider(
|
|
@@ -382,7 +382,7 @@ class ComponentSettingsDialog(QDialog):
|
|
|
382
382
|
widget = ComponentSettingsNameSelector(
|
|
383
383
|
self, parameter, parameter_dict, self._settings
|
|
384
384
|
)
|
|
385
|
-
elif parameter_dict["type"] == list:
|
|
385
|
+
elif parameter_dict["type"] == "list":
|
|
386
386
|
widget = ComponentSettingsListSelector(
|
|
387
387
|
self, parameter, parameter_dict, self._settings
|
|
388
388
|
)
|
digsim/circuit/_circuit.py
CHANGED
|
@@ -5,11 +5,12 @@
|
|
|
5
5
|
Module that handles the circuit simulation of components
|
|
6
6
|
"""
|
|
7
7
|
|
|
8
|
-
import json
|
|
9
8
|
import os
|
|
10
9
|
|
|
10
|
+
from digsim.storage_model import CircuitDataClass, CircuitFileDataClass
|
|
11
|
+
|
|
11
12
|
from ._waves_writer import WavesWriter
|
|
12
|
-
from .components.atoms import
|
|
13
|
+
from .components.atoms import DigsimException
|
|
13
14
|
|
|
14
15
|
|
|
15
16
|
class CircuitError(DigsimException):
|
|
@@ -70,6 +71,11 @@ class Circuit:
|
|
|
70
71
|
else:
|
|
71
72
|
self._vcd = None
|
|
72
73
|
|
|
74
|
+
@property
|
|
75
|
+
def name(self):
|
|
76
|
+
"""Get the circuit name"""
|
|
77
|
+
return self._name
|
|
78
|
+
|
|
73
79
|
@property
|
|
74
80
|
def time_ns(self):
|
|
75
81
|
"""Get the current simulation time (ns)"""
|
|
@@ -243,65 +249,24 @@ class Circuit:
|
|
|
243
249
|
return comp
|
|
244
250
|
raise CircuitError(f"Component '{component_name}' not found")
|
|
245
251
|
|
|
246
|
-
def
|
|
247
|
-
source_component_name = source.split(".")[0]
|
|
248
|
-
source_port_name = source.split(".")[1]
|
|
249
|
-
dest_component_name = dest.split(".")[0]
|
|
250
|
-
dest_port_name = dest.split(".")[1]
|
|
251
|
-
|
|
252
|
-
source_component = self.get_component(source_component_name)
|
|
253
|
-
dest_componment = self.get_component(dest_component_name)
|
|
254
|
-
source_component.port(source_port_name).wire = dest_componment.port(dest_port_name)
|
|
255
|
-
|
|
256
|
-
def to_dict(self, folder=None):
|
|
252
|
+
def to_dataclass(self, folder=None):
|
|
257
253
|
"""Generate dict from circuit, used when storing circuit"""
|
|
258
254
|
if self._name is None:
|
|
259
255
|
raise CircuitError("Circuit must have a name")
|
|
260
|
-
|
|
261
256
|
self._folder = folder
|
|
262
|
-
|
|
263
|
-
for comp in self.get_toplevel_components():
|
|
264
|
-
components_list.append(comp.to_dict())
|
|
257
|
+
return CircuitDataClass.from_circuit(self)
|
|
265
258
|
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
for port in comp.ports:
|
|
269
|
-
port_conn_list = port.to_dict_list()
|
|
270
|
-
connection_list.extend(port_conn_list)
|
|
271
|
-
|
|
272
|
-
circuit_dict = {
|
|
273
|
-
"circuit": {
|
|
274
|
-
"name": self._name,
|
|
275
|
-
"components": components_list,
|
|
276
|
-
"wires": connection_list,
|
|
277
|
-
}
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
return circuit_dict
|
|
281
|
-
|
|
282
|
-
def from_dict(
|
|
283
|
-
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
|
|
284
261
|
):
|
|
285
262
|
"""Clear circuit and add components from dict"""
|
|
286
263
|
self._folder = folder
|
|
287
264
|
self.clear()
|
|
288
|
-
if "circuit" not in circuit_dict:
|
|
289
|
-
raise CircuitError("No 'circuit' in JSON")
|
|
290
|
-
json_circuit = circuit_dict["circuit"]
|
|
291
|
-
if "name" not in json_circuit:
|
|
292
|
-
raise CircuitError("No 'circuit/name' in JSON")
|
|
293
|
-
self._name = json_circuit["name"]
|
|
294
|
-
if "components" not in json_circuit:
|
|
295
|
-
raise CircuitError("No 'circuit/components' in JSON")
|
|
296
|
-
json_components = json_circuit["components"]
|
|
297
|
-
if "wires" not in json_circuit:
|
|
298
|
-
raise CircuitError("No 'circuit/connections' in JSON")
|
|
299
|
-
json_connections = json_circuit["wires"]
|
|
300
265
|
|
|
301
266
|
exception_str_list = []
|
|
302
|
-
for
|
|
267
|
+
for component in circuit_dc.components:
|
|
303
268
|
try:
|
|
304
|
-
|
|
269
|
+
component.create(self)
|
|
305
270
|
except DigsimException as exc:
|
|
306
271
|
if component_exceptions:
|
|
307
272
|
raise exc
|
|
@@ -310,9 +275,9 @@ class Circuit:
|
|
|
310
275
|
if component_exceptions:
|
|
311
276
|
raise exc
|
|
312
277
|
exception_str_list.append(f"{str(exc.__class__.__name__)}:{str(exc)}")
|
|
313
|
-
for
|
|
278
|
+
for wire in circuit_dc.wires:
|
|
314
279
|
try:
|
|
315
|
-
|
|
280
|
+
wire.connect(self)
|
|
316
281
|
except DigsimException as exc:
|
|
317
282
|
if connect_exceptions:
|
|
318
283
|
raise exc
|
|
@@ -322,15 +287,10 @@ class Circuit:
|
|
|
322
287
|
|
|
323
288
|
def to_json_file(self, filename):
|
|
324
289
|
"""Store circuit in json file"""
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
with open(filename, mode="w", encoding="utf-8") as json_file:
|
|
329
|
-
json_file.write(json_object)
|
|
290
|
+
circuitfile_dc = CircuitFileDataClass(circuit=self.to_dataclass())
|
|
291
|
+
circuitfile_dc.save(filename)
|
|
330
292
|
|
|
331
293
|
def from_json_file(self, filename, folder=None):
|
|
332
294
|
"""Load circuit from json file"""
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
circuit_dict = json.load(json_file)
|
|
336
|
-
self.from_dict(circuit_dict, folder)
|
|
295
|
+
file_dc = CircuitFileDataClass.load(filename)
|
|
296
|
+
self.from_dataclass(file_dc.circuit, folder)
|
|
@@ -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,
|
|
@@ -44,7 +44,7 @@ class ConfigPortsComponent(Component):
|
|
|
44
44
|
def get_parameters(cls):
|
|
45
45
|
return {
|
|
46
46
|
"ports": {
|
|
47
|
-
"type": int,
|
|
47
|
+
"type": "int",
|
|
48
48
|
"min": 2,
|
|
49
49
|
"max": 8,
|
|
50
50
|
"default": 2,
|
|
@@ -161,17 +161,17 @@ class DFF(Component):
|
|
|
161
161
|
def get_parameters(cls):
|
|
162
162
|
return {
|
|
163
163
|
"async_reset": {
|
|
164
|
-
"type": bool,
|
|
164
|
+
"type": "bool",
|
|
165
165
|
"default": False,
|
|
166
166
|
"description": "Use asynchronous reset",
|
|
167
167
|
},
|
|
168
168
|
"clock_enable": {
|
|
169
|
-
"type": bool,
|
|
169
|
+
"type": "bool",
|
|
170
170
|
"default": False,
|
|
171
171
|
"description": "Use clock enable",
|
|
172
172
|
},
|
|
173
173
|
"width": {
|
|
174
|
-
"type": int,
|
|
174
|
+
"type": "int",
|
|
175
175
|
"min": 1,
|
|
176
176
|
"max": 32,
|
|
177
177
|
"default": 1,
|
|
@@ -215,7 +215,7 @@ class MUX(Component):
|
|
|
215
215
|
"description": "Number of input ports",
|
|
216
216
|
},
|
|
217
217
|
"width": {
|
|
218
|
-
"type": int,
|
|
218
|
+
"type": "int",
|
|
219
219
|
"min": 1,
|
|
220
220
|
"max": 32,
|
|
221
221
|
"default": 1,
|
|
@@ -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
|
},
|
|
@@ -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
|
}
|
|
@@ -5,7 +5,6 @@
|
|
|
5
5
|
|
|
6
6
|
import abc
|
|
7
7
|
import copy
|
|
8
|
-
import importlib
|
|
9
8
|
|
|
10
9
|
from ._digsim_exception import DigsimException
|
|
11
10
|
|
|
@@ -166,44 +165,6 @@ class Component(abc.ABC):
|
|
|
166
165
|
comp_str += f"\n - O:{port.name()}={port.value}"
|
|
167
166
|
return comp_str
|
|
168
167
|
|
|
169
|
-
def to_dict(self):
|
|
170
|
-
"""Return the component information as a dict, used when storing a circuit"""
|
|
171
|
-
component_dict = {
|
|
172
|
-
"name": self.name(),
|
|
173
|
-
"display_name": self.display_name(),
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
module_split = type(self).__module__.split(".")
|
|
177
|
-
type_str = ""
|
|
178
|
-
for module in module_split:
|
|
179
|
-
if not module.startswith("_"):
|
|
180
|
-
type_str += f"{module}."
|
|
181
|
-
type_str += type(self).__name__
|
|
182
|
-
component_dict["type"] = type_str
|
|
183
|
-
component_dict["settings"] = self.settings_to_dict()
|
|
184
|
-
return component_dict
|
|
185
|
-
|
|
186
|
-
@classmethod
|
|
187
|
-
def from_dict(cls, circuit, json_component):
|
|
188
|
-
"""Factory: Create a component from a dict"""
|
|
189
|
-
component_name = json_component["name"]
|
|
190
|
-
component_type = json_component["type"]
|
|
191
|
-
component_settings = json_component.get("settings", {})
|
|
192
|
-
if "path" in component_settings:
|
|
193
|
-
component_settings["path"] = circuit.load_path(component_settings["path"])
|
|
194
|
-
|
|
195
|
-
display_name = json_component.get("display_name")
|
|
196
|
-
py_module_name = ".".join(component_type.split(".")[0:-1])
|
|
197
|
-
py_class_name = component_type.split(".")[-1]
|
|
198
|
-
|
|
199
|
-
module = importlib.import_module(py_module_name)
|
|
200
|
-
class_ = getattr(module, py_class_name)
|
|
201
|
-
component = class_(circuit=circuit, **component_settings)
|
|
202
|
-
component.set_name(component_name)
|
|
203
|
-
if display_name is not None:
|
|
204
|
-
component.set_display_name(display_name)
|
|
205
|
-
return component
|
|
206
|
-
|
|
207
168
|
@property
|
|
208
169
|
def has_action(self):
|
|
209
170
|
"""Return True if this component is interactive"""
|
|
@@ -31,6 +31,11 @@ class Port(abc.ABC):
|
|
|
31
31
|
self._edge_detect_value = "X"
|
|
32
32
|
self.update_wires("X")
|
|
33
33
|
|
|
34
|
+
@property
|
|
35
|
+
def wired_ports(self):
|
|
36
|
+
"""Get wires from thisport"""
|
|
37
|
+
return self._wired_ports
|
|
38
|
+
|
|
34
39
|
@property
|
|
35
40
|
def value(self):
|
|
36
41
|
"""Get the value of the port, can be "X" """
|
|
@@ -174,20 +179,6 @@ class Port(abc.ABC):
|
|
|
174
179
|
def __str__(self):
|
|
175
180
|
return f"{self._parent.name()}:{self._name}={self.value}"
|
|
176
181
|
|
|
177
|
-
def to_dict_list(self):
|
|
178
|
-
"""Output port connections as a dict, used when storing a circuit"""
|
|
179
|
-
port_conn_list = []
|
|
180
|
-
for port in self._wired_ports:
|
|
181
|
-
# Only add port on top-level components
|
|
182
|
-
if port.parent().is_toplevel():
|
|
183
|
-
port_conn_list.append(
|
|
184
|
-
{
|
|
185
|
-
"src": f"{self.parent().name()}.{self.name()}",
|
|
186
|
-
"dst": f"{port.parent().name()}.{port.name()}",
|
|
187
|
-
}
|
|
188
|
-
)
|
|
189
|
-
return port_conn_list
|
|
190
|
-
|
|
191
182
|
|
|
192
183
|
class PortWire(Port):
|
|
193
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
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# Copyright (c) Fredrik Andersson, 2023-2024
|
|
2
|
+
# All rights reserved
|
|
3
|
+
|
|
4
|
+
"""
|
|
5
|
+
Module that handles the dataclasses for application
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
import json
|
|
11
|
+
from dataclasses import asdict
|
|
12
|
+
from typing import Any
|
|
13
|
+
|
|
14
|
+
from pydantic import Field
|
|
15
|
+
from pydantic.dataclasses import dataclass
|
|
16
|
+
|
|
17
|
+
from ._circuit import CircuitDataClass
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
@dataclass
|
|
21
|
+
class GuiPositionDataClass:
|
|
22
|
+
x: int = 100
|
|
23
|
+
y: int = 100
|
|
24
|
+
z: int = 0
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
@dataclass
|
|
28
|
+
class AppFileDataClass:
|
|
29
|
+
circuit: CircuitDataClass
|
|
30
|
+
gui: dict[str, GuiPositionDataClass] = Field(default_factory=dict)
|
|
31
|
+
shortcuts: dict[str, str] = Field(default_factory=dict)
|
|
32
|
+
settings: dict[str, Any] = Field(default_factory=dict)
|
|
33
|
+
|
|
34
|
+
@staticmethod
|
|
35
|
+
def load(filename):
|
|
36
|
+
with open(filename, mode="r", encoding="utf-8") as json_file:
|
|
37
|
+
app_filedata_class = AppFileDataClass(**json.load(json_file))
|
|
38
|
+
return app_filedata_class
|
|
39
|
+
|
|
40
|
+
def save(self, filename):
|
|
41
|
+
json_object = json.dumps(asdict(self), indent=4)
|
|
42
|
+
with open(filename, mode="w", encoding="utf-8") as json_file:
|
|
43
|
+
json_file.write(json_object)
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
@dataclass
|
|
47
|
+
class ModelDataClass:
|
|
48
|
+
circuit: CircuitDataClass
|
|
49
|
+
gui: dict[str, GuiPositionDataClass]
|
|
50
|
+
|
|
51
|
+
@staticmethod
|
|
52
|
+
def from_app_file_dc(app_file_dc):
|
|
53
|
+
return ModelDataClass(circuit=app_file_dc.circuit, gui=app_file_dc.gui)
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
# Copyright (c) Fredrik Andersson, 2023-2024
|
|
2
|
+
# All rights reserved
|
|
3
|
+
|
|
4
|
+
"""
|
|
5
|
+
Module that handles the dataclasses for circuit load/save
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
import importlib
|
|
11
|
+
import json
|
|
12
|
+
from dataclasses import asdict
|
|
13
|
+
|
|
14
|
+
from pydantic import Field
|
|
15
|
+
from pydantic.dataclasses import dataclass
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@dataclass
|
|
19
|
+
class WireDataClass:
|
|
20
|
+
src: str
|
|
21
|
+
dst: str
|
|
22
|
+
|
|
23
|
+
def connect(self, circuit):
|
|
24
|
+
src_comp = circuit.get_component(self.src.split(".")[0])
|
|
25
|
+
dst_comp = circuit.get_component(self.dst.split(".")[0])
|
|
26
|
+
src_comp.port(self.src.split(".")[1]).wire = dst_comp.port(self.dst.split(".")[1])
|
|
27
|
+
|
|
28
|
+
@classmethod
|
|
29
|
+
def list_from_port(cls, src_port):
|
|
30
|
+
wires = []
|
|
31
|
+
for port in src_port.wired_ports:
|
|
32
|
+
# Only add port on top-level components
|
|
33
|
+
if port.parent().is_toplevel():
|
|
34
|
+
wires.append(
|
|
35
|
+
WireDataClass(
|
|
36
|
+
src=f"{src_port.parent().name()}.{src_port.name()}",
|
|
37
|
+
dst=f"{port.parent().name()}.{port.name()}",
|
|
38
|
+
)
|
|
39
|
+
)
|
|
40
|
+
return wires
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
@dataclass
|
|
44
|
+
class ComponentDataClass:
|
|
45
|
+
"""Component data class"""
|
|
46
|
+
|
|
47
|
+
name: str
|
|
48
|
+
type: str
|
|
49
|
+
display_name: str = Field(default="")
|
|
50
|
+
settings: dict = Field(default_factory=dict)
|
|
51
|
+
|
|
52
|
+
def create(self, circuit):
|
|
53
|
+
"""Factory: Create a component from a dict"""
|
|
54
|
+
if "path" in self.settings:
|
|
55
|
+
self.settings["path"] = circuit.load_path(self.settings["path"])
|
|
56
|
+
|
|
57
|
+
py_module_name = ".".join(self.type.split(".")[0:-1])
|
|
58
|
+
py_class_name = self.type.split(".")[-1]
|
|
59
|
+
|
|
60
|
+
module = importlib.import_module(py_module_name)
|
|
61
|
+
class_ = getattr(module, py_class_name)
|
|
62
|
+
component = class_(circuit=circuit, **self.settings)
|
|
63
|
+
component.set_name(self.name)
|
|
64
|
+
if self.display_name is not None:
|
|
65
|
+
component.set_display_name(self.display_name)
|
|
66
|
+
return component
|
|
67
|
+
|
|
68
|
+
@staticmethod
|
|
69
|
+
def from_component(component):
|
|
70
|
+
"""Return the component information as a dict, used when storing a circuit"""
|
|
71
|
+
module_split = type(component).__module__.split(".")
|
|
72
|
+
type_str = ""
|
|
73
|
+
for module in module_split:
|
|
74
|
+
if not module.startswith("_"):
|
|
75
|
+
type_str += f"{module}."
|
|
76
|
+
type_str += type(component).__name__
|
|
77
|
+
|
|
78
|
+
return ComponentDataClass(
|
|
79
|
+
name=component.name(),
|
|
80
|
+
display_name=component.display_name(),
|
|
81
|
+
type=type_str,
|
|
82
|
+
settings=component.settings_to_dict(),
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
@dataclass
|
|
87
|
+
class CircuitDataClass:
|
|
88
|
+
name: str = "unnamed"
|
|
89
|
+
components: list[ComponentDataClass] = Field(default_factory=list)
|
|
90
|
+
wires: list[WireDataClass] = Field(default_factory=list)
|
|
91
|
+
|
|
92
|
+
@staticmethod
|
|
93
|
+
def from_circuit(circuit):
|
|
94
|
+
dc = CircuitDataClass(name=circuit.name)
|
|
95
|
+
for comp in circuit.get_toplevel_components():
|
|
96
|
+
dc.components.append(ComponentDataClass.from_component(comp))
|
|
97
|
+
|
|
98
|
+
for comp in circuit.get_toplevel_components():
|
|
99
|
+
for port in comp.ports:
|
|
100
|
+
dc.wires.extend(WireDataClass.list_from_port(port))
|
|
101
|
+
|
|
102
|
+
return dc
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
@dataclass
|
|
106
|
+
class CircuitFileDataClass:
|
|
107
|
+
circuit: CircuitDataClass
|
|
108
|
+
|
|
109
|
+
@staticmethod
|
|
110
|
+
def load(filename):
|
|
111
|
+
with open(filename, mode="r", encoding="utf-8") as json_file:
|
|
112
|
+
dc = CircuitFileDataClass(**json.load(json_file))
|
|
113
|
+
return dc
|
|
114
|
+
|
|
115
|
+
def save(self, filename):
|
|
116
|
+
json_object = json.dumps(asdict(self), indent=4)
|
|
117
|
+
with open(filename, mode="w", encoding="utf-8") as json_file:
|
|
118
|
+
json_file.write(json_object)
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: digsim-logic-simulator
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.6.0
|
|
4
4
|
Summary: Interactive Digital Logic Simulator
|
|
5
5
|
Author-email: Fredrik Andersson <freand@gmail.com>
|
|
6
6
|
Maintainer-email: Fredrik Andersson <freand@gmail.com>
|
|
7
7
|
License: The Clear BSD License
|
|
8
8
|
|
|
9
|
-
Copyright (c) 2023, Fredrik Andersson
|
|
9
|
+
Copyright (c) 2023-2024, Fredrik Andersson
|
|
10
10
|
All rights reserved.
|
|
11
11
|
|
|
12
12
|
Redistribution and use in source and binary forms, with or without
|
|
@@ -41,20 +41,20 @@ Project-URL: homepage, https://github.com/freand76/digsim
|
|
|
41
41
|
Keywords: educational,simulation,digital
|
|
42
42
|
Classifier: Development Status :: 5 - Production/Stable
|
|
43
43
|
Classifier: Programming Language :: Python :: 3
|
|
44
|
-
Classifier: Programming Language :: Python :: 3.8
|
|
45
44
|
Classifier: Programming Language :: Python :: 3.9
|
|
46
45
|
Classifier: Programming Language :: Python :: 3.10
|
|
47
46
|
Classifier: Programming Language :: Python :: 3.11
|
|
48
47
|
Classifier: Programming Language :: Python :: 3.12
|
|
49
48
|
Classifier: Programming Language :: Python :: 3 :: Only
|
|
50
|
-
Requires-Python: >=3.
|
|
49
|
+
Requires-Python: >=3.9
|
|
51
50
|
Description-Content-Type: text/markdown
|
|
52
51
|
License-File: LICENSE.md
|
|
53
|
-
Requires-Dist: pyvcd >=0.
|
|
54
|
-
Requires-Dist: pyside6
|
|
55
|
-
Requires-Dist: pexpect ==4.
|
|
52
|
+
Requires-Dist: pyvcd >=0.4.0
|
|
53
|
+
Requires-Dist: pyside6 <6.8,>=6.7.3
|
|
54
|
+
Requires-Dist: pexpect ==4.9.0
|
|
55
|
+
Requires-Dist: pydantic ==2.9.2
|
|
56
56
|
Requires-Dist: qtawesome
|
|
57
|
-
Requires-Dist: yowasp-yosys ==0.
|
|
57
|
+
Requires-Dist: yowasp-yosys ==0.45.0.0.post775
|
|
58
58
|
|
|
59
59
|
# DigSim - Interactive Digital Logic Simulator
|
|
60
60
|
|
|
@@ -135,6 +135,11 @@ Then the following package must be installed:
|
|
|
135
135
|
> gtkwave sr.vcd
|
|
136
136
|
```
|
|
137
137
|
|
|
138
|
+
### Examples of writing pytest/python test benches for synthesized verilog code
|
|
139
|
+
```
|
|
140
|
+
> pytest examples/pytest_tb
|
|
141
|
+
```
|
|
142
|
+
|
|
138
143
|
## Yosys synthesis helper tool
|
|
139
144
|
|
|
140
145
|
```
|
|
@@ -11,7 +11,7 @@ digsim/app/gui_objects/__init__.py,sha256=DV7hnqz4Xcwk_-BiKrPxB31c7k-R4Oemmo_KOU
|
|
|
11
11
|
digsim/app/gui_objects/_bus_bit_object.py,sha256=Q8oW-bAGLRAvR2-8PxyHL4M68FLKFgNpDiL4E7BPUOQ,3059
|
|
12
12
|
digsim/app/gui_objects/_buzzer_object.py,sha256=p_7O361t98K6BIUxK6gHdfcSn2wUVXTRfnf7oQXSIK4,3352
|
|
13
13
|
digsim/app/gui_objects/_component_context_menu.py,sha256=57M23M8Xb4t8eN8l9GQQ4AUBYZlEBjE0_a4d71yCDos,2821
|
|
14
|
-
digsim/app/gui_objects/_component_object.py,sha256=
|
|
14
|
+
digsim/app/gui_objects/_component_object.py,sha256=7fIvnMfew7cwyfk9m6nMnha6df5NEH67bc2-K5lg7lE,13142
|
|
15
15
|
digsim/app/gui_objects/_component_port_item.py,sha256=Rxl952_3BCqM2H7TJDfbSTlalfFicDStrjqMUKEtdns,2089
|
|
16
16
|
digsim/app/gui_objects/_dip_switch_object.py,sha256=6SmqoyF3MuUphLJA4tlyff4JXJBxJLWmt3ZEferFtf4,3576
|
|
17
17
|
digsim/app/gui_objects/_gui_note_object.py,sha256=sMakGjdR0truGBzaR2GaFZZoDg99v76Bs5DD6ea3cjA,2604
|
|
@@ -49,54 +49,57 @@ digsim/app/gui_objects/images/YOSYS.png,sha256=etTO9jadU0amxQG7ySRjD6fME4HjrEEqX
|
|
|
49
49
|
digsim/app/gui_objects/images/ZERO.png,sha256=hXnZgEVO3T_zN5CiFhu6cIXr19LAu6SdvX-sIOq06E4,3459
|
|
50
50
|
digsim/app/images/app_icon.png,sha256=OfPoYA4o4Af79DTqQxSNLca0FdXRHEYteBK-xCQFEAw,16041
|
|
51
51
|
digsim/app/model/__init__.py,sha256=atbReJBH_qTVZqsKLvF3p9eZWxkglFi6cvt7fEGo0bo,159
|
|
52
|
-
digsim/app/model/_model.py,sha256=
|
|
53
|
-
digsim/app/model/_model_components.py,sha256=
|
|
52
|
+
digsim/app/model/_model.py,sha256=JE9-iJMxzgcY0r-4s708gDtA-aadw_hFSuERjKNZlfE,6421
|
|
53
|
+
digsim/app/model/_model_components.py,sha256=Q2iztl7MlWv_7vaa7me-dp-gOx6-7Tg3LZmTUQNBPrw,6371
|
|
54
54
|
digsim/app/model/_model_new_wire.py,sha256=5HnF5-gtKtB1Tp6ZIF7QuNo5zEHmsUpnBEmj6ZllLiA,1810
|
|
55
|
-
digsim/app/model/_model_objects.py,sha256=
|
|
56
|
-
digsim/app/model/_model_settings.py,sha256=
|
|
57
|
-
digsim/app/model/_model_shortcuts.py,sha256=
|
|
55
|
+
digsim/app/model/_model_objects.py,sha256=lqOjNIygIHT6Dq_PPa-D0B5elC49dB0KshF0ATzJZ0s,5217
|
|
56
|
+
digsim/app/model/_model_settings.py,sha256=FewI3hm1iwbjPwdN3IeixuINPtamDORrTh1ANGRNwX8,1035
|
|
57
|
+
digsim/app/model/_model_shortcuts.py,sha256=TT4osN7-dMEgKXWHW9cJ0XILIIkUfRqBBfx6rvYT2JI,2488
|
|
58
58
|
digsim/app/settings/__init__.py,sha256=0tkoBSYeJFFiUI8c_FqvqqyM4-_SU9Xq7mXCwiew5Oo,308
|
|
59
|
-
digsim/app/settings/_component_settings.py,sha256=
|
|
59
|
+
digsim/app/settings/_component_settings.py,sha256=88D9OuEcFIlaqZozomWHSYrl7opz4jZW2e8xGuUyTpg,16287
|
|
60
60
|
digsim/app/settings/_gui_settings.py,sha256=sDi2POUsHvS7_4SO5qsTu_nN48HsTN4UfGPzdmECs9w,2764
|
|
61
61
|
digsim/app/settings/_shortcut_dialog.py,sha256=JTm7aawG2ar_DvWhBT8ZzgWsq9gLEJ6pJ_-eHUMPh-c,1524
|
|
62
62
|
digsim/circuit/__init__.py,sha256=yGyhcdnlcpht_hyR2az_A4c7-bO_NkT2lBIDFvtI010,216
|
|
63
|
-
digsim/circuit/_circuit.py,sha256=
|
|
63
|
+
digsim/circuit/_circuit.py,sha256=UNJBM2MyTXPWWEPXe4T4Z9Qc6vsm9We_Rk7mEfV9yIA,10023
|
|
64
64
|
digsim/circuit/_waves_writer.py,sha256=hh-hwNrT9c0jDLLxYw0anvwomJXVJK5iIbGVjcQddG0,1645
|
|
65
65
|
digsim/circuit/components/__init__.py,sha256=j-xNFbXJ15rSJLhDg7E-SlKvxn6Uy7Zl42YDUkZBFZo,1267
|
|
66
|
-
digsim/circuit/components/_bus_bits.py,sha256=
|
|
66
|
+
digsim/circuit/components/_bus_bits.py,sha256=mHWkwAHtkEq88pOEQ0b5ndFZvum794j7kUkTAWHUCdc,1916
|
|
67
67
|
digsim/circuit/components/_button.py,sha256=Q8drjQ2kNFCfgK-7UzlmNHP47bOpGa9_t16pDtjhL4s,1028
|
|
68
|
-
digsim/circuit/components/_buzzer.py,sha256=
|
|
69
|
-
digsim/circuit/components/_clock.py,sha256=
|
|
70
|
-
digsim/circuit/components/_dip_switch.py,sha256=
|
|
68
|
+
digsim/circuit/components/_buzzer.py,sha256=vArzQVe0yFjtqMxIx2BIvjRA-m-aipPUHVlgwbwpCXM,1125
|
|
69
|
+
digsim/circuit/components/_clock.py,sha256=Kks82_Ni_XJYvrgLFvPsAagbUnmH9QutGuwm1puM0B0,1487
|
|
70
|
+
digsim/circuit/components/_dip_switch.py,sha256=6f5EXVr3P-OXRB_FY5UOMTkBcJtUR2HHeeD38V7Wfmk,1807
|
|
71
71
|
digsim/circuit/components/_flip_flops.py,sha256=eOB1hpSfK7vlpcOQzHqILpAzfwsqQPobC-_ebDxGVLw,2942
|
|
72
|
-
digsim/circuit/components/_gates.py,sha256=
|
|
73
|
-
digsim/circuit/components/_hexdigit.py,sha256=
|
|
72
|
+
digsim/circuit/components/_gates.py,sha256=K_aFT4GTo4JF_zoaNYiCRZfZEx4vEibMHZSCDImfPHQ,7167
|
|
73
|
+
digsim/circuit/components/_hexdigit.py,sha256=MQlmEnQkQnuH6rGc-FB68mOctjVY8QyAR5FCOHYNCns,2259
|
|
74
74
|
digsim/circuit/components/_ic.py,sha256=Rs8Z_PuhKo3peK9pwdbvlGNK8_w6evSdXYNdrjWB3-8,917
|
|
75
|
-
digsim/circuit/components/_label_wire.py,sha256=
|
|
75
|
+
digsim/circuit/components/_label_wire.py,sha256=5xcPNWt8GtQEUk_BDJXWHQ3RfH62bAFQpiyeJlppOpA,5116
|
|
76
76
|
digsim/circuit/components/_led.py,sha256=hR_iclDWZua8duNy9BQcTBuhKkIh3g5ahpfkHQ1LYSA,452
|
|
77
|
-
digsim/circuit/components/_logic_analyzer.py,sha256=
|
|
77
|
+
digsim/circuit/components/_logic_analyzer.py,sha256=K6sUfN23lUfQ5GHQFrxvR8fgfWKLy29Cj0K7dZzW_cE,1809
|
|
78
78
|
digsim/circuit/components/_mem64kbyte.py,sha256=tqex3qFxa7jk841f87inNB4UIY9E5z1SleqAL82eCUY,1482
|
|
79
79
|
digsim/circuit/components/_memstdout.py,sha256=sCYkKH8XuWhB7-14VQOy7TkTgq-g0UDbhiI1HmM4HW8,1255
|
|
80
|
-
digsim/circuit/components/_note.py,sha256=
|
|
80
|
+
digsim/circuit/components/_note.py,sha256=ZpFPxKzJKbyOmd5YzLxfFllT49xqG3q9fGP1VBk3fW0,604
|
|
81
81
|
digsim/circuit/components/_on_off_switch.py,sha256=b2h_EClKRbOQTBpQYrOLRXzdps8da64lO9Nd7fp1RSY,1200
|
|
82
82
|
digsim/circuit/components/_seven_segment.py,sha256=UxxjGLuIirVB2Px09XlL8_zjgE7F89cY6z2SMS5FcPU,797
|
|
83
83
|
digsim/circuit/components/_static_level.py,sha256=2Assm1cmAfryVZ3KTQ1uGY8Q6eRrBipdwLITewXfIHg,677
|
|
84
|
-
digsim/circuit/components/_static_value.py,sha256=
|
|
84
|
+
digsim/circuit/components/_static_value.py,sha256=vfRPS_F9mKOXpHJxzs0JQKXqcj0o6d-090zbyZaECA4,1236
|
|
85
85
|
digsim/circuit/components/_yosys_atoms.py,sha256=NeH8XjjpoACHBfQRqR5RJxWorZhSjGk0t73cJOviSZw,37599
|
|
86
86
|
digsim/circuit/components/_yosys_component.py,sha256=XDNSAfM6Qvhe6G0-M1uiY2NQ-A6oPSQX4kcB_ccvSWg,8810
|
|
87
87
|
digsim/circuit/components/atoms/__init__.py,sha256=kPr-ZKYPiW8NgEvKooMyLYc4DpfMurkALqWcKLhuK28,483
|
|
88
|
-
digsim/circuit/components/atoms/_component.py,sha256=
|
|
88
|
+
digsim/circuit/components/atoms/_component.py,sha256=pnPzWmJYvgcdYt0TFTq12M88mz-esZBg1E7VtlZ5WK8,8287
|
|
89
89
|
digsim/circuit/components/atoms/_digsim_exception.py,sha256=Y5mBve15zZbduqNNAyf7WzqDk4NtvUL_g2vYy5kBQ3U,173
|
|
90
|
-
digsim/circuit/components/atoms/_port.py,sha256=
|
|
90
|
+
digsim/circuit/components/atoms/_port.py,sha256=BzfCBSQT34AMH10PyAj-eg0UqQpvFJz01fd3HmCwHhE,11688
|
|
91
91
|
digsim/circuit/components/ic/74162.json,sha256=BtLDDhNP4jYQD2EZ2nBHfUMRbuPztR54luLEpWl7j-o,26632
|
|
92
92
|
digsim/circuit/components/ic/7448.json,sha256=7p9l6l_QSw6DtphZcGgBMMP0PyMB5DYglciMhqCKp04,21211
|
|
93
|
+
digsim/storage_model/__init__.py,sha256=lubmO9_BCUtEahyW1yE7f3aGHngEevGIwf_0LeOB7Y8,289
|
|
94
|
+
digsim/storage_model/_app.py,sha256=Aer9s_mUBKSydsyeWYvVPHX2XF5ZGPuXq8z4PoXu8lA,1353
|
|
95
|
+
digsim/storage_model/_circuit.py,sha256=NnaHLwqb9gAhqAxeZ1RkHHvoS_YJwixlz0xs-zmIrQU,3596
|
|
93
96
|
digsim/synth/__init__.py,sha256=jhBHLOHf-vNa94Zg5q5dGcf0fgQTModfjUKtmUSffiw,180
|
|
94
97
|
digsim/synth/__main__.py,sha256=wZWAzWsisoxA7hfqkKtu3H066uWyFajgPro2MEGlKbs,2173
|
|
95
98
|
digsim/synth/_synthesis.py,sha256=ug9vSeTyZrvRCboNLL7dDIFVpGqH_ibr5fhOZJHpqUs,4271
|
|
96
99
|
digsim/utils/__init__.py,sha256=Az_zmbORYMzmptuA2_xfn5jDxbCPRSMlVuntr0sYexU,167
|
|
97
100
|
digsim/utils/_yosys_netlist.py,sha256=g-7hkVgGOYJUQbKv8wBqHMHqj44utuGHGbtaRb-qG60,8562
|
|
98
|
-
digsim_logic_simulator-0.
|
|
99
|
-
digsim_logic_simulator-0.
|
|
100
|
-
digsim_logic_simulator-0.
|
|
101
|
-
digsim_logic_simulator-0.
|
|
102
|
-
digsim_logic_simulator-0.
|
|
101
|
+
digsim_logic_simulator-0.6.0.dist-info/LICENSE.md,sha256=FrvohZfyfpH4xrvKdXiQ5hD7dUB7w4DcsRA3p-pOmLw,1693
|
|
102
|
+
digsim_logic_simulator-0.6.0.dist-info/METADATA,sha256=-Gakjy1u6-q6HFTAz49L5u2HuH5Vw3EwxvUlnc2JfdA,6445
|
|
103
|
+
digsim_logic_simulator-0.6.0.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
|
|
104
|
+
digsim_logic_simulator-0.6.0.dist-info/top_level.txt,sha256=qpCMzQKADZHVqZIoQgFrv3qJ3u7PPU73gTCXQglqLa8,7
|
|
105
|
+
digsim_logic_simulator-0.6.0.dist-info/RECORD,,
|
{digsim_logic_simulator-0.4.0.dist-info → digsim_logic_simulator-0.6.0.dist-info}/top_level.txt
RENAMED
|
File without changes
|