Delayredux
Convert delays into explicit module instances.
This transform eliminates simple delays on continuous assignments
and gate instances by turning them into explicit instances of delay
modules.
Note: esim has no notion of delays and just implements
*vl-1-bit-delay-1* as a simple assignment. Other backend tools, of
course, can treat delays in different ways.
The delayredux transform, vl-design-delayredux, takes two keyword
arguments, :vecp and :state-onlyp, both Boolean values defaulting to
NIL, whose meanings are discussed below.
We only target simple delays like
#5. Our delay modules are based on the *vl-1-bit-delay-1* unless
the :vecp option is set, in which case they are based on N-bit single-tick
delay modules (see vl-make-n-bit-delay-1). We chain these modules in series
to generate modules that produce an arbitrary M-tick delay; see vl-make-n-bit-delay-m.
If the :state-onlyp option is set, then delay modules are only inserted
for assignments and gates annotated with the "VL_STATE_DELAY" attribute;
other delays are just deleted, leaving the assignments or gates delay-free.
The "VL_STATE_DELAY" attribute comes from always-block processing (see vl-design-always-backend); it is applied to tick delays that are used to
implement flop or latch primitives, but not tick delays that merely affect
signal timing within a clock phase. :state-onlyp is therefore useful in
frameworks that are not delay-sensitive, but that make use of the definitions
of VL latch and flop modules rather than considering them to be primitives.
The following explanation applies in cases where the :state-onlyp
option is not set or else the "VL_STATE_DELAY" annotation is present.
For continuous assignments, we basically replace assignments like
assign #5 lhs = rhs;
with an explicit delay module instance and a delay-free assignment,
e.g.,
wire [6:0] tmp; // same width as rhs
VL_7_BIT_DELAY_5 mkdel (tmp, rhs);
assign lhs = tmp;
Why bother with tmp? Couldn't we just write:
VL_7_BIT_DELAY_5 mkdel (lhs, rhs);
instead? That would work when lhs and rhs are the same size, but
using the temporary wire has the nice property that, by just making tmp
the same size as rhs, we can just let the truncation happen in the
assignment as before.
For gate instances, we push the delays onto the inputs, e.g.,
and #3 (o, a, b);
gets rewritten to something like:
wire del_a, del_b;
VL_1_BIT_DELAY_3 mk_del_a (del_a, a);
VL_1_BIT_DELAY_3 mk_del_b (del_b, b);
and (o, del_a, del_b);
We could perhaps instead delay the outputs. But a nice feature of delaying
the inputs is that we can leave the rest of the gate intact. That is, notice
that o above is still being driven directly by the gate, not by some
assignment or generated instance. This means, for instance, that its drive
strength will still be the same, in case some backend cares about those sorts
of things.
We only remove delays from inout-free gates. We do now know what it means
for a gate with inouts to have a delay.
Ordering Notes
This transform must be run after sizing so that we can introduce delay
modules of the appropriate sizes. It also should be run after the always
backend, which can add delays that this transform should process.
We generally want to do this before split. Otherwise, when we see an
assignment like:
assign #1 out = ~in;
We can end up creating:
VL_1_BIT_DELAY_1 mkdel (del, ~in) ;
And the ~in argument isn't split up, which can confuse later transforms
like occform.
Subtopics
- Vl-gatearg-delayredux
- Vl-assign-delayredux
- Remove the delay from an assignment by introducing an explicit delay
module.
- Vl-gatearglist-delayredux
- Vl-gateinst-delayredux
- Vl-module-delayredux
- Vl-simpledelay-p
- Recognize simple delays like #5.
- Vl-modulelist-delayredux-aux
- Vl-gateinstlist-delayredux
- Vl-assignlist-delayredux
- Vl-modulelist-delayredux
- Vl-gateargs-ok-for-delayredux-p
- (vl-gateargs-ok-for-delayredux-p x) recognizes lists where every element satisfies vl-gatearg-ok-for-delayredux-p.
- Vl-first-bad-gatearg-for-delayredux
- For error reporting, find an arg that has a problem.
- Vl-design-delayredux
- Vl-why-is-gatearg-bad-for-delayredux
- For error reporting, say what the problem with this bad argument is.
- Vl-gatearg-ok-for-delayredux-p