VHDL syn_looplimit和合成

时间:2016-03-17 06:58:45

标签: vhdl synthesis

我的VHDL代码在综合方面存在问题:我试图获得输入信号S_ink的对数值:

我的代码:

entity ....
....

architecture rtl of myEntity is
attribute syn_looplimit : integer;
attribute syn_looplimit of loopabc : label is 16384;

logcalc:process(I_clk)
  variable temp : integer;
  variable log  : integer;
  begin

    if(I_clk'event and I_clk='1') then
      if (IN_rst='0') then
        S_klog<=0;
        temp:=0; 
        log:=0;
      else 
        temp := S_ink+1;               --S_ink is an input of my entity (integer)
        log:=0;
        loopabc:while (temp/=0) loop
          temp:=temp/2;
          log :=log+1;
        end loop loopabc;
        S_klog<=3*log;
      end if;
    end if;
end process;

它在模拟中非常有效,但不能合成。 错误消息是:“while循环未终止。您可以使用syn_looplimit属性设置循环迭代的最大值”

然而,这段代码合成(但这不是我想要的)

entity ....
....

architecture rtl of myEntity is
attribute syn_looplimit : integer;
attribute syn_looplimit of loopabc : label is 16384;

logcalc:process(I_clk)
  variable temp : integer;
  variable log  : integer;
  begin

    if(I_clk'event and I_clk='1') then
      if (IN_rst='0') then
        S_klog<=0;
        temp:=0; 
        log:=0;
      else
        temp := 3000;       -- a random constant value
        log:=0;
        loopabc:while (temp/=0) loop
          temp:=temp/2;
          log :=log+1;
        end loop loopabc;
        S_klog<=3*log;
      end if;
    end if;
end process;

2 个答案:

答案 0 :(得分:2)

当综合工具转换设计时,它将构成一个拓扑结构不依赖于数据值但电线承载数据值的电路。电路必须在每个触发器级别之间具有固定的计算延迟,因此时序分析可以确定触发器之间的逻辑量是否适合指定的频率。在此过程中,任何循环都会展开,您可以将其视为将循环转换为一系列普通(非循环)语句。要进行此展开,合成工具必须能够确定循环中的迭代次数,因此在循环展开时它可以重复循环体次数。

在第一个代码示例中,循环中的迭代次数取决于S_ink值,因此综合工具无法将循环展开到固定电路,因为电路取决于数据值。 / p>

在第二个代码示例中,综合工具可以确定循环中的迭代次数,从而展开到固定电路。

解决这个问题的一种方法是使算法具有固定的迭代次数,其中这个迭代次数可以处理最坏情况的输入数据,并且其他输入数据上的任何多余迭代都不会改变结果。

答案 1 :(得分:1)

解决方案:

process(I_clk)
  variable temp : integer;
  variable log  : integer;
  begin

    if(I_clk'event and I_clk='1') then
      if (IN_rst='0') then
        S_klog<=0;
        temp:=0; 
        log:=0;
      else 
        temp := S_ink+1;
        log:=0;
        for I in 1 to 14 loop
          temp := temp/2;
          if (temp /=0) then
            log :=log+1;
          end if;
        end loop;
        S_klog<=3*log;                           -- 3*log because of my application
      end if;
end if;
end process;
相关问题