karthik
karthik

Reputation: 29

Strange VHDL behavior on hardware unlike simulation

I have a simple VHDL code which has two process. The second process updates the output port m_LED based on the state CF value. In simulation I see the behavior as expected. But when I program the FPGA I noticed that, the output port m_LED is producing some random values which is not even assigned in the code. I am totally clueless from where these values are coming. Any hint will be much appreciated!

entity monitor is
Port ( 
           io_LED: in std_logic_vector(3 downto 0); 
           m_LED: out std_logic_vector(3 downto 0) 
     );
end monitor;
 
architecture Behavioral of monitor is
    type state_type is (s0, s1, s2,s3);
    signal state: state_type :=s0;
    signal nrst:std_logic:='1';
begin

Process (io_LED)
    begin 
        if (nrst= '0') then    
            state<= s0;  
        else
                case state is                       
                   when s1 =>          
                        if (io_LED = "0000") then
                            state <= s2;
                        end if;                                                                        
                    when others => state <= s0; 
                                         
                end case;            
            end if;    
    end Process;
    
    Process(io_LED)
    begin
        m_LED<="0000";
        case state is 
            when s0 =>
                m_LED<="0000";
            when s1 =>
                m_LED<="0001";
            when others => m_LED<="0000";            
        end case; 
    end Process;

end Behavioral;

Upvotes: 0

Views: 234

Answers (1)

Fra93
Fra93

Reputation: 2082

I believe that what you are doing is a very long combinational path for a state machine. State machines are better implemented using a register to actually keep the state.

The downside is that you will need to provide a clock for the state register to sample the input and launch the output.

Changes:

  • CF is made as a register CF_r, to hold the state.\
  • First process is a sequential process, with the CF_r register holding the code { i, t, f,e } as defined by the input.
  • CF is the only element in the second process sensitivity list as it is a combinational output based only on the state.

-- Synchronous reset
    entity monitor is
    Port ( 
               io_LED: in std_logic_vector(3 downto 0); 
               monit_LED: out std_logic_vector(3 downto 0) 
         );
    end monitor;
     
    architecture Behavioral of monitor is
        type Code is (i, t, f,e);
        signal CF_r: Code:=i;
        signal nrst:std_logic:='1';
    begin

    -- Synchronous reset
    Process (clk)
        begin 

            if rising_edge(clk) then
                if (nrst= '0') then    --should be adapted to postive logic
                    CF_r <= t;  --reset
                else
                    case CF_r is                       
                       when i =>          
                            if (io_LED = "0000") then
                                CF_r <= t;
                            end if;
                        
                       when t =>
                            if (io_LED = "0001") then
                                CF_r <= f;
                            else 
                                CF_r <=e;
                            end if;
                            
                        when f =>
                            if (io_LED = "0010") then
                                CF_r <= t;   
                            else 
                                CF_r <=e;
                            end if;
                            
                        when others => CF_r <= i; 
                    end case;
                end if;            
            end if;    
        end Process;
        
        -- The output depends only on the state
        Process(CF_r)
        begin
            case CF_r is 
                when i =>
                    monit_LED<="0000";
                when t =>
                    monit_LED<="0001";
                when f =>
                    monit_LED<="0010";
                when e =>
                    monit_LED<="1111";
                when others => monit_LED<="0000";            
            end case; 
        end Process;

    end Behavioral;

Upvotes: 2

Related Questions