基于FPGA的VGA協議實現

文章目錄

  • 一、VGA介紹
    • 1.1 VGA原理
    • 1.2VGA電路
  • 二、配置
  • 三、實現
    • 3.1 字符顯示
    • 3.2圖片顯示
  • 四、代碼
    • 4.1.vga驅動模塊
    • 4.2數據模塊
    • 4.3按鍵消抖模塊
    • 4.4頂層模塊
    • 4.5TCL引腳綁定
  • 參考

一、VGA介紹

1.1 VGA原理

VGA接口
在這里插入圖片描述
最主要的幾根線:
在這里插入圖片描述
VGA其實就是相當于一塊芯片,跟單片機驅動IC一樣,滿足一定的時序,便能驅動起來。VGA的掃描其實很簡單,大致軌跡如下所示:
在這里插入圖片描述
每掃描完一行,從新開始下一行;每掃完一場,重新開始下一場。
以下是行掃描,場掃描HS,VS時序圖
在這里插入圖片描述
VS時序如下所示:
在這里插入圖片描述
可見時序的循環,可被劃分為a,b,c,d4個時期。這四個時期定義如下:

A~B:場消隱期 即同步,相當于還原掃描坐標吧

B~C:場消隱后肩 相當于準備開始掃描吧

C~D:場顯示期 掃描中,數據有效區域

D~E:場消隱前肩 完成掃描,相當于準備同步

HS時序深入分析
在這里插入圖片描述
可見時序的循環,可被劃分為a,b,c,d4個時期。這四個時期定義如下:

A~B:行消隱期 即同步,相當于還原掃描坐標吧

B~C:行消隱后肩 相當于準備開始掃描吧

C~D:行顯示期 掃描中,數據有效區域

D~E:行消隱前肩 完成掃描,相當于準備同步

綜上描述,我們只要知道每個時期的時間,便可以表示出VGA的時序。而FPGA的工作是由固定頻率的時鐘觸發的,因此某固定時間可以用n次觸發來表示。因此我們很容易就想到了FPGA常用的計數方法:比如說行掃描,我們計數0~H_total-1。用另一個進程將其劃分為4個時期,安標注分配。其實這相當于狀態機。

1.2VGA電路

VGA接口:R,G,B三通道,直接賦給數字信號,RGB,最多產生8種色彩。這是最基本的。電路如下所示:
在這里插入圖片描述

二、配置

打開Quartus,選擇IP核
在這里插入圖片描述
命名之后,將基礎時鐘改為50M
在這里插入圖片描述
點擊next后,取消該勾選
在這里插入圖片描述
默認next,直到該界面,c0默認輸出50M即可,c1分頻到25M,如需其他時鐘頻率可以自己進行設置在這里插入圖片描述
勾選,finish
在這里插入圖片描述

三、實現

3.1 字符顯示

字模軟件
百度網盤:
https://pan.baidu.com/s/1542q14FRzCawo8WNp8J-Kg
提取碼: jdzg
在子模提取工具里面輸入需要顯示的字符并設置字符大小為64*64
在這里插入圖片描述
然后點擊文件-另存為,把圖片保存為BMP圖片,再點擊文件-打開,把保存的BMP圖片打開得到整體的字符。
在這里插入圖片描述
參數設置
在這里插入圖片描述
保存為.txt格式
在這里插入圖片描述
在這里插入圖片描述
將得到的字模替換。

3.2圖片顯示

想要顯示的圖片,但是圖片的大小超過了芯片的內存,無法把圖片保存進去,故采用一張100*100的圖片進行顯示。
在這里插入圖片描述
使用工具把圖片轉為HEX文件

工具鏈接: https://pan.baidu.com/s/1o8ii9ei密碼:62uv
在這里插入圖片描述
圖片數據太多需要使用ROM來存儲數據
打開quartus,找到ROM
在這里插入圖片描述
取消勾選下列選項
在這里插入圖片描述
剛才生成的,hex
在這里插入圖片描述
finish
在這里插入圖片描述

四、代碼

4.1.vga驅動模塊

module vga_dirve (input			wire						clk,            //系統時鐘input			wire						rst_n,          //復位input			wire		[ 15:0 ]		rgb_data,       //16位RGB對應值output			wire							vga_clk,    //vga時鐘 25Moutput			reg							h_sync,     //行同步信號output			reg							v_sync,     //場同步信號output			reg		[ 11:0 ]				addr_h, //行地址output			reg		[ 11:0 ]				addr_v,  //列地址output			wire		[ 4:0 ]				rgb_r,  //紅基色output			wire		[ 5:0 ]				rgb_g,  //綠基色output			wire		[ 4:0 ]				rgb_b  //藍基色
);// 640 * 480 60HZ
localparam	 H_FRONT = 16; // 行同步前沿信號周期長
localparam	 H_SYNC  = 96; // 行同步信號周期長
localparam	 H_BLACK = 48; // 行同步后沿信號周期長
localparam	 H_ACT   = 640; // 行顯示周期長
localparam	 V_FRONT = 11; // 場同步前沿信號周期長
localparam	 V_SYNC  = 2; // 場同步信號周期長
localparam	 V_BLACK = 31; // 場同步后沿信號周期長
localparam	 V_ACT   = 480; // 場顯示周期長// 800 * 600 72HZ
// localparam	 H_FRONT = 40; // 行同步前沿信號周期長
// localparam	 H_SYNC  = 120; // 行同步信號周期長
// localparam	 H_BLACK = 88; // 行同步后沿信號周期長
// localparam	 H_ACT   = 800; // 行顯示周期長
// localparam	 V_FRONT = 37; // 場同步前沿信號周期長
// localparam	 V_SYNC  = 6; // 場同步信號周期長
// localparam	 V_BLACK = 23; // 場同步后沿信號周期長
// localparam	 V_ACT   = 600; // 場顯示周期長localparam	H_TOTAL = H_FRONT + H_SYNC + H_BLACK + H_ACT; // 行周期
localparam	V_TOTAL = V_FRONT + V_SYNC + V_BLACK + V_ACT; // 列周期reg			[ 11:0 ]			cnt_h			; // 行計數器
reg			[ 11:0 ]			cnt_v			; // 場計數器
reg			[ 15:0 ]			rgb			; // 對應顯示顏色值// 對應計數器開始、結束、計數信號
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時鐘 行周期*場周期*刷新率 = 800 * 525* 60
wire							clk_25			;
// 50M時鐘 1040 * 666 * 72
wire							clk_50			;
//PLL
pll	pll_inst (.areset ( ~rst_n ),.inclk0 ( clk ),.c0 ( clk_50 ), //50M.c1 ( clk_25 ), //25M);
//根據不同分配率選擇不同頻率時鐘
assign vga_clk = clk_25;// 行計數
always @( posedge vga_clk or negedge rst_n ) beginif ( !rst_n ) begincnt_h <= 0;endelse if ( flag_enable_cnt_h ) beginif ( flag_clear_cnt_h ) begincnt_h <= 0;endelse begincnt_h <= cnt_h + 1;endendelse begincnt_h <= 0;end
end
assign flag_enable_cnt_h = 1;
assign flag_clear_cnt_h  = cnt_h == H_TOTAL - 1;// 行同步信號
always @( posedge vga_clk or negedge rst_n ) beginif ( !rst_n ) beginh_sync <= 0;endelse if ( cnt_h == H_SYNC - 1 ) begin // 同步周期時為1h_sync <= 1;endelse if ( flag_clear_cnt_h ) begin // 其余為0h_sync <= 0;endelse beginh_sync <= h_sync;end
end// 場計數
always @( posedge vga_clk or negedge rst_n ) beginif ( !rst_n ) begincnt_v <= 0;endelse if ( flag_enable_cnt_v ) beginif ( flag_clear_cnt_v ) begincnt_v <= 0;endelse if ( flag_add_cnt_v ) begincnt_v <= cnt_v + 1;endelse begincnt_v <= cnt_v;endendelse begincnt_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;// 場同步信號
always @( posedge vga_clk or negedge rst_n ) beginif ( !rst_n ) beginv_sync <= 0;endelse if ( cnt_v == V_SYNC - 1 ) beginv_sync <= 1;endelse if ( flag_clear_cnt_v ) beginv_sync <= 0;endelse beginv_sync <= v_sync;end
end// 對應有效區域行地址 1-640
always @( posedge vga_clk or negedge rst_n ) beginif ( !rst_n ) beginaddr_h <= 0;endelse if ( valid_area ) beginaddr_h <= cnt_h - H_SYNC - H_BLACK + 1;endelse beginaddr_h <= 0;end
end
// 對應有效區域列地址 1-480
always @( posedge vga_clk or negedge rst_n ) beginif ( !rst_n ) beginaddr_v <= 0;endelse if ( valid_area ) beginaddr_v <= cnt_v -V_SYNC - V_BLACK + 1;endelse beginaddr_v <= 0;end
end
// 有效顯示區域
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;// 顯示顏色
always @( posedge vga_clk or negedge rst_n ) beginif ( !rst_n ) beginrgb <= 16'h0;endelse if ( valid_area ) beginrgb <= rgb_data;endelse beginrgb <= 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

4.2數據模塊

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[ 89:0 ];localparam	states_1 = 1; // 彩條
localparam	states_2 = 2; // 字符
localparam	states_3 = 3; // 圖片parameter	height = 78; // 圖片高度
parameter	width  = 128; // 圖片寬度
reg			[ 1:0 ]			states_current			; // 當前狀態
reg			[ 1:0 ]			states_next			    ; // 下個狀態
reg			[ 13:0 ]		rom_address				; // ROM地址
wire			[ 15:0 ]		rom_data				; // 圖片數據wire							flag_enable_out1			; // 文字有效區域
wire							flag_enable_out2			; // 圖片有效區域
wire							flag_clear_rom_address		; // 地址清零
wire							flag_begin_h			    ; // 圖片顯示行
wire							flag_begin_v			    ; // 圖片顯示列//狀態轉移
always @( posedge vga_clk or negedge rst_n ) beginif ( !rst_n ) beginstates_current <= states_1;endelse beginstates_current <= states_next;end
end//狀態判斷
always @( posedge vga_clk or negedge rst_n ) beginif ( !rst_n ) beginstates_next <= states_1;endelse if ( key[ 0 ] ) beginstates_next <= states_1;endelse if ( key[ 1 ] ) beginstates_next <= states_2;endelse if ( key[ 2 ] ) beginstates_next <= states_3;endelse beginstates_next <= states_next;end
end//狀態輸出
always @( * ) begincase ( states_current )states_1 : beginif ( addr_h == 0 ) beginrgb_data = black;endelse if ( addr_h >0 && addr_h <81 ) beginrgb_data = red;endelse if ( addr_h >80 && addr_h <161 ) beginrgb_data = orange;endelse if ( addr_h >160 && addr_h <241 ) beginrgb_data = yellow;endelse if ( addr_h >240 && addr_h <321 ) beginrgb_data = green;endelse if ( addr_h >320 && addr_h <401 ) beginrgb_data = blue;endelse if ( addr_h >400 && addr_h <481 ) beginrgb_data = indigo;endelse if ( addr_h >480 && addr_h <561 ) beginrgb_data = purple;endelse if ( addr_h >560 && addr_h <641 ) beginrgb_data = white;endelse beginrgb_data = black;endendstates_2 : beginif ( flag_enable_out1 ) beginrgb_data = char_line[ addr_v-208 ][ 532 - addr_h ]? white:black;endelse beginrgb_data = black;endendstates_3 : beginif ( flag_enable_out2 ) beginrgb_data = rom_data;endelse beginrgb_data = black;endenddefault: begincase ( 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;endcaseendendcase
endassign 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地址計數器
always @( posedge vga_clk or negedge rst_n ) beginif ( !rst_n ) beginrom_address <= 0;endelse if ( flag_clear_rom_address ) begin //計數滿清零rom_address <= 0;endelse if ( flag_enable_out2 ) begin  //在有效區域內+1rom_address <= rom_address + 1;endelse begin  //無效區域保持rom_address <= rom_address;end
end
assign flag_clear_rom_address = rom_address == height * width - 1;//初始化顯示文字
always@( posedge vga_clk or negedge rst_n ) beginif ( !rst_n ) beginchar_line[0]=  384'h000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000;char_line[1]=  384'h000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000;char_line[2]=  384'h000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000;char_line[3]=  384'h000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000;char_line[4]=  384'h000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000;char_line[5]=  384'h0000000000000000000000000000000000000000000000000000000000000000000000000E0000000000000400000000;char_line[6]=  384'h000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000;char_line[7]=  384'h00000000000004000F8000000100000E0000080000000000000000000000000000000000000000000000000000000000;char_line[8]=  384'h00000000000000000000000000000000000000000000000003000E000F8000000180001F0C001C000000000000000000;char_line[9]=  384'h000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003FFFF00;char_line[10]= 384'h0F00000001FFFFFF0FFFFF00000000000000000000000000000000000000000000000000000000000000000000000000;char_line[11]= 384'h0000000000000000000000000000000003FFFF001F00000001FFFFFF8FFFFF0000000000000000000000000000000000;char_line[12]= 384'h00000000000000000000000000000000000000000000000000000000000000000000000003C01E001E00000001E00F00;char_line[13]= 384'h0F001C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000;char_line[14]= 384'h000000000000000003C01C001E00000001E00F000F001C00000000000000000000000000000000000000000000000000;char_line[15]= 384'h0000000000000000000000000000000000000000000000000000000003C03C003C00030001E00F000F001C0000000000;char_line[16]= 384'h0001FC00000FE000000FF000000040000007E00003FFFFF00007E0000001FC000007E00000000E00000FE00000004000;char_line[17]= 384'h03C038003C00078001E00F000F001C00000000000007FF00007FF800003FFE000000C000001FF80007FFFFF0001FF800;char_line[18]= 384'h0007FF00001FF80000000E00007FF8000000C00003C039FFFFFFFFC001E00F000F001C0000000000001E078000E07C00;char_line[19]= 384'h00F81F000001C000003C1E0007FFFFF0003C1E00001E0780003C1E0000001E0000E07C000001C00003C070FFFFFFFFE0;char_line[20]= 384'h01E00F000F001C0000000000003803C001801E0001E007800007C00000700F0007FFFFE000700F00003803C000700F00;char_line[21]= 384'h00003E0001801E000007C00003C070407800000001E00F080F001C0000000000007003E003000F0003C003C001FFC000;char_line[22]= 384'h00E0070007C000C000E00700007003E000E0070000003E0003000F0001FFC00003C060007000000001E30F1C0F001C00;char_line[23]= 384'h0000000000E003E003000780078001E001FFC00001E00380070000C001E0038000E003E001E0038000007E0003000780;char_line[24]= 384'h01FFC00003C0E000F000000001E3FFFE0F001C000000000001C003E007000780070001E00007C00003C003C006000180;char_line[25]= 384'h03C003C001C003E003C003C00000FE00070007800007C00003C0E000E000000001E3FFFE0F001C0000000000038003E0;char_line[26]= 384'h070007C0070000F00003C00003C001C00600018003C001C0038003E003C001C00000DE00070007C00003C00003C0C001;char_line[27]= 384'hE000000001E3C01C0F001C0000000000038001C0078003C00F0000F00003C000078001E00C000300078001E0038001C0;char_line[28]= 384'h078001E000019E00078003C00003C00003C0C001C0E0000001E3C01C0F001C000000000007000000078003C00F8000F0;char_line[29]= 384'h0003C000078000E00C000300078000E007000000078000E000039E00078003C00003C00003C18003C0F8000001E3C01C;char_line[30]= 384'h0FFFFC000000000007000000078003C00F8000F00003C000070000E00C000600070000E007000000070000E000031E00;char_line[31]= 384'h078003C00003C00003C1800380F8000001E3C01C0FFFFC000000000007000000030003C00FC000F00003C0000F0000F0;char_line[32]= 384'h000006000F0000F0070000000F0000F000071E00030003C00003C00003C1000380F0000001E3C01C0F001C0000000000;char_line[33]= 384'h0F000000000003C00FC000F00003C0000F0000F000000C000F0000F00F0000000F0000F000061E00000003C00003C000;char_line[34]= 384'h03C3000780F0000001E3C01C0F001C00000000000F000000000003C00FC000F00003C0000F0000F000001C000F0000F0;char_line[35]= 384'h0F0000000F0000F0000C1E00000003C00003C00003C1000700F0000001E3C01C0F001800000000000E00000000000780;char_line[36]= 384'h078001E00003C0000F000070000018000F0000700E0000000F000070001C1E00000007800003C00003C0800F00F00000;char_line[37]= 384'h01E3C01C0F000000000000000E00000000000780000001E00003C0001E000078000038001E0000780E0000001E000078;char_line[38]= 384'h00181E00000007800003C00003C0C00E00F0000001E3FFFC0F000000000000000E03F80000000F00000001E00003C000;char_line[39]= 384'h1E000078000038001E0000780E03F8001E00007800301E0000000F000003C00003C0601E00F0010001E3FFFC0F000000;char_line[40]= 384'h000000001E0FFF0000000E00000003C00003C0001E000078000030001E0000781E0FFF001E00007800701E0000000E00;char_line[41]= 384'h0003C00003C0301C00F0030001E3CF1C0F000000000000001E3FFF8000003C00000003C00003C0001E00007800007000;char_line[42]= 384'h1E0000781E3FFF801E00007800601E0000003C000003C00003C0383C00F0078001E38F180F0001803FFFFFFC1E7C0FC0;char_line[43]= 384'h0000F800000007800003C0001E000078000070001E0000781E7C0FC01E00007800C01E000000F8000003C00003C01C7F;char_line[44]= 384'hFFFFFFC001E20F000F0001803FFFFFFC1EF003E0000FE00000000F000003C0001E0000780000E0001E0000781EF003E0;char_line[45]= 384'h1E00007801C01E00000FE0000003C00003C01CFFFFFFFFE001E00F000F000180000000001EE001E0000FF80000000E00;char_line[46]= 384'h0003C0001E0000780000E0001E0000781EE001E01E00007801801E00000FF8000003C00003C01E7800F0000001E00F00;char_line[47]= 384'h0F000180000000001FC001F000007C0000001C000003C0001E0000780001E0001E0000781FC001F01E00007803001E00;char_line[48]= 384'h00007C000003C00003C00E3000F0000001E00F000F000180000000001F8000F000000F00000038000003C0001E000078;char_line[49]= 384'h0001C0001E0000781F8000F01E00007803001E0000000F000003C00003C00E0000F0000001E00F000F00018000000000;char_line[50]= 384'h1F0000F000000780000070000003C0001E0000780003C0001E0000781F0000F01E00007806001E00000007800003C000;char_line[51]= 384'h03C00E0000F0000001E00F000F000180000000001F000078000003C00000E0000003C0001E0000780003C0001E000078;char_line[52]= 384'h1F0000781E0000780E001E00000003C00003C00003C00F0080F0000001E00F000F0001C0000000001E000078000001C0;char_line[53]= 384'h0001C0000003C0001E000078000380001E0000781E0000781E0000780C001E00000001C00003C00003C00F01E0F00000;char_line[54]= 384'h01E00F030F8003E0000000001E000078000001E0000380000003C0001E000078000780001E0000781E0000781E000078;char_line[55]= 384'h18001E00000001E00003C00003C00F01F0F1000001E00F0787FFFFE0000000001E000078000000E0000700000003C000;char_line[56]= 384'h1E000078000780001E0000781E0000781E00007838001E00000000E00003C00003C00E03F8F0C00003FFFFFFC7FFFFE0;char_line[57]= 384'h000000001E000078000000F0000E00000003C0000F000070000780000F0000701E0000780F0000703FFFFFFC000000F0;char_line[58]= 384'h0003C00003E01E03E0F0600001FFFFFFE1FFFF80000000001E000078000000F0001C00000003C0000F0000F0000F8000;char_line[59]= 384'h0F0000F01E0000780F0000F03FFFFFFC000000F00003C00003DFFE07C0F0380000C0000000000000000000000E000078;char_line[60]= 384'h000000F0003800000003C0000F0000F0000F80000F0000F00E0000780F0000F000001E00000000F00003C00003C7FC07;char_line[61]= 384'h80F01C000000000000000000000000000F000078038000F0007000000003C0000F0000F0000F80000F0000F00F000078;char_line[62]= 384'h0F0000F000001E00038000F00003C00003C3F80F00F00E000000000000000000000000000F00007807C000F000E00030;char_line[63]= 384'h0003C000070000E0000F8000070000E00F000078070000E000001E0007C000F00003C00003C1F01E00F00F8000000000;char_line[64]= 384'h00000000000000000F0000700FC000F001C000300003C000078001E0000F8000078001E00F000070078001E000001E00;char_line[65]= 384'h0FC000F00003C00003C0C01E00F007C0000000002000C00000000000070000F00FC000F0038000300003C000078001E0;char_line[66]= 384'h001F8000078001E0070000F0078001E000001E000FC000F00003C00003C0003C00F003C000180C003000700000000000;char_line[67]= 384'h078000F00FC001E0078000300003C00003C001C0001F800003C001C0078000F003C001C000001E000FC001E00003C000;char_line[68]= 384'h03C0007800F003E0001806001C0038000000000003C000E00F8001E0070000600003C00003C003C0001F800003C003C0;char_line[69]= 384'h03C000E003C003C000001E000F8001E00003C00003C000F000F001E0001807000E003C000000000003C001E0078003C0;char_line[70]= 384'h0E0000E00003C00001E00380001F800001E0038003C001E001E0038000001E00078003C00003C00003C000E000F001F0;char_line[71]= 384'h003803800F001E000000000001E001C0078003801C0001E00003C00000E00700001F800000E0070001E001C000E00700;char_line[72]= 384'h00001E00078003800003C00003C001C000F000F0003803C007801F000000000000F0038003C007001FFFFFE00007E000;char_line[73]= 384'h00700F00001F800000700F0000F0038000700F0000001E0003C007000007E00003C0038000F000E0007803E007800F00;char_line[74]= 384'h00000000007C0F0001F01E001FFFFFE0000FF000003C1E00001F8000003C1E00007C0F00003C1E0000003F0001F01E00;char_line[75]= 384'h000FF00003C0070000F0006000F001E007C00F8000000000003FFE00007FFC001FFFFFE001FFFF80001FF800001F8000;char_line[76]= 384'h001FF800003FFE00001FF800000FFFF8007FFC0001FFFF8003C00C0000F0000000F001E003C00F80000000000007F000;char_line[77]= 384'h001FE0001FFFFFE001FFFF800007E000000F00000007E0000007F0000007E000000FFFF8001FE00001FFFF8003C01801;char_line[78]= 384'hF0F0000001F001E003C00780000000000000000000000000000000000000000000000000000000000000000000000000;char_line[79]= 384'h0000000000000000000000000000000003C020007FF0000007E001E00380078000000000000000000000000000000000;char_line[80]= 384'h00000000000000000000000000000000000000000000000000000000000000000000000003C000001FE0000007E000C0;char_line[81]= 384'h030007000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000;char_line[82]= 384'h000000000000000003C0000007E000000380008000000200000000000000000000000000000000000000000000000000;char_line[83]= 384'h0000000000000000000000000000000000000000000000000000000003C0000003C00000000000000000000000000000;char_line[84]= 384'h000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000;char_line[85]= 384'h038000000300000000000000000000000000000000000000000000000000000000000000000000000000000000000000;char_line[86]= 384'h000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000;char_line[87]= 384'h000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000;char_line[88]= 384'h000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000;char_line[89]= 384'h000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000;end
end//實例化ROM
rom	rom_inst (
.address ( rom_address ),
.clock ( vga_clk ),
.q ( rom_data )
);
endmodule // data_drive

4.3按鍵消抖模塊

module key_debounce(input 	wire	clk,input 	wire 	rst_n,input 	wire 	key,output 	reg 	flag,// 0抖動, 1抖動結束output 	reg	key_value//key抖動結束后的值
);parameter MAX_NUM = 20'd1_000_000;reg [19:0] delay_cnt;//1_000_000reg key_reg;//key上一次的值always @(posedge clk or negedge rst_n) beginif(!rst_n) beginkey_reg <= 1;delay_cnt <= 0;endelse beginkey_reg <= key;//當key為1 key 為0 表示按下抖動,開始計時if(key_reg  != key  ) begin delay_cnt <= MAX_NUM ;endelse beginif(delay_cnt > 0)delay_cnt <= delay_cnt -1;elsedelay_cnt <= 0;endend
end//當計時完成,獲取key的值
always @(posedge clk or negedge rst_n) beginif(!rst_n) beginflag <= 0;key_value <= 1;endelse begin// 計時完成 處于穩定狀態,進行賦值if(delay_cnt == 1) beginflag <= 1;key_value <= key;endelse beginflag <= 0;key_value <= key_value;endend
endendmodule

4.4頂層模塊

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模塊
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_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 )
);//按鍵消抖
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 ) beginif ( !rst_n ) begincnt <= 0;endelse if ( cnt == 50_000_000 - 1 ) begincnt <= 0;endelse begincnt <= cnt + 1;end
end
always @( posedge clk or negedge rst_n ) beginif ( !rst_n ) beginled <= 4'b0000;endelse if ( cnt == 50_000_000 -1 )beginled <= ~led;endelse beginled <= led;end
end
endmodule // vga_top

4.5TCL引腳綁定

package require ::quartus::projectset_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_syncset_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]

參考

``

https://blog.csdn.net/weixin_51755670/article/details/118076488
https://blog.csdn.net/qq_45659777/article/details/124834294

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/16303.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/16303.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/16303.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

gcc g++不同版本切換命令

sudo update-alternatives --config g sudo update-alternatives --config gcc ubuntu20.04 切換 gcc/g 版本_ubuntu降低g版本-CSDN博客

YOLOv10嘗鮮測試五分鐘極簡配置

最近清華大學團隊又推出YOLOv10&#xff0c;真是好家伙了。 安裝&#xff1a; pip install supervision githttps://github.com/THU-MIG/yolov10.git下載權重&#xff1a;https://github.com/THU-MIG/yolov10/releases/download/v1.0/yolov10n.pt 預測&#xff1a; from ult…

Superset,基于瀏覽器的開源BI工具

BI工具是數據分析的得力武器&#xff0c;目前市場上有很多BI軟件&#xff0c;眾所周知的有Tableau、PowerBI、Qlikview、帆軟等&#xff0c;其中大部分是收費軟件或者部分功能收費。這些工具一通百通&#xff0c;用好一個就夠了&#xff0c;重要的是分析思維。 我一直用的Tabl…

【HMGD】STM32/GD32 CAN通信

各種通信協議速度分析 協議最高速度(btis/s)I2C400KCAN1MCAN-FD5M48510MSPI36M CAN協議圖和通信幀 CubeMX CAN配置說明 CAN通信波特率 APB1頻率 / 分頻系數 /&#xff08;BS1 BS2 同步通信段&#xff09;* 1000 ? 42 / 1 / (111) * 1000 ? 14,000 KHz ? 1400000…

吉林大學計科21級《軟件工程》期末考試真題

文章目錄 21級期末考試題一、單選題&#xff08;2分一個&#xff0c;十個題&#xff0c;一共20分&#xff09;二、問答題&#xff08;5分一個&#xff0c;六個題&#xff0c;一共30分&#xff09;三、分析題&#xff08;一個10分&#xff0c;一共2個&#xff0c;共20分&#xf…

前端自定義Echarts 圖的時候,重新渲染,頁面還保存原來的數據

自定義 setAxisSingleOption(optionData){var options this.axisSingleOptionoptions.title.text optionData.title.textoptions.xAxis.data optionData.xAxis.dataoptions.legend.data optionData.legend.dataoptions.series optionData.seriesoptions.grid optionData…

【C語言】10.C語言指針(1)

文章目錄 1.內存和地址1.1 內存1.2 究竟該如何理解編址 2.指針變量和地址2.1 取地址操作符&#xff08;&&#xff09;2.2 指針變量和解引?操作符&#xff08;*&#xff09;2.2.1 指針變量2.2.2 如何拆解指針類型2.2.3 解引?操作符 2.3 指針變量的?? 3.指針變量類型的意…

匯編:字符串的輸出

在16位匯編程序中&#xff0c;可以使用DOS中斷21h的功能號09h來打印字符串&#xff1b;下面是一個簡單的示例程序&#xff0c;演示了如何在16位匯編程序中打印字符串&#xff1a; assume cs:code,ds:data ? data segmentszBuffer db 0dh,0ah,HelloWorld$ //定義字符串 data …

【C++】哈夫曼編碼:高效的壓縮算法

哈夫曼編碼&#xff1a;高效的壓縮算法 什么是哈夫曼編碼&#xff1f; 哈夫曼編碼是一種用于數據壓縮的無損編碼方法&#xff0c;由David A. Huffman于1952年提出。它利用了字符出現頻率的不均勻性&#xff0c;通過構建最優前綴碼&#xff0c;能夠有效減少數據的冗余&#xf…

Flutter仿照微信實現九宮格頭像

一、效果圖 2、主要代碼 import dart:io; import dart:math;import package:cached_network_image/cached_network_image.dart; import package:flutter/material.dart;class ImageGrid extends StatelessWidget {final List<String> imageUrls; // 假設這是你的圖片URL…

關于Iterator 和ListIterator的詳解

1.Iterator Iterator的定義如下&#xff1a; public interface Iterator<E> {} Iterator是一個接口&#xff0c;它是集合的迭代器。集合可以通過Iterator去遍歷集合中的元素。Iterator提供的API接口如下&#xff1a; forEachRemaining(Consumer<? super E> act…

VS2022通過C++網絡庫Boost.Asio創建一個簡單的同步TCP服務器和客戶端

Boost.Asio是一個用于網絡和異步編程的C庫。它提供了一種跨平臺的方式來處理網絡編程和異步操作&#xff0c;使開發人員能夠創建高性能的網絡應用程序&#xff0c;asio幾乎支持所有你能夠想到的網絡協議&#xff0c;比如tcp、udp、ip、http、icmp等&#xff0c;C通過asio庫可以…

找出第 K 大的異或坐標值

問題 給你一個二維矩陣 matrix 和一個整數 k &#xff0c;矩陣大小為 m x n 由非負整數組成。 矩陣中坐標 (a, b) 的 值 可由對所有滿足 0 < i < a < m 且 0 < j < b < n 的元素 matrix[i][j]&#xff08;下標從 0 開始計數&#xff09;執行異或運算得到。…

淺談網絡通信(1)

文章目錄 一、認識一些網絡基礎概念1.1、ip地址1.2、端口號1.3、協議1.4、協議分層1.5、協議分層的2種方式1.5.1、OSI七層模型1.5.2、TCP/IP五層模型[!]1.5.2.1、TCP/IP五層協議各層的含義及功能 二、網絡中數據傳輸的基本流程——封裝、分用2.1、封裝2.2、分用2.2.1、5元組 三…

基于大模型和RAG技術實現的開源項目

基于大模型和RAG技術實現的開源項目 為解決大模型的不足&#xff0c;使用RAG技術增強大模型生成內容的針對性和可讀性能力&#xff0c;有很多不錯的開源項目。例如下面的項目。 1 ragflow 優點&#xff1a;可以對文檔和知識庫進行管理&#xff0c;構建不同的知識庫&#xff…

python冰雹序列的探索與編程實現

新書上架~&#x1f447;全國包郵奧~ python實用小工具開發教程http://pythontoolsteach.com/3 歡迎關注我&#x1f446;&#xff0c;收藏下次不迷路┗|&#xff40;O′|┛ 嗷~~ 目錄 一、冰雹序列的奧秘 二、編程實現冰雹序列 三、測試與驗證 四、總結與展望 一、冰雹序列的…

整理好了!2024年最常見 20 道 Redis面試題(八)

上一篇地址&#xff1a;整理好了&#xff01;2024年最常見 20 道 Redis面試題&#xff08;七&#xff09;-CSDN博客 十五、Redis 的性能調優有哪些方法&#xff1f; Redis的性能調優是一個多方面的工作&#xff0c;涉及到硬件、配置、代碼層面的優化等多個方面。以下是一些常…

openEuler 22.03 LTS SP3源碼編譯部署OpenStack-Caracal

openEuler 22.03 LTS SP3源碼編譯部署OpenStack-Caracal 說明機器詳情安裝操作系統注意事項基礎準備Controller節點 && Compute節點 && Block節點關閉防火墻關閉selinux設置靜態IP更新安裝前準備Controller節點 && Compute節點 && Block節點設…

第十課,while循環

一&#xff0c;認識循環是什么 循環普遍存在于日常生活中&#xff0c;同樣&#xff0c;在程序中&#xff0c;循環功能也是至關重要的基礎功能。 當程序需要重復執行某一段代碼&#xff0c;利用循環可以輕松完成工作 例如我要你打印100次上課&#xff0c;直接寫100次print&…

python調用阿里云通義千問(q-wen-max)API-只能總結pdf文檔內容

文章目錄 通義千問插件PDF解析插件調用案例通義千問插件 Dashscope插件功能能夠使得大模型的生成內容與外部三方應用結合,使得模型生成的內容更加準確和豐富,模型將擁有更好的生成能力。您也可以通過開發自定義插件,來使得模型生成更符合您預期的結果。 使用插件功能,大模…