这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » FPGA » PL部分驱动VGA显示静态彩色图像

共1条 1/1 1 跳转至

PL部分驱动VGA显示静态彩色图像

菜鸟
2017-06-27 15:54:15     打赏
在本篇文章中,将实现在Xilinx ZYNQ上实现用PL部分驱动VGA显示12bit的彩色图像,涉及到VGA的驱动原理,vivado上的PLL IP和ROM IP的使用以及彩色图像coe文件的生成。最后将提供整个项目代码。 本文所使用的开发板是Miz702(兼容zedboard),软件开发环境:vivado 2015.2 一、VGA的原理 VGA的协议比较简洁,主要是有五个信号线组成,行同步信号 HSYNC,场同步信号VSYNC和3条色彩电压传输信号(R、G、B分别对应)。色彩信
号的电压为 0~0.7V。本次要实现的分辨率是640*480,帧率是60Hz,所需要的时钟是25Mhz.话不多说,直接上图:

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


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

[plain] view plain copy


  • module vga_sync(  
  •         input   wire            clk,  
  •         input   wire            rst_n,  
  •         output  wire        video_en,              //数据有效  
  •         output  reg             hsync,                 //场同步信号  
  •         output  reg             vsync,                 //行同步信号  
  •         output  wire    [9:0]   pixel_x,               //待显示待像素的x坐标  
  •         output  wire    [9:0]   pixel_y                //待显示待像素的y坐标   
  •         );  
  •            
  •         reg     [9:0] pixel_cnt;  
  •         reg     [9:0] line_cnt;  
  •             
  •             
  •         reg             v_video_en;  
  •         reg             h_video_en;  
  •          
  •          
  •         always @(posedge clk or negedge rst_n)  
  •             if(!rst_n)  
  •                 begin  
  •                     pixel_cnt <= 10'b0;  
  •                 end  
  •             else  
  •                 begin  
  •                     pixel_cnt <= pixel_cnt + 1'b1;  
  •             if(pixel_cnt == 10'd799)  
  •             begin  
  •                 pixel_cnt <= 10'b0;  
  •             end  
  •                 end  
  •                   
  •                  
  •          always @(posedge clk or negedge rst_n)  
  •             if(!rst_n)  
  •                 begin  
  •                     h_video_en <= 1'b1;  
  •             hsync <= 1'b1;  
  •                 end  
  •             else  
  •                 begin  
  •                     case (pixel_cnt)   
  •                         10'd0:  
  •                             begin  
  •                                 h_video_en <= 1'b1;  
  •                             end  
  •                         10'd639:  
  •                             begin  
  •                                 h_video_en <= 1'b0;  
  •                             end   
  •                         10'd655:  
  •                             begin  
  •                                 hsync <= 1'b0;  
  •                             end   
  •                         10'd751:  
  •                             begin  
  •                                 hsync <= 1'b1;  
  •                             end               
  •                     endcase  
  •                 end  
  •                   
  •                   
  •                  
  •          always @(posedge clk or negedge rst_n)  
  •             if(!rst_n)  
  •                 begin  
  •                     line_cnt <= 10'b0;  
  •                 end  
  •             else  
  •                 begin  
  •                     if(pixel_cnt == 10'd799)  
  •                         begin  
  •                             line_cnt <= line_cnt + 1'b1;  
  •                         end   
  •                      
  •                       if(line_cnt == 10'd524)  
  •                       begin  
  •                             line_cnt <= 10'b0;  
  •                       end   
  •                 end  
  •                   
  •         always @(posedge clk or negedge rst_n)  
  •             if(!rst_n)  
  •                 begin  
  •                     v_video_en <= 1'b1;  
  •                     vsync <= 1'b1;  
  •                 end  
  •             else  
  •                 begin  
  •                     case(line_cnt)  
  •                         10'd0:  
  •                             begin  
  •                                 v_video_en <= 1'b1;  
  •                             end   
  •                         10'd479:  
  •                             begin  
  •                                 v_video_en <= 1'b0;  
  •                             end   
  •                         10'd489:  
  •                             begin  
  •                                 vsync <= 1'b0;  
  •                             end   
  •                         10'd491:  
  •                             begin  
  •                                 vsync <= 1'b1;  
  •                             end   
  •                     endcase  
  •                 end                 
  •    
  •         assign pixel_x = pixel_cnt;  
  •         assign pixel_y = line_cnt;  
  •             
  •     assign video_en = ((h_video_en == 1'b1) &&  (v_video_en == 1'b1));   
  •          
  • endmodule  

[plain] view plain copy


  • //由于开发板上的PL部分时钟是100Mh的,所以需要用PLL把VGA的基准时钟时钟分频到25Mhz  



[plain] view plain copy


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

[plain] view plain copy


  • module vga_test(  
  •                     input   wire            sys_clk,  
  •                     input   wire            sys_rst_n,  
  •                     output  wire            hsync,  
  •                     output  wire            vsync,  
  •                     output  wire   [11:0]   rgb,  
  •             output  reg             led  
  •                 );  
  • //红_绿_蓝  
  • parameter   BLACK   = 12'b0000_0000_0000;   
  • parameter   BLUE    = 12'b0000_0000_1111;  
  • parameter   GREEN   = 12'b0000_1111_0000;  
  • parameter   DIAN    = 12'b0000_1111_1111;  
  • parameter   RED     = 12'b1111_0000_0000;  
  • parameter   PURPLE  = 12'b1111_0000_1111;  
  • parameter   YELLOW  = 12'b1111_1111_0000;  
  • parameter   WHITE   = 12'b1111_1111_1111;  
  •                        
  • wire    [9:0]   pixel_x;  
  • wire    [9:0]   pixel_y;  
  • wire            clk_25mhz;  
  • reg [11:0]  rgb_reg;  
  •   
  •   
  • //显示静态图像640*480  
  • reg     [23:0] cnt;  
  • always @(posedge clk_25mhz or negedge sys_rst_n)  
  •     if(!sys_rst_n)  
  •         begin  
  •             cnt <= 0;  
  •             led <= 0;  
  •         end   
  •     else  
  •            begin  
  •             cnt <= cnt + 1'b1;  
  •         if(cnt == 24'd12500000)  
  •             begin   
  •                cnt <= 24'b0;  
  •                led <= ~led;  
  •                 end   
  •         end   
  • always @ (posedge clk_25mhz or negedge sys_rst_n)  
  •     if(!sys_rst_n)  
  •         begin  
  •             rgb_reg <= 12'b0;  
  •         end   
  •     else  
  •         begin               //显示图像  
  •         //rgb_reg <= q_sig;            
  •         rgb_reg[3:0] <= q_sig[7:4];  
  •         rgb_reg[7:4] <= q_sig[3:0];  
  •         rgb_reg[11:8] <= q_sig[11:8];      
  •     end      
  • always @ (posedge clk_25mhz or negedge sys_rst_n)  
  •     if(!sys_rst_n)  
  •         begin  
  •             address_sig <= 19'b0;  
  •         end   
  •     else  
  •     begin                 
  •         if(pixel_x>=0 && pixel_x<= 639 && pixel_y>=0 && pixel_y<=479)  
  •         address_sig = (pixel_x + 640*pixel_y);  
  •     end   
  •   
  •   
  •   
  • //////////////////////////////////////////////////////////////        
  • assign rgb = (video_en == 1'b1) ? rgb_reg:12'b0;  
  •   
  • vga_sync vga_syn_inst(  
  •             .clk            (clk_25mhz),  
  •             .rst_n          (sys_rst_n),  
  •             .video_en       (video_en),  
  •             .hsync          (hsync),  
  •             .vsync          (vsync),  
  •             .pixel_x        (pixel_x),  
  •             .pixel_y        (pixel_y)  
  •                         
  •         );  
  •   
  • reg     [18:0]  address_sig;  
  • wire    [11:0]  q_sig;  
  •   
  • rom_pic rom_pic_inst (  
  •   .clka(clk_25mhz),    // input wire clka  
  •   .addra(address_sig),  // input wire [18 : 0] addra  
  •   .douta(q_sig)  // output wire [11 : 0] douta  
  • );  
  •   
  • clk_wiz_0 clk_wiz_0_inst   
  •        (  
  •        // Clock in ports  
  •         .clk_in1(sys_clk),  
  •         // Clock out ports  
  •         .clk_out1(clk_25mhz)  
  •        );  
  •                  
  • endmodule  
[url=][/url]



三、生成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测试了
测试效果如图所示:


共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]