digsim-logic-simulator 0.8.0__py3-none-any.whl → 0.10.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of digsim-logic-simulator might be problematic. Click here for more details.

@@ -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
+
digsim/utils/__init__.py CHANGED
@@ -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
@@ -5,268 +5,124 @@
5
5
  Module with classes to parse a yosys netlist
6
6
  """
7
7
 
8
+ from __future__ import annotations
8
9
 
9
- class _NetlistPort:
10
- """A class describing a port within a netlist"""
10
+ from typing import Any, Optional, Union
11
11
 
12
- def __init__(self, parent, name, net=None, is_source=None):
13
- self._parent = parent
14
- self._name = name
15
- self._is_source = is_source
16
- self._sinks = []
17
- if net is None:
18
- self._nets = []
19
- else:
20
- self._nets = [net]
21
-
22
- def name(self):
23
- """Return port name"""
24
- return self._name
25
-
26
- def get_parent(self):
27
- """Return port parent"""
28
- return self._parent
29
-
30
- def is_source(self):
31
- """Return true if port is a source (false for sink)"""
32
- return self._is_source
33
-
34
- def add_sinks(self, sinks):
35
- """Add sinks to source port"""
36
- self._sinks.extend(sinks)
37
-
38
- def get_sinks(self):
39
- """Get source port sinks"""
40
- return self._sinks
41
-
42
- def get_nets(self):
43
- """Get port nets"""
44
- return self._nets
45
-
46
- def from_module_dict(self, port_dict, global_nets):
47
- """Create xternal port from module dict"""
48
- self._is_source = port_dict["direction"] == "input"
49
- for net in port_dict["bits"]:
50
- if net not in global_nets:
51
- global_nets.append(net)
52
- self._nets.append(net)
12
+ from pydantic import Field
13
+ from pydantic.dataclasses import dataclass
53
14
 
54
15
 
55
- class _NetlistBlock:
56
- """Common base class for modules and cells"""
16
+ @dataclass
17
+ class NetPort:
18
+ parent: Union[YosysModule, YosysCell]
19
+ parent_name: str
20
+ name: str
21
+ bit_index: Optional[int] = None
57
22
 
58
- def __init__(self, name, block_type=None):
59
- self._name = name
60
- self._ports = {}
61
- self._nets = []
62
- self._block_type = block_type
63
- self._net_to_source_port = {}
64
- self._net_to_sink_ports = {}
65
23
 
66
- def name(self):
67
- """Return name of block (cell or module)"""
68
- return self._name
24
+ @dataclass
25
+ class Nets:
26
+ source: dict[int, NetPort] = Field(default_factory=dict)
27
+ sinks: dict[int, list[NetPort]] = Field(default_factory=dict)
69
28
 
70
- def get_type(self):
71
- """Get type"""
72
- return self._block_type
73
29
 
74
- def set_type(self, block_type):
75
- """Set type"""
76
- self._block_type = block_type
30
+ @dataclass
31
+ class YosysPort:
32
+ direction: str
33
+ bits: list[Union[int, str]]
77
34
 
78
- def add_port(self, name, port):
79
- """Add port to block (cell or module)"""
80
- self._ports[name] = port
81
- nets = port.get_nets()
82
- if port.is_source():
83
- for net in nets:
84
- self._net_to_source_port[net] = port
85
- else:
86
- for net in nets:
87
- if net not in self._net_to_sink_ports:
88
- self._net_to_sink_ports[net] = []
89
- if port not in self._net_to_sink_ports[net]:
90
- self._net_to_sink_ports[net].append(port)
91
-
92
- def get_nets(self):
93
- """Get nets of block (cell or module)"""
94
- return self._nets
95
-
96
- def get_source_ports(self):
97
- """Get source ports of block (cell or module)"""
98
- ports = []
99
- for _, port in self._net_to_source_port.items():
100
- ports.append(port)
101
- return ports
102
-
103
- def get_source_port(self, net):
104
- """Get source port of block (cell or module)"""
105
- return self._net_to_source_port.get(net)
35
+ @property
36
+ def is_output(self):
37
+ return self.direction == "output"
106
38
 
107
- def get_sink_ports(self, net):
108
- """Get sink port of block (cell or module)"""
109
- return self._net_to_sink_ports.get(net, [])
110
-
111
-
112
- class _NetlistCell(_NetlistBlock):
113
- """A class holding a cell in a yosys netlist"""
39
+ def is_same(self, compare_port):
40
+ return (compare_port.direction == self.direction) and (
41
+ len(compare_port.bits) == len(self.bits)
42
+ )
114
43
 
115
- def __init__(self, name):
116
- super().__init__(name)
117
44
 
118
- def get_friendly_name(self):
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):
119
66
  """Return a friendly name for a netlist cell"""
120
- return f"{self.name().split('$')[-1]}_{self.get_friendly_type()}"
67
+ return f"{name.split('$')[-1]}_{self.component_type()}"
121
68
 
122
- def get_friendly_type(self):
69
+ def component_type(self):
123
70
  """Return a friendly type for a netlist cell"""
124
- return f"_{self.get_type()[2:-1]}_"
125
-
126
- def from_dict(self, cell_dict, global_nets):
127
- """Create netlist cell from dict"""
128
- self.set_type(cell_dict["type"])
129
- for port_name, port_dir in cell_dict["port_directions"].items():
130
- output = port_dir == "output"
131
- port_net = cell_dict["connections"][port_name]
132
- self._nets.extend(port_net)
133
- for net in port_net:
134
- if net not in global_nets:
135
- global_nets.append(net)
136
- port = _NetlistPort(self, port_name, net, output)
137
- self.add_port(port_name, port)
138
-
139
-
140
- class _NestlistModule(_NetlistBlock):
141
- """A class holding a module in a yosys netlist"""
142
-
143
- def __init__(self, name):
144
- super().__init__(name, "module")
145
- self._cells = {}
146
- self._module_nets = []
147
- self._ext_if = {}
148
-
149
- static_cell = _NetlistCell("StaticLevel")
150
- static_cell.from_dict(
151
- {
152
- "type": "$_StaticLevel_",
153
- "port_directions": {"L": "output", "H": "output"},
154
- "connections": {"L": ["0"], "H": ["1"]},
155
- },
156
- self._nets,
157
- )
158
- self._cells["StaticLevel"] = static_cell
159
-
160
- def from_dict(self, module_dict):
161
- """Create module from dict"""
162
- for ext_port_name, port_dict in module_dict["ports"].items():
163
- ext_port = _NetlistPort(self, ext_port_name)
164
- ext_port.from_module_dict(port_dict, self._nets)
165
- nets = ext_port.get_nets()
166
- ext_port_dict = {"output": ext_port.is_source(), "nets": nets}
167
- self._ext_if[ext_port_name] = ext_port_dict
168
- self.add_port(ext_port_name, ext_port)
169
-
170
- for cell_name, cell_dict in module_dict["cells"].items():
171
- cell = _NetlistCell(cell_name)
172
- cell.from_dict(cell_dict, self._nets)
173
- if cell.get_type() == "$scopeinfo":
174
- continue
175
- self._cells[cell_name] = cell
176
-
177
- def get_cells(self):
178
- """Get cells dict"""
179
- return self._cells
180
-
181
- def get_external_interface(self):
182
- """Get external interface dict"""
183
- return self._ext_if
184
-
185
- def get_source(self, net):
186
- """Get source port for net"""
187
- module_port = self.get_source_port(net)
188
- if module_port is not None:
189
- return module_port
190
- for _, cell in self._cells.items():
191
- cell_port = cell.get_source_port(net)
192
- if cell_port is not None:
193
- return cell_port
194
- return None
195
-
196
- def get_sinks(self, net):
197
- """Get module sinks (input ports)"""
198
- sink_ports = self.get_sink_ports(net)
199
- for _, cell in self._cells.items():
200
- cell_sink_ports = cell.get_sink_ports(net)
201
- for port in cell_sink_ports:
202
- if port not in sink_ports:
203
- sink_ports.append(port)
204
- return sink_ports
205
-
206
- def connect(self):
207
- """Connect all nets within module"""
208
- _source_port_dict = {}
209
- _sink_ports_dict = {}
210
- _cells_dict = {}
211
-
212
- # Build net to cell dict
213
- for _, cell in self._cells.items():
214
- for cell_net in cell.get_nets():
215
- if cell_net not in _cells_dict:
216
- _cells_dict[cell_net] = []
217
- _cells_dict[cell_net].append(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
218
102
 
219
- # Build net to ports dict
220
- for net in self._nets:
221
- # Module
222
- port = self.get_source_port(net)
223
- if port is not None:
224
- _source_port_dict[net] = port
225
- sink_ports = self.get_sink_ports(net)
226
- # Cells
227
- for cell in _cells_dict.get(net, []):
228
- port = cell.get_source_port(net)
229
- if port is not None:
230
- _source_port_dict[net] = port
231
- cell_sink_ports = cell.get_sink_ports(net)
232
- sink_ports.extend(cell_sink_ports)
233
- _sink_ports_dict[net] = sink_ports
103
+ def get_nets(self):
104
+ nets = Nets()
234
105
 
235
- # Connect
236
- for net in self._nets:
237
- source_port = _source_port_dict[net]
238
- sink_ports = _sink_ports_dict[net]
239
- source_port.add_sinks(sink_ports)
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
240
115
 
241
- # Connect module nets
242
- for module_net in self._module_nets:
243
- nets = module_net.get_nets()
244
- ports = []
245
- for net in nets:
246
- port = _source_port_dict[net]
247
- ports.append(port)
248
- module_net.set_ports(ports)
116
+ for cell_name, cell in self.cells.items():
117
+ cell.get_nets(cell_name, nets)
249
118
 
250
- def get_module_nets(self):
251
- """Get the nets for this module"""
252
- return self._module_nets
119
+ return nets
253
120
 
254
121
 
122
+ @dataclass
255
123
  class YosysNetlist:
256
- """A class holding the content of a yosys netlist"""
257
-
258
- def __init__(self):
259
- self._modules = {}
124
+ creator: Optional[str] = None
125
+ modules: dict[str, YosysModule] = Field(default_factory=dict)
260
126
 
261
127
  def get_modules(self):
262
- """Get modules dict"""
263
- return self._modules
264
-
265
- def from_dict(self, netlist_dict):
266
- """Parse netlist from dict"""
267
- for module_name, module_dict in netlist_dict["modules"].items():
268
- module = _NestlistModule(module_name)
269
- module.from_dict(module_dict)
270
- self._modules[module_name] = module
271
- for _, module in self._modules.items():
272
- module.connect()
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
@@ -54,7 +54,7 @@ digsim/app/model/_model_components.py,sha256=Q2iztl7MlWv_7vaa7me-dp-gOx6-7Tg3LZm
54
54
  digsim/app/model/_model_new_wire.py,sha256=5HnF5-gtKtB1Tp6ZIF7QuNo5zEHmsUpnBEmj6ZllLiA,1810
55
55
  digsim/app/model/_model_objects.py,sha256=lqOjNIygIHT6Dq_PPa-D0B5elC49dB0KshF0ATzJZ0s,5217
56
56
  digsim/app/model/_model_settings.py,sha256=FewI3hm1iwbjPwdN3IeixuINPtamDORrTh1ANGRNwX8,1035
57
- digsim/app/model/_model_shortcuts.py,sha256=TT4osN7-dMEgKXWHW9cJ0XILIIkUfRqBBfx6rvYT2JI,2488
57
+ digsim/app/model/_model_shortcuts.py,sha256=xrUgs2Y18mSVun3sxzVscYTZ6n5DJTTZOnFhs4Jt_0M,2439
58
58
  digsim/app/settings/__init__.py,sha256=0tkoBSYeJFFiUI8c_FqvqqyM4-_SU9Xq7mXCwiew5Oo,308
59
59
  digsim/app/settings/_component_settings.py,sha256=88D9OuEcFIlaqZozomWHSYrl7opz4jZW2e8xGuUyTpg,16287
60
60
  digsim/app/settings/_gui_settings.py,sha256=sDi2POUsHvS7_4SO5qsTu_nN48HsTN4UfGPzdmECs9w,2764
@@ -83,23 +83,23 @@ digsim/circuit/components/_seven_segment.py,sha256=UxxjGLuIirVB2Px09XlL8_zjgE7F8
83
83
  digsim/circuit/components/_static_level.py,sha256=2Assm1cmAfryVZ3KTQ1uGY8Q6eRrBipdwLITewXfIHg,677
84
84
  digsim/circuit/components/_static_value.py,sha256=vfRPS_F9mKOXpHJxzs0JQKXqcj0o6d-090zbyZaECA4,1236
85
85
  digsim/circuit/components/_yosys_atoms.py,sha256=NeH8XjjpoACHBfQRqR5RJxWorZhSjGk0t73cJOviSZw,37599
86
- digsim/circuit/components/_yosys_component.py,sha256=XDNSAfM6Qvhe6G0-M1uiY2NQ-A6oPSQX4kcB_ccvSWg,8810
86
+ digsim/circuit/components/_yosys_component.py,sha256=LkYneNSvzQMn61RzlHk3aSkl9tF6JjibknfwmLeWCFk,8792
87
87
  digsim/circuit/components/atoms/__init__.py,sha256=NU45pfJcSrdwZA-SVQeORlaznl_0BciY4VN3vVSnD8o,498
88
88
  digsim/circuit/components/atoms/_component.py,sha256=DpMS1yOWWgk11Y9ae0PfuOJdlJsrzgrzuYrgsN62dbQ,8815
89
89
  digsim/circuit/components/atoms/_digsim_exception.py,sha256=Y5mBve15zZbduqNNAyf7WzqDk4NtvUL_g2vYy5kBQ3U,173
90
90
  digsim/circuit/components/atoms/_port.py,sha256=yT1TqmKPVlw8G_0r_6dErcqIkXCqB8z0pE5oL6Bnxzo,12596
91
- digsim/circuit/components/ic/74162.json,sha256=XY-qHubOw3P7xeuV1ZZDTD-XcDBwAovTZ1Ic-rTnYqY,26694
92
- digsim/circuit/components/ic/7448.json,sha256=WnVrq6nr0L_ywg2cJlrqg3gpv0l1Pha5yfNza-lE9S4,21186
91
+ digsim/circuit/components/ic/74162.json,sha256=RAeSva6TVuwfKHsvU9HC-ZVfRVrCkIsQUz_jcANT_fE,26693
92
+ digsim/circuit/components/ic/7448.json,sha256=hKMXhPqW-JBTF6rdz9u5HC_hY9cBRpJtMkLP7uOQXIo,21185
93
93
  digsim/storage_model/__init__.py,sha256=lubmO9_BCUtEahyW1yE7f3aGHngEevGIwf_0LeOB7Y8,289
94
94
  digsim/storage_model/_app.py,sha256=Aer9s_mUBKSydsyeWYvVPHX2XF5ZGPuXq8z4PoXu8lA,1353
95
95
  digsim/storage_model/_circuit.py,sha256=NnaHLwqb9gAhqAxeZ1RkHHvoS_YJwixlz0xs-zmIrQU,3596
96
96
  digsim/synth/__init__.py,sha256=jhBHLOHf-vNa94Zg5q5dGcf0fgQTModfjUKtmUSffiw,180
97
97
  digsim/synth/__main__.py,sha256=wZWAzWsisoxA7hfqkKtu3H066uWyFajgPro2MEGlKbs,2173
98
98
  digsim/synth/_synthesis.py,sha256=ug9vSeTyZrvRCboNLL7dDIFVpGqH_ibr5fhOZJHpqUs,4271
99
- digsim/utils/__init__.py,sha256=Az_zmbORYMzmptuA2_xfn5jDxbCPRSMlVuntr0sYexU,167
100
- digsim/utils/_yosys_netlist.py,sha256=ElnqPUsOO5zjTuf6UFSyEH3UabNlhxiLpwgACcX74rk,8635
101
- digsim_logic_simulator-0.8.0.dist-info/licenses/LICENSE.md,sha256=FrvohZfyfpH4xrvKdXiQ5hD7dUB7w4DcsRA3p-pOmLw,1693
102
- digsim_logic_simulator-0.8.0.dist-info/METADATA,sha256=CGio3nKIsVeQLBUhfl3N6LOZjxH9Z0VnB2mrgl7GC8w,4557
103
- digsim_logic_simulator-0.8.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
104
- digsim_logic_simulator-0.8.0.dist-info/top_level.txt,sha256=qpCMzQKADZHVqZIoQgFrv3qJ3u7PPU73gTCXQglqLa8,7
105
- digsim_logic_simulator-0.8.0.dist-info/RECORD,,
99
+ digsim/utils/__init__.py,sha256=MT9TNcpa7fNAqtBsmCcceKMrUSU_v9xeJ6Nox_TL7Lo,191
100
+ digsim/utils/_yosys_netlist.py,sha256=Lcuo9seKcDu4O-NdBpJUpExvTT7Rx1STCBtF0xT8Nkc,3843
101
+ digsim_logic_simulator-0.10.0.dist-info/licenses/LICENSE.md,sha256=FrvohZfyfpH4xrvKdXiQ5hD7dUB7w4DcsRA3p-pOmLw,1693
102
+ digsim_logic_simulator-0.10.0.dist-info/METADATA,sha256=Sjx2LJyb7CSKNkJVmT17qGyOmKOCtaFmeyKBdi6ip9U,4558
103
+ digsim_logic_simulator-0.10.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
104
+ digsim_logic_simulator-0.10.0.dist-info/top_level.txt,sha256=qpCMzQKADZHVqZIoQgFrv3qJ3u7PPU73gTCXQglqLa8,7
105
+ digsim_logic_simulator-0.10.0.dist-info/RECORD,,