views:

451

answers:

3

I've gotten in the habit of developing a lot testbenches and use for() and while() loops for testing purpose. Thats fine. The problem is that I've taken this habit over to coding for circuits which should be synthesizable. XST and others refuse to synthesize code (without additional modification to synthesis parameters) such as:

while (num < test_number) 
     begin 
     . 
     . 
     . 
     num = num+1; 
     end

This is bad coding style because to the synthesizer test_num is an int with value 2^32! or it sees it as unbounded parameter. Either way, its a bad coding habit. But I'm so used to doing this in C and testbenches. What would be the equivalent synthesizable of code of the above code segment?

Thanks!

+1  A: 

You need to have a clock to control it to start.

always @(posedge clk or negedge rst_n)
  if (!rst_n)
     num <= 32'b0; // or whatever your width is.
  else
     if (num < test_number)
       num <= num + 1'b1;
Brian Carlton
That seems like a good solution. But the while() loop was initially in a task. If I pass the clk to the task, it doesnt seem that its value would be updated. But wait, if I'm using a task, do i even need a clk port for the task, or can I use the clk without passing it as a argument?
chester.boo
Tasks and functions have access to variables, inputs, and outputs declared in the same module as the task. Arguments are passed into tasks and functions by value (that is, by copying) once when the task begins. Output arguments are copied out when the task exists. Therefore, do not pass the clock into the task.
Steve K
A: 

If your synthesis tool does not support while or for loops, then don't use a loop. Just expand your code out.

wire [1:0] addr;
reg  [3:0] wren;

always @(posedge clk) begin
    wren[0] <= (addr == 2'd0);
    wren[1] <= (addr == 2'd1);
    wren[2] <= (addr == 2'd2);
    wren[3] <= (addr == 2'd3);
end

I am unfamiliar with XST, but some synthesis tools do support loops (Synopsys, for example).

toolic
I know XST would allow loops, but it has a limit on the number of iterations. Mine is set a conservative 64. You can of course change this limit, but having a loop with 100+ iterations for synthesis doesnt seem like a good idea even if its allowed.What is DC's default limit on the number of iterations. Does it warm you if you being to use a while() or for() for synthesis?
chester.boo
I know DC allows `for` loops. I have never tried to synthesize a `while` loop, but the documentation has several examples of synthesizable `while` loops. I do not know what the limit on iterations is.
toolic
-1 for advising the breakage of DRY (unnecessarily)
Earlz
@Earlz: But it is necessary to overcome the limitation of a synthesis tool which does not support looping constructs. I clearly stated this assumption in my Answer. Are you aware that logic synthesis tools only support a subset of the Verilog syntax? Of course my recommendation is not a good practice, but if it overcomes the limitation of a tool, it is valid.
toolic
A: 

Synthesis tools vary but generally a loop can be synthesized so long as the number of iterations is known a to the synthesis tool. So,

for ( i = 0; i < 10; i = i + 1 )

is OK because the tool knows there are 10 loop iterations. But

reg [10:0] r;
for ( i = 0; i < r; i = i + 1 )

is not OK because r is a variable r's value is unknown at synthesis time.

Think of loops in RTL code as creating a known fixed number of copies of a piece of logic.

Steve K