Description
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):
ArrayProxy
has a lot of code that has nothing to do with multiplexing per se (it deals with transparent-ish proxying of Python sequences).Array
andArrayProxy
are 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
ArrayProxy
is 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
(#73 (comment)) without any changes to the RTLIL backend.