密码锁22.docx
《密码锁22.docx》由会员分享,可在线阅读,更多相关《密码锁22.docx(28页珍藏版)》请在冰点文库上搜索。
密码锁22
电子与信息工程学院
课程设计报告
(2011—2012学年第一学期)
课程名称:
EDA课程设计与实现
班级:
______________
学号:
______________
姓名:
__________________
指导教师:
__
20101年10月
课程设计题目:
EDA课程设计与实现
实验目的:
1.掌握VHDL语言的使用,学会用VHDL语言来编程解决实际问题;
2.学会使用EDA开发软件设计小型综合电路,掌握仿真的技巧;
3.学会应用开发系统实现硬件电路,检验电路的功能。
实验要求:
用VHDL语言设计一个密码锁,用波形仿真验证其功能后,实现到GW48实验系统。
功能描述:
用于模仿密码锁的工作过程。
完成密码锁的核心控制功能。
功能要求:
设计一个密码锁,平时处于等待状态。
管理员可以设置或更改密码。
如果不预置密码,密码缺省为“1234”。
用户如果需要开锁,按相应的按键进入输入密码状态,输入4位密码,按下确定键后,若密码正确,锁打开;若密码错误,将提示密码错误,要求重新输入,三次输入都错误,将发出报警信号。
报警后,只有管理员作相应的处理才能停止报警。
用户输入密码时,若输入错误,在按下确定键之前,可以通过按取消键重新输入。
正确开锁后,用户处理完毕后,按下确定键,系统回到等待状态。
系统操作过程中,只要密码锁没有打开,如果60秒没有对系统操作,系统回到等待状态。
要求密码在输入过程中被依次显示,即先输入的为密码的第一位,总是显示在最左边。
用两个发光二极管模拟显示,其中一个显示当前的工作模式,灭表示用户模式,亮表示管理员模式;另外一个指示锁的状态,灭表示锁处于锁定,亮表示锁被开启。
用两个按键实现密码输入,Key1选择输入的是第几位,Key2输入密码数字。
功能描述:
初始状态:
初次使用密码锁时,要先用Reset键初始化。
初始状态下,用户密码为“1234”,管理员密码为“0000”。
用户开锁:
默认情况下,密码锁处于用户使用状态。
如果当前为管理员状态,则按下user键回到用户状态。
用户开锁时,输入四位数用户密码,可以从out_code6的输出状态确定密码输入状态。
如输入错误则按下clear清除前一位输入。
输入完毕后按enter,如果密码正确,则开锁,否则重新输入密码。
开锁后再次按下enter键则关锁,回到等待状态。
三次密码输入错误,警报器alarming为1。
要管理员输入管理员密码解除警报。
此时哪怕用户再输对密码也没用。
管理员解除警报:
当用户三次密码输入错误的时候,alarming为1,此时,只要管理员密码输入正确后,按下clear键,alarming为0,报警取消。
管理员修改密码:
在非警报和为开锁状态下,任何时候按admin键进入管理员状态。
按chgcode选择修改密码,先选择修改的是用户密码还是管理员密码。
修改用户密码则按user键,修改管理员密码则按admin键。
然后分别输入旧密码,新密码,新密码要输入两次。
旧密码与所要修改的密码对应。
如旧密码输入错误,则无法修改;当验证不成功即两次新密码不相同时,修改密码失败。
返回等待状态。
成功后也返回等待状态。
定时返回:
用户在未开锁状态下,60s没有按键输入,则返回等待状态,但不包括alarming状态。
只要是alarming,则只有管理输入管理员密码才能解锁并按下clear
消除警报。
Verilog程序源代码:
module
mimasuo(clk,reset,user,admin,clear,chgcode,enter,key1,key2,led1,led2,alarming);
inputclk,reset,user,admin,chgcode,enter,clear;
inputkey1,key2;
outputled1,led2,alarming;
wireclk,reset,user,sdmin,chgcode,enter;
wirekey1,key2;
reg[3:
0]count1,count2;
regled1,led2,alarming;
reg[15:
0]ram_user;
reg[15:
0]new_ram_user1,new_ram_user2;
reg[15:
0]ram_admin,new_ram_admin1,new_ram_admin2;
reg[2:
0]try_count,try_count2;
parameter[2:
0]
user_state=3'b000,
admin_state=3'b001,
wait_state=3'b010,
alarming_state=3'b011,
unclock_state=3'b100,
clock_state=3'b101;
reg[15:
0]user_mima,admin_mima;
reg[15:
0]current_state,next_state,sub_current_state,sub_next_state;
reg[5:
0]numtime;
regback;
always@(negedgereset)
begin
if(~reset)
admin_mima=16'b0;
user_mima=16'b0001001000110100;
alarming=1'b0;
end
always@(*)
begin
if(user==1'b1)
current_state<=user_state;
if(admin==1'b1)
current_state<=admin_state;
end
always@(*)状态转换
begin
case(current_state)
user_state:
begin
led1=1'b0;
if(admin==1'b1)
next_state<=admin_state;
if(admin==1'b0)
next_state<=user_state;
if(ram_user==user_mima&&enter==1'b1)
next_state<=clock_state;
if(ram_user!
=user_mima||enter!
=1'b1)
next_state<=unclock_state;
else
next_state<=user_state;
end
admin_state:
begin
led1<=1'b1;
if(user==1'b1)
next_state<=user_state;
if(new_ram_user1==new_ram_user2&&enter==1'b1)
next_state<=wait_state;
if((ram_user!
=user_mima&&enter==1'b1)||(new_ram_user1!
=new_ram_user2&&enter==1'b1))
next_state<=wait_state;
if((new_ram_admin1==new_ram_admin2)&&enter==1'b1)
next_state<=wait_state;
if((ram_admin!
=admin_mima&&enter==1'b1)||(new_ram_admin1!
=new_ram_admin2&&enter==1'b1))
next_state<=wait_state;
else
next_state<=admin_state;
end
alarming_state:
begin
alarming=1'b1;
if(admin_mima==ram_admin&&enter==1'b1&&clear==1'b1)
alarming<=1'b0;
next_state<=admin_state;
if((admin_mima!
=ram_admin&&enter==1'b1)||clear!
=1'b1)
alarming<=1'b1;
next_state<=alarming_state;
end
unclock_state:
begin
if(back==1'b1)
next_state<=wait_state;
elseif(back==1'b0)
next_state<=unclock_state;
end
clock_state:
begin
if(enter==1'b1)
led2<=1'b0;
next_state<=wait_state;
if(admin==1'b1||enter!
=1'b1)
next_state<=admin_state;
end
wait_state:
begin
led2<=1'b0;
end
default:
begin
next_state<=user_state;
end
endcase
end
always@(posedgeclkornegedgereset)
begin
if(~reset)
current_state<=user_state;
else
current_state<=next_state;
end
parameter[2:
0]
one=3'b0,
two=3'b1,
three=3'b10,
four=3'b011,
finish=3'b100;
always@(*)//putinuser_mima
begin
if(current_state==user_state||current_state==admin_state)
case(sub_current_state)
one:
begin
if(clear==1'b1)
sub_next_state<=one;
else
sub_next_state<=two;
end
two:
begin
if(clear==1'b1)
sub_next_state<=two;
else
sub_next_state<=three;
end
three:
begin
if(clear==1'b1)
sub_next_state<=three;
else
sub_next_state<=four;
end
four:
begin
if(clear==1'b1)
sub_next_state<=four;
else
sub_next_state<=finish;
end
finish:
begin
sub_next_state<=finish;
end
default:
sub_next_state<=sub_current_state;
endcase
end
always@(posedgeclkornegedgereset)
begin
if(~reset)
sub_current_state<=one;
else
sub_current_state<=next_state;
end
always@(posedgeenter)
begin
if(~reset)
try_count=2'b0;
elseif(current_state==user_state)
begin
if(user_mima!
=ram_user&&enter==1'b1)
try_count=try_count+1'b1;
else
if(current_state==alarming_state)
try_count=2'b0;
else
try_count=try_count;
end
else
try_count=2'b0;
end
always@(posedgeenterornegedgereset)//错误密码计数
begin
if(~reset)
alarming<=1'b0;
elseif(try_count==2'b10&&try_count2==2'b10)
alarming<=1'b1;
next_state<=alarming_state;
end
always@(negedgereset)//输入用户密码
begin
if(~reset)
ram_user<=16'b0001001000110100;
elseif(sub_current_state==one)
if(count1==4'b0&&user==1'b1)
ram_user[15:
12]<=count2;
else
if(count1==4'b1&&user==1'b1)
ram_user[11:
8]<=count2;
else
if(count1==4'b10&&user==1'b1)
ram_user[7:
4]<=count2;
else
if(count1==4'b100&&user==1'b1)
ram_user[3:
0]<=count2;
end
always@(negedgereset)//输入管理员密码
begin
if(~reset)
ram_admin<=16'b0;
else
if(count1==4'b1&&admin==1'b1)
ram_admin[15:
12]<=count2;
else
if(count1==4'b10&&admin==1'b1)
ram_admin[11:
8]<=count2;
else
if(count1==4'b10&&admin==1'b1)
ram_admin[7:
4]<=count2;
else
if(count1==4'b11&&admin==1'b1)
ram_admin[3:
0]<=count2;
end
always@(posedgeclkornegedgereset)//计时模块
begin
if(~reset)
numtime<=6'b0;
elseif(numtime==6'b111100)
numtime<=6'b0;
elseif(numtime<6'b111100)
numtime<=numtime+1'b1;
end
always@(posedgeclkornegedgereset)
begin
if(~reset||numtime<6'b111100)
back<=1'b0;
else
back<=1'b1;
end
always@(*)
begin
if(~reset)
led2<=1'b0;
elseif(current_state==user_state||current_state==admin_state)
if((ram_user==user_mima&&enter==1'b1)||(ram_admin==admin_mima&&enter==1'b1))
led2<=1'b1;
else
led2<=1'b0;
end
always@(*)
begin
if(current_state==admin_state)
if(chgcode==1'b1)
led2=1'b0;//修改密码
if(user==1'b1)
if(user_mima==ram_user)
if(count1==4'b0)
new_ram_user1[15:
12]<=count2;
else
if(count1==4'b1)
new_ram_user1[11:
8]<=count2;
else
if(count1==4'b10)
new_ram_user1[7:
4]<=count2;
else
if(count1==4'b11)
new_ram_user1[3:
0]<=count2;
if(count1==4'b0)
new_ram_user2[15:
12]<=count2;
else
if(count1==4'b1)
new_ram_user2[11:
8]<=count2;
else
if(count1==4'b10)
new_ram_user2[7:
4]<=count2;
else
if(count1==4'b11)
new_ram_user2[3:
0]<=count2;
if(new_ram_user1==new_ram_user2&&enter==1'b1)
ram_user<=new_ram_user2;
led2=1'b0;
if((ram_user!
=user_mima&&enter==1'b1)||(new_ram_user1!
=new_ram_user2&&enter==1'b1))
ram_user=ram_user;
if(admin==1'b1)
if(admin_mima==ram_admin)
if(count1==4'b0)
new_ram_admin1[15:
12]<=count2;
else
if(count1==4'b1)
new_ram_admin1[11:
8]<=count2;
else
if(count1==4'b10)
new_ram_admin1[7:
4]<=count2;
else
if(count1==4'b11)
new_ram_admin1[3:
0]<=count2;
if(count1==4'b0)
new_ram_admin2[15:
12]<=count2;
else
if(count1==4'b1)
new_ram_admin2[11:
8]=count2;
else
if(count1==4'b10)
new_ram_admin2[7:
4]<=count2;
else
if(count1==4'b1)
new_ram_admin2[3:
0]<=count2;
if(new_ram_admin1==new_ram_admin2)
ram_admin<=new_ram_admin2;
if(ram_admin!
=admin_mima||new_ram_admin1!
=new_ram_admin2)
ram_admin<=ram_admin;
end
always@(posedgekey1ornegedgereset)设置Key1,Key2的按键模式
begin
if(~reset)
count1<=4'b0;
else
if(count1==4'b11)
count1<=4'b0;
elseif(count1<4'b11&&key1==1'b1)
count1<=count1+1'b1;
end
always@(posedgekey2ornegedgereset)
begin
if(~reset)
count2<=4'b0;
elseif(key2==4'b1)
count2<=count2+1'b1;
end
always@(posedgeenterornegedgereset)
begin
if(~reset)
try_count2<=1'b0;
else
if(try_count2==2'b10)
try_count2<=2'b0;
elseif(try_count2<2'b10&&enter==1'b1)
try_count2<=try_count2+1'b1;
end
endmodule
Tb测试文件程序:
`timescale1ns/1ps
moduletbmimasuo;
regreset,clk,user,admin,chgcode,enter,clear;
regkey1,key2;
wireled1,led2,alarming;
always#100clk=~clk;
initial
begin
clk=1'b1;
user=1'b0;
key1=4'b0;
key2=4'b0;
admin=1'b0;
clear=1'b0;
chgcode=1'b0;
enter=1'b0;
reset=1'b0;
#50reset=1'b1;
admin=1'b1;
chgcode=1'b1;
admin=1'b1;
#50key1=1'b1;
#10key1=1'b0;
key2=1'b0;
#150key1=1'b1;
#10key1=1'b0;
#50key1=1'b1;
#10key1=1'b0;
key2=1'b1;
#10key2=1'b0;
#50key1=1'b1;
#10key1=1'b0;
key2=1'b0;
#50key1=1'b1;
#10key1=1'b0;
#50key1=1'b1;
#10key1=1'b0;
#100key1=1'b1;
#10key1=1'b0;
key2=1'b0;
#50key1=1'b1;
#10key1=1'b0;
#50key1=1'b1;
#10key1=1'b0;
#50key1=1'b1;
#10key1=1'b0;
key2=1'b0;
#10enter=1'b1;
#150enter=1'b0;
#50key1=1'b1;
#10key1=1'b0;
key2=1'b1;
#10key2=1'b0;
#150key1=1'b1;
#10key1=1'b0;
#50key1=1'b1;
#10key1=1'b0;
key2=1'b1;
#10key2=1'b0;
#50key1=1'b1;
#10key1=1'b0;
#50key1=1'b1;
#10key1=1'b0;
#50key1=1'b1;
#10key1=1'b0;
#50key2=1'b1;
#10key2=1'b0;
#100key1=1'b1;
#10key1=1'b0;
key1=1'b1;
#10key1=1'b0;
#50key1=1'b1;
#10key1=1'b0;
#50key1=1'b1;
#10key1=1'b0;
#50key1=1'b1;
#10key1=1'b0;
#50key2=1'b1;
#10key2