Today, we bring you the design of a VGA/LCD display controller based on FPGA. Due to the length, it is divided into three parts. Today we present the third part, which includes simulation and testing of the program and a summary. Without further ado, let’s get started.
The first two articles and previous articles related to VGA display are referenced here, providing hyperlinks for your reference.
Design of VGA/LCD Display Controller Based on FPGA (Part 1)
Design of VGA/LCD Display Controller Based on FPGA (Part 2)
Source Code Series: VGA Driver Design Based on FPGA (With Source Project)
Introduction
VGA (Video Graphics Array) is a video transmission standard using analog signals launched by IBM in 1987 with the PS/2 (Personal System 2). This standard is now outdated in today’s personal computer market. However, at that time, it had advantages such as high resolution, fast display rate, and rich colors, achieving widespread application in the field of color displays and supported by many manufacturers as a low standard.
LCD (Liquid Crystal Display) is a type of display technology. The construction of an LCD involves placing a liquid crystal box between two parallel glass substrates. The lower substrate has a TFT (Thin Film Transistor), and the upper substrate has a color filter. The direction of rotation of the liquid crystal molecules is controlled by signals and voltages on the TFT, allowing control over whether polarized light is emitted from each pixel. Depending on the backlight source, LCDs can be divided into CCFL displays and LED displays. LCDs have replaced CRTs as the mainstream technology, with prices significantly reduced and widespread adoption.
In previous articles, we introduced how to acquire and process video signals provided by a camera. In practical applications, the processed signals need to be displayed on a monitor. This process is the opposite of the signal processing, where digital signals are composed according to the timing and format requirements of television signals, along with various synchronization signals for control. This article will implement a VGA/LCD display controller instance using FPGA and detail the implementation process.
Summary of the third part: This part will introduce simulation and testing of the program, as well as a summary.
4. Program Simulation and Testing
To verify whether the program achieves the pre-set functions, a simulation program needs to be written. The main code of the simulation program is as follows:
module test; // Registers reg clk; reg rst; // Parameters parameter LINE_FIFO_AWIDTH = 7; // Wire declarations 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 definitions `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 region $display("\n\n"); $display("*****************************************************"); $display("*** XXX Test ***"); $display("*****************************************************\n"); s0.fill_mem(1); repeat(10) @(posedge clk); // Parameter settings 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); // Each row of data for(l=0;l9000) 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: Received 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 ), // Slave signals .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 ), // Master signals .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 signals .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
5. Summary
This article introduced an instance of a VGA/LCD display controller. It first introduced related knowledge about VGA/LCD display, then detailed the main structure of the program and the implementation of the main functional modules. Finally, a test program was used to verify whether the program’s functions meet the requirements. This chapter provides a usable solution for you to design your own VGA/LCD display controller.
This article ends here. See you next time!
Selected Past Articles
[Free] FPGA Engineer Recruitment Platform
FPGA talent recruitment, enterprises HR, look here!
Selected System Design | Real-time Image Edge Detection System Design Based on FPGA (With Code)
Gigabit Ethernet RGMII Interface Design Based on Primitives
Timing Analysis Theory and TimeQuest Usage _ Chinese Electronic Version
Job Interview | Latest Summary of FPGA or IC Interview Questions
FPGA Image Processing Special Course Adds Vivado Content, Registration Available Online and Offline
FPGA Timing Analysis and Constraints Special Course Adds Vivado Content, Registration Available Online and Offline
Data Summary | FPGA Software Installation Packages, Books, Source Code, Technical Documents… (Updated 2023.07.09)
FPGA Employment Class, Starting December 18, 2023, More Content at No Extra Cost, Systematic Learning of FPGA for High-paying Jobs, Online and Offline Simultaneously!
FPGA Technology Community Broadly Inviting Community Posts
No Ads, Pure Mode, Providing a Clean Space for Technical Exchange, from beginners to industry elites, from military to civilian enterprises, covering fields from communication, image processing to artificial intelligence, QQ WeChat dual selection, FPGA technology community builds the purest and most professional technical exchange and learning platform.
FPGA Technology Community WeChat Group
Add the group owner’s WeChat, note your name + school/company + major/position to join the group
FPGA Technology Community QQ Group
Note your name+school/company+major/position to join the group
Leave a Comment
Your email address will not be published. Required fields are marked *