digsim-logic-simulator 0.7.0__tar.gz → 0.9.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 (123) hide show
  1. {digsim_logic_simulator-0.7.0/src/digsim_logic_simulator.egg-info → digsim_logic_simulator-0.9.0}/PKG-INFO +5 -38
  2. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/pyproject.toml +6 -6
  3. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/gui/_circuit_area.py +2 -2
  4. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/gui_objects/_image_objects.py +4 -2
  5. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/src/digsim/circuit/_circuit.py +60 -41
  6. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/src/digsim/circuit/_waves_writer.py +19 -8
  7. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/src/digsim/circuit/components/_label_wire.py +3 -3
  8. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/src/digsim/circuit/components/_yosys_component.py +57 -46
  9. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/src/digsim/circuit/components/atoms/__init__.py +2 -1
  10. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/src/digsim/circuit/components/atoms/_component.py +40 -37
  11. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/src/digsim/circuit/components/atoms/_port.py +70 -65
  12. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/src/digsim/circuit/components/ic/74162.json +88 -86
  13. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/src/digsim/circuit/components/ic/7448.json +75 -73
  14. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/src/digsim/utils/__init__.py +1 -1
  15. digsim_logic_simulator-0.9.0/src/digsim/utils/_yosys_netlist.py +123 -0
  16. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0/src/digsim_logic_simulator.egg-info}/PKG-INFO +5 -38
  17. digsim_logic_simulator-0.9.0/src/digsim_logic_simulator.egg-info/requires.txt +6 -0
  18. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/tests/test_yosys_netlist.py +21 -17
  19. digsim_logic_simulator-0.7.0/src/digsim/utils/_yosys_netlist.py +0 -270
  20. digsim_logic_simulator-0.7.0/src/digsim_logic_simulator.egg-info/requires.txt +0 -6
  21. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/LICENSE.md +0 -0
  22. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/MANIFEST.in +0 -0
  23. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/README.md +0 -0
  24. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/setup.cfg +0 -0
  25. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/src/digsim/__init__.py +0 -0
  26. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/__main__.py +0 -0
  27. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/gui/__init__.py +0 -0
  28. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/gui/_component_selection.py +0 -0
  29. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/gui/_main_window.py +0 -0
  30. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/gui/_top_bar.py +0 -0
  31. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/gui/_utils.py +0 -0
  32. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/gui/_warning_dialog.py +0 -0
  33. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/gui_objects/__init__.py +0 -0
  34. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/gui_objects/_bus_bit_object.py +0 -0
  35. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/gui_objects/_buzzer_object.py +0 -0
  36. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/gui_objects/_component_context_menu.py +0 -0
  37. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/gui_objects/_component_object.py +0 -0
  38. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/gui_objects/_component_port_item.py +0 -0
  39. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/gui_objects/_dip_switch_object.py +0 -0
  40. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/gui_objects/_gui_note_object.py +0 -0
  41. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/gui_objects/_gui_object_factory.py +0 -0
  42. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/gui_objects/_hexdigit_object.py +0 -0
  43. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/gui_objects/_label_object.py +0 -0
  44. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/gui_objects/_logic_analyzer_object.py +0 -0
  45. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/gui_objects/_seven_segment_object.py +0 -0
  46. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/gui_objects/_shortcut_objects.py +0 -0
  47. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/gui_objects/_yosys_object.py +0 -0
  48. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/gui_objects/images/AND.png +0 -0
  49. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/gui_objects/images/Analyzer.png +0 -0
  50. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/gui_objects/images/BUF.png +0 -0
  51. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/gui_objects/images/Buzzer.png +0 -0
  52. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/gui_objects/images/Clock.png +0 -0
  53. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/gui_objects/images/DFF.png +0 -0
  54. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/gui_objects/images/DIP_SWITCH.png +0 -0
  55. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/gui_objects/images/FlipFlop.png +0 -0
  56. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/gui_objects/images/IC.png +0 -0
  57. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/gui_objects/images/LED_OFF.png +0 -0
  58. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/gui_objects/images/LED_ON.png +0 -0
  59. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/gui_objects/images/MUX.png +0 -0
  60. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/gui_objects/images/NAND.png +0 -0
  61. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/gui_objects/images/NOR.png +0 -0
  62. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/gui_objects/images/NOT.png +0 -0
  63. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/gui_objects/images/ONE.png +0 -0
  64. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/gui_objects/images/OR.png +0 -0
  65. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/gui_objects/images/PB.png +0 -0
  66. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/gui_objects/images/Switch_OFF.png +0 -0
  67. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/gui_objects/images/Switch_ON.png +0 -0
  68. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/gui_objects/images/XNOR.png +0 -0
  69. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/gui_objects/images/XOR.png +0 -0
  70. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/gui_objects/images/YOSYS.png +0 -0
  71. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/gui_objects/images/ZERO.png +0 -0
  72. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/images/app_icon.png +0 -0
  73. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/model/__init__.py +0 -0
  74. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/model/_model.py +0 -0
  75. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/model/_model_components.py +0 -0
  76. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/model/_model_new_wire.py +0 -0
  77. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/model/_model_objects.py +0 -0
  78. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/model/_model_settings.py +0 -0
  79. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/model/_model_shortcuts.py +0 -0
  80. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/settings/__init__.py +0 -0
  81. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/settings/_component_settings.py +0 -0
  82. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/settings/_gui_settings.py +0 -0
  83. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/settings/_shortcut_dialog.py +0 -0
  84. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/src/digsim/circuit/__init__.py +0 -0
  85. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/src/digsim/circuit/components/__init__.py +0 -0
  86. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/src/digsim/circuit/components/_bus_bits.py +0 -0
  87. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/src/digsim/circuit/components/_button.py +0 -0
  88. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/src/digsim/circuit/components/_buzzer.py +0 -0
  89. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/src/digsim/circuit/components/_clock.py +0 -0
  90. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/src/digsim/circuit/components/_dip_switch.py +0 -0
  91. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/src/digsim/circuit/components/_flip_flops.py +0 -0
  92. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/src/digsim/circuit/components/_gates.py +0 -0
  93. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/src/digsim/circuit/components/_hexdigit.py +0 -0
  94. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/src/digsim/circuit/components/_ic.py +0 -0
  95. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/src/digsim/circuit/components/_led.py +0 -0
  96. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/src/digsim/circuit/components/_logic_analyzer.py +0 -0
  97. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/src/digsim/circuit/components/_mem64kbyte.py +0 -0
  98. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/src/digsim/circuit/components/_memstdout.py +0 -0
  99. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/src/digsim/circuit/components/_note.py +0 -0
  100. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/src/digsim/circuit/components/_on_off_switch.py +0 -0
  101. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/src/digsim/circuit/components/_seven_segment.py +0 -0
  102. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/src/digsim/circuit/components/_static_level.py +0 -0
  103. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/src/digsim/circuit/components/_static_value.py +0 -0
  104. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/src/digsim/circuit/components/_yosys_atoms.py +0 -0
  105. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/src/digsim/circuit/components/atoms/_digsim_exception.py +0 -0
  106. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/src/digsim/storage_model/__init__.py +0 -0
  107. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/src/digsim/storage_model/_app.py +0 -0
  108. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/src/digsim/storage_model/_circuit.py +0 -0
  109. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/src/digsim/synth/__init__.py +0 -0
  110. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/src/digsim/synth/__main__.py +0 -0
  111. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/src/digsim/synth/_synthesis.py +0 -0
  112. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/src/digsim_logic_simulator.egg-info/SOURCES.txt +0 -0
  113. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/src/digsim_logic_simulator.egg-info/dependency_links.txt +0 -0
  114. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/src/digsim_logic_simulator.egg-info/top_level.txt +0 -0
  115. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/tests/test_gates.py +0 -0
  116. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/tests/test_yosys_aldff.py +0 -0
  117. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/tests/test_yosys_dff.py +0 -0
  118. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/tests/test_yosys_dlatch.py +0 -0
  119. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/tests/test_yosys_gates.py +0 -0
  120. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/tests/test_yosys_latch.py +0 -0
  121. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/tests/test_yosys_sdff.py +0 -0
  122. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/tests/test_yosys_sr.py +0 -0
  123. {digsim_logic_simulator-0.7.0 → digsim_logic_simulator-0.9.0}/tests/test_yosys_synth.py +0 -0
@@ -1,42 +1,9 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: digsim-logic-simulator
3
- Version: 0.7.0
3
+ Version: 0.9.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
- License: The Clear BSD License
8
-
9
- Copyright (c) 2023-2024, Fredrik Andersson
10
- All rights reserved.
11
-
12
- Redistribution and use in source and binary forms, with or without
13
- modification, are permitted provided that the following conditions are met:
14
-
15
- * Redistributions of source code must retain the above copyright notice, this
16
- list of conditions and the following disclaimer.
17
-
18
- * Redistributions in binary form must reproduce the above copyright notice,
19
- this list of conditions and the following disclaimer in the documentation
20
- and/or other materials provided with the distribution.
21
-
22
- * Neither the name of the copyright holder nor the names of its
23
- contributors may be used to endorse or promote products derived from
24
- this software without specific prior written permission.
25
-
26
- NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS
27
- LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
28
- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
29
- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30
- ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
31
- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32
- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
33
- GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34
- HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35
- LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
36
- OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37
-
38
- -------------------------------------------------------------------------------
39
-
40
7
  Project-URL: homepage, https://github.com/freand76/digsim
41
8
  Keywords: educational,simulation,digital
42
9
  Classifier: Development Status :: 5 - Production/Stable
@@ -50,12 +17,12 @@ Classifier: Programming Language :: Python :: 3 :: Only
50
17
  Requires-Python: >=3.9
51
18
  Description-Content-Type: text/markdown
52
19
  License-File: LICENSE.md
53
- Requires-Dist: pyvcd>=0.4.1
54
- Requires-Dist: pyside6>=6.9.0
20
+ Requires-Dist: pyvcd==0.4.1
21
+ Requires-Dist: pyside6==6.9.1
55
22
  Requires-Dist: pexpect==4.9.0
56
- Requires-Dist: pydantic==2.11.4
23
+ Requires-Dist: pydantic==2.11.7
57
24
  Requires-Dist: qtawesome==1.4.0
58
- Requires-Dist: yowasp-yosys==0.53.0.0.post912
25
+ Requires-Dist: yowasp-yosys==0.57.0.0.post986
59
26
  Dynamic: license-file
60
27
 
61
28
  # DigSim - Interactive Digital Logic Simulator
@@ -5,11 +5,11 @@ build-backend = "setuptools.build_meta"
5
5
  [project]
6
6
  name = "digsim-logic-simulator"
7
7
  description = "Interactive Digital Logic Simulator"
8
- version = "0.7.0"
8
+ version = "0.9.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"
12
- license = { file = "LICENSE.md" }
12
+ license-files = ["LICENSE.md"]
13
13
  urls = { homepage = "https://github.com/freand76/digsim" }
14
14
 
15
15
  classifiers = [
@@ -25,12 +25,12 @@ classifiers = [
25
25
 
26
26
  requires-python = ">=3.9"
27
27
  dependencies = [
28
- "pyvcd>=0.4.1",
29
- "pyside6>=6.9.0",
28
+ "pyvcd==0.4.1",
29
+ "pyside6==6.9.1",
30
30
  "pexpect==4.9.0",
31
- "pydantic==2.11.4",
31
+ "pydantic==2.11.7",
32
32
  "qtawesome==1.4.0",
33
- "yowasp-yosys==0.53.0.0.post912",
33
+ "yowasp-yosys==0.57.0.0.post986",
34
34
  ]
35
35
 
36
36
  keywords = ["educational", "simulation", "digital"]
@@ -1,4 +1,4 @@
1
- # Copyright (c) Fredrik Andersson, 2023-2024
1
+ # Copyright (c) Fredrik Andersson, 2023-2025
2
2
  # All rights reserved
3
3
 
4
4
  """The circuit area and component widget"""
@@ -275,7 +275,7 @@ class _CircuitAreaScene(QGraphicsScene):
275
275
  component_objects = self._app_model.objects.components.get_object_list()
276
276
  for src_comp_item in component_objects:
277
277
  for src_port in src_comp_item.component.outports():
278
- for dst_port in src_port.get_wires():
278
+ for dst_port in src_port.wired_ports:
279
279
  dst_comp_item = self._app_model.objects.components.get_object(
280
280
  dst_port.parent()
281
281
  )
@@ -3,6 +3,8 @@
3
3
 
4
4
  """A component with an image as symbol the GUI"""
5
5
 
6
+ from __future__ import annotations
7
+
6
8
  from pathlib import Path
7
9
 
8
10
  from PySide6.QtCore import QPoint, Qt
@@ -14,8 +16,8 @@ from ._component_object import ComponentObject
14
16
  class ImageObject(ComponentObject):
15
17
  """The class for a image component placed in the GUI"""
16
18
 
17
- IMAGE_FILENAME = None
18
- ACTIVE_IMAGE_FILENAME = None
19
+ IMAGE_FILENAME: str | None = None
20
+ ACTIVE_IMAGE_FILENAME: str | None = None
19
21
  _pixmap = None
20
22
  _pixmap_active = None
21
23
 
@@ -1,16 +1,19 @@
1
- # Copyright (c) Fredrik Andersson, 2023-2024
1
+ # Copyright (c) Fredrik Andersson, 2023-2025
2
2
  # All rights reserved
3
3
 
4
4
  """
5
5
  Module that handles the circuit simulation of components
6
6
  """
7
7
 
8
+ from __future__ import annotations
9
+
8
10
  import os
11
+ from typing import Tuple
9
12
 
10
13
  from digsim.storage_model import CircuitDataClass, CircuitFileDataClass
11
14
 
12
15
  from ._waves_writer import WavesWriter
13
- from .components.atoms import DigsimException
16
+ from .components.atoms import Component, DigsimException, PortOutDelta
14
17
 
15
18
 
16
19
  class CircuitError(DigsimException):
@@ -23,90 +26,89 @@ class CircuitEvent:
23
26
  delta events in the simulation.
24
27
  """
25
28
 
26
- def __init__(self, time_ns, port, value):
27
- self._time_ns = time_ns
28
- self._port = port
29
- self._value = value
29
+ def __init__(self, time_ns: int, port: PortOutDelta, value: int | str | None):
30
+ self._time_ns: int = time_ns
31
+ self._port: PortOutDelta = port
32
+ self._value: int | str | None = value
30
33
 
31
34
  @property
32
- def time_ns(self):
35
+ def time_ns(self) -> int:
33
36
  """Get the simulation time (ns) of this event"""
34
37
  return self._time_ns
35
38
 
36
39
  @property
37
- def port(self):
40
+ def port(self) -> PortOutDelta:
38
41
  """Get the port of this event"""
39
42
  return self._port
40
43
 
41
44
  @property
42
- def value(self):
45
+ def value(self) -> int | str | None:
43
46
  """Get the delta cycle value of this event"""
44
47
  return self._value
45
48
 
46
- def is_same_event(self, port):
49
+ def is_same_event(self, port: PortOutDelta):
47
50
  """Return True if the in the event is the same as"""
48
51
  return port == self._port
49
52
 
50
- def update(self, time_ns, value):
53
+ def update(self, time_ns: int, value: int | str | None):
51
54
  """Update the event with a new time (ns) and a new value"""
52
55
  self._time_ns = time_ns
53
56
  self._value = value
54
57
 
55
- def __lt__(self, other):
58
+ def __lt__(self, other) -> bool:
56
59
  return other.time_ns > self.time_ns
57
60
 
58
61
 
59
62
  class Circuit:
60
63
  """Class thay handles the circuit simulation"""
61
64
 
62
- def __init__(self, name=None, vcd=None):
63
- self._components = {}
64
- self._circuit_events = []
65
- self._name = name
66
- self._time_ns = 0
67
- self._folder = None
65
+ def __init__(self, name: str | None = None, vcd: str | None = None):
66
+ self._components: dict[str, Component] = {}
67
+ self._circuit_events: list[CircuitEvent] = []
68
+ self._name: str | None = name
69
+ self._time_ns: int = 0
70
+ self._folder: str | None = None
71
+ self._vcd: WavesWriter | None = None
68
72
 
69
73
  if vcd is not None:
70
74
  self._vcd = WavesWriter(filename=vcd)
71
- else:
72
- self._vcd = None
73
75
 
74
76
  @property
75
- def name(self):
77
+ def name(self) -> str | None:
76
78
  """Get the circuit name"""
77
79
  return self._name
78
80
 
79
81
  @property
80
- def time_ns(self):
82
+ def time_ns(self) -> int:
81
83
  """Get the current simulation time (ns)"""
82
84
  return self._time_ns
83
85
 
84
86
  @property
85
- def components(self):
87
+ def components(self) -> list[Component]:
86
88
  """Get the components in this circuit"""
87
89
  comp_array = []
88
90
  for _, comp in self._components.items():
89
91
  comp_array.append(comp)
90
92
  return comp_array
91
93
 
92
- def load_path(self, path):
94
+ def load_path(self, path) -> str:
93
95
  """Get the load path relative to the circuit path"""
94
96
  if self._folder is not None:
95
97
  return self._folder + "/" + path
96
98
  return path
97
99
 
98
- def store_path(self, path):
100
+ def store_path(self, path) -> str:
99
101
  """Get the store path relative to the circuit path"""
100
102
  if self._folder is not None:
101
103
  return os.path.relpath(path, self._folder)
102
104
  return path
103
105
 
104
- def delete_component(self, component):
106
+ def delete_component(self, component: Component):
105
107
  """Delete a component from the circuit"""
106
108
  del self._components[component.name()]
107
109
  component.remove_connections()
108
110
 
109
- def get_toplevel_components(self):
111
+ def get_toplevel_components(self) -> list[Component]:
110
112
  """Get toplevel components in the circuit"""
111
113
  toplevel_components = []
112
114
  for _, comp in self._components.items():
@@ -157,7 +159,7 @@ class Circuit:
157
159
  for port in comp.ports:
158
160
  self._vcd.write(port, self._time_ns)
159
161
 
160
- def _time_to_ns(self, s=None, ms=None, us=None, ns=None):
162
+ def _time_to_ns(self, s=None, ms=None, us=None, ns=None) -> int:
161
163
  time_ns = 0
162
164
  time_ns += s * 1e9 if s is not None else 0
163
165
  time_ns += ms * 1e6 if ms is not None else 0
@@ -168,7 +170,7 @@ class Circuit:
168
170
  def __exit__(self, exc_type, exc_value, exc_traceback):
169
171
  self._vcd.close()
170
172
 
171
- def process_single_event(self, stop_time_ns=None):
173
+ def process_single_event(self, stop_time_ns=None) -> Tuple[bool, bool]:
172
174
  """
173
175
  Process one simulation event
174
176
  Return False if ther are now events of if the stop_time has passed
@@ -190,13 +192,20 @@ class Circuit:
190
192
  self._vcd.write(event.port, self._time_ns)
191
193
  return True, toplevel
192
194
 
193
- def _is_toplevel_event(self):
195
+ def _is_toplevel_event(self) -> bool:
194
196
  if len(self._circuit_events) == 0:
195
197
  return False
196
198
  event = self._circuit_events[0]
197
199
  return event.port.parent().is_toplevel()
198
200
 
199
- def run(self, s=None, ms=None, us=None, ns=None, single_step=False):
201
+ def run(
202
+ self,
203
+ s: int | None = None,
204
+ ms: int | None = None,
205
+ us: int | None = None,
206
+ ns: int | None = None,
207
+ single_step: bool = False,
208
+ ) -> bool:
200
209
  """Run simulation for a period of time"""
201
210
  stop_time_ns = self._time_ns + self._time_to_ns(s=s, ms=ms, us=us, ns=ns)
202
211
  single_step_stop = False
@@ -210,13 +219,19 @@ class Circuit:
210
219
  self._time_ns = max(self._time_ns, stop_time_ns)
211
220
  return single_step_stop
212
221
 
213
- def run_until(self, s=None, ms=None, us=None, ns=None):
222
+ def run_until(
223
+ self,
224
+ s: int | None = None,
225
+ ms: int | None = None,
226
+ us: int | None = None,
227
+ ns: int | None = None,
228
+ ):
214
229
  """Run simulation until a specified time"""
215
230
  stop_time_ns = self._time_to_ns(s=s, ms=ms, us=us, ns=ns)
216
231
  if stop_time_ns >= self._time_ns:
217
232
  self.run(ns=stop_time_ns - self._time_ns)
218
233
 
219
- def add_event(self, port, value, propagation_delay_ns):
234
+ def add_event(self, port: PortOutDelta, value: int | str | None, propagation_delay_ns: int):
220
235
  """Add delta cycle event, this will also write values to .vcd file"""
221
236
  event_time_ns = self._time_ns + propagation_delay_ns
222
237
  # print(f"Add event {port.parent().name()}:{port.name()} => {value}")
@@ -226,7 +241,7 @@ class Circuit:
226
241
  return
227
242
  self._circuit_events.append(CircuitEvent(event_time_ns, port, value))
228
243
 
229
- def add_component(self, component):
244
+ def add_component(self, component: Component):
230
245
  """Add component to circuit"""
231
246
  name_id = 1
232
247
  namebase = component.name()
@@ -235,21 +250,21 @@ class Circuit:
235
250
  name_id += 1
236
251
  self._components[component.name()] = component
237
252
 
238
- def change_component_name(self, component, name):
253
+ def change_component_name(self, component: Component, name: str):
239
254
  """Change component name"""
240
255
  comp = self._components[component.name()]
241
256
  del self._components[component.name()]
242
257
  comp.set_name(name, update_circuit=False)
243
258
  self.add_component(comp)
244
259
 
245
- def get_component(self, component_name):
260
+ def get_component(self, component_name: str) -> Component:
246
261
  """Get component witgh 'component_name'"""
247
262
  comp = self._components.get(component_name)
248
263
  if comp is not None:
249
264
  return comp
250
265
  raise CircuitError(f"Component '{component_name}' not found")
251
266
 
252
- def to_dataclass(self, folder=None):
267
+ def to_dataclass(self, folder: str | None = None) -> CircuitDataClass:
253
268
  """Generate dict from circuit, used when storing circuit"""
254
269
  if self._name is None:
255
270
  raise CircuitError("Circuit must have a name")
@@ -257,8 +272,12 @@ class Circuit:
257
272
  return CircuitDataClass.from_circuit(self)
258
273
 
259
274
  def from_dataclass(
260
- self, circuit_dc, folder=None, component_exceptions=True, connect_exceptions=True
261
- ):
275
+ self,
276
+ circuit_dc: CircuitDataClass,
277
+ folder: str | None = None,
278
+ component_exceptions: bool = True,
279
+ connect_exceptions: bool = True,
280
+ ) -> list[str]:
262
281
  """Clear circuit and add components from dict"""
263
282
  self._folder = folder
264
283
  self.clear()
@@ -285,12 +304,12 @@ class Circuit:
285
304
 
286
305
  return exception_str_list
287
306
 
288
- def to_json_file(self, filename):
307
+ def to_json_file(self, filename: str):
289
308
  """Store circuit in json file"""
290
309
  circuitfile_dc = CircuitFileDataClass(circuit=self.to_dataclass())
291
310
  circuitfile_dc.save(filename)
292
311
 
293
- def from_json_file(self, filename, folder=None):
312
+ def from_json_file(self, filename: str, folder: str | None = None):
294
313
  """Load circuit from json file"""
295
314
  file_dc = CircuitFileDataClass.load(filename)
296
315
  self.from_dataclass(file_dc.circuit, folder)
@@ -1,35 +1,46 @@
1
- # Copyright (c) Fredrik Andersson, 2023-2024
1
+ # Copyright (c) Fredrik Andersson, 2023-2025
2
2
  # All rights reserved
3
3
 
4
4
  """
5
5
  Module that handles the creation of vcd files
6
6
  """
7
7
 
8
+ import io
9
+ from typing import Any, Tuple
10
+
8
11
  from vcd import VCDWriter
9
12
 
13
+ from .components.atoms import Port
14
+
10
15
 
11
16
  class WavesWriter:
12
17
  """Class that handles the creation of vcd files"""
13
18
 
14
- def __init__(self, filename):
15
- self._vcd_name = filename
16
- self._vcd_file = None
17
- self._vcd_writer = None
18
- self._vcd_dict = {}
19
+ def __init__(self, filename: str):
20
+ self._vcd_name: str = filename
21
+ self._vcd_file: io.TextIOWrapper | None = None
22
+ self._vcd_writer: VCDWriter | None = None
23
+ self._vcd_dict: dict[str, Any] = {}
19
24
 
20
- def init(self, port_info):
25
+ def init(self, port_info: list[Tuple[str, str, int]]):
21
26
  """Initialize vcd writer"""
22
27
  if self._vcd_file is not None or self._vcd_writer is not None:
23
28
  self.close()
24
29
  self._vcd_file = open(self._vcd_name, mode="w", encoding="utf-8")
30
+ if self._vcd_file is None:
31
+ raise RuntimeError("VCD file is None")
25
32
  self._vcd_writer = VCDWriter(self._vcd_file, timescale="1 ns", date="today")
26
33
  for port_path, port_name, port_width in port_info:
27
34
  var = self._vcd_writer.register_var(port_path, port_name, "wire", size=port_width)
28
35
  self._vcd_dict[f"{port_path}.{port_name}"] = var
29
36
  self._vcd_file.flush()
30
37
 
31
- def write(self, port, time_ns):
38
+ def write(self, port: Port, time_ns: int):
32
39
  """Write port value to vcd file"""
40
+ if self._vcd_file is None:
41
+ raise RuntimeError("VCD file is None")
42
+ if self._vcd_writer is None:
43
+ raise RuntimeError("VCD Writer is None")
33
44
  for wired_port in port.get_wired_ports_recursive():
34
45
  var = self._vcd_dict.get(f"{wired_port.path()}.{wired_port.name()}")
35
46
  if var is None:
@@ -3,15 +3,15 @@
3
3
 
4
4
  """Label Wire components module"""
5
5
 
6
- from .atoms import Component, DigsimException, PortWire
6
+ from .atoms import Component, DigsimException, PortIn, PortWire
7
7
 
8
8
 
9
9
  class _LabelWireStorage:
10
10
  """Singleton class with label wires"""
11
11
 
12
12
  _instance = None
13
- _wire_drivers = {}
14
- _wire_sinks = {}
13
+ _wire_drivers: dict[str, PortWire] = {}
14
+ _wire_sinks: dict[str, PortIn] = {}
15
15
 
16
16
  def __new__(cls):
17
17
  if cls._instance is None:
@@ -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,4 +1,4 @@
1
- # Copyright (c) Fredrik Andersson, 2023
1
+ # Copyright (c) Fredrik Andersson, 2023-2025
2
2
  # All rights reserved
3
3
 
4
4
  """All classes within digsim.circuit.components.atoms namespace"""
@@ -11,6 +11,7 @@ from ._component import ( # noqa: F401
11
11
  )
12
12
  from ._digsim_exception import DigsimException # noqa: F401
13
13
  from ._port import ( # noqa: F401
14
+ Port,
14
15
  PortConnectionError,
15
16
  PortIn,
16
17
  PortMultiBitWire,