VHDL-syn_循环极限与综合

VHDL-syn_循环极限与综合,vhdl,synthesis,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

我在使用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;
实体。。。。
....
myEntity的体系结构rtl是
属性syn_looplimit:整数;
loopabc的属性syn_looplimit:标签为16384;
logcalc:过程(I_clk)
变量温度:整数;
变量log:整数;
开始
如果(I_clk'event和I_clk='1'),则
如果(IN_rst='0'),则

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

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

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

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

解决方案:

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;
过程(I_clk)
变量温度:整数;
变量log:整数;
开始
如果(I_clk'event和I_clk='1'),则
如果(IN_rst='0'),则

谢谢你的回复。问题是S_ink是一个介于1和16384之间的整数。。。。所以我的“固定数量的迭代循环”太长了。合成工具不知道迭代次数,但syn_looplimit属性应该可以解决此问题?@Dimitri-Lecomte如果S_ink的最大值为16384,则循环的最大迭代次数为14(或15?)。始终循环该次数,但仅执行
log:=log+1如果
temp
大于零。@Morten Zimer讽刺的是,使用递归函数实现相同的算法,它的合成效果很好。感谢您的回复。你说得对,最大值是14。我将发布正确的答案,但我仍然不明白为什么syn_looplimit在我的第一个示例中不起作用。使用此属性,合成工具可以知道最大迭代次数…@dimitriecomte:我假设您使用Lattice,因为我找不到为Altera或Xilinx定义的属性
syn_looplimit
。在示例中,Lattice给出的循环数仍然是常数,因此不依赖于数据,因此
syn_looplimit
似乎只是对工具的提示。因此,即使在应用
syn_looplimit
时,该工具也无法确定展开循环时的迭代次数。我建议在可合成代码中使用
for
而不是
while
循环,即
for I in 1 to maxloop
或类似的东西。我原以为,它更可能在任何旧的合成器上进行合成。无论如何,您已经使用
while
循环手动为
循环有效地编码了自己的
。while循环已更改。非常感谢。
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;