VHDL语言数字时钟论文

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

实验名称:基于FPGA的具有闹钟和校时功能的数字钟设计
一、设计内容和要求
实验要求使用 VHDL进行多功能时钟的设计具体要求如下:
1.能将基本的小时、分钟、及秒钟显示在数码管上。

2.能利用拨码开关进行时间的校正。

3.具有整点报时和闹钟的功能。

二、 FPGA简介
以硬件描述语言(Verilog或VHDL)所完成的电路设计,可以经过简单的综合与布局,快速的烧录至 FPGA 上进行测试,是现代 IC设计验证的技术主流。

这些可编辑元件可以被用来实现一些基本的逻辑门电路(比如
AND、OR、XOR、NOT)或者更复杂一些的组合功能比如解码器或数学方程式。

在大多数的FPGA里面,这些可编辑的元件里也包含记忆元件例如触发器(Flip-flop)或者其他更加完整的记忆块。

FPGA采用了逻辑单元阵列LCA(Logic Cell Array)这样一个概念,内
部包括可配置逻辑模块CLB(Configurable Logic Block)、输入输出模块
IOB(Input Output Block)和内部连线(Interconnect)三个部分。

现场可
编程门阵列(FPGA)是可编程器件,与传统逻辑电路和门阵列(如PAL,GAL
及CPLD器件)相比,FPGA具有不同的结构。

FPGA利用小型查找表
(16×1RAM)来实现组合逻辑,每个查找表连接到一个D触发器的输入端,触
发器再来驱动其他逻辑电路或驱动I/O,由此构成了既可实现组合逻辑功能又
可实现时序逻辑功能的基本逻辑单元模块,这些模块间利用金属连线互相连接
或连接到I/O模块。

FPGA的逻辑是通过向内部静态存储单元加载编程数据来实现的,存储在存储器单元中的值决定了逻辑单元的逻辑功能以及各模块之间或
模块与I/O间的联接方式,并最终决定了FPGA所能实现的功能,FPGA允许无
限次的编程。

FPGA基本特点
采用FPGA设计ASIC电路(专用集成电路),用户不需要投片生产,就能
得到合用的芯片。

FPGA可做其它全定制或半定制ASIC电路的中试样片。

FPGA内部有丰富的触发器和I/O引脚。

FPGA是ASIC电路中设计周期最短、开发费用最低、风险最小的器件之一。

FPGA采用高速CMOS工艺,功耗低,可以与CMOS、TTL电平兼容。

可以说,FPGA芯片是小批量系统提高系统集成度、可靠性的最佳选择之一。

FPGA是由存放在片内RAM中的程序来设置其工作状态的,因此,工作时
需要对片内的RAM进行编程。

用户可以根据不同的配置模式,采用不同的编程
方式。

加电时,FPGA芯片将EPROM中数据读入片内编程RAM中,配置完成后,
FPGA进入工作状态。

掉电后,FPGA恢复成白片,内部逻辑关系消失,因此,FPGA能够反复使用。

FPGA的编程无须专用的FPGA编程器,只须用通用的EPROM、PROM编程器即可。

当需要修改FPGA功能时,只需换一片EPROM即可。

这样,同一片FPGA,不同的编程数据,可以产生不同的电路功能。

因此,FPGA 的使用非常灵活。

如图2.1所示,逻辑单元(LE)结构主要由一个4输入查找表和一个可编程寄存器构成,4输入查找表用以完成组合逻辑功能,每个逻辑单元中的可编程寄存器可被配置成为 D、T、JK 和 SR 触发器。

每个可编程触发器具有数据、时钟、时钟时能、异步数据装载、清零和异步置位/复位信号。

逻辑单元中的时钟、时钟使能选择逻辑可以灵活配置寄存器的时钟以及时钟使能信号。

如果是纯组合逻辑应用,可将触发器旁路,这样查找表的输出可以直接作为逻辑单元的输出。

每个逻辑单元的输出都可以连接到局部连线、行列、寄存器链等布线资源。

图2.1:查找表(LUT)结构示意图
三、设计原理
1.工作原理
多功能数字钟系统共包括三个模块,即分频器模块、计数器模块和显示译码模块。

多功能数字钟的功能可以从整体上分为三类,分别是正常计时、时钟校对和闹钟设置,所以考虑在系统中设置一个模式控制信号kb。

模式控制信号对应两个按键,当kb=00时,则数字钟将在正常计时;当kb=01时,则数字钟将在时间校对;当kb=10或kb=11时,则数字钟将在闹钟设置;
在设计中,时钟校对和闹钟设置工作模式都需要对时间进行设置,通常是对小时和分钟进行设置,所以需要在系统中设置一个时间设置信号turn,对应一个按键,每按一次相当于在小时设置和分钟设置之间进行转换。

时间设置时,分钟和小时计时单位之间互相独立,不存在进位关系。

同时设置一个时间调整信号change,每按一次与change对应的按键,相当于对需要调整的分钟或小时的数字进行加1操作。

数字钟的计时输出信号时必不可少的,用
hourh,hourl,minuteh,minutel,secondh和secondl信号分别表示需要显示的小时、分钟和秒钟的计时结果,上述计时结果将通过译码显示模块进行译码后,连接到外部的七段数码显示器。

在带有闹钟设置功能的数字钟中,闹钟输出信号也是必不可少的,到达到闹钟设置的时间后,要向外部扬声器发送一个闹铃信号,设置voice。

另外,我们还提供了闹钟铃声信号alert,当alert为0的时候,闹钟处于静音状态下,即使时间达到闹钟设定的时间也不会发声,当alert为1的时候,可以正常闹铃,alert信号对应一个拨码开关。

图3.1:总体功能图
在设计中,其中rst为复位信号,当rst为高电平是复位,clk为时钟信号,en为使能信号,turn为调时调分转换信号,kb为三种模式转换信号,change为手动调时或调分信号,每按一次与change对应的按键,相当于对需要调整的分钟或小时的数字进行加1操作。

alert 为闹钟设置信号,alert 为高电平是表示设置了闹钟,voice 为输出闹钟信号。

本设计中的小时、分钟和秒钟的计时结果采用BCD码表示方法。

采用这种表示方法便于对数结果的高位和低位分别进行译码。

2.秒、分、时模块原理图或硬件描述语言程序
程序中秒钟和分钟是以60进制计数的,而60进制又是由一个6进制和一个10进制组合而成的其代码如下:
6进制:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity count6 is
port
(
rst:in std_logic;
clk:in std_logic;
en:in std_logic;
co:out std_logic;
output:out std_logic_vector(3 downto 0)
);
end count6;
architecture c6 of count6 is
signal qout:std_logic_vector(3 downto 0);
begin
output<=qout;
process(rst,clk)
begin
if (rst='1') then
qout<="0000";
elsif(clk'event and clk='1') then
if(en='1') then
if(qout="0101")then
qout<="0000";
co<='1';
else
qout<=qout+1;
co<='0';
end if;
end if;
end if;
end process;
end c6;
10进制:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity count10 is
port
(
rst:in std_logic;
clk:in std_logic;
en:in std_logic;
co:out std_logic;
output:out std_logic_vector(3 downto 0) );
end count10;
architecture c10 of count10 is
signal qout:std_logic_vector(3 downto 0);
begin
output<=qout;
process(rst,clk)
begin
if (rst='1') then
qout<="0000";
elsif(clk'event and clk='1') then
if(en='1') then
if(qout="1001")then
qout<="0000";
co<='1';
else
qout<=qout+1;
co<='0';
end if;
end if;
end if;
end process;
end c10;
24进制:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity count24 is
port
(
rst:in std_logic;
clk:in std_logic;
en:in std_logic;
outputh:out std_logic_vector(3 downto 0);
outputl:out std_logic_vector(3 downto 0);
);
end count24;
architecture c24 of count24 is
signal qouth:std_logic_vector(3 downto 0);
signal qoutl:std_logic_vector(3 downto 0);
begin
outputh<=qouth;
outputl<=qoutl;
process(rst,clk)
begin
if (rst='1') then
qouth<="0000";
qoutl<="0000";
elsif(clk'event and clk='1') then
if(en='1') then
if(qouth="0010"and qoutl="0011")then
qouth<="0000";
qoutl<="0000";
elsif(qoutl=9)then
qoutl<="0000";
qouth<=qouth+1;
else
qoutl<=qoutl+1;
end if;
end if;
end if;
end process;
end c24;
60进制:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity count60 is
port
(
rst:in std_logic;
clk:in std_logic;
en:in std_logic;
co:out std_logic;
outputh:out std_logic_vector(3 downto 0);
outputl:out std_logic_vector(3 downto 0)
);
end count60;
architecture c60 of count60 is
signal qouth:std_logic_vector(3 downto 0);
signal qoutl:std_logic_vector(3 downto 0);
begin
outputh<=qouth;
outputl<=qoutl;
process(rst,clk)
begin
if (rst='1') then
qouth<="0000";
qoutl<="0000";
elsif(clk'event and clk='1') then
if(en='1') then
if(qouth="0101"and qoutl="1001")then
qouth<="0000";
qoutl<="0000";
co<='1';
elsif(qoutl=9)then
qoutl<="0000";
qouth<=qouth+1;
co<='0';
else
qoutl<=qoutl+1;
co<='0';
end if;
end if;
end if;
end process;
end c60;
3.系统顶层设计及其他功能程序设计
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity clock is
port
(
rst:in std_logic;
clk:in std_logic;
en:in std_logic;
turn:in std_logic;
kb:in std_logic_vector(1 downto 0);
change:in std_logic;
stopvoice:in std_logic;
voice:out std_logic;
hourh:buffer std_logic_vector(3 downto 0);
hourl:buffer std_logic_vector(3 downto 0);
minuteh:buffer std_logic_vector(3 downto 0);
minutel:buffer std_logic_vector(3 downto 0);
secondh:buffer std_logic_vector(3 downto 0);
secondl:buffer std_logic_vector(3 downto 0)
);
end clock;
architecture clockqm of clock is
signal change1: std_logic;
signal change2: std_logic;
signal change3: std_logic;
signal hourh1:std_logic_vector(3 downto 0);
signal hourl1:std_logic_vector(3 downto 0);
signal minuteh1:std_logic_vector(3 downto 0);
signal minutel1:std_logic_vector(3 downto 0);
signal secondh1:std_logic_vector(3 downto 0);
signal secondl1:std_logic_vector(3 downto 0);
signal cosm: std_logic;
signal comh: std_logic;
signal clockhourh1:std_logic_vector(3 downto 0);
signal clockhourl1:std_logic_vector(3 downto 0);
signal clockminuteh1:std_logic_vector(3 downto 0);
signal clockminutel1:std_logic_vector(3 downto 0);
component count60 is
port
(
rst:in std_logic;
clk:in std_logic;
en:in std_logic;
co:out std_logic;
outputh:out std_logic_vector(3 downto 0);
outputl:out std_logic_vector(3 downto 0) );
end component;
component count24 is
port
(
rst:in std_logic;
clk:in std_logic;
en:in std_logic;
outputh:out std_logic_vector(3 downto 0);
outputl:out std_logic_vector(3 downto 0) );
end component;
begin
hourh<=hourh1;
hourl<=hourl1;
minuteh<=minuteh1;
minutel<=minutel1;
secondh<=secondh1;
secondl<=secondl1;
process(rst,clk,kb,stopvoice)
begin
if (stopvoice='0'and (clockhourh1=hourh )and (clockhourl1=hourl) and (clockminuteh1=minuteh) and (clockminutel1=minutel))then
voice<='1';
end if;
if(minuteh="0000"and minutel="0000")then
voice<='1';
end if;
if(kb="00")then
change1<=clk;
change2<=cosm;
change3<=comh;
elsif(kb="01")then
if(turn='0')then
change1<=clk;
change2<=change;
change3<='0';
else
change1<=clk;
change2<='0';
change3<=change;
end if;
else
clockhourh1<=hourh1;
clockhourl1<=hourl1;
clockminuteh1<=minuteh1;
clockminutel1<=minutel1;
if(turn='0')then
change1<=clk;
change2<=change;
change3<='0';
else
change1<=clk;
change2<='0';
change3<=change;
end if;
end if;
end process a ;
second60:count60 port map(rst=>rst,clk=>change1,en=>en, co=>cosm,outputh=>secondh1,outputl=>secondl1);
minute60:count60 port map(rst=>rst,clk=>change2,en=>en,
co=>comh,outputh=>minuteh1,outputl=>minutel1);
hour24:count24 port map(rst=>rst,clk=>change3,en=>en,
outputh=>hourh1,outputl=>hourl1);
end clockqm;
四、实验结果(对自己的实验结果进行描述)
1、设置闹钟:
1.kb=10或kb=01,此时数码管显示为闹钟设置数值,初始值为
00:00:00。

2.turn引脚置低电平,开始设置闹钟的分钟值,按下单脉冲30次,设置闹钟的分钟值为30,此时数码管显示00:30:00。

3. turn引脚置高电平,开始设置闹钟的小时值,按下单脉冲1次,设置闹钟的分钟值为30,此时数码管显示01:30:00。

4.kb=00时,数码管显示正常计时,发现在设置闹钟的过程中,计时依然在正常进行。

假设此时计时以计至00:00:00时刻。

2、设置计时时间:
1. kb=01置低电平,turn引脚置高电平,设置小时至01时,Turn引脚置低电平,设置分钟至29分。

2.kb=00时,使时钟从01:29:00时刻开始正常计时。

3、闹钟功能的验证:
从2起60秒后,时钟计时至01:30:00时刻,即和闹钟所设定的时刻一致,此时如预先期望一致,蜂鸣器响起。

五、实验体会及对课程的教学过程和效果的综合评价
本任务设计了一个简易数字钟,能实现小时、分钟和秒的计时及显示,其中控制小时、分钟和秒计时的数模块是本次设计的核心。

计数模块的关键在于能够理解三个计时单位之间的联系,即秒计数满60产生一个向分钟的进位,分钟计数满60产生一个向小时的进位,这两个进位信号将小时、分和秒联系起来,是理解本设计的关键点。

六、其时序仿真波形图如下:
1.6进制
2.10进制
3.24进制
4.60进制
5.整点报时
6.闹钟报时
7.调整时间及设置闹钟。

相关文档
最新文档