FPGA的VGA显示驱动部分知识点
vga显示这边的的的知识点不难,在我写代码的时候却没能显示成功,现在重新设计一遍设计思路。
根据下面的这个时序图,可以用计数器的方式来设计,在不同时间段选择显示情况。
目前我电脑的副屏是一个1440*900的显示器,在网上找到了他的VGA时序图。
根据这个与时序表对应。完成项目代码,最后顶层文件例化框图如下,显示效果如下
在第一次模仿写代码的时候,一直不显示,没信号,后来发现是时钟IP核的复位是高电平有效,例化的时候需要取反。
vga_ctrl驱动
module vga_ctrl(
clk_106m, //1904*932*60hz = 106,471,680HZ = 106.5Mhz 时钟IP核只能到这个点
reset_n,
//vga
vga_data_in, //想要输入的信号值
vga_data_out, //实际输出的信号值
hs_count, //行计数
vs_count, //列计数
vga_hs, //行使能
vga_vs, //列使能
vga_blk, //实际显示信号使能
vga_clk
);
input clk_106m;
input reset_n;
input [23:0] vga_data_in; //8位 R G B
output [23:0] vga_data_out;
output [11:0] hs_count; //实际图像区域的像素计数
output [11:0] vs_count;
output vga_hs;
output vga_vs;
output vga_blk;
output vga_clk;
// hs_whole = 1904;
// hs_front_porch = 80;
// hs_sync_pulse = 152;
// hs_real_data = 1440
// hs_back_porch = 232
parameter hs_whole = 1904;
parameter hs_data_begin = 384; //hs_sync_porch + hs_back_porch
parameter hs_sync_pulse = 152;
parameter hs_data_end = 1824; //hs_data_begin + hs_real_data
parameter vs_whole = 932;
parameter vs_data_begin = 31; //hs_sync_porch + hs_back_porch
parameter vs_sync_pulse = 3;
parameter vs_data_end = 931; //hs_data_begin + hs_real_data
reg [11:0] hs_count_r; //行列像素计数
reg [11:0] vs_count_r;
//行计数到最大值清零
always @(posedge clk_106m or negedge reset_n)
if(!reset_n)
hs_count_r <= 0;
else if(hs_count_r == hs_whole - 1)
hs_count_r <= 0;
else
hs_count_r <= hs_count_r + 1'd1;
//列计数到行计数一行结束,到最大值清零
always @(posedge clk_106m or negedge reset_n)
if(!reset_n)
vs_count_r <= 0;
else if(hs_count_r == hs_whole - 1) begin
if(vs_count_r == vs_whole - 1)
vs_count_r <= 0;
else
vs_count_r <= vs_count_r + 1'd1;
end
else
vs_count_r <= vs_count_r;
//阻塞赋值
assign vga_blk = ((hs_count_r >= hs_data_begin) && (hs_count_r < hs_data_end )
&& (vs_count_r >= vs_data_begin) && (vs_count_r < vs_data_end)) ? 1'b1:1'b0;
assign vga_hs = (hs_count_r <= hs_sync_pulse)?1'b0:1'b1;
assign vga_vs = (vs_count_r <= vs_sync_pulse)?1'b0:1'b1;
assign vga_data_out = (vga_blk)?vga_data_in:24'h000000;
assign hs_count = (vga_blk)?(hs_count_r - hs_data_begin):12'd0; //实际的显示图像计数
assign vs_count = (vga_blk)?(vs_count_r - vs_data_begin):12'd0;
assign vga_clk=clk_106m;
endmodule
顶层文件中时钟例化,生成一个106.5M的时钟。
vga_test顶层文件
module vga_test(
clk,
reset_n,
vga_data_out, //实际输出的信号值
vga_hs, //行使能
vga_vs, //列使能
vga_blk, //实际显示信号使能
vga_clk
);
input clk;
input reset_n;
output [23:0] vga_data_out;
output vga_hs;
output vga_vs;
output vga_blk;
output vga_clk;
reg [23:0] vga_data_in;
wire [11:0] hs_count;
wire [11:0] vs_count;
wire clk_106m;
wire locked;
localparam BLACK = 24'h000000,//黑色
BLUE = 24'h0000FF,//蓝色
RED = 24'hFF0000,//红色
PURPPLE = 24'hFF00FF,//紫色
GREEN = 24'h00FF00,//绿色
CYAN = 24'h00FFFF,//青色
YELLOW = 24'hFFFF00,//黄色
WHITE = 24'hFFFFFF;//白色
clk_wiz_0 instance_name
(
// Clock out ports
.clk_out1(clk_106m), // output clk_out1
// Status and control signals
.reset(!reset_n), // input reset
.locked(locked), // output locked
// Clock in ports
.clk_in1(clk)
); // input clk_in1
vga_ctrl vga_ctrl_inst(
.clk_106m(clk_106m), //1904*932*60hz = 106,471,680HZ = 106.5Mhz 时钟IP核只能到这个点
.reset_n(reset_n),
//vga
.vga_data_in(vga_data_in), //想要输入的信号值
.vga_data_out(vga_data_out), //实际输出的信号值
.hs_count(hs_count), //行计数
.vs_count(vs_count), //列计数
.vga_hs(vga_hs), //行使能
.vga_vs(vga_vs), //列使能
.vga_clk(vga_clk),
.vga_blk(vga_blk) //实际显示信号使能
);
//4行2列
wire v0_act = hs_count >= 0 && hs_count < 720; //第一列
wire v1_act = hs_count >= 720 && hs_count < 1440; //第二列
wire h0_act = vs_count >= 0 && vs_count < 225; //第一行
wire h1_act = vs_count >= 225 && vs_count < 450;
wire h2_act = vs_count >= 450 && vs_count < 675;
wire h3_act = vs_count >= 675 && vs_count < 900; //第四行
wire h0_v0_act = h0_act & v0_act;
wire h0_v1_act = h0_act & v1_act;
wire h1_v0_act = h1_act & v0_act;
wire h1_v1_act = h1_act & v1_act;
wire h2_v0_act = h2_act & v0_act;
wire h2_v1_act = h2_act & v1_act;
wire h3_v0_act = h3_act & v0_act;
wire h3_v1_act = h3_act & v1_act;
always @(posedge clk)
begin
case({h3_v1_act,h3_v0_act,h2_v1_act,h2_v0_act,h1_v1_act,h1_v0_act,h0_v1_act,h0_v0_act})
8'b0000_0001: vga_data_in <= BLACK;
8'b0000_0010: vga_data_in <= BLUE;
8'b0000_0100: vga_data_in <= RED;
8'b0000_1000: vga_data_in <= PURPPLE;
8'b0001_0000: vga_data_in <= GREEN;
8'b0010_0000: vga_data_in <= CYAN;
8'b0100_0000: vga_data_in <= YELLOW;
8'b1000_0000: vga_data_in <= WHITE;
endcase
end
endmodule
本文来自博客园,作者:祈愿树下,转载请注明原文链接:https://www.cnblogs.com/cjl520/p/18077434