一、設計目標:
設計一個LCD控制器,該控制器基於Altera的SOPC系統,通過SOPC中的Avalon匯流排介面與Nios II處理器和SDRAM控制器通信,使之能顯示640*480解析度,顯示顏色深度達到16bit,輸出介面兼容TFT LCD。
二.設計原理:
1、系統工作原理:
如圖1所示,Nios II處理器在SDRAM中開闢framebuffer,可以是單緩衝也可以是雙緩衝,以單緩衝為例。Nios II處理器將一幀圖象數據(640×480×2Bytes,RGB565,16bit)存入framebuffer,然後將framebuffer的首地址寫入到LCD控制器,並啟動LCD控制器,該控制器自動從傳來的首地址處開始讀取圖象數據,並按照TFT的格式輸出。
圖中各模塊由Avalon Bus連接在一起。Avalon Bus是一種簡單的匯流排結構,在SOPC中,Nios II軟核處理器和各種外設都通過Avalon Bus連接在一起。由圖1可以看出,作為Slaver的SDRAM Controller分別要受到Processor 和LCD Controller的控制,為了解決匯流排衝突,Avalon Bus自動在有衝突的介面上加入了Arbitrator這樣一個仲裁模塊,用於合理分配匯流排時間,用戶通過改變每個模塊的權值來改變對其分配匯流排時間的多少。在這個系統中,SDRAM Controller處的衝突是影響整個系統性能的關鍵。以SDRAM時鐘頻率為100MHz計算,16bit位寬的SDRAM其數據總帶寬為200MByte/s,640*480*2Bytes*60Hz的TFT LCD要佔用36MByte/s左右的帶寬,這對於還要處理其他任務的處理器來說是很大的影響。解決的辦法是另外增加一塊SDRAM,專門用作Frame buffer,這樣就可以有效減少對系統匯流排帶寬的佔用。
2、LCD Controller工作原理
如圖2所示,LCD Controller主要由Avalon 匯流排介面、寄存器組、控制模塊、DMA、FIFO以及時序生成模塊組成。每個寄存器獨立編址,處理器可以通過匯流排讀寫存儲器的方式來訪問。處理器通過Avalon匯流排接讀寫寄存器,從而完成對LCD控制器工作狀態的設定與控制。
控制器啟動后,DMA Master通過avalon匯流排讀取SDRAM中的數據,然後存入FIFO中,時序生成模塊按照TFT時序要求從FIFO中讀取數據,然後送出去顯示。整個數據讀取過程不需要處理器干涉,實際上是一個DMA過程。
考慮到DMA讀取的速度與TFT時序發生器輸出的速度不一致(前者大於後者),所以在DMA與TFT時序發生器之間加入了FIFO用來緩衝數據。DMA有控制模塊控制其工作。控制模塊不斷檢測FIFO狀態,當FIFO快滿時,暫停DMA,當FIFO快空時,重新啟動DMA,如此循環,可保證FIFO不溢出,保證顯示畫面連續穩定。
三、設計細節
1、Avalon Bus Slaver從匯流排介面
Avalon從匯流排介面負責處理器與LCD控制器的介面控制,LCD控制器在整個系統中作為從設備,通過該介面,接受CPU的控制。根據設計需要,該介面所需要的各信號為:
input: | |
chipselect | 片選,高電平有效 |
Write_n | 寫信號,低電平有效 |
Read_n | 讀信號,低電平有效 |
Reset_n | 複位,低電平有效 |
clk | 系統時鐘 |
address[1:0] | 地址信號 |
writedata[31:0] | 寫數據 |
output: | |
readdata[31:0] | 讀數據 |
irq_n | 中斷請求,低電平有效 |
這些信號均要求滿足Avalon匯流排的時序要求:(採用基本時序)
讀時序:
如圖3所示,讀時序在一個系統時鐘周期內完成。在第一個clk上升沿,系統將address、byteenable、read信號輸出到從設備介面,系統內部對address進行地址解碼,生成chipselect信號也傳輸到從設備介面,一旦chipselect被置高,從設備立即將readdata信號輸出到從設備介面,系統在第二個時鐘上升沿讀取該數據,從而完成一次讀操作。
為滿足此時序,可利用第一個clk的下降沿來檢測address、read、chipselect信號是否有效,如果有效,立即輸出數據。
代碼如下:
always @(posedge slave_clk or negedge reset_n)
begin
if(reset_n == 0)
begin
slave_readdata<=0;
end
else if(slave_chipselect && ~slave_read_n)
begin
case(slave_address)
2''b00:
slave_readdata<=controlReg;
2''b01:
slave_readdata<=interStatus;
2''b10:
slave_readdata<=startAddress;
2''b11:
slave_readdata<=addressCounter;
endcase
end
寫時序:
如圖4所示,寫操作也在一個時鐘周期內完成。在第一個clk上升沿,系統設置address、byteenable、writedata、write信號有效,然後內部將address信號解碼得出chipselect信號並立即傳輸到從設備介面,從設備在第二個clk上升沿捕獲介面上的數據,從而完成一個寫操作。
為滿足此時序,從設備介面在第二個clk上升沿檢測address、write、chipselect信號是否有效,若有效,則將數據口上的數據writedata寫入到內部寄存器。
代碼如下:
always @(posedge slave_clk or negedge reset_n)
begin
if(reset_n == 0)
begin
controlReg<=0;
//
statusReg<=0;
startAddress<=0;
frameLength<=0;
end
else if(slave_chipselect && ~slave_write_n)
begin
case(slave_address)
2''b00:
controlReg<=slave_writedata;
//2''b01:
statusReg<=slave_writedata;
2''b10:
startAddress<=slave_writedata;
2''b11:
frameLength<=slave_writedata;
endcase
end
end
clk信號為系統時鐘信號,這裡取100MHz。
reset_n為複位信號,低電平有效,複位后,LCD控制器應該處於一個設定好的狀態。
irq為中斷請求信號,當控制器滿足下列條件之一時,向系統發出中斷請求信號,將irq信號置高,直到系統響應該信號,並用軟體將其清零。(暫時未使用)
2、Avalon Bus DMA Master主設備介面
Avalon Bus DMA Master負責按照控制模塊的指令,讀取SDRAM中的數據,並寫入到FIFO中。其核心部分是DMA地址累加器,當條件滿足時,地址累加器開始在100MHz的時鐘下以4為單位開始累加(為何以4為單位,是由avalon匯流排的地址映射方式決定的。avalon匯流排按位元組進行編址,而SDRAM控制器一次讀取32bit即4Byte的數據,所以地址要以4為單位累加),用於生成讀取SDRAM的地址。讀完一幀的數據后,自動複位到首地址,繼續累加。
主設備介面信號列表:
input: | |
Master_clk | 主設備時鐘100MHz |
Master_waitrequest | 主設備等待信號 |
Master_readdatavalid | 主設備數據有效信號 |
Master_readdata[31:0] | 主設備數據 |
Output: | |
Master_read_n | 主設備讀信號 |
Master_address[31:0] | 主設備地址信號 |
controlReg | 控制寄存器,用於控制LCD控制器的運行與停止 |
statusReg | 狀態寄存器,用於指示LCD控制器的工作狀態(保留) |
startAddress | DMA首地址,即緩衝區首地址 |
frameLength | 幀長度 |
5、Control(控制模塊)
控制模塊用於協調LCD控制器各部分的工作,用於連接寄存器組與時序發生器。在實際的設計中並沒有獨立的這麼一個控制模塊,各種控制關係實際上已經集成到各個分模塊裡面去了。
6、LCD Timing Generator(LCD顯示時序發生器)
時序發生器用於產生TFT屏幕所需的時序,將圖象數據按特定的時序輸出。本設計專門針對三菱公司的AA084VC05液晶屏設計,下面是其時序分析:
LCD時序發生器以DCLK為時鐘基準,該DCLK即上面所說的PCLK,也就是像點時鐘,每個象素點的數據以該時鐘驅動進入LCD。如上圖所示,為AA084VC05的水平掃描時序,其中,DATA為18位數據信號(本設計中只用其中的16位),DENA為數據有效信號,高電平使能,其有效寬度THA為640個DCLK;HD為水平同步信號,低電平有效,其有效寬度TWHL為96個DCLK。一行640個象素掃描完畢之後,控制器將驅動HD有效,在HD有效之前插入THFP(Horizontal Front Porch)為16個DCLK,有效之後插入THBP(Horizontal Back Porch)為144個DCLK,然後再開始下一行的掃描。如此一來,行掃描信號的頻率FH典型值為31.5KHz。而讀FIFO信號要提前DENA信號一個時鐘節拍到來,提前一個時鐘節拍結束,因為該FIFO有一個時鐘節拍的延遲。
AA084VC05的垂直掃描時序與水平掃描時序類似,該時序以HD為時鐘基準,其中,VD為垂直同步信號(幀同步)。每掃描完一幀(480行),控制器將驅動VD有效(低電平),有效寬度TWVL為2個HD。同樣,在VD有效之前插入TVFP(Vertical Front Porch)為10個HD,有效之後插入TVBP(Vertical Back Porch)為35個HD,如此一來,垂直掃描信號頻率FV的典型值為60Hz。
在本設計中,所有這些時序參數都用parameter來表示,在以後更一般化的設計中,這些參數將由寄存器組來設置。
parameter LINES= 480;
//Number of lines
parameter COLUMNS = 640;
//Pixel Number Per Line
parameter THFP= 16;
// Horizontal Front Porch(DCLK)
parameter THBP= 144;
// Horizontal Back Porch(DCLK)
parameter TWHL= 96;
// Horizontal Low Width(DCLK)
parameter TVFP= 10;
// Vertical Front Porch(HD)
parameter TVBP= 35;
// Vertical Back Porch(HD)
parameter TWVL= 2;
// Vertical Low Width(HD)
時序發生器採用狀態機實現,如下代碼:
reg oHSYNC;
reg oVSYNC;
reg oDENA;
reg lineENA;
reg[9:0] cCounter;
reg[9:0] lCounter;
assign oSC= 0;
assign oPCLK = clk_25M;
assign oPDATA =oDENA ? {tft_data[15:11],1''b0,tft_data[10:0],1''b0} : 18''hz;
//horizontal sync signal generator
always @(posedge clk_25M)
begin
if(tft_reset_n == 0)
//reset active
begin
oDENA<=0;
oHSYNC<=0;
cCounter[9:0]<=0;
fifo_rdreq<=0;
end
else if(tft_GoBit == 1)
begin
case(cCounter)
0:
begin
oHSYNC<=0;
cCounter<=cCounter + 1;
end
TWHL - 1:
begin
oHSYNC<=1;
cCounter<=cCounter + 1;
end
THBP - 2:
begin
//generate the fifo read request signal,
//sets earlier for 1 clock than oDENA
fifo_rdreq<=lineENA & tft_GoBit;
cCounter<=cCounter + 1;
end
THBP - 1:
begin
oDENA<=lineENA & tft_GoBit;
//only when lineENA active then oDENA active
cCounter<=cCounter + 1;
end
THBP + COLUMNS - 2:
begin
//fifo read request signal ends earlier for 1 clock than oDENA
fifo_rdreq<=0;
cCounter<=cCounter + 1;
end
THBP + COLUMNS - 1:
begin
oDENA<=0;
cCounter<=cCounter + 1;
end
THBP + COLUMNS + THFP - 1:
begin
oHSYNC<=0;
cCounter<=0;
end
default:
cCounter<=cCounter + 1;
endcase
end
end
//vertical sync signal generator
always @(negedge oHSYNC)
begin
if(tft_reset_n == 0)
//reset active
begin
lineENA<=0;
oVSYNC<=0;
lCounter[9:0]<=0;
end
else if(tft_GoBit == 1)begin
case(lCounter)
0:
begin
oVSYNC<=0;
lCounter<=lCounter + 1;
end
TWVL - 1:
begin
oVSYNC<=1;
lCounter<=lCounter + 1;
end
TVBP - 1:
begin
lineENA<=1;
lCounter<=lCounter + 1;
end
TVBP + LINES - 1:
begin
lineENA<=0;
lCounter<=lCounter + 1;
end
TVBP + LINES + TVFP - 1:
begin
oVSYNC<=0;
lCounter<=0;
end
default:
lCounter<=lCounter + 1;
endcase
end
end
四、設計總結
本文設計實現了一個簡單的基於Avalon匯流排的TFT LCD控制器,能實現640×480,顏色深度為16bit的彩色圖形顯示,可應用於各種TFT LCD,亦可改寫為VGA控制器。在SOPC系統的使用中,有較大的靈活性。同時,通過本設計的實現過程,我也從中學到了不少知識,對SOPC,對Avalon匯流排等的理解更深了一步。
[admin via 研發互助社區 ] 基於Avalon匯流排的TFT LCD 控制器的設計已經有4868次圍觀
http://cocdig.com/docs/show-post-43086.html