数字逻辑电路
—课程设计报告
数字逻辑课程设计报告
-----多功能数字钟的实现
一.设计目的:
1.学会应用数字系统设计方法进行电路设计。
2.进一步提高MaxplusII软件开发应用能力。
3.培养学生综合实验能力。
二. 实验仪器与器材:
1、开发软件 MaxplusII软件
2、微机
3、ISP实验板 SE_3型ISP数字实验开发系统
4、打印机
三.实验任务及要求
设计一个多功能数字钟:
1.能进行正常的时、分、秒计时功能。
1)用M6M5进行24进制小时的显示;
2)用M4M3进行60进制分的显示;
3)用M2M1进行60进制秒的显示。
2.利用按键实现“校时”、“校分”和“秒清单”功能。
1)按下SA键时,计时器迅速递增,按24小时循环,并且计满23时回到00。
2)按下SB键时,计时器迅速递增,按60小时循环,并且计满59时回到00,但不向时进位。
3)按下SC,秒清零。要求按下“SA”或“SB”均不会产生数字跳变(“SA”、“SB”按键是有抖动的,必须对“SA”“SB”进行消抖动处理。)
3.能利用实验板上的扬声器作整点报时功能。
1)当计时到达59分50秒时开始报时,在59分50、52、54、56、58秒鸣叫,鸣叫声频为500Hz。
2)到达59分60秒时为最后一声整点报时。整点报时的频率为1Kz。
4.能闹时
1)闹时的最小时间间隙为10分钟。
2)闹时长度为1分钟。
3)闹时声响是单频的。
5.用MaxplusII软件设计符合以上功能要求的多功能数字钟,并用层次化设计方法设计该电路。
1)通过语言实现各模块的功能,然后再画出该电路的顶层图。
2)消抖电路可以通过设计一个D触发器来实现,SA、SB、SC等为包含抖动的诸如信号,而电路的输出则是一个边沿整齐的输出信号。
3) 其他的计时功能、显示功能、多路选择功能、分频功能、报时功能和闹时等功能模块都用VHDL语言实现。简单的与非门是调用系统内部的元件。
四、设计说明
多功能数字钟的顶层图为:
模块功能如下:
1. 计数器、分计数器、时计数器组成了最基本的数字钟计时电路,其输出本应都连接到一个六选一多路选择器上,作为该选择器的输入。但由于考虑到之后的闹时模块有一个时间比较模块,故而将计数器的所有时间输出都先连接到比较器上,然后再连接到六选一的多路选择器上。
2. 频率分频器可分频出标准的1Hz频率信号,用于秒计数的时钟信号;分频出4Hz频率信号,用于校时,校分的快速递增信号。分频出的64Hz频率信号用于对按动“校时”、 “校分”按键消除抖动。
3.select2_1_31是二选一数据选择器,用于对校时、校分与正常计时的选择。
4. D触发器实际上是用来完成消除抖动的。64Hz作为该触发器时钟,SA、SB、SC是包含着抖动的输入信号,而模块的输出则是一个边沿整齐的输出信号。
5.整点报时电路需要500Hz通过一个组合电路完成功能,前五声讯响功能报时电路还需用一个触发器来保证整点报时的时间为1秒。
6、闹时模块闹时时间长度为1分钟,频率为512Hz。是由一个时间设定模块和一个时间比较模块来完成的。
五 框图及相关模块说明:
1、总体框图:
说明:程序在编译后进行下载,自动进入计时状态,sa,sb可分别调时、分两个状态;sc用来对秒进行清零操作;set用来调节闹钟的时间,当set拨开时,sa、sb分别调闹时的时、分两个状态,当set关闭时,sa、sb分别调正常计时的时、分的两个状态;se用于快速结束闹铃,即可以实现提前终止闹铃的功能。
2、模块说明:
1计时模块:
a计时模块VHDL源程序:
计时模块主要完成正常计时功能,它通过小时分钟和秒的关系来完成计时。即由两个模60的计数器和一个模24的计数器,经过联合来完成,其联系模块可在顶层图中看出。计时模块的VHDL源程序为:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity cnt60_31 is -----分和秒的计数
port (clk:in std_logic;
clear:in std_logic;
c:out std_logic;
k1,k0:out std_logic_vector(3 downto 0));
end cnt60_31;
architecture cnt of cnt60_31 is
signal q1,q0:std_logic_vector(3 downto 0);
begin
process(clk,clear)
begin
if(clear='1')then
q1<="0000";q0<="0000";c<='0';
else
if(clk'event and clk='1')then
if(q1="0101" and q0="1001")then-----到59
q1<="0000";q0<="0000";c<='1';
elsif(q1<"0101" and q0="1001")then
q0<="0000";q1<=q1+'1';c<='0';
elsif(q0<"1001") then
q0<=q0+'1';
end if;
end if;
end if;
k1<=q1;
k0<=q0;
end process;
end cnt;
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity hour24_31 is
port (clk:in std_logic;
h1,h0:out std_logic_vector(3 downto 0));
end hour24_31;
architecture hour of hour24_31 is
signal q1,q0:std_logic_vector(3 downto 0);
begin
process(clk)
begin
if(clk'event and clk='1')then
if(q1="0010" and q0="0011")then
q1<="0000";q0<="0000";
elsif(q0="1001")then
q0<="0000";q1<=q1+'1';
else
q0<=q0+'1';
end if;
end if;
h1<=q1;
h0<=q0;
end process;
end hour;
2校时模块:
a 校时模块最初的图形:
3整点报时模块:
a整点报时模块VHDL源程序:
此模块主要完成
整点的报时功能。它通过对预设的时间和计时的时间的比较来完成整点报时,当计时到达59分50秒时开始报时,在59分50、52、54、56、58秒鸣叫,鸣叫声频为500Hz。到达59分60秒时为最后一声整点报时。整点报时的频率为1Kz。该模块的VHDL代码为:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity alert_31 is
port(m1,m0,s1,s0:in std_logic_vector(3 downto 0);
siga,sigb:out std_logic);
end alert_31;
architecture alert of alert_31 is
begin
siga<='1'when(m1="0101" and m0="1001" and s1="0101" and (s0="0000" or s0="0010" or s0="0100" or s0="0110" or s0="1000"))else'0';
sigb<='1'when(m1="0000" and m0="0000" and s1="0000" and s0="0000")else'0';
end alert;
b报时生成器件图:
本模块端口说明:m1,m0,s1,s0分别为分和秒的高低位的输入;siga,sigb分别为500hz和1khz鸣叫的控制信号。
功能实现:定义一个以m1、m0、s1、s0为敏感信号的一个比较进程,在进程判断分是否为59分,若是则判断秒的高位是否是5,若是则如果秒的低位为0、2、6、8则siga为1;若分不是59则判断分和秒是否都为0,若都为0则sigb为1。
a分频生成器件图:
b源代码:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity fenpin_31 is
port (clk:in std_logic; hz512,hz256,hz64,hz4,hz1:out std_logic);
end fenpin_31;
architecture fenpin of fenpin_31 is
signal cc: std_logic_vector(9 downto 0);
begin
process(clk)
begin
if(clk'event and clk='1') then
if(cc="1111111111")then
cc<="0000000000";
else
cc<=cc+1;
end if;
end if;
end process;
hz512<=cc(0);
hz256<=cc(1);
hz64<=cc(3);
hz4<=cc(7);
hz1<=cc(9);
end fenpin;
C分频仿真波形图:
模块说明:由于clk的频率为1024hz,所以可以定义一个std_logic_vecture(9 downto 0),使它不停地从0000000000加到1111111111然后又返回000000000,由于最低位在clk脉冲到来时从0变成1,然后又在下一个脉冲变回0,因此最低位的时钟周期为clk的时钟周期的两倍,它的频率就为clk频率的1/2即512HZ。同理,次高位的频率就为clk频率的1/2*1/2=1/4,用这种方法就可以得到各种能整除1024的频率,从而实现分频功能。
5. 24进制模块
a 24进制器件生成图
b24进制源程序:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity hour24_31 is
port (clk:in std_logic;
h1,h0:out std_logic_vector(3 downto 0));
end hour24_31;
architecture hour of hour24_31 is
signal q1,q0:std_logic_vector(3 downto 0);
begin
process(clk)
begin
if(clk'event and clk='1')then
if(q1="0010" and q0="0011")then
q1<="0000";q0<="0000";
elsif(q0="1001")then
q0<="0000";q1<=q1+'1';
else
q0<=q0+'1';
end if;
end if;
h1<=q1;
h0<=q0;
end process;
end hour;
c 24进制仿真波形图:
本模块端口说明:clk输入端;h1和h0分别为小时的高位和低位输出,用来在数码管中分别显示小时的高位和低位数值,定义为std_logic_vector(3 downto 0).
功能实现:在clk上升沿来临时,如果高位为2,低位为3则高位各低位都变回0,不然再低位进行判断,若低位为9变回0,高位加1,若不为9则低位直接加1即可同样实现.
6.60进制模块:
a 60进制器件生成图:
b 60进制源程序:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity cnt60_31 is -----60进制的分和秒的计数
port (clk:in std_logic;
clear:in std_logic;
c:out std_logic;
k1,k0:out std_logic_vector(3 downto 0));
end cnt60_31;
architecture cnt of cnt60_31 is
signal q1,q0:std_logic_vector(3 downto 0);
begin
process(clk,clear)
begin
if(clear='1')then
q1<="0000";q0<="0000";c<='0';
else
if(clk'event and clk='1')then
if(q1="0101" and q0="1001")then-----到59
q1<="0000";q0<="0000";c<='1';
elsif(q1<"0101" and q0="1001")then
q0<="0000";q1<=q1+'1';c<='0';
elsif(q0<"1001") then
q0<=q0+'1';
end if;
end if;
end if;
k1<=q1;
k0<=q0;
end process;
end cnt;
c 60 进制仿真波形图:
本模块端口说明:clk为脉冲信号输入端;clear为置0端,并且高电平有效,用来在校时时秒位清零;c为进位输入端;k1和k0分别是秒或分的高位或低位,定义为std_logic_vector(3 downto 0),用来分别在数码管中显示读数.
功能说明:以clk和clear而敏感变量,先判断clear是否为1,若为1则k1种k0都为”0000”;如果不为0,则执行累加;否则,再判断高位是否为5,若为5则进位输出为1、低位和高位都赋予0,若不为5则高位加1,低位赋予0.从而实现了60进制的累加.
7扫描显示及译码模块
a动态扫描模块包含一个六路选择器和一个七段译码器,其生成的元器件分别为:
b源程序代码为:
为完成动态显示模块设计了一个六路选择器和一个七段译码器。其源程序代码分别为:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity yima_31 is -------七段译码器
port(d:in std_logic_vector(3 downto 0);
y:out std_logic_vector(6 downto 0));
end yima_31;
architecture yima of yima_31 is
begin
process(d)
begin
case d is
when"0000"=>y<="1111110";
when"0001"=>y<="0110000";
when"0010"=>y<="1101101";
when"0011"=>y<="1111001";
when"0100"=>y<="0110011";
when"0101"=>y<="1011011";
when"0110"=>y<="1011111";
when"0111"=>y<="1110000";
when"1000"=>y<="1111111";
when"1001"=>y<="1111011";
when"1111"=>y<="0000001";
when others=>y<="0000000";
end case;
end process;
end yima;
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity select6_1_31 is
port (clk:in std_logic;
a0,a1,a2,a3,a4,a5:in std_logic_vector(3 downto 0);
sel:out std_logic_vector(3 downto 0);
b0,b1,b2,b3,b4,b5:out std_logic);
end select6_1_31;
architecture select6_1 of select6_1_31 is
signal ss:std_logic_vector(3 downto 0);
signal ww:std_logic_vector(2 downto 0);
begin
process(clk)
begin
if(clk'event and clk='1')then
if (ww<"101")then
ww<=ww+1;
else
ww<="000";
end if;
case ww is
when "000"=>
ss<=a0;
b0<='1';
b1<='0';
b2<='0';
b3<='0';
b4<='0';
b5<='0';
when "001"=>
ss<=a1;
b0<='0';
b1<='1';
b2<='0';
b3<='0';
b4<='0';
b5<='0';
when "010"=>
ss<=a2;
b0<='0';
b1<='0';
b2<='1';
b3<='0';
b4<='0';
b5<='0';
when "011"=>
ss<=a3;
b0<='0';
b1<='0';
b2<='0';
b3<='1';
b4<='0';
b5<='0';
when "100"=>
ss<=a4;
b0<='0';
b1<='0';
b2<='0';
b3<='0';
b4<='1';
b5<='0';
when "101"=>
ss<=a5;
b0<='0';
b1<='0';
b2<='0';
b3<='0';
b4<='0';
b5<='1';
when others=>ss<="0000";
end case;
end if;
sel<=ss;
end process;
end select6_1;
c 动态显示模块的源图为:
本模块端口说明:ao、a1、a2、a3、a4、a5分别为时、分、秒的输入端,定义为std_logic_vector(3 downto 0);sel为七端显示管的输出,定义为std_logic_vector(3 downto 0); bo、b1、b2、b3、b4、b5分别为地址扫描端,定义为std_logic_vector(5 downto 0),某一时刻只有一个为1,对应的数组号即为当前扫描的数码管的编号.
六.设计中出现的问题以及体会
这次多功能数字钟的课程设计中,我出现了很多问题,尤其是当一个程序写完之后进行编译的时候出现了很多的错误,包括语法错误和算法错误,有时候在改正一个错误后又出现了很多错误,当时和灰心,但在老师和同学的帮助下,我解决了这个问题。语法错误相对比较好修改,但是算法错误就比较难找出了,比如在画顶层时,当把器件连接起来进行下载编译时,出现了比较多的问题,比如:数字钟不计数、扬声器从一开始就一直在响等等问题,这些都让我困惑了很久,后来在同学的帮助下找到了问题所在并进行了一些修改,知道问题全部解决了,这才松了口气。
在这次的数字逻辑电路的课程设计中,我出现了非常多的错误,这才深深的感觉到自己在学数字逻辑电路这门课方面的学习是非常欠缺的。
以前上课的时候只是对课本或者老师的课件进行理论学习,很少动手操作,了解的也只是单个的器件或者的某个程序的一部分,这显然是不够的,而在为期一周的课程设计中,我学会了如何利用基本器件制作综合器件,如何通过简单的器件和门电路的综合实现某种功能,并对MaxplusII软件操作有了进一步了解和熟悉。
通过这次的课程设计之后,我们的数字电路、数字系统的综合设计能流利进一步提高了,同时让我们对isp器件的开发工具—Synario软件的开发应用能力,虽然只是了解到冰山一角,但我相信在以后的学习过程中,我们一定会好好学习相关的知识以及我们其他专业课程的相关知识,争取能够更进一步的了解MaxplusII软件和isp器件的开发工具—Synario软件的开发和应用,最好能够是理论联系实际的,既能够在理论方面了解又能够实际动手自己实现一些功能。相信这也是我们学习的最终目的。