大俠好,歡迎來(lái)到FPGA技術(shù)江湖,江湖偌大,相見即是緣分。大俠可以關(guān)注FPGA技術(shù)江湖,在“闖蕩江湖”、"行俠仗義"欄里獲取其他感興趣的資源,或者一起煮酒言歡。
今天給大俠帶來(lái)基于FPGA的VGA/LCD顯示控制器設(shè)計(jì),由于篇幅較長(zhǎng),分三篇。今天帶來(lái)第三篇,下篇,程序的仿真與測(cè)試以及總結(jié),話不多說(shuō),上貨。
前兩篇和之前推送過(guò)關(guān)于VGA顯示相關(guān)的文章,這里給個(gè)超鏈接,給各位大俠作個(gè)參考。
基于FPGA的VGA/LCD顯示控制器設(shè)計(jì)(上)
基于FPGA的VGA/LCD顯示控制器設(shè)計(jì)(中)
源碼系列:基于FPGA的VGA驅(qū)動(dòng)設(shè)計(jì)(附源工程)
導(dǎo)讀
VGA (Video Graphics Array) 即視頻圖形陣列,是IBM于1987年隨PS/2機(jī)(PersonalSystem 2)一起推出的使用模擬信號(hào)的一種視頻傳輸標(biāo)準(zhǔn)。這個(gè)標(biāo)準(zhǔn)對(duì)于現(xiàn)今的個(gè)人電腦市場(chǎng)已經(jīng)十分過(guò)時(shí)。但在當(dāng)時(shí)具有分辨率高、顯示速率快、顏色豐富等優(yōu)點(diǎn),在彩色顯示器領(lǐng)域取得了廣泛的應(yīng)用,是眾多制造商所共同支持的一個(gè)低標(biāo)準(zhǔn)。
LCD ( Liquid Crystal Display 的簡(jiǎn)稱)液晶顯示器。LCD 的構(gòu)造是在兩片平行的玻璃基板當(dāng)中放置液晶盒,下基板玻璃上設(shè)置TFT(薄膜晶體管),上基板玻璃上設(shè)置彩色濾光片,通過(guò)TFT上的信號(hào)與電壓改變來(lái)控制液晶分子的轉(zhuǎn)動(dòng)方向,從而達(dá)到控制每個(gè)像素點(diǎn)偏振光出射與否而達(dá)到顯示目的。按照背光源的不同,LCD可以分為CCFL顯示器和LED顯示器兩種。LCD已經(jīng)替代CRT成為主流,價(jià)格也已經(jīng)下降了很多,并已充分普及。
在之前的文章中介紹了如何獲取、處理攝像頭提供的視頻信號(hào),在實(shí)際應(yīng)用中還需要將經(jīng)過(guò)處理的信號(hào)顯示在顯示器上。這個(gè)過(guò)程與信號(hào)處理中的過(guò)程上是相反的,將數(shù)字信號(hào)按照電視信號(hào)的制式組成合乎時(shí)序、格式要求的信號(hào),并加入用于控制的各種同步信號(hào)。本篇將通過(guò) FPGA實(shí)現(xiàn)一個(gè) VGA/LCD 顯示控制器的實(shí)例,并詳細(xì)介紹實(shí)現(xiàn)過(guò)程。
第三篇內(nèi)容摘要:本篇會(huì)介紹程序的仿真與測(cè)試以及總結(jié)等相關(guān)內(nèi)容。
四、程序的仿真與測(cè)試
為了檢驗(yàn)程序是否實(shí)現(xiàn)預(yù)先設(shè)定的功能,需要編寫仿真程序。仿真程序的主要代碼如下:
module test; //寄存器 reg clk; reg rst; //參數(shù) parameter LINE_FIFO_AWIDTH = 7; //wire 申明 wire int; wire [31:0] wb_addr_o; wire [31:0] wb_data_i; wire [31:0] wb_data_o; wire [3:0] wb_sel_o; wire wb_we_o; wire wb_stb_o; wire wb_cyc_o; wire [2:0] wb_cti_o; wire [1:0] wb_bte_o; wire wb_ack_i; wire wb_err_i; wire [31:0] wb_addr_i; wire [31:0] wbm_data_i; wire [3:0] wb_sel_i; wire wb_we_i; wire wb_stb_i; wire wb_cyc_i; wire wb_ack_o; wire wb_rty_o; wire wb_err_o; reg pclk_i; wire pclk; wire hsync; wire vsync; wire csync; wire blanc; wire [7:0] red; wire [7:0] green; wire [7:0] blue; wire dvi_pclk_p_o; wire dvi_pclk_m_o; wire dvi_hsync_o; wire dvi_vsync_o; wire dvi_de_o; wire [11:0] dvi_d_o; wire vga_stb_i; wire clut_stb_i; reg scen; // 測(cè)試程序變量 integer wd_cnt; integer error_cnt; reg [31:0] data; reg [31:0] pattern; reg int_warn; integer n; integer mode; reg [7:0] thsync, thgdel; reg [15:0] thgate, thlen; reg [7:0] tvsync, tvgdel; reg [15:0] tvgate, tvlen; reg hpol; reg vpol; reg cpol; reg bpol; integer p, l; reg [31:0] pn; reg [31:0] pra, paa, tmp; reg [23:0] pd; reg [1:0] cd; reg pc; reg [31:0] vbase; reg [31:0] cbase; reg [31:0] vbara; reg [31:0] vbarb; reg [7:0] bank; // 常量定義 `define CTRL 32'h0000_0000 `define STAT 32'h0000_0004 `define HTIM 32'h0000_0008 `define VTIM 32'h0000_000c `define HVLEN 32'h0000_0010 `define VBARA 32'h0000_0014 `define VBARB 32'h0000_0018 `define USE_VC 1 parameter PCLK_C = 20; //測(cè)試內(nèi)容 initial begin $timeformat (-9, 1, " ns", 12); $display(" "); $display("******************************************************"); $display("*VGA/LCD Controller Simulation started ... *"); $display("******************************************************"); $display(" "); `ifdef WAVES $shm_open("waves"); $shm_probe("AS",test,"AS"); $display("INFO: Signal dump enabled ... "); `endif scen = 0; error_cnt = 0; clk = 0; pclk_i = 0; rst = 0; int_warn=1; repeat(20) @(posedge clk); rst = 1; repeat(20) @(posedge clk); if(0) begin end else if(1) begin `ifdef VGA_12BIT_DVI dvi_pd_test; `endif end else begin // 測(cè)試區(qū)域 $display(" "); $display("*****************************************************"); $display("*** XXX Test ***"); $display("***************************************************** "); s0.fill_mem(1); repeat(10) @(posedge clk); //參數(shù)設(shè)置 vbara = 32'h0000_0000; vbarb = 32'h0001_0000; m0.wb_wr1( `VBARA, 4'hf, vbara ); m0.wb_wr1( `VBARB, 4'hf, vbarb ); thsync = 0; thgdel = 0; thgate = 340; thlen = 345; tvsync = 0; tvgdel = 0; tvgate = 240; tvlen = 245; /* thsync = 0; thgdel = 0; thgate = 63; thlen = 70; tvsync = 0; tvgdel = 0; tvgate = 32; tvlen = 36; */ hpol = 0; vpol = 0; cpol = 0; bpol = 0; m0.wb_wr1( `HTIM, 4'hf, {thsync, thgdel, thgate} ); m0.wb_wr1( `VTIM, 4'hf, {tvsync, tvgdel, tvgate} ); m0.wb_wr1( `HVLEN, 4'hf, {thlen, tvlen} ); mode = 2; for(bank=0;bank<3;bank=bank + 1) begin case(mode) 0: begin cd = 2'h2; pc = 1'b0; end 1: begin cd = 2'h0; pc = 1'b0; end 2: begin cd = 2'h0; pc = 1'b1; end 3: begin cd = 2'h1; pc = 1'b0; end endcase m0.wb_wr1( `CTRL, 4'hf, { 16'h0, // Reserved bpol, cpol, vpol, hpol, pc, // 1'b0, // PC cd, // 2'h2, // CD 2'h0, // VBL 1'b0, // Reserved 1'b1, // CBSWE 1'b1, // VBSWE 1'b0, // BSIE 1'b0, // HIE 1'b0, // VIE 1'b1 // Video Enable }); $display("Mode: %0d Screen: %0d", mode, bank); //repeat(2) @(posedge vsync); @(posedge vsync); // 每一行數(shù)據(jù) for(l=0;l9000) begin $display(" ************************************* "); $display("ERROR: Watch Dog Counter Expired "); $display("************************************* "); $finish; end always @(posedge int) if(int_warn) begin $display(" ************************************* "); $display("WARNING: Recieved Interrupt (%0t)", $time); $display("************************************* "); end always #2.5 clk = ~clk; always #(PCLK_C/2) pclk_i = ~pclk_i; //模塊原型 vga_enh_top #(1'b0, LINE_FIFO_AWIDTH) u0 ( .wb_clk_i ( clk ), .wb_rst_i ( 1'b0 ), .rst_i ( rst ), .wb_inta_o ( int ), //從信號(hào) .wbs_adr_i ( wb_addr_i[11:0] ), .wbs_dat_i ( wb_data_i ), .wbs_dat_o ( wb_data_o ), .wbs_sel_i ( wb_sel_i ), .wbs_we_i ( wb_we_i ), .wbs_stb_i ( wb_stb_i ), .wbs_cyc_i ( wb_cyc_i ), .wbs_ack_o ( wb_ack_o ), .wbs_rty_o ( wb_rty_o ), .wbs_err_o ( wb_err_o ), //主信號(hào) .wbm_adr_o ( wb_addr_o[31:0] ), .wbm_dat_i ( wbm_data_i ), .wbm_sel_o ( wb_sel_o ), .wbm_we_o ( wb_we_o ), .wbm_stb_o ( wb_stb_o ), .wbm_cyc_o ( wb_cyc_o ), .wbm_cti_o ( wb_cti_o ), .wbm_bte_o ( wb_bte_o ), .wbm_ack_i ( wb_ack_i ), .wbm_err_i ( wb_err_i ), //VGA 信號(hào) .clk_p_i ( pclk_i ), `ifdef VGA_12BIT_DVI .dvi_pclk_p_o ( dvi_pclk_p_o ), .dvi_pclk_m_o ( dvi_pclk_m_o ), .dvi_hsync_o ( dvi_hsync_o ), .dvi_vsync_o ( dvi_vsync_o ), .dvi_de_o ( dvi_de_o ), .dvi_d_o ( dvi_d_o ), `endif .clk_p_o ( pclk ), .hsync_pad_o ( hsync ), .vsync_pad_o ( vsync ), .csync_pad_o ( csync ), .blank_pad_o ( blanc ), .r_pad_o ( red ), .g_pad_o ( green ), .b_pad_o ( blue ) ); wb_mast m0( .clk( clk ), .rst( rst ), .adr( wb_addr_i ), .din( wb_data_o ), .dout( wb_data_i ), .cyc( wb_cyc_i ), .stb( wb_stb_i ), .sel( wb_sel_i ), .we( wb_we_i ), .ack( wb_ack_o ), .err( wb_err_o ), .rty( 1'b0 ) ); wb_slv #(24) s0(.clk( clk ), .rst( rst ), .adr( {1'b0, wb_addr_o[30:0]} ), .din( 32'h0 ), .dout( wbm_data_i ), .cyc( wb_cyc_o ), .stb( wb_stb_o ), .sel( wb_sel_o ), .we( wb_we_o ), .ack( wb_ack_i ), .err( wb_err_i ), .rty( ) ); `include "tests.v" endmodule
五、總結(jié)
本篇介紹了一個(gè) VGA/LCD 顯示控制器的實(shí)例。首先介紹了 VGA/LCD 顯示的相關(guān)知識(shí),然后介紹了程序的主要結(jié)構(gòu)和主要功能模塊的實(shí)現(xiàn)過(guò)程。最后用一個(gè)測(cè)試程序驗(yàn)證程序的功能是否滿足要求。本章為各位大俠設(shè)計(jì)自己的 VGA/LCD 顯示控制器提供了一個(gè)可以使用的方案。
本篇到此結(jié)束,各位大俠,有緣再見!
審核編輯:湯梓紅
-
FPGA
+關(guān)注
關(guān)注
1625文章
21620瀏覽量
601231 -
lcd
+關(guān)注
關(guān)注
34文章
4405瀏覽量
166930 -
顯示控制器
+關(guān)注
關(guān)注
0文章
23瀏覽量
15454
原文標(biāo)題:基于FPGA的VGA/LCD顯示控制器設(shè)計(jì)(附代碼)
文章出處:【微信號(hào):HXSLH1010101010,微信公眾號(hào):FPGA技術(shù)江湖】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論