无法使用 while 循环完成进程编译

  • 本文关键字:进程 编译 循环 while vhdl
  • 更新时间 :
  • 英文 :


我有以下过程,应该将其输入(input_1)右移,直到它达到0,然后结束循环:

DFF_PROCESS: process (input_0, input_1, input_2, CLK)
variable eX : integer;
...
begin
eX := input_1;
...
while (eX > 0) loop
if ( CLK'event and CLK = '1' ) then
...
eX := to_integer(shift_right(to_unsigned(eX,32), 1));
end if;
end loop;
result <= rE;
end process;

但当我试图编译它时,它不会产生任何错误,而是停留在Analysis&合成部分。编译器似乎在工作(通过ProcessExplorer检查),但即使在一个多小时后,也没有任何进展。有人能帮忙吗?

我需要这个组件是可合成的,所以如果我的方法有逻辑缺陷,请给我指明正确的方向。

合成while循环通常是个坏主意,稍微想一想就会明白为什么。。。

而环路不能保证终止;并且迭代次数通常不能在编译(合成)时知道,因此您正试图生成一个在运行时之前大小未知的硬件结构!

那行不通。。。

通常,您需要将While循环转换为具有本地静态边界(大致:可以从该源文件中确定)的密切相关的For循环,这是可合成的。

在您的情况下,您将变量转换为32位无符号变量,并一次右移1位:一个合适的For循环将在32位无信号变量中的位上循环。

这并不能处理不同的输入值:然而,for循环中的条件(if ex = 0 then)会做到这一点(显然是可合成的)

类似。。。

DFF_PROCESS: process (CLK, input_1)
variable eX : unsigned(31 downto 0);
...
begin
eX := to_unsigned(input_1);
...
for i in ex'range loop  -- better way of saying 31 downto 0)
if rising_edge(clk) then
if ex > 0 then
...   
eX := shift_right(eX, 1);
end if;
end if;
end loop;
end process;

这还有其他问题:它不是一个正确的时钟进程,ex不断被输入值覆盖,所以它不会做你期望的事情。

有两种前进的方式:一种是快速(每个时钟周期一个结果),但生成大量硬件,另一种是小型(但最坏情况下需要32个时钟周期)。

第一个展开循环,生成32个循环体副本,以在单个时钟周期内生成结果:

DFF_PROCESS: process (CLK)
variable eX : unsigned(31 downto 0);
...
begin
if rising_edge(clk) then
eX := to_unsigned(input_1, ex'length);
...
for i in ex'range loop  
if ex > 0 then  -- done
...
eX := shift_right(eX, 1);
end if;
end loop;
result <= ...
end if;
end process;

另一种是状态机,它可以在每个时钟周期中接受新的输入值,也可以处理单个比特,但不能同时处理这两个比特。

DFF_PROCESS: process (CLK)
variable eX : unsigned(31 downto 0);
type State_type is (Read, Process_Data);
variable State : State_Type;
begin
if rising_edge(clk) then
if State = Read then
eX    := to_unsigned(input_1, ex'length);
State := Process_Data;
else
if ex = 0 then
result <= ...
State := Read;
else
...
eX := shift_right(eX, 1);
end if;
end if;
end if;
end process;

(如果你愿意,你可以添加状态,让它在读取新值之前等待…)

最新更新