Verilog实现密码箱实验报告_第1页
Verilog实现密码箱实验报告_第2页
Verilog实现密码箱实验报告_第3页
Verilog实现密码箱实验报告_第4页
Verilog实现密码箱实验报告_第5页
已阅读5页,还剩18页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Verilog实现密码箱1.功能概述小脚丫开发板的有4位拨码开关,可以表示数字0-9,有两个七段数码管,所以密码设为两位(00—99),初始密码00,利用四位拨码开关(sw)输入密码,,按下个位确认按键(low),在数码管上显示个位数字;再次输入密码,按下十位确认按键(high),在数码管上显示十位数字。按下确认按键(enter),比较密码正误,若正确,实现开锁功能,用led8灯亮表示;错误,实现报错功能,用led1灯亮表示;连续错三次,实现警报功能,用8个灯全亮表示,此时只有重置(rst)才能重新输入密码。初始密码为21。为保证安全性,只有在开锁状态下,才可修改密码,修改拨码开关数值,按下个位确认按键(low),设置新密码个位,再次修改拨码开关数值,按下个位确认按键(high),设置新密码十位(实际上两个位密码修改与输入顺序不影响)。再按下重置键(rst),即可重新输入密码。同时在使用按键时,注意到了消抖。2.效果展示密码错误密码正确修改后密码正确视频展示(双击播放)3.代码分析一、密码显示在数码管上always@(*)//数码管显示控制模块begin case(code_low) 4'd0:seg_led1=9'b000111111;//数码管1显示0 4'd1:seg_led1=9'b000000110;//1 4'd2:seg_led1=9'b001011011;//2 4'd3:seg_led1=9'b001001111;//3 4'd4:seg_led1=9'b001100110;//4 4'd5:seg_led1=9'b001101101;//5 4'd6:seg_led1=9'b001111101;//6 4'd7:seg_led1=9'b000000111;//7 4'd8:seg_led1=9'b001111111;//8 4'd9:seg_led1=9'b001101111;//9 default:seg_led1=9'b100111111;//0 endcase case(code_high) 4'd0:seg_led2=9'b000111111;//数码管2显示0 4'd1:seg_led2=9'b000000110;//1 4'd2:seg_led2=9'b001011011;//2 4'd3:seg_led2=9'b001001111;//3 4'd4:seg_led2=9'b001100110;//4 4'd5:seg_led2=9'b001101101;//5 4'd6:seg_led2=9'b001111101;//6 4'd7:seg_led2=9'b000000111;//7 4'd8:seg_led2=9'b001111111;//8 4'd9:seg_led2=9'b001101111;//9 default:seg_led2=9'b100111111;//0 endcaseend二、密码比对判断always@(posedgeclk)//密码判断begin if(!rst) begin wrong_cnt<=2'b00;//初始错误次数为0 code_low<=4'b0000; code_high<=4'b0000; led<=8'b11111111; end elseif(low_d) begin code_low<=sw; end elseif(high_d) begin code_high<=sw; end elseif(enter_d) begin if(wrong_cnt!=2'd2) begin if((code_low==Y&&code_high==X)||(code_low==newcode_low&&code_high==newcode_high)) begin led<=8'b01111111;//密码正确,led8亮 wrong_cnt<=2'd0; end else begin led<=8'b11111110;//密码错误,led1亮错误次数加一 wrong_cnt<=wrong_cnt+1; end end else led<=8'b00000000;//密码输错三次,报警 endend三、密码修改实现//修改控制模块always@(posedgeclk) begin if(!rst) change<=0; elseif(led<=8'b01111111) change<=1; if(change==1&&high_d) begin newcode_high<=sw; end elseif(change==1&&low_d) begin newcode_low<=sw; end endendmodule四、按键消抖实现//按键消抖模块moduledebounce(clk,rst,key,key_pulse);parameterN=2;//要消除的按键的数量 inputclk;inputrst;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@(posedgeclkornegedgerst)begin if(!rst) begin key_rst<={N{1'b1}};//初始化时给key_rst赋值全为1,{}中表示N个1key_rst_pre<={N{1'b1}};endelse begin key_rst<=key;//第一个时钟上升沿触发之后key的值赋给key_rst,同时key_rst的值赋给key_rst_pre key_rst_pre<=key_rst;//非阻塞赋值。相当于经过两个时钟触发,key_rst存储的是当前时刻key的值,key_rst_pre存储的是前一个时钟的key的值endendassignkey_edge=key_rst_pre&(~key_rst);//脉冲边沿检测。当key检测到下降沿时,key_edge产生一个时钟周期的高电平 reg [17:0] cnt;//产生延时所用的计数器,系统时钟12MHz,要延时20ms左右时间,至少需要18位计数器//产生20ms延时,当检测到key_edge有效是计数器清零开始计数always@(posedgeclkornegedgerst) begin if(!rst) cnt<=18'h0;elseif(key_edge)cnt<=18'h0;elsecnt<=cnt+1'h1;endreg[N-1:0]key_sec_pre;//延时后检测电平寄存器变量reg[N-1:0]key_sec;//延时后检测key,如果按键状态变低产生一个时钟的高脉冲。如果按键状态是高的话说明按键无效always@(posedgeclkornegedgerst) begin if(!rst) key_sec<={N{1'b1}};elseif(cnt==18'h3ffff)key_sec<=key;endalways@(posedgeclkornegedgerst) begin if(!rst) key_sec_pre<={N{1'b1}};elsekey_sec_pre<=key_sec;endassignkey_pulse=key_sec_pre&(~key_sec);endmodule4.附录,源码图以及源码//顶层模块modulesafebox_plus( inputclk, input[3:0]sw,//四位拨码开关,用作十进制密码 inputrst,//复位键 inputenter,//密码确认键 inputhigh,//十位输入键 inputlow,//个位输入键 outputreg[7:0]led,//八位报警灯,led8为正确提示灯,led1为错误提示灯 outputreg[8:0]seg_led1,//数码管1显示个位密码 outputreg[8:0]seg_led2//数码管2显示十位密码);parameterX=4'd0;//用作初始密码parameterY=4'd0;wireenter_d;//key[3]确认密码输入wirelow_d;//key[1]个位确认wirehigh_d;//key[2]十位确认reg[1:0]wrong_cnt;//统计错误次数reg[3:0]code_low;//个位密码reg[3:0]code_high;//十位密码regchange;//可修改密码状态reg[3:0]newcode_low;//更新密码个位reg[3:0]newcode_high;//更新密码十位//例化调用消抖模块debounce#(.N(3))u1( .clk(clk), .rst(rst), .key({enter,low,high}), .key_pulse({enter_d,low_d,high_d}));always@(*)//数码管显示控制模块begin case(code_low) 4'd0:seg_led1=9'b000111111;//数码管1显示0 4'd1:seg_led1=9'b000000110;//1 4'd2:seg_led1=9'b001011011;//2 4'd3:seg_led1=9'b001001111;//3 4'd4:seg_led1=9'b001100110;//4 4'd5:seg_led1=9'b001101101;//5 4'd6:seg_led1=9'b001111101;//6 4'd7:seg_led1=9'b000000111;//7 4'd8:seg_led1=9'b001111111;//8 4'd9:seg_led1=9'b001101111;//9 default:seg_led1=9'b100111111;//0 endcase case(code_high) 4'd0:seg_led2=9'b000111111;//数码管2显示0 4'd1:seg_led2=9'b000000110;//1 4'd2:seg_led2=9'b001011011;//2 4'd3:seg_led2=9'b001001111;//3 4'd4:seg_led2=9'b001100110;//4 4'd5:seg_led2=9'b001101101;//5 4'd6:seg_led2=9'b001111101;//6 4'd7:seg_led2=9'b000000111;//7 4'd8:seg_led2=9'b001111111;//8 4'd9:seg_led2=9'b001101111;//9 default:seg_led2=9'b100111111;//0 endcaseendalways@(posedgeclk)//密码判断begin if(!rst) begin wrong_cnt<=2'b00;//初始错误次数为0 code_low<=4'b0000; code_high<=4'b0000; led<=8'b11111111; end elseif(low_d) begin code_low<=sw; end elseif(high_d) begin code_high<=sw; end elseif(enter_d) begin if(wrong_cnt!=2'd2) begin if((code_low==Y&&code_high==X)||(code_low==newcode_low&&code_high==newcode_high)) begin led<=8'b01111111; wrong_cnt<=2'd0; end else begin led<=8'b11111110; wrong_cnt<=wrong_cnt+1; end end else led<=8'b00000000; endend//修改控制模块always@(posedgeclk) begin if(!rst) change<=0; elseif(led<=8'b01111111) change<=1; if(change==1&&high_d) begin newcode_high<=sw; end elseif(change==1&&low_d) begin newcode_low<=sw; end endendmodule//按键消抖模块moduledebounce(clk,rst,key,key_pulse);parameterN=2;//要消除的按键的数量 inputclk;inputrst;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@(posedgeclkornegedgerst)begin if(!rst) begin key_rst<={N{1'b1}};//初始化时给key_rst赋值全为1,{}中表示N个1key_rst_pre<={N{1'b1}};endelse begin key_rst<=key;//第一个时钟上升沿触发之后key的值赋给key_rst,同时key_rst的值赋给key_rst_pre key_rst_pre<=key_rst;//非阻塞赋值。相当于经过两个时钟触发,key_rst存储的是当前时刻key的值,key_rst_pre存储的是前一个时钟的key的值endendassignkey_edge=key_rst_pre&(~key_rst);//脉冲边沿检测。当key检测到下降沿时,key_edge产生一个时钟周期的高电平 reg [17:0] cnt;//产生延时所用的计数器,系统时钟12MHz,要延时20ms左右时间,至少需要18

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论