基于VHDL的全自动洗衣机控制器设计

全自动洗衣机控制器设计

  • 《数字电子技术》课程设计报告
  • 《数字电子技术》课程设计任务书
    • 设计内容与要求
  • 1.概述
    • 1.1EDA简介
    • 1.2开发软件quartus简介
  • 2.基本原理
    • 2.1洗衣机原理
    • 2.2定时器原理
    • 2.3状态转换原理
  • 3.设计方案
  • 4.设计验证与测试
    • 4.1设计软件环境搭建
    • 4.2定时模块实现(DSMK.vhd和DSMK.vwf)
    • 4.3状态机实现(ZTJ.vhd和ZTJ.vwf)
    • 4.4顶层设计实现(DCSJ.vhd和DCSJ.vwf)
  • 5.结论
    • 5.1问题与思考
    • 5.2完成感想
  • 参考文献
  • 附录
    • 1.定时模块源代码
    • 2.状态机源代码
    • 3.顶层设计源代码

        本文章发布时距离实践已有些许时间,代码和相关描述来自存留的作业文档存根,保证逻辑正确性但不保证一些缩进和其他格式是否出现问题,可根据错误提示自行改正。本设计为非专业人士设计,存在效率以及整体规划不够理想的缺陷,仅提供参考。

《数字电子技术》课程设计报告

题 目: 全自动洗衣机控制器设计
专业班级: 通信17级
学 号: 000000000000
姓 名: XXXX
指导教师: XXX
完成日期: 2020.6.28

《数字电子技术》课程设计任务书

设计内容与要求

一、设计目的
        设计全自动洗衣机控制器,学习较复杂的数字系统设计方法。
二、设计原理
        设计一个简易的全自动洗衣机控制器,该控制器可以实现全自动洗衣机的定时启动,自动控制及定时设置等功能。其工作流程为:定时启动→正转20s→暂停10s→反转20s→暂停10s→定时不到,重复上述过程,若定时已到,停止发出音响。控制器的设计主要是定时器的设计,利用减法计数器,时序控制电路和工作状态控制电路等组成,可以实现正转、反转和暂停等洗衣机的工作过程,并且用四个数码管可以显示预置洗涤时间,按倒计时方式对洗涤过程进行计数显示,直到时间到停机。
三、设计内容及要求
        根据实验原理,设计全自动洗衣机控制器的各功能模块,通过按键可以设置预置洗涤时间,三种时间可选:15min,30min和45min,然后系统按洗衣机的工作原理模拟其工作过程,并用三个发光二极管表示正反转和暂停三个状态。
四、设计总结报告
        根据以上的设计内容写出设计报告,包括设计程序、软件编译、仿真波形图,并做分析总结。

1.概述

1.1EDA简介

        EDA是电子设计自动化(Electronic Design Automation)的缩写,在20世纪90年代初从计算机辅助设计(CAD)、计算机辅助制造(CAM)、计算机辅助测试(CAT)和计算机辅助工程(CAE)的概念发展而来的。
        20世纪90年代,国际上电子和计算机技术较先进的国家,一直在积极探索新的电子电路设计方法,并在设计方法、工具等方面进行了彻底的变革,取得了巨大成功。在电子技术设计领域,可编程逻辑器件(如CPLD、FPGA)的应用,已得到广泛的普及,这些器件为数字系统的设计带来了极大的灵活性。这些器件可以通过软件编程而对其硬件结构和工作方式进行重构,从而使得硬 件的设计可以如同软件设计那样方便快捷。这一切极大地改变了传统的数字系统设计方法、设计过程和设计观念,促进了EDA技术的迅速发展。
        EDA技术就是以计算机为工具,设计者在EDA软件平台上,用硬件描述语言HDL完成设计文件,然后由计算机自动地完成逻辑编译、化简、分割、综合、优化、布局、布线和仿真,直至对于特定目标芯片的适配编译、逻辑映射和编程下载等工作。EDA技术的出现,极大地提高了电路设计的效率和可操作性,减轻了设计者的劳动强度。
        利用EDA工具,电子设计师可以从概念、算法、协议等开始设计电子系统,大量工作可以通过计算机完成,并可以将电子产品从电路设计、性能分析到设计出IC版图或PCB版图的整个过程的计算机上自动处理完成。
        现在对EDA的概念或范畴用得很宽。包括在机械、电子、通信、航空航天、化工、矿产、生物、医学、军事等各个领域,都有EDA的应用。目前EDA技术已在各大公司、企事业单位和科研教学部门广泛使用。例如在飞机制造过程中,从设计、性能测试及特性分析直到飞行模拟,都可能涉及到EDA技术。

1.2开发软件quartus简介

        Altera Quartus II 作为一种可编程逻辑的设计环境, 由于其强大的设计能力和直观易用的接口,越来越受到数字系统设计者的欢迎。
        Altera Quartus II (3.0和更高版本)设计软件是业界唯一提供FPGA和固定功能HardCopy器件统一设计流程的设计工具。工程师使用同样的低价位工具对 Stratix FPGA进行功能验证和原型设计,又可以设计HardCopy Stratix器件用于批量成品。系统设计者现在能够用Quartus II软件评估HardCopy Stratix器件的性能和功耗,相应地进行最大吞吐量设计。
        Altera的Quartus II可编程逻辑软件属于第四代PLD开发平台。该平台支持一个工作组环境下的设计要求,其中包括支持基于Internet的协作设计。Quartus平台与Cadence、ExemplarLogic、 MentorGraphics、Synopsys和Synplicity等EDA供应商的开发工具相兼容。改进了软件的LogicLock模块设计功能,增添了FastFit编译选项,推进了网络编辑性能,而且提升了调试能力。

2.基本原理

2.1洗衣机原理

        全自动洗衣机具有时间预置、模式选择、自动控制及状态显示等功能。其工作流程为:预置时间→选择模式→以模式设定程序驱动运转→定时未到,重复上述过程,若定时已到,停止发出音响。控制器的设计主要是定时器的设计,利用减法计数器,时序控制电路和工作状态控制电路等组成,可以实现正转、反转和暂停等洗衣机的工作过程,并且用四个数码管可以显示预置洗涤时间,按倒计时方式对洗涤过程进行计数显示,直到时间到停机。其工作过程图如下图。

开机
预置洗涤时间
模式选择
开始洗涤
洗涤结束
是否再次洗涤
结束

2.2定时器原理

        定时器与计时器不同的是定时器是倒计时,而计时器是正计时,因此有一个减法和加法的区别。定时器需要先将输入的CLK信号分频到1Hz然后在每个上升沿减一。这就涉及到了减法借位的问题,而且单位是时间,所以需要对每一位单独设置进制数,最高位为分钟的十位设为6进制,次位为分钟的个位设为9进制,再次位为秒钟的十位设为6进制,最低位为秒钟的个位设为9进制。预置定时数据输入后会存在每次计数都会输入数据,倒计时结束后,还应发出信号并停止计时,因此设置一个变量表示计数状态是不可或缺的。该变量在开始时置为1,结束时置为零。

2.3状态转换原理

        洗衣机存在正转、反转、暂停三个状态,但是为了方便起见,设置四个状态,正转、正转暂停、反转、反转暂停。本设计采用Moore状态机,在时钟信号进程下,满足条件则发生状态转移,在当前状态进程下,当前状态改变则更新下一个状态,并且输入状态信号,一直到倒计时结束时,停止状态转移。

3.设计方案

基于VHDL的全自动洗衣机控制器设计_第1张图片
        全自动洗衣机可以预置时间,选择模式,然后开始运行,结束发出信号。其中可选模式有强力洗涤,普通洗涤,甩干三种模式。所有输入信号有开/关机信号、预置时间信号、模式选择信号、开始/暂停信号、时钟源信号(内置);输出信号有数码管、二极管、蜂鸣器。考虑到功能众多,将整体设计划分为三个部分:定时模块、状态机和顶层设计。具体的模块与信号关系如上图。
        定时模块主要处理输入的预置时间信号,首先将输入的CLK信号分频为1Hz,然后在开始信号到达后将预置信号的信息送入定时器开始倒计时,当倒计时结束后送出分频信号和倒计时完成信号,还会实时的将时间信息显示在数码管上。倒计时的逻辑较为特殊,考虑到状态机和倒计时的同步性,在状态机上不加开始运行信号,由倒计时完成信号的高电平期间控制状态机运行,因此,倒计时开始和结束的瞬间都会改变倒计时结束的信号。
        状态机会根据秒钟信号和模式选择信号使的洗衣机按照一定的规律运行,并将其状态显示在二极管上。状态机有四个状态,不同的模式下状态机运作方式不同,
当处于强力洗涤模式时,正转20s,正转暂停10s,反转20s,反转暂停10s;当处于普通洗涤模式时,正转15s,正转暂停15s,反转15s,反转暂停15s;当处于甩干模式时,正转15s,正转暂停15s,反转0s,反转暂停0s。详细状态转移如下图。
基于VHDL的全自动洗衣机控制器设计_第2张图片
        顶层文件设计是将所有模块组合在一起拼成一个完整的功能电路,将外部信号与内部信号连接在一起完成设计的最后一步。选择硬件板也是必不可少的一部分,本设计选择了模式9作为硬件环境,其中含有8个带有译码器的数码管,以及8个并行输出二极管和一个蜂鸣器。还有8个单脉冲按键,考虑到既满足必须器件且保持输入统一化,因此选择模式9。数码管的显示为左到右依次为分钟十位,分钟个位,秒钟十位,秒钟个位。二极管左到右,全灭为关机状态,亮灭灭为正转状态,灭亮灭为暂停状态,灭灭亮为反转状态,亮亮亮表示当前选择强力洗涤模式,亮亮灭表示当前选择甩干模式,灭亮亮表示当前选择普通洗涤模式。蜂鸣器发出响声表示洗涤完成。由于选择了8个脉冲按键,因此按键驱动程序也变的复杂起来,把单脉冲转换成需要的信号显得尤为重要。

4.设计验证与测试

4.1设计软件环境搭建

        本设计使用软件QUARTUS II开发,硬件使用的GW48-PK3的主板和GW3C40的适配板。开发时选择目标器件为CycloneIII的EP3C40Q240C8。如下图所示。新建工程文件命名为keshe并新建DSMK.vhd、ZTJ.vhd、DCSJ.vhd、DSMK.vwf、ZTJ.vwf、DCSJ.vwf文件。
基于VHDL的全自动洗衣机控制器设计_第3张图片

4.2定时模块实现(DSMK.vhd和DSMK.vwf)

        定时模块的输入有时钟源信号(CLK)、电源信号(DYXH)、预置时间信号(YZSJ)、开始运行信号(KSYX);输出信号有秒钟输出信号(MZSC)、完成判定信号(WCPD)、时间显示信号(SJXS)。
        时钟源信号输入为4Hz和方波信号,经过分频后传递给秒钟输出信号输出;电源信号为按键输入的单脉冲信号,需要经过转化变为每按一次就改变电平。预置时间信号也为单脉冲信号,每按一次改变预置时间:15分钟→30分钟→40分钟,共三种情况,每次按键还要使得数码管上显示对应的预置时间,该按键仅在电源打开,完成判定信号为低电平时有效,且只在按键单脉冲上升沿上改变预置时间;开始运行信号能将预置的时间送入倒计时进程,且触发倒计时,该信号为单脉冲信号,在触发后第一个秒种上升沿传递预置时间并触发倒计时。
        秒钟输出信号是分频时钟源后的信号;完成判定信号是倒计时的一个状态信号,当倒计时开始的那个秒钟上升沿变为高电平,在倒计时结束那个秒钟上升沿变为低电平,其他时间为低电平;时间显示信号是一个16位数据,其16进制字符表示时间,高位到低位每四位连接一个数码管,如(1500)16表示15分钟,当完成判定信号为低电平时显示预置时间,否则显示倒计时时间。
        该模块进程繁多,实现进程之间的信号传递比较繁琐,需要对进程和信号理解通透,且设置的中间信号较多,须有清楚的逻辑思路。应该熟练运用VHDL语句及QUARTUS II软件。设计的模块代码见附录,模块图如下图。
基于VHDL的全自动洗衣机控制器设计_第4张图片
        时序仿真波形图如图4-2-2和图4-2-3,观察图4-2-2发现电源信号功能正常,高电平时其他各项都有信号,低电平时,其他各项均无信号;预置时间信号功能正常,能够改变预置时间,且在倒计时状态无响应,在未预置时间时进入默认的40分钟选项;开始运行信号功能正常,能够送入预置时间且触发倒计时,并且在倒计时状态无响应;秒钟输出信号功能正常,完成了分频;完成判定信号能够在开始倒计时时变为高电平;观察图4-2-3可以发现,模块在关机重启后显示的是上次的预置时间,且依旧可以预置时间,而倒计时结束后预置时间点击开始运行又可以继续倒计时,无须关机重启,完成判定信号也在倒计时结束后自动变为低电平。
基于VHDL的全自动洗衣机控制器设计_第5张图片

图 4-2-2 定时模块(DSMK)时序仿真图一

基于VHDL的全自动洗衣机控制器设计_第6张图片

图 4-2-3 定时模块(DSMK)时序仿真图二

4.3状态机实现(ZTJ.vhd和ZTJ.vwf)

        状态机的输入有电源信号(DYXH)、模式输入信号(MSSR)、秒钟输入信号(MZSR)、完成判定信号(WCPD);输出信号有状态显示信号(ZTXS)。
        电源信号与定时模块一致,不再赘述;模式输入信号是一个按键发出的单脉冲信号,该信号能够改变寄存器内所存的18位数据,从高位到低位,前4位是反转暂停时间秒数,紧跟的5位是反转时间秒数,再紧跟4位是正转暂停秒数,最后5位是正转秒数。秒钟输入信号即为定时模块秒钟输出信号,该信号输入为了让状态机在规定的时间点转移状态;完成判定信号即为定时模块的完成判定信号,该信号为高电平时状态机会转移状态,并使显示信号显示当前状态,否则显示所选模式。
        状态显示信号包含状态机以及所选模式的信息,是一个3位数据,从高位到低位表示三个二极管的亮/灭情况,当完成判定信号为低电平且电源打开时,状态显示信号显示三种模式,依次为普通洗涤模式(灭亮亮)→强力洗涤模式(亮亮亮)→甩干模式(亮亮灭);当完成判定信号位高电平且电源打开时显示三种状态,依次为正转(亮灭灭)→暂停(灭亮灭)→反转(灭灭亮);当电源关闭时,输出全零信号即三灯全灭。
        设计的模块代码见附录,模块图如下图。

基于VHDL的全自动洗衣机控制器设计_第7张图片
        时序仿真图如图4-3-2、图4-3-3、图4-3-4和图4-3-5。在图4-3-2中可以看出电源信号功能正常,完成判定信号在定时模块里跟随电源会变为低电平,但是这里是手动输入信号,因此没有跳变,但电源信号功能不受影响。模式选择信号未跳变时,程序自己选择默认模式即普通洗涤模式。完成判定信号功能正常,能够在指定时间内运行状态机,并且完成后继续显示所选模式。状态显示信号功能正常,能够显示目标状态,但是是时序仿真可以看到有延迟和毛刺。从图4-3-3可以看出模式选择按键功能正常,状态显示也正常,统计对应状态的秒钟周期数发现与目标要求一致,实现了正转15s→暂停15s→反转15s→暂停15s。从图4-3-4可以看出模式选择按键功能正常,状态显示也正常,统计对应状态的秒钟周期数发现与目标要求一致,实现了正转20s→暂停10s→反转20s→暂停10s。从图4-3-5可以看出模式选择按键功能正常,状态显示也正常,统计对应状态的秒钟周期数发现与目标要求一致,实现了正转15s→暂停15s→正转15s→暂停15s。
基于VHDL的全自动洗衣机控制器设计_第8张图片

图 4-3-2 状态机(ZTJ)默认模式时序仿真图

基于VHDL的全自动洗衣机控制器设计_第9张图片

图 4-3-3 状态机(ZTJ)普通洗涤模式时序仿真图

基于VHDL的全自动洗衣机控制器设计_第10张图片

图 4-3-4 状态机(ZTJ)强力洗涤模式时序仿真图

基于VHDL的全自动洗衣机控制器设计_第11张图片

图 4-3-5 状态机(ZTJ)甩干模式时序仿真图

4.4顶层设计实现(DCSJ.vhd和DCSJ.vwf)

        顶层设计的输入有时钟源信号(CLK)、蜂鸣器输入时钟(FMQR)、电源信号(DYXH)、预置时间信号(YZSJ)、开始运行信号(KSYX)和模式选择信号(MSXZ);输出信号有蜂鸣器输出信号(FMQC)、状态显示信号(ZTXS)、时间显示信号(SJXS)。
        时钟源信号选择4Hz的方波信号,与定时模块的时钟源信号相连接;蜂鸣器输入时钟选择4096Hz的方波信号;电源信号、预置时间信号、开始运行信号和模式选择信号都是来自按键的单脉冲信号分别与定时模块和状态机对应信号相连接。
        蜂鸣器输出信号使得蜂鸣器在倒计时完成后发出响声5s;状态显示信号来自于状态机的输出,时间显示信号来自于定时模块的输出。
        顶层设计的模块图如图4-4-1,RTL图如图4-4-2。代码见附录。
基于VHDL的全自动洗衣机控制器设计_第12张图片

图 4-4-1 顶层设计(DCSJ)模块图

基于VHDL的全自动洗衣机控制器设计_第13张图片

图 4-4-2 顶层设计(DCSJ)RTL图

        时序仿真图如图4-4-3和图4-4-4。考虑到设计的三个时间较长,虽然可以提高仿真时钟源频率,但是考虑到电脑性能及运行时间,故将15分钟、30分钟和40分钟分别改为1分钟、2分钟和4分钟,并不影响仿真结果。从图4-4-3中可以看出开机、模式选择、预置时间和开始运行都实现了目标要求,时间显示和状态显示也很正常。从图4-4-4可以看出来,蜂鸣器正常工作,倒计时结束后与预置时间和选择模式可继续下一次任务,无需关机重启。

基于VHDL的全自动洗衣机控制器设计_第14张图片

图 4-4-3 顶层设计(DCSJ)时序仿真图一

基于VHDL的全自动洗衣机控制器设计_第15张图片

图 4-4-4 顶层设计(DCSJ)时序仿真图二

        本次设计选择模式9,其引脚锁定图如图4-5-1,电路结构图如图4-5-2,成功下载到开发板如图4-5-3。键1是开/关电源,按键2是预置时间,按键3是选择模式,按键4是开始运行;二极管D3、D2、D1显示当前状态或所选模式,数码管4、3、2、1显示时间。
基于VHDL的全自动洗衣机控制器设计_第16张图片

图 4-5-1 引脚锁定图

基于VHDL的全自动洗衣机控制器设计_第17张图片

图 4-5-2 模式9电路结构图

基于VHDL的全自动洗衣机控制器设计_第18张图片

图 4-5-3 成功下载到开发板图

5.结论

5.1问题与思考

        虽然完成了该设计但是仍然存在一些问题。在图4-4-4中可以看见完成最后一秒是“多余”的。这是因为倒计时是按60s到0s共计61秒,导致最后一秒显得“多余”。事实上第60s还未开始,但是设计程序时由于理解偏差使得从60s开始倒计时。电源信号事实上可以设置为电源线上一个开关,在程序里事实上并未做到真正的关机,因为程序一直在识别电源信号,所以只是显示的信息与关机一样而已。查看附录代码会发现电源按键的进程多次出现,这是由于前期准备不充分,计划不完善,后期修改程序导致代码繁琐效率变低,影响实际的时间延迟。

5.2完成感想

        经过几天的思考和测试,程序终于完成了,虽然还有些许瑕疵,但是功能上已经满了目标需求。整个设计过程比较曲折,前期的学习并没有使得我对VHDL语言达到熟练使用的地步,所以前期工作显得异常辛苦,好在对数字电路的理解较为通透,有大致的设计思路和方法,通过查找课本和网络上的资料,逐渐熟悉VHDL语言的语法,慢慢感受到了它的魅力和精彩之处,对于硬件关系的叙述全面又不失一般性,简洁却又功能强大。它里面的信号SIGNAL仿佛一把万能钥匙打开了所有进程之间的大门,使得看似无理的电路在时间信号驱动下变得华丽多姿。不过对于我来说真正理解它还是不容易的,这也使得前期我总是为了某个需要的波形绞尽脑汁,走很多弯路,甚至一度笃定不可能出现这种波形,直到后期渐入佳境,改变原本的人的思维,从机器的角度思考问题,深刻理解同步的概念,才获得了一些进步。事实上距离有限器件内想要什么波形就有什么波形的境界相差甚远,但只要不断学习和进步,就一定不会错。
        事实上这次我收获最大的就是进程之间的通信,VHDL语言规定了每个信号或者变量都必须被完整描述,比如在两个进程内给同一信号无条件赋值就会报错:该变量不能有多驱动,这就是得一些游走在各个地方需要被赋值的信号总要严格的完整描述,而一种简单方法就是设置多个信号,每个进程内的信号赋值可以由别的信号描述,这样看似每个信号都被独立描述,实则相互联系,可以产生需要的波形。

参考文献

[1] 潘松,黄继业.EDA技术实用教程——Verilog HDL版[M].4版.北京:科学出版社,2010.
[2] 潘明,潘松.数字电子技术基础[M].北京:科学出版社,2008.
[3] 潘松,潘明,黄继业.现代计算机组成原理[M].2版.北京:科学出版社,2013.
[4] 曾繁泰,侯亚宁,崔元明.可编程器件应用导论[M].北京:清华大学出版社,2001.
[5] Altera Corporation. Altera Digital Library[G]. Altera,2002.
[6] 潘松,黄继业.EDA技术实用教程——VHDL版[M].5版.北京:科学出版社,2013.

附录

1.定时模块源代码

LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY DSMK IS--定时模块
	PORT ( CLK : IN STD_LOGIC;--时钟源信号
		  DYXH : IN STD_LOGIC;----电源信号
		  YZSJ : IN STD_LOGIC;--预置时间信号
		  KSYX : IN STD_LOGIC;--开始运行信号
		  MZSC : OUT STD_LOGIC;--秒钟输出信号
		  WCPD : OUT STD_LOGIC;--完成判定信号
		  SJXS : OUT STD_LOGIC_VECTOR(15 DOWNTO 0));--时间显示信号
END;
ARCHITECTURE one OF DSMK IS
	SIGNAL      CNTX : STD_LOGIC;
	SIGNAL MZSC_TEMP : STD_LOGIC;
	SIGNAL WCPD_TEMP : STD_LOGIC;
	SIGNAL DYXH_TEMP : STD_LOGIC;
	SIGNAL   KSYX_T0 : STD_LOGIC;
	SIGNAL   KSYX_T1 : STD_LOGIC;
	SIGNAL SJXS_TEMP : STD_LOGIC_VECTOR(15 DOWNTO 0);
	SIGNAL SJXS_TMEP : STD_LOGIC_VECTOR(15 DOWNTO 0);
	SIGNAL      CNT3 : STD_LOGIC_VECTOR(1 DOWNTO 0);
	SIGNAL    SJXS_0 : STD_LOGIC_VECTOR(3 DOWNTO 0);
	SIGNAL    SJXS_1 : STD_LOGIC_VECTOR(3 DOWNTO 0);
	SIGNAL    SJXS_2 : STD_LOGIC_VECTOR(3 DOWNTO 0);
	SIGNAL    SJXS_3 : STD_LOGIC_VECTOR(3 DOWNTO 0);
BEGIN
	PROCESS(DYXH) IS --电源按键驱动进程
		BEGIN
			IF DYXH'EVENT AND DYXH = '1' THEN 
				DYXH_TEMP <= NOT DYXH_TEMP;
			END IF;
	END PROCESS;
	PROCESS(KSYX) IS--开始按键驱动进程
		BEGIN
			IF KSYX_T1 = '1' THEN 
				KSYX_T0 <= KSYX_T0 AND (NOT KSYX_T1);
			ELSE 
				IF KSYX'EVENT AND KSYX = '1' THEN 
					KSYX_T0 <= '1';
				END IF;
			END IF;
	END PROCESS;
	MZSCJC: PROCESS(CLK) IS--秒钟输出进程(4HZ)
		BEGIN
			IF CLK'EVENT AND CLK = '1' THEN
				CNTX <= NOT CNTX;
				IF CNTX = '1' THEN
					MZSC_TEMP <= NOT MZSC_TEMP;
				END IF;
			END IF;
	END PROCESS MZSCJC;
	YZSJJC: PROCESS(YZSJ) IS--预置时间进程
		BEGIN
			IF DYXH_TEMP = '1' THEN 
				IF SJXS_TEMP <= x"0000" THEN 
					SJXS_TEMP <= x"0400";
				ELSE	
					IF YZSJ'EVENT AND YZSJ = '1' THEN
						IF WCPD_TEMP = '0' THEN
							CASE(CNT3) IS
								WHEN "01" => CNT3 <= CNT3 + 1;SJXS_TEMP <= x"0200";
								WHEN "10" => CNT3 <= "00";SJXS_TEMP <= x"0400";
								WHEN OTHERS => CNT3 <= CNT3 + 1;SJXS_TEMP <= x"0100";
							END CASE;
						END IF;
					END IF;
				END IF;
			END IF;
	END PROCESS YZSJJC;
	WCPDJC: PROCESS(MZSC_TEMP) IS--完成判定进程
		BEGIN
			IF KSYX_T0 = '1' THEN
				IF MZSC_TEMP'EVENT AND MZSC_TEMP = '1' THEN
					KSYX_T1 <= '1';
				END IF;
			ELSE 
				KSYX_T1 <= '0';
			END IF;
			IF MZSC_TEMP'EVENT AND MZSC_TEMP = '1' THEN
			--时间显示
				IF DYXH_TEMP = '1' THEN
					IF (KSYX_T0 AND (NOT WCPD_TEMP)) = '1' THEN
						CASE(CNT3) IS
							WHEN "10" => SJXS_3 <= x"0";SJXS_2 <= x"2";SJXS_1 <= x"0";SJXS_0 <= x"0";
							WHEN "00" => SJXS_3 <= x"0";SJXS_2 <= x"4";SJXS_1 <= x"0";SJXS_0 <= x"0";
							WHEN OTHERS => SJXS_3 <= x"0";SJXS_2 <= x"1";SJXS_1 <= x"0";SJXS_0 <= x"0";
						END CASE;
						WCPD_TEMP <= '1';
					ELSE
						IF SJXS_0 = x"0" THEN
							IF SJXS_1 = x"0" THEN
								IF SJXS_2 = x"0" THEN
									IF SJXS_3 = x"0" THEN 
										WCPD_TEMP <= '0';
									ELSE 
										SJXS_3 <= SJXS_3 - 1;
										SJXS_2 <= x"9";
										SJXS_1 <= x"5";
										SJXS_0 <= x"9";
										WCPD_TEMP <= '1';
									END IF;
								ELSE
									SJXS_2 <= SJXS_2 - 1;
									SJXS_1 <= x"5";
									SJXS_0 <= x"9";
									WCPD_TEMP <= '1';
								END IF;
							ELSE
								SJXS_1 <= SJXS_1 - 1;
								SJXS_0 <= x"9";
								WCPD_TEMP <= '1';
							END IF;
						ELSE
							SJXS_0 <= SJXS_0 - 1;
							WCPD_TEMP <= '1';
						END IF;
					END IF;
				ELSE
					SJXS_0 <= x"0";
					SJXS_1 <= x"0";
					SJXS_2 <= x"0";
					SJXS_3 <= x"0";
					WCPD_TEMP <= '0';
				END IF;
			END IF;
	END PROCESS WCPDJC;
	SJXS <= SJXS_3&SJXS_2&SJXS_1&SJXS_0 WHEN (DYXH_TEMP AND WCPD_TEMP) = '1' ELSE  
							  SJXS_TEMP WHEN        DYXH_TEMP = '1'          ELSE 
							  	x"0000";
	WCPD <= WCPD_TEMP;
	MZSC <= MZSC_TEMP;
END;

2.状态机源代码

LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY ZTJ IS--状态机
	PORT (DYXH : IN STD_LOGIC;----电源信号
		  MSSR : IN STD_LOGIC;--模式输入信号
		  MZSR : IN STD_LOGIC;--秒钟输入信号
		  WCPD : IN STD_LOGIC;--完成判定信号
		  ZTXS : OUT STD_LOGIC_VECTOR(2 DOWNTO 0));--状态显示信号
END;
ARCHITECTURE one OF ZTJ IS
	SIGNAL DYXH_TEMP : STD_LOGIC;
	SIGNAL     CNT_1 : STD_LOGIC_VECTOR(4 DOWNTO 0);
	SIGNAL     CNT_2 : STD_LOGIC_VECTOR(3 DOWNTO 0);
	SIGNAL     CNT_3 : STD_LOGIC_VECTOR(4 DOWNTO 0);
	SIGNAL     CNT_4 : STD_LOGIC_VECTOR(3 DOWNTO 0);
	SIGNAL      CNT3 : STD_LOGIC_VECTOR(1 DOWNTO 0);
	SIGNAL   ZT_TEMP : STD_LOGIC_VECTOR(2 DOWNTO 0);
	SIGNAL ZTXS_TEMP : STD_LOGIC_VECTOR(2 DOWNTO 0);
	SIGNAL    ZTXS_F : STD_LOGIC_VECTOR(2 DOWNTO 0);
	SIGNAL      MSXZ : STD_LOGIC_VECTOR(17 DOWNTO 0);
BEGIN
	PROCESS(DYXH) IS --电源按键驱动进程
		BEGIN
			IF DYXH'EVENT AND DYXH = '1' THEN 
				DYXH_TEMP <= NOT DYXH_TEMP;
			END IF;
	END PROCESS;
	PROCESS(MSSR) IS --模式显示进程
		BEGIN
		IF DYXH_TEMP = '1' THEN
			IF WCPD = '0' THEN
				IF ZTXS_F = "000" THEN  
					ZTXS_F <= "011";
					MSXZ <= "11"&x"DFEE";
				ELSE 
					IF MSSR'EVENT AND MSSR = '1' THEN
						CASE(CNT3) IS
							WHEN "01" => CNT3 <= CNT3 + 1;MSXZ <= "10"&x"A953";ZTXS_F <= "111";
							WHEN "10" => CNT3 <= "00";MSXZ <= "00"&x"01EE";ZTXS_F <= "110";
							WHEN OTHERS => CNT3 <= CNT3 + 1;MSXZ <= "11"&x"DFEE";ZTXS_F <= "011";
						END CASE;
					END IF;
				END IF;
			END IF;
		ELSE 
			ZTXS_F <= "000";
		END IF;
	END PROCESS;
	PROCESS(MZSR) IS--状态转移进程
		BEGIN
			IF DYXH_TEMP = '1' THEN 
				IF MZSR'EVENT AND MZSR = '1' THEN
					IF WCPD = '1' THEN
						IF CNT_1=(MSXZ(4)&MSXZ(3)&MSXZ(2)&MSXZ(1)&MSXZ(0)) THEN
							ZT_TEMP <= "001";
							IF CNT_2 = (MSXZ(8)&MSXZ(7)&MSXZ(6)&MSXZ(5)) THEN
								IF (MSXZ(17) OR MSXZ(10)) = '0' THEN 
									ZT_TEMP <= "000";
									CNT_1 <= "00000";
									CNT_2 <= "0000";
								ELSE 
									ZT_TEMP <= "011";
									IF CNT_3= (MSXZ(13)&MSXZ(12)&MSXZ(11)&MSXZ(10)&MSXZ(9)) THEN
										ZT_TEMP <= "010";
										IF CNT_4=(MSXZ(17)&MSXZ(16)&MSXZ(15)&MSXZ(14)) THEN
											CNT_1 <= "00000";CNT_2 <= "0000";
											CNT_3 <= "00000";CNT_4 <= "0000";
											ZT_TEMP <= "000";
										ELSE 
											CNT_4 <= CNT_4 + 1;
										END IF;
									ELSE
										CNT_3 <= CNT_3 + 1;
									END IF;
								END IF;
							ELSE 
								CNT_2 <= CNT_2 + 1;
							END IF;
						ELSE 
							CNT_1 <= CNT_1 + 1;
						END IF;
					END IF;
				END IF;
			END IF;
	END PROCESS;
	PROCESS(ZT_TEMP) IS--状态显示进程
	BEGIN
		IF DYXH_TEMP = '1' THEN
			CASE(ZT_TEMP) IS
				WHEN "000" => ZTXS_TEMP <= "100";
				WHEN "001" => ZTXS_TEMP <= "010";
				WHEN "011" => ZTXS_TEMP <= "001";
				WHEN "010" => ZTXS_TEMP <= "010";
				WHEN OTHERS => ZTXS_TEMP <= "100";
			END CASE;
		ELSE
			ZTXS_TEMP <= "000";
		END IF;
	END PROCESS;
	ZTXS <= ZTXS_F WHEN WCPD = '0' ELSE ZTXS_TEMP;
END;

3.顶层设计源代码

LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY DCSJ IS--顶层设计
	PORT ( CLK : IN STD_LOGIC;--时钟源信号(4HZ)
		  FMQR : IN STD_LOGIC;--蜂鸣器输入时钟(4096HZ)
	      DYXH : IN STD_LOGIC;--电源信号(单脉冲按键)
		  YZSJ : IN STD_LOGIC;--预置时间信号(单脉冲按键)
		  KSYX : IN STD_LOGIC;--开始运行信号(单脉冲按键)
		  MSXZ : IN STD_LOGIC;--模式选择信号(单脉冲按键)
		  FMQC : OUT STD_LOGIC;--蜂鸣器输出信号
		  ZTXS : OUT STD_LOGIC_VECTOR(2 DOWNTO 0);--状态显示信号(二极管)
		  SJXS : OUT STD_LOGIC_VECTOR(15 DOWNTO 0));--时间显示信号(数码管)
END;
ARCHITECTURE one OF DCSJ IS
	SIGNAL  WCPD : STD_LOGIC;
	SIGNAL  MZSC : STD_LOGIC;
	SIGNAL TEMP0 : STD_LOGIC;
	SIGNAL TEMP1 : STD_LOGIC;
	SIGNAL TEMPD : STD_LOGIC;
	SIGNAL   CNT : INTEGER RANGE 0 TO 4;
COMPONENT DSMK IS--定时模块
	PORT ( CLK : IN STD_LOGIC;--时钟源信号
		  DYXH : IN STD_LOGIC;----电源信号
		  YZSJ : IN STD_LOGIC;--预置时间信号
		  KSYX : IN STD_LOGIC;--开始运行信号
		  MZSC : OUT STD_LOGIC;--秒钟输出信号
		  WCPD : OUT STD_LOGIC;--完成判定信号
		  SJXS : OUT STD_LOGIC_VECTOR(15 DOWNTO 0));--时间显示信号
END COMPONENT;
COMPONENT ZTJ IS--状态机
PORT (DYXH : IN STD_LOGIC;----电源信号
	  MSSR : IN STD_LOGIC;--模式输入信号
  	  MZSR : IN STD_LOGIC;--秒钟输入信号
	  WCPD : IN STD_LOGIC;--完成判定信号
	  ZTXS : OUT STD_LOGIC_VECTOR(2 DOWNTO 0));--状态显示信号
END COMPONENT;
BEGIN
	PROCESS(DYXH) IS --电源按键驱动进程
		BEGIN
			IF DYXH'EVENT AND DYXH = '1' THEN 
				TEMPD <= NOT TEMPD;
			END IF;
	END PROCESS;
	PROCESS(WCPD,TEMP1) IS--蜂鸣器驱动进程
	BEGIN
		IF TEMPD = '1' THEN 
			IF TEMP1 = '0' THEN
				IF WCPD'EVENT AND WCPD = '0' THEN 
					TEMP0 <= '1';
				END IF;
			ELSE  
				TEMP0 <= NOT TEMP1;
			END IF;
		ELSE 
			TEMP0 <= '0';
		END IF;
	END PROCESS;
	PROCESS(MZSC) IS--蜂鸣器关闭进程
	BEGIN
		IF MZSC'EVENT AND MZSC = '1' THEN
			IF TEMPD = '1' THEN
				IF TEMP0 = '1' THEN 
					CNT <= CNT + 1;
					IF CNT = 4 THEN 
						TEMP1 <= '1';
					END IF;
				ELSE 
					TEMP1 <= '0';
				END IF;
			ELSE 
				TEMP1 <= '0';
			END IF;
		END IF;
	END PROCESS;
	FMQC <= FMQR WHEN TEMP0  = '1' ELSE '0';
	U1 : DSMK PORT MAP(CLK => CLK,DYXH => DYXH,YZSJ => YZSJ,KSYX => KSYX,MZSC => MZSC,WCPD => WCPD,SJXS => SJXS);
	U2 : ZTJ PORT MAP(DYXH => DYXH,MSSR => MSXZ,MZSR => MZSC,WCPD => WCPD,ZTXS => ZTXS);
END;

你可能感兴趣的:(quartus-VHDL,vhdl,fpga)