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 decoder 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
|
|
|
|
din_p : in std_logic; -- data from dvi cable
|
|
|
|
din_n : in std_logic; -- data from dvi cable
|
|
|
|
other_valid_i : in std_logic_vector(1 downto 0); -- other has valid data now
|
|
|
|
other_ready_i : in std_logic_vector(1 downto 0); -- other has detected a valid starting pixel
|
|
|
|
|
|
|
|
valid_o : out std_logic; -- I have valid data now
|
|
|
|
ready_o : out std_logic; -- I have detected a valid new pixel
|
|
|
|
psalgnerr : out std_logic; -- Phase alignment error
|
|
|
|
c0_o : out std_logic;
|
|
|
|
c1_o : out std_logic;
|
|
|
|
de_o : out std_logic;
|
|
|
|
sdout_o : out std_logic_vector(9 downto 0);
|
|
|
|
dout_o : out std_logic_vector(7 downto 0)
|
|
|
|
);
|
|
|
|
end decoder;
|
|
|
|
|
|
|
|
architecture decoder of decoder is
|
|
|
|
signal rst : std_logic;
|
|
|
|
signal rxclk : std_logic;
|
|
|
|
signal flipgear : std_logic;
|
|
|
|
signal flipgearx2 : std_logic;
|
|
|
|
signal toggle : std_logic;
|
|
|
|
signal rx_toggle : std_logic;
|
|
|
|
signal raw5bit : std_logic_vector(4 downto 0);
|
|
|
|
signal raw5bit_q : std_logic_vector(4 downto 0);
|
|
|
|
signal rawword : std_logic_vector(9 downto 0);
|
|
|
|
|
|
|
|
signal bitslipx2 : std_logic;
|
|
|
|
signal bitslip_q : std_logic;
|
|
|
|
signal bitslip : std_logic;
|
|
|
|
signal psaligned : std_logic;
|
|
|
|
|
|
|
|
signal rawdata : std_logic_vector(9 downto 0);
|
|
|
|
signal sdata : std_logic_vector(9 downto 0);
|
|
|
|
signal ready : std_logic;
|
|
|
|
signal c0 : std_logic;
|
|
|
|
signal c1 : std_logic;
|
|
|
|
signal de : std_logic;
|
|
|
|
signal dout : std_logic_vector(7 downto 0);
|
|
|
|
signal dout_c : std_logic_vector(7 downto 0);
|
|
|
|
signal sdout : std_logic_vector(9 downto 0);
|
|
|
|
signal data : std_logic_vector(7 downto 0);
|
|
|
|
begin
|
|
|
|
rst <= not rst_n;
|
|
|
|
valid_o <= psaligned;
|
|
|
|
ready_o <= ready;
|
|
|
|
c0_o <= c0;
|
|
|
|
c1_o <= c1;
|
|
|
|
de_o <= de;
|
|
|
|
dout_o <= dout;
|
|
|
|
sdout_o <= sdout;
|
|
|
|
|
|
|
|
-- ----------------------------------------------------------
|
|
|
|
-- 5-bit to 10-bit gear box
|
|
|
|
-- ----------------------------------------------------------
|
|
|
|
rx_toggle <= toggle xor flipgearx2; -- reverse hi-lo position
|
|
|
|
|
|
|
|
process (pclkx2, rst_n)
|
|
|
|
begin
|
|
|
|
if rst_n = '0' then
|
|
|
|
toggle <= '0';
|
|
|
|
flipgearx2 <= '0';
|
|
|
|
raw5bit_q <= (others => '0');
|
|
|
|
elsif rising_edge(pclkx2) then
|
|
|
|
flipgearx2 <= flipgear;
|
|
|
|
raw5bit_q <= raw5bit;
|
|
|
|
toggle <= not toggle;
|
|
|
|
|
|
|
|
-- gear from 5 bit to 10 bit
|
|
|
|
if rx_toggle = '1' then
|
|
|
|
rawword <= raw5bit & raw5bit_q;
|
|
|
|
end if;
|
|
|
|
end if;
|
|
|
|
end process;
|
|
|
|
|
|
|
|
-- ----------------------------------------------------------
|
|
|
|
-- bitslip signal sync to pclkx2
|
|
|
|
-- ----------------------------------------------------------
|
|
|
|
process (pclkx2, rst_n)
|
|
|
|
begin
|
|
|
|
if rst_n = '0' then
|
|
|
|
bitslip_q <= '0';
|
|
|
|
bitslipx2 <= '0';
|
|
|
|
elsif rising_edge(pclkx2) then
|
|
|
|
bitslip_q <= bitslip;
|
|
|
|
bitslipx2 <= bitslip and not bitslip_q;
|
|
|
|
end if;
|
|
|
|
end process;
|
|
|
|
|
|
|
|
-- ----------------------------------------------------------
|
|
|
|
-- 1:5 de-serializer working at x2 pclk rate
|
|
|
|
-- ----------------------------------------------------------
|
|
|
|
des_0: entity work.serdes_1_to_5_diff_data
|
|
|
|
generic map (
|
|
|
|
DIFF_TERM => false,
|
|
|
|
BITSLIP_ENABLE => true
|
|
|
|
-- DIFF_TERM => "FALSE",
|
|
|
|
-- BITSLIP_ENABLE => "TRUE"
|
|
|
|
)
|
|
|
|
port map (
|
|
|
|
rst => rst,
|
|
|
|
gclk => pclkx2,
|
|
|
|
rxioclk_i => pclkx10,
|
|
|
|
datain_p => din_p,
|
|
|
|
datain_n => din_n,
|
|
|
|
use_phase_detector_i => '1',
|
|
|
|
rxserdesstrobe_i => serdesstrobe_i,
|
|
|
|
bitslip_i => bitslipx2,
|
|
|
|
data_o => raw5bit
|
|
|
|
);
|
|
|
|
|
|
|
|
-- ----------------------------------------------------------
|
|
|
|
-- Doing word boundary detection here
|
|
|
|
-- ----------------------------------------------------------
|
|
|
|
rawdata <= rawword;
|
|
|
|
|
|
|
|
-- ----------------------------------------------------------
|
|
|
|
-- Phase Alignment Instance
|
|
|
|
-- ----------------------------------------------------------
|
|
|
|
phsalgn_0: entity work.phsaligner
|
|
|
|
port map (
|
|
|
|
rst_n => rst_n,
|
|
|
|
clk => pclk,
|
|
|
|
sdata_i => rawdata,
|
|
|
|
bitslip_o => bitslip,
|
|
|
|
flipgear_o => flipgear,
|
|
|
|
psaligned_o => psaligned
|
|
|
|
);
|
|
|
|
|
|
|
|
-- ----------------------------------------------------------
|
|
|
|
-- Per Channel De-skew Instance
|
|
|
|
-- ----------------------------------------------------------
|
|
|
|
cbnd: entity work.chnlbond
|
|
|
|
port map (
|
|
|
|
clk => pclk,
|
|
|
|
rst_n => rst_n,
|
|
|
|
rawdata_i => rawdata,
|
|
|
|
psaligned_i => psaligned,
|
|
|
|
other_valid_i => other_valid_i,
|
|
|
|
other_ready_i => other_ready_i,
|
|
|
|
ready_o => ready,
|
|
|
|
sdata_o => sdata
|
|
|
|
);
|
|
|
|
|
|
|
|
-- ----------------------------------------------------------
|
|
|
|
-- performs the 10B-8B decoding function defined in DVI 1.0
|
|
|
|
-- Specification: Section 3.3.3, Figure 3-6, page 31.
|
|
|
|
-- ----------------------------------------------------------
|
|
|
|
data <= not sdata(7 downto 0) when sdata(9) = '1' else sdata(7 downto 0);
|
|
|
|
dout_c(0) <= data(0);
|
|
|
|
dout_c(1) <= data(1) xor data(0) when sdata(8) = '1' else (data(1) xnor data(0));
|
|
|
|
dout_c(2) <= data(2) xor data(1) when sdata(8) = '1' else (data(2) xnor data(1));
|
|
|
|
dout_c(3) <= data(3) xor data(2) when sdata(8) = '1' else (data(3) xnor data(2));
|
|
|
|
dout_c(4) <= data(4) xor data(3) when sdata(8) = '1' else (data(4) xnor data(3));
|
|
|
|
dout_c(5) <= data(5) xor data(4) when sdata(8) = '1' else (data(5) xnor data(4));
|
|
|
|
dout_c(6) <= data(6) xor data(5) when sdata(8) = '1' else (data(6) xnor data(5));
|
|
|
|
dout_c(7) <= data(7) xor data(6) when sdata(8) = '1' else (data(7) xnor data(6));
|
|
|
|
process (pclk, rst_n)
|
|
|
|
begin
|
|
|
|
if rst_n = '0' then
|
|
|
|
c0 <= '0';
|
|
|
|
c1 <= '0';
|
|
|
|
de <= '0';
|
|
|
|
sdout <= (others => '0');
|
|
|
|
dout <= (others => '0');
|
|
|
|
elsif rising_edge(pclk) then
|
|
|
|
if ready = '1' and other_ready_i = "11" then
|
|
|
|
case sdata is
|
|
|
|
when CTRLTOKEN0 =>
|
|
|
|
c0 <= '0'; c1 <= '0'; de <= '0';
|
|
|
|
when CTRLTOKEN1 =>
|
|
|
|
c0 <= '1'; c1 <= '0'; de <= '0';
|
|
|
|
when CTRLTOKEN2 =>
|
|
|
|
c0 <= '0'; c1 <= '1'; de <= '0';
|
|
|
|
when CTRLTOKEN3 =>
|
|
|
|
c0 <= '1'; c1 <= '1'; de <= '0';
|
|
|
|
when others =>
|
|
|
|
dout <= dout_c; de <= '1';
|
|
|
|
end case;
|
|
|
|
sdout <= sdata;
|
|
|
|
else
|
|
|
|
c0 <= '0'; c1 <= '0'; de <= '0';
|
|
|
|
sdout <= (others => '0');
|
|
|
|
dout <= (others => '0');
|
|
|
|
end if;
|
|
|
|
end if;
|
|
|
|
end process;
|
|
|
|
|
|
|
|
end decoder;
|