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]郵件聯繫

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