Verilog中的FFT实现:使用嵌套for循环时出错

时间:2014-05-21 07:27:13

标签: fft verilog

这篇文章与我之前关于FFT的帖子有关。

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

我想将第一级的输出分配给FFT蝶形模块的第二级输入。我必须根据第二阶段的输入重新排序第一阶段的输出。这是我实现交换的代码。

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

当我合成它时,它会产生2个错误。

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. 

我们不能使用非常数增量和非静态停止编码吗?

如果是这样,我们如何处理这个问题。

感谢任何帮助。 提前谢谢。

2 个答案:

答案 0 :(得分:3)

综合工具展开循环以合成电路。因此,只有循环迭代一定次数的循环,其常量在编译/精化时才知道是可合成的。

当停止值未知时,您可以假设最大迭代次数并将其用作停止条件。然后在循环中将原始停止条件添加为条件语句:

        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

如果N不是常量,外部循环也应该使用类似的条件语句来修复。您还需要修复增量值,每次添加一个常量值。使用条件语句检查是否jj==jj+(2**(level+1))

显然,您需要小心,因为高最大数字可能会增加您的最坏情况延迟和最小时钟周期时间。

答案 1 :(得分: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

你可以试试这个。它必须工作。但问题是外循环会执行K次。