In the past, ESI has only supported valid-ready signaling, so we didn't
need to encode the signaling standard. Since we're about to add FIFO
signaling, we need a way to encode the signaling standard. Create an
enum and add it as a parameter to the channel type, defaulting to
ReadyValid so we don't have to fix a bunch of tests.
This analysis maps values back to their definitions (operations which produce a new value) and provides an indexing path in the original definition to produce the current value.
Subaccesses produce a -1 (wildcard) in the path.
The analysis provides the user with a stable summary node for each value which is suitable to use in other data-structures.
wire a : firrtl.vector<bundle<f1: uint, f2: uint>, 4> => definition, is a root (empty path)
v = subindex(a, 2) => derived from a with path {2}
w = subfield(v, f2) => derived from a with path {2, 1}
Add a known and supported annotation to the LowerAnnotations Annotation
table. This was accidentally never added, even though it works.
Signed-off-by: Schuyler Eldridge <schuyler.eldridge@sifive.com>
Test that resolving using relative include directories works, and check behavior re:search order
(relative to working directory is searched first, specified paths after).
Adds the '--exec' flag to tell this util to run the file instead of
parsing it and constructing a python script. Also removes unused
functionality SOURCES: and ARGS:. If `--exec` is used, the program's
first two args are the cosim port number and the path to the schema. If
the specified test application ends in '.py', it'll run the python
script with the python interpreter.
A module containing only ESI channels and modules with only ESI ports. All non-local connectivity is done through ESI services. If this module is the top level in the design, then the design's actual top level ports are defined by a BSP.
Useful for both simulation and synthesis via ESI BSPs.
Change the way that BoringUtils-backing infrastructure creates wiring
problems to not suggest a name derived from the "pin". This is often
auto-generated and may introduce a name collision between the port and
the source/sink, causing the source/sink to be renamed. Instead, rely
on the default behavior for how WiringProblems generate names to create
better names that are derived from the source/sink name.
Signed-off-by: Schuyler Eldridge <schuyler.eldridge@sifive.com>
Block removal of read-only memories that are initialized via a file.
This is a common FPGA ROM pattern (and is also used by the upstream
Chisel tests of file initialization API).
Signed-off-by: Schuyler Eldridge <schuyler.eldridge@sifive.com>
This PR extends HWLegalizeModules to support aggregate constants.
Also `signalPassFailure` is called when we fail to legalize expressions.
Fix https://github.com/llvm/circt/issues/4623.
Add an integration test of Chisel features for loading memories:
1. loadMemoryFromFile
2. loadMemoryFromFileInline
These APIs provide a way for a user to specify that a memory should get
either a "$readmemh" or "$readmemb" in an initial block using a
specified file. For (1), the memory is initialized using a module that
is bound into the memory module and does its "$readmem*" using an XMR.
For (2), the memory is initialized directly inside the memory module.
Signed-off-by: Schuyler Eldridge <schuyler.eldridge@sifive.com>
Add support to HWMemSimImpl for doing file-based memory initialization.
This comes in two flavors:
1. Inline initialization
2. Bind-based initialization
In (1), a ReadMemOp is used to initialize the memory from a file.
In (2), a separate module is created that initializes the memory via
ReadMemOp using an XMRRefOp. This new module is then instantiated in
the memory module via a bind.
Signed-off-by: Schuyler Eldridge <schuyler.eldridge@sifive.com>
Add Memory Initialization information to FIRRTL pipeline infrastructure.
This information is dropped at LowerToHW right now.
Signed-off-by: Schuyler Eldridge <schuyler.eldridge@sifive.com>
Add parsing of the two memory initialization annotations which implement
the Chisel loadMemoryFromFile and loadMemoryFromFileInline APIs:
- firrtl.annotations.LoadMemoryAnnotation
- firrtl.annotations.MemoryFileInlineAnnotation
These are parsed into the optional MemoryInitAttr on CHIRRTL or FIRRTL
memory operations.
Signed-off-by: Schuyler Eldridge <schuyler.eldridge@sifive.com>
Add a MemoryInitAttr to CHIRRTL memories (CombMemOp and SeqMemOp) to
record information about file-based memory initialization.
Signed-off-by: Schuyler Eldridge <schuyler.eldridge@sifive.com>
Add an optional attribute of type MemoryInitAttr to FIRRTL's MemOp in
order to capture external memory initialization behavior.
Signed-off-by: Schuyler Eldridge <schuyler.eldridge@sifive.com>
Add, but do not use a dialect attribute, "MemoryInitAttr". This is a
single attribute that represents both
"firrtl.annotations.LoadMemoryFromFile" and
"firrtl.annotations.MemoryFileInlineAnnotation". This will be added as
an attribute on FIRRTL memories in later commits.
Signed-off-by: Schuyler Eldridge <schuyler.eldridge@sifive.com>
Adds a "BSP" for XRT which just sets up the infrastructure. Outputs the "build package" complete with everything necessary to do an XRT image build and connect to the resulting accelerator. Does not have any communication with the accelerator. That's the next PR.
Often, we unconditionally print a space before printing optional attribute
dictionaries. However, the majority of the time, the attr dict is elided, so
that we end up with a double-space in our output. It turns out, the underlying
utility in MLIR, printOptionalAttrDict, will print a leading space if it has to
print the attr dict, so it's pointless for us to be outputting one ourselves.
This PR removes the extra whitespace for a number of ops.
A large number of ops use a custom directive to print the attributes. To
suppress leading whitespace in this case, we can use an empty literal (``) in
the asm format.
Modified Ops:
firrtl.circuit
firrtl.module
firrtl.wire
firrtl.mem
firrtl.node
firrtl.printf
firrtl.reg
firrtl.regreset
firrtl.instance
sv.wire
sv.reg
sv.logic
sv.interface.instance
sv.localparam
systemc.cpp.variable
esi.buffer
esi.pipeline
Co-authored-by: Robert Young <robert.young@shopify.com>
With the recent change to how port location information is handled, the
upstream pass StripDebugInfo no longer leaves the IR in a valid state,
as it does not update the debug information stored in module ops. To
fix this problem, we just have to use the local version of this pass,
StripDebugInfoWithPred and tell it to remove all locations.
Closes#4631.
This commit fixes bugs in spilling logic regarding expressions used in sensitivity list.
* PrettifyVerilog is changed to check lowering options so that CSEd expressions are not cloned into users when `exprInEventControl` is enabled.
* There was a duplicated logic in isExpressionUnableToInline and PrepareForEmission so the logic was unified into isExpressionUnableToInline.
Fix https://github.com/llvm/circt/issues/4620
Change the existing ReadMemOp to use an SSA Value for its destination
memory as opposed to a symbol. This more closely models how the
operation actually works and enables the operation to be used to be used
with XMRRefOp to initialize memories that are not in the current module.
Signed-off-by: Schuyler Eldridge <schuyler.eldridge@sifive.com>
* Migrate to the new folding api
In the old folding API, folders would get an array of attributes, where each
entry corresponds to an input operand of the op.
In the new folding API, this array is wrapped by an op-specific FoldAdaptor,
which gives us structured and nicely named accessors to the underlying array of
attributes.
This new folding API will soon be the only way to write folders, and as such,
ODS generates a warning when a dialect has not switched over to the new folding
API.
This commit moves every dialect in circt to the new folding API.
* Make constFoldFIRRTLBinaryOp's calculate callback take input by const ref
APInts are not trivially copyable, so passing them by const-reference might
save us some allocations. This change was suggested by clang-tidy.
The goal of this PR is to parse in FIRRTL debug source locations for module ports, and maintain them through the pipeline, eventually printing the locations as part of the port list. To accomplish this whole pipeline support, changes were required to the FIRRTL and HW dialects. The changes to HW modules motivated changes to the MSFT dialect to ensure that the generic module functionality still worked for both dialects. The port locations give better error messages when emitting a diagnostic on a block argument value.
The first design point is that I decided to support port locations on FIRRTL `FExtModuleOp`s. With regular modules, we can attach port locations to all the block arguments. For `FExtModuleOp`s we require a `portLocations` attribute of type `ArrayAttr<LocationAttr>` to track the port locations. To keep things simple, I decided to add the `portLocation` attribute to all kinds of FIRRTL modules. For regular `FModuleOp`s, we copy these locations into the block argument values and add a verifier to ensure that these are kept in sync.
The FIRRTL parser was storing the Module's location in each of the block arguments, despite having code for parsing port specific location information. It was modified to stop overriding the port's parsed location.
Port location information was added to the `FModuleLike` op interface.
Some internal FIRRTL helpers were refactored to have only common functionality, with `FModuleOp` handling the specifics of owning a region after calling the generic helpers.
The FIRRTL MLIR module printer was modified to print the debug locations when the `--mlir-print-debuginfo` option is specified. There appears to be a problem in the printer's support for debuginfo, and it will create attribute aliases for all locations even if it does not end up printing the location. To get around this, we query the OpPrinterFlags directly, which will be populated by the command line options. The downside of this approach is that if someone is programmatically modifying the printer's OpPrinterOptions, we will not respect those settings. I don't think this will be an issue in practice, but it would be nice to fix this upstream.
The FIRRTL IR module parser was modified to read in an optional source location when parsing the port list. If no location is found, it uses a location pointing to the MLIR file.
Dedup was modified to properly combine the location information of modules and their block arguments.
LowerTypes was modified to spread the port location information to each lowered port.
LowerToHW was modified to properly transfer the location information during lowering.
In the HW dialect, I continued the design point to allow port location information to be tracked by `hw.module.extern`, which required adding two attributes for tracking locations; an `argLocs` and a `resultLocs` attribute was added to HW modules.
Similar to the FIRRTL dialect many HW module helpers were updated to support these new attributes.
The HW pass StripDebugInfoWithPred now strips location information from the port location attributes.
The HW pass FlattenIO was modified to spread the locations to flattened ports the same way as LowerTypes, as well as fix the block locations which were removed by signature conversion.
HWArithToHWPass restores the block argument locations after SignatureConversion deletes them
ExportVerilog was updated to allow the printing of location attributes directly, instead of taking a set of operations. Some printer bugs were fixed here especially around consecutive 0-width ports, and some better alignment. See `test/Conversion/ExportVerilog/port-decl-sharing.mlir` for some tests. @dtzSiFive Will you please take a look at these changes, I see sometimes we are using nbsp and other times space literals and I don't know the difference.
ExportVerilog now always prints the closing `);` on a newline when there is a non-empty port-list. This was needed to support trailing location comments. Technically, we could still print it on the same line when location information is not emitted for the last port in the list, but I didn't consider it worth the effort. As an example:
```verilog
// Was:
module Foo(
output [3:0] if_0);
// Now:
module Foo(
output [3:0] if_0 // foo.scala:10:20
);
```
The MSFT and SystemC dialects has to be updated to support these new attributes. The MSFT module was updated to support the same form of location attributes as HW modules. SystemC modules are, for now, using the common functionality but throwing away the attributes. This way, we could maintain a common set of code for creating, parsing, printing, updating modules.
Added a verifier to the MSFTModuleOp that made sure that the location attributes matched the block argument attributes
The ESI ESIPortsPass was updated to spread the locations of `ChannelTypes` to the ready/valid ports it lowers them to.
MSFTPartition pass now preserves the location information.
The python bindings were updated to attach these new attributes to `HWModuleOp`s. These location always default to `unkown`, for the time being. Since `LocationAttr`s are not represented in the upstream MLIR API, we had to create the attribute by calling out to the MLIR parser.
This PR reimplements #4451 revered by #4465. The bug was that `getOrCreateAggregateConstantAttribute` re-used IntegerAttribute used by firrtl.aggregateconstant op. In FIRRTL dialect, integer attrs are APSIntAttr, which aren't compatible with normal integer attributes. 103e595556 includes a fix to explicitly convert APSIntAttr into normal integer attrs.
Instead of calling `_obj_to_value` from the support library, use some
OOP to leverage the `Type` system to do it. The `_obj_to_value` function
dates back to when we were using raw `ir.Types` and not extending them.
Now that we have a proper type hierarchy (and can rely on it being
used), this change is possible.
This fixes a problem where we do not respect the `isInOut` flag of the
PortInfo when adding block arguments. This bug has already been fixed in
HWModuleOps. This also adds verifiers are taken from the HW module op.
When we create the PortInfo object for a module, if the port is a
HW::InOutType, we strip it and set the isInOut field to true. When we create a
module from a PortInfo object we respect this field while constructing the
function type, but were not respecting the isInOut when creating the block
arguments.
This change starts respecting the `isInOut` field of port info when
constructing the block argument types. This also adds a verifier that the
function type of the module matches the block argument types.