VHDL FSM problem, need help!

Discussion in 'VHDL' started by ro888, Apr 29, 2008.

  1. ro888

    ro888

    Joined:
    Apr 13, 2008
    Messages:
    1
    I am designing a VDHL interface for communction between A and B.

    A is running at unkown frequency, but much slower than B(let's say 5Mhz)

    B is running at 50 Mhz.

    I am using a FSM to do a strobe detection.

    The bit pattern is written to the data_in_val0 when state = WAIT_RISING
    The bit pattern is written to the data_in_val1 when state = WAIT_RETURN

    data_in_val0 and data_in_val1 will be compared when state = DATA_READY

    As DATA_READY only occurs in one cycle period, this make sure the output will have a one cycle period as well.

    However, it doesn't work at all. When state = DATA_READY, it gives me some pattern like "000000X" when data_in_val0 and data_in_val1 = "0000001".

    Could any body tell me if there is any other better way to archieve an output of only one clock cycle duration.

    Code:
    library IEEE;
    use IEEE.STD_LOGIC_1164.ALL;
    use IEEE.STD_LOGIC_ARITH.ALL;
    use IEEE.STD_LOGIC_UNSIGNED.ALL;
    
    entity fsm is
      port (clk   : in std_logic;
            reset : in std_logic;
    	   data_in : in std_logic_vector(7 downto 0);
    	   data_out: out std_logic_vector (6 downto 0)
    			);
    end fsm;
    
    
    architecture Behavioral of FSM is
    
    -- state machine
    type state_type is (WAIT_RISING, WAIT_RETURN, DATA_READY);
    signal state, next_state: state_type;
    signal strobe: std_logic_vector (0 downto 0);
    signal data_in_val0: std_logic_vector (6 downto 0);
    signal data_in_val1: std_logic_vector (6 downto 0);
    
    begin    
    	
    	
       --state register
        SYNC_PROC: process (clk, reset)
        begin
           if (reset='1') then
    			data_in_val0 <= "0000000";
    			data_in_val1 <= "0000000";
    			data_out <= "0000000";
    			strobe <= "0";
             state <= WAIT_RISING;	
           elsif (clk'event and clk = '1') then
    			strobe <= data_in (7 downto 7);
             state <= next_state;
           end if;
        end process;
     
       --next state logic
        COMB_PROC: process (state,strobe)
        begin
    		
           case state is
    
                when WAIT_RISING =>
    		    if strobe = "1" then 
                       next_state <= WAIT_RETURN;	--TRUE
    		    else
                       next_state <= WAIT_RISING;	--FALSE
    		    end if;
    
                when WAIT_RETURN =>
    		    if strobe = "0" then 
                       next_state <= DATA_READY;		--TRUE
    		    else
                       next_state <= WAIT_RETURN;	--FALSE
    		    end if;
    
                when DATA_READY =>
                       next_state <= WAIT_RISING;
    	
    
                when others =>
    		    next_state <= WAIT_RISING;
    
           end case;
        
        end process;
    
    	--input comparision logic
    	COMP:process (state)
    	begin
    
    		if (state = WAIT_RISING) then
    			data_in_val0(6 downto 0) <= data_in(6 downto 0);
    		else
    			data_in_val0(6 downto 0) <= "ZZZZZZZ";
    		end if;
    		
    		if (state = WAIT_RETURN) then
    			data_in_val1(6 downto 0) <= data_in(6 downto 0);
    		else
    			data_in_val1(6 downto 0) <= "ZZZZZZZ";
    		end if;
    		
    		if (state = DATA_READY) then
    			if ((data_in_val0 - data_in_val1)="0000000") then
    
    				data_out <= data_in(6 downto 0);
    			else
    				data_out <= "XXXXXXX";
    			end if;
    		end if;
    
    	end process;
    
    end Behavioral;
     
    ro888, Apr 29, 2008
    #1
    1. Advertising

  2. ro888

    jcayer

    Joined:
    Apr 25, 2007
    Messages:
    4
    Location:
    Canada
    Are you trying to make sure that the data is metastable?

    If so, use 2 sequential clocked flip-flops to capture edge of strobe and then latch data.

    dualFF : process(reset, clk)
    begin
    -- async and wan to capture rising edge with 20ns pulse
    if (reset = '1') then
    strobe1 <= '0';
    strobe2 <= '0';
    elsif (rising_edge(clk)) then
    strobe1 <= data_in(7);
    strobe2 <= data_in(7) and not strobe1;
    end if;
    end process dualFF;


    latchData : process (reset, clk)
    begin
    if(reset = '1') then
    data_out <= (others => '0'); --sets vector to all zeros regardless of lenght
    elsif (risign_edge(clk)) then
    elsif(strobe2 = '1') then
    data_out <= data_in(6 downto 0);
    end if;
    end if;
    end process latchData;
     
    jcayer, Apr 30, 2008
    #2
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. msd
    Replies:
    1
    Views:
    572
    Mike Treseler
    Feb 22, 2005
  2. Bigyellow

    FSM in VHDL

    Bigyellow, May 12, 2005, in forum: VHDL
    Replies:
    8
    Views:
    11,734
    psycoclan1
    May 29, 2010
  3. Joh
    Replies:
    4
    Views:
    468
    Mike Maxwell
    Sep 3, 2004
  4. afd
    Replies:
    1
    Views:
    8,414
    Colin Paul Gloster
    Mar 23, 2007
  5. MM
    Replies:
    3
    Views:
    1,510
    Mike Treseler
    May 15, 2007
Loading...

Share This Page