VHDL code works well in ModelSim and strange behavior in Altera FPGA

fpgaintel-fpgavhdl

I'm trying to understand a strange (for me) behavior of a simple VHDL code. I have realized a stupid code that works well in ModelSim and doesn't work in a real FPGA (Altera MAX 10).

Library IEEE;
use IEEE.std_logic_1164.all; 

entity test is
port( CLOCK_50:     in std_logic;
        SGN_IN:     in std_logic;
        RESET:      in std_logic;
        SGN_OUT:    out std_logic
        );
end test;

architecture beha of test is
   type state is (ST0, ST1);
   signal NEXT_STATE, PRESENT_STATE: state := ST0;
   signal Y: std_logic := '0';
begin

listen: process(SGN_IN) is
begin   
    case PRESENT_STATE is
        when ST0 =>
            NEXT_STATE <= ST1;
            Y <= '0'; 
        when ST1 =>
            NEXT_STATE <= ST0;
            Y <= '1'; 
    end case;
end process listen;

state_output: process(CLOCK_50) 
begin   
    if(rising_edge(CLOCK_50)) then
        if(RESET = '1') then
            PRESENT_STATE <= ST0;
            SGN_OUT <= '0';
        else
            PRESENT_STATE <= NEXT_STATE;
            SGN_OUT <= Y;
        end if;
    end if;
end process state_output;
end architecture beha;

In simulation, the process 'listen' is triggered every time 'SGN_IN' changes. The trigger changes 'NEXT_STATE' and the output 'Y'. If 'SGN_IN' is idle the process is never executed and the output doesn't change.
In FPGA the process 'listen' is executed independently of the 'SGN_IN' signal and the output signal 'SGN_OUT'changes at a frequency equal to \$F_{clk\_50}/2\$ (half the frequency clock).

Could you, please, explain me the reasons of this behavior? And why in the simulation everything works well?

Thank you

Best Answer

There are several problems in your code:

1)
PRESENT_STATE is not in the sensitivity list of process listen. It should be, otherwise the simulation gives you other results as in hardware.

2) SGN_IN is not an input of your FSM. There is no transition that depends on this signal. Listing signals in the sensitivity list does not promote them to inputs. This list is just for simulators and ignored by synthesis tools.

3) Because you are using SGN_IN in the sensitivity list it seams to work correctly in simulation, but this is just the luck of 2 errors resulting in the correct simulation result :). Your FSM would also transition if SGN_IN is changed to X or L, because the signal changed, but I assume you want to check for 1-0/0-1 transitions, am I right?

listen: process(PRESENT_STATE, SGN_IN) is
begin
  NEXT_STATE <= PRESENT_STATE;
  Y          <= '0';

  case PRESENT_STATE is
    when ST0 =>
      if (SGN_IN = '1') then
        NEXT_STATE <= ST1;
      end if;
    when ST1 =>
      Y <= '1'; 
      if (SGN_IN = '0') then
        NEXT_STATE <= ST0;
      end if;
  end case;
end process listen;
Related Topic