Verilog HDL设计——电梯控制器模块

设计一个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变成中间变量,表示电梯需要停下并开关门的楼层。整个系统功能完善了许多,也更具备实用性。

  • 14
    点赞
  • 134
    收藏
    觉得还不错? 一键收藏
  • 12
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值