Zedboard学习(七):VGA显示
来源:互联网 发布:专业日语翻译软件 编辑:程序博客网 时间:2024/05/29 14:48
VGA硬件接口
到zedboard官方给出的原理图中查看:
RGB信号,各四位;这里的设计是使用了电阻分压模拟了DAC芯片实现了4X4X4的RGB信号,如果要更好的显示效果还是建议使用专门的DAC。
上面给出了所有的引脚分配。
VGA时序分析
如上图所示,就是VGA时序的表示。按照这个时序图,编写程序。
Hsync是行同步信号,表示一行的开始和上一行的结束;
Vsync是列同步信号,表示一场的开始和上一场的结束;
行时序是以像素为单位的, 场时序是以行为单位的;
像素点从左到右算一行,行数从上到下算一场。
在图上定义了很多区间,而根据这些区间我们可以看到整个时序图被分为了三个矩形:中间的Adressable Video,其外面的Border,还有最外面的Blanking。
传输数据的时间就是中间的Adressable Video的这段时间,同步到每个像素即可。中间的那个矩形就对应显示器显示的范围,其他的矩形可以看做是不可见的。
VGA的时序我只是简单介绍了下,详细的介绍可以查看:[笔记]VGA时序及其原理
列出几个常用的时序:
640×480 @60HZ
800×600@60HZ
上面给出了几个示例,图中给出了时序参数的计算步骤以及最后结果,可以到这下载:VGA时序标准
现在我们只提取出最后要用到的时序参数:
(这个图是我直接在网上截图的,不保证全部正确,最好参考VGA时序标准确认一遍,以手册为准)
编写代码
新建工程,添加Verilog代码,这些步骤不再赘述。
直接上代码了,代码中添加了注释。我选取的是800×600@60HZ。
程序的结构:
产生vga信号的代码:
vga_data_gen.v
`timescale 1ns / 1ps//////////////////////////////////////////////////////////////////////////////////// Company: // Engineer: // // Create Date: 2017/07/27 23:15:37// Design Name: // Module Name: vga_data_gen// Project Name: // Target Devices: // Tool Versions: // Description: // // Dependencies: // // Revision:// Revision 0.01 - File Created// Additional Comments:// //////////////////////////////////////////////////////////////////////////////////module vga_data_gen( input pixel_clk, //像素时钟 input rst, //复位按键,高电平复位 output [7:0] vga_r, //vga信号红色视频信号 output [7:0] vga_g, //vga信号绿色视频信号 output [7:0] vga_b, //vga信号蓝色视频信号 output vga_hs, //行同步信号 output vga_vs, //场同步信号 output vga_de, //vga信号有效,如当前时刻传输数据有效,即为1;否则为0; input turn_mode, //按键。按下为高电平,切换vga显示模式 output [3:0] mode //当前显示模式,用4位编码 );//---------------------------------//// 水平扫描参数的设定 800*600 60HZ//--------------------------------//parameter H_Total = 1056 - 1;parameter H_Sync = 128 - 1;parameter H_Back = 88 - 1;parameter H_Active = 800 - 1;parameter H_Front = 40 - 1;parameter H_Start = 216 - 1;parameter H_End = 1016 - 1;//-------------------------------//// 垂直扫描参数的设定 1280*720 60HZ//-------------------------------//parameter V_Total = 628 - 1;parameter V_Sync = 4 - 1;parameter V_Back = 23 - 1;parameter V_Active = 600 - 1;parameter V_Front = 1 - 1;parameter V_Start = 27 - 1;parameter V_End = 627 - 1;//行信号计数器reg [11:0] x_cnt;always @(posedge pixel_clk or posedge rst)begin if(rst) x_cnt <= 12'd0; else if(x_cnt == H_Total) x_cnt <= 12'd0; else x_cnt <= x_cnt + 1'b1;end//根据时序图参数,产生行同步信号reg hsync_r;always @(posedge pixel_clk or posedge rst)begin if(rst) hsync_r <= 1'b1; else if(x_cnt>=0 && x_cnt < H_Sync) hsync_r <= 1'b0; else hsync_r <= 1'b1;end//行信号有效,即当前数据有效reg hs_de;always @(posedge pixel_clk or posedge rst)begin if(rst) hs_de <= 1'b0; else if(x_cnt>=H_Start && x_cnt<H_End) hs_de <= 1'b1; else hs_de <= 1'b0;end//场信号计数器reg [11:0] y_cnt;always @(posedge pixel_clk or posedge rst)begin if(rst) y_cnt <= 12'd0; else if(y_cnt == V_Total) y_cnt <= 12'd0; else if(x_cnt == H_Total) y_cnt <= y_cnt + 1'b1;end//根据时序图参数,产生场同步信号reg vsync_r;always @(posedge pixel_clk or posedge rst)begin if(rst) vsync_r <= 1'b1; else if(y_cnt>=0 && y_cnt<V_Sync) vsync_r <= 1'b0; else vsync_r <= 1'b1;end//列信号有效,即当前数据有效reg vs_de;always @(posedge pixel_clk or posedge rst)begin if(rst) vs_de <= 1'b0; else if(y_cnt>=V_Start && y_cnt<V_End) vs_de <= 1'b1; else vs_de <= 1'b0;end//按键消抖,按下后延时一段时间,再检测是否按下reg [16:0] key_counter;always @(posedge pixel_clk)begin if(turn_mode) key_counter <= 17'd0; else if((turn_mode == 1'b0) && (key_counter <= 17'h11704)) key_counter <= key_counter + 1'b1;end//显示模式技术,每次按下按键,模式改变,最多有12种显示模式reg [3:0] dis_mode;assign mode = dis_mode;always @(posedge pixel_clk)begin if(key_counter == 17'h11704) begin if(dis_mode == 4'd12) dis_mode <= 4'd0; else dis_mode <= dis_mode +1'b1; endend//产生小格子,黑白棋盘reg [7:0] grid_data_1;always @(posedge pixel_clk)begin if((x_cnt[4] == 1'b0) ^ (y_cnt[4] == 1'b0)) grid_data_1 <= 8'h00; else grid_data_1 <= 8'hff;end//产生大格子,黑白棋盘reg [7:0] grid_data_2;always @(posedge pixel_clk)begin if((x_cnt[6] == 1'b0) ^ (y_cnt[6] == 1'b0)) grid_data_2 <= 8'h00; else grid_data_2 <= 8'hff;end//产生彩条reg [23:0] color_bar;always @(posedge pixel_clk)begin if(x_cnt>=216 && x_cnt<316) color_bar <= 24'hff0000; else if(x_cnt>=316 && x_cnt<416) color_bar <= 24'h00ff00; else if(x_cnt>=416 && x_cnt<516) color_bar <= 24'h0000ff; else if(x_cnt>=516 && x_cnt<616) color_bar <= 24'hff00ff; else if(x_cnt>=616 && x_cnt<716) color_bar <= 24'hffff00; else if(x_cnt>=716 && x_cnt<816) color_bar <= 24'h00ffff; else if(x_cnt>=816 && x_cnt<916) color_bar <= 24'hffffff; else if(x_cnt>=916 && x_cnt<1016) color_bar <= 24'h000000; else color_bar <= color_bar;end//根据显示模式传输rgb信号到缓存器中reg [7:0] vga_r_reg;reg [7:0] vga_g_reg;reg [7:0] vga_b_reg;always @(posedge pixel_clk or posedge rst)begin if(rst) begin vga_r_reg <= 8'd0; vga_g_reg <= 8'd0; vga_b_reg <= 8'd0; end else begin case(dis_mode) 4'd0: //全黑 begin vga_r_reg <= 8'd0; vga_g_reg <= 8'd0; vga_b_reg <= 8'd0; end 4'd1: //全白 begin vga_r_reg <= 8'b1111_1111; vga_g_reg <= 8'b1111_1111; vga_b_reg <= 8'b1111_1111; end 4'd2: //全红 begin vga_r_reg <= 8'b1111_1111; vga_g_reg <= 8'd0; vga_b_reg <= 8'd0; end 4'd3: //全绿 begin vga_r_reg <= 8'd0; vga_g_reg <= 8'b1111_1111; vga_b_reg <= 8'd0; end 4'd4: //全蓝 begin vga_r_reg <= 8'd0; vga_g_reg <= 8'd0; vga_b_reg <= 8'b1111_1111; end 4'd5: //小格子,黑白棋盘 begin vga_r_reg <= grid_data_1; vga_g_reg <= grid_data_1; vga_b_reg <= grid_data_1; end 4'd6: //大格子,黑白棋盘 begin vga_r_reg <= grid_data_2; vga_g_reg <= grid_data_2; vga_b_reg <= grid_data_2; end 4'd7: //根据行信号渐变,周期性从黑到白 begin vga_r_reg <= x_cnt[7:0]; vga_g_reg <= x_cnt[7:0]; vga_b_reg <= x_cnt[7:0]; end 4'd8: //根据场信号渐变,周期性从黑到白 begin vga_r_reg <= y_cnt[7:0]; vga_g_reg <= y_cnt[7:0]; vga_b_reg <= y_cnt[7:0]; end 4'd9: //根据行信号渐变,周期性红色从浅到深 begin vga_r_reg <= x_cnt[7:0]; vga_g_reg <= 8'd0; vga_b_reg <= 8'd0; end 4'd10: //根据列信号渐变,周期性绿色从浅到深 begin vga_r_reg <= 8'd0; vga_g_reg <= x_cnt[7:0]; vga_b_reg <= 8'd0; end 4'd11: //根据行信号渐变,周期性蓝色从浅到深 begin vga_r_reg <= 8'd0; vga_g_reg <= 8'd0; vga_b_reg <= x_cnt[7:0]; end 4'd12: //彩条信号 begin vga_r_reg <= color_bar[23:16]; vga_g_reg <= color_bar[15:8]; vga_b_reg <= color_bar[7:0]; end default: begin vga_r_reg <= 8'b1111_1111; vga_g_reg <= 8'b1111_1111; vga_b_reg <= 8'b1111_1111; end endcase endend//将这些寄存器中的信号输出assign vga_hs = hsync_r;assign vga_vs = vsync_r;assign vga_de = hs_de & vs_de; //只有当行信号和场信号同时有效时数据才有效assign vga_r = (hs_de & vs_de) ? vga_r_reg : 8'h0;assign vga_g = (hs_de & vs_de) ? vga_g_reg : 8'h0;assign vga_b = (hs_de & vs_de) ? vga_b_reg : 8'h0;endmodule
由于VGA信号是800×600@60HZ,我们还需要一个像素时钟40MHZ。zedboard的PL部分默认的时钟是100MHZ,所以我们还需要一个时钟单元来产生40MHZ的特定时钟。分频的方法不稳定,不推荐。
点击准备添加IP核。
如下图所示找到clocking wizard。打开它,开始配置其功能。
这些都默认不改动,时钟是100MHZ。
修改输出时钟为40MHZ,其他不做修改。
直接点击OK,创建IP核。
点击generate产生IP核。
最后会产生这个,我们可以通过Verilog调用这个模块。
最后编写顶层Verilog代码:只是把前面几个模块包进来。
vga_disp.v
`timescale 1ns / 1ps//////////////////////////////////////////////////////////////////////////////////// Company: // Engineer: // // Create Date: 2017/07/27 23:12:46// Design Name: // Module Name: vga_disp// Project Name: // Target Devices: // Tool Versions: // Description: // // Dependencies: // // Revision:// Revision 0.01 - File Created// Additional Comments:// //////////////////////////////////////////////////////////////////////////////////module vga_disp( input clk100M, input rst, input key, output [3:0] vga_r, output [3:0] vga_g, output [3:0] vga_b, output vga_hs, output vga_vs, output [3:0] led ); wire pixel_clk; wire [7:0] R, G, B; wire HS, VS, DE; assign vga_r = R[7:4]; assign vga_g = G[7:4]; assign vga_b = B[7:4]; assign vga_hs = HS; assign vga_vs = VS; vga_data_gen vga_data_gen( .pixel_clk(pixel_clk), .rst(rst), .vga_r(R), .vga_g(G), .vga_b(B), .vga_hs(HS), .vga_vs(VS), .vga_de(DE), .turn_mode(key), .mode(led) ); clk_wiz_0 clk ( .clk_out1(pixel_clk), .reset(1'b0), .locked(), .clk_in1(clk100M) );endmodule
编写引脚约束文件,在官方给出的原理图中都可以查到。
pins.xdc
# Clk(板子上的GCLK)set_property PACKAGE_PIN Y9 [get_ports {clk100M}]set_property IOSTANDARD LVCMOS33 [get_ports {clk100M}]# Rst(板子上的BTNU)set_property PACKAGE_PIN T18 [get_ports {rst}]set_property IOSTANDARD LVCMOS33 [get_ports {rst}]# key 板子上的按键set_property PACKAGE_PIN P16 [get_ports {key}]set_property IOSTANDARD LVCMOS33 [get_ports {key}]# Led0set_property PACKAGE_PIN T22 [get_ports {led[0]}]set_property IOSTANDARD LVCMOS33 [get_ports {led[0]}]# Led1set_property PACKAGE_PIN T21 [get_ports {led[1]}]set_property IOSTANDARD LVCMOS33 [get_ports {led[1]}]# Led2set_property PACKAGE_PIN U22 [get_ports {led[2]}]set_property IOSTANDARD LVCMOS33 [get_ports {led[2]}]# Led3set_property PACKAGE_PIN U21 [get_ports {led[3]}]set_property IOSTANDARD LVCMOS33 [get_ports {led[3]}]set_property PACKAGE_PIN Y19 [get_ports {vga_vs}]set_property IOSTANDARD LVCMOS33 [get_ports {vga_vs}]set_property PACKAGE_PIN AA19 [get_ports {vga_hs}]set_property IOSTANDARD LVCMOS33 [get_ports {vga_hs}]set_property PACKAGE_PIN V20 [get_ports {vga_r[0]}]set_property IOSTANDARD LVCMOS33 [get_ports {vga_r[0]}]set_property PACKAGE_PIN U20 [get_ports {vga_r[1]}]set_property IOSTANDARD LVCMOS33 [get_ports {vga_r[1]}]set_property PACKAGE_PIN V19 [get_ports {vga_r[2]}]set_property IOSTANDARD LVCMOS33 [get_ports {vga_r[2]}]set_property PACKAGE_PIN V18 [get_ports {vga_r[3]}]set_property IOSTANDARD LVCMOS33 [get_ports {vga_r[3]}]set_property PACKAGE_PIN AB22 [get_ports {vga_g[0]}]set_property IOSTANDARD LVCMOS33 [get_ports {vga_g[0]}]set_property PACKAGE_PIN AA22 [get_ports {vga_g[1]}]set_property IOSTANDARD LVCMOS33 [get_ports {vga_g[1]}]set_property PACKAGE_PIN AB21 [get_ports {vga_g[2]}]set_property IOSTANDARD LVCMOS33 [get_ports {vga_g[2]}]set_property PACKAGE_PIN AA21 [get_ports {vga_g[3]}]set_property IOSTANDARD LVCMOS33 [get_ports {vga_g[3]}]set_property PACKAGE_PIN Y21 [get_ports {vga_b[0]}]set_property IOSTANDARD LVCMOS33 [get_ports {vga_b[0]}]set_property PACKAGE_PIN Y20 [get_ports {vga_b[1]}]set_property IOSTANDARD LVCMOS33 [get_ports {vga_b[1]}]set_property PACKAGE_PIN AB20 [get_ports {vga_b[2]}]set_property IOSTANDARD LVCMOS33 [get_ports {vga_b[2]}]set_property PACKAGE_PIN AB19 [get_ports {vga_b[3]}]set_property IOSTANDARD LVCMOS33 [get_ports {vga_b[3]}]
分析综合产生比特流文件,后进行下载。
按键设置:
图中BTNU键位复位键;BTNC键位模式切换键,每按一次切换显示模式。
连上vga线,可以看到现象如下:
- Zedboard学习(七):VGA显示
- Zedboard学习(八):zedboard移植opencv
- ZedBoard学习手记(七)小插曲:如何让代码开机自动运行
- zedboard--zedboard学习小结
- zedboard--zedboard学习小结
- ZedBoard学习(5)-ZedBoard和System Generator
- ZedBoard学习手记(十) 图形界面控制ZedBoard硬件
- zedboard学习
- Fpga的vga显示设计(一)
- FPGA学习笔记1——VGA显示
- ZedBoard学习(3)U盘读写
- ZedBoard学习(2)-FTP文件传输
- Zedboard学习(六):XADC读取数据
- zedboard demo hdmi显示
- zedboard--zedboard的qt测试和usb视频采集和显示(十六)
- Zedboard---实验七秒计数
- VGA显示--ROM部分
- 显示设置vga framebuffer
- POJ 3691 DNA repair AC自动机 + dp
- 在Go语言中使用JSON
- 处理冒泡的两种方式
- Linux CentOS 7 安装Apache Subversion
- python中数字类型与处理工具
- Zedboard学习(七):VGA显示
- spring boot 教程(二)模板依赖
- [bzoj3784][点分治]树上的路径
- JIRA
- webpack学习系列三(https://webpack.js.org/concepts/output/)
- 复习
- jmeter的response data乱码
- web项目 easyui-datagrid开发实践
- 伪类