3

This post is related to the my previous post related to FFT.

FFT implemetation in Verilog: Assigning Wire input to Register type array

I want to assign output of first stage to input of second stage of FFT butterfly modules. I have to re-order the output of first stage according to input of second stage. Here is my code to implement the swapping.

always@ (posedge y_ndd[0] or posedge J)
begin

if(J==1'b1)
begin
    for (idx=0; idx<N/2; idx=idx+1)
     begin
         IN[2*idx] <= X[idx*2*X_WDTH+: 2*X_WDTH];
         IN[2*idx+1] <= X[(idx+N/2)*2*X_WDTH+: 2*X_WDTH];
     end
end

else
begin
    level=level+1;
    modulecount=0;
    for(jj=0;jj<N;jj=jj+(2**(level+1)))
        begin
        for (jx=jj; jx<jj+(2**level); jx=jx+1)//jj+(2**level)
         begin
             IN[modulecount] <=OUT[jx];
             IN[modulecount+1] <=OUT[jx+(2**level)];
             modulecount=modulecount+1;
         end
        end
end

end

When I synthesize this, It gives 2 errors.

ERROR:Xst:891 - "Network.v" line 161: For Statement is only supported when the new step evaluation is constant increment or decrement of the loop variable.
ERROR:Xst:2634 - "Network.v" line 161: For loop stop condition should depend on loop variable or be static. 

Can't we use non-constant increment and non-static stop coditions?

If that so, how we handle this.

Any help is appreciated. Thanks in advance.

Jey
  • 79
  • 1
  • 9
  • So you want wires that move and change their connections in your device? – N8TRO May 21 '14 at 09:28
  • IN is register type and OUT is wire type. IN is the input for butterfly module and OUT is the output from the module. The Main module source code in the above link I mentioned. – Jey May 21 '14 at 09:37
  • I want to change IN array value in every level. So in every step input of butterfly modules has to vary. – Jey May 21 '14 at 09:40
  • I have to apologize.. The indexing syntax should be like this answer: http://stackoverflow.com/a/18068296/1906816 – N8TRO May 21 '14 at 11:16
  • What is resetting `level`? I only see `level=level+1`. Also, asynchronous set/rst is normally set to a constant. If possible make `J` synchronous. – Greg May 21 '14 at 17:49
  • ya. I have to add stop condition for level. Thanks. – Jey May 22 '14 at 05:01
  • What hardware do you want from `always@ (posedge y_ndd[0] or posedge J)`? pretty sure you will get a flip-flop clocked by `y_ndd[0]` with an active high reset controlled by `J` – Morgan May 22 '14 at 14:59

2 Answers2

3

Synthesis tools unroll loops in order to synthesize the circuit. Therefore, only loops that iterate a constant number of times, whose constant is known at compile/elaboration time are synthetisable.

When the stop value is not known, you can assume a maximum number of iterations and use that as the stop condition. Then add the original stop condition as a conditional statement inside the loop:

        for (jx=jj; jx < MAX_LOOP_ITERATION; jx=jx+1)//jj+(2**level)
         begin
           if (jx<jj+(2**level))   // <---------- Add stop condition here
           begin
             IN[modulecount] <=OUT[jx];
             IN[modulecount+1] <=OUT[jx+(2**level)];
             modulecount=modulecount+1;
           end
         end

If N is not a constant, the outer loop should also be fixed using a similar conditional statement. You also need to fix the increment value and each time add a constant value. Use a conditional statement to check if jj==jj+(2**(level+1))

Obviously, you need to be careful as a high max number may increase your worst case delay and the minimum clock cycle time.

Ari
  • 7,251
  • 11
  • 40
  • 70
  • need one more if statement between the for loops to resolve the _"For Statement is only supported when the new step evaluation is constant increment or decrement of the loop variable."_ – Greg May 21 '14 at 17:53
  • @Greg: I was only looking at the inner loop. Improved the answer for the outer loop. – Ari May 21 '14 at 18:01
  • Thanks Ari. It's helpful. – Jey May 22 '14 at 07:03
1
//ll,level,K has to be declare. 
always@ (posedge y_ndd[0] or posedge J)
    begin

    if(J==1'b1)
        begin
        for (idx=0; idx<N/2; idx=idx+1)
            begin
            IN[2*idx] <= X[idx*2*X_WDTH+: 2*X_WDTH];
            IN[2*idx+1] <= X[(idx+N/2)*2*X_WDTH+: 2*X_WDTH];
         end
    end     
    else
        begin   
        ll=ll+1;
        modulecount=0;
        for(level=0;level<K;level=level+1) //K time you need to execute
            begin
            if(ll==level)
                begin
                for(jj=0;jj<N;jj=jj+(2**(level+1)))
                    begin
                    for (jx=jj; jx<jj+(2**level); jx=jx+1)
                        begin
                        IN[modulecount] <=OUT[jx];
                        IN[modulecount+1] <=OUT[jx+(2**level)];
                        modulecount=modulecount+1;
                    end
                end
            end
        end 
            //ll=ll+1;
    end
end

You can try this. It has to work. But problem is outer loop will execute K times.

Jothy
  • 31
  • 5