预习报告部分
- 实验目的:设计和实现一个数字电子钟(利用蜂鸣器能设定条件进行报时),学会设计模块化和复用,以及时钟信号的生成与管理,学会如何使用VHDL来描述和实现复杂的硬件功能。
- 实验原理:
这个电子钟包括分频模块、计数器模块、去抖动模块、控制模块、控制蜂鸣器模块、解码模块和数码管驱动时间显示模块,计数器模块中又有六十计数器模块和二十四计数器模块。其中六十计数器用来实现分秒计时,二十四计数器用来实现小时计数。并且该实验使用来自外部的高频时钟信号,并将其划分为较低的频率,这些频率适合驱动计算秒、分钟和小时的计时逻辑,并且在计时的同时也将各个部分的计数值输入给数码管驱动电路,电路将编码结果输出给数码管作为字选和段选信号。控制模块中,用户可以通过拨动开关的方式输入时间或启动暂停时间,并使用七段显示显示时间。蜂鸣器,蜂鸣器报时,防抖,用来设定在特定时间启动。(比如秒数个位为9时响一次)。
该实验是通过使用一系列计数器来表示小时、分钟和秒来实现的。这些计数器由时钟信号递增,该时钟信号通常以远高于每秒一个脉冲的频率运行。计数器被设计为在达到最大计数时翻转,如在计数分钟或秒时从 59 移动到 00。
- 实验内容:编写VHDL语言代码来在HDLE-1硬件描述语言综合实验平台上,实现数字电子钟功能。
- 实验所用设备: PC个人计算机、Windows操作系统、Quartus II集成开发环境软件、HDLE-2硬件描述语言综合实验平台。
- 实验步骤:①建立工程、②编辑代码、③编译及修改错误、④实验平台装载程序、⑤演示实验结果。
实验报告部分
- 实验步骤:
- 建立工程
左侧即为建立的各个功能模块,digitalclock作为顶层实体,将其它模块进行综合。
2.编写代码与编译
- 分频模块:采用高频时钟输入并生成几个较慢的时钟信号,用于以适当的速度驱动时钟逻辑的不同部分。
- 计时器模块:用于秒、分钟和小时的计数器模块。它们会增加时间,并在结束复位时提供结转信号 (co)(例如,从 59 秒到 00)。
- 去抖动模块:清除来自输入按钮(key1、key2、key3)的信号,过滤掉按下按钮时产生的机械噪音。
- 控制模块:处理来自按钮的输入以设置时间或控制其他功能。
- 解码模块:将二进制编码的十进制 (BCD) 输入转换为用于驱动七段显示器的信号。将高低BCD数字转换为相应的7段代码进行显示。
- saomiao模块:负责扫描或多路复用显示器,驱动数码管显示时间。
- 蜂鸣器控制模块:
3.分配芯片引脚并编译
4. 实验平台装载程序并演示实验结果
二、 实验数据及结果分析:
编译程序在实验箱上运行结果如下:
- 实验结论:
要用VHDL语言设计一个数字电子时钟,可采用顶层设计的方法,先根据设计系统的功能,从总体要求出发,再从上到下逐步将设计内容细化,最后完成系统硬件的整体设计。在这个实验中,我通过集成分频模块、计数器模块、去抖动模块、控制模块、蜂鸣器控制模块、解码模块以及扫描驱动模块设计了这个数字电子钟系统。该系统能够显示时间,并在设定条件下通过蜂鸣器发出报时信号。实验结果验证了设计的功能性和可靠性,所有模块均能协同工作,符合预期的实验要求。
- 总结及心得体会:
在这次实验中,我选择了数字电子钟作为我的实验内容,这让我受益匪浅。通过这次实验,我深入了解了数字时钟的工作原理和VHDL在硬件设计中的应用。我理解了通过模块化设计能够使问题更加简单化,并且会更便于理解与调试。在实验过程中,我学会了如何处理时钟信号,如何实现模块间的通信,以及如何将抽象概念转化为实际的硬件逻辑,这对我来说无疑是很大的提升。此外,在设计分频器和计数器时,我意识到了精确时序控制的重要性。并且在调试过程中我也遇到了一些困难,但是这些困难与挑战也教会了我在做实验的时候耐心和细致是非常重要的,我意识到了每一个小错误都可能导致整个系统的失败。所以这次实验的成功完成对我来说也有很大帮助,给我带来了许多收获。通过这次实验,我锻炼了我的问题解决和创新思维能力,并且我的专业知识和技能也都有很大提升。当然我也认识到自己还有许多不足,代码设计是一个不断积累和提升的过程,我仍需要去继续努力,提高自己的编程能力,为自己将来可能遇到的工程实践和创新研究打下坚实基础。
- 附录(实验源码)
顶层实体:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity DigitalClock is
port(Clk:in std_logic;
speaker1:out std_logic;
key1,key2,key3: in std_logic;
s:buffer std_logic_vector(7 downto 0);--段选
q:buffer std_logic_vector(5 downto 0));--字选
end entity DigitalClock;
architecture rtl of DigitalClock is
component fenpin
port (clk:in std_logic;
clk1: out std_logic;
clk500: out std_logic;
clk1000: out std_logic;
clk16:out std_logic;
clk256: out std_logic);
end component;
component second
port (clk,clr:in std_logic;
sec1,sec0:out std_logic_vector(3 downto 0);
co:out std_logic);
end component;
component minute
port (clk:in std_logic;
min1,min0:out std_logic_vector(3 downto 0);
co:out std_logic);
end component;
component hour
port(clk:in std_logic;
h1,h0:out std_logic_vector(3 downto 0));
end component;
component debounce
port(clk:in std_logic;
din:in std_logic;
dout:out std_logic);
end component;
component ctrl
port(clk:in std_logic; --10HZ
key1,key2,key3:in std_logic;
led1,led2,led3:out std_logic);
end component;
component xiang
port(m1,m0,s1,s0:in std_logic_vector(3 downto 0);
clk1,clk2:in std_logic;
speaker:out std_logic);
end component;
component saomiao
port(
clk500:in std_logic;
cnt1:out integer);
end component;
component f2e
port(
clk:in std_logic;
high,low:in std_logic_vector(3 downto 0);
num1,num0:out std_logic_vector(7 downto 0));
end component;
signal S_clr,net,mclk,hclk,ground,nnet8,nnet11, net1,net2,net3,net4,net5,net8,net11,net14,net15,net16: std_logic;
signal net17: std_logic_vector(2 downto 0);
signal net_7,net_6,net_10,net_9,net_13,net_12,net6,net7,net9,net10,net12,net13,net18:std_logic_vector(3 downto 0);
signal sec_0,sec_1,min_0,min_1,h_0,h_1,Shumaguan: std_logic_vector(7 downto 0);
signal cn1: integer;
begin
u1: fenpin port map (clk => Clk, clk1 => net1,clk16 => net2,
clk256 => net3, clk500 => net4, clk1000 => net5);
u2: second port map (clk => net1, sec0 => net6, sec1 => net7,
co => net8, clr => S_clr);
u3: minute port map (clk => mclk, min0 => net9, min1 => net10,
co => net11);
u4: hour port map (clk => hclk, h0 => net12, h1 => net13
);
u5: debounce port map (clk => clk, din => key1,
dout => net14);
u6: debounce port map (clk => clk, din => key2,
dout => net15);
u7: debounce port map (clk => clk, din => key3,
dout => net16);
u8: ctrl port map (clk => net2, key1 => net14, key2 => net15,
key3 => net16, led2 => nnet8, led1 => nnet11,
led3 => S_clr);
u9: f2e port map (clk => Clk, high => net7, low => net6,
num1 => sec_1, num0 => sec_0);
u10: f2e port map (clk => Clk, high => net10, low => net9,
num1 => min_1, num0 => min_0);
u11: f2e port map (clk => Clk, high => net13, low => net12,
num1 => h_1, num0 => h_0);
u12: saomiao port map (clk500 =>net4, cnt1 => cn1);
u13: xiang port map (clk1 => net4, clk2 => net5, speaker =>speaker1,
m1 => net10, m0 => net9, s1 => net7, s0 => net6);
process (net4,s,q)
begin
mclk <= net8 or nnet8;
hclk <= net11 or nnet11;
case cn1 is
when 0 => s <= h_1; q <="011111";
when 1 => s <= h_0; q <="101111";
when 2 => s <= min_1; q <="110111";
when 3 => s <= min_0; q <="111011";
when 4 => s <= sec_1; q <="111101";
when 5 => s <= sec_0; q <="111110";
when others => null;
end case;
end process;
end rtl;
时间计数开关(控制开关模块):
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
entity ctrl is
port(clk:in std_logic; --10HZ
key1,key2,key3:in std_logic;
led1,led2,led3:out std_logic);
end ctrl;
architecture a of ctrl is
begin
process (clk)
begin
if(clk'event and clk='1')then
if(key1='0')then
led1<='1';
elsif(key1='1')then
led1<='0';
end if;
if(key2='0')then
led2<='1';
elsif(key2='1')then
led2<='0';
end if;
if(key3='0')then
led3<='1';
elsif(key3='1')then
led3<='0';
end if;
end if;
end process;
end a;
防抖模块:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity debounce is
port( clk,din: in std_logic;
dout: out std_logic);
end debounce;
architecture behav of debounce is
signal counter:integer range 0 to 50000000;
signal df_1,df_2,df,rst_n:std_logic;
constant timer:integer:=5000;
begin
process(clk)
begin
if clk'event and clk='1' then
df_1<=din;
df_2<=df_1;
end if;
df<=df_1 xor df_2;
rst_n<=df;
end process;
process(clk,rst_n)
begin
if rst_n='1' then
counter<=0;
elsif clk'event and clk='1' then
counter<=counter+1;
if counter=50000000 then
counter<=0;
end if;
if counter>=timer then
dout<=din;
end if;
end if;
end process;
end behav;
解码段选模块:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity f2e is
port(
clk:in std_logic;
high,low:in std_logic_vector(3 downto 0);--------------------------------时钟信号
num1,num0:out std_logic_vector(7 downto 0));
end f2e;
architecture beh of f2e is
begin
process(clk,high,low)
begin
case high is
when ("0000")=> num1 <= "11000000";
when ("0001")=> num1 <= "11111001";
when ("0010")=> num1 <= "10100100";
when ("0011")=> num1 <= "10110000";
when ("0100")=> num1 <= "10011001";
when ("0101")=> num1 <= "10010010";
when ("0110")=> num1 <= "10000010";
when ("0111")=> num1 <= "11111000";
when ("1000")=> num1 <= "10000000";
when ("1001")=> num1 <= "10010000";
when others=> num1 <= null;
end case;
case low is
when "0000"=> num0 <= "11000000";
when "0001"=> num0 <= "11111001";
when "0010"=> num0 <= "10100100";
when "0011"=> num0 <= "10110000";
when "0100"=> num0 <= "10011001";
when "0101"=> num0 <= "10010010";
when "0110"=> num0 <= "10000010";
when "0111"=> num0 <= "11111000";
when "1000"=> num0 <= "10000000";
when "1001"=> num0 <= "10010000";
when others=> num0 <= null;
end case;
end process;
end beh;
分频模块:
library ieee;
use ieee.std_logic_1164.all;
entity fenpin is
port (clk:in std_logic;
clk1: out std_logic;
clk500: out std_logic;
clk1000: out std_logic;
clk16:out std_logic;
clk256: out std_logic);
end fenpin;
architecture fen_arc of fenpin is
begin
process(clk)
variable cnt1: integer range 0 to 24999999;
variable cnt500: integer range 0 to 49999;
variable cnt1000: integer range 0 to 24999;
variable cnt16: integer range 0 to 1669999;
variable cnt256: integer range 0 to 99999;
variable x: std_logic;
variable y: std_logic;
variable z: std_logic;
variable m: std_logic;
variable n: std_logic;
begin
if clk'event and clk = '1' then
if cnt1<24999999 then
cnt1:=cnt1+1;
else
cnt1:=0;
x:= not x;
end if;
end if;
clk1<=x;
if clk'event and clk = '1' then
if cnt500<49999 then
cnt500:=cnt500+1;
else
cnt500:=0;
y:= not y;
end if;
end if;
clk500<=y;
if clk'event and clk = '1' then
if cnt1000<24999 then
cnt1000:=cnt1000+1;
else
cnt1000:=0;
z:= not z;
end if;
end if;
clk1000<=z;
if clk'event and clk = '1' then
if cnt16<1669999 then
cnt16:=cnt16+1;
else
cnt16:=0;
m:= not m;
end if;
end if;
clk16<=m;
if clk'event and clk = '1' then
if cnt256<99999 then
cnt256:=cnt256+1;
else
cnt256:=0;
n:= not n;
end if;
end if;
clk256<=n;
end process;
end fen_arc;