VHDL code to simulate elevator operation

This page of VHDL source code section covers VHDL code to simulate elevator operation.

VHDL code to simulate elevator operation

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use work.lcd_grap.all;
entity elevator is
generic(bits : integer := 8 ); -- number of bits used for duty cycle.
-- also determines pwm period.
port ( clk: in std_logic; -- 4 mhz clock
reset,en: in std_logic; -- master reset pin
lcd_rw : out std_logic;
pwm : out std_logic_vector(1 downto 0);
lcd_select : out std_logic;
lcd_enable : out std_logic;
row: in std_logic_vector(0 to 3); -- this are the row lines
lcd_data: out std_logic_vector (7 downto 0); -- gives registered data output
col: inout std_logic_vector(0 to 3));
end elevator;
architecture rtl of elevator is
signal counter : std_logic_vector(bits - 1 downto 0):="00000000";
type keypad_state_type is (wait_r_0, c3, c2, c1, c0, found, sample, wait_r_1);
-- state names
type state_type is (initial,display,clear,location,putchar);
signal state,next_state: state_type;
-- clear screen.
constant clr: std_logic_vector(7 downto 0) := "00000001";
-- display on, without cursor.
constant don: std_logic_vector(7 downto 0) := "00001100";
-- function set for 8-bit data transfer and 2-line display

constant set: std_logic_vector(7 downto 0) := "00111000";
--frequency divider
constant big_delay: integer :=16;
constant small_delay: integer :=2;
constant reg_setup: integer :=1;
signal cs, ns: keypad_state_type; -- signals for current and next states
signal duty_cycle,duty_cycle1 : std_logic_vector(bits - 1 downto 0);
signal div_reg: std_logic_vector (22 downto 0); -- clock divide register
signal dclk,ddclk: std_logic; -- this has the divided clock.
signal col_reg_value: std_logic_vector (0 to 3);
signal r1,clk_d,start,stop: std_logic; -- row detection signal
signal key_value1,floor,key_value: integer range 0 to 15;
signal data,data1,floor_num: std_logic_vector (7 downto 0);
signal temp1,temp2,temp3,temp4: std_logic_vector (7 downto 0);
signal temp5,temp6,temp7,temp8: std_logic_vector (7 downto 0);
begin
--clk_out <= dclk;
r1 <= row(3) or row(2) or row(1) or row(0);
---------------------------- begining of fsm1 (keypad scanner) ----------------
sync_proc: process (dclk, reset, key_value) -- this is the synchronous part
begin
if (reset = '0') then -- you must have a reset for fsm to synthesize properly
cs <= wait_r_0;
elsif (dclk'event and dclk = '1') then
cs <= ns;
end if; end process;
comb_proc: process (cs, r1, col_reg_value) -- this is the combinational part
begin
case cs is
when wait_r_0 => -- waits till a button is pressed
col <= "1111"; -- keep all columns activated
if r1 = '1' then -- a button was pressed. but which one?
ns <= c3; -- let's find out
else
ns <= wait_r_0;
end if;
------------------------------------------------------------------------------
when c3 => --
col <= "0001"; -- activate column 3
if r1 = '0' then -- this means button was not in column 3
ns <= c2; -- so check if it was in column 2
else ns <= found; -- button was in column 3
end if;

when c2 => --
col <= "0010"; -- activate column 2
if r1 = '0' then -- this means button was not in column 2
ns <= c1; -- so check if it was in column 1
else
ns <= found; -- button was in column 2
end if;
-------------------------------------------------------------------------------
when c1 => --
col <= "0100"; -- activate column 1
if r1 = '0' then -- this means button was not in column 1
ns <= c0; -- so check if it was in column 0
else
ns <= found; -- button was in column 1
end if;
---------------------------------------------------------------------------
when c0 => --
col <= "1000"; -- activate column 0
if r1 = '0' then -- this means button was not in column 0 ??
ns <= wait_r_0; -- so the button must have been depressed fast
else
ns <= found; -- button was in column 3
end if;
-------------------------------------------------------------------------
when found => --
col <= col_reg_value;
if r1 = '0' then -- this means button is depressed
ns <= wait_r_0; -- so go back to initial state
else
ns <= sample; -- otherwise write the key value to data register
end if;
-----------------------------------------------------------------------------
when sample => -- this state will generate a signal with one clock period for
sampling
col <= col_reg_value;
ns <= wait_r_1; -- otherwise wait till button is pressed
-----------------------------------------------------------------------------
when wait_r_1 => --
col <= col_reg_value;
if r1 = '0' then -- this means button was depressed
ns <= wait_r_0; -- so go back to initial state
else

ns <= wait_r_1; -- otherwise wait till button is pressed
end if;
-----------------------------------------------------------------------------
end case;
end process;
-----------------------------------------------------------------------------
write_data: process (dclk, cs, key_value) -- write valid data to register
begin
if dclk'event and dclk = '0' then -- on the falling edge
if cs = found then
key_value <= key_value1;
end if;
end if;
end process; -- write_data
------------------------------------------------------------------------------
col_reg: process (dclk, cs, col) -- this is the column value register
begin
if (dclk'event and dclk = '0') then -- register the col value on the falling edge
if (cs = c3 or cs = c2 or cs = c1 or cs = c0) then -- provided we're in states c3
thru c0 only
col_reg_value <= col; -- otherwise the column value is not valid
end if;
end if;
end process; -- col_reg
---------------------------------------------------------------------------------
decoder: process(row, col_reg_value) -- decodes binary value of pressed key
from row and
column
variable code: std_logic_vector (0 to 7);
begin
code := (row & col_reg_value);
case code is
-- col
-- row 0 0123
when "00010001" => key_value1 <= 0;
when "00010010" => key_value1 <= 1;
when "00010100" => key_value1 <= 2;
when "00011000" => key_value1 <= 3;
-- row 1
when "00100001" => key_value1 <= 4;
when "00100010" => key_value1 <= 5;
when "00100100" => key_value1 <= 6;
when "00101000" => key_value1 <= 7;

-- row 2
when "01000001" => key_value1 <= 8;
when "01000010" => key_value1 <= 9;
when "01000100" => key_value1 <= 10;
when "01001000" => key_value1 <= 11;
-- row 3
when "10000001" => key_value1 <= 12;
when "10000010" => key_value1 <= 13;
when "10000100" => key_value1 <= 14;
when "10001000" => key_value1 <= 15;
when others => key_value1 <= 0;
end case;
end process; -- decoder
---------------------------- end of fsm1 (keypad scanner) ---------------------
-- select the appropriate lines for setting frequency
clk_div: process (clk, div_reg) -- clock divider
begin
if (clk'event and clk='1') then
div_reg <= div_reg + 1;
end if;
end process;
dclk <= div_reg(8);
ddclk<=div_reg(10);
clk_d<=div_reg(22);
---------------------------- end of clock divider ------------------------------
lcd_rw<='0';
process (ddclk,reset)
variable count: integer range 0 to big_delay;
variable c1 : std_logic_vector(7 downto 0);
begin
if reset = '0' then
state<=initial;
count:=0;
lcd_enable<='0';
lcd_select<='0';
c1 := "01111111";
elsif ddclk'event and ddclk = '1' then
case state is
when initial => -- to set the function
if count=reg_setup then
lcd_enable<='1';
else lcd_enable<='0';
end if;

lcd_data<=set;
lcd_select<='0';
if count=small_delay then
state<=display;
count:=0;
else count:=count+1;
end if;
when display => -- to set display on
if count=reg_setup then
lcd_enable<='1';
else lcd_enable<='0';
end if;
lcd_data<=don;
lcd_select<='0';
if count=small_delay then
state<=clear;
count:=0;
else count:=count+1;
end if;
when clear => -- clear the screen
if count=reg_setup then
lcd_enable<='1';
else lcd_enable<='0';
end if;
lcd_data<=clr;
lcd_select<='0';
if count=big_delay then
state<=location;
count:=0;
else count:=count+1;
end if;
when location => -- clear the screen
if count=reg_setup then
lcd_enable<='1';
else lcd_enable<='0';
end if;
if count=0 then
if c1="10001111" then
c1:="11000000";
elsif c1="11001111" then
c1:="10000000";
else c1:=c1+'1';
end if;

end if;
lcd_data <= c1;
lcd_select<='0';
if count=big_delay then
state<=putchar;
count:=0;
else count:=count+1;
end if;
when putchar=> -- display the character on the lcd
if count=reg_setup then
lcd_enable<='1';
else lcd_enable<='0';
end if;
case c1 is
when "10000000" => lcd_data<= f ;--sigle line
when "10000001" => lcd_data<= l ;--sigle line
when "10000010" => lcd_data<= o ;--sigle line
when "10000011" => lcd_data<= o ;--sigle line
when "10000100" => lcd_data<= r ;--sigle line
when "10000101" => lcd_data<= space ;--sigle line
when "10000110" => lcd_data<= n ;--sigle line
when "10000111" => lcd_data<= u ;--sigle line
when "10001000" => lcd_data<= m ;
when "10001001" => lcd_data<= b ;
when "10001010" => lcd_data<= e ;
when "10001011" => lcd_data<= r ;
when "10001100" => lcd_data<= space ;
when "10001101" => lcd_data<= equal ;
when "10001110" => lcd_data<= floor_num ;
when "10001111" => lcd_data<= space;
when "11000000" => lcd_data<= s ;--sigle line
when "11000001" => lcd_data<= t ;--sigle line
when "11000010" => lcd_data<= a ;--sigle line
when "11000011" => lcd_data<= t ;--sigle line
when "11000100" => lcd_data<= u ;--sigle line
when "11000101" => lcd_data<= s ;--sigle line
when "11000110" => lcd_data<= space ;--sigle line
when "11000111" => lcd_data<= temp1 ;--sigle line
when "11001000" => lcd_data<= temp2 ;
when "11001001" => lcd_data<= temp3 ;
when "11001010" => lcd_data<= temp4 ;
when "11001011" => lcd_data<= space ;
when "11001100" => lcd_data<= temp5 ;

when "11001101" => lcd_data<= temp6 ;
when "11001110" => lcd_data<= temp7 ;
when "11001111" => lcd_data<= temp8 ;
when others => null;
end case ;
lcd_select<='1';
if count=small_delay then
state<=location;
count:=0;
else count:=count+1;
end if; end case; end if; end process;
process(clk_d,reset)
variable cou : std_logic_vector(1 downto 0);
variable start,stop: std_logic; -- row detection signal
begin
if reset='0' then
cou:="00";
temp1 <= l ;
temp2 <= i ;
temp3 <= f ;
temp4 <= t ;
temp5 <= i ;
temp6 <= d ;
temp7 <= l ;
temp8 <= e ;
floor_num <= zero ;
elsif rising_edge(clk_d) then
case key_value is
when 0 => floor_num <= zero ;
floor <=0;
when 1 => floor_num <= one ;
floor <=1;
when 2 => floor_num <= two ;
floor <=2;
when 3 => floor_num <= three ;
floor <=3;
when 4 =>
temp1 <= d ;
temp2 <= o ;
temp3 <= o ;
temp4 <= r ;
temp5 <= o ;
temp6 <= p ;

temp7 <= e ;
temp8 <= n ;
when 5 =>
temp1 <= d ;
temp2 <= o ;
temp3 <= o ;
temp4 <= r ;
temp5 <= c ;
temp6 <= l ;
temp7 <= o ;
temp8 <= s ;
when 6 =>
start:='1';
stop:='0';
when 7 =>
stop:='1';
start:='0';
when others =>
temp1 <= i ;
temp2 <= d ;
temp3 <= l ;
temp4 <= e ;
temp5 <= k ;
temp6 <= e ;
temp7 <= y ;
temp8 <= space ;
end case;
if start='1' then
if cou=floor then
start := '0';
cou:=cou;
temp7 <= "001100" & cou ;
elsif cou<=floor then
cou:=cou + '1';
temp1 <= u ;
temp2 <= p ;
temp3 <= space ;
temp4 <= space ;
temp5 <= space ;
temp6 <= "01111110" ;
temp7 <= "001100" & cou ;
temp8 <= space ;
elsif cou>=floor then

cou:=cou-'1';
temp1 <= d ;
temp2 <= o ;
temp3 <= w ;
temp4 <= n ;
temp5 <= space ;
temp6 <= "01111111" ;
temp7 <= "001100" & cou ;
temp8 <= space ;
end if; end if; end if;
end process;
end rtl;


USEFUL LINKS to VHDL CODES

Refer following as well as links mentioned on left side panel for useful VHDL codes.
D Flipflop
T Flipflop
Read Write RAM
4X1 MUX
4 bit binary counter
Radix4 Butterfly
16QAM Modulation
2bit Parallel to serial

USEFUL LINKS to Verilog Codes

Following are the links to useful Verilog codes.
Low Pass FIR Filter
Asynchronous FIFO design with verilog code
D FF without reset
D FF synchronous reset
1 bit 4 bit comparator
All Logic Gates

RF and Wireless tutorials

WLAN  802.11ac  802.11ad  wimax  Zigbee  z-wave  GSM  LTE  UMTS  Bluetooth  UWB  IoT  satellite  Antenna  RADAR