硬件描述语言大作业:数字电子钟

预习报告部分

  • 实验目的:设计和实现一个数字电子钟(利用蜂鸣器能设定条件进行报时),学会设计模块化和复用,以及时钟信号的生成与管理,学会如何使用VHDL来描述和实现复杂的硬件功能。
  • 实验原理:

这个电子钟包括分频模块、计数器模块、去抖动模块、控制模块控制蜂鸣器模块解码模块和数码管驱动时间显示模块计数器模块中又有六十计数器模块和二十四计数器模块。其中六十计数器用来实现分秒计时,二十四计数器用来实现小时计数。并且该实验使用来自外部的高频时钟信号,并将其划分为较低的频率,这些频率适合驱动计算秒、分钟和小时的计时逻辑,并且在计时的同时也将各个部分的计数值输入给数码管驱动电路,电路将编码结果输出给数码管作为字选和段选信号。控制模块中,用户可以通过拨动开关的方式输入时间或启动暂停时间,并使用七段显示显示时间。蜂鸣器,蜂鸣器报时,防抖,用来设定在特定时间启动。(比如秒数个位为9时响一次)。

该实验是通过使用一系列计数器来表示小时、分钟和秒来实现的。这些计数器由时钟信号递增,该时钟信号通常以远高于每秒一个脉冲的频率运行。计数器被设计为在达到最大计数时翻转,如在计数分钟或秒时从 59 移动到 00。

  • 实验内容:编写VHDL语言代码来在HDLE-1硬件描述语言综合实验平台上,实现数字电子钟功能。
  • 实验所用设备: PC个人计算机、Windows操作系统、Quartus II集成开发环境软件、HDLE-2硬件描述语言综合实验平台。
  • 实验步骤:①建立工程、②编辑代码、③编译及修改错误、④实验平台装载程序、⑤演示实验结果。

实验报告部分

  • 实验步骤:
  1. 建立工程

左侧即为建立的各个功能模块,digitalclock作为顶层实体,将其它模块进行综合。

2.编写代码与编译

  1. 分频模块:采用高频时钟输入并生成几个较慢的时钟信号,用于以适当的速度驱动时钟逻辑的不同部分。

  1. 计时器模块:用于秒、分钟和小时的计数器模块。它们会增加时间,并在结束复位时提供结转信号 (co)(例如,从 59 秒到 00)。

  1. 去抖动模块:清除来自输入按钮(key1、key2、key3)的信号,过滤掉按下按钮时产生的机械噪音。

  1. 控制模块:处理来自按钮的输入以设置时间或控制其他功能。

  1. 解码模块:将二进制编码的十进制 (BCD) 输入转换为用于驱动七段显示器的信号。将高低BCD数字转换为相应的7段代码进行显示。

  1. saomiao模块:负责扫描或多路复用显示器,驱动数码管显示时间。

  1. 蜂鸣器控制模块:

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;

  • 16
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值