本文為明德揚原創及錄用文章,轉載請注明出處!
1.1 總體設計
1.1.1 概述
液晶顯示器是一-種通過液晶和色彩過濾器過濾光源,在平面面板上產生圖像的數字顯示器。LCD 的構造是在兩片平行的玻璃基板當中放置液晶盒,下基板玻璃上設置薄膜晶體管,.上基板玻璃上設置彩色濾光片,通過薄膜晶體管上的信號與電壓改變來控制液晶分子的轉動方向,從而達到控制每個像素點偏振光出射與否而達到顯示目的。與傳統的陰極射線管相比,LCD具有占用空間小,低功耗,低輻射,無閃爍,降低視覺疲勞等優點。現在LCD已漸替代CRT成為主流,價格也已經下降了很多,并已充分的普及。
1.1.2 設計目標
1.在7寸LCD顯示屏上實現明德揚LOGO圖標的左上角顯示和大寫字母“E”圖片的居中顯示;
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 )
);
/*************************************************/
endmodule
1.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.1接口信號
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開發板——縮小0倍

mp801開發板——縮小1倍

mp801開發板——縮小2倍

mp801開發板——縮小3倍

本案例設計教學視頻和源工程代碼,可到明德揚論壇進行下載學習。
溫馨提示:明德揚2023推出了全新課程——邏輯設計基本功修煉課,降低學習FPGA門檻的同時,增加了學習的趣味性,并組織了考試贏積分活動
http://www.cqqtmy.cn/ffkc/415.html
(點擊→了解課程詳情?)感興趣請聯系易老師:13112063618(微信同步)