1
\$\begingroup\$

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?

\$\endgroup\$
1

1 Answer 1

1
\$\begingroup\$

You are not understanding the rule correctly. You must not mix = and <= to the same variable within an always block.

And yes, generally you should use non-blocking <= assignments to sequential logic. You must us a non-blocking assignment if one always @(posedge clock) block writes, and another always @(posedge clock) reads the same variable, or combinatorial expression of the same variable).

The synthesis tool makes the variable sequential if one of the following is true:

  1. The variable is written with a non-blocking assignment <=
  2. The variable is read before written within the block
  3. The variable is read somewhere else outside the block

Otherwise it becomes combinational logic.

\$\endgroup\$
2
  • \$\begingroup\$ Thanks, got it. One more thing, should I always put the combinational part in one block and the sequential part in the other block, so that it's easy to understand the code? \$\endgroup\$ Oct 21, 2019 at 15:26
  • \$\begingroup\$ That is another frequently asked question with highly opinionated answers. Many people do choose to separate the block to avoid any possible confusion. \$\endgroup\$
    – dave_59
    Oct 21, 2019 at 15:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.