话说玩这块板子,也有好长时间了,实在是不怎么溜。连数据显示都搞了很久,这可是数据的一扇窗户啊。
不能看始终不过瘾是不。
好像大多使用的还是VGA的驱动方式,更通用,更简单。但是现在可是高清的时代,好歹也要跟上高清的步伐啊。
虽然官方提供了 好几个 HDMI的历程,不过,我看到那么多ip和,编译一次,好几十分钟,也是。。。
先写HDMI的时序,我这里用的是1280*720的的分辨率,其他的需要自己修改一下,包括像素时钟
----------------------------------------------------------------------------------
-- Engineer: Mike Field
--
-- Create Date: 06:01:06 10/02/2013
--
-- Description:
-- Drive the ADV7511 HDMI encoder directly from the PL fabric
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
Library UNISIM;
use UNISIM.vcomponents.all;
entity zedboard_hdmi is
Port ( clk_100 : in STD_LOGIC;
hdmi_clk : out STD_LOGIC;
hdmi_hsync : out STD_LOGIC;
hdmi_vsync : out STD_LOGIC;
colour : in STD_LOGIC_VECTOR (23 downto 0);
hdmi_d : out STD_LOGIC_VECTOR (15 downto 0);
hdmi_de : out STD_LOGIC;
hdmi_int : in STD_LOGIC;
hdmi_scl : out STD_LOGIC;
hdmi_sda : inout STD_LOGIC);
end zedboard_hdmi;
architecture Behavioral of zedboard_hdmi is
COMPONENT i2c_sender
PORT(
clk : IN std_logic;
resend : IN std_logic;
siod : INOUT std_logic;
sioc : OUT std_logic
);
END COMPONENT;
signal blanking : std_logic := '0';
signal hsync : std_logic := '0';
signal vsync : std_logic := '0';
signal edge : std_logic := '0';
-- signal colour : STD_LOGIC_VECTOR (23 downto 0);
signal Y : STD_LOGIC_VECTOR (15 downto 0);
signal Cr : STD_LOGIC_VECTOR (15 downto 0);
signal Cb : STD_LOGIC_VECTOR (15 downto 0);
signal hdmi_clk_bits : STD_LOGIC_VECTOR (1 downto 0);
signal hcounter : unsigned(10 downto 0) := (others => '0');
signal vcounter : unsigned(10 downto 0) := (others => '0');
constant ZERO : unsigned(10 downto 0) := (others => '0');
signal hVisible : unsigned(10 downto 0);
signal hStartSync : unsigned(10 downto 0);
signal hEndSync : unsigned(10 downto 0);
signal hMax : unsigned(10 downto 0);
signal hSyncActive : std_logic := '1';
signal vVisible : unsigned(10 downto 0);
signal vStartSync : unsigned(10 downto 0);
signal vEndSync : unsigned(10 downto 0);
signal vMax : unsigned(10 downto 0);
signal vSyncActive : std_logic := '1';
signal clk_vgax2 : std_logic;
signal clkfb : std_logic;
signal clk : std_logic;
-- Colours converted using The RGB -> YCbCr converter app found on Google Gadgets
-- Y Cb Cr
constant C_BLACK : std_logic_vector(23 downto 0) := x"108080"; -- 16 128 128
constant C_RED : std_logic_vector(23 downto 0) := x"515AF0"; -- 81 90 240
constant C_GREEN : std_logic_vector(23 downto 0) := x"AC2A1B"; -- 172 42 27
constant C_BLUE : std_logic_vector(23 downto 0) := x"20F076"; -- 32 240 118
constant C_WHITE : std_logic_vector(23 downto 0) := x"EA8080"; -- 234 128 128
begin
-- Set the video mode to 1280x720x60Hz (75MHz pixel clock needed)
hVisible <= ZERO + 1280;
hStartSync <= ZERO + 1280+72;
hEndSync <= ZERO + 1280+72+80;
hMax <= ZERO + 1280+72+80+216-1;
vSyncActive <= '1';
vVisible <= ZERO + 720;
vStartSync <= ZERO + 720+3;
vEndSync <= ZERO + 720+3+5;
vMax <= ZERO + 720+3+5+22-1;
hSyncActive <= '1';
-- colour_proc: process(hcounter,vcounter)
-- begin
-- if hcounter < 256 then
-- colour <= C_RED;
-- elsif hcounter < 512 then
-- colour <= C_BLACK;
-- elsif hcounter < 768 then
-- colour <= C_GREEN;
-- elsif hcounter < 1024 then
-- colour <= C_WHITE;
-- else
-- colour <= C_BLUE;
-- end if;
-- end process;
-- there is a 16 bit interface into the HDMI transmitter, although I only use 8 bits
Y <= colour(23 downto 16) & x"00";
Cb <= colour(15 downto 8) & x"00";
Cr <= colour( 7 downto 0) & x"00";
vga_clkx2_process: process (clk_vgax2)
begin
if rising_edge(clk_VGAx2) then
---------------------------------------------------------------------------
-- signal generation for the HDMI encoder
--
-- Transfer on rising edge of clock Y
-- on falling edge of clock Either Cr or Cb
--
-- Because I am a wimp I don't use any DDR except for generating the DDR clk.
----------------------------------------------------------------------------
if edge = '0' then
edge <= '1';
hdmi_clk_bits <= "11";
if blanking = '1' then
hdmi_d <= (others => '0');
hdmi_de <= '0';
else
hdmi_d <= Y;
hdmi_de <= '1';
end if;
else
edge <= '0';
hdmi_clk_bits <= "00";
if blanking = '1' then
hdmi_d <= (others => '0');
hdmi_de <= '0';
else
if hcounter(0) = '0' then
hdmi_d <= Cr;
else
hdmi_d <= Cb;
end if;
hdmi_de <= '1';
end if;
end if;
hdmi_hsync <= hsync;
hdmi_vsync <= vsync;
------------------------------------------------------------------------
-- VGA Signal Generation
-- We only update when the second clock edge has been sent
--- to the HDMI encoder
------------------------------------------------------------------------
if edge = '1' then
if vcounter >= vVisible then
blanking <= '1';
elsif hcounter >= hVisible then
blanking <= '1';
else
blanking <= '0';
end if;
-- Generate the sync Pulses
if vcounter = vStartSync then
vSync <= vSyncActive;
elsif vCounter = vEndSync then
vSync <= not(vSyncActive);
end if;
if hcounter = hStartSync then
hSync <= hSyncActive;
elsif hCounter = hEndSync then
hSync <= not(hSyncActive);
end if;
-- Advance the position counters
IF hCounter = hMax THEN
-- starting a new line
hCounter <= (others => '0');
IF vCounter = vMax THEN
vCounter <= (others => '0');
ELSE
vCounter <= vCounter + 1;
END IF;
ELSE
hCounter <= hCounter + 1;
END IF;
end if;
end if;
end process;
ODDR_inst : ODDR
generic map(
DDR_CLK_EDGE => "OPPOSITE_EDGE", INIT => '0',SRTYPE => "SYNC")
port map (
Q => hdmi_clk,
C => clk_VGAx2,
D1 => hdmi_clk_bits(0),
D2 => hdmi_clk_bits(1),
CE => '1', R => '0', S => '0'
);
Inst_i2c_sender: i2c_sender PORT MAP(
clk => clk,
resend => '0',
sioc => hdmi_scl,
siod => hdmi_sda
);
-- Generate a 130MHz and 100Mhz clock from the input.
PLLE2_BASE_inst : PLLE2_BASE
generic map (
BANDWIDTH => "OPTIMIZED", -- OPTIMIZED, HIGH, LOW
CLKFBOUT_MULT => 9, -- Multiply value for all CLKOUT, (2-64)
CLKFBOUT_PHASE => 0.0, -- Phase offset in degrees of CLKFB, (-360.000-360.000).
CLKIN1_PERIOD => 10.0, -- Input clock period in ns to ps resolution (i.e. 33.333 is 30 MHz).
-- CLKOUT0_DIVIDE - CLKOUT5_DIVIDE: Divide amount for each CLKOUT (1-128)
CLKOUT0_DIVIDE => 9,
CLKOUT1_DIVIDE => 6,
CLKOUT2_DIVIDE => 1,
CLKOUT3_DIVIDE => 1,
CLKOUT4_DIVIDE => 1,
CLKOUT5_DIVIDE => 1,
-- CLKOUT0_DUTY_CYCLE - CLKOUT5_DUTY_CYCLE: Duty cycle for each CLKOUT (0.001-0.999).
CLKOUT0_DUTY_CYCLE => 0.5,
CLKOUT1_DUTY_CYCLE => 0.5,
CLKOUT2_DUTY_CYCLE => 0.5,
CLKOUT3_DUTY_CYCLE => 0.5,
CLKOUT4_DUTY_CYCLE => 0.5,
CLKOUT5_DUTY_CYCLE => 0.5,
-- CLKOUT0_PHASE - CLKOUT5_PHASE: Phase offset for each CLKOUT (-360.000-360.000).
CLKOUT0_PHASE => 0.0,
CLKOUT1_PHASE => 0.0,
CLKOUT2_PHASE => 0.0,
CLKOUT3_PHASE => 0.0,
CLKOUT4_PHASE => 0.0,
CLKOUT5_PHASE => 0.0,
DIVCLK_DIVIDE => 1, -- Master division value, (1-56)
REF_JITTER1 => 0.0, -- Reference input jitter in UI, (0.000-0.999).
STARTUP_WAIT => "FALSE" -- Delay DONE until PLL Locks, ("TRUE"/"FALSE")
)
port map (
-- Clock Outputs: 1-bit (each) output: User configurable clock outputs
CLKOUT0 => clk,
CLKOUT1 => clk_VGAx2,
CLKOUT2 => open,
CLKOUT3 => open,
CLKOUT4 => open,
CLKOUT5 => open,
CLKFBOUT => clkfb, -- 1-bit output: Feedback clock
LOCKED => open, -- 1-bit output: LOCK
CLKIN1 => clk_100, -- 1-bit input: Input clock
PWRDWN => '0', -- 1-bit input: Power-down
RST => '0', -- 1-bit input: Reset
CLKFBIN => clkfb -- 1-bit input: Feedback clock
);
end Behavioral;
然后封装成ip核
如下图所示
留出了数据的输入输出接口及数据使能端口
然后写一个测试数据的文件,我也把他写出IP核
最后连接 如下图
最后贴一个官方的图
当然了,例程里面实现了很多功能,不过有时候,并不想这样,不是么。
下次使用axi4 stream tpg vtc 来试试HDMI的显示,总的会啊