amaranth
amaranth copied to clipboard
Add a minimal value-addressable multiplexer primitive valid on LHS and RHS
Right now, Array holds a special position in the language: it is one of the few constructs (the other being indexed part select) that encapsulates control flow, and at the same time can be used at both left-hand and right-hand side of assignment. That is, the result of indexing Array with a value, ArrayProxy, can be assigned to, but unlike ValueCastable, it doesn't have to be replaced with just a single value. This is made possible by expanding any statements that contains an ArrayProxy (or several) into a switch statement where the branches are the combinatorial product of every possible value of every controlling expression of an ArrayProxy.
It is unfortunate that ArrayProxy is tied deep into the language because it has broad powers (control flow + being on LHS) restricted to a narrow scope (emulating the list interface):
ArrayProxyhas a lot of code that has nothing to do with multiplexing per se (it deals with transparent-ish proxying of Python sequences).ArrayandArrayProxyare mimicking Python lists. This is a reasonable approach, but not the only reasonable approach: it would be nice to have something similar mimicking Python dicts.- Building abstractions on top of
ArrayProxyis a bad experience, as @pepijndevos discovered. Since nMigen aims to be a toolkit suitable for building HLS-style systems, it is important to enable this.
I propose to add a new primitive tentatively called ValueSwitch (name subject to bikeshed), that would encapsulate only the bare minimum of what Array does, enabling downstream code to easily define their own variations on Array that translate efficiently, and also potentially enabling us to add AssocArray (#73) and migrate ArrayProxy to be a simple ValueCastable (https://github.com/nmigen/nmigen/issues/73#issuecomment-631226598) without any changes to the RTLIL backend.