HDMI

Using Real Digital's HDMI IP Core

2840

Analog/VGA displays are becoming rare, so the Blackboard includes an HDMI source connector to support video controller design projects. Because HDMI display controllers are more complex than analog/VGA controllers, Real Digital provides a VGA-to-HDMI IP block. Using this IP block, users can design a typical VGA controller with resolutions up to 1280x720, and use it to drive the HDMI connector via the VGA-to-HDMI IP block.

The VGA-to-HDMI core receives the VGA timing signals HSync, VSync, and VDE (Video Display Enable), and video data signals (R, G, and B) with up to 8 bits per color. These signals are mapped into HDMI timing and data signals, effectively allowing HDMI controller details to be ignored. Details on accessing and using the VGA-to-HDMI IP block are available in the link. An additional link provides background information on creating a VGA controller circuit.

In addition to the VGA timing and data signals, one additional clock signal running at 5X the pixel clock is needed. This faster clock can be produced using one of the Clock Management Tile IP blocks available in FPGA. Details on configuring and instantiating the CMT IP block are available in the Clocking Wizard link above.

To ensure the video controller can reliably drive displays of at least 720p, a TI HDMI transmitter is used between the FPGA and the HDMI connector.

The figure below shows a block diagram of a display controller based on a VGA controller driving the VGA-to-HDMI IP block. In the FPGA block shown in the figure, the VGA Controller is user-designed IP, and the CMT and VGA to HDMI blocks are pre-existing IP blocks that only need to be configured and instantiated. All three blocks can then be assembled in a higher-level HDL module as shown in the example code.

`timescale 1ns / 1ps

module vga_wrapper(
    input clk,  
    output hdmi_clk_n, hdmi_clk_p, 
    output [2:0] hdmi_tx_n,
    output [2:0] hdmi_tx_p,
);

wire rst;
wire clk_25MHz, clk_125MHz;
wire locked;
wire hsync, vsync, vde;
wire [7:0] red, green, blue;
wire [9:0] px, py;

clk_wiz_0 clk_wiz (
    .clk_out1(clk_25MHz),  
    .clk_out2(clk_125MHz),    
    .reset(rst),
    .locked(locked),
    .clk_in1(clk)
);

vga_sync vga (
    .clk(clk_25MHz),
    .rst(rst),
    .hsync(hsync), 
    .vsync(vsync), 
    .video_active(vde),
    .px(px),
    .py(py)
);


hdmi_tx_0 vga_to_hdmi (
  .pix_clk(clk_25MHz),              
  .pix_clkx5(clk_125MHz),           
  .pix_clk_locked(locked),          
  .rst(rst),               
          
  .red(red2),                      
  .green(green2),                    
  .blue(blue2),                     
  .hsync(hsync),                    
  .vsync(vsync),                    
  .vde(vde),               
 
  .aux0_din(4'b0),              
  .aux1_din(4'b0),              
  .aux2_din(4'b0),              
  .ade(1'b0),                       
  
  // Differential outputs
  .TMDS_CLK_P(hdmi_clk_p),          
  .TMDS_CLK_N(hdmi_clk_n),          
  .TMDS_DATA_P(hdmi_tx_p),         
  .TMDS_DATA_N(hdmi_tx_n)          
);

endmodule