After a year's hiatus, I returned to learning VHDL. I'm working on the exercises on Peter Ashenden's book Beginner's Guide to VHDL and I'm stuck on exercise 11 of chapter 3.

The goal is to write a module, that will perform basic arithmetic operations on two real numbers. Here is my module:

-- floating point ALUish thing

entity FPALU is
port ( x, y : in real;
f1, f0 : in bit;
z : out real );
end entity FPALU;

architecture behav of FPALU is
begin
fpalu_behavioral : process(x, y, f1, f0) --is
variable result : real := 0.0;
begin
if f1 = '0' and f0 = '0' then
result := x + y;
elsif f1 = '0' and f0 = '1' then
result := x - y;
elsif f1 = '1' and f0 = '0' then
result := x * y;
elsif f1 = '1' and f0 = '1' then
result := x / y;
-- else null;
end if;
z <= result;
end process fpalu_behavioral;
end architecture behav;


And its test bench:

-- test bench for floating point operations

entity FPALU_test_bench is
end entity FPALU_test_bench;

architecture test_FPALU of FPALU_test_bench is

signal x, y, z : real;
signal f0, f1 : bit;

begin
dut : entity work.FPALU(behav)
port map ( x, y, f1, f0, z );

stimulus : process is
begin
x <= 3.4; y <= 5.8; f1 <= '0'; f0 <= '0'; wait for 20 ns;
x <= 3.4; y <= 5.8; f1 <= '0'; f0 <= '1'; wait for 20 ns;
x <= 3.4; y <= 5.8; f1 <= '1'; f0 <= '0'; wait for 20 ns;
x <= 3.4; y <= 5.8; f1 <= '1'; f0 <= '1'; wait for 20 ns;
wait;
end process stimulus;

end architecture test_FPALU;


This code will analyze and elaborate fine, but once I try to run the test bench I get this error:

ghdl -r FPALU_test_bench --vcd=FPALU.vcd
./fpalu_test_bench:error: bound check failure at FPALU.vhdl:15
./fpalu_test_bench:error: simulation failed


Line 15 being result := x + y;. This question seems to be similar, but since packages haven't been introduced yet in the book, I assume it should be possible to do without. Also, I added two real numbers in a similar fashion in another module and it worked fine. So, why won't this simulation run? I guess it's an "overflow issue" from what I have found here and on Google, but no definite answer.

• i am not very familiar with VHDL, but i read your question. ... the question that you refer to has an answer with this line The syntax for resize in fixed_pkg appears to differ from that used in numeric_std for signed and unsigned numbers. ... it implies that numeric_std has a resize command (or statement?) also Commented Jan 31, 2018 at 3:13
• The implicit initial value for an object of type real without an explicit initial value is real'left (-1.79769313486232E+308 for later ghdl versions). Add two of those together and you have a negative number with a value not between the left and right range bounds (inclusively). Explicitly initialize x and y: signal x, y: real := 0.0; signal z: real; Your testbench then simulates. Your adding before the first assignment takes effect using the implicit initial values.
– user8352
Commented Jan 31, 2018 at 5:05
• @user8352 avoid writing answers in comments Commented Feb 1, 2018 at 13:34
• Here's an example of the same problem for multiplication of reals with no explicit initial value. Simualtion (sic) stops at time 0 after a real to real multiplication!. Addition and multiplication both can have a result for operands of the value real'left that is out of the value range of type real. Division yields 1.0 while subtraction yields 0.0. You could provide initial values for f0 and f1 or reorder the operations and duplicate the linked question problem.
– user8352
Commented Feb 1, 2018 at 16:04

I'm sorry for my late reply, I got caught up in other stuff yet again. I managed to update my code the way @user8352 suggested to get it to run, so here are the working versions:

entity floatALU is
port ( x, y : in real;
f1, f0 : in bit;
z : out real );
end entity floatALU;

-- behavrioal body
architecture behav of floatALU is
begin
calculate : process ( x, y, f1, f0 ) is
begin
-- I combine if and case statements on purpose here
if f1 = '0' then
case f0 is
when '0' => z <= x + y;
when '1' => z <= x - y;
end case;
else
case f0 is
when '0' => z <= x * y;
when '1' => z <= x / y;
end case;
end if;
end process calculate;
end architecture behav;


And the test bench:

entity floatALU is
port ( x, y : in real;
f1, f0 : in bit;
z : out real );
end entity floatALU;

-- behavrioal body
architecture behav of floatALU is
begin
calculate : process ( x, y, f1, f0 ) is
begin
-- I combine if and case statements on purpose here
if f1 = '0' then
case f0 is
when '0' => z <= x + y;
when '1' => z <= x - y;
end case;
else
case f0 is
when '0' => z <= x * y;
when '1' => z <= x / y;
end case;
end if;
end process calculate;
end architecture behav;


Thank you all for your help!