-- ----------------------------------------------------------------------------- -- Copyright (c) 2013 Benjamin Krill -- -- Permission is hereby granted, free of charge, to any person obtaining a copy -- of this software and associated documentation files (the "Software"), to deal -- in the Software without restriction, including without limitation the rights -- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -- copies of the Software, and to permit persons to whom the Software is -- furnished to do so, subject to the following conditions: -- -- The above copyright notice and this permission notice shall be included in -- all copies or substantial portions of the Software. -- -- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -- THE SOFTWARE. -- ----------------------------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; use work.dvi_package.all; library UNISIM; use UNISIM.Vcomponents.all; entity dvi_decoder is port ( ext_rst : in std_logic; -- external reset input, e.g. reset button tmdsclk_p : in std_logic; -- tmds clock tmdsclk_n : in std_logic; -- tmds clock din_p : in std_logic_vector(COLOR_CNT-1 downto 0); -- data in din_n : in std_logic_vector(COLOR_CNT-1 downto 0); -- data in reset_n : out std_logic; -- rx reset_n pclk_o : out std_logic; -- regenerated pixel clock pclkx2_o : out std_logic; -- double rate pixel clock pclkx10_o : out std_logic; -- 10x pixel as IOCLK pll_lckd_o : out std_logic; -- send pll_lckd out so it can be fed into a different BUFPLL serdesstrobe_o : out std_logic; -- BUFPLL serdesstrobe output tmdsclk_o : out std_logic; -- TMDS cable clock hsync_o : out std_logic; -- hsync data vsync_o : out std_logic; -- vsync data dat_en_o : out std_logic; -- data enable valid_o : out std_logic_vector(COLOR_CNT-1 downto 0); ready_o : out std_logic_vector(COLOR_CNT-1 downto 0); psalgnerr_o : out std_logic; sdout_o : out sdat_t(COLOR_CNT-1 downto 0); color_o : out color_t(COLOR_CNT-1 downto 0) -- pixel data out ); end dvi_decoder; architecture dvi_decoder of dvi_decoder is signal rst_n : std_logic; signal rxclk_b : std_logic; signal rxclk : std_logic; signal clkfbout : std_logic; signal pclk : std_logic; signal pclkx2 : std_logic; signal pclkx10 : std_logic; signal pllclk0 : std_logic; signal pllclk1 : std_logic; signal pllclk2 : std_logic; signal pll_locked : std_logic; signal bufpll_lock : std_logic; signal serdesstrobe : std_logic; signal ready : std_logic_vector(COLOR_CNT-1 downto 0); signal hsync : std_logic_vector(COLOR_CNT-1 downto 0); signal vsync : std_logic_vector(COLOR_CNT-1 downto 0); signal valid : std_logic_vector(COLOR_CNT-1 downto 0); type matrix_t is array (natural range <>) of std_logic_vector(COLOR_CNT-2 downto 0); signal other_ready : matrix_t(COLOR_CNT-1 downto 0); signal other_valid : matrix_t(COLOR_CNT-1 downto 0); signal psalgnerr : std_logic_vector(COLOR_CNT-1 downto 0); signal dat_en : std_logic_vector(COLOR_CNT-1 downto 0); begin -- ---------------------------------------------------------- -- I/O mapping -- ---------------------------------------------------------- rst_n <= bufpll_lock; reset_n <= rst_n; pclk_o <= pclk; pclkx2_o <= pclkx2; pclkx10_o <= pclkx10; pll_lckd_o <= pll_locked; serdesstrobe_o <= serdesstrobe; valid_o <= valid; ready_o <= ready; psalgnerr_o <= psalgnerr(RED) or psalgnerr(GREEN) or psalgnerr(BLUE); dat_en_o <= dat_en(BLUE); hsync_o <= hsync(BLUE); vsync_o <= vsync(BLUE); -- ---------------------------------------------------------- -- clocking -- ---------------------------------------------------------- ibuf_rxclk: IBUFDS generic map ( IOSTANDARD => "TMDS_33", DIFF_TERM => false ) port map ( i => tmdsclk_p, ib => tmdsclk_n, o => rxclk_b ); bufio_tmdsclk_0: BUFIO2 generic map ( DIVIDE_BYPASS => true, DIVIDE => 1 ) port map ( DIVCLK => rxclk, IOCLK => open, SERDESSTROBE => open, I => rxclk_b ); tmdsclk_bufg: BUFG port map (I => rxclk, O => tmdsclk_o); -- PLL is used to generate three clocks: -- 1. pclk: same rate as TMDS clock -- 2. pclkx2: double rate of pclk used for 5:10 soft gear box and ISERDES DIVCLK -- 3. pclkx10: 10x rate of pclk used as IO clock PLL_ISERDES: PLL_BASE generic map ( CLKIN_PERIOD => 10.0, CLKFBOUT_MULT => 10, -- set VCO to 10x of CLKIN CLKOUT0_DIVIDE => 1, CLKOUT1_DIVIDE => 10, CLKOUT2_DIVIDE => 5, COMPENSATION => "INTERNAL" ) port map ( CLKFBOUT => clkfbout, CLKOUT0 => pllclk0, CLKOUT1 => pllclk1, CLKOUT2 => pllclk2, CLKOUT3 => open, CLKOUT4 => open, CLKOUT5 => open, LOCKED => pll_locked, CLKFBIN => clkfbout, CLKIN => rxclk, RST => ext_rst ); --Pixel Rate clock buffer pclkbufg: BUFG port map ( I => pllclk1, O => pclk); -- 2x pclk is going to be used to drive IOSERDES2 DIVCLK pclkx2bufg: BUFG port map (I => pllclk2, O => pclkx2); -- 10x pclk is used to drive IOCLK network so a bit rate reference -- can be used by IOSERDES2 ioclk_buf: BUFPLL generic map( DIVIDE => 5 ) port map ( PLLIN => pllclk0, GCLK => pclkx2, LOCKED => pll_locked, IOCLK => pclkx10, SERDESSTROBE => serdesstrobe, LOCK => bufpll_lock ); -- ---------------------------------------------------------- -- decoder mapping -- ---------------------------------------------------------- other_valid(RED) <= valid(BLUE) & valid(GREEN); other_valid(GREEN) <= valid(BLUE) & valid(RED); other_valid(BLUE) <= valid(RED) & valid(GREEN); other_ready(RED) <= ready(BLUE) & ready(GREEN); other_ready(GREEN) <= ready(BLUE) & ready(RED); other_ready(BLUE) <= ready(RED) & ready(GREEN); dec: for I in 0 to COLOR_CNT-1 generate decoder: entity work.decoder port map ( rst_n => rst_n, pclk => pclk, pclkx2 => pclkx2, pclkx10 => pclkx10, serdesstrobe_i => serdesstrobe, din_p => din_p(I), din_n => din_n(I), other_valid_i => other_valid(I), other_ready_i => other_ready(I), valid_o => valid(I), ready_o => ready(I), psalgnerr => psalgnerr(I), c0_o => hsync(I), c1_o => vsync(I), de_o => dat_en(I), sdout_o => sdout_o(I), dout_o => color_o(I) ); end generate dec; end dvi_decoder;