# Stmttemps

Replace if conditions and right-hand sides into temporary
wires.

This is a preprocessing step in synthesizing always blocks. We
expect it to be run only after expressions are sized.

We rewrite statements throughout each flop-like always block, adding
temporary wires for:

- non-trivial conditions of if expressions
- non-sliceable right-hand sides of assignment statements

We don't apply this transform to latch-like blocks, because it would
interfere with our sensitivity-list checking. That is, if our sensitivity list
is something like @(en1 or en2 or d) and we rewrite if (en1 & en2)
... to if (temp_123) ..., we would think the resulting sensitivity list
was incorrect.

Regarding (1), this is mainly an optimization. The idea is that we want to
simplify the condition expressions, since we might end up duplicating them
across many flops. That is, if we have a block like:

always @@(posedge clk)
if (foo1 + foo2 + foo3 + foo4 == 1) begin
a <= b;
c <= d;
end

Then this might lead to flops like:

myflop flop1 (a, (foo1 + foo2 + foo3 + foo4 == 1) ? b : a, clk);
myflop flop2 (c, (foo1 + foo2 + foo3 + foo4 == 1) ? d : c, clk);

And we'll be redundantly synthesizing this complex expression. This
wouldn't necessarily be any kind of problem, but it seems like we can do better
by pulling the combinational logic out of the conditions, e.g.:

wire temp = |( foo1 + foo2 + foo3 + foo4 == 1);
always @(posedge clk)
if (temp) begin
a <= b;
c <= d;
end

When we synthesize this simpler block, we'll avoid introducing the repeated
subexpression. That is, our output will be something like:

wire temp = |( foo1 + foo2 + foo3 + foo4 == 1);
myflop flop1 (a, temp ? b : a, clk);
myflop flop2 (c, temp ? d : c, clk);

Regarding (2), the idea here is that to support blocks that write to
different bits of wires, we may need to split up the right-hand sides. For
instance, if we are trying to synthesize something like:

always @@(posedge clk)
if (cond)
{a[1:0], a[3:2]} <= b1 + b2;
else
a[3:0] <= b1 + b2 + 1;

Then we're basically going to end up dealing with this at the bit level, and
we're going to have to talk about bit 0 of these compound expressions like
b1 + b2. So we will want to be able to split up the right-hand sides we
see. We also split up any wires where the widths of the lhs/rhs don't agree,
so that later transforms just need to deal with compatible assignments.

### Subtopics

- Vl-modulelist-stmttemps
`(vl-modulelist-stmttemps x)` maps vl-module-stmttemps across a list.- Vl-ifstmt-stmttemps
- Introduce temp wires for if-statement conditions.
- Vl-assignstmt-stmttemps
- Introduce temp wires for right-hand sides.
- Vl-stmt-stmttemps
- Apply the stmttemps transform to a statement
- Vl-alwayslist-stmttemps
- Vl-always-stmttemps
- Vl-module-stmttemps
- Vl-design-stmttemps
- Top-level stmttemps transform.