0
\$\begingroup\$

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

\$\endgroup\$

1 Answer 1

2
\$\begingroup\$

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;
\$\endgroup\$
2
  • \$\begingroup\$ Understood!! As golden rule, is it possible assert that every signal present in sensitivity list must be read inside the process otherwise the process is ignored by the synthesis tools? (indeed in my code the process is ignored and the case is synthesized as concurrent statement). \$\endgroup\$
    – Alessio
    Jun 21, 2015 at 9:31
  • \$\begingroup\$ @Alessio No. Synthesis tools ignore the sensitivity list. They just look which signals are used. But your process does not use ` SGN_IN`, so it's ignored. Due to your process descriptions, synthesis infered a toggle FlipFlop. Sensitivity lists are needed for simulation. Simulators just look for listed signals, because this list is mostly shorter than the list of used signals in a process. This restriction speeds up your simulation. \$\endgroup\$
    – Paebbels
    Jun 21, 2015 at 18:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.