EDA四位十进制频率计课程设计报告解析Word格式.docx
《EDA四位十进制频率计课程设计报告解析Word格式.docx》由会员分享,可在线阅读,更多相关《EDA四位十进制频率计课程设计报告解析Word格式.docx(16页珍藏版)》请在冰豆网上搜索。
2、四位十进制频率计顶层文件原理图如下:
图3.2顶层文件生成4位十进制频率计外部接口图
3、本设计中重要端口说明:
Clk_1hz:
给Tctl模块提供1hz的频率输入。
Fin;
被测频率输入。
scan_led:
给scan_led模块提供扫描输入频率输入。
bt[1..0]:
片选信号输出。
Sg[6..0]:
译码信号输出。
Cout:
进位输出
四、各个模块的设计说明及设计步骤
1、顶层文件原理图设计:
图4.1顶层文件原理图
2、x4Cnt10模块说明
x4Cnt10为含异步清零和同步时钟使能的十进制计数器,采用级联的方法进行计数,计数范围与所用x4cnt10级联个数有关,本次设计采用的是4个cnt10的级联,所有测频范围是0—9999hz。
仿真时序图如下:
图4.2x4Cnt10仿真波形图
3、Tctl模块说明
根据频率的定义和测量的基本原理,测定信号的频率必须有一个脉宽为1秒的对输入信号脉冲计数允许的信号;
1秒计数结束后,计数值锁入锁存器信号和为下一测频计数周期做准备的计数器清零信号。
这三个信号可以由一个测频控制信号发生器Tctl产生,其设计要求是Tctl的计数使能信号en能产生一个一秒脉宽的周期信号,并且对频率计的每一计数器cnt10的en使能进行同步控制,当en高定平时,允许继续:
低电平时停止计数,并保持其所计数的脉冲数,在停止计数期间,首先需要一个锁存信号load的上升沿将计数器前一秒钟的计数值锁存进各锁存器reg16中,并由外部的译码器译出并显示计数值,锁存信号之后,必须有一个清零信号rst对计数器进行清零,为下一秒的计数操作做准备。
控制模块Tctl时序仿真:
图4.3频率计测频控制器Tctl侧可控时序图
图中clk的频率为1hz,en的高电平程序时间为1秒,此时计数器开始工作,当en低电平时停止计数,并将计数值经过load锁存的reg16中最后通过scan_led译码器显示输入,en的计时长度为一秒,即en的周期为2秒,计数器在en高电平计数完成即en从高电平跳跃到低电平时将计数结果锁存在reg16中,rst在满足clk和en均为低电平的时候对已锁存入锁存器的计数信号进行清零工作,为下一个计数周期作准备。
4、锁存器reg16模块的说明
设置锁存器的目的是使显示的数据稳定,不会由于周期性的清零信号而不断闪烁,每次显示数据位上一计数周期锁存的计数值。
Reg16锁存器时序仿真图:
图4.4reg16锁存器仿真波形图
5、scan_led模块说明
动态显示是把所有的led管的输入信号连在一起,每次向LED写数据时,通过片选信号选通其中一个Led管并把数据写入,因此每一个时刻只有一个Led是亮的。
为了能够程序看到led上面的显示内容,必须对led管进行扫描,即一次循环点亮各个led管,利用人眼的视觉暂留,加上发光器件的余晖效益,在一定的扫描频率下,人眼就会看到多个led管一起点亮。
扫描的大小必须合适才能达到很好的效果。
如果扫描频率太低,就会产生闪烁;
而扫描频率太高会造成Led的频率开启和关断,增加led的功耗。
通常扫描频率选择50Hz比较合适。
本次设计为4为led动态扫描输出,clkwie扫描时钟,考虑到cnt8的分频作用,此时设计采用的频率为200hz:
sg[6..0]为当前正在显示的led地址的已译码数据;
bt[1..0]为输出的片选信号,决定某led在某时某刻显示数据:
din[15..0]为4为一组的bcd码,共4位供显示输出的数据输入,scan_led的内部以下三个进程:
计数模块扫描时钟发生器,多路选通器模块和译码模块。
led动态扫描输出scan_led时序仿真图;
图4.5动态扫描仿真波形图
Clk_1hz输入周期为1hz;
Fin为测量频率,频率范围是100-9999hz,此次波形仿真设计时间为1khz;
Clk为扫描时钟,周期为200hz;
Sg为输出led七段显示译码结果,bt为输出片选信号,由波形仿真图可以看出片选0(00)时led显示为0,片选1(01)时led显示为0,片选2(10)时led显示为0,片选3(11)时led显示为1;
即此时频率计计数频率为1000hz,与实际输入频率相同。
Clk_1hz的1hz输入频率通过DE2内部clock_50的50M晶振分频来实现。
输入频率信号和扫描频率也由50M晶振分频得到,又由于仿真设计中采用的是一个led现实动态数据,所以下载到DE2板上是还要进行动态显示电路的设计。
6、分频器:
(可以通过改变不同的cout值来进行不同的分频)
分频器时序仿真图:
图4.6分频仿真波形图
7、动态显示时序仿真图
图4.7动态显示仿真波形
8、调用各子模块编译仿真,时序仿真图如下
图4.8调用各子模块时序仿真图
9、编译仿真完成后,定义管脚,如下图所示:
图4.9引脚定义
10、定义完引脚后,开始下载设计文件,在试验箱进行硬件测试并完善设计。
11、预测结果:
试验箱选择模式6,1HZ测频控制信号由clock0输入控制,待测信号由clock5输入,可选择相应的频率值,在数码管显示器上显示相应的频率值。
五、总结
通过这次的eda设计使我更加的了解了vhdl语言的应用,由于书上设计的是由数码管进行动态显示,但是这种情况下不利于读取数据,所以我们后来设计成由四个七段数码管静态输出结果的方式,但书上没有源程序可以参考,所以只能通过自己在网上查找资料并尝试,在这其过程中出现了很多错误,我们一步步更改,要求我们修改编写程序时要细心,谨防出现细小的错误。
尤其是实用语句的时候要考虑全面,不能前面写过忘记结尾,例如在使用if语句时要注意endif的个数与前相对应,不能少也不能多。
在设计时还要考虑到设计引脚是否能够在试验箱上找到。
最后在老师的指导下我们总算是顺利地完成了这次的课程设计。
参考文献
[1]潘松,黄继业.EDA技术实用教程(第二版).科学出版社,1998。
[2]宋万杰,罗丰,吴顺军.CPLD技术及其应用.西安:
西安电子科技大学出版社,1999。
[3]徐志军王金明.EDA技术与PLD设计.人民邮电出版社。
[4]康华光.电子技术基础(数字部分).高等教育出版社。
[5]XX文科4位十进制频率计设计。
附录:
四位十进制频率计顶层文件源程序如下:
libraryieee;
useieee.std_logic_1164.all;
useieee.std_logic_unsigned.all;
entitydcis
port(fin,clk_1hz:
instd_logic;
ledout:
outstd_logic_vector(27downto0));
enddc;
architectureoneofdcis
componentTct1---Tct1元件声明
port(clk:
instd_logic;
en,rst,load:
outstd_logic);
endcomponent;
componentx4cnt10----x4cnt10元件声明
port(clk,rst,en:
q0,q1,q2,q3:
outstd_logic_vector(3downto0);
cout:
componentreg16---reg16元件声明
port(load:
di:
instd_logic_vector(15downto0);
dout:
outstd_logic_vector(15downto0));
componentscan_led---scan_led元件声明
port(din:
sg:
outstd_logic_vector(6downto0);
bt:
outstd_logic_vector(1downto0));
signalx,z,f:
std_logic;
signalh:
std_logic_vector(3downto0);
signalg0,g1,g2,g3:
signalh0,h1,h2,h3:
signalleds:
std_logic_vector(27downto0);
begin---元件例化产生电路,完成设计
u1:
Tct1portmap(clk=>
clk_1hz,en=>
x,rst=>
z,load=>
f);
u2:
x4cnt10portmap(clk=>
fin,rst=>
z,en=>
x,q0=>
g0,q1=>
g1,q2=>
g2,q3=>
g3);
u3:
reg16portmap(load=>
f,di(3downto0)=>
g0,di(7downto4)=>
g1,di(11downto8)=>
g2,di(15downto12)=>
g3,dout(3downto0)=>
h0,dout(7downto4)=>
h1,dout(11downto8)=>
h2,dout(15downto12)=>
h3);
u4:
scan_ledportmap(din(3downto0)=>
h0(3downto0),sg(6downto0)=>
leds(6downto0));
u5:
scan_ledportmap(din(7downto4)=>
h1(3downto0),sg(6downto0)=>
leds(13downto7));
u6:
scan_ledportmap(din(11downto8)=>
h2(3downto0),sg(6downto0)=>
leds(20downto14));
u7:
scan_ledportmap(din(15downto12)=>
h3(3downto0),sg(6downto0)=>
leds(27downto21));
ledout<
=leds;
end;
计数模块x4cnt10的源代码程序:
entityx4cnt10is
port(clk,rst,ena:
--端口定义
bufferstd_logic_vector(3downto0);
--分别定义四个计
数端口,用于4
endx4cnt10;
个cnt10的设计
architecturethreeofx4cnt10is
signalen1,en2,en3:
std_logic;
---使能信号声明
begin
process(clk,rst,ena,q0)---控制q0端的十进制计数
ifrst='
1'
thenq0<
="
0000"
;
elsifclk'
eventandclk='
then
ifena='
ifq0="
1001"
thenq0<
="
elseq0<
=q0+1;
endif;
endif;
thenen1<
='
elseen1<
0'
endprocess;
process(clk,rst,en1,q1)---控制q1端的十进制计数
begin
ifrst='
thenq1<
ifen1='
ifq1="
thenq1<
elseq1<
=q1+1;
thenen2<
elseen2<
process(clk,rst,en2,q2)--控制q2端的十进制计数
thenq2<
ifen2='
anden1='
then
ifq2="
thenq2<
elseq2<
=q2+1;
thenen3<
elseen3<
process(clk,rst,en3,q3)---控制q3端的十进制计数
thenq3<
ifen3='
anden2='
ifq3="
thenq3<
elseq3<
=q3+1;
thencout<
elsecout<
endthree;
---将设计元x4cnt10的声明装入my_pkg程序包中
packagemy_pkg1is
componentx4cnt10
endcomponent;
end;
控制模块Tctl源代码程序;
Libraryieee;
Useieee.std_logic_1164.all;
Useieee.std_logic_unsigned.all;
EntityTct1is
Port(clk:
---端口定义
ena,rst,load:
EndTct1;
ArchitectureoneofTct1is
Signaldivclk:
---divclk信号声明
Begin
Process(clk)
ifclk'
thendivclk<
=notdivclk;
---clk上升沿时,divclk取反
endif;
Endprocess;
Process(clk,divclk)
Ifclk='
anddivclk='
then---clk和divclk同时为0时,rst置1,否则rst清0
rst<
Elserst<
Endif;
Load<
----将divclk取反赋值到load端,将divclk的值赋给ena
ena<
=divclk;
endone;
Reg16锁存器源代码程序:
Entityreg16is
Port(load:
----端口定义
din:
instd_logic_vector(15downto0);
dout:
outstd_logic_vector(15downto0));
Endreg16;
Architectureoneofreg16is
Process(load,din)
if(load'
eventandload='
)then---load为上升沿时,把din值锁存到dout中
dout<
=din;
endprocess;
Endone;
led动态扫描输出scan_led源代码程序;
Entityscan_ledis
--16位的输入端口
sg:
outstd_logic_vector(6downto0);
--7位的输出端口(译码地址)
outstd_logic_vector(1downto0));
--2位的输出端口(片选信号)
Architectureoneofscan_ledis
Signalcnt8:
std_logic_vector(1downto0);
---信号声明
Signalq:
p1:
Process(cnt8)---多路选通模块
casecnt8is---通过cnt8的值来选择片选信号bt
when"
00"
=>
bt<
q<
=din(3downto0);
决定某led在某时某刻的
01"
=din(7downto4);
显示数据
10"
=din(11downto8);
11"
=din(15downto12);
whenothers=>
null;
endcase;
endprocessp1;
p2:
process(clk)---计数模块扫描时钟发生器
begin---时钟信号clk有效上升沿时,cnt8开始计数
thencnt8<
=cnt8+1;
endprocessp2;
p3:
process(q)---译码模块
caseq(3downto0)is---通过q的值来选择sg的led地址的已译码数据
sg<
0111111"
0001"
0000110"
0010"
1011011"
0011"
1001111"
0100"
1100110"
0101"
1101101"
0110"
1111101"
0111"
0000111"
1000"
1111111"
1101111"
endprocessp3;
分频的主要源程序:
Entitycountis
Port(clk50:
qlk:
Endcount;
Architectureoneofcountis
HZ:
process(clk50)
Variablecout:
integer:
=0;
---设置变量cout,且其初值为0
Ifclk50'
eventandclk50='
then---时钟信号clk50上升沿时,cout值就增1
cout:
=cout+1;
Ifcout<
=24999thenqlk<
---cout<
=249999时,qlk置0
Elseifcout<
=49999thenqlk<
---24999<
cout<
=49999时,qlk置1
Elsec