本文为明德扬原创文章,转载请注明出处!
1.1 总体设计
1.1.1 概述
液晶显示器是一-种通过液晶和色彩过滤器过滤光源,在平面面板上产生图像的数字显示器。LCD 的构造是在两片平行的玻璃基板当中放置液晶盒,下基板玻璃上设置薄膜晶体管,.上基板玻璃上设置彩色滤光片,通过薄膜晶体管上的信号与电压改变来控制液晶分子的转动方向,从而达到控制每个像素点偏振光出射与否而达到显示目的。与传统的阴极射线管相比,LCD具有占用空间小,低功耗,低辐射,无闪烁,降低视觉疲劳等优点。现在LCD已渐替代CRT成为主流,价格也已经下降了很多,并已充分的普及。
1.1.2 设计目标
在7寸LCD显示屏上实现图片显示。
其中,在显示屏左上角显示明德扬的LOGO图标,在显示屏的中间居中显示字母“E”。
1.1.3 系统结构框图
系统结构框图如下所示:
图一
1.1.4模块功能
PLL模块实现功能
1.将输入的50MHz时钟分频输出40MHz时钟。
ROM模块实现功能
1.FPGA_rom存储明德扬LOGO的图像数据;
2.e_rom存储字母“E”的图像数据。
LCD驱动模块实现功能
1、产生驱动LCD屏显示的时序
2、读取ROM里存储的数据并输出显示
1.1.5顶层信号
信号名
| I/O | 位宽 | 定义 |
clk | I | 1 | 系统工作时钟 50M |
rst_n | I | 1 | 系统复位信号,低电平有效 |
hys | O | 1 | LCD 行时序信号 |
vys | O | 1 | LCD 场时序信号 |
lcd_de | O | 1 | LCD 数据输入使能信号 |
lcd_rgb | O | 24 | LCD RGB信号,RGB格式为使用24位来表示一个像素,RGB分量都用8位表示,取值范围为0-255。 |
lcd_dclk | O | 1 | LCD 数据采样时钟 |
1.1.6参考代码
a.
module top_mdyLcdPicOverlay(
b.
c.
clk ,
d.
e.
rst_n ,
f.
g.
hys ,
h.
i.
vys ,
j.
k.
lcd_de ,
l.
m.
lcd_rgb ,
n.
o.
lcd_dclk
p.
q.
);
r.
s.
t.
u.
parameter PICTURE_W = 24 ;
v.
w.
x.
y.
input clk ;
z.
aa.
input rst_n ;
ab.
ac.
output hys ;
ad.
ae.
output vys ;
af.
ag.
output lcd_de ;
ah.
ai.
output [PICTURE_W-1:0] lcd_rgb ;
aj.
ak.
output lcd_dclk ;
al.
am.
an.
ao.
ap.
aq.
wire clk_0 ;
ar.
as.
at.
au.
wire hys ;
av.
aw.
wire vys ;
ax.
ay.
wire lcd_de ;
az.
ba.
wire [PICTURE_W-1:0] lcd_rgb ;
bb.
bc.
wire lcd_dclk ;
bd.
be.
bf.
bg.
bh.
bi.
//40MHz
bj.
bk.
pll_40m u_pll_40m(
bl.
bm.
.areset (~rst_n ),
bn.
bo.
.inclk0 (clk ),
bp.
bq.
.c0 (clk_0 )
br.
bs.
);
bt.
bu.
bv.
bw.
bx.
by.
lcd_driver u2(
bz.
ca.
.clk (clk_0 ),//40MHz
cb.
cc.
.rst_n (rst_n ),
cd.
ce.
cf.
cg.
.hys (hys ),
ch.
ci.
.vys (vys ),
cj.
ck.
.lcd_de (lcd_de ),
cl.
cm.
.lcd_rgb (lcd_rgb ),
cn.
co.
.lcd_dclk (lcd_dclk )
cp.
cq.
);
cr.
cs.
ct.
cu.
endmodule
cv.
复制代码
1.2 PLL模块设计
1.2.1接口信号
下面为PLL的接口信号:
信号名
| I/O | 位宽 | 定义 |
areset | I | 1 | PLL复位信号,高电平有效 |
inclk0 | I | 1 | PLL输入时钟 50MHz |
c0 | O | 1 | PLL输出时钟 40MHz |
1.2.2 设计思路
本模块主要用于产生LCD驱动时序所需要的时钟,关于PLL的使用详细介绍请看下方链接:
http://www.fpgabbs.cn/forum.php?mod=viewthread&tid=322&fromuid=100105
1.3 ROM模块设计
1.3.1接口信号
信号名
| I/O | 位宽 | 定义 |
address | I | 16 | ROM数据存放地址 |
clock | I | 1 | ROM工作时钟40MHz |
q | O | 8 | ROM输出数据 |
1.3.2设计思路
本模块主要用于存储需要显示的图像数据,关于ROM的使用详细介绍请查看IP核右上角数据手册“Documentation”。
1.4 LCD驱动模块设计
1.4.1接口信号
信号名
| I/O | 位宽 | 定义 |
clk | I | 1 | 模块工作时钟 40MHz |
rst_n | I | 1 | 系统复位信号,低电平有效 |
hys | O | 1 | LCD 行时序信号 |
vys | O | 1 | LCD 场时序信号 |
lcd_de | O | 1 | LCD 数据输入使能信号 |
lcd_rgb | O | 24 | LCD RGB信号,RGB格式为使用24位来表示一个像素,RGB分量都用8位表示,取值范围为0-255。 |
lcd_dclk | O | 1 | LCD 数据采样时钟 |
1.4.2设计思路
产生驱动LCD显示的行场时序信号,其计数器架构如下图所示:
行计数器h_cnt:该计数器用来计算行同步信号的帧长。加一条件为1,表示一直在计数。结束条件为数1056个,也就是一行有1056个像素。
场计数器v_cnt:该计数器用来计算场同步信号的帧长。加一条件为end_h_cnt,即行计数器的计数器的结束条件,表示每计数完一行像素就加一。结束条件为数525个,也就是一共有525行像素。
其中,在从存储图像“E”的ROM里读取数据的时候,有一个操作就是读取的地址从第8位开始,也就是说18位数据地址,低三位不读,读取的是e_rom_addr[16:3]。有这样一个操作的话就能实现对存储的图像进行8倍的放大显示。
1.4.3参考代码
a.
module lcd_driver(
b.
c.
clk ,//40MHz
d.
e.
rst_n ,
f.
g.
h.
i.
hys ,
j.
k.
vys ,
l.
m.
lcd_de ,
n.
o.
lcd_rgb ,
p.
q.
lcd_dclk
r.
s.
);
t.
u.
v.
w.
input clk ;
x.
y.
input rst_n ;
z.
aa.
ab.
ac.
output hys ;
ad.
ae.
output vys ;
af.
ag.
output lcd_de ;
ah.
ai.
output [23:0] lcd_rgb ;
aj.
ak.
output lcd_dclk ;
al.
am.
an.
ao.
reg hys ;
ap.
aq.
reg vys ;
ar.
as.
reg lcd_de ;
at.
au.
reg [23:0] lcd_rgb ;
av.
aw.
wire lcd_dclk ;
ax.
ay.
az.
ba.
//1056
bb.
bc.
parameter THPW = 20 ;
bd.
be.
parameter THB = 46 ;
bf.
bg.
parameter THD = 800 ;
bh.
bi.
parameter THFP = 210 ;
bj.
bk.
bl.
bm.
//525
bn.
bo.
parameter TVPW = 10 ;
bp.
bq.
parameter TVB = 23 ;
br.
bs.
parameter TVD = 480 ;
bt.
bu.
parameter TVFP = 22 ;
bv.
bw.
bx.
by.
parameter HDE_CENTRE = THD/2 ;//400
bz.
ca.
parameter VDE_CENTRE = TVD/2 ;//240
cb.
cc.
cd.
ce.
parameter LOGO_X0 = (0 + (THB-1)) ;
cf.
cg.
parameter LOGO_X1 = (120 + (THB-1)) ;
ch.
ci.
parameter LOGO_Y0 = (0 + (TVB-1)) ;
cj.
ck.
parameter LOGO_Y1 = (55 + (TVB-1)) ;
cl.
cm.
cn.
co.
parameter E_X0 = ((HDE_CENTRE-200) + (THB-1)) ;
cp.
cq.
parameter E_X1 = ((HDE_CENTRE+200) + (THB-1)) ;
cr.
cs.
parameter E_Y0 = ((VDE_CENTRE-150) + (TVB-1)) ;
ct.
cu.
parameter E_Y1 = ((VDE_CENTRE+150) + (TVB-1)) ;
cv.
cw.
cx.
cy.
reg [ 10:0] h_cnt ;
cz.
da.
wire add_h_cnt ;
db.
dc.
wire end_h_cnt ;
dd.
de.
reg [ 9:0] v_cnt ;
df.
dg.
wire add_v_cnt ;
dh.
di.
wire end_v_cnt ;
dj.
dk.
dl.
dm.
dn.
do.
wire active_area ;
dp.
dq.
reg logo_rom_area ;
dr.
ds.
reg [15:0] logo_rom_addr ;
dt.
du.
wire [7:0] logo_rom_data ;
dv.
dw.
reg e_rom_area ;
dx.
dy.
reg [17:0] e_rom_addr ;
dz.
ea.
wire [7:0] e_rom_data ;
eb.
ec.
reg [2:0] e_rom_addr_low ;
ed.
ee.
reg e_sel ;
ef.
eg.
eh.
ei.
ej.
ek.
el.
em.
always @(posedge clk or negedge rst_n) begin
en.
eo.
if (rst_n==0) begin
ep.
eq.
h_cnt <= 0;
er.
es.
end
et.
eu.
else if(add_h_cnt) begin
ev.
ew.
if(end_h_cnt)
ex.
ey.
h_cnt <= 0;
ez.
fa.
else
fb.
fc.
h_cnt <= h_cnt+1 ;
fd.
fe.
end
ff.
fg.
end
fh.
fi.
assign add_h_cnt = 1;
fj.
fk.
assign end_h_cnt = add_h_cnt && h_cnt == (THB + THD + THFP)-1 ;
fl.
fm.
fn.
fo.
fp.
fq.
fr.
fs.
always @(posedge clk or negedge rst_n) begin
ft.
fu.
if (rst_n==0) begin
fv.
fw.
v_cnt <= 0;
fx.
fy.
end
fz.
ga.
else if(add_v_cnt) begin
gb.
gc.
if(end_v_cnt)
gd.
ge.
v_cnt <= 0;
gf.
gg.
else
gh.
gi.
v_cnt <= v_cnt+1 ;
gj.
gk.
end
gl.
gm.
end
gn.
go.
assign add_v_cnt = end_h_cnt;
gp.
gq.
assign end_v_cnt = add_v_cnt && v_cnt == (TVB + TVD + TVFP)-1 ;
gr.
gs.
gt.
gu.
/*******************************************************/
gv.
gw.
//dclk
gx.
gy.
assign lcd_dclk = clk;
gz.
ha.
hb.
hc.
//hsync
hd.
he.
always @(posedge clk or negedge rst_n)begin
hf.
hg.
if(rst_n==1'b0)begin
hh.
hi.
hys <= 0;
hj.
hk.
end
hl.
hm.
else if(add_h_cnt && h_cnt==THPW-1)begin
hn.
ho.
hys <= 1;
hp.
hq.
end
hr.
hs.
else if(end_h_cnt)begin
ht.
hu.
hys <= 0;
hv.
hw.
end
hx.
hy.
end
hz.
ia.
ib.
ic.
id.
ie.
//vsync
if.
ig.
always @(posedge clk or negedge rst_n)begin
ih.
ii.
if(rst_n==1'b0)begin
ij.
ik.
vys <= 0;
il.
im.
end
in.
io.
else if(add_v_cnt && v_cnt==TVPW-1)begin
ip.
iq.
vys <= 1;
ir.
is.
end
it.
iu.
else if(end_v_cnt)begin
iv.
iw.
vys <= 0;
ix.
iy.
end
iz.
ja.
end
jb.
jc.
jd.
je.
jf.
jg.
//lcd_de
jh.
ji.
always @(posedge clk or negedge rst_n)begin
jj.
jk.
if(rst_n==1'b0)begin
jl.
jm.
lcd_de <= 0;
jn.
jo.
end
jp.
jq.
else if(active_area)begin
jr.
js.
lcd_de <= 1;
jt.
ju.
end
jv.
jw.
else begin
jx.
jy.
lcd_de <= 0;
jz.
ka.
end
kb.
kc.
end
kd.
ke.
kf.
kg.
kh.
ki.
/********************************************************************/
kj.
kk.
kl.
km.
kn.
ko.
kp.
kq.
assign active_area = h_cnt>=(THB-1) && h_cnt<(THB+THD-1) && v_cnt>=(TVB-1) && v_cnt<(TVB+TVD-1);
kr.
ks.
kt.
ku.
kv.
kw.
always @(*)begin
kx.
ky.
logo_rom_area = h_cnt >=LOGO_X0 && h_cnt < LOGO_X1 && v_cnt >= LOGO_Y0 && v_cnt < LOGO_Y1;
kz.
la.
end
lb.
lc.
ld.
le.
always @(*)begin
lf.
lg.
e_rom_area = h_cnt >=E_X0 && h_cnt < E_X1 && v_cnt >= E_Y0 && v_cnt < E_Y1;
lh.
li.
end
lj.
lk.
ll.
lm.
ln.
lo.
lp.
lq.
always @(posedge clk or negedge rst_n)begin
lr.
ls.
if(rst_n==1'b0)begin
lt.
lu.
lcd_rgb <= 0;
lv.
lw.
end
lx.
ly.
else if(active_area)begin
lz.
ma.
if(logo_rom_area)
mb.
mc.
lcd_rgb <= {logo_rom_data[7:5],5'b11111,logo_rom_data[4:2],5'b11111,logo_rom_data[1:0],6'b111111};
md.
me.
else if(e_rom_area)
mf.
mg.
lcd_rgb <= {24{e_sel}};
mh.
mi.
else
mj.
mk.
lcd_rgb <= {24{1'b1}};
ml.
mm.
end
mn.
mo.
else begin
mp.
mq.
lcd_rgb <=0;
mr.
ms.
end
mt.
mu.
end
mv.
mw.
mx.
my.
mz.
na.
nb.
nc.
nd.
ne.
always @(*)begin
nf.
ng.
logo_rom_addr = (h_cnt-LOGO_X0) + 120*(v_cnt-LOGO_Y0);
nh.
ni.
end
nj.
nk.
nl.
nm.
always @(*)begin
nn.
no.
e_rom_addr = (h_cnt-E_X0) + 400*(v_cnt-E_Y0);
np.
nq.
end
nr.
ns.
nt.
nu.
nv.
nw.
nx.
ny.
always @(posedge clk or negedge rst_n)begin
nz.
oa.
if(rst_n==1'b0)begin
ob.
oc.
e_rom_addr_low <= 0;
od.
oe.
end
of.
og.
else begin
oh.
oi.
e_rom_addr_low <= e_rom_addr[2:0];
oj.
ok.
end
ol.
om.
end
on.
oo.
op.
oq.
or.
os.
always @(*)begin
ot.
ou.
e_sel = ~e_rom_data[7-e_rom_addr_low];
ov.
ow.
end
ox.
oy.
oz.
pa.
pb.
pc.
fpga_rom u_fpga_rom(
pd.
pe.
.address (logo_rom_addr),
pf.
pg.
.clock (clk ),
ph.
pi.
.q (logo_rom_data));
pj.
pk.
pl.
pm.
e_rom u_e_rom(
pn.
po.
.address (e_rom_addr[16:3] ),
pp.
pq.
.clock (clk ),
pr.
ps.
.q (e_rom_data ));
pt.
pu.
pv.
pw.
px.
py.
endmodule
pz.
复制代码
1.5 效果和总结
以下为工程上板后的现象效果图:
mp801开发板
ms980试验箱
设计视频和源工程代码请到论坛下载学习:http://www.fpgabbs.cn/thread-1162-1-1.html
访问明德扬论坛(http://www.fpgabbs.cn/)进行更多FPGA相关工程设计学习。
温馨提示:明德扬2023推出了全新课程——逻辑设计基本功修炼课,降低学习FPGA门槛的同时,增加了学习的趣味性,并组织了考试赢积分活动
http://www.mdy-edu.com/ffkc/415.html
(点击→了解课程详情☝)感兴趣请联系易老师:13112063618(微信同步)