FPGA 學習筆記(十一) VGA驅動的實現
VGA時序圖
1)行掃描時序圖
a:行同步時期,掃描地址的復位
b:行消隱後肩,掃描地址轉移後的穩定等待準備期
c:行顯示時期,資料有效區域
d:行消隱前肩,掃描地址轉移的準備
e:行掃描總時間,一行掃描的總時間
2)場掃描時序圖
o:場同步時期,掃描地址的復位
p:場消隱後肩,掃描地址轉移後的穩定等待準備期
q:場顯示時期,資料有效區域
r:場消隱前肩,掃描地址轉移的準備
s:場掃描總時間,一場掃描的總時間
3)VGA顯示器掃描軌跡
常見的重新整理率時序表
由於FPGA擅長計數電路這裡採用畫素表示法來設計驅動
FPGA硬體 測試時要將sys_pll中的輸出頻率改為25MHZ。
驅動電路的verilog設計(lcd_driver)
由亍目前液晶顯示器的普及,而高於 60Hz 的重新整理率對於液晶來說,沒有任何意義,所以我們以 640*480 在 60Hz 的重新整理率下為例。
本次我們採用的是ADV7123視訊轉換晶片來實現。
1)為便於移植,根據640*480 60hz解析度下的引數,巨集定義相關資料
//---------------------------------
// 640 * 480
`define H_FRONT 11'd16
`define H_SYNC 11'd96
`define H_BACK 11'd48
`define H_DISP 11' d640
`define H_TOTAL 11'd800
`define V_FRONT 11'd10
`define V_SYNC 11'd2
`define V_BACK 11'd33
`define V_DISP 11'd480
`define V_TOTAL 11'd525
2)行掃描單位hcnt計數
/*******************************************
SYNC--BACK--DISP--FRONT
*******************************************/
//------------------------------------------
//h_sync counter & generator
reg [10:0] hcnt;
always @ (posedge clk or negedge rst_n)
begin
if (!rst_n)
hcnt <= 11'd0;
else
begin
if(hcnt < `H_TOTAL - 1'b1) //line over
hcnt <= hcnt + 1'b1;
else
hcnt <= 11'd0;
end
end
assign lcd_hs = (hcnt <= `H_SYNC - 1'b1) ? 1'b0 : 1'b1;
//VGA行同步訊號
3)列掃描單位vcnt計數
每掃描完一行,即hcnt完成H_TOTAL次計數後,vcnt進行自加。
//------------------------------------------
//v_sync counter & generator
reg [10:0] vcnt;
[email protected](posedge clk or negedge rst_n)
begin
if (!rst_n)
vcnt <= 11'b0;
else if(hcnt == `H_TOTAL - 1'b1) //line over
begin
if(vcnt < `V_TOTAL - 1'b1) //frame over
vcnt <= vcnt + 1'b1;
else
vcnt <= 11'd0;
end
end
assign lcd_vs = (vcnt <= `V_SYNC - 1'b1) ? 1'b0 : 1'b1;
//VGA場同步訊號
4)ADV7123控制訊號輸出
為了實現資料在lcd_dclk上升沿有效,我們將clk翻轉輸出,已實現上升沿取樣
lcd_blank作為顯示空白訊號,低電平有效。
設計中不需要lcd_sync資訊,可以直接接地。
//------------------------------------------
//LCELL LCELL(.in(clk),.out(lcd_dclk));
assign lcd_dclk = ~clk;
assign lcd_blank = lcd_hs & lcd_vs;
assign lcd_sync = 1'b0;
5)有效顯示使能訊號輸出
當使能訊號有效時,接收外部輸入的RGB資料lcd_data.
//-----------------------------------------
assign lcd_en = (hcnt >= `H_SYNC + `H_BACK && hcnt < `H_SYNC + `H_BACK + `H_DISP) &&
(vcnt >= `V_SYNC + `V_BACK && vcnt < `V_SYNC + `V_BACK + `V_DISP)
? 1'b1 : 1'b0;
assign lcd_rgb = lcd_en ? lcd_data : 24'h000000; //ffffff;
6)外部資料請求控制訊號。
為了實現資料的穩定,lcd_request要提前一個時鐘請求外部輸入資料
同時,設計中實時顯示下一時刻的掃描地址lcd_xpos、lcd_ypos,也要提前一個時鐘輸出,以保證外部資料輸入的同步化。
lcd_xpos、lcd_ypos作為顯示器有效顯示區域的行列座標計數值。
//------------------------------------------
//ahead x clock
localparam H_AHEAD = 11'd1;
assign lcd_request = (hcnt >= `H_SYNC + `H_BACK - H_AHEAD && hcnt < `H_SYNC + `H_BACK + `H_DISP - H_AHEAD) &&
(vcnt >= `V_SYNC + `V_BACK && vcnt < `V_SYNC + `V_BACK + `V_DISP)
? 1'b1 : 1'b0;
//lcd xpos & ypos
assign lcd_xpos = lcd_request ? (hcnt - (`H_SYNC + `H_BACK - H_AHEAD)) : 11'd0;
assign lcd_ypos = lcd_request ? (vcnt - (`V_SYNC + `V_BACK)) : 11'd0;
模擬VGA影象資料的輸入
1)巨集定義三原色組合的顏色如下
//define colors RGB--8|8|8
`define RED 24'hFF0000 /*11111111,00000000,00000000 */
`define GREEN 24'h00FF00 /*00000000,11111111,00000000 */
`define BLUE 24'h0000FF /*00000000,00000000,11111111 */
`define WHITE 24'hFFFFFF /*11111111,11111111,11111111 */
`define BLACK 24'h000000 /*00000000,00000000,00000000 */
`define YELLOW 24'hFFFF00 /*11111111,11111111,00000000 */
`define CYAN 24'hFF00FF /*11111111,00000000,11111111 */
`define ROYAL 24'h00FFFF /*00000000,11111111,11111111 */
這裡要注意你所用的VGA驅動電路是RGB888還是RGB565,若是RGB565,三原色要改成下面樣式,並把其他程式中lcd_data的位數改為16位:
筆者曾在這裡犯過錯誤。
//define colors RGB--5|6|5
`define RED 16'hF800 /*11111111,00000000,00000000 */
`define GREEN 16'h07E8 /*00000000,11111111,00000000 */
`define BLUE 16'h0011 /*00000000,00000000,11111111 */
`define WHITE 16'hFFFF /*11111111,11111111,11111111 */
`define BLACK 16'h0000 /*00000000,00000000,00000000 */
`define YELLOW 16'hFFE0 /*11111111,11111111,00000000 */
`define CYAN 16'hF81F /*11111111,00000000,11111111 */
`define ROYAL 16'h07FF /*00000000,11111111,11111111 */
2)根據輸入的行、列地址訊號,輸出三原色組合後得到的8條彩色。
//-------------------------------------------
`ifdef VGA_HORIZONTAL_COLOR
[email protected](posedge clk or negedge rst_n)
begin
if(!rst_n)
lcd_data <= 24'h0;
else
begin
if (lcd_ypos >= 0 && lcd_ypos < (`V_DISP/8)*1)
lcd_data <= `RED;
else if(lcd_ypos >= (`V_DISP/8)*1 && lcd_ypos < (`V_DISP/8)*2)
lcd_data <= `GREEN;
else if(lcd_ypos >= (`V_DISP/8)*2 && lcd_ypos < (`V_DISP/8)*3)
lcd_data <= `BLUE;
else if(lcd_ypos >= (`V_DISP/8)*3 && lcd_ypos < (`V_DISP/8)*4)
lcd_data <= `WHITE;
else if(lcd_ypos >= (`V_DISP/8)*4 && lcd_ypos < (`V_DISP/8)*5)
lcd_data <= `BLACK;
else if(lcd_ypos >= (`V_DISP/8)*5 && lcd_ypos < (`V_DISP/8)*6)
lcd_data <= `YELLOW;
else if(lcd_ypos >= (`V_DISP/8)*6 && lcd_ypos < (`V_DISP/8)*7)
lcd_data <= `CYAN;
else// if(lcd_ypos >= (`V_DISP/8)*7 && lcd_ypos < (`V_DISP/8)*8)
lcd_data <= `ROYAL;
end
end
`endif
不同解析度的VGA驅動
lcd_para檔案定義了四種VGA解析度驅動,這裡只需修改定義的註釋就行,並把PLL鎖相環中的頻率改為相應的頻率。
//`define VGA_640_480_60FPS_25MHz
//`define VGA_800_600_72FPS_50MHz
//`define VGA_1024_768_60FPS_65MHz
`define VGA_1280_1024_60FPS_105MHz
PLL修改方法為直接修改下面引數中的乘法除法因子:
altpll_component.clk0_divide_by = 10,
altpll_component.clk0_duty_cycle = 50,
altpll_component.clk0_multiply_by = 21,
altpll_component.clk0_phase_shift = "0",
altpll_component.compensate_clock = "CLK0",
altpll_component.inclk0_input_frequency = 20000,
相關推薦
FPGA 學習筆記(十一) VGA驅動的實現
VGA時序圖 1)行掃描時序圖 a:行同步時期,掃描地址的復位 b:行消隱後肩,掃描地址轉移後的穩定等待準備期 c:行顯示時期,資料有效區域 d:行消隱前肩,掃描地址轉移的準備 e:行掃描總時間,一行掃描的總時間 2)場掃描時序圖 o:場
Python學習筆記(十一)裝飾器
before 原來 return wrap 文本 wiki 模塊 http 學習筆記 摘抄:https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/0014318
如鵬網學習筆記(十一)JQuery
on() jquery操作 等於 asc 空字符串 name屬性 string 包含 ret 一、jQuery簡介 jQuery是一個JavaScript庫,特性豐富,包含若幹對象和很多函數,可以替代傳統DOM編程的操作方式和操作風格 jQuery通過對DOM
Python學習筆記(十一)
def __init__ 實現 完成 cti uniq ive 枚舉 elf 一、Python的多重繼承功能 Python中的主線是單一繼承的 Python中可以存在功能類,即專註於完成一定功能的類,相當於其他一些動態語言中的接口的概念 class Class_
EF學習筆記(十一):實施繼承
long cannot oid data- turn cati com list pac 學習總目錄:ASP.NET MVC5 及 EF6 學習筆記 - (目錄整理) 上篇鏈接:EF學習筆記(十) 處理並發 本篇原文鏈接:Implementing Inheritance 面
R語言學習筆記(十一):廣義線性模型
學習筆記 Education 5.0 1.3 style only 可能性 div erro #Logistic 回歸 install.packages("AER") data(Affairs,package="AER") summary(Affairs) a
python學習筆記(十一)之函數
last 函數返回 traceback keep disco show 全局變量 not 默認參數 牛刀小試: 定義一個無參函數 1 >>> def myFirstFunc(): 2 ... print("Hello python
JavaScript學習筆記(十一)——閉包
進行 性能 ole 直接 狀態 聲明變量 垃圾 函數 官方網站 在學習廖雪峰前輩的JavaScript教程中,遇到了一些需要註意的點,因此作為學習筆記列出來,提醒自己註意! 如果大家有需要,歡迎訪問前輩的博客https://www.liaoxuefeng.com/學習。
學習筆記(十一)——數據庫的索引碎片、計劃緩存、統計信息
部分 null 文章 mage like 分享 show not 決定 1.索引碎片 數據庫存儲本身是無序的,建立了聚集索引,會按照聚集索引物理順序存入硬盤。既鍵值的邏輯順序決定了表中相應行的物理順序 而且在大多數的情況下,數據庫寫入頻率遠低於讀取頻率,索引的存在為了讀
Linux學習筆記(十一)用戶組管理 、用戶管理
.net nologin follow 另一個 window ftp log product windows文件 一、linux和windows互傳文件 目前我所學到的linux與windows互傳文件的方法有兩種; yum install -y lrzsz輸入sz
hadoop學習筆記(十一):MapReduce數據類型
筆記 ash all 記錄 write 一個 操作 png bool 一、序列化 1 hadoop自定義了數據類型,在hadoop中,所有的key/value類型必須實現Writable接口。有兩個方法,一個是write,一個是readFileds。分別用於讀(反序列化操
Nodejs學習筆記(十一)—數據采集器示例(request和cheerio)
列表 意思 9.1 很多 AD 開發 com http undefined 寫在之前 很多人都有做數據采集的需求,用不同的語言,不同的方式都能實現,我以前也用C#寫過,主要還是發送各類請求和正則解析數據比較繁瑣些,總體來說沒啥不好的,就是效率要差一些, 用nodej
ASP.NET Core 2 學習筆記(十一)Cookies & Session
自動 asp Go 內存 rtu serialize .html call names 原文:ASP.NET Core 2 學習筆記(十一)Cookies & Session基本上HTTP是沒有記錄狀態的協定,但可以通過Cookies將Request來源區分出來,並
javaweb學習筆記(十一):JSP(1)
目錄 jsp(1) 1.基本概念 1 .1Jsp的執行過程 1.2 JSP與servlet 2 JSP語法 2.1 Jsp模板 2.2 Jsp表示式 2.3 Jsp指令碼 2.4 Jsp宣告 2.5 Jsp註釋 jsp(1) 1.基本
python基礎教程(第三版)學習筆記(十一)
第十一章 檔案 11.1 開啟檔案 要開啟檔案,可使用函式open,它位於自動匯入的模組io中。函式open將檔名作為唯一必不可少的引數,並返回一個檔案物件。 from contextlib import contextmanager import sys,pprint f=open('xx.
學習筆記(十一):使用K-Means演算法檢測DGA域名
1.資料收集與清洗:同(十) 2.特徵化:同(十) 3.訓練樣本 model = KMeans(n_clusters = 2, random_state=random_state) y_pred = model.fit_predict(x) 4.效果驗證:使用TSNE將
機器學習筆記(十一): TensorFlow實戰三(MNIST數字識別問題)
1 - MNIST數字識別問題 前面介紹了這樣用TensorFlow訓練一個神經網路模型和主要考慮的問題及解決這些問題的常用方法。下面我們用一個實際的問題來驗證之前的解決方法。 我們使用的是MNIST手寫數字識別資料集。在很多深度學習教程中,這個資料集都會被當做一個案例。 1.1
Python學習筆記(十一)關鍵字、函式和方法
關鍵字是 Python內建的、具有特殊意義的識別符號 關鍵字後面不需要使用括號 函式封裝了獨立功能,可以直接呼叫
Python學習筆記(十一)關鍵字、函數和方法
python 選擇 使用 通過 標識 很多 div 方法 針對 關鍵字是 Python內置的、具有特殊意義的標識符 關鍵字後面不需要使用括號 函數封裝了獨立功能,可以直接調用 函數名(參數)
Golang學習筆記(十一)函式變數,將函式作為值使用
Golang中,函式也可以作為一個變數來使用。 寫一個普通函式來讓一段字串,實現大小寫交替顯示: func processCase1(str string) string { result := "" for i, value := range str { if i%2 == 0 {