四层电梯设计verilog

介绍

本文介绍的是使用verilog进行四层电梯的设计。

一共有四个按键,以及四个小灯

    input  key1,
	input  key2,
	input  key3,
	input  key4,
	output reg led1,
	output reg led2,
	output reg led3,
	output reg led4

key1,key2,key3,key4表示你要去的楼层,led1,led2,led3,led4在你按下相应的按键后会亮,直到电梯到达对应楼层后熄灭,如果电梯不在一楼且当前无按键操作,那么电梯将默认返回一楼,此时led1会默认亮起,且到达一楼后led1不熄灭,直到电梯处于上升状态且不在一楼熄灭。电梯每上升一个楼层将花费10个时钟周期,如果到达小灯亮的楼层,那么电梯会停留5个时钟周期,然后继续运行

下面将分功能进行介绍

按键key

always@(posedge clk)begin
	if(~rst_n)
	begin
	key1_r2<=0;
	key2_r2<=0;
	key3_r2<=0;
	key4_r2<=0;//对四个状态进行复位置零
	end
	else if(key1)
		begin
			key1_r2<=key1;
		end
	else if(key2)
		begin
			key2_r2<=key2;
		end
	else if(key3)
		begin
			key3_r2<=key3;
		end
	else if(key4)
		begin
			key4_r2<=key4;//如果按下,将其状态传到对应寄存器
		end
	else if(key2_r2&&dir)
	begin
		key1_r2<=0;//按下key2后对key1的状态清零,表示离开一楼
		if(waittime==3'd5)
			key2_r2<=0;//按下key2后在二楼等待5秒后key2_r2清零
	end
	else if(key3_r2&&dir)
	begin
		key1_r2<=0;
		if(waittime==3'd5)
			key3_r2<=0;
	end
	else if(key4_r2&&dir)
	begin
		key1_r2<=0;
		if(waittime==3'd5)
			key4_r2<=0;
	end
	else if(!key1_r2&&!key2_r2&&!key3_r2&&!key4_r2)
	begin
		key1_r2<=1;//如果无操作的话,电梯将返回一楼
	end
	else if(key3_r2&&!dir)
		begin
			key1_r2<=1;//如果是下降状态,默认最终到达一楼,此时key1_r2为1
			if(waittime==3'd5)
				key3_r2<=0;
		end
	else if(key2_r2&&!dir)
		begin
			key1_r2<=1;
			if(waittime==3'd5)
				key2_r2<=0;
		end
	else if(key1_r2)
		begin
		end

end

计数器cnt

always@(posedge clk)begin
	if(~rst_n)
		cnt<=10;//复位时计数器为10,代表1楼;后面20代表2楼,以此类推
	else if(key2_r2&&dir)
	begin
		cnt<=cnt+1;//上升过程中cnt加一,下降过程中cnt减一
		if(cnt==8'd20)
		cnt<=cnt;//到达20后计数器保持不变,此时waittime开始计时
	end
	else if(key3_r2&&dir)
	begin
		cnt<=cnt+1;
		if(cnt==8'd30)
		cnt<=cnt;
	end
	else if(key4_r2&&dir)
	begin
		cnt<=cnt+1;
		if(cnt==8'd40)
		cnt<=cnt;
	end
	else if(!key1_r2&&!key2_r2&&!key3_r2&&!key4_r2)
	begin
		cnt<=cnt-1;
		if(cnt==8'd10)
			cnt<=cnt;
	end
	else if(key3_r2&&!dir)
		begin
			cnt<=cnt-1;
			if(cnt==8'd30)
				cnt<=cnt;
		end
	else if(key2_r2&&!dir)
		begin
			cnt<=cnt-1;
			if(cnt==8'd20)
				cnt<=cnt;
		end
	else if(key1_r2)
		begin
			cnt<=cnt-1;
			if(cnt==8'd10)
				cnt<=cnt;
		end

end

等待时间waittime

always@(posedge clk)begin
	if(~rst_n)
		waittime<=0;
	else if(key2_r2&&cnt==8'd20&&dir)
	begin
		waittime<=waittime+1;//到达所在楼层后开始计算等待时长
		if(waittime==3'd5)
			waittime<=0;
	end
	else if(key3_r2&&cnt==8'd30&&dir)
	begin
		waittime<=waittime+1;
		if(waittime==3'd5)
			waittime<=0;
	end
	else if(key4_r2&&cnt==8'd40&&dir)
	begin
		waittime<=waittime+1;
		if(waittime==3'd5)
			waittime<=0;
	end
	else if(!key1_r2&&!key2_r2&&!key3_r2&&!key4_r2)
	begin
		cnt<=cnt-1;
		if(cnt==8'd10)
			cnt<=cnt;
	end
	else if(key3_r2&&cnt==8'd30&&!dir)
		begin
			waittime<=waittime+1;
			if(waittime==3'd5)
			waittime<=0;
		end
	else if(key2_r2&&cnt==8'd20&&!dir)
		begin
		waittime<=waittime+1;
		if(waittime==3'd5)
			waittime<=0;
		end
	else waittime<=waittime;
end

方向dir

always@(posedge clk)begin
	if(~rst_n)
		dir<=1;
	else if(key2_r2&&(cnt==8'd10))//如果按了二楼而当前处于一楼,那么方向上升
		dir<=1;
	else if(key3_r2&&(cnt==8'd20))
		dir<=1;
	else if(key4_r2&&(cnt==8'd30))
		dir<=1;
	else if(key4_r2&&(cnt==8'd40)&&(waittime==3'd5))
		dir<=0;//如果按了四楼且当前处于四楼,等待5秒后,方向变为向下
	else if(key3_r2&&(cnt==8'd35))
		dir<=0;
	else if(key2_r2&&(cnt==8'd30))
		dir<=0;
	else if(key1_r2&&(cnt==8'd10))
		dir<=1;

end

小灯led

assign led1=key1_r2?1:0;//只要key1_r2的状态为1,那么小灯就亮

assign led2=(key2_r2&&(cnt==8'd20))?0:key2_r2?1:0;//只要key2按下,那么小灯就开始亮,直到到达对应楼层
assign led3=(key3_r2&&(cnt==8'd30))?0:key3_r2?1:0;
assign led4=(key4_r2&&(cnt==8'd40))?0:key4_r2?1:0;

全部代码

module test2(
	input clk,
	input rst_n,
	input  key1,
	input  key2,
	input  key3,
	input  key4,
	output reg led1,
	output reg led2,
	output reg led3,
	output reg led4
	);
reg [7:0]cnt;
reg dir;
reg [2:0]waittime;
reg key1_r2,key2_r2,key3_r2,key4_r2;




//key
always@(posedge clk)begin
	if(~rst_n)
	begin
	key1_r2<=0;
	key2_r2<=0;
	key3_r2<=0;
	key4_r2<=0;
	end
	else if(key1)
		begin
			key1_r2<=key1;
		end
	else if(key2)
		begin
			key2_r2<=key2;
		end
	else if(key3)
		begin
			key3_r2<=key3;
		end
	else if(key4)
		begin
			key4_r2<=key4;
		end
	else if(key2_r2&&dir)
	begin
		key1_r2<=0;
		if(waittime==3'd5)
			key2_r2<=0;
	end
	else if(key3_r2&&dir)
	begin
		key1_r2<=0;
		if(waittime==3'd5)
			key3_r2<=0;
	end
	else if(key4_r2&&dir)
	begin
		key1_r2<=0;
		if(waittime==3'd5)
			key4_r2<=0;
	end
	else if(!key1_r2&&!key2_r2&&!key3_r2&&!key4_r2)
	begin
		key1_r2<=1;
	end
	else if(key3_r2&&!dir)
		begin
			key1_r2<=1;
			if(waittime==3'd5)
				key3_r2<=0;
		end
	else if(key2_r2&&!dir)
		begin
			key1_r2<=1;
			if(waittime==3'd5)
				key2_r2<=0;
		end
	else if(key1_r2)
		begin
		end

end




//cnt
always@(posedge clk)begin
	if(~rst_n)
		cnt<=10;
	else if(key2_r2&&dir)
	begin
		cnt<=cnt+1;
		if(cnt==8'd20)
		cnt<=cnt;
	end
	else if(key3_r2&&dir)
	begin
		cnt<=cnt+1;
		if(cnt==8'd30)
		cnt<=cnt;
	end
	else if(key4_r2&&dir)
	begin
		cnt<=cnt+1;
		if(cnt==8'd40)
		cnt<=cnt;
	end
	else if(!key1_r2&&!key2_r2&&!key3_r2&&!key4_r2)
	begin
		cnt<=cnt-1;
		if(cnt==8'd10)
			cnt<=cnt;
	end
	else if(key3_r2&&!dir)
		begin
			cnt<=cnt-1;
			if(cnt==8'd30)
				cnt<=cnt;
		end
	else if(key2_r2&&!dir)
		begin
			cnt<=cnt-1;
			if(cnt==8'd20)
				cnt<=cnt;
		end
	else if(key1_r2)
		begin
			cnt<=cnt-1;
			if(cnt==8'd10)
				cnt<=cnt;
		end

end

//waittime
always@(posedge clk)begin
	if(~rst_n)
		waittime<=0;
	else if(key2_r2&&cnt==8'd20&&dir)
	begin
		waittime<=waittime+1;
		if(waittime==3'd5)
			waittime<=0;
	end
	else if(key3_r2&&cnt==8'd30&&dir)
	begin
		waittime<=waittime+1;
		if(waittime==3'd5)
			waittime<=0;
	end
	else if(key4_r2&&cnt==8'd40&&dir)
	begin
		waittime<=waittime+1;
		if(waittime==3'd5)
			waittime<=0;
	end
	else if(!key1_r2&&!key2_r2&&!key3_r2&&!key4_r2)
	begin
		cnt<=cnt-1;
		if(cnt==8'd10)
			cnt<=cnt;
	end
	else if(key3_r2&&cnt==8'd30&&!dir)
		begin
			waittime<=waittime+1;
			if(waittime==3'd5)
			waittime<=0;
		end
	else if(key2_r2&&cnt==8'd20&&!dir)
		begin
		waittime<=waittime+1;
		if(waittime==3'd5)
			waittime<=0;
		end
	else waittime<=waittime;
end
//dir

always@(posedge clk)begin
	if(~rst_n)
		dir<=1;
	else if(key2_r2&&(cnt==8'd10))
		dir<=1;
	else if(key3_r2&&(cnt==8'd20))
		dir<=1;
	else if(key4_r2&&(cnt==8'd30))
		dir<=1;
	else if(key4_r2&&(cnt==8'd40)&&(waittime==3'd5))
		dir<=0;
	else if(key3_r2&&(cnt==8'd35))
		dir<=0;
	else if(key2_r2&&(cnt==8'd30))
		dir<=0;
	else if(key1_r2&&(cnt==8'd10))
		dir<=1;

end





assign led1=key1_r2?1:0;

assign led2=(key2_r2&&(cnt==8'd20))?0:key2_r2?1:0;
assign led3=(key3_r2&&(cnt==8'd30))?0:key3_r2?1:0;
assign led4=(key4_r2&&(cnt==8'd40))?0:key4_r2?1:0;
endmodule : test2



`timescale 1ns/1ps

module tb_test2 (); /* this is automatically generated */

	// clock
	logic clk;
	initial begin
		clk = '0;
		forever #(0.5) clk = ~clk;
	end

	// synchronous reset
	logic rst_n;
	initial begin
		rst_n <= '0;
		repeat(10)@(posedge clk);
		rst_n <= '1;
	end

	// (*NOTE*) replace reset, clock, others

	logic  key1;
	logic  key2;
	logic  key3;
	logic  key4;
	logic  led1;
	logic  led2;
	logic  led3;
	logic  led4;

	test2 inst_test2
		(
			.clk   (clk),
			.rst_n (rst_n),
			.key1  (key1),
			.key2  (key2),
			.key3  (key3),
			.key4  (key4),
			.led1  (led1),
			.led2  (led2),
			.led3  (led3),
			.led4  (led4)
		);

	initial begin
		key1=0;
		key2=0;
		key3=0;
		key4=0;
		#30 key2=1;
		#2 key2=0;
		key3=1;
		#2
		key3=0;
		#5 key4=1;
		#2 key4=0;
		#40 key2=1;
		#2 key2=0;
	end

endmodule

仿真结果

 

评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

与fpga斗智斗勇

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值