Pipelines data words through a number of register stages. Common uses include pipeline alignment, and pipelining inputs so the registers can retime forward into logic to allow a faster clock.
This module is a simplification of the Register
Pipeline, which allows parallel input/output and
initial values other than zero, but does not support a PIPE_DEPTH
of
zero like this one.
Each cycle clock_enable
is high, the pipeline shifts by one from
pipe_in
towards pipe_out
. clear
sets all registers to zero. If
PIPE_DEPTH
is zero, pipe_in
becomes directly wired to pipe_out
and no
logic is inferred.
`default_nettype none module Register_Pipeline_Simple #( parameter WORD_WIDTH = 0, parameter PIPE_DEPTH = -1 ) ( // If PIPE_DEPTH is zero, these are unused // verilator lint_off UNUSED input wire clock, input wire clock_enable, input wire clear, // verilator lint_on UNUSED input wire [WORD_WIDTH-1:0] pipe_in, output reg [WORD_WIDTH-1:0] pipe_out ); localparam WORD_ZERO = {WORD_WIDTH{1'b0}}; initial begin pipe_out = WORD_ZERO; end genvar i; generate if (PIPE_DEPTH == 0) begin always @(*) begin pipe_out = pipe_in; end end else if (PIPE_DEPTH > 0) begin
We strip out first iteration of Register instantiations to avoid having to
refer to index -1 in the generate loop, and also to connect to pipe_in
rather than the output of a previous register.
wire [WORD_WIDTH-1:0] pipe [PIPE_DEPTH-1:0]; Register #( .WORD_WIDTH (WORD_WIDTH), .RESET_VALUE (WORD_ZERO) ) input_stage ( .clock (clock), .clock_enable (clock_enable), .clear (clear), .data_in (pipe_in), .data_out (pipe[0]) );
Now repeat over the remainder of the pipeline stages, starting at stage 1, connecting each pipeline stage to the output of the previous pipeline stage.
for (i=1; i < PIPE_DEPTH; i=i+1) begin: pipe_stages Register #( .WORD_WIDTH (WORD_WIDTH), .RESET_VALUE (WORD_ZERO) ) pipe_stage ( .clock (clock), .clock_enable (clock_enable), .clear (clear), .data_in (pipe[i-1]), .data_out (pipe[i]) ); end
And finally, connect the output of the last register to the module pipe output.
always @(*) begin pipe_out = pipe[PIPE_DEPTH-1]; end end endgenerate endmodule