|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?注册
x
本帖最后由 89274616 于 2011-3-31 19:13 编辑
//设计一个6层电梯控制器。电梯控制器是按照乘客的要求自动上、下的装置。
//1、每层电梯入口处设置上下请求开关,电梯内设有顾客到达层次的停站请求开关。
//2、设有电梯所处位置指示装置以及电梯运行模式(上升或者下降)指示装置。
//3、电梯每秒升降一层楼。
//4、电梯到达有停站请求的楼层,经过1秒电梯门打开,开门4秒后,电梯门关闭(开门指示灯灭),电梯继续运行,直至执行完最后一个请求信号后停留在当前层。
//5、电梯能记忆电梯内外所有请求信号,并按照电梯运行规则按顺序响应,每个请求信号保留至有电梯响应后消除。
//6、电梯运行规则:当电梯上升时,只响应比电梯所在位置高的上楼请求信号,由下而上逐个执行,直到最后一个上楼请求执行完毕;
//如果高层有下楼请求,则直接升到下楼请求的最高楼层,然后进入下降模式。当电梯处于下降模式时与上升正好相反
module elerun(clk,alarm,reset,fuplight,fdnlight,stlight,position,doorlight,cleardn,clearup,yanshi,tiqian);
input clk;//电梯时钟
input alarm;//报警
input reset;//异步置位
input [6:1] fuplight,fdnlight,stlight;//电梯外部上升请求指示灯,电梯外部下降请求指示灯,电梯内部各层指示灯
wire [2:0] position;//电梯位置指示
output doorlight,clearup,cleardn;//电梯门开关指示灯,用于清除上升请求指示灯的信号,用于清除下降请求指示灯的信号
reg doorlight,cleatup,cleardn;
input yanshi;//延时关门//
input tiqian;//提前关门//
output [7:0]udsig;//电梯上升或下降指示灯//
reg [7:0]udsig;
parameter [3:0] stopon1=0;
parameter [3:0] dooropen=1;
parameter [3:0] doorclose=2;
parameter [3:0] doorwait1=3;
parameter [3:0] doorwait2=4;
parameter [3:0] doorwait3=5;
parameter [3:0] doorwait4=6;
parameter [3:0] doorwait5=7;
parameter [3:0] doorwait6=8;
parameter [3:0] up=9;
parameter [3:0] down=10;
parameter [3:0] stop=11;
reg [3:0] mylift;
wire [2:0] pos;
reg udflag;
reg [2:0] posreg;
reg [6:1] one;
always@(posedge clk or negedge reset)
begin
if(reset==1'b1|alarm==1'b1)
begin
mylift<=stopon1;
clearup<=1'b1;
cleardn<=1'b1;
end
else
begin if(!clk)
case(mylift)
stopon1: begin
doorlight<=1'b0;
posreg<=1'b1;
mylift<=doorwait1;
clearup<=1'b0;
cleardn<=1'b0;
udsig<=8'b00000010;
end
doorwait1: begin//开门时间为doorwait1~doorwait6,5个时钟周期//
//如果期间提前信号tiqian有效,则电梯直接跳到doorclose状// //如果期间延时信号yanshi有效,则电梯直接跳到doorwait1状态
if(tiqian)
begin
mylift<=doorclose;
end
else
if(yanshi)
begin
mylift<=doorwait1;
end
else
begin
mylift<=doorwait2;
end
clearup<=1'b0;
cleardn<=1'b0;
end
doorwait2:
begin
if(tiqian)
begin
mylift<=doorclose;
end
else if(yanshi)
begin
mylift<=doorwait1;
end
else
begin
mylift<=doorwait3;
end
clearup<=1'b0;
cleardn<=1'b0;
end
doorwait3:
begin
if(tiqian)
begin
mylift<=doorclose;
end
else if(yanshi)
begin
mylift<=doorwait1;
end
else
begin
mylift<=doorwait4;
end
clearup<=1'b0;
cleardn<=1'b0;
end
doorwait4:
begin
if(tiqian)
begin
mylift<=doorclose;
end
else if(yanshi)
begin
mylift<=doorwait1;
end
else
begin
mylift<=doorwait5;
end
clearup<=1'b0;
cleardn<=1'b0;
end
doorwait5:
begin
if(tiqian)
begin
mylift<=doorclose;
end
else if(yanshi)
begin
mylift<=doorwait1;
end
else begin
mylift<=doorwait6;
end
clearup<=1'b0;
cleardn<=1'b0;
end
doorwait6:
begin
mylift<=doorclose;
clearup<=~udflag;
cleardn<=udflag;//在doorwait6状态,输出上升清除信号与下降清除信号//
end
doorclose:
begin
doorlight<=1'b0;//开门灯灭//
clearup<=1'b0;
cleardn<=1'b0;
//根据按键处理模块,控制电梯的上升和下降//
//如果电梯在六楼//
if(posreg==1'h6)
begin
if(stlight==6'b000000&fuplight==6'b000000&fdnlight==6'b000000)//如果电梯在6楼,且电梯外部与内部没有任何按键请求,电梯转到关门状态//
begin
mylift<=doorclose;
udsig<=8'b00000010;//数码管的横灯亮,表示电梯停止没有上升或向下运动//
end
else //电梯在6楼,且电梯外部与内部有任何按键请求时,电梯转到下降状态//
begin
mylift<=down;
udsig<=8'b01111010;//数码管的现实为小写的d,表示电梯下降运行//
udflag<=1'b1;//电梯运行状态指示下降//
end
end
else
//如果电梯在1楼//
if(posreg==1'h1)
begin
if(stlight==6'b000000&fuplight==6'b000000&fdnlight==6'b000000)//如果电梯在1楼,且电梯外部与内部没有任何按键请求,电梯转到关门状态//
//电梯运行状态指示停止//
begin
mylift<=doorclose;
udsig<=8'b00000010;//数码管的横杠亮,表示电梯停止,没有向上或向下运动//
end
else //如果电梯在1层,且电梯外部与内部有任何按键请求,电梯转到上升状态//
begin
mylift<=up;//进入上升状态//
udsig<=8'b01111100;//数码管的现实为U,表示电梯上升运行//
udflag<=1'b0;//电梯的运行状态指示上升//
end
end
//在其他楼层情况//
else
begin
if(stlight==6'b000000&fuplight==6'b000000&fdnlight==6'b000000)//电梯在2-5层,且电梯外部与内部没有任何按键请求,电梯转到关门状态//
//电梯运行状态指示停止//
begin
mylift<=doorclose;
udsig<=8'b00000010;//数码管的横杠亮,表示电梯停止没有向上或向下运行//
end
else //如果电梯外部上升或者下降请求所在的楼层比电梯当前楼层高,或是电梯内部前往的楼层比电梯当前
//楼层高,电梯转到上升状态
begin if(stlight>=(one+one)|fuplight>=(one+one)|fdnlight>=(one+one))
begin
mylift<=up;
udsig<=8'b01111100;//数码管的显示为U,表示电梯上升运行
udflag<=0;//电梯的运行状态指示上升
end
end
else begin if((stilight+stlight)<=one|(fuplight+fuplight)<=one|(fdnlight+fdnlight)<=one)//
//如果电梯外部上升或者下降请求所在的楼层比电梯当前楼层高,或是电梯内部前往的楼层
//比电梯当前楼层低,电梯转到下降状态
mylift<=down;
udsig<=8'b01111010;//数码管的显示为小写的d,表示电梯下降运行
udflag<=1;//电梯运行状态为下降
end
else
begin
mylift<=doorclose;
end
end
//当电梯在上升状态
up:
begin
clearup<=0;
cleardn<=0;
begin
if(posreg<6&((stlight[posreg])==1'b1|(fuplight[posreg])==1'b1|(stlight==6'b000000&(fdnlight[posreg])==1'b1)))//当电梯所在楼层低于6层,当前楼层是电梯前往楼层之一,或是当前楼层有人请求上升
//或是电梯内部没有请求信号但当前楼层有人请求下降,电梯则转到停止状态
begin
mylift<=stop;
if(stlight==6'b000000&(fdnlight[posreg])==1'b1&fuplight==6'b000000)//
//如果电梯内部没有请求信号,电梯外部没有上升请求信号,且当前楼层有电梯外部下降请求信号,
//则电梯运行时转到下降
begin
udflag<=1;//1--下降指示
end
end
else if(posreg==1'd6&((stlight[posreg])==1|(fuplight[posreg])==1|(fdnlight[posreg])==1'b1|fuplight==6'b000000))//当电梯所在楼层为6层,有人前往第6层,或者第6层有人下降请求,电梯则转到停止状态
begin
mylift<=stop;
end
else if(posreg==1'd6&(fdnlight>6'b000000|fuplight>6'b000000))
begin
mylift<=stop;
end
//其他情况,电梯继续上升运行,电梯所在楼层加1
else begin
mylift<=up;//电梯进入上升状态
udsig<=8'b01111100;//数码管显示U,表示电梯上升
udflag<=1'b0;//电梯运行状态上升
if(posreg<=1'd6)
begin
posreg=<posreg+1'b1;
end
end
end
//当电梯下降运行时
down:
begin
clearup<=1'b0;
cleardn<=1'b0;
//当电梯所有楼层为2-6层时,当前楼层是电梯前往楼层之上,或是当前楼层有人请求下降
//或是电梯内部没有前往信号但楼层有人请求上升
if(posreg>1&((stlight[posreg])==1'b1|fdnlight[posreg]==1'b1|(fuplight[posreg])==1'b1))
begin
mylift<=stop;
//当电梯内部没有前往信号,电梯外部也没有下降请求信号,且当前楼层有上升请求信号,电梯运行转为上升
if(stlight==6'b000000&(fuplight[posreg]==1'b1&fdnlight==6'b000000))
udflag<=1'b0;
end
//当前楼层为第1层,当前楼层有电梯内部前往楼层之一,或是1楼有人请求上升
else if(posreg==1'b1&((stlight[posreg])==1'b1|(fdnlight[posreg])==1'b1|(fdnlight==6'b00000&(fuplight[posreg])==1'b1)))
begin
mylift<=stop;
end
else if(posreg==1'b1&(fdnlight>6'b000000|fuplight>6'b000000))
begin
mylift<=stop;
end
else
begin
mylift<=down;
udsig<=6'b01111010;
udflag<=1'b1;//下降
end
if(posreg>1)
begin
posreg<=posreg-1;
end
end
//电梯为停止状态,则转到电梯开门状态
stop:
begin
mylift<=dooropen;
clearup<=1'b0;
cleardn<=1'b0;
end
//电梯为开门状态,开门灯亮,转到关门等待状态
dooropen:
begin
doorlight<=1'b1;
clearup<=1'b0;
cleardn<=1'b0;
mylift<=doorwait1;
end
//电梯的其他状态则转到电梯关门等待状态下
default:
begin
mylift<=doorwait1;
clearup<=1'b0;
cleardn<=1'b0;
end
endcase
end
end
assign postion=posreg;
always@(posedge clk or posreg)
begin
if(!clk)
case(posreg)
1: one<=6'b000001;
2: one<=6'b000010;
3: one<=6'b000100;
4: one<=6'b001000;
5: one<=6'b010000;
6: one<=6'b100000;
endcase
end
endmodule |
|