I've found a strange bug with GHDL and buffer ports. Here is a very stripped-down example.
Run with:
$ ghdl -i ghdl_bug.vhdl && ghdl -m ghdl_bug && ./ghdl_bug 2<&1 | head -5
analyze ghdl_bug.vhdl
elaborate ghdl_bug
ghdl_bug.vhdl:34:5:@40930001ps:(assertion error): expected = 0 actual = 2047
ghdl_bug.vhdl:34:5:@40950001ps:(assertion error): expected = 1 actual = 0
ghdl_bug.vhdl:34:5:@40970001ps:(assertion error): expected = 2 actual = 1
ghdl_bug.vhdl:34:5:@40990001ps:(assertion error): expected = 3 actual = 2
ghdl_bug.vhdl:34:5:@41010001ps:(assertion error): expected = 4 actual = 3
You might assume the bug is that "num" wasn't initialized. But then try
changing the process that just READS the port, and you'll see that it also
affect it's value.
For example, change this part:
proc_read : process is
variable val : integer := 1;
begin
To have val = 2:
$ ghdl -i ghdl_bug.vhdl && ghdl -m ghdl_bug && ./ghdl_bug 2<&1 | head -5
analyze ghdl_bug.vhdl
elaborate ghdl_bug
ghdl_bug.vhdl:34:5:@10001ps:(assertion error): expected = 2 actual = 1
ghdl_bug.vhdl:34:5:@30001ps:(assertion error): expected = 3 actual = 2
ghdl_bug.vhdl:34:5:@50001ps:(assertion error): expected = 4 actual = 3
ghdl_bug.vhdl:34:5:@70001ps:(assertion error): expected = 5 actual = 4
ghdl_bug.vhdl:34:5:@90001ps:(assertion error): expected = 6 actual = 5
Or val = 0:
$ ghdl -i ghdl_bug.vhdl && ghdl -m ghdl_bug && ./ghdl_bug 2<&1 | head -5
analyze ghdl_bug.vhdl
elaborate ghdl_bug
ghdl_bug.vhdl:34:5:@10001ps:(assertion error): expected = 0 actual = 1
ghdl_bug.vhdl:34:5:@30001ps:(assertion error): expected = 1 actual = 2
ghdl_bug.vhdl:34:5:@50001ps:(assertion error): expected = 2 actual = 3
ghdl_bug.vhdl:34:5:@70001ps:(assertion error): expected = 3 actual = 4
ghdl_bug.vhdl:34:5:@90001ps:(assertion error): expected = 4 actual = 5
Or instead, putting val back to 1, change this part:
num <= (others => '0');
To be:
num <= (others => '1');
$ ghdl -i ghdl_bug.vhdl && ghdl -m ghdl_bug && ./ghdl_bug 2<&1 | head -5
analyze ghdl_bug.vhdl
elaborate ghdl_bug
ghdl_bug.vhdl:34:5:@10001ps:(assertion error): expected = 1 actual = 0
ghdl_bug.vhdl:34:5:@30001ps:(assertion error): expected = 2 actual = 1
ghdl_bug.vhdl:34:5:@50001ps:(assertion error): expected = 3 actual = 2
ghdl_bug.vhdl:34:5:@70001ps:(assertion error): expected = 4 actual = 3
ghdl_bug.vhdl:34:5:@90001ps:(assertion error): expected = 5 actual = 4
Now change val = 0:
$ ghdl -i ghdl_bug.vhdl && ghdl -m ghdl_bug && ./ghdl_bug 2<&1 | head -5
analyze ghdl_bug.vhdl
elaborate ghdl_bug
ghdl_bug.vhdl:34:5:@40950001ps:(assertion error): expected = 0 actual = 2047
ghdl_bug.vhdl:34:5:@40970001ps:(assertion error): expected = 1 actual = 0
ghdl_bug.vhdl:34:5:@40990001ps:(assertion error): expected = 2 actual = 1
ghdl_bug.vhdl:34:5:@41010001ps:(assertion error): expected = 3 actual = 2
ghdl_bug.vhdl:34:5:@41030001ps:(assertion error): expected = 4 actual = 3
This is using ghdl 0.29 from Debian:
$ ghdl --version
GHDL 0.29 (20100109) [Sokcho edition]
Compiled with GNAT Version: 4.4.5
GCC back-end code generator
Written by Tristan Gingold.
library ieee;
use ieee.numeric_bit.all;
entity ghdl_bug is
port (
num : buffer unsigned(10 downto 0)
);
end entity;
architecture bug of ghdl_bug is
signal clk : bit;
begin
proc_clk : process is
begin
wait for 10 ns;
clk <= not clk;
end process;
proc_write : process is
begin
num <= (others => '0');
loop
wait until rising_edge(clk);
num <= num + 1;
end loop;
end process;
proc_read : process is
variable val : integer := 1;
begin
wait until rising_edge(clk);
wait for 1 ps;
assert(val = to_integer(num))
report "expected = " & integer'image(val) &
" actual = " & integer'image(to_integer(num));
val := val + 1;
if val = 2**11-1 then
val := 0;
end if;
end process;
end architecture;
signature.asc
Description: This is a digitally signed message part.
_______________________________________________ Ghdl-discuss mailing list [email protected] https://mail.gna.org/listinfo/ghdl-discuss
