VGA控制的verilog模塊設計


VGA接口是一種最常見的顯示屏接口,其時序與控制都比較簡單。

1.VGA接口

VGA只需要三個接口:

R:紅色深度值

G:綠色深度值

B:黃色深度值

HS:行同步

VS:場同步

下圖是zynq7000開發板上的VGA接口原理圖。


2.VGA時序

顯示器的逐行掃描方式如下圖所示,由屏幕左上方出發逐行向右下方掃描。掃描一行的頻率為行頻率,掃完一幀的頻率為場頻率。屏幕的自我刷新頻率即場頻率,常見為60Hz,行頻為31.5KHz。

不過並非所有的掃描點都會發射電子到屏幕上,每一行掃描完是都要回到行首進行下一行的掃描,這期間不會有電子束打出到屏幕上,這就是行(場)消隱。通常來說,行掃描或場掃描的掃描計數均可分為四個階段。其中顯示階段大小為真實屏幕分辨率大小。


在這四個階段中,只有在顯示階段是的行輸出x_vld有效,此時傳出相應的像素值完場行同步,即可在該行相應位置顯示相應顏色。每計滿一行后,列計數器數值+1,顯示方式與行同步一樣。


對於不同刷新速度的屏幕以及不同的分辨率,行同步與場同步的數值如下,其中C與Q為實際分辨率值。所需時鍾頻率計算方式以640*480@60Hz為例:

clk = 800 * 525 *60 = 25'200'000 = 25MHz


3.VGA接口模塊

一個簡單的在屏幕上顯示一個色塊的代碼如下,輸入時鍾為25MHz。

module vga(
    output [4:0] vga_r,
    output [5:0] vga_g,
    output [4:0] vga_b,
    output reg vga_hs,
    output reg vga_vs,
	 
    input clk,
    input rst,
    );

  reg[9:0]xsync,ysync;
  always @(posedge clk or posedge rst) begin
    if (rst) begin  
      xsync <= 10'd0;
    end
    else if (xsync == 10'd799) begin
      xsync <= 10'd0;
    end
    else begin
      xsync <= xsync + 1;
    end
  end

  always @(posedge clk or posedge rst) begin
    if (rst) begin
      ysync <= 10'd0;
    end
    else if (ysync == 10'd524) begin
      ysync <= 10'd0;
    end
    else if (xsync == 10'd799) begin
      ysync <= ysync + 1;
    end
  end
  
  always @(posedge clk or posedge rst) begin
    if (rst) begin
      vga_hs <= 1'b0;
    end
    else if (xsync == 799) begin
      vga_hs <=1'b0;
    end
    else if (xsync == 95) begin
      vga_hs <= 1'b1;
    end
  end

  always @(posedge clk or posedge rst) begin
    if (rst) begin
      vga_vs <= 1'b0;
    end
    else if (ysync == 0) begin
      vga_vs <=1'b0;
    end
    else if (ysync == 1) begin
      vga_vs <= 1'b1;
    end
  end
  
  wire valid;
  assign valid = (xsync > 143) && (xsync < 784) && (ysync > 34) && (ysync < 515);

  assign x_pos = xsync - 143;
  assign y_pos = ysync -34;
  
  wire block_vld;
  assign block_vld = (x_pos >= 50) && (x_pos < 100) && (y_pos >= 50) && (y_pos < 100);

  always @(posedge clk or posedge rst) begin
    if (rst) begin
      // reset
      RGB <= 16'b0;
    end
	 else if (block_vld && valid) begin
	   RGB <= 16'b11111_000000_11111;
	 end
	 else if (valid) begin
      RGB <= 16'b00000_000000_11111;
    end
    else begin
      RGB <= 16'b0;
    end
  end
endmodule






免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM