172 lines
5.9 KiB
VHDL
172 lines
5.9 KiB
VHDL
|
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;
|