OpenCores
URL https://opencores.org/ocsvn/core1990_interlaken/core1990_interlaken/trunk

Subversion Repositories core1990_interlaken

[/] [core1990_interlaken/] [trunk/] [gateware/] [sources/] [interlaken/] [receiver/] [decoder.vhd] - Rev 11

Compare with Previous | Blame | View Log

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
 
entity Decoder is
    port(
        Clk             : in std_logic;                     -- Clock input
        Reset		    : in std_logic;					 -- Reset decoder
        Data_In         : in std_logic_vector(66 downto 0); -- Data input
        Decoder_En      : in std_logic;                     -- Enables the decoder
        Data_Valid_In   : in std_logic;
        Data_Valid_Out  : out std_logic;
        Data_Out        : out std_logic_vector(66 downto 0);-- Decoded 64-bit output
        Data_Control    : out std_logic;                    --	Indicates whether the word is data or control
 
        Sync_Locked  : out std_logic;
        Sync_Error	 : out std_logic;
        Bitslip      : out std_logic
    );
end entity Decoder;
 
architecture Decoding of Decoder is
    type state_type is (IDLE, SYNC, LOCKED);
	signal pres_state, next_state : state_type;
 
	signal Data_T1, Data_T2, Data_T3 : std_logic_vector(66 downto 0);
	--shared variable Sync_ChangeCounter : integer range 0 to 65; -- Counts common bit changes
 
	signal Data_Valid_P1, Data_Valid_P2, Data_Valid_P3 : std_logic;
	signal Data_P1, Data_P2, Data_P3 : std_logic_vector(66 downto 0);
	signal Sync_Transition_Location : integer := 0;
	signal Sync_Search : std_logic;
	signal Sync_Counter, Word_Counter : integer range 0 to 65;
	signal Sync_Error_Counter : integer range 0 to 17;
	signal Trans_result : integer range 0 to 65;
begin
 
    input : process (Clk, Reset) is --Input registers/pipelining
    begin 
        if (Reset = '1') then
            Data_P1 <= (others => '1');
            Data_P2 <= (others => '1');
            Data_P3 <= (others => '1');
        elsif (rising_edge(clk)) then
            Data_P3 <= Data_P2;
            Data_P2 <= Data_P1;
 
            Data_Valid_P3 <= Data_Valid_P2;
            Data_Valid_P2 <= Data_Valid_P1;
 
            if (Data_Valid_In = '1') then
                Data_P1(66 downto 64) <= Data_In(66 downto 64);
                Data_P1(63 downto 0) <= Data_In(63 downto 0);
                Data_Valid_P1 <= '1';
            else
                Data_P1 <= Data_P1;
                Data_Valid_P1 <= '0';
            end if;
        end if;
    end process input;
 
    transitions : process (Clk, Reset) is -- Detect transitions to locate the preamble
	begin
        if (Reset = '1') then
			Data_T1 <= (others => '1');
			Data_T2 <= (others => '1');
        elsif (rising_edge(clk)) then
 
            for i in 66 downto 1  loop      -- Indicates bit transitions of incoming data
                Data_T1(i) <= (Data_P1(i) xor Data_P1(i-1));
            end loop;
            Data_T1(0) <= '0';              -- Last bit must be zero
 
            Data_T2 <= Data_T1 and Data_T2; -- Loop and compare to new data, only the transitions always occuring will be left
 
            if Data_T1 = (Data_T1'range => '0') or Data_T2 = (Data_T2'range => '0') then
                Data_T2 <= (others => '1');
            end if;
 
        end if;
    end process transitions;
 
    synchronize : process (Clk, Reset, Sync_Search, Data_T2) is --Locate the preamble according to the detected transitions
        variable Sync_TransitionCounter: integer range 0 to 65 := 0; -- Counts common bit transitions
    begin
        if (Reset = '1') then
            Sync_TransitionCounter := 0;
        elsif (rising_edge(clk)) then
            Sync_TransitionCounter := 0;
            if (Sync_Search = '1') then
                Sync_TransitionCounter := 0;
 
                for j in 66 downto 0  loop  -- Count transitions that occur
                    if(Data_T2(j) = '1') then
                        Sync_TransitionCounter := Sync_TransitionCounter + 1;
                        Sync_Transition_Location <= j;
                    else
                        Sync_TransitionCounter := Sync_TransitionCounter;
                    end if;
                end loop;
 
            end if;
            Trans_result <= Sync_TransitionCounter;
 
        end if;
    end process synchronize;
 
	state_register : process (clk) is
    begin
        if (rising_edge(clk)) then
            pres_state <= next_state;
        end if;
    end process state_register;
 
    state_decoder : process (pres_state, Decoder_En, Sync_Counter, Sync_Error_Counter, Trans_result, Sync_Transition_Location) is
    begin
        case pres_state is
        when IDLE =>
            if (Decoder_En = '1' and Trans_result < 67) then
                next_state <= SYNC;
            else
                next_state <= IDLE;
            end if;
        when SYNC =>
            if(Sync_Counter >= 63 and Trans_result = 1 and Sync_Transition_Location = 65) then
                next_state <= Locked;
            elsif (Trans_result = 0) then
                next_state <= IDLE;
            else
                next_state <= SYNC;
            end if;
        when LOCKED =>
            if (Sync_Error_Counter > 14) then
                next_state <= IDLE;
            else
                next_state <= LOCKED;
            end if;
        when others =>
            next_state <= IDLE;
        end case;
    end process state_decoder;
 
    output : process (pres_state, clk) is
        variable Data_Temp : std_logic_vector(63 downto 0);
        variable Data_Lock : std_logic_vector(66 downto 0);
        variable Data_Header : std_logic_vector(2 downto 0);
        variable shift_timeout : integer range 0 to 63;
    begin
        if rising_edge(clk) then
            Bitslip <= '0';
            case pres_state is
            when IDLE =>
                Sync_Error <= '0';
                Sync_Locked <= '0';
                Sync_Search <= '1';
                Sync_Counter <= 0;
                Data_Control <= '0';
                Data_T3 <= (others => '0');
                Data_Lock := (others => '0');
                Data_Out <= (others => '0');
 
--                if (Decoder_En = '1' and Sync_TransitionCounter < 67) then
--                   Sync_Counter <= 1;
--                end if;
 
            when SYNC =>
             if (Data_Valid_In = '1') then
                Sync_Counter <= Sync_Counter + 1; --Count sync words passed
                if(Sync_Counter >= 63 and Trans_result = 1 and Sync_Transition_Location = 65) then
                    Data_Lock := Data_T2;   -- If decoder goes in lock, data including bit position will be saved
                    Sync_Counter <= 0 ;     -- Reset counter after changing state
                    Sync_Locked <= '1';
                    Sync_Search <= '0';
                    Data_Control <= '1';
                    Data_T3 <= Data_Lock and Data_T1;
                elsif (Trans_result = 0) then
                    Sync_Error <= '1';
                end if;
 
                if (Sync_Transition_Location /= 65) then
                    if(shift_timeout = 0) then
                        Bitslip <= '1';
                        shift_timeout := 63;
                    else
                        shift_timeout := shift_timeout - 1;
                        Bitslip <= '0';
                    end if;
                else
                    Bitslip <= '0';
                end if;
             end if;
            when LOCKED =>
                Sync_Locked <= '1';
                Sync_Error <= '0';
                Word_Counter <= Word_Counter + 1; -- Count data words passed
 
                Data_T3 <= Data_Lock and Data_T1;
 
                if(Data_T3(Sync_Transition_Location) = '0') then
                    Sync_Error_Counter <= Sync_Error_Counter + 1;
                    Sync_Error <= '1';
                    Data_out <= (others => '0');
                    Data_Header := "010";
                else
                    --Change to P2!!!
                    Data_Temp := Data_P3(63 downto 0);
                    Data_Header := Data_P3(66 downto 64);
                end if;
 
                Data_Valid_Out <= Data_Valid_P3;
 
                if (Data_Header(2) = '1') then -- Read inversion bit
                    Data_Out(63 downto 0) <= not(Data_Temp(63 downto 0));
                else
                    Data_Out(63 downto 0) <= Data_Temp(63 downto 0);
                end if;
                Data_Out(66 downto 64) <= Data_Header;
 
                if(Data_Header(1) = '1') then -- Read control word bit
                    Data_Control <= '1';
                else
                    Data_Control <= '0';
                end if;
 
                if (Sync_Error_Counter > 14) then -- Rest error counter after 16 errors
                    Sync_Locked <= '0';
                    Sync_Error_Counter <= 0;
                end if;
 
                if (Word_Counter > 63) then -- Reset word and error counters after 64 passed words
                    Word_Counter <= 1;
                    Sync_Error_Counter <= 0;
                end if; 
            end case;
        end if;
    end process output;
 
end architecture Decoding;

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.