Passes
This document describes the available CIRCT passes and their contracts.
Conversion Passes ¶
-calyx-remove-groups-fsm
: Perform FSM outlining and group removal ¶
This pass will outline the FSM into module scope and replace any SSA value references
from within the FSM body with additional inputs. Given this, the FSM
is instantiated as a fsm.hw_module
operation within the Calyx component.
Using the FSM I/O (which is the group go/done signals), the calyx.group
operations are removed from the component, with the group go and done signals
being wired up to the FSM instance.
Example:
calyx.component {
%reg, ... = calyx.register ... : i1
calyx.wires {
// Groups have explicit done signals, and assignments are not guarded
// by a group go signal.
calyx.group @A {
...
calyx.assign %reg = ...
...
calyx.group_done %foo ? %bar
}
}
calyx.control {
// Machine is defined inside the `calyx.control` operation and references
// SSA values defined outside the machine.
fsm.machine @control(%A_done : i1) -> (%A_go : i1) {
...
%0 = comb.not %reg // reference some SSA value defined outside the machine
...
}
}
}
into
// The machine has been outlined into module scope, and no longer references
// any SSA values defined outside the machine. It is now fully independent
// from any notion of Calyx.
fsm.machine @control(%A_done : i1, %reg : i1) -> (%A_go : i1) {
...
%0 = comb.not %reg // reference some SSA value defined outside the machine
...
}
calyx.component {
%reg, ... = calyx.register ...
// Done signals are now wires
%A_done_in, %A_done_out = calyx.wire : i1
// The FSM is now instantiated as an `fsm.hwinstance` module
%A_go = fsm.hwinstance @control(%A_done_out, %reg) : ...
calyx.wires {
// Groups have been inlined, the group go signal is now a guard for
// all assignments, and `calyx.group_done` operations have been
// replaced by wire assignments.
...
calyx.assign %reg = %A_go ? ...
...
calyx.assign %A_done_in = %foo ? %bar
}
calyx.control {
}
}
-convert-affine-to-loopschedule
: Convert Affine dialect to LoopSchedule scheduled loops ¶
This pass analyzes Affine loops and control flow, creates a Scheduling problem using the Calyx operator library, solves the problem, and lowers the loops to a LoopSchedule.
-convert-comb-to-arith
: Convert combinational ops and constants into arith ops ¶
-convert-fsm-to-sv
: Convert FSM to HW ¶
-convert-hw-to-llhd
: Convert HW to LLHD ¶
This pass translates a HW design into an equivalent structural LLHD description.
-convert-hw-to-llvm
: Convert HW to LLVM ¶
This pass translates HW to LLVM.
-convert-hw-to-systemc
: Convert HW to SystemC ¶
This pass translates a HW design into an equivalent SystemC design.
-convert-llhd-to-llvm
: Convert LLHD to LLVM ¶
This pass translates LLHD to LLVM.
-convert-moore-to-core
: Convert Moore to Core ¶
This pass translates Moore to the core dialects (Comb/HW/LLHD).
-convert-to-arcs
: Outline logic between registers into state transfer arcs ¶
This pass outlines combinational logic between registers into state transfer arc definitions. The the original combinational logic and register is replaced with an arc invocation, where the register is now represented as a latency.
-export-chisel-interface
: Emit a Chisel interface to a FIRRTL circuit ¶
This pass generates a Scala Chisel interface for the top level module of a FIRRTL circuit.
-export-split-chisel-interface
: Emit a Chisel interface to a FIRRTL circuit to a directory of files ¶
This pass generates a Scala Chisel interface for the top level module of a FIRRTL circuit.
Options ¶
-dir-name : Directory to emit into
-export-split-verilog
: Emit the IR to a (System)Verilog directory of files ¶
This pass generates (System)Verilog for the current design, mutating it where necessary to be valid Verilog.
Options ¶
-dir-name : Directory to emit into
-export-verilog
: Emit the IR to a (System)Verilog file ¶
This pass creates empty module bodies for external modules. This is useful for linting to eliminate missing file errors.
-handshake-remove-block-structure
: Remove block structure in Handshake IR ¶
-insert-merge-blocks
: Insert explicit merge blocks ¶
This pass inserts additional merge blocks for each block with more than two successors. A merge block is a block that only contains one operation, a terminator, and has two predecessors. The order successors are merged together mirrors the order different control paths are created. Thus, each block with two successors will have a corresponding merge block.
This pass brings the CFG into a canonical form for further transformations.
Treats loops and sub-CFGs with irregular control flow like single blocks.
-legalize-anon-enums
: Prepare anonymous enumeration types for ExportVerilog ¶
This pass transforms all anonymous enumeration types into typedecls to work around difference in how anonymous enumerations work in SystemVerilog.
-lower-arc-to-llvm
: Lower state transfer arc representation to LLVM ¶
-lower-calyx-to-fsm
: Lower Calyx to FSM ¶
This pass lowers a Calyx control schedule to an FSM representation.
An fsm.machine
operation is nested within the control
region of the Calyx
component. This machine is itself in an intermediate format wherein it has
no I/O ports and solely contains output statements with calyx.enable
s
referencing calyx.group
and transition logic guarded by the SSA values
specified in the source control schedule.
This intermediate state facilitates transformation of the FSM, given that
top-level I/O has yet to be materialized (one input and output per activated
group) as well as guard transition logic (every transition must be guarded
on all groups active within the state having finished). As such, calyx.enable
operations can easily be moved between states without worrying about updating
transition guards while doing so.
Eventually, the FSM must be materialized (materialize I/O ports, remove
calyx.enable
operations in favor of asserting output ports, guarding
transitions by input done
ports) and outlined to a separate module.
-lower-calyx-to-hw
: Lower Calyx to HW ¶
This pass lowers Calyx to HW.
-lower-firrtl-to-hw
: Lower FIRRTL to HW ¶
Lower a module of FIRRTL dialect to the HW dialect family.
Options ¶
-disable-mem-randomization : Disable emission of memory randomization code
-disable-reg-randomization : Disable emission of register randomization code
-warn-on-unprocessed-annotations : Emit warnings on unprocessed annotations during lower-to-hw pass
-emit-chisel-asserts-as-sva : Convert all Chisel asserts to SVA
-add-mux-pragmas : Annotate mux pragmas to multibit mux and subacess results
-lower-handshake-to-dc
: Lower Handshake to DC ¶
Lower Handshake to DC operations.
Currently, a handshake.func
will be converted into a hw.module
. This
is principally an incorrect jump of abstraction - DC does not imply any
RTL/hardware semantics. However, DC does not define a container operation,
and there does not exist an e.g. func.graph_func
which would be a generic
function with graph region behaviour. Thus, for now, we just use hw.module
as a container operation.
-lower-handshake-to-hw
: Lower Handshake to ESI/HW/Comb/Seq ¶
Lower Handshake to ESI/HW/Comb/Seq.
-lower-hwarith-to-hw
: Lower HWArith to HW/Comb ¶
This pass lowers HWArith to HW/Comb.
-lower-loopschedule-to-calyx
: Lower LoopSchedule to Calyx ¶
This pass lowers LoopSchedule to Calyx.
Options ¶
-top-level-function : Identifier of top-level function to be the entry-point component of the Calyx program.
-cider-source-location-metadata : Whether to track source location for the Cider debugger.
-lower-pipeline-to-hw
: Lower Pipeline to HW ¶
This pass lowers pipeline.rtp
operations to HW.
-lower-scf-to-calyx
: Lower SCF/Standard to Calyx ¶
This pass lowers SCF / standard to Calyx.
Options ¶
-top-level-function : Identifier of top-level function to be the entry-point component of the Calyx program.
-cider-source-location-metadata : Whether to track source location for the Cider debugger.
-lower-std-to-handshake
: Lower Standard MLIR into Handshake IR ¶
Options ¶
-source-constants : If true, will connect constants to source operations instead of to the control network. May reduce the size of the final circuit.
-disable-task-pipelining : If true, will disable support for task pipelining. This relaxes the restrictions put on the structure of the input CDFG. Disabling task pipelining may severely reduce kernel II.
-materialize-calyx-to-fsm
: Materializes an FSM embedded inside the control of this Calyx component. ¶
Materializes the FSM in the control of the component. This materializes the
top-level I/O of the FSM to receive group_done
signals as input and
group_go
signals as output, based on the calyx.enable
operations
used within the states of the FSM.
Each transition of the FSM is predicated on the enabled groups within a
state being done, or, for static groups, a separate sub-FSM is instantiated
to await the group finishing.
Given an FSM that enables N unique groups, the top-level FSM will have N+1 in- and output ports, wherein:
- Input # 0 to N-1 are
group_done
signals - Input N is the top-level
go
port - Output 0 to N-1 are
group_go
signals - Output N is the top-level
done
port
-maximize-ssa
: Convert every function in the module into maximal SSA form ¶
Convert the region within every function into maximal SSA form. This ensures that every value used within a block is also defined within the block, making dataflow explicit and removing block dominance-based dataflow semantics. The pass achieves this by adding block arguments wherever necessary to forward values to the block(s) where they are used.
-prepare-for-emission
: Prepare IR for ExportVerilog ¶
This pass runs only PrepareForEmission. It is not necessary for users to run this pass explicitly since ExportVerilog internally runs PrepareForEmission.
-test-apply-lowering-options
: Apply lowering options ¶
This pass allows overriding lowering options. It is intended for test construction.
Options ¶
-options : Lowering Options
Arc Dialect Passes ¶
-arc-add-taps
: Add taps to ports and wires such that they remain observable ¶
Options ¶
-ports : Make module ports observable
-wires : Make wires observable
-named-values : Make values with `sv.namehint` observable
-arc-allocate-state
: Allocate and layout the global simulation state ¶
-arc-canonicalizer
: Simulation centric canonicalizations ¶
Statistics ¶
num-arc-args-removed : Number of arguments removed from DefineOps
-arc-dedup
: Deduplicate identical arc definitions ¶
This pass deduplicates identical arc definitions. If two arcs differ only by constants, the constants are outlined such that the arc can be deduplicated.
-arc-group-resets-and-enables
: Group reset and enable conditions of lowered states ¶
-arc-infer-memories
: Convert FIRRTL_Memory
instances to dedicated memory ops ¶
-arc-infer-state-properties
: Add resets and enables explicitly to the state operations ¶
-arc-inline
: Inline very small arcs ¶
Options ¶
-into-arcs-only : Call operations to inline
-max-body-ops : Max number of non-trivial ops in the region to be inlined
Statistics ¶
inlined-arcs : Arcs inlined at a use site
removed-arcs : Arcs removed after full inlining
trivial-arcs : Arcs with very few ops
single-use-arcs : Arcs with a single use
-arc-inline-modules
: Eagerly inline private modules ¶
This pass eagerly inlines private HW modules into their instantiation sites. After outlining combinational logic and registers into arcs, module bodies become fairly lightweight. Since arc definitions now fulfill the purpose of code reuse by allowing a single definition to be called multiple times, the module hierarchy degenerates into a purely cosmetic construct. At that point it is beneficial to fully flatten the module hierarchy to simplify further analysis and optimization of state transfer arcs.
-arc-isolate-clocks
: Group clocked operations into clock domains ¶
-arc-latency-retiming
: Push latencies through the design ¶
Statistics ¶
num-ops-removed : Number of zero-latency passthrough states removed
latency-units-saved : Number of latency units saved by merging them in a successor state
-arc-legalize-state-update
: Insert temporaries such that state reads don’t see writes ¶
-arc-lower-clocks-to-funcs
: Lower clock trees into functions ¶
-arc-lower-lut
: Lowers arc.lut into a comb and hw only representation. ¶
-arc-lower-state
: Split state into read and write ops grouped by clock tree ¶
-arc-make-tables
: Transform appropriate arc logic into lookup tables ¶
-arc-mux-to-control-flow
: Convert muxes with large independent fan-ins to if-statements ¶
-arc-print-state-info
: Print the state storage layout in JSON format ¶
Options ¶
-state-file : Emit file with state description
-arc-simplify-variadic-ops
: Convert variadic ops into distributed binary ops ¶
Statistics ¶
skipped-multiple-blocks : Ops skipped due to operands in different blocks
simplified : Ops simplified into binary ops
created : Ops created as part of simplification
reordered : Ops where simplification reordered operands
-arc-split-loops
: Split arcs to break zero latency loops ¶
-arc-strip-sv
: Remove SV wire, reg, and assigns ¶
Options ¶
-replace-ext-module-outputs : When enabled replaces all extern module instance outputs with 0 and removes the instances and external modules
Calyx Dialect Passes ¶
-calyx-clk-insertion
: Inserts assignments from component clock to sub-component clock. ¶
-calyx-compile-control
: Generates latency-insensitive finite state machines to realize control. ¶
This pass performs a bottom-up traversal of the control program and does the following:
- For each control statement such as “calyx.seq”, create a new GroupOp to contain all the structure to realize the schedule.
- Implement the schedule by setting the constituent groups’ GoOp and DoneOp.
- Replace the control statement in the control program with the corresponding compilation group.
-calyx-gicm
: Lift group-invariant operations to wire-scope. ¶
This pass performs GICM (group-invariant code motion) of operations which are
deemed to be invariant of the group in which they are placed. In practice,
this amounts to anything which is not a calyx.group_done/assign/group_go
operation. GICM’d operations are lifted to wire-scope.
After GICM, a Calyx component has the following properties:
- No values are being defined within groups (excluding
calyx.group_go
). As such, groups will only contain group-level assignments (calyx.assign/group_done). - Any value referenced by operations within the group may safely be referenced by other groups, or operations in wire scope.
- A group does not define anything structural; it exclusively describes wiring between existing structures.
-calyx-go-insertion
: Insert go signals into the guards of a group’s non-hole assignments ¶
This pass inserts the operation “calyx.group_go” into the guards of all assignments housed in the group, with the exception of the “calyx.group_done” terminator. For example,
Before:
calyx.group @Group1 {
calyx.assign %in = %out1, %guard ? : i8
%done = calyx.group_done %out2 : i1
}
After:
// The `go` assignment takes on an undefined
// value until the Compile Control pass.
%undef = calyx.undef : i1
...
calyx.group @Group1 {
%go = calyx.group_go %undef : i1
%and = comb.and %guard, %go : i1
calyx.assign %in = %out1, %and ? : i8
%done = calyx.group_done %out2 : i1
}
-calyx-remove-comb-groups
: Removes combinational groups from a Calyx component. ¶
Transforms combinational groups, which have a constant done condition, into proper groups by registering the values read from the ports of cells used within the combinational group.
It also transforms (invoke,if,while)-with into semantically equivalent control programs that first enable a group that calculates and registers the ports defined by the combinational group execute the respective cond group and then execute the control operator.
Example ¶
group comb_cond<"static"=0> {
lt.right = 32'd10;
lt.left = 32'd1;
eq.right = r.out;
eq.left = x.out;
comb_cond[done] = 1'd1;
}
control {
invoke comp(left = lt.out, ..)(..) with comb_cond;
if lt.out with comb_cond {
...
}
while eq.out with comb_cond {
...
}
}
into:
group comb_cond<"static"=1> {
lt.right = 32'd10;
lt.left = 32'd1;
eq.right = r.out;
eq.left = x.out;
lt_reg.in = lt.out
lt_reg.write_en = 1'd1;
eq_reg.in = eq.out;
eq_reg.write_en = 1'd1;
comb_cond[done] = lt_reg.done & eq_reg.done ? 1'd1;
}
control {
seq {
comb_cond;
invoke comp(left = lt_reg.out, ..)(..);
}
seq {
comb_cond;
if lt_reg.out {
...
}
}
seq {
comb_cond;
while eq_reg.out {
...
comb_cond;
}
}
}
-calyx-remove-groups
: Inlines the groups in a Calyx component. ¶
This pass removes the Group interface from the Calyx program, and inlines all assignments. This is done in the following manner:
- Assign values to the ‘done’ signal of the component, corresponding with the top-level control group’s DoneOp. Add the ‘go’ signal of the component to all assignments.
- TODO(Calyx): If there are multiple writes to a signal, replace the reads with the disjunction.
- Remove all groups.
-calyx-reset-insertion
: Connect component reset to sub-component reset for applicable components. ¶
ESI Dialect Passes ¶
-esi-clean-metadata
: Clean up ESI service metadata ¶
-esi-connect-services
: Connect up ESI service requests to service providers ¶
-esi-emit-collateral
: Emit all the neccessary collateral ¶
Options ¶
-schema-file : File to output capnp schema into
-tops : List of top modules to export Tcl for
-esi-emit-cpp-api
: Add C++ cosimulation API to the module ¶
Options ¶
-output-file : File to output C++ API into
-to-stderr : If true, will emit the generated API to stderr
-lower-esi-ports
: Lower ESI input and/or output ports. ¶
-lower-esi-to-hw
: Lower ESI to HW where possible and SV elsewhere. ¶
-lower-esi-to-physical
: Lower ESI abstract Ops to ESI physical ops. ¶
-lower-esi-types
: Lower ESI high level types. ¶
FIRRTL Dialect Passes ¶
-firrtl-add-seqmem-ports
: Add extra ports to memory modules ¶
This pass looks for AddSeqMemPortAnnotation
annotations and adds extra
ports to memories. It will emit metadata based if the
AddSeqMemPortsFileAnnotation
annotation is specified.
This pass requires that FIRRTL MemOps have been lowered to modules to add the extra ports.
Statistics ¶
num-added-ports : Number of extra ports added
-firrtl-blackbox-reader
: Load source files for black boxes into the IR ¶
This pass reads the Verilog source files for black boxes and adds them as
sv.verbatim.file
operations into the IR. Later passes can then write
these files back to disk to ensure that they can be accessed by other tools
down the line in a well-known location. Supports inline and path
annotations for black box source files.
The supported firrtl.circuit
annotations are:
{class = "firrtl.transforms.BlackBoxTargetDirAnno", targetDir = "..."}
Overrides the target directory into which black box source files are emitted.{class = "firrtl.transforms.BlackBoxResourceFileNameAnno", resourceFileName = "xyz.f"}
Specifies the output file name for the list of black box source files that is generated as a collateral of the pass.
The supported firrtl.extmodule
annotations are:
Specifies the black box source code ({ class = "firrtl.transforms.BlackBoxInlineAnno", name = "myfile.v", text = "..." }
text
) inline. Generates a file with the givenname
in the target directory.
Specifies the file{ class = "firrtl.transforms.BlackBoxPathAnno", path = "myfile.v" }
path
as source code for the module. Copies the file to the target directory.
Options ¶
-input-prefix : Prefix for input paths in black box annotations. This should be the directory where the input file was located, to allow for annotations relative to the input file.
-firrtl-check-comb-cycles
: Check combinational cycles and emit errors ¶
This pass checks combinational cycles in the IR and emit errors.
Options ¶
-print-simple-cycle : Print a simple cycle instead of printing all operations in SCC
-firrtl-check-comb-loops
: Check combinational cycles and emit errors ¶
This pass checks combinational cycles in the IR and emit errors.
-firrtl-dedup
: Deduplicate modules which are structurally equivalent ¶
This pass detects modules which are structurally equivalent and removes the duplicate module by replacing all instances of one with the other. Structural equivalence ignores the naming of operations and fields in bundles, and any annotations. Deduplicating a module may cause the result type of instances to change if the field names of a bundle type change. To handle this, the pass will update any bulk-connections so that the correct fields are legally connected. Deduplicated modules will have their annotations merged, which tends to create many non-local annotations.
Statistics ¶
num-erased-modules : Number of modules which were erased by deduplication
-firrtl-dft
: Wires test enables to clock gates for DFT infrastructure ¶
This pass will take a 1-bit signal targeted by
DFTTestModeEnableAnnotation
and wires it to the test_en
port of every
module named EICG_wrapper
. This will create ports in any intermediate
module on the path from the signal to the EICG_wrapper
modules. This
pass is used to enable the “Design For Testing” style of design when the
intermediate modules were not originally built with DFT in mind.
-firrtl-drop-const
: Drop ‘const’ modifier from types ¶
This pass drops the ‘const’ modifier from all types and removes all const-cast ops.
This simplifies downstream passes and folds so that they do not need to take ‘const’ into account.
-firrtl-drop-names
: Drop interesting names ¶
This pass changes names of namable ops to droppable so that we can disable full name preservation. For example, before:
%a = firrtl.node interesting_name %input
after:
%a = firrtl.node droppable_name %input
Options ¶
-preserve-values : specify the values which can be optimized away
Statistics ¶
num-names-dropped : Number of names dropped
num-names-converted : Number of interesting names made droppable
-firrtl-emit-metadata
: Emit metadata of the FIRRTL modules ¶
This pass handles the emission of several different kinds of metadata.
Options ¶
-repl-seq-mem : Lower the seq mem for macro replacement and emit relevant metadata
-repl-seq-mem-circuit : Circuit root for seq mem metadata
-repl-seq-mem-file : File to which emit seq meme metadata
-firrtl-emit-omir
: Emit OMIR annotations ¶
This pass gathers the OMIRAnnotation
s in the design, updates the contained
targets with the trackers that were scattered throughout the design upon
reading the OMIR, and serializes the resulting data into a JSON file.
Options ¶
-file : Output file for the JSON-serialized OMIR data
-firrtl-expand-whens
: Remove all when conditional blocks. ¶
This pass will:
- Resolve last connect semantics.
- Remove all when operations.
When a wire has multiple connections, only the final connection is used, all previous connections are overwritten. When there is a conditional connect, the previous connect is only overwritten when the condition holds:
w <= a
when c :
w <= b
; Equivalent to:
w <= mux(c, b, a)
This pass requires that all connects are expanded.
-firrtl-extract-instances
: Move annotated instances upwards in the module hierarchy ¶
This pass takes instances in the design annotated with one out of a particular set of annotations and pulls them upwards to a location further up in the module hierarchy.
The annotations that control the behaviour of this pass are:
MarkDUTAnnotation
ExtractBlackBoxAnnotation
ExtractClockGatesFileAnnotation
-firrtl-finalize-ir
: Perform final IR mutations after ExportVerilog ¶
This pass finalizes the IR after it has been exported with ExportVerilog, and before firtool emits the final IR. This includes mutations like dropping verbatim ops that represent sideband files and are not required in the IR.
-firrtl-flatten-memory
: Flatten aggregate memory data to a UInt ¶
This pass flattens the aggregate data of memory into a UInt, and inserts appropriate bitcasts to access the data.
Statistics ¶
num-flatten-mems : Number of memories flattened
-firrtl-grand-central
: Remove Grand Central Annotations ¶
Processes annotations associated with SiFive’s Grand Central utility.
Options ¶
-instantiate-companion-only : Instantiate the companion without a bind and drop the interface
Statistics ¶
num-views-created : Number of top-level SystemVerilog interfaces that were created
num-interfaces-created : Number of SystemVerilog interfaces that were created
num-xmrs-created : Number of SystemVerilog XMRs added
num-annotations-removed : Number of annotations removed
-firrtl-imconstprop
: Intermodule constant propagation and dead code elimination ¶
Use optimistic constant propagation to delete ports and unreachable IR.
Statistics ¶
num-folded-op : Number of operations folded
num-erased-op : Number of operations erased
-firrtl-imdeadcodeelim
: Intermodule dead code elimination ¶
This pass performs inter-module liveness analysis 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.
Statistics ¶
num-erased-ops : Number of operations erased
num-erased-modules : Number of modules erased
num-removed-ports : Number of ports erased
-firrtl-infer-resets
: Infer reset synchronicity and add implicit resets ¶
This pass infers whether resets are synchronous or asynchronous, and extends reset-less registers with an asynchronous reset based on the following annotations:
sifive.enterprise.firrtl.FullAsyncResetAnnotation
sifive.enterprise.firrtl.IgnoreFullAsyncResetAnnotation
-firrtl-infer-rw
: Infer the read-write memory port ¶
This pass merges the read and write ports of a memory, using a simple
module-scoped heuristic. The heuristic checks if the read and write enable
conditions are mutually exclusive.
The heuristic tries to break up the read enable and write enable logic into an
AND
expression tree. It then compares the read and write AND
terms,
looking for a situation where the read/write is the complement of the write/read.
Statistics ¶
num-rw-port-mems-inferred : Number of memories inferred to use RW port
-firrtl-infer-widths
: Infer the width of types ¶
This pass infers the widths of all types throughout a FIRRTL module, and emits diagnostics for types that could not be inferred.
-firrtl-inject-dut-hier
: Add a level of hierarchy outside the DUT ¶
This pass takes the DUT (as indicated by the presence of a MarkDUTAnnotation) and moves all the contents of it into a new module insided the DUT named by an InjectDUTHierarchyAnnotation. This pass is intended to be used in conjunction with passes that pull things out of the DUT, e.g., SRAM extraction, to give the extracted modules a new home that is still inside the original DUT.
-firrtl-inliner
: Performs inlining, flattening, and dead module elimination ¶
This inliner pass will inline any instance of module marked as inline, and recursively inline all instances inside of a module marked with flatten. This pass performs renaming of every entity with a name that is inlined by prefixing it with the instance name. This pass also will remove any module which is not reachable from the top level module.
The inline and flatten annotation attributes are attached to module definitions, and they are:
{class = "firrtl.passes.InlineAnnotation"}
{class = "firrtl.transforms.FlattenAnnotation"}
-firrtl-inner-symbol-dce
: Eliminate dead inner symbols ¶
This pass deletes all inner symbols which have no uses. This is necessary to unblock optimizations and removal of the operations which have these unused inner symbols.
Statistics ¶
num-inner-refs-found : Number of inner-refs found
num-inner-sym-found : Number of inner symbols found
num-inner-sym-removed : Number of inner symbols removed
-firrtl-lower-annotations
: Lower FIRRTL annotations to usable entities ¶
Lower FIRRTL annotations to usable forms. FIRRTL annotations are a big bag of semi-structured, irregular JSON. This pass normalizes all supported annotations and annotation paths.
Options ¶
-disable-annotation-classless : Ignore classless annotations.
-disable-annotation-unknown : Ignore unknown annotations.
-no-ref-type-ports : Create normal ports, not ref type ports.
Statistics ¶
num-raw-annos : Number of raw annotations on circuit
num-added-annos : Number of additional annotations
num-annos : Total number of annotations processed
num-unhandled-annos : Number of unhandled annotations
num-reused-hierpath : Number of reused HierPathOp's
-firrtl-lower-chirrtl
: Infer the memory ports of SeqMem and CombMem ¶
This pass finds the CHIRRTL behavioral memories and their ports, and
transforms them into standard FIRRTL memory operations. For each
seqmem
or combmem
, a new memory is created. For every memoryport
operation using a CHIRRTL memory, a memory port is defined on the
new standard memory.
The direction or kind of the port is inferred from how each of the memory
ports is used in the IR. If a memory port is only written to, it becomes
a Write
port. If a memory port is only read from, it become a Read
port. If it is used both ways, it becomes a ReadWrite
port.
Write
, ReadWrite
and combinational Read
ports are disabled by
default, but then enabled when the CHIRRTL memory port is declared.
Sequential Read
ports have more complicated enable inference:
- If a wire or register is used as the index of the memory port, then the memory is enabled whenever a non-invalid value is driven to the address.
- If a node is used as the index of the memory port, then the memory is enabled at the declaration of the node.
- In all other cases, the memory is never enabled.
In the first two cases, they can easily produce a situation where we try to enable the memory before it is even declared. This produces a compilation error.
Statistics ¶
num-created-mems : Number of memories created
num-lowered-mems : Number of memories lowered
num-portless-mems : Number of memories dropped as having no valid ports
-firrtl-lower-intrinsics
: Lower intrinsics ¶
This pass lowers intrinsics encoded as extmodule with annotation and intmodule to their implementation or op.
-firrtl-lower-matches
: Remove all matchs conditional blocks ¶
Lowers FIRRTL match statements in to when statements, which can later be lowered with ExpandWhens.
-firrtl-lower-memory
: Lower memories to generated modules ¶
This pass lowers FIRRTL memory operations to generated modules.
Statistics ¶
num-created-mem-modules : Number of modules created
num-lowered-mems : Number of memories lowered
-firrtl-lower-open-aggs
: Lower ‘Open’ aggregates by splitting out non-hardware elements ¶
This pass lowers aggregates of the more open varieties into their equivalents using only hardware types, by pulling out non-hardware to other locations.
-firrtl-lower-types
: Lower FIRRTL types to ground types ¶
Lower aggregate FIRRTL types to ground types. Memories, ports, wires, etc are split apart by elements of aggregate types. The only aggregate types which exist after this pass are memory ports, though memory data types are split.
Connect and expansion and canonicalization happen in this pass.
Options ¶
-flatten-mem : Concat all elements of the aggregate data into a single element.
-preserve-aggregate : Specify aggregate preservation mode
-preserve-memories : Specify memory preservation mode
-firrtl-lower-xmr
: Lower ref ports to XMR ¶
This pass lowers RefType ops and ports to verbatim encoded XMRs.
-firrtl-mem-to-reg-of-vec
: Convert combinational memories to a vector of registers ¶
This pass generates the logic to implement a memory using Registers.
Options ¶
-repl-seq-mem : Prepare seq mems for macro replacement
-ignore-read-enable-mem : ignore the read enable signal, instead of assigning X on read disable
Statistics ¶
num-converted-mems : Number of memories converted to registers
-firrtl-prefix-modules
: Prefixes names of modules and mems in a hierarchy ¶
This pass looks for modules annotated with the
NestedPrefixModulesAnnotation
and prefixes the names of all modules
instantiated underneath it. If inclusive
is true, it includes the target
module in the renaming. If inclusive
is false, it will only rename
modules instantiated underneath the target module. If a module is required
to have two different prefixes, it will be cloned.
The supported annotation is:
{
class = "sifive.enterprise.firrtl.NestedPrefixModulesAnnotation",
prefix = "MyPrefix_",
inclusive = true
}
-firrtl-print-field-source
: Print field source information. ¶
-firrtl-print-instance-graph
: Print a DOT graph of the module hierarchy. ¶
-firrtl-print-nla-table
: Print the NLA Table. ¶
-firrtl-randomize-register-init
: Randomize register initialization. ¶
This pass eagerly creates large vectors of randomized bits for initializing registers, and marks each register with attributes indicating which bits to read. If the registers survive until LowerToHW, their initialization logic will pick up the correct bits.
This ensures a stable initialization, so registers should always see the same initial value for the same seed, regardless of optimization levels.
-firrtl-register-optimizer
: Optimizer Registers ¶
This pass applies classic FIRRTL register optimizations. These optimizations are isolated to this pass as they can change the visible behavior of the register, especially before reset.
-firrtl-remove-unused-ports
: Remove unused ports ¶
This pass removes unused ports without annotations or symbols. Implementation wise, this pass iterates over the instance graph in a topological order from leaves to the top so that we can remove unused ports optimally.
Statistics ¶
num-removed-ports : Number of ports erased
-firrtl-resolve-traces
: Write out TraceAnnotations to an output annotation file ¶
This pass implements Chisel’s Trace API. It collects all TraceAnnotations that exist in the circuit, updates them with information about the final target in a design, and writes these to an output annotation file. This exists for Chisel users to build tooling around them that needs to query the final output name/path of some component in a Chisel circuit.
Note: this pass and API are expected to be eventually replaced via APIs and language bindings that enable users to directly query the MLIR.
Options ¶
-file : Output file for the JSON-serialized Trace Annotations
-firrtl-sfc-compat
: Perform SFC Compatibility fixes ¶
-firrtl-vb-to-bv
: Transform vector-of-bundles to bundle-of-vectors ¶
This pass converts vectors containing bundles, into bundles containing vectors.
-merge-connections
: Merge field-level connections into full bundle connections ¶
Options ¶
-aggressive-merging : Merge connections even when source values won't be simplified.
-vectorization
: Transform firrtl primitive operations into vector operations ¶
FSM Dialect Passes ¶
-fsm-print-graph
: Print a DOT graph of the module hierarchy. ¶
Handshake Dialect Passes ¶
-handshake-add-ids
: Add an ID to each operation in a handshake function. ¶
This pass adds an ID to each operation in a handshake function. This id can
be used in lowerings facilitate mapping lowered IR back to the handshake code
which it originated from. An ID is unique with respect to other operations
of the same type in the function. The tuple of the operation name and the
operation ID denotes a unique identifier for the operation within the
handshake.func
operation.
-handshake-dematerialize-forks-sinks
: Dematerialize fork and sink operations. ¶
This pass analyses a handshake.func operation and removes all fork and sink operations.
-handshake-insert-buffers
: Insert buffers to break graph cycles ¶
Options ¶
-strategy : Strategy to apply. Possible values are: cycles, allFIFO, all (default)
-buffer-size : Number of slots in each buffer
-handshake-legalize-memrefs
: Memref legalization and lowering pass. ¶
Lowers various memref operations to a state suitable for passing to the StandardToHandshake lowering.
-handshake-lock-functions
: Lock each function to only allow single invocations. ¶
This pass adds a locking mechanism to each handshake function. This mechanism ensures that only one control token can be active in a function at each point in time.
-handshake-lower-extmem-to-hw
: Lowers handshake.extmem and memref inputs to ports. ¶
Lowers handshake.extmem and memref inputs to a hardware-targeting memory accessing scheme (explicit load- and store ports on the top level interface).
Options ¶
-wrap-esi : Create an ESI wrapper for the module. Any extmem will be served by an esi.mem.ram service
-handshake-materialize-forks-sinks
: Materialize fork and sink operations. ¶
This pass analyses a handshake.func operation and inserts fork and sink operations ensuring that all values have exactly one use.
-handshake-op-count
: Count the number of operations (resources) in a handshake function. ¶
This pass analyses a handshake.func operation and prints the number of operations (resources) used the function.
-handshake-print-dot
: Print .dot graph of a handshake function. ¶
This pass analyses a handshake.func operation and prints a .dot graph of the structure. If multiple functions are present in the IR, the top level function will be printed, and called functions will be subgraphs within the main graph.
-handshake-remove-buffers
: Remove buffers from handshake functions. ¶
This pass analyses a handshake.func operation and removes any buffers from the function.
HW Dialect Passes ¶
-hw-flatten-io
: Flattens hw::Structure typed in- and output ports. ¶
Options ¶
-recursive : Recursively flatten nested structs.
-hw-print-instance-graph
: Print a DOT graph of the module hierarchy. ¶
-hw-print-module-graph
: Print a DOT graph of the HWModule’s within a top-level module. ¶
Options ¶
-verbose-edges : Print information on SSA edges (types, operand #, ...)
-hw-specialize
: Specializes instances of parametric hw.modules ¶
Any hw.instance
operation instantiating a parametric hw.module
will
trigger a specialization procedure which resolves all parametric types and
values within the module based on the set of provided parameters to the
hw.instance
operation. This specialized module is created as a new
hw.module
and the referring hw.instance
operation is rewritten to
instantiate the newly specialized module.
LLHD Dialect Passes ¶
-llhd-early-code-motion
: Move side-effect-free instructions and llhd.prb up in the CFG ¶
Moves side-effect-free instructions as far up in the CFG as possible. That
means to the earliest block where all operands are defined. Special care has
to be given to the llhd.prb
instruction (which is the only side-effect
instruction moved by this pass) as it must stay in the same temporal region,
because otherwise it might sample an older or newer state of the signal.
This pass is designed as a preparatory pass for the Temporal Code Motion
pass to be able to move the llhd.drv
operations in a single TR exiting
block without having to move operations defining the operands used by the
llhd.drv
. It also enables total control flow elimination as the llhd.prb
instructions would not be moved by other canonicalization passes.
-llhd-function-elimination
: Deletes all functions. ¶
Deletes all functions in the module. In case there is still a function
call in an entity or process, it fails.
This pass is intended as a post-inlining pass to check if all functions
could be successfully inlined and remove the inlined functions. This
is necessary because Structural LLHD does not allow functions. Fails in
the case that there is still a function call left in a llhd.proc
or
llhd.entity
.
-llhd-memory-to-block-argument
: Promote memory to block arguments. ¶
Promotes memory locations allocated with llhd.var
to block arguments. This
enables other optimizations and is required to be able to lower behavioral
LLHD to structural LLHD. This is because there are no memory model and
control flow in structural LLHD. After executing this pass, the
“-llhd-block-argument-to-mux” pass can be used to convert the block
arguments to multiplexers to enable more control-flow elimination.
Example:
llhd.proc @check_simple(%condsig : !llhd.sig<i1>) -> () {
%c5 = llhd.const 5 : i32
%cond = llhd.prb %condsig : !llhd.sig<i1>
%ptr = llhd.var %c5 : i32
cond_br %cond, ^bb1, ^bb2
^bb1:
%c6 = llhd.const 6 : i32
llhd.store %ptr, %c6 : !llhd.ptr<i32>
br ^bb2
^bb2:
%ld = llhd.load %ptr : !llhd.ptr<i32>
%res = llhd.not %ld : i32
llhd.halt
}
is transformed to
llhd.proc @check_simple(%condsig : !llhd.sig<i1>) -> () {
%c5 = llhd.const 5 : i32
%cond = llhd.prb %condsig : !llhd.sig<i1>
cond_br %cond, ^bb1, ^bb2(%c5 : i32)
^bb1:
%c6 = llhd.const 6 : i32
br ^bb2(%c6 : i32)
^bb2(%arg : i32):
%res = llhd.not %arg : i32
llhd.halt
}
-llhd-process-lowering
: Lowers LLHD Processes to Entities. ¶
TODO
MSFT Dialect Passes ¶
-lower-msft-to-hw
: Lower MSFT ops to hw ops ¶
Options ¶
-verilog-file : File to output Verilog into
-msft-discover-appids
: Discover the appids in a module hierarchy ¶
-msft-export-tcl
: Create tcl ops ¶
Options ¶
-tops : List of top modules to export Tcl for
-tcl-file : File to output Tcl into
-msft-lower-constructs
: Lower high-level constructs ¶
-msft-lower-instances
: Lower dynamic instances ¶
-msft-partition
: Move the entities targeted for a design partition ¶
-msft-wire-cleanup
: Cleanup unnecessary ports and wires ¶
Pipeline Dialect Passes ¶
-pipeline-explicit-regs
: Makes stage registers explicit. ¶
Makes all stage-crossing def-use chains into explicit registers.
-pipeline-schedule-linear
: Schedules a linear pipeline. ¶
Schedules a linear pipeline based on operator latencies.
Seq Dialect Passes ¶
-lower-seq-firrtl-init-to-sv
: Prep the module with macro definitions for firrtl registers. ¶
-lower-seq-firrtl-to-sv
: Lower sequential firrtl ops to SV. ¶
Options ¶
-disable-reg-randomization : Disable emission of register randomization code
-emit-separate-always-blocks : Emit assigments to registers in separate always blocks
Statistics ¶
num-subaccess-restored : Number of lhs subaccess operations restored
-lower-seq-hlmem
: Lowers seq.hlmem operations. ¶
-lower-seq-to-sv
: Lower sequential ops to SV. ¶
Options ¶
-lower-to-always-ff : Place assignments to registers into `always_ff` blocks
SSP Dialect Passes ¶
-ssp-print
: Prints all SSP instances as DOT graphs. ¶
-ssp-roundtrip
: Roundtrips all SSP instances via the scheduling infrastructure ¶
Options ¶
-check : Check the problem's input constraints.
-verify : Verify the problem's solution constraints.
-ssp-schedule
: Schedules all SSP instances. ¶
Options ¶
-scheduler : Scheduling algorithm to use.
-options : Scheduler-specific options.
SV Dialect Passes ¶
-hw-cleanup
: Cleanup transformations for operations in hw.module bodies ¶
This pass merges sv.alwaysff operations with the same condition, sv.ifdef nodes with the same condition, and perform other cleanups for the IR. This is a good thing to run early in the HW/SV pass pipeline to expose opportunities for other simpler passes (like canonicalize).
Options ¶
-merge-always-blocks : Allow always and always_ff blocks to be merged
-hw-export-module-hierarchy
: Export module and instance hierarchy information ¶
This pass exports the module and instance hierarchy tree for each module with the firrtl.moduleHierarchyFile attribute. These are lowered to sv.verbatim ops with the output_file attribute.
Options ¶
-dir-name : Directory to emit into
-hw-generator-callout
: Lower Generator Schema to external module ¶
This pass calls an external program for all the hw.module.generated nodes, following the description in the hw.generator.schema node.
Options ¶
-schema-name : Name of the schema to process
-generator-executable : Generator program executable with optional full path
-generator-executable-arguments : Generator program arguments separated by ;
-hw-legalize-modules
: Eliminate features marked unsupported in LoweringOptions ¶
This pass lowers away features in the SV/Comb/HW dialects that are unsupported by some tools, e.g. multidimensional arrays. This pass is run relatively late in the pipeline in preparation for emission. Any passes run after this must be aware they cannot introduce new invalid constructs.
-hw-memory-sim
: Implement FIRRTMMem memories nodes with simulation model ¶
This pass replaces generated module nodes of type FIRRTLMem with a model suitable for simulation.
Options ¶
-disable-mem-randomization : Disable emission of memory randomization code
-disable-reg-randomization : Disable emission of register randomization code
-repl-seq-mem : Prepare seq mems for macro replacement
-ignore-read-enable : ignore the read enable signal, instead of assigning X on read disable
-add-mux-pragmas : Add mux pragmas to memory reads
-add-vivado-ram-address-conflict-synthesis-bug-workaround : Add a vivado attribute to specify a ram style of an array register
-hw-stub-external-modules
: transform external hw modules to empty hw modules ¶
This pass creates empty module bodies for external modules. This is useful for linting to eliminate missing file errors.
-prettify-verilog
: Transformations to improve quality of ExportVerilog output ¶
This pass contains elective transformations that improve the quality of SystemVerilog generated by the ExportVerilog library. This pass is not compulsory: things that are required for ExportVerilog to be correct should be included as part of the ExportVerilog pass itself to make sure it is self contained.
-sv-extract-test-code
: Extract simulation only constructs to modules and bind ¶
This pass extracts cover, assume, assert operations to a module, along with any ops feeding them only, to modules which are instantiated with a bind statement.
Options ¶
-disable-instance-extraction : Disable extracting instances only that feed test code
-disable-module-inlining : Disable inlining modules that only feed test code
Statistics ¶
num-ops-extracted : Number of ops extracted
num-ops-erased : Number of ops erased
-sv-trace-iverilog
: Add tracing to an iverilog simulated module ¶
This pass adds the necessary instrumentation to a HWModule to trigger tracing in an iverilog simulation.
Options ¶
-top-only : If true, will only add tracing to the top-level module.
-module : Module to trace. If not provided, will trace all modules
-dir-name : Directory to emit into