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.
1 Answer 1
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!
The syntax for resize in fixed_pkg appears to differ from that used in numeric_std for signed and unsigned numbers.
... it implies thatnumeric_std
has a resize command (or statement?) also \$\endgroup\$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\$