Configurable Pipeline Delays

by GateForge Consulting Ltd.

Here is a configurable "jellybean" module which is quite handy for aligning various computations along a pipeline. It can be trivially configured via parameters, and automatically removes itself if the pipeline depth is set to zero. Another benefit is that you can express that multiple signals travel together by concatenating them at the in/out ports (e.g.: {foo,bar,baz,bob}).

This module also ensures that all pipeline stages are set to zero initially, which helps simulation and matches the expected synthesis behaviour on FPGAs. If you need the pipeline pre-filled with live, operational values, I suggest you hold the downstream circuit in a steady state (e.g.: via no-ops or holding in reset) until the delay line fills up.


// A configurable multi-stage pipeline, with no logic.

module Delay_Line 
#(
    parameter       DEPTH           = 0, 
    parameter       WIDTH           = 0
) 
(
    input   wire                    clock,
    input   wire    [WIDTH-1:0]     in,
    output  reg     [WIDTH-1:0]     out
);
    initial begin
        out = 0;
    end

    generate
        if (DEPTH == 0) begin
            always @(*) begin
                out <= in;
            end
        end
        else begin
            integer i;
            reg [WIDTH-1:0] stage [DEPTH-1:0];

            initial begin
                for(i = 0; i < DEPTH; i = i + 1) begin
                    stage[i] = 0;
                end
            end 

            always @(posedge clock) begin
                stage[0] <= in;
                for(i = 1; i < DEPTH; i = i + 1) begin
                    stage[i] <= stage[i-1];
                end
            end

            always @(*) begin
                out <= stage[DEPTH-1];
            end
        end
    endgenerate
endmodule

However, in the common case where you need to simply register the output of a combinational circuit I prefer the following idiom, placed immediately after a combinational output wire raw, and yielding a final registered output cooked:

reg [WIDTH-1:0] cooked = 0;

always @(posedge clock) begin
    cooked <= raw;
end

fpgacpu.ca