This does a simple wire preservation. This means:
nodes and wires become wires if they have names
names that don't start with '_' are preserved
names don't block constant propgation, but do block deleting wires.
We don't have to extract assertions from modules in testbench since
it already separated from DUT. This commit addsfirrtl.extract.do_not_extract
attribue to modules on LowerToHW if they are located in testbench.
And in SVExtractTestCode, we skip extractions if that attribute appears.
This change will hopefully improve simulation performance by reducing overheads
of module instantiations.
Remove a check that asynchronous reset registers are only reset to
constant values from the LowerToHW conversion. This check has been
moved into the SFCCompat test.
Signed-off-by: Schuyler Eldridge <schuyler.eldridge@sifive.com>
This commit removes conditions of `isExpressionUnableToInline` regarding
users in different blocks. Dominance between user and def blocks is guaranteed
even in graph regions and because we are generating temporary wires at the
beginning of blocks, we don't have to check that condition today.
When the ReadInOutOp accessing a register or a wire was after the use of the read value, a temporary wire was emitted. This patch instead moves both the definition of the read operation and the read itself to the top of the module, ensuring the order is correct and no temporaries are needed.
As a result, the verilog representation of a large design is 0.6% shorter, with thousands of temporaries eliminated.
This commit adds an extra initialization for async registers so
that they are set to initial values if reset signal is enabled at
an initial randomization phase. This matches SFC's behaviour.
Close#2999.
Update the memory module name and instance names with an "_ext" suffix to
match SFC behavior. This commit adds a utility to Namespace, to generate
a unique new name with a given suffix.
This utility is used to generate the memory module name with "_ext" suffix.
This commit also updates the LowerToHW to add the "_ext" suffix to
the instance name.
This commit adds `LocationInfoStyle` enum to control location info
in output verilog. Specifically we want to distinguish location information
from normal comments more clearly. As one implemention, `WrapInAtSquareBracket`
option is added to emit location information wrapped in `@[` and `]`
such as:
```
assign .. ; // @[perf/regress/AddNot.fir:3:10, :7:{10,17}]
```
This fixes a bug introduced by 286c483. An iterator is mistakenly incremented in certain execution. Since opIterator is incremented in the beginning of the loop,
we are not actually processing next operations. This causes an assertion failure
on ExportVerilog in internal designs.
This aligns the textual IR format, the emitter, and any locations
these ops were constructed in code to the result order defined by the
native Calyx compiler. This is required for these ops to be able to
round-trip through the native compiler.
Don't generate always blocks with ifdef in them for side effecting operations, generate ifdef with always in them. This reduces preprocessing work during synthesis and allows merging only verif op's always blocks.
This commit adds a new lowering option emitReplicatedOpsToHeader
to create a header file which stores replicated ops.
Currently, this PR creates circt_header.svh under the output
directory and users are expected to manually register the header to their
include paths.
* [Conversions][Transforms] Add missing includes due to refactoring in upstream MLIR.
LLVM commit 36d3efea15e6202edd64b05de38d8379e2baddb2 removed a few
include statements from mlir/Pass/Pass.h, so we have to update a few of
the files here to add back in some includes.
* [Handshake][SV] Migrate from StrEnumAttr to EnumAttr.
StrEnumAttr was removed in upstream LLVM commit
60e34f8dddb4a3ae5b82e8d55728c021126c4af8. It has been replaced with
EnumAttr, which can do everything that StrEnumAttr could do but more
efficiently.
This affected two specific attributes: Handshake's BufferType, and SV's
ModportDirectionAttr. Both have been converted over to EnumAttrs. Their
parsers had to be updated, since the new EnumAttr no longer likes having
double quotes around the enum value in the assembly format.
Consequently, the tests were also updated.
* Bump llvm to 1aa4f0bb6cc21b7666718f5534c88d03152ddfb1.
This is somewhat involved, and complicates ExportVerilog
significantly. Since we have developed a solution to handle this
problem in #2795, we can remove this code, and address this scenario
in PrepareForEmission.
It is also important to remove this code because it has bugs. I
believe they could have been resolved with #2773, but ultimately it is
better to do this in PrepareForEmission.
If the new logic doesn't cause a spill when the old logic would have,
the worst case is the expression remains inline. This might cause
Verilator to complain. But the previous logic could potentially drop
wires in illegal places, and it is best to remove that.
This commit allows struct_extract ops to be inlined even when they have multiple uses. It will make the output more readable.
For the following IR:
```mlir
hw.module @Foo(%a: !hw.struct<v: i1>) -> (b: i1, c: i1) {
%0 = hw.struct_extract %a["v"] : !hw.struct<v: i1>
hw.output %0, %0 : i1, i1
}
```
Before:
```verilog
wire _GEN = a.v;
assign b = _GEN;
assign c = _GEN;
```
After:
```verilog
assign b = a.v;
assign c = a.v;
```
This commit adds support for having parametric hw.array types. This is allowed for both the dimension as well as the inner type.
One small thing; I found it necessary to remove the "multidimensional array error message" (i.e. `hw.array<1x2xi3>`) due to difficulties with writing a parser for an n-ary, 'x' delimited list which also supports attributes. This doesn't imply a utility regression, since we nevertheless do not support multidimensional arrays in SV emission.
Change the --lowering-options=explicitBitcastAddMul option to not be
gated on a subexpression being in an assign. This is needed (according
to Spyglass...) anytime an addition or multiplication shows up.
Signed-off-by: Schuyler Eldridge <schuyler.eldridge@sifive.com>
`firrtl` and `hw` modules can now be annotated with MLIR visibility attributes.
The FIR parser sets the visibility of all non-main modules to private if the main module is defined, otherwise all modules remain public.
Transformations were altered to inspect the visibility attribute instead of checking whether a module matches the main of a circuit.
If the else block of an `IfOp` consists of a single `IfOp` and possibly multiple expressions, the block is printed as an `else if` and the intermediate wires are hoisted to the scope of the parent `if` block.
To extend the capabilities of parametric modules, this commit introduces support for `hw.instance`'iating `hw.module`s with parametric input/output types. Upon instantiation (and `hw.instance` verification), module types are resolved based on the set of provided parameters to the `hw.instance` op.
The brunt of the work for supporting this is added through two new functions:
- resolveParametricType: Based on a set of parameters, a parametric type is resolved to its actual type. For now, only parametric `!hw.int` types are supported, but #2703 will add support for parametric array types.
- evaluateParamAttr: Based on a set of parameters, a parametric expression is evaluated through use of the existing ParamExprAttr canonicalizers.
As a first step towards bringing the Moore IRs into the CIRCT project,
add a `ConcatOp` to the Moore dialect which represents a concatenation
expression. The intention is to make this MLIR op precisely capture the
semantics specified in the SystemVerilog standard. The documentation for
the op points at the relevant pieces of the standard.
This op will allow Moore to start emitting `moore.mir.concat` instead of
directly doing the lowering to LLHD/Comb, which is a great starting
point to move the code generation logic from the Rust code into CIRCT.
Add a conversion pattern for `UnrealizedConversionCastOp`s which applies
type lowering and removes the cast if it has become and identity
mapping. This will later allow partial lowering and intermixing of the
Moore and LLHD/core dialects.
The Comb dialect arithmetic op result has the same bit-width as the input operands.
Some lint tools can complain that the assignment results in loss in bits.
This commit has a lowering option to add an explicit cast, to avoid such lint errors.
For example, the following code snippet can generate an error,
width 18 is less than RHS: '(_GEN_7 * _GEN_8)' width 36 in assignment
wire [17:0] _GEN_7 = ...
wire [17:0] _GEN_8 = ...
wire [17:0] reg_out = _GEN_7 * _GEN_8 ;
The lowering-option=explicitBitcastAddMul makes the cast explicit.
wire [17:0] _GEN_7 = ...
wire [17:0] _GEN_8 = ...
wire [17:0] reg_out = 18'(_GEN_7 * _GEN_8 );
If an expression has more than the maximum number of terms, and we are
able to drop a wire or hoist it and drop a wire, we do so. The intent
is to remove the burden of spilling expressions larger than the
maximum token limit of some simulators by guessing what's "too large"
and doing it before ExportVerilog. Better algorithms and heuristics
for deciding to drop a wire can be added to shouldSpillWire.
The current implementation of prepareHWModule makes the phase ordering
of this a little interesting: we need to know it is "too large" before
we break the expression up into a binary tree. We also need to move
this addition, the splitting, and other canonicalizations to later in
prepareHWModule. If the spill happens while we are working on a
non-procedural region, we we can just proceed to splitting, but inside
a procedural region we actually move on down the block before
returning up.
[FIRRTL] Verified types for RegOp, NodeOp and RegResetOp
This patch introduces a new type, `NonAnalogPassiveType`, to represent
the values that can be assigned to nodes and registers. Section 4.1.4
bans `AnalogType` from being directly used, although analog types in bundles
and vectors are still permitted and asserted by tests included in CIRCT.
Section 6.9 requires the type of Muxes to be passive, so `PassiveType`
is still required.
Additionally, the type of the reset value of a register must match
the type of the register, according to the language of the spec.
While the specification is vague, the FIRRTL compiler expects
the types to be equivalent structurally: bundles and vectors must
match, although both integer truncation and extension is allowed,
verified by existing CIRCT tests.
The spec could be changed to recursively ban analog, changing the
condition of `NonAnalogPassiveType` to `containsAnalog`. Additionally,
truncation in register initialisation could be banned to define
behaviour corresponding to `ConnectOp`.
Generalize casez to support other case statements. Case and Casex support the same range of case selector patterns, they differ only in their interpretation of 'x' and 'z'.
There is an issue during module processing where we needed to know if
the module was instantiated underneath the DUT, and the answer to this
question depended on if we found the DUT module yet.
The typical way we have been handling this is to move this logic into a
post-pass, after we have found the DUT. I don't think that this is the
first time this has burned us, so to make it safe we would need to
remove the DUT from the CircuitLoweringState to make sure no one used it
before it was populated.
Instead, this change finds the DUT in a pre-pass, so it is available
while processing each module. This let me remove a post-pass to set the
testbench directory. We were already doing a pre-pass of the circuit to
look for NLAs, so I just stuck it in there.
This is a unary expression that calculates the ceiling of log base 2 of its
argument. Following the Verilog spec, clog2(0) is 0.
This is useful for calculating things such as the minimum bitwidth needed
to address a memory of a given size.
From the FIRRTL flow we need to be able to specify multiple output files
for the module hierarchy. To do this, this change switches the
`firrtl.moduleHierarchyFile` to have an array of files instead of a
single file.
The FIRRTL flow needs to be able to output a module hierarchy file for
the testharness (top level module) and the DUT module. When these two
modules are the same, we would end up only outputing a single hierarchy
file. Unfortunately, the SiFive build system is really hard coded to
expect both files (for now) so we had to add the ability to generate the
same file twice.
Co-authored-by: Megan Wachs <megan@sifive.com>