Instead users should use CombToArith+ArithToLLVM. There is still a pattern population function left for the comb.parity op, which does not have an equivalent in the arith dialect.
Add utilities to allow C++ to link against and drive a software model
generated from the arc dialect.
The `arcilator-header-cpp.py` utility accepts the state JSON file
generated by the `PrintStateInfo` pass and converts it into a C++ header
that makes the lowered LLVM model feel close to Verilator output. The
mapping is not perfect: there is no `eval` function, but dedicated clock
and passthrough functions to be called instead. The commonalities of the
generated C++ header are collected in `arcilator-runtime.h`.
The utilities and headers aren't installed yet properly.
Co-authored-by: Martin Erhart <maerhart@outlook.com>
Co-authored-by: Zachary Yedidia <zyedidia@gmail.com>
After the muxes that represent enables and resets are factored out by
the `InterStateProperties` pass, there are still a lot of muxes left
that have big fan-ins and can be converted to proper branches for some
performance benefit.
There is still a bit of work to do in the backend, that I haven't
included here, to support lowering of if-statements (or nested regions
in general).
The heuristics for deciding whether to convert to if-statements are not
properly fine-tuned yet because I'm still working on a proper set of
benchmarks to evaluate it and it likely changes anyways until we have a
somewhat stable set of optimizations implemented.
A pass to detect resets and enables in arcs. Making them explicit allows
another pass to pick them up more easily and, e.g., group the ones with
the same conditions together to reduce the number of branches, position
the ones with the same resets next to each other in memory to do a
simple memset over a continuous region in mem, etc.
I don't particularly like the way this is represented in the IR right
now because it makes the state ops more complex and basically everything
is just represented with this single op. It also forces us to have a
static order of reset and enable (currently the reset operand always has
higher precedence).
Add two passes to lower a design to a software model.
The `LowerClocksToFuncs` pass outlines all `arc.clock_tree` and
`arc.passthrough` operations into separate MLIR functions. This
conceptually converts clocks from being a signal in the design into a
function that can be called in order to execute the state update
triggered by that clock.
The `LowerArcToLLVM` conversion pass does exactly as it says: it sets up
a dialect conversion from Arc and the core CIRCT dialects to Func/SCF,
and from there to the LLVM dialect.
Also add an output format option to the arcilator tool that allows for
the direct emission of LLVM IR (as opposed to the MLIR's LLVM dialect).
Co-authored-by: Martin Erhart <maerhart@outlook.com>
Co-authored-by: Zachary Yedidia <zyedidia@gmail.com>
Add three passes that implement state allocation. The passes take the
abstract state allocation ops, compute a memory layout for the overall
state of the model, and replace the allocation ops with simple pointer
getter ops that access the allocated piece of memory. The passes operate
as follows:
- `LegalizeStateUpdate` detects read-after-write hazards and introduces
temporary storage locations that allow the read and write ops to
occur without infringing on each other.
- `AllocateState` computes the overall memory layout and replaces
allocation ops with simple accessor ops.
- `PrintStateInfo` emits the memory layout as a JSON file. This allows
other tools to reason about the exact memory layout of the design.
State update legalization is still lacking proper handling of memory
reads and writes, which are significantly more involved than the simple
scalar registers. Follow-up work.
Co-authored-by: Martin Erhart <maerhart@outlook.com>
Co-authored-by: Zachary Yedidia <zyedidia@gmail.com>
Add the `LowerState` pass and accompanying operations to convert a
design from a pure state transfer graph composed of arcs to a more
procedural read-modify-write representation. After this transformation
the design is a significant step down the path of becoming a software
model.
The `LowerState` pass proceeds as follows:
- Group all `arc.state` ops according to their clock into
`arc.clock_tree`s. Operations that are on direct input-to-output
passthrough or on state-to-output paths are grouped into a
`arc.passthrough` op.
- Introduce an explicit state storage allocation op for every state op,
memory op, as well as every input and output port of the root module.
- Replace the root `hw.module` with a `arc.model` which no longer has
any input and output ports, but a storage pointer argument instead.
Storage allocation ops represent specific chunks of memory behind this
pointer.
- Split every `arc.state` op with latency >0 up into a `arc.state_read`,
`arc.state` with latency 0, and `arc.state_write` operation. This
essentially breaks `arc.state` up into two parts: a read for all users
of the state, and a transfer function plus write for all operands of
the arc.
In doing so, the sea-of-gates representation of the HW dialect, which
is a pure graph without op ordering constraints, is converted into a
a sea-of-clocks, where each group contains the parts of the circuit that
are triggered by the same clock. The actual computation that occurs on
that trigger is represented procedurally in a proper SSA/CFG block.
TL;DR: This goes from "How do the gates connect together?" to "How does
a computer simulate these gates?".
Co-authored-by: Martin Erhart <maerhart@outlook.com>
Co-authored-by: Zachary Yedidia <zyedidia@gmail.com>
Fix an issue where `pruneUnusedOps` would remove operations that the
overall `circt-reduce` driver would later still try to modify. Instead,
reductions can now notify the driver that an op was erased, and any
reductions on that op will just be skipped.
This defines the dialect boilerplate, as well as a rationale document
that explains the intended use case and initial core constructs that
will be added in future patches.
Fix a source of crash in `circt-reduce` where the tool would try to
apply a reduction to a parent operation *and* some of its nested child
operations at the same time. Add a set to keep track of which operations
were already affected by a reduction on their parent, and skip those.
Also fix poor scaling behaviour in `computeTransitiveModuleSize` which
made the FIRRTL module externalizer and instance stubber very slow. The
new simplified implementation doesn't produce reduction estimates as
accurately, but it is a lot faster and seems sufficient in most cases.
Implements parts of #4100.
Add an `arc.tap` operation that allows us to assign a name to an
arbitrary SSA value such that it remains observable after any subsequent
transformations. Also add an `AddTaps` pass which adds an `arc.tap` op
to every module port and every wire, making them observable even after
transformations have completely flattened the original hierarchy.
Co-authored-by: Zachary Yedidia <zyedidia@gmail.com>
Add an experimental pass to convert operations in the Comb dialect to
their equivalent in the Arith dialect. The pass isn't used anywhere yet,
but conversion to Arith allows all canonicalizations defined on that
dialect to take effect before mapping things to LLVM to generate a
software model.
Co-authored-by: Martin Erhart <maerhart@outlook.com>
Many CIRCT frontends don't generate clean HW representations of their
inputs, but instead intersperse SV dialect operations to explicitly
materialize named wires. Add a makeshift `StripSV` pass to remove some
of the trivial SV dialect ops (wires just for the sake of naming) and
to replace `seq.firreg` with `seq.compreg` throughout the input. At a
later point we'll want to introduce a "register" op interface such that
passes can inquire about a register op's semantics in a uniform manner.
Similarly, the Seq dialect lacks a memory construct. The FIRRTL pipeline
lowers its `firrtl.mem` ops into HW generator ops. Add a `InferMemories`
pass that converts this generator op into a proper `arc.memory` op with
associated `arc.memory_read` and `arc.memory_write` operations.
Co-authored-by: Martin Erhart <maerhart@outlook.com>
Co-authored-by: Zachary Yedidia <zyedidia@gmail.com>
Add the `MakeTables` pass which finds small arcs and converts them into
a lookup table where possible.
Co-authored-by: Martin Erhart <maerhart@outlook.com>
Co-authored-by: Zachary Yedidia <zyedidia@gmail.com>
Add the `SinkInputs` pass which sinks constants into arc definitions
where possible. The arc conversion pass keeps constants out of arcs to
increase the chance of discovering arcs that only differ by constant
values, at the cost of additional arc arguments. The `SinkInputs` pass
is intended to run after deduplication, to simplify arc inputs that are
set to the same constant at all arc call sites.
Co-authored-by: Martin Erhart <maerhart@outlook.com>
Co-authored-by: Zachary Yedidia <zyedidia@gmail.com>
Add the `SplitLoops` pass which splits arcs with multiple results into
arcs with just one result. This is intended to break "false" loops among
`arc.state` ops. Grouping combinational ops into arcs may introduce
loops between the arcs even though the combinational ops had no loops
themselves. Ideally we'd be more clever about the splitting and only
separate the arc outputs that actually cause these loops, implementing
this is a bit more involved than the current solution though. Reducing
arcs to one output suffices for now.
Co-authored-by: Martin Erhart <maerhart@outlook.com>
Co-authored-by: Zachary Yedidia <zyedidia@gmail.com>
This PR removes many hidden developer options from `firtool`. These
options were more useful when we would regularly have crashes in
specific passes and a developer would want to temporarily bypass the
pass. Now that we are much more stable, these options don't add any
utility, and we risk that a user may find and start using one of these
options.
This change also:
- removes the unused `emit-metadata` flag
- stops predicating the dedup pass on `--disable-opt`, which allows us
to disable optimization and run the dedup pass.
- restores the original intent of the test in `chirrtl.fir`, which was
to make sure that optimizations were not affecting enable inference
of CHIRRTL read ports.
Add the `arcilator` convenience tool to make experimenting with the
dialect easier. The intended pass sequence performs the full conversion
from a circuit cut along port boundaries (through modules) to a circuit
cut along the state elements (through arcs). The tool simply executes
this pass pipeline.
Co-authored-by: Martin Erhart <maerhart@outlook.com>
Co-authored-by: Zachary Yedidia <zyedidia@gmail.com>
Add the `Dedup` pass which deduplicates arcs with identical definitions.
If arcs differ only by constant values, the pass outlines the constants
such that the arcs can be deduplicated.
Identical arcs are surprisingly common since splitting modules along the
fundamental state elements yields a finer-grained subdivision than the
modules themselves, which has the potential to uncover additional
redundancies.
Co-authored-by: Martin Erhart <maerhart@outlook.com>
Co-authored-by: Zachary Yedidia <zyedidia@gmail.com>
Make IMCP not try to optimize registers. All the existing firrtl register optimizations are unsafe in that they change visible behavior. For this reason, they those optimizations are to be moved out to a separate pass and IMCP will be left as purely behavior preserving.
Secondly, many folders can operate on incomplete operand information. Rather than giving up and not folding these, if we have some constants, we try to fold, but we don't over-define if some of the operands were unknown. This way things like or(const 0, unknown) can fold.
Perform vb->bv conversion before flattening memories. The vb-to-bv pass cannot
reshape memories that have been flattened.
Add a memory preservation option to lower types. Before, lower-types would
unconditionally fully scalarize memories. Now we can run lower types without
lowering memories. This lets us use lowerTypes to scalarize the ports of
public modules, before running vb->bv, without affecting memories.
This commit moves FirtoolPassInstrumentation to a support header and rename FirtoolPassInstrumentation to VerbosePassInstrumentation.
This subsumes https://github.com/llvm/circt/pull/3931/. Calling `isa<firrtl::CircuitOp>` caused circular deps between firrtl and support so this PR instead used template arguments to filter operation types.
Add the `ConvertToArcs` conversion which collects the combinational
operations in a module body, divides them into distinct sets split along
registers and a few other potentially state-holding operations, and
outlines these sets into arc definitions, inserting an `arc.state` op in
place of the original combinational ops.
Note that this merely replaces logic and registers with arc invocations,
but keeps the module hierarchy intact.
Co-authored-by: Martin Erhart <maerhart@outlook.com>
Co-authored-by: Zachary Yedidia <zyedidia@gmail.com>
Add the `Arc` dialect which is useful for capturing a canonical
representation of the state transfer in a circuit. It does this by
introducing function-like arc definitions (`arc.define`) and call-like
arc invocations (`arc.state`). The state op represents a transfer
function, given by the arc definition, and zero or more registers, as
specified by its latency attribute.
Co-authored-by: Martin Erhart <maerhart@outlook.com>
Co-authored-by: Zachary Yedidia <zyedidia@gmail.com>
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.
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.
Add "-lower-annotations-no-ref-type-ports" option to firtool. This is
an option that will cause the LowerAnnotations pass to only create
"real" ports, instead of ref type ports, when resolving WiringProblems.
The intended use case of this pass is to enable Grand Central Tap
collateral to be made synthesizable.
Signed-off-by: Schuyler Eldridge <schuyler.eldridge@sifive.com>
Add an option that will cause Grand Central companion modules to not be
bound in (they are directly instantiated) and interfaces are no longer
emitted.
Signed-off-by: Schuyler Eldridge <schuyler.eldridge@sifive.com>
* Bump LLVM submodule
Minimal progress, but worth sharing.
* compiling now
* clang-format
* remove unnecessary includes from msft dialect
* XFAIL'ing broken Calyx tests
* Bump LLVM submodule
Minimal progress, but worth sharing.
* compiling now
* clang-format
* remove unnecessary includes from msft dialect
* XFAIL'ing broken Calyx tests
* Fix Calyx tests and ASAN, and re-enable. (#4592)
* Bump to 26th Jan
* switch to ninja and latest cmake
* hopefully fix ci builds
* use full path
* [circt-reduce] Set the default op for pass manager to builtin.module
---------
Co-authored-by: Andrew Young <youngar17@gmail.com>
Co-authored-by: Mike Urbach <mikeurbach@gmail.com>
Co-authored-by: Prithayan Barua <prithayan@gmail.com>
This pass should generally be run as late as possible so it can clean
up after all prior passes. It currently runs just before the
BlackBoxReader pass, which happens to leave behind some dead symbols.
This moves it as late as possible: just before InnerSymbolDCE. While
there is no new integration test of the firtool pipeline with this
change, it has been shown to remove symbols that would otherwise
remain.
This PR deprecates `strip-mux-pragmas` flag and add `add-mux-pragmas` flag. Mux pragmas will not be emitted by default. `strip-mux-pragmas` is not deleted for now so that we can deploy a new version of firtool more smoothly.
* LLVM.h: drop mlir::Optional.
It's an alias for std::optional now, just drop
instead of adding the templated using alias here as well
(which we'd have to remember to drop).
* Convert Optional -> std::optional.
Drop some unnecessary initializations, but keep them for fields for now.
Particularly:
StandardToHandshake.h: keep init for field, for omission in {} initializers.
FSMToSV: similarly keep the current initialization.
Remove the Grand Central (GCT) Data/Mem Taps pass from the firtool
pipeline. All Annotations related to these features have been migrated
to be handled by LowerAnnotations using RefType infrastructure.
Signed-off-by: Schuyler Eldridge <schuyler.eldridge@sifive.com>
This is NFC. The only change is related to the transition from
llvm::None to std::nullopt, so I cleaned those up.
This LLVM commit includes a few additions to the MLIR Python API that
will be good to build on top of.
This bumps llvm just before 53406427cd which will cause a lot of complication failures about FunctionOpInterface. This PR mostly replaces llvm::None with std::nullopt.
Add support for intrinsics in FIRRTL. Until intrinsics are supported in the firrtl spec, or we have more complex intrinsics, do direct lowering of intrinsics into their ops.
It is expected that eventually something like an "intmodule" will exist and annotated extern modules will not be used for intrinsics or first they will lower to intmodules internally, then intmodules will be handled uniformly.
As an example, add a sizeof operator which returns the number of bits in the argument type. This let's you query the result of type inference from inside the circuit.
Also adds support for isX as an intrinsic and plusarg sv functions.
The `InitAllPasses.h` header file includes all the generated pass header
files, e.g. `"circt/Dialect/SystemC/Passes.h.inc"`. To make sure this
header file is generated properly before we try to include it, we have
to depend on the associated transform library. Since hlstool does not
depend on every single transform library, this causes the build to
occasionally fail. To fix this, we need to only include header files
belonging to the dialects we are actually depending on.
This error can be seen in the following build:
https://github.com/llvm/circt/actions/runs/3657570236/jobs/6181309548
This finds and removes any InnerSymAttrs that are not used.
It starts with a walk through the IR to find any InnerRefAttrs. This
looks through all operations' attributes, descending through nested
attributes using the sub element interface.
After finding all live InnerRefAttrs, it walks through each module in
parallel looking for operations with an InnerSymAttr. If the module
and symbol were not in the set of live inner references, the inner sym
is removed.
Signed-off-by: Schuyler Eldridge <schuyler.eldridge@sifive.com>
Co-authored-by: Mike Urbach <mikeurbach@gmail.com>
Introduce the notion of a "board support package" (BSP). It controls the top level of the design and assembles the system into a "package". A package generally includes the hardware output (+ any other collateral needed to build the design), the software runtime, and a script (makefile) to build the system and (for some BSPs) run it.
This adds an option `--add-vivado-ram-address-conflict-synthesis-bug-workaround` to add a workaround that vivado maps BRAM to memory register that has caused an incorrect synthesis result. To prevent vivado from using BRAM for registers, this expliclity specifies the ram style so that vivado selects LUTs. With this PR, registers used as memory are annotated in the following way:
```
(* ram_style = "distributed" *)
reg [15:0] Memory[0:9];
```
This applies a new pass generation method(ref:https://github.com/llvm/circt/issues/3962) to seq dialect passes, that automatically defines a struct of options (e.g. `LowerSeqFIRRTLToSVOptions`) and creates a pass constructor to take the option.
Change all existing CIRCT tools to use a CIRCT-specific bug report
message. Previously a crash would tell people to file a bug on LLVM
which isn't correct.
Signed-off-by: Schuyler Eldridge <schuyler.eldridge@sifive.com>
These new additions are both fairly significant departures from past
behavior, so add an ability to disable them. They remain enabled by
default. The new flags are plumbed out to firtool flags so they can be
disabled from firtool, and a test is added that this behavior can be
controlled from firtool.
This commit adds mux pragmas to memory reads in HWMemSimImpl in a similar way to https://github.com/llvm/circt/pull/3404. This commit also adds a flag `strip-mux-pragmas` for firtool
to remove mux pragmas annotated at HWMemSimImpl and LowerToHW.
Add a pass to overwrite lowering options on a module. This lets us get rid of the in-library cmdline option and move it to the two tools which need it. With this, prepare and export never change the lowering options.
Also make prepare a nested pass.
We create and manage many thousands of HierPathOp's unnecessarily.
Fix this by addressing the primary location they're added to the IR: LowerAnnotations, by using a simple cache to avoid emitting duplicate ops.
This reduces the count from thousands to tens on even small-ish designs.
Modify GC and GCT passes to stop deleting HierPathOp's as they don't know if they're still used. Indeed, in our tests we were deleting these ops despite them still being alive (breadcrumbs).
Add SymbolDCE to the pipeline to do this cleanup instead, thanks to various recent changes using private visibility in many places, particularly the HierPathOp's themselves (#3871).
This commit adds a flag to `hlstool` that allows selecting the kind of parallelism to support. Currently, these options are "pipelining", "locking", and "none".
This commit adds the two options of the buffer insertion to the `hlstool`. Thus, it's now possible to specify both buffering strategy and buffer size when using the tool.
Change `firtool -parse-only` to stop after parsing, verification, and
annotation lowering as opposed to stopping after parsing. It is
incredibly rare that a user (or, much more likely, a developer) actually
wants the behavior of stopping after parsing as opposed to stopping
after annotation lowering. This avoids a frequent pattern where a
user/developer will use something like the following instead of
`-parse-only` for any circuit that includes annotations:
firtool -parse-only Foo.fir | circt-opt -firrtl-lower-annotations
Signed-off-by: Schuyler Eldridge <schuyler.eldridge@sifive.com>
[Pipeline] Add pipeline stage register materialization pass
This commit adds an intermediate transformation to the Pipeline dialect
which is responsible for converting `pipeline.stage` to `pipeline.stage.register`
operations. The purpose of this transformation is to 'fix' where
registers needs to be placed in the pipeline, after all stages have been
defined and placed.
In short, the transformation will scan through the pipeline (in order,
top to bottom) and insert `pipeline.stage.register` operations in place
of `pipeline.stage` operations. Any operand used in any operation will
be analyzed to determine if it originates in between the last seen stage
and the operation itself. If not, this means that the operand crossed
a pipeline stage, and as such, the value will be routed through the
predecessor stage (`routeThroughStage`).
* [Calyx][FIRRTL] Put explicit type hints for TypedValue where necessary.
With the introduction of TypedValue in upstream llvm commit
688c51a5acc53b456014e53663051476d825e896, there are now a few cases
where we need to explicitly write the types. In some cases, we need to
explicitly upcast to Value to be consistent with other Values in the
expression, and in other cases, we need to upcast the type parameter of
TypedValue when there are ambiguous implicit conversions.
* [FIRRTL] Replace llvm::GreatestCommonDivisor64 with std::gcd.
GreatestCommonDivisor64 was removed in upstream LLVM in
87c38323a2cff5b26023b24c36a7c01741aba834, and the recommended migration
path is to use std::gcd. This performs an explicit cast to uint64_t for
the same reasons described in 4a2377afd69bcf014492cb665ee955eab3121c4c,
which is that std::gcd may have different and unexpected semantics when
its arguments are of different types and signedness.
* [NFC] Explicitly set dialect accessor prefix to kEmitAccessorPrefix_Raw.
Upstream recently changed the default value of emitAccessorPrefix to
kEmitAccessorPrefix_Prefixed. This patch explicitly sets
emitAccessorPrefix to the previous default value of
kEmitAccessorPrefix_Raw, which will allow us to the new accessor prefix
style more gradually and at our own pace. Upstream will completely
remove the _Raw style in the next couple of months, so we will need to
make the migration soon, though.
See [1] for more information.
[1]: https://discourse.llvm.org/t/psa-ods-generated-accessors-will-change-to-have-a-get-prefix-update-you-apis/4476
* [firtool] Pass config object to new writeBytecodeToFile API.
The third argument to writeBytecodeToFile() now takes a
BytecodeWriterConfig object instead of just the producer string.
* Bump llvm to 13f1bc41888e7d6555c532ba5fa925b9fe3e6b2f.
This is a fairly straight-forward transformation since the brunt of the
work of detecting which values will be registered in a given pipeline
stage has already been performed by a prior pass.
This pass simply elaborates the `pipeline.stage.register` operations
into `seq.compreg` operations and stitches up the circuit.
... the long awaited.
This intends to be a mostly boilerplate-y commit for introducing an `hlstool` to circt. The goal is fairly clear - provide a tool which composes the various passes and abstractions in CIRCT which care about high-level design/synthesis.
By doing so, the tool intends to take out the guesswork in terms of how these abstractions are to be composed, as well as when and where to run a pass.
Benefits should be fairly immediate - both in terms of reducing the verbosity of integration tests (many of which currently have to manually describe a fairly long pass pipeline) as well as for newcomers to CIRCT, which can be pointed to a tool/pass pipeline that shows a verified phase ordering of lowering/transformation passes.
As for tests, this commit includes modifications to most of the Handshake integration tests using the 'all' driver.
To replace all tests, a follow-up commit should define how to handle flow-specific arguments to `hlstool`.
These new options support expanded ESI/PyCDE integration tests.
'interactive' runs the python script in the foreground to enable
interactive debugging. 'tmpdir' is generally used for finding the
generated ESI runtime API.
* [FIRRTL] Use BitVector over ArrayRef/SmallVector for eraseArguments.
Upstream MLIR removed an overload of `eraseArguments()` in
27e8ee208cb2142514ee2e3ab342dafaf6374f9e, stating that the overload
isn't useful because we should probably be using BitVector in most
cases.
This mostly affected code in the FIRRTL dialect that used SmallVector
for holding the list of port indices to delete, which indeed can be
replaced with a BitVector.
One thing to be careful about is that while `push_back()` is still
defined on BitVector, it has different behavior than
`SmallVector<unsigned>::push_back()`, in that the former only allows you
to push back a boolean 0 or 1 to the end of the bit vector, while the
latter pushes back an integer index. `BitVector::set()` matches the
previous behavior.
Co-authored-by: Will Dietz <will.dietz@sifive.com>
Endpoint IDs differ by simulator by prefix, wherein the prefix is based
on the top module. Instead of specializing tests to the simulator,
automatically prepend the endpoint ID prefix to endpoint IDs on open
requests.
We have many flags which control whether or not we run a specific pass,
such as `--lower-types`. Most of these flags should never be used by
regular firtool users; they are only really useful for circumventing a
crash in a pass and can often lead to other crashes. This moves most of
the pass options to be of the form `--disable-mypass`, and makes them
hidden by default. The descriptions of these options were made
uniform, at the cost of a less detailed description.
The `GrandCentral` pass was enabled by default. Since its behavior is
controlled by annotations, it should always run.
This also did a small sweep to make sure that all our option
descriptions begin with a capital letter.
This commit adds the `LowerXMR` pass to the firtool pipeline and enables it
by default. This is required since the `LowerToHW` pass cannot handle `RefType`,
so all ops and ports of `RefType` must be removed.
Towards aggregate preservation, this PR disables CheckCombCycles for now
when aggregate preservation is enabled. This should be reverted once CheckCombCycles
pass support aggregate.
Support emitting bytecode via new `-emit-bytecode` flag.
Use the `-f` flag to force printing to terminal.
Also, auto-detect and parse bytecode when passed to stdin.
Bump LLVM and the required updates:
1. Rename getEnclosingAffineForAndIfOps to getEnclosingAffineOps: The utility was extended to also support affine.parallel ops) The commit: llvm/llvm-project@26fedf9
2. Update lit tests to make DefaultValueAttr, not optional! llvm/llvm-project@af3ed4a
3. Move hasValue to has_value
If they happen to call APIs which need some of the shared libraries,
it's important they use the same Python version against which we
compiled those libraries.
* [ExportChiselInterface] Basic infrastructure for Chisel Interface file emission
This commit adds a pass for FIRRTL that generates a Scala file with a module
class that represents the interface for the top module of the FIRRTL circuit.
This is to support the development of separable compilation of FIRRTL circuits.
The details about linking circuits together are to be determined. The generated
Scala module extends ExtModule, although a new module class may be introduced
in the future.
This now tracks when randomized registers exceed a threshold, and
splits them up into multiple registers. This is intended to work
around register size limits in simulators that may be exceeded by
using a single large register to hold all of the random bits for each
module.
This adds a pass that collects all registers in each module, computes
how many bits of random data should be used to initialize them, and
saves this information for each module and register. In FirRegLower,
this is used to create one large random register per module, and
select out the appropriate bits for each register in the initial
block. This ensures the same large random register is created, and the
same bits are always selected for the same register, regardless of
optimizations that may remove registers.
FIRRTLType is still base for all FIRRTL types,
but all current types are now under a new FIRRTLBaseType.
This makes it possible to add new (non-base) types to FIRRTL in the future.
This representation and conversion aren't being used, and never
connected to Verilog output. The newer PipelineWhileOp could subsume
this use-case, and further evolution is coming to this dialect, so it
seems like a good time to clean out the older parts that aren't used.
Motivation:
1. This file is nearing 2000 LOC. I personally find that having a single file per pass helps in quickly navigating to/between implementations of different passes. Bunching everything into one file makes locating things just a bit harder.
2. This is the style used in the remainder of CIRCT.
3. Uses canonical CMake structure for declaring passes.
It is probably fair to conclude that naming this dialect `StaticLogic` has been a pain point for a while. This commit proposes a dialect renaming to `Pipeline`, for a couple of reaons:
1. So far, we've only been working with pipeline abstractions within this dialect.
2. Pipeline representations aren't necessarily statically scheduled - we plan on adding switches to select between latency sensitive and latency insensitive lowerings of pipelines.
This name change does not preclude renamings in the future if we want to fit more stuff into this dialect. Personally, i think it is prudent to maintain a dialect name which reflects what's actually being done within the dialect, as well as the (near/mid/"someone actually intends to work on this"-term) future plans for the dialect.
Primarily:
getValue -> value
hasValue -> has_value
Value accesses not dominated by a presence check use 'value'.
(only use 'operator *' when clearly dominated by check)
"operator bool" and "operator *" used only when meaning was clear
(if variable looks like an integer, like getBitWidth(),
don't use operator bool unless the code already does so;
if returning result of a presence check prefer has_value, etc.)
Few places are slightly simplified, such as: using value_or,
avoiding calling same method for presence check and for the value,
and X.getValue().y -> X->y.
Fixes#3552.
(LLVM will be deprecating the old method names)
Moves Comb to LLVM and HW to LLVM conversions out of the LLHDToLLVM pass and into their own dedicated lowering passes, as proposed in #3539.
The methods convertToLLVMEndianess and llvmIndexOfStructField are also encapsulated here within a HWToLLVMEndianessConverter class, in order to allow easier re-use between different passes.
Apparently using an interface like FModuleLike as the source
for a isa/dyn_cast causes these errors.
Workaround by grabbing the actual operation and checking that.
This commit represents a lowering pass for converting a Calyx control schedule (seq/if/while/enable) into an FSM representation. The FSM is embedded within the Calyx component, and references both the group symbols and cell SSA values.
The lowering method is a fairly straight forward conversion, which leaves plenty of canonicalization opportunities to remove redundant states in the generated FSM. However, doing it as presented in this PR lends itself to some very clean code (which I prefer, rather than prematurely optimizing during lowering) as well as meaningful naming of states (which i think is fairly important).
Cull unnecessary dependences. Reduces the number of files which need to
be compiled for check-circt by ~20%. Compiles and links fine on my machine,
but we've had linking issues in the past, so this may be bumpy.
This adds an option to `firtool` to specify the optimizations at a large
granularity, with two `release` and `debug`. Right now, this just
customizes the value preservation flag. The use of a hook allows these
options to compose sensibly with the finer grained options, s the last
command line option specified overrides previous settings.
This PR modifies LowerTypes to specify types preserved by aggregate preservation, i.e. `-preserve-aggregate={none, 1d-vec, vec, all}`.
Implementation wise, `peelType` takes the enum and selectively lower types.
This commit adds an option `emit-chisel-asserts-as-sva` to emit chisel
asserts as SVA assertions at LowerToHW. Users sometimes want to emit
only SVA for verification purpose and therefore, this commit provides a
command line option to emit "ifElseFatal" style assertion as SVA.
Ensure the passes we use are registered before parsing the command line
options, so that options such as `--mlir-print-ir-before=` work.
Add test.
It would be better if we didn't have to worry about this,
("did we remember to register all the passes" / early loading)
but in the meantime these options are very helpful for debugging
large designs.
Improve the `InstanceStubber` reduction to properly remove modules that
become unused after an instance has been dropped. This now eagerly gets
rid of stubbed-out modules instead of relying on some later
canonicalization and operation pruning to do this.
Add options to set a lower and upper bound on the granularity at which
reductions are applied to operations. The limit can be set based on the
number of operations processed at once, or the number of chunks into
which the input is subdivided. This allows the user to perform coarse
passes over an input before advancing to more fine-grained reductions.
Also properly hides the MLIR/LLVM options from the default help page.
Add a reduction that eagerly inlines modules. This should ideally be run
after the instance stubber and module externalization patterns, to avoid
a huge blow-up of the IR in case modules are multiply instantiated. But
as @darthscsi observed, removing hierarchy usually has a very beneficial
effect on reduceability.
Add a reduction pattern which replaces wires with the connected value.
This tends to be more aggressive than the canonicalizer and happily
nukes wires that may be marked as to be preserved for user inspection.
Improve the progress summary printed by `circt-reduce` by making it
actually end in a newline, adding additional information, and properly
overwriting the previous summary if no other output has been printed in
the meantime.
This implements `-strip-fir-debug-info` option (enabled by default) to drop source locators of fir files
just before ExportVerilog emission. The pass StripDebugInfoWithPred is similar to StripDebugInfo
pass, but StripDebugInfoWithPred selectively strips locations using given predicate.
This change moves more logic related to name preservation into the
DropNames pass. The parser no longer determines if names should be
droppable at parse time, it always creates wires and registers with
`interesting_name`s.
The drop names pass used to unconditionally mark all operation as
"droppable_name"s when run. The `DropNames` pass now takes a parameter
if it should preserve everything, nothing, or only things with meaningful
names.
I think that there is a problem with our current naming of "name
preservation": it is not about whether the "name" is preserved or
dropped, it describes whether a wire or register should be preserved or
dropped. For this reason I think it makes more sense to refer to it as
"value preservation". As the first step toward moving the focus , I
changed the command line option of `firtool` from `-drop-names` to
`--preserve-values=[none | named | all]`. Alternatives suggestions
welcome!
In the future, I think it would make sense to change the enum attributes
`interesting_name` to `preserved` and `droppable_name` to `droppable`.
This also changes firtool to mark all values droppable by default.
Remove all logic related to handling SubAnnotationAttr inside FIRRTL
Dialect passes, utilities, and tools. This is work towards fully
removing SubAnnotationAttr.
Remove the (now unused) SubAnnotationAttr. This has been, in prior
commits, fully replaced with a "circt.fieldID" field that is added to
annotations which apply only to part of an aggregate. This was done
because "circt.fieldID" is viewed as a lighter weight solution that
avoids the need for constant special casing of different "types" of
annotations, i.e., is this a dictionary or is this a SubAnnotationAttr.
Signed-off-by: Schuyler Eldridge <schuyler.eldridge@sifive.com>
This commit creates a new Attribute `InnerSymAttr` for inner_sym and replaces
the `SymbolNameAttr` with `InnerSymAttr`.
The `InnerSymAttr` contains a single field `StringAttr` for the inner_sym name.
The plan is to extend the `InnerSymAttr` to specify symbols per field of an
aggregate type, and also specify public/private visibility for each symbol.
Every `FIRRTLOp` that has the `InnerSym` trait, now has the `InnerSymAttr`
attribute. Also update the builders to either take the new attribute or
convert a `StringAttr` to `InnerSymAttr`
Majority of the changes in this commit is to create an `InnerSymAttr`
from a `StringAttr`.
This pass performs inter-module liveness anaysis and deletes dead code
aggressively. A value is considered as alive if it is connected to a port
of public modules or a value with a symbol. We first populate alive values
into a set, and then propagate the liveness by looking at their dataflow.
The framework is almost same as IMCP except that lattice has two states
(knownAlive, assumedDead) and direction of propagation is opposite.
Writing failing tests for PyCDE code gets cumbersome, quickly, without --split-input-file behaviour like we're used to in opt tools.
This commit adds a small python script which splits an input file based on a split token (# -----) and executes each split separately, catching any exceptions which might be thrown.
Middle-end passes might introduce operations with interesting names so this
commit adds another instance of DropNamesPass so that we can clean up them.
This commit adds a pass `DropNamesPass` to change names to droppable
in order to disable name preservation. The pass walks `FNamableOp` and
drop their names. This pass should be executed in the very early pipeline
so that other passes can get more freedom about their names.
This PR adds NameKindAttr to explicitly represent name preservations of node, wire and register ops. Previously, `name` is directly used to represent the preservation kind (useless or interesting name) but it would be nicer to have the information explicitly, considering that name attributes are used as SSA names too. NameKindEnum has two elements, `InterestingName` and `DroppableName`. `InterestingName` must be preserved.
Example:
```scala
circuit Foo:
module Foo:
input a: UInt<1>
node b = a
node _c = a
```
Parse only output:
```mlir
firrtl.module @Foo(in %a: !firrtl.uint<1>) {
%b = firrtl.node %a : !firrtl.uint<1>
// same as %b = firrtl.node interesting_name %a: !firrtl.uint<1>
%_c = firrtl.node droppable_name %a : !firrtl.uint<1>
}
```
This adds the `firrtl-` prefix to the beginning of the command line
option for this pass, so that we keep our dialect passes namespaced.
I found the use of capital letters in the command line option to be a
unconventional, so I spread it out to the significantly longer
`firrtl-mem-to-reg-of-vec`. In the future maybe we can think about
renaming this pass.
The `BlackBoxMemory` pass was an earlier implementation of SFC's
`ReplaceMemMacros` and has since been totally superseded by the newer
`LowerMemory` pass.
Due some hasty changes when we realized that `MemToRegOfVec` transform
should not lower all memories, we started blackboxing seq mems which
we shouldn't be. We need to make sure that the `LowerMemory` pass is
gated on the `repl-seq-mem` flag in firtool, which will allow SRAMs to
be lowered to generated memory modules instead of blackboxes.
* [FIRRTL] basic support for subcircuit signal driving flows
This is handled with a two-step flow:
* main.fir + subCircuit.json --(firtool)--> (normal output) + sigdrive.json (new)
* subcircuit.fir + sigdrive.json --(firtool)--> (normal output)
The new test in 'subcircuit-flow' demonstrates this in action.
There are many limitations, this is meant to just be enough to
support some specific existing use cases only.
See PR for more details.
Change firtool to always run LowerAnnotations. Remove the "--new-anno"
option to conditionally run LowerAnnotations.
Move all logic related to Grand Central (GCT) view annotation scattering
from FIRAnnotations into the LowerAnnotations pass. In this commit
there are difficult to spot changes to parseAugmentedType and
applyGCTView functions (where the latter is extracted from the body of a
method inside FIRAnnotations):
1. Functions now use ApplyState instead of parameters passed to the
functions.
2. Any scattered annotations are handled by using ApplyState's ability
to add annotations to the worklist. E.g., parseAugmentedType will add a
new annotation to the worklist for every ground type leaf.
Co-authored-by: Will Dietz <will.dietz@sifive.com>
Signed-off-by: Schuyler Eldridge <schuyler.eldridge@sifive.com>
This PR adds a functionality to include build information in output files.
The format of the version string is `<releases tag name>-
<how many commits since the tag>-g(means git)<current commit hash>[-dirty]`
Two cmake flags are added to control version strings,
`CIRCT_RELEASE_TAG_ENABLED` (default is On) and
`CIRCT_RELEASE_TAG` (default is `circtorg`).
If `CIRCT_RELEASE_TAG_ENABLED` is false, the version string becomes
"unknown" and cmake script is ran only at the first cmake configuration. Example,
```
$ cmake .. -DCIRCT_RELEASE_TAG=pycde
// Generated by CIRCT pycde-0.0.5-28-ge846cf26e
module Bar(
$ cmake .. -DCIRCT_RELEASE_TAG=sifive
// Generated by CIRCT sifive/0/9/0-31-ge846cf26e
module Bar(
$ cmake .. -DCIRCT_RELEASE_TAG_ENABLED=Off
// Generated by CIRCT unknown git version
```
Co-authored-by: Hideto Ueno <uenoku.tokotoko@gmail.com>
Moved the definiton of `Seq` passes to a separate `SeqPasses.h`, similarly to other dialects.
Exposed the `createSeqLowerToSV` function to be used by other clients.
* [FIRRTL] Remove all-or-nothing LowerAnnos
Change the behavior of the LowerAnnos pass to work with existing
annotation scattering. Previously, use of the `--new-anno` firtool
flag (and backing FIRParser option) would cause ONLY the LowerAnnos pass
to be used. This changes that to use normal scattering and then apply
LowerAnnos. This is done to enable piecemeal migration of scattering
work into LowerAnnos.
* [FIRRTL] Make LowerAnnos search non-standard attr
Change the LowerAnnotations pass to only process annotations from a
non-standard attribute on the circuit with key
"annotationsForLowerAnnotations". This is done to enable the
LowerAnnotations pass to be run _after_ normal annotation processing
inside FIRAnnotations and FIRParser. This then enables us to migrate
annotations one-by-one from FIRAnnotation/FIRParser handling (by moving
the annotation into "annotationsForLowerAnnotations"). This commit does
not put any annotations into this area for processing. That will be
handled by subsequent commits.
* [FIRRTL] Add LowerAnnos passthrough in Parser
Modify the FIRRTL parser to let annotations that come in with the key
"annotationsForLowerAnnotations" to be placed in an attribute on the
circuit with this key. This is currently unused infrastructure that
lets annotations inside FIRAnnotations be put behind this key to let
them be handled by the LowerAnnos pass.
* [FIRRTL] Add isAnnoClassLowered util, NFC
Add a utility, isAnnoClassLowered, that returns true if an annotation
class name is known to be handled by the LowerAnnotations pass. This
effectively leaks internal information from the LowerAnnotations-defined
table of known annotations to let parsing/scattering logic know that
these annotations will be handled later.
* [FIRRTL] Skip LowerAnnos Annos During Parsing
Modify the Annotation parser to NOT handle annotations that are known to
LowerAnnotations. This is done to enable seamless migration from
annotation handling in the parser to annotation handling in
LowerAnnotations.
Signed-off-by: Schuyler Eldridge <schuyler.eldridge@sifive.com>
The metadata for seq_mems.json needs to be created before extract
instances runs, since it needs the original paths to the memory
operations.
This PR reverts the recent improvement to metadata emission, which used
symbols to ensure that the metadata reflected changes in the hierarchy.
It also modified the CreateSiFiveMetadata to pass to be able to run
before BlackBoxMemory. This just involved adding one extra annotation
to the list of known BlackBoxReader annotations.
Eventually, we will be getting rid of this particular piece of metadata, and
replacing it with OM.
Run the MemToRegofVec transformation only on DUT memories and ignore any
modules in the testbench. Also retain MemOps marked with
`ExcludeMemFromMemToRegOfVec` annotation.
LowerMemory pass should not error out on CombMems, but just retain them to be
lowered by HWMemSimImpl to registers.
This changes the memory-related metadata emitted by this pass to be
created from FMemModules instead of MemOps. The memories will have
already been lowered into modules. The pass can be simplified because
it no longer has to worry about deduplicating the memories itself.
Initial implementation of LLVM graph traits for an FSM machine operation. This will most likely be a useful piece of code for building further transformations, visualizations, ... upon.
This commit adds the MemToRegOfVec transformation to the FIRRTL pipeline.
This transformation converts all comb memories, to registers.
The mem tap and Async reset transformation are also updated to align
with this transformation.
(More details in the updated FIRRTL doc)
This transformation is enabled by default.
This adds a new FIRRTL transformation which looks for
`AddSeqMemPortsAnnotation` and attaches the extra port specified to all
SRAMs under the DUT. The extra ports are always of type UInt<> with a
user specified width. The extra ports are wired up through the top of
the DUT and tied off to 0 in the testharness.
This pass requires that memories have been lowered to modules, and will
emit an error if it finds a regular mem op in the module. This is
because it is not possible to add arbitrary ports to a `mem` op that don't
match the schema of a memory `r`/`w`/`rw` port.
This commit introduces tuple types to the handshake runner. Tuple values
are represented as vectors of values.
Tuples can be feed to the handshake runner by using the `"(val1, ...,
valN)"` syntax.
This works similarly to output-omir: if specified, the final MLIR is
written into this file. This is useful to get the final MLIR output
alongside some other output, especially split-verilog.
This would close https://github.com/llvm/circt/issues/2946.
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.
This commit moves the ExtractInstances pass before the GCT passes.
GCT passes can embed the instance paths into Verbatim ops, which can later be
updated by the ExtractInstances pass, causing incorrect instance paths being
generated into the verilog.
This commit should fix that bug with invalid instance paths.
Add a `ExtractInstances` pass which implements a combined version of the
Scala `ExtractBlackBoxes`, `ExtractClockGates`, and `ExtractSeqMems`
passes. The pass is split into two phases:
As a first step it traverses modules and instances in the design and
marks the ones appropriately annotated for extraction.
In a second step it repeatedly pushes the marked instances up one level
of the hierarchy until they reach the desired parent module (usually
indicated with a `MarkDUTAnnotation`). The extracted instances are then
optionally grouped into a submodule at their extracted location. Finally
the pass also emits a text file indicating where the extracted instances
were originally located in the design.
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>
Change RemoveInvalid pass (yet again) to be called SFCCompat. This
better reflects that this pass is currently and will be later changed to
be where SFC compatible modifications or checks live.
Signed-off-by: Schuyler Eldridge <schuyler.eldridge@sifive.com>
* circt-reduce: cleanup --help output, put options in category
Hides unrelated options from LLVM+co, and makes it easier
to find the most relevant options at glance.
When building CIRCT against LLVM built as shared libraries
(as preferred by many Linux distributions) this greatly
reduces the number of options printed.
* firtool: cleanup --help output, put options in category
Hides unrelated options from LLVM+co, and makes it easier
to find the most relevant options at glance.
When building CIRCT against LLVM built as shared libraries
(as preferred by many Linux distributions) this greatly
reduces the number of options printed.
* llhd-sim: group llhd-sim options in --help output
Hides unrelated options from LLVM+co, and makes it easier
to find the most relevant options at glance.
When building CIRCT against LLVM built as shared libraries
(as preferred by many Linux distributions) this greatly
reduces the number of options printed.
Even for the statically linked version more commonly used
with CIRCT, the help output is significantly reduced.
* llhd-sim: touchup optimizationLevel cl::opt to be static (NFCI)
* test/llhd-sim: Add commandline test
* circt-reduce: check categories in help test
* firtool: check categories in help test
* firtool: add new option to mainCategory too