Forum: GHDL anyone confirm this bug in ghdl?

Posted by Steve Franks (Guest)
on 2009-03-28 09:03
(Received via mailing list)
Hi,

Before I submit a bug report, maybe someone can double-check me?  I've
got a very simple state-machine, and it bounces back & forth between
two mutually exclusive states.  Look in the waveform viewer when
TestNum=3 and SubtestNum=2.  I can't see how I can bounce between
states 3 & 5, but maybe my conceptualization of VHDL is lacking...

Best,
Steve

Mutex.vhd:
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity Mutex is port
(
  clk      : in  std_logic;
  reset    : in  std_logic;

  HatfieldReq    : in  std_logic;
  McCoyReq    : in  std_logic;

  State    : out std_logic_vector(3 downto 0);

  HatfieldGrant  : out std_logic;
  McCoyGrant  : out std_logic--;
);
end Mutex;

architecture Behavioral of Mutex is

  type states is
  (
    Check_Req,
    Issue_HatfieldGrant, Wait4_HatfieldReqDone
    Issue_McCoyGrant, Wait4_McCoyReqDone
  );

  signal NextState  : states;
  signal CurrentState: states;

begin

  Mutex_states : process(clk, reset, CurrentState, HatfieldReq, 
McCoyReq)
  begin

    if reset = '1' then

      CurrentState <= Check_Req;
         HatfieldGrant <= '0';
      McCoyGrant <= '0';

      State <= x"0";

    elsif rising_edge(clk) then

      CurrentState <= NextState;

      case CurrentState is

        when Check_Req =>

          State <= x"1";

          --Just to be sure
          HatfieldGrant <= '0';
          McCoyGrant <= '0';

          if McCoyReq = '1' then

            NextState <= Issue_McCoyGrant;

          else

            if HatfieldReq = '1' then

              NextState <= Issue_HatfieldGrant;

            else

              NextState <= Check_Req;

            end if;

          end if;

        -- Grant ARM access to resource

        when Issue_HatfieldGrant =>

          State <= x"2";

          HatfieldGrant <= '1';
          McCoyGrant <= '0';
          NextState <= Wait4_HatfieldReqDone;

        when Wait4_HatfieldReqDone =>

          State <= x"3";

          if HatfieldReq = '1' then

            NextState <= Wait4_HatfieldReqDone;

          else

            HatfieldGrant <= '0';
            NextState <= Check_Req;

          end if;

        --  End of ARM access


        -- Grant PC access to resource

        when Issue_McCoyGrant =>

          State <= x"4";

          McCoyGrant <= '1';
          HatfieldGrant <= '0';
          NextState <= Wait4_McCoyReqDone;

        when Wait4_McCoyReqDone =>

          State <= x"5";

          if McCoyReq = '1' then

            NextState <= Wait4_McCoyReqDone;

          else

            McCoyGrant <= '0';
            NextState <= Check_Req;

          end if;

        --  End of PC access

        when others =>

          State <= x"F";

          NextState <= Check_Req;

      end case;

    end if;

  end process Mutex_states;

end Behavioral;


Mutex_tb.vhd:
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.std_logic_unsigned.all;
USE ieee.numeric_std.ALL;

ENTITY Mutex_tb IS
END Mutex_tb;

ARCHITECTURE behavior OF Mutex_tb IS

    -- Component Declaration for the Unit Under Test (UUT)

    COMPONENT Mutex
    PORT(
         HatfieldReq : IN  std_logic;
         McCoyReq : IN  std_logic;

     State    : out std_logic_vector(3 downto 0);

         HatfieldGrant : OUT  std_logic;
         McCoyGrant : OUT  std_logic;
         clk : IN  std_logic;
         reset : IN  std_logic
        );
    END COMPONENT;

   --Inputs
   signal HatfieldReq : std_logic := '0';
   signal McCoyReq : std_logic := '0';
   signal clk : std_logic := '0';
   signal reset : std_logic := '0';

   --Outputs
   signal HatfieldGrant : std_logic;
   signal McCoyGrant : std_logic;

   -- Clock period definitions
   constant clk_period : time := 21 ns;

   --Info
   signal State : std_logic_vector(3 downto 0);
   signal Testnum : std_logic_vector(3 downto 0);
   signal SubTestnum : std_logic_vector(3 downto 0);

BEGIN

  -- Instantiate the Unit Under Test (UUT)
   uut: Mutex PORT MAP (
          HatfieldReq => HatfieldReq,
          McCoyReq => McCoyReq,

      State => State,

          HatfieldGrant => HatfieldGrant,
          McCoyGrant => McCoyGrant,
          clk => clk,
          reset => reset
        );

   -- Clock process definitions
   clk_process :process
   begin
    clk <= '0';
    wait for clk_period/2;
    clk <= '1';
    wait for clk_period/2;
   end process;


   -- Stimulus process
   stim_proc: process
   begin

   -- hold reset state for 100ms.
  wait for 10 ns;
  wait for clk_period*10;

  Testnum <= x"0";
  SubTestnum <= x"0";

  reset <= '1';
  HatfieldReq <= '0';
  McCoyReq <= '0';
  wait for clk_period*10;
  reset <= '0';
  wait for 10 us;

  --Slow
  Testnum <= x"1";
  SubTestnum <= x"0";

  SubTestnum <= x"0";
  HatfieldReq <= '0';
  McCoyReq <= '0';
  wait for 999 ns;

  HatfieldReq <= '1';
  McCoyReq <= '0';
  wait for 999 ns;

  SubTestnum <= x"1";
  HatfieldReq <= '0';
  McCoyReq <= '0';
  wait for 999 ns;

  HatfieldReq <= '0';
  McCoyReq <= '1';
  wait for 999 ns;

  SubTestnum <= x"2";
  HatfieldReq <= '0';
  McCoyReq <= '0';
  wait for 999 ns;

  HatfieldReq <= '1';
  McCoyReq <= '1';
  wait for 999 ns;

  --Fast
  Testnum <= x"2";
  SubTestnum <= x"0";
  HatfieldReq <= '0';
  McCoyReq <= '0';
  wait for 10 us;

  SubTestnum <= x"0";
  HatfieldReq <= '0';
  McCoyReq <= '0';
  wait for clk_period;

  HatfieldReq <= '1';
  McCoyReq <= '0';
  wait for clk_period;

  SubTestnum <= x"1";
  HatfieldReq <= '0';
  McCoyReq <= '0';
  wait for clk_period;

  HatfieldReq <= '0';
  McCoyReq <= '1';
  wait for clk_period;

  SubTestnum <= x"2";
  HatfieldReq <= '0';
  McCoyReq <= '0';
  wait for clk_period;

  HatfieldReq <= '1';
  McCoyReq <= '1';
  wait for clk_period;

  --Staggered
  Testnum <= x"3";
  SubTestnum <= x"0";
  HatfieldReq <= '0';
  McCoyReq <= '0';
  wait for 10 us;

  SubTestnum <= x"0";
  HatfieldReq <= '0';
  McCoyReq <= '0';
  wait for 999 ns;

  HatfieldReq <= '1';
  wait for clk_period;
  McCoyReq <= '0';
  wait for 999 ns;

  SubTestnum <= x"1";
  HatfieldReq <= '0';
  McCoyReq <= '0';
  wait for 999 ns;

  HatfieldReq <= '0';
  wait for clk_period;
  McCoyReq <= '1';
  wait for 999 ns;

  SubTestnum <= x"2";
  HatfieldReq <= '0';
  McCoyReq <= '0';
  wait for 999 ns;

  HatfieldReq <= '1';
  wait for clk_period;
  McCoyReq <= '1';
  wait for 999 ns;

  SubTestnum <= x"3";
  HatfieldReq <= '0';
  McCoyReq <= '0';
  wait for 999 ns;

  McCoyReq <= '1';
  wait for clk_period;
  HatfieldReq <= '1';
  wait for 999 ns;

  --Switched
  Testnum <= x"4";
  SubTestnum <= x"0";
  HatfieldReq <= '0';
  McCoyReq <= '0';
  wait for 10 us;

  SubTestnum <= x"0";
  HatfieldReq <= '0';
  McCoyReq <= '0';
  wait for 999 ns;

  McCoyReq <= '1';
  wait for clk_period;
  HatfieldReq <= '1';
  wait for clk_period;
  McCoyReq <= '0';
  wait for 999 ns;

  SubTestnum <= x"1";
  HatfieldReq <= '0';
  McCoyReq <= '0';
  wait for 999 ns;

  HatfieldReq <= '1';
  wait for clk_period;
  McCoyReq <= '1';
  wait for clk_period;
  HatfieldReq <= '0';
  wait for 999 ns;

  --Nuts
  Testnum <= x"5";
  SubTestnum <= x"0";
  HatfieldReq <= '0';
  McCoyReq <= '0';
  wait for 10 us;

  SubTestnum <= x"0";
  HatfieldReq <= '1';
  McCoyReq <= '1';
  wait for clk_period;

  SubTestnum <= x"1";
  HatfieldReq <= '0';
  McCoyReq <= '1';
  wait for clk_period;

  SubTestnum <= x"2";
  HatfieldReq <= '1';
  McCoyReq <= '0';
  wait for clk_period;

  SubTestnum <= x"3";
  HatfieldReq <= '1';
  McCoyReq <= '1';
  wait for clk_period;

  SubTestnum <= x"4";
  HatfieldReq <= '0';
  McCoyReq <= '0';
  wait for clk_period;

  SubTestnum <= x"5";
  HatfieldReq <= '1';
  McCoyReq <= '0';
  wait for clk_period;

  SubTestnum <= x"6";
  HatfieldReq <= '1';
  McCoyReq <= '1';
  wait for clk_period;

  SubTestnum <= x"7";
  HatfieldReq <= '0';
  McCoyReq <= '1';
  wait for clk_period;

  SubTestnum <= x"8";
  HatfieldReq <= '1';
  McCoyReq <= '1';
  wait for clk_period;

  SubTestnum <= x"9";
  HatfieldReq <= '0';
  McCoyReq <= '0';
  wait for clk_period;


  wait for 999 ns;

  wait;

   end process;

END;
Posted by Steve Franks (Guest)
on 2009-03-28 09:22
(Received via mailing list)
Um, sorry, named two variables the same name.  In this case, the bug
should have been a multisource, I think.  The files below shouldn't
compile, should they (they appear to on my system)? Let me rename
things and see if I can get the origonal problem back...

Steve
Posted by Steve Franks (Guest)
on 2009-03-28 09:35
(Received via mailing list)
Ok, here's a cleaner implementation.  Look at test3, subtest3.  Note
how we pingpong between states 3 & 5.  Somehow that's either a
problem, or I'm missing something obvious....

Steve


Mutex.vhd
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use IEEE.NUMERIC_STD.all;

entity Mutex is port
(
  clk      : in  std_logic;
  reset    : in  std_logic;

  HatfieldReq    : in  std_logic;
  McCoyReq    : in  std_logic;

  StateOut      : out std_logic_vector(3 downto 0);
  NextStateOut    : out std_logic_vector(3 downto 0);

  HatfieldGrant  : out std_logic;
  McCoyGrant  : out std_logic--;
);
end Mutex;

architecture Behavioral of Mutex is

  type states is
  (
    Check_Req,
    Issue_HatfieldGrant, Wait4_HatfieldReqDone,
    Issue_McCoyGrant, Wait4_McCoyReqDone
  );

  signal NextState  : states;
  signal CurrentState: states;

begin

  Mutex_states : process(clk, reset, CurrentState, HatfieldReq, 
McCoyReq)
  begin

    if reset = '1' then

      CurrentState <= Check_Req;
      NextState <= Check_Req;
         HatfieldGrant <= '0';
      McCoyGrant <= '0';

      StateOut <= x"0";
      NextStateOut <= x"1";

    elsif rising_edge(clk) then

      CurrentState <= NextState;

      case CurrentState is

        when Check_Req =>

          StateOut <= x"1";

          --Just to be sure
          HatfieldGrant <= '0';
          McCoyGrant <= '0';

          if HatfieldReq = '1' then

            NextState <= Issue_HatfieldGrant;
            NextStateOut <= x"2";

          else

            if McCoyReq = '1' then

              NextState <= Issue_McCoyGrant;
              NextStateOut <= x"4";

            else

              NextState <= Check_Req;
              NextStateOut <= x"1";

            end if;

          end if;

        -- Grant ARM access to resource

        when Issue_HatfieldGrant =>

          StateOut <= x"2";
          NextStateOut <= x"3";

          HatfieldGrant <= '1';
          McCoyGrant <= '0';
          NextState <= Wait4_HatfieldReqDone;

        when Wait4_HatfieldReqDone =>

          StateOut <= x"3";

          if HatfieldReq = '1' then

            NextState <= Wait4_HatfieldReqDone;

            NextStateOut <= x"3";

          else

            HatfieldGrant <= '0';
            NextState <= Check_Req;

            NextStateOut <= x"1";

          end if;

        --  End of ARM access


        -- Grant PC access to resource

        when Issue_McCoyGrant =>

          StateOut <= x"4";

          McCoyGrant <= '1';
          HatfieldGrant <= '0';
          NextState <= Wait4_McCoyReqDone;

          NextStateOut <= x"5";

        when Wait4_McCoyReqDone =>

          StateOut <= x"5";

          if McCoyReq = '1' then

            NextState <= Wait4_McCoyReqDone;

            NextStateOut <= x"5";

          else

            McCoyGrant <= '0';
            NextState <= Check_Req;

            NextStateOut <= x"1";

          end if;

        --  End of PC access

        when others =>

          StateOut <= x"F";

          NextState <= Check_Req;

      end case;

    end if;

  end process Mutex_states;

end Behavioral;

Mutex_tb.vhd
--------------------------------------------------------------------------------
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.std_logic_unsigned.all;
USE ieee.numeric_std.ALL;

ENTITY Mutex_tb IS
END Mutex_tb;

ARCHITECTURE behavior OF Mutex_tb IS

    -- Component Declaration for the Unit Under Test (UUT)

    COMPONENT Mutex
    PORT(
         HatfieldReq : IN  std_logic;
         McCoyReq : IN  std_logic;

     StateOut    : out std_logic_vector(3 downto 0);
     NextStateOut    : out std_logic_vector(3 downto 0);

         HatfieldGrant : OUT  std_logic;
         McCoyGrant : OUT  std_logic;
         clk : IN  std_logic;
         reset : IN  std_logic
        );
    END COMPONENT;

   --Inputs
   signal HatfieldReq : std_logic := '0';
   signal McCoyReq : std_logic := '0';
   signal clk : std_logic := '0';
   signal reset : std_logic := '0';

   --Outputs
   signal HatfieldGrant : std_logic;
   signal McCoyGrant : std_logic;

   -- Clock period definitions
   constant clk_period : time := 21 ns;

   --Info
   signal State : std_logic_vector(3 downto 0);
   signal NextState : std_logic_vector(3 downto 0);
   signal Testnum : std_logic_vector(3 downto 0);
   signal SubTestnum : std_logic_vector(3 downto 0);

BEGIN

  -- Instantiate the Unit Under Test (UUT)
   uut: Mutex PORT MAP (
          HatfieldReq => HatfieldReq,
          McCoyReq => McCoyReq,

      StateOut => State,
      NextStateOut => NextState,

          HatfieldGrant => HatfieldGrant,
          McCoyGrant => McCoyGrant,
          clk => clk,
          reset => reset
        );

   -- Clock process definitions
   clk_process :process
   begin
    clk <= '0';
    wait for clk_period/2;
    clk <= '1';
    wait for clk_period/2;
   end process;


   -- Stimulus process
   stim_proc: process
   begin

   -- hold reset state for 100ms.
  wait for 10 ns;
  wait for clk_period*10;

  Testnum <= x"0";
  SubTestnum <= x"0";

  reset <= '1';
  HatfieldReq <= '0';
  McCoyReq <= '0';
  wait for clk_period*10;
  reset <= '0';
  wait for 10 us;

  --Slow
  Testnum <= x"1";
  SubTestnum <= x"0";

  SubTestnum <= x"0";
  HatfieldReq <= '0';
  McCoyReq <= '0';
  wait for 999 ns;

  HatfieldReq <= '1';
  McCoyReq <= '0';
  wait for 999 ns;

  SubTestnum <= x"1";
  HatfieldReq <= '0';
  McCoyReq <= '0';
  wait for 999 ns;

  HatfieldReq <= '0';
  McCoyReq <= '1';
  wait for 999 ns;

  SubTestnum <= x"2";
  HatfieldReq <= '0';
  McCoyReq <= '0';
  wait for 999 ns;

  HatfieldReq <= '1';
  McCoyReq <= '1';
  wait for 999 ns;

  --Fast
  Testnum <= x"2";
  SubTestnum <= x"0";
  HatfieldReq <= '0';
  McCoyReq <= '0';
  wait for 10 us;

  SubTestnum <= x"0";
  HatfieldReq <= '0';
  McCoyReq <= '0';
  wait for clk_period;

  HatfieldReq <= '1';
  McCoyReq <= '0';
  wait for clk_period;

  SubTestnum <= x"1";
  HatfieldReq <= '0';
  McCoyReq <= '0';
  wait for clk_period;

  HatfieldReq <= '0';
  McCoyReq <= '1';
  wait for clk_period;

  SubTestnum <= x"2";
  HatfieldReq <= '0';
  McCoyReq <= '0';
  wait for clk_period;

  HatfieldReq <= '1';
  McCoyReq <= '1';
  wait for clk_period;

  --Staggered
  Testnum <= x"3";
  SubTestnum <= x"0";
  HatfieldReq <= '0';
  McCoyReq <= '0';
  wait for 10 us;

  SubTestnum <= x"0";
  HatfieldReq <= '0';
  McCoyReq <= '0';
  wait for 999 ns;

  HatfieldReq <= '1';
  wait for clk_period;
  McCoyReq <= '0';
  wait for 999 ns;

  SubTestnum <= x"1";
  HatfieldReq <= '0';
  McCoyReq <= '0';
  wait for 999 ns;

  HatfieldReq <= '0';
  wait for clk_period;
  McCoyReq <= '1';
  wait for 999 ns;

  SubTestnum <= x"2";
  HatfieldReq <= '0';
  McCoyReq <= '0';
  wait for 999 ns;

  HatfieldReq <= '1';
  wait for clk_period;
  McCoyReq <= '1';
  wait for 999 ns;

  SubTestnum <= x"3";
  HatfieldReq <= '0';
  McCoyReq <= '0';
  wait for 999 ns;

  McCoyReq <= '1';
  wait for clk_period;
  HatfieldReq <= '1';
  wait for 999 ns;

  --Switched
  Testnum <= x"4";
  SubTestnum <= x"0";
  HatfieldReq <= '0';
  McCoyReq <= '0';
  wait for 10 us;

  SubTestnum <= x"0";
  HatfieldReq <= '0';
  McCoyReq <= '0';
  wait for 999 ns;

  McCoyReq <= '1';
  wait for clk_period;
  HatfieldReq <= '1';
  wait for clk_period;
  McCoyReq <= '0';
  wait for 999 ns;

  SubTestnum <= x"1";
  HatfieldReq <= '0';
  McCoyReq <= '0';
  wait for 999 ns;

  HatfieldReq <= '1';
  wait for clk_period;
  McCoyReq <= '1';
  wait for clk_period;
  HatfieldReq <= '0';
  wait for 999 ns;

  --Nuts
  Testnum <= x"5";
  SubTestnum <= x"0";
  HatfieldReq <= '0';
  McCoyReq <= '0';
  wait for 10 us;

  SubTestnum <= x"0";
  HatfieldReq <= '1';
  McCoyReq <= '1';
  wait for clk_period;

  SubTestnum <= x"1";
  HatfieldReq <= '0';
  McCoyReq <= '1';
  wait for clk_period;

  SubTestnum <= x"2";
  HatfieldReq <= '1';
  McCoyReq <= '0';
  wait for clk_period;

  SubTestnum <= x"3";
  HatfieldReq <= '1';
  McCoyReq <= '1';
  wait for clk_period;

  SubTestnum <= x"4";
  HatfieldReq <= '0';
  McCoyReq <= '0';
  wait for clk_period;

  SubTestnum <= x"5";
  HatfieldReq <= '1';
  McCoyReq <= '0';
  wait for clk_period;

  SubTestnum <= x"6";
  HatfieldReq <= '1';
  McCoyReq <= '1';
  wait for clk_period;

  SubTestnum <= x"7";
  HatfieldReq <= '0';
  McCoyReq <= '1';
  wait for clk_period;

  SubTestnum <= x"8";
  HatfieldReq <= '1';
  McCoyReq <= '1';
  wait for clk_period;

  SubTestnum <= x"9";
  HatfieldReq <= '0';
  McCoyReq <= '0';
  wait for clk_period;


  wait for 999 ns;

  wait;

   end process;

END;
This topic is locked and can not be replied to.