当前位置:网站首页>VGA display of color bar, character and picture based on FPGA

VGA display of color bar, character and picture based on FPGA

2022-06-09 03:41:00 Intoxication, thousand layer dream

One 、VGA

What is? VGA?VGA It's not the screen used for display , It's an interface for transmitting signals .VGA The full name is Video Graphics Array, Video graphics array , It is a video transmission standard for analog signals .

Two 、 Sequence diagram

 Insert picture description here

3、 ... and 、 Realization

Parameters corresponding to different resolutions
 Insert picture description here

0. The clock frequency division

Separate use 640×480 60HZ and 800×600 72HZ, The corresponding clocks are 25M and 50M, Need to use PLL Frequency division clock frequency = Line frame length × Column frame length * The refresh rate ,640 ×480 60HZ Corresponding clock frequency = 800 ×525 × 60 = 25.2M
ip Found in the nucleus ALTPLL
 Insert picture description here
Basic clock selection 50M
 Insert picture description here
Uncheck output enable
 Insert picture description here
c0 Default output 50M that will do ,c1 Frequency division to 25M, If you need other clock frequencies, you can set them yourself
 Insert picture description here
Check the following options finish Insert picture description here

1. Color bar display

Judge the color to be displayed according to the address of the current line .

2. Character display

Input the characters to be displayed in the sub module extraction tool and set the character size to 64*64
 Insert picture description here
Then click file - Save as , Save picture as BMP picture
 Insert picture description here
And then click file - open , Put the preserved BMP Open the picture to get the whole character
 Insert picture description here
Then click the option to set the following parameters
 Insert picture description here

Finally, click generate character and save the character as a text file
 Insert picture description here
The resulting characters are as follows
 Insert picture description here
Put the obtained characters in verilog It can be used inside
 Insert picture description here

3. Picture shows

Because of one 640×480 Of 24 The size of the bit image exceeds the memory of the chip , Unable to save the picture , Therefore, one sheet is used 128*78 The picture of .
Original picture :
 Insert picture description here

Use the tool to turn the picture into HEX file
 Insert picture description here
The conversion is completed and data1.hex, Content as shown
 Insert picture description here
Too much picture data needs to be used ROM To store data
open quartus, find ROM
 Insert picture description here
Set the bit width to 16 position , The size is the size of the picture 128×78 = 9984
 Insert picture description here
Uncheck the following options
 Insert picture description here
Find the data1.hex file
 Insert picture description here
Check the following options and directly finsh that will do
 Insert picture description here
For data reading and use, refer to the following code section

Four 、 Code

be based on EP4CEF17C8 Model chip

1.vga Driver module

module vga_dirve (input			wire						clk,            // The system clock 
                  input			wire						rst_n,          // Reset 
                  input			wire		[ 15:0 ]		rgb_data,       //16 position RGB Corresponding value 
                  output			wire							vga_clk,    //vga The clock  25M
                  output			reg							h_sync,     // Line sync 
                  output			reg							v_sync,     // Field synchronization signal 
                  output			reg		[ 11:0 ]				addr_h, // Line address 
                  output			reg		[ 11:0 ]				addr_v,  // Column address 
                  output			wire		[ 4:0 ]				rgb_r,  // Red base color 
                  output			wire		[ 5:0 ]				rgb_g,  // Green base color 
                  output			wire		[ 4:0 ]				rgb_b  // Blue base color 
);

// 640 * 480 60HZ
localparam	 H_FRONT = 16; //  The leading edge signal period of line synchronization is long 
localparam	 H_SYNC  = 96; //  The period of line synchronization signal is long 
localparam	 H_BLACK = 48; //  The signal period of the trailing edge of line synchronization is long 
localparam	 H_ACT   = 640; //  The line display cycle is long 
localparam	 V_FRONT = 11; //  The signal period at the front of field synchronization is long 
localparam	 V_SYNC  = 2; //  The period of field synchronization signal is long 
localparam	 V_BLACK = 31; //  The signal period at the trailing edge of field synchronization is long 
localparam	 V_ACT   = 480; //  Long field display period 

// 800 * 600 72HZ
// localparam H_FRONT = 40; //  The leading edge signal period of line synchronization is long 
// localparam H_SYNC = 120; //  The period of line synchronization signal is long 
// localparam H_BLACK = 88; //  The signal period of the trailing edge of line synchronization is long 
// localparam H_ACT = 800; //  The line display cycle is long 
// localparam V_FRONT = 37; //  The signal period at the front of field synchronization is long 
// localparam V_SYNC = 6; //  The period of field synchronization signal is long 
// localparam V_BLACK = 23; //  The signal period at the trailing edge of field synchronization is long 
// localparam V_ACT = 600; //  Long field display period 


localparam	H_TOTAL = H_FRONT + H_SYNC + H_BLACK + H_ACT; //  Line period 
localparam	V_TOTAL = V_FRONT + V_SYNC + V_BLACK + V_ACT; //  Column period 

reg			[ 11:0 ]			cnt_h			; //  Row counter 
reg			[ 11:0 ]			cnt_v			; //  Field counter 
reg			[ 15:0 ]			rgb			; //  Corresponding display color value 

//  The corresponding counter starts 、 end 、 Counting signal 
wire							flag_enable_cnt_h			;
wire							flag_clear_cnt_h			;
wire							flag_enable_cnt_v			;
wire							flag_clear_cnt_v			;
wire							flag_add_cnt_v  			;
wire							valid_area      			;


// 25M The clock   Line period * Field period * The refresh rate  = 800 * 525* 60
wire							clk_25			;
// 50M The clock  1040 * 666 * 72
wire							clk_50			;
//PLL
pll	pll_inst (
	.areset ( ~rst_n ),
	.inclk0 ( clk ),
	.c0 ( clk_50 ), //50M
	.c1 ( clk_25 ), //25M
	);
// Select different frequency clocks according to different allocation rates 
assign vga_clk = clk_25;


//  Line count 
always @( posedge vga_clk or negedge rst_n ) begin
    if ( !rst_n ) begin
        cnt_h <= 0;
    end
    else if ( flag_enable_cnt_h ) begin
        if ( flag_clear_cnt_h ) begin
            cnt_h <= 0;
        end
        else begin
            cnt_h <= cnt_h + 1;
        end
    end
    else begin
        cnt_h <= 0;
    end
end
assign flag_enable_cnt_h = 1;
assign flag_clear_cnt_h  = cnt_h == H_TOTAL - 1;

//  Line sync 
always @( posedge vga_clk or negedge rst_n ) begin
    if ( !rst_n ) begin
        h_sync <= 0;
    end
    else if ( cnt_h == H_SYNC - 1 ) begin //  The synchronization period is 1
        h_sync <= 1;
    end
        else if ( flag_clear_cnt_h ) begin //  Others are 0
        h_sync <= 0;
        end
    else begin
        h_sync <= h_sync;
    end
end

//  Field count 
always @( posedge vga_clk or negedge rst_n ) begin
    if ( !rst_n ) begin
        cnt_v <= 0;
    end
    else if ( flag_enable_cnt_v ) begin
        if ( flag_clear_cnt_v ) begin
            cnt_v <= 0;
        end
        else if ( flag_add_cnt_v ) begin
            cnt_v <= cnt_v + 1;
        end
        else begin
            cnt_v <= cnt_v;
        end
    end
    else begin
        cnt_v <= 0;
    end
end
assign flag_enable_cnt_v = flag_enable_cnt_h;
assign flag_clear_cnt_v  = cnt_v == V_TOTAL - 1;
assign flag_add_cnt_v    = flag_clear_cnt_h;

//  Field synchronization signal 
always @( posedge vga_clk or negedge rst_n ) begin
    if ( !rst_n ) begin
        v_sync <= 0;
    end
    else if ( cnt_v == V_SYNC - 1 ) begin
        v_sync <= 1;
    end
        else if ( flag_clear_cnt_v ) begin
        v_sync <= 0;
        end
    else begin
        v_sync <= v_sync;
    end
end

//  Corresponding to the effective area row address  1-640
always @( posedge vga_clk or negedge rst_n ) begin
    if ( !rst_n ) begin
        addr_h <= 0;
    end
    else if ( valid_area ) begin
        addr_h <= cnt_h - H_SYNC - H_BLACK + 1;
    end
    else begin
        addr_h <= 0;
    end
end
//  Corresponding valid area column address  1-480
always @( posedge vga_clk or negedge rst_n ) begin
    if ( !rst_n ) begin
        addr_v <= 0;
    end
    else if ( valid_area ) begin
        addr_v <= cnt_v -V_SYNC - V_BLACK + 1;
    end
    else begin
        addr_v <= 0;
    end
end
//  Effective display area 
assign valid_area = cnt_h >= H_SYNC + H_BLACK && cnt_h <= H_SYNC + H_BLACK + H_ACT && cnt_v >= V_SYNC + V_BLACK && cnt_v <= V_SYNC + V_BLACK + V_ACT;


//  Display color 
always @( posedge vga_clk or negedge rst_n ) begin
    if ( !rst_n ) begin
        rgb <= 16'h0;
    end
    else if ( valid_area ) begin
        rgb <= rgb_data;
    end
    else begin
        rgb <= 16'b0;
    end
end
assign rgb_r = rgb[ 15:11 ];
assign rgb_g = rgb[ 10:5 ];
assign rgb_b = rgb[ 4:0 ];

endmodule // vga_dirve

2. Display data generation module

module data_drive (input			wire						vga_clk,
                   input			wire						rst_n,
                   input			wire		[ 11:0 ]		addr_h,
                   input			wire		[ 11:0 ]		addr_v,
                   input			wire		[ 2:0 ]		 key,
                   output			reg		[ 15:0 ]				rgb_data);

localparam	red    = 16'd63488;
localparam	orange = 16'd64384;
localparam	yellow = 16'd65472;
localparam	green  = 16'd1024;
localparam	blue   = 16'd31;
localparam	indigo = 16'd18448;
localparam	purple = 16'd32784;
localparam	white  = 16'd65503;
localparam	black  = 16'd0;
reg [ 383:0 ] char_line[ 64:0 ];

localparam	states_1 = 1; //  Color bar 
localparam	states_2 = 2; //  character 
localparam	states_3 = 3; //  picture 

parameter	height = 78; //  Picture height 
parameter	width  = 128; //  Image width 
reg			[ 1:0 ]			states_current			; //  current state 
reg			[ 1:0 ]			states_next			    ; //  Next state 
reg			[ 13:0 ]		rom_address				; // ROM Address 
wire			[ 15:0 ]		rom_data				; //  Picture data 

wire							flag_enable_out1			; //  Text valid area 
wire							flag_enable_out2			; //  Picture effective area 
wire							flag_clear_rom_address		; //  The address is cleared 
wire							flag_begin_h			    ; //  The picture shows the line 
wire							flag_begin_v			    ; //  Picture display column 

// State shift 
always @( posedge vga_clk or negedge rst_n ) begin
    if ( !rst_n ) begin
        states_current <= states_1;
    end
    else begin
        states_current <= states_next;
    end
end

// State judgement 
always @( posedge vga_clk or negedge rst_n ) begin
    if ( !rst_n ) begin
        states_next <= states_1;
    end
    else if ( key[ 0 ] ) begin
        states_next <= states_1;
    end
        else if ( key[ 1 ] ) begin
        states_next <= states_2;
        end
        else if ( key[ 2 ] ) begin
        states_next <= states_3;
        end
    else begin
        states_next <= states_next;
    end
end

// State output 
always @( * ) begin
    case ( states_current )
        states_1 : begin
            if ( addr_h == 0 ) begin
                rgb_data = black;
            end
            else if ( addr_h >0 && addr_h <81 ) begin
                rgb_data = red;
            end
            else if ( addr_h >80 && addr_h <161 ) begin
                rgb_data = orange;
            end
            else if ( addr_h >160 && addr_h <241 ) begin
                rgb_data = yellow;
            end
            else if ( addr_h >240 && addr_h <321 ) begin
                rgb_data = green;
            end
            else if ( addr_h >320 && addr_h <401 ) begin
                rgb_data = blue;
            end
            else if ( addr_h >400 && addr_h <481 ) begin
                rgb_data = indigo;
            end
            else if ( addr_h >480 && addr_h <561 ) begin
                rgb_data = purple;
            end
            else if ( addr_h >560 && addr_h <641 ) begin
                rgb_data = white;
            end
            else begin
                rgb_data = black;
            end
            
        end
        states_2 : begin
            if ( flag_enable_out1 ) begin
                rgb_data = char_line[ addr_v-208 ][ 532 - addr_h ]? white:black;
            end
            else begin
                rgb_data = black;
            end
        end
        states_3 : begin
            if ( flag_enable_out2 ) begin
                rgb_data = rom_data;
            end
            else begin
                rgb_data = black;
            end
            
        end
        default: begin
            case ( addr_h )
                0 : rgb_data      = black;
                1 : rgb_data      = red;
                81 : rgb_data     = orange;
                161: rgb_data     = yellow;
                241: rgb_data     = green;
                321: rgb_data     = blue;
                401: rgb_data     = indigo;
                481: rgb_data     = purple;
                561: rgb_data     = white;
                default: rgb_data = rgb_data;
            endcase
        end
    endcase
end

assign flag_enable_out1 = states_current == states_2 && addr_h > 148 && addr_h < 533 && addr_v > 208  && addr_v < 273 ;
assign flag_begin_h     = addr_h > ( ( 640 - width ) / 2 ) && addr_h < ( ( 640 - width ) / 2 ) + width + 1;
assign flag_begin_v     = addr_v > ( ( 480 - height )/2 ) && addr_v <( ( 480 - height )/2 ) + height + 1;
assign flag_enable_out2 = states_current == states_3 && flag_begin_h && flag_begin_v;

//ROM Address counter 
always @( posedge vga_clk or negedge rst_n ) begin
    if ( !rst_n ) begin
        rom_address <= 0;
    end
    else if ( flag_clear_rom_address ) begin // When the count is full, it is cleared 
        rom_address <= 0;
    end
        else if ( flag_enable_out2 ) begin  // Within the effective area +1
        rom_address <= rom_address + 1;
        end
    else begin  // Invalid region hold 
        rom_address <= rom_address;
    end
end
assign flag_clear_rom_address = rom_address == height * width - 1;

// Initialize display text 
[email protected]( posedge vga_clk or negedge rst_n ) begin
    if ( !rst_n ) begin
        char_line[ 0 ]  = 384'h000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000;
        char_line[ 1 ]  = 384'h000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000;
        char_line[ 2 ]  = 384'h000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000;
        char_line[ 3 ]  = 384'h000000000000000000000008000000000000000000000000000000000000000000000000000000000000200000800000;
        char_line[ 4 ]  = 384'h0000000001E000000000000E000000000000000000000000000000000002000000000000000000000000380000E00000;
        char_line[ 5 ]  = 384'h0000003000F800000000000780000000000000000000000000000000000F0000001000000000080000003E0000F80000;
        char_line[ 6 ]  = 384'h00000070007C000000000003C0000000000000000000000000000000007F8000000C000000001C0000003E0000FC0000;
        char_line[ 7 ]  = 384'h000000F8007E000000000003C000000000000000000000000000000003FFC000000FFFFFFFFFFE0000003C0000F00000;
        char_line[ 8 ]  = 384'h3FFFFFFC003E000000000003C00300000000000000000000000000003FFFE000000FFFFFFFFFFF0000003C0000F00000;
        char_line[ 9 ]  = 384'h3FFFFFFE003E000000000001C0078000000000000000000000000007FFFF8000000F000000003E0000003C0000F00000;
        char_line[ 10 ] = 384'h1F3E7C00003E0180001FFFFFFFFFC0000000000000000000000000FFFF800000000F000000003C0000003C0000F00000;
        char_line[ 11 ] = 384'h003E7C00001E03C0000FFFFFFFFFE000000000000000000000003FFFC0000000000F000000003C0000003C0000F00000;
        char_line[ 12 ] = 384'h003E7C00001C07E000000600010000000000000000000000001FFFC3C0000000000F000000003C0000003C3000F00600;
        char_line[ 13 ] = 384'h003E7C07FFFFFFF00000038003C00000000000000000000000300003C0000000000F000000003C0000003C7800F00F00;
        char_line[ 14 ] = 384'h003E7C07FFFFFFF8000001C003E00000000000000000000000000003C0000000000F000000003C0007FFFFFDFFFFFF80;
        char_line[ 15 ] = 384'h003E7C03EC006000000001E003C00000000000000000000000000003C0000000000F000000003C0003FFFFFEFFFFFFC0;
        char_line[ 16 ] = 384'h003E7C000F007800000000E007800000000000000000000000000003C0000000000F000000003C0001803C0001F80000;
        char_line[ 17 ] = 384'h003E7C601FC07E00000000E007000000000000000000000000000003C0000000000FFFFFFFFFFC0000007C0001FC0000;
        char_line[ 18 ] = 384'h0F3E7CF01F807E00000000E00E000200000000000000000000000003C0000000000FFFFFFFFFFC0000007C0003F40000;
        char_line[ 19 ] = 384'h0FFFFFF81F00FC00000000E00C000700000000000000000000000003C0000000000E000000003C000000FF8003F60000;
        char_line[ 20 ] = 384'h0FFFFFF81F00F8000000000018000F80000002000000000000000003C0000000000E000000003E000000FDF007F30000;
        char_line[ 21 ] = 384'h0FBE7DF03E00F8000FFFFFFFFFFFFFC0000001800000000000000003C0000000000E0000000030000001FCF80FF38000;
        char_line[ 22 ] = 384'h0FBE7DF03E01F00007FFFFFFFFFFFFE0000000C00000000000000003C0000000000E0000000000000003FC7C0EF1C000;
        char_line[ 23 ] = 384'h0FBE7DF03E01F8000300000000000000000000700000000000000003C0000000000E0000000000000003FC7C1EF1E000;
        char_line[ 24 ] = 384'h0FBE7DF07F83FC0000000000000000000000007C0000000000000003C0000000000E0000000000000007BC3C3CF0F000;
        char_line[ 25 ] = 384'h0FBE7DF07BE3FF0000000000000000000000003E0000000000000003C0000180000E000000000000000F3C1838F07C00;
        char_line[ 26 ] = 384'h0FBE7DF07BF7CFC000030000000700000000001F8000000000000003C00003C0000E000000003000001E3C1870F03F00;
        char_line[ 27 ] = 384'h0FBE7DF0F1F787E00003FFFFFFFF80000000000FC000000000000003C00007E0000E000000007800001C3C00E0F03FC0;
        char_line[ 28 ] = 384'h0FBE7DF0F1FF83E00003FFFFFFFFC00000000007F00000003FFFFFFFFFFFFFF0000E07FFFFFFFC0000383C01C0F01FF8;
        char_line[ 29 ] = 384'h0FBC7DF1E0FF03F00003C0000007000000000003F80000001FFFFFFFFFFFFFF8000E03FFFFFFFE0000703C0300F007E0;
        char_line[ 30 ] = 384'h0FBC7DF1E0FE01F00003C0000007000000000001FC0000000C000003C0000000000E01000000000000E03C0600F00300;
        char_line[ 31 ] = 384'h0FBC7DF3C07C01F00003C0000007000000000000FE00000000000003C0000000001E00000000000001803C2800F00100;
        char_line[ 32 ] = 384'h0FBC7DF3807800E00003C0000007000000000000FE00000000000003C0000000001E00000000000007003C3000F00000;
        char_line[ 33 ] = 384'h0FBC7DF7007000C00003FFFFFFFF0000000000007F00000000000003C0000000001E0000000000000C003C7800F00000;
        char_line[ 34 ] = 384'h0FF87DF700FC00000003FFFFFFFF0000000000003F00000000000003C0000000001E00000000000018003C7E00E00000;
        char_line[ 35 ] = 384'h0FF87FFE01FF00000003C00000070000000000003F00000000000003C0000000001E000000000100000030FC00808000;
        char_line[ 36 ] = 384'h0FF83FFC013F00000003C00000070000000000001F00000000000003C0000000001E000000000380000001F00001C000;
        char_line[ 37 ] = 384'h0FF01FF0003E00000003C00000070000000000001F00000000000003C0000000001C0000000007C0000003FFFFFFE000;
        char_line[ 38 ] = 384'h0FE001F0003E00C00003C00000070000000000000E00000000000003C0000000001CFFFFFFFFFFE0000003FFFFFFF000;
        char_line[ 39 ] = 384'h0FE001F0003E01E00003C00000070000000000000400000000000003C0000000001C7FFFFFFFFFF0000007800003F800;
        char_line[ 40 ] = 384'h0FC001F0003E03F00003FFFFFFFF0000000000000000000000000003C0000000001C20006000000000000F000003E000;
        char_line[ 41 ] = 384'h0F8001FFFFFFFFF80003FFFFFFFF0000000000000000000000000003C0000000003C00007000000000001E000007C000;
        char_line[ 42 ] = 384'h0F8001FFFFFFFFFC0003C02000070000000000000000000000000003C0000000003C0000FC00000000003C00000F8000;
        char_line[ 43 ] = 384'h0FFFFFF7C03E00000003801800060000000000000000000000000003C000000000380000FC00000000007E00001F0000;
        char_line[ 44 ] = 384'h0FFFFFF0003E00000000000E00000000000000000000000000000003C000000000380001F80000000000E780003E0000;
        char_line[ 45 ] = 384'h0F8001F0003E00000000100780000000000000000000000000000003C000000000380001E00000000001C3C0003E0000;
        char_line[ 46 ] = 384'h0F8001F0003E000000001C07C0018000000000000000000000000003C000000000780003C0000000000781F0007C0000;
        char_line[ 47 ] = 384'h0F8001F0003E000000081F03E000E000000000000000000000000003C00000000070000780000000000E00F800F80000;
        char_line[ 48 ] = 384'h0F8001F0003E000000181E01E0007800000000000000000000000003C00000000070000700180000001C007803F00000;
        char_line[ 49 ] = 384'h0F8001F0003E000000181C00E0183E00000000000000000000000003C00000000070000E000C00000070007807E00000;
        char_line[ 50 ] = 384'h0F8001F0003E000000181C00E0181F00000000000000000000000003C000000000E0001C0007000000C000380F800000;
        char_line[ 51 ] = 384'h0F8001F0003E000000381C0060180F80000000000000000000000003C000000000E0003800038000010000381F000000;
        char_line[ 52 ] = 384'h0F8001F0003E000000381C00401807C0000000000000000000000003C000000000C000700001E000000000187E000000;
        char_line[ 53 ] = 384'h0FFFFFF0003E000000701C00001807C0000000000000000000000003C000000001C000600001F00000000010F8000000;
        char_line[ 54 ] = 384'h0FFFFFF0003E000000F01C00001803C0000000000000000000000003C0000000018001C00000F80000000003F0000000;
        char_line[ 55 ] = 384'h0F8001F0003E000003F01C00001803C0000000000000000000000003C00000000380038000007C000000000FC0000000;
        char_line[ 56 ] = 384'h0F8001F0003E000003E01E00003C0180000000000000000000000003C000000003000700FFFFFE000000003F00000000;
        char_line[ 57 ] = 384'h0F8001F0003E000007E01FFFFFFE0000000000000000000000000003C000000006001FFFFFF03E00000001FC00000000;
        char_line[ 58 ] = 384'h0F8001F0003E000003800FFFFFFC0000000000000000000000000003C000000006000FFFE0001E0000000FF000000000;
        char_line[ 59 ] = 384'h0F8001E0003E0000000007FFFFF00000000000000000000000000003C00000000C000FF800001E000000FF8000000000;
        char_line[ 60 ] = 384'h0F000000003C00000000000000000000000000000000000000000003800000000800070000000E00000FF80000000000;
        char_line[ 61 ] = 384'h00000000003800000000000000000000000000000000000000000002000000001800040000000C0001FF000000000000;
        char_line[ 62 ] = 384'h000000000000000000000000000000000000000000000000000000000000000010000000000000000F80000000000000;
        char_line[ 63 ] = 384'h000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000;
        char_line[ 64 ] = 384'h000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000;
    end
end

// Instantiation ROM
rom	rom_inst (
.address ( rom_address ),
.clock ( vga_clk ),
.q ( rom_data )
);
endmodule // data_drive

3. Key anti shake module

module key_debounce(
	input 	wire	clk,
	input 	wire 	rst_n,
	input 	wire 	key,
	
	output 	reg 	flag,// 0 shake , 1 Jitter end 
	output 	reg	key_value//key The value after dithering 
);

parameter MAX_NUM = 20'd1_000_000;

reg [19:0] delay_cnt;//1_000_000

reg key_reg;//key Last time's value 

always @(posedge clk or negedge rst_n) begin
	if(!rst_n) begin
		key_reg <= 1;
		delay_cnt <= 0;
	end
	
	else begin
		key_reg <= key;
		// When key by 1 key  by 0  Indicates press jitter , Start timing 
		if(key_reg  != key  ) begin 
		   delay_cnt <= MAX_NUM ;
		end
		else begin
		    if(delay_cnt > 0)
				delay_cnt <= delay_cnt -1;
			else
				delay_cnt <= 0;
		end
	end
end


// When the timing is done , obtain key Value 
always @(posedge clk or negedge rst_n) begin
	if(!rst_n) begin
		flag <= 0;
		key_value <= 1;
	end

	else begin
		
		//  Time to finish   In a stable state , Assign a value 
		if(delay_cnt == 1) begin
			flag <= 1;
			key_value <= key;
		end
		else begin
			flag <= 0;
			key_value <= key_value;
		end
	end
end

endmodule

4. Top level modules

module vga_top (input			wire						clk,
                input			wire						rst_n,
                input			wire		[ 2:0 ]		    key,
                output			wire						vga_clk,
                output			wire						h_sync,
                output			wire						v_sync,
                output			wire		[ 4:0 ]			rgb_r,
                output			wire		[ 5:0 ]			rgb_g,
                output			wire		[ 4:0 ]			rgb_b,
                output			reg		    [ 3:0 ]			led);

reg			[ 27:0 ]			cnt			        ;
wire		[ 11:0 ]		    addr_h              ;
wire		[ 11:0 ]		    addr_v              ;
wire		[ 15:0 ]			rgb_data			;
wire		[ 2:0 ]			    key_flag			;
wire		[ 2:0 ]			    key_value			;

//vga modular 
vga_dirve u_vga_dirve(
.clk      ( clk ),
.rst_n    ( rst_n ),
.rgb_data ( rgb_data ),
.vga_clk  ( vga_clk ),
.h_sync   ( h_sync ),
.v_sync   ( v_sync ),
.rgb_r    ( rgb_r ),
.rgb_g    ( rgb_g ),
.rgb_b    ( rgb_b ),
.addr_h   ( addr_h ),
.addr_v   ( addr_v )
);

// Data module 
data_drive u_data_drive(
.vga_clk ( vga_clk ),
.rst_n   ( rst_n ),
.addr_h  ( addr_h ),
.addr_v  ( addr_v ),
.key     ( {
    key_value[ 2 ] && key_flag[ 2 ], key_value[ 1 ] && key_flag[ 1 ], key_value[ 0 ] && key_flag[ 0 ] } ),
.rgb_data  ( rgb_data )
);


// Press the key to shake off 
key_debounce u_key_debounce0(
.clk   ( vga_clk ),
.rst_n ( rst_n ),
.key   ( key[ 0 ] ),
.flag  ( key_flag[ 0 ] ),
.key_value  ( key_value[ 0 ] )
);

key_debounce u_key_debounce1(
.clk   ( vga_clk ),
.rst_n ( rst_n ),
.key   ( key[ 1 ] ),
.flag  ( key_flag[ 1 ] ),
.key_value  ( key_value[ 1 ] )
);

key_debounce u_key_debounce2(
.clk   ( vga_clk ),
.rst_n ( rst_n ),
.key   ( key[ 2 ] ),
.flag  ( key_flag[ 2 ] ),
.key_value  ( key_value[ 2 ] )
);

// led
always @( posedge clk or negedge rst_n ) begin
    if ( !rst_n ) begin
        cnt <= 0;
    end
    else if ( cnt == 50_000_000 - 1 ) begin
        cnt <= 0;
    end
    else begin
        cnt <= cnt + 1;
    end
end
always @( posedge clk or negedge rst_n ) begin
    if ( !rst_n ) begin
        led <= 4'b0000;
    end
    else if ( cnt == 50_000_000 -1 )begin
        led <= ~led;
    end
    else begin
        led <= led;
    end
end
endmodule // vga_top

5.TCL Binding pin code

package require ::quartus::project

set_location_assignment PIN_E1 -to clk
set_location_assignment PIN_E15 -to rst_n
set_location_assignment PIN_C16 -to h_sync
set_location_assignment PIN_D15 -to v_sync

set_location_assignment PIN_E16 -to key[0]
set_location_assignment PIN_M16 -to key[1]
set_location_assignment PIN_M15 -to key[2]

set_location_assignment PIN_G15 -to led[0]
set_location_assignment PIN_F16 -to led[1]
set_location_assignment PIN_F15 -to led[2]
set_location_assignment PIN_D16 -to led[3]

set_location_assignment PIN_A14 -to rgb_b[4]
set_location_assignment PIN_B14 -to rgb_b[3]
set_location_assignment PIN_A15 -to rgb_b[2]
set_location_assignment PIN_B16 -to rgb_b[1]
set_location_assignment PIN_C15 -to rgb_b[0]


set_location_assignment PIN_A11 -to rgb_g[5]
set_location_assignment PIN_B11 -to rgb_g[4]
set_location_assignment PIN_A12 -to rgb_g[3]
set_location_assignment PIN_B12 -to rgb_g[2]
set_location_assignment PIN_A13 -to rgb_g[1]
set_location_assignment PIN_B13 -to rgb_g[0]

set_location_assignment PIN_C8 -to rgb_r[4]
set_location_assignment PIN_A9 -to rgb_r[3]
set_location_assignment PIN_B9 -to rgb_r[2]
set_location_assignment PIN_A10 -to rgb_r[1]
set_location_assignment PIN_B10 -to rgb_r[0]

5、 ... and 、 effect

Switch the status by pressing the key , Output color bars according to different states 、 character 、 picture .

RTL View

top floor
 Insert picture description here
vga_drive
 Insert picture description here
data_drive
 Insert picture description here

Color bar

640 × 480 Resolution down
 Insert picture description here
800 × 600 The resolution of the
be relative to 640 × 480 The overall resolution is shifted to the left , In line with expectations
 Insert picture description here

character

 Insert picture description here

picture

 Insert picture description here

video

640 ×480 Shooting at resolution
 Insert picture description here

6、 ... and 、 Reference resources

http://www.mdy-edu.com/zhijian/2019/1210/461.html
https://blog.csdn.net/Bunny9__/article/details/118873815

原网站

版权声明
本文为[Intoxication, thousand layer dream]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/160/202206090337332218.html