I am having a really hard time to understand where to use blocking and non-blocking assignments. I have read many answers regarding this on this site and have also referred to book on Verilog by "Samir Palnitkar". But when I sit to actually implement some circuit, I am not able to decide which one to use.
I have following questions regarding this:
a) In a sequential circuit, say Synchronous 4-bit counter implemented using JK flip-flops, we need to use two & gates and the output of one & gate is used as the input of the other. Now, I follow the thumb rule that I should use <= for sequential circuts and should not mix = and <= assignments in an @always block.
always @(posedge clk or posedge rst)
begin
if(en)
begin
if(rst)
q<=4'b0000;
else
begin
q[0]<=(~q[0]);
if(q[0]==1)
q[1]<=(~q[1]);
if(q[0]&q[1]==1)
q[2]<=~q[2];
if(q[0]&q[1]&q[2]==1)
q[3]=~q[3];
end
end
end
In the above code for the same circuit, what if I want to store the o/p of q[0]&q[1] in another register and then use it to find q[0]&q[1]&q[2]? If I use <=, I may end up getting wrong value of q[0]&q[1]&q[2].
How should I store the intermediate outputs and use them as inputs in the sequential circuit (May be needed for complex circuits)?
b) What are some rules/guidlines that I should follow so that I don't encounter some race condition or other undesired o/p from my code?