1
\$\begingroup\$

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.

asked Jan 31, 2018 at 1:30
\$\endgroup\$
4
  • \$\begingroup\$ 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 \$\endgroup\$ Commented Jan 31, 2018 at 3:13
  • 1
    \$\begingroup\$ 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. \$\endgroup\$ Commented Jan 31, 2018 at 5:05
  • \$\begingroup\$ @user8352 avoid writing answers in comments \$\endgroup\$ Commented Feb 1, 2018 at 13:34
  • \$\begingroup\$ 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. \$\endgroup\$ Commented Feb 1, 2018 at 16:04

1 Answer 1

1
\$\begingroup\$

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!

answered Feb 18, 2018 at 18:20
\$\endgroup\$
0

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.