学习笔记1:verilog VGA控制器

大家可以根据B站小梅哥进行学习

分辨率为640*480

根据行场同步信号需要的各个时间节点。

以行扫描进行分析:(场扫描同理)

  1. Sync Pulse对应 H Sync Time 时间节点96,即代码中的HS_End
  2. Back Porch对应 H Back Porch 时间节点40
  3. Left Border对应H Left Border 时间节点8
  4. 此时行数据开始信号即代码中的Hdat_Begin = 96+40+8=144 即上面序号1.2.3时间节点相加
  5. Visible area对应HData Time 时间节点640即行像素
  6. 此时代码中的Hdat_End = 144 + 640=784 即数据结束位置
  7. Right Boder对应H Right Bordes 时间节点8
  8. Front Porch对应 H Front Porch 时间节点8 
  9. H Total Time = 96+40+8+640+8+8 = 800 即代码中的Hsync_End =800

设计代码:

//640*480
module VGA_CTRL(
	input Clk,//时钟25Mhz换算成40ns
	input Rest_n,
	input [23:0]Data,//输入24位数据
	output reg [9:0]hcount,//扫描行像素的位置 640换算成2进制为10位
	output reg [8:0]vcount,//扫描场像素的位置 480换算成2进制为9位
	output reg VGA_HS,//行脉冲信号
	output reg VGA_VS,//场脉冲信号
	output reg VGA_Blk,//像素输出信号 0-639 0-479
	output reg Data_Req,//数据请求脉冲信号,用于延时一拍,将像素输出信号与数据实时对应
	output reg [23:0]VGA_RGB//输出24位数据
);

localparam Hsync_End = 800;//行同步信号结束位置
localparam Vsync_End = 525;//场同步信号结束位置:单位行
localparam HS_End = 96;//行同步脉冲结束位置
localparam VS_End = 2;//场同步脉冲结束位置:单位行
localparam Hdat_Begin = 144;//行数据开始输出位置
localparam Hdat_End = 784;//行数据结束输出位置
localparam Vdat_Begin = 35;//场数据开始输出位置:单位行
localparam Vdat_End = 515;//场数据结束输出位置:单位行

//行计数器
reg [9:0] h_cnt;//行总共需要计数800个像素,换算为2进制为10位
always @(posedge Clk or negedge Rest_n)
	if(!Rest_n)
		h_cnt <= 1'b0;
	else if( h_cnt == Hsync_End - 1'd1 )
		h_cnt <= 1'b0;
	else 
		h_cnt <= h_cnt + 1'b1;
		 

//行脉冲信号
always @(posedge Clk)
	VGA_HS <= (h_cnt <= (HS_End - 1'd1)) ? 0:1;

//场计数器
reg [9:0] v_cnt;//场总共需要计数525个像素,换算为2进制为10位
always @(posedge Clk or negedge Rest_n)
	if(!Rest_n)
		v_cnt <= 1'b0;
	else  if( h_cnt == Hsync_End - 1'd1 )
		begin
				if(v_cnt == Vsync_End - 1'd1)
					v_cnt <= 1'b0;
				else 
					v_cnt <= v_cnt + 1'b1;
		end
	else 
		v_cnt <= v_cnt;	

//场脉冲信号
always @(posedge Clk)
	VGA_VS <= (v_cnt <= (VS_End - 1'd1)) ? 0:1;

//数据输出信号
always @(posedge Clk)
	Data_Req <= ((h_cnt >= Hdat_Begin - 1'd1)&&(h_cnt < Hdat_End - 1'd1)&&(v_cnt > Vdat_Begin - 1'd1 )&&(v_cnt <= Vdat_End -1'd1))?1:0;

always @(posedge Clk)
	VGA_Blk <= Data_Req;
//数据输出
always @(posedge Clk)
	VGA_RGB <= Data_Req ? Data: 0;
	
//行扫描像素输出
always @(posedge Clk)
	hcount <= Data_Req ? (h_cnt - Hdat_Begin):0;
	
//场扫描像素输出	
always @(posedge Clk)
	vcount <= Data_Req ? (v_cnt - Vdat_Begin):0;


endmodule 

测试代码:

`timescale 1ns / 1ps

module VGA_CTRL_tb();


reg Clk;
reg Rest_n;
reg [23:0]Data;
wire [9:0]hcount;
wire [8:0]vcount;
wire VGA_HS;
wire VGA_VS;
wire VGA_Blk;
wire [23:0]VGA_RGB;
wire Data_Req;

VGA_CTRL VGA_CTRL(
	Clk,
	Rest_n,
	Data,
	hcount,
	vcount,
	VGA_HS,
	VGA_VS,
	VGA_Blk,
	Data_Req,
	VGA_RGB
);

initial Clk = 1;
always #20 Clk = ~Clk;//25M时钟 1/25000000=40ns 即20ns翻转一次


initial begin 
	Rest_n = 0;
	#201;
	Rest_n = 1;
	#200000000;
	$stop;
end

always @( posedge Clk or negedge Rest_n )
	if(!Rest_n)
		Data <= 1'b0;
	else if(Data_Req)
		Data <= Data + 1'b1;
	else 
		Data <= Data;

endmodule 

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

夏澄啊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值