-- ----------------------------------------------------------------------------- -- 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_encoder is port ( rst_n : in std_logic; -- external reset input, e.g. reset button pclk : in std_logic; -- pixel clock pclkx2 : in std_logic; -- double pixel rate for gear box pclkx10 : in std_logic; -- IOCLK serdesstrobe_i : in std_logic; -- serdesstrobe for iserdes2 color_i : in color_t(COLOR_CNT-1 downto 0); -- pixel data out hsync_i : in std_logic; -- hsync data vsync_i : in std_logic; -- vsync data dat_en_i : in std_logic; -- data enable tmds_p : out std_logic_vector(3 downto 0); -- tmds tmds_n : out std_logic_vector(3 downto 0) -- tmds ); end dvi_encoder; architecture dvi_encoder of dvi_encoder is signal rst : std_logic; signal toggle : std_logic; signal tmdsclkint : std_logic_vector(4 downto 0); signal data : sdat_t(COLOR_CNT-1 downto 0); signal sdata : std_logic_vector(29 downto 0); type data_5bit_t is array(natural range <>) of std_logic_vector(4 downto 0); signal tmds_data : data_5bit_t(3 downto 0); signal tmdsint : std_logic_vector(3 downto 0); signal tmds_clk : std_logic; begin rst <= not rst_n; -- ---------------------------------------------------------- -- Forward TMDS Clock Using OSERDES2 block -- ---------------------------------------------------------- process (pclkx2, rst_n) begin if rst_n = '0' then toggle <= '0'; tmdsclkint <= (others => '0'); elsif rising_edge(pclkx2) then toggle <= not toggle; if toggle = '1' then tmdsclkint <= (others => '1'); else tmdsclkint <= (others => '0'); end if; end if; end process; clkout: entity work.serdes_n_to_1 generic map (SF => 5) port map ( ioclk => pclkx10, gclk => pclkx2, rst => rst, serdesstrobe_i => serdesstrobe_i, data_i => tmdsclkint, data_o => tmds_clk ); TMDS3: OBUFDS port map (I => tmds_clk, O => tmds_p(3), OB => tmds_n(3)); -- clock -- ---------------------------------------------------------- -- Forward TMDS Data: 3 channels -- ---------------------------------------------------------- forward: for I in 0 to COLOR_CNT-1 generate oserdes_I: entity work.serdes_n_to_1 generic map (SF => 5) port map ( ioclk => pclkx10, gclk => pclkx2, rst => rst, serdesstrobe_i => serdesstrobe_i, data_i => tmds_data(I), data_o => tmdsint(I) ); TMDS_I: OBUFDS port map (I => tmdsint(I), O => tmds_p(I), OB => tmds_n(I)); enc_I: entity work.encoder port map ( clk => pclk, rst_n => rst_n, data_i => color_i(I), c0 => hsync_i, c1 => vsync_i, de => dat_en_i, data_o => data(I) ); end generate; sdata <= data(RED)(9 downto 5) & data(GREEN)(9 downto 5) & data(BLUE)(9 downto 5) & data(RED)(4 downto 0) & data(GREEN)(4 downto 0) & data(BLUE)(4 downto 0); pixel2x: entity work.convert_30to15_fifo port map ( rst => rst, clk => pclk, clkx2 => pclkx2, data_i => sdata, data_o(14 downto 10) => tmds_data(2), data_o( 9 downto 5) => tmds_data(1), data_o( 4 downto 0) => tmds_data(0) ); end dvi_encoder;