diff --git a/dvi_tb.vhd b/dvi_tb.vhd new file mode 100644 index 0000000..9a0c8d8 --- /dev/null +++ b/dvi_tb.vhd @@ -0,0 +1,208 @@ +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_tb IS +END dvi_tb; + +ARCHITECTURE rtl OF dvi_tb IS + constant CLK_PERIOD : time := 20.0 ns; + constant CLK1_PERIOD : time := 10.0 ns; + constant CLK2_PERIOD : time := 2.0 ns; + signal clk : std_logic; + signal clk1 : std_logic; + signal clk2 : std_logic; + signal rst : std_logic; + signal rst_n : std_logic; + + signal en_stb_i : std_logic; + signal hsync_o : std_logic; + signal vsync_o : std_logic; + signal color_en_o : std_logic; + signal color_o : color_t(COLOR_CNT-1 downto 0); + + signal en_stb_iq : std_logic; + signal hsync_oq : std_logic; + signal vsync_oq : std_logic; + signal color_en_oq : std_logic; + signal color_oq : color_t(COLOR_CNT-1 downto 0); + + -- dvi encoder + signal pclk : std_logic; + signal pclk_buf : std_logic; + signal tx_pclkx2 : std_logic; + signal tx_pclkx10 : std_logic; + signal tx_reset_n : std_logic; + signal tx_serdesstrobe : std_logic; + signal tx_clkfbout : std_logic; + signal tx_clkfbin : std_logic; + signal tx_plllckd : std_logic; + signal tx_pllclk0 : std_logic; + signal tx_pllclk2 : std_logic; + signal tx_bufpll_lock : std_logic; + signal tx_tmds : std_logic_vector(3 downto 0); + signal tx_tmds_n : std_logic_vector(3 downto 0); + + -- dvi decoder + signal rx_pll_lckd : std_logic; + signal rx_rst_n : std_logic; + signal rx_pclk : std_logic; + signal rx_hsync : std_logic; + signal rx_vsync : std_logic; + signal rx_color : color_t(COLOR_CNT-1 downto 0); + signal rx_color_en : std_logic; +BEGIN + rst <= transport '1', '0' after (4 * CLK_PERIOD); + rst_n <= not rst; + + clock: process + begin + clk <= '1', '0' after CLK_PERIOD/2; + wait for CLK_PERIOD; + end process; + clock1: process + begin + clk1 <= '1', '0' after CLK1_PERIOD/2; + wait for CLK1_PERIOD; + end process; + clock2: process + begin + clk2 <= '1', '0' after CLK2_PERIOD/2; + wait for CLK2_PERIOD; + end process; + + -- ---------------------------------------------------------------------------- + -- ---------------------------------------------------------------------------- + -- DVI ENCODER + -- ---------------------------------------------------------------------------- + -- ---------------------------------------------------------------------------- + -- ---------------------------------------------------------------------------- + -- Instantiate a dedicate PLL for output port + -- ---------------------------------------------------------------------------- + tx_plllckd <= rst_n; + tx_pllclk0 <= clk2; + pclk_buf <= clk; + tx_pllclk2 <= clk1; + + pclk_buf_0: BUFG port map(I => pclk_buf, O => pclk); + + -- ---------------------------------------------------------------------------- + -- This BUFG is needed in order to deskew between PLL clkin and clkout + -- So the tx0 pclkx2 and pclkx10 will have the same phase as the pclk input + -- ---------------------------------------------------------------------------- + tx_clkfb_buf: BUFG port map(I => tx_clkfbout, O => tx_clkfbin); + + -- -------------------------------- + -- regenerate pclkx2 for TX + -- -------------------------------- + tx_pclkx2_buf: BUFG port map(I => tx_pllclk2, O => tx_pclkx2); + + -- -------------------------------- + -- regenerate pclkx10 for TX + -- -------------------------------- + tx_ioclk_buf: BUFPLL + generic map ( DIVIDE => 5 ) + port map ( + PLLIN => tx_pllclk0, + GCLK => tx_pclkx2, + LOCKED => tx_plllckd, + IOCLK => tx_pclkx10, + SERDESSTROBE => tx_serdesstrobe, + LOCK => tx_bufpll_lock + ); + tx_reset_n <= tx_bufpll_lock; + + dvi_encoder_0: entity work.dvi_encoder + port map ( + rst_n => tx_reset_n, + pclk => pclk, + pclkx2 => tx_pclkx2, + pclkx10 => tx_pclkx10, + serdesstrobe_i => tx_serdesstrobe, + color_i => color_o, + hsync_i => hsync_o, + vsync_i => vsync_o, + dat_en_i => color_en_o, + tmds_p => tx_tmds, + tmds_n => tx_tmds_n + ); + + reg: process begin + wait until rising_edge(clk); + en_stb_iq <= en_stb_i; + hsync_o <= hsync_oq; + vsync_o <= vsync_oq; + color_o <= color_oq; + color_en_o <= color_en_oq; + end process; + + dut: entity work.sig + generic map ( + H_ACTIVE_PIXEL => x"500", + H_BLANKING => x"198", + H_SYNC_WIDTH => x"070", + H_SYNC_OFFSET => x"030", + V_ACTIVE_LINES => x"400", + V_BLANKING => x"02a", + V_SYNC_WIDTH => x"01", + V_SYNC_OFFSET => x"03" + ) + port map ( + clk => clk, + rst_n => rst_n, + en_stb_i => en_stb_iq, + hsync_o => hsync_oq, + vsync_o => vsync_oq, + color_en_o => color_en_oq, + color_o => color_oq + ); + + beh: process begin + en_stb_i <= '0'; + wait for 250000 ns; + en_stb_i <= '1'; + wait; + end process; + + -- ---------------------------------------------------------------------------- + -- ---------------------------------------------------------------------------- + -- DVI DECODER + -- ---------------------------------------------------------------------------- + -- ---------------------------------------------------------------------------- + dvi_decoder_0: entity work.dvi_decoder + port map ( + ext_rst => rst, + + tmdsclk_p => tx_tmds(3), + tmdsclk_n => tx_tmds_n(3), + din_p => tx_tmds(2 downto 0), + din_n => tx_tmds_n(2 downto 0), + + reset_n => rx_rst_n, -- rx reset + pclk_o => rx_pclk, -- regenerated pixel clock + pclkx2_o => open, -- double rate pixel clock + pclkx10_o => open, -- 10x pixel as IOCLK + + pll_lckd_o => rx_pll_lckd, -- send pll_lckd out so it can be fed into a different BUFPLL + serdesstrobe_o => open, -- BUFPLL serdesstrobe output + tmdsclk_o => open, -- TMDS cable clock + + hsync_o => rx_hsync, -- hsync data + vsync_o => rx_vsync, -- vsync data + valid_o => open, + ready_o => open, + psalgnerr_o => open, + sdout_o => open, + dat_en_o => rx_color_en, -- data enable + color_o => rx_color + ); +end rtl; + +configuration dvi_tb_rtl_cfg of dvi_tb is + for rtl + end for; +end dvi_tb_rtl_cfg;