当前位置:   article > 正文

电子计时时钟带设计报告VHDL代码Quartus仿真_电子秒表仿真设计quartus

电子秒表仿真设计quartus

名称:电子计时时钟带设计报告VHDL代码Quartus仿真(文末获取)

软件:Quartus

语言:VHDL

代码功能:

电子计时时钟带设计报告

利用VHDL语言,实现电子计时时钟,要求能够显示分钟、秒钟,显示输出为共阴极数码管,要求:

1、电子计时时钟具有异步清零、同步置数功能,用VHDL实现计数逻辑,并阐述设计原理,给出关键block diagram设计框图。

2、用VHDL实现译码显示逻辑,并阐述设计原理,给出关键block diagram设计框图。

3、驱动的数码管为共阴极数码管,阐述电路原理,给出相应编码方式。

(1)按设计指导书中要求的格式书写,所有内容一律打印;

(2)报告内容包括设计过程、软件仿真的结果及分析; 

(3)报告中要有整体电路原理图、各模块原理图; 

(4)软件仿真包括各个模块的仿真和整体电路的仿真;

1. 工程文件

2. 程序文件

3. 程序编译

4. RTL图

5. 仿真图

整体仿真图

60进制计数器模块

显示模块

电子计时时钟设计报告

一、功能要求

利用VHDL语言,实现电子计时时钟,要求能够显示分钟、秒钟,显示输出为共阴极数码管,要求:

1、电子计时时钟具有异步清零、同步置数功能,用VHDL实现计数逻辑,并阐述设计原理,给出关键block diagram设计框图。

2、用VHDL实现译码显示逻辑,并阐述设计原理,给出关键block diagram设计框图。

3、驱动的数码管为共阴极数码管,阐述电路原理,给出相应编码方式。

二、设计原理

根据功能要求分析,设计电子计时时钟,要求能够显示分钟、秒钟,分钟和秒钟都是60进制,因此可以设计一个60进制的计数器,然后将该计数器调用2次,将秒钟对应的60进制计数器的进位输出控制分钟计数,也就是当秒钟计数60次后,分钟计数1次。这样就能实现分钟和秒钟的控制。秒钟的60进制计数器控制时钟为1Hz,即1秒计数一次。要求驱动的数码管为共阴极数码管,共阴极数码管的原理为8个发光二极管的阴极连在一起,分8个端口的控制信号,当端口输入高电平时,对应的二极管点亮,如下图所示。

三、设计过程

3.1. 60进制的计数器设计

60进制计数器的输入端口有时钟端口clk,异步清零端口reset、同步置数信号set_key,同步置数十位time_ten[3:0]和同步置数十位time_one[3:0]以及使能信号端口enable;输出端口为十位输出cnt_ten[3:0],个位输出cnt_one[3:0]以及进位输出cout。

下图为60进制计数器的原理图

具体代码编码分2部分,一部分为计数控制,一部分为进位信号控制。计数控制首先判断reset值若为高电平,则输出全为0,然后在时钟clk的上升沿检测同步置数信号,若为高电平,则进行置位,将同步置数十位time_ten[3:0]和同步置数十位time_one[3:0]赋值给计数器。然后判断enable,若为高电平则正常计数,计数时先对个位计数,个位计数到9后,个位清零,十位加1,若计数到59,则十位个位均回0。

进位信号的控制为判断此时十位和个位是否已经计数到59,若是,则输出1,否则输出0。至此60进制计数器就设计完成了。

3.2 显示译码模块设计

显示译码模块的输入信号为分钟十位和个位cnt_ten_minute[3:0]、cnt_one_minute[3:0]以及秒钟的十位和个位cnt_ten_second[3:0]、cnt_one_second[3:0]。输出打端口为4个数码管输出端口,与输入一一对应,分别为分十位、分个位、秒十位、秒个位:HEX_ten_minute[3:0]、HEX_one_minute[3:0]、HEX_ten_second[3:0]、HEX_one_second[3:0]。下图为显示译码模块的原理图。

具体代码编码采用case语句,分为4个进程,一个进程对应一个数码管的译码,输入计数信号的值为0~9的范围,因此需要对0~9共10个数进行编码。根据下图,可以分析得到每个数字对应的a,b,c,d,e,f,g,dp值。

3.3 顶层电路设计

模块代码设计完成后,在顶层新建原理图文件,添加2个60进制计数器模块和一个显示译码模块,原理图如下:

图中,将秒钟的60进制计数器的cout信号作为分钟的enable信号,使得秒钟计数到59时可以触发分钟的计数器加1。再将秒钟的计数输出和分钟的计数输出都连到显示模块的输入,最终得到完成的电路图。

四、仿真结果及分析

4.1 计数器模块仿真

60进制计数器模块的仿真图如下所示

上图中,当reset信号为高电平时,电路异步清零,cnt_ten和cnt_one输出均为0,reset信号为低电平时,enable为高电平,开始计数,当检测到set_key为高电平时,进行同步置数,cnt_ten和cnt_one输出均为置数的time_ten和time_one。set_key为低电平时,继续从当前值进行计数,当计数到59时输出进位信号cout,同时计数器回到0。仿真图验证了计数器的各项功能。

4.2 译码模块仿真

译码模块的仿真图如下图所示:

上图中,HEX_ten_minute[3:0]、HEX_one_minute[3:0]、HEX_ten_second[3:0]、HEX_one_second[3:0]分别表示分十位、分个位、秒十位、秒个位。其中HEX_ten_minute对应的译码值为01001111(最高位为dp,最低位为a),通过与数码管对应的a,b,c,d,e,f,g,dp值比较,该码对应的数字为3,与cnt_ten_minute的值一致,因此分钟十位译码仿真正确,其他为同理,均能验证仿真正确。

4.3 整体仿真

整体功能仿真如下图所示:

图中,异步清零和同步置数功能与60进制计数器模块的仿真一致,且可以观察到秒钟计数到59后,分钟才加1,且同时秒钟回答0重新开始计数。下图为整体仿真图的局部放大图,图中可以清晰看到秒钟到分钟的进位过程。

最终的4个数码管显示信号为HEX0、HEX1,HEX2,HEX3,其中HEX1为秒钟个位,HEX0为秒钟十位,HEX3为分钟个位,HEX2为分钟十位。

五、总结

通过此次实验,我使用QuartusII软件和VHDL语言,设计了电子计时时钟,且通过模块仿真和整体仿真验证了设计的正确性,使我对Quartus软件的使用更加熟悉,同时也进一步加深了对VHDL语言的理解。目前我所设计的这个电子时钟只是仿真,并没有时间在硬件上运行,后续如果改进的话可以尝试使其真正的在开发板上运行。

部分代码展示:

LIBRARY ieee;
   USE ieee.std_logic_1164.all;
   USE ieee.std_logic_unsigned.all;
--60进制计数器
ENTITY counter_60 IS
   PORT (
      clk      : IN STD_LOGIC;--时钟
  enable   : IN STD_LOGIC;--使能
  reset    : IN STD_LOGIC;--复位,异步清零
      set_key  : IN STD_LOGIC;--同步置数按键
      time_ten : IN STD_LOGIC_VECTOR(3 DOWNTO 0);--置数值十位
      time_one : IN STD_LOGIC_VECTOR(3 DOWNTO 0);--置数值个位  
      cnt_ten  : OUT STD_LOGIC_VECTOR(3 DOWNTO 0);--计数值十位
      cnt_one  : OUT STD_LOGIC_VECTOR(3 DOWNTO 0);--计数值个位
      cout     : OUT STD_LOGIC--进位
   );
END counter_60;
ARCHITECTURE behave OF counter_60 IS
   SIGNAL cnt_ten_buf : STD_LOGIC_VECTOR(3 DOWNTO 0) := "0000";--计数值十位
   SIGNAL cnt_one_buf : STD_LOGIC_VECTOR(3 DOWNTO 0) := "0000";--计数值个位
BEGIN
   PROCESS (clk,reset)
   BEGIN
IF(reset='1')THEN--异步复位
cnt_ten_buf <= "0000";
        cnt_one_buf <= "0000";
ELSIF (clk'EVENT AND clk = '1') THEN--正常计时
IF(set_key='1')THEN--同步置数
cnt_ten_buf <= time_ten;--置数值十位
cnt_one_buf <= time_one;--置数值个位  
ELSIF(enable='1')THEN--使能
 IF (cnt_ten_buf = "0101" AND cnt_one_buf = "1001") THEN--59后变为00
cnt_ten_buf <= "0000";
cnt_one_buf <= "0000";
 ELSIF (cnt_one_buf = "1001") THEN--个位为9,十位加1
cnt_ten_buf <= cnt_ten_buf + "0001";
cnt_one_buf <= "0000";
 ELSE--个位累加
cnt_ten_buf <= cnt_ten_buf;
cnt_one_buf <= cnt_one_buf + "0001";
 END IF;
END IF;
     END IF;
   END PROCESS;
cout<='1' when (cnt_ten_buf = "0101" AND cnt_one_buf = "1001") else '0';--进位
   
   cnt_ten <= cnt_ten_buf;--计数值十位
   cnt_one <= cnt_one_buf;--计数值个位   
END behave;
源代码

 扫描文章末尾的公众号二维码

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小小林熬夜学编程/article/detail/467466
推荐阅读
相关标签
  

闽ICP备14008679号