205 lines
6.4 KiB
VHDL
205 lines
6.4 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 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;
|