VHDL仿真错误

时间:2014-04-02 14:03:42

标签: vhdl fpga square-root

我正在尝试设计模拟,但我一直在ISim中收到此错误:

ERROR: In process nearfield_processing.vhd:distance_to_delay 
FATAL ERROR:ISim: This application has discovered an exceptional condition from which it cannot recover. Process will terminate. To search for possible resolutions to this issue, refer to the Xilinx answer database by going to http://www.xilinx.com/support/answers/index.htm and search with keywords 'ISim' and 'FATAL ERROR'. For technical support on this issue, please open a WebCase with this project attached at http://www.xilinx.com/support.
INFO: Simulator is stopped.

我不知道这里有什么问题,但下面是发生错误的方法。

distance_to_delay : process (i_clock)
begin

if(i_reset = '1') then
    delay_1        <= 0;
    delay_2        <= 0;
    delay_3        <= 0;
    delay_4        <= 0;
    ds_squared     <= 0;
    ds_squareroot  <= 0;
elsif(rising_edge(i_clock)) then
    -- Delay 1 calculations
    ds_squared <= (distance*distance + (speaker_distance)*(speaker_distance));
    for n in 0 to 20 loop
        ds_squareroot <=  ((50 + ds_squared/ds_squareroot)/2);
    end loop;
    delay_1 <= (ds_squareroot - distance)/ speed_sound;

    -- Delay 2 calculations
    ds_squared <= (distance*distance + (speaker_distance*2)*(speaker_distance*2));
    for n in 0 to 20 loop
        ds_squareroot <=  ((50 + ds_squared/ds_squareroot)/2);
    end loop;
    delay_2 <= (ds_squareroot - distance)/ speed_sound;

    -- Delay 3 calculations
    ds_squared <= (distance*distance + (speaker_distance*3)*(speaker_distance*3));
    for n in 0 to 20 loop
        ds_squareroot <=  ((50 + ds_squared/ds_squareroot)/2);
    end loop;
    delay_3 <= (ds_squareroot - distance)/ speed_sound;

    -- Delay 4 calculations
    ds_squared <= (distance*distance + (speaker_distance*4)*(speaker_distance*4));
    for n in 0 to 20 loop
        ds_squareroot <=  ((50 + ds_squared/ds_squareroot)/2);
    end loop;
    delay_4 <= (ds_squareroot - distance)/ speed_sound;     
end if;

    --********** Manually Set Delays ****************--

--      delay_1 <= (22+2); --42
--      delay_2 <= (44+2); --72
--      delay_3 <= (66+2); --91
--      delay_4 <= (88+2); --97
--      sample_period <= 22;

        --********** End Manually Set Delays ************--
end process;

此外,这里是完整设计文件https://github.com/srohrer32/beamformer/tree/delay_calc/hdl的链接。我有一种感觉它与for循环有关,我用来尝试和近似平方根函数,但我不确定。任何帮助表示赞赏。

2 个答案:

答案 0 :(得分:3)

首先,看起来你试图除以零,因为ds_squareroot被初始化为零。

另一件让我感到惊讶的是你的循环语句。

for n in 0 to 20 loop
    ds_squareroot <=  ((50 + ds_squared/ds_squareroot)/2);
end loop;

在HDL中,循环语句的所有迭代都是同时执行的,而不是像您熟悉的其他语言一样顺序执行。 (正如评论所指出的那样)你的循环语句实际上进行了21次相同的精确计算(每次都使用相同的值,因为同步信号只在时钟边沿上更新)。为了使你的计算循环迭代21次,就像我想你要做的那样,你必须使用变量。

如果延迟不是问题,那么我可能会对计算进行管道处理,以便我更容易满足时间要求。因此,对于您的情况,如果您想在使用该值之前进行21次ds_squareroot计算,则可能需要执行以下操作:

for n in 0 to 21 loop
    ds_squareroot[n] <=  ((50 + ds_squared/ds_squareroot[n-1])/2);
end loop;

并确保将数组中的所有ds_squareroot值初始化为零以外的值,并在其余计算中仅使用ds_squareroot [21]。根据您在此处所做的操作,您可能需要添加data_valid标志或某些内容以指示[21]值何时有效。这样做会导致从开始计算到完成计算的21个时钟延迟。

编辑:如果你采用我提到的方法,不要忘记让ds_squareroot成为一个整数数组。

奖金编辑:不确定您使用HDL合成的经验水平,但您也应该意识到您的设计必须满足时间要求。基本上,一个reg更新的输出到达下一个reg的输入所需的时间之间的时间必须小于你的时钟周期。你的逻辑存在于这两点之间。因此,如果两个reg之间有太多逻辑,则无法满足时序(通过逻辑传播将花费太长时间)。如果你使用变量在一个时钟周期内运行该计算21次,我的直觉就是regs之间的逻辑过多,你将无法满足时机要求。当然这取决于你的时钟频率,所以我说这只是我的感觉。

答案 1 :(得分:0)

重置系统时,此行初始化ds_square_root

ds_squareroot  <= 0;

然后在你的计时部分,你将它作为一个除数使用:

    ds_squareroot <=  ((50 + ds_squared/ds_squareroot)/2);

除以零是一种例外情况,尽管你希望得到比你得到的更具描述性的错误信息是正确的!


除此之外,我认为你错过了关于VHDL的一个关键点:signal只在流程结束时更新,它们获得了写入它们的最后一个值,无论何时读取它们都需要他们在流程开始时拥有的价值。这意味着这个循环:

for n in 0 to 20 loop
    ds_squareroot <=  ((50 + ds_squared/ds_squareroot)/2);
end loop;

不执行迭代更新,只有最后一次迭代才生效,所以它只被逻辑“执行”一次。

ArcticWhite已经为您提供了一些关于如何使用中间信号阵列解决问题的指示,这会在您得到答案之前增加时钟周期数,但允许快速时钟或使用变量,这意味着你'我会在一个时钟周期内得到你的答案,但那个时钟周期可能会非常(非常)长。

另请注意,除以非常数也会产生非常大的逻辑。还有其他几种(在速度,逻辑利用率,功率方面可能更好)在逻辑中实现平方根的方法。