Closed dan-fritchman closed 1 year ago
Draft of this is in #196
And has been quite helpful thus far, especially in contexts mixing generator-calls with "other stuff". E.g. referring to result-Module
attributes for simulation or for layout.
Downsides to this that I can think of:
generator
s will be slow. And some of them will be executed in (python) module-scope Module
definitions. E.g.@h.generator
def sloooooooow(p: Params) -> h.Module:
...
@h.module
class GetsSlowed:
i = sloooooooow()() # <= this runs at import-time
This change doesn't effect their runtime - it just changes when they run, from elaboration-time to import-time. Which can be annoying.
GetsSlowed
a generator too, or defering its importing to inside some other function. Paired with this, the orginal reason for deferred generator
evalution is the half-baked Context
feature.
@h.generator
def uses_context(p: Params, ctx: Context) -> h.Module:
# Maybe get, like, VDD and VSS signals from that `ctx` object
@h.module
class HasThat:
i = uses_context(Params()) # <= note the idea is, this does not need to provide the `Context`
Context
has never really been implemented. And there's not a great train of progress or inspiration towards doing so.
The general philosophy of how Hdl21 works has always included something like "defer all execution that we can".
This generally manifests as having two "eras" of execution:
Most downstream consumers of Hdl21 (via VLSIR) can only use the Hdl21 stuff post-elaboration. After we have computed out things like generators, bundles, port-usages, arrays, etc. (Basically all the niceties that Hdl21 is for.) But we like those niceties! So they're all available at generation-time.
Examples of stuff deferred from generation-time to elaboration-time include:
Instance
s ofModule
s and similar are not resolvedBundle
s are left "rolled up", and are then "flattened" during elaborationInstance
andBundle
attributes are just that - references. Nowhere in the program knows whether they are valid, or will turn up to be.Elaboration is essentially Hdl21's compiler. Inspired by popular compilers and by Chisel elaboration, it is organized in a series of
ElabPass
classes which traverse the hierarchy, generally doing a targeted single-thing at a time, e.g. "flatten bundles", "resolve port refs", or "just check that everything looks OK".The one that's kinda special, and weird, and always goes first, is
GeneratorElaborator
, whose purpose is "run all the generator functions". That action has always been a part of elaboration time. There are a few reasons I can remember as to why, which may no longer be relevant. And there may be a few more that I no longer remember. The liabilities of this approach tend to come up more than the other elaborators, particularly the need to keep track of whichGeneratorCall
s have been executed, and which are "future" promises to do so.The issue here: should we just run the
Generator
s "right away" in user-code-time instead?At minimum I wanna try it. And see if there's some similar-sized liability going the other way.