I am trying to get a design to simulate but I consistently receive this error in 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.

I have no idea what the problem is here, but below is the method in which the error occurs.

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;

Additionally, here is the link to the full design files https://github.com/srohrer32/beamformer/tree/delay_calc/hdl. I have a feeling it has something to do with the for loop that I am using to try and approximate a square root function, but I'm not sure. Any help is appreciated.

有帮助吗?

解决方案

First of all, it looks like you're trying to divide by zero since ds_squareroot is initialized to zero.

Another thing that stands out to me is your loop statements.

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

In HDLs all iterations of a loop statement are executed concurrently, not sequentially like other languages you may be familiar with. (As the comments pointed out) Your loop statement is actually doing the same exact calculation 21 times (with the same values each time because synchronous signals only update on a clock edge). To make your calculation iterate 21 times in a loop like I think you are trying to do you'd have to use variables.

If latency isn't an issue then I would probably pipeline the calculations so I have an easier time meeting timing. So for your case if you want to do the ds_squareroot calculation 21 times before using the value you may have to do something like this:

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

And make sure to initialize all ds_squareroot values in the array to something other than zero and only use ds_squareroot[21] in the rest of your calculations. Depending on what you're doing here you may want to add an data_valid flag or something to indicate when you the [21] value is valid. Doing so will lead to a 21 clock latency from when you start the calculation to when you have finished the calculation.

EDIT : Don't forget to make ds_squareroot an array of integers if you go with the approach I mentioned.

BONUS EDIT: Not sure of your level of experience with HDL synthesis but you should also be aware that your design has to meet timing. Basically the time between the output of one reg updating to the time it takes to reach the input of the next reg has to be less than your clock period. Your logic exists between these two points. Therefore if you have too much logic between two regs you won't meet timing (it will take too long to propagate through logic). If you were to use variables to run that calculation 21 times in one clock cycle my gut feeling is that would be way too much logic between regs and you would not be able to meet timing. Of course it would depend on your clock frequency, so as I said it's just my guy feeling.

其他提示

When you reset your system, this line initialises ds_square_root

ds_squareroot  <= 0;

Then in your clocked part, you make use of it as a divisor:

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

Divide by zero is an exceptional condition, although you'd be right to hope for a more descriptive error message than the one you are getting!


Beyond that, I think you are missing a critical point about VHDL: signals only update at the end of the process, they get the last value they had written to them, and whenever they are read they take the value they had at the start of the process. This means that this loop:

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

does not perform an iterative update, only the last iteration takes effect, so it is only "executed" by the logic once.

ArcticWhite has given you some pointers on how to solve that problem wither using an array of intermediate signals, which increases the number of clock cycles before you get your answer, but allows a fast clock, or using variables, which means you'll get your answer in a single clock cycle, but that clock cycle will probably ned up being very (very) long.

Also note that dividing by a non-constant will create very large logic as well. There are several other (probably better in terms of speed, logic utilisation, power) ways of implementing square-roots in logic.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top