用VHDL语言设计的数字电子钟

《电子设计自动化(EDA)技术》课程实训报告

1、课程设计内容与要求 (3)

1.1 设计内容 (3)

1.2 具体内容 (3)

2、系统设计 (3)

2.1 设计思路 (3)

2.2 系统原理 (4)

3、系统的实现 (6)

3.1 秒计数器模块及代码 (6)

3.2 分钟计数器模块及代码 (7)

3.3 小时计数器模块及代码 (8)

3.4 数码管位选择信号模块及代码 (9)

3.5 多路选择器模块及代码 (9)

3.6 七段译码器模块及代码 (10)

3.7 整点报时模块及代码 (10)

3.8 自动电子钟源代码 (10)

4、系统的仿真 (14)

4.1 VHDL的工作环境 (14)

4.2程序的编译和波形的仿真 (15)

4.3引脚的设置 (18)

4.4 全程编译及配置文件下载 (19)

5、硬件验证说明 (20)

6、总结 (21)

7、参考书目 (21)

数字电子钟设计

王海峰

重庆三峡学院应用技术学院电子信息工程(仪器仪表)2008级重庆万州404000

摘要:基于VHDL的自动电子钟,芯片采用ALTERA公司的ACEX1K 系列的EP1K10TC100-3,本文在简要介绍了EDA技术特点的基础上,用EDA技术作开发手段,运用VHDL语言,采用了自顶向下的设计方法,实现计时24小时的电子时钟的设计,并利用Quartus II 软件集成开发环境进行编译、综合、波形仿真、定义管脚,并下载到FPGA器件中,经实际电路测试,该系统性能实现。

关键词:VHDL EDA 数字电子钟 FPGA

1、课程设计内容与要求

1.1 设计内容

数字电子钟

1.2 具体内容

1.用24小时制进行时间显示;

2.能够显示小时、分钟、秒;

3.通电后从“00 00 00”开始显示。

4. 随时可复位,可暂停工作;

5. 整点报时。

2、系统设计

2.1 设计思路

数字电子钟端口说明

1.clk信号为实验板上的标准的1Hz脉冲。

2.en信号为使能端,en信号为低电平,此时所有的显示器均不显示,en为高电平时,所有的显示器均从0开始递增的工作。

3. clr信号为高电平清零信号。

4.Scanclk信号为数码管的位选择时钟信号。

5.led<7:0>信号是来驱动数码管显示的。

6.sel<2:0>为位选择控制信号,决定哪一个数码管显示数字。

7. speaker为报时用的扬声器端口输出信号。

2.2系统原理

自动电子钟将采用模块化的设计,模块分别是数码管位选择信号、秒计数器、分计数器、时计数器、多路选择器、7段译码器。用VHDL编写程序实现自动电子钟,其系统原理模块如下:

实际设计实现原理图如下:

数字电子钟原理图

1.进程P1描述60s计数器,输出秒个位的BCD码。

2.进程P2描述60min计数器,根据秒计数器的输出值,输出分十位和分个位的BCD 码。

3.进程P3描述23h计数器,根据秒计数器和分计数器的输出值,输出小时十位和个位的BCD码。

4.进程P4和P5根据进程产生数码管的位选择信号,从小时、分钟和秒中,选择一个BCD码给7段译码器。

5. 进程P6作为报时装置,当整点时就输出高电平,由Speaker发出声音。

3、系统的实现

3.1 秒计数器模块及代码

秒是这次电子钟设计的最底层模块.其核心是一个60进制计数器,以外来时钟信号作为其触发时钟信号,当外来信号进入clk时钟信号端,其内部的60进制计数器便开始工作,对信号源进行计数.计数结果由led<7:0>输出至数码管显示秒钟时间.当计数到60时,其值置零,并向外输出一个进位信号sj,这个进位信号便为下个分钟模块的输入时钟信号。

p1:process(clk,en,clr) --60秒计数器

VARIABLE s11:STD_LOGIC_VECTOR(3 DOWNTO 0);

VARIABLE s21:STD_LOGIC_VECTOR(3 DOWNTO 0);

BEGIN

IF clr='1' THEN

s11:=(OTHERS=>'0');

s21:=(OTHERS=>'0');

ELSIF clk'EVENT AND clk='1' THEN

IF EN='1' THEN

IF s21<9 THEN

s21:=s21+1;

ELSE

s21:=(OTHERS=>'0');

IF s11<5 THEN

s11:=s11+1;

ELSE

s11:=(OTHERS=>'0');

END IF;

END IF;

END IF;

END IF;

IF (s11=5 AND s21=9) THEN

sj<='1';

ELSE

sj<='0';

END IF;

s1<=s11;

s2<=s21;

end process p1;

3.2 分钟计数器模块及代码

分钟模块核心也是一个60进制计数器,其功能的实现是将秒模块的进位信号进行计数,计数结果由led<7:0>输至数码管显示,当计数至60是数值置零,并向外输出进位信号mj。

p2:process(sj,en,clr) --60分计数器

VARIABLE m11:STD_LOGIC_VECTOR(3 DOWNTO 0);

VARIABLE m21:STD_LOGIC_VECTOR(3 DOWNTO 0);

BEGIN

IF clr='1' THEN

m11:=(OTHERS=>'0');

m21:=(OTHERS=>'0');

ELSIF sj'EVENT AND sj='1' THEN

IF EN='1' THEN

IF m21<9 THEN

m21:=m21+1;

ELSE

m21:=(OTHERS=>'0');

IF m11<5 THEN

m11:=m11+1;

ELSE

m11:=(OTHERS=>'0');

END IF;

END IF;

END IF;

END IF;

IF (m11=5 AND m21=9) THEN

mj<='1';

ELSE

mj<='0';

END IF;

m1<=m11;

m2<=m21;

end process p2;

3.3 小时计数器模块及代码

小时模块核心也是一个60进制计数器,其功能的实现是将分钟模块的进位信号进行计数,计数结果由led<7:0>输至数码管显示,当计数至60是数值置零。

p3:process(mj,en,clr) --24小时计数器

VARIABLE h11:STD_LOGIC_VECTOR(3 DOWNTO 0);

VARIABLE h21:STD_LOGIC_VECTOR(3 DOWNTO 0);

BEGIN

IF clr='1' THEN

h11:=(OTHERS=>'0');

h21:=(OTHERS=>'0');

ELSIF mj'EVENT AND mj='1' THEN

IF EN='1' THEN

IF h21<3 THEN

h21:=h21+1;

ELSE

h21:=(OTHERS=>'0');

IF h11<2 THEN

h11:=h11+1;

ELSE

h11:=(OTHERS=>'0');

END IF;

END IF;

END IF;

END IF;

h1<=h11;

h2<=h21;

end process p3;

3.4 数码管位选择信号模块及代码

数码管位选择信号核心在于结合多路选择器从小时、分钟和秒中,选择一个BCD码给7段译码器。

P4:process(scanclk) --动态扫描时钟

begin

if rising_edge(scanclk) then

if dispcnt="101" then

dispcnt<="000";

else

dispcnt<=dispcnt+'1';

end if; end if;

end process P4;

3.5 多路选择器模块及代码

多路选择器核心在于结合数码管为选择信号从小时、分钟和秒中,选择一个BCD码给7段译码器。

P5:process(dispcnt) --选择对应位的BCD码

begin

if dispcnt="000" then

sel<="000";data<=h1;

elsif dispcnt="001"then

sel<="001";data<=h2;

elsif dispcnt="010"then

sel<="010";data<=m1;

elsif dispcnt="011"then

sel<="011";data<=m2;

elsif dispcnt="100"then

sel<="100";data<=s1;

elsif dispcnt="101"then

sel<="101";data<=s2;

end if;

end process P5;

3.6 七段译码器模块及代码

对多路选择器输出的信号进行译码,驱动7段数码管的显示。

--a,b,c,d,e,f,g,dp

with data select --7段译码器

led<= "11111100" when "0000", --0

"01100000" when "0001", --1

"11011010" when "0010", --2

"11110010" when "0011", --3

"01100110" when "0100", --4

"10110110" when "0101", --5

"00111110" when "0110", --6

"11100000" when "0111", --7

"11111110" when "1000", --8

"11100110" when "1001", --9

"00000000" when others;

3.7 整点报时模块及代码

当分位和秒位时钟同时为零时,进行整点报时,输出高电平信号驱动speaker发出声音。

P6:process(m1,m2,s1,s2) --整点报时

begin

if((m1="0000")and(m2="0000")and(s1="0000")and(s2="0000")) then

speaker<='1';

else

speaker<='0';

end if;

end process p6;

3.8 自动电子钟源代码

library ieee;

use ieee.std_logic_1164.all;

use ieee.std_logic_arith.all;

use ieee.std_logic_unsigned.all;

entity shizhong is

port(clk,en,scanclk,clr:in std_logic;

sel:out std_logic_vector(2 downto 0);

speaker:out std_logic;

led: out std_logic_vector( 7 downto 0));

end shizhong;

architecture szdzz of shizhong is

signal h2,h1,m2,m1,s2,s1:std_logic_vector(3 downto 0); signal sj,mj:std_logic;

signal data:std_logic_vector(3 downto 0);

signal dispcnt: std_logic_vector(2 downto 0);

begin

p1:process(clk,en,clr) --60秒计数器 VARIABLE s11:STD_LOGIC_VECTOR(3 DOWNTO 0);

VARIABLE s21:STD_LOGIC_VECTOR(3 DOWNTO 0);

BEGIN

IF clr='1' THEN

s11:=(OTHERS=>'0');

s21:=(OTHERS=>'0');

ELSIF clk'EVENT AND clk='1' THEN

IF EN='1' THEN

IF s21<9 THEN

s21:=s21+1;

ELSE

s21:=(OTHERS=>'0');

IF s11<5 THEN

s11:=s11+1;

ELSE

s11:=(OTHERS=>'0');

END IF;

END IF;

END IF;

END IF;

IF (s11=5 AND s21=9) THEN

sj<='1';

ELSE

sj<='0';

END IF;

s1<=s11;

s2<=s21;

end process p1;

p2:process(sj,en,clr) --60分计数器 VARIABLE m11:STD_LOGIC_VECTOR(3 DOWNTO 0);

VARIABLE m21:STD_LOGIC_VECTOR(3 DOWNTO 0);

BEGIN

IF clr='1' THEN

m11:=(OTHERS=>'0');

m21:=(OTHERS=>'0');

ELSIF sj'EVENT AND sj='1' THEN

IF EN='1' THEN

IF m21<9 THEN

m21:=m21+1;

ELSE

m21:=(OTHERS=>'0');

IF m11<5 THEN

m11:=m11+1;

ELSE

m11:=(OTHERS=>'0');

END IF;

END IF;

END IF;

END IF;

IF (m11=5 AND m21=9) THEN

mj<='1';

ELSE

mj<='0';

END IF;

m1<=m11;

m2<=m21;

end process p2;

p3:process(mj,en,clr) --24小时计数器 VARIABLE h11:STD_LOGIC_VECTOR(3 DOWNTO 0);

VARIABLE h21:STD_LOGIC_VECTOR(3 DOWNTO 0);

BEGIN

IF clr='1' THEN

h11:=(OTHERS=>'0');

h21:=(OTHERS=>'0');

ELSIF mj'EVENT AND mj='1' THEN

IF EN='1' THEN

IF h21<3 THEN

h21:=h21+1;

ELSE

h21:=(OTHERS=>'0');

IF h11<2 THEN

h11:=h11+1;

ELSE

h11:=(OTHERS=>'0');

END IF;

END IF;

END IF;

END IF;

h1<=h11;

h2<=h21;

end process p3;

P6:process(m1,m2,s1,s2) --整点报时

begin

if((m1="0000")and(m2="0000")and(s1="0000")and(s2="0000")) then speaker<='1';

else

speaker<='0';

end if;

end process p6;

p4:process(scanclk) --动态扫描时钟

begin

if rising_edge(scanclk)then

if dispcnt="101"then

dispcnt<="000";

else

dispcnt<=dispcnt+'1';

end if;

end if;

end process p4;

P5:process(dispcnt) --选择对应位的BCD码

begin

if dispcnt="000" then

sel<="000";data<=h1;

elsif dispcnt="001"then

sel<="001";data<=h2;

elsif dispcnt="010"then

sel<="010";data<=m1;

elsif dispcnt="011"then

sel<="011";data<=m2;

elsif dispcnt="100"then

sel<="100";data<=s1;

elsif dispcnt="101"then

sel<="101";data<=s2;

end if;

end process P5;

--a,b,c,d,e,f,g,dp

with data select --7段译码器

led<= "11111100" when "0000", --0

"01100000" when "0001", --1

"11011010" when "0010", --2

"11110010" when "0011", --3

"01100110" when "0100", --4

"10110110" when "0101", --5

"00111110" when "0110", --6

"11100000" when "0111", --7

"11111110" when "1000", --8

"11100110" when "1001", --9

"00000000" when others;

end szdzz;

4、系统的仿真

4.1 VHDL的工作环境

在菜单栏中选择File New New Quartus Project。芯片的选择:

4.2程序的编译和波形的仿真

芯片的选择一定要与实验室或者自己购买的芯片一致。项目创建完之后,接着就新建一个VHDL语言的文件,创建方法和项目的创建大同小异,File New VHDL

File。然后将自己的程序写入:

程序输入完之后,就进行语法编写,语法编译是检查程序的正确性,若有错误,程序自动指出。

在命令栏中选择Start Analysis & synthesis按钮,编译后成功后如下(警告可以忽略):

接下来就是波形的仿真,首先还是要新建一个波形文件,方法是File Vector WaveForm File,然后把程序中的输入输出端导入到这个波形中:

导入完后,就是设置输入端的初始值:

最后就是波形的编译,编译之前,一定要先进行网表的生成:

网表生成后才能波形的仿真,结果如下:

方法是在菜单栏中选择Assignment Editor

然后在Category中选择Pin

然后逐个的进行设置:

4.4 全程编译及配置文件下载

在菜单栏中点击Start Comiplation进行全程编译

最后一步就是程序的下载(配置文件的下载),点击菜单栏中的Programmer图标

图中所示,点击Start,程序的所有相关配置文件就下载到FPGA中。

5、硬件验证说明

程序下载到FPGA中,接好相应的引脚线之后,使能端置‘0’时,数码管全显示0,,

当使能端置‘1’时,数码管均从0开始递增的工作。

相关主题
相关文档
最新文档