DVI(Digital Visual Interface), DDWG tarafından geliştirilen dijital video görüntü arayüzüdür. İlk olarak 1999'da kullanılmaya başlanmıştır. Dijital bir arayüz olduğundan dolayı VGA gibi analog arayüzlerden, aktarım hızı ve aktarım mesafesi bakımından çok daha başarılıdır. Aktarım single-link için 3 görüntü ve 1 clock hattı olmak üzere toplamda 4 diferansiyel hat üzerinden gerçekleşir. Dual-link'de ek olarak 3 görüntü hattı daha eklenir. Diferansiyel tür olarak CML kullanılır. Aktarım tek yönlüdür.
DVI arayüzünün temeli VGA'dır. VGA HSync, VSync ve RGB sinyallerinden oluşur. HSync ve VSync sinyalleri görüntü senkronizasyon için kullanılır. RGB sinyalleri üzerinden de görüntü sinyali aktarılır. VGA ile daha ayrıntılı bilgi için daha önce yazdığım FPGA ile VGA Monitör Kontrolü yazısına bakabilirsiniz. DVI arayüzü üretilen HSync, VSync ve RGB sinyallerini birleştirerek dijital bir şekilde monitöre aktarır.
HSync, VSync ve RGB sinyalleri serializer'a gitmeden önce TMDS(Transition-minimized differential signaling) kodlayıcıdan geçer. TMDS algoritması diferansiyel hat üzerindeki elekromanyetik girişimi engeller ve DC değeri dengeler. Bu sayede daha uzun mesafelere görüntü sinyali taşınabilir. TMDS kodlama algoritması aşağıda gösterilmiştir.
DVI arayüzünün blok şeması aşağıda gösterilmiştir.
TMDS kodlayıcıdaki C0 ve C1 girişleri kontrol girişleridir. DVI arayüzünde sadece CH0'ın kontrol girişleri kullanılır. Bunlar HSync ve VSync dir. Diğer TMDS kodlayıcıların kontrol girişleri gelecek için rezerve edilmiştir(HDMI'da bu kontrol girişleri ses aktarımı için kullanılmıştır). DE(Data Enable) girişlerine aktif görüntü alanında '1', blanking alanında '0' değerini gönderilir. DVI arayüzünde HSync ve VSync polariteleri her zaman pozitiftir.
FPGA Üzerinde DVI Kontrolcüsü Tasarımı
TMSD Kodlayıcı
VHDL kodu:
-------------------------- TMDS_Encoder.vhd --------------------------- -- Bertan Taşkın -- 7.6.2017 -- Verisyon 1.0 -- -- TMDS kodlayıcı. DVI ve HDMI arayüzleri için elektromanyerik girişimleri -- engelleyerek daha uzun mesafelere aktarımı sağlar. -- -- -- Versiyon Notları: -- -- Versiyon 1.0 (27.6.2017): İlk sürüm. -- --Kütüphaneler library IEEE; use IEEE.STD_LOGIC_1164.ALL; USE ieee.numeric_std.ALL; use ieee.math_real.all; entity TMDS_Encoder is port(Clk, Enable : in std_logic; --Clock ve Enable Girişleri D : in std_logic_vector(7 downto 0); --Data Girişi DE, C0, C1 : in std_logic; --Data Enable ve Kontrol Girişleri q_out : out std_logic_vector(9 downto 0)); --Kodlanmış Data Çıkışı end TMDS_Encoder; architecture Behavioral of TMDS_Encoder is --Data vektöründeki '1' lerin sayısını bulan fonksiyon function N1(Data : std_logic_vector) return integer is variable X : integer := 0; begin a : for i in 0 to Data'length - 1 loop if Data(i) = '1' then X := X + 1; end if; end loop; return X; end N1; --Data vektöründeki '0' ların sayısını bulan fonksiyon function N0(Data : std_logic_vector) return integer is variable X : integer := 0; begin a : for i in 0 to Data'length - 1 loop if Data(i) = '0' then X := X + 1; end if; end loop; return X; end N0; --Std_logic tipini integer'a dönüştüren fonksiyon --'0' için 0, '1' için 1 function StdlogictoInteger(X : std_logic) return integer is begin if X = '1' then return 1; else return 0; end if; end StdlogictoInteger; signal C : std_logic_vector(1 downto 0); signal Cnt : integer; begin C(0) <= C0; C(1) <= C1; process(Clk) variable q_m : std_logic_vector(8 downto 0); begin --TMDS Algoritması if N1(D) > 4 or (N1(D) = 4 and D(0) = '0') then q_m(0) := D(0); q_m(1) := q_m(0) xnor D(1); q_m(2) := q_m(1) xnor D(2); q_m(3) := q_m(2) xnor D(3); q_m(4) := q_m(3) xnor D(4); q_m(5) := q_m(4) xnor D(5); q_m(6) := q_m(5) xnor D(6); q_m(7) := q_m(6) xnor D(7); q_m(8) := '0'; else q_m(0) := D(0); q_m(1) := q_m(0) xor D(1); q_m(2) := q_m(1) xor D(2); q_m(3) := q_m(2) xor D(3); q_m(4) := q_m(3) xor D(4); q_m(5) := q_m(4) xor D(5); q_m(6) := q_m(5) xor D(6); q_m(7) := q_m(6) xor D(7); q_m(8) := '1'; end if; if rising_edge(Clk) and Enable = '1' then if DE = '0' then case C is when "00" => q_out <= "0010101011"; when "01" => q_out <= "1101010100"; when "10" => q_out <= "0010101010"; when others => q_out <= "1101010101"; end case; Cnt <= 0; else if Cnt = 0 or (N1(q_m(7 downto 0)) = N0(q_m(7 downto 0))) then q_out(9) <= not q_m(8); q_out(8) <= q_m(8); if q_m(8) = '1' then q_out(7 downto 0) <= q_m(7 downto 0); else q_out(7 downto 0) <= not q_m(7 downto 0); end if; if q_m(8) = '0' then Cnt <= Cnt + N0(q_m(7 downto 0)) - N1(q_m(7 downto 0)); else Cnt <= Cnt + N1(q_m(7 downto 0)) - N0(q_m(7 downto 0)); end if; else if (Cnt > 0 and N1(q_m(7 downto 0)) > N0(q_m(7 downto 0))) or (Cnt < 0 and N0(q_m(7 downto 0)) > N1(q_m(7 downto 0))) then q_out(9) <= '1'; q_out(8) <= q_m(8); q_out(7 downto 0) <= not q_m(7 downto 0); Cnt <= Cnt + 2 * stdlogictoInteger(q_m(8)) + N0(q_m(7 downto 0)) - N1(q_m(7 downto 0)); else q_out(9) <= '0'; q_out(8) <= q_m(8); q_out(7 downto 0) <= q_m(7 downto 0); Cnt <= Cnt - 2 * stdlogictoInteger(not q_m(8)) + N1(q_m(7 downto 0)) - N0(q_m(7 downto 0)); end if; end if; end if; end if; end process; end Behavioral;
RTL Şeması:
Fmax Değerleri(EP4CE22F17C6, Cyclone IV -6 Speed Grade):
DVI Kontrolcüsü
VHDL kodu:
-------------------------- DVIController.vhd ----------------------------- -- Bertan Taşkın -- 17.10.2017 -- Versiyon 1.0 -- -- DVI kontrolcüsü. Zamanlama parametreleri generic kısmından ayarlanabilir. -- HSync ve VSync polariteleri pozitif olarak ayarlanmıştır. BufferAddress -- aktif pikselin ramdeki adresini işaretler. BufferAddress güncellendikten -- 1 cycle sonra BufferData'dan veriler okunur ve ekranda gösterilir. -- BufferAddress FeedbackClock ile güncellenir ve FeedbackClock'un yükselen -- kenarı ile BufferData okunur. Renk derinliği sabit 24 bittir. BufferData -- aşağıdaki gibi parçalara ayrılabilir: -- -- BufferData <= (Red & Green & Blue) -- -- Versiyon Notları: -- -- Versiyon 1.0 (17.10.2017): İlk sürüm. -- --Kütüphaneler library IEEE; use IEEE.STD_LOGIC_1164.ALL; USE ieee.numeric_std.ALL; use ieee.math_real.all; entity DVIController is generic(HorizontalVisibleArea : natural := 1024; --Zamanlama Parametreleri HorizontalFrontPorch : natural := 24; HorizontalSyncPulse : natural := 136; HorizontalBackPorch : natural := 144; VerticalVisibleArea : natural := 768; VerticalFrontPorch : natural := 3; VerticalSyncPulse : natural := 6; VerticalBackPorch : natural := 29); port(DVIClk, Enable : in std_logic; --Clock ve Enable Girişleri DVI_Channel0 : out std_logic; --DVI Kanal 0 Çıkışı DVI_Channel1 : out std_logic; --DVI Kanal 1 Çıkışı DVI_Channel2 : out std_logic; --DVI Kanal 2 Çıkışı DVI_Clock : out std_logic; --DVI Clock Çıkışı FeedbackClock : out std_logic; --Geri Besleme Clock Çıkışı BufferAddress : out std_logic_vector(31 downto 0); --Buffer Adresi Çıkışı BufferData : in std_logic_vector(23 downto 0)); --Buffer Veri Girişi(RGB) end DVIController; architecture Behavioral of DVIController is --VGA Kontrolcüsü (Versiyon 2.0) component VGA generic(HorizontalVisibleArea : natural := 1440; --Zamanlama Parametreleri HorizontalFrontPorch : natural := 80; HorizontalSyncPulse : natural := 152; HorizontalBackPorch : natural := 232; VerticalVisibleArea : natural := 900; VerticalFrontPorch : natural := 1; VerticalSyncPulse : natural := 3; VerticalBackPorch : natural := 28; HorizontalSyncPolarity : std_logic := '1'; --Sync Polariteleri VerticalSyncPolarity : std_logic := '1'; RGBLength : integer := 8); port(PixelClk, Enable : in std_logic; --Pixel Clock ve Enable Girişi Red, Green, Blue : out unsigned(RGBLength - 1 downto 0); --RGB Çıkışları HSync, VSync : out std_logic; --HSync ve VSync Çıkışı DE : out std_logic; --Data Enable Çıkışı BufferAddress : out std_logic_vector(31 downto 0); --Buffer Address Çıkışı BufferData : in std_logic_vector(RGBLength * 3 - 1 downto 0)); --Buffer Data Girişi end component; --TMDS Kodlayıcı (Versiyon 1.0) component TMDS_Encoder port(Clk, Enable : in std_logic; --Clock ve Enable Girişleri D : in std_logic_vector(7 downto 0); --8 Bitlik veri girişi DE, C0, C1 : in std_logic; --DE ve Kontrol Sinyalleri Girişleri q_out : out std_logic_vector(9 downto 0)); --Kodlanmış Sinyal Çıkışı end component; --Serializer (Versiyon 3.0) component Serializer generic(SerializationFactor : natural := 10; --Serializer Katsayısı NumberofChannel : natural := 1; --Kanal Sayısı ClockPattern : string := "AutoGenerate"; --Clock Pattern'i UserClockPattern : std_logic_vector := "1111100000"; --Kullanıcı Clock Pattern'i FeedbackClockSource : string := "ExternalRing"; --Geri Besleme Clock Kaynağı FeedbackPipelineLength : natural := 2; --Geri Besleme Gecikmesi FirstBit : string := "LSB"); --Gönderilecek İlk Bit port(Clk, Enable : in std_logic; --Clock ve Enable Girişleri DataIn : in std_logic_vector(SerializationFactor * NumberofChannel - 1 downto 0); --Veri Girişi SerializerData : out std_logic_vector(NumberofChannel - 1 downto 0); --Serializer Veri Çıkışı SerializerClock : out std_logic; --Serializer Clock Çıkışı FeedbackClock : out std_logic); --Geri Besleme Clock Çıkışı end component; signal Div10Clk : std_logic; signal Red, Green, Blue : unsigned(7 downto 0); signal HSync, VSync : std_logic; signal DE : std_logic; signal q_out0, q_out1, q_out2 : std_logic_vector(9 downto 0); signal SerOut : std_logic_vector(2 downto 0); signal SerClk : std_logic; begin --VGA sinyal üretici --HSync ve VSync polariteleri pozitif VGAController : VGA generic map(HorizontalVisibleArea => HorizontalVisibleArea, HorizontalFrontPorch => HorizontalFrontPorch, HorizontalSyncPulse => HorizontalSyncPulse, HorizontalBackPorch => HorizontalBackPorch, VerticalVisibleArea => VerticalVisibleArea, VerticalFrontPorch => VerticalFrontPorch, VerticalSyncPulse => VerticalSyncPulse, VerticalBackPorch => VerticalBackPorch, HorizontalSyncPolarity => '1', VerticalSyncPolarity => '1', RGBLength => 8) port map(PixelClk => Div10Clk, Enable => Enable, Red => Red, Green => Green, Blue => Blue, HSync => HSync, VSync => VSync, DE => DE, BufferAddress => BufferAddress, BufferData => BufferData); --Kanal 0 TMDS kodlayıcı --Mavi, HSync ve VSync TMDSEncoder0 : TMDS_Encoder port map(Clk => Div10Clk, Enable => Enable, D => std_logic_vector(Blue), DE => DE, C0 => HSync, C1 => VSync, q_out => q_out0); --Kanal 1 TMDS kodlayıcı --Yeşil TMDSEncoder1 : TMDS_Encoder port map(Clk => Div10Clk, Enable => Enable, D => std_logic_vector(Green), DE => DE, C0 => '0', C1 => '0', q_out => q_out1); --Kanal 2 TMDS kodlayıcı --Kırmızı TMDSEncoder2 : TMDS_Encoder port map(Clk => Div10Clk, Enable => Enable, D => std_logic_vector(Red), DE => DE, C0 => '0', C1 => '0', q_out => q_out2); --Serializer --Serialization Factor = 10 Ser : Serializer generic map(SerializationFactor => 10, NumberofChannel => 3, ClockPattern => "AutoGenerate", UserClockPattern => "1111100000", FeedbackClockSource => "ExternalRing", FeedbackPipelineLength => 2, FirstBit => "LSB") port map(Clk => DVIClk, Enable => Enable, DataIn => (q_out2 & q_out1 & q_out0), SerializerData => SerOut, SerializerClock => SerClk, FeedbackClock => Div10Clk); --Serializer çıkışlarının modül çıkışlarına aktarılması DVI_Channel0 <= SerOut(0); DVI_Channel1 <= SerOut(1); DVI_Channel2 <= SerOut(2); DVI_Clock <= SerClk; --Geri dönüş clock'u FeedbackClock <= Div10Clk; end Behavioral;
RTL Şeması:
Fmax Değerleri(EP4CE22F17C6, Cyclone IV -6 Speed Grade):
1024x768@70Hz, Pixel Clock = 750Mhz, Toplam Hız = 2.25Gbps
Bertan bey iyi günler. Aktif iseniz mesaj atabilirmisiniz.