Pipelines in Verilog
Pipelines in Verilog
Pipelines, queues, and FIFOs are common logic structures which are all related, in the
sense that data moves from one storage location to another synchronously, based on a
strobe signal, usually a clock.
For this discussion, we will talk about a simple pipeline, but the issues covered apply
equally to the other types of structures.
This code works fine. The only potential problem is that out changes value on the clock
edge, so whatever takes it as an input may get the wrong value. A better version would be
to use a non-blocking assign:
always @(posedge clock) begin
out <= pipe[2];
pipe[2] <= pipe[1];
pipe[1] <= in;
end
Note that with the non-blocking assign, the order of the assignment statements is
irrelevent.
An interesting variation is the following:
module pipeline (out, in, clock);
output out;
input in;
reg pipe[1:2];
always @(posedge clock)
{out, pipe[2], pipe[1]} = #d {pipe[2], pipe[1], in};
endmodule
Use of the intra-assignment delay is possible here because there is only one statement in
the always block.
This, however, doesn't work, and it is worth repeating that the source order of the
different always blocks makes no difference. As we have pointed out before, both of the
following alternatives will work.
always@(posedge clock)
out <= pipe2;
always@(posedge clock)
out = #d pipe2;
always@(posedge clock)
pipe2 <= pipe1;
always@(posedge clock)
pipe2 = #d pipe1;
always@(posedge clock)
pipe1 <= in;
always@(posedge clock)
pipe1 = #d in;
Many designers use an intra-assignment delay with a non-blocking assign in this case.
While it works, there is no benefit to doing it, and it is somewhat less efficient than either
of these two methods.
(s1out, in,
clock),
(s2out, s1out, clock),
(out,
s2out, clock);
Of course, this works just like the previous version, and the pipestage module is nothing
more than a D flip-flop.
Notice that there is no need to put a delay on the continuous assignments, because the
delay is done in the pipestage module (using the NBA). Alternatively, one could make
the pipestage delay-less and put a delay on the continuous assignments.
Test Module
module test;
wire out;
reg in, clk;
zero3 z3 (out, in, clk);
initial begin
in = 0;
clk = 0;
forever #5 clk = ~clk;
end
initial begin
$monitor($stime,,"clk: %b
in: %b
out);
#1
end
endmodule
clk);
clk);
clk) ;
clk) in <= ~in;
0;
clk) ;
/*
* parameter 'size' is the width of multiplier/multiplicand;.Application
Notes 10-5
* parameter 'level' is the intended number of stages of the
* pipelined multiplier;
* which is typically the smallest integer greater than or equal
* to base 2 logarithm of 'size'
*/
// pipelined_multiplier