Menu Close

HDMI FPGA 工程设计1(框架设计)

根据PRX100T-D原理图和项目设计要求,我们设计了hdmi 图像显示项目的框图:

%title插图%num

其中:

虚线中的是fpga内部逻辑,IN_CLK_50M 为板子上的时钟输入给FPGA;PB[7:1] 代表7个按键;HDMI_CLK 为fpga 输出的pixel 时钟(adv7511 视频输入时钟); IIC_SDA,IIC_SCL 为fpga 输出用来配置adv7511 寄存器;  HDMI_HS,HDMI_VS,HDMI_D[23:0],  HDMI_EN 有fpga 输出, 提供给adv7511 作为VESA视频格式信号。

FPGA主要分为几个主要的模块:

  • pll:输入的时钟源50M 时钟, 产生50M 系统时钟; 产生VESA 标准所需要的148.5M 时钟(1920 x 1080 @60Hz)。
  • key_filter: 使用148.5M 时钟, 将输入按键滤波,同时产生和148.5M时钟同步的单沿脉冲。
  • rom: 存储莲花图像数据,之后会根据VESA 标准 ,将数据输出到adv7511 上。
  • vga_driver: 产生VESA标准的1920 x 1080 @ 60Hz 所需要的h,v,de 信号。
  • vga_show: 根据h,v,de等信号,平时输出莲花图像在屏幕中心,当有按键信号时, 根据按键信号的含义,将图像上下左右移动, 按OK 键 ,回到初始位置。
  • iic_cfg: 用于配置adv7511 芯片, 包括adv7511 输入视频格式, 输出视频格式等。

 

设计需求:

  • 要求使用100T开发板上的ADV7511进行图片显示;
  • 显示区域分辨率为1920*1080,要显示的图片分辨率480 * 270pix;
  • 要求图片显示在屏幕中央,可以通过按键进行上下移动, 按下中心按键可以返回中心;

%title插图%num

 

项目顶层代码:

`timescale 1ns / 1ps
module hdmi_pic_show
(

    input               IN_CLK_50M,
    input   [7:1]       PB,

    output              HDMI_CLK,
    output              HDMI_HS,
    output              HDMI_VS,
    output              HDMI_EN,
    output  [23:0]      HDMI_D,

    inout               IIC_SDA,
    inout               IIC_SCL
);
    
//====================================
//pll
wire    sys_clk_50m,vga_clk;
wire    locked,sys_rst_n;

pll pll_inst
(
    .clk_out1   (sys_clk_50m),  // output clk_out1
    .clk_out2   (vga_clk),      // 148.5MHz
    .reset      (1'b0),         // input reset
    .locked     (locked),       // output locked
    .clk_in1    (IN_CLK_50M)
);      // input clk_in1
  
assign   sys_rst_n = locked;
//=====================================
//key
wire    center_flag;
wire    up_flag;
wire    down_flag;
wire    left_flag;
wire    right_flag;

key_filter #(
    .DVI_CNT(148)
)
key_filter_inst(
    .clk        (vga_clk),
    .rst_n      (sys_rst_n),
    .pb         (PB),
    .center_flag(center_flag),
    .up_flag    (up_flag),
    .down_flag  (down_flag),
    .left_flag  (left_flag),
    .right_flag (right_flag)
    );
//=================================
//vga_driver
wire		h_sync;
wire		v_sync;
wire		hv_de;

vga_driver #(
    .h_sync_pola (1),
    .v_sync_pola (1)
)
vga_driver_inst(
    .vga_clk    (vga_clk),
    .rst_n      (sys_rst_n),
    
    .h_sync     (h_sync),
    .v_sync     (v_sync),
    .hv_de      (hv_de)
);
//=================================      
//rom   
wire  [16:0]  rd_rom_addr;
wire  [23:0]  rd_rom_data;
pic_rom pic_rom_inst (
  .clka     (vga_clk),      // input wire clka
  .addra    (rd_rom_addr),  // input wire [16 : 0] addra
  .douta    (rd_rom_data)   // output wire [23 : 0] douta
);   

//=================================
// i2c
iic_cfg iic_cfg_inst(
    .clk        (sys_clk_50m),            //50m
    .rst_n      (sys_rst_n),
   
    .iic_sda    (IIC_SDA),
    .iic_scl    (IIC_SCL)
    );  
//================================
vga_show #(
    .h_pix  (1920),
    .v_pix  (1080)
)
vga_show_inst(

    .vga_clk    (vga_clk),
    .rst_n      (sys_rst_n),
    
    .h_sync     (h_sync),
    .v_sync     (v_sync),
    .hv_de      (hv_de),
    
    .center_flag(center_flag),
    .up_flag    (up_flag),
    .down_flag  (down_flag),
    .left_flag  (left_flag),
    .right_flag (right_flag),   
    
    .rd_rom_data(rd_rom_data),
    .rd_rom_addr(rd_rom_addr),
    
    .hdmi_hs    (HDMI_HS),
    .hdmi_vs    (HDMI_VS),
    .hdmi_en    (HDMI_EN),
    .hdmi_d     (HDMI_D)
);

//assign	HDMI_CLK = vga_clk;  

ODDR #
(
    .DDR_CLK_EDGE   ("SAME_EDGE"), // "OPPOSITE_EDGE" or "SAME_EDGE"
    .INIT           (1'b0),        // Initial value of Q: 1'b0 or 1'b1
    .SRTYPE         ("ASYNC")      // Set/Reset type: "SYNC" or "ASYNC"
)
pclk_clk_out
(
    .Q  (HDMI_CLK), // 1-bit DDR output
    .C  (vga_clk),
    .CE (1'b1),     // 1-bit clock enable input
    .D1 (1'b1),     // 1-bit data input (positive edge)
    .D2 (1'b0),     // 1-bit data input (negative edge)
    .R  (1'b0),     // 1-bit reset
    .S  (1'b0)      // 1-bit set
);

endmodule

 

pll 产生的时钟vga_clk (148.5M)没有直接使用assign 输出到pin 上, 而是使用了xilinx 的原语ODDR,这样可以保证时钟比较稳定,不受片外负载的影响。相当于将ODDR 的D1, D2 的数据 输出到HDMI_CLK 上了。

 

Posted in FPGA, FPGA, Verilog, Verilog, Verilog语言编程与FPGA, 教材与教案, 文章

发表评论

相关链接