欢迎使用CSDN-markdown编辑器
来源:互联网 发布:短暂的婚姻 知乎 编辑:程序博客网 时间:2024/06/06 01:45
**FPGA学习之VGA显示图片** 这周刚刚调完用FPGA自带的ROM来存储图片,并且用VGA在显示器上显示,下面上详细的操作步骤。
一、从整体上认识我们要做什么
从图中可以看到,我们需要控制的信号有VGA_CLK,VGA_SYNC_N,
VGA_BLANK_N,VGA_R,VGA_G,VGA_B等。相应的信号定义见以下代码。
//system signals input wire s_clk , input wire s_rst_n , //VGA signals output wire vga_clk , output wire [7:0] vga_R , output wire [7:0] vga_G , output wire [7:0] vga_B , output wire vga_sync_n , output wire vga_black_n , output reg vga_vs , output reg vga_hs
二、定义的信号解释
s_clk : 输入时钟,频率为25M
s_rst_n : 系统复位,低电平复位
vga_clk : VGA时钟,频率为25M
vga_R、vga_G、vga_B :图片的红、绿、蓝三个分量
vga_sync_n、vga_black_n:DAC的控制信号
vga_vs、vga_hs:vga行信号、场信号
三、VGA控制时序
我们要实现的分辨率是640*480,需要用到的VGA时钟就是25MHz(具体的计算方法网上可以找到),根据VGA时序的具体要求,我们能得到以下参数(这些代码中的数字表示要经过多少个时钟周期):
//=========场信号parameter h_total = 12'd800 - 12'd1 ;parameter h_sync = 12'd96 ;//同步信号parameter h_back_proch = 12'd48 ;//显示后沿parameter h_front_proch = 12'd16 ;//显示前沿parameter h_display = 12'd640 ;//显示区域//=========行信号parameter v_total = 12'd525 - 12'd1 ;parameter v_sync = 12'd2 ;//同步信号parameter v_back_proch = 12'd33 ;//显示后沿parameter v_front_proch = 12'd10 ;//显示前沿parameter v_display = 12'd480 ;//显示区域
下面是行信号与场信号的产生:
//=============================================//行信号always @ ( posedge s_clk or negedge s_rst_n )begin if ( !s_rst_n ) vga_hs <= 1'b0 ; else if ( xcnt >= h_sync ) vga_hs <= 1'b1 ; else vga_hs <= 1'b0 ;end//==============================================//场信号always @ ( posedge s_clk or negedge s_rst_n )begin if ( !s_rst_n ) vga_vs <= 1'b0 ; else if ( ycnt >= v_sync ) vga_vs <= 1'b1 ; else vga_vs <= 1'b0 ;end//=============================================
接下来,行像素计数和场信号像素计数:
//=============================================//行信号计数always @ ( posedge s_clk or negedge s_rst_n )begin if ( !s_rst_n ) xcnt <= 12'd0 ; else if ( xcnt == h_total ) xcnt <= 12'd0 ; else xcnt <= xcnt + 1'b1 ;end//==============================================//场信号计数always @ ( posedge s_clk or negedge s_rst_n )begin if ( !s_rst_n ) ycnt <= 12'd0 ; else if ( xcnt == h_total ) ycnt <= ycnt + 1'b1 ; else if ( ycnt == v_total ) ycnt <= 12'd0 ;end
确定显示器的显示区域(和定义的参数数据一起看):
//=============================================//显示有效区域always @ ( posedge s_clk or negedge s_rst_n )begin if ( !s_rst_n ) display_en <= 1'b0 ; else if ( ( xcnt >= h_sync + h_back_proch ) && ( xcnt <= h_sync + h_back_proch + h_display ) && ( ycnt >= v_sync + v_back_proch ) && ( ycnt <= v_sync + v_back_proch + v_display) ) display_en <= 1'b1 ; else display_en <= 1'b0 ;end
由于在工程中调用了ROM,所以,把ROM例化:
//=============================================//ROM例化wire [23:0] q ;reg [15:0] addr ;my_rom u_my_rom( .address ( addr ) , .clock ( s_clk ) , .q ( q )) ;
重头戏来了,图片显示坐标的确定,我参考的是网上一些计算公式来确定ROM的地址信息:
//图像区域显示reg picture ;reg [11:0] y_cnt ; always @ ( posedge s_clk or negedge s_rst_n )begin if ( !s_rst_n ) picture <= 1'b0 ; else if ( xcnt >= 12'd201 && ycnt >= 12'd200 && xcnt <= 12'd468 && ycnt <= 12'd349 ) picture <= 1'b1 ; else picture <= 1'b0 ;end
addr <= ( ycnt - 16’d200 ) * 16’d267 + ( xcnt - 16’d200 );
这句代码中的数字解释一下,括号中的200指的是显示图片的原点,及ROM地址为0,267指的是图像的宽度,这样计算,就能得到相应的ROM地址,也就能得到像素的值。
//ROM数据读取always @ ( posedge s_clk or negedge s_rst_n )begin if ( !s_rst_n ) addr <= 16'd0 ; else if ( picture ) addr <= ( ycnt - 16'd200 ) * 16'd267 + ( xcnt - 16'd200 ); else addr <= 16'd0 ;end
DAC控制信号代码(为什么信号这么赋值,请参考数据手册):
assign vga_sync_n = 1'b0 ;assign vga_black_n = display_en ;
四、mif文件的生成
用画图软件将需要显示的图片从JPG另存为BMP,然后用下面这个软件,根据自己想要的格式,一键转换成mif文件:
将mif文件添加到ROM中,接下来就可以愉快的用VGA来显示图片了!
五、结束语
第一次写博客,可能没有很好地组织语言,各位看官若是有什么问题,欢迎发送邮件到otherfiles@163.com讨论!谢谢!
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- Go并发:利用sync.WaitGroup实现协程同步
- 最详细的maven pom.xml标签详解(转)
- kubernetes中的Volumes
- MySQL常用引擎的锁机制
- Submit a Spark job to YARN from code
- 欢迎使用CSDN-markdown编辑器
- Windows下Nginx的启动、停止等命令
- jQuery:改进图像
- MyBatis的执行过程总结
- 汇编--学习笔记(五)-组织数据
- (MySql)distinct、group by去重
- Oracle ADF MenuDemo 案例
- Java基础之泛型
- 图像增强之频域增强