本文為明德揚原創及錄用文章,轉載請注明出處!
1.1 總體設計
1.1.1 概述
1.1.2 設計目標
1.1.3 系統結構框圖

1.1.4模塊功能
mdyPllAltera模塊實現功能
mdyRom模塊實現功能
mdyCfg模塊實現功能
mdyKey模塊實現功能
PicZoomInAndOut模塊實現功能
mdyLcd驅動模塊實現功能
mdyGetEdge模塊實現功能
mdyStatic_1S模塊實現功能
1.1.5頂層信號
1.1.6參考代碼
module top_mdyLcdPicZoomInAndOut( clk , rst_n , key , uart_rxd , uart_txd , lcd_hs , lcd_vs , lcd_de , lcd_dat , lcd_clk ); parameter PICTURE_W = 24 ; parameter KEY_W = 4 ; input clk ;//50MHz input rst_n ; input [KEY_W-1 :0] key ; input uart_rxd ; output uart_txd ; output lcd_hs ; output lcd_vs ; output lcd_de ; output [PICTURE_W-1:0] lcd_dat ; output lcd_clk ; wire uart_txd ; wire lcd_hs ; wire lcd_vs ; wire lcd_de ; wire [PICTURE_W-1:0] lcd_dat ; wire lcd_clk ; wire clk_0 ; wire [23:0] pic_data ; wire [10:0] req_x ; wire [ 9:0] req_y ; wire frame_start ; wire [KEY_W-1:0] key_vld ; wire frame_pos ; wire [63:0] uart_dout ; wire uart_dout_vld ; wire [63:0] cfgCtrl_dout ; wire cfgCtrl_dout_vld ; `include "mdyCfg_wire.v" /****************** PLL模塊 *******************************/ mdyPllAltera#(.C0_M(4),.C0_D(5)) u1_pll_40m( .areset (~rst_n ), //高電平有效 .inclk0 (clk ), .c0 (clk_0 ), .c1 ( ), .c2 ( ), .c3 ( ), .c4 ( ), .locked ( ) ); /****************** LCD驅動模塊 *******************************/ mdyLcd#(.D_DLY(1)) u2_lcd_driver( .clk (clk_0 ),//40MHz .rst_n (rst_n ), .ack_data (pic_data ), .req_x (req_x ), .req_y (req_y ), .req_en ( ), .req_addr ( ), .hys (lcd_hs ), .vys (lcd_vs ), .lcd_de (lcd_de ), .lcd_rgb (lcd_dat ), .lcd_dclk (lcd_clk ), .frame_start (frame_start ) ); /****************** 功能模塊 *******************************/ PicZoomInAnDout u3_PicZoomInAnDout( .clk (clk_0 ), .rst_n (rst_n ), .mode (MODE_SELECT_en), .key_en (key_vld ), .cpu_ZoomIn (SOFTWARE_CTRL_in), .cpu_ZoomOut (SOFTWARE_CTRL_out), .req_h (req_x ), .req_v (req_y ), .pic_data (pic_data ) ); /********************* 按鍵模塊 ****************************/ mdyKey#(.DATA_W(24),.TIME_20MS(8_00_000)) u4_mdykey( .clk (clk_0 ), .rst_n (rst_n ), .key_in (key ), .key_vld (key_vld ) ); /********************* 邊沿檢測模塊 ****************************/ mdyGetEdge u5_GetEdge( .clk (clk_0 ), .rst_n (rst_n ), .cfg_init_value (0 ), .din (frame_start ), .dout_pos (frame_pos), .dout_neg ( ), .dout_pos_reg ( ), .dout_neg_reg ( ) ); /********************* 1s統計模塊 ****************************/ mdyStatic_1S u6_Static_1S( .clk (clk_0 ), .rst_n (rst_n ), .cfg_num_1s (50_000_000 ), .cfg_add_1s (1 ), .din_vld (frame_pos ), .sta_1s (DATA_FRAME_data ),//32bit .sta_rt ( ) ); /********************* 指令模塊 ****************************/ top_uart_cfg#(.BPS(4167)) u7_top_uart_cfg( .clk (clk_0 ), .rst_n (rst_n ), .cfg_head (16'h55d5 ), .rx (uart_rxd ), .tx (uart_txd ), .din (cfgCtrl_dout ),//s2p .din_vld (cfgCtrl_dout_vld ), .din_rdy ( ), .dout (uart_dout ),//p2s .dout_vld (uart_dout_vld ) ); mdyCfgCtrl u8_mdyCfgCtrl( `include "mdyCfg_inst.v" .clk (clk_0 ), .rst_n (rst_n ), .din (uart_dout ), .din_vld (uart_dout_vld ), .dout (cfgCtrl_dout ), .dout_vld (cfgCtrl_dout_vld ) ); /*************************************************/ endmodule1.2 mdyPllAltera模塊接口說明
1.2.1接口信號
1.2.2 使用說明
1.3 mdyRom模塊設計
1.3.1接口信號
1.3.2設計思路
1.4 mdyCfg模塊接口說明
1.4.1接口信號
mdyCfgCtrl模塊的接口信號:
1.4.2 使用說明
1.5 mdyKey模塊接口說明
1.5.1接口信號
1.5.2使用說明
1.6 PicZoomInAndOut模塊接口說明
1.6.2參考代碼
module PicZoomInAnDout( clk , rst_n , mode , key_en , cpu_ZoomIn , cpu_ZoomOut , req_h ,//h_cnt - THB req_v ,//v_cnt - TVB pic_data ); //LCD顯示屏居中 parameter HDE_CENTRE = 400 ;//800/2 parameter VDE_CENTRE = 240 ;//480/2 parameter DATA_W = 8; parameter KEY_W = 4; //輸入信號定義 input clk ; input rst_n ; input mode ; input cpu_ZoomIn ; input cpu_ZoomOut ; input [KEY_W-1 :0] key_en ; //輸出信號定義 input [10:0] req_h ; input [ 9:0] req_v ; output [23:0] pic_data ; //輸出信號reg定義 reg [23:0] pic_data ; //中間信號 reg [15:0] logo_rom_addr ; reg logo_rom_area ; wire [7:0] logo_rom_data ; reg [17:0] e_rom_addr ; reg e_rom_area ; reg [2:0] e_rom_addr_low ; reg e_dataout ; wire [7:0] e_rom_data ; reg [ 2:0] size ; reg [ 2:0] size_ff0 ; wire [9:0] len_size ; wire [9:0] wid_size ; wire [9:0] e_x0 ; wire [9:0] e_x1 ; wire [9:0] e_y0 ; wire [9:0] e_y1 ; wire [9:0] x ; wire [9:0] y ; /******************************************************/ always @(posedge clk or negedge rst_n)begin if(rst_n==1'b0)begin size <= 0; end else if(mode==1)begin if(cpu_ZoomOut)begin if(size!=3) size <= size + 1; end else if(cpu_ZoomIn)begin if(size!=0) size <= size - 1; end end else if(mode==0)begin if(key_en==4'b0010)begin if(size!=3) size <= size + 1; end else if(key_en==4'b0001)begin if(size!=0) size <= size - 1; end end end always @(posedge clk or negedge rst_n)begin if(rst_n==1'b0)begin size_ff0 <= 0; end else if(req_h==(HDE_CENTRE-200) && req_v==(VDE_CENTRE-150)) begin size_ff0 <= size; end end assign len_size = 400 >> size_ff0;//縮小多少倍 assign wid_size = 300 >> size_ff0; assign e_x0 = (HDE_CENTRE-len_size[9:1]); assign e_x1 = (HDE_CENTRE+len_size[9:1]); assign e_y0 = (VDE_CENTRE-wid_size[9:1]); assign e_y1 = (VDE_CENTRE+wid_size[9:1]); assign x = (req_h-e_x0)<<size; assign y = (req_v-e_y0)<<size; always @(*)begin e_rom_area = req_h >=(e_x0+5) && req_h < e_x1 && req_v >= e_y0 && req_v < (e_y1+5); end always @(*)begin e_rom_addr = x + 400*y; end /******************************************************/ //120*55 always @(*)begin logo_rom_area = req_h >=0 && req_h < 119 && req_v >= 0 && req_v < 54; end always @(*)begin logo_rom_addr = req_h + 120*req_v; end /******************************************************/ always @(posedge clk or negedge rst_n)begin if(rst_n==1'b0)begin e_rom_addr_low <= 0; end else begin e_rom_addr_low <= e_rom_addr[2:0]; end end always @(*)begin if(e_rom_area) e_dataout = ~e_rom_data[7-e_rom_addr_low]; else e_dataout = 1; end always @(posedge clk or negedge rst_n)begin if(rst_n==1'b0)begin pic_data <= 0; end else if(e_rom_area)begin pic_data <= {24{e_dataout}}; end else if(logo_rom_area)begin pic_data <= {logo_rom_data[7:5],5'b11111,logo_rom_data[4:2],5'b11111,logo_rom_data[1:0],6'b111111} ; end end /******************************************************/ mdyRom#(.MIF("../src/data/logo.mif"),.DEP(8192),.D_W(8)) u_fpga_rom( .address (logo_rom_addr ), .clock (clk ), .q (logo_rom_data ) ); mdyRom#(.MIF("../src/data/e.mif"),.DEP(16384),.D_W(8)) u_e_rom( .address (e_rom_addr[16:3] ), .clock (clk ), .q (e_rom_data ) );
endmodule
1.7.1使用說明
1.8 mdyGetEdge模塊接口說明
1.8.1接口信號
1.8.2使用說明
1.9 mdyStatic_1S模塊接口說明
1.9.1接口信號
1.9.2使用說明
1.10 效果和總結
以下為工程上板后的現象效果圖:

mp801開發板——縮小1倍

mp801開發板——縮小2倍

mp801開發板——縮小3倍

本案例設計教學視頻和源工程代碼,可到明德揚論壇進行下載學習。
感興趣的朋友也可以訪問明德揚論壇(http://www.fpgabbs.cn/)進行FPGA相關工程設計學習,也可以看一下我們往期的文章:
MP801開發板——千兆網、ADDA、大容量SDRAM等,學習和項目需求一步到位。網絡培訓班——不管時間和空間,明德揚隨時在你身邊,助你快速學習FPGA。周末培訓班——明天的你會感激現在的努力進取,升職加薪明德揚來助你。就業培訓班——七大企業級項目實訓,獲得豐富的項目經驗,高薪就業。專題課程——高手修煉課:提升設計能力;實用調試技巧課:提升定位和解決問題能力;FIFO架構設計課:助你快速成為架構設計師;時序約束、數字信號處理、PCIE、綜合項目實踐課等你來選。項目承接——承接企業FPGA研發項目。人才服務——提供人才推薦、人才代培、人才派遣等服務。