当前位置:网站首页>Design of vga/lcd display controller based on FPGA (with code)
Design of vga/lcd display controller based on FPGA (with code)
2022-06-27 15:34:00 【FPGA technology Jianghu】
Hello, great Xia , Welcome to FPGA Technical Jianghu , The world is so big , Meeting is fate .
Today, I bring you FPGA Of VGA/LCD Display controller design , Because of the long space , It is divided into three parts . Today brings the third , The next part , Program simulation and testing and summary , Don't talk much , Loading .
The first two articles and previous tweets about VGA Show related articles , Here is a hyperlink , For your reference .
be based on FPGA Of VGA/LCD Display controller design ( On )
be based on FPGA Of VGA/LCD Display controller design ( in )
Source series : be based on FPGA Of VGA Drive design ( Source attached works )
Reading guide
VGA (Video Graphics Array) Video graphics array , yes IBM On 1987 Annual follow PS/2 machine (PersonalSystem 2) A video transmission standard using analog signals . This standard is very outdated for today's PC market . But at that time, it had high resolution 、 The display speed is fast 、 Rich colors, etc , It has been widely used in the field of color display , It is a low standard supported by many manufacturers .
LCD ( Liquid Crystal Display For short ) Liquid crystal display .LCD The structure is to place a liquid crystal cell between two parallel glass substrates , The lower base plate is arranged on the glass TFT( Thin film transistor ), A color filter is arranged on the upper substrate glass , adopt TFT The rotation direction of liquid crystal molecules is controlled by changing the signal and voltage on the liquid crystal , So as to control whether the polarized light of each pixel is emitted or not and achieve the purpose of display . According to the different backlights ,LCD Can be divided into CCFL A display and a LED There are two types of monitors .LCD Has replaced CRT The mainstream , Prices have also fallen a lot , And has been fully popularized .
In the previous article, I introduced how to get 、 Process the video signal provided by the camera , In practical application, the processed signals need to be displayed on the display . This process is opposite to that in signal processing , The composition of digital signals according to the system of TV signals conforms to the time sequence 、 Signal with required format , And add various synchronization signals for control . This article will pass FPGA Achieve one VGA/LCD Displays an instance of the controller , And the implementation process is introduced in detail .
Part three content summary : This chapter will introduce the simulation, testing and summary of the program .
Four 、 Program simulation and testing
In order to check whether the program realizes the preset function , Need to write simulation program . The main code of the simulation program is as follows :
module test; // register reg clk; reg rst; // Parameters parameter LINE_FIFO_AWIDTH = 7; //wire Affirming 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; // Test program variables 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; // Constant definition `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; // Test content initial begin $timeformat (-9, 1, " ns", 12); $display("\n\n"); $display("******************************************************"); $display("*VGA/LCD Controller Simulation started ... *"); $display("******************************************************"); $display("\n"); `ifdef WAVES $shm_open("waves"); $shm_probe("AS",test,"AS"); $display("INFO: Signal dump enabled ...\n\n"); `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 // Test area $display("\n\n"); $display("*****************************************************"); $display("*** XXX Test ***"); $display("*****************************************************\n"); s0.fill_mem(1); repeat(10) @(posedge clk); // Parameter setting 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); // Every line of data for(l=0;l<tvgate+1;l=l+1) // For each Pixel for(p=0;p<thgate+1;p=p+1) begin while(blanc) @(posedge pclk); if(bank[0]) vbase = vbarb[31:2]; else vbase = vbara[31:2]; if(bank[0]) cbase = 32'h0000_0c00; else cbase = 32'h0000_0800; // Various display modes // Number of pixels = Row number * (thgate + 1) + p pn = l * (thgate + 1) + p; case(mode) 0: // 24 Bit mode begin pra = pn[31:2] * 3; paa = pra + vbase; // Pixels determine the address // pixel data case(pn[1:0]) 0: begin tmp = s0.mem[paa]; pd = tmp[31:8]; end 1: begin tmp = s0.mem[paa]; pd[23:16] = tmp[7:0]; tmp = s0.mem[paa+1]; pd[15:0] = tmp[31:16]; end 2: begin tmp = s0.mem[paa+1]; pd[23:8] = tmp[15:0]; tmp = s0.mem[paa+2]; pd[7:0] = tmp[31:24]; end 3: begin tmp = s0.mem[paa+2]; pd = tmp[23:0]; end endcase end 1: // 8 Bit grayscale mode begin pra = pn[31:2]; // Pixel relative address paa = pra + vbase; // Pixel absolute address case(pn[1:0]) 0: begin tmp = s0.mem[paa]; pd = { tmp[31:24], tmp[31:24], tmp[31:24] }; end 1: begin tmp = s0.mem[paa]; pd = { tmp[23:16], tmp[23:16], tmp[23:16] }; end 2: begin tmp = s0.mem[paa]; pd = { tmp[15:8], tmp[15:8], tmp[15:8] }; end 3: begin tmp = s0.mem[paa]; pd = { tmp[7:0], tmp[7:0], tmp[7:0] }; end endcase end 2: // 8 Bit pseudo color mode begin pra = pn[31:2]; // Pixel relative address paa = pra + vbase; // Pixel absolute address case(pn[1:0]) 0: begin tmp = s0.mem[paa]; tmp = s0.mem[cbase[31:2] + tmp[31:24]]; pd = tmp[23:0]; end 1: begin tmp = s0.mem[paa]; tmp = s0.mem[cbase[31:2] + tmp[23:16]]; pd = tmp[23:0]; end 2: begin tmp = s0.mem[paa]; tmp = s0.mem[cbase[31:2] + tmp[15:8]]; pd = tmp[23:0]; end 3: begin tmp = s0.mem[paa]; tmp = s0.mem[cbase[31:2] + tmp[7:0]]; pd = tmp[23:0]; end endcase end 3: // 16 Bit mode begin pra = pn[31:1]; // Pixel relative address paa = pra + vbase; // Pixel absolute address case(pn[0]) 0: begin tmp = s0.mem[paa]; tmp[15:0] = tmp[31:16]; pd = {tmp[15:11], 3'h0, tmp[10:5], 2'h0, tmp[4:0], 3'h0}; end 1: begin tmp = s0.mem[paa]; pd = {tmp[15:11], 3'h0, tmp[10:5], 2'h0, tmp[4:0], 3'h0}; end endcase end endcase if(pd !== {red, green, blue} ) begin $display("ERROR: Pixel Data Mismatch: Expected: %h, Got: %h %h %h", pd, red, green, blue); $display(" pixel=%0d, line=%0d, (%0t)",p,l,$time); error_cnt = error_cnt + 1; end @(posedge pclk); end end show_errors; $display("*****************************************************"); $display("*** Test DONE ... ***"); $display("*****************************************************\n\n"); end repeat(10) @(posedge clk); $finish; end // Synchronous monitoring `ifdef VGA_12BIT_DVI sync_check #(PCLK_C*2) ucheck( `else sync_check #(PCLK_C) ucheck( `endif .pclk( pclk ), .rst( rst ), .enable( scen ), .hsync( hsync ), .vsync( vsync ), .csync( csync ), .blanc( blanc ), .hpol( hpol ), .vpol( vpol ), .cpol( cpol ), .bpol( bpol ), .thsync( thsync ), .thgdel( thgdel ), .thgate( thgate ), .thlen( thlen ), .tvsync( tvsync ), .tvgdel( tvgdel ), .tvgate( tvgate ), .tvlen( tvlen ) ); // Video data monitoring wb_b3_check u_wb_check ( .clk_i ( clk ), .cyc_i ( wb_cyc_o ), .stb_i ( wb_stb_o ), .cti_i ( wb_cti_o ), .bte_i ( wb_bte_o ), .we_i ( wb_we_o ), .ack_i ( wb_ack_i ), .err_i ( wb_err_i ), .rty_i ( 1'b0 ) ); // Watchdog counter always @(posedge clk) if(wb_cyc_i | wb_cyc_o | wb_ack_i | wb_ack_o | hsync) wd_cnt <= #1 0; else wd_cnt <= #1 wd_cnt + 1; always @(wd_cnt) if(wd_cnt>9000) begin $display("\n\n*************************************\n"); $display("ERROR: Watch Dog Counter Expired\n"); $display("*************************************\n\n\n"); $finish; end always @(posedge int) if(int_warn) begin $display("\n\n*************************************\n"); $display("WARNING: Recieved Interrupt (%0t)", $time); $display("*************************************\n\n\n"); end always #2.5 clk = ~clk; always #(PCLK_C/2) pclk_i = ~pclk_i; // Module prototype 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 ), // From the signal .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 ), // Main signal .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 The signal .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
This article introduces a VGA/LCD Displays an instance of the controller . First, it introduces VGA/LCD Show relevant knowledge , Then it introduces the main structure of the program and the implementation process of the main functional modules . Finally, a test program is used to verify whether the function of the program meets the requirements . This chapter designs your own VGA/LCD The display controller provides a usable solution .
This is the end of this article , Great Xia , I'll see you again ! END
It will be updated continuously in the future , bring Vivado、 ISE、Quartus II 、candence Installation related design tutorial , Learning resources 、 Project resources 、 Good article recommendation and so on , I hope great Xia will continue to pay attention to .
Heroes , The world is so big , Keep going , May everything be well , I'll see you again !
边栏推荐
- Keep valid digits; Keep n digits after the decimal point;
- Lei Jun lost another great general, and liweixing, the founding employee of Xiaomi No. 12, left his post. He once had porridge to create Xiaomi; Intel's $5.4 billion acquisition of tower semiconductor
- About tensorflow using GPU acceleration
- PSS: you are only two convolution layers away from the NMS free+ point | 2021 paper
- CentOS8-postgresql初始化时报错:initdb: error: invalid locale settings; check LANG and LC_* environment
- Atomic operation class
- Reflection learning summary
- Luogu_ P1003 [noip2011 improvement group] carpet laying_ Violence enumeration
- PR second training notes
- 原子操作类
猜你喜欢
Luogu_ P1003 [noip2011 improvement group] carpet laying_ Violence enumeration
Interview question: rendering 100000 data solutions
Atomic operation class
What is the London Silver unit
Why can't the start method be called repeatedly? But the run method can?
Strong, weak, soft and virtual references of ThreadLocal
洛谷入门2【分支结构】题单题解
Lei Jun lost another great general, and liweixing, the founding employee of Xiaomi No. 12, left his post. He once had porridge to create Xiaomi; Intel's $5.4 billion acquisition of tower semiconductor
PSS: you are only two convolution layers away from the NMS free+ point | 2021 paper
SQL parsing practice of Pisa proxy
随机推荐
Pisa-Proxy 之 SQL 解析实践
我想買固收+產品,但是不了解它主要投資哪些方面,有人知道嗎?
【kotlin】第二天
Beginner level Luogu 2 [branch structure] problem list solution
专用发票和普通发票的区别
February 16, 2022 freetsdb compilation and operation
Format of mobile number
直播app运营模式有哪几种,我们该选择什么样的模式?
June 27, 2022 Daily: swin transformer, Vit authors and others said: a good basic model is the simple pursuit of CV researchers
机械硬盘和ssd固态硬盘的原理对比分析
Longest substring without repeated characters (Sword finger offer 48)
SQL parsing practice of Pisa proxy
522. longest special sequence II / Sword finger offer II 101 Split equal sum subset
About tensorflow using GPU acceleration
What is the London Silver code
R language error
2022-2-16 learning the imitated Niuke project - Section 6 adding comments
優雅的自定義 ThreadPoolExecutor 線程池
Different perspectives
洛谷_P1007 独木桥_思维