-2
\$\begingroup\$
always_comb begin

  for (index = 0; index < NUM_REQUESTORS; index++ ) begin

          if (valid[index]) begin

               grant = index;

               break ;

          end

  end

end

My guess is that it will synthesize to a chain of multiplexers as many as NUM_REQUESTORS, with the one closest to grant having select line valid[0]. But surely this can't scale well with large NUM_REQUESTORS. What do you think?

\$\endgroup\$

2 Answers 2

0
\$\begingroup\$

Simply, it won't synthesise.

The break statement in Verilog is for simulation purposes only - i.e for making test benches.

You cannot break out of a for-loop in synthesisable Verilog, simply because the for-loop is not "executed" as a for-loop. It is unrolled by the compiler into hardware. This is why the number of loops must be a known constant at the point of synthesis. You cannot for example synthesise:

for (idx = 0; idx < someVariable; idx = idx + 1) ...

Because just as with a break statement, the number of loops would no longer be known at point of synthesis.


Instead you need to think about this in terms of hardware. What your describing appears to be a priority encoder - it will set grant equal to the lowest index for which valid is a 1. You can achieve this result using a loop without the need for a break statement. If we use blocking assignments, we can do:

grant = 0; //Default value if there are none valid
for (idx = NUM_REQUESTORS; idx > 0; idx = idx - 1) begin
    if (valid[idx-1]) begin
        grant = idx-1;
    end
end

Note that here we are counting down as all loop passes will produce hardware and we want the lowest index to have the highest priority.

This loop will as you suspect unroll into a chain of multiplexers - similar to doing a long if-elseif-else chain. That is the price you pay for priority encoders.


If you don't need priority in your system - say you are simply trying to arbitrate between multiple masters accessing a slave - you can use other arbitration schemes such as round robin. In round robin you would simply have the grant signal being a counter. Each clock cycle the counter would either stay the same if the current master is valid, or increment to the next master if not.

\$\endgroup\$
7
  • \$\begingroup\$ Are you certain about break (and this code in particular) not being synthesizable? \$\endgroup\$
    – frank_010
    Sep 20, 2018 at 10:45
  • 1
    \$\begingroup\$ @frank_010 If you are going to ask "are you certain" then you need to specify which synthesis tools you are using. It's possible that somewhere, someone has written a synthesizer that is smart enough to deal with your code, but I agree with Tom that it's poor HDL style and unlikely to be synthesizable. \$\endgroup\$ Sep 20, 2018 at 11:54
  • \$\begingroup\$ @frank_010 quite certain. \$\endgroup\$ Sep 20, 2018 at 13:48
  • \$\begingroup\$ FYI, this code is from production, synthesized by Synopsis design compiler. And also if you put it through Spyglass it will give it clean chit. \$\endgroup\$
    – frank_010
    Sep 20, 2018 at 16:28
  • \$\begingroup\$ @frank_010 fair enough then. It's obviously smart enough to synthesise it - most compilers won't. It will probably work out that it is a priority encoder and produce a chain of muxes. \$\endgroup\$ Sep 20, 2018 at 17:11
0
\$\begingroup\$

One can easily re-write this without a break statement, a synthesis tool can too.

bit breakout;
always_comb begin
  breakout = 0;
  grant = some_value; // if there is no valid[index]
  for (index = 0; index < NUM_REQUESTORS; index++ ) begin
     if (!breakout)
          if (valid[index] ) begin
               grant = index;
               breakout = 1;
          end
  end
end

This gets unrolled as

grant = valid[0] ? 0 : valid[1] ? 1 : valid[2] ? 2 : ... : some_value
\$\endgroup\$

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.