Vivado两层电梯简易设计

小白创作,请多指教。
设计要求:
1、实现 2 层楼的简易电梯控制系统。
2、电梯有 4 个按键。1 楼外只有向上按键(KEY0),2 楼外只有向下按键(KEY1),电梯内还
有 2 个按键分别为 1 楼按键(KEY2)和 2 楼按键(KEY3)。所有楼层外和电梯内的按键产生的信
号作为给电梯的运行请求信号。电梯在 1 楼时,只有 KEY1、KEY3 有效,在 2 楼时只有 KEY0、
KEY2 有效。电梯在上升过程中只有 KEY0、KEY2 有效,且到达 2 楼后会自动运行回到 1 楼。
在下降过程中只有 KEY1、KEY3 有效,且到达 1 楼后会自动运行回到 2 楼。
3、电梯有 4 个指示灯(LED0、LED1、LED2、LED3)。
LED0(P9): 按下 KEY0 键,若电梯不在 1 楼,则 LED0 亮。
LED1(R8): 按下 KEY1 键,若电梯不在 2 楼,则 LED1 亮。
LED2(R7): 电梯在 2 楼,按 KEY2 键, 则 LED2 亮,电梯到 1 楼后 LED2 灭。
LED3(T5): 电梯在 1 楼,按 KEY3 键, 则 LED3 亮,电梯到 2 楼后 LED3 灭。
4、有 2 个数码管,分别显示当前运行状态及楼层。
1)1 个数码管(H13)显示当前运行状态,电梯有三个运行状态:待机、上行、下行。待机:
电梯停在 1 楼或 2 楼且无请求信号时均为待机状态。
上行状态:电梯停在 1 楼,有 KEY1 或 KEY3 被按下,进入上行状态。
下行状态:电梯停在 2 楼,有 KEY0 或 KEY2 被按下,进入下行状态。
2)1 个数码管(G12)显示所在楼层,显示 1 或 2;每一层楼之间的运行时间间隔为 5 秒。
5、有 2 个拨码开关。
1)复位开关 SW11(F3),向下拨动后,电梯复位回到 1 楼。
2)启动开关 SW0(T9),向上拨动后,按键有效,电梯正常工作。
6、数码管 N14、N11 显示电梯运行剩余时间,精确到 0.1 秒。
7、电梯在 1 楼时,只有 KEY1、KEY3 有效,在 2 楼时只有 KEY0、KEY2 有效。电梯在上升
过程中只有 KEY0、KEY2 有效,且到达 2 楼后会自动运行回到 1 楼。在下降过程中只有 KEY1、
KEY3 有效,且到达 1 楼后会自动运行回到 2 楼。
8、电梯到达新楼层后蜂鸣器会发出“嘀”声。
设计方案:
Vivado代码:
约束文件:
约束文件
#ajxd
set_property PACKAGE_PIN K3 [get_ports {row[0]}]
set_property PACKAGE_PIN M6 [get_ports {row[1]}]
set_property PACKAGE_PIN P10 [get_ports {row[2]}]
set_property PACKAGE_PIN R10 [get_ports {row[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {row[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {row[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {row[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {row[3]}]
set_property PACKAGE_PIN R12 [get_ports {col[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {col[0]}]
set_property PACKAGE_PIN T12 [get_ports {col[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {col[1]}]
set_property PACKAGE_PIN R11 [get_ports {col[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {col[2]}]
set_property PACKAGE_PIN T10 [get_ports {col[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {col[3]}]
set_property PULLDOWN true [get_ports {col[3]}]
set_property PULLDOWN true [get_ports {col[2]}]
set_property PULLDOWN true [get_ports {col[1]}]
set_property PULLDOWN true [get_ports {col[0]}]
#dynamic_led2
set_property PACKAGE_PIN G12 [get_ports {dig[0]}]
set_property PACKAGE_PIN H13 [get_ports {dig[1]}]
set_property PACKAGE_PIN M12 [get_ports {dig[2]}]
set_property PACKAGE_PIN N13 [get_ports {dig[3]}]
set_property PACKAGE_PIN N14 [get_ports {dig[4]}]
set_property PACKAGE_PIN N11 [get_ports {dig[5]}]
set_property IOSTANDARD LVCMOS33 [get_ports {dig[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {dig[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {dig[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {dig[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {dig[4]}]
set_property IOSTANDARD LVCMOS33 [get_ports {dig[5]}]
set_property PACKAGE_PIN L13 [get_ports {seg[7]}]
set_property PACKAGE_PIN M14 [get_ports {seg[6]}]
set_property PACKAGE_PIN P13 [get_ports {seg[5]}]
set_property PACKAGE_PIN K12 [get_ports {seg[4]}]
set_property PACKAGE_PIN K13 [get_ports {seg[3]}]
set_property PACKAGE_PIN L14 [get_ports {seg[2]}]
set_property PACKAGE_PIN N12 [get_ports {seg[1]}]
set_property PACKAGE_PIN P11 [get_ports {seg[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {seg[7]}]
set_property IOSTANDARD LVCMOS33 [get_ports {seg[6]}]
set_property IOSTANDARD LVCMOS33 [get_ports {seg[5]}]
set_property IOSTANDARD LVCMOS33 [get_ports {seg[4]}]
set_property IOSTANDARD LVCMOS33 [get_ports {seg[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {seg[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {seg[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {seg[0]}]
#led
set_property PACKAGE_PIN P9 [get_ports {led[0]}]
set_property PACKAGE_PIN R8 [get_ports {led[1]}]
set_property PACKAGE_PIN R7 [get_ports {led[2]}]
set_property PACKAGE_PIN T5 [get_ports {led[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {led[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {led[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {led[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {led[3]}]
set_property PACKAGE_PIN D4 [get_ports clk]
#SW
set_property PACKAGE_PIN F3 [get_ports reset]
set_property PACKAGE_PIN T9 [get_ports start]
set_property IOSTANDARD LVCMOS33 [get_ports clk]
set_property IOSTANDARD LVCMOS33 [get_ports reset]
set_property IOSTANDARD LVCMOS33 [get_ports start]
#蜂鸣器
set_property PACKAGE_PIN L2 [get_ports buzzer_out]
set_property IOSTANDARD LVCMOS33 [get_ports buzzer_out]

1.顶层模块lift.v
`timescale 1ns / 1ps

module lift(
    input clk,         //50M时钟
    input [3:0] col,   //按键消抖后的信号
    input reset,       //复位
    input start,       //启动
    output [3:0] row,  //矩阵键盘行线
    output [7:0] seg,  //数码管显示
    output [5:0] dig,  //数码管使能
    output [3:0] led,  //LED灯
    output buzzer_out  //蜂鸣器标志信号
    );
wire [3:0] btn_out,r0,r4,r5;
wire [1:0] r1;
wire btn_clk,buzzer;
//分频,50Hz
clk_div l1(.clk(clk),
           .btn_clk(btn_clk));
//按键消抖
ajxd l2(.col(col),
        .row(row),
        .btn_clk(btn_clk),
        .btn_out(btn_out));
//数码管显示
dynamic_led l3(.r0(r0),
                .r1(r1),
                .r4(r4),
                .r5(r5),
                .clk(clk),
                .seg(seg),
                .dig(dig));
//蜂鸣器
buzzer l4(.clk(clk),
          .buzzer(buzzer),
          .buzzer_out(buzzer_out));
//电梯控制
lift_ctrl l5(.clk(clk),
             .key_in(btn_out),
             .reset(reset),
             .start(start),
             .r1(r1),
             .r0(r0),
             .r4(r4),
             .r5(r5),
             .led(led),
             .buzzer(buzzer)
             );
endmodule

2.电梯控制模块lift_ctrl.v

`timescale 1ns / 1ps

module lift_ctrl(
    input clk,
    input [3:0] key_in,
    input reset,
    input start,
    output [1:0] r1,
    output [3:0] r0,
    output [3:0] r4,
    output [3:0] r5,  //数码管显示
    output [3:0] led,
    output buzzer
    );
//定义寄存器
reg f=0,i=0,flag=0,buzzer_reg=0,rst_reg=1;
reg key_flag=1;  //按键允许标志
reg nd_2=0;  //是否按下第二次标志
reg buzzer_flag=0;  //蜂鸣器发声标志
reg [1:0] k=0,state=0;
reg [3:0] key=0,key1=0,key2=0,led_o=0,floor=1;
reg [5:0] show_time=0;
reg [30:0] count=0;
assign led=led_o;
assign r0=floor;
assign r1=state;
assign r4=show_time%10;//将show_time分为
assign r5=(show_time-(show_time%10))/10;//十位和个位
assign buzzer=buzzer_reg;

always@(posedge clk)  
begin
  //检测复位信号,转化为单周期脉冲
  if((f==0)&&(reset==0))
  begin
    rst_reg<=reset;
    f<=1;
  end
  else if((f==1)&&(rst_reg==0))
  begin
    rst_reg<=1;
  end
  else if((f==1)&&(rst_reg==1)&&(reset==1))
  begin
    f<=0;
  end
  //检测按键信号,转化为单周期脉冲
  if((start==1)&&(i==0)&&(key_in!=4'b0000))
  begin
    key<=key_in;
    i<=1;
  end
  else if((i==1)&&(key!=4'b0000))
  begin
    key<=4'b0000;
  end
  else if((i==1)&&(key==4'b0000)&&(key_in==4'b0000))
  begin
    i<=0;
  end
  //检测按键、复位脉冲,控制输出
  if((rst_reg==0)&&(floor==2)&&(state==0))
  begin
    state<=2;
    flag<=1;
    key_flag<=0;  //复位期间按键无效
  end
  else if((key!=0)&&(rst_reg==1)&&(key_flag==1))
  begin
    if(key[0])//检测KEY0
    begin
      if((key1==4'b0000)&&(floor==2))
      begin
        flag<=1;
        led_o[0]<=1;
        key1[0]<=1;
        state<=2;
      end
      else if((key1[1]==1)||(key1[3]==1))
      begin
        led_o[0]<=1;
        key2[0]<=1;
        key_flag<=0;
      end
    end
    else if(key[1])//检测KEY1
    begin
      if((key1==4'b0000)&&(floor==1))
      begin
        flag<=1;
        led_o[1]<=1;
        key1[1]<=1;
        state<=1;
      end
      else if((key1[0]==1)||(key1[2]==1))
      begin
        led_o[1]<=1;
        key2[1]<=1;
        key_flag<=0;
      end
    end
    else if(key[2])检测KEY2
    begin
      if((key1==4'b0000)&&(floor==2))
      begin
        flag<=1;
        led_o[2]<=1;
        key1[2]<=1;
        state<=2;
      end
      else if((key1[1]==1)||(key1[3]==1))
      begin
        led_o[2]<=1;
        key2[2]<=1;
        key_flag<=0;
      end
    end
    else if(key[3])//检测KEY3
    begin
      if((key1==4'b0000)&&(floor==1))
      begin
        flag<=1;
        led_o[3]<=1;
        key1[3]<=1;
        state<=1;
      end
      else if((key1[0]==1)||(key1[2]==1))
      begin
        led_o[3]<=1;
        key2[3]<=1;
        key_flag<=0;
      end
    end
  end
  else无按键按下
  begin
    if(count==1)
    begin
      show_time<=50;
      count<=count+1;
    end
    else if((count>0)&&(count<250000000)&&(count%5000000==0))
    begin
      show_time<=50-count/5000000;
      count<=count+1;
    end
    else if((count>250000000)&&(count<500000000)&&(count%5000000==0))
    begin
      count<=count+1;
      show_time<=100-count/5000000;
    end
    else if(count==30'd250000000)
    begin
      buzzer_reg<=1;
      show_time<=0;  //显示回零,蜂鸣器"嘀"
      k[0]<=1;
      count<=count+1;
    end
    else if(count==30'd250000002)
    begin
      k[0]<=0;
      count<=count+1;
    end
    else if(count==30'd500000000)
    begin
      k[1]<=1;
      buzzer_reg<=1;
      show_time<=0;  //显示回零,蜂鸣器"嘀"
      count<=count+1;
    end
    else if(k[0]==1)/检测5s
    begin
      count<=count+1;
      buzzer_reg<=0;
      if(floor==1)  floor<=2;
      else if(floor==2)  floor<=1;
      if(led_o==4'b0000)  //复位完成
      begin
        state<=0;
        k[0]<=0;
        flag<=0;
        count<=0;
        key_flag<=1;
      end
      else if((led_o==4'b0001)||(led_o==4'b0010)||(led_o==4'b0100)||(led_o==4'b1000))  
      //没有按第二次,将灯熄灭
      begin
        key1<=4'b0000;
        key2<=4'b0000;
        led_o<=4'b0000;
        state<=0;
        k[0]<=0;
        flag<=0;
        count<=0;
        key_flag<=1;
      end
      else  //按了第二次,将第一次按的灯熄灭
      begin
        count<=count+1;
        nd_2<=1;  //按了第二次
        if(state==1)  state<=2;
        else if(state==2)  state<=1;  //运行状态反转
        case(key1)
        4'b0001:led_o[0]<=0;
        4'b0010:led_o[1]<=0;
        4'b0100:led_o[2]<=0;
        4'b1000:led_o[3]<=0;
        default:led_o<=4'b0000;
        endcase
      end
    end
    else if(k[1]==1)/检测10s
    begin
      if(floor==1)  floor<=2;
      else if(floor==2)  floor<=1;
      key1<=4'b0000;
      key2<=4'b0000;
      led_o<=4'b0000;
      state<=0;
      k[1]<=0;
      key_flag<=1;
      flag<=0;
      count<=0;
      buzzer_reg<=0;
    end 
    else计数
    begin
      if(flag==1)  count<=count+1;  
    end
  end
end
endmodule

3.分频模块clk_div.v

`timescale 1ns / 1ps

module clk_div( clk,btn_clk);
input clk;
output  btn_clk;// 20ms两个输出
reg[31:0] btn_clk_cnt = 0;//对50M时钟1M分频的计数器
reg btn_clk = 0;//50Hz信号,周期20ms,初值为0 
always@(posedge clk) //系统时钟上升沿时,20ms,50Hz,50M/50=1000000 ,1M分频
begin
    if(btn_clk_cnt==499999)
    begin
        btn_clk =~ btn_clk;
        btn_clk_cnt = 0;
    end
    else
        btn_clk_cnt = btn_clk_cnt+1'b1;
end
endmodule

4.按键消抖模块ajxd.v

`timescale 1ns / 1ps
//按键消抖模块
module ajxd(
    input [3:0] col,
    output [3:0] row,
    input btn_clk,
    output [3:0] btn_out);
reg [2:0] btn0,btn1,btn2,btn3;
assign row=4'b0001;
assign btn_out[0]=(btn0[2]&btn0[1]&btn0[0])|(~btn0[2]&btn0[1]&btn0[0]);
assign btn_out[1]=(btn1[2]&btn1[1]&btn1[0])|(~btn1[2]&btn1[1]&btn1[0]);
assign btn_out[2]=(btn2[2]&btn2[1]&btn2[0])|(~btn2[2]&btn2[1]&btn2[0]);
assign btn_out[3]=(btn3[2]&btn3[1]&btn3[0])|(~btn3[2]&btn3[1]&btn3[0]);
always@ (posedge btn_clk)
begin
    //KEY0
    btn0[0]<=col[0];
    btn0[1]<=btn0[0];
    btn0[2]<=btn0[1];
    //KEY1
    btn1[0]<=col[1];
    btn1[1]<=btn1[0];
    btn1[2]<=btn1[1];
    //KEY2
    btn2[0]<=col[2];
    btn2[1]<=btn2[0];
    btn2[2]<=btn2[1];
    //KEY3
    btn3[0]<=col[3];
    btn3[1]<=btn3[0];
    btn3[2]<=btn3[1];
end
endmodule

5.数码管显示模块dynamic_led.v

`timescale 1ns / 1ps

module dynamic_led(
    input [3:0] r0,
    input [1:0] r1,
    input [3:0] r4,
    input [3:0] r5,
    input clk,
    output reg [7:0] seg,
    output reg [5:0] dig);
//分频
reg[24:0] clk_div_cnt=0;
reg clk_div=0;
always @ (posedge clk)
begin
    if (clk_div_cnt==25000)
	begin
		clk_div=~clk_div;
		clk_div_cnt=0;
	end
	else 
        clk_div_cnt=clk_div_cnt+1;
end
//6进制计数器
reg [2:0] num=0;
always @ (posedge clk_div)
begin
	if (num>=5)
		num=0;
	else
		num=num+1;
end
//译码器
always @ (num)
begin	
	case(num)
	    0:dig=6'b111110;
	    1:dig=6'b111101;
	    2:dig=6'b111011;
        3:dig=6'b110111;
        4:dig=6'b101111;
        5:dig=6'b011111;
        default: dig=6'b111111;
	endcase
end
	
//选择器,确定显示数据
always @ (num)
begin	
    if(num==0)
    begin
        case(r0)
            4'h0: seg=8'h3f;// DP,GFEDCBA
            4'h1: seg=8'h06;
            4'h2: seg=8'h5b;
            4'h3: seg=8'h4f;
            4'h4: seg=8'h66;
            4'h5: seg=8'h6d;
            4'h6: seg=8'h7d;
            4'h7: seg=8'h07;
            4'h8: seg=8'h7f;
            4'h9: seg=8'h6f;
            4'ha: seg=8'h77;
            4'hb: seg=8'h7c;
            4'hc: seg=8'h39;
            4'hd: seg=8'h5e;
            4'he: seg=8'h79;
            4'hf: seg=8'h71;
            default: seg=0;
        endcase
    end
    else if(num==1)
	begin
	    case(r1)
            2'b00: seg=8'h40;
            2'b01: seg=8'h01;
            2'b10: seg=8'h08;
            2'b11: seg=8'h00;
            default:seg=0;
        endcase
    end
    else if(num==4)
    begin
	    case(r4)
            4'h0: seg=8'h3f;// DP,GFEDCBA
            4'h1: seg=8'h06;
            4'h2: seg=8'h5b;
            4'h3: seg=8'h4f;
            4'h4: seg=8'h66;
            4'h5: seg=8'h6d;
            4'h6: seg=8'h7d;
            4'h7: seg=8'h07;
            4'h8: seg=8'h7f;
            4'h9: seg=8'h6f;
            4'ha: seg=8'h77;
            4'hb: seg=8'h7c;
            4'hc: seg=8'h39;
            4'hd: seg=8'h5e;
            4'he: seg=8'h79;
            4'hf: seg=8'h71;
            default: seg=0;
        endcase
	end
    else if(num==5)
	begin
	    case(r5)
            4'h0: seg=8'hbf;// DP,GFEDCBA,显示小数点
            4'h1: seg=8'h86;
            4'h2: seg=8'hdb;
            4'h3: seg=8'hcf;
            4'h4: seg=8'he6;
            4'h5: seg=8'h6d;
            4'h6: seg=8'hfd;
            4'h7: seg=8'h87;
            4'h8: seg=8'hff;
            4'h9: seg=8'hef;
            4'ha: seg=8'hf7;
            4'hb: seg=8'hfc;
            4'hc: seg=8'hb9;
            4'hd: seg=8'hce;
            4'he: seg=8'hf9;
            4'hf: seg=8'hf1;
            default: seg=0;
        endcase
	end
    else
	    seg=8'h00;
end
endmodule

6.蜂鸣器模块buzzer.v

`timescale 1ns / 1ps

module buzzer(
    input clk,
    input buzzer,
    output buzzer_out
    );
reg buzzer_clk=0,buzzer_out_flag;
reg [30:0] buzzer_clk_cnt=0;
reg [30:0] buzzer_out_cnt=0;
assign buzzer_out=buzzer_out_flag&&buzzer_clk;
always@(posedge clk) //系统时钟上升沿时 
     begin  
       //5kHz,50M/5000=10000 ,1M分频
       if(buzzer_clk_cnt==4999)
       begin
         buzzer_clk =~ buzzer_clk;
         buzzer_clk_cnt = 0;
       end
       else
       begin
         buzzer_clk_cnt = buzzer_clk_cnt+1'b1;
       end
       //当buzzer脉冲到来时,将buzzer_out_flag置高0.5秒,即蜂鸣器"嘀"0.5秒
       if(buzzer==1)
       begin
         buzzer_out_flag<=1;
       end
       else if((buzzer==0)&&(buzzer_out_cnt>=25000000))
       begin
         buzzer_out_flag<=0;
       end
       if(buzzer_out_flag==1)
       begin
         buzzer_out_cnt<=buzzer_out_cnt+1;
       end
       else
       begin
         buzzer_out_cnt<=0;
       end
       end
  endmodule

RTL分析:

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值