├── README.md ├── constrs └── 1.xdc ├── sim ├── control_tb.v ├── counter_tb.v ├── keyinput_tb.v ├── request_tb.v └── top_tb.v ├── src ├── clkDiv.v ├── control.v ├── counter.v ├── global.vh ├── key_input.v ├── keyled.v ├── num_segMsg.v ├── request.v ├── signal_segMsg.v └── top.v └── 电梯.pptx /README.md: -------------------------------------------------------------------------------- 1 | # verilog_elevator2020 2 | 3 | ## 介绍 4 | 这是一个电梯。 -------------------------------------------------------------------------------- /constrs/1.xdc: -------------------------------------------------------------------------------- 1 | set_property IOSTANDARD LVCMOS33 [get_ports {external[7]}] 2 | set_property IOSTANDARD LVCMOS33 [get_ports {external[6]}] 3 | set_property IOSTANDARD LVCMOS33 [get_ports {external[5]}] 4 | set_property IOSTANDARD LVCMOS33 [get_ports {external[4]}] 5 | set_property IOSTANDARD LVCMOS33 [get_ports {external[3]}] 6 | set_property IOSTANDARD LVCMOS33 [get_ports {external[2]}] 7 | set_property IOSTANDARD LVCMOS33 [get_ports {external[1]}] 8 | set_property IOSTANDARD LVCMOS33 [get_ports {external[0]}] 9 | set_property IOSTANDARD LVCMOS33 [get_ports {internal[3]}] 10 | set_property IOSTANDARD LVCMOS33 [get_ports {internal[2]}] 11 | set_property IOSTANDARD LVCMOS33 [get_ports {internal[1]}] 12 | set_property IOSTANDARD LVCMOS33 [get_ports {internal[0]}] 13 | set_property IOSTANDARD LVCMOS33 [get_ports {LED[7]}] 14 | set_property IOSTANDARD LVCMOS33 [get_ports {LED[6]}] 15 | set_property IOSTANDARD LVCMOS33 [get_ports {LED[5]}] 16 | set_property IOSTANDARD LVCMOS33 [get_ports {LED[4]}] 17 | set_property IOSTANDARD LVCMOS33 [get_ports {LED[3]}] 18 | set_property IOSTANDARD LVCMOS33 [get_ports {LED[2]}] 19 | set_property IOSTANDARD LVCMOS33 [get_ports {LED[1]}] 20 | set_property IOSTANDARD LVCMOS33 [get_ports {LED[0]}] 21 | set_property IOSTANDARD LVCMOS33 [get_ports {posH[3]}] 22 | set_property IOSTANDARD LVCMOS33 [get_ports {posH[2]}] 23 | set_property IOSTANDARD LVCMOS33 [get_ports {posH[1]}] 24 | set_property IOSTANDARD LVCMOS33 [get_ports {posH[0]}] 25 | set_property IOSTANDARD LVCMOS33 [get_ports {posL[3]}] 26 | set_property IOSTANDARD LVCMOS33 [get_ports {posL[2]}] 27 | set_property IOSTANDARD LVCMOS33 [get_ports {posL[1]}] 28 | set_property IOSTANDARD LVCMOS33 [get_ports {posL[0]}] 29 | set_property IOSTANDARD LVCMOS33 [get_ports {segH[7]}] 30 | set_property IOSTANDARD LVCMOS33 [get_ports {segH[6]}] 31 | set_property IOSTANDARD LVCMOS33 [get_ports {segH[5]}] 32 | set_property IOSTANDARD LVCMOS33 [get_ports {segH[4]}] 33 | set_property IOSTANDARD LVCMOS33 [get_ports {segH[3]}] 34 | set_property IOSTANDARD LVCMOS33 [get_ports {segH[2]}] 35 | set_property IOSTANDARD LVCMOS33 [get_ports {segH[1]}] 36 | set_property IOSTANDARD LVCMOS33 [get_ports {segH[0]}] 37 | set_property IOSTANDARD LVCMOS33 [get_ports {segL[7]}] 38 | set_property IOSTANDARD LVCMOS33 [get_ports {segL[6]}] 39 | set_property IOSTANDARD LVCMOS33 [get_ports {segL[5]}] 40 | set_property IOSTANDARD LVCMOS33 [get_ports {segL[4]}] 41 | set_property IOSTANDARD LVCMOS33 [get_ports {segL[3]}] 42 | set_property IOSTANDARD LVCMOS33 [get_ports {segL[2]}] 43 | set_property IOSTANDARD LVCMOS33 [get_ports {segL[1]}] 44 | set_property IOSTANDARD LVCMOS33 [get_ports {segL[0]}] 45 | set_property IOSTANDARD LVCMOS33 [get_ports clk100mhz] 46 | set_property PACKAGE_PIN P17 [get_ports clk100mhz] 47 | set_property PACKAGE_PIN R11 [get_ports {internal[3]}] 48 | set_property PACKAGE_PIN R15 [get_ports {internal[2]}] 49 | set_property PACKAGE_PIN V1 [get_ports {internal[1]}] 50 | set_property PACKAGE_PIN U4 [get_ports {internal[0]}] 51 | set_property PACKAGE_PIN P5 [get_ports {external[7]}] 52 | set_property PACKAGE_PIN P3 [get_ports {external[6]}] 53 | set_property PACKAGE_PIN R2 [get_ports {external[5]}] 54 | set_property PACKAGE_PIN N4 [get_ports {external[4]}] 55 | set_property PACKAGE_PIN P4 [get_ports {external[3]}] 56 | set_property PACKAGE_PIN P2 [get_ports {external[2]}] 57 | set_property PACKAGE_PIN R1 [get_ports {external[0]}] 58 | set_property PACKAGE_PIN F6 [get_ports {LED[7]}] 59 | set_property PACKAGE_PIN G3 [get_ports {LED[6]}] 60 | set_property PACKAGE_PIN H4 [get_ports {LED[5]}] 61 | set_property PACKAGE_PIN J2 [get_ports {LED[4]}] 62 | set_property PACKAGE_PIN G4 [get_ports {LED[3]}] 63 | set_property PACKAGE_PIN J4 [get_ports {LED[2]}] 64 | set_property PACKAGE_PIN J3 [get_ports {LED[1]}] 65 | set_property PACKAGE_PIN K2 [get_ports {LED[0]}] 66 | set_property PACKAGE_PIN G2 [get_ports {posH[3]}] 67 | set_property PACKAGE_PIN C2 [get_ports {posH[2]}] 68 | set_property PACKAGE_PIN C1 [get_ports {posH[1]}] 69 | set_property PACKAGE_PIN H1 [get_ports {posH[0]}] 70 | set_property PACKAGE_PIN G1 [get_ports {posL[3]}] 71 | set_property PACKAGE_PIN F1 [get_ports {posL[2]}] 72 | set_property PACKAGE_PIN E1 [get_ports {posL[1]}] 73 | set_property PACKAGE_PIN G6 [get_ports {posL[0]}] 74 | set_property PACKAGE_PIN D5 [get_ports {segH[7]}] 75 | set_property PACKAGE_PIN B2 [get_ports {segH[6]}] 76 | set_property PACKAGE_PIN B3 [get_ports {segH[5]}] 77 | set_property PACKAGE_PIN A1 [get_ports {segH[4]}] 78 | set_property PACKAGE_PIN B1 [get_ports {segH[3]}] 79 | set_property PACKAGE_PIN A3 [get_ports {segH[2]}] 80 | set_property PACKAGE_PIN A4 [get_ports {segH[1]}] 81 | set_property PACKAGE_PIN B4 [get_ports {segH[0]}] 82 | set_property PACKAGE_PIN H2 [get_ports {segL[7]}] 83 | set_property PACKAGE_PIN D2 [get_ports {segL[6]}] 84 | set_property PACKAGE_PIN E2 [get_ports {segL[5]}] 85 | set_property PACKAGE_PIN F3 [get_ports {segL[4]}] 86 | set_property PACKAGE_PIN F4 [get_ports {segL[3]}] 87 | set_property PACKAGE_PIN D3 [get_ports {segL[2]}] 88 | set_property PACKAGE_PIN E3 [get_ports {segL[1]}] 89 | set_property PACKAGE_PIN D4 [get_ports {segL[0]}] 90 | 91 | set_property IOSTANDARD LVCMOS33 [get_ports rst_in] 92 | set_property PACKAGE_PIN R17 [get_ports rst_in] 93 | set_property PACKAGE_PIN M4 [get_ports {external[1]}] 94 | -------------------------------------------------------------------------------- /sim/control_tb.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | 3 | module tb_control; 4 | 5 | // control Parameters 6 | parameter PERIOD = 10; 7 | parameter INIT = 0; 8 | 9 | // control Inputs 10 | reg clk10hz = 0 ; 11 | reg clk1hz = 0 ; 12 | reg rst = 1 ; 13 | reg [2:0] req = 0 ; 14 | 15 | // control Outputs 16 | wire [7:0] curr_floor ; 17 | wire [3:0] running_state ; 18 | wire [3:0] door_state ; 19 | wire [3:0] state ; 20 | 21 | always #(PERIOD/2) clk10hz = ~clk10hz; 22 | always #(5*PERIOD) clk1hz = ~clk1hz; 23 | 24 | control u_control ( 25 | .clk10hz ( clk10hz ), 26 | .clk1hz ( clk1hz ), 27 | .rst ( rst ), 28 | .req ( req [2:0] ), 29 | 30 | .curr_floor ( curr_floor [7:0] ), 31 | .running_state ( running_state [3:0] ), 32 | .door_state ( door_state [3:0] ), 33 | .state ( state [3:0] ) 34 | ); 35 | 36 | initial 37 | begin 38 | #PERIOD rst = 0; 39 | req = 3'b100; 40 | #(5*PERIOD) req = 3'b001; 41 | #(10*PERIOD) req = 3'b000;end 42 | 43 | endmodule -------------------------------------------------------------------------------- /sim/counter_tb.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | 3 | module tb_counter; 4 | 5 | // counter Parameters 6 | parameter PERIOD = 10; 7 | 8 | 9 | // counter Inputs 10 | reg clk = 0 ; 11 | reg start = 0 ; 12 | reg st = 0; 13 | reg [7:0] m_time = 8'd10 ; 14 | reg [7:0] fuck = 0; 15 | 16 | // counter Outputs 17 | wire done ; 18 | 19 | 20 | always #(PERIOD/2) clk = ~clk; 21 | 22 | counter u_counter ( 23 | .clk ( clk ), 24 | .start ( start ), 25 | .m_time ( m_time [7:0] ), 26 | 27 | .done ( done ) 28 | ); 29 | 30 | initial 31 | begin 32 | #PERIOD st = 1; 33 | #(20*PERIOD) st = 1; 34 | end 35 | 36 | always @(posedge clk) begin 37 | if(st == 1) start = 1; 38 | else begin 39 | start = 0; 40 | st = 0; 41 | end 42 | end 43 | 44 | always @(*) begin 45 | if(done == 1) begin 46 | fuck = fuck + 1; 47 | start = 0; 48 | end 49 | else begin 50 | start = 1; 51 | end 52 | end 53 | 54 | endmodule -------------------------------------------------------------------------------- /sim/keyinput_tb.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | 3 | module tb_key_input; 4 | 5 | // key_input Parameters 6 | parameter PERIOD = 10, W = 4; 7 | 8 | 9 | // key_input Inputs 10 | reg clk = 0 ; 11 | reg [W - 1:0] keys = 0 ; 12 | 13 | // key_input Outputs 14 | wire [W - 1: 0] key_press ; 15 | 16 | 17 | initial 18 | begin 19 | forever #(PERIOD/2) clk=~clk; 20 | end 21 | 22 | key_input #(W) u_key_input ( 23 | .clk ( clk ), 24 | .keys ( keys [W - 1:0] ), 25 | 26 | .key_press ( key_press [W - 1: 0] ) 27 | ); 28 | 29 | initial 30 | begin 31 | #PERIOD keys = 4'b0010; 32 | #(5*PERIOD) keys = 4'b0000; 33 | end 34 | 35 | endmodule -------------------------------------------------------------------------------- /sim/request_tb.v: -------------------------------------------------------------------------------- 1 | `define F_N 4 2 | `timescale 1ns / 1ps 3 | 4 | module tb_request; 5 | 6 | // request Parameters 7 | parameter PERIOD = 10; 8 | 9 | 10 | // request Inputs 11 | reg clk380hz = 0 ; 12 | reg clk10hz = 0 ; 13 | reg rst = 0 ; 14 | reg [7:0] curr_floor = 0 ; 15 | reg [3:0] running_state = 0 ; 16 | reg [3:0] door_state = 4'b0100 ; 17 | reg [`F_N-1:0] floor_in = 0 ; 18 | reg [`F_N-1:0] up_in = 0 ; 19 | reg [`F_N-1:0] down_in = 0 ; 20 | 21 | // request Outputs 22 | wire [2:0] req ; 23 | wire [7:0] demand_state ; 24 | 25 | always #(PERIOD/2) clk380hz=~clk380hz; 26 | always #(5*PERIOD) clk10hz=~clk10hz; 27 | 28 | // initial 29 | // begin 30 | // #(PERIOD*2) rst = 1; 31 | // end 32 | 33 | request u_request ( 34 | .clk380hz ( clk380hz ), 35 | .clk10hz ( clk10hz ), 36 | .clk1hz ( clk1hz ), 37 | .rst ( rst ), 38 | .curr_floor ( curr_floor [7:0] ), 39 | .running_state ( running_state [3:0] ), 40 | .door_state ( door_state [3:0] ), 41 | .floor_in ( floor_in [`F_N-1:0] ), 42 | .up_in ( up_in [`F_N-1:0] ), 43 | .down_in ( down_in [`F_N-1:0] ), 44 | 45 | .req ( req [2:0] ), 46 | .demand_state ( demand_state [7:0] ) 47 | ); 48 | 49 | initial 50 | begin 51 | #1000 up_in[2] = 1; 52 | #1000 down_in[1] = 1; 53 | end 54 | 55 | endmodule -------------------------------------------------------------------------------- /sim/top_tb.v: -------------------------------------------------------------------------------- 1 | `define F_N 4 2 | `timescale 1ns / 100ps 3 | 4 | module tb_top; 5 | 6 | // top Parameters 7 | parameter PERIOD = 10; 8 | 9 | 10 | // top Inputs 11 | reg clk380hz = 0 ; 12 | reg clk10hz = 0 ; 13 | reg clk1hz = 0 ; 14 | reg rst = 1 ; 15 | reg [2*`F_N - 1:0] external = 0 ; 16 | reg [ `F_N - 1:0] internal = 0 ; 17 | 18 | 19 | always #(PERIOD/2) clk380hz = ~clk380hz; 20 | always #(5*PERIOD) clk10hz = ~clk10hz; 21 | always #(10*PERIOD) clk1hz = ~clk1hz; 22 | 23 | wire [7:0] curr_floor; 24 | wire [3:0] running_state; 25 | wire [3:0] door_state; 26 | wire [2:0] req; 27 | wire [2*`F_N-1:0] demand_state; 28 | wire [3:0] state_dataBus; 29 | wire [15:0] number_dataBus; 30 | wire [15:0] signal_dataBus; 31 | wire posL, segL; 32 | wire posH, segH; 33 | 34 | request Request( 35 | .clk380hz(clk380hz), .clk10hz(clk10hz), .clk1hz(clk1hz), 36 | .rst(rst), 37 | .curr_floor(curr_floor), 38 | .running_state(running_state), 39 | .door_state(door_state), 40 | .floor_in(internal), 41 | .up_in(external[2*`F_N-1:`F_N]), 42 | .down_in(external[`F_N-1:0]), 43 | .req(req), 44 | .demand_state(demand_state) 45 | ); 46 | 47 | control Control( 48 | .clk380hz(clk380hz), .clk10hz(clk10hz), .clk1hz(clk1hz), 49 | .rst(rst), 50 | .req(req), 51 | .curr_floor(curr_floor), 52 | .running_state(running_state), 53 | .door_state(door_state), 54 | .state(state_dataBus) 55 | ); 56 | 57 | num_segMsg numbers(clk380hz, number_dataBus, posL, segL); 58 | signal_segMsg signals(clk380hz, signal_dataBus, posH, segH); 59 | 60 | assign number_dataBus = {state_dataBus[3:0], curr_floor[3:0]+1, 8'hff}; 61 | assign signal_dataBus = {running_state[3:0], door_state[3:0], 8'b0}; 62 | 63 | initial 64 | begin 65 | #PERIOD rst = 0; 66 | #(5*PERIOD) external[6] = 1; 67 | #(5*PERIOD) external[5] = 1; 68 | end 69 | 70 | endmodule -------------------------------------------------------------------------------- /src/clkDiv.v: -------------------------------------------------------------------------------- 1 | module clkDiv ( 2 | input clk100mhz, 3 | output clk380hz, 4 | output clk10hz, 5 | output reg clk1hz = 0 6 | ); 7 | reg [25:0] count = 0; 8 | reg [27:0] count_1hz = 0; 9 | 10 | assign clk380hz = count[17]; 11 | assign clk10hz = count[23]; 12 | 13 | always@(posedge clk100mhz) begin 14 | count <= count + 1; 15 | 16 | if(count_1hz == 50_000_000) begin 17 | clk1hz <= ~clk1hz; 18 | count_1hz <= 0; 19 | end 20 | else count_1hz <= count_1hz + 1; 21 | end 22 | endmodule -------------------------------------------------------------------------------- /src/control.v: -------------------------------------------------------------------------------- 1 | `include "./global.vh" 2 | module control ( 3 | input clk380hz, 4 | input clk10hz, 5 | input clk1hz, 6 | input rst, //高电平复位 7 | input [2:0] req, //请求 8 | output [7:0] curr_floor, //当前楼层 9 | output reg [3:0] running_state, //运行状态 10 | output reg [3:0] door_state, //门开关状态 11 | output [3:0] state //状态机状态 12 | ); 13 | 14 | //状态机参数 15 | parameter INIT = 4'd0, 16 | UP = 4'd1, //上行 17 | DOWN = 4'd2, //下行 18 | UP_OPEN = 4'd3, //上行开门 19 | UP_CLOSE = 4'd4, //上行关门 20 | DOWN_OPEN = 4'd5, //下行开门 21 | DOWN_CLOSE = 4'd6; //下行关门 22 | 23 | reg [3:0] curr = INIT, next; 24 | reg [7:0] curr_pos = 0; //当前楼层,从0开始计数 25 | assign curr_floor = curr_pos; //楼层显示 26 | assign state = curr; 27 | 28 | //指令 29 | wire go_up = req[2]; 30 | wire go_down = req[1]; 31 | wire open_door = req[0]; 32 | 33 | //计时器 34 | reg cd_start = 0; 35 | wire cd_done; 36 | reg ce_start = 0; 37 | wire ce_done; 38 | counter c_door(clk1hz, cd_start, `OPEN_TIME, cd_done); 39 | counter c_elev(clk1hz, ce_start, `MOVE_TIME, ce_done); 40 | 41 | //计时模块的输入驱动always块 42 | always @(posedge clk10hz or posedge rst) begin 43 | if(rst == 1) begin 44 | {ce_start, cd_start, curr_pos} <= 0; 45 | end 46 | else case (curr) 47 | UP: begin 48 | if(ce_done == 1) begin //如果计时完成 49 | curr_pos <= curr_pos == `F_N - 1 ? `F_N - 1 : curr_pos + 1'b1; //则向上移动一层 50 | ce_start <= 0; //且复位开始信号 51 | end 52 | else ce_start <= 1; //否则将开始计时信号置为1 53 | end 54 | DOWN: begin 55 | if(ce_done == 1) begin 56 | curr_pos <= curr_pos == 0 ? 0 : curr_pos - 1'b1; 57 | ce_start <= 0; 58 | end 59 | else ce_start <= 1; 60 | end 61 | UP_OPEN: begin 62 | cd_start <= ~cd_done; 63 | end 64 | DOWN_OPEN: begin 65 | cd_start <= ~cd_done; 66 | end 67 | default: begin 68 | ce_start <= 0; 69 | cd_start <= 0; 70 | end 71 | endcase 72 | end 73 | 74 | 75 | //状态转换的always #1 76 | always @(posedge clk10hz or posedge rst) begin 77 | curr <= rst == 1 ? INIT : next; 78 | end 79 | 80 | //状态转换的always #2 81 | always @(*) begin 82 | case (curr) 83 | INIT: begin 84 | next = req > 0 ? UP_CLOSE : INIT; 85 | end 86 | UP_OPEN: begin 87 | next = cd_done == 1 ? UP_CLOSE : UP_OPEN;//计时完成则关门 88 | end 89 | UP_CLOSE: begin 90 | if(open_door == 1) next = UP_OPEN; //每一层判断是否开门 91 | else if(go_up == 1) next = UP; //优先向上 92 | else if(go_down == 1) next = DOWN; //否则向下 93 | else next = UP_CLOSE; //再否则保持关门状态 94 | end 95 | UP: begin 96 | next = ce_done == 1 ? UP_CLOSE : UP; //计时完成则进行判断 97 | end 98 | DOWN_OPEN: begin 99 | next = cd_done == 1 ? DOWN_CLOSE : DOWN_OPEN; 100 | end 101 | DOWN_CLOSE: begin 102 | if(open_door == 1) next = DOWN_OPEN; 103 | else if(go_down == 1) next = DOWN; 104 | else if(go_up == 1) next = UP; 105 | else next = DOWN_CLOSE; 106 | end 107 | DOWN: begin 108 | next = ce_done == 1 ? DOWN_CLOSE : DOWN; 109 | end 110 | default: next = INIT; 111 | endcase 112 | end 113 | 114 | //状态转换的always #3 115 | always @(*) begin 116 | case(curr) 117 | INIT: 118 | {running_state, door_state} = 119 | {`RS_UP, `DS_CLOSE}; 120 | UP_OPEN: 121 | {running_state, door_state} = 122 | {`RS_UP, `DS_OPEN}; 123 | UP_CLOSE: 124 | {running_state, door_state} = 125 | {`RS_UP, `DS_CLOSE}; 126 | UP: 127 | {running_state, door_state} = 128 | {`RS_UP, `DS_CLOSE}; 129 | DOWN_OPEN: 130 | {running_state, door_state} = 131 | {`RS_DOWN, `DS_OPEN}; 132 | DOWN_CLOSE: 133 | {running_state, door_state} = 134 | {`RS_DOWN, `DS_CLOSE}; 135 | DOWN: 136 | {running_state, door_state} = 137 | {`RS_DOWN, `DS_CLOSE}; 138 | default: 139 | {running_state, door_state} = 140 | {`RS_UP, `DS_CLOSE}; 141 | endcase 142 | end 143 | 144 | endmodule -------------------------------------------------------------------------------- /src/counter.v: -------------------------------------------------------------------------------- 1 | module counter( 2 | input clk, 3 | input start, 4 | input [7:0] m_time, 5 | output done 6 | ); 7 | reg [7:0] count = 0; 8 | assign done = start && count >= m_time; 9 | 10 | always @(posedge clk) begin 11 | if(start == 0) begin 12 | count <= 0; 13 | end 14 | else count <= done ? count : count + 1; 15 | end 16 | 17 | endmodule 18 | -------------------------------------------------------------------------------- /src/global.vh: -------------------------------------------------------------------------------- 1 | `ifndef __GLOBAL_VH__ 2 | `define __GLOBAL_VH__ 0 3 | 4 | //常数 5 | //时间常数 6 | `define OPEN_TIME 8'd5 //开门持续时间 7 | `define MOVE_TIME 8'd1 //层间移动时间 8 | 9 | //元参数 10 | `define F_N 4 //楼层数量 11 | 12 | //状态码,留出部分位长用于拓展 13 | //运行状态 14 | `define RS_UP 4'b0000 15 | `define RS_DOWN 4'b0001 16 | `define RS_STOP 4'b0010 17 | 18 | //门开关状态 19 | `define DS_OPEN 4'b0011 20 | `define DS_CLOSE 4'b0100 21 | 22 | `define INVALID 4'b1111 23 | 24 | `endif -------------------------------------------------------------------------------- /src/key_input.v: -------------------------------------------------------------------------------- 1 | //当开关状态与之前不同时,相应位置输出一个时钟周期的高电平信号(用开关模拟按钮) 2 | module key_input #(parameter W = 8) ( 3 | input clk, 4 | input [W - 1:0] keys, 5 | output reg [W - 1: 0] key_press = 0 6 | ); 7 | 8 | reg [W - 1: 0] prev = 0; 9 | 10 | always @(posedge clk) begin 11 | key_press <= prev ^ keys; 12 | prev <= keys; 13 | end 14 | 15 | endmodule 16 | -------------------------------------------------------------------------------- /src/keyled.v: -------------------------------------------------------------------------------- 1 | module keyled ( 2 | input clk, 3 | input key_in, 4 | output reg key_out = 0 5 | ); 6 | reg [31:0] counter_low, counter_high; 7 | parameter standerd_time = 500000; 8 | 9 | always@(posedge clk) begin 10 | if(key_in == 1'b1) 11 | counter_high <= counter_high + 1; 12 | else 13 | counter_high <= 0; 14 | end 15 | 16 | always@(posedge clk) begin 17 | if(key_in == 1'b0) 18 | counter_low <= counter_low + 1; 19 | else 20 | counter_low <= 0; 21 | end 22 | 23 | always@(posedge clk) begin 24 | if(counter_low == standerd_time) 25 | key_out <= 0; 26 | else if(counter_high == standerd_time) 27 | key_out <= 1; 28 | end 29 | 30 | endmodule 31 | -------------------------------------------------------------------------------- /src/num_segMsg.v: -------------------------------------------------------------------------------- 1 | //数字显示 2 | `include "./global.vh" 3 | module num_segMsg ( 4 | input clk380hz, 5 | input [15:0] dataBus, 6 | output reg [3:0] pos, 7 | output reg [7:0] seg 8 | ); 9 | reg [2:0] posC; 10 | reg [3:0] dataP; 11 | always @(posedge clk380hz) begin 12 | case (posC) 13 | 0: begin 14 | pos <= 4'b0001; 15 | dataP <= dataBus[3:0]; 16 | end 17 | 1: begin 18 | pos <= 4'b0010; 19 | dataP <= dataBus[7:4]; 20 | end 21 | 2: begin 22 | pos <= 4'b0100; 23 | dataP <= dataBus[11:8]; 24 | end 25 | 3: begin 26 | pos <= 4'b1000; 27 | dataP <= dataBus[15:12]; 28 | end 29 | endcase 30 | posC = posC + 1; 31 | end 32 | 33 | always@ (dataP) begin 34 | case(dataP) 35 | 0 : seg = 8'b0011_1111; 36 | 1 : seg = 8'b0000_0110; 37 | 2 : seg = 8'b0101_1011; 38 | 3 : seg = 8'b0100_1111; 39 | 4 : seg = 8'b0110_0110; 40 | 5 : seg = 8'b0110_1101; 41 | 6 : seg = 8'b0111_1101; 42 | 7 : seg = 8'b0000_0111; 43 | 8 : seg = 8'b0111_1111; 44 | 9 : seg = 8'b0110_1111; 45 | default: 46 | seg = 8'b0100_0000; 47 | endcase 48 | end 49 | 50 | endmodule 51 | -------------------------------------------------------------------------------- /src/request.v: -------------------------------------------------------------------------------- 1 | `include "./global.vh" 2 | module request( 3 | input clk380hz, 4 | input clk10hz, 5 | input clk1hz, 6 | input rst, 7 | //control传过来的状态参数 8 | input [7:0] curr_floor, 9 | input [3:0] running_state, 10 | input [3:0] door_state, 11 | //输入参数 12 | input [`F_N-1:0] floor_in, //按钮 13 | input [`F_N-1:0] up_in, //开关 14 | input [`F_N-1:0] down_in, //(通过开关代替按钮) 15 | output [2*`F_N-1:0] demand_state, //信号显示 16 | output [2:0] req //发给control的请求 17 | ); 18 | 19 | //需求寄存器,没完成的需求都在这里 20 | reg [`F_N-1:0] floor = 0,//内部各层 21 | up = 0,//外部上行,最高层不能向上 22 | down = 0;//外部下行,最底层不能向下 23 | //需求显示 24 | assign demand_state = {up[`F_N-1:0], down[`F_N-1:0]}; 25 | 26 | //增加需求 27 | wire [`F_N-1:0] floor_add, up_add, down_add; 28 | 29 | //通过异或来将真实开关转换为模拟按键输入 30 | key_input #(`F_N) ki_up (clk10hz, {1'b0, up_in[`F_N-2:0]}, up_add); 31 | key_input #(`F_N) ki_down (clk10hz, {down_in[`F_N-1:1], 1'b0}, down_add); 32 | 33 | always @(posedge clk380hz) begin 34 | if(rst == 1) {floor, up, down} <= 0; 35 | else begin 36 | //开关状态改变时触发更新需求 37 | begin 38 | floor <= floor | floor_in; 39 | up <= up | up_add; 40 | down <= down | down_add; 41 | end 42 | //需求完成则对应位置复位 43 | if(door_state == `DS_OPEN) begin 44 | floor[curr_floor] <= 0; 45 | up [curr_floor] <= 0; 46 | down [curr_floor] <= 0; 47 | end 48 | end 49 | end 50 | 51 | //需求寄存器拓展 52 | wire [3*`F_N-1:0] w_floor, w_up, w_down; 53 | wire [7:0] w_curr_floor; 54 | 55 | //这里采取一种hacky的方式:将需求寄存器的前后均进行扩展,使得其宽度为原来的三倍 56 | //然后在判断请求时可以直接片选`F_N宽的信号,通过判断其中是否有1来确定是否有请求 57 | //采取这样的方式是为了保证扩展性,但不推荐 58 | assign w_floor = {{`F_N{1'b0}}, floor[`F_N-1:0], {`F_N{1'b0}}}, 59 | w_up = {{(`F_N+1){1'b0}}, up[`F_N-2:0], {`F_N{1'b0}}}, 60 | w_down = {{`F_N{1'b0}}, down[`F_N-1:1], {(`F_N+1){1'b0}}}; 61 | assign w_curr_floor = curr_floor + `F_N; 62 | 63 | //运行过程中条件判断 64 | wire up_req, //向上移动请求 65 | down_req, //向下移动请求 66 | go_up, //是否真要向上 67 | go_down, //向下 68 | open_door; //是否开门 69 | 70 | //根据需求寄存器判断各种请求 71 | //向上请求信号(不一定收到请求就向上,需要根据下面go_up信号判断) 72 | assign up_req = curr_floor != `F_N - 1 && //不在最顶层(最顶层不可能有向上请求) 73 | w_floor[(w_curr_floor + 1) +: `F_N] > 0 || //电梯内部选择当前位置之上的楼层 74 | w_up[(w_curr_floor + 1) +: `F_N] > 0 || //电梯外部有当前楼层之上的楼层的向上请求 75 | w_down[(w_curr_floor + 1) +: `F_N] > 0; //电梯外部有当前楼层之上的楼层的向下请求 76 | 77 | //向下请求 78 | assign down_req = curr_floor != 0 && 79 | w_floor[(w_curr_floor - 1) -: `F_N] > 0 || 80 | w_up[(w_curr_floor - 1) -: `F_N] > 0 || 81 | w_down[(w_curr_floor - 1) -: `F_N] > 0; 82 | 83 | //真的向上的信号 84 | assign go_up = (running_state == `RS_UP && up_req) || //正常的向上请求 85 | (running_state == `RS_DOWN && !down_req && up_req); //或没有向下请求时的向上请求 86 | 87 | //真的向下的信号 88 | assign go_down = (running_state == `RS_DOWN && down_req) || 89 | (running_state == `RS_UP && !up_req && down_req); 90 | 91 | //开门信号 92 | assign open_door = floor[curr_floor] == 1 || //到达指定楼层 93 | ( //或 94 | curr_floor != `F_N-1 && //不在最顶层 95 | ((running_state == `RS_UP && up[curr_floor] == 1) || //且当前层有向上请求,且电梯运行状态向上 96 | (!up_req && (down[curr_floor] == 1 || up[curr_floor] == 1))) //或者没有向上请求了(保持运动状态的优先级高于距离最近),但当前层有请求 97 | ) || 98 | ( 99 | curr_floor != 0 && 100 | ((running_state == `RS_DOWN && down[curr_floor] == 1) || 101 | (!down_req && (down[curr_floor] == 1 || up[curr_floor] == 1))) 102 | ); 103 | 104 | assign req = rst == 1 ? 0 : {go_up, go_down, open_door}; 105 | 106 | endmodule 107 | -------------------------------------------------------------------------------- /src/signal_segMsg.v: -------------------------------------------------------------------------------- 1 | //状态码显示 2 | `include "./global.vh" 3 | module signal_segMsg ( 4 | input clk380hz, 5 | input [15:0] dataBus, 6 | output reg [3:0] pos, 7 | output reg [7:0] seg 8 | ); 9 | reg [2:0] posC; 10 | reg [3:0] dataP; 11 | always @(posedge clk380hz) begin 12 | case (posC) 13 | 0: begin 14 | pos <= 4'b0001; 15 | dataP <= dataBus[3:0]; 16 | end 17 | 1: begin 18 | pos <= 4'b0010; 19 | dataP <= dataBus[7:4]; 20 | end 21 | 2: begin 22 | pos <= 4'b0100; 23 | dataP <= dataBus[11:8]; 24 | end 25 | 3: begin 26 | pos <= 4'b1000; 27 | dataP <= dataBus[15:12]; 28 | end 29 | endcase 30 | posC = posC + 1; 31 | end 32 | 33 | always @(dataP) begin 34 | case (dataP) 35 | `RS_UP: seg = 8'b0110_0011; 36 | `RS_DOWN: seg = 8'b0101_1100; 37 | `RS_STOP: seg = 8'b0100_0000; 38 | `DS_OPEN: seg = 8'b0011_0110; 39 | `DS_CLOSE: seg = 8'b0111_1111; 40 | `INVALID: seg = 8'b0100_0000; 41 | default: seg = 8'b0100_0000; 42 | endcase 43 | end 44 | endmodule -------------------------------------------------------------------------------- /src/top.v: -------------------------------------------------------------------------------- 1 | `include "./global.vh" 2 | module top( 3 | input clk100mhz, 4 | input rst_in, //高电平异步复位 5 | input [2*`F_N - 1:0] external, //电梯外部按键 6 | input [ `F_N - 1:0] internal, //电梯内部按键 7 | output [2*`F_N-1:0] LED, //需求LED指示 8 | output [3:0] posH, 9 | output [7:0] segH, 10 | output [3:0] posL, 11 | output [7:0] segL 12 | ); 13 | 14 | wire clk380hz, clk10hz, clk1hz; 15 | clkDiv cd(clk100mhz, clk380hz, clk10hz, clk1hz); 16 | 17 | wire [3:0] inter_keys; 18 | genvar i; 19 | generate 20 | for(i = 0; i < `F_N; i = i + 1) begin : KEYLED 21 | keyled led(clk100mhz, internal[i], inter_keys[i]); 22 | end 23 | endgenerate 24 | keyled rst_key(clk100mhz, rst_in, rst); 25 | 26 | wire [7:0] curr_floor; 27 | wire [3:0] running_state; 28 | wire [3:0] door_state; 29 | wire [2:0] req; 30 | wire [2*`F_N-1:0] demand_state; 31 | wire [3:0] state_dataBus; 32 | wire [15:0] number_dataBus; 33 | wire [15:0] signal_dataBus; 34 | 35 | request Request( 36 | .clk380hz(clk380hz), .clk10hz(clk10hz), .clk1hz(clk1hz), 37 | .rst(rst), 38 | .curr_floor(curr_floor), 39 | .running_state(running_state), 40 | .door_state(door_state), 41 | .floor_in(inter_keys), 42 | .up_in(external[2*`F_N-1:`F_N]), 43 | .down_in(external[`F_N-1:0]), 44 | .req(req), 45 | .demand_state(demand_state) 46 | ); 47 | 48 | control Control( 49 | .clk380hz(clk380hz), .clk10hz(clk10hz), .clk1hz(clk1hz), 50 | .rst(rst), 51 | .req(req), 52 | .curr_floor(curr_floor), 53 | .running_state(running_state), 54 | .door_state(door_state), 55 | .state(state_dataBus) 56 | ); 57 | 58 | assign LED = demand_state; 59 | assign number_dataBus = {state_dataBus[3:0], curr_floor[3:0]+1, 8'hff}; 60 | assign signal_dataBus = {running_state[3:0], door_state[3:0], `INVALID, `INVALID}; 61 | num_segMsg numbers(clk380hz, number_dataBus, posL, segL); 62 | signal_segMsg signals(clk380hz, signal_dataBus, posH, segH); 63 | 64 | endmodule 65 | -------------------------------------------------------------------------------- /电梯.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/observerw/USTB_verilog_elevator/c07bc1deddd1e682514d1349e58d94279a8948fb/电梯.pptx --------------------------------------------------------------------------------