VHDL 课程设计
题 目
多功能数字钟设计
专业名称 信号与信息处理
学生姓名
指导教师
宋万杰
完成时间
2009 年 12 月
一: 课程设计的任务
设计一个多功能的数字时钟,具有以下功能:
1. 正常的显示功能:显示 AM、PM、时、分、秒(24 进制或者 12 进制)。
2. 手动校时功能:按动方式键,将电路置于校时状态,则计时电路可用手动方式校准,
每按一下校时键,时计数器加 1;按动方式键,将电路置于校分状态,以同样方式手动
校分。按动按键有滴滴声,并且数码管显示的数字会闪动。
3. 万年历功能:显示年、月、日、星期、是否闰年。
4. 手动校正日历功能。按动方式键,将电路置于校年状态,则计时电路可用手动方式
校准,每按一下校年键,时计数器加 1;按动方式键,将电路置于校月状态,以同样方
式手动校月。按动按键有滴滴声,并且数码管显示的数字会闪动。
5. 闹钟功能:按动方式键进入闹钟设定模块,设定闹钟时间。闹铃信号到达播放音乐
《两只蝴蝶》,按动停止键则立即停止播放音乐,若不按动停止键则自动播放音乐 1 分
钟后停止。
6. 整点播报功能,从 59 分 50 秒开始发出播报,每隔 2 秒发出一声(信号名叫持续时间
1 秒,间隙 1 秒)连续发出 5 次,到达整点时停止播报。
7. 秒表功能:按动开始键开始计时,按动停止键数字保持不变,按动复位键从新计时
二:系统设计
根据以上对于多功能数字钟的功能的描述,可以将整个的电路设计分为以下几个模块:
1. 分频模块:由于实验电路板上所能提供的只有 1Khz 和 6Mhz 的信号,而本设计过
程的即时以及跑表模块需要 1hz、100hz 和 4hz 的时钟信号。
2. 控制模块:为达到多动能数字钟在计时、校时、显示日历、跑表等不同的模块之间
切换,需要控制模块产生时序要不相冲突的控制信号,保证各个模块的功能有序的执行。
3. 计时模块:在输入的 1hz 时钟信号,产生显示的 AM、PM、时、分、秒信号,由
于要涉及到后面的校时模块,这里采用带有置数的计时模块,在 load 信号控制下将校时
模块设定的时间转载至初始值,在初始值的基础上正常计时。
4. 校时模块:当功能切换至校时模块时,本程序采用在外部按键的上升沿即:每按动
一次校时键对应显示相应加 1。
5. 万年历模块:在计时模块的进位输出信号(每次跳动代表一年),产生显示的年、月、
日、星期、是否闰年信号,同样类似于计时模块考虑到后面的校正日历模块,这里同样
采用带有置数的计时模块,在 load 信号控制下将校正日历模块设定的日历转载至初始
值,在初始值的基础上正常计时。
6. 校正日历模块:切换至该模块时,采用外部按键的上升沿:每按动一次校正键对应的
显示相应的加 1。
7. 闹钟模块:这里采用和校时模块同样的电路设定闹钟的时间,一旦触发信号为高电
平,触发音乐播放模块,播放歌曲《两只蝴蝶》,不按停止键播放一分钟自动停止。
8. 跑表模块:采用显示毫秒、秒、分的显示格式,并设有 stop 按钮和 reset 按钮。
9. 显示模块:采用从控制模块中出来的 mode 信号为变量,跟随该信号的变化,选着
不同的模块的输出信号,通过两个译码器输出数据连接到数码管显示。
以上简单的介绍了构成电路的几大模块,下面给出本设计电路的总的模块化示意图:
图 一 系统总模块化示意图
三:模块实现
根据以上的介绍可知闹钟的设计的组成模块:分频模块、控制模块、计时模块、校时模
块、万年历模块、校正日历模块、闹钟模块(包块音乐模块)、跑表模块、显示模块。
以下将就着上面的模块电路的各个模块加以详细的说明。对以上模块的实现进行具体的
VHDL 的设计。注:(在前面定义的子模块,后面不再定义而是直接的例化使用)
一:分频模块
由于开发板系统提供的时钟只有 1Khz 和 6Mhz(专用于音乐模块),而本实验的计时模块、
音乐模块、跑表模块等需要 1hz、100hz 的时钟信号,故需要加以分频实现所需信号。
分频电路的模块化示意图如下:
下面给出分频模块的 RTL 级的描述:
图 二 分频电路模块图
1)10 分频模块:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity fenpin10 is
port (clk_in:in std_logic;- - 输入时钟信号
clk_out:buffer std_logic);- -输出时钟信号
end fenpin10;
architecture rtl of fenpin10 is
signal cnt:std_logic_vector(3 downto 0);- -定义计数器模值
begin
process (clk_in)
begin
if (clk_in'event and clk_in='1') then
if (cnt="0100") then
clk_out<=not clk_out;
cnt<="0000";
else
end if;
cnt<=cnt+'1';
end if;
end process ;
end rtl;
2)分频模块的 RTL 描述:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity fenpin is
port (clk_1khz:in std_logic;- -输入 1Khz 时钟信号
clk_1hz,clk_100hz:buffer std_logic);- - 输出的 1hz 和 100hz 信号
end fenpin;
architecture rtl of fenpin is
signal clk_10hz:std_logic;
component fenpin10 is- - 例化 10 分频电路,在本设计中调用
port (clk_in:in std_logic;
clk_out:buffer std_logic);
end component;
begin
u0: fenpin10
port map(clk_in=>clk_1khz,- - 时钟输入
clk_out=>clk_100hz);- - 时钟输出
u1: fenpin10
port map (clk_in=>clk_100hz, - - 时钟输入
clk_out=>clk_10hz); - - 时钟输出
u2: fenpin10
port map (clk_in=>clk_10hz, - - 时钟输入
clk_out=>clk_1hz); - - 时钟输出
end rtl;
3)分频模块的仿真图
仿真图分析:输入信号为 1Khz 经过分频成功产生 100hz 和 1hz 时钟信号
图 三 分频模块仿真图
二:计时模块
本计时完成时间输出功能,根据秒、分、时(24 进制)计时原理故需要设计到 60、24
进制的 BCD 计数器,并在此基础上构成 RTL 级的计时描述,模块图如下所示:
图四 计时电路模块图
end cnt60;
architecture rtl of cnt60 is
signal h_temp,l_temp:std_logic_vector(3 downto 0)
begin
process (clk_in,en) ----个位计数进程(0-9)循环计数
begin
if (reset='1') then---清 0
l_temp<="0000";
elsif (load='1') then---下载预置数
l_temp<=l_in;
elsif (clk_in'event and clk_in='0') then---正常计数
if((en='1')and(stop='0')) then
if (l_temp="1001") then
l_temp<="0000";
else
l_temp<=l_temp+'1';
end if;
end if;
下面给出计时模块的 RTL 级的描述:
由于考虑到后面的跑表和校时模块的预置数,这里的模 60、24BCD 计数器均设计成带有
预置数端口,和暂停计数功能。同时考虑到现实 AM、PM,以及整点报时以及对于报时声
音时宽的要求,加入实现上述功能的子模块。
1)模 60BCD 计数器 循环的进行 0-59 计数,产生秒、分信号输出
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity cnt60 is
port (clk_in,reset,load,stop,en:in std_logic;--输入的时钟、清 0、置数、暂停、使能信号
l_in,h_in:in std_logic_vector(3 downto 0);--预置数,高 4 位和低 4 位
enout:out std_logic;--输出地进位信号
h,l:out std_logic_vector(3 downto 0));---输出信号的高 4 位和低 4 位
end if;
end process low_proc;
l<=l_temp;
process (clk_in,en)----十位计数进程(0~5)循环计数
begin
if (reset='1') then---清 0
h_temp<="0000";
elsif (load='1') then---下载预置数
h_temp<=h_in;
elsif (clk_in'event and clk_in='0')
then
if (l_temp="1001") then
if((en='1')and(stop='0'))
then---正常计数
if (h_temp="0101") then
h_temp<="0000";
h_temp<=h_temp+'1';
else
end if;
end if;
end if;
end if;
end process high_proc;
h<=h_temp;
enout<='1' when l_temp="1001" and h_temp="0101" else---计满 60 产生进位输出
'0';
end rtl;
2)模 24BCD 计数器 循环进行 0-23 计数 产生时输出信号
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity cnt24 is
port ( clk_in,reset,load,stop,en:in std_logic; ---输入的时钟、清 0、置数、暂停、使能信号
h_in,l_in:in std_logic_vector(3 downto 0);---输入的预置数
enout:out std_logic;---输出进位信号
h,l:out std_logic_vector(3 downto 0));---输出信号的高 4 位和低 4 位
end cnt24;
architecture rtl of cnt24 is
signal l_temp:std_logic_vector(3 downto 0);
signal h_temp:std_logic_vector(3 downto 0);
signal clr:std_logic:='0';---计满模 24 产生的清 0 信号
begin
process (clk_in,en,clr)---个位的计数进程(0~9)循环计数
begin
if (reset='1') then---清 0 信号
l_temp<="0000";
elsif (load='1') then---下载预置数
l_temp<=l_in;
elsif (clk_in'event and clk_in='0') then---正常计数
if ((en='1')and(stop='0')) then
if ((l_temp="1001") or (clr='1'))
then
l_temp<="0000";
l_temp<=l_temp+'1';
else
end if;
end if;
end if;
end process low_proc;
l<=l_temp;
process (clk_in,en,clr)---十位计数进程(0~2)循环计数
begin
if (reset='1') then
h_temp<="0000";
elsif (load='1') then
h_temp<=h_in;
elsif (clk_in'event and clk_in='0') then
if ((en='1')and(stop='0')) then
if (clr='1') then
h_temp<="0000";
elsif (l_temp="1001") then
h_temp<=h_temp+'1';
end if;
end if;
end if;
end process high_proc;
h<=h_temp;
clr<='1' when l_temp="0011" and h_temp="0010" else---计满模 24 产生清 0 信号
'0';
enout<=clr;---计满 24 产生进位信号
end rtl;
3)整点模块 时刻为 59 分 50 秒开始报时,知道 00 分 00 秒停止
library ieee;
use ieee.std_logic_1164.all;
entity zd is
port (clk_in,en:in std_logic;---输入时钟,使能信号
cmh,cml,csh,csl:in std_logic_vector(3 downto 0);---输入的分、秒
voiceon:out std_logic);---声音信号输出
end zd;
architecture rtl of zd is
signal key:std_logic:='0';
signal temp:std_logic_vector(3 downto 0);
begin
process (clk_in)---判断时间是否为 59 分 50 秒
begin
if (clk_in'event and clk_in='1') then
voiceon<='1';
temp<="0000";
key<='1';
end if;
if ((temp=csl)and(key='1'))
voiceon<='0';
key<='0';
end if;
end if;
end process;
end rtl;
4)二分频电路
if ((csl="0000")and(csh="0101")and(cml="1001")and(cmh="0101")and(en='1')) then
then---声音持续十秒停止
因为整点报时 10 秒,为达到报时信号周期 2s,每周期响铃 1s,故需通过二分频电路
library ieee;
use ieee.std_logic_1164.all;
entity fenpin2 is
port (clk_1hz,en:in std_logic;---输入时钟信号、使能信号(整点报时信号)
clk_out:buffer std_logic);---输出周期 2s,闹铃 1s 闹钟信号
end fenpin2;
architecture rtl of fenpin2 is
begin
process (clk_1hz)---模 2 计数
begin
if (en='1') then
if (clk_1hz'event and clk_1hz='1')
then
clk_out<=not clk_out;
end if;
end if;
end process ;
end rtl;