FPGA电子秒表计时器verilog试验报告文档格式.docx
《FPGA电子秒表计时器verilog试验报告文档格式.docx》由会员分享,可在线阅读,更多相关《FPGA电子秒表计时器verilog试验报告文档格式.docx(14页珍藏版)》请在冰豆网上搜索。
ej.se
if(CountJ)IV<
(CUCFzeq;
/(,*0UT.Fre<
i)-1>
)CanntJHV+l11;
else
begin
Connt_DIV<
CLK_Out<
=*CLK_Ou七;
endl
endmodnLe
原理:
输入的100MHz的信号为CLK.lOOMHz每当CLK.lOOMHz±
升沿来时,Count.DIV计数加1,且每当Count.DIV=100M/(2*100)=0.5M时,CLK.Out取反一次并且Count.DIV<
=0,这样会得到一个100Hz的信号。
当需耍得到4000Hz的clk_seg时.在顶层模块中修改parameterOUT_Freq=4000;
这样,每当Count^DIV=100M/(2*4000)=12500时,CLK.Out取反•次并且Count.DIV〈二0,这样会得到-•个4000Hz的信号。
在主程序中修改参数如下:
Di*riderDO(CLK^IOOMHerst,elk);
defpa.E*amDO4N=tDO•CLK^Freq—L二:
=二几
DO.OUT.Freq-.0;
Di?
videitDI(CLK.IOOMHePxstfclk.seg);
defpa^ajnDI+N=,DI*CLK_Fxeq=Ln30000'
DI*OUT.Fjteq—10;
2;
仿真时,为便于观察,在testbench中,将CLK.100MHZ的周期设为2ns:
always#1CLK.lOOMHz<
=“CLK_100MHz;
并修改参数如下,验证分频模块的正确性(图中数字16,8,1只农示频率的倍数关系,并非真
正的频率)
DzLTFZ.cleirDO(CLK..10GmHe,匸日七<
c丄lc)fdefparajnDO・M=50”
DO”CTiKAFrAAl丘,
DO.0UT_Frcq=l;
Divider口1(亡T>
F_丄0OMHh:
rst,clk_seg);
defpara_nlI>
1_・N—50fDI.CLKFreq=lfaf
DI•OUT_Frecq=a;
其仿真图如下图:
L7a7e_:
e3VCL?
-_lDQr.
'
mTTnTTTTJTTTTLTTTITTTTnTTnrLJ
LrJ-L-T-LLJ-OTO
的周期为4ns,elk的周期为32ns,符合
从图中可以看出,CLK.100MHZ勺周期为2ns,clk_seg倍数关系,故分频模块的正确性得到验证。
2)七段数码管显示模块
运用4个七段数码管,前两个显示秒的十位和个位,后两个显示小数点后两位,因为要显示
4个数码管,I大I此用4000Hz的频率扫描4个数码管,使每个数码管每隔1ms亮一次。
代码如下:
MloduleSecondj,Sscondlrclk^jeg,2cajiTEK_SEG_in,dot};
inputelkaeg:
inputEX.SEG.lii;
■■数三二齊■吏能
input[:
]SecondCfSe'
andl;
outputregl:
]oSSG;
outputregj:
]scan;
outputreqdaN//衣示小数点
reg[:
)ent・:
reg:
.IiDIt*
alwaysd(pcs'
d*ecll_3Eg)
cnt<
=ciLJt+:
end
always3f「.nt)
aa*e(unt)
beginscan<
-■•:
二l_K;
iD:
3[:
:
]<
-3eocnd0['
];
dot<
T•;
2*b:
lbegin3Gan<
=fl♦bllll11C1;
iDIG[3:
=SecC!
rLdO['
:
4]:
dot<
=lrbl;
endbe*in
scan<
sa'
bll11:
iDI5[:
J<
=Seccndlf3:
?
]:
*0A<
sA£
ll_5£
6_l□:
endbegin
29bllscar.<
=:
‘,‘]_、;
lDIS[:
«
Sec:
ndl[*:
]:
6ot<
endjCAse
且・(1DLG.ENSEGin)
if(EN_SEG_in)begin
c&
se(iDIG)
4fhC:
QSEG<
*7*blOO_OLOO:
4rhlzoSE^^bllFCOl:
•一:
eSEG<
='
t21・」1_:
:
4'
h3:
oSEG<
-7'
bdlPOOO/
■'
h.4:
oSE4<
-♦t331_11・C1:
='
二;
4xh€:
aSE(X=7'
bOOO0C10:
H'
oSE&
<
匕11二_1二I二0:
4:
h0SQSEGL'
bOOCTOOO:
h?
oSE(X=・EDO-1」・CO:
HefauJ.七:
t>
SEG*C=7'
匕111111T
endcase
elseBecfinoSEG<
=;
endmodule
3)十进制计数器模块
因为每个数码管的计数规律都为:
0-1-2-3-4-5-6-7-8-9-0-1……,所以采用十进制计数器。
传入的参数stop农示暂停信号,若有暂停信号或没有使能,则保持计数不变。
rnoBTilecou.il七Q匸10(Q匚吕七」它凶sdk(mtop》:
inputelk,rst,EN"
stop;
outputreg[■-.Q;
alwaysQCposedgeI:
lkorpcsedgexst)begin
if(rstJC"
二41dO;
elseif(stopI|兀EM}X=Q:
elseif(Q=l'
1dO;
elseQ<
=Q"
M・dl;
endnodule
4)主程疗:
模块代码如下:
1tuLS\ale1111/二m
module57;
h<
:
u玮,sh•證Qr5:
a»
?
filarr;
・d:
t);
input卫lCIMEi.rs.,已二岂二二壬Sl+fl开始,北呼表示曹玉计寸结更
output16:
OJHEXO:
output[:
J3*ai:
outputtegalai!
ii:
outputdot:
//才嗷点
wirecllt*Ikseg;
wire[:
]3ecDndOrSec3ndl:
wireK_9T5_in:
reg5N.SEG:
DividerD0(^LK_10iHHz.ist,elk):
defparanDlLK=:
.*
BO.3LK_?
req=190:
30C:
CO.
*17iderCl5sg):
■■d
defpdramDLN=j
DI.MJretrKO^.X:
Ci.QO_Freq=r:
alvays'
{paaedgerstorposedgefinishorposedges:
art)begin
iffrstl
EK_SEG<
;
alarr<
nd
if(Start)
3J_SE(X-rbl;
if(finish)alamfrrtl;
else:
elsebeginIKSZG<
alam=;
counterlO01(SeccndO*rst'
3tartfclk,3toellfinish);
counterlOC2(Seconder:
4]frstf(SM0ndD[2:
[]=}rclk,3t:
pIfici/h);
countetlOC3(Sec2nd.1[:
.1/izt,(Sec2ud0=:
>
.:
);
elk,stop11finieh);
ounterl0(Se:
ndl[:
];
rszt(Seczndl[■:
‘]=djMSecradO—h?
tjclk^tcpllfinuh};
assignENSEGin=ENSEG;
SEG7LUISEGO(HEXO:
SBcandOr£
eccndl,dkHWHcanJEBSEGiiUdnt);
endnadule
代码分析:
SecondO[3:
0]示百分位的数字,SecondO[7:
4]示十分位的数字,Secondl[3:
0]衣示个位的数字,Secondl[7:
4]农示十位的数字。
如果start为1,即计时开始,则开启数码管使能,数码管开始显示计数值,如果finish
等于1,表示计时完成,则alarm=l;
点亮报警灯。
接下来调用四个counterl0模块,通过控制其使能信号实现正确计时,第-•个(C1)的使能信号为start,也就是按下开启键便开始计时,第二个(C2)的使能信号为SecondO[3:
0]=4'
d9,也就是当百分位计时到了9,且下一个时钟的上升沿到来时,则十分
位加1;
第三个(C3)的使能信号为Second0==8h99,也就是当小数点后计时到了99,且下
一个时钟的上升沿到来时,则个位加1;
第四个(C4)的使能信号为Secondl[3:
0]=4'
h9&
&
Second0=8h99,也就是当小数点后计时到了99而且个位计数到了9,且下-•个时钟的上
升沿到来时,则十位加1;
这样,就能确保计时的准确性。
TestBench
*timescaleIns/Ins
modulestopwatch_test:
regCLK_100MHz:
regrst:
regstart:
regstop;
regfinish;
wire[6:
0]HEXO;
wire[7:
0]sean;
wirealarm;
wiredot:
stopwatchuut(・CLK_100MHz(CLK_100MHz),.rst(rst),
・start(start),・stop(stop),・finish(finish),・HEXO(HEXO),・sean(sean),・alarm(alarm),・dot(dot)
);
initialbeginCLK.lOOMHz=0;
rst=0;
start=0;
stop=0;
finish=0;
#5;
rst=l;
rst=0;
start=rbl;
#64;
stop=rbl;
stop=0;
#6400;
finish=fbl;
#700;
endmodule
always#1CLK_100MHz<
CLK_100MHz;
仿真波形
1.暂停键
氏叩
A•
1
>切「'
圧屯:
址IU1巴tMO*ID01
訓删旳
从图中可以看出,当stop=0即暂停键没有按下的时候,只要elk上升沿一到,SecondO的数值就加一:
当stop=l即暂停键按下的时候,即使elk上升沿到了,SecondO也不变,也就是暂停计时了。
3•进位
1)
StD
1II
—
1p
/stopMdi_tesVuut/DOOIOH
tnnd
n(QOOLO
IpOf11
/讪atchjte軌哪000(10
OOOO
这是从Second0[3:
0]向Second0[7:
4]进位,从图中可以看出,Second0=8'
bOOOOJLOOl时,当下一个elk±
升沿到来的时候,SecondO变为8'
b0001_0000,即实现了从0・09到0.10的进位。
2)
*1stopwatch_test5r
Stl
L
r
」jstopwatch_test/uut/Se
00000100
10011000
11001
•
■
21
/stopwatch_test/uut/S
00000001
jlUQBOOOQ
IQ
aooo
这是从SecondO向Secondl[3:
0]进位,从图中可以看出,Second0=8,bl001_1001Ihf(也就是计时到了99),当下一个elk上升沿到来的时候,SecondO变为8fb0000_0000,Secondl[3:
0]由0变成了1,即实现了从0.99到1.00进位。
2.PWM波产生器
本实验的思路较简单,在-•个固定的时间间距内,当Count_DIV的值从0计数到duty时,输出电平反转;
计数到这个时间间距后,电平再反转,将Count_DIV置零,并将duty的值增加10%。
然后下一个循环开始,以此达到输出占空比按10賀递进的PWM波的目的。
实验代码:
timescaleIns/Lps
modulePWMtCL'
100MHz/st,匚LK_0ut);
parameterN=i;
parameter匚LK_Fii?
eq二1000JU00J;
parameter0UT_Freq=L00C:
inputCLK_100MH2fr£
t:
outputr«
gCLK_0ut;
reg[N-li0]Q3unt_DIU;
reg[NT:
C]duty;
always(g>
(po^edgeCLK_100MHi
Iiiffrst)begin
CLK_0ut<
=0;
duty〈二;
Count_DIV=0;
elsebegin
用匚ount_DIV<
(CILK.Freq/(7*0UT_Freq)・))
Couiit.DIV=C0uni_DIV+TbL:
iflCount_DIV==duty)beginCLK_Out〈二”CLK_Out;
endelse;
CountDIV=J:
=%LK_0ut:
duty<
=(dut\-二(CLK_F、q/(2・0UT_Fr己q)))?
duty+CLK_Freq/[_0*0UT_Freq);
andendendendmcdule
Testbench:
z,timescaleIns/Ins
module垃曰tf
regCLK_100MHzrrst;
wireCLK_0ut;
PWMPC(CLK100MHZ/rst,CLKQut);
initialbeginCLK_100HHa-(}7
rsr二t);
巳口(1
=,CLK.lOOMHz:
c:
ndniodule
仿真波形:
从图中可以看出,输出波形的占空比以10%逐渐增加,可知代码正确。
5.调试过程及实验结果
引脚分配如下:
NET^CLK.IOOMH?
4IOSTANDARD=LVCMOS33|L0C="
E3w:
NET♦Srst"
IOSTANDARD=LVCMOS33|LOC’VLO"
NET'
rst"
CLOCKJ>
ED1CATED.F1OUTE=FALSE;
NET〃tart°
IOSTANDAFtD^LVCMCSSSILOC-"
U11**;
NET1rstart<
TCLOCKDEDICATEDROUTE=FALSE;
NET"
stop"
IO5TANDARD=LVCMOS33|L0EP12"
NLT^stop*!
LOCKDLDICAJLDROUTL-FALSE;
NET■finiih"
IDSTANDARD^LV匚弓IOC=‘‘H6"
NET■啊nlmKCLQCKJ)I01匚ATfD_R(31JTE-TAISE;
NETNlarnTIOSTANDARD=LVCM0S33|LOC^ll"
NET*HEXOIOJTIOSTANDARD=LVCMOS33|LOC二“TdO"
NET,wHEXOr订‘IQSTANDARD=LVCM0S33ILaC-R10F,;
NET"
HEX0r2]"
IOSTA忖口找尺口二1」匚20332|LOC=*K164;
NET■'
HEX0[3r・I06TANDARD=LVCM0533|LOC^KIJ*;
NET”HE)CCI4]"
10兮TAMDARD=LV(ZIVIC)%Am|I
QP15八;
NET■41EX0[S]°
I0STANDARD-LVCM0S33|I0C-1T1K;
NrT‘T1匚|LaC-1L1S°
NET*'
dot*"
IOSTANDARD=LVCMOS33|LOOMIS1f;
NET"
scanHOj"
I0STANDARD=LVCIVI0S33|LOC=*‘J171;
NET=1an|(1]』I0S1ANDARD=LVCM0S33|LOC*JIS'
NET匕can(2厂IOSTANDARD=LVCMO533IL0C=**T9"
NET"
s丨nn]刁:
T|UDI=・\i工4”.NFT"
sriinH]*I05TANDARD=IVQI0S33|L0C=“P14"
NET*5can(5]*IOSTANDARD-1VCM0S33ILOC-1T14"
;
NETT"
scon(6)'
I05TANDARD-LVCM0533|LOC-*1K2"
;
NET1'
sGar471*1iaSTANDARD=LVCMOS33IL0UIB"
调试过程及结果
在调试过程中,我碰到了如下问题,并找到了相应的解决方案:
1•问题:
按下start按钮后,数码管没有显示。
解决方案:
检査代码后发现,原来是忘记开启数码管使能(EN_SEG=I,于是在原代码中
加上后解决了这个问题。
2•问题:
实验中发现,本来只要一个小数点亮,但四个数码管的小数点都亮了起来。
在SEG7_LUT.v(数码管模块)中,扫描数码管时,将其他三个数码管的小数点的电平设为无效电平(dot=l),而需要显示小数点的那个数码管的dot=~EN_SEG_in也
就是当数码管使能(EN_SEG_in=l)时,小数点亮:
不使能则不亮。
修改后的代码如下:
always"
(posedgeclk_seg)
rnt<
=<
nt+:
endalways®
(crit)
case(ent)
29bOO:
beginscan<
*81bllIL1110"
lDIG[3M1)<
SecondO[.-l)"
or=lbljcnd
i2rb01:
=S*bl111_:
■:
iDIGpf*AsSecondOpz*Jjdot*slnJcnd
=111l_li1:
iDIGl:
Z<
=Secandl?
Z:
=**EN_SEG」n:
end;
beginSC11W:
iJiu[:
5tLuridi[:
clot<
2.PWM波产生器
NEThCLK.100MHznIOSTANDARD=LVlMOBS|LQC,E31
"
rsflOSTANDARDlVCW/SS|LOC二"
V10"
NETJrsfCLOCKDEDICATEDROUTE=FALSE;
CLK—Oirt11IOSTAINDARD=LVCMOS33|LQC=rlG6rlJ
调试步骤:
1.将开发板与示波器共地,并将开发板的G6引出与示波器的CH1相
连,在示波器上观察波形,实现了预期结果。
6.实验的收获、体会与改进建议
在这次实验过程中,我掌握了verilog程序的模块化设计方法和数码管的扫描。
以下是我的一些感悟:
1.电了秒农实验中,通过使能信号的灵活运用从而达到控制计数的目的,可谓巧妙。
不仅代码简洁,由此设计出的电路也更简单和易于调试。
2.模块化设计能减轻开发人员的难度,逻辑更淸晰。