FPGA 硬件设计---VGA设计

淘宝地址:https://shop259121138.taobao.com/?spm=2013.1.1000126.d21.4b556901wuYhcM

最近学习FPGA设计,学习了VGA驱动电脑显示屏的驱动方式、硬件设计、程序设计、数据转换工具设计等。主要包括VGA时序、驱动写入、数据处理等
一、VGA时序
1、VGA时序在网上有很多博客都写了其时序方式,在这里我就不详细说明了,其行时序主要包括行段的A、B、C、D四段,工作过程中A段拉低,其他三段拉高,进行行同步信号;场时序包括O、P、Q、R工作过程中O段拉低,其他三段拉高,进行场同步信号;
2、频率设计,根据每一段的总时钟数,F=H_CLK*VCLK*60,即60帧的数据即可得到稳定的人眼可识别图像。
二、程序设计
1、驱动设计(.v)
设计VGA驱动
时钟频率12M,利用PLL增频率到40M,采用VGA_800X600_60Hz

 // --------------------------------------------------------------------
// >>>>>>>>>>>>>>>>>>>>>>>>> COPYRIGHT NOTICE <<<<<<<<<<<<<<<<<<<<<<<<<
// --------------------------------------------------------------------
// Module: VGA_module
// 
// Author: Jun
// 
// Description: VGA_module
//
// --------------------------------------------------------------------
// Code Revision History :
// --------------------------------------------------------------------
// Version: |Mod. Date:   |Changes Made:
// V1.1     |2017/5/7   |Initial ver
// --------------------------------------------------------------------

 module VGA_module
 (
        input           clk_in,         //system clock pin 40MHz
        input           rst_n_in,       //system reset pin,active low

        output reg     sync_v,          //V_Fild signal
        output reg      sync_h,         //H_Fild signal

        output reg [2:0] vga_data       //vga data,[R,G,B]
 );

reg             [15:0]  x_cnt;
reg             [15:0]  y_cnt;
reg                     vga_valid;

reg             [7:0]   Rom_address;
wire            [127:0] Rom_data;

My_Rom  u_My_Rom
(
        .Address(Rom_address),
        .Data(Rom_data)
);


//reg           [9:0]   IP_Rom_address;
//wire          [63:0]  IP_Rom_data;
//Rom   u_Rom
//(
//      .address(IP_Rom_address),
//      .clock(clk_in),
//      .q(IP_Rom_data)
//);

 //accumulate the num of row num
 always @(posedge clk_in or negedge rst_n_in)
 begin
        if(!rst_n_in) x_cnt<=16'd0;              //reset signal 
        else if(x_cnt >= `HSYNC_D) x_cnt<=16'd0;        //clear x_cnt
        else x_cnt<=x_cnt+1'b1;                         //accumulate x_cnt
 end

 //accumulate the num of coum num
 always @(posedge clk_in or negedge rst_n_in)
 begin 
        if(!rst_n_in) y_cnt<=16'd0;                  //reset signal 
        else if(x_cnt == `HSYNC_D)                      //x_cnt come to the end
            begin
            if(y_cnt>=`VSYNC_R) y_cnt <= 16'd0;     //clear y_cnt
            else y_cnt <= y_cnt+1'b1;                       //accumulate y_cnt
            end
        else y_cnt <= y_cnt;
 end

 //change the lever of HSYNC Signal 
 //A->low  BCD->High
 always @(posedge clk_in ,negedge rst_n_in)
 begin 
        if(!rst_n_in) sync_h<=1'b1;                  //reset signal 
        else if(x_cnt < `HSYNC_A) sync_h <= 1'b0;       //A low lever
        else sync_h <= 1'b1;                                    //BCD  high lever
 end

  //change the lever of VSYNC Signal 
 //O->low  PQR->High
  always @(posedge clk_in ,negedge rst_n_in)
 begin 
        if(!rst_n_in) sync_v<=1'b1;                  //reset signal 
        else if(y_cnt < `VSYNC_O) sync_v <= 1'b0;       //O low lever
        else sync_v <= 1'b1;
 end            

 //judge availability of vga_valid
  always @(posedge clk_in ,negedge rst_n_in)
  begin
        if(!rst_n_in) vga_valid<=1'b0;              //reset ,unvalid
        //x_cnt between B_C,,y_cnt between P_Q
        else if((x_cnt > `HSYNC_B) && (x_cnt <`HSYNC_C) && (y_cnt > `VSYNC_P) && (y_cnt < `VSYNC_Q))
        vga_valid <= 1'b1;                              //valid
        else vga_valid <=1'b0;                          //unvalid
  end

  always @(posedge clk_in ,negedge rst_n_in)
  begin 
        if(!rst_n_in) vga_data=3'b000;
        else if(vga_valid)

            begin 

                // display the color block
//              if((x_cnt > `HSYNC_B) && (x_cnt <= `HSYNC_B + 10'd100))                 
//                  vga_data = 3'b100;          //红色
//              else if((x_cnt > `HSYNC_B + 10'd100) && (x_cnt <= `HSYNC_B + 10'd200))  
//                  vga_data = 3'b010;          //黄色
//              else if((x_cnt > `HSYNC_B + 10'd200) && (x_cnt <= `HSYNC_B + 10'd300))  
//                  vga_data = 3'b001;          //黄色
//              else if((x_cnt > `HSYNC_B + 10'd300) && (x_cnt <= `HSYNC_B + 10'd400))  
//                  vga_data = 3'b110;          //黄色
//              else if((x_cnt > `HSYNC_B + 10'd400) && (x_cnt <= `HSYNC_B + 10'd500))  
//                  vga_data = 3'b101;          //黄色
//              else if((x_cnt > `HSYNC_B + 10'd500) && (x_cnt <= `HSYNC_B + 10'd600))  
//                  vga_data = 3'b011;          //黄色
//              else if((x_cnt > `HSYNC_B + 10'd600) && (x_cnt <= `HSYNC_B + 10'd700))  
//                  vga_data = 3'b111;          //蓝色
//              else if((x_cnt > `HSYNC_B + 10'd700) && (x_cnt <= `HSYNC_B + 10'd800))  
//                  vga_data = 3'b000;          //绿色
//              else
//                  vga_data = 3'b111;          //黑色    

                //display the picture
                //0-544 comu data   0-63 raw data
                if((x_cnt > `HSYNC_B+10'd100) && (x_cnt <= `HSYNC_B+10'd100 + 10'd127)&&(y_cnt > `VSYNC_P+10'd100)&&(y_cnt < `VSYNC_P+10'd100 + 10'd127))  
                    begin
                        Rom_address[7:0] <= x_cnt - `HSYNC_B -10'd100;
                        if(Rom_data[10'd127-(y_cnt - `VSYNC_P-10'd100)]) vga_data<=3'b110;
                        else vga_data<=3'b000;
                    end
                else vga_data<=3'b000;
            end
        else vga_data<=3'b000;

        end


endmodule

2、数据处理设计

改数据处理用到三个软件,包括字膜处理软件、Mif生成软件以及自己开发的一款直接把MIF文件转换成.v文件的软件
1.字模软件设置

这里写图片描述
2.Mif生成软件(用管理员身份运行)
Mif生成软件
3.自己写的转换软件
转换软件
4.如果需要图像显示,只能显示二进制图像,需要用软件将普通图片转换成二值化图像,可以用MATLAB实现

I = imread('C:\Users\Jun\Desktop\5555.bmp');
imshow(I);
I3=im2bw(I);
imshow(I3);
I4=imresize(I3,[128 128]);
imwrite(I4,'C:\Users\Jun\Desktop\6666.bmp');

经过这些步骤即可得在显示屏中设计出自己想看到的图片
如果有什么问题,可以讨论[email protected]邮件联系

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章