This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TLK1501 or TLK2501 Initialization and synchronization VHDL source file

Other Parts Discussed in Thread: TLK1501

hi i designed a board using one TLK1501 SerDes in every side.an A3P125 FPGA is connected to every device and is responsible for initialize and send and receive data to and from SerDes.i could not understand from datasheet that how to initialize and send data by TLK1501.so can anyone help me by a VHDL source file?

  • Hi Hassan,

    The TLK1501 is hardware controlled so as long as you put the device in the proper state the TLK1501 will automatically receive your data, encode it and ship it out. What is the current configuration of your control pins on the device?

    Regards,

    Mike

  • Hi,

    Thanks for your attention to my request.

    I have two VHDL source file  for every side of my link . however i have transmit and receive in both side of link , because the data payload from one side to another is more than other side , one program is called TRANSMITTER and the other is called RECEIVER.

    Here i put the Transmitter and receiver program and hope that it be communicative for you.

    -- Transmitter.vhd
    library IEEE;
    use IEEE.STD_LOGIC_1164.ALL;
    use IEEE.STD_LOGIC_ARITH.ALL;
    use IEEE.STD_LOGIC_UNSIGNED.ALL;

    entity Transmitter is
    port(   XTALCLKIN : in std_logic;
            --TLK2501 Serializer/Deserializer
            GTX_CLK : out std_logic;
            DI : out std_logic_vector(15 downto 0);
            TX_EN : out std_logic;
            LOOPEN : out std_logic;
            TX_ER : out std_logic;
            ENABLE : out std_logic;
            PRBSEN : out std_logic;
            TESTEN : out std_logic;
            
            DO : in std_logic_vector(3 downto 0);
            LCKREFN : out std_logic;
            RX_ER : in std_logic;
            RX_DV : in std_logic;
            RXCLK : in std_logic;        
            --Camera Link signals
            PCLK : in std_logic;
            LCLK : in std_logic;
            FCLK : in std_logic;
            CLDATA : in std_logic_vector(11 downto 0);
            CLTXD : out std_logic;
            CLRXD : in std_logic;
            --Analog Camera1 signals
            C1DATA : in std_logic_vector(9 downto 0);
            C1CLK : out std_logic;
            C1COMPSYNC : in std_logic;
            --Analog Camera2 signals
            C2DATA : in std_logic_vector(9 downto 0);
            C2CLK : out std_logic;
            C2COMPSYNC : in std_logic;
            --One Serial RS422 signals                 
            TX1 : out std_logic;
            RX1 : in std_logic;
            --Two Serial RS232 signals
            TXD1 : out std_logic;
            TXD2 : out std_logic;
            RXD1 : in std_logic;
            RXD2 : in std_logic;
            --Micro Controller signals
            UCTXD : in std_logic;
            UCRXD : out std_logic;
            XTAL1 : out std_logic;
            
            LED1 : out std_logic;
            LED2 : out std_logic;
            LED3 : out std_logic                        
        );        
    end Transmitter;

    architecture behave of Transmitter is

        signal TraClk : std_logic;
        
        signal LineClkOld : std_logic;    
        signal LineClkSync : STD_LOGIC;
        signal PixelClock : STD_LOGIC;
        signal FrameClk : STD_LOGIC;
        
        signal Rst : std_logic;
        signal RstCtr : integer range 0 to 65535;
        signal PllIntLock : std_logic;
        signal AnaCam1Data : std_logic_vector(9 downto 0);
        signal AnaCam2Data : std_logic_vector(9 downto 0);
        signal SendDataType : integer range 0 to 3;
        signal ClkUC : std_logic;
        signal DataValid : std_logic;
        signal sendState : integer range 0 to 7;
        signal RecAdr : integer range 0 to 3;
        signal RecState : std_logic_vector(1 downto 0);
        signal RecStateForSend : std_logic_vector(1 downto 0);
        signal Tra_RecState : std_logic_vector(1 downto 0);        --transmitter receive state
        
        signal BufWriData : std_logic_vector(12 downto 0);    
        signal BufReadData : std_logic_vector(12 downto 0);
        signal BufWriEna : std_logic;
        signal BufReadEna : std_logic;    
        signal BufReadClk : std_logic;
        signal BufReadCtr : integer range 0 to 1023;
        signal BufRst : std_logic;
        signal BufFull : std_logic;
        signal SerDesPllStartUpDly : integer range 0 to 4095;
        signal SerDesPllStartUp : std_logic;
        
        signal Tx1Rec : STD_LOGIC;
        signal Tx2Rec : STD_LOGIC;
    --=======================================================================================
    component PllCore is
        port(    POWERDOWN, CLKA : in std_logic;  LOCK, GLA, GLB : out std_logic);
    end component;
    --=======================================================================================
    component CamBuf is
        port(     DATA : in std_logic_vector(12 downto 0); Q : out std_logic_vector(12 downto 0);
                WE, RE, WCLOCK, RCLOCK : in std_logic; FULL, EMPTY : out std_logic;
                  RESET : in std_logic; AEMPTY, AFULL : out std_logic);
    end component;
    --=======================================================================================
    begin
        
        pll1 : PllCore
        port map (POWERDOWN => '0',
                       CLKA => XTALCLKIN,
                    LOCK => PllIntLock,
                       GLA => TraClk,            --80MHZ for Serializer clock
                       GLB => ClkUC);            --8MHZ for Microcontroller clock
    --=======================================================================================                
        CameraBuffer : CamBuf
        port map (DATA => BufWriData,                
                    Q => BufReadData,
                    WE => BufWriEna,                
                    RE => BufReadEna,
                    WCLOCK => PixelClock,
                    RCLOCK => BufReadClk,
                    FULL => open,
                    EMPTY => open,
                    RESET => BufRst,
                    AEMPTY => open,
                    AFULL => BufFull);
    --=======================================================================================
        GTX_CLK <= TraClk;                --Transmitter clock
        LOOPEN <= '0';                    --When LOOPEN is active high, the internal loop-back path is activated.
        TX_ER <= '0';                    --When TX_ER is deasserted with TX_EN asserted, indicates that normal data is being presented.
        PRBSEN <= '0';                    --When PRBSEN = low (deasserted), RX_ER/PRBS_PASS is used to indicate receive error (RX_ER).
        TESTEN <= '0';                    --This terminal should be left unconnected or tied low.
        
        LCKREFN <= '1';                    --When LCKREFN is deasserted high, the receiver is locked to the received data stream and must receive valid codes from the synchronization state machine
        --********************************
        TX1 <= Tx1Rec;
        TXD1 <= Tx2Rec;
        --//////////////////
        TXD2 <= UCTXD;    --//
        UCRXD <= RXD2;    --//
        --//////////////////
    --    LED1 <= DataValid;
    --    LED2 <= not Tx1Rec;
        
        BufWriData <= FCLK & CLDATA;
        BufWriEna <= LCLK and Rst and (not BufFull);    
        PixelClock <= PCLK and Rst;
        
    --    AnaCam1Data <= C1DATA;
        AnaCam1Data <= "1111100000";
    --    AnaCam2Data <= C2DATA;
        AnaCam2Data <= "0000011111";
        XTAL1 <= ClkUC;
        ENABLE <= Rst;    
    --#######################################################################################  
        process(PllIntLock,ClkUC)
        begin
            if PllIntLock = '0' then
                Rst <= '0';
                RstCtr <= 0;
            elsif ClkUC'event and ClkUC = '1' then
                if RstCtr < 65535 then
                    RstCtr <= RstCtr + 1;
                else
                    Rst <= '1';
                end if;
            end if;
        end process;
    --#######################################################################################    
        process(Rst,ClkUC)
        begin
            if Rst = '0' then
                SerDesPllStartUpDly <= 0;
                SerDesPllstartUp <= '0';
            elsif ClkUC'event and ClkUC = '1' then
                if SerDesPllStartUpDly < 4095 then
                    SerDesPllStartUpDly <= SerDesPllStartUpDly + 1;
                else
                    SerDesPllstartUp <= '1';
                end if;
            end if;
        end process;
    --#######################################################################################    
    --Make clocks for read camera link buffer and ADCs conversion start
        process(Rst,TraClk)
        begin
            if Rst = '0' then            
                BufReadClk <= '0';
                C1CLK <= '0';
                C2CLK <= '0';
                SendDataType <= 0;            
            elsif TraClk'event and TraClk = '1' then
                case SendDataType is
                    when 0 =>
                        BufReadClk <= '1';
                        C1CLK <= '0';
                        C2CLK <= '1';
                        SendDataType <= 1;
                    
                    when 1 =>
                        BufReadClk <= '0';
                        SendDataType <= 2;
                    
                    when 2 =>
                        BufReadClk <= '1';
                        C1CLK <= '1';
                        C2CLK <= '0';
                        SendDataType <= 3;
                        
                    when 3 =>
                        BufReadClk <= '0';
                        SendDataType <= 0;
                    when others =>
                        null;
                end case;
            end if;
        end process;
    --#######################################################################################    
        process(Rst,BufReadClk)
        begin
            if Rst = '0' then
                LineClkOld <= '0';
                LineClkSync <= '0';
                BufReadEna <= '0';
                BufReadCtr <= 0;
                BufRst <= '0';
            elsif BufReadClk'event and BufReadClk = '0' then
                case BufReadEna is
                    when '0' =>
                        LineClkSync <= LCLK;
                        LineClkOld <= LineClkSync;
                        if LineClkOld = '1' and LineClkSync = '0' then
                            if BufFull = '1' then
                                BufReadEna <= '1';
                            else
                                BufRst <= '0';
                            end if;
                        elsif BufRst = '0' then
                            BufRst <= '1';
                        end if;
                    
                    when '1' =>
                        BufReadCtr <= BufReadCtr + 1;                
                        if BufReadCtr = 999 then
                            BufReadCtr <= 0;
                            BufReadEna <= '0';
                        end if;
                end case;
            end if;
        end process;

    --    LED1 <= BufFull;     
    --#######################################################################################                          
    --    Process for send data to serializer    
        process(SerDesPllstartUp,TraClk)
        begin
            if SerDesPllstartUp = '0' then
                SendState <= 0;
                TX_EN <= '1';            
            elsif TraClk'event and TraClk = '0' then
    --            if SendState < 3 then
    --                SendState <= SendState + 1;
    --            elsif Tra_RecState /= "10" then
    --                SendState <= 0;
    --                TX_EN <= '0';
    --            else
    --                TX_EN <= '1';        
                    case SendDataType is
                    when 0 =>
                        DI(9 downto 0) <= AnaCam1Data;                    
                        DI(11 downto 10) <= RecStateForSend(1 downto 0);                    
                        DI(12) <= RX1;
                        DI(13) <= RXD1;
                        DI(15 downto 14) <= "00";                        --Address 0            
                    --**********************************************    
                    when 1 =>
                        if BufReadEna = '1' then                
                            DI(11 downto 0) <= BufReadData(11 downto 0);                
                            DI(12) <= '1';                                --LCLK = '1' when buffer is reading
                            DI(13) <= BufReadData(12);
                            FrameClk <= BufReadData(12);
                        else
                            DI(11 downto 0) <= "111111000000";                
                            DI(12) <= '0';                                --LCLK = '0' when buffer is reading
                            DI(13) <= FrameClk;
                        end if;    
                        DI(15 downto 14) <= "01";                        --Address 1                            
                    --**********************************************    
                    when 2 =>
                        DI(9 downto 0) <= AnaCam2Data;                    
                        DI(11 downto 10) <="11";                    
                        DI(12) <= CLRXD;
                        DI(13) <= UCTXD;
                        DI(15 downto 14) <= "10";                        --Address 2                    
                    --**********************************************    
                    when 3 =>
                        if BufReadEna = '1' then                
                            DI(11 downto 0) <= BufReadData(11 downto 0);                
                            DI(12) <= '1';                                --LCLK = '1' when buffer is reading
                            DI(13) <= BufReadData(12);
                            FrameClk <= BufReadData(12);
                        else
                            DI(11 downto 0) <= "111111000000";                
                            DI(12) <= '0';                                --LCLK = '0' when buffer is reading
                            DI(13) <= FrameClk;
                        end if;    
                        DI(15 downto 14) <= "11";                        --Address 3                    
                    --**********************************************
                    when others =>
                        null;
                    end case;
    --            end if;            
            end if;
        end process;    
    --#######################################################################################    
        --Process for receive data from deserializer
        RecAdr <= conv_integer(DO(1 downto 0));
        RecState <= RX_DV & RX_ER;
        
        process(RXCLK)
        begin
            if RXCLK'event and RXCLK = '1' then            
                RecStateForSend <= RecState;
                LED1 <= RX_DV;
                LED2 <= RX_ER;
                case RecState is
                    when "10" =>
                        DataValid <= '1';
                        case RecAdr is
                            when 0 =>                        
                                Tx1Rec <= DO(2);
                                Tx2Rec <= DO(3);
                                
                            when 1 =>
                                CLTXD <= DO(2);
    --                            UCRXD <= DO(3);
        
                            when 2 =>
                                Tra_RecState <= DO(3 downto 2);
    --                        
    --                        when 3 =>
    --                            null;
                                
                            when others =>
                                null;
                        end case;
                    --***************************    
                    when others =>            
                        DataValid <= '0';
                end case;    
            end if;
        end process;
    --#######################################################################################              
    end behave;

    -- Receiver.vhd
    library IEEE;
    use IEEE.STD_LOGIC_1164.ALL;
    use IEEE.STD_LOGIC_ARITH.ALL;
    use IEEE.STD_LOGIC_UNSIGNED.ALL;

    entity Receiver is
    port(   XTALCLKIN : in std_logic;
            --TLK1501 Serializer/Deserializer
            GTX_CLK : out std_logic;
            DI : out std_logic_vector(3 downto 0);
            TX_EN : out std_logic;
            LOOPEN : out std_logic;
            TX_ER : out std_logic;
            ENABLE : out std_logic;
            PRBSEN : out std_logic;
            TESTEN : out std_logic;
            
            DO : in std_logic_vector(15 downto 0);
            LCKREFN : out std_logic;
            RX_ER : in std_logic;
            RX_DV : in std_logic;
            RXCLK : in std_logic;
            --Camera Link signals
            PCLK : out std_logic;
            LCLK : out std_logic;
            FCLK : out std_logic;
            CLDATA : out std_logic_vector(11 downto 0);
            CLPWRDOWN : out std_logic;
            CLTXD : out std_logic;
            CLRXD : in std_logic;
            --Analog Camera1 signals
            C1DATA : out std_logic_vector(9 downto 0);
            C1CLK : out std_logic;        
            --Analog Camera2 signals
            C2DATA : out std_logic_vector(9 downto 0);
            C2CLK : out std_logic;        
            --Two Serial RS232 signals
            TXD1 : out std_logic;
            TXD2 : out std_logic;
            RXD1 : in std_logic;
            RXD2 : in std_logic;                
            --Micro Controller signals
            UCTXD : in std_logic;
            UCRXD : out std_logic;
            XTAL1 : out std_logic;
            
            LED1 : out std_logic;
            LED2 : out std_logic
    --        IDLE : out std_logic;            --Idle
    --        CAR_EXT : out std_logic;        --Carrier Extend
    --        NOR_DATA_CHR : out std_logic;    --Normal Data Character
    --        REC_ERR_PRO : out std_logic        --Receive Error Propagation
        );        
    end Receiver;

    architecture behave of Receiver is

        signal TraClk : std_logic;
        signal SendAdr : integer range 0 to 3;
        signal sendState : integer range 0 to 7;
        signal RecAdr : integer range 0 to 3;
        signal RecState : std_logic_vector(1 downto 0);    
        signal RecStateForSend : std_logic_vector(1 downto 0);
        signal Tra_RecState : std_logic_vector(1 downto 0);        --transmitter receive state
        signal SerDesPllStartUpDly : integer range 0 to 4095;
        signal SerDesPllStartUp : std_logic;
            
        signal Rst : std_logic;
        signal PllIntLock : std_logic;
        signal RstCtr : integer range 0 to 65535;
        signal ClkUC : std_logic;
        signal DataValid : std_logic;
        
        signal Txd1Tra : STD_LOGIC;
        signal Txd2Tra : STD_LOGIC;
        
        signal CLPowerDown : STD_LOGIC;
        signal PowerDownTime : integer range 0 to 1023;
    --=======================================================================================
    component PllCore is
        port(POWERDOWN, CLKA : in std_logic;  LOCK, GLA, GLB : out
            std_logic) ;
    end component;     
    --=======================================================================================
    begin
        
        pll1 : PllCore
        port map (POWERDOWN => '0',
                   CLKA => XTALCLKIN,
                   LOCK => PllIntLock,
                   GLA => TraClk,                --62.2MHZ for serializer
                   GLB => ClkUC);                --8MHZ for microcontroller
    --=======================================================================================
        GTX_CLK <= TraClk;                --Transmitter clock
        LOOPEN <= '0';                    --When LOOPEN is active high, the internal loop-back path is activated.
        TX_ER <= '0';                    --When TX_ER is deasserted with TX_EN asserted, indicates that normal data is being presented.
        PRBSEN <= '0';                    --When PRBSEN = low (deasserted), RX_ER/PRBS_PASS is used to indicate receive error (RX_ER).
        TESTEN <= '0';                    --This terminal should be left unconnected or tied low.
        
        LCKREFN <= '1';                    --When LCKREFN is deasserted high, the receiver is locked to the received data stream and must receive valid codes from the synchronization state machine
        --********************************   
        TXD1 <= Txd1Tra;
    --    TXD2 <= Txd2Tra;
        --//////////////
        TXD2 <= UCTXD;
        UCRXD <= RXD2;
        --//////////////    
    --    LED2 <= not Txd1Tra;
        
    --    CLDATA <= DO(11 downto 0);
    --    PCLK <= CLKOUT and Rst;            --camera link pixel clock is equal to output clock of deserializer
    --    LCLK <= DO(13);
    --    FCLK <= DO(12);    
        CLPWRDOWN <= CLPowerDown;
        XTAL1 <= ClkUC;
        ENABLE <= Rst;
    --#######################################################################################
        process(PllIntLock,ClkUC)
        begin
            if PllIntLock = '0' then
                Rst <= '0';
                RstCtr <= 0;
    --            ENABLE <= '0';
            elsif ClkUC'event and ClkUC = '1' then
                if RstCtr < 65535 then
                    RstCtr <= RstCtr + 1;
    --                ENABLE <= '1';
                else
                    Rst <= '1';
                end if;
            end if;
        end process;
    --#######################################################################################    
        process(Rst,ClkUC)
        begin
            if Rst = '0' then
                SerDesPllStartUpDly <= 0;
                SerDesPllstartUp <= '0';
            elsif ClkUC'event and ClkUC = '1' then
                if SerDesPllStartUpDly < 4000 then
                    SerDesPllStartUpDly <= SerDesPllStartUpDly + 1;
                else
                    SerDesPllstartUp <= '1';
                end if;
            end if;
        end process;
    --#######################################################################################
        process(Rst,TraClk)
        begin
            if Rst = '0' then
                CLPowerDown <= '0';
                PowerDownTime <= 0;
            elsif TraClk'event and TraClk = '1' then
                if DataValid = '1' and CLPowerDown = '0' then
                    PowerDownTime <= PowerDownTime + 1;
                    if PowerDownTime = 1023 then
                        CLPowerDown <= '1';
                    end if;
                end if;
            end if;
        end process;            
    --#######################################################################################                 
        --Process for send data to serializer
        process(SerDesPllstartUp,TraClk)
        begin
            if SerDesPllstartUp = '0' then
                SendAdr <= 0;
                SendState <= 0;
                TX_EN <= '1';    
            elsif TraClk'event and TraClk = '0' then
    --            if SendState < 3 then
    --                SendState <= SendState + 1;
    --            elsif Tra_RecState /= "10" then
    --                SendState <= 0;
    --                TX_EN <= '0';                
    --            else
    --                TX_EN <= '1';                        
                    case SendAdr is
                    when 0 =>                    
                        DI(1 downto 0) <= "00";                                    
                        DI(2) <= RXD1;
                        DI(3) <= RXD2;
                        SendAdr <= 1;
                            
                    when 1 =>    
                        DI(1 downto 0) <= "01";
                        DI(2) <= CLRXD;
                        DI(3) <= UCTXD;
                        SendAdr <= 2;
                                
                    when 2 =>
                        DI(1 downto 0) <= "10";
                        DI(3 downto 2) <= RecStateForSend(1 downto 0);
                        SendAdr <= 3;
                            
                    when 3 =>    
                        DI(1 downto 0) <= "11";
                        DI(2) <= '0';
                        DI(3) <= '0';
                        SendAdr <= 0;
                    when others =>
                        null;                
                    end case;
    --            end if;                                
            end if;
        end process;
    --#######################################################################################      
        --Process for receive data from deserializer
        RecAdr <= conv_integer(DO(15 downto 14));
        RecState <= RX_DV & RX_ER;
        
        process(Rst,RXCLK)
        begin
            if Rst = '0' then
                Tra_RecState <= "00";
            elsif RXCLK'event and RXCLK = '1' then
                RecStateForSend <= RecState;
                LED1 <= RX_DV;
                LED2 <= RX_ER;
                case RecState is
                    when "10" =>                
                        DataValid <= '1';                
                        case RecAdr is
                            when 0 =>                
                                
                                Tra_RecState(1 downto 0) <= DO(11 downto 10);
                                Txd1Tra <= DO(12);
                                Txd2Tra <= DO(13);
                            --***********************************************************    
    --                        when 1 =>
                            
                                
                            --***********************************************************    
                            when 2 =>
                                
                                CLTXD <= DO(12);
    --                            UCRXD <= DO(13);                        
                            --***********************************************************
    --                        when 3 =>
                                
        
                            --***********************************************************
                            when others =>
                                null;    
                        end case;
                    when others =>
                        DataValid <= '0';
                end case;    
            end if;
        end process;
    --#######################################################################################
    end behave;

  • Hi Hassan,

    What I can see from looking through some of your VHDL is that you are partitioning the TLK1501 correctly.  Do you have access to these boards for debug? Or are you assuming the problem is in the VHDL only? 

    You can try setting the TX_EN = 0 and TX_ER = 0 so that the device continuously sends comma characters which will allow you to probe the output for some movement of data. Also, check your input clock (GTX_CLK) and make sure that you are in fact sending the TLK1501 a valid frequency for operation. Next, try probing the RX_CLK and check to see that you are recovering a valid clock. You can also probe the RX_DV/LOS pin to make sure that the device is receiving a signal. By looking at these pins you should be able to at least see if your transmitter is transmitting and if your receiver is receiving.Keep me informed on your progress.

    Regards,

    Mike

  • Hi Hassan,

    One thing I did notice while reviewing your VHDL code was that on line 111 of the transmitter portion there is a comment about an 80MHz serializer clock. The TLK1501 requires a clock between 30 and 75MHz. So I cannot comment on the operation of the IC beyond its data sheet specs. Try reducing that and see if it helps.

    Regards,

    Mike

  • hi Michael,

    Before every thing i thank you a lot of for your guidance,

    By reading the TLK1501 EVM user guide I understood that i have problems in my hardware.

    Here i write my problems for you and want you to check them and guide me in problems.

    1 - The traces length between FPGA and TLK1501 must be equal in both TXDs and RXDs lines.(what is the acceptable equality error in traces?)

    2 - The logic level of  A3P125 FPGA pins that connects to TLK1501 should be 2.5V.

    3 -  All traces between FPGA and TLK1501 must be terminated with 50 ohm resistors.(is this termination way true or i should use another termination way?)

  • Hi Hassan,

    1. The trace lengths on the TxDs should all be length matched (+/- .5 mil) to each other to meet the tSU and tH specs and the  that are identified in the data sheet and the same goes for the RxDs on the TLK1501.

    2. 2.5V will be suitable for your logic levels as the TLK1501 ranges from a minimum of 1.7V to a maximum of 3.6V.

    3. If your source and load are terminated well to each other there may be no need for a termination resistor on the TTL signal lines. If there is a mismatch between the two the best approach for TTL signals is a series resistance to make up for the impedance mismatch to minimize reflections.

    Regards,

    Mike