Skip to main content

VHDL architectures; elevator controller

Short answer

VHDL architectures model an entity in three styles: behavioral (sequential process), dataflow (concurrent signal assignments), and structural (component instances). The elevator FSM assumes 4 floors, stored requests, one clock per floor move, 4-clock door open; states are IDLE, MOVE_UP, MOVE_DOWN, DOOR with transitions based on pending requests above/below and door timer.

Explain different architecture in VHDL. Write a VHDL code to design an elevator's control unit with necessary assumptions using state machine.

Architectures (modelling styles) in VHDL

An entity describes the interface; its architecture describes the internal working. One entity can have several architectures, each in one of three styles:

  1. Behavioral: describes what the circuit does using sequential statements inside a process (if, case, loops), without specifying gates.
architecture behav of mux2 is
begin
  process (a, b, s)
  begin
    if s = '0' then y <= a; else y <= b; end if;
  end process;
end architecture;
  1. Dataflow (RTL): describes how data flows between signals using concurrent signal assignments, e.g. y <= (a and not s) or (b and s); or with ... select.
  2. Structural: describes the circuit as interconnected components (instances with port maps), like a netlist of gates and sub-blocks.

Elevator control unit

Assumptions: 4 floors (0-3); req(3:0) are the floor buttons (inside and outside, one bit per floor), which are stored until served; the cabin needs one clock to move one floor; the door stays open for 4 clocks; when requests exist both above and below, the cabin serves upward requests first.

Outputs: floor (current floor), up, down (motor) and door_open.

States:

StateMeaningNext state
IDLEWaiting; examines stored requestsDOOR if request for the current floor; MOVE_UP if a request above; MOVE_DOWN if a request below; else IDLE
MOVE_UPMotor up, floor = floor + 1IDLE
MOVE_DOWNMotor down, floor = floor - 1IDLE
DOORDoor open, timer counts 3 down to 0, the request for this floor is clearedIDLE when the timer reaches 0
 IDLE --request for this floor--> DOOR
 IDLE --request above-----------> MOVE_UP
 IDLE --request below-----------> MOVE_DOWN
 MOVE_UP / MOVE_DOWN --(1 clock, floor +/- 1)--> IDLE
 DOOR --timer = 0--> IDLE
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

-- 4-floor elevator control unit (floors 0..3)
entity elevator is
  port (
    clk       : in  std_logic;
    rst       : in  std_logic;                      -- active high
    req       : in  std_logic_vector(3 downto 0);   -- floor buttons (inside + outside)
    floor     : out unsigned(1 downto 0);           -- current floor
    up        : out std_logic;                      -- motor up
    down      : out std_logic;                      -- motor down
    door_open : out std_logic                       -- door open
  );
end entity elevator;

architecture fsm of elevator is
  type state_t is (IDLE, MOVE_UP, MOVE_DOWN, DOOR);
  signal state   : state_t;
  signal cur     : unsigned(1 downto 0);            -- current floor register
  signal pending : std_logic_vector(3 downto 0);    -- stored requests
  signal timer   : unsigned(1 downto 0);            -- door-open time
begin
  process (clk, rst)
    variable pend  : std_logic_vector(3 downto 0);
    variable above : boolean;
    variable below : boolean;
  begin
    if rst = '1' then
      state   <= IDLE;
      cur     <= (others => '0');                   -- start at ground floor
      pending <= (others => '0');
      timer   <= (others => '0');
    elsif rising_edge(clk) then
      pend := pending or req;                       -- remember new requests
      above := false;
      below := false;
      for i in 0 to 3 loop
        if pend(i) = '1' then
          if i > to_integer(cur) then above := true; end if;
          if i < to_integer(cur) then below := true; end if;
        end if;
      end loop;

      case state is
        when IDLE =>
          if pend(to_integer(cur)) = '1' then       -- request for this floor
            pend(to_integer(cur)) := '0';           -- clear it
            timer <= "11";
            state <= DOOR;
          elsif above then
            state <= MOVE_UP;
          elsif below then
            state <= MOVE_DOWN;
          end if;
        when MOVE_UP =>
          cur   <= cur + 1;                         -- one floor per clock
          state <= IDLE;
        when MOVE_DOWN =>
          cur   <= cur - 1;
          state <= IDLE;
        when DOOR =>
          if timer = 0 then
            state <= IDLE;                          -- close door
          else
            timer <= timer - 1;
          end if;
      end case;
      pending <= pend;
    end if;
  end process;

  floor     <= cur;
  up        <= '1' when state = MOVE_UP   else '0';
  down      <= '1' when state = MOVE_DOWN else '0';
  door_open <= '1' when state = DOOR      else '0';
end architecture fsm;

The design was analysed and simulated with GHDL: a request for floor 3 from floor 0 moves the car up and opens the door at floor 3; a later request for floor 1 moves it down to floor 1; simultaneous requests for floors 0 and 2 serve floor 2 first and then 0.

✓ Answer checked by Claude Opus 5.5 (high effort)

All Embedded System chapter 9 questions →