The process of composing together a netlist of svex assignments into full update functions.

Suppose we have a module with a lot of assignment statements. We want to compose together the RHS expressions in order to get the update formula for each wire, in terms of the PIs and registers.

One basic thing to do is DFS through each of the expressions, building full update formulas. Every time we get to a wire, either it is a PI/register or another internal wire. If it is a PI/register, we leave it; if it's an internal wire, either we've seen it before and computed some formula for it, or we descend into its update formula and compute that first.

Two kinds of problems arise when using this strategy. First, there might be variable-level self-loops, e.g.:

wire [5:0] a = b | (a[4:0] << 1);

Here,

Second, there might be bit-level self-loops. These are bad news but they do sometimes come up, e.g. in latch-based (as opposed to flipflop-based) logic as well as with clock gating where the clock gate signal depends on the output of a register that it gates (depending on how the clock gate is represented in the logic).

To deal with these two problems, we do two further steps after the initial simple DFS composition step; step 2 effectively deals with variable-level self-loops and step 3 deals with bit-level self-loops. The full sequence of steps:

- 1. Simple depth-first search composition, stopping whenever we reach a variable that is still in the stack.
- 2. Iterative self-composition of the remaining signals, using caremasks to
determine when a variable needs to be composed in. This is implemented in as
svex-alist-maskcompose-iter in "mask-compose.lisp". - 3. Break up into bits any remaining internal signals that other signals still depend on, then find strongly-connected components of the bit-level dependency graph and try to self-compose those components enough times to resolve further dependencies. Then translate the decomposed signals back into the original namespace.
- 4. Finally, replace any remaining internal signal dependencies with Xes.

This is implemented

- Svex-compose-assigns-keys
- Compose together svex assignments (using svex-compose-dfs) for the listed keys.
- Svex-compose
- Compose an svex with a substitution alist. Variables not in the substitution are left in place.
- Svex-compose*
- Compose an svex with a substitution alist. Variables not in the substitution are left in place.
- Svex-compose-svstack
- Compose an svex with a substitution alist. Variables not in the substitution are left in place.
- Svex-assigns-compose1
- Given an alist mapping variables to assigned expressions, compose them together into full update functions.
- Svex-assigns-compose
- Given an alist mapping variables to assigned expressions, compose them together into full update functions.
- Svex-compose-bit-sccs
- Svex-compose-assigns
- Compose together an alist of svex assignments, with no unrolling when variables depend on themselves.
- Svex-replace-var
- Replace occurrences of a variable within an svex with an svex.