What does the following Verilog code realize

verilog

I was learning verilog hardware description language. I was confused a bit with the blocking and non-blocking statements. Can someone tell me what the following verilog codes realize and simple hints how

always@(posedge clk)
begin
   q1=d;
   q2<=q1;
   q3=q2;
end

always@(posedge clk)
begin
   q1<=d;
   q2<=q1;
   q3=q2;
end

These are two different codes implemented separately. I think FF comes into the picture because of edge detection. But I don't understand what it realizes as it has a intermix of blocking and non-blocking statements

Best Answer

Let's start with d=0 q1=1 q2=2 q3=3.

always@(posedge clk)
begin
   q1=d;

q1 immediately gets the value of d=0.

   q2<=q1;

Non-blocking assignment: save the current value of q1 (which is currently the same as d=0)

   q3=q2;

q3 gets the unchanged value of q2, =2

end

At this point the nonblocking assignment happens and q2 gets the value 0.

I'm assuming the next always block is in a different module; putting it in the same module will just cause further confusion as you're overwriting the same variables again.

Start with d=0 q1=1 q2=2 q3=3 again.

always@(posedge clk)
begin
   q1<=d;
   q2<=q1;

Queue assignment of q1 to 0 and q2 to 1. These happen at the end of the block.

   q3=q2;

Set q3 to the current value of q2, ie 2.

end

Finally set q1=0 and q2=1.

Generally it's bad style to mix = and <= in the same block, and generally for synthesis you should always use <=. '=' can be helpful in testbenches where it behaves more like a conventional imperative programming language.