概述
设计一个10层楼的电梯控制器模块,要求:(1) 以按键的时间先后优先级进行设计;(2) 以楼层最短位置先后优先级进行设计。
电梯运行规则:
当电梯处在上升模式时,只响应比电梯所在位置高的上楼请求,由下向上逐个执行,直到最后一个上楼请求执行完毕。如果高层有下楼请求,直接升到有下楼请求的最高楼层,然后进入下降模式。下降模式类似。
定义每层楼的状态,可扩展至任意楼层。
UP(IN):XXXXXXXXXX(10~1楼;1有效,0无效),上楼请求
DOWN(IN):XXXXXXXXXX(10~1楼;1有效,0无效),下楼请求
其中1层只能有上楼请求,10层只能有下楼请求,同一层不能既有上楼请求又有下楼请求。上楼或下楼请求被响应后对应位清零。
BUTTON(IN):XXXXXXXXXX(10~1楼;1有效,0无效),要去往的楼层
到达要去往的楼层后对应位清零。
POSITION(OUT):XXXX(当前楼层)
FLOOR:XXXXXXXXXX(10~1楼;1有效,0无效),电梯需要停下并开关门的楼层
电梯处在上升模式时,FLOOR=UP|BUTTON;电梯处在下降模式时,FLOOR=DOWN|BUTTON。
UP_DOWN:X(0上升模式,1下降模式)
状态图
仿真流程图
Design Block:
module elevator (CLK,RESET,UP,DOWN,BUTTON,POSITION);
input CLK,RESET;
input [10:1] UP,DOWN,BUTTON;
output reg [3:0] POSITION;
reg [3:0] P;
reg [10:1] FLOOR;
reg UP_DOWN;
reg tmp,flag;
integer temp;
reg [8:0] CurrentState,NextState;
parameter S0=9'b000000001,S1=9'b000000010,S2=9'b000000100,S3=9'b000001000,S4=9'b000010000,S5=9'b000100000,S6=9'b001000000,S7=9'b010000000,S8=9'b100000000;
always @ (posedge CLK or negedge RESET)
begin
if(~RESET) CurrentState<=S0;
else CurrentState<=NextState;
end
always @ (RESET or CurrentState or UP_DOWN or UP or DOWN or BUTTON or P or flag)
begin
if(~RESET)
begin
UP_DOWN=0;
FLOOR=10'b0;
P=4'b0001;
flag=0;
end
else
begin
if(flag==0) FLOOR=UP_DOWN?DOWN|BUTTON:UP|BUTTON;
case(CurrentState)
S0:
begin
POSITION=P;
if(FLOOR==10'b0) NextState=S0;
else
begin
if(UP_DOWN==0)
begin
if(P==4'b1010) UP_DOWN=1;
else
begin
case(P)
4'b0001:
tmp=FLOOR[2] | FLOOR[3] | FLOOR[4] | FLOOR[5] | FLOOR[6] | FLOOR[7] | FLOOR[8] | FLOOR[9] | FLOOR[10];
4'b0010:
tmp=FLOOR[3] | FLOOR[4] | FLOOR[5] | FLOOR[6] | FLOOR[7] | FLOOR[8] | FLOOR[9] | FLOOR[10];
4'b0011:
tmp=FLOOR[4] | FLOOR[5] | FLOOR[6] | FLOOR[7] | FLOOR[8] | FLOOR[9] | FLOOR[10];
4'b0100:
tmp=FLOOR[5] | FLOOR[6] | FLOOR[7] | FLOOR[8] | FLOOR[9] | FLOOR[10];
4'b0101:
tmp=FLOOR[6] | FLOOR[7] | FLOOR[8] | FLOOR[9] | FLOOR[10];
4'b0110:
tmp=FLOOR[7] | FLOOR[8] | FLOOR[9] | FLOOR[10];
4'b0111:
tmp=FLOOR[8] | FLOOR[9] | FLOOR[10];
4'b1000:
tmp=FLOOR[9] | FLOOR[10];
4'b1001:
tmp=FLOOR[10];
endcase
if(tmp==0)
begin
FLOOR=DOWN|BUTTON;
case(P)
4'b0001:
tmp=FLOOR[2] | FLOOR[3] | FLOOR[4] | FLOOR[5] | FLOOR[6] | FLOOR[7] | FLOOR[8] | FLOOR[9] | FLOOR[10];
4'b0010:
tmp=FLOOR[3] | FLOOR[4] | FLOOR[5] | FLOOR[6] | FLOOR[7] | FLOOR[8] | FLOOR[9] | FLOOR[10];
4'b0011:
tmp=FLOOR[4] | FLOOR[5] | FLOOR[6] | FLOOR[7] | FLOOR[8] | FLOOR[9] | FLOOR[10];
4'b0100:
tmp=FLOOR[5] | FLOOR[6] | FLOOR[7] | FLOOR[8] | FLOOR[9] | FLOOR[10];
4'b0101:
tmp=FLOOR[6] | FLOOR[7] | FLOOR[8] | FLOOR[9] | FLOOR[10];
4'b0110:
tmp=FLOOR[7] | FLOOR[8] | FLOOR[9] | FLOOR[10];
4'b0111:
tmp=FLOOR[8] | FLOOR[9] | FLOOR[10];
4'b1000:
tmp=FLOOR[9] | FLOOR[10];
4'b1001:
tmp=FLOOR[10];
endcase
if(tmp==0) UP_DOWN=1;
else
begin
flag=1;
UP_DOWN=0;
end
end
end
end
else
begin
if(P==4'b0001) UP_DOWN=0;
else
begin
case(P)
4'b1010:
tmp=FLOOR[9] | FLOOR[8] | FLOOR[7] | FLOOR[6] | FLOOR[5] | FLOOR[4] | FLOOR[3] | FLOOR[2] | FLOOR[1];
4'b1001:
tmp=FLOOR[8] | FLOOR[7] | FLOOR[6] | FLOOR[5] | FLOOR[4] | FLOOR[3] | FLOOR[2] | FLOOR[1];
4'b1000:
tmp=FLOOR[7] | FLOOR[6] | FLOOR[5] | FLOOR[4] | FLOOR[3] | FLOOR[2] | FLOOR[1];
4'b0111:
tmp=FLOOR[6] | FLOOR[5] | FLOOR[4] | FLOOR[3] | FLOOR[2] | FLOOR[1];
4'b0110:
tmp=FLOOR[5] | FLOOR[4] | FLOOR[3] | FLOOR[2] | FLOOR[1];
4'b0101:
tmp=FLOOR[4] | FLOOR[3] | FLOOR[2] | FLOOR[1];
4'b0100:
tmp=FLOOR[3] | FLOOR[2] | FLOOR[1];
4'b0011:
tmp=FLOOR[2] | FLOOR[1];
4'b0010:
tmp=FLOOR[1];
endcase
if(tmp==0)
begin
FLOOR=UP|BUTTON;
case(P)
4'b1010:
tmp=FLOOR[9] | FLOOR[8] | FLOOR[7] | FLOOR[6] | FLOOR[5] | FLOOR[4] | FLOOR[3] | FLOOR[2] | FLOOR[1];
4'b1001:
tmp=FLOOR[8] | FLOOR[7] | FLOOR[6] | FLOOR[5] | FLOOR[4] | FLOOR[3] | FLOOR[2] | FLOOR[1];
4'b1000:
tmp=FLOOR[7] | FLOOR[6] | FLOOR[5] | FLOOR[4] | FLOOR[3] | FLOOR[2] | FLOOR[1];
4'b0111:
tmp=FLOOR[6] | FLOOR[5] | FLOOR[4] | FLOOR[3] | FLOOR[2] | FLOOR[1];
4'b0110:
tmp=FLOOR[5] | FLOOR[4] | FLOOR[3] | FLOOR[2] | FLOOR[1];
4'b0101:
tmp=FLOOR[4] | FLOOR[3] | FLOOR[2] | FLOOR[1];
4'b0100:
tmp=FLOOR[3] | FLOOR[2] | FLOOR[1];
4'b0011:
tmp=FLOOR[2] | FLOOR[1];
4'b0010:
tmp=FLOOR[1];
endcase
if(tmp==0) UP_DOWN=0;
else
begin
flag=1;
UP_DOWN=1;
end
end
end
end
NextState=S1;
end
end
S1:
NextState=S2;
S2:
NextState=S3;
S3:
NextState=S4;
S4:
begin
if(UP_DOWN==0) NextState=S5;
else NextState=S6;
end
S5:
begin
if(FLOOR==10'b0) NextState=S0;
else
begin
P=P+1'b1;
if(flag==1)
begin: B1
integer i;
temp=0;
for(i=10;i>0 && temp==0;i=i-1)
if(FLOOR[i]==1) temp=i;
if(P==temp)
begin
flag=0;
UP_DOWN=1;
NextState=S0;
end
else
NextState=S7;
end
else
begin
if(FLOOR[P]) NextState=S0;
else NextState=S7;
end
end
end
S6:
begin
if(FLOOR==10'b0) NextState=S0;
else
begin
P=P-1'b1;
if(flag==1)
begin: B2
integer i;
temp=0;
for(i=1;i<11 && temp==0;i=i+1)
if(FLOOR[i]==1) temp=i;
if(P==temp)
begin
flag=0;
UP_DOWN=0;
NextState=S0;
end
else
NextState=S8;
end
else
begin
if(FLOOR[P]) NextState=S0;
else NextState=S8;
end
end
end
S7:
NextState=S5;
S8:
NextState=S6;
endcase
end
end
endmodule
Test Bench:
`timescale 1ns/1ns
module Test_elevator;
reg CLK,RESET;
reg [10:1] UP,DOWN,BUTTON;
wire [3:0] POSITION;
elevator U0(CLK,RESET,UP,DOWN,BUTTON,POSITION);
always begin
CLK=1'b0;
#5 CLK=1'b1;
#5;
end
initial begin
RESET=1'b0;
#10 RESET=1'b1;
#790 $stop;
end
initial begin
UP=10'b0;
#10 UP=10'b0000010001;
#40 UP=10'b0000010000;
#160 UP=10'b0;
end
initial begin
DOWN=10'b0;
#210 DOWN=10'b1100000000;
#180 DOWN=10'b0100000000;
#60 DOWN=10'b0;
#120 DOWN=10'b0000100000;
#40 DOWN=10'b0;
end
initial begin
BUTTON=10'b0;
#10 BUTTON=10'b0000001000;
#140 BUTTON=10'b0;
#20 BUTTON=10'b0010000000;
#140 BUTTON=10'b0;
#40 BUTTON=10'b0000100000;
#200 BUTTON=10'b0;
#20 BUTTON=10'b0000000001;
#180 BUTTON=10'b0;
end
endmodule
仿真波形图:
总结
这个题目去年做过,今年回过头来看有了一些新的思考。相比之前在每层楼增加了上下楼请求按钮(UP、DOWN),在电梯里增加了要去往的楼层按键(BUTTON),将FLOOR变成中间变量,表示电梯需要停下并开关门的楼层。整个系统功能完善了许多,也更具备实用性。
最后
以上就是靓丽康乃馨为你收集整理的Verilog HDL设计——电梯控制器模块的全部内容,希望文章能够帮你解决Verilog HDL设计——电梯控制器模块所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复