问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

数字逻辑课程设计——数字密码锁(VHDL)

创作时间:
作者:
@小白创作中心

数字逻辑课程设计——数字密码锁(VHDL)

引用
CSDN
1.
https://blog.csdn.net/systemcall0122/article/details/135029936

本文是一篇关于数字密码锁VHDL设计的课程设计报告,详细介绍了设计目的、内容、方案分析、具体实现过程以及总结。文章内容完整,结构清晰,包含了具体的VHDL代码和设计思路,对于学习数字逻辑和VHDL编程具有较高的参考价值。

一、课程设计目的

  1. 学会应用数字系统设计方法进行数字电路设计;
  2. 进一步提高quartus II软件的开发应用能力;
  3. 提高VHDL进行综合设计的能力;
  4. 培养学生书写综合实验报告的能力。

二、课程设计内容

  1. 密码锁采用十进制数形式,可以进行密码修改,错误报警等功能。
  2. 如果输入的密码与设置的密码相同,则密码锁被打开,控制器的输出端key=0;否则控制输出端warn=1,发出警报。
  3. 实验时,“上锁”状态通过发光的LED灯显示,声、光报警通过有源蜂鸣器和LED灯指示
  4. 写出设计步骤,对各个模块设计VHDL代码
  5. 画出电路原理图
  6. 对设计的电路进行仿真、修改,使仿真结果达到设计要求。

三、实验方案分析与设计

根据“自顶向下”的设计方法,先确定系统顶层实体的功能设计,按功能划分为若干模块,然后对每一个模块进一步细分,得到简单易实现的子模块。

经分析,该数字密码锁有如下模块:控制器、用于记录输入密码位数的计数器1、用于记录错误次数的计数器2、比较器、译码器、寄存器。

控制器本质上为一个具有7个状态的状态机,由各转移信号控制以进入对应的状态。具体状态有:OUTLOCK(开锁)、INLOCK(关锁)、PS_INPUT(输入密码)、PS_CHANGE(修改密码)、PS_RIGHT(密码正确)、PS_WRONG(密码错误)、ALARM(警报)。

(下面几个模块写得简略一点)

译码器:将输入信号转为二进制

比较器:比较译码器输出信号是否与寄存器中预设密码相同

计数器1:记录密码输入位数

计数器2:记录错误次数

寄存器:根据使能信号的不同实现不同功能,修改密码 / 传输密码

四、具体实现过程描述

(VHDL的层次化是相当显著的,这边我给大家一个顶层封装逻辑图和一个重要模块的底层代码设计)

注意:只是供大家参考,根据每个人设计的不同,每个模块会有不同的端口。

顶层封装逻辑图:

下面给出最重要的控制器的底层逻辑,给出了两个状态对应的逻辑信号控制和状态转移控制。如果读者理解了数字密码锁的要求(什么状态读什么信号转移成什么状态)和上面的顶层封装逻辑图的话,仿照给出模块将控制器代码补全并不是难事。

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
entity control1 is
    port(
    clk:in std_logic;       --时钟信号
    lock:in std_logic;      --上锁信号
    start:in std_logic;     --开始输入密码信号
    off_al:in std_logic;    --消除警报信号
    ps_ch:in std_logic;     --修改密码信号
    enter:in std_logic;     --确认信号
    wro_count:in std_logic; --错误次数
    ps_i:in std_logic;      --输入密码
    cmp_r:in std_logic;     --比较器结果
    cin:in std_logic;       --密码位数是否正确
    
    code_en:out std_logic;  --译码器使能
    cnt_clr:out std_logic;  --计数器1清零
    cnt_clr2:out std_logic; --计数器2清零
    cnt_clk2:out std_logic; --计数器2时钟
    reg_wr:out std_logic;   --决定寄存器当前作用是输出密码还是修改密码
    key:out std_logic;      --锁的开关
    warn:out std_logic      --警报信号
    );
end control1;
architecture behave of control1 is
CONSTANT KEY_ACTIVE:STD_LOGIC:='1';   --有效电平
type state_type is (OUTLOCK,INLOCK,PS_INPUT,PS_RIGHT,PS_WRONG,ALARM,PS_CHANGE);   --七个状态
signal state:state_type;
begin
    
    process(clk)
    begin
        if rising_edge(clk) then
            case state is
            --------------------------
                when OUTLOCK=>   --开锁状态
                    key<='0';
                    --状态转移
                    if lock=KEY_ACTIVE then
                    state<=INLOCK;
                    
                    ELSIF ps_ch=KEY_ACTIVE then
                    state<=PS_CHANGE;
                    
                    ELSE
                    state<=OUTLOCK;
                    
                    end if;
            --------------------------		
                when INLOCK=>   --关锁状态
                   --控制其他模块的信号
                    --状态转移
            -------------------------
                when PS_INPUT=>  --输入密码状态
                 --控制其他模块的信号
                   key<='1';
                    code_en<='1';
                    cnt_clr<='0';
                    reg_wr<='0';
                    --状态转移
                    if cin='1' and ps_i='1' and cmp_r='1' then
                        code_en<='0';
                        cnt_clr<='1';
                        cnt_clr2<='1';
                        state<=PS_RIGHT;
                        
                    elsif ps_i='1' and cmp_r='0' then
                        code_en<='0';
                        cnt_clr<='1';
                        cnt_clr2<='0';
                        cnt_clk2<='1';
                        state<=PS_WRONG;
                        
                    elsif enter=KEY_ACTIVE and cin='0' then
                        code_en<='0';
                        cnt_clr<='1';
                        cnt_clr2<='0';
                        cnt_clk2<='1';
                        state<=ALARM;
                        
                    else
                        state<=PS_INPUT;
                    end if;
            --------------------------		
                when PS_RIGHT=>  --密码正确
                   --状态转移
            -------------------------
                when PS_WRONG=>  --密码错误
                   --状态转移
            -------------------------
                when ALARM=>  --警报状态
                   --状态转移
            -------------------------
                when PS_CHANGE=>  --修改密码状态
                   --控制其他模块的信号
                    --状态转移
            -------------------------
                WHEN OTHERS=>
                    state<=INLOCK;
            end case;
        end if;
    end process;
end behave;  

至于其他功能模块……把控制器补全之后其他模块也并不难,译码器、计数器、比较器都是非常经典的应用,但寄存器需要动点脑筋(因为我的寄存器根据使能信号有两个功能,所以当时花了点时间想办法,不想想办法的话把寄存器拆成两个模块也可以)

总的来说,数字逻辑课程的逻辑性是非常强的,用低级语言去完成一个逻辑性极强的设计确实有一定难度,需要大家好好思考。

数字密码锁设计的所有文件:

五、实现效果

系统上电时,处于开锁状态(OUTLOCK),此时默认密码为“0000”。当输入ps_ch信号时,系统进入修改密码状态(PS_CHANGE);若输入lock信号,进入关锁状态(INLOCK),锁闭合;在关锁状态,输入start信号,进入密码输入状态(PS_INPUT);在输入密码状态,由ps_i密码脉冲作为计数时钟,计数值输出作为寄存器地址,当计数器计到4时,返回计数满信号cin,如果密码内容和长度均正确,进入密码初验正确状态(PS_RIGHT),如果密码错误,进入密码初验错误状态(PS_WRONG);在密码初验错误状态,输入确认信号enter时,进入开锁状态;在密码初验错误状态,输入确认信号enter时,如果错误次数没有达到4次,则进入关锁状态并输出错误信号,如果错误次数达到4次,进入报警状态;在报警状态, warn信号等于‘1’,如果输入清除警报信号off_al,进入关锁状态。

六、总结

本次课程设计中遇到了很多有意思的问题,我也针对这些问题想出了许多解决方法。比如说,怎么去输入密码。一开始的想法是用四个译码器去编译每一个输入的数据,然后将这些数据并行输入到比较器中,但这样的化又需要另外需要四个译码器去设置密码,从实际考虑需要消耗非常多的材料。况且如果要修改密码位数的话又需要在原理图中修改译码器的个数,非常麻烦。经过思考,我通过一个addr信号去控制了密码输入的位数,也通过这个信号控制了当前输入的数是第几位,如果需要改变密码位数的话也只要在代码里修改addr的取值范围就好;通过一个寄存器完成了修改密码与输入密码两个功能,将预置密码与输入密码需要的译码器合并为一个,极大地节省了材料。而且如果不使用状态机的话,各种功能之间的转换需要非常非常多的元件模块,工程量大又要耗费许多材料。

因此,从上述经历中我得到的最大的启发就是:在实际行动之前,一定要对将要完成的任务做充分的思考,从而找到一个更好的解决方案。那些简单粗暴的方法(比如在本次课程设计中使用八个译码器,不使用状态机而去直接连接各个时序电路等等)可以让我们很快地开始着手制作,但最后的结果往往不尽如人意。只有经过充分的考量,才可以得出一个较为完美的解决方案。

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号