最近用VHDL语言写的数字钟

来源:互联网 发布:mobi域名开始多少年了 编辑:程序博客网 时间:2024/04/30 14:47

数字钟设计

一、实验目的:

1.熟悉和掌握基本电子计数器及数码显示的工作原理

2.能独立的完成基本电子计数器的设计,并由此设计出带一定功能的电子钟

二、实验要求

设计一个能进行时、分、秒计时的十二小时制或二十四小时制的数字钟,并具有定时与闹钟功能,能在设定的时间发出闹铃音,能非常方便地对小时、分钟和秒进行手动调节以校准时间,每逢整点,产生报时音报时。

三、实验平台:

MAX+PLUSII10.1

四、实验过程

一)、总体思路:

   这是一个电子钟,其功能如下:可以实现正常的时钟功能,可以调整时间,整点会报时(用显示灯表示),同时还可以设置闹钟,可以显示所设的闹钟值,闹钟有分响铃(用批示灯表示)。在需要校正时间时,不需要暂停时间,可以像在手机上操作一样,用三个调整键,分别对小时调整(CHANGEH),对分钟的第一位调整(CHANGETM),对分钟的第二位调整(CHANGEM)。为了更好的操作,加一个UPDOWN键,为1时,则是每次加1,为0时,则是每次减1。对闹钟进行设置时,不影响正常的计时模块,所以不分影响准确的时间。对每一部分的操作则是通过总的控制模块来实现的。

 

 

整个数字钟的系统框图如下图所示:

 

 

 

 

该数字钟的硬件系统示意图如下图所示:

 

 

二)、模块及代码和波形图:

1、正常计时模块:

★、六进制计数器COUNT6VHDL代码:

LIBRARY IEEE;

USE IEEE.STD_LOGIC_1164.ALL;

USE IEEE.STD_LOGIC_ARITH.ALL;

USE IEEE.STD_LOGIC_UNSIGNED.ALL;

ENTITY COUNT6 IS

 PORT( CLK,UPDOWN,CLR,P:IN STD_LOGIC;

       Q:BUFFER STD_LOGIC_VECTOR(2 DOWNTO 0);

       COUT:OUT STD_LOGIC);

END COUNT6;

 

ARCHITECTURE RTL OF COUNT6 IS

BEGIN

 PROCESS(CLK,CLR,P)

 BEGIN

  IF(CLR='0')THEN

    Q<="000";

    COUT<='0';

  ELSIF(CLK'EVENT)AND(CLK='1')THEN

      IF(P='0')THEN

           IF(Q="101")THEN

              Q<="000";

              COUT<='1';

           ELSE Q<=Q+1;

              COUT<='0';

           END IF;

      ELSE

        IF(UPDOWN='1')THEN

           IF(Q="101")THEN

              Q<="000";

              COUT<='0';

           ELSE Q<=Q+1;

              COUT<='0';

           END IF;

        ELSE 

           IF(Q="000")THEN

              Q<="101";

              COUT<='0';

           ELSE Q<=Q-1;

              COUT<='0';

           END IF;

        END IF;

      END IF;

  END IF;

 END PROCESS;

END RTL;

COUNT6波形仿真图:

 

★、十进制计数器COUNT10VHDL代码:

LIBRARY IEEE;

USE IEEE.STD_LOGIC_1164.ALL;

USE IEEE.STD_LOGIC_ARITH.ALL;

USE IEEE.STD_LOGIC_UNSIGNED.ALL;

ENTITY COUNT10 IS

 PORT( CLK,UPDOWN,CLR,P:IN STD_LOGIC;

       Q:BUFFER STD_LOGIC_VECTOR(3 DOWNTO 0);

       COUT:OUT STD_LOGIC);

END COUNT10;

 

ARCHITECTURE RTL OF COUNT10 IS

BEGIN

 PROCESS(CLK,CLR,P)

 BEGIN

  IF(CLR='0')THEN

    Q<="0000";

    COUT<='0';

  ELSIF(CLK'EVENT)AND(CLK='1')THEN

      IF(P='0')THEN

           IF(Q="1001")THEN

              Q<="0000";

              COUT<='1';

           ELSE Q<=Q+1;

              COUT<='0';

           END IF;

      ELSE

        IF(UPDOWN='1')THEN

           IF(Q="1001")THEN

              Q<="0000";

              COUT<='1';

           ELSE Q<=Q+1;

              COUT<='0';

           END IF;

        ELSE 

           IF(Q="0000")THEN

              Q<="1001";

              COUT<='1';

           ELSE Q<=Q-1;

              COUT<='0';

           END IF;

        END IF;

      END IF;

  END IF;

 END PROCESS;

END RTL;

COUNT10的波开仿真图:

 

★、12小时进制的计数器COUNTM代码:

LIBRARY IEEE;

USE IEEE.STD_LOGIC_1164.ALL;

USE IEEE.STD_LOGIC_ARITH.ALL;

USE IEEE.STD_LOGIC_UNSIGNED.ALL;

ENTITY COUNTM IS

 PORT( CLK,UPDOWN,CLR,P:IN STD_LOGIC;

       Q:BUFFER STD_LOGIC_VECTOR(3 DOWNTO 0));

      

END COUNTM;

 

ARCHITECTURE RTL OF COUNTM IS

BEGIN

 PROCESS(CLK,CLR,P)

 BEGIN

  IF(CLR='0')THEN

    Q<="0000";

  ELSIF(CLK'EVENT)AND(CLK='1')THEN

      IF(P='0')THEN

           IF(Q="1011")THEN

              Q<="0000";

           ELSE Q<=Q+1;

           END IF;

      ELSE

        IF(UPDOWN='1')THEN

           IF(Q="1011")THEN

              Q<="0000";

           ELSE Q<=Q+1;

           END IF;

        ELSE 

           IF(Q="0000")THEN

              Q<="1011";

           ELSE Q<=Q-1;

           END IF;

        END IF;

      END IF;   

  END IF;

 END PROCESS;

END RTL;

COUNTM波形图:

 

2、闹钟设置模块:

★、六进制闹钟设置模块RING6代码:

LIBRARY IEEE;

USE IEEE.STD_LOGIC_1164.ALL;

USE IEEE.STD_LOGIC_ARITH.ALL;

USE IEEE.STD_LOGIC_UNSIGNED.ALL;

ENTITY RING6 IS

 PORT( CLK,UPDOWN,CLR,P:IN STD_LOGIC;

       Q:BUFFER STD_LOGIC_VECTOR(2 DOWNTO 0);

       COUT:OUT STD_LOGIC);

END RING6;

 

ARCHITECTURE RTL OF RING6 IS

BEGIN

 PROCESS(CLK,CLR,P)

 BEGIN

  IF(CLR='0')THEN

    Q<="000";

    COUT<='0';

  ELSIF(CLK'EVENT)AND(CLK='1')THEN

      IF(P='0')THEN

            COUT<='0';

           Q<=Q;

      ELSE

        IF(UPDOWN='1')THEN

           IF(Q="101")THEN

              Q<="000";

              COUT<='0';

           ELSE Q<=Q+1;

              COUT<='0';

           END IF;

        ELSE 

           IF(Q="000")THEN

              Q<="101";

              COUT<='0';

           ELSE Q<=Q-1;

              COUT<='0';

           END IF;

        END IF;

      END IF;

  END IF;

 END PROCESS;

END RTL;

 

RING6波形图:

 

★、十进制闹钟设置模块RING10代码:

LIBRARY IEEE;

USE IEEE.STD_LOGIC_1164.ALL;

USE IEEE.STD_LOGIC_ARITH.ALL;

USE IEEE.STD_LOGIC_UNSIGNED.ALL;

ENTITY RING10 IS

 PORT( CLK,UPDOWN,CLR,P:IN STD_LOGIC;

       Q:BUFFER STD_LOGIC_VECTOR(3 DOWNTO 0);

       COUT:INOUT STD_LOGIC);

END RING10;

 

ARCHITECTURE RTL OF RING10 IS

BEGIN

 PROCESS(CLK,CLR,P)

 BEGIN

  IF(CLR='0')THEN

    Q<="0000";

    COUT<='0';

  ELSIF(CLK'EVENT)AND(CLK='1')THEN

      IF(P='0')THEN

          COUT<='0';

           Q<=Q;

      ELSE

        IF(UPDOWN='1')THEN

           IF(Q="1001")THEN

              Q<="0000";

              COUT<='1';

           ELSE Q<=Q+1;

              COUT<='0';

           END IF;

        ELSE IF(UPDOWN='0')THEN

           IF(Q="0000")THEN

              Q<="1001";

              COUT<='1';

           ELSE Q<=Q-1;

              COUT<='0';

           END IF;

        END IF;

      END IF;

  END IF;

 END IF;

 END PROCESS;

END RTL;

 

RING10波形仿真图:

★、闹钟模块12小时进制RING12Y代码

LIBRARY IEEE;

USE IEEE.STD_LOGIC_1164.ALL;

USE IEEE.STD_LOGIC_ARITH.ALL;

USE IEEE.STD_LOGIC_UNSIGNED.ALL;

ENTITY RING12Y IS

 PORT( CLK,UPDOWN,CLR,P:IN STD_LOGIC;

       Q:BUFFER STD_LOGIC_VECTOR(3 DOWNTO 0));

END RING12Y;

 

ARCHITECTURE RTL OF RING12Y IS

BEGIN

 PROCESS(CLK,CLR,P)

 BEGIN

  IF(CLR='0')THEN

    Q<="0000";

  ELSIF(CLK'EVENT)AND(CLK='1')THEN

      IF(P='0')THEN

           Q<=Q;

      ELSE

        IF(UPDOWN='1')THEN

           IF(Q="1011")THEN

              Q<="0000";

          

           ELSE Q<=Q+1;

           END IF;

        ELSE 

           IF(Q="0000")THEN

              Q<="1011";

           ELSE Q<=Q-1;

           END IF;

        END IF;

      END IF;

  END IF;

 END PROCESS;

END RTL;

RING12Y波形图:

 

3、整个闹钟模块的测试:

电路图:

 

RS1时,设置闹钟,可对闹钟进行调整,当UPDOWN1 时,每一个CLK使相应的计时模块加1 ,当UPDOWN0时,每一个CLK使相应的模块减1 ;当RS0时,则定了闹钟。为了便于调整,每一个模块都有一个CHANGE,否则当从0调到60时,则要按60次,而我这样设计,对各个模块进行调整,非常方便。

 

 

波形仿真图:

 

 

4、正常时钟模块测试:

电路图:

此时的时钟周期是20ns的波形图:

由于时钟周期不够,固不能看到分钟和时钟的变化。但但秒的变化是很明显的。其中,MFIVE[3..0]是秒的个位;MFOUR[3..0]是秒的十位。从图中可以看出,到了9秒后,就往十位进一。再到9秒后再进一,十位变为2

 

当把时钟周期减小时,时钟周期为2ns时的波形图:

由于周期太小,所以秒的个位看不见。但可以很明显看到,到达59秒后,又恢复0秒,然而分钟的个位增1,即进位,再次到达59秒后,又进一,分钟个位为2,即到达2分钟。

 

调整时钟波形图:

 

 

从图中可以看出,当调整时钟信号有效时,可以进行高速时钟,而且与预期的结果相同。同时还验证了另一个功能的正确性。即对小时部分十位的显示。小小于10小时时,十位显示的是0,而当大于等于10小时时,十位显示的是1.如,10小时时,十位显示1,个位显示011小时时,十位显示1,个位显示112小时则是显示00

 

 

5、控制模块的测试:

 

CONTROLALL代码:

 

SUBDESIGN CONTROLALL

 ( 

       A,B,RESET,RESET1,TURN:INPUT;

    LD_H,LD_M,RS,CLR,XIANSHI,NFOUR[3..0],NFIVE[3..0]:OUTPUT;)

BEGIN

  NFOUR[3..0]=B"0000";

  NFIVE[3..0]=B"0000";

IF(RESET==B"0")THEN

      CLR=B"0";

      XIANSHI=B"0";

      LD_H=B"0";

      LD_M=B"0";

  RS=B"0";

ELSE

   CLR=B"1";

   IF (A==B"0" AND B==B"0")THEN

      XIANSHI=B"0";

      LD_H=B"0";

      LD_M=B"0";

      RS=B"0";   

    

   ELSIF(A==B"0" AND B==B"1")THEN

     IF(TURN==B"0")THEN

      RS=B"0";

      XIANSHI=B"0";

      LD_H=B"1";

      LD_M=B"0";

     ELSE

      LD_H=B"0";

      LD_M=B"1";

      XIANSHI=B"0";

      RS=B"0";

     END IF;  

 

   ELSIF(A==B"1" AND B==B"0")THEN

    IF(RESET1==B"1")THEN

     RS=B"1";

     LD_H=B"0";

     LD_M=B"0";

     XIANSHI=B"1";

    ELSE

      RS=B"0";

      XIANSHI=B"1";

      LD_H=B"0";

      LD_M=B"0";

    END IF;

  ELSE

      RS=B"0";

      XIANSHI=B"0";

      LD_H=B"0";

      LD_M=B"0";        

  END IF;

 END IF;

END;

 

 

测试电路图:

 

 

波形仿真图:

从图中可以看出,与预期的结果相同,能实现各个控制信号的控制。

总图:

 

打包后: