We generally type-erase objects at the boundary, to avoid needing to
declare the objects' classes as part of the interface. This adds a
cast for the metadataObj reference, so we don't have to declare its
class as part of the interface. The evaluator and any tooling built on
it already know how to "see through" this cast.
... while factoring out `InnerSymbol`+name logic into a new interface that is also used by Ibis port-like ops. This model could probably be factored into the `hw` dialect, seeing as we're also eventually going to divorce symbol names and actual names in `hw.module`.
Also adds de-aliasing logic to `ContainersToHW`, which is required given that `hw.module` doesn't yet split its symbol and name (#7023).
This PR implements ExportVerilog support of sv.func, sv.func.dpi.import, sv.func.call and sv.func.call.procedural.
sv.func emission is similar to hw.module but one difference is a return value. Surprisingly in SV a function name is used as a placeholder for a return value so name legalization properly sets `hw.verilogName` of a returned value to a function name.
Result names of sv.func.call.procedural are attached to temporary registers created in PrepareForEmission. This is similar implementation approach to hw.instance.
[Moore] Modify the tests related to the RefType.
Add a wrapper type(moore::RefType) to work for VariableOp/NetOp, ReadOp, and AssignOpBase, and it can wrap any SystemVerilog types. We added RefType in order to introduce Mem2Reg into moore to eliminate the local temporary variables. Meanwhile, we added a new op named moore.extract_ref which is the copy of moore.extract that explicitly works on the ref type. And moore.concat_ref is the copy of moore.concat. Later, we will tweak union/struct ops like moore.struct_create in order to support the ref type.
moore.variable/moore.net will return a result with ref<T>, it's similar to memref.alloca.
Change moore::ReadLValueOp to moore::ReadOp, it's similar to memref.load. Initially, we need moore.read_lvalue only to service for assigmen operations(like +=, *=, etc). However, moore. read is not only for assignment operations but also to take a value with RefType(ref) and return the current value with the nested type(T). For example, a = b + c, moore.read will take b and c(both are ref<T>), and then return a value with the nested type(T).
We think the MooreLValueType and VariableDeclOp(52a71a6) that had been removed eventually found their proper site.
We also divide convertExpression() into convertLvalueExpression() for the LHS of assignments and convertRvalueExpression() for the RHS of assignments. The former will return a value with RefType like ref<i32>, but the latter returns a value without RefType like i32.
Co-authored-by: Fabian Schuiki <fschuiki@iis.ee.ethz.ch>
This changes pre-passes for ExportVerilog to run on HWEmittableModuleLike instead of HWModuleOp. #6977 is going to add a support for SV func op and legalization needed for SV func as well.
HWEmittableModuleLike is a new interface that inherits Emittable+HWModuleLike. I considered to use a trait but we cannot use a trait for pass scheduling so an interface is used.
Add module types and support for ports to the `moore.module` and
`moore.instance` operations. Also add a `moore.output` operation as a
terminator for modules, similar to the HW dialect. Extend ImportVerilog
to generate ports.
The ports on SVModuleOp follow a similar strategy as in HWModuleOp: all
input, inout, and ref ports are passed to the module as inputs and are
carried inside the module as block arguments, while output ports are
assigned by the OutputOp terminator. The Moore dialect reuses the
`hw::ModuleType` but does not use the `inout` direction. Instead, inout
ports will be represented as inputs with a `net<T>` wrapper type, while
ref ports will be wrapped as `ref<T>`.
Instances work identically to the HW dialect: input, inout, and ref port
connections are carried as operands, while output ports are represented
as results.
This commit also adds module and instance port support to the
ImportVerilog conversion. Regular ports are mapped to corresponding
ports on the module with the appropriate direction. Multi-ports, which
are a weird quirk of SystemVerilog that allow multiple ports to be
grouped up and presented to the outside as a single named port, are
split up into individual module ports. This is necessary since this
group can contain ports of different directions.
Inside a module Slang automatically generates local net or variable
declarations for all ports. The user may specify these declarations
themselves when using non-ANSI port lists, which Slang handles properly.
ImportVerilog inserts appropriate continuous assignments to drive the
actual input port value onto the local net or variable declaration, and
to drive the local declaration's value onto the actual output port of
the module. This properly adapts from SystemVerilog's assignable and
connectable ports that feel like nets or variables, to the Moore
dialect's by-value passing of inputs and outputs.
Instances in Slang have expressions connected to their ports. Input
ports lower this expression and directly use the result as an operand.
Output ports lower this expression and drive it through a continuous
assignment inserted after the instance, with the instance's
corresponding result on the right-hand side of the assignment.
Once we have a `ref<T>` type, and later potentially also a `net<T>`
type, the port lowering shall be revisited to ensure that inout and ref
ports are mapped to net and ref types, respectively. The lowering of
expressions connected to ports requires more care to ensure that they
are appropriately lowered to lvalues or rvalues, as needed by the port
direction. A `moore.short_circuit` operation or similar would help to
connect inout ports to the local net declarations in a module, and to
capture `alias` statements.
---------
Co-authored-by: cepheus <buyun.xu@terapines.com>
Co-authored-by: Hailong Sun <hailong.sun@terapines.com>
We stated in a comment that we copy the leading part of the
hierarchical path from the owning module to the start of the
annotation's NLA. But we never actually did that, so this adds (back)
that logic.
Fixes https://github.com/llvm/circt/issues/7125.
This turns the multiple-instantiation error into a warning in
ResolvePaths and LowerClasses. In real designs coming from Chisel
today, we are not yet able to enforce single instantiation. This was
never a requirement of the original way that we handled hierarchical
paths in EmitOMIR, so this removes the requirement for now. Adding it
back is tracked in https://github.com/llvm/circt/issues/7128.
With this change, the ResolvePaths logic was simplified to stop trying
to disambiguate paths in some cases, and instead allow the annotations
to simply convey the user's requested local or hierarchical path. In
LowerClasses, if there are multiple instances, this means we have
ambiguity. In practice, this logic will produce the same outputs as
EmitOMIR, once we fix https://github.com/llvm/circt/issues/7125.
Add a missing check for absent port location information to
`printModuleSignatureNew`. This would cause crashes if the
`--mlir-print-debuginfo` option was set during emission and there are
not port locations available. This mirrors what we already do for
port attributes.
Thanks @uenoku for pointing this out in #7112.
Create these constants as unsigned of unknown width,
instead of s64.
This way when connecting to the address, we don't emit
a connnect between s64 and something like u3
(requiring casts/trim/etc).
Fix a subtle issue in ImportVerilog's statement converter, where a call
to `convertExpression` returning a null value would not properly be
mapped to a `failure()` result.
The original line was `success(<value>)`, which apparently still returns
success even with a null value. Changing this to `failure(!<value>)`
fixes the issue.
While at it, remove all error test cases that simply check for Slang
frontend errors. These things are already tested in Slang. ImportVerilog
should only test for the errors it generates itself.
* [ImportVerilog]Support union types.
* [ImportVerilog]Rename structMember with structLikeMember
* [ImportVerilog] check the type of new Expressions.
* [ImportVerilog]Add value check for new Expressions.
* clang-format modify recommand
* [importVerilog]Remove useless inlcludes
* [ImportVerilog]Add union size and domain
* [ImportVerilog]Give more specefic errors