vivado数字密码锁verilog带详细设计报告ego1开发板验证

名称:vivado数字密码锁verilog带详细设计报告ego1开发板验证

软件:VIVADO

语言:Verilog

代码功能:

1.设计一个开锁密码至少为4位数字的密码锁

2.当开锁按键开关(可设置为8位或更多,其中只有4位有效,其余为虚设)的输入代码等于所设密码时启动开锁控制电路,用F1灯亮,F2灯灭表示开锁状态,并用数码管显示英文大写的OP

3.从第一个按键触动后的10秒内若未能将锁打开,则电路自动复位,同时用F1灯灭,F2灯亮表示关锁状态,并用数码管显示英文大写LC

4.10秒开锁倒计时要求用数码管显示

FPGA代码Verilog/VHDL代码资源下载:www.hdlcode.com

本代码已在ego1开发板验证,开发板如下,其他开发板可以修改管脚适配:

ego1开发板.png

代码下载:vivado数字密码锁verilog带详细设计报告ego1开发板验证名称:vivado数字密码锁verilog带详细设计报告ego1开发板验证(代码在文末下载)软件:VIVADO语言:Verilog代码功能:1.设计一个开锁密码至少为4位数字的密码锁2.当开锁按键开关(可设置为8位或更多,其中只有4位有效,其余为虚设)的输入代码等于所设密码时启动开锁控制电路,用F1灯亮,F2灯灭表示开锁状态,并用数码管显示英文大写的OP3.从第一个按键触动后的10秒内若未能将锁打icon-default.png?t=N7T8http://www.hdlcode.com/index.php?m=home&c=View&a=index&aid=313

一、设计要求

1. 设计一个开锁密码至少为4位数字的密码锁

2. 当开锁按键开关(可设置为8位或更多,其中只有4位有效,其余为虚设)的输入代码等于所设密码时启动开锁控制电路,用F1灯亮,F2灯灭表示开锁状态,并用数码管显示英文大写的OP

3. 从第一个按键触动后的10秒内若未能将锁打开,则电路自动复位,同时用F1灯灭,F2灯亮表示关锁状态,并用数码管显示英文大写LC

4. 10秒开锁倒计时要求用数码管显示

二、工作原理及系统方框图

根据设计要求,采用Verilog代码设计,代码采用自顶向下的设计方法,分为顶层模块和子模块,顶层模块调用子模块。子模块包括按键消抖模块,密码输入模块,密码控制模块,密码重置模块,数码管显示模块。顶层模块负责将上述模块调用并连接,最终形成完整的密码锁控制系统,实现设计要求。

整体设计采用状态机进行控制,通过按键控制状态机的跳转,不同状态对应不同的功能及输出。其中按键消抖模将外输入的按键进行消抖,防止按键误操作;密码输入模块通过密码输入按键输入开锁密码;密码控制模块为主控模块,内部包含状态机,通过整体及控制整体流程,比如开锁输入密码、倒计时、开锁、关锁、修改密码灯状态。密码重置模块用于在修改密码状态下更新密码锁的开锁密码;数码管显示模块通过控制8个数码管,显示倒计时、开关锁状态、输入密码值等功能。

系统方框图如下图所示:

上图中,key_jitter为按键消抖模块,mima_input为密码输入模块,reset_password为密码重置模块,mimasuo_ctrl为密码锁控制模块,display为显示模块。

三、各部分具体模块及设计思路

3.1 按键消抖模块

按键消抖模块用于对按键进行消抖,按键所用开关为机械弹性开关,当机械触点断开、闭合时,由于机械触点的弹性作用,一个按键开关在闭合时不会马上稳定地接通,在断开时也不会一下子断开。因而在闭合及断开的瞬间均伴随有一连串的抖动,为了不产生这种现象而作的措施就是按键消抖。按键抖动如下图所示:

机械式按键的抖动次数、抖动时间、抖动波形都是随机的。不同类型的按键其最长抖动时间也有差别,抖动时间的长短和按键的机械特性有关,按键输出的信号的跳变时间(上升沿和下降沿)最大是在20ms左右。按键消抖的关键是提取稳定的低电平(或高电平)状态,滤除按键稳定前后的抖动脉冲。

3.2 密码锁控制模块

密码锁控制模块用于对密码锁的整体功能进行控制,控制采用状态机的方式。一个分为6个状态,分别是s_lock,s_compare,s_pass,s_error,s_modify,s_keyin;s_lock表示锁定状态,s_compare表示比较输入的密码和正确的密码,s_pass表示密码正确,s_error表示密码错误,s_modify表示修改密码,s_keyin表示密码输入状态。系统初始处于锁定状态(s_lock),若按下密码输入按键,则进入密码输入状态(s_keyin),此时开始倒计时,当倒计时结束还未输入完成,则跳转到锁定状态(s_lock),否则跳转到s_compare状态比较输入的密码和正确的密码。若密码正确,则进入s_pass状态,否则进入s_error状态。在pass状态下,若按下修改按键,则进入修改密码状态(s_modify)。在修改密码状态下,可以再次输入密码,按下确认键后即修改完成,状态机回到s_pass状态。状态转移图如下图所示:

3.3密码输入模块

密码输入模块用于控制密码输入,密码输入采用移位的方式,首先定义一个16bit的信号,表示4位数的密码,每个密码为4bit,采用BCD码表示。当按下按键时,将对应的键值赋值到信号的最低位,同时将原先的第11~0位左移到第15~4位。即每次按下按键后,密码都会整体左移一位,新输入的数字位于最低位。

3.4密码重置模块

密码重置模块用于在修改密码的状态下,将新输入的数字替换为密码锁的密码。在改模块下,首先需要定义一个初始密码,本系统设置为3210。当检测到状态进入修改密码状态后,将输入的密码赋值为当前的正确密码即完成了密码的修改。本模块的前提是在控制模块内已经是系统正确进入了修改密码状态。

3.5数码管显示模块

数码管显示模块用于控制数码管对应值显示出来,显示内容有倒计时,LC/OP状态,输入密码值等。数码管显示使用动态扫描的方式,依次显示频率的不同位。使用8段数码管显示,每个数码管输入为8位,对应下图中的abcdefg7段加上小数点dp,当输入1时对应的段点亮,当输入为0时,对应的段灭。

根据上图可以观察到,若要显示数字0,需要DP灭,G灭,ABCDEF亮,也就是对应编码为“00111111”,其中从左到右依次对应DP-GFEDCBA。以此类推可以得到0~9的所有编码。一共有8个数码管,每4个数码管共用一组段选信号(dig_led),因此为了同时显示8个数码管,需要对8个数码管依次切换,控制位选信号(wei_led)按顺序循环选通,低电平时对应数码管点亮。

四、调试过程

4.1 按键消抖模块

代码编译无误后,对按键消抖模块进行仿真,仿真图如下图所示:

按键消抖的原理为先检测按键是否按下,即图中pp信号,在按键变化的瞬间会产生一个脉冲信号,根据这个脉冲信号进行计时,计时够20ms左右时,再采集稳定的按键信号,本模块仿真时,为便于快速仿真,将计时20ms省去,最终输出为key_negedge信号,改信号表示按键消抖后的按键下降沿。图中可以看到,按键按下的时候,输出了一个下降沿脉冲信号,故该模块验证正确。

4.2 密码输入模块

代码编译无误后,对密码输入模块进行仿真,密码输入模块的核心为数字按下后,对应的密码要整体左移一位。仿真图如下图所示:

上图中,key0~3表示按键按下,password表示输入的密码值,可以看到当依次按下key3,2,1,0后,password显示0003,0032,0321,3210。因此代码正确的实现了按键输入和数字移位的功能。

4.3 密码锁控制模块

代码编译无误后,对密码锁控制模块进行仿真,控制模块使用状态机控制,根据按键控制和倒计时值的不同控制状态的跳转,下图中仿真了按键开锁、改密码、重新开锁的过程。图中state信号即为状态机的状态值,password为输入的密码值,correct_password为正确密码,down_cnt为倒计时,led_open为开锁指示信号。

图中,复位后,依次按下密码3210,时密码锁打开,led_open变为高电平,然后按下修改密码按键modify,进入修改状态,此时输入0123,并确认,将密码锁密码修改为0123,然后再按下关锁键关锁。此时再输入3210后无法开锁,led_open保持低电平。重新输入0123后按下确认键,密码锁打开,led_open变为高电平。在此期间,down_cnt在第一次输入密码时开始倒计时。根据上图可以验证密码锁控制模块功能正确。

4.4 密码重置模块

代码编译无误后,对密码重置模块进行仿真,下图中,current_state信号即为状态机的状态值,password为输入的密码值,correct_password为正确密码。

对上述仿真图进行分析,当current_state为4时,表示进入修改密码状态,此时若确认按键按下,会将当前输入的数字修改为密码锁的密码。图中可以看到,current_state为4时有一个确认按键的脉冲,此时correct_password立刻变为password的值,即从3210变为0123。因此验证该功能正确。

4.5 数码管显示模块

代码编译无误后,对数码管显示模块进行仿真,数码管一共有8个,分为2组,每组有一对位选(wei_led)和段选(dig_led)信号。下图中可以看到位选(wei_led)信号是依次选中(高电平),即在某一时刻只有一个数码管显示,然后再切换位下一个数码管,当切换速度够快时,人眼就认为是所有数码管同时显示了。

数码管显示内容有倒计时,LC/OP状态,输入密码值等,以上图中黄色标线处为例,此时第一组的最左边数码管亮,显示值为00111001,根据数码管从左到右依次对应DP-GFEDCBA的顺序,可知当前该数码管显示的内容为“C”,即当前位锁定状态。通过该方法,可以分析其他数码管显示内容,经过分析,该模块可以在8个数码管上依次显示倒计时,LC/OP状态以及输入密码值。

4.6 整体仿真

分模块仿真完成后,对系统进行状态仿真,仿真图如下所示:

图中可以看到,复位后,依次按下密码3210,时密码锁打开,开锁灯亮,然后按下修改密码按键modify,进入修改状态,此时输入0123,并确认,将密码锁密码修改为0123,然后再按下关锁键关锁,关锁灯亮。此时再输入3210后无法开锁,关锁灯亮。重新输入0123后按下确认键,密码锁打开,开锁灯亮。在此期间,down_cnt在第一次输入密码时开始倒计时。根据上图可以验证整体功能正确。

五、设计结论

本设计根据设计要求,结合Verilog语言的设计规范,使用VIVADO设计软件,采用分模块的设计思路,对每个模块的功能进行划分和编程调试,最终完成了4位密码锁的设计。代码编译无误,且分别进行了单模块仿真和系统整体仿真,仿真了各项功能指标,均正确。最后对该设计的输入输出端口进行管脚分配后,成功下载到EGO1的板子上进行了实物验证,分别观察了输入密码,修改密码,倒计时,开关锁指示灯,数码管显示等功能。实验表明,系统能按设计的方式运行,与仿真的功能一致,达到了设计要求。

六、设计总结

本设计根据设计要求,结合本次设计要求,该课题从软件实现平台的学习到程序的设计、仿真、下载和调试,实现了4位密码锁的设计。

在开发期间,学习了关于密码锁的知识,对Verilog语言有了深刻地了解与掌握,并对VIVADO软件有了深入的了解。

运用VIVADO软件,基于Verilog的密码锁设计,完成了以下工作:  

针对4位密码锁的总体框图划分成几个相对独立的模块,然后对各个模块在开发环境中进行编程和调试。

对每个模块单独进行分析设计,并在VIVADO中进行了功能仿真。

在设计的过程中,对拥有固定意义的信号统一命名,并在代码中进行注释(包括但不限于低/高有效),方便多个信号连接时应用,同时也将一些常用的模块定义为单独模块(按键消抖),以便共享和复用,使设计具有可重用性和可移植性,提高工作效率。

各个模块都调试成功后将各个模块连接起来总体调试,按照总体的设计图进行集成调试。

4位密码锁的仿真及实验结果表明密码锁达到了设计的功能要求。

参考文献:

[1]李晶皎, 李景宏. 曹阳. 逻辑与数字系统设计(M) .北京: 清华大学出版社, 2018.

[2]周润景, 苏良碧著. 基于Quartus II的FPGA/CPLD数字系统设计[M]. 北京: 电子工业出版社, 2013.

[3] 叶淑群,陈鸿鹏,梁士坤.实现基于FPGA的硬件算法加速器[J].宝鸡文理学院学报(自然科学版),2006(02):154-155+168.

[4] 丁黄胜,陆生礼,田渊,吴旭凡.基于FPGA的HMAC_SHA1_96算法设计与实现[J].半导体技术,2003(06):25-28+32.

[5] 房宝光. FPGA在OCD系统中模拟算法的加速应用[D].电子科技大学,2013.

部分代码展示:

//密码锁
module mimasuo(
input clk,//时钟
input reset,//-复位
//数字输入按键
input key_0,//--SW0
input key_1,//--SW1
input key_2,//--SW2
input key_3,//--SW3
input key_4,//--(虚设)
input key_5,//--(虚设)
input key_6,//--(虚设)
input key_7,//--(虚设)
input confirm_key,//-确认键--S0
input modify_key,//--修改--S1
input lock_up_key,//--上锁--S2
output led_open,//开锁,灯
output led_close,//关锁,灯
output        [7:0] dig_led_1,
 output        [3:0] wei_led_1, 
 output        [7:0] dig_led_2,
 output        [3:0] wei_led_2//高电平点亮,高电平选通
);
wire key_0_p;
wire key_1_p;
wire key_2_p;
wire key_3_p;
wire [2:0] current_state;
wire [15:0] password;
wire [15:0] correct_password;
wire confirm;
wire modify;
wire lock_up;
wire [3:0] down_cnt;//10秒倒计时
wire open;
assign led_close=~open;
assign led_open=open;
//上升沿检测
key_jitter i1_key_jitter(
. clkin(clk),    
. key_in(confirm_key),//输入
. key_posedge(),//消抖后按键上升沿
. key_negedge(confirm),//消抖后按键下降沿
. key_value()//消抖后按键
);
//上升沿检测
key_jitter i2_key_jitter(
. clkin(clk),    
. key_in(modify_key),//输入
. key_posedge(),//消抖后按键上升沿
. key_negedge(modify),//消抖后按键下降沿
. key_value()//消抖后按键
);
//上升沿检测
key_jitter i3_key_jitter(
. clkin(clk),    
. key_in(lock_up_key),//输入
. key_posedge(),//消抖后按键上升沿
. key_negedge(lock_up),//消抖后按键下降沿
. key_value()//消抖后按键
);
//密码输入模块
mima_input i_mima_input(
. clk(clk),
. key_0(key_0),
. key_1(key_1),
. key_2(key_2),
. key_3(key_3),
. key_0_p(key_0_p),
. key_1_p(key_1_p),
. key_2_p(key_2_p),
. key_3_p(key_3_p),
. current_state(current_state),
. password(password)
);
//密码锁控制模块
mimasuo_ctrl i_mimasuo_ctrl(
. clk(clk),
. password(password),
. correct_password(correct_password),
. confirm(confirm),
. reset(reset),
. modify(modify),
. lock_up(lock_up),
. key_0(key_0_p),
. key_1(key_1_p),
. key_2(key_2_p),
. key_3(key_3_p),
. down_cnt(down_cnt),//10秒倒计时
. led_open(open),
. current_state(current_state)
);
//重置密码模块
reset_password i_reset_password(
. clk(clk),
. password(password),
. correct_password(correct_password),
. confirm(confirm),
. current_state(current_state)
);
//显示模块
display i_display(
.clk(clk),
.down_cnt(down_cnt),
. current_state(current_state),//当前状态
. password(password),//输入密码
. dig_led_1(dig_led_1),
. wei_led_1(wei_led_1),   
. dig_led_2(dig_led_2),
. wei_led_2(wei_led_2)//高电平点亮,高电平选通
);
endmodule

猜你喜欢

转载自blog.csdn.net/diaojiangxue/article/details/134656657
今日推荐