The textual pass pipeline has a bit more overhead due to the string parsing, but it reduces the required maintenance as we don't have to write CAPI and Python bindings for all the pass options.
Add a pass to group tests to output files. Currently, this matches what the emission pass does but can be extended to group tests according to certain requirements demanded from the execution environment. Also add a simple pass that inlines the tests without any gluecode (matching what the emission pass currently does). The emission pass will be simplified in a future PR to only iterate over the file operations and print what's inside
This patch implements lowering of hw.array_inject operations to combinational
logic in the HWAggregateToComb transformation pass.
The implementation creates a 2D array where each row represents the result
of injecting the new value at a specific index. A multiplexer then selects
the appropriate row based on the injection index.
This commit introduces a new operation to the Comb dialect:
`comb.reverse`, which performs bitwise reversal (mirroring) of an
integer value.
It also adds Verilog export support for this operation using
SystemVerilog’s streaming operator `{<<{}}`.
Bit reversal is a common operation in hardware design, especially in
signal processing and communication protocols. Previously, reversing
bits required generating many explicit `assign` statements. This new
operation makes the IR cleaner and enables direct export to compact
Verilog syntax.
Technology mapping/Cut rewriting requires enumerating multiple cuts to find best cuts, so representing a single cut as an operation doesn't make sense in general. When the AIG dialect was originally introduced, the cut operation was not well-thought-out and not used anywhere so clean up before implementing tech mapping.
Close https://github.com/llvm/circt/issues/8761
* Initiate datapath to comb pass
* Add tests and tidy datapath to compress implementation
* Improve comments
* Formatting and test corrections
* Correct CAPI
* Move wallace tree reduction and full-adder to comb ops
* Adding integration tests using circt-lec and correcting review comments
* Fix bug in Booth code for final sign correction row and add testing using lec. Add a forceBooth option largely for testing purposes
* Minor fix
* Formatting
* Removing populate patterns function
* Formatting
This adds the ability to the FullResetTransform to create enumeration
values which are 0. When the enumeration has a valid variant that is
encoded as a 0, we create this value using the FEnumCreateOp. If there
is no valid variant with the value 0, we create a constant 0 and bitcast
it to the enumeration type.
TagExtractOp's type inference predates adding user-defined encodings for
enums in FIRRTL. This fixes the issue by using the bitwidth helpers
defined on the enumeration type.
Add the new RegOfVecToMem pass to the circt-verilog pipeline. This will
detect memories described as `always` blocks and map them from the
current `seq.firreg` representation to the correpsonding `seq.firmem`.
This allows later parts of the pipeline to reason about memories more
easily and transform them if needed.
Preserve the order of module ports when converting from `moore.module`
to `hw.module`. The current implementation populates separate input and
output vectors, which makes all inputs appear before all outputs. The
updated version just populates a single array of ports, which preserves
order. This makes it easier to round-trip Verilog through circt-verilog,
and makes the output of circt-verilog more predictable.
This commit implements the lowering of hw.array_inject operations to SMT
expressions using smt.array.store operations. The lowering creates a new
array with the specified element injected at the given index, with proper
bounds checking to handle out-of-bounds accesses gracefully.
The implementation includes bounds checking that compares the index against
the maximum valid index (numElements - 1) and uses smt.ite to return either
the updated array (if in bounds) or the original array (if out of bounds).
This adds support to flatten memories with enumeration in them.
Enumerations are treated as non-aggregate types, and so they get a
single bit mask to control the whole value.
This commit introduces a new transformation pass `RegOfVecToMem` that converts
register arrays following memory access patterns into `seq.firmem` operations.
When a valid pattern is detected, the pass replaces the register array with a
`seq.firmem` operation and corresponding read/write ports.
This is required for the `circt-verilog` tool, to identify memories, such that
other `circt` transformations/analysis can be run in the `seq` dialect on the
`mlir` parsed from verilog.
This commit refactors the AIG longest path analysis C API to use native C structures instead of JSON strings, providing better performance and type safety.
The API changes replace `aigLongestPathCollectionGetPath` returning JSON with `aigLongestPathCollectionGetDataflowPath` returning native objects. New opaque handle types are added including `AIGLongestPathObject`, `AIGLongestPathHistory`, and `AIGLongestPathDataflowPath`. Comprehensive APIs are provided for accessing path data, history, and object properties.
InstancePath C API support is introduced in `circt-c/Support/InstanceGraph.h`. Currently `InstancePathCache` itself is not provided, as the use of LongestPathAnalysis is read-only and there is no need to mutate/construct InstancePath. Unfortunately due to that testing of CAPI of InstancePath got a bit tricky. For now AIGLongestPathAnalysis is used to produce InstancePath in CAPI.
The Python binding updates refactor Object, DataflowPath, and LongestPathHistory classes to use the native C API. JSON parsing dependencies and from_json_string() methods are removed. Proper property accessors using the new C API are added while maintaining backward compatibility for existing Python interfaces. So the existing integration tests cover most of the APIs.
Testing updates include comprehensive coverage in the existing C API tests in `test/CAPI/aig.c`. A new `test/CAPI/support.c` is added for InstancePath API testing. Python integration tests are updated to work with the new API.
This change improves performance by eliminating JSON serialization/deserialization overhead and provides a more robust, type-safe interface for accessing longest path analysis results.
This adds verifiers to the FIRRTL parser and to the FEnumType to prevent
having uninferred widths and resets inside enumerations. It seems like
the trickiness to implement these features would be hard to take
advantage of in practice, making it not worth it. This also fixes the
error messages produced by the type verifier that had extraneous quotes
around the field name, and rearranges some tests to be co-located in the
test file.
Fix a bug introduced in [[1]] where two parameters passed to the
LowerAnnotations pass were swapped. Swap these back and add a test of
this behavior.
[1]: 2b98e4233
Signed-off-by: Schuyler Eldridge <schuyler.eldridge@sifive.com>
This updates LowerToHW to handle the TagExtractOp. This reflects on the
lowered input value's type to determine how the enum was lowered. If it
was lowered to a struct, we extract the tag field. If it was lowered to
a integer, we can return the integer directly.
This adds the ability to specify the constants used to encode
enumeration variants in the tag. For example,
``` firrtl
wire a : {| A = 10, B = 5 |}
```
The values can be unspecified, in which case it defaults to one higher
than the previous value, or zero if it is the first value. For example,
these two enumerations are the same:
``` firrtl
{| A = 0, B = 1 |} == {| A, B |}
```
In FIRRTL, Two enumeration types are considered equal if they have the
same variants with the same values and data, without regard to variant
order. Internally in FIRRTL dialect IR, enumerations types must have
the variants sorted from low to high. For example the following two
enumeration types are equivalent:
``` firrtl
{| B = 1, A = 0 |} == {| A, B |}
```
The mlir syntax has been updated to ellide the the tag values and data
types if they are implicit. For example, the first type would be
roundtripped to the second type:
``` mlir
!firrtl.enum<a = 0 : uint<0>> => !firrtl.enum<a>
```
Enumerations are no longer lowered to SystemVerilog enumerations, but to
regular integer types. This is for a variety of reasons, but mainly
because enumerations in SV are nominal and it was not a good fit for our
structural enumerations.
In LowerToHW, the `firrtl.istag` operation lowers to a comparison to a
constant value created with a localparam, which can show up in the
output depending on how the module is optimized. The FIRRTL code below,
``` firrtl
FIRRTL version 4.0.0
circuit Enums:
public module Enums:
input in : {|A = 8 : UInt<8>, B = 16 |}
output out : UInt<8>
match in:
A(data):
connect out, data
B:
connect out, UInt<8>(16)
```
produces:
``` verilog
module Enums(
input struct packed {logic [4:0] tag; union packed {logic [7:0] A;/*B: Zero Width;*/ } body; } in,
output [7:0] out
);
localparam [4:0] A = 8;
assign out = in.tag == A ? in.body.A : 8'h10;
endmodule
```
This PR adds the RefinementCheckingOp to the verif dialect. The motivation behind this operation is to be able to automatically check whether a 'target' circuit is a refinement of a 'source' circuit. This should be a small step towards performing translation validation comparable to Alive2. The operation is structurally identical to the LogicEquivalenceCheckingOp, so I factored out most of the ODS into a common CircuitRelationCheckOp. If there is no non-determinism present in the circuits, the operation is also functionally identical to LogicEquivalenceCheckingOp.
Co-authored-by: Bea Healy <57840981+TaoBi22@users.noreply.github.com>
This pass prints the names of the tests in the IR. Since tests can be duplicated and elaborated differently during compilation, it prints both the newly uniqued name and the original name as specified by the user in the frontend.
This adds support for enumerations to LowerSigs so that the pass no
longer fails when it encounters an enum, and just passes them through
unchanged.
Fixes#7106
This modifies circt-synth to make it more practical.
* Remove verification code from synthesis parts. ExtarctTestCode is currently used, but eventually it must be replaced with something cleaner.
* Add an option to disable wordsToBits.
We are currently printing 1-bit localparams without a size, which causes
verilator to complain that it does not have a known bitwidth when used
in some expressions. This changes ExportVerilog to always print the
bitwidth of localparams, which is something we already do for
parameters.
Fixes the canonicalizers for wrap operations in the ESI dialect by replacing problematic attribute-based folding with proper operation creation and improving pattern matching logic.
- Updates `WrapValidReadyOp` and `WrapFIFOOp` fold methods to create `NullSourceOp` operations instead of using attributes
- Improves the `WrapFIFOOp` canonicalize method with better error handling and more robust user checking
- Delegates constant materialization to the HW dialect for better consistency
This fixes a long standing bug when parsing match statements which
contain numeric constants.
The FIRParser has a contant cache so that we can reuse any constant
operation created as we parse, by inserting them into the top-level body
of the module. To find the top level block, we were searching upwards
from the current insertion point.
In general, when creating any operation, we are required to know how
many regions the operation has; it is impossible to add more regions
after creating the operation. Due to this, when parsing the arms of a
match statement, the expressions are inserted into a region which is not
attached to any operation. This means we can not search upwards from
the insertion point to find the top level block. When operations do not
have this problem as they always have space 2 regions.
This change passes in the top level block when creating the
FIRModuleContext. If it turns out that the region we are inserting into
is not underneath the module, then we can insert the constant at the end
of the module's block.
This change also makes the cache itself a private member, and removes a
bit of code which was unnecessarily directly accessing the cache.