This is quite invasive. This converts from the functiontype printer to the moduletype printer.
---------
Co-authored-by: Mike Urbach <mikeurbach@gmail.com>
Presumably, this error message stems from when BackedgeBuilder was initially used solely for creating backedges to top-level port assignments when creating a new module instance. However, the `BackedgeBuilder` is also used for other operations (and useful as a general tool), wherein 'port' may be misleading. Changing this to `Backedge` makes it explicit that a backedge was created, and was expected to be assigned to.
This is an initial commit for adding a CAPI for FSM as well as PyCDE support for constructing these.
See `test_fsm.py` for usage.
FSMs are constructed in a similar manner to PyCDE modules through a decorator on a class describing the FSM.
The FSM class may contain inputs (no outputs for now) and must provide
- A dictionary containing the states and their transitions
- A default state
State transitions may be either always taken, or taken based on some guard. This guard is defined by a function provided to the transition, which (like `@generator` functions) acts on the ports of the FSM.
The FSM will then be constructed with an output for each state, asserted when that state is active.
One important implementation note is the fact that the `fsm.machine` operation is treated as a PyCDE Module - there was surprisingly little friction slotting it into the current code and everything works as expected wrt. referencing `fsm.machine` in/out arguments through the transition guard functions.
However, modules instantiating the FSM expect a hardware-like interface, this being the ports of the `fsm.machine` operation + clock and reset signals. An `fsm.machine` op does not have these signals at the top level, since these are added during hardware lowering. To me, this is a sensible design choice, seeing that the FSM dialect should be applicable to both software and hardware representations (...eventually).
To get around this, the user will specify the intended name of the `clock` and optional `reset` signal of an FSM. A wrapper module is then created that provides the correct interface to the instantiating module, as well as instantiating the FSM through a `fsm.hw_instance` operation, doing the proper hoop-jumping to attach the clock signal (see `fsm_wrapper_class`).
There's still some work to do on the CIRCT side of the FSM dialect to clean it up a bit + make it a viable target for a front-end, but this commit represents the brunt of work on the PyCDE side.
- Creating new frontends top level directory which contains frontends which are optionally included.
- Moving @module and @Generator into PyCDE frontend.
- Keeping connect in the bindings since it's used in the bindings tests.
- Fixing the integration tests.
Closes#1179.
Create an `OutputOp` out of the return value from `body_builder`. Eliminate input ports as `construct` args. Move all of the `module.entry_block.arguments[1]` ugliness to the new `module.foo` syntax.
This adds `circt.connect` to "connect" two values. It sets the
destination OpOperand to the new value.
To integrate with the builder approach, this updates the
InstanceBuilder to return a wrapper BuilderValue around any Values
accessed through `__getattr__`. This works with the connect API to
pass around the needed index to ultimately set the Value and erase any
temporary backedges the builder created.
As the builder approach is generalized to other ops, the connect API
should work in exactly the same manner.
This is no longer needed now that the BackedgeBuilder is implicit.
This change also includes some whitespace updates to line things up
after the RTL->HW name change.
Divorces the support BackedgeBuilder from InstanceBuilder (so it can be used
elsewhere). Stores some extra information in the edge instead of digging it up
later in an InstanceBuilder-specific way.
Keep a stack of BackedgeBuilders in a contextvar. Provide a static method to
get the top.
This makes sure not to rename FIRRTL to HWRTL :-), and I spot checked a
many things to avoid changing general references to RTL (e.g. when referring
to external tools) but I suspect that I missed some. Please let me know (or
directly correct) any mistakes in this mechanical patch.
Python. The builder accepts a name for the instance and optional
values to assign to the input ports. The InstanceBuilder supports
attribute getters and setters for the ports.
When ports are not set on creation, temporary operations are inserted
into the IR via a BackedgeBuilder. The BackedgeBuilder can be used as
a context manager, and checks the temporary operations are all
resolved on exit. This is wrapped around the body_builder of modules
to ensure all instances are wired up after the body_builder exits.
A create method is added to RTLModuleOp, which constructs and returns
an InstanceBuilder for an instance of that module.