The canonicalization was ignoring any registers with a preset, this commit fixes that.
Add fold and canonicalization patterns for registers with a preset.
When making a directory absolute, the remove_dots helper canonicalizes away any
trailing slash. Add the slash back on, which ensures that we interpret the path
as a directory correctly.
This fixes a bug where a path, when LCA'd with itself, drops the last segment.
An example of the problem: given a path foo/bar/, if we drop the trailing
slash, foo/bar is interpreted as a file called bar in a directory called foo.
When we LCA foo/bar with itself, the common parent directory is determined to
be foo/. By retaining the trailing slash, we can ensure that the correct LCA
path foo/bar/ is computed.
Fixes: #7347
Make the `name` attribute of `VariableOp`, `NetOp`, and `AssignedVarOp`
optional in the Moore dialect. The HW dialect does the same thing for
its wire op. Making the name optional allows us to have temporary and
compiler-generated variables without requiring dummy names to be
conjured up.
Infer the result type of `moore.read` by unpacking the `RefType` of its
operand. This triggers a lot of mechanical changes to the tests. Remove
the type from most `CHECK` lines to make future changes easier.
Add support for enum variants in expressions. Until now, ImportVerilog
would emit a "unknown name" diagnostic when an enum variant is used in
an expression. This is due to the lowering of named value expressions
simply checking whether an MLIR value is present in the `valueSymbols`
table for the referenced symbol name. This works for variables which
create dedicated declarations, but not for enum variants which
potentially live outside the current module's scope.
Instead, ImportVerilog will now check if the named value is a constant,
for example a parameter or an enum variant, and materialize that
constant directly as a `moore.constant` op. This will also be able to
deal with parameters declared inside of packages, for which the table of
value symbols of the current module does not contain any value. (Local
parameters inside the module generate a `moore.named_constant` op that
is present in the table.)
Due to historical circumstances, the SFC parser for FIRRTL treated commas (`,`) as whitespace. This behavior was carried over into the CIRCT implementation of `firtool`.
This behavior is utterly bizarre.
Moreover, the FIRRTL spec has indicated comma tokens (`,`) for at least every version since last year.
This PR removes this quirk and properly tokenizes commas, requiring them in the places dictated by the FIRRTL spec.
The impact of this PR should be low, but it may break code (in CIRCT, in Chisel, and elsewhere) in places where FIRRTL was being emitted with a loose interpretation, or where the spec was ambiguous.
Changes:
* Update several tests which were leaning into the "commas-are-whitespace" behavior.
* Removed `','` from the list of "horizontal whitespace" and added an explicit `FIRToken::comma` token.
* Made changes to the various `parse*()` methods to consume the tokens.
* Note the use of a pattern I found useful in several places where I use a boolean `first` to skip parsing comma tokens on the first iteration. Please check me here, since I learned C++ before lambdas were a thing.
* Made a few judgment calls around unspeced constructs (`smem`).
* * I changed the FIRRTL emitter in one place where the syntax was unspeced, and there seemed to be conflicting examples.
* @seldridge For some reason, it seemed ambiguous whether `layer` decls need commas. I opted *for* commas. I can swap if I got this backwards.
* I added `parseRUW()` as a non-optional variant of `parseOptionalRUW()`, since the comma token can be used to determine optionality in one case.
Handle calls to the `$signed` and `$unsigned` system tasks by simply
passing through the argument. The casting is handled by Slang during
type checking and is materialized as a type conversion node in the AST.
The call itself has no function after that.
The `visitCall` function is going to be the place to add handling for
other system calls in the future. IEEE 1800-2017 section 20 defines a
fairly substantial list of builtin system tasks. Most of these will want
to have a dedicated `moore.builtin.*` op in the future.
This commit adds unpacked array create op that will be lowered into array literal
`'{..}`.
Since array literal must be used in assignment-like context,`unpacked_array_create`
is always spilled to a temporary wire.
The operand ordering follows HW array representation. This is currently tricky since
we emit unpacked types slightly differently (`downTo`) but the correct ordering is emitted
in ExportVerilog.
For the new concept of Moore dialect, some operations will be defined as memory-related operations. Modeling memref Dialect and LLVM dialect, the operation relationship is as follows:
ReadOp and blockingAssignOp are related to loadOp and storeOp.
VariableOp is related to allocaOp.
However, the operations mentioned below are for basic types. This PR will support nested types in the following way:
VariableOp with nested types is still related to allocaOp (will be replaced with structCreateOp and UnionCreateOp).
structExtractRefOp is related to storeOp.
structExtractOp is related to loadOp.
To implement this:
Since these operations will be lowered to the hw dialect, the design largely refers to the hw dialect.
Add the trait DestructurableAllocationOpInterface for VariableOp.
Add the trait DestructurableAccessorOpInterface for structExtractOp and structExtractRefOp.
Implement the DestructurableTypeInterface for structLikeType and the reftype of structLikeType.
For local variables:
Use the SROA (Scalar Replacement of Aggregates) Pass to destructure all nested-type variables into basic-type variables.
Use the Mem2Reg (Memory to Register) Pass to replace variables imported by SROA with constants.
For global/module-level variables:
When importing Verilog, use structInjectOp rather than blockingAssignOp, because structExtractRefOp has the Destructurable trait, but global variables should not be destructured.
structInjectOp means creating a new struct with new values and other old values.
Use the canonicalizer Pass to fold duplicate injecting same field operations.
Use the canonicalizer Pass to explicitly show new struct creation.
Use the canonicalizer Pass to send source values directly and remove structExtractOp.
Also, remove some unnecessary spaces in other code.
What's more:
Verify that the input of nested-type-related operations should match the field type defined.
To do:
Update the use of struct SSA values referring to the latest structInjectOp SSA values.
Design the method for union types.
Add and support the dbg dialect to keep local variables visible after SROA & Mem2Reg.
Co-authored-by: Théo Degioanni <degiotheo@gmail.com>
Co-authored-by: Fabian Schuiki <fabian@schuiki.ch>
Add handling for package definitions and accept empty packages for the
time being. Later on we'll want to support parameters, variables,
functions, and other things that can appear in packages. These require
a mechanism to refer to things outside of an `SVModuleOp` though, which
does not yet exist.
The goal of this PR is to introduce a first round of new test intent operations, for formal tests this time, to the verif dialect.
The ops that have been added in this PR are:
- verif.formal
- verif.symbolic_input
- verif.concrete_input
Fix an issue where ImportVerilog would currently crash if an unbased,
unsized literal like `'0` is used to initialize or assign to a packed
struct. Instead, the integer literal should be constructed and then
converted to the packed aggregate type. In a later pass, this conversion
can be lowered to a more careful `moore.struct_create`.
Use `upper_bound` to pick an insertion point for modules. This ensures
that multiple parametrizations of a module appear in the order in which
they were instantiated, instead of the reverse order.
This commit adds "context" property to DPI import statements to enable us to call exported functions from DPI functions. Ideally it's better to create an attribute to specify the property "context" or "pure" but "context" by default should be ok for now.
Coerce a two-channel, bidirectional bundle to a different two-channel,
bidirectional bundle type. Transform functions can be provided to
transform the individual channels for situations where the types do not
match.
This was originally added to avoid a use-after-free. However, it got
removed as part of f4920aa. It seems this is still required, even when
we process PathTrackers sequentially. I confirmed there was a
use-after-free without this change, which is fixed after adding this
back.
Closes https://github.com/llvm/circt/issues/7327.
Change FIRRTL's deduplication pass to report all errors arising from
modules marked "must deduplicate" that do not expectedly deduplicate.
This provides a better user experience because they do not have to iterate
on long compiles only to get "one more error".
Fixes#7324.
Signed-off-by: Schuyler Eldridge <schuyler.eldridge@sifive.com>
This PR introduces a new assert property op to the sv dialect and uses that as an intermediary for property assertion emission. This should solve the issue of the polarity being different in SV and in verif for the enable signals ( enable in verif, disable in sv ).
Adds a channel buffer to an ESI channel. Since the channel buffer lowers
to a SystemVerilog primitive, we need to copy the ESI primitives file
into the output dir.
Only affects Questa simulation.
- Fix the build rpath so one can run Questa on the build directory.
- Remove the CXX path as it doesn't seem to be necessary any longer.
- Switch the timescale to something more reasonable.
Introduce a new Python "interface" class (to make type checkers closer
to happy). It simply unifies classes which can be (and are required to
be) assigned to.
Casting from interface to operation generates these warnings,
as with other instances resolve by casting from Operation* instead.
> llvm/llvm/include/llvm/Support/Casting.h:490:69: warning: returning reference to local temporary object [-Wreturn-stack-address]