---------------------------------------------------------------------------- -- top.vhd -- MicroZed simple HDMI example -- Version 1.1 -- -- Copyright (C) 2015 H.Poetzl -- -- This program is free software: you can redistribute it and/or -- modify it under the terms of the GNU General Public License -- as published by the Free Software Foundation, either version -- 2 of the License, or (at your option) any later version. -- -- Vivado 2014.2: -- mkdir -p build.vivado -- (cd build.vivado && vivado -mode tcl -source ../vivado.tcl) ---------------------------------------------------------------------------- library IEEE; use IEEE.std_logic_1164.all; use IEEE.numeric_std.ALL; library unisim; use unisim.VCOMPONENTS.ALL; use work.vect_pkg.ALL; entity top is port ( hdmi_north_clk_p : out std_logic; hdmi_north_clk_n : out std_logic; -- hdmi_north_d_p : out std_logic_vector (2 downto 0); hdmi_north_d_n : out std_logic_vector (2 downto 0); -- hdmi_north_scl : inout std_logic; hdmi_north_sda : inout std_logic; -- hdmi_south_clk_p : out std_logic; hdmi_south_clk_n : out std_logic; -- hdmi_south_d_p : out std_logic_vector (2 downto 0); hdmi_south_d_n : out std_logic_vector (2 downto 0); -- hdmi_south_scl : inout std_logic; hdmi_south_sda : inout std_logic; -- debug : out std_logic_vector (1 downto 0); -- i2c_sda : inout std_logic; i2c_scl : inout std_logic ); end entity top; architecture RTL of top is signal clk_125 : std_logic; signal clk_cfg : std_logic; signal clk_cfgm : std_logic; signal blue_led_n : std_logic; signal blue_led : std_logic; -------------------------------------------------------------------- -- MMCM/PLL Signals -------------------------------------------------------------------- signal pll_fbout : std_logic; signal pll_fbin : std_logic; signal pll_locked : std_logic; signal pll_pwrdwn : std_logic; signal pll_reset : std_logic; signal pll_pix_clk : std_logic; signal pll_bit_clk : std_logic; signal pix_clk : std_logic; signal bit_clk : std_logic; signal scan_clk : std_logic; signal scan_reset : std_logic; signal scan_pream : std_logic; signal scan_guard : std_logic; signal scan_blank : std_logic; signal scan_hsync : std_logic; signal scan_vsync : std_logic; signal scan_hpos : std_logic_vector (11 downto 0); signal scan_vpos : std_logic_vector (11 downto 0); signal scan_frame : std_logic; -------------------------------------------------------------------- -- North Signals -------------------------------------------------------------------- signal rgb_north_data : vec8_a (2 downto 0) := (others => (others => '0')); signal rgb_north_pream : std_logic; signal rgb_north_guard : std_logic; signal rgb_north_blank : std_logic; signal rgb_north_hsync : std_logic; signal rgb_north_vsync : std_logic; signal tmds_north_io : std_logic_vector (3 downto 0); -------------------------------------------------------------------- -- South Signals -------------------------------------------------------------------- signal rgb_south_data : vec8_a (2 downto 0) := (others => (others => '0')); signal rgb_south_pream : std_logic; signal rgb_south_guard : std_logic; signal rgb_south_blank : std_logic; signal rgb_south_hsync : std_logic; signal rgb_south_vsync : std_logic; signal tmds_south_io : std_logic_vector (3 downto 0); -------------------------------------------------------------------- -- Control Signals -------------------------------------------------------------------- signal hdmi_enable : std_logic; signal hdmi_reset : std_logic; -------------------------------------------------------------------- -- PS7 Signals -------------------------------------------------------------------- signal ps_fclk : std_logic_vector (3 downto 0); signal ps_reset_n : std_logic_vector (3 downto 0); signal emio_gpio : std_logic_vector (63 downto 0); -------------------------------------------------------------------- -- I2C Signals -------------------------------------------------------------------- signal i2c0_sda_i : std_logic; signal i2c0_sda_o : std_logic; signal i2c0_sda_t : std_logic; signal i2c0_sda_t_n : std_logic; signal i2c0_scl_i : std_logic; signal i2c0_scl_o : std_logic; signal i2c0_scl_t : std_logic; signal i2c0_scl_t_n : std_logic; signal i2c1_sda_i : std_logic; signal i2c1_sda_o : std_logic; signal i2c1_sda_t : std_logic; signal i2c1_sda_t_n : std_logic; signal i2c1_scl_i : std_logic; signal i2c1_scl_o : std_logic; signal i2c1_scl_t : std_logic; signal i2c1_scl_t_n : std_logic; begin -------------------------------------------------------------------- -- PS7 Interface -------------------------------------------------------------------- ps7_stub_inst : entity work.ps7_stub port map ( ps_fclk => ps_fclk, ps_reset_n => ps_reset_n, -- emio_gpio_o => emio_gpio, -- i2c0_sda_i => i2c0_sda_i, i2c0_sda_o => i2c0_sda_o, i2c0_sda_t_n => i2c0_sda_t_n, -- i2c0_scl_i => i2c0_scl_i, i2c0_scl_o => i2c0_scl_o, i2c0_scl_t_n => i2c0_scl_t_n, -- i2c1_sda_i => i2c1_sda_i, i2c1_sda_o => i2c1_sda_o, i2c1_sda_t_n => i2c1_sda_t_n, -- i2c1_scl_i => i2c1_scl_i, i2c1_scl_o => i2c1_scl_o, i2c1_scl_t_n => i2c1_scl_t_n); clk_125 <= ps_fclk(3); -------------------------------------------------------------------- -- I2C Interface -------------------------------------------------------------------- i2c1_sda_t <= not i2c1_sda_t_n; IOBUF_sda_inst : IOBUF port map ( I => i2c1_sda_o, O => i2c1_sda_i, T => i2c1_sda_t, IO => i2c_sda ); i2c1_scl_t <= not i2c1_scl_t_n; PULLUP_sda_inst : PULLUP port map ( O => i2c_sda ); IOBUF_scl_inst : IOBUF port map ( I => i2c1_scl_o, O => i2c1_scl_i, T => i2c1_scl_t, IO => i2c_scl ); PULLUP_scl_inst : PULLUP port map ( O => i2c_scl ); -------------------------------------------------------------------- -- HDMI North I/O -------------------------------------------------------------------- OBUFDS_north_clk_inst : OBUFDS port map ( O => hdmi_north_clk_p, OB => hdmi_north_clk_n, I => tmds_north_io(3) ); OBUFDS_NORTH_GEN: for I in 2 downto 0 generate OBUFDS_north_data_inst : OBUFDS port map ( O => hdmi_north_d_p(I), OB => hdmi_north_d_n(I), I => tmds_north_io(2 - I) ); end generate; hdmi_north_scl <= 'Z'; hdmi_north_sda <= 'Z'; -------------------------------------------------------------------- -- HDMI South I/O -------------------------------------------------------------------- OBUFDS_south_clk_inst : OBUFDS port map ( O => hdmi_south_clk_p, OB => hdmi_south_clk_n, I => tmds_south_io(3) ); OBUFDS_SOUTH_GEN: for I in 2 downto 0 generate OBUFDS_south_data_inst : OBUFDS port map ( O => hdmi_south_d_p(I), OB => hdmi_south_d_n(I), I => tmds_south_io(2 - I) ); end generate; -- hdmi_south_scl <= 'Z'; -- hdmi_south_sda <= 'Z'; -------------------------------------------------------------------- -- Startup for DONE LED -------------------------------------------------------------------- STARTUPE2_inst : STARTUPE2 generic map ( PROG_USR => "FALSE", -- Program event security feature. SIM_CCLK_FREQ => 0.0 ) -- Configuration Clock Frequency(ns) port map ( CFGCLK => clk_cfg, -- 1-bit output: Configuration main clock output CFGMCLK => clk_cfgm, -- 1-bit output: Configuration internal oscillator clock output EOS => open, -- 1-bit output: Active high output signal indicating the End Of Startup. PREQ => open, -- 1-bit output: PROGRAM request to fabric output CLK => '0', -- 1-bit input: User start-up clock input GSR => '0', -- 1-bit input: Global Set/Reset input (GSR cannot be used for the port name) GTS => '0', -- 1-bit input: Global 3-state input (GTS cannot be used for the port name) KEYCLEARB => '0', -- 1-bit input: Clear AES Decrypter Key input from Battery-Backed RAM (BBRAM) PACK => '0', -- 1-bit input: PROGRAM acknowledge input USRCCLKO => '0', -- 1-bit input: User CCLK input USRCCLKTS => '0', -- 1-bit input: User CCLK 3-state enable input USRDONEO => '0', -- 1-bit input: User DONE pin output control USRDONETS => blue_led_n ); -- 1-bit input: User DONE 3-state enable output blue_led_n <= not blue_led when emio_gpio(12) = '1' else emio_gpio(13); div_led_inst0 : entity work.async_div generic map ( STAGES => 28 ) port map ( clk_in => bit_clk, clk_out => blue_led ); -------------------------------------------------------------------- -- MMCME (PLL) -------------------------------------------------------------------- mmcm_inst : MMCME2_BASE generic map ( BANDWIDTH => "LOW", CLKIN1_PERIOD => 8.0, -- CLKFBOUT_MULT_F => 11.88, CLKFBOUT_PHASE => 0.000, -- CLKOUT0_DIVIDE_F => 5.0, -- *20 for debug CLKOUT1_DIVIDE => 1, -- *20 for debug -- CLKOUT0_PHASE => 0.000, CLKOUT1_PHASE => 0.000, -- DIVCLK_DIVIDE => 2 ) port map ( CLKIN1 => clk_125, CLKFBOUT => pll_fbout, CLKFBIN => pll_fbin, CLKOUT0 => pll_pix_clk, CLKOUT1 => pll_bit_clk, LOCKED => pll_locked, PWRDWN => pll_pwrdwn, RST => pll_reset ); pll_fbin <= pll_fbout; pll_pwrdwn <= '0'; pll_reset <= '0'; BUFG_bit_clk_inst : BUFG port map ( I => pll_bit_clk, -- 1-bit input: Clock buffer input O => bit_clk ); -- 1-bit output: Clock output port BUFG_pix_clk_inst : BUFG port map ( I => pll_pix_clk, -- 1-bit input: Clock buffer input O => pix_clk ); -- 1-bit output: Clock output port -------------------------------------------------------------------- -- Scan Generator (shared) -------------------------------------------------------------------- scan_hdmi_inst : entity work.scan_hdmi port map ( clk => scan_clk, reset => scan_reset, -- total_w => x"897", -- 2200 clocks horizontal total_h => x"464", -- 1125 clocks vertical -- pream_s => x"88E", -- 8 clocks before guard guard_s => x"896", -- 2 clocks before active hdisp_e => x"780", -- 1920 active clocks vdisp_e => x"438", -- 1080 active rows -- hsync_s => x"7D8", -- 88 clocks after video hsync_e => x"804", -- 148 clocks before active vsync_s => x"43C", -- 41 rows before video vsync_e => x"441", -- 5 rows vsync -- pream => scan_pream, guard => scan_guard, blank => scan_blank, hsync => scan_hsync, vsync => scan_vsync, -- hpos => scan_hpos, vpos => scan_vpos, frame => scan_frame); scan_clk <= pix_clk; scan_reset <= '0'; -------------------------------------------------------------------- -- North Image -------------------------------------------------------------------- rgb_north_proc : process (scan_clk) begin if rising_edge(scan_clk) then if scan_hpos = x"000" or scan_vpos = x"000" or scan_hpos = x"77F" or scan_vpos = x"437" then rgb_north_data(0) <= x"FFF"; rgb_north_data(1) <= x"FFF"; rgb_north_data(2) <= x"FFF"; else rgb_north_data(0) <= scan_hpos(7 downto 0); rgb_north_data(1) <= scan_vpos(7 downto 0); rgb_north_data(2) <= scan_hpos(10 downto 8) & scan_vpos(9 downto 8) & "000"; end if; rgb_north_vsync <= scan_vsync; rgb_north_hsync <= scan_hsync; rgb_north_pream <= scan_pream; rgb_north_guard <= scan_guard; rgb_north_blank <= scan_blank; end if; end process; -------------------------------------------------------------------- -- South Image -------------------------------------------------------------------- rgb_south_proc : process (scan_clk) begin if rising_edge(scan_clk) then if scan_hpos = x"000" or scan_vpos = x"000" then rgb_south_data(0) <= x"FFF"; rgb_south_data(1) <= x"FFF"; rgb_south_data(2) <= x"FFF"; else rgb_south_data(0) <= scan_hpos(7 downto 0); rgb_south_data(1) <= scan_vpos(7 downto 0); rgb_south_data(2) <= scan_hpos(10 downto 8) & scan_vpos(9 downto 8) & "000"; end if; rgb_south_vsync <= scan_vsync; rgb_south_hsync <= scan_hsync; rgb_south_pream <= scan_pream; rgb_south_guard <= scan_guard; rgb_south_blank <= scan_blank; end if; end process; -------------------------------------------------------------------- -- North TMDS Conversion -------------------------------------------------------------------- hdmi_tmds_north_inst : entity work.hdmi_tmds port map ( pix_clk => pix_clk, bit_clk => bit_clk, -- enable => hdmi_enable, reset => hdmi_reset, -- rgb => rgb_north_data, -- pream => rgb_north_pream, guard => rgb_north_guard, blank => rgb_north_blank, hsync => rgb_north_hsync, vsync => rgb_north_vsync, -- d0idx => emio_gpio(1 downto 0) xor "00", d1idx => emio_gpio(4 downto 3) xor "01", d2idx => emio_gpio(7 downto 6) xor "10", clidx => emio_gpio(10 downto 9) xor "11", -- d0inv => emio_gpio(2) xor '0', d1inv => emio_gpio(5) xor '0', d2inv => emio_gpio(8) xor '0', clinv => emio_gpio(11) xor '0', -- tmds => tmds_north_io ); -------------------------------------------------------------------- -- South TMDS Conversion -------------------------------------------------------------------- hdmi_tmds_south_inst : entity work.hdmi_tmds port map ( pix_clk => pix_clk, bit_clk => bit_clk, -- enable => hdmi_enable, reset => hdmi_reset, -- rgb => rgb_south_data, -- pream => rgb_south_pream, guard => rgb_south_guard, blank => rgb_south_blank, hsync => rgb_south_hsync, vsync => rgb_south_vsync, -- d0idx => emio_gpio(1 downto 0) xor "00", d1idx => emio_gpio(4 downto 3) xor "01", d2idx => emio_gpio(7 downto 6) xor "10", clidx => emio_gpio(10 downto 9) xor "11", -- d0inv => emio_gpio(2) xor '1', d1inv => emio_gpio(5) xor '0', d2inv => emio_gpio(8) xor '0', clinv => emio_gpio(11) xor '1', -- tmds => tmds_south_io ); -------------------------------------------------------------------- -- Control -------------------------------------------------------------------- hdmi_reset <= emio_gpio(14); hdmi_enable <= '1'; debug(0) <= rgb_south_pream; debug(1) <= rgb_south_guard; hdmi_south_scl <= rgb_south_hsync; hdmi_south_sda <= rgb_south_vsync; end RTL;