digsim-logic-simulator 0.8.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.
- {digsim_logic_simulator-0.8.0/src/digsim_logic_simulator.egg-info → digsim_logic_simulator-0.9.0}/PKG-INFO +2 -2
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/pyproject.toml +2 -2
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/src/digsim/circuit/components/_yosys_component.py +57 -46
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/src/digsim/circuit/components/ic/74162.json +3 -2
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/src/digsim/circuit/components/ic/7448.json +14 -13
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/src/digsim/utils/__init__.py +1 -1
- digsim_logic_simulator-0.9.0/src/digsim/utils/_yosys_netlist.py +123 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0/src/digsim_logic_simulator.egg-info}/PKG-INFO +2 -2
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/src/digsim_logic_simulator.egg-info/requires.txt +1 -1
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/tests/test_yosys_netlist.py +21 -17
- digsim_logic_simulator-0.8.0/src/digsim/utils/_yosys_netlist.py +0 -272
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/LICENSE.md +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/MANIFEST.in +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/README.md +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/setup.cfg +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/src/digsim/__init__.py +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/__main__.py +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/gui/__init__.py +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/gui/_circuit_area.py +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/gui/_component_selection.py +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/gui/_main_window.py +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/gui/_top_bar.py +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/gui/_utils.py +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/gui/_warning_dialog.py +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/gui_objects/__init__.py +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/gui_objects/_bus_bit_object.py +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/gui_objects/_buzzer_object.py +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/gui_objects/_component_context_menu.py +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/gui_objects/_component_object.py +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/gui_objects/_component_port_item.py +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/gui_objects/_dip_switch_object.py +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/gui_objects/_gui_note_object.py +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/gui_objects/_gui_object_factory.py +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/gui_objects/_hexdigit_object.py +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/gui_objects/_image_objects.py +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/gui_objects/_label_object.py +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/gui_objects/_logic_analyzer_object.py +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/gui_objects/_seven_segment_object.py +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/gui_objects/_shortcut_objects.py +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/gui_objects/_yosys_object.py +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/gui_objects/images/AND.png +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/gui_objects/images/Analyzer.png +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/gui_objects/images/BUF.png +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/gui_objects/images/Buzzer.png +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/gui_objects/images/Clock.png +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/gui_objects/images/DFF.png +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/gui_objects/images/DIP_SWITCH.png +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/gui_objects/images/FlipFlop.png +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/gui_objects/images/IC.png +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/gui_objects/images/LED_OFF.png +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/gui_objects/images/LED_ON.png +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/gui_objects/images/MUX.png +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/gui_objects/images/NAND.png +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/gui_objects/images/NOR.png +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/gui_objects/images/NOT.png +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/gui_objects/images/ONE.png +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/gui_objects/images/OR.png +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/gui_objects/images/PB.png +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/gui_objects/images/Switch_OFF.png +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/gui_objects/images/Switch_ON.png +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/gui_objects/images/XNOR.png +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/gui_objects/images/XOR.png +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/gui_objects/images/YOSYS.png +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/gui_objects/images/ZERO.png +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/images/app_icon.png +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/model/__init__.py +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/model/_model.py +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/model/_model_components.py +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/model/_model_new_wire.py +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/model/_model_objects.py +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/model/_model_settings.py +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/model/_model_shortcuts.py +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/settings/__init__.py +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/settings/_component_settings.py +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/settings/_gui_settings.py +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/src/digsim/app/settings/_shortcut_dialog.py +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/src/digsim/circuit/__init__.py +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/src/digsim/circuit/_circuit.py +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/src/digsim/circuit/_waves_writer.py +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/src/digsim/circuit/components/__init__.py +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/src/digsim/circuit/components/_bus_bits.py +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/src/digsim/circuit/components/_button.py +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/src/digsim/circuit/components/_buzzer.py +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/src/digsim/circuit/components/_clock.py +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/src/digsim/circuit/components/_dip_switch.py +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/src/digsim/circuit/components/_flip_flops.py +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/src/digsim/circuit/components/_gates.py +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/src/digsim/circuit/components/_hexdigit.py +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/src/digsim/circuit/components/_ic.py +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/src/digsim/circuit/components/_label_wire.py +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/src/digsim/circuit/components/_led.py +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/src/digsim/circuit/components/_logic_analyzer.py +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/src/digsim/circuit/components/_mem64kbyte.py +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/src/digsim/circuit/components/_memstdout.py +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/src/digsim/circuit/components/_note.py +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/src/digsim/circuit/components/_on_off_switch.py +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/src/digsim/circuit/components/_seven_segment.py +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/src/digsim/circuit/components/_static_level.py +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/src/digsim/circuit/components/_static_value.py +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/src/digsim/circuit/components/_yosys_atoms.py +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/src/digsim/circuit/components/atoms/__init__.py +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/src/digsim/circuit/components/atoms/_component.py +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/src/digsim/circuit/components/atoms/_digsim_exception.py +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/src/digsim/circuit/components/atoms/_port.py +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/src/digsim/storage_model/__init__.py +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/src/digsim/storage_model/_app.py +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/src/digsim/storage_model/_circuit.py +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/src/digsim/synth/__init__.py +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/src/digsim/synth/__main__.py +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/src/digsim/synth/_synthesis.py +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/src/digsim_logic_simulator.egg-info/SOURCES.txt +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/src/digsim_logic_simulator.egg-info/dependency_links.txt +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/src/digsim_logic_simulator.egg-info/top_level.txt +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/tests/test_gates.py +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/tests/test_yosys_aldff.py +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/tests/test_yosys_dff.py +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/tests/test_yosys_dlatch.py +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/tests/test_yosys_gates.py +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/tests/test_yosys_latch.py +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/tests/test_yosys_sdff.py +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.0}/tests/test_yosys_sr.py +0 -0
- {digsim_logic_simulator-0.8.0 → digsim_logic_simulator-0.9.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.
|
|
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>
|
|
@@ -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.
|
|
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
|
+
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"
|
|
@@ -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.
|
|
33
|
+
"yowasp-yosys==0.57.0.0.post986",
|
|
34
34
|
]
|
|
35
35
|
|
|
36
36
|
keywords = ["educational", "simulation", "digital"]
|
|
@@ -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.
|
|
58
|
+
for portname, port_dict in self._netlist_module.ports.items():
|
|
55
59
|
external_port = PortMultiBitWire(
|
|
56
|
-
self, portname, width=len(port_dict
|
|
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
|
-
|
|
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.
|
|
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.
|
|
96
|
+
digsim.circuit.components._yosys_atoms, cell.component_type()
|
|
98
97
|
)
|
|
99
|
-
component = component_class(self._circuit, name=cell.
|
|
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
|
|
105
|
-
"""Connect
|
|
106
|
-
|
|
107
|
-
|
|
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
|
-
|
|
113
|
-
|
|
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.
|
|
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
|
|
124
|
-
|
|
125
|
-
|
|
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
|
-
"""
|
|
129
|
-
for bit_idx, net in enumerate(port_dict
|
|
130
|
-
for sink_port in self.
|
|
131
|
-
if sink_port.
|
|
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
|
-
|
|
134
|
-
|
|
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
|
-
|
|
140
|
-
|
|
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.
|
|
145
|
-
if
|
|
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.
|
|
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:
|
|
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.
|
|
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": [
|
|
80
|
-
"B": [
|
|
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": [
|
|
118
|
-
"B": [
|
|
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": [
|
|
174
|
-
"B": [
|
|
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": [
|
|
380
|
-
"B": [
|
|
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": [
|
|
530
|
-
"B": [
|
|
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": [
|
|
604
|
-
"B": [
|
|
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
|
+
|
|
@@ -0,0 +1,123 @@
|
|
|
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
|
+
for netlist_port_name, netlist_port in netlist.ports.items():
|
|
92
|
+
module_port = self.ports.get(netlist_port_name)
|
|
93
|
+
if module_port is None or not module_port.is_same(netlist_port):
|
|
94
|
+
is_same = False
|
|
95
|
+
break
|
|
96
|
+
return is_same
|
|
97
|
+
|
|
98
|
+
def get_nets(self):
|
|
99
|
+
nets = Nets()
|
|
100
|
+
|
|
101
|
+
for port_name, port_item in self.ports.items():
|
|
102
|
+
for bit_index, net in enumerate(port_item.bits):
|
|
103
|
+
port = NetPort(parent=self, parent_name="top", name=port_name, bit_index=bit_index)
|
|
104
|
+
if port_item.is_output:
|
|
105
|
+
if net not in nets.sinks:
|
|
106
|
+
nets.sinks[net] = []
|
|
107
|
+
nets.sinks[net].append(port)
|
|
108
|
+
else:
|
|
109
|
+
nets.source[net] = port
|
|
110
|
+
|
|
111
|
+
for cell_name, cell in self.cells.items():
|
|
112
|
+
cell.get_nets(cell_name, nets)
|
|
113
|
+
|
|
114
|
+
return nets
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
@dataclass
|
|
118
|
+
class YosysNetlist:
|
|
119
|
+
creator: Optional[str] = None
|
|
120
|
+
modules: dict[str, YosysModule] = Field(default_factory=dict)
|
|
121
|
+
|
|
122
|
+
def get_modules(self):
|
|
123
|
+
return self.modules
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: digsim-logic-simulator
|
|
3
|
-
Version: 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>
|
|
@@ -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.
|
|
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,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
|
|
@@ -63,8 +66,7 @@ def test_yosys_component_create():
|
|
|
63
66
|
"""Test create YosysComponent"""
|
|
64
67
|
circuit = Circuit()
|
|
65
68
|
comp = YosysComponent(circuit)
|
|
66
|
-
yosys_netlist = YosysNetlist()
|
|
67
|
-
yosys_netlist.from_dict(netlist_dict_if_one)
|
|
69
|
+
yosys_netlist = YosysNetlist(**netlist_dict_if_one)
|
|
68
70
|
comp.create_from_netlist(yosys_netlist)
|
|
69
71
|
|
|
70
72
|
comp.in_port.value = 0xA
|
|
@@ -76,16 +78,14 @@ def test_yosys_component_create_reload():
|
|
|
76
78
|
"""Test create YosysComponent - and reload changed netlist OK"""
|
|
77
79
|
circuit = Circuit()
|
|
78
80
|
comp = YosysComponent(circuit)
|
|
79
|
-
yosys_netlist = YosysNetlist()
|
|
80
|
-
yosys_netlist.from_dict(netlist_dict_if_one)
|
|
81
|
+
yosys_netlist = YosysNetlist(**netlist_dict_if_one)
|
|
81
82
|
comp.create_from_netlist(yosys_netlist)
|
|
82
83
|
|
|
83
84
|
comp.in_port.value = 0xA
|
|
84
85
|
circuit.run(ms=1)
|
|
85
86
|
assert comp.out_port.value == 0x5
|
|
86
87
|
|
|
87
|
-
yosys_netlist = YosysNetlist()
|
|
88
|
-
yosys_netlist.from_dict(netlist_dict_if_two)
|
|
88
|
+
yosys_netlist = YosysNetlist(**netlist_dict_if_two)
|
|
89
89
|
comp.reload_from_netlist(yosys_netlist)
|
|
90
90
|
|
|
91
91
|
comp.in_port.value = 0xA
|
|
@@ -97,18 +97,16 @@ def test_yosys_component_create_reload_fail():
|
|
|
97
97
|
"""Test create YosysComponent - and reload changed netlist OK"""
|
|
98
98
|
circuit = Circuit()
|
|
99
99
|
comp = YosysComponent(circuit)
|
|
100
|
-
yosys_netlist = YosysNetlist()
|
|
101
|
-
yosys_netlist.from_dict(netlist_dict_if_one)
|
|
100
|
+
yosys_netlist = YosysNetlist(**netlist_dict_if_one)
|
|
102
101
|
comp.create_from_netlist(yosys_netlist)
|
|
103
102
|
|
|
104
|
-
yosys_netlist = YosysNetlist()
|
|
105
|
-
yosys_netlist.from_dict(netlist_dict_if_three)
|
|
103
|
+
yosys_netlist = YosysNetlist(**netlist_dict_if_three)
|
|
106
104
|
|
|
107
105
|
# Fail due to wider in_port
|
|
108
106
|
with pytest.raises(YosysComponentException):
|
|
109
107
|
comp.reload_from_netlist(yosys_netlist)
|
|
110
108
|
|
|
111
|
-
yosys_netlist
|
|
109
|
+
yosys_netlist = YosysNetlist(**netlist_dict_if_four)
|
|
112
110
|
|
|
113
111
|
# Fail due to wider out_port
|
|
114
112
|
with pytest.raises(YosysComponentException):
|
|
@@ -132,8 +130,7 @@ def test_yosys_component_create_static_levels():
|
|
|
132
130
|
}
|
|
133
131
|
circuit = Circuit()
|
|
134
132
|
comp = YosysComponent(circuit)
|
|
135
|
-
yosys_netlist = YosysNetlist()
|
|
136
|
-
yosys_netlist.from_dict(netlist_dict_static)
|
|
133
|
+
yosys_netlist = YosysNetlist(**netlist_dict_static)
|
|
137
134
|
comp.create_from_netlist(yosys_netlist)
|
|
138
135
|
circuit.init()
|
|
139
136
|
circuit.run(ms=1)
|
|
@@ -167,8 +164,7 @@ def test_yosys_component_not_gate_multiple_outputs():
|
|
|
167
164
|
}
|
|
168
165
|
circuit = Circuit()
|
|
169
166
|
comp = YosysComponent(circuit)
|
|
170
|
-
yosys_netlist = YosysNetlist()
|
|
171
|
-
yosys_netlist.from_dict(netlist_dict)
|
|
167
|
+
yosys_netlist = YosysNetlist(**netlist_dict)
|
|
172
168
|
comp.create_from_netlist(yosys_netlist)
|
|
173
169
|
circuit.init()
|
|
174
170
|
comp.in_port.value = 0
|
|
@@ -202,10 +198,18 @@ def test_yosys_component_not_gate_static_input():
|
|
|
202
198
|
}
|
|
203
199
|
circuit = Circuit()
|
|
204
200
|
comp = YosysComponent(circuit)
|
|
205
|
-
yosys_netlist = YosysNetlist()
|
|
206
|
-
yosys_netlist.from_dict(netlist_dict)
|
|
201
|
+
yosys_netlist = YosysNetlist(**netlist_dict)
|
|
207
202
|
comp.create_from_netlist(yosys_netlist)
|
|
208
203
|
circuit.init()
|
|
209
204
|
assert comp.out_port.value == "X"
|
|
210
205
|
circuit.run(ms=1)
|
|
211
206
|
assert comp.out_port.value == 1
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
def test_yosys_complex_netlist():
|
|
210
|
+
comlex_json_netlist_file = (
|
|
211
|
+
Path(__file__).parent.parent / "src/digsim/circuit/components/ic/74162.json"
|
|
212
|
+
)
|
|
213
|
+
with open(comlex_json_netlist_file, encoding="utf-8") as json_file:
|
|
214
|
+
netlist_dict = json.load(json_file)
|
|
215
|
+
YosysNetlist(**netlist_dict)
|