vga彩条显示,640*480模式可以显示1600*900
1. VGA显示
1.1 VGA的端口定义
1.2 VGA的显示时序
扫描显示的过程
行同步时序
场同步时序
二维时序图
1.3 像素点与时序
1.4 此处选择DELL_E2016HV型显示器,分辨率1600900;显示模式为640480@60
2. vivado设计与仿真
2.1 总体框图
2.2 clk_gen模块,主要实现100MHz转25MHz
引入locked和rst_n的必要性,IP核产生的时钟有延时,可以利用locked信号作为标识
在vivado中使用pll,使用的时候直接调用IP核
搜索clk,选择红色框
设置PLL,其他选项默认
仿真图
clk_25mhz产生的时候需要注意的点
1.复位信号sys_rst_n高电平有效,这里的低电平有效是对输入时的数据进行了取反操作
2.clk_25mhz并不是立即产生的,复位信号无效后的第2个周期产生了一个高电平,下图可以看出;
延时 1655-115=150ns 后产生正常的50MHz信号
2.3 vga_pic模块,实现坐标位置与数据的转换
2.3.1 vga_pic.v文件
利用坐标位置 pix_x 赋值时使用到了 casez 语句,增强代码可读性和节省资源;
使用 if-else 多层嵌套也是可以的;
亦可使用 case 语句在关键点赋值,例如 pix_x = 63,…;其他时间保持不变即可
module vga_pic
(
input wire vga_clk ,
input wire sys_rst_n ,
input wire [9:0] pix_x ,
input wire [9:0] pix_y ,
output reg [11:0] pix_data
);
parameter H_VALID = 10'd640,
V_VALID = 10'd480;
parameter RED = 12'hF00,
ORANGE = 12'hF80,
YELLOW = 12'hFF0,
GREEN = 12'h0F0,
CYAN = 12'h0FF,
BLUE = 12'h00F,
PURPLE = 12'hF0F,
BLACK = 12'h000,
WHITE = 12'hFFF,
GRAY = 12'hDDD;
always@(posedge vga_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
pix_data <= RED;
else casez(pix_x)
10'b00_00??_???? : pix_data <= RED ;
10'b00_01??_???? : pix_data <= ORANGE;
10'b00_10??_???? : pix_data <= YELLOW;
10'b00_11??_???? : pix_data <= GREEN ;
10'b01_00??_???? : pix_data <= CYAN ;
10'b01_01??_???? : pix_data <= BLUE ;
10'b01_10??_???? : pix_data <= PURPLE;
10'b01_11??_???? : pix_data <= BLACK ;
10'b10_00??_???? : pix_data <= WHITE ;
10'b10_01??_???? : pix_data <= GRAY ;
endcase
endmodule
2.4 vga_ctrl模块,实现数据的转换显示
2.4.1 色彩565与444的转换
从NEXYS4_DDR的原理图可以看出,其使用权电阻网络,且红、绿、蓝的色深为4位
对比565,将多余的低位除去,可得444的编码
2.4.2 vga_ctrl框图
2.4.3 时序图
2.4.4 vga_ctrl.v文件
module vga_ctrl
(
input wire vga_clk ,
input wire sys_rst_n ,
input wire [11:0] pix_data ,
output wire [9:0] pix_x ,
output wire [9:0] pix_y ,
output wire hsync ,
output wire vsync ,
output wire [11:0] vga_rgb
);
//hsync800
parameter H_SYNC = 10'd96 ,
H_BACK = 10'd40 ,
H_LEFT = 10'd8 ,
H_VALID = 10'd640,
H_RIGHT = 10'd8 ,
H_FRONT = 10'd8 ,
H_TOTAL = 10'd800;
//vsync525
parameter V_SYNC = 10'd2 ,
V_BACK = 10'd25 ,
V_TOP = 10'd8 ,
V_VALID = 10'd480,
V_BOTTOM = 10'd8 ,
V_FRONT = 10'd2 ,
V_TOTAL = 10'd525;
reg [9:0] cnt_h ;
reg [9:0] cnt_v ;
wire pix_data_req;
wire rgb_valid ;
//cnt_h
always@(posedge vga_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
cnt_h <= 10'd0;
else if(cnt_h == H_TOTAL - 1'b1)
cnt_h <= 10'd0;
else
cnt_h <= cnt_h + 1'b1;
//cnt_v
always@(posedge vga_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
cnt_v <= 10'd0;
else if((cnt_v == V_TOTAL - 1'b1) && (cnt_h == H_TOTAL - 1'b1))
cnt_v <= 10'd0;
else if(cnt_h == H_TOTAL - 1'b1)
cnt_v <= cnt_v + 1'b1;
else
cnt_v <= cnt_v;
//rgb_valid
assign rgb_valid = (((cnt_h >= H_SYNC + H_BACK + H_LEFT)
&& (cnt_h < H_SYNC + H_BACK + H_LEFT + H_VALID))
&&((cnt_v >= V_SYNC + V_BACK + V_TOP)
&& (cnt_v < V_SYNC + V_BACK + V_TOP + V_VALID)))
? 1'b1 : 1'b0;
//pix_data_req
assign pix_data_req = ((cnt_h >= H_SYNC + H_BACK + H_LEFT - 1'b1)
&& (cnt_h < H_SYNC + H_BACK + H_LEFT + H_VALID - 1'b1)
&& (cnt_v >= V_SYNC + V_BACK + V_TOP)
&& (cnt_v < V_SYNC + V_BACK + V_TOP + V_VALID))
? 1'b1 : 1'b0;
assign pix_x = (pix_data_req == 1'b1) ? (cnt_h - (H_SYNC + H_BACK + H_LEFT - 1'b1)) : 10'h3ff;
assign pix_y = (pix_data_req == 1'b1) ? (cnt_v - (V_SYNC + V_BACK + V_TOP)) : 10'h3ff;
assign hsync = (cnt_h <= H_SYNC - 1'b1) ? 1'b1 : 1'b0;
assign vsync = (cnt_v <= V_SYNC - 1'b1) ? 1'b1 : 1'b0;
assign vga_rgb = (rgb_valid == 1'b1) ? pix_data : 12'h000;
endmodule
2.4.5 tb_vga_ctrl.v文件
显示模式设定为60帧,由于仿真速度较慢,且图像的实际显示只有1帧,可直接仿真17ms(1000/60=16.67ms)
此处将三个.v文件的例化集中到一个,可以不用编写 tb_vga_pic.v 文件
`timescale 1ns/1ns
module tb_vga_ctrl();
reg sys_clk ;
reg sys_rst_n ;
wire [11:0] pix_data ;
wire vga_clk ;
wire locked ;
wire rst_n ;
wire [9:0] pix_x ;
wire [9:0] pix_y ;
wire hsync ;
wire vsync ;
wire [11:0] vga_rgb ;
initial
begin
sys_clk = 1'b1;
sys_rst_n <= 1'b0;
#20
sys_rst_n <= 1'b1;
end
always #5 sys_clk = ~sys_clk;
assign rst_n = sys_rst_n && locked;
always@(posedge vga_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
pix_data <= 12'h000;
else if(pix_x >= 10'd0 && pix_x <= 10'd639
&& pix_y >= 10'd0 && pix_y <= 10'd479)
pix_data <= 12'hfff;
else
pix_data <= 12'h000;
clk_gen clk_gen_inst
(
.clk_in1 (sys_clk ), // input clk_in1
.reset (~sys_rst_n ), // input reset
.clk_out1 (vga_clk ), // output clk_out1
.locked (locked ) // output locked
);
vga_ctrl vga_ctrl_inst
(
.vga_clk (vga_clk ),
.sys_rst_n (rst_n),
.pix_data (pix_data ),
.pix_x (pix_x ),
.pix_y (pix_y ),
.hsync (hsync ),
.vsync (vsync ),
.vga_rgb (vga_rgb )
);
vga_pic vga_pic_inst
(
.vga_clk (vga_clk ),
.sys_rst_n (rst_n ),
.pix_x (pix_x ),
.pix_y (pix_y ),
.pix_data (pix_data )
);
endmodule
2.5 顶层vga_colorbar模块
2.5.1 vga_colorbar.v文件
module vga_colorbar
(
input wire sys_clk ,
input wire sys_rst_n ,
output wire hsync ,
output wire vsync ,
output wire [11:0] vga_rgb
);
wire vga_clk ;
wire locked ;
wire rst_n ;
wire [9:0] pix_x ;
wire [9:0] pix_y ;
wire [11:0] pix_data ;
assign rst_n = (sys_rst_n && locked);
clk_gen clk_gen_inst
(
.clk_in1 (sys_clk ), // input clk_in1
.reset (~sys_rst_n ), // input reset
.clk_out1 (vga_clk ), // output clk_out1
.locked (locked ) // output locked
);
vga_ctrl vga_ctrl_inst
(
.vga_clk (vga_clk ),
.sys_rst_n (rst_n),
.pix_data (pix_data ),
.pix_x (pix_x ),
.pix_y (pix_y ),
.hsync (hsync ),
.vsync (vsync ),
.vga_rgb (vga_rgb )
);
vga_pic vga_pic_inst
(
.vga_clk (vga_clk ),
.sys_rst_n (rst_n ),
.pix_x (pix_x ),
.pix_y (pix_y ),
.pix_data (pix_data )
);
endmodule
2.5.2 tb_vga_colorbar.v文件
`timescale 1ns/1ns
module tb_vga_colorbar();
reg sys_clk ;
reg sys_rst_n ;
wire hsync ;
wire vsync ;
wire [11:0] vga_rgb ;
initial
begin
sys_clk = 1'b1;
sys_rst_n <= 1'b0;
#20
sys_rst_n <= 1'b1;
end
always #10 sys_clk = ~sys_clk;
vga_colorbar
(
.sys_clk (sys_clk ),
.sys_rst_n (sys_rst_n),
.hsync (hsync ),
.vsync (vsync ),
.vga_rgb (vga_rgb )
);
endmodule
2.6 vivado生成的框图
3. NEXYS4_DDR迪芝伦XC7A100TCSG324-1型的原理图与管脚绑定
3.1 原理图
板子上的引脚提示
R (A4 C5 B4 A3)
G (A6 B6 A5 C6)
B (D8 D7 C7 B7)
HS (B11)
VS (B12)
3.2 vga_colorbar.xdc文件
set_property IOSTANDARD LVCMOS33 [get_ports hsync]
set_property IOSTANDARD LVCMOS33 [get_ports sys_clk]
set_property IOSTANDARD LVCMOS33 [get_ports sys_rst_n]
set_property IOSTANDARD LVCMOS33 [get_ports vsync]
set_property IOSTANDARD LVCMOS33 [get_ports {vga_rgb[11]}]
set_property IOSTANDARD LVCMOS33 [get_ports {vga_rgb[10]}]
set_property IOSTANDARD LVCMOS33 [get_ports {vga_rgb[9]}]
set_property IOSTANDARD LVCMOS33 [get_ports {vga_rgb[8]}]
set_property IOSTANDARD LVCMOS33 [get_ports {vga_rgb[7]}]
set_property IOSTANDARD LVCMOS33 [get_ports {vga_rgb[6]}]
set_property IOSTANDARD LVCMOS33 [get_ports {vga_rgb[5]}]
set_property IOSTANDARD LVCMOS33 [get_ports {vga_rgb[4]}]
set_property IOSTANDARD LVCMOS33 [get_ports {vga_rgb[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {vga_rgb[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {vga_rgb[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {vga_rgb[0]}]
set_property PACKAGE_PIN A4 [get_ports {vga_rgb[11]}]
set_property PACKAGE_PIN C5 [get_ports {vga_rgb[10]}]
set_property PACKAGE_PIN B4 [get_ports {vga_rgb[9]}]
set_property PACKAGE_PIN A3 [get_ports {vga_rgb[8]}]
set_property PACKAGE_PIN A6 [get_ports {vga_rgb[7]}]
set_property PACKAGE_PIN B6 [get_ports {vga_rgb[6]}]
set_property PACKAGE_PIN A5 [get_ports {vga_rgb[5]}]
set_property PACKAGE_PIN C6 [get_ports {vga_rgb[4]}]
set_property PACKAGE_PIN D8 [get_ports {vga_rgb[3]}]
set_property PACKAGE_PIN D7 [get_ports {vga_rgb[2]}]
set_property PACKAGE_PIN C7 [get_ports {vga_rgb[1]}]
set_property PACKAGE_PIN B7 [get_ports {vga_rgb[0]}]
set_property PACKAGE_PIN B11 [get_ports hsync]
set_property PACKAGE_PIN B12 [get_ports vsync]
set_property PACKAGE_PIN E3 [get_ports sys_clk]
set_property PACKAGE_PIN J15 [get_ports sys_rst_n]