Skip to content

Commit fc6112d

Browse files
committed
refactoring wip
1 parent 60084b8 commit fc6112d

8 files changed

Lines changed: 372 additions & 437 deletions

File tree

edg/abstract_parts/BaseIoControllerWrapped.py

Lines changed: 53 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ def _remap_pin_assigns_list(
2525
2626
If invert_remapping is True, the remapping dict is inverted before applying.
2727
Assigns not present in the remapping dict are passed unchanged, eg for non-pin-assigns like bundle containers.
28+
29+
Internal utility.
2830
"""
2931
if invert_remapping:
3032
remapping = {v: k for k, v in remapping.items()}
@@ -60,7 +62,10 @@ def _generator_pin_dict(self) -> Dict[str, Port]:
6062
6163
For Vector-typed IO ports, this generates the subports and must be authoritative.
6264
This cannot be used with anything else that generates vector sub-ports.
63-
This must be a GeneratorBlock."""
65+
This must be a GeneratorBlock.
66+
67+
Internal utility.
68+
"""
6469
assert isinstance(self, GeneratorBlock)
6570

6671
pin_dict: Dict[str, Port] = {}
@@ -93,7 +98,10 @@ def _remap_to_footprint_pinning(
9398
"""Generates pinning that can be passed into a footprint, given the pin assign dict from _remap_pin_assigns_list
9499
and pin dict from _generator_pin_dict.
95100
96-
This requires all pins to be assigned."""
101+
This requires all pins to be assigned.
102+
103+
Internal utility.
104+
"""
97105
pinning: Dict[str, HasPassivePort] = {}
98106

99107
for name, assign in pin_assigns.items():
@@ -109,7 +117,10 @@ def _remap_to_footprint_pinning(
109117
@staticmethod
110118
def _remap_assigns_to_value(assigns: Dict[str, Tuple[Optional[str], Optional[str]]]) -> List[str]:
111119
"""Given a dict of pin assigns from _remap_pinning_assigns, returns a list of assign strings
112-
for use in self.actual_pin_assigns"""
120+
for use in self.actual_pin_assigns.
121+
122+
Internal utility.
123+
"""
113124
pin_assigns: List[str] = []
114125
for name, assign in assigns.items():
115126
if assign[0] is not None and assign[1] is not None:
@@ -137,3 +148,42 @@ def _make_pinning(
137148
fixed_pinning.update(self._remap_to_footprint_pinning(remapped_pin_assigns, pin_dict))
138149
self.assign(self.actual_pin_assigns, self._remap_assigns_to_value(remapped_pin_assigns))
139150
return fixed_pinning
151+
152+
153+
class BaseIoControllerWrapper(BaseIoController):
154+
"""Base class for a block that contains a BaseIoControllerWrapped as the physical footprint
155+
as well as a non-physical device model.
156+
157+
This provides utilities to remap pin assignments from the device specification to the model.
158+
"""
159+
160+
def _export_tap_ios_inner(self, inner: "BaseIoController") -> None:
161+
"""Export-taps all IO ports from some inner BaseIoController.
162+
This must be a SubboardBlock to support the export_tap connection.
163+
This must be called in contents() or generate(), after IOs have been defined."""
164+
from ..core.Blocks import BlockElaborationState
165+
166+
assert isinstance(self, WrapperSubboardBlock)
167+
assert self._elaboration_state in (
168+
BlockElaborationState.contents,
169+
BlockElaborationState.generate,
170+
), "can only run in contents() or generate()"
171+
172+
inner_ios_by_type = {self._type_of_io(io_port): io_port for io_port in inner._io_ports}
173+
for self_io in self._io_ports:
174+
self_io_type = self._type_of_io(self_io)
175+
assert self_io_type in inner_ios_by_type, f"inner missing IO of type {self_io_type}"
176+
inner_io = inner_ios_by_type[self_io_type]
177+
self.export_tap(self_io, inner_io)
178+
179+
def _make_model_pinning(self, remapping: Dict[str, str], device_assigns: List[str]) -> List[str]:
180+
"""Remaps my own assigns (pinned in device-space) to model-space.
181+
182+
Requires _generator_param_all_ios, so all the IOs names are available.
183+
"""
184+
185+
BaseIoControllerWrapped._remap_assigns_to_value(
186+
BaseIoControllerWrapped._remap_pin_assigns_list(
187+
Xiao_Rp2040_Device._PIN_REMAPPING, self.get(self.pin_assigns), invert_remapping=True
188+
)
189+
),

edg/abstract_parts/IoController.py

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -187,25 +187,6 @@ def _wrap_inner(
187187
self.assign(self.actual_pin_assigns, inner.actual_pin_assigns)
188188
self.assign(self.io_current_draw, inner.io_current_draw)
189189

190-
def _export_tap_ios_inner(self, inner: "BaseIoController") -> None:
191-
"""Export-taps all IO ports from some inner BaseIoController.
192-
This must be a SubboardBlock to support the export_tap connection.
193-
This must be called in contents() or generate(), after IOs have been defined."""
194-
from ..core.Blocks import BlockElaborationState
195-
196-
assert isinstance(self, WrapperSubboardBlock)
197-
assert self._elaboration_state in (
198-
BlockElaborationState.contents,
199-
BlockElaborationState.generate,
200-
), "can only run in contents() or generate()"
201-
202-
inner_ios_by_type = {self._type_of_io(io_port): io_port for io_port in inner._io_ports}
203-
for self_io in self._io_ports:
204-
self_io_type = self._type_of_io(self_io)
205-
assert self_io_type in inner_ios_by_type, f"inner missing IO of type {self_io_type}"
206-
inner_io = inner_ios_by_type[self_io_type]
207-
self.export_tap(self_io, inner_io)
208-
209190
def _generator_param_all_ios(self) -> None:
210191
"""Declares all BaseIoController IOs as generator params.
211192
This must be a GeneratorBlock."""

edg/abstract_parts/PinMappable.py

Lines changed: 0 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -328,44 +328,6 @@ def resource_pin(resource: BasePinMapResource) -> List[str]:
328328

329329
return PinMapUtil(remapped_resources, self.transforms)
330330

331-
def filter_pins(self, allowed_pins: List[str]) -> "PinMapUtil":
332-
"""Returns a new PinMapUtil with only the specified pins kept.
333-
If the allowed_pins list is empty, returns the input (all pins kept).
334-
allowed_pins may be specified as a pin name or pin number."""
335-
336-
if not allowed_pins:
337-
return self
338-
339-
def filter_resource(resource: BasePinMapResource) -> Optional[BasePinMapResource]:
340-
if isinstance(resource, PinResource):
341-
if resource.pin in allowed_pins or resource.pinname in allowed_pins:
342-
return resource
343-
else:
344-
return None
345-
elif isinstance(resource, PeripheralFixedPin):
346-
filtered_keys = []
347-
for key, pin in resource.inner_allowed_pins.items():
348-
if pin in allowed_pins or resource.inner_pinnames[key] in allowed_pins:
349-
filtered_keys.append(key)
350-
if filtered_keys:
351-
return PeripheralFixedPin(
352-
resource.name,
353-
resource.port_model,
354-
{k: v for k, v in resource.inner_allowed_pins.items() if k in filtered_keys},
355-
{k: v for k, v in resource.inner_pinnames.items() if k in filtered_keys},
356-
)
357-
else:
358-
return None
359-
elif isinstance(resource, BaseDelegatingPinMapResource):
360-
return resource
361-
else:
362-
raise NotImplementedError(f"unknown resource {resource}")
363-
364-
filtered_resources_raw = [filter_resource(resource) for resource in self.resources]
365-
filtered_resources = [resource for resource in filtered_resources_raw if resource is not None]
366-
367-
return PinMapUtil(filtered_resources, self.transforms)
368-
369331
@staticmethod
370332
def _resource_port_types(resource: BasePinMapResource) -> List[Type[Port]]:
371333
if isinstance(resource, PinResource):

edg/abstract_parts/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@
129129

130130
from .IoController import BaseIoController, IoController, IoControllerPowerRequired, BaseIoControllerPinmapGenerator
131131
from .IoControllerExportable import BaseIoControllerExportable
132-
from .BaseIoControllerWrapped import BaseIoControllerWrapped
132+
from .BaseIoControllerWrapped import BaseIoControllerWrapped, BaseIoControllerWrapper
133133
from .IoControllerInterfaceMixins import (
134134
IoControllerSpiPeripheral,
135135
IoControllerI2cTarget,

edg/abstract_parts/test_pinmappable.py

Lines changed: 0 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -98,56 +98,6 @@ def test_assign_remapped(self) -> None: # fully user-specified
9898
self.assertIn(AllocatedResource(ain_model, "AIO4", "P4", "4"), allocated)
9999
self.assertIn(AllocatedResource(ain_model, "AIO5", "P5", "5"), allocated)
100100

101-
def test_assign_filtered(self) -> None: # fully user-specified
102-
dio_model = DigitalBidir()
103-
allocated = (
104-
PinMapUtil(
105-
[
106-
PinResource("P1", {"PIO1": dio_model}),
107-
PinResource("P2", {"PIO2": dio_model}),
108-
PinResource("P3", {"PIO3": dio_model}),
109-
]
110-
)
111-
.remap_pins(
112-
{
113-
"P1": "1",
114-
"P2": "2",
115-
"P3": "3",
116-
}
117-
)
118-
.filter_pins(["P1", "P3"]) # test both pin name and pin number
119-
.allocate([(DigitalBidir, ["DIO1", "DIO3"])])
120-
)
121-
self.assertIn(AllocatedResource(dio_model, "DIO1", "P1", "1"), allocated)
122-
self.assertIn(AllocatedResource(dio_model, "DIO3", "P3", "3"), allocated)
123-
124-
def test_assign_filtered_empty(self) -> None:
125-
dio_model = DigitalBidir()
126-
allocated = (
127-
PinMapUtil(
128-
[
129-
PinResource("P1", {"PIO1": dio_model}),
130-
PinResource("P2", {"PIO2": dio_model}),
131-
]
132-
)
133-
.filter_pins([])
134-
.allocate([(DigitalBidir, ["DIO1", "DIO2"])])
135-
)
136-
self.assertIn(AllocatedResource(dio_model, "DIO1", "P1", "P1"), allocated)
137-
self.assertIn(AllocatedResource(dio_model, "DIO2", "P2", "P2"), allocated)
138-
139-
def test_assign_filtered_overflow(self) -> None:
140-
dio_model = DigitalBidir()
141-
with self.assertRaises(AutomaticAllocationError):
142-
PinMapUtil(
143-
[
144-
PinResource("1", {"PIO1": dio_model}),
145-
PinResource("3", {"PIO3": dio_model}),
146-
]
147-
).filter_pins(
148-
["1"]
149-
).allocate([(DigitalBidir, ["DIO1", "DIO2"])])
150-
151101
def test_assign_mixed(self) -> None: # mix of user-specified and automatic assignments, assuming greedy algo
152102
dio_model = DigitalBidir()
153103
ain_model = AnalogSink()

0 commit comments

Comments
 (0)