当前位置:文档之家› EDA设计数字时钟

EDA设计数字时钟

EDA设计数字时钟
EDA设计数字时钟

EDA设计Ⅱ实验报告

——多功能数字钟设计EDA设计Ⅱ实验报告

——多功能数字钟设计

目录

一、摘要 (1)

二、关键字 (2)

三、正文 (2)

1、设计要求说明 (2)

2、方案论证 (3)

3、各子模块设计原理 (3)

(1)计时电路 (3)

(2)脉冲发生电路 (6)

(3)译码显示电路 (8)

(4)报时电路 (12)

(5)校分电路 (13)

(6)清零电路 (14)

(7)闹钟电路 (15)

4、整体电路图 (19)

5、调试 (19)

6、仿真 (20)

7、编程下载 (20)

四、结论 (20)

五、实验感想 (20)

1、实验中遇到的问题及解决方法 (20)

2、实验的收获与感受 (21)

六、参考文献 (21)

一、摘要

FPGA(Field Programmable Gates Array)现场可编程门阵列与CPLD(Complex Programmable Logic Device)复杂可编程逻辑器件都是可编程逻辑器件,是在PAL、GAL等逻辑器件基础之上发展起来的,规模比较大,适合于时序、组合等逻辑电路应用场合,不仅可编程性好并且实现方案容易改动,是电子工程设计过程中很重要的器件之一,对其编程环境的熟练使用也随之成为电子工程设计人员必备的素质之一。

本文详细阐述了如何在QuartusII软件平台下用原理图及VHDL语言的方法对逻辑器件进行编程,并下载到SmartSOPC实验系统中实现一个多功能数字钟的设计。

该多功能数字钟在正常时分秒走时的基础上还能够完成计星期、校分、校时、保持、清零等各种调整功能,且能够整点报时、设置闹钟时间并在所预置的时间响起音乐彩铃。

Abstract

FPGA (Field Programmable Gates Array) field programmable gate array and CPLD (Complex Programmable Logic Device) complex programmable logic devices are programmable logic devices, which develop based on the PAL, GAL and other logic devices.They are relatively large-scale and are suitable for timing, and combination logic circuit applications.Their programmability is not only good but also easy to implement changes.It’s one of the important electronic devices of engineering design process, and the skilled use of their programming environment will become one of the essential qualities of a a electronic engineer.

This paper describes how to program under the software platform QuartusII by the means of schematic or VHDL, and download it to the SmartSOPC versatile experimental system to implement a digital clock design.

The multi-function digital clock is able to complete the week counting, hours correction, minutes correction, time holding, clearing and other adjustment functions.It can also ring every hour, and the music ringtones will ring at the time which is set by the alarm.

二、关键字

现场可编程门阵列FPGA(Field Programmable Gates Array)

多功能数字钟(multi-function digital clock)

校分(minutes correction)

校时(hours correction)

保持(time holding)

清零(clearing)

闹钟(alarm)

QuartusII

VHDL

三、正文

1、设计要求说明

本实验要求利用QuartusII软件平台设计一个多功能数字钟,并下载到SmartSOPC实验系统中,要求该数字钟在控制电路的作用下实现以下基本功能:

(1)可以完成00:00:00到23:59:59的计时功能,分别由六个数码管动态显示时分秒的计时;

(2)保持功能,即可以随时控制数字钟停在某一时刻不动,取消控制后数字钟仍能继续正常计时;

(3)清零功能,即可以随时控制数字钟的时分秒全部复位清零;

(4)快速校时、校分功能,即可以随时控制数字钟的时位或分位不受计时时钟的控制而快速校正到想要达到的位置,并且校分的同时不进位不影响时位的正确性;

(5)整点报时功能,即当时钟计到59’53”时开始报时,在59’53”、59’55”、59’57”时报时频率为512Hz,59’59”时报时频率为1KHz;

(6)闹钟设定功能,即可以任意设定闹钟时间使数字钟报时。

在实验中我们在基本功能的基础上,又添加了以下功能:

(1)计星期功能,即除显示时分秒正常走时之外同时显示星期,并同样能够实现校星期的功能;

(2)闹钟显示功能,即可以通过开关控制显示闹钟时间或显示正常走时时间;

(2)彩铃功能,即到达闹钟设定时间时音乐报时。

2、方案论证

为了实现以上多种功能,采取自顶向下的设计思路,先将该数字钟划分成若干个部分,再逐一细化设计,直至最终完成。

多功能数字钟整体设计基本结构框图如下:

如上图所示该数字钟共有以下六个部分组成:

(1)计时电路

(2)脉冲发生电路

(3)译码显示电路

(4)报时电路

(5)校分电路(包含校分、校时、校星期)

(6)清零电路

同时还附加了闹钟电路。

3、各子模块设计原理

(1)计时电路

a.基本原理

计时电路包含了时、分、秒的分别计时及进位:

首先,用三个计数器实现计时,分、秒均各自采用模六十的计数器,小时采用模二十四的计数器,则实现了六十分、六十秒、二十四小时的分别走时;

第二,秒、分、时三个计数器之间均采用同步的方式连接,即在同一个时钟的作用下,通过上一位的进位端驱动下一位的使能端,从而实现了六十秒进一分、六十分进一小时。

第三,为了实现保持功能,将保持开关信号与秒位的时钟端相与,当停秒时分时即停。

b.实现方式

本实验采用VHDL语言编程的方式实现了模六十和模二十四计数器,封装后经过连线构成整个计时电路。保持电路仅用以与门实现。

c.程序及电路图

模六十计数器VHDL语言程序如下:

library ieee;

use ieee.std_logic_1164.all;

use ieee.std_logic_unsigned.all;

ENTITY counter_60 IS

PORT(en:IN std_logic; ----en为使能端clrn:IN std_logic; ----clrn为清零端idn:IN std_logic; ---- idn为置数使能端d:IN std_logic_vector(7 downto 0); ----d为预置数的输入端clk:IN std_logic; ----clk为时钟端rco:out std_logic; ----rco为进位输出端qh:buffer std_logic_vector(3 downto 0);

ql:buffer std_logic_vector(3 downto 0)

);

END counter_60;

ARCHITECTURE behave OF counter_60 IS

BEGIN

rco<='1' when(qh="0101"and ql="1001" and en='1')else '0'; ----当计数到59时进位端输出1 PROCESS(clk,clrn)

BEGIN

IF(clrn='0')THEN ----定义清零端为低电平有效qh<="0000";

ql<="0000";

ELSIF(clk'EVENT AND clk='0')THEN ----定义该计数器为时钟下降沿有效if(idn='1')then ----定义置数端为高电平有效qh<=d(7 downto 4);

ql<=d(3 downto 0);

elsif(en='1')then ----定义使能端为高电平有效if(ql=9)then ----模六十的具体说明ql<="0000";

if(qh=5)then

qh<="0000";

else qh<=qh+1;

end if;

else ql<=ql+1;

end if;

END IF;

END IF;

END PROCESS;

END behave;

类似的,模24计数器也包含有使能端(高电平有效)、清零端(低电平有效)、置数使能端(高电平有效)、预置数端、时钟端(下降沿有效)、进位输出端。

模24计数器VHDL语言程序如下:

library ieee;

use ieee.std_logic_1164.all;

use ieee.std_logic_unsigned.all;

ENTITY counter_24 IS

PORT(en:IN std_logic;

clrn:IN std_logic;

idn:IN std_logic;

d:IN std_logic_vector(7 downto 0);

clk:IN std_logic;

rco:out std_logic;

qh:buffer std_logic_vector(3 downto 0);

ql:buffer std_logic_vector(3 downto 0)

);

END counter_24;

ARCHITECTURE behave OF counter_24 IS

BEGIN

rco<='1' when(qh="0010"and ql="0011" and en='1')else '0'; PROCESS(clk,clrn)

BEGIN

IF(clrn='0')THEN

qh<="0000";

ql<="0000";

ELSIF(clk'EVENT AND clk='0')THEN

if(idn='1')then

qh<=d(7 downto 4);

ql<=d(3 downto 0);

elsif(en='1')then

if(qh="0010"and ql="0011")then

qh<="0000";

ql<="0000";

elsif(ql<"1001")then

ql<=ql+1;

else

ql<="0000";

qh<=qh+1;

end if;

END IF;

END IF;

END PROCESS;

END behave;

计时部分电路图如下:

d.仿真波形

计时部分仿真波形如下(FUNCTIONAL ):

(2)脉冲发生电路

a.基本原理

实验箱提供了48M 频率的时钟,所以我们需要将其分频,从而得到1Hz 、2Hz 、512Hz 、1kHz 等频率,分别用于计时、报时、校分等电路。 b.实现方式

本实验采用VHDL 语言编程的方法实现分频器。在程序中,通过改变不同的count 数实现不同的分频,计算公式如下:

482M

f count

例如要得到1Hz ,则count 数需为24000000。 c.程序及电路图

分频器VHDL 语言程序如下: LIBRARY IEEE;

USE IEEE.STD_LOGIC_1164.ALL; ENTITY fenpin3 IS

PORT(clk: IN STD_LOGIC; ----待分频时钟 hz:buffer STD_LOGIC; hz1:buffer STD_LOGIC; hz2:buffer STD_LOGIC;

khz:buffer STD_LOGIC; khz2:buffer STD_LOGIC;

hz3:buffer STD_LOGIC;

hz4:buffer STD_LOGIC);

END fenpin3;

ARCHITECTURE beh OF fenpin3 IS

SIGNAL count: integer range 0 to 24000000;

SIGNAL countl: integer range 0 to 24000;

SIGNAL count2: integer range 0 to 24000000;

SIGNAL count3: integer range 0 to 24000000;

SIGNAL count4: integer range 0 to 24000;

SIGNAL count5: integer range 0 to 480000;

SIGNAL count6: integer range 0 to 4;

BEGIN

PROCESS(clk)

BEGIN

IF (clk='1') THEN

count<=count+1;

countl<=countl+1;

count2<=count2+1;

count3<=count3+1;

count4<=count4+1;

count5<=count5+1;

count6<=count6+1;

IF(count=23999999) Then

count<=0;

hz<=NOT hz; ----hz端口输出1Hz频率END IF;

IF(countl=23999) Then

countl<=0;

khz<=NOT khz; ----khz端口输出1kHz频率END IF;

IF(count2=11999999) Then

count2<=0;

hz1<=NOT hz1; ----hz1端口输出2Hz频率END IF;

IF(count3=46874) Then

count3<=0;

hz2<=NOT hz2; ----hz2端口输出512Hz频率END IF;

IF(count4=11999) Then

count4<=0;

khz2<=NOT khz2; ----kh2端口输出2kHz频率END IF;

IF(count5=479999) Then

count5<=0;

hz3<=NOT hz3; ----h3z 端口输出100Hz 频率 END IF;

IF(count6=3) Then count6<=0;

hz4<=NOT hz4; ----hz4端口输出6MHz 频率 END IF; END IF;

END PROCESS; END beh;

封装后分频器的模块如下图:

(3)译码显示电路

a.基本原理

本实验采用动态显示,即仅使用一个显示译码器实现六个七段显示数码管的显示。具体 结构框图如下:

整个译码显示电路由24选4数据选择器、模8计数器、译码器、显示译码器四部分组成。其工作原理如下:

为了通过控制开关能够实现闹钟显示与正常走时显示的切换,该电路中分别采用了两个数据选择器,分别用于选择正常走时的时间和闹钟的时间,两组数据共用其余的译码器、显示译码器以及模8计数器,通过一个选择程序控制显示译码器的输入端与哪一个数据选择器相连。

DIG0

DIG1

DIG2DIG3DIG4DIG5

b.实现方式

本实验中24选4数据选择器、模8计数器、显示译码器均采用VHDL语言编写,译码器使用74138实现。

其中74138芯片的功能表如下:

c.程序及电路图

24选4数据选择器VHDL语言程序如下(该程序为32选4,将星期电路考虑在内):LIBRARY IEEE;

USE IEEE.STD_LOGIC_1164.ALL;

ENTITY bus_mux4 IS

PORT(i0,i1,i2,i3,i4,i5,i6,i7:IN STD_LOGIC_VECTOR(3 DOWNTO 0);

a,b,c:IN STD_LOGIC; ----abc为三个控制端q:OUT STD_LOGIC_VECTOR(3 DOWNTO 0)); ----输出端END bus_mux4;

ARCHITECTURE beh OF bus_mux4 IS

SIGNAL sel: STD_LOGIC_VECTOR(2 DOWNTO 0);

BEGIN

sel<=c&b&a;

q<=i0 WHEN sel="000" ELSE

i1 WHEN sel="001" ELSE

i2 WHEN sel="010" ELSE

i3 WHEN sel="011" ELSE

i4 WHEN sel="100"ELSE

i5 WHEN sel="101"ELSE

i6 WHEN sel="110"ELSE

i7 WHEN sel="111";

END beh;

library ieee;

use ieee.std_logic_1164.all;

use ieee.std_logic_unsigned.all;

ENTITY counter_8 IS

PORT(en:IN std_logic;

clrn:IN std_logic;

idn:IN std_logic;

d:IN std_logic_vector(2 downto 0);

clk:IN std_logic;

rco:out std_logic;

q:buffer std_logic_vector(2 downto 0)

);

END counter_8;

ARCHITECTURE behave OF counter_8 IS

BEGIN

rco<='1' when(q="111" and en='1')else '0'; PROCESS(clk,clrn)

BEGIN

IF(clrn='0')THEN

q<="000";

ELSIF(clk'EVENT AND clk='1')THEN

if(idn='1')then

q<=d(2 downto 0);

elsif(en='1')then

if(q=8)then

q<="000";

else q<=q+1;

end if;

END IF;

END IF;

END PROCESS;

END behave;

显示译码器VHDL程序如下(驱动共阳七段数码管):LIBRARY IEEE;

USE IEEE.STD_LOGIC_1164.ALL;

ENTITY bcd_7seg IS

PORT(bcd_led:IN STD_LOGIC_VECTOR(3 DOWNTO 0); ledseg:OUT STD_LOGIC_VECTOR(6 DOWNTO 0));

END bcd_7seg;

ARCHITECTURE beh OF bcd_7seg IS

BEGIN

WITH bcd_led SELECT

ledseg<="1000000"WHEN"0000", "1111001"WHEN"0001", "0100100"WHEN"0010", "0110000"WHEN"0011", "0011001"WHEN"0100", "0010010"WHEN"0101", "0000010"WHEN"0110", "1011000"WHEN"0111", "0000000"WHEN"1000", "0010000"WHEN"1001",

"0111111"WHEN"1110",

"1111111"WHEN OTHERS;

END beh;

则该显示译码器功能表如下:

二选一选择电路VHDL语言程序如下:

library ieee;

use ieee.std_logic_1164.all;

use ieee.std_logic_arith.all;

use ieee.std_logic_unsigned.all;

ENTITY select21 IS

PORT(a,b:in std_logic_vector(3 downto 0);

mode:IN std_logic;

output:OUT std_logic_vector(3 downto 0)); END select21;

ARCHITECTURE one OF select21 IS

BEGIN

process(mode)

begin

if mode='0' then output<=a;

else output<=b;

end if;

end process;

END ARCHITECTURE one;

译码显示电路图如下:

(4)报时电路

a.基本原理

要实现从59分53秒开始报时,每隔一秒发一声,共发三声低音,一声高音;即59分53秒、59分55秒、59分57秒发低音(512Hz ),59分59秒发高音(1kHz ),

即:

H=59'53''f3+59'55''f3+59'57''f3+59'59''f4

=59'51''(2''f3+4''f3+6''f3+8''f4)

=59'51''(2''34''38''4f f f ??)

依次用m8m7m6m5m4m3m2m1s8s7s6s5s4s3s2s1表示分秒的十位个位,那么上面的表达式即可表示为:

H=m7m5m4m1s7s5s1(234334s f s f s f ??)

则该部分的结构框图如下:

b.实现方式

该部分全部用逻辑门电路实现。

c.电路图

报时电路图如下:

(5)校分电路

a.基本原理

校分电路包含校分、校时、校星期,其原理大致相同,都是通过开关控制时钟端接1Hz 的同时使能端接上一位进位端,或者时钟端接2Hz的同时使能端置1,即通过开关控制某位计数器是否受上一位的影响。

同时,校分、校时时都应保持不进位,使校正位不影响正确位,则控制使能端是否连接进位信号。

b.实现方式

该部分电路全部由逻辑门实现。

c.校分电路图

校分、校时、校星期电路图逻辑关系相似,如下图:

控制计数器时钟端

控制计数器使能端

d.仿真波形图

校分时仿真波形图如下:

校时时仿真波形图如下:

(6)清零电路

a.基本原理

计时电路中各计数器均具备清零端,只要把它们同时用一开关控制,则可实现一键清零的功能。

b.实现方式

用一个开关输入信号同时控制三个清零端即可。

c.仿真波形图

输入清零信号后的仿真波形图如下:

(7)闹钟电路

a.基本原理

闹钟电路基本由设置电路、比较器两部分组成:

设置电路用两个计数器实现,分别设置分和小时(闹钟与秒位无关)。与计时电路中的计数器类似,分采用模六十计数器,小时采用模二十四计数器,简单之处在于,设置闹钟的过程并不需要分向小时进位,只要单独设置分和小时即可,于是两个计数器独立工作,而设置的过程为节省时间均采用2Hz的时钟。

比较器的功能是比较正常走时电路与设置的闹钟时间,使得当二者相等时输出一个信号到蜂鸣器端使之发出报警。

b.实现方式

用前述计时电路的计数器实现设置电路,比较器通过VHDL语言编程,设定比较条件从而实现比较功能。彩铃的实现仍旧通过VHDL语言编程,此实验中彩铃音乐的整体框架程序来源于网络,其中的乐谱为自己编写。

c.程序与电路图

计数器程序如前,不再赘述。

比较器VHDL程序如下:

LIBRARY IEEE;

USE IEEE.STD_LOGIC_1164.ALL;

ENTITY comparator IS

PORT(a1,a2,a3,a4,b1,b2,b3,b4:in std_logic_vector(3 downto 0);

c:buffer bit);

END comparator;

ARCHITECTURE beh OF comparator IS

SIGNAL a,b: std_logic_vector(15 downto 0);

BEGIN

a<=a4&a3&a2&a1;b<=b4&b3&b2&b1;

PROCESS(a,b)

BEGIN

IF (a=b and (a/="0000" or b/="0000")) THEN ----两组数相等时输出闹铃信号c<='1';

else c<='0';

end if;

end process;

end beh;

彩铃VHDL程序如下:

library ieee;

use ieee.std_logic_1164.all;

entity aiqingmaimai is

port(

clk : in std_logic;

beep: out std_logic);

end aiqingmaimai;

architecture beh of aiqingmaimai is

type state_type is (do_l,re_l,mi_l,fa_l,sol_l,la_l,si_l,do_m,re_m,mi_m,fa_m,sol_m,la_m,si_m,do_h,re_h,mi_h,f a_h,sol_h,la_h,si_h,none);

----用状态机分别来定义低音、中音和高音的do,re,mi,fa,sol,la和si signal counter : integer range 0 to 100000 := 0; ----counter是用来找音调的signal count : integer range 0 to 99 := 0; ----count是整个歌曲的记拍器signal beep_reg: std_logic;

signal clk1khz,clk4hz : std_logic;

signal note : state_type ;

begin

beep <= beep_reg;

beep_pro : process(clk)

variable cnt : integer range 0 to 100000 := 0;

begin

if clk'event and clk='1' then

if cnt < counter then

cnt := cnt + 1 ;

else

cnt := 0 ; beep_reg <= not beep_reg;

end if;

end if;

end process beep_pro;

clk1khz_pro : process(clk) ----产生1khz的频率信号variable cnt : integer range 0 to 24999;

begin

if clk'event and clk='1' then

if cnt = 24999 then

cnt := 0 ; clk1khz <= not clk1khz;

else

cnt := cnt + 1;

end if;

end if;

end process clk1khz_pro;

clk4hz_pro :process(clk1khz) ----产生4hz的频率信号,在本程序中4hz

(250ms)为1拍,是乐曲的节奏variable cnt : integer range 0 to 124 := 0;

begin

if clk1khz'event and clk1khz = '1' then

if cnt = 124 then

cnt := 0 ; clk4hz <= not clk4hz;

else

cnt := cnt + 1;

end if;

end if;

end process clk4hz_pro;

count_pro : process(clk4hz) ----记拍器进程begin

if clk4hz'event and clk4hz ='1' then

if count <= 66 then

count <= count + 1;

else

count <= 0;

end if;

end if;

end process count_pro;

note_pro : process(note)

begin

case note is

when do_l => counter <= 95566 ;

when re_l => counter <= 85121 ;

when mi_l => counter <= 75850 ;

when fa_l => counter <= 71592 ;

when sol_l => counter <=63776 ;

when la_l => counter <= 56818 ;

when si_l => counter <= 50618 ;

when do_m => counter <= 47774 ;

when re_m => counter <= 42568 ;

when mi_m => counter <= 37919 ;

when fa_m => counter <= 35791 ;

when sol_m => counter <=31888 ;

when la_m => counter <= 28409 ;

when si_m => counter <= 25309 ;

when do_h => counter <= 23912 ;

when re_h => counter <= 21282 ;

when mi_h => counter <= 18961 ;

when sol_h => counter <=15944 ;

when la_h => counter <= 14205 ;

when si_h => counter <= 12605 ;

when others => counter <= 0;

end case;

end process note_pro;

music_pro : process(count) ----乐谱begin

case count is

when 0 => note <= mi_m ;

when 1 => note <= la_m;

when 2 => note <= do_h ;

when 3 => note <= do_h ;

when 4 => note <= mi_m ;

when 5 => note <= la_m ;

when 6 => note <= do_h ;

when 7 => note <= si_m;

when 8 => note <= si_m ;

when 9 => note <= la_m;

when 10 => note <= sol_m;

when 11|12 => note <= mi_m ;

when 13 => note <= re_m ;

when 14 => note <= re_m;

when 15 => note <= re_m ;

when 16 => note <= la_l ;

when 17 => note <= re_m ;

when 18 => note <= mi_m ;

when 19 => note <= sol_m ;

when 20 => note <= mi_m;

when 21 => note <= si_m ;

when 22 => note <= si_m;

when 23 => note <= sol_m;

when 24|25 => note <= mi_m ;

when 26 => note <= mi_m ;

when 27 => note <= la_m;

when 28 => note <= do_h ;

when 29 => note <= do_h ;

when 30 => note <= mi_m ;

when 31 => note <= la_m ;

when 32 => note <= do_h ;

when 33 => note <= mi_h ;

when 34 => note <= mi_h;

when 35 => note <= re_h;

when 37|38 => note <= re_h ;

when 39 => note <= mi_h ;

when 40 => note <= mi_h;

when 41 => note <= re_h;

when 42 => note <= do_h;

when 43 => note <= re_h;

when 44 => note <= re_h;

when 45 => note <= do_h;

when 46 => note <= si_m;

when 47 => note <= sol_m;

when 48 => note <= mi_m;

when 49 => note <= sol_m;

when 50 => note <= la_m;

when 51|52 => note <= la_m;

when others => note <= none;

end case;

end process music_pro;

end beh;

4、整体电路图

5、调试

编程完成后将所要编译的文件置为顶层实体,通过Progressing/Start Compilation进行编译,修改编译中出现的错误,直至编译成功。

相关主题
文本预览
相关文档 最新文档