我的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;
答案 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;