BLUETOOTH BASED WIRELESS
HOME AUTOMATION SYSTEM
19ECE383 VLSI Design Lab
B. Tech. ECE
Batch: C1
2023-2024 Even Semester
CB.EN.U4ECE21216 HARSHINI M
CB.EN.U4ECE21224 UMESH KUMAR
CB.EN.U4ECE21239 NITHIN RAVI
Faculty In-charges: Dr. Navya Mohan & Dr. Anita J.P
Signature of the Faculty:
Department of Electronics and Communication Engineering
Amrita School of Engineering
Amrita Vishwa Vidyapeetham
Amritanagar, Coimbatore – 641112
1. OBJECTIVE:
The primary objective of this project is to develop a PMOD Wi-Fi interfacing solution
for FPGA-based systems, enabling seamless wireless communication for a variety of
applications. The project aims to leverage the flexibility of FPGA technology combined
with PMOD connectivity to establish reliable and efficient wireless communication
channels.
Key goals include:
Designing and implementing a robust hardware interface between the FPGA
development board and the PMOD Wi-Fi module.
Developing firmware/software to manage the PMOD Wi-Fi module's operation,
including initialization, configuration, and data transfer.
Demonstrating the integrated solution’s capability in real-world applications,
particularly in areas such as IoT, industrial automation, and embedded systems.
2. SOFTWARE-HARDWARE USED:
Software used: ModelSim and Vivado
3. OVERVIEW OF THE SYSTEM:
This project encompasses the development of a comprehensive Wi-Fi interfacing
solution for FPGA platforms using PMOD modules. The focus is on creating a seamless
and efficient communication bridge between FPGA development boards and Wi-Fi
modules, facilitating bidirectional data transfer and control functionalities. The
hardware component involves designing an interface that ensures robust connectivity
and protocol handling, while the firmware/software component includes the creation of
routines for initialization, configuration, and data management.
4. BLOCK DIAGRAM:
FPGA
Board
PMOD External
Software
Interface
WiFi- FPGA
Module
Design
Page 2 of 12
5. INTRODUCTION:
Wireless communication is essential in modern technology applications, including IoT
and industrial automation. FPGAs offer significant flexibility and performance but
integrating wireless capabilities can be challenging. This project addresses this by
developing firmware for a PMOD Wi-Fi module, enabling FPGA systems to
communicate wirelessly. The software handles tasks such as initialization,
configuration, and data transfer, ensuring efficient and reliable communication.
By focusing on the software development, we demonstrate the feasibility of wireless
communication for FPGA-based applications. Simulating and testing the firmware in
virtual environments validates its functionality and robustness. This approach not only
showcases the flexibility of FPGAs but also sets the stage for innovative uses in various
industries, paving the way for future integration with hardware.
There are totally four modules involved in our project namely,
1. Top Module
Function: Integrates the UART receiver, UART transmitter, and WiFi interface. It
routes signals and manages data flow between these components, facilitating serial
communication and WiFi data exchange.
2. UART Receiver (UART_RX)
Function: Converts incoming serial data into parallel data using a state machine. It
detects the start bit, reads data bits, verifies the stop bit, and outputs the received byte
along with a data valid signal.
3. UART Transmitter (UART_TX)
Function: Converts parallel data into serial data for transmission. It manages the start
bit, data bits, and stop bit sequentially through a state machine and signals when the
transmission is active and complete.
4. WiFi Module Interface
Function: Manages data communication with a WiFi module. It handles the reception
and transmission of data to and from the WiFi module and signals when the WiFi
module is ready for communication.
Page 3 of 12
6. COMPLETE CODE WITH COMMENTS:
MODULE 1 – WIFI INTERFACING
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity WiFi_Interface is
Port (
clk : in STD_LOGIC;
reset : in STD_LOGIC;
wifi_rx : in STD_LOGIC_VECTOR(7 downto 0);
wifi_tx : out STD_LOGIC_VECTOR(7 downto 0);
wifi_ready : out STD_LOGIC
);
end WiFi_Interface;
architecture Behavioral of WiFi_Interface is
-- Define signals for internal communication with WiFi module
signal wifi_data_in : std_logic_vector(7 downto 0);
signal wifi_data_out : std_logic_vector(7 downto 0);
signal wifi_ready_sig : std_logic := '0'; -- Indicates if WiFi module is ready
begin
-- WiFi module control and data exchange process
process(clk, reset)
begin
if reset = '1' then
-- Reset state
wifi_data_out <= (others =>
'0'); wifi_ready_sig <= '0';
elsif rising_edge(clk) then
wifi_data_out <= wifi_rx; -- Echo received data
-- Set ready signal once communication is done
-- For a real implementation, this might involve checking status signals from
the WiFi module
wifi_ready_sig <= '1';
end if;
end process;
-- Assign internal signals to ports
wifi_tx <= wifi_data_out;
wifi_ready <= wifi_ready_sig;
end Behavioral;
Page 4 of 12
MODULE 2 - UART TRANSMISSION
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity UART_TX is
generic (
g_CLKS_PER_BIT : integer := 115 -- Needs to be set correctly
);
port (
i_Clk : in std_logic;
i_TX_DV : in std_logic;
i_TX_Byte : in std_logic_vector(7 downto 0);
o_TX_Active : out std_logic;
o_TX_Serial : out
std_logic; o_TX_Done :
out std_logic
);
end UART_TX;
architecture RTL of UART_TX is
type t_SM_Main is (s_Idle, s_TX_Start_Bit, s_TX_Data_Bits,
s_TX_Stop_Bit, s_Cleanup);
signal r_SM_Main : t_SM_Main := s_Idle;
signal r_Clk_Count : integer range 0 to g_CLKS_PER_BIT-1 := 0;
signal r_Bit_Index : integer range 0 to 7 := 0; -- 8 Bits Total
signal r_TX_Data : std_logic_vector(7 downto 0) := (others =>
'0'); signal r_TX_Done : std_logic := '0';
begin
p_UART_TX : process (i_Clk)
begin
if rising_edge(i_Clk) then
case r_SM_Main is
when s_Idle =>
o_TX_Active <= '0';
o_TX_Serial <= '1'; -- Drive Line High for
Idle r_TX_Done <= '0';
r_Clk_Count <= 0;
r_Bit_Index <= 0;
if i_TX_DV = '1' then
r_TX_Data <= i_TX_Byte;
Page 5 of 12
r_SM_Main <= s_TX_Start_Bit;
else
r_SM_Main <= s_Idle;
end if;
-- Send out Start Bit. Start bit =
0 when s_TX_Start_Bit =>
o_TX_Active <= '1';
o_TX_Serial <= '0';
-- Wait g_CLKS_PER_BIT-1 clock cycles for start bit to
finish if r_Clk_Count < g_CLKS_PER_BIT-1 then
r_Clk_Count <= r_Clk_Count + 1;
r_SM_Main <= s_TX_Start_Bit;
else
r_Clk_Count <= 0;
r_SM_Main <= s_TX_Data_Bits;
end if;
-- Wait g_CLKS_PER_BIT-1 clock cycles for data bits to
finish when s_TX_Data_Bits =>
o_TX_Serial <= r_TX_Data(r_Bit_Index);
if r_Clk_Count < g_CLKS_PER_BIT-1 then
r_Clk_Count <= r_Clk_Count + 1;
r_SM_Main <= s_TX_Data_Bits;
else
r_Clk_Count <= 0;
-- Check if we have sent out all
bits if r_Bit_Index < 7 then
r_Bit_Index <= r_Bit_Index + 1;
r_SM_Main <= s_TX_Data_Bits;
else
r_Bit_Index <= 0;
r_SM_Main <= s_TX_Stop_Bit;
end if;
end if;
-- Send out Stop bit. Stop bit = 1
when s_TX_Stop_Bit =>
o_TX_Serial <= '1';
-- Wait g_CLKS_PER_BIT-1 clock cycles for Stop bit to
finish if r_Clk_Count < g_CLKS_PER_BIT-1 then
r_Clk_Count <= r_Clk_Count + 1;
r_SM_Main <= s_TX_Stop_Bit;
else
r_TX_Done <= '1';
r_Clk_Count <= 0;
r_SM_Main <= s_Cleanup;
Page 6 of 12
end if;
-- Stay here 1 clock
when s_Cleanup =>
o_TX_Active <= '0';
r_TX_Done <= '1';
r_SM_Main <= s_Idle;
when others =>
r_SM_Main <= s_Idle;
end case;
end if;
end process p_UART_TX;
o_TX_Done <= r_TX_Done;
end RTL;
MODULE 3 – UART RECEIVER
library ieee;
use ieee.std_logic_1164.ALL;
use ieee.numeric_std.all;
entity UART_RX is
generic (
g_CLKS_PER_BIT : integer := 115 -- Needs to be set correctly
);
port (
i_Clk : in std_logic;
i_RX_Serial : in std_logic;
o_RX_DV : out std_logic;
o_RX_Byte : out std_logic_vector(7 downto 0)
);
end UART_RX;
architecture rtl of UART_RX is
type t_SM_Main is (s_Idle, s_RX_Start_Bit, s_RX_Data_Bits,
s_RX_Stop_Bit, s_Cleanup);
signal r_SM_Main : t_SM_Main := s_Idle;
signal r_RX_Data_R : std_logic :=
'0'; signal r_RX_Data : std_logic :=
'0';
signal r_Clk_Count : integer range 0 to g_CLKS_PER_BIT-1 := 0;
signal r_Bit_Index : integer range 0 to 7 := 0; -- 8 Bits Total
signal r_RX_Byte : std_logic_vector(7 downto 0) := (others =>
'0'); signal r_RX_DV : std_logic := '0';
Page 7 of 12
begin
-- Purpose: Double-register the incoming data.
-- This allows it to be used in the UART RX Clock Domain.
-- (It removes problems caused by
metastabiliy) p_SAMPLE : process (i_Clk)
begin
if rising_edge(i_Clk) then
r_RX_Data_R <= i_RX_Serial;
r_RX_Data <= r_RX_Data_R;
end if;
end process p_SAMPLE;
-- Purpose: Control RX state
machine p_UART_RX : process
(i_Clk)
begin
if rising_edge(i_Clk) then
case r_SM_Main is
when s_Idle =>
r_RX_DV <= '0';
r_Clk_Count <= 0;
r_Bit_Index <= 0;
if r_RX_Data = '0' then -- Start bit
detected r_SM_Main <= s_RX_Start_Bit;
else
r_SM_Main <= s_Idle;
end if;
-- Check middle of start bit to make sure it's still low
when s_RX_Start_Bit =>
if r_Clk_Count = (g_CLKS_PER_BIT-1)/2 then
if r_RX_Data = '0' then
r_Clk_Count <= 0; -- reset counter since we found the middle
r_SM_Main <= s_RX_Data_Bits;
else
r_SM_Main <= s_Idle;
end if;
else
r_Clk_Count <= r_Clk_Count +
1; r_SM_Main <=
s_RX_Start_Bit; end if;
-- Wait g_CLKS_PER_BIT-1 clock cycles to sample serial data
when s_RX_Data_Bits =>
if r_Clk_Count < g_CLKS_PER_BIT-1 then
r_Clk_Count <= r_Clk_Count + 1;
r_SM_Main <= s_RX_Data_Bits;
else
r_Clk_Count <= 0;
Page 8 of 12
r_RX_Byte(r_Bit_Index) <= r_RX_Data;
-- Check if we have sent out all
bits if r_Bit_Index < 7 then
r_Bit_Index <= r_Bit_Index + 1;
r_SM_Main <= s_RX_Data_Bits;
else
r_Bit_Index <= 0;
r_SM_Main <= s_RX_Stop_Bit;
end if;
end if;
-- Receive Stop bit. Stop bit = 1
when s_RX_Stop_Bit =>
-- Wait g_CLKS_PER_BIT-1 clock cycles for Stop bit to
finish if r_Clk_Count < g_CLKS_PER_BIT-1 then
r_Clk_Count <= r_Clk_Count + 1;
r_SM_Main <= s_RX_Stop_Bit;
else
r_RX_DV <= '1';
r_Clk_Count <= 0;
r_SM_Main <= s_Cleanup;
end if;
-- Stay here 1 clock
when s_Cleanup =>
r_SM_Main <= s_Idle;
r_RX_DV <= '0'; when others =>
r_SM_Main <= s_Idle;
end case;
end if;
end process p_UART_RX;
o_RX_DV <= r_RX_DV;
o_RX_Byte <= r_RX_Byte;
end rtl;
MODULE 4 – TOP MODULE
library ieee;
use ieee.std_logic_1164.all;
entity Top_Module is
port (
clk : in std_logic;
reset : in std_logic;
i_RX_Serial : in std_logic;
o_RX_DV : out std_logic;
Page 9 of 12
o_RX_Byte : out std_logic_vector(7 downto
0); i_TX_DV : in std_logic;
i_TX_Byte : in std_logic_vector(7 downto 0);
o_TX_Active : out std_logic;
o_TX_Serial : out std_logic; -- Change to std_logic
o_TX_Done : out std_logic;
wifi_rx : in std_logic_vector(7 downto 0);
wifi_tx : out std_logic_vector(7 downto 0);
wifi_ready : out std_logic
);
end entity Top_Module;
architecture Behavioral of Top_Module is
component UART_RX is
generic (
g_CLKS_PER_BIT : integer := 115
);
port (
i_Clk : in std_logic;
i_RX_Serial : in std_logic;
o_RX_DV : out std_logic;
o_RX_Byte : out std_logic_vector(7 downto 0)
);
end component UART_RX;
component UART_TX is
generic (
g_CLKS_PER_BIT : integer := 115
);
port (
i_Clk : in std_logic;
i_TX_DV : in std_logic;
i_TX_Byte : in std_logic_vector(7 downto 0);
o_TX_Active : out std_logic;
o_TX_Serial : out std_logic; -- Change to std_logic
o_TX_Done : out std_logic
);
end component UART_TX;
component WiFi_Interface is
port (
clk : in std_logic;
reset : in std_logic;
wifi_rx : in std_logic_vector(7 downto 0);
wifi_tx : out std_logic_vector(7 downto 0);
wifi_ready : out std_logic
);
end component WiFi_Interface;
signal uart_rx_dv, uart_tx_active, uart_tx_done : std_logic;
signal uart_rx_byte, wifi_data_out : std_logic_vector(7 downto 0);
Page 10 of 12
signal wifi_ready_sig : std_logic;
begin
UART_RX_inst : UART_RX
generic map
( g_CLKS_PER_BIT => 115
)
port map (
i_Clk => clk,
i_RX_Serial =>
i_RX_Serial, o_RX_DV
=> uart_rx_dv,
o_RX_Byte => uart_rx_byte
);
UART_TX_inst : UART_TX
generic map
( g_CLKS_PER_BIT => 115
)
port map (
i_Clk => clk,
i_TX_DV => i_TX_DV,
i_TX_Byte => i_TX_Byte,
o_TX_Active => uart_tx_active,
o_TX_Serial => o_TX_Serial, -- Corrected port mapping
o_TX_Done => uart_tx_done
);
WiFi_Interface_inst : WiFi_Interface
port map (
clk => clk,
reset => reset,
wifi_rx => wifi_rx,
wifi_tx => wifi_data_out,
wifi_ready => wifi_ready_sig
);
-- Assign outputs
o_RX_DV <= uart_rx_dv;
o_RX_Byte <= uart_rx_byte;
o_TX_Active <= uart_tx_active;
o_TX_Done <= uart_tx_done;
wifi_tx <= wifi_data_out;
wifi_ready <= wifi_ready_sig;
end architecture Behavioral;
Page 11 of 12
7. RTL:
8. RESOURCE UTILIZATION SUMMARY TABLE:
9. OUTPUT WAVEFORM:
Page 12 of 12