On 27/06/11 3:04 AM, Wesley J. Landaker wrote:

>From running your original test case ghdl_bug.vhdl using --stop-time, it
appears to require a roll over event on val.

ghdl -r ghdl_bug bug --stop-time=40960ns
ghdl_bug.vhdl:34:5:@40930001ps:(assertion error): expected = 0 actual = 2047
ghdl_bug.vhdl:34:5:@40950001ps:(assertion error): expected = 1 actual = 0

This captures the very first two  assertion events.  You can see the roll
over event on num ended up with val out of step out for where val should
have been 2047 it became 0. The precession appears to only happen on  val
roll over.  Once the processes are out of step they remain so until the next
precession.

This is demonstrated by --stop-time=81920ns and catching the next precession:

(tail -5)
ghdl_bug.vhdl:34:5:@81850001ps:(assertion error): expected = 2046 actual = 2045
ghdl_bug.vhdl:34:5:@81870001ps:(assertion error): expected = 0 actual = 2046
ghdl_bug.vhdl:34:5:@81890001ps:(assertion error): expected = 1 actual = 2047
ghdl_bug.vhdl:34:5:@81910001ps:(assertion error): expected = 2 actual = 0
ghdl:info: simulation stopped by --stop-time

The reasoning for the stop time derives from the roll over count for val and
the 20 nsec clock period.

Note that the value 2047 doesn't show up in expected (val).  Instead of 2047
val went to zero.   val went from 2046 to 0  on successive 20 nsec clocks
(@81850001ps to @81870001ps).

This is with the ghdl mcode version I did for Mac OS X.  I managed to get my
kubuntu 10.10 running ghdl, installed with Kpackagekit from ubuntu's
repository.  The results were identical.


I ran another experiment.  See ghdl_bug7.vhdl.  This change resulted in a
simulation that did not fail.

diff ghdl_bug.vhdl ghdl_bug7.vhdl
37c37
<     val := val + 1;
---
> --    val := val + 1;
39a40,41
>     else
>       val := val + 1;

 --

Basically, it moves any assignment to val under the conditional expression
in proc_read:

--    val := val + 1;
    if val = 2**11-1 then
      val := 0;
    else
      val := val + 1;
    end if;

This doesn't fail either under the Mac OS X mcode version or the Linux
ubuntu version.  Both num and val operate modulo 2048.  They stay in step.

The difference is that the val value stays at 2047 for an entire clock
before going from 2047 to 0.  The 2047 count is actually available for
comparison to num.

Now for the kicker.  The original ghdl_bug.vhdl code should not work,
because it is modulo 2047.  val is incremented by one, becomes now 2047
(2**11-1) and is immediately reset to 0 before it can be used.  The
available outputs are 0 to 2046.

Pre increment and the test value  should be 2**11 (2048).  Fix it (in
ghdl_bug8.vhdl) and it works just fine.

ghdl_bug.vhdl (your original test case) runs val modulo 2047, while
ghdl_bug7.vhdl and ghdl_bug8.vhdl both operate val modulo 2048.

Your test case is defective.

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;
    else
      val := val + 1;
    end if;
  end process;

end architecture;
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 then
      val := 0;
    end if;
  end process;

end architecture;
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;
_______________________________________________
Ghdl-discuss mailing list
[email protected]
https://mail.gna.org/listinfo/ghdl-discuss

Reply via email to