本文为明德扬原创及录用文章,转载请注明出处!
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.mdy-edu.com/ffkc/415.html
(点击→了解课程详情☝)感兴趣请联系易老师:13112063618(微信同步)