超出了非静态循环限制

时间:2013-02-09 14:49:24

标签: vhdl xilinx

我想实现用于256位向量的汉明权重计算的K& R算法。我已经在vhdl中编写了我的代码:

entity counter_loop is
    Port ( dataIn : in  STD_LOGIC_VECTOR (255 downto 0);
              dataOut : out STD_LOGIC_VECTOR (8 downto 0);
           threshold : in  STD_LOGIC_VECTOR (8 downto 0);
           clk : in  STD_LOGIC;
           flag : out  STD_LOGIC);
end counter_loop;

architecture Behavioral of counter_loop is
    signal val : STD_LOGIC_VECTOR (255 downto 0) := X"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF";
begin
    process (clk)
        variable count : STD_LOGIC_VECTOR (8 downto 0):= "000000000";       
    begin
        flag <= '0';
        val <= dataIn;
        --if(clk'event and clk = '1') then 
            while (val > 0) loop
                count := count+1;
                val <= (val and (val-1));
                if (count > threshold) then
                    flag <= '1';
                end if;
            end loop;
                dataOut <= count;
        --end if;
    end process;
end Behavioral;

但是,在使用Xilinx进行合成时,错误就出现了

第53行:超出非静态循环限制

有什么线索吗?

P.S:第53行是 - 而(val> 0)循环

2 个答案:

答案 0 :(得分:3)

所以,我将忽略实际满足时间的问题(val - 1是昂贵的)并实际谈论你的逻辑。

这是你的一段代码:

signal val : std_logic_vector(255 downto 0) := (others => '1');

process (clk)
begin
    while (val > 0) loop
        val <= (val and (val-1));
    end loop;
end process;

val是一个信号,而不是一个变量。这意味着当您完成增量循环时它将被更新。在这种情况下,将永远不会。所以你有一个无限循环。


如果您只是想计算一个数字的popcount,那你为什么不这样做呢?虽然我怀疑这也会满足时序(可能需要在多个时钟周期内将其分解)。

process (clk)
    variable count : std_logic_vector(8 downto 0) := "0" & x"00";
begin
    if rising_edge(clk) then
        for i in dataIn'range loop
            if dataIn(i) = '1' then
                count := count + 1;
            end if;
        end loop;

        dataOut <= count_i;
    end if;
end process;

最后,大多数人会争辩说,为C代码设计的算法通常在硬件上表现不佳,因为硬件具有与固定处理器不同的功能。

答案 1 :(得分:3)

您需要了解signalvariable之间的区别。

当您分配到signal时,您只安排下一个时间点的更改(在像您这样的时钟流程中,这是您的流程到达结束时以及所有其他流程)目前计划执行的也有。)

因此,当您在流程中的循环中编写val <= something时,val只会被安排更新。当进程检查val的值时,它会看到当前值,而不是计划值。您需要使用变量以这种方式跟踪事物。

然而,正如其他地方所述,如果你只想计算那些,那就容易多了:

count:=0;
for i in dataIn'range loop
   if dataIn(i) = '1' then 
      count:=count+1; 
   end if;
end loop;