我是靠谱客的博主 凶狠天空,最近开发中收集的这篇文章主要介绍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

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

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

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

最后

以上就是凶狠天空为你收集整理的Verilog 四层电梯设计的全部内容,希望文章能够帮你解决Verilog 四层电梯设计所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(48)

评论列表共有 0 条评论

立即
投稿
返回
顶部