Timing
Inspired by Filament, logic values in Neo contain timing information to ensure soundness of pipelines. Neo currently supports three types of timings: constant, always, and single cycle. Multi-cycle timings are on the roadmap.
Constant
Immediate values have a constant timing. Since these values never change and are always available, they can be used anywhere, regardless of expected timing.
// If no timing is specified, constant is assumed
logic my_logic: Int(64) = 42#64;
Always
Values that are always available but are not constant have a timing of always, denoted with a *
. Always timed values are useful for forwarding values across stages of a decoupled pipeline, for instance. Often, values have a timing of always but are not necessarily always valid. In this case, they should be wrapped in a Valid
union to ensure correct use.
logic my_logic(*): Valid(Int(64)) = .Valid(a + b);
// a and b must also be always
Single Cycle
Single cycles timings are composed of a trigger and an offset. The trigger represents the event (such as a Decoupled
's ready-valid handshake) that initiates the pipeline, which will propagate into the value offset cycles later.
logic my_logic(t+1): Int(64) = Reg(a + b);
// a and b must have timing of `t` (or be constant or always)