⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 passed_lock.v

📁 用状态机实现密码锁State machine used to achieve code lock
💻 V
字号:
module passed_lock(
				clk,
				resetb,
				
				cmd,
				
				alarmed,
				passed,
				password,
				main_state,
				try_count
);
input			clk;			//输入时钟信号
input			resetb;		//输入复位信号
input 	[4:0]	cmd;		//输入命令信号0
output			alarmed;		//输出警报信号led
output			passed;		//输出通过信号led
output  [2:0]   main_state;//lcd
output  [1:0]   try_count;
output  [15:0]  password;
wire			clk;
wire			resetb;
wire	[4:0]	cmd;
reg				alarmed;
reg				passed;
//输入与输出的声明部分,其中,clk为输入的时钟信号,resetb为密码舒服的输入信号,cmd为输入命令,需注意的时,cmd并不是总在表示密码,也表示密码的间隔,如当输入4位密码后需要一个确认“enter”信号,当密码输入错误时,需要取消“cancel”信号,这些信号之间在设计中通过有限状态转换机实现。

parameter		PASSWORD=16'd1234;//盛放密码的参数
reg		[15:0]	password;//输入数值盛放寄存器

//输入的数字编码 0~9,enter,cancel
reg			    one=5'b10001,
				two=5'b10010,
				three=5'b10011,
				four=5'b10100,
				five=5'b10101,
				six=5'b10110,
				seven=5'b10111,
				eight=5'b11000,
				nine=5'b11001,
				zero=5'b10000,
				
				enter=5'b11010,
				cancel=5'b11011;
reg			cmd_t;//检验是否有按键按下

reg			[2:0]	main_state;//主状态
reg			[2:0]	next_state;//下一个状态


//主有限状态转换机的三个状态:waits、pass、alarm
parameter		    waits=3'b001,
					pass=3'b010,
					alarm=3'b100;

reg		[2:0]	sub_state;
reg		[2:0]	next_sub_state;

 //主有限状态转换机的三个状态:first、second、third、fourth、finish。
parameter		    first=3'b000,
					second=3'b001,
					third=3'b010,
					fourth=3'b011,
					finish=3'b100;
//通过计时寄存器
reg		[7:0]	pass_count;
//警报计时寄存器
reg		[10:0]	alarm_count;
//尝试次数寄存器
reg		[1:0]	try_count;

//输入状态寄存器:error和correct
reg			error;
reg			correct;
//以上为中间状态的一些寄存器和一些所用到的参数
//主机状态机部分

always@(main_state or correct or error)
begin
	case(main_state)
		waits:
			if(correct==1) //由waits转换到pass的条件
				next_state=pass;
			else if(error==1&&try_count==2)
				next_state=alarm; //由waits转换到alarm的条件
			else
				next_state=waits;
		pass:
			if(pass_count[7]==1)//由pass转换到waits的条件
				next_state=waits;
			else
				next_state=pass;
		alarm:
			if(alarm_count[10]==1)// 由alarm转换到waits的条件
				next_state=waits;
			else
				next_state=alarm;
		default://默认状态:waits
			next_state=waits;
		endcase
	end


//状态转换
always@(posedge clk or negedge resetb)
begin
	if(!resetb)
		main_state<=waits;
	else
		main_state<=next_state;
end

//输出控制部分
always@(posedge clk or negedge resetb)
begin
	if(!resetb)//复位时,开锁输出与警报输出都为零
		begin
			passed<=0;
			alarmed<=0;
		end
	else if(main_state==pass)//当主机状态为pass时,开锁
		begin
			passed<=1;
			alarmed<=0;
		end
	else if(main_state==alarm)//当主机状态为alarm时,警报
		begin
			passed<=0;
			alarmed<=1;
		end
	else//其它状态复位
		begin
			passed<=0;
			alarmed<=0;
		end
end

//alarm一段时间后,自动进入waits状态
//alarm定时器
always@(posedge clk or negedge resetb)
begin
	if(!resetb)
		alarm_count<=0;
	else if(main_state==alarm)//alarm状态计时器alarm定时器加1
		alarm_count<=alarm_count+1;
	else
		alarm_count<=0;
end

//锁pass以后计数开始,当规定的时间到达后自动上锁,并进入waits状态
//pass定时器
always@(posedge clk or negedge resetb)
	begin
		if(!resetb)
			pass_count<=0;
		else if(main_state==pass) //pass状态计时器pass定时器加1
			pass_count<=pass_count+1;
		else
			pass_count<=0;
	end
	
//从状态机,用于输入4位密码


always@(posedge clk or negedge resetb)
begin 
	if(!resetb)
		cmd_t<=0;
	else 
		cmd_t<=-cmd[4];
end

always@(posedge clk or negedge resetb)
begin
	if(!resetb)
		sub_state<=first;
	else
		sub_state<=next_sub_state;
end

always@(cmd or cmd_t or sub_state)
//always@(cmd or sub_state)
begin
	if(cmd_t==0&&cmd[4]==1)
		case(cmd)
			cancel://密码输入错误时,重复上一个状态
			begin
				if(sub_state==first)// 第1个密码输入错误
					next_sub_state=first;
				else
					case(sub_state)
					second: // 第2个密码输入错误
						next_sub_state=first;
					third: // 第3个密码输入错误
						next_sub_state=second;
					fourth: // 第4个密码输入错误
						next_sub_state=third;
					finish:
						next_sub_state=fourth;
					endcase
			end
			enter://4个密码输完时,进行确认
				next_sub_state=first;
			//以下4个命令位无效的命令,状态保持不变
			5'b11100:
				next_sub_state=next_sub_state;
			5'b11101:
				next_sub_state=next_sub_state;
			5'b11110:
				next_sub_state=next_sub_state;
			5'b11111:
				next_sub_state=next_sub_state;
				
			//default为输入了某位密码,输入完自动将状态转入下一位
			default:
				case(sub_state)
				first:
					next_sub_state=second;
				second:
					next_sub_state=third;
				third:
					next_sub_state=fourth;
				fourth:
					next_sub_state=finish;
//当输入完4位密码以后状态保持不变,等待输入enter命
//令
				finish:
					next_sub_state=finish;	
				endcase
			endcase
		else
			next_sub_state=sub_state;
end

//比较密码,产生正确或者错误信息
always@(posedge clk or negedge resetb)
begin
	if(!resetb)
		begin
			correct<=0;
			error<=0;
		end
	else if(cmd_t ==0&&cmd==enter)
		if(password==PASSWORD)//密码正确时
			begin
				correct<=1;
				error<=0;
			end
		else//密码错误时
			begin
				error<=1;
				correct<=0;
			end
		else
			begin
				correct<=0;
				error<=0;
			end
end

//记录密码
always@(posedge clk or negedge resetb)
begin
	if(!resetb)
		password<=0;
	else if(cmd_t==0&&cmd[4]==1)
		case(sub_state)
		first:
			password[15:12]<=cmd[3:0];
		second:
			password[11:8]<=cmd[3:0];
		third:
			password[7:4]<=cmd[3:0];
		fourth:
			password[3:0]<=cmd[3:0];
		default:
			password<=password;
		endcase
	else
		password<=password;
end

//记录错误次数
always@(posedge clk or negedge resetb)
begin
if(!resetb)
		try_count<=0;
	else if(error==1)
		try_count<=try_count+1;
	else if(main_state==pass||main_state==alarm)
		try_count<=0;
	end
endmodule

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -