Zedboard学习(二):VGA显示

在本篇文章中,将实现在Xilinx ZYNQ上实现用PL部分驱动VGA显示12bit的彩色图像,涉及到VGA的驱动原理,vivado上的PLL IP和ROM IP的使用以及彩色图像coe文件的生成。最后将提供整个项目代码。

本文所使用的开发板是Miz702(兼容zedboard),软件开发环境:vivado 2015.2

一、VGA的原理

VGA的协议比较简洁,主要是有五个信号线组成,行同步信号 HSYNC,场同步信号VSYNC3条色彩电压传输信号(RGB分别对应)。色彩信
号的电压为
0~0.7V。本次要实现的分辨率是640*480,帧率是60Hz,所需要的时钟是25Mhz.话不多说,直接上图:


VGA 时序图


需要注意的是,VGA的时序图和参数表可以看出,每帧需要525个vsync脉冲,在每个vsync的周期中,即Tvsync,又包含着800个hsync脉冲,而图像RGB的有效时间在hsync的640个显示脉冲之中。

二、逻辑实现

//vga_sync.v  VGA同步控制逻辑

  
  

  
  
  1. module vga_sync(
  2. input wire clk,
  3. input wire rst_n,
  4. output wire video_en, //数据有效
  5. output reg hsync, //场同步信号
  6. output reg vsync, //行同步信号
  7. output wire [ 9: 0] pixel_x, //待显示待像素的x坐标
  8. output wire [ 9: 0] pixel_y //待显示待像素的y坐标
  9. );
  10. reg [ 9: 0] pixel_cnt;
  11. reg [ 9: 0] line_cnt;
  12. reg v_video_en;
  13. reg h_video_en;
  14. always @(posedge clk or negedge rst_n)
  15. if(!rst_n)
  16. begin
  17. pixel_cnt <= 10 'b0;
  18. end
  19. else
  20. begin
  21. pixel_cnt <= pixel_cnt + 1'b1;
  22. if(pixel_cnt == 10 'd799)
  23. begin
  24. pixel_cnt <= 10'b0;
  25. end
  26. end
  27. always @(posedge clk or negedge rst_n)
  28. if(!rst_n)
  29. begin
  30. h_video_en <= 1 'b1;
  31. hsync <= 1'b1;
  32. end
  33. else
  34. begin
  35. case (pixel_cnt)
  36. 10 'd0:
  37. begin
  38. h_video_en <= 1'b1;
  39. end
  40. 10 'd639:
  41. begin
  42. h_video_en <= 1'b0;
  43. end
  44. 10 'd655:
  45. begin
  46. hsync <= 1'b0;
  47. end
  48. 10 'd751:
  49. begin
  50. hsync <= 1'b1;
  51. end
  52. endcase
  53. end
  54. always @(posedge clk or negedge rst_n)
  55. if(!rst_n)
  56. begin
  57. line_cnt <= 10 'b0;
  58. end
  59. else
  60. begin
  61. if(pixel_cnt == 10'd799)
  62. begin
  63. line_cnt <= line_cnt + 1 'b1;
  64. end
  65. if(line_cnt == 10'd524)
  66. begin
  67. line_cnt <= 10 'b0;
  68. end
  69. end
  70. always @(posedge clk or negedge rst_n)
  71. if(!rst_n)
  72. begin
  73. v_video_en <= 1'b1;
  74. vsync <= 1 'b1;
  75. end
  76. else
  77. begin
  78. case(line_cnt)
  79. 10'd0:
  80. begin
  81. v_video_en <= 1 'b1;
  82. end
  83. 10'd479:
  84. begin
  85. v_video_en <= 1 'b0;
  86. end
  87. 10'd489:
  88. begin
  89. vsync <= 1 'b0;
  90. end
  91. 10'd491:
  92. begin
  93. vsync <= 1 'b1;
  94. end
  95. endcase
  96. end
  97. assign pixel_x = pixel_cnt;
  98. assign pixel_y = line_cnt;
  99. assign video_en = ((h_video_en == 1'b1) && (v_video_en == 1 'b1));
  100. endmodule
//由于开发板上的PL部分时钟是100Mh的,所以需要用PLL把VGA的基准时钟时钟分频到25Mhz
  
  


//test_vga.v文件   利用上面的代码显示彩色图像
  
  

  
  
  1. module vga_test(
  2. input wire sys_clk,
  3. input wire sys_rst_n,
  4. output wire hsync,
  5. output wire vsync,
  6. output wire [ 11: 0] rgb,
  7. output reg led
  8. );
  9. //红_绿_蓝
  10. parameter BLACK = 12 'b0000_0000_0000;
  11. parameter BLUE = 12'b0000_0000_1111;
  12. parameter GREEN = 12 'b0000_1111_0000;
  13. parameter DIAN = 12'b0000_1111_1111;
  14. parameter RED = 12 'b1111_0000_0000;
  15. parameter PURPLE = 12'b1111_0000_1111;
  16. parameter YELLOW = 12 'b1111_1111_0000;
  17. parameter WHITE = 12'b1111_1111_1111;
  18. wire [ 9: 0] pixel_x;
  19. wire [ 9: 0] pixel_y;
  20. wire clk_25mhz;
  21. reg [ 11: 0] rgb_reg;
  22. //显示静态图像640*480
  23. reg [ 23: 0] cnt;
  24. always @(posedge clk_25mhz or negedge sys_rst_n)
  25. if(!sys_rst_n)
  26. begin
  27. cnt <= 0;
  28. led <= 0;
  29. end
  30. else
  31. begin
  32. cnt <= cnt + 1 'b1;
  33. if(cnt == 24'd12500000)
  34. begin
  35. cnt <= 24 'b0;
  36. led <= ~led;
  37. end
  38. end
  39. always @ (posedge clk_25mhz or negedge sys_rst_n)
  40. if(!sys_rst_n)
  41. begin
  42. rgb_reg <= 12'b0;
  43. end
  44. else
  45. begin //显示图像
  46. //rgb_reg <= q_sig;
  47. rgb_reg[ 3: 0] <= q_sig[ 7: 4];
  48. rgb_reg[ 7: 4] <= q_sig[ 3: 0];
  49. rgb_reg[ 11: 8] <= q_sig[ 11: 8];
  50. end
  51. always @ (posedge clk_25mhz or negedge sys_rst_n)
  52. if(!sys_rst_n)
  53. begin
  54. address_sig <= 19 'b0;
  55. end
  56. else
  57. begin
  58. if(pixel_x>=0 && pixel_x<= 639 && pixel_y>=0 && pixel_y<=479)
  59. address_sig = (pixel_x + 640*pixel_y);
  60. end
  61. //////////////////////////////////////////////////////////////
  62. assign rgb = (video_en == 1'b1) ? rgb_reg: 12 'b0;
  63. vga_sync vga_syn_inst(
  64. .clk (clk_25mhz),
  65. .rst_n (sys_rst_n),
  66. .video_en (video_en),
  67. .hsync (hsync),
  68. .vsync (vsync),
  69. .pixel_x (pixel_x),
  70. .pixel_y (pixel_y)
  71. );
  72. reg [18:0] address_sig;
  73. wire [11:0] q_sig;
  74. rom_pic rom_pic_inst (
  75. .clka(clk_25mhz), // input wire clka
  76. .addra(address_sig), // input wire [18 : 0] addra
  77. .douta(q_sig) // output wire [11 : 0] douta
  78. );
  79. clk_wiz_0 clk_wiz_0_inst
  80. (
  81. // Clock in ports
  82. .clk_in1(sys_clk),
  83. // Clock out ports
  84. .clk_out1(clk_25mhz)
  85. );
  86. endmodule

 
 
 
 


三、生成coe文件


1.准备软件BmpToMif和Image2Lcd 下载

2.准备好640*480的彩色图片

3.打开Image2Lcd ,并且打开待显示的图片,并且按照下图配置参数:


4.配置完毕后,点击保存

5.打开BmpToMif,选择数据文件,打开刚才生成的bin文件,字长改为12,点击生成Mif文件(弹出的窗口可以选择否)。


6.用excel 打开生成的mif文件,选中这一列


7.然后在菜单栏中选择 数据->分列


8.选择分隔符号,下一步


9.选择其他,输入冒号(注意是英文的冒号),下一步

10.然后,按Ctrl+H,把分号换成逗号,(最后一组数据是分号)。


11.到此为止,图片的数据就准备好了,下面把数据添加到vivado,的coe文件里面。打开vivado,点击 IP Catalog ,搜索rom,双击 Block memory Cenerator


12.Memor type 选择Signal Poart ROM,Port A Opation按照如图所示配置


13.然后选择 Other Options(也可以先做好coe文件在此选择)

点击Edit,选择YES,输入文件名


14.radix 必须是2,vector可以先随便输,save,close

15.打开刚才新建的coe文件,按照如图所示的格式把生成的图像数据复制进来,注意最后一行数据以分号结束


16.至此,coe文件已经生成好了,ROM初始化的时候,会加载,供我们读取,显示在VGA上。


四、下面写好代码,生成bit文件后,就可以把代码烧到ZYNQ测试了


测试效果如图所示:


项目工程源码下载

oschina:点击打开链接

百度网盘链接:链接:http://pan.baidu.com/s/1mgER0VY 密码:mvkw


更多关于zynq开发相关的文章和问题请点击:

http://www.osrc.cn/forum.php?mod=forumdisplay&fid=292

http://blog.csdn.net/rzjmpb




猜你喜欢

转载自blog.csdn.net/zhipao6108/article/details/81072974
VGA