REVIEW
VGA 时序与实现-CSDN博客
对于不同分辨率,每次使用都去查表比较麻烦;
学习条件编译的使用,减轻后续调用的麻烦。
1. 条件编译格式
条件编译是当设计中满足某个条件时,将该条件下的一段代码编译进设计中。
因此,只需设置编译条件,并在对应的编译条件下编写正确的代码,就可以实现条件编译。
|
cnt_max.v |
`define
CASE_A
//`define CASE_B
`ifdef
CASE_A
`define
CNT_MAX
2000
`elsif CASE_B
`define
CNT_MAX
2500
`endif
|
`include"cnt_max.v" cnt = `CNT_MAX; //注意这里那个` |
2. VGA_parameter.v
// 小梅哥视频23E 多分辨率适配VGA控制器设计_哔哩哔哩_bilibili
包含RGB_MODE
/*
使用时根据实际工作需求选择几个预定义参数就可以
MODE_RGB888 和 MODE_RGB565 两个参数二选一,用来决定驱动工作在 16 位模式还是
24 位模式
针对小梅哥提供的一系列显示设备,各个设备参数如下所述
4.3 寸屏:16 位色 RGB565 模式
5 寸屏:16 位色 RGB565 模式
GM7123 模块使用 24 位色 RGB888 模式,
Resolution_xxxx 预定义用来决定显示设备分辨率,常见设备分辨率如下所述
4.3 寸 TFT 显示屏:Resolution_480x272
5 寸 TFT 显示屏:Resolution_800x480
VGA 常见分辨率:
Resolution_640x480
Resolution_800x600
Resolution_1024x768
Resolution_1280x720
Resolution_1920x1080
*/
//以下两行预定义根据实际使用的模式,选择一个使能,另外一个使用注释的方式屏蔽
`define MODE_RGB888
//`define MODE_RGB565
//以下 7 行预定义根据实际使用的分辨率,选择一个使能,另外 6 个使用注释的方式屏蔽
//`define Resolution_480x272 1 //时钟为 9MHz
`define Resolution_640x480 1 //时钟为 25.175MHz
//`define Resolution_800x480 1 //时钟为 33MHz
//`define Resolution_800x600 1 //时钟为 40MHz
//`define Resolution_1024x768 1 //时钟为 65MHz
//`define Resolution_1280x720 1 //时钟为 74.25MHz
//`define Resolution_1920x1080 1 //时钟为 148.5MHz
//定义不同的颜色深度
`ifdef MODE_RGB888
`define Red_Bits 8
`define Green_Bits 8
`define Blue_Bits 8
`elsif MODE_RGB565
`define Red_Bits 5
`define Green_Bits 6
`define Blue_Bits 5
`endif
//定义不同分辨率的时序参数
`ifdef Resolution_480x272
`define H_Total_Time 12'd525
`define H_Right_Border 12'd0
`define H_Front_Porch 12'd2
`define H_Sync_Time 12'd41
`define H_Back_Porch 12'd2
`define H_Left_Border 12'd0
`define V_Total_Time 12'd286
`define V_Bottom_Border 12'd0
`define V_Front_Porch 12'd2
`define V_Sync_Time 12'd10
`define V_Back_Porch 12'd2
`define V_Top_Border 12'd0
`elsif Resolution_640x480
`define H_Total_Time 12'd800
`define H_Right_Border 12'd8
`define H_Front_Porch 12'd8
`define H_Sync_Time 12'd96
`define H_Back_Porch 12'd40
`define H_Left_Border 12'd8
`define V_Total_Time 12'd525
`define V_Bottom_Border 12'd8
`define V_Front_Porch 12'd2
`define V_Sync_Time 12'd2
`define V_Back_Porch 12'd25
`define V_Top_Border 12'd8
`elsif Resolution_800x480
`define H_Total_Time 12'd1056
`define H_Right_Border 12'd0
`define H_Front_Porch 12'd40
`define H_Sync_Time 12'd128
`define H_Back_Porch 12'd88
`define H_Left_Border 12'd0
`define V_Total_Time 12'd525
`define V_Bottom_Border 12'd8
`define V_Front_Porch 12'd2
`define V_Sync_Time 12'd2
`define V_Back_Porch 12'd25
`define V_Top_Border 12'd8
`elsif Resolution_800x600
`define H_Total_Time 12'd1056
`define H_Right_Border 12'd0
`define H_Front_Porch 12'd40
`define H_Sync_Time 12'd128
`define H_Back_Porch 12'd88
`define H_Left_Border 12'd0
`define V_Total_Time 12'd628
`define V_Bottom_Border 12'd0
`define V_Front_Porch 12'd1
`define V_Sync_Time 12'd4
`define V_Back_Porch 12'd23
`define V_Top_Border 12'd0
`elsif Resolution_1024x768
`define H_Total_Time 12'd1344
`define H_Right_Border 12'd0
`define H_Front_Porch 12'd24
`define H_Sync_Time 12'd136
`define H_Back_Porch 12'd160
`define H_Left_Border 12'd0
`define V_Total_Time 12'd806
`define V_Bottom_Border 12'd0
`define V_Front_Porch 12'd3
`define V_Sync_Time 12'd6
`define V_Back_Porch 12'd29
`define V_Top_Border 12'd0
`elsif Resolution_1280x720
`define H_Total_Time 12'd1650
`define H_Right_Border 12'd0
`define H_Front_Porch 12'd110
`define H_Sync_Time 12'd40
`define H_Back_Porch 12'd220
`define H_Left_Border 12'd0
`define V_Total_Time 12'd750
`define V_Bottom_Border 12'd0
`define V_Front_Porch 12'd5
`define V_Sync_Time 12'd5
`define V_Back_Porch 12'd20
`define V_Top_Border 12'd0
`elsif Resolution_1920x1080
`define H_Total_Time 12'd2200
`define H_Right_Border 12'd0
`define H_Front_Porch 12'd88
`define H_Sync_Time 12'd44
`define H_Back_Porch 12'd148
`define H_Left_Border 12'd0
`define V_Total_Time 12'd1125
`define V_Bottom_Border 12'd0
`define V_Front_Porch 12'd4
`define V_Sync_Time 12'd5
`define V_Back_Porch 12'd36
`define V_Top_Border 12'd0
`endif
3. 对vga增加行列位置信息
`include"vga_parameter.v"
module vga(
input clk ,
input reset_n ,
input [`Red_Bits + `Green_Bits + `Blue_Bits - 1:0]data ,
output reg data_req ,
output reg VGA_HS ,
output reg VGA_VS ,
output reg VGA_BLK ,
output reg [`Red_Bits - 1 :0]VGA_R ,
output reg [`Green_Bits - 1 :0]VGA_G ,
output reg [`Blue_Bits - 1 :0]VGA_B ,
output reg [11:0]H_addr ,
output reg [11:0]V_addr
);
localparam VGA_HS_end = `H_Sync_Time - 1'b1 ;
localparam Hdat_begin = `H_Sync_Time + `H_Back_Porch + `H_Left_Border - 1'b1 ;
localparam Hdat_end = `H_Total_Time - `H_Right_Border - `H_Front_Porch - 1'b1 ;
localparam Hpixel_end = `H_Total_Time - 1'b1 ;
localparam VGA_VS_end = `V_Sync_Time - 1'b1 ;
localparam Vdat_begin = `V_Sync_Time + `V_Back_Porch + `V_Top_Border - 1'b1 ;
localparam Vdat_end = `V_Total_Time - `V_Bottom_Border - `V_Front_Porch - 1'b1 ;
localparam Vline_end = `V_Total_Time - 1'b1 ;
//行计数器
reg[11:0]H_cnt;
always@(posedge clk or negedge reset_n)
if(!reset_n) H_cnt <= 0 ;
else if(H_cnt == Hpixel_end)
H_cnt <= 0 ;
else
H_cnt <= H_cnt + 1'b1 ;
// 场计数器
reg[11:0]V_cnt;
always@(posedge clk or negedge reset_n)
if(!reset_n) V_cnt <= 0 ;
else if(H_cnt == Hpixel_end)
if(V_cnt == Vline_end)
V_cnt <= 0 ;
else
V_cnt <= V_cnt + 1'b1 ;
else
V_cnt <= V_cnt ;
// VGA_HS
always@(posedge clk or negedge reset_n)
if(!reset_n) VGA_HS <= 1;
else if(H_cnt == 0) VGA_HS <= 0;
else if(H_cnt > VGA_HS_end) VGA_HS <= 1;
// VGA_VS
always@(posedge clk or negedge reset_n)
if(!reset_n) VGA_VS <= 1;
else if(V_cnt == 0) VGA_VS <= 0;
else if(V_cnt > VGA_VS_end) VGA_VS <= 1;
// data_req
always@(posedge clk or negedge reset_n)
if(!reset_n) data_req <= 0 ;
else data_req <= ((H_cnt >= Hdat_begin)&&(H_cnt < Hdat_end)&&(V_cnt >= Vdat_begin)&&(V_cnt <= Vdat_end)) ? 1 : 0;
// VGA_BLK
always@(posedge clk or negedge reset_n)
if(!reset_n) VGA_BLK <= 0 ;
else VGA_BLK <= data_req ;
// VGA_RGB
always@(posedge clk )
if(data_req)
{VGA_R,VGA_G,VGA_B} <= data;
else
{VGA_R,VGA_G,VGA_B} <= 0;
//address
always@(posedge clk )
if(data_req)
begin
H_addr <= H_cnt - Hdat_begin;
V_addr <= V_cnt - Vdat_begin;
end
else
begin
H_addr <= 0;
V_addr <= 0;
end
endmodule
4. tb
`timescale 1ns / 1ns
module vga_tb( );
reg clk , reset_n;
reg [`Red_Bits + `Green_Bits + `Blue_Bits - 1'b1:0]data;
wire data_req ,VGA_HS ,VGA_VS ,VGA_BLK;
wire [`Red_Bits- 1'b1:0]VGA_R;
wire [`Green_Bits- 1'b1:0]VGA_G;
wire [`Blue_Bits- 1'b1:0]VGA_B;
wire [11:0]H_addr ;
wire [11:0]V_addr ;
vga vga_(
clk ,
reset_n ,
data ,
data_req ,
VGA_HS ,
VGA_VS ,
VGA_BLK ,
VGA_R ,
VGA_G ,
VGA_B ,
H_addr ,
V_addr
);
initial clk = 1 ;
always#20 clk = ~clk ;
initial
begin
reset_n = 0 ;
#201 ;
reset_n = 1 ;
#40000000;
$stop;
end
always@(posedge clk or negedge reset_n)
if(!reset_n) data <= 20'b11110000000100000001 ;
else if(data_req) data <= data + 1'b1 ;
else data <= data ;
endmodule
5. 运行结果
行 |
场 |