HDMI Input

From Hamsterworks Wiki!

Jump to: navigation, search

This FPGA Project was started in July 2014, and is currently in active development.

At the moment it can receive 720p in DVI-D format and display it on an Analogue VGA output. See a video at https://www.youtube.com/watch?v=AvHPYmEQb04

I've still got to make it automagically adjust the pixel clock phase, and implement the EDID I2C ROM.

Contents

Test setup

Here's the test setup I used during development:

Dvid in test setup.jpg

On the left is a Pipistrello acting as a HDMI source, and on the right is the Papilio Pro, receiving the HDMI signal.

And here is the initial results @ 720p:

Dvid in test errors.jpg

And once the pixel clock to bit clock phase was adjusted all the errors are gone:

Dvid in test no errors.jpg

Wing PCB Design

With the Spartan 6 FPGA you need external termination resistors if you want to receive TMDS signals - a 50 ohm resistor is needed from 3.3 V to each of the signal lines. Also the Extended Display Identification Data (EDID) interface runs at 5V logic, so a level converter is needed.

Dvid in pcb v01.jpg

The revision 0.1 PCB has an error on it, so I've got a v0.2 on its way. It is missing the 3.3V supply to the I2C level translator (D'oh!).

Should you want a PCB just drop me an email - it needs eight 50 Ohm (or slightly bigger) resistors, and an HDMI socket. If you want to use EDID support you will need to add a wire bodge to power the level translator.

I'm actually surprised that it actually worked - the three channels are running at 750 Mb/s each, and the termination resistors are quite far from the FPGA - in fact it is the other side of a 0.1" header!

PCB design files

Coming soon - they really need tidying up before publishing. However if you want them just drop me an email.

HDL Source

dvi_in.vhd

----------------------------------------------------------------------------------
-- Engineer:    Mike Field <hamster@snap.net.nz>
-- 
-- Module Name: dvi_in.vhd - Behavioral 
--
-- Description: Design to capture raw DVI-D input
--
-- REALLY IMPORTANT NOTE - on my PCB some of the + and - differential
-- pairs are transposed to allow better routing and avioding vias. 
-- You most likely want to change the value of "invert" on the gearbox 
-- instances.
--
-- I've also got do do some work to automatically adjust the phase of the
-- bit clocks, at the moment it needs to be manually tuned to match your source
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

library UNISIM;
use UNISIM.VComponents.all;

entity dvi_in is
    Port ( clk32      : in  STD_LOGIC;
           hdmi_clk_p : in  STD_LOGIC;
           hdmi_clk_n : in  STD_LOGIC;
           hdmi_c0_p  : in  STD_LOGIC;
           hdmi_c0_n  : in  STD_LOGIC;
           hdmi_c1_p  : in  STD_LOGIC;
           hdmi_c1_n  : in  STD_LOGIC;
           hdmi_c2_p  : in  STD_LOGIC;
           hdmi_c2_n  : in  STD_LOGIC;
           hdmi_sclk  : inout  STD_LOGIC;
           hdmi_sdat  : inout  STD_LOGIC;
                      
           red        : out std_logic_vector(2 downto 0);
           green      : out std_logic_vector(2 downto 0);
           blue       : out std_logic_vector(1 downto 0);
           hsync      : out std_logic;
           vsync      : out std_logic;
           
           btns       : in  std_logic_vector(3 downto 0);
           leds       : out std_logic_vector(3 downto 0));
end dvi_in;

architecture Behavioral of dvi_in is
   signal hdmi_clk             : std_logic;
   signal hdmi_clk_buffered    : std_logic;
   signal ioclock              : std_logic;
   signal serdes_strobe        : std_logic;

      
   signal clock_x1             : std_logic;
   signal clock_x2             : std_logic;
   signal clock_x10            : std_logic;
   signal clock_x10_unbuffered : std_logic;
   signal clock_x2_unbuffered  : std_logic;
   signal clock_x1_unbuffered  : std_logic;

   signal clk_feedback         : std_logic;
   signal pll_locked           : std_logic;
   signal sync_seen            : std_logic;

   signal c0_d       : std_logic_vector(7 downto 0);
   signal c0_c       : std_logic_vector(1 downto 0);
   signal c0_active  : std_logic;

   signal c1_d       : std_logic_vector(7 downto 0);
   signal c1_c       : std_logic_vector(1 downto 0);
   signal c1_active  : std_logic;

   signal c2_d       : std_logic_vector(7 downto 0);
   signal c2_c       : std_logic_vector(1 downto 0);
   signal c2_active  : std_logic;

   signal led_count   : unsigned( 2 downto 0)        := (others => '0');
   signal framing     : std_logic_vector(3 downto 0) := (others => '0');
   signal since_sync  : unsigned(14 downto 0)        := (others => '0');

   signal start_calibrate : std_logic;
   signal reset_delay     : std_logic;
   signal cal_start_count : unsigned(7 downto 0) := (others => '0');          
   
   COMPONENT input_channel
   GENERIC(
         fixed_delay     : in natural
      );
   PORT(
      clk_fabric    : IN  std_logic;
      clk_fabric_x2 : IN  std_logic;
      clk_input     : IN  std_logic;
      strobe        : IN  std_logic;
      tmds_p        : in  STD_LOGIC;
      tmds_n        : in  STD_LOGIC;
      invert        : IN  std_logic;
      framing       : IN  std_logic_vector(3 downto 0);          
      data_out      : OUT std_logic_vector(7 downto 0);
      control       : OUT std_logic_vector(1 downto 0);
      active_data   : OUT std_logic;
      sync_seen     : OUT std_logic;
           
      adjust_delay    : IN  std_logic;
      increase_delay  : IN  std_logic;
      reset_delay     : IN  std_logic;
      start_calibrate : IN  std_logic;          
      calibrate_busy  : OUT std_logic
      );
   END COMPONENT;

begin   
   ----------------------------------
   -- Output the decoded VGA signals
   ----------------------------------
   red   <= c0_d(7 downto 5);
   blue  <= c1_d(7 downto 6);
   green <= c2_d(7 downto 5);
   hsync <= c2_c(0);
   vsync <= c2_c(1);

   ----------------------------------
   -- Debug
   ----------------------------------
   leds <= framing;

   ----------------------------------
   -- EDID I2C signals (not implemented)
   ----------------------------------
   hdmi_sclk <= '1';
   hdmi_sdat <= '1';

------------------------------------------
-- Receive the differential clock
------------------------------------------
clk_diff_input : IBUFDS
   generic map (
      DIFF_TERM    => FALSE,
      IBUF_LOW_PWR => TRUE,
      IOSTANDARD   => "TMDS_33")
   port map (
      O  => hdmi_clk,
      I  => hdmi_clk_p,
      IB => hdmi_clk_n
   );
   
------------------------------------------
-- Buffer it before the PLL
------------------------------------------
BUFG_clk : BUFG port map ( I => hdmi_clk, O => hdmi_clk_buffered);

------------------------------------------
-- Generate the bit clocks for the serdes
-- 
-- Adjust the phase in a 10:2:1 ratio (e.g. 50:10:5)
------------------------------------------
PLL_BASE_inst : PLL_BASE
   generic map (
      CLKFBOUT_MULT => 10,                  
      -- Almost works with Western Digital Live @ 720p/60 -Noise on blue channel.
      --CLKOUT0_DIVIDE => 1,       CLKOUT0_PHASE => 200.0,   -- Output 10x original frequency
      --CLKOUT1_DIVIDE => 5,       CLKOUT1_PHASE => 40.0,   -- Output 2x original frequency
      --CLKOUT2_DIVIDE => 10,      CLKOUT2_PHASE => 20.0,    -- Output 1x original frequency
      -- Works with Western Digital Live @ 640x480/60Hz
      CLKOUT0_DIVIDE => 1,       CLKOUT0_PHASE => 0.0,   -- Output 10x original frequency
      CLKOUT1_DIVIDE => 5,       CLKOUT1_PHASE => 0.0,   -- Output 2x original frequency
      CLKOUT2_DIVIDE => 10,      CLKOUT2_PHASE => 0.0,    -- Output 1x original frequency
      CLK_FEEDBACK => "CLKFBOUT",                         -- Clock source to drive CLKFBIN ("CLKFBOUT" or "CLKOUT0")
      CLKIN_PERIOD => 10.0,                               -- IMPORTANT! Approx 77 MHz
      DIVCLK_DIVIDE => 1                                  -- Division value for all output clocks (1-52)
   )
      port map (
      CLKFBOUT => clk_feedback, 
      CLKOUT0  => clock_x10_unbuffered,
      CLKOUT1  => clock_x2_unbuffered,
      CLKOUT2  => clock_x1_unbuffered,
      CLKOUT3  => open,
      CLKOUT4  => open,
      CLKOUT5  => open,
      LOCKED   => pll_locked,      
      CLKFBIN  => clk_feedback,    
      CLKIN    => hdmi_clk_buffered, 
      RST      => '0'              -- 1-bit input: Reset input
   );

   BUFG_pclockx2  : BUFG port map ( I => clock_x2_unbuffered,  O => clock_x2);
   BUFG_pclock    : BUFG port map ( I => clock_x1_unbuffered,  O => clock_x1);
   BUFG_pclockx10 : BUFG port map ( I => clock_x10_unbuffered, O => clock_x10 );

  
------------------------------------------------
-- Buffer the clocks ready to go the serialisers
------------------------------------------------
BUFPLL_inst : BUFPLL
   generic map (
      DIVIDE => 5,         -- DIVCLK divider (1-8) !!!! IMPORTANT TO CHANGE THIS AS NEEDED !!!!
      ENABLE_SYNC => TRUE  -- Enable synchrnonization between PLL and GCLK (TRUE/FALSE) -- should be true
   )
   port map (
      IOCLK        => ioclock,               -- Clock used to receive bits
      LOCK         => open,                 
      SERDESSTROBE => serdes_strobe,         -- Clock use to load data into SERDES 
      GCLK         => clock_x2,              -- Global clock use as a reference for serdes_strobe
      LOCKED       => pll_locked,            -- When the upstream PLL is locked 
      PLLIN        => clock_x10_unbuffered   -- Clock to use for bit capture - this must be unbuffered
   );

----------------------------------------
-- c0 channel input - Carries the RED channel
----------------------------------------
input_channel_c0: input_channel GENERIC MAP(
      fixed_delay     => 30
    ) PORT MAP(
      clk_fabric      => clock_x1,
      clk_fabric_x2   => clock_x2,
      clk_input       => ioclock,
      strobe          => serdes_strobe,
      tmds_p          => hdmi_c0_p,
      tmds_n          => hdmi_c0_n,
      invert          => '0',
      framing         => framing,
      data_out        => c0_d,
      control         => c0_c,
      active_data     => c0_active,
      sync_seen       => open,
      adjust_delay    => '0',
      increase_delay  => '0',
      reset_delay     => reset_delay,
      start_calibrate => start_calibrate,
      calibrate_busy  => open
   );   

----------------------------------------
-- c1 channel input - Carries the BLUE channel
----------------------------------------
   
input_channel_c1: input_channel GENERIC MAP(
      fixed_delay     => 40
    ) PORT MAP(
      clk_fabric      => clock_x1,
      clk_fabric_x2   => clock_x2,
      clk_input       => ioclock,
      strobe          => serdes_strobe,
      tmds_p          => hdmi_c1_n,
      tmds_n          => hdmi_c1_p,
      invert          => '1',
      framing         => framing,
      data_out        => c1_d,
      control         => c1_c,
      active_data     => c1_active,
      sync_seen       => open,
      adjust_delay    => '0',
      increase_delay  => '0',
      reset_delay     => reset_delay,
      start_calibrate => start_calibrate,
      calibrate_busy  => open
   );   

----------------------------------------
-- c2 channel input - Carries the GREEN channel and syncs
----------------------------------------
input_channel_c2: input_channel GENERIC MAP(
      fixed_delay     => 30
    )  PORT MAP(
      clk_fabric      => clock_x1,
      clk_fabric_x2   => clock_x2,
      clk_input       => ioclock,
      strobe          => serdes_strobe,
      tmds_p          => hdmi_c2_n,
      tmds_n          => hdmi_c2_p,
      invert          => '1',
      framing         => framing,
      data_out        => c2_d,
      control         => c2_c,
      active_data     => c2_active,
      sync_seen       => sync_seen,
      adjust_delay    => '0',
      increase_delay  => '0',
      reset_delay     => reset_delay,
      start_calibrate => start_calibrate,
      calibrate_busy  => open
   );   

calibrate_preocess: process (clock_x2)
   begin
      if rising_edge(clock_x2) then
         if cal_start_count = "10000000" then
            start_calibrate <= '0';
         else
            start_calibrate <= '0';
         end if;
         if cal_start_count = "11111100" then
            reset_delay <= '0';
         else
            reset_delay <= '0';
         end if;
         
         if cal_start_count /= "11111111" then
            cal_start_count <= cal_start_count + 1;
         end if;
      end if;
   end process;
   
process(clock_x1) 
   begin
      if rising_edge(clock_x1) then
         -- Work out what we need to do to frame the TMDS data correctly
         if sync_seen = '1' then
            ------------------------------------------------------------
            -- We've just seen a sync codeword, so restart the counter
            -- This means that we are in sync
            ------------------------------------------------------------
            since_sync  <= (others => '0');
         elsif since_sync = "111111111111111" then
            ------------------------------------------------------------
            -- We haven't seen a sync in 16383 pixel cycles, so it can't 
            -- be in sync. By incrementing 'framing' we bitslip one bit.
            --            
            -- The 16k number is special, as they two sync codewords
            -- being looked for will not be seen during the VSYNC period
            -- (assuming that you are looking in the channel that 
            -- includes the encoded HSYNC/VSYNC signals 
            ------------------------------------------------------------
            if framing = "1001" then
               framing <= (others =>'0');
            else
               framing <= std_logic_vector(unsigned(framing) + 1);
            end if;
            since_sync  <= since_sync + 1;
         else
            ------------------------------------------------------------
            -- Keep counting and hoping for a sync codeword
            ------------------------------------------------------------
            since_sync  <= since_sync + 1;
         end if;

      end if;
   end process;
end Behavioral;

input_channel.vhd

----------------------------------------------------------------------------------
-- Engineer: Mike Field <hamster@snap.net.nz>
-- 
-- Module Name:    input_channel - Behavioral 
-- Description:    The end-to-end processing of a TMDS input channel
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
library UNISIM;
use UNISIM.VComponents.all;


entity input_channel is
   GENERIC(
         fixed_delay     : in natural
      );
    Port ( clk_fabric      : in  STD_LOGIC;
           clk_fabric_x2   : in  STD_LOGIC;
           clk_input       : in  STD_LOGIC;
           strobe          : in  STD_LOGIC;
           tmds_p          : in  STD_LOGIC;
           tmds_n          : in  STD_LOGIC;
           invert          : in  STD_LOGIC;
           framing         : in  std_logic_vector(3 downto 0);
           data_out        : out STD_LOGIC_VECTOR (7 downto 0);
           control         : out STD_LOGIC_VECTOR (1 downto 0);
           active_data     : out std_logic;
           sync_seen       : out std_logic;
           
           adjust_delay    : IN  std_logic;
           increase_delay  : IN  std_logic;
           reset_delay     : IN  std_logic;
           start_calibrate : IN  std_logic;          
           calibrate_busy  : OUT std_logic
);
end input_channel;

architecture Behavioral of input_channel is

   COMPONENT input_serialiser
   PORT(
      clk_fabric_x2 : IN  std_logic;
      clk_input     : IN  std_logic;
      strobe        : IN  std_logic;
      ser_input     : IN  std_logic;          
      ser_data      : OUT std_logic_vector(4 downto 0)
      );
   END COMPONENT;

   COMPONENT gearbox
   PORT(
      clk_fabric_x2 : IN  std_logic;
      framing       : IN  std_logic_vector(3 downto 0);
      invert        : IN  std_logic;
      data_in       : IN  std_logic_vector(4 downto 0);
      data_out      : OUT std_logic_vector(9 downto 0)
      );
   END COMPONENT;

   COMPONENT tmds_decode
   PORT(
      clk         : IN  std_logic;
      data_in     : IN  std_logic_vector(9 downto 0);          
      data_out    : OUT std_logic_vector(7 downto 0);
      c           : OUT std_logic_vector(1 downto 0);
      active_data : OUT std_logic
      );
   END COMPONENT;
   
   signal serial_data         : std_logic;
   signal raw_tmds_word       : std_logic_vector(9 downto 0);          
   signal half_words          : std_logic_vector(4 downto 0);          
begin

diff_input : IBUFDS
   generic map (
      DIFF_TERM    => FALSE,
      IBUF_LOW_PWR => TRUE,
      IOSTANDARD   => "TMDS_33")
   port map (
      O  => serial_data,
      I  => tmds_p,
      IB => tmds_n
   );

i_input_serialiser: input_serialiser PORT MAP(
      clk_fabric_x2 => clk_fabric_x2,
      clk_input     => clk_input,
      strobe        => strobe,
      ser_input     => serial_data,
      ser_data      => half_words
   );
   
i_gearbox: gearbox PORT MAP(
      clk_fabric_x2 => clk_fabric_x2,
      invert        => invert,
      framing       => framing,
      data_in       => half_words,
      data_out      => raw_tmds_word
   );

i_tmds_decode: tmds_decode PORT MAP(
      clk         => clk_fabric,
      data_in     => raw_tmds_word,
      data_out    => data_out,
      c           => control,
      active_data => active_data 
   );
   
look_for_sync: process (clk_fabric)
   begin
      if rising_edge(clk_fabric) then
         ------------------------------------------------------------
         -- Is the TMDS data one of two special sync codewords?
         ------------------------------------------------------------
         if raw_tmds_word = "1101010100" or raw_tmds_word = "0010101011" then
            sync_seen <= '1';
         else
            sync_seen <= '0';
         end if;
      end if;
   end process;
end Behavioral;

gearbox.vhd

This 'gearbox' takes 5-bit data at 2x the pixel clock, and converts it to 10-bit data at the pixel clock.

----------------------------------------------------------------------------------
-- Engineer: Mike Field <hamster@snap.net.nz>
--
-- Module Name:    Gearbox - Behavioral 
-- Project Name:   DVI-I Input
-- Description:  Receives the 5-bits-per-cycle data from the serialisers at twice
--               the pixel clock, then 'downshifts' the data to 10-bit words.
--
--               The 'framing' signal allows to bit-slip to different word
--               framing, allowing the design to hunt for the sync codewords.
--
-- Revision: 
-- Revision 0.01 - File Created
-- Additional Comments: 
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity gearbox is
    Port ( clk_fabric_x2 : in  STD_LOGIC;
           invert        : in  STD_LOGIC;
           framing       : in  std_logic_vector(3 downto 0);
           data_in       : in  std_logic_vector(4 downto 0);
           data_out      : out std_logic_vector(9 downto 0));
end gearbox;

architecture Behavioral of gearbox is
   signal every_other : std_logic := '0';
   signal joined      : std_logic_vector(14 downto 0);
begin

process(clk_fabric_x2) 
   begin
      if rising_edge(clk_fabric_x2) then
         if every_other = '1' then
            case framing is
               when "0000" => data_out <= joined( 9 downto 0);
               when "0001" => data_out <= joined(10 downto 1);
               when "0010" => data_out <= joined(11 downto 2);
               when "0011" => data_out <= joined(12 downto 3);
               when "0100" => data_out <= joined(13 downto 4);
               when others => NULL;
            end case;
         else
            case framing is
               when "0101" => data_out <= joined( 9 downto 0);
               when "0110" => data_out <= joined(10 downto 1);
               when "0111" => data_out <= joined(11 downto 2);
               when "1000" => data_out <= joined(12 downto 3);
               when "1001" => data_out <= joined(13 downto 4);
               when others => NULL;
            end case;
         end if;
         if invert = '1' then 
            joined <= data_in & joined(joined'high downto 5) ;
         else
            joined <= (data_in xor "11111") & joined(joined'high downto 5) ;
         end if;
         every_other <= not every_other;
      end if;
   end process;

end Behavioral;

tmds_decode.vhd

----------------------------------------------------------------------------------
-- Engineer: Mike Field <hamster@snap.net.nz>
-- 
-- Module Name:    tmds_decode - Behavioral 
--
-- Description: TMDS decode as per Digital Display Working Groups Digital Visual 
--              Interface Revision 1.0 section 3.3.3
--
-- This doesn't seem 100% correct - "elsif sometimes_inverted(8) = '0' then" should
-- be "elsif sometimes_inverted(8) = '1' then" according to the standard.
-- 
-- However it does actually work!
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity tmds_decode is
    Port ( clk         : in  STD_LOGIC;
           data_in     : in  STD_LOGIC_VECTOR (9 downto 0);
           data_out    : out  STD_LOGIC_VECTOR (7 downto 0);
           c           : out  STD_LOGIC_VECTOR (1 downto 0);
           active_data : out std_logic);
end tmds_decode;

architecture Behavioral of tmds_decode is
   signal data_delayed       : STD_LOGIC_VECTOR(9 downto 0);
   signal sometimes_inverted : STD_LOGIC_VECTOR(8 downto 0);
   signal next_c             : STD_LOGIC_VECTOR(1 downto 0);
   signal next_active_data   : STD_LOGIC;
begin
   
process(clk)
   begin
      if rising_edge(clk) then
      
         c           <= next_c;
         active_data <= next_active_data;
 
         if next_active_data = '0' then
            data_out <= (others => '0');
         elsif sometimes_inverted(8) = '0' then
            data_out(0) <= sometimes_inverted(0);
            data_out(1) <= sometimes_inverted(1) XOR sometimes_inverted(0);
            data_out(2) <= sometimes_inverted(2) XOR sometimes_inverted(1);
            data_out(3) <= sometimes_inverted(3) XOR sometimes_inverted(2);
            data_out(4) <= sometimes_inverted(4) XOR sometimes_inverted(3);
            data_out(5) <= sometimes_inverted(5) XOR sometimes_inverted(4);
            data_out(6) <= sometimes_inverted(6) XOR sometimes_inverted(5);
            data_out(7) <= sometimes_inverted(7) XOR sometimes_inverted(6);
         else
            data_out(0) <= sometimes_inverted(0);
            data_out(1) <= sometimes_inverted(1) XNOR sometimes_inverted(0);
            data_out(2) <= sometimes_inverted(2) XNOR sometimes_inverted(1);
            data_out(3) <= sometimes_inverted(3) XNOR sometimes_inverted(2);
            data_out(4) <= sometimes_inverted(4) XNOR sometimes_inverted(3);
            data_out(5) <= sometimes_inverted(5) XNOR sometimes_inverted(4);
            data_out(6) <= sometimes_inverted(6) XNOR sometimes_inverted(5);
            data_out(7) <= sometimes_inverted(7) XNOR sometimes_inverted(6);
         end if;
 
         if data_delayed(9) = '1' then
            sometimes_inverted <= data_delayed(8 downto 0) xor "011111111";
         else
            sometimes_inverted <= data_delayed(8 downto 0);
         end if;
 
         case data_in is
            when "0010101011" => next_c <= "01"; next_active_data <= '0';
            when "1101010100" => next_c <= "00"; next_active_data <= '0';
            when "0101010100" => next_c <= "10"; next_active_data <= '0';
            when "1010101011" => next_c <= "11"; next_active_data <= '0';
            when others       => next_c <= "00"; next_active_data <= '1';
         end case;
         
         data_delayed <= data_in;
      end if;
   end process;
end Behavioral;

input_serialiser.vhd

----------------------------------------------------------------------------------
-- Engineer:   Mike Field <hamster@snap.net.nz>
-- 
-- Module Name: input_serialiser 
--
-- Description: A 5-bits per cycle SDR input serialiser
--
--              Maybe in the future the 'bitslip' funciton can be implemented.
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
library UNISIM;
use UNISIM.VComponents.all;

entity input_serialiser is
    Port ( clk_fabric_x2 : in  STD_LOGIC;
           clk_input     : in  STD_LOGIC;
           strobe        : in  STD_LOGIC;
           ser_data      : out  STD_LOGIC_VECTOR (4 downto 0);
           ser_input     : in STD_LOGIC);
end input_serialiser;

architecture Behavioral of input_serialiser is
   signal clk0,     clk1,     clkdiv : std_logic;
   signal cascade : std_logic;
   signal bitslip : std_logic := '0';
begin
   clkdiv <= clk_fabric_x2;
   clk0   <= clk_input;
   clk1   <= '0';

ISERDES2_master : ISERDES2
   generic map (
      BITSLIP_ENABLE => TRUE,         -- Enable Bitslip Functionality (TRUE/FALSE)
      DATA_RATE      => "SDR",        -- Data-rate ("SDR" or "DDR")
      DATA_WIDTH     => 5,            -- Parallel data width selection (2-8)
      INTERFACE_TYPE => "RETIMED",    -- "NETWORKING", "NETWORKING_PIPELINED" or "RETIMED" 
      SERDES_MODE    => "MASTER"      -- "NONE", "MASTER" or "SLAVE" 
   )
   port map (
      CFB0      => open,      -- 1-bit output: Clock feed-through route output
      CFB1      => open,      -- 1-bit output: Clock feed-through route output
      DFB       => open,       -- 1-bit output: Feed-through clock output
      FABRICOUT => open,      -- 1-bit output: Unsynchrnonized data output
      INCDEC    => open,      -- 1-bit output: Phase detector output
      -- Q1 - Q4: 1-bit (each) output: Registered outputs to FPGA logic
      Q1        => ser_data(1),
      Q2        => ser_data(2),
      Q3        => ser_data(3),
      Q4        => ser_data(4),
      SHIFTOUT  => cascade,   -- 1-bit output: Cascade output signal for master/slave I/O
      VALID     => open,      -- 1-bit output: Output status of the phase detector
      BITSLIP   => bitslip ,   -- 1-bit input: Bitslip enable input
      CE0       => '1',        -- 1-bit input: Clock enable input
      CLK0      => clk0,       -- 1-bit input: I/O clock network input
      CLK1      => clk1,       -- 1-bit input: Secondary I/O clock network input
      CLKDIV    => clkdiv,     -- 1-bit input: FPGA logic domain clock input
      D         => ser_input,  -- 1-bit input: Input data
      IOCE      => strobe,     -- 1-bit input: Data strobe input
      RST       => '0',        -- 1-bit input: Asynchronous reset input
      SHIFTIN   => '0'         -- 1-bit input: Cascade input signal for master/slave I/O
   );

ISERDES2_slave : ISERDES2
   generic map (
      BITSLIP_ENABLE => TRUE,         -- Enable Bitslip Functionality (TRUE/FALSE)
      DATA_RATE      => "SDR",        -- Data-rate ("SDR" or "DDR")
      DATA_WIDTH     => 5,            -- Parallel data width selection (2-8)
      INTERFACE_TYPE => "RETIMED",    -- "NETWORKING", "NETWORKING_PIPELINED" or "RETIMED" 
      SERDES_MODE    => "SLAVE"       -- "NONE", "MASTER" or "SLAVE" 
   )
   port map (
      CFB0      => open,      -- 1-bit output: Clock feed-through route output
      CFB1      => open,      -- 1-bit output: Clock feed-through route output
      DFB       => open,      -- 1-bit output: Feed-through clock output
      FABRICOUT => open,    -- 1-bit output: Unsynchrnonized data output
      INCDEC    => open,    -- 1-bit output: Phase detector output
      -- Q1 - Q4: 1-bit (each) output: Registered outputs to FPGA logic
      Q1        => open,
      Q2        => open,
      Q3        => open,
      Q4        => ser_data(0),
      SHIFTOUT  => open,      -- 1-bit output: Cascade output signal for master/slave I/O
      VALID     => open,      -- 1-bit output: Output status of the phase detector
      BITSLIP   => bitslip,   -- 1-bit input: Bitslip enable input
      CE0       => '1',       -- 1-bit input: Clock enable input
      CLK0      => clk0,      -- 1-bit input: I/O clock network input
      CLK1      => clk1,      -- 1-bit input: Secondary I/O clock network input
      CLKDIV    => clkdiv,    -- 1-bit input: FPGA logic domain clock input
      D         => '0',       -- 1-bit input: Input data
      IOCE      => '1',       -- 1-bit input: Data strobe input
      RST       => '0',       -- 1-bit input: Asynchronous reset input
      SHIFTIN   => cascade    -- 1-bit input: Cascade input signal for master/slave I/O
   );
   
end Behavioral;

Personal tools