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.

Files changed (28) hide show
  1. digsim/app/gui_objects/_component_object.py +6 -3
  2. digsim/app/model/_model.py +13 -14
  3. digsim/app/model/_model_components.py +12 -15
  4. digsim/app/model/_model_objects.py +29 -23
  5. digsim/app/model/_model_settings.py +1 -5
  6. digsim/app/model/_model_shortcuts.py +3 -3
  7. digsim/app/settings/_component_settings.py +4 -4
  8. digsim/circuit/_circuit.py +20 -60
  9. digsim/circuit/components/_bus_bits.py +2 -2
  10. digsim/circuit/components/_buzzer.py +1 -1
  11. digsim/circuit/components/_clock.py +1 -1
  12. digsim/circuit/components/_dip_switch.py +1 -1
  13. digsim/circuit/components/_gates.py +5 -5
  14. digsim/circuit/components/_hexdigit.py +2 -2
  15. digsim/circuit/components/_label_wire.py +3 -3
  16. digsim/circuit/components/_logic_analyzer.py +1 -1
  17. digsim/circuit/components/_note.py +1 -1
  18. digsim/circuit/components/_static_value.py +1 -1
  19. digsim/circuit/components/atoms/_component.py +0 -39
  20. digsim/circuit/components/atoms/_port.py +5 -14
  21. digsim/storage_model/__init__.py +7 -0
  22. digsim/storage_model/_app.py +53 -0
  23. digsim/storage_model/_circuit.py +118 -0
  24. {digsim_logic_simulator-0.4.0.dist-info → digsim_logic_simulator-0.6.0.dist-info}/LICENSE.md +1 -1
  25. {digsim_logic_simulator-0.4.0.dist-info → digsim_logic_simulator-0.6.0.dist-info}/METADATA +13 -8
  26. {digsim_logic_simulator-0.4.0.dist-info → digsim_logic_simulator-0.6.0.dist-info}/RECORD +28 -25
  27. {digsim_logic_simulator-0.4.0.dist-info → digsim_logic_simulator-0.6.0.dist-info}/WHEEL +1 -1
  28. {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 to_dict(self):
369
- """Return position as dict"""
370
- return {"x": int(self._save_pos.x()), "y": int(self._save_pos.y()), "z": self.zlevel}
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
+ )
@@ -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
- circuit_dict = self.objects.circuit_to_dict(circuit_folder)
159
- shortcuts_dict = self.shortcuts.to_dict()
160
- circuit_dict.update(shortcuts_dict)
161
- settings_dict = self.settings.to_dict()
162
- circuit_dict.update(settings_dict)
163
- json_object = json.dumps(circuit_dict, indent=4)
164
- with open(path, mode="w", encoding="utf-8") as json_file:
165
- json_file.write(json_object)
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
- with open(path, mode="r", encoding="utf-8") as json_file:
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.dict_to_circuit(circuit_dict, circuit_folder)
178
- self.shortcuts.from_dict(circuit_dict)
179
- self.settings.from_dict(circuit_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 create_from_dict(self, circuit_dict):
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
- gui_dict = circuit_dict.get("gui", {})
156
- component_dict = gui_dict.get(comp.name(), {})
157
- x = component_dict.get("x", 100)
158
- y = component_dict.get("y", 100)
159
- z = component_dict.get("z", 0)
160
- component_object = self._add_object(comp, x, y)
161
- component_object.zlevel = z
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
- model_components_dict["gui"][comp.name()] = comp_object.to_dict()
168
- return model_components_dict
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 circuit_to_dict(self, circuit_folder):
76
- """Convert circuit and objects to dict"""
77
- circuit_dict = self.circuit.to_dict(circuit_folder)
78
- model_components_dict = self.components.get_circuit_dict()
79
- circuit_dict.update(model_components_dict)
80
- return circuit_dict
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
- exception_str_list = self.circuit.from_dict(
87
- circuit_dict, circuit_folder, component_exceptions=False, connect_exceptions=False
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 _restore_state(self, state):
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.dict_to_circuit(state, "/")
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.circuit_to_dict("/"))
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.circuit_to_dict("/"))
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
- state = self._undo_stack.pop()
134
- self._restore_state(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
- state = self._redo_stack.pop()
143
- self._restore_state(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 = {"shortcuts": {}}
75
+ shortcuts_dict = {}
76
76
  for key, component in self._shortcut_component.items():
77
- shortcuts_dict["shortcuts"][key] = component.name()
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
  )
@@ -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 Component, DigsimException
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 _connect_from_dict(self, source, dest):
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
- components_list = []
263
- for comp in self.get_toplevel_components():
264
- components_list.append(comp.to_dict())
257
+ return CircuitDataClass.from_circuit(self)
265
258
 
266
- connection_list = []
267
- for comp in self.get_toplevel_components():
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 json_component in json_components:
267
+ for component in circuit_dc.components:
303
268
  try:
304
- Component.from_dict(self, json_component)
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 json_connection in json_connections:
278
+ for wire in circuit_dc.wires:
314
279
  try:
315
- self._connect_from_dict(json_connection["src"], json_connection["dst"])
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
- circuit_dict = self.to_dict()
326
- json_object = json.dumps(circuit_dict, indent=4)
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
- self._folder = folder
334
- with open(filename, mode="r", encoding="utf-8") as json_file:
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,
@@ -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",
@@ -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,
@@ -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,
@@ -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
  }
@@ -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,
@@ -17,7 +17,7 @@ class Note(Component):
17
17
  def get_parameters(cls):
18
18
  return {
19
19
  "text": {
20
- "type": str,
20
+ "type": "str",
21
21
  "default": "Write something here...",
22
22
  "description": "Note text",
23
23
  "reconfigurable": True,
@@ -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,
@@ -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,6 +1,6 @@
1
1
  The Clear BSD License
2
2
 
3
- Copyright (c) 2023, Fredrik Andersson
3
+ Copyright (c) 2023-2024, Fredrik Andersson
4
4
  All rights reserved.
5
5
 
6
6
  Redistribution and use in source and binary forms, with or without
@@ -1,12 +1,12 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: digsim-logic-simulator
3
- Version: 0.4.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.8
49
+ Requires-Python: >=3.9
51
50
  Description-Content-Type: text/markdown
52
51
  License-File: LICENSE.md
53
- Requires-Dist: pyvcd >=0.3.0
54
- Requires-Dist: pyside6 >=6.6.0
55
- Requires-Dist: pexpect ==4.8.0
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.36.0.8.post620
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=NIszLF61tjwyKYzQQby6BXP3rU7d1cj5VxZp-SY6LgY,13078
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=7zkn3i2YSFp-lhhsxGxyac0wv-PkjbZrjgKNz933iLc,6506
53
- digsim/app/model/_model_components.py,sha256=8x96YmkeHEaBYaB5i88G_Zf9MHcc05g8Go_YEBJ3R_o,6500
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=M3UxXqjqVg1PIDe96_3SH0L_BJGQEIvODa0XyUI7q4g,5040
56
- digsim/app/model/_model_settings.py,sha256=3nKzdhaSwYogC10-IFyNzbCsvXbmy9lrZ7hb_yRCyLg,1141
57
- digsim/app/model/_model_shortcuts.py,sha256=ovZ2uJC0rRYaLgf6UStPd4P33CiphvRmIOYx6c7M89M,2511
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=3kOh_q0I01h9yUHLcoDkGcgJtfO64zemToyH7fIGwZo,16279
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=hj0D6NMnAi39USIyZsBp6Nd8ktrqpjNW9cO3JVd1Wbw,11748
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=0AvvteRnG4SpW_l-0e-cgBG85VxYlbfdVQFvQVSp88Y,1912
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=bJXMfJyZo66ZiUs_4qT5MyNEHof5ZCI0cIBrdeFdTfA,1123
69
- digsim/circuit/components/_clock.py,sha256=Mw2R6tHmPAS5-ueiFkZPwYmgPMAg_slAOWiMDimiWGQ,1485
70
- digsim/circuit/components/_dip_switch.py,sha256=55IfnZrQr-Ru_ncWvFdDeiGwfC8dc1xqmF4ReQBI-TI,1805
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=QcsNUINdtLQyLt1pcXTmCks9x2mi1-db7VVLNZTIYZ4,7157
73
- digsim/circuit/components/_hexdigit.py,sha256=9ir8EGEB10mQbpDa5Jxff4EIdLzQ1_dw-KB_vBamcEA,2255
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=cd4FFERz_PngKGfbK3YwOQcHmCbasiX-JH73TvkT-wU,5110
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=MHkXGmQuXnDVJonxVkeZy9JOVmsapdT3voi6tsdZcbQ,1807
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=4o4bRw_7smKc_FGrVkhPwwIqC_500Vj_w8TrNtK1A8s,602
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=HNTsvjx0dsK8o4-tBLux3v57RZ425CcnpNmVS5B2CHw,1234
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=x0e2NUi9ozV4keuT10tsK9MqwBF8Vg1uInvadoS4DiE,9824
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=VYtKglAPJxaXG7ucTRNay_GS4aVX02gsqlJecNs1xlM,12119
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.4.0.dist-info/LICENSE.md,sha256=nx2x6ryeruncSHeHtF33WLjt5JARcm5rLdZuK_c8hL0,1688
99
- digsim_logic_simulator-0.4.0.dist-info/METADATA,sha256=l5jm-fI-iCGARKme6DBniaEXzUe73czseQVFwPuApg8,6336
100
- digsim_logic_simulator-0.4.0.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
101
- digsim_logic_simulator-0.4.0.dist-info/top_level.txt,sha256=qpCMzQKADZHVqZIoQgFrv3qJ3u7PPU73gTCXQglqLa8,7
102
- digsim_logic_simulator-0.4.0.dist-info/RECORD,,
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,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: bdist_wheel (0.43.0)
2
+ Generator: setuptools (75.1.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5