CrazyBingo

算了,那么多人问我VGA,我还是满世界免费发放吧,那么懒

0
阅读(1990) 评论(0)

时序:  http://tinyvga.com/vga-timing

Verilog设计:vga_desin->vga_display->vga_driver层层递归

(1)顶层不说了 ,你懂的

(2)vga_diaplay: 读取行列值,给颜色就可以,发挥你的想象力

/*******所有代码仅在lcd_display改写即可******/
//LCD VGA接口都一样
module lcd_display
(
 input   clk,
 input   rst_n,
 
 input [8:0] x_pos,
 input [8:0] y_pos,
 output [15:0] lcd_data
);

//定义颜色变量RGB--5|6|5
parameter RED     = 16'hF800;  /*11111,000000,00000 F800 红*/
parameter GREEN     = 16'h07E0;  /*00000,111111,00000 07E0 绿*/
parameter BLUE      = 16'h001F;  /*00000,000000,11111 001F 蓝*/
parameter WHITE     = 16'hFFFF;  /*11111,111111,11111 FFFF 白*/
parameter BLACK     = 16'h0000;  /*00000,000000,00000 0000 黑*/
parameter YELLOW    = 16'hFFE0;  /*11111,111111,00000 FFE0 黄*/
parameter CYAN      = 16'hF81F;  /*11111,000000,11111 F81F 青*/
parameter ROYAL     = 16'h07FF;  /*00000,111111,11111 07FF 品*/
...
...
endmodule

(3)vga_driver底层驱动代码,根据时序写,方便一直

/********************************************************************
* Module Name       :   vga_driver
* Author            :   Crazy Bingo
* Device            :   EP2C8Q208C8N
* Version           :   Quartus II 9.1
* Date              :   2011/2/15
* Description       :   Dispaly programs for the vga
*********************************************************************/
/********************************************************************
* Revision Author   :   Crazy Bingo
* Date              :   2010-10-9 9:12
* Description       :   VS不能用门控时钟,只能用使能时钟,否则影响整体性能,造成数据缺失
                        用最高时钟控制整个系统,始终满天飞会使得系统性能下降,甚至出错
*********************************************************************/


module vga_driver
(   
 input   clk_vga, // VGA像素时钟
 input   rst_n,      // 异步复位信号
 
 input [15:0] vga_data,
 output [15:0] vga_rgb, // 接收要显示的色彩
 output reg  vga_hs,  // VGA管脚 行同步
 output reg  vga_vs,  // VGA管脚 场同步
 
 output [10:0] x_pos,  // 像素横坐标位置
 output [9:0] y_pos  // 像素纵坐标位置
); 

 /* |     显示     |前沿|同步|后沿|     显示     |前沿|同步|后沿|
 *                      |____|   |                   |____|    |
 * ______________ ______________  ______________ ______________
 *  |     显示     |    不显示    |     显示     |    不显示    |
 * _____________________________  ______________ ______________
 * |       显示一行帧长          |       显示一行帧长          |
 */
//定义VGA_1024_768_65M_60HZ显示协议标准 
parameter H_DISP  = 11'd1024;   // 显示时序
parameter H_FRONT = 11'd24;    // 显示前沿
parameter H_SYNC  = 11'd136;   // 同步脉冲
parameter H_BACK  = 11'd160;    // 显示后沿
parameter H_TOTAL = 11'd1344;  // 时序帧长

parameter V_DISP  = 10'd768;   // 显示时序     
parameter V_FRONT = 10'd3;    // 显示前沿
parameter V_SYNC  = 10'd6;     // 同步脉冲
parameter V_BACK  = 10'd29;    // 显示后沿
parameter V_TOTAL = 10'd806;   // 时序帧长

//------------------------------------------
// 行同步信号发生器
reg [10:0] hcnt;
always @ (posedge clk_vga or negedge rst_n)
begin
 if (!rst_n)
  hcnt <= 0;
 else
  begin
        if (hcnt < H_TOTAL-1)   
            hcnt <= hcnt+1'b1;
        else
            hcnt <= 0;
  end
end

always@(posedge clk_vga or negedge rst_n)
begin
 if(!rst_n)
  vga_hs <= 1;
 else
  begin
        if( (hcnt >= H_DISP+H_FRONT-1) && (hcnt < H_DISP+H_FRONT+H_SYNC-1) )//Delay for one clk
            vga_hs <= 0;      
        else
            vga_hs <= 1;
  end
end

//------------------------------------------
// 场同步信号发生器
reg [9:0] vcnt;
always @ (posedge clk_vga or negedge rst_n)
begin
 if (!rst_n)
  vcnt <= 0;
 else
  begin
  if(hcnt == H_DISP-1)
   begin
   if (vcnt < V_TOTAL-1)   
    vcnt <= vcnt+1'b1;
   else
    vcnt <= 0;  
   end
  end
end

always @ (posedge clk_vga or negedge rst_n)
begin
 if(!rst_n)
  vga_vs <= 1;
 else
  begin
  if( (vcnt >= V_DISP+V_FRONT-1) && (vcnt < V_DISP+V_FRONT+V_SYNC-1) )//Delay for one clk
            vga_vs <= 0;       
        else
            vga_vs <= 1;  
  end
end

//------------------------------------------
/*定义H_DISP*V_DISP行列坐标*/
assign x_pos = (hcnt < H_DISP) ? hcnt[9:0] : 10'd0;
assign y_pos = (vcnt < V_DISP) ? vcnt[9:0] : 10'd0;
assign vga_rgb = ((hcnt < H_DISP) && (vcnt < V_DISP)) ? vga_data : 16'd0;


endmodule

过些天有时间写成IP再说