digsim-logic-simulator 0.8.0__tar.gz → 0.10.0__tar.gz

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 (122) hide show
  1. {digsim_logic_simulator-0.8.0/src/digsim_logic_simulator.egg-info → digsim_logic_simulator-0.10.0}/PKG-INFO +2 -2
  2. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/pyproject.toml +2 -2
  3. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/src/digsim/app/model/_model_shortcuts.py +1 -2
  4. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/src/digsim/circuit/components/_yosys_component.py +57 -46
  5. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/src/digsim/circuit/components/ic/74162.json +3 -2
  6. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/src/digsim/circuit/components/ic/7448.json +14 -13
  7. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/src/digsim/utils/__init__.py +1 -1
  8. digsim_logic_simulator-0.10.0/src/digsim/utils/_yosys_netlist.py +128 -0
  9. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0/src/digsim_logic_simulator.egg-info}/PKG-INFO +2 -2
  10. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/src/digsim_logic_simulator.egg-info/requires.txt +1 -1
  11. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/tests/test_yosys_netlist.py +77 -18
  12. digsim_logic_simulator-0.8.0/src/digsim/utils/_yosys_netlist.py +0 -272
  13. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/LICENSE.md +0 -0
  14. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/MANIFEST.in +0 -0
  15. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/README.md +0 -0
  16. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/setup.cfg +0 -0
  17. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/src/digsim/__init__.py +0 -0
  18. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/src/digsim/app/__main__.py +0 -0
  19. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/src/digsim/app/gui/__init__.py +0 -0
  20. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/src/digsim/app/gui/_circuit_area.py +0 -0
  21. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/src/digsim/app/gui/_component_selection.py +0 -0
  22. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/src/digsim/app/gui/_main_window.py +0 -0
  23. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/src/digsim/app/gui/_top_bar.py +0 -0
  24. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/src/digsim/app/gui/_utils.py +0 -0
  25. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/src/digsim/app/gui/_warning_dialog.py +0 -0
  26. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/src/digsim/app/gui_objects/__init__.py +0 -0
  27. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/src/digsim/app/gui_objects/_bus_bit_object.py +0 -0
  28. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/src/digsim/app/gui_objects/_buzzer_object.py +0 -0
  29. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/src/digsim/app/gui_objects/_component_context_menu.py +0 -0
  30. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/src/digsim/app/gui_objects/_component_object.py +0 -0
  31. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/src/digsim/app/gui_objects/_component_port_item.py +0 -0
  32. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/src/digsim/app/gui_objects/_dip_switch_object.py +0 -0
  33. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/src/digsim/app/gui_objects/_gui_note_object.py +0 -0
  34. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/src/digsim/app/gui_objects/_gui_object_factory.py +0 -0
  35. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/src/digsim/app/gui_objects/_hexdigit_object.py +0 -0
  36. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/src/digsim/app/gui_objects/_image_objects.py +0 -0
  37. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/src/digsim/app/gui_objects/_label_object.py +0 -0
  38. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/src/digsim/app/gui_objects/_logic_analyzer_object.py +0 -0
  39. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/src/digsim/app/gui_objects/_seven_segment_object.py +0 -0
  40. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/src/digsim/app/gui_objects/_shortcut_objects.py +0 -0
  41. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/src/digsim/app/gui_objects/_yosys_object.py +0 -0
  42. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/src/digsim/app/gui_objects/images/AND.png +0 -0
  43. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/src/digsim/app/gui_objects/images/Analyzer.png +0 -0
  44. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/src/digsim/app/gui_objects/images/BUF.png +0 -0
  45. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/src/digsim/app/gui_objects/images/Buzzer.png +0 -0
  46. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/src/digsim/app/gui_objects/images/Clock.png +0 -0
  47. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/src/digsim/app/gui_objects/images/DFF.png +0 -0
  48. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/src/digsim/app/gui_objects/images/DIP_SWITCH.png +0 -0
  49. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/src/digsim/app/gui_objects/images/FlipFlop.png +0 -0
  50. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/src/digsim/app/gui_objects/images/IC.png +0 -0
  51. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/src/digsim/app/gui_objects/images/LED_OFF.png +0 -0
  52. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/src/digsim/app/gui_objects/images/LED_ON.png +0 -0
  53. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/src/digsim/app/gui_objects/images/MUX.png +0 -0
  54. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/src/digsim/app/gui_objects/images/NAND.png +0 -0
  55. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/src/digsim/app/gui_objects/images/NOR.png +0 -0
  56. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/src/digsim/app/gui_objects/images/NOT.png +0 -0
  57. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/src/digsim/app/gui_objects/images/ONE.png +0 -0
  58. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/src/digsim/app/gui_objects/images/OR.png +0 -0
  59. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/src/digsim/app/gui_objects/images/PB.png +0 -0
  60. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/src/digsim/app/gui_objects/images/Switch_OFF.png +0 -0
  61. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/src/digsim/app/gui_objects/images/Switch_ON.png +0 -0
  62. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/src/digsim/app/gui_objects/images/XNOR.png +0 -0
  63. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/src/digsim/app/gui_objects/images/XOR.png +0 -0
  64. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/src/digsim/app/gui_objects/images/YOSYS.png +0 -0
  65. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/src/digsim/app/gui_objects/images/ZERO.png +0 -0
  66. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/src/digsim/app/images/app_icon.png +0 -0
  67. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/src/digsim/app/model/__init__.py +0 -0
  68. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/src/digsim/app/model/_model.py +0 -0
  69. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/src/digsim/app/model/_model_components.py +0 -0
  70. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/src/digsim/app/model/_model_new_wire.py +0 -0
  71. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/src/digsim/app/model/_model_objects.py +0 -0
  72. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/src/digsim/app/model/_model_settings.py +0 -0
  73. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/src/digsim/app/settings/__init__.py +0 -0
  74. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/src/digsim/app/settings/_component_settings.py +0 -0
  75. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/src/digsim/app/settings/_gui_settings.py +0 -0
  76. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/src/digsim/app/settings/_shortcut_dialog.py +0 -0
  77. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/src/digsim/circuit/__init__.py +0 -0
  78. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/src/digsim/circuit/_circuit.py +0 -0
  79. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/src/digsim/circuit/_waves_writer.py +0 -0
  80. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/src/digsim/circuit/components/__init__.py +0 -0
  81. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/src/digsim/circuit/components/_bus_bits.py +0 -0
  82. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/src/digsim/circuit/components/_button.py +0 -0
  83. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/src/digsim/circuit/components/_buzzer.py +0 -0
  84. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/src/digsim/circuit/components/_clock.py +0 -0
  85. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/src/digsim/circuit/components/_dip_switch.py +0 -0
  86. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/src/digsim/circuit/components/_flip_flops.py +0 -0
  87. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/src/digsim/circuit/components/_gates.py +0 -0
  88. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/src/digsim/circuit/components/_hexdigit.py +0 -0
  89. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/src/digsim/circuit/components/_ic.py +0 -0
  90. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/src/digsim/circuit/components/_label_wire.py +0 -0
  91. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/src/digsim/circuit/components/_led.py +0 -0
  92. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/src/digsim/circuit/components/_logic_analyzer.py +0 -0
  93. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/src/digsim/circuit/components/_mem64kbyte.py +0 -0
  94. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/src/digsim/circuit/components/_memstdout.py +0 -0
  95. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/src/digsim/circuit/components/_note.py +0 -0
  96. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/src/digsim/circuit/components/_on_off_switch.py +0 -0
  97. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/src/digsim/circuit/components/_seven_segment.py +0 -0
  98. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/src/digsim/circuit/components/_static_level.py +0 -0
  99. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/src/digsim/circuit/components/_static_value.py +0 -0
  100. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/src/digsim/circuit/components/_yosys_atoms.py +0 -0
  101. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/src/digsim/circuit/components/atoms/__init__.py +0 -0
  102. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/src/digsim/circuit/components/atoms/_component.py +0 -0
  103. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/src/digsim/circuit/components/atoms/_digsim_exception.py +0 -0
  104. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/src/digsim/circuit/components/atoms/_port.py +0 -0
  105. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/src/digsim/storage_model/__init__.py +0 -0
  106. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/src/digsim/storage_model/_app.py +0 -0
  107. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/src/digsim/storage_model/_circuit.py +0 -0
  108. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/src/digsim/synth/__init__.py +0 -0
  109. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/src/digsim/synth/__main__.py +0 -0
  110. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/src/digsim/synth/_synthesis.py +0 -0
  111. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/src/digsim_logic_simulator.egg-info/SOURCES.txt +0 -0
  112. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/src/digsim_logic_simulator.egg-info/dependency_links.txt +0 -0
  113. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/src/digsim_logic_simulator.egg-info/top_level.txt +0 -0
  114. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/tests/test_gates.py +0 -0
  115. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/tests/test_yosys_aldff.py +0 -0
  116. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/tests/test_yosys_dff.py +0 -0
  117. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/tests/test_yosys_dlatch.py +0 -0
  118. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/tests/test_yosys_gates.py +0 -0
  119. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/tests/test_yosys_latch.py +0 -0
  120. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/tests/test_yosys_sdff.py +0 -0
  121. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/tests/test_yosys_sr.py +0 -0
  122. {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.10.0}/tests/test_yosys_synth.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: digsim-logic-simulator
3
- Version: 0.8.0
3
+ Version: 0.10.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>
@@ -22,7 +22,7 @@ Requires-Dist: pyside6==6.9.1
22
22
  Requires-Dist: pexpect==4.9.0
23
23
  Requires-Dist: pydantic==2.11.7
24
24
  Requires-Dist: qtawesome==1.4.0
25
- Requires-Dist: yowasp-yosys==0.55.0.0.post944
25
+ Requires-Dist: yowasp-yosys==0.57.0.0.post986
26
26
  Dynamic: license-file
27
27
 
28
28
  # DigSim - Interactive Digital Logic Simulator
@@ -5,7 +5,7 @@ build-backend = "setuptools.build_meta"
5
5
  [project]
6
6
  name = "digsim-logic-simulator"
7
7
  description = "Interactive Digital Logic Simulator"
8
- version = "0.8.0"
8
+ version = "0.10.0"
9
9
  authors = [{name = "Fredrik Andersson", email = "freand@gmail.com"}]
10
10
  maintainers = [{name = "Fredrik Andersson", email = "freand@gmail.com"}]
11
11
  readme = "README.md"
@@ -30,7 +30,7 @@ dependencies = [
30
30
  "pexpect==4.9.0",
31
31
  "pydantic==2.11.7",
32
32
  "qtawesome==1.4.0",
33
- "yowasp-yosys==0.55.0.0.post944",
33
+ "yowasp-yosys==0.57.0.0.post986",
34
34
  ]
35
35
 
36
36
  keywords = ["educational", "simulation", "digital"]
@@ -77,10 +77,9 @@ class ModelShortcuts:
77
77
  shortcuts_dict[key] = component.name()
78
78
  return shortcuts_dict
79
79
 
80
- def from_dict(self, model_dict):
80
+ def from_dict(self, shortcuts_dict):
81
81
  """Generate shortcuts from dict"""
82
82
  self.clear()
83
- shortcuts_dict = model_dict.get("shortcuts")
84
83
  if shortcuts_dict is not None:
85
84
  for key, component_name in shortcuts_dict.items():
86
85
  component = self._app_model.objects.circuit.get_component(component_name)
@@ -10,8 +10,9 @@ import json
10
10
 
11
11
  import digsim.circuit.components._yosys_atoms
12
12
  from digsim.synth import Synthesis
13
- from digsim.utils import YosysNetlist
13
+ from digsim.utils import YosysCell, YosysModule, YosysNetlist
14
14
 
15
+ from ._static_level import GND, VDD
15
16
  from .atoms import Component, DigsimException, MultiComponent, PortMultiBitWire
16
17
 
17
18
 
@@ -29,6 +30,7 @@ class YosysComponent(MultiComponent):
29
30
  self._gates_comp = None
30
31
  self._net_comp = None
31
32
  self._netlist_module = None
33
+ self._netlist_nets = None
32
34
  self._setup_base()
33
35
 
34
36
  if nets:
@@ -47,13 +49,15 @@ class YosysComponent(MultiComponent):
47
49
  modules = netlist_object.get_modules()
48
50
  module_name = list(modules.keys())[0]
49
51
  self._netlist_module = netlist_object.get_modules()[module_name]
52
+ self._netlist_nets = self._netlist_module.get_nets()
53
+
50
54
  # Set Name
51
55
  self.set_name(module_name)
52
56
  self.set_display_name(module_name)
53
57
  # Add External Ports
54
- for portname, port_dict in self._netlist_module.get_external_interface().items():
58
+ for portname, port_dict in self._netlist_module.ports.items():
55
59
  external_port = PortMultiBitWire(
56
- self, portname, width=len(port_dict["nets"]), output=not port_dict["output"]
60
+ self, portname, width=len(port_dict.bits), output=port_dict.is_output
57
61
  )
58
62
  self.add_port(external_port)
59
63
  # Create component
@@ -64,18 +68,10 @@ class YosysComponent(MultiComponent):
64
68
  modules = netlist_object.get_modules()
65
69
  module_name = list(modules.keys())[0]
66
70
  reload_module = netlist_object.get_modules()[module_name]
71
+ reload_nets = reload_module.get_nets()
67
72
 
68
- # Verify that new external interface is the same as the current
69
- current_ext_if = self._netlist_module.get_external_interface()
70
- new_ext_if = reload_module.get_external_interface()
71
-
72
- if current_ext_if.keys() != new_ext_if.keys():
73
+ if not self._netlist_module.is_same_interface(reload_module):
73
74
  raise YosysComponentException("Yosys component interface differs")
74
- for key, _ in current_ext_if.items():
75
- if len(current_ext_if[key]["nets"]) != len(new_ext_if[key]["nets"]):
76
- raise YosysComponentException("Yosys component interface differs")
77
- if current_ext_if[key]["output"] != new_ext_if[key]["output"]:
78
- raise YosysComponentException("Yosys component interface differs")
79
75
 
80
76
  # Disconnect ports
81
77
  self._disconnect_external_ports()
@@ -86,63 +82,79 @@ class YosysComponent(MultiComponent):
86
82
  self._net_comp.delete_all_ports()
87
83
  # Setup netlist
88
84
  self._netlist_module = reload_module
85
+ self._netlist_nets = reload_nets
89
86
  # Create component
90
87
  self._create_component()
91
88
 
92
89
  def _create_cells(self):
93
90
  """Create cells in component"""
94
91
  components_dict = {}
95
- for cellname, cell in self._netlist_module.get_cells().items():
92
+ for cellname, cell in self._netlist_module.cells.items():
93
+ if cell.type == "$scopeinfo":
94
+ continue
96
95
  component_class = getattr(
97
- digsim.circuit.components._yosys_atoms, cell.get_friendly_type()
96
+ digsim.circuit.components._yosys_atoms, cell.component_type()
98
97
  )
99
- component = component_class(self._circuit, name=cell.get_friendly_name())
98
+ component = component_class(self._circuit, name=cell.component_name(cellname))
100
99
  self._gates_comp.add(component)
101
100
  components_dict[cellname] = component
101
+
102
+ vdd = VDD(self._circuit)
103
+ self._gates_comp.add(vdd)
104
+ components_dict["VDD"] = vdd
105
+ gnd = GND(self._circuit)
106
+ self._gates_comp.add(gnd)
107
+ components_dict["GND"] = gnd
108
+
102
109
  return components_dict
103
110
 
104
- def _connect_cell_port(self, components_dict, src_cell, source_port):
105
- """Connect cell ports"""
106
- src_comp = components_dict[src_cell.name()]
107
- src_comp_port = src_comp.port(source_port.name())
108
- net = source_port.get_nets()[0]
109
- for sink_port in source_port.get_sinks():
110
- if sink_port.get_parent().get_type() == "module":
111
+ def _connect_sinks(self, components_dict, src_comp_port, sinks):
112
+ """Connect a source port to multiple sinks"""
113
+ for sink_port in sinks:
114
+ if isinstance(sink_port.parent, YosysModule):
111
115
  # Connect cell output to module top
112
- for dst_bit, sink_net in enumerate(sink_port.get_nets()):
113
- if net == sink_net:
114
- dst_port = self.port(sink_port.name()).get_bit(dst_bit)
115
- src_comp_port.wire = dst_port
116
+ dst_port = self.port(sink_port.name).get_bit(sink_port.bit_index)
117
+ src_comp_port.wire = dst_port
116
118
  else:
117
119
  # Connect cell output to cell input
118
- dst_comp = components_dict[sink_port.get_parent().name()]
119
- src_comp_port.wire = dst_comp.port(sink_port.name())
120
+ dst_comp = components_dict[sink_port.parent_name]
121
+ src_comp_port.wire = dst_comp.port(sink_port.name)
120
122
 
121
123
  def _connect_cells(self, components_dict):
122
124
  """Connect all cells"""
123
- for _, src_cell in self._netlist_module.get_cells().items():
124
- for source_port in src_cell.get_source_ports():
125
- self._connect_cell_port(components_dict, src_cell, source_port)
125
+ for net, source in self._netlist_nets.source.items():
126
+ if isinstance(source.parent, YosysModule):
127
+ # Only connect cells here
128
+ continue
129
+ if isinstance(source.parent, YosysCell):
130
+ src_comp = components_dict[source.parent_name]
131
+ self._connect_sinks(
132
+ components_dict, src_comp.port(source.name), self._netlist_nets.sinks[net]
133
+ )
134
+
135
+ gnd_sinks = self._netlist_nets.sinks.get("0", [])
136
+ self._connect_sinks(components_dict, components_dict["GND"].port("O"), gnd_sinks)
137
+ vdd_sinks = self._netlist_nets.sinks.get("1", [])
138
+ self._connect_sinks(components_dict, components_dict["VDD"].port("O"), vdd_sinks)
126
139
 
127
140
  def _connect_external_input_port(self, components_dict, portname, port_dict):
128
- """Conenct external input port"""
129
- for bit_idx, net in enumerate(port_dict["nets"]):
130
- for sink_port in self._netlist_module.get_sinks(net):
131
- if sink_port.get_parent().get_type() == "module":
141
+ """Connect external input port"""
142
+ for bit_idx, net in enumerate(port_dict.bits):
143
+ for sink_port in self._netlist_nets.sinks[net]:
144
+ if isinstance(sink_port.parent, YosysModule):
132
145
  # Connect module input to module output
133
- for dst_bit, sink_net in enumerate(sink_port.get_nets()):
134
- if net == sink_net:
135
- dst_port = self.port(sink_port.name()).get_bit(dst_bit)
136
- self.port(portname).get_bit(bit_idx).wire = dst_port
146
+ dst_port = self.port(sink_port.name).get_bit(sink_port.bit_index)
147
+ self.port(portname).get_bit(bit_idx).wire = dst_port
137
148
  else:
138
149
  # Connect module input to cell input
139
- dst_comp = components_dict[sink_port.get_parent().name()]
140
- self.port(portname).get_bit(bit_idx).wire = dst_comp.port(sink_port.name())
150
+ self._connect_sinks(
151
+ components_dict, self.port(portname).get_bit(bit_idx), [sink_port]
152
+ )
141
153
 
142
154
  def _connect_external_input(self, components_dict):
143
155
  """Connect all external input ports"""
144
- for portname, port_dict in self._netlist_module.get_external_interface().items():
145
- if not port_dict["output"]:
156
+ for portname, port_dict in self._netlist_module.ports.items():
157
+ if port_dict.direction == "output":
146
158
  continue
147
159
  self._connect_external_input_port(components_dict, portname, port_dict)
148
160
 
@@ -176,8 +188,7 @@ class YosysComponent(MultiComponent):
176
188
  else:
177
189
  raise YosysComponentException(f"Unknown file extension '{self._path}'")
178
190
 
179
- yosys_netlist = YosysNetlist()
180
- yosys_netlist.from_dict(netlist_dict)
191
+ yosys_netlist = YosysNetlist(**netlist_dict)
181
192
  modules = yosys_netlist.get_modules()
182
193
 
183
194
  if len(modules) > 1:
@@ -1,6 +1,6 @@
1
1
 
2
2
  {
3
- "creator": "Yosys 0.53+101 (git sha1 2a25d9241, g++ 13.3.0-6ubuntu2~24.04 -fPIC -O3)",
3
+ "creator": "Yosys 0.57 (git sha1 3aca86049, ccache clang++ 18.1.3 -O3 -flto -flto)",
4
4
  "modules": {
5
5
  "ttl_74162": {
6
6
  "attributes": {
@@ -821,7 +821,7 @@
821
821
  }
822
822
  },
823
823
  "netnames": {
824
- "$abc$895$auto$opt_dff.cc:194:make_patterns_logic$32": {
824
+ "$abc$895$auto$opt_dff.cc:247:make_patterns_logic$32": {
825
825
  "hide_name": 1,
826
826
  "bits": [ 18 ],
827
827
  "attributes": {
@@ -1111,3 +1111,4 @@
1111
1111
  }
1112
1112
  }
1113
1113
  }
1114
+
@@ -1,6 +1,6 @@
1
1
 
2
2
  {
3
- "creator": "Yosys 0.53+101 (git sha1 2a25d9241, g++ 13.3.0-6ubuntu2~24.04 -fPIC -O3)",
3
+ "creator": "Yosys 0.57 (git sha1 3aca86049, ccache clang++ 18.1.3 -O3 -flto -flto)",
4
4
  "modules": {
5
5
  "ic7448": {
6
6
  "attributes": {
@@ -76,8 +76,8 @@
76
76
  "Y": "output"
77
77
  },
78
78
  "connections": {
79
- "A": [ 2 ],
80
- "B": [ 3 ],
79
+ "A": [ 3 ],
80
+ "B": [ 2 ],
81
81
  "Y": [ 15 ]
82
82
  }
83
83
  },
@@ -114,8 +114,8 @@
114
114
  "Y": "output"
115
115
  },
116
116
  "connections": {
117
- "A": [ 3 ],
118
- "B": [ 4 ],
117
+ "A": [ 4 ],
118
+ "B": [ 3 ],
119
119
  "Y": [ 17 ]
120
120
  }
121
121
  },
@@ -170,8 +170,8 @@
170
170
  "Y": "output"
171
171
  },
172
172
  "connections": {
173
- "A": [ 2 ],
174
- "B": [ 3 ],
173
+ "A": [ 3 ],
174
+ "B": [ 2 ],
175
175
  "Y": [ 19 ]
176
176
  }
177
177
  },
@@ -376,8 +376,8 @@
376
376
  "Y": "output"
377
377
  },
378
378
  "connections": {
379
- "A": [ 2 ],
380
- "B": [ 3 ],
379
+ "A": [ 3 ],
380
+ "B": [ 2 ],
381
381
  "Y": [ 28 ]
382
382
  }
383
383
  },
@@ -526,8 +526,8 @@
526
526
  "Y": "output"
527
527
  },
528
528
  "connections": {
529
- "A": [ 2 ],
530
- "B": [ 3 ],
529
+ "A": [ 3 ],
530
+ "B": [ 2 ],
531
531
  "Y": [ 34 ]
532
532
  }
533
533
  },
@@ -600,8 +600,8 @@
600
600
  "Y": "output"
601
601
  },
602
602
  "connections": {
603
- "A": [ 2 ],
604
- "B": [ 3 ],
603
+ "A": [ 3 ],
604
+ "B": [ 2 ],
605
605
  "Y": [ 37 ]
606
606
  }
607
607
  },
@@ -895,3 +895,4 @@
895
895
  }
896
896
  }
897
897
  }
898
+
@@ -3,4 +3,4 @@
3
3
 
4
4
  """All classes within digsim.utils namespace"""
5
5
 
6
- from ._yosys_netlist import YosysNetlist # noqa: F401
6
+ from ._yosys_netlist import YosysCell, YosysModule, YosysNetlist # noqa: F401
@@ -0,0 +1,128 @@
1
+ # Copyright (c) Fredrik Andersson, 2023
2
+ # All rights reserved
3
+
4
+ """
5
+ Module with classes to parse a yosys netlist
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ from typing import Any, Optional, Union
11
+
12
+ from pydantic import Field
13
+ from pydantic.dataclasses import dataclass
14
+
15
+
16
+ @dataclass
17
+ class NetPort:
18
+ parent: Union[YosysModule, YosysCell]
19
+ parent_name: str
20
+ name: str
21
+ bit_index: Optional[int] = None
22
+
23
+
24
+ @dataclass
25
+ class Nets:
26
+ source: dict[int, NetPort] = Field(default_factory=dict)
27
+ sinks: dict[int, list[NetPort]] = Field(default_factory=dict)
28
+
29
+
30
+ @dataclass
31
+ class YosysPort:
32
+ direction: str
33
+ bits: list[Union[int, str]]
34
+
35
+ @property
36
+ def is_output(self):
37
+ return self.direction == "output"
38
+
39
+ def is_same(self, compare_port):
40
+ return (compare_port.direction == self.direction) and (
41
+ len(compare_port.bits) == len(self.bits)
42
+ )
43
+
44
+
45
+ @dataclass
46
+ class YosysCell:
47
+ type: str
48
+ port_directions: dict[str, str] = Field(default_factory=dict)
49
+ connections: dict[str, list[Union[str, int]]] = Field(default_factory=dict)
50
+ hide_name: int = 0
51
+ parameters: dict[str, Any] = Field(default_factory=dict)
52
+ attributes: dict[str, Any] = Field(default_factory=dict)
53
+
54
+ def get_nets(self, name, nets):
55
+ for port_name, net_list in self.connections.items():
56
+ net = net_list[0]
57
+ port = NetPort(parent=self, parent_name=name, name=port_name)
58
+ if self.port_directions[port_name] == "input":
59
+ if net not in nets.sinks:
60
+ nets.sinks[net] = []
61
+ nets.sinks[net].append(port)
62
+ else:
63
+ nets.source[net] = port
64
+
65
+ def component_name(self, name):
66
+ """Return a friendly name for a netlist cell"""
67
+ return f"{name.split('$')[-1]}_{self.component_type()}"
68
+
69
+ def component_type(self):
70
+ """Return a friendly type for a netlist cell"""
71
+ return f"_{self.type[2:-1]}_"
72
+
73
+
74
+ @dataclass
75
+ class YosysNetName:
76
+ bits: list[int]
77
+ attributes: dict[str, Any] = Field(default_factory=dict)
78
+ hide_name: int = 0
79
+
80
+
81
+ @dataclass
82
+ class YosysModule:
83
+ attributes: dict[str, Any] = Field(default_factory=dict)
84
+ parameter_default_values: dict[str, Any] = Field(default_factory=dict)
85
+ ports: dict[str, YosysPort] = Field(default_factory=dict)
86
+ cells: dict[str, YosysCell] = Field(default_factory=dict)
87
+ netnames: dict[str, YosysNetName] = Field(default_factory=dict)
88
+
89
+ def is_same_interface(self, netlist):
90
+ is_same = True
91
+ if len(netlist.ports) == len(self.ports):
92
+ for netlist_port_name, netlist_port in netlist.ports.items():
93
+ module_port = self.ports.get(netlist_port_name)
94
+ if module_port is None or not module_port.is_same(netlist_port):
95
+ # Port does not exist or has a different bitwidth
96
+ is_same = False
97
+ break
98
+ else:
99
+ # The number of ports does not match
100
+ is_same = False
101
+ return is_same
102
+
103
+ def get_nets(self):
104
+ nets = Nets()
105
+
106
+ for port_name, port_item in self.ports.items():
107
+ for bit_index, net in enumerate(port_item.bits):
108
+ port = NetPort(parent=self, parent_name="top", name=port_name, bit_index=bit_index)
109
+ if port_item.is_output:
110
+ if net not in nets.sinks:
111
+ nets.sinks[net] = []
112
+ nets.sinks[net].append(port)
113
+ else:
114
+ nets.source[net] = port
115
+
116
+ for cell_name, cell in self.cells.items():
117
+ cell.get_nets(cell_name, nets)
118
+
119
+ return nets
120
+
121
+
122
+ @dataclass
123
+ class YosysNetlist:
124
+ creator: Optional[str] = None
125
+ modules: dict[str, YosysModule] = Field(default_factory=dict)
126
+
127
+ def get_modules(self):
128
+ return self.modules
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: digsim-logic-simulator
3
- Version: 0.8.0
3
+ Version: 0.10.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>
@@ -22,7 +22,7 @@ Requires-Dist: pyside6==6.9.1
22
22
  Requires-Dist: pexpect==4.9.0
23
23
  Requires-Dist: pydantic==2.11.7
24
24
  Requires-Dist: qtawesome==1.4.0
25
- Requires-Dist: yowasp-yosys==0.55.0.0.post944
25
+ Requires-Dist: yowasp-yosys==0.57.0.0.post986
26
26
  Dynamic: license-file
27
27
 
28
28
  # DigSim - Interactive Digital Logic Simulator
@@ -3,4 +3,4 @@ pyside6==6.9.1
3
3
  pexpect==4.9.0
4
4
  pydantic==2.11.7
5
5
  qtawesome==1.4.0
6
- yowasp-yosys==0.55.0.0.post944
6
+ yowasp-yosys==0.57.0.0.post986
@@ -3,6 +3,9 @@
3
3
 
4
4
  """Pystest module to test functionality of yosys component"""
5
5
 
6
+ import json
7
+ from pathlib import Path
8
+
6
9
  import pytest
7
10
 
8
11
  from digsim.circuit import Circuit
@@ -58,13 +61,39 @@ netlist_dict_if_four = {
58
61
  }
59
62
  }
60
63
 
64
+ netlist_dict_if_2outports = {
65
+ "modules": {
66
+ "counter": {
67
+ "ports": {
68
+ "in_port": {"direction": "input", "bits": [2, 3, 4, 5]},
69
+ "out_port_a": {"direction": "output", "bits": [2, 3, 4, 5]},
70
+ "out_port_b": {"direction": "output", "bits": [2, 3, 4, 5]},
71
+ },
72
+ "cells": {},
73
+ }
74
+ }
75
+ }
76
+
77
+ netlist_dict_if_3outports = {
78
+ "modules": {
79
+ "counter": {
80
+ "ports": {
81
+ "in_port": {"direction": "input", "bits": [2, 3, 4, 5]},
82
+ "out_port_a": {"direction": "output", "bits": [2, 3, 4, 5]},
83
+ "out_port_b": {"direction": "output", "bits": [2, 3, 4, 5]},
84
+ "out_port_c": {"direction": "output", "bits": [2, 3, 4, 5]},
85
+ },
86
+ "cells": {},
87
+ }
88
+ }
89
+ }
90
+
61
91
 
62
92
  def test_yosys_component_create():
63
93
  """Test create YosysComponent"""
64
94
  circuit = Circuit()
65
95
  comp = YosysComponent(circuit)
66
- yosys_netlist = YosysNetlist()
67
- yosys_netlist.from_dict(netlist_dict_if_one)
96
+ yosys_netlist = YosysNetlist(**netlist_dict_if_one)
68
97
  comp.create_from_netlist(yosys_netlist)
69
98
 
70
99
  comp.in_port.value = 0xA
@@ -76,16 +105,14 @@ def test_yosys_component_create_reload():
76
105
  """Test create YosysComponent - and reload changed netlist OK"""
77
106
  circuit = Circuit()
78
107
  comp = YosysComponent(circuit)
79
- yosys_netlist = YosysNetlist()
80
- yosys_netlist.from_dict(netlist_dict_if_one)
108
+ yosys_netlist = YosysNetlist(**netlist_dict_if_one)
81
109
  comp.create_from_netlist(yosys_netlist)
82
110
 
83
111
  comp.in_port.value = 0xA
84
112
  circuit.run(ms=1)
85
113
  assert comp.out_port.value == 0x5
86
114
 
87
- yosys_netlist = YosysNetlist()
88
- yosys_netlist.from_dict(netlist_dict_if_two)
115
+ yosys_netlist = YosysNetlist(**netlist_dict_if_two)
89
116
  comp.reload_from_netlist(yosys_netlist)
90
117
 
91
118
  comp.in_port.value = 0xA
@@ -93,28 +120,54 @@ def test_yosys_component_create_reload():
93
120
  assert comp.out_port.value == 0xA
94
121
 
95
122
 
96
- def test_yosys_component_create_reload_fail():
123
+ def test_yosys_component_create_reload_fail_portwidth():
97
124
  """Test create YosysComponent - and reload changed netlist OK"""
98
125
  circuit = Circuit()
99
126
  comp = YosysComponent(circuit)
100
- yosys_netlist = YosysNetlist()
101
- yosys_netlist.from_dict(netlist_dict_if_one)
127
+ yosys_netlist = YosysNetlist(**netlist_dict_if_one)
102
128
  comp.create_from_netlist(yosys_netlist)
103
129
 
104
- yosys_netlist = YosysNetlist()
105
- yosys_netlist.from_dict(netlist_dict_if_three)
130
+ yosys_netlist = YosysNetlist(**netlist_dict_if_three)
106
131
 
107
132
  # Fail due to wider in_port
108
133
  with pytest.raises(YosysComponentException):
109
134
  comp.reload_from_netlist(yosys_netlist)
110
135
 
111
- yosys_netlist.from_dict(netlist_dict_if_four)
136
+ yosys_netlist = YosysNetlist(**netlist_dict_if_four)
112
137
 
113
138
  # Fail due to wider out_port
114
139
  with pytest.raises(YosysComponentException):
115
140
  comp.reload_from_netlist(yosys_netlist)
116
141
 
117
142
 
143
+ def test_yosys_component_create_reload_fail_extra_ports():
144
+ """Test create YosysComponent - and reload changed netlist OK"""
145
+ circuit = Circuit()
146
+ comp = YosysComponent(circuit)
147
+ yosys_netlist = YosysNetlist(**netlist_dict_if_2outports)
148
+ comp.create_from_netlist(yosys_netlist)
149
+
150
+ yosys_netlist = YosysNetlist(**netlist_dict_if_3outports)
151
+
152
+ # Fail due to extra port
153
+ with pytest.raises(YosysComponentException):
154
+ comp.reload_from_netlist(yosys_netlist)
155
+
156
+
157
+ def test_yosys_component_create_reload_fail_less_ports():
158
+ """Test create YosysComponent - and reload changed netlist OK"""
159
+ circuit = Circuit()
160
+ comp = YosysComponent(circuit)
161
+ yosys_netlist = YosysNetlist(**netlist_dict_if_3outports)
162
+ comp.create_from_netlist(yosys_netlist)
163
+
164
+ yosys_netlist = YosysNetlist(**netlist_dict_if_2outports)
165
+
166
+ # Fail due to extra port
167
+ with pytest.raises(YosysComponentException):
168
+ comp.reload_from_netlist(yosys_netlist)
169
+
170
+
118
171
  def test_yosys_component_create_static_levels():
119
172
  """Test create YosysComponent - with static levels"""
120
173
  netlist_dict_static = {
@@ -132,8 +185,7 @@ def test_yosys_component_create_static_levels():
132
185
  }
133
186
  circuit = Circuit()
134
187
  comp = YosysComponent(circuit)
135
- yosys_netlist = YosysNetlist()
136
- yosys_netlist.from_dict(netlist_dict_static)
188
+ yosys_netlist = YosysNetlist(**netlist_dict_static)
137
189
  comp.create_from_netlist(yosys_netlist)
138
190
  circuit.init()
139
191
  circuit.run(ms=1)
@@ -167,8 +219,7 @@ def test_yosys_component_not_gate_multiple_outputs():
167
219
  }
168
220
  circuit = Circuit()
169
221
  comp = YosysComponent(circuit)
170
- yosys_netlist = YosysNetlist()
171
- yosys_netlist.from_dict(netlist_dict)
222
+ yosys_netlist = YosysNetlist(**netlist_dict)
172
223
  comp.create_from_netlist(yosys_netlist)
173
224
  circuit.init()
174
225
  comp.in_port.value = 0
@@ -202,10 +253,18 @@ def test_yosys_component_not_gate_static_input():
202
253
  }
203
254
  circuit = Circuit()
204
255
  comp = YosysComponent(circuit)
205
- yosys_netlist = YosysNetlist()
206
- yosys_netlist.from_dict(netlist_dict)
256
+ yosys_netlist = YosysNetlist(**netlist_dict)
207
257
  comp.create_from_netlist(yosys_netlist)
208
258
  circuit.init()
209
259
  assert comp.out_port.value == "X"
210
260
  circuit.run(ms=1)
211
261
  assert comp.out_port.value == 1
262
+
263
+
264
+ def test_yosys_complex_netlist():
265
+ comlex_json_netlist_file = (
266
+ Path(__file__).parent.parent / "src/digsim/circuit/components/ic/74162.json"
267
+ )
268
+ with open(comlex_json_netlist_file, encoding="utf-8") as json_file:
269
+ netlist_dict = json.load(json_file)
270
+ YosysNetlist(**netlist_dict)