DESIGNING DIGITAL CONTROLLER FOR ELECTRONIC DUMBWAITER LIFT (EDL) SYSTEM

#digital #y2021 #vhdl

INTRODUCTION

For this Design Project, I had to design a digital controller for a Electronic Dumbwaiter Lift(EDL) for a hotel. The typical view of EDL controller as below,
Pasted image 20240527204207.png

And the given specifications are,
1.      The hotel owner initially plan’s to implements the system for three stories (ground floor, first floor, and second floor).
2.      Push buttons are used for selecting the appropriate floor to move the lift from the default location (ground floor kitchen).
3.      Limit Switches will be used for identifying the floor when the lift reaches.
4.      Return switches are used for sending the EDL to the default location.
5.      RESET can be used to reset the EDL system.

For implement this designed controller, I used a mealy machine with a encoder, In my design have 7 inputs and 2 output to control the motor direction.
With this controller, There are two control panel required to located in a kitchen and on EDL as below.
Pasted image 20240527204310.png
1st panel is for kitchen and 2nd panel is for EDL. I made following initial assumptions for continue the deign tasks
·         EDL can transport goods between floors from/to kitchen and a floor only. It can’t go intermediate floors.(Ex. It can’t go from 1st floor to 2nd )
·         When start the system (Powered up),EDL went to ground floor.
·         If press the reset, controller goes to initial state.(If system not work properly, can press ‘reset’).
·         Assume initially not pressed any button.
·         After start the transition, Buttons can’t change the destination, other than with press reset.

BLOCK DIAGRAM AND INPUT OUTPUTS OF THE SYSTEM

BLOCK DIAGRAM

Pasted image 20240527204418.png

This controller has two components known as, priority encoder and a controller. Priority encoders reduce the number of inputs to the controller, and it maintain the input priority. Controllers hold the current state and make decisions according to the inputs.

INPUTS AND OUTPUTS

Inputs
# Input Encoder Output Code Description
1 CLK - Synchronize Clock
2 RST 000 Reset - reset the EDL system.
3 P[0] 001 1st push button. Use to select 1st floor
4 P[1] 010 2nd push button. Use to select 2nd floor
5 L[0] 011 Ground Limit switch – activated when Lift reaches the kitchen
6 L[1] 100 1st Limit switch – activated when Lift reaches 1st Floor
7 L[2] 101 2nd   Limit switch – activated when Lift reaches 2nd Floor
8 RET 110 Return – use to return lift to the kitchen
9 RUN 111 Nothing (Implement at the hardware level by using a push-up resistors)
Outputs
# Output Code Function
1 M[1],M[0] 00 Stop Motor
2 M[1],M[0] 01 Start Motor Upward
3 M[1],M[0] 10 Start Motor Downward
4 M[1],M[0] 11 Stop Motor

Flow Chart

Pasted image 20240527204644.png
Pasted image 20240527204650.png

STATE DIAGRAM

States before Minimizing

State Description
II Initial State
GG Ground Floor State
F1 1st Floor State
F2 2nd Floor State
TG Go to Ground Floor State
T1 Go to 1st Floor State
T2 Go to 2nd Floor State

State Table before minimizing

Present State Next State, Output
RST P [0] P [1] L [0] L [1] L [2] RET RUN *
II II,00 -,- -,- GG,00 II,10 II,10 -,- II,10
GG II,00 T1,01 T2,01 GG,00 -,- -,- GG,00 GG,00
F1 II,00 F1,00 F1,00 -,- F1,00 -,- TG,10 F1,00
F2 II,00 F2,00 F2,00 -,- -,- F2,00 TG,10 F2,00
TG II,00 TG,10 TG,10 GG,00 TG,10 TG,10 TG,10 TG,10
T1 II,00 T1,01 T1,01 T1,01 F1,00 -,- T1,01 T1,01
T2 II,00 T2,01 T2,01 T2,01 T2,01 F2,00 T2,01 T2,01
NO* II,10 II,10 II,10 GG,00 II,10 II,10 II,00 II,00

State Diagram before minimizing

Pasted image 20240527213659.png

Minimizing States using Implication Chart

Pasted image 20240527213745.png

Minimized States

State Description Code
1 II Initial State 000
2 GG Ground Floor State 100
3 FF NOT Ground Floor State 011
4 T1 Go to 1st Floor State 001
5 T2 Go to 2nd Floor State 010

State Diagram

Pasted image 20240527213854.png

Circuit diagram of EDL

Transition Table – Controller

Pasted image 20240527214055.png
Pasted image 20240527214249.png

TRANSITION TABLE – PRIORITY ENCODER

Pasted image 20240527214450.png

Minimizing P:
P = RST’ . P0’ . P1’.L0’ [L1 + L1’.L2+L1’.L2’.RET]
P = RST’ . P0’ . P1’.L0’[L1+L2+ L1’.L2’.RET]

Minimizing Q:
Q = RST’ . P0’ . P1 + RET’ . P0’ . P1’ . L0 + RST’ . P0’. P1’.L0’.L1’.L2’

Minimizing R:
R = RST’ [P0 + P0’.P1’.L0 + P0’.P1’.L0’.L1’.L2 + P0’ P1’ L0’ L1’ L2’ RET]
R = RST’ [P0 + P1’.L0’ + P0’.P1’.L0’.L1’ [L2+RET]]

CIRCUIT OF CONTROLLER’S STATES

Pasted image 20240527231636.png

CIRCUIT OF CONTROLLER’S OUTPUT

Pasted image 20240527231714.png

Circuit of Priority Encoder

Pasted image 20240527231733.png

·         Controller has 5 states and developed by using D Flip flop.

·         Output also depended on the current states and input (Merely machine).

·         Included Power-on-reset circuit. So, when power up the system, system goes to initial state.

VHDL code for EDL

Pasted image 20240527231810.png

CODE FOR ENCODER

library IEEE; --Not a Picture 
use IEEE.STD_LOGIC_1164.ALL;      
use ieee.NUMERIC_STD.all; 
 
entity Encorder is 
    Port ( BUT1 : in  STD_LOGIC; 
           BUT2 : in  STD_LOGIC; 
           G_lmt : in  STD_LOGIC; 
           lmt_1 : in  STD_LOGIC; 
           lmt_2 : in  STD_LOGIC; 
           ret : in  STD_LOGIC; 
           reset : in  STD_LOGIC; 
           Y : out  STD_LOGIC_VECTOR (2 downto 0)); 
end Encorder; 
 
architecture Behavioral of Encorder is 
 
begin  
 
process(BUT1,BUT2,G_lmt,lmt_1,lmt_2,ret,reset)   
begin 
     
if (reset = '1') then Y <= "000";    
elsif (ret = '1') then Y <= "001"; 
elsif (BUT1 = '1') then Y<="010";  
elsif (BUT2 = '1') then Y<="011"; 
elsif (G_lmt = '1') then Y<="100"; 
elsif (lmt_1 = '1') then Y<="101"; 
elsif (lmt_2 = '1') then Y<="110"; 
else Y<="111";     
     
end if;  
end process;

CODE FOR STATE CONTROLLER

library ieee; -- Not a picture 
use IEEE.STD_LOGIC_1164.ALL; 
 
 
entity EDL_2 is 
port( 
clk: in std_logic; 
encod : in std_logic_vector(2 downto 0); 
M :out std_logic_vector(1 downto 0) 
); 
end EDL_2; 
 
architecture arch_EDL_2 of EDL_2 is 
type state_type is (II,GG,FF,T1,T2); 
signal state_reg, state_next : state_type; 
 
begin 
    process(clk) 
    begin 
        if encod = "000" then state_reg <=II; 
        elsif (rising_edge(clk)) then state_reg <= state_next; 
        end if; 
    end process; 
         
     
    process(encod,state_reg) 
    begin 
        state_next <= state_reg; 
        M <= "00"; 
         
        case state_reg is  
            when II => 
            if (encod = "100") then M <= "00";  
                state_next <= GG; 
            else 
                M <= "10";        
                state_next <= II; 
            end if; 
             
            when GG => 
            if (encod = "010") then M <= "01"; 
                state_next <= T1; 
            elsif (encod = "011") then M <= "01"; 
                state_next <= T2; 
            else 
                M <= "00"; 
                state_next <= GG; 
            end if; 
             
            when FF => 
            if(encod = "001") then M <= "10"; 
                state_next <= II; 
            else 
                M <= "00";    
                state_next <= FF;    
            end if; 
             
            when T1 => 
            if(encod = "101") then M <= "00"; 
                state_next <= FF; 
            else 
                M <= "01"; 
                state_n
				 when T2 => 
            if(encod = "110") then M <= "00"; 
                state_next <= FF; 
            else 
                M <= "01"; 
                state_next <= T2; 
            end if;    
            end case;    
            end process; 
             
 
             
    end arch_EDL_2; 

VHDL CODE FOR EDL SYSTEM (STRUCTURED ABOVE TWO ENTITIES)

use ieee.std_logic_1164.all; 
 
entity EDL is 
    port( 
    clk, reset :in std_logic; 
    BUT1,BUT2,G_lmt,lmt_1,lmt_2,RET :in std_logic;        -- p - push button , l - limit 
switch , -M motor, ret-return 
    M : out std_logic_vector(1 downto 0) 
    ); 
end EDL; 
 
architecture arch_EDL of EDL is  
 
signal P : std_logic_vector(2 downto 0);     -- internal signals  
 
component EDL_2 is 
    port( 
    clk: in std_logic; 
    encod : in std_logic_vector(2 downto 0); 
    M :out std_logic_vector(1 downto 0) 
    ); 
         
end component;   
component Encorder is  
 
     Port ( BUT1 : in  STD_LOGIC; 
           BUT2 : in  STD_LOGIC; 
           G_lmt : in  STD_LOGIC; 
           lmt_1 : in  STD_LOGIC; 
           lmt_2 : in  STD_LOGIC; 
           ret : in  STD_LOGIC; 
           reset : in  STD_LOGIC; 
           Y : out  STD_LOGIC_VECTOR (2 downto 0)); 
            
 end component; 
     
 -- port map 
  
 begin 
    controller :    EDL_2 port map (encod => P, M =>M, clk =>clk);       
    encod:  Encorder port map (BUT1 => BUT1,BUT2 => BUT2,G_lmt => G_lmt, lmt_1 => 
lmt_1, 
    lmt_2 =>lmt_2, ret => ret, reset => reset, Y => P); 
 end arch_EDL; 

TEST BENCH CODE FOR CONTROLLER

TEST BENCH FOR ENCODER

library ieee; 
use ieee.std_logic_1164.all; 
use ieee.NUMERIC_STD.all; 
    -- Add your library and packages declaration here ... 
 
entity encorder_tb is 
end encorder_tb; 
 
architecture TB_ARCHITECTURE of encorder_tb is 
    -- Component declaration of the tested unit 
    component encorder 
    port( 
        BUT1 : in STD_LOGIC; 
        BUT2 : in STD_LOGIC; 
        G_lmt : in STD_LOGIC; 
        lmt_1 : in STD_LOGIC; 
        lmt_2 : in STD_LOGIC; 
        ret : in STD_LOGIC; 
        reset : in STD_LOGIC; 
        Y : out STD_LOGIC_VECTOR(2 downto 0) ); 
    end component; 
 
    -- Stimulus signals - signals mapped to the input and inout ports of tested entity 
    signal BUT1 : STD_LOGIC; 
    signal BUT2 : STD_LOGIC; 
    signal G_lmt : STD_LOGIC; 
    signal lmt_1 : STD_LOGIC; 
    signal lmt_2 : STD_LOGIC; 
    signal ret : STD_LOGIC; 
    signal reset : STD_LOGIC; 
    -- Observed signals - signals mapped to the output ports of tested entity 
    signal Y : STD_LOGIC_VECTOR(2 downto 0); 
 
begin 
    -- Unit Under Test port map 
    UUT : encorder 
        port map ( 
            BUT1 => BUT1, 
            BUT2 => BUT2, 
            G_lmt => G_lmt, 
            lmt_1 => lmt_1, 
            lmt_2 => lmt_2, 
            ret => ret, 
            reset => reset, 
            Y => Y 
        ); 
 
    reset <= '1', '0' after 50ns; 
    BUT1 <= '0', '1' after 100 ns, '0' after 150ns; 
    BUT2 <= '0', '1' after 200 ns, '0' after 250ns; --  G_lmt <= '0', '1' after 100ns , '0' after 150ns; 
     
 
end TB_ARCHITECTURE; 
 
configuration TESTBENCH_FOR_encorder of encorder_tb is 
    for TB_ARCHITECTURE 
        for UUT : encorder 
            use entity work.encorder(behavioral); 
        end for; 
    end for; 
end TESTBENCH_FOR_encorder; 

TEST BENCH FOR STATE CONTROLLER

o 0) ); 
    end component; 
 
    -- Stimulus signals - signals mapped to the input and inout ports of tested entity 
    signal clk : STD_LOGIC; 
    signal encod : STD_LOGIC_VECTOR(2 downto 0); 
    -- Observed signals - signals mapped to the output ports of tested entity 
    signal M : STD_LOGIC_VECTOR(1 downto 0); 
 
    -- Add your code here ... 
 
begin 
 
    -- Unit Under Test port map 
    UUT : edl_2 
        port map ( 
            clk => clk, 
            encod => encod, 
            M => M 
        ); 
 
    clock_process: process                                                                                          
    begin 
        clk <='0'; 
        wait for clk_period/2; 
        clk <= '1'; 
        wait for clk_period/2; 
    end process; 
     
    encod <= "000", "100" after 100ns, "110" after 200ns; 
 
end TB_ARCHITECTURE; 
 
configuration TESTBENCH_FOR_edl_2 of edl_2_tb is 
    for TB_ARCHITECTURE 
        for UUT : edl_2 
            use entity work.edl_2(arch_edl_2); 
        end for; 
    end for; 
end TESTBENCH_FOR_edl_2; 

TEST BENCH FOR THE CONTROLLER

library ieee; 
use ieee.std_logic_1164.all; 
 
    -- Add your library and packages declaration here ... 
 
entity edl_tb is 
end edl_tb; 
 
architecture TB_ARCHITECTURE of edl_tb is -- Component declaration of the tested unit  
        constant clk_period : time := 10 ns; --defining clock 
    component edl 
    port( 
        clk : in STD_LOGIC; 
        reset : in STD_LOGIC; 
        BUT1 : in STD_LOGIC; 
        BUT2 : in STD_LOGIC; 
        G_lmt : in STD_LOGIC; 
        lmt_1 : in STD_LOGIC; 
        lmt_2 : in STD_LOGIC; 
        RET : in STD_LOGIC; 
        M : out STD_LOGIC_VECTOR(1 downto 0) ); 
    end component; 
 
    -- Stimulus signals - signals mapped to the input and inout ports of tested entity 
    signal clk : STD_LOGIC; 
    signal reset : STD_LOGIC; 
    signal BUT1 : STD_LOGIC; 
    signal BUT2 : STD_LOGIC; 
    signal G_lmt : STD_LOGIC; 
    signal lmt_1 : STD_LOGIC; 
    signal lmt_2 : STD_LOGIC; 
    signal RET : STD_LOGIC; 
    -- Observed signals - signals mapped to the output ports of tested entity 
    signal M : STD_LOGIC_VECTOR(1 downto 0); 
 
    -- Add your code here ... 
 
begin 
 
    -- Unit Under Test port map 
    UUT : edl 
        port map ( 
            clk => clk, 
            reset => reset, 
            BUT1 => BUT1, 
            BUT2 => BUT2, 
            G_lmt => G_lmt, 
            lmt_1 => lmt_1, 
            lmt_2 => lmt_2, 
            RET => RET, 
            M => M 
        ); 
 
    -- Add your stimulus here ... 
    clock_process: process                                                                                          
    begin 
        clk <='0'; 
        wait for clk_period/2; 
        clk <= '1'; 
        wait for clk_period/2; 
    end process; 
     
17 
 
    stim: process 
    begin 
        ----------------Case 00------------------------------ 
         reset <= '1';  --Initially reset occur at hardware  
         wait for 200ns; 
         reset <='0'; 
         wait for 300ns;      -- Initillay find lift go to kitchen       
        G_lmt <= '1';   --Lift  reach the Ground Floor    
        wait for 100ns; 
        assert M = "00" report "Check Case 00 - 1"  severity error; 
        wait for 400ns; -- Remain at kitchen  
         
        -----------------------Case 01------------------------ 
             
        BUT1 <= '1'; --Press 1st button  
        wait for 100ns; 
        BUT1 <='0'; 
        G_lmt <= '0'; 
        wait for 100ns; 
        assert M = "01" report "Check Case 01 - 1"  severity error;   
        wait for 300ns; 
        lmt_1 <= '1'; --Reach 1st floor    
        wait for 500ns; 
        assert M = "00" report "Check Case 01 - 2"  severity error;  
        RET <= '1';  --press return button 
        wait for 100ns; 
        RET <= '0'; 
        lmt_1 <='0'; 
        wait for 400ns;  
        assert M = "10" report "Check Case 01 - 3"  severity error;  
        G_lmt <= '1'; -- Reach kitchen 
        assert M = "00" report "Check Case 01 - 4"  severity error;    
             
        wait; 
             
        end process;     
         
 
 
 
end TB_ARCHITECTURE; 
 
configuration TESTBENCH_FOR_edl of edl_tb is 
    for TB_ARCHITECTURE 
        for UUT : edl 
            use entity work.edl(arch_edl); 
        end for; 
    end for; 
end TESTBENCH_FOR_edl; 

SIMULATION RESULTS FOR ENCODER

Pasted image 20240527232428.png

Initially reset is hold sometimes trough hardware (Included it in the circuit diagram). Then the motor output provided as downward (M[]=2) until reach the kitchen (G_lmt). Then motor was stopped. Then press 1st floor button (BUT1). Then motor was start to upward direction (M[]=1). The ground limit went to zero. When reach 1st floor 1st limit switch(lmt_1) turn on. Then Motor was stopped. Finally press the return button(RET), Then motor goes to downward until reach the ground limit.

Blue color indicate the user pressing buttons. Red color indicates the system inputs such as limit switches. Green color indicates the motor output.