重庆建网站诚选快忻科技悉心,珠海手机微信网站建设小程序开发,网络服务商在哪咨询,网站软件设计北邮22信通一枚~
跟随课程进度更新北邮信通院数字系统设计的笔记、代码和文章
持续关注作者 迎接数电实验学习~
获取更多文章#xff0c;请访问专栏#xff1a;
北邮22级信通院数电实验_青山如墨雨如画的博客-CSDN博客
目录
一.密码箱的功能和安全性
显示#xff1a;…北邮22信通一枚~
跟随课程进度更新北邮信通院数字系统设计的笔记、代码和文章
持续关注作者 迎接数电实验学习~
获取更多文章请访问专栏
北邮22级信通院数电实验_青山如墨雨如画的博客-CSDN博客
目录
一.密码箱的功能和安全性
显示
输入部分
确认键
复位键
输出部分
二.verilog代码
三.消抖模块
四.管脚分配 一.密码箱的功能和安全性
下面介绍本博客实现的密码箱的显示、输入和输出构架
显示 FPGA开发版上右数码管常亮显示你还有几次尝试机会。
代码中人为规定了尝试机会为3次。
每错一次右数码管上显示的数字都会减少1。
如果三次尝试都失败了密码箱会被锁死。
输入部分
四位二进制密码四个拨码开关的调节。
确认键
四位二进制密码输入完成后按确认键
FPGA会通过亮灯形式通知你输入的密码是否正确
如果正确FPGA开发板上的绿灯亮起右数码管上的数字变成一条横线 如果错误FPGA开发板上的红灯亮起右数码管上的数字减一 如果连续三次尝试错误FPGA开发板上红灯绿灯同时亮起右数码管显示数字0密码箱锁死。 复位键
主要是为了解决密码箱锁死之后还想继续测试的情况。
当密码箱锁死之后按下复位键程序会将所有数据重置开发板密码箱回到初始状态。
确认键和复位键都通过按键开关来实现。 输出部分
如上描述输出部分包括右数码管的数字显示、红灯和绿灯的两个指示灯。
二.verilog代码
module password(clk,rst,key_confirm,key_set,sw_password,led,sega);input clk; //时钟input rst; //重置input key_confirm; //复位键input key_set; //修改密码input [3:0] sw_password; //四位二进制密码output [1:0] led; //是否解锁指示灯output [8:0] sega; //右数码管output [8:0] segb; //左数码管reg password 4b0000; //初始密码reg [1:0] sgn; //两位指示灯信号对应两路指示灯reg [8:0] seg[3:0]; //9位宽信号用来储存数码管数字显示器reg [8:0] seg_data[1:0]; //数码管显示信号寄存器reg [1:0] cnt; //计数器泳衣统计错误次数reg lock; //程序锁用于结束程序wire confirm_dbs; //消抖后确认脉冲initial begin //初始化seg[0]9h3f; //数码管显示数字0seg[1]9h06; //数字1seg[2]9h5b; //数字2seg[3]9h4f; //数字3seg_data[0]9h3f; //右初始数字显示数字0cnt2b11; //计数器初始值3endalways (posedge clk or negedge rst) //时钟边沿触发或复位按键触发beginif(!rst) //复位begin sgn2b11; //亮灯均火seg_data[0]seg[3]; //右显示数字3cnt2b11; //计数器复位到3lock2b11; //程序锁默认状态1正常endelse if (confirm_dbs lock) //按下确认键此处用的消抖后的脉冲信号\//若程序已锁则不执行beginif(sw_password password) //密码正确beginsgn2b10; //绿灯亮seg_data[0]9h40; seg_data[1]9h40; //密码输入正确后两根数码管显示两根横线lock2b10; //程序锁进入状态2可调密码endelse if(cnt2b11)beginsgn2b01; //红灯亮seg_data[0]seg[2]; //数码管显示数字2cnt2b10; //计数器移至2endelse if(cnt2b10)beginsgn2b01; //红灯亮seg_data[0]seg[1]; //数码管显示数字1cnt2b01; //计数器移至1endelse if(cnt2b01)beginsgn2b00; //绿灯和红灯同时亮seg_data[0]seg[0]; //数码管显示数字0lock0; //程序锁进入状态0锁死endendendassign ledsgn; //绿灯代表密码正确红灯代表密码错误assign segaseg_data[0]; //右数码管随输入信号变化改变数值debounce key_confirm_dbs //消抖模块用以消抖确认键( .clk(clk),.rst(rst),.key(key_confirm),.key_pulse(confirm_dbs));
endmodule
三.消抖模块
module debounce (clk,rst,key,key_pulse);parameter N 1; //要消除的按键的数量input clk;input rst;input [N-1:0] key; //输入的按键 output [N-1:0] key_pulse; //按键动作产生的脉冲 reg [N-1:0] key_rst_pre; //定义一个寄存器型变量存储上一个触发时的按键值reg [N-1:0] key_rst; //定义一个寄存器变量储存储当前时刻触发的按键值wire [N-1:0] key_edge; //检测到按键由高到低变化是产生一个高脉冲//利用非阻塞赋值特点将两个时钟触发时按键状态存储在两个寄存器变量中always (posedge clk or negedge rst)beginif (!rst) beginkey_rst {N{1b1}}; //初始化时给key_rst赋值全为1{}中表示N个1key_rst_pre {N{1b1}};endelse beginkey_rst key; //第一个时钟上升沿触发之后key的值赋给key_rst,//同时key_rst的值赋给key_rst_prekey_rst_pre key_rst; //非阻塞赋值。相当于经过两个时钟触发//key_rst存储的是当前时刻key的值//key_rst_pre存储的是前一个时钟的key的值end endassign key_edge key_rst_pre (~key_rst);//脉冲边沿检测。当key检测到下降沿时//key_edge产生一个时钟周期的高电平reg [17:0] cnt; //产生延时所用的计数器系统时钟12MHz//要延时20ms左右时间至少需要18位计数器 //产生20ms延时当检测到key_edge有效是计数器清零开始计数always (posedge clk or negedge rst)beginif(!rst)cnt 18h0;else if(key_edge)cnt 18h0;elsecnt cnt 1h1;end reg [N-1:0] key_sec_pre; //延时后检测电平寄存器变量reg [N-1:0] key_sec; //延时后检测key如果按键状态变低产生一个时钟的高脉冲。//如果按键状态是高的话说明按键无效always (posedge clk or negedge rst)beginif (!rst) key_sec {N{1b1}}; else if (cnt18h3ffff)key_sec key; endalways (posedge clk or negedge rst)beginif (!rst)key_sec_pre {N{1b1}};else key_sec_pre key_sec; end assign key_pulse key_sec_pre (~key_sec); endmodule
四.管脚分配