Expand description
Passes for the Calyx compiler.
Structs
Perform serval canonicalizations on the program.
Given a LiveRangeAnalysis that specifies the “share” and “state_share” cells
alive at each group, minimizes the cells used for each component.
Adds assignments from a components
clk
port to every
component that contains an input clk
port.Collapses and de-nests control constructs.
Propagate unconditional reads and writes from wires.
Compiles
ir::Invoke
statements into an ir::Enable
that runs the
invoked component.Compiles
ir::Invoke
statements into an ir::Enable
that runs the invoked component.Compiles Static Islands
Compiles @sync without use of std_sync_reg
Upon encountering @sync, it first instantiates a std_reg(1) for each thread(
bar
)
and a std_wire(1) for each barrier (s
)
It then continuously assigns the value of (s.in
) to 1’d1 guarded by the
expression that all values of bar
for threads under the barrier are
set to 1’d1
Then it replaces the @sync control operator with
seq {
barrier;
clear;
}
barrier
simply sets the value of bar
to 1’d1 and then waits
for s.out
to be up
clear
resets the value of bar
to 1’d0 for reuse of barrier
Using this method, each thread only incurs 3 cycles of latency overhead for
the barrier, and we theoretically won’t have a limit for number of threads
under one barrierInlines all sub-components marked with the
@inline
attribute.
Cannot inline components when they:Infers
@control
and @data
annotations for cells.
A cell marked with @data
can have 'x
assignments to its @data
ports
which enables downstream optimizations.Removes unused assigns from groups.
Analyzes the writes to combinational cells in groups
In order for a combinational cell to be considered “used”, it must:
Removes unused cells from components.
Removes unused groups and combinational groups from components.
A group is considered in use when it shows up in an ir::Enable.
A combinational group is considered in use when it is a part of an
ir::If or ir::While or ir::Invoke.
Adds default assignments to all non-
@data
ports of an instance.A pass to detect cells that have been inlined into the top-level component
and turn them into real cells marked with ir::BoolAttr::External.
Turns memory cell primitives with the
@external(1)
attribute into
ref
memory cells without the @external
attribute.Externalize input/output ports for cells marked with the
@external(1)
attribute.
The ports of these cells are exposed through the ports of the parent
component.Add the group’s
go
signal into the guards of all non-hole assignments
of this group.Transform groups that are structurally invoking components into equivalent
ir::Invoke statements.
Transforms a group into a seq of 2 smaller groups, if possible.
Currently, in order for a group to be transformed must
Removes all groups and inlines reads and writes from holes.
This pass checks if components are (state) shareable. Here is the process it
goes through: if a component uses any ref cells, or non-shareable cells then it
is automatically not shareable. Otherwise, check if each read of a stateful
cell is guaranteed to be dominated by a write to the same cell– we check this
by building a domination map. If so, component is state shareable.
Lowers guards into a purely structural representation. After this pass,
all guards are guaranteed to be either ir::Guard::True or ir::Guard::Port.
Merge assignments of the form with the same (dst_port, src_port) pairs.
Pass to check for common errors such as missing assignments to
done
holes
of groups.Transforms all
par
into seq
. Uses analysis::ControlOrder to get a
sequentialization of par
such that the program still computes the same
value. When there is no such sequentialization, errors out.Unsharing registers reduces the amount of multiplexers used in the final design, trading them
off for more memory.
Removes NODE_ID, BEGIN_ID, and END_ID from each control statement
Adds assignments from a components
reset
port to every
component that contains an input reset
port.Simplifies Static Guards
In particular if g = g1 & g2 & …gn, then it takes all of the g_i’s that
are “static timing intervals”, e.g., %[2:3], and combines them into one
timing interval.
For example: (port.out | !port1.out) & (port2.out == port3.out) & %[2:8] & %[5:10] ?
becomes (port.out | !port1.out) & (port2.out == port3.out) & %[5:8] ?
by “combining” %[2:8] & %[5:10]
Transforms combinational groups into normal groups by registering the values
read from the ports of cells used within the combinational group.
Infer @promotable annotation
for groups and control.
Inference occurs whenever possible.
Promote control to static when (conservatively) possible, using @promote_static
annotations from
infer_static
.Pass to check common synthesis issues.
Core lowering pass.
Compiles away the control programs in components into purely structural code using an
finite-state machine (FSM).
Fully unroll all
while
loops with a given @bound
.Pass to check if the program is well-formed.
Alternate hole inliner that removes groups and group holes by instantiating
wires that hold the value for each signal.
If the top-level component is not named
main
, adds a new main
component
and makes it the top-level component.
This is useful because a lot of our tools rely on the name main
being the design under test (DUT).