Artix 7 1080p passthrough

From Hamsterworks Wiki!

Jump to: navigation, search

This FPGA Project was completed in July 2015

This design performs the following actions:

  1. Receive the HDMI bitstreams, through the Input buffers,
  2. Generates a x1 and x5 clock, from the incoming HDMI clock
  3. Delays the incoming serial data, to optimize the timing of the sampling.
  4. Deserialize the incoming data on the three data channels.
  5. Then serialize the three data channels, along with a new clock channel
  6. Transmit these through the output buffers

NOTE: It does not yet dynamically tune the input delay - you have to do that with switches 4 through 0!

Contents

Source code

hdmi_passthrough.vhd

----------------------------------------------------------------------------------
-- Engineer: Mike Field <hamster@snap.net.nz> 
-- 
-- Create Date: 02.07.2015 08:24:33
-- Module Name: hdmi_passthorugh - Behavioral
-- Description: Pass a HDMI bitstream through the Artix 7 PGA
--
-- NOTE: When running you will need to adjust switches 4 to 0 to tune the delay.
--       I found "11010" worked for my test source.
----------------------------------------------------------------------------------

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

library UNISIM;
use UNISIM.VComponents.all;

entity hdmi_passthrough is
    Port (  clk           : in    STD_LOGIC;
            switches      : in    std_logic_vector(4 downto 0);
            led           : out   std_logic_vector(7 downto 0);
            --HDMI in
            hdmi_rx_cec   : inout std_logic;
            hdmi_rx_hpa   : out std_logic;
            hdmi_rx_scl   : inout std_logic;
            hdmi_rx_sda   : inout std_logic;
            hdmi_rx_txen  : out   std_logic;
            hdmi_rx_clk_n : in    std_logic;
            hdmi_rx_clk_p : in    std_logic;
            hdmi_rx_n     : in    std_logic_vector(2 downto 0);
            hdmi_rx_p     : in    std_logic_vector(2 downto 0);

            --- HDMI out
            hdmi_tx_cec   : inout std_logic;
            hdmi_tx_clk_n : out   std_logic;
            hdmi_tx_clk_p : out   std_logic;
            hdmi_tx_hpd   : in    std_logic;
            hdmi_tx_rscl  : inout std_logic;
            hdmi_tx_rsda  : inout std_logic;
            hdmi_tx_p     : out   std_logic_vector(2 downto 0);
            hdmi_tx_n     : out   std_logic_vector(2 downto 0)
        );
end hdmi_passthrough;

architecture Behavioral of hdmi_passthrough is
    component deserialiser_1_to_10 is
    Port ( clk_mgmt    : in  STD_LOGIC;
           delay_ce    : in STD_LOGIC;
           delay_count : in STD_LOGIC_VECTOR (4 downto 0);
           clk_x1      : in STD_LOGIC;
           clk_x5      : in STD_LOGIC;
           reset       : in std_logic;
           serial      : in STD_LOGIC;
           data        : out STD_LOGIC_VECTOR (9 downto 0));
    end component;

    component serialiser_10_to_1 is
    Port ( clk_x1 : in STD_LOGIC;
           clk_x5 : in STD_LOGIC;
           reset  : in std_logic;
           data   : in STD_LOGIC_VECTOR (9 downto 0);
           serial : out STD_LOGIC);
    end component;

    signal delay_ce      : std_logic                    := '0';
    signal delay_count   : std_logic_vector(4 downto 0) := (others => '0');
    -- The input streams
    signal serial_in_ch0 : std_logic;
    signal serial_in_ch1 : std_logic;
    signal serial_in_ch2 : std_logic;
    signal serial_in_clk : std_logic;

    -- The recovered clocks
    signal locked           : std_logic;
    signal clkfb_1          : std_logic;
    signal clkfb_2          : std_logic;
    signal clk_200          : std_logic;
    signal clk_pixel_x1     : std_logic;
    signal clk_pixel_x5     : std_logic;
    signal clk_pixel_x5_raw : std_logic;
    
    -- The received data
    signal ch0_data_in : std_logic_vector(9 downto 0);
    signal ch1_data_in : std_logic_vector(9 downto 0);
    signal ch2_data_in : std_logic_vector(9 downto 0);
    
    -- The transmit data
    signal ch0_data_out : std_logic_vector(9 downto 0);
    signal ch1_data_out : std_logic_vector(9 downto 0);
    signal ch2_data_out : std_logic_vector(9 downto 0);

    -- The output streams
    signal reset          : std_logic := '0';
    signal serial_out_ch0 : std_logic;
    signal serial_out_ch1 : std_logic;
    signal serial_out_ch2 : std_logic;
    signal serial_out_clk : std_logic;

    signal count : unsigned(19 downto 0);
    
    attribute IODELAY_GROUP : STRING;
    attribute IODELAY_GROUP of IDELAYCTRL_inst: label is "idelay_group";

begin
    -- Debug signals
    led(0) <= not hdmi_tx_hpd;
    led(1) <= locked;
    hdmi_rx_txen  <= '1';
    hdmi_rx_hpa   <= '1';
    reset <= not locked;
    
    -------------------------------------------
    -- Convert the 100MHz system clock into 
    -- a 200MHz clock for the IDELAY reference
    --------------------------------------------
clk_MMCME2_BASE_inst : MMCME2_BASE
   generic map (
      BANDWIDTH => "OPTIMIZED",      -- Jitter programming (OPTIMIZED, HIGH, LOW)
      DIVCLK_DIVIDE   => 1,          -- Master division value (1-106)
      CLKFBOUT_MULT_F => 8.0,        -- Multiply value for all CLKOUT (2.000-64.000).
      CLKFBOUT_PHASE => 0.0,         -- Phase offset in degrees of CLKFB (-360.000-360.000).
      CLKIN1_PERIOD => 1000.0/148.5, -- Input clock period in ns to ps resolution (i.e. 33.333 is 30 MHz).
      -- CLKOUT0_DIVIDE - CLKOUT6_DIVIDE: Divide amount for each CLKOUT (1-128)
      CLKOUT0_DIVIDE_F => 4.0,       -- Divide amount for CLKOUT0 (1.000-128.000).
      CLKOUT1_DIVIDE   => 1,
      CLKOUT2_DIVIDE   => 1,
      CLKOUT3_DIVIDE   => 1,
      CLKOUT4_DIVIDE   => 1,
      CLKOUT5_DIVIDE   => 1,
      CLKOUT6_DIVIDE   => 1,
      -- CLKOUT0_DUTY_CYCLE - CLKOUT6_DUTY_CYCLE: Duty cycle for each CLKOUT (0.01-0.99).
      CLKOUT0_DUTY_CYCLE => 0.5,
      CLKOUT1_DUTY_CYCLE => 0.5,
      CLKOUT2_DUTY_CYCLE => 0.5,
      CLKOUT3_DUTY_CYCLE => 0.5,
      CLKOUT4_DUTY_CYCLE => 0.5,
      CLKOUT5_DUTY_CYCLE => 0.5,
      CLKOUT6_DUTY_CYCLE => 0.5,
      -- CLKOUT0_PHASE - CLKOUT6_PHASE: Phase offset for each CLKOUT (-360.000-360.000).
      CLKOUT0_PHASE => 0.0,
      CLKOUT1_PHASE => 0.0,
      CLKOUT2_PHASE => 0.0,
      CLKOUT3_PHASE => 0.0,
      CLKOUT4_PHASE => 0.0,
      CLKOUT5_PHASE => 0.0,
      CLKOUT6_PHASE => 0.0,
      CLKOUT4_CASCADE => FALSE,  -- Cascade CLKOUT4 counter with CLKOUT6 (FALSE, TRUE)
      REF_JITTER1 => 0.0,        -- Reference input jitter in UI (0.000-0.999).
      STARTUP_WAIT => FALSE      -- Delays DONE until MMCM is locked (FALSE, TRUE)
   )
   port map (
      -- Clock Outputs: 1-bit (each) output: User configurable clock outputs
      CLKOUT0   => clk_200,      -- 1-bit output: CLKOUT0
      CLKOUT0B  => open,         -- 1-bit output: Inverted CLKOUT0
      CLKOUT1   => open,         -- 1-bit output: CLKOUT1
      CLKOUT1B  => open,         -- 1-bit output: Inverted CLKOUT1
      CLKOUT2   => open,         -- 1-bit output: CLKOUT2
      CLKOUT2B  => open,         -- 1-bit output: Inverted CLKOUT2
      CLKOUT3   => open,         -- 1-bit output: CLKOUT3
      CLKOUT3B  => open,         -- 1-bit output: Inverted CLKOUT3
      CLKOUT4   => open,         -- 1-bit output: CLKOUT4
      CLKOUT5   => open,         -- 1-bit output: CLKOUT5
      CLKOUT6   => open,         -- 1-bit output: CLKOUT6
      -- Feedback Clocks: 1-bit (each) output: Clock feedback ports
      CLKFBOUT  => clkfb_1,      -- 1-bit output: Feedback clock
      CLKFBOUTB => open,         -- 1-bit output: Inverted CLKFBOUT
      -- Status Ports: 1-bit (each) output: MMCM status ports
      LOCKED    => open,         -- 1-bit output: LOCK
      -- Clock Inputs: 1-bit (each) input: Clock input
      CLKIN1    => clk,          -- 1-bit input: Clock
      -- Control Ports: 1-bit (each) input: MMCM control ports
      PWRDWN    => '0',          -- 1-bit input: Power-down
      RST       => '0',          -- 1-bit input: Reset
      -- Feedback Clocks: 1-bit (each) input: Clock feedback ports
      CLKFBIN   => clkfb_1       -- 1-bit input: Feedback clock
   );

   ------------------------------
   -- Input Delay reference
   --
   -- These are tied to the delay instances  
   -- by the IODELAY_GROUP attribute.
   --------------------------------------------    
IDELAYCTRL_inst : IDELAYCTRL
    port map (
        RDY    => open,    -- 1-bit output: Ready output
        REFCLK => clk_200, -- 1-bit input:  Reference clock input
        RST    => '0'      -- 1-bit input:  Active high reset input
    );

   ---------------------
   -- Input buffers
   ---------------------
in_clk_buf: IBUFDS generic map ( IOSTANDARD => "TMDS_33")
    port map ( I  => hdmi_rx_clk_p, IB => hdmi_rx_clk_n, O => serial_in_clk);
    
in_rx0_buf: IBUFDS generic map ( IOSTANDARD => "TMDS_33")
    port map ( I  => hdmi_rx_p(0),  IB => hdmi_rx_n(0),  O  => serial_in_ch0);

in_rx1_buf: IBUFDS generic map ( IOSTANDARD => "TMDS_33")
    port map ( I  => hdmi_rx_p(1),  IB => hdmi_rx_n(1),  O  => serial_in_ch1);

in_rx2_buf: IBUFDS generic map ( IOSTANDARD => "TMDS_33")
    port map ( I  => hdmi_rx_p(2),  IB => hdmi_rx_n(2),  O  => serial_in_ch2);

   --------------------------------
   -- MMCM driven by the HDMI clock
   --------------------------------
hdmi_MMCME2_BASE_inst : MMCME2_BASE
   generic map (
      BANDWIDTH => "OPTIMIZED",      -- Jitter programming (OPTIMIZED, HIGH, LOW)
      DIVCLK_DIVIDE   => 1,          -- Master division value (1-106)
      CLKFBOUT_MULT_F => 5.0,        -- Multiply value for all CLKOUT (2.000-64.000).
      CLKFBOUT_PHASE => 0.0,         -- Phase offset in degrees of CLKFB (-360.000-360.000).
      CLKIN1_PERIOD => 1000.0/148.5, -- Input clock period in ns to ps resolution (i.e. 33.333 is 30 MHz).
      -- CLKOUT0_DIVIDE - CLKOUT6_DIVIDE: Divide amount for each CLKOUT (1-128)
      CLKOUT0_DIVIDE_F => 5.0,       -- Divide amount for CLKOUT0 (1.000-128.000).
      CLKOUT1_DIVIDE   => 5,
      CLKOUT2_DIVIDE   => 1,
      CLKOUT3_DIVIDE   => 1,
      CLKOUT4_DIVIDE   => 1,
      CLKOUT5_DIVIDE   => 1,
      CLKOUT6_DIVIDE   => 1,
      -- CLKOUT0_DUTY_CYCLE - CLKOUT6_DUTY_CYCLE: Duty cycle for each CLKOUT (0.01-0.99).
      CLKOUT0_DUTY_CYCLE => 0.5,
      CLKOUT1_DUTY_CYCLE => 0.5,
      CLKOUT2_DUTY_CYCLE => 0.5,
      CLKOUT3_DUTY_CYCLE => 0.5,
      CLKOUT4_DUTY_CYCLE => 0.5,
      CLKOUT5_DUTY_CYCLE => 0.5,
      CLKOUT6_DUTY_CYCLE => 0.5,
      -- CLKOUT0_PHASE - CLKOUT6_PHASE: Phase offset for each CLKOUT (-360.000-360.000).
      CLKOUT0_PHASE => 0.0,
      CLKOUT1_PHASE => 0.0,
      CLKOUT2_PHASE => 0.0,
      CLKOUT3_PHASE => 0.0,
      CLKOUT4_PHASE => 0.0,
      CLKOUT5_PHASE => 0.0,
      CLKOUT6_PHASE => 0.0,
      CLKOUT4_CASCADE => FALSE,  -- Cascade CLKOUT4 counter with CLKOUT6 (FALSE, TRUE)
      REF_JITTER1 => 0.0,        -- Reference input jitter in UI (0.000-0.999).
      STARTUP_WAIT => FALSE      -- Delays DONE until MMCM is locked (FALSE, TRUE)
   )
   port map (
      -- Clock Outputs: 1-bit (each) output: User configurable clock outputs
      CLKOUT0   => open,         -- 1-bit output: CLKOUT0
      CLKOUT0B  => open,         -- 1-bit output: Inverted CLKOUT0
      CLKOUT1   => clk_pixel_x1, -- 1-bit output: CLKOUT1
      CLKOUT1B  => open,         -- 1-bit output: Inverted CLKOUT1
      CLKOUT2   => clk_pixel_x5_raw, -- 1-bit output: CLKOUT2
      CLKOUT2B  => open,         -- 1-bit output: Inverted CLKOUT2
      CLKOUT3   => open,         -- 1-bit output: CLKOUT3
      CLKOUT3B  => open,         -- 1-bit output: Inverted CLKOUT3
      CLKOUT4   => open,         -- 1-bit output: CLKOUT4
      CLKOUT5   => open,         -- 1-bit output: CLKOUT5
      CLKOUT6   => open,         -- 1-bit output: CLKOUT6
      -- Feedback Clocks: 1-bit (each) output: Clock feedback ports
      CLKFBOUT  => clkfb_2,       -- 1-bit output: Feedback clock
      CLKFBOUTB => open,          -- 1-bit output: Inverted CLKFBOUT
      -- Status Ports: 1-bit (each) output: MMCM status ports
      LOCKED    => locked,        -- 1-bit output: LOCK
      -- Clock Inputs: 1-bit (each) input: Clock input
      CLKIN1    => serial_in_clk, -- 1-bit input: Clock
      -- Control Ports: 1-bit (each) input: MMCM control ports
      PWRDWN    => '0',           -- 1-bit input: Power-down
      RST       => '0',           -- 1-bit input: Reset
      -- Feedback Clocks: 1-bit (each) input: Clock feedback ports
      CLKFBIN   => clkfb_2        -- 1-bit input: Feedback clock
   );

   ----------------------------------
   -- Force the highest speed clock 
   -- through the IO clock buffer
   -- (this is only rated for 600MHz!)
   -----------------------------------  
BUFIO_inst : BUFIO
   port map (
      O => clk_pixel_x5,     -- 1-bit output: Clock output (connect to I/O clock loads).
      I => clk_pixel_x5_raw  -- 1-bit input: Clock input (connect to an IBUF or BUFMR).
   );

   ----------------------------------
   -- Process to control the setting 
   -- of the input delays when the user
   -- changes the switches
   -----------------------------------    
delay_control_proc: process(clk)
    begin
        if rising_edge(clk) then
            if count = 0 then
                if delay_count /= switches(4 downto 0) then
                    delay_count <= switches(4 downto 0);
                    delay_ce <= '1';
                end if;
            else
                delay_ce <= '0';
            end if;
            count <= count+1;
        end if;
    end process;
           
    ---------------------------------------
    -- Three channels of deserialization
    -- for the HDMI stream. 
    ---------------------------------------
deser_ch0: deserialiser_1_to_10 port map (
        clk_mgmt    => clk,
        delay_ce    => delay_ce,
        delay_count => delay_count,
        clk_x1      => clk_pixel_x1,
        clk_x5      => clk_pixel_x5,
        reset       => reset,
        serial      => serial_in_ch0,
        data        => ch0_data_in);

deser_ch1: deserialiser_1_to_10 port map (
        clk_mgmt    => clk,
        delay_ce    => delay_ce,
        delay_count => delay_count,
        clk_x1      => clk_pixel_x1,
        clk_x5      => clk_pixel_x5,
        reset       => reset,
        serial      => serial_in_ch1,
        data        => ch1_data_in);

deser_ch2: deserialiser_1_to_10 port map (
        clk_mgmt    => clk,
        delay_ce    => delay_ce,
        delay_count => delay_count,
        clk_x1      => clk_pixel_x1,
        clk_x5      => clk_pixel_x5,
        reset       => reset,
        serial      => serial_in_ch2,
        data        => ch2_data_in);

    -------------------------------------
    -- Process that doesn't actually do  
    -- anything with the data, other
    -- than pass it through to the output
    -------------------------------------    
mode_data_proc: process(clk_pixel_x1)
    begin
        if rising_edge(clk_pixel_x1) then
            led(7 downto 2) <= ch0_data_in(9 downto 4);
            ch0_data_out <= ch0_data_in;
            ch1_data_out <= ch1_data_in;
            ch2_data_out <= ch2_data_in;
        end if;
    end process;
    
    ---------------------
    -- Output serializers
    ---------------------
ser_ch0: serialiser_10_to_1 port map ( 
        clk_x1 => clk_pixel_x1,
        clk_x5 => clk_pixel_x5,
        reset  => reset,
        data   => ch0_data_out,
        serial => serial_out_ch0);
        
ser_ch1: serialiser_10_to_1 port map ( 
        clk_x1 => clk_pixel_x1,
        clk_x5 => clk_pixel_x5,
        reset  => reset,
        data   => ch1_data_out,
        serial => serial_out_ch1);

ser_ch2: serialiser_10_to_1 port map (
        clk_x1 => clk_pixel_x1,
        clk_x5 => clk_pixel_x5,
        reset  => reset,
        data   => ch2_data_out,
        serial => serial_out_ch2);

ser_clk: serialiser_10_to_1 Port map (
        clk_x1 => clk_pixel_x1,
        clk_x5 => clk_pixel_x5,
        reset  => reset,
        data   => "1110000011",
        serial => serial_out_clk);

    -----------------
    -- Output buffers
    -----------------
out_clk_buf: OBUFDS generic map ( IOSTANDARD => "TMDS_33",  SLEW => "FAST")
    port map ( O  => hdmi_tx_clk_p, OB => hdmi_tx_clk_n, I => serial_out_clk);
    
out_tx0_buf: OBUFDS generic map ( IOSTANDARD => "TMDS_33",  SLEW => "FAST")
    port map ( O  => hdmi_tx_p(0), OB => hdmi_tx_n(0), I  => serial_out_ch0);

out_tx1_buf: OBUFDS generic map ( IOSTANDARD => "TMDS_33",  SLEW => "FAST")
    port map ( O  => hdmi_tx_p(1), OB => hdmi_tx_n(1), I  => serial_out_ch1);

out_tx2_buf: OBUFDS generic map ( IOSTANDARD => "TMDS_33",  SLEW => "FAST")
    port map ( O  => hdmi_tx_p(2), OB => hdmi_tx_n(2), I  => serial_out_ch2);

end Behavioral;

deserialiser_1_to_10.vhd

----------------------------------------------------------------------------------
-- Engineer: Mike Field <hamster@snap.net.nz> 
-- 
-- Module Name: deserialiser_1_to_10 - Behavioral
-- Description: A 10-to-1 deserialiser for the Artix 7   
-- 
----------------------------------------------------------------------------------

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

library UNISIM;
use UNISIM.VComponents.all;

entity deserialiser_1_to_10 is
    Port ( clk_mgmt    : in  STD_LOGIC;
           delay_ce    : in STD_LOGIC;
           delay_count : in STD_LOGIC_VECTOR (4 downto 0);
           clk_x1      : in  STD_LOGIC;
           clk_x5      : in  STD_LOGIC;
           serial      : in  STD_LOGIC;
           reset       : in  STD_LOGIC;
           data        : out STD_LOGIC_VECTOR (9 downto 0));
end deserialiser_1_to_10;

architecture Behavioral of deserialiser_1_to_10 is
    signal delayed : std_logic := '0';
    signal shift1  : std_logic := '0';
    signal shift2  : std_logic := '0';
    signal bitslip : std_logic := '0';
    signal ce      : std_logic := '1';
    signal clkb    : std_logic := '1';
    attribute IODELAY_GROUP : STRING;
    attribute IODELAY_GROUP of IDELAYE2_inst: label is "idelay_group";

begin
ce_proc: process(clk_x5)
    begin
        ce <= not reset;
    end process;

IDELAYE2_inst : IDELAYE2
    generic map (
          CINVCTRL_SEL          => "FALSE",
          DELAY_SRC             => "DATAIN",
          HIGH_PERFORMANCE_MODE => "TRUE",
          IDELAY_TYPE           => "VAR_LOAD",
          IDELAY_VALUE          => 0,
          PIPE_SEL              => "FALSE",
          REFCLK_FREQUENCY      => 200.0,
          SIGNAL_PATTERN        => "DATA"
    )
    port map (
          DATAIN      => serial,
          IDATAIN     => '0',
          DATAOUT     => delayed,
          --
          CNTVALUEOUT => open,
          C           => clk_mgmt,
          CE          => delay_ce,
          CINVCTRL    => '0',
          CNTVALUEIN  => delay_count,
          INC         => '0',
          LD          => '1',
          LDPIPEEN    => '0',
          REGRST      => '0'
    );
    clkb <= not clk_x5;

ISERDESE2_master : ISERDESE2
   generic map (
      DATA_RATE         => "DDR",
      DATA_WIDTH        => 10,
      DYN_CLKDIV_INV_EN => "FALSE",
      DYN_CLK_INV_EN    => "FALSE",
      INIT_Q1 => '0', INIT_Q2 => '0', INIT_Q3 => '0', INIT_Q4 => '0',
      INTERFACE_TYPE    => "NETWORKING",
      IOBDELAY          => "BOTH",
      NUM_CE            => 1,
      OFB_USED          => "FALSE",
      SERDES_MODE       => "MASTER",
      SRVAL_Q1 => '0', SRVAL_Q2 => '0', SRVAL_Q3 => '0', SRVAL_Q4 => '0' 
   )
   port map (
      O => open,
      Q1 => data(9), Q2 => data(8), Q3 => data(7), Q4 => data(6),
      Q5 => data(5), Q6 => data(4), Q7 => data(3), Q8 => data(2),
      SHIFTOUT1 => shift1, SHIFTOUT2 => shift2,
      BITSLIP   => bitslip,
      CE1 => ce, CE2 => '0',
      CLKDIVP      => '0',
      CLK          => clk_x5,
      CLKB         => clkb,
      CLKDIV       => clk_x1,
      OCLK         => '0', 
      DYNCLKDIVSEL => '0',
      DYNCLKSEL    => '0',
      D            => '0',
      DDLY         => delayed,
      OFB          => '0',
      OCLKB        => '0',
      RST          => reset,
      SHIFTIN1     => '0',
      SHIFTIN2     => '0' 
   );
					
ISERDESE2_slave : ISERDESE2
   generic map (
      DATA_RATE         => "DDR",
      DATA_WIDTH        => 10,
      DYN_CLKDIV_INV_EN => "FALSE",
      DYN_CLK_INV_EN    => "FALSE",
      INIT_Q1 => '0', INIT_Q2 => '0', INIT_Q3 => '0', INIT_Q4 => '0',
      INTERFACE_TYPE    => "NETWORKING",
      IOBDELAY          => "BOTH",
      NUM_CE            => 1,
      OFB_USED          => "FALSE",
      SERDES_MODE       => "SLAVE",  
      SRVAL_Q1 => '0', SRVAL_Q2 => '0', SRVAL_Q3 => '0', SRVAL_Q4 => '0' 
   )
   port map (
      O => open,
      Q1 => open, Q2 => open, Q3 => data(1), Q4 => data(0),
      Q5 => open, Q6 => open, Q7 => open,    Q8 => open,
      SHIFTOUT1 => open, SHIFTOUT2 => open,
      BITSLIP   => bitslip,
      CE1 => ce, CE2 => '0',
      CLKDIVP      => '0',
      CLK          => CLK_x5,
      CLKB         => clkb,
      CLKDIV       => clk_x1,
      OCLK         => '0', 
      DYNCLKDIVSEL => '0',
      DYNCLKSEL    => '0',
      D            => '0',
      DDLY         => '0',
      OFB          => '0',
      OCLKB        => '0',
      RST          => reset,
      SHIFTIN1     => shift1,
      SHIFTIN2     => shift2 
   );
end Behavioral;

serialiser_1_to_10

----------------------------------------------------------------------------------
-- File: serialiser_10_to_1.vhd
--
-- Engineer:  Mike Field <hamster@snap.net.nz> 
-- 
-- Module Name: serialiser_10_to_1 - Behavioral
--
-- Description: Using the OSERDESE2 as a 10:1 serialiser, using a x1 and x5
--              clocks (using DDR outputs).
--
-- The tricky bit is that reset needs to be asserted, and then CE asserted 
-- after the reset or it will not simulate correctly (outputs show as 'X') 
-- 
----------------------------------------------------------------------------------


library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
library UNISIM;
use UNISIM.VComponents.all;

entity serialiser_10_to_1 is
    Port ( clk_x1 : in STD_LOGIC;
           clk_x5 : in STD_LOGIC;
           data   : in STD_LOGIC_VECTOR (9 downto 0);
           reset  : in std_logic;
           serial : out STD_LOGIC);
end serialiser_10_to_1;

architecture Behavioral of serialiser_10_to_1 is
    signal shift1      : std_logic := '0';
    signal shift2      : std_logic := '0';
    signal ce_delay    : std_logic_vector(7 downto 0) := (others => '1');
    signal reset_delay : std_logic_vector(7 downto 0) := (others => '0');
begin

master_serdes : OSERDESE2
   generic map (
      DATA_RATE_OQ => "DDR",
      DATA_RATE_TQ => "DDR",
      DATA_WIDTH => 10,
      INIT_OQ => '1',
      INIT_TQ => '1',
      SERDES_MODE => "MASTER",
      SRVAL_OQ => '0',
      SRVAL_TQ => '0',
      TBYTE_CTL => "FALSE",
      TBYTE_SRC => "FALSE",
      TRISTATE_WIDTH => 1
   )
   port map (
      OFB       => open,
      OQ        => serial,
      SHIFTOUT1 => open,
      SHIFTOUT2 => open,
      TBYTEOUT  => open,
      TFB       => open,
      TQ        => open,
      CLK       => clk_x5,
      CLKDIV    => clk_x1,
      D1 => data(0),
      D2 => data(1),
      D3 => data(2),
      D4 => data(3),
      D5 => data(4),
      D6 => data(5),
      D7 => data(6),
      D8 => data(7),
      OCE => ce_delay(0),
      RST => reset,
      SHIFTIN1 => SHIFT1,
      SHIFTIN2 => SHIFT2,
      T1 => '0',
      T2 => '0',
      T3 => '0',
      T4 => '0',
      TBYTEIN => '0',
      TCE => '0'
   );

slave_serdes : OSERDESE2
   generic map (
      DATA_RATE_OQ   => "DDR",
      DATA_RATE_TQ   => "DDR",
      DATA_WIDTH     => 10,
      INIT_OQ        => '1',
      INIT_TQ        => '1',
      SERDES_MODE    => "SLAVE",
      SRVAL_OQ       => '0',
      SRVAL_TQ       => '0',
      TBYTE_CTL      => "FALSE",
      TBYTE_SRC      => "FALSE",
      TRISTATE_WIDTH => 1
   )
   port map (
      OFB       => open,
      OQ        => open,
      SHIFTOUT1 => shift1,
      SHIFTOUT2 => shift2,      
      TBYTEOUT  => open,
      TFB       => open,
      TQ        => open,
      CLK       => clk_x5,
      CLKDIV    => clk_x1,
      D1       => '0',
      D2       => '0',
      D3       => data(8),
      D4       => data(9),
      D5       => '0',
      D6       => '0',
      D7       => '0',
      D8       => '0',
      OCE      => ce_delay(0),
      RST      => reset,
      SHIFTIN1 => '0',
      SHIFTIN2 => '0',
      T1       => '0',
      T2       => '0',
      T3       => '0',
      T4       => '0',
      TBYTEIN  => '0',
      TCE      => '0'
   );
delay_ce: process(clk_x5)
    begin
        if rising_edge(clk_x5) then
--            ce_delay <= not reset & ce_delay(ce_delay'high downto 1);
              ce_delay <= (others => '1');
        end if;
    end process;
end Behavioral;

NexysVideo.xdc

##Clock Signal
set_property -dict { PACKAGE_PIN R4    IOSTANDARD LVCMOS33 } [get_ports { clk }];
    create_clock -add -name sys_clk_pin -period 10.00 -waveform {0 5} [get_ports clk]
    
##HDMI in
create_clock -add -name hdmi_clk -period 6.7 -waveform {0 5} [get_ports hdmi_rx_clk_p]

set_property -dict { PACKAGE_PIN AA5   IOSTANDARD LVCMOS33 } [get_ports { hdmi_rx_cec }]; #IO_L10P_T1_34 Sch=hdmi_rx_cec
set_property -dict { PACKAGE_PIN W4    IOSTANDARD TMDS_33  } [get_ports { hdmi_rx_clk_n }]; #IO_L12N_T1_MRCC_34 Sch=hdmi_rx_clk_n
set_property -dict { PACKAGE_PIN V4    IOSTANDARD TMDS_33  } [get_ports { hdmi_rx_clk_p }]; #IO_L12P_T1_MRCC_34 Sch=hdmi_rx_clk_p
set_property -dict { PACKAGE_PIN AB12  IOSTANDARD LVCMOS25 } [get_ports { hdmi_rx_hpa }]; #IO_L7N_T1_13 Sch=hdmi_rx_hpa
set_property -dict { PACKAGE_PIN Y4    IOSTANDARD LVCMOS33 } [get_ports { hdmi_rx_scl }]; #IO_L11P_T1_SRCC_34 Sch=hdmi_rx_scl
set_property -dict { PACKAGE_PIN AB5   IOSTANDARD LVCMOS33 } [get_ports { hdmi_rx_sda }]; #IO_L10N_T1_34 Sch=hdmi_rx_sda
set_property -dict { PACKAGE_PIN R3    IOSTANDARD LVCMOS33 } [get_ports { hdmi_rx_txen }]; #IO_L3P_T0_DQS_34 Sch=hdmi_rx_txen
set_property -dict { PACKAGE_PIN AA3   IOSTANDARD TMDS_33  } [get_ports { hdmi_rx_n[0] }]; #IO_L9N_T1_DQS_34 Sch=hdmi_rx_n[0]
set_property -dict { PACKAGE_PIN Y3    IOSTANDARD TMDS_33  } [get_ports { hdmi_rx_p[0] }]; #IO_L9P_T1_DQS_34 Sch=hdmi_rx_p[0]
set_property -dict { PACKAGE_PIN Y2    IOSTANDARD TMDS_33  } [get_ports { hdmi_rx_n[1] }]; #IO_L4N_T0_34 Sch=hdmi_rx_n[1]
set_property -dict { PACKAGE_PIN W2    IOSTANDARD TMDS_33  } [get_ports { hdmi_rx_p[1] }]; #IO_L4P_T0_34 Sch=hdmi_rx_p[1]
set_property -dict { PACKAGE_PIN V2    IOSTANDARD TMDS_33  } [get_ports { hdmi_rx_n[2] }]; #IO_L2N_T0_34 Sch=hdmi_rx_n[2]
set_property -dict { PACKAGE_PIN U2    IOSTANDARD TMDS_33  } [get_ports { hdmi_rx_p[2] }]; #IO_L2P_T0_34 Sch=hdmi_rx_p[2]


##HDMI out
set_property -dict { PACKAGE_PIN AA4   IOSTANDARD LVCMOS33 } [get_ports { hdmi_tx_cec }]; #IO_L11N_T1_SRCC_34 Sch=hdmi_tx_cec
set_property -dict { PACKAGE_PIN U1    IOSTANDARD TMDS_33  } [get_ports { hdmi_tx_clk_n }]; #IO_L1N_T0_34 Sch=hdmi_tx_clk_n
set_property -dict { PACKAGE_PIN T1    IOSTANDARD TMDS_33  } [get_ports { hdmi_tx_clk_p }]; #IO_L1P_T0_34 Sch=hdmi_tx_clk_p
set_property -dict { PACKAGE_PIN AB13  IOSTANDARD LVCMOS25 } [get_ports { hdmi_tx_hpd }]; #IO_L3N_T0_DQS_13 Sch=hdmi_tx_hpd
set_property -dict { PACKAGE_PIN U3    IOSTANDARD LVCMOS33 } [get_ports { hdmi_tx_rscl }]; #IO_L6P_T0_34 Sch=hdmi_tx_rscl
set_property -dict { PACKAGE_PIN V3    IOSTANDARD LVCMOS33 } [get_ports { hdmi_tx_rsda }]; #IO_L6N_T0_VREF_34 Sch=hdmi_tx_rsda
set_property -dict { PACKAGE_PIN Y1    IOSTANDARD TMDS_33  } [get_ports { hdmi_tx_n[0] }]; #IO_L5N_T0_34 Sch=hdmi_tx_n[0]
set_property -dict { PACKAGE_PIN W1    IOSTANDARD TMDS_33  } [get_ports { hdmi_tx_p[0] }]; #IO_L5P_T0_34 Sch=hdmi_tx_p[0]
set_property -dict { PACKAGE_PIN AB1   IOSTANDARD TMDS_33  } [get_ports { hdmi_tx_n[1] }]; #IO_L7N_T1_34 Sch=hdmi_tx_n[1]
set_property -dict { PACKAGE_PIN AA1   IOSTANDARD TMDS_33  } [get_ports { hdmi_tx_p[1] }]; #IO_L7P_T1_34 Sch=hdmi_tx_p[1]
set_property -dict { PACKAGE_PIN AB2   IOSTANDARD TMDS_33  } [get_ports { hdmi_tx_n[2] }]; #IO_L8N_T1_34 Sch=hdmi_tx_n[2]
set_property -dict { PACKAGE_PIN AB3   IOSTANDARD TMDS_33  } [get_ports { hdmi_tx_p[2] }]; #IO_L8P_T1_34 Sch=hdmi_tx_p[2]

##Switches
set_property -dict { PACKAGE_PIN E22  IOSTANDARD LVCMOS25 } [get_ports { switches[0] }]; #IO_L22P_T3_16 Sch=sw[0]
set_property -dict { PACKAGE_PIN F21  IOSTANDARD LVCMOS25 } [get_ports { switches[1] }]; #IO_25_16 Sch=sw[1]
set_property -dict { PACKAGE_PIN G21  IOSTANDARD LVCMOS25 } [get_ports { switches[2] }]; #IO_L24P_T3_16 Sch=sw[2]
set_property -dict { PACKAGE_PIN G22  IOSTANDARD LVCMOS25 } [get_ports { switches[3] }]; #IO_L24N_T3_16 Sch=sw[3]
set_property -dict { PACKAGE_PIN H17  IOSTANDARD LVCMOS25 } [get_ports { switches[4] }]; #IO_L6P_T0_15 Sch=sw[4]
#set_property -dict { PACKAGE_PIN J16  } [get_ports { sw[5] }]; #IO_0_15 Sch=sw[5]
#set_property -dict { PACKAGE_PIN K13  } [get_ports { sw[6] }]; #IO_L19P_T3_A22_15 Sch=sw[6]
#set_property -dict { PACKAGE_PIN M17  } [get_ports { sw[7] }]; #IO_25_15 Sch=sw[7]

##LEDs
set_property -dict { PACKAGE_PIN T14   IOSTANDARD LVCMOS25 } [get_ports { led[0] }]; #IO_L15P_T2_DQS_13 Sch=led[0]
set_property -dict { PACKAGE_PIN T15   IOSTANDARD LVCMOS25 } [get_ports { led[1] }]; #IO_L15N_T2_DQS_13 Sch=led[1]
set_property -dict { PACKAGE_PIN T16   IOSTANDARD LVCMOS25 } [get_ports { led[2] }]; #IO_L17P_T2_13 Sch=led[2]
set_property -dict { PACKAGE_PIN U16   IOSTANDARD LVCMOS25 } [get_ports { led[3] }]; #IO_L17N_T2_13 Sch=led[3]
set_property -dict { PACKAGE_PIN V15   IOSTANDARD LVCMOS25 } [get_ports { led[4] }]; #IO_L14N_T2_SRCC_13 Sch=led[4]
set_property -dict { PACKAGE_PIN W16   IOSTANDARD LVCMOS25 } [get_ports { led[5] }]; #IO_L16N_T2_13 Sch=led[5]
set_property -dict { PACKAGE_PIN W15   IOSTANDARD LVCMOS25 } [get_ports { led[6] }]; #IO_L16P_T2_13 Sch=led[6]
set_property -dict { PACKAGE_PIN Y13   IOSTANDARD LVCMOS25 } [get_ports { led[7] }]; #IO_L5P_T0_13 Sch=led[7]

Personal tools