Add a pass to overwrite lowering options on a module. This lets us get rid of the in-library cmdline option and move it to the two tools which need it. With this, prepare and export never change the lowering options.
Also make prepare a nested pass.
* Implement emission patterns for all emitc operations except variable for which we have our own implementation. Support for template arguments to function calls is not added yet, but can be easily added when there is a need.
* Add emission pattern support for attributes: this is helpful for operations like emitc.constant which can take any attribute and print it. Having them pattern based allows for more modularity and reuse.
* Move the helper function to emit parentheses around an expression to the InlineEmitter to share it across the various files implementing emission patterns and allow for easier use.
* blockDeclarationInsertPoint is only written, never used
* blockDeclarationIndentLevel is used but is same as normal indent
(likely because we aren't inserting to different point anymore)
Change the diagnostic when LowerAnnotations hits an unknown annotation
from warning to error. LowerAnnotations will immediately exit after
this message and it is more appropriate to use an error than a warning.
Add a test of this behavior.
Signed-off-by: Schuyler Eldridge <schuyler.eldridge@sifive.com>
* [Handshake][NFC] fix error re:not returning value
In non-assert builds this code must return something.
Windows CI is producing error because of this.
* [Handshake][NFC] Small tweaks to quiet warnings about shifts.
This fixes https://github.com/llvm/circt/issues/4030. The crash was caused by comparing different width of APInt so this PR fixes the issue by checking types before comparing APInt.
This PR improves namehints heuristic and add a heuristic to spill wires for mux. Namehint heuristic is modified to spill wires for namehints that doesn't have "\_" prefix regardless of term sizes. For expressions with "\_" prefix, if the term is greater than a threshold, the expression is spilled to a wire. Also this PR adds a heuristic option to spill all mux.
Co-authored-by: Will Dietz <will.dietz@sifive.com>
This is intended to be a lowering used for transforming Handshake to hardware.
The transformation materializes the top-level `memref` to a new set of in- and output arguments, and plumbs to the in- and output values of the `handshake.extmem` operation which referenced the memref. This is essentially what is was done by `HandshakeToFIRRTL`/`HandshakeToHW` but can be moved as a preprocessing step.
Another motivation for doing so is to create a more natural interface for external users to interact with:
- Store ports now have a single handshake'd output port with combined addr+data.
- Load ports now only requires a single handshake'd data input. This input is then forked into its data+control parts to feed the load- and store operations.
In doing so, we also use `!hw.struct` types to ensure that correct names are being maintained for the in- and output values. This is opposed to using tuples, which does not have named fields.
The tuple requires use of `hw.struct_create` - in HandshakeToHW, this can be supported identically to `handshake.pack` which itself uses `hw.struct_create` after tuple types have been lowered to structs.
Currently, ExportVerilog will crash on trying to emit a `hw.struct_explode` operation. Fixed by lowering the op to a set of `hw.struct_extract` ops during prepareForEmission, which has clear emission semantics.
Been annoyed by this assert being thrown for a long time. If unsupported operations is fed to the ExportVerilog pass (may happen if some other lowering pass wasn't run or export verilog is missing an implementation for lowering some op), a very unhelpful assert would be thrown stating `value expected a name but doesn't have one` - telling us nothing about which op actually violated the condition.
Modifies this to actually printing the op + an error message indicating the most likely cause for tripping this assert.
Make the `InferResets` pass properly ignore foreign types which by
definition don't contribute to the resets being inferred. Before this
change the pass would abort on various `cast<FIRRTLType>()` calls. These
all become `dyn_cast<FIRRTLType>()` now with graceful handling of the
non-FIRRTL type case, which makes the pass more robust.
The `InferWidths` pass should ignore any foreign types that might be
present in the IR. These types cannot contribute any width constraints
and don't participate in the width inference process in general, so this
commit makes the pass ignore such types more explicitly.
Also add support for `UnrealizedConversionCastOp`. In case such a cast
has a result of uninferred width, the pass would now assign a width to
it as with any other operation. The applicability of this in practice is
fairly limited since width inference can only affect the FIRRTL-typed
results of the cast, but it can't propagate any information through the
cast. However, in some applications a partial dialect lowering might be
sensitive to the source type of the cast and do the right thing based on
what width was assigned, making this a niche but useful change.
If a module has only inputs after extraction, it can and should be
moved to the test code area. Such modules are marked to be output into
the test code path.
Closes https://github.com/llvm/circt/issues/2351.
In order to support partial lowerings involving the FIRRTL dialect, and
to mix in foreign operations and types, we need a way to pass foreign
types through FIRRTL modules, instances, and trivial connects.
This commit extends `FModuleLike`, `InstanceOp`, `StrictConnectOp`, and
`WireOp` to also accept foreign, non-FIRRTL types for ports and
connections to those ports. It also adapts the `LowerToHW` pass to
simply pass through foreign-typed values when they appear in module and
instance ports. This requires adding special case handling in a few
places since we cannot create an `InOutType` and therefore `sv::WireOp`
around arbitrary foreign types, so we generally have to immediately
materialize foreign values.
This lowering can be quite usefully combined with the builtin
`unrealized_conversion_cast` to wrap and unwrap values of foreign types
and establish a path for FIRRTL values to cross dialect boundaries in a
controlled fashion.
In more details, this PR does the following:
- Allow foreign types in:
- `FModuleLike`
- `InstanceOp`
- `StrictConnectOp`
- `WireOp`
- During lowering to HW, force module and instance port connections to
materialize connected values directly if they are of foreign type,
since we cannot create temporary wires to hold these values.