Verilog 四层电梯设计

能跑就行系列。。


描述:设计一个4层楼的电梯控制系统,完成电梯向上或向下移动到被请求楼层(假设电梯每移动一层需要1秒)。请求可来自每层楼的呼叫按钮,也可来自电梯内的目的楼层选择。当电梯到达被请求楼层后,打开电梯门10秒(假设该电梯内只有楼层按键,没有开门和关门按键),然后关闭电梯门前往下一个被请求楼层;如果没有请求则停在本层。电梯运行中保持电梯门关闭。当同时有多个请求时,应答的优先原则为尽可能不改变电梯运动方向且距离当前楼层最近。

top_module模块

module top_module(
input clr,              //清零端子
input clk,              //时钟信号
input [3:0]in_floor,    //电梯内楼层输入
input [2:0]out_up,      //电梯上升信号
input [3:1]out_down,     //电梯下降信号

output [3:0]led,     //小灯泡
output [3:0] pos,    
output [7:0] seg
    );
    
wire [15:0]dataBus;    //数据传输
wire clk190hz;
wire clk_1s;           //时钟信号(1s)
wire clk_10s;          //时钟信号(10s)

segMsgout U1(.clk190hz(clk190hz),.dataBus(dataBus),.pos(pos),.seg(seg));
counter   U2(.clr(clr),.clk(clk),.clk_1s(clk_1s),.clk_10s(clk_10s));
clkDiv    U3(.clk100mhz(clk),.clk190hz(clk190hz));
elevator_controller U4(.clr(clr),.clk(clk),.clk_1s(clk_1s),.clk_10s(clk_10s),.in_floor(in_floor),
                       .out_up(out_up),.out_down(out_down),.dataBus(dataBus),.led(led));

endmodule

elevator_controller模块

module elevator_controller(
input clr,              //清零端子
input clk,              //时钟信号
input clk_1s,           //时钟信号(1s)
input clk_10s,          //时钟信号(10s)
input [3:0]in_floor,    //电梯内楼层输入
input [2:0]out_up,      //电梯上升信号
input [3:1]out_down,    //电梯下降信号

output reg [15:0]dataBus,//数据传输
output [3:0]led      //小灯泡

);

 parameter stop=2'b00,down=2'b01,up=2'b10;
 parameter one_stop=4'b0000,  one_up=4'b0001, /* x_stop 代表电梯停止状态  
                                                  x_up   代表电梯向上运行状态  
                                                  x_down 代表电梯向下运行状态 */    
            two_stop=4'b0010,  two_up=4'b0011,  two_down=4'b0100,
            three_stop=4'b0101,three_up=4'b0110,three_down=4'b0111,
            four_stop=4'b1000, four_down=4'b1001,
            Cstop=4'b1010;   //Cstop 代表电梯运动过程中响应的停止状态
            
 reg [2:0]now_floor; // 楼层号
 reg [1:0]elevator;  // 电梯运行状态
 reg [3:0]Cstate;    // 电梯控制器状态机的状态值
 reg door;           // 电梯门开关状态

 reg [3:0]present_state;
 reg [3:0]next_state;
 
initial
begin
    now_floor=0;
    elevator=stop;
    door=0;
    Cstate=0;
    present_state=0;
    next_state=0;
end

always@(posedge clk) //数据传输
begin
    dataBus[15:0]<={1'b0,now_floor[2:0]+3'b001,2'b00,elevator[1:0],Cstate[3:0],3'b000,door};
end

always@(posedge clk or posedge clr) //状态控制
  begin
  if(clr)
    begin
        present_state<=one_stop;
        next_state<=one_stop;
    end
  else
    begin
    
    present_state<=next_state; //现状态转变为下一状态
    
    case(present_state)
      one_stop:
        begin
            if(!(out_up[0]|out_up[1]|out_up[2]|out_down[1]|out_down[2]|out_down[3]))
                next_state<=one_stop;
            else
                begin
                    if(clk_10s) next_state<=one_up;
                    else        next_state<=next_state;
                end
        end    
      one_up:
        begin
            if(!(out_up[0]|out_up[1]|out_up[2]|out_down[1]|out_down[2]|out_down[3]|in_floor[0]|in_floor[1]|in_floor[2]|in_floor[3]))
                begin
                    next_state<=one_stop;
                end
            else
                begin
                    if(clk_1s)
                        begin
                            if(out_up[1]|out_down[1]|in_floor[1])
                                next_state<=Cstop;
                            else if(in_floor[0]|(out_up[0]&&!(in_floor[1]|in_floor[2]|in_floor[3])))
                                next_state<=one_stop;
                            else 
                                next_state<=two_up;
                        end
                    else    next_state<=next_state;
                end
        end
      two_stop:
        begin
            if(!(out_up[0]|out_up[1]|out_up[2]|out_down[1]|out_down[2]|out_down[3]))
                next_state<=two_stop;
            else
                begin
                    if(clk_10s)
                        begin
                            if(out_up[1]|out_up[2]|out_down[2]|out_down[3])
                                next_state<=two_up;
                            else if(out_up[0]|out_down[1])
                                next_state<=two_down;
                        end
                    else    next_state<=next_state;
                end
        end
      two_up:
        begin
            if(!(out_up[0]|out_up[1]|out_up[2]|out_down[1]|out_down[2]|out_down[3]|in_floor[0]|in_floor[1]|in_floor[2]|in_floor[3]))
                next_state<=two_stop;
            else
                begin
                    if(clk_1s)
                        begin
                            if(out_up[2]|out_down[2]|in_floor[2])
                                next_state<=Cstop;
                            else if(in_floor[1]|(out_up[1]&&!(in_floor[2]|in_floor[3])))
                                next_state<=two_stop;
                            else
                                next_state<=three_up;
                        end
                    else    next_state<=next_state;
                end
        end
      two_down:
        begin
            if(!(out_up[0]|out_up[1]|out_up[2]|out_down[1]|out_down[2]|out_down[3]|in_floor[0]|in_floor[1]|in_floor[2]|in_floor[3]))
                next_state<=two_stop;
            else
                begin   
                    if(clk_1s)
                        begin
                            if(in_floor[1]|(out_down[1]&&(~in_floor[0])))       
                                next_state<=two_stop;                                             
                            else
                                next_state<=Cstop;                                             
                        end
                    else    next_state<=next_state;
                end 
        end
      three_stop:
        begin
            if(!(out_up[0]|out_up[1]|out_up[2]|out_down[1]|out_down[2]|out_down[3]))            
                next_state<=three_stop;
            else
                begin
                    if(clk_10s)
                        begin
                            if(out_up[2]|out_down[3])
                                next_state<=three_up;
                            else if(out_up[0]|out_up[1]|out_down[1]|out_down[2])
                                next_state<=three_down;
                        end
                    else    next_state<=next_state;
                end
        end
      three_up:
        begin
            if(!(out_up[0]|out_up[1]|out_up[2]|out_down[1]|out_down[2]|out_down[3]|in_floor[0]|in_floor[1]|in_floor[2]|in_floor[3]))
                next_state<=three_stop;
            else
                begin
                    if(clk_1s)
                        begin
                            if(in_floor[2]|(out_up[2]&&(~in_floor[3])))
                                next_state<=three_stop;
                            else
                                next_state<=Cstop;
                        end
                    else    next_state<=next_state;
                end
        end
      three_down:
        begin
            if(!(out_up[0]|out_up[1]|out_up[2]|out_down[1]|out_down[2]|out_down[3]|in_floor[0]|in_floor[1]|in_floor[2]|in_floor[3]))
                next_state<=three_stop;
            else
                begin
                    if(clk_1s)
                        begin
                            if(out_down[1]|out_up[1]|in_floor[1])
                                next_state<=Cstop;
                            else if(in_floor[2]|(out_down[2]&&!(in_floor[0]|in_floor[1])))
                                next_state<=three_stop;
                            else 
                                next_state<=two_down;
                        end
                    else    next_state<=next_state;
                end
        end
      four_stop:
        begin
            if(!(out_up[0]|out_up[1]|out_up[2]|out_down[1]|out_down[2]|out_down[3]))
                next_state<=four_stop;
            else
                begin
                    if(clk_10s) next_state<=four_down;
                    else        next_state<=next_state;
                end
        end 
      four_down:
        begin
            if(!(out_up[0]|out_up[1]|out_up[2]|out_down[1]|out_down[2]|out_down[3]|in_floor[0]|in_floor[1]|in_floor[2]|in_floor[3]))
                next_state<=four_stop;
            else
                begin
                    if(clk_1s)
                        begin
                            if(out_down[2]|out_up[2]|in_floor[2])
                                next_state<=Cstop;
                            else if(in_floor[3]|(out_down[3]&&!(in_floor[0]|in_floor[1]|in_floor[2])))
                                next_state<=four_stop;
                            else 
                                next_state<=three_down;
                        end
                    else    next_state<=next_state;
                end
        end
      Cstop:
         begin
            if(now_floor[2:0]==3'b000)       next_state<=one_stop;
            else if(now_floor[2:0]==3'b001)  next_state<=two_stop;
            else if(now_floor[2:0]==3'b010)  next_state<=three_stop;
            else if(now_floor[2:0]==3'b011)  next_state<=four_stop;            
         end 
    endcase  
    end    
  end

always@(posedge clk or posedge clr) //输出控制
    begin
    if(clr)
        begin
            now_floor[2:0]<=3'b000;
            elevator[1:0]<=stop;
            door<=1'b0;
            Cstate[3:0]<=one_stop;
        end
    else if(clr!=1)
        begin  
        case(present_state) //当前电梯所在的楼层、电梯运行状态、电梯门开关状态
            one_stop:
                begin
                    now_floor[2:0]<=3'b000;
                    elevator[1:0]<=stop;
                    door<=1;
                end
            one_up:    
                begin
                    elevator[1:0]<=up;
                    door<=0;
                    if(in_floor[0]==1)  now_floor[2:0]<=3'b000;
                    else                now_floor[2:0]<=3'b001;                    
                end
            two_stop:
                begin
                    now_floor[2:0]<=3'b001;
                    elevator[1:0]<=stop;
                    door<=1;
                end
            two_up:
                begin
                    elevator[1:0]<=up;
                    door<=0;
                    if(in_floor[1]==1)  now_floor[2:0]<=3'b001;
                    else                now_floor[2:0]<=3'b010;                    
                end            
            two_down:
                begin              
                    elevator[1:0]<=down;
                    door<=0;   
                    if(in_floor[1]==1)  now_floor[2:0]<=3'b001;
                    else                now_floor[2:0]<=3'b000;                                           
                end            
            three_stop:
                begin
                    now_floor[2:0]<=3'b010;
                    elevator[1:0]<=stop;
                    door<=1;                    
                end            
            three_up:
                begin                    
                    elevator[1:0]<=up;
                    door<=0;            
                    if(in_floor[2]==1)  now_floor[2:0]<=3'b010;
                    else                now_floor[2:0]<=3'b011;                            
                end            
            three_down:
                begin             
                    elevator[1:0]<=down;
                    door<=0;    
                    if(in_floor[2]==1)  now_floor[2:0]<=3'b010;
                    else                now_floor[2:0]<=3'b001;                                         
                end            
            four_stop:
                begin
                    now_floor[2:0]<=3'b011;
                    elevator[1:0]<=stop;
                    door<=1;                    
                end            
            four_down:
                begin                   
                    elevator[1:0]<=down;
                    door<=0; 
                    if(in_floor[3]==1)  now_floor[2:0]<=3'b011;
                    else                now_floor[2:0]<=3'b010;                                        
                end
            default:
                begin
                    now_floor[2:0]<=now_floor[2:0];
                    elevator[1:0]<=elevator[1:0];
                    door<=door;
                end      
        endcase
        
        case(next_state) //电梯控制器状态机的状态值
            one_stop:
                    Cstate[3:0]<=one_stop;
            one_up:    
                    Cstate[3:0]<=one_up;                
            two_stop:
                    Cstate[3:0]<=two_stop;               
            two_up:
                    Cstate[3:0]<=two_up;                
            two_down:
                    Cstate[3:0]<=two_down;                
            three_stop:
                    Cstate[3:0]<=three_stop;                
            three_up:
                    Cstate[3:0]<=three_up;                
            three_down:
                    Cstate[3:0]<=three_up;                
            four_stop:
                    Cstate[3:0]<=four_stop;                
            four_down:
                    Cstate[3:0]<=four_down;                
            Cstop:
                    Cstate[3:0]<=Cstop;                
            default:
                    Cstate[3:0]<=Cstate[3:0];                
        endcase        
        end
    else
    begin
            now_floor[2:0]<=now_floor[2:0];
            elevator[1:0]<=elevator[1:0];
            door<=door;
            Cstate[3:0]<=Cstate[3:0];         
    end    
    end

assign led[0]=(now_floor[2:0]==3'b000)?1:0;
assign led[1]=(now_floor[2:0]==3'b001)?1:0;
assign led[2]=(now_floor[2:0]==3'b010)?1:0;
assign led[3]=(now_floor[2:0]==3'b011)?1:0;

endmodule

 counter模块

module counter(
    input clk,
    input clr,
    output clk_1s,
    output clk_10s
    );
        reg [13:0]cnt_first,cnt_second;
        reg [3:0]cnt_third;
        reg [13:0]cnt_second_t;
        initial
        begin
             cnt_second=14'd5;
             cnt_second_t=14'd0;
        end
        
        always @(posedge clk or posedge clr)
            if(clr)
                cnt_first<=14'd0;
            else if(cnt_first==14'd10000)
                cnt_first<=14'd0;
            else
                cnt_first<=cnt_first +1'b1;
       always @(posedge clk or posedge clr)
        begin
            if(clr)
            begin
                  cnt_second<=14'd5;
                  cnt_second_t<=14'd0;
            end
            else if(cnt_second ==14'd10000)
                cnt_second<=14'd0;
            else if(cnt_second_t==14'd10000)
                cnt_second_t<=14'd0;
            else if(cnt_first==14'd10000)
            begin
                cnt_second<=cnt_second+1'b1;
                cnt_second_t<=cnt_second_t+1'b1;
            end
        end
        always @(posedge clk or posedge clr)
        begin
            if(clr)
                cnt_third<=4'd0;
            else if(cnt_third==4'd10)
                cnt_third<=4'd0;
            else if(cnt_second_t==14'd10000)
                cnt_third<=cnt_third+1'b1;  
        end 
        assign clk_1s=  (cnt_second==14'd10000)?1'b1 : 1'b0;    
        assign clk_10s= (cnt_third==4'd10)?1'b1 : 1'b0;
endmodule

 clkDiv模块

module clkDiv(
input clk100mhz,
output clk190hz
    );
    reg [25:0]count=0;
    assign clk190hz=count[18];
    always@(posedge clk100mhz)
     count<=count+1;
endmodule

 segMsgout模块

module segMsgout(
input clk190hz,
 input [15:0] dataBus, 
 output reg [3:0] pos,
 output reg [7:0] seg
 );
	reg [1:0] posC; 
	reg [3:0] dataP;
always @(posedge clk190hz )begin
case(posC)
	0: begin
	pos<=4'b1000;
    dataP<=dataBus[15:12];
	end
	1:begin
	pos <=4'b0100;
	dataP <= dataBus[11:8];
	end
	2:begin
	pos <=4'b0010;
	dataP <= dataBus[7:4];
	end
	3:begin
	pos <=4'b0001;
	dataP <= dataBus[3:0];
	end
	endcase
	posC = posC + 2'b01;
 end
 always @(dataP)
 case(dataP)
        4'b0000:seg=8'b0011_1111;
        4'b0001:seg=8'b0000_0110;
        4'b0010:seg=8'b0101_1011;
        4'b0011:seg=8'b0100_1111;
        4'b0100:seg=8'b0110_0110;
        4'b0101:seg=8'b0110_1101;
        4'b0110:seg=8'b0111_1101;
        4'b0111:seg=8'b0000_0111;
        4'b1000:seg=8'b0111_1111;
        4'b1001:seg=8'b0110_1111;
	    4'b1010:seg=8'b0111_0111;
	    4'b1011:seg=8'b0111_1100;
	    4'b1100:seg=8'b0011_1001;
	    
        default:seg=8'b0000_1000;
 endcase
endmodule

有些地方不够完善,仅供参考

由于未使用消抖开关的原因,烧录后板上按键响应有时会失效,不过小心使用,过验收应该没问题

此外,本作品未考虑按键同时按下的情况,可进行相应补充

  • 11
    点赞
  • 79
    收藏
    觉得还不错? 一键收藏
  • 15
    评论
以下是一个简单的四层电梯verilog代码实现: ```verilog module elevator( input clk, input reset, input [1:0] floor_req, input up, input down, output [1:0] current_floor ); reg [1:0] current_floor; reg [1:0] next_floor; reg [1:0] floor_mask; reg up_pressed; reg down_pressed; parameter idle = 2'b00; parameter moving_up = 2'b01; parameter moving_down = 2'b10; //设置当前楼层为1楼 initial current_floor = 2'b01; //设置电梯状态为 idle reg [1:0] state = idle; always @(posedge clk) begin if (reset) begin // 重置电梯状态为 idle state <= idle; floor_mask <= 2'b00; end else begin case (state) idle: begin if (floor_req != 2'b00) begin if (floor_req > current_floor) begin next_floor <= floor_req; state <= moving_up; end else if (floor_req < current_floor) begin next_floor <= floor_req; state <= moving_down; end end end moving_up: begin // 电梯上升 current_floor <= current_floor + 1; // 到达目标楼层 if (current_floor == next_floor) begin // 打开电梯门,并清除该楼层的请求 floor_mask <= floor_mask & ~(1 << (current_floor - 1)); // 如果还有请求,继续移动 if (floor_mask != 2'b00) begin next_floor <= $ffs(floor_mask) - 1; end else begin state <= idle; end end end moving_down: begin // 电梯下降 current_floor <= current_floor - 1; // 到达目标楼层 if (current_floor == next_floor) begin // 打开电梯门,并清除该楼层的请求 floor_mask <= floor_mask & ~(1 << (current_floor - 1)); // 如果还有请求,继续移动 if (floor_mask != 2'b00) begin next_floor <= $clog2(floor_mask) - 1; end else begin state <= idle; end end end endcase end end // 按下上行或下行按钮 always @(*) begin if (up) begin up_pressed = 1; end else if (down) begin down_pressed = 1; end else begin up_pressed = 0; down_pressed = 0; end end // 处理楼层请求 always @(*) begin if (up_pressed || down_pressed) begin // 设置请求位 floor_mask <= floor_mask | (1 << (floor_req - 1)); // 如果电梯处于空闲状态,则开始移动 if (state == idle) begin if (up_pressed) begin next_floor <= $ffs(floor_mask) - 1; state <= moving_up; end else if (down_pressed) begin next_floor <= $clog2(floor_mask) - 1; state <= moving_down; end end end end endmodule ``` 该代码实现了一个简单的四层电梯,包含了上行、下行、楼层请求、电梯状态等功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 15
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值