We built the brain of an elevator in software and then proved it works correctly before a single wire is soldered. Navigate the floors to see how.
The elevator's logic is modelled as a Finite State Machine (FSM) with three modes: IDLE, UP, and DOWN. It reads which floors are requested, decides which direction to move, climbs or descends one floor at a time, and opens the door when it arrives.
| SIGNAL | DIR | WIDTH | DESCRIPTION |
|---|---|---|---|
| clk | IN | 1-bit | System clock the heartbeat. Every tick, the controller takes one step. |
| rst | IN | 1-bit | Reset like a power cycle. Sends the elevator back to floor 0, waiting. |
| request | IN | 5-bit | Floor buttons pressed. 5 bits = 5 floors. Bit 3 = "1" means floor 3 was requested. |
| current_floor | OUT | 3-bit | Where the elevator is right now (floor 0 to 4). |
| direction | OUT | 1-bit | Which way it's moving. 1 = going up, 0 = going down. |
| door_open | OUT | 1-bit | Should the doors open? 1 = yes (the elevator has arrived at a requested floor). |
module elevator_controller ( input logic clk, input logic rst, input logic [4:0] request, output logic [2:0] current_floor, output logic direction, output logic door_open ); typedef enum logic [1:0] {IDLE, UP, DOWN} state_t; state_t state; always_ff @(posedge clk or posedge rst) begin if (rst) begin current_floor <= 0; state <= IDLE; door_open <= 0; end else begin door_open <= 0; case (state) IDLE: begin if (request[current_floor]) door_open <= 1; else if (request_above(...)) state <= UP; else if (request_below(...)) state <= DOWN; end UP: begin direction <= 1; current_floor <= current_floor + 1; if (request[current_floor+1]) door_open <= 1; state <= IDLE; end DOWN: begin direction <= 0; current_floor <= current_floor - 1; if (request[current_floor-1]) door_open <= 1; state <= IDLE; end endcase end end endmodule
$finish signal like checking an exam paper was actually submitted.