您的位置:首页 > 其它

FPGA 硬件设计---VGA设计

2017-05-15 20:17 295 查看
淘宝地址: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生成软件(用管理员身份运行)



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');


经过这些步骤即可得在显示屏中设计出自己想看到的图片

如果有什么问题,可以讨论496663398@qq.com邮件联系
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  FPGA设计