2013-10-07 09:07:08 +02:00
|
|
|
-- -----------------------------------------------------------------------------
|
|
|
|
-- Copyright (c) 2013 Benjamin Krill <benjamin@krll.de>
|
2013-10-07 09:34:06 +02:00
|
|
|
--
|
2013-10-07 09:07:08 +02:00
|
|
|
-- 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:
|
2013-10-07 09:34:06 +02:00
|
|
|
--
|
2013-10-07 09:07:08 +02:00
|
|
|
-- The above copyright notice and this permission notice shall be included in
|
|
|
|
-- all copies or substantial portions of the Software.
|
2013-10-07 09:34:06 +02:00
|
|
|
--
|
2013-10-07 09:07:08 +02:00
|
|
|
-- 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.
|
|
|
|
-- -----------------------------------------------------------------------------
|
2013-09-23 10:20:49 +02:00
|
|
|
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;
|