【接口协议】FPGA 驱动 VGA 显示实验(二)实验设计部分

目录

实验任务

实验环境

实验设计

程序设计

VGA 时序模块

模块框图

仿真波形

顶层模块

约束文件


实验任务

利用FPGA驱动VGA实现彩条显示,分辨率为800 × 600@60Hz,分别显示三种颜色。

实验环境

开发环境:vivado 2021.2

FPGA 器件:ZedBoard

实验设计

本次实验VGA显示为800 × 600@60Hz,根据下图的参数可以对相应的参数进行设定。

【接口协议】FPGA 驱动 VGA 显示实验(二)实验设计部分_第1张图片

将参行时序和列时序的参数进行申明

【接口协议】FPGA 驱动 VGA 显示实验(二)实验设计部分_第2张图片

并定义两个计数器,分别计数行和列。并在正确的计数值显示图像信息,根据时序要求,必须在行和列都处于显示区域才可以输出图像显示,也就是出去了同步脉冲部分,这个部分是在扫描一行后切换到下一行的时间,因此这段时间是不输出图像的。

【接口协议】FPGA 驱动 VGA 显示实验(二)实验设计部分_第3张图片

程序设计

VGA 时序模块

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ 
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
// Author      : Linest-5
// File        : vga_800_600.v
// Create      : 2022-10-04 10:08:05
// Revise      : 2022-10-04 11:10:17
// Module Name : vga_800_600
// Description : vga输出分辨率为800*600@60HZ,俄罗斯国旗
// Editor      : sublime text3, tab size (4)
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ 
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

module vga_800_600(
	input                 clk,             //40MHz
	input                 rst,             //复位信号,高有效
	output reg            hsync,           //行同步信号
	output reg            vsync,           //场同步信号
	output reg  [23:0]    vga_data         //VGA输出
	);
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ 
/*       Parameters & Signals                                                    */
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
parameter   H_SYNC_PULSE   =  'd128;       //行同步脉冲 
parameter   H_BACK_PORCH   =  'd88;        //行显示后沿
parameter   H_DISPLAY      =  'd800;       //行显示区域
parameter   H_FRONT_PORCH  =  'd40;        //行显示前沿
parameter   H_FRAME_LEN    =  'd1056;      //行帧长
parameter   V_SYNC_PULSE   =  'd4;         //场同步脉冲
parameter   V_BACK_PORCH   =  'd23;        //场显示后沿
parameter   V_DISPLAY      =  'd600;       //场显示区域 
parameter   V_FRONT_PORCH  =  'd1;         //场显示前沿
parameter   V_FRAME_LEN    =  'd628;       //场帧长

reg   [11:0]              hsync_cnt;
wire                      add_hsync_cnt;
wire                      end_hsync_cnt;
reg   [11:0]              vsync_cnt;
wire                      add_vsync_cnt;
wire                      end_vsync_cnt;

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ 
/*       Main Code                                                               */
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
//行帧长计数
always @(posedge clk or posedge rst) begin
	if (rst) begin
		hsync_cnt <= 'd0;
	end
	else if (add_hsync_cnt && end_hsync_cnt) begin
		hsync_cnt <= 'd0;
	end
	else if (add_hsync_cnt) begin
		hsync_cnt <= hsync_cnt + 'd1;
	end
	else begin
		hsync_cnt <= hsync_cnt;
	end
end

assign add_hsync_cnt = 'd1;
assign end_hsync_cnt = add_hsync_cnt && (hsync_cnt == (H_FRAME_LEN - 1));

//场帧长计数
always @(posedge clk or posedge rst) begin
	if (rst) begin
		vsync_cnt <= 'd0;
	end
	else if (add_vsync_cnt && end_vsync_cnt) begin
		vsync_cnt <= 'd0;
	end
	else if (add_vsync_cnt) begin
		vsync_cnt <= vsync_cnt + 'd1;
	end
	else begin
		vsync_cnt <= vsync_cnt;
	end
end

assign add_vsync_cnt = end_hsync_cnt;
assign end_vsync_cnt = add_vsync_cnt && (vsync_cnt == (V_FRAME_LEN - 1));

//行同步信号
always @(posedge clk or posedge rst) begin
	if (rst) begin
		hsync <= 'd0;
	end
	else if (hsync_cnt >= 'd0 && (hsync_cnt <= (H_SYNC_PULSE - 2))) begin
		hsync <= 'd0;
	end
	else begin
		hsync <= 'd1;
	end
end

//场同步信号
always @(posedge clk or posedge rst) begin
	if (rst) begin
		vsync <= 'd0;
	end
	else if (vsync_cnt >= 'd0 && (vsync_cnt <= (V_SYNC_PULSE - 2))) begin
		vsync <= 'd0;
	end
	else begin
		vsync <= 'd1;
	end
end

//VGA输出信号
always @(posedge clk or posedge rst) begin
	if (rst) begin
		vga_data <= 'd0;      //BLACK
	end
	else if ((hsync_cnt >= 'd215) && (hsync_cnt <= 'd1014) && (vsync_cnt >= 'd26) && (vsync_cnt <= 'd225)) begin
		vga_data <= 24'hffffff;    //white
	end
	else if ((hsync_cnt >= 'd215) && (hsync_cnt <= 'd1014) && (vsync_cnt >= 'd226) && (vsync_cnt <= 'd425)) begin
		vga_data <= 24'h0000ff;    //BLUE
	end
	else if ((hsync_cnt >= 'd215) && (hsync_cnt <= 'd1014) && (vsync_cnt >= 'd426) && (vsync_cnt <= 'd625)) begin
		vga_data <= 24'hff0000;    //RED
	end
	else begin
		vga_data <= 'd0;                     //BLACK
	end
end

endmodule

模块框图

【接口协议】FPGA 驱动 VGA 显示实验(二)实验设计部分_第4张图片

仿真波形

可以看到当行计数每完成依次行帧长计数,场计数加1,由于计数值过大无法展开细看。

【接口协议】FPGA 驱动 VGA 显示实验(二)实验设计部分_第5张图片

顶层模块

顶层模块的作用是例化VGA时序模块以及PLL时钟模块,因为这里VGA所需时钟为40MHz,而板卡上的时钟为100MHz,因此需要例化锁相环将时钟分频到40MHz。最后,因为VGA输出引脚为RGB三种各4个,因此需要将VGA时序模块输出的8位信号截取4位输出。

【接口协议】FPGA 驱动 VGA 显示实验(二)实验设计部分_第6张图片

完整代码

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ 
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
// Author      : Linest-5
// File        : vga_top.v
// Create      : 2022-10-05 19:01:03
// Revise      : 2022-10-05 20:32:00
// Module Name : 
// Description :
// Editor      : sublime text3, tab size (4)
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ 
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

module vga_top(
	input             clk_in,
	input             rst,
	output            hsync,
	output            vsync,
	output  [3:0]     rgb_red,
	output  [3:0]     rgb_green,
	output  [3:0]     rgb_blue
    );

wire                  clk;
wire  [23:0]          vga_data;

assign rgb_red   = vga_data[23:20];
assign rgb_green = vga_data[15:12];
assign rgb_blue  = vga_data[7:4];

vga_800_600 inst_vga_800_600 (
	.clk      (clk),
	.rst      (rst),
	.hsync    (hsync),
	.vsync    (vsync),
	.vga_data (vga_data)
);

vga_clk_40m vga_clk_inst (
    // Clock out ports
    .clk_out1(clk),     // output clk_out1
    // Clock in ports
    .clk_in1(clk_in)   // input clk_in1
);      

endmodule

约束文件

对着原理图进行绑定即可,可以手动约束,也可以自己写约束文件。

set_property PACKAGE_PIN V18 [get_ports {rgb_red[3]}]
set_property PACKAGE_PIN V19 [get_ports {rgb_red[2]}]
set_property PACKAGE_PIN V20 [get_ports {rgb_red[0]}]
set_property PACKAGE_PIN U20 [get_ports {rgb_red[1]}]
set_property PACKAGE_PIN AB22 [get_ports {rgb_green[0]}]
set_property PACKAGE_PIN AA22 [get_ports {rgb_green[1]}]
set_property PACKAGE_PIN AB21 [get_ports {rgb_green[2]}]
set_property PACKAGE_PIN AA21 [get_ports {rgb_green[3]}]
set_property PACKAGE_PIN Y21 [get_ports {rgb_blue[0]}]
set_property PACKAGE_PIN Y20 [get_ports {rgb_blue[1]}]
set_property PACKAGE_PIN AB20 [get_ports {rgb_blue[2]}]
set_property PACKAGE_PIN AB19 [get_ports {rgb_blue[3]}]
set_property PACKAGE_PIN AA19 [get_ports hsync]
set_property PACKAGE_PIN Y19 [get_ports vsync]
set_property PACKAGE_PIN Y9 [get_ports clk_in]
set_property PACKAGE_PIN T18 [get_ports rst]
set_property IOSTANDARD LVCMOS33 [get_ports {rgb_blue[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {rgb_blue[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {rgb_blue[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {rgb_blue[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {rgb_green[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {rgb_green[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {rgb_green[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {rgb_green[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {rgb_red[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {rgb_red[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {rgb_red[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {rgb_red[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports clk_in]
set_property IOSTANDARD LVCMOS33 [get_ports hsync]
set_property IOSTANDARD LVCMOS33 [get_ports rst]
set_property IOSTANDARD LVCMOS33 [get_ports vsync]

最后生成比特流文件下载至板卡,用VGA线将FPGA和显示屏相连接,即可看到以下效果(俄罗斯国旗~)。

【接口协议】FPGA 驱动 VGA 显示实验(二)实验设计部分_第7张图片

你可能感兴趣的:(总线接口协议,fpga开发,VGA,接口,图像处理)