我想实现用于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)循环
答案 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)
您需要了解signal
和variable
之间的区别。
当您分配到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;