[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

Re: gEDA-user: my first Verilog project



On Feb 10, 2008 1:11 AM, DJ Delorie <dj@xxxxxxxxxxx> wrote:

> > Also note the use of blocking assignments (=), not non-blocking
> > assignments (<=). It is recommended to use blocking assignments for
> > combinatorial blocks and non-blocking assignments for sequential
> > (clocked) blocks.
>
> I tried both, but the way I sequenced the statements, it didn't make a
> difference.

It won't make a difference for synthesis, but it will if you simulate
your design (for any reasonably sized project, you should).
for clocked constructs, "<=" is a must:

always @(posedge clk)
begin
  pipe1 <= your_input;
  pipe2 <= pipe1;
  pipe3 <= pipe2;
  your_output <= pipe3;
end

This will give you the expected 4 clock cycle delay, but if you will do:

always @(posedge clk)
begin
  pipe1 = your_input;
  pipe2 = pipe1;
  pipe3 = pipe2;
  your_output = pipe3;
end

The assignments's value will be available immediately, yielding only
one clock delay.
However, if you reorder the statements:

always @(posedge clk)
begin
  your_output = pipe3;
  pipe3 = pipe2;
  pipe2 = pipe1;
  pipe1 = your_input;
end

You will get the same 4 clock cycle delay as the non-blocking assignments.

Things gets interesting when you have multiple always blocks:

always @(posedge clk)
  your_output = pipe3;
always @(posedge clk)
  pipe3 = pipe2;
always @(posedge clk)
  pipe2 = pipe1;
always @(posedge clk)
  pipe1 = your_input;

The code above have no defined behavior and will show different
results under different simulators, and will change when you reorder
the always blocks above.

the following code, however:

always @(posedge clk)
  your_output <= pipe3;
always @(posedge clk)
  pipe3 <= pipe2;
always @(posedge clk)
  pipe2 <= pipe1;
always @(posedge clk)
  pipe1 <= your_input;

Will always yield a 4 cycle delay, no matter how you reorder the
always blocks above.

As for blocking assignments, they are used in combinatorial blocks:

wire [15:0]vect;
reg [4:0]count;
integer i;
always @(*)
begin
  count = 4'b0;
  for (i =0 ; i < 16; i = i + 1)
    count = count + {3'b0, vect[i]};
end

The code above is an inefficient but correct way to count the number
of 1's in the input vector. This would not work if non-blocking
assignments were used.

Udi


_______________________________________________
geda-user mailing list
geda-user@xxxxxxxxxxxxxx
http://www.seul.org/cgi-bin/mailman/listinfo/geda-user