Skip to content

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.

neo
// 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.

neo
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.

neo
logic my_logic(t+1): Int(64) = Reg(a + b);
// a and b must have timing of `t` (or be constant or always)