-
Notifications
You must be signed in to change notification settings - Fork 20
Description
This came about while thinking of other ways to create a VirtualMux that will be type hint and IDE friendly. Originally a comment on #184 but I think it is better to have an issue separate from that so it doesn't get lost.
Each signal would be a method on the resulting VirtualMux subclass. This would be a big change for existing scripts. But once the jig refactor PR lands, we could introduce something like this and scripts could choose which style to use. For new scripts, the IDE autocomplete benefits of this approach would be nice to have. (There might be a way to type-hint the current VirtualMux, but I haven't figured it out)
# existing
class Mux(VirtualMux):
pin_list = ("x0", "x1", "x2")
map_list = (
("sig1", "x0"),
("sig2", "x1"),
("sig3", "x2", "x0"),
)
#new
@dataclass
class MuxNew(VirtualMux):
sig1: Sig = signal("x0")
sig2: Sig = signal("x1")
sig3: Sig = signal("x2", "x0")
dm.jig.mux.Mux("sig2")
# becomes
dm.jig.mux.NewMux.sig2()
# For tree defined multiplexers
# __________
# a0-------------------------------| |
# ________ | |
# a1_b0----------------| |--| |
# a1_b1----------------| Mux B | | |
# (None)--| 4:1 | | |
# a1_b3----------------| x3 x2 | | |
# |________| | |
# | Mux A |
# a2-------------------------------| 4:1 |
# ________ | |
# a3_c0----------------| |--| |
# a3_c1----------------| Mux C | | |
# a3_c2----------------| 4:1 | | |
# (None)--| x5 x4 | | |
# |________| | |
# |__x1__x0__|
muxA = MuxTree("x0", "x1")
muxB = MuxTree("x2", "x3", nest=muxA)
muxC = MuxTree("x4", "x5", nest=muxA)
@dataclass
class Mux(VirtualMux):
a0: Sig = muxA()
a1_b0: Sig = muxB()
a1_b1: Sig = muxB()
muxB() # "throw away" one entry
a1_b3: Sig = muxB()
a2: Sig = muxA()
a3_c0: Sig = muxC()
a3_c1: Sig = muxC()
a3_c2: Sig = muxC()Implementation - Maybe? very not tested... Most likely bugs, but I think the concept is O.K. I think we would end up with signal returning a class instead of a function, but this maps out the general idea.
Sig = Callable[[VirtualMux, bool], None]
def signal(*pins) -> Sig:
def _func(self: VirtualMux, trigger_update: bool=False):
self._do_switch(pins, trigger_update)
_func.pins = pins
return _func
class MuxTree:
def __init__(self, *pins: tuple[Pin], nest: MuxTree) -> None:
self._pins = set(pins)
self._pin_gen = generate_bit_sets(pins)
if nest is not None:
self._fixed_pins = nest().pins
else:
self._fixed_pins = set()
def __call__(self) -> Sig:
pins = self._fixed_pins | next(self._pin_gen)
return signal(*pins)