25
ECE 551 Digital System Design Final Project Distance measurement between two object using RF signal communications Group 7 Md Badruddoja Majumder Jiali Li

ECE 551 Digital System Design Final Project

  • Upload
    others

  • View
    6

  • Download
    0

Embed Size (px)

Citation preview

ECE 551

Digital System Design

Final Project

Distance measurement between two object using RF signal communications

Group 7

Md Badruddoja Majumder

Jiali Li

Objective: The aim of this project is to develop a system on chip that can be used to measure the distance between

two objects. The idea is using a RF transmitter in one object and a RF receiver in other object to measure

the distance between them based on the received signal strength value. Different parts of the system

will be developed with hardware description language, VHDL, combined together and implemented on

a Xilinx 6-series fpga and a Nexys 4 fpga board.

Background: Localization of an object in a wireless sensor network is an active research area. The location of an

object within a wireless sensor network can be obtained based on the interaction with other nodes.

There are a number of ways for finding the location of an object in a wireless network. Few of the

methods are Global Positioning System (GPS), Radio frequency identification (RFID), measurement of

different parameters such as Time of arrival (TOA) , Angle of arrival (AOA), Radio signal strength

indicator (RSSI). In this project, we have chosen RSSI based localization technique to measure the

location of an object relative to another object.

Received power of a RF signal reduces as the signal propagates through a path after being transmitted.

In an ideal case where there is no interference occurs in the signal propagation due to other objects in

the surrounding environment, received signal power is inversely proportional to the square of the

distance between transmitter and receiver. In this ideal case the distance can be measured directly

from the observed RSSI of the received signal. However, to improve accuracy an offline classifier is

useful that classifies a given RSSI to a distance after being trained by a large number of known RSSI

and corresponding distances.

Tools to be used:

Two WARP (Wireless open access research platform) v3 board, one 680 X 480 VGA display are the

main tools going to be used in this project. Some of the features of WARP V3 board is:

Xilinx Virtex-6 LX240T FPGA;

programmable RF interfaces, each with:

12-bit 170MSps DACs,12-bit 100MSps ADCs;

Dual-band PA(20dBm Tx power);

2.4/5GHz transceiver (40MHz RF bandwidth);

Overall Design:

Figure 1. Overall system block diagram

We utilize the on-the-board RF communication interface for transmitting and receiving analog signal,

which is used to detect the location of moving object. From transmitter part, I/Q data was send out as

packet. Transmitter and receiver were controlled by Matlab code from PC port, these two boards connect

with PC via Ethernet cable. We calculate RSSI value in Matlab using I (or Q) data, and send RSSI value

to Nexys 4 board for distance determining process. Based on the relationship of distance and RSSI

value, Nexys 4 board will display distance per 15 cm. We use VGA to display the location of the object

as a visual output.

Communication Interface:

Figure 2. Transmitter part diagram

We planned to use broadband signal to get more information which would be helpful when we analyzing

the relationship between RSSI and distance. In this case, we need some modulation process of primary

data stream. After the process of Orthogonal Frequency Division Multiplexing (OFDM) modulation, I/Q

data would be send out from transmitter port. We use Matlab code to generate random data and control

the transmitter to send I/Q data out.

RF A

(Transmitter)

RF B

(Receiver)

Signal Matlab Control

Nexys 4

(Processor) VGA

Figure 3. Receiver part diagram

After the I/Q data received from antenna, it was sent to Matlab and showed in console. We calculate the

root-mean-square value of I data in decibel, which represents the strength of the received signal also

known as RSSI value. We throughput the RSSI value to Nexys 4, and compare it with calibration set to

output the distance between the transmitter and receiver. The relationship of distance and RSSI value

comes from average result of several experiments. Distance and RSSI (db) value are displayed in both

7 segment and VGA.

Signal Processing Unit:

Data Transfer from MATLAB:

Actual analog RF signal received by the receiver node is converted to digital value with an on

board 12 bit ADC. Receiver receives data packet as both in phase, I and quadrature, Q

components. However, both of I and Q signals are same but differing in phase. We simply

considered the in phase samples, I for measuring RSSI of the received signal. Received data

in MATLAB is sent to the processing FPGA (Nexys 4 board) through UART interface. While

sending the received signal from MATLAB to processing FPGA, samples are quantized with 8

bit resolution for a range of 0 to 1 V. Though this reduction in the sample resolution from 12 bit

to 8 bit reduces the resolution of distance measurement, it makes the speed of the whole system

in real time faster. For RSSI measurement, we just need the absolute value of samples and

that’s why signal range is considered as 0 to 1 V, rather than considering the actual range -1 to

1 V.

Figure 4. Signal processing unit

Matlab Nexys4 RSSI Signal

VGA Distance

Value Antenna

I/Q Data

RSSI calculation:

Received signal samples from MATLAB are taken into a finite state machine implemented in

VHDLfor RSSI calculation. RSSI is basically calculating the received signal power. For RSSI

calculation, we followed the basic algorithm of calculating power of a digital signal. It involves

multiple operation such as calculating sum of square of received samples, averaging over total

number of samples and converting into decibel. Instead of directly converting the signal power

to db, we first calculated square root of the signal power which represent the root mean square

of the signal. Signal power (RSSI) in db can be measured then using the following formula.

𝑅𝑆𝑆𝐼 (𝑑𝑏) = 20 ∗ 𝑙𝑜𝑔10 (𝑉𝑟𝑚𝑠 ) .

Figure 5: Finite state machine for calculating RSSI in VHDL

FSM for rssi calculation in VHDL:

S0 (Sum of Square):

This state is the initial state which starts after every reset. In this state, received samples, x from

UART are squared and accumulated in a variable sum. A counting variable, cnt is counting by

1 in every iteration. FSM remains in the same state if cnt is less than a predefined number of

samples. Otherwise, it goes to next state S1. We considered 1000 samples for calculating signal

power in every measurement.

S1 (Average):

In this state, signal energy calculated in the previous state is averaged over the total number of

samples. We used a customized integer division operation to perform this operation. The

divisor, cnt is multiplied by a integer variable, i counting from 1. if the remainder, d is greater

than or equal the divisor, FSM remains in the same state. Otherwise, it goes to the next state.

At the end of this state, the counting integer variable, i contains the signal power rounded to

nearest integer.

S2 (Square root):

In this state, floored square root of the signal power is estimated. A counting integer variable, j

is squared at each clock cycle. If the product is less than the estimated signal power measured

in the previous state, FSM remains in the same state. Otherwise, it goes into the next state and

the count variable, j is decremented by 1. At the end of this state j represents the square root of

signal power or root mean square of the signal samples.

Sreset (Reset):

This is the reset state which takes the FSM into the first state and allows a new measurement

of rssi. A reset signal is sent from MATLAB after sending every data packets of 1000 samples.

Reset state can be reached by an external state as well. In the reset state, all variables used in

the signal rssi measurement are reset to 0.

Decibel Conversion:

The most common and convenient unit used to represent a RF signal strength is decibel (db).

Calculated signal rms value is converted into equivalent decibel (db) using a lookup table. Since

the probable db range for the received signal is known, it is more efficient to use a lookup table

for converting the signal power into db. Moreover, generalized db calculation in hardware is not

only difficult but also has accuracy issue. As the sampled signals are quantized using 8 bits

while sending through UART, possible db value would be one of 256 values. We generated a

log table in matlab that corresponds to all possible 8 bit quantized signal samples within 0 and

1. db value is represented using 16 bits; 8 for representing the whole number and 8 bits for the

fraction up to two digits. Generated log table is written in a coefficient (.coe) file which is stored

in a block ram. RMS signal value is given to that block ram as its address and corresponding

db value is found.

Simulation Results:

.

Figure 6: Test simulation for rssi calculation.

Above simulation waveform shows the calculation of signal rssi in db for 10 test samples.

From the simulation, it can be seen that, signal energy result becomes available first. After

that, in the next state, signal power become available. Signal rms value is calculated using

signal power in the next state. Finally rms value is fed into block ram containing the log table

and gives the rssi of the signal in db. In the following simulation waveform a rounded db value

is shown, though we considered floating points for the decibel value in the project. Simulated

results perfectly matched with the simulation of same algorithm in MATLAB.

Calibration:

Calibration is one of the most important parts of this project. In this calibration phase, we tried to

measure rssi of the received signal for different distances between the transmitter and receiver. This

measurement is performed for a number of times and some statistical analysis is performed over it. For

each set of measurement, the range of rssi value corresponding to each distances are recorded and

the most frequently occurred range is considered for calibration. For distance measurement, we

restricted the maximum distance to 105 cm, as we were using a low gain for rx gain controller. However,

we could use a larger range for distance by increasing the rx gain. But the resolution will be scaled

down to too with the scaling of distance range. We could not go higher than 15 cm resolution as the

rssi ranges between two successive distances start to overlap with one another and measurement

becomes unreliable.

Figure 7: Calibration data for measuring distance using rssi of received signal

Display Unit:

We used both 7 segment and VGA displays for showing the measured distance between the

transmitter and receiver. Rightmost four displays in the Nexys 4 board show the measured rssi

value in db. Rssi value is displayed in binary coded decimal value. Leftmost four displays show

the distance value in cm. A bcd representation is used here too for the distance display.

We also implemented a simple VGA display for showing the relative distance between the

transmitter and receiver graphically. Two vertical bars are used of two different colours to

represent the location of the transmitter and receiver. Whenever, processing unit measures a

new distance , VGA updates the relative position of the receiver as compared to the transmitter.

Distance is represented as a multiple of 15 cm equivalent in the VGA display. Any intermediate

distance gives only a rounded value of the multiples of 15 cm up to 105 cm.

FIgure 8: Display unit (VGA and 7 segment)

Conclusion: This project is intended for having a hands on experience of fpga based system on chip design. The

overall system consists of a communication protocol, signal processing unit and a display unit. These

components are built on a fpga and added together to make the overall system on chip. There are a

number of challenges are associated with the project. Adjusting receiver gain to a suitable value that

allows distance measurement within a reasonable resolution was difficult. As a number of

communications between different devices are involved in this project, speed of the whole system in

Output processing unit

VGA display

(640X480)

VGA controller

RGB input

Clock

RGB

Sync signal

Result from

signal

distance Rssi (db)

7- segment display

real time was a great challenge. However, by maintaining a optimization between the measurement

accuracy, resolution and speed we were able to reach a point that worked really good in real time.

Appendix:

VHDL Source code:

library IEEE;

use IEEE.STD_LOGIC_1164.ALL;

use IEEE.NUMERIC_STD.ALL;

-- Uncomment the following library declaration if instantiating

-- any Xilinx leaf cells in this code.

--library UNISIM;

--use UNISIM.VComponents.all;

entity rssi_new is

Port ( uart_tx : out STD_LOGIC;

uart_rx : in STD_LOGIC;

seg: out std_logic_vector(6 downto 0);

an: out std_logic_vector(7 downto 0);

dp: out std_logic;

led: out std_logic_vector(15 downto 0);

clk : in STD_LOGIC;

rst : in STD_LOGIC;

rgb: out std_logic_vector (2 downto 0);

HS : out std_logic;

VS : out std_logic);

end rssi_new;

architecture Behavioral of rssi_new is

component vga_controller is

port(

rst : in std_logic;

clk_in : in std_logic;

sw: in std_logic_vector (2 downto 0);

rgb: out std_logic_vector (2 downto 0);

HS : out std_logic;

VS : out std_logic

-- hcount : out std_logic_vector(10 downto 0);

--vcount : out std_logic_vector(10 downto 0);

--blank : out std_logic

);

end component;

component uart_tx6

Port ( data_in : in std_logic_vector(7 downto 0);

en_16_x_baud : in std_logic;

serial_out : out std_logic;

buffer_write : in std_logic;

buffer_data_present : out std_logic;

buffer_half_full : out std_logic;

buffer_full : out std_logic;

buffer_reset : in std_logic;

clk : in std_logic);

end component;

component uart_rx6

Port ( serial_in : in std_logic;

en_16_x_baud : in std_logic;

data_out : out std_logic_vector(7 downto 0);

buffer_read : in std_logic;

buffer_data_present : out std_logic;

buffer_half_full : out std_logic;

buffer_full : out std_logic;

buffer_reset : in std_logic;

clk : in std_logic);

end component;

--signals that connect to uart transmitter

signal uart_tx_data_in : std_logic_vector(7 downto 0);

signal write_to_uart_tx : std_logic;

signal uart_tx_data_present : std_logic;

signal uart_tx_half_full : std_logic;

signal uart_tx_full : std_logic;

signal uart_tx_reset : std_logic;

signal clk_out2 : std_logic;

--signals that connect to uart receiver

signal uart_rx_data_out : std_logic_vector(7 downto 0);

signal read_from_uart_rx : std_logic;

signal uart_rx_data_present : std_logic;

signal uart_rx_half_full : std_logic;

signal uart_rx_full : std_logic;

signal uart_rx_reset : std_logic;

--signals controlling baud rate

signal baud_count : integer range 0 to 1024 := 0;

signal en_16_x_baud : std_logic := '0';

signal x: std_logic_vector(7 downto 0);

signal sum_sig: std_logic_vector(31 downto 0);

signal divisor : STD_LOGIC_VECTOR (15 downto 0);

signal dividend : STD_LOGIC_VECTOR (31 downto 0);

signal quotient :STD_LOGIC_VECTOR (15 downto 0);

signal sqrt_quotient: std_logic_vector(15 downto 0);

signal remainder,data :STD_LOGIC_VECTOR (15 downto 0);

signal bcd1,bcd2,bcd3,bcd4,dontcare1,dontcare2: std_logic_vector(3 downto 0);

signal trig1,trig2: std_logic;

TYPE State_type IS (S0,S1, S2, S3, S4, S5, S6); -- Define the states

Type state_type1 is (P0,P1,P2);

Type state_type2 is (Q0, Q1,Q2);

SIGNAL State : State_Type; -- Create a signal that uses

signal state_1: state_type1;

signal state_2: state_type2;

signal val: integer range 0 to 10000;

signal distance: std_logic_vector(7 downto 0);

signal dbcd1,dbcd2,dbcd3: std_logic_vector(3 downto 0);

signal dist: std_logic_vector(2 downto 0);

COMPONENT blk_mem_gen_0

PORT (

clka : IN STD_LOGIC;

wea : IN STD_LOGIC_VECTOR(0 DOWNTO 0);

addra : IN STD_LOGIC_VECTOR(7 DOWNTO 0);

dina : IN STD_LOGIC_VECTOR(15 DOWNTO 0);

douta : OUT STD_LOGIC_VECTOR(15 DOWNTO 0)

);

END COMPONENT;

COMPONENT clockdivider

Port ( clk_in : in STD_LOGIC;

count_val: in integer range 0 to 1000000000;

clk_out : out STD_LOGIC);

end component;

component bcd is

Port (

number : in std_logic_vector (7 downto 0);

hundreds : out std_logic_vector (3 downto 0);

tens : out std_logic_vector (3 downto 0);

ones : out std_logic_vector (3 downto 0)

);

end component;

begin

vga_cnt: vga_controller port map(rst,clk,dist,rgb,HS,VS);

bcd_c1: bcd port map(data(15 downto 8),dontcare1,bcd1,bcd2);

bcd_c2: bcd port map(data(7 downto 0),dontcare2,bcd3,bcd4);

bcd_c3: bcd port map(distance,dbcd1,dbcd2,dbcd3);

tx: uart_tx6

port map ( data_in => uart_tx_data_in,

en_16_x_baud => en_16_x_baud,

serial_out => uart_tx,

buffer_write => write_to_uart_tx,

buffer_data_present => uart_tx_data_present,

buffer_half_full => uart_tx_half_full,

buffer_full => uart_tx_full,

buffer_reset => uart_tx_reset,

clk => clk);

rx: uart_rx6

port map ( serial_in => uart_rx,

en_16_x_baud => en_16_x_baud,

data_out => uart_rx_data_out,

buffer_read => read_from_uart_rx,

buffer_data_present => uart_rx_data_present,

buffer_half_full => uart_rx_half_full,

buffer_full => uart_rx_full,

buffer_reset => uart_rx_reset,

clk => clk);

baud_rate: process(clk)

begin

if clk'event and clk = '1' then

if baud_count = 651 then -- counts 54 states including zero

baud_count <= 0;

en_16_x_baud <= '1'; -- single cycle enable pulse

else

baud_count <= baud_count + 1;

en_16_x_baud <= '0';

end if;

end if;

end process baud_rate;

write_to_uart_tx <= '1' when uart_tx_full='0'

else '0';

read_from_uart_rx <= '1' when uart_rx_data_present='1'

else '0';

uart_rx_data_out<=uart_tx_data_in;

--led<=quotient;

x<=uart_rx_data_out(7 downto 0);

db_ram: blk_mem_gen_0

PORT MAP (

clka => clk,

wea => "0",

addra => sqrt_quotient(7 downto 0),

dina => "0000000000000000",

douta => data

);

--led<=bcd1&bcd2&bcd3&bcd4;

--led<=sqrt_quotient;

-- RSSI calculation FSM

process(clk)

variable mul_ind,sqrt_ind: integer range 0 to (2**16)-1:=0;

variable temp_prod: unsigned (31 downto 0);

variable temp_rem: unsigned (31 downto 0);

variable prod: std_logic_vector(15 downto 0);

variable sum: std_logic_vector(31 downto 0);

variable count: integer range 0 to 1000000000;

begin

if(clk'event and clk='1')then

if (rst='1')then

state<=S0;

state_1<=P0;

state_2<=Q0;

sum:="00000000000000000000000000000000";

mul_ind:=0;

count:=0;

sqrt_ind:=0;

else

Case state is

when S0=>

if(read_from_uart_rx='1') then

count:=count+1;

prod:=std_logic_vector(unsigned(x)*unsigned(x));

sum:=std_logic_vector(unsigned(sum)+unsigned(prod));

--led<=sum(15 downto 0);

led<=prod;

end if;

if (count<1000)then

state<=S0;

else

sum_sig<=sum;

state<=S1;

end if;

when S1=>

divisor<=std_logic_vector(to_unsigned(count,16));

state<=S2;

when S2=>

dividend<=sum_sig;

state<=S3;

when S3=>

temp_prod:=unsigned(divisor)*to_unsigned(mul_ind,16);

temp_rem:=unsigned(dividend)-temp_prod;

IF(to_integer(temp_rem) < to_integer(unsigned(divisor))) THEN

state<=S4;

else

state<=S3;

mul_ind:=mul_ind+1;

end if;

when S4=>

quotient<=std_logic_vector(to_unsigned(mul_ind,16));

remainder<=std_logic_vector(temp_rem(15 downto 0));

state<=S5 ;

when S5=>

prod:=std_logic_vector(to_unsigned((sqrt_ind*sqrt_ind),16));

if(to_integer(unsigned(prod))>to_integer(unsigned(quotient)))then

state<=S6;

sqrt_ind:=sqrt_ind-1;

else

state<=S5;

sqrt_ind:=sqrt_ind+1;

end if;

when S6=>

sqrt_quotient<=std_logic_vector(to_unsigned(sqrt_ind,16));

state<=S6;

--trig1<='1';

--trig2<='1';

led<=sqrt_quotient;

if (x="11111111")then

state<=S0;

state_1<=P0;

state_2<=Q0;

sum:="00000000000000000000000000000000";

mul_ind:=0;

count:=0;

sqrt_ind:=0;

end if;

end case;

end if;

end if;

end process;

val<=to_integer(unsigned(data(15 downto 8)));

--calibration:

process(val)

begin

if (val>=1 and val<=6)then

distance<=std_logic_vector(to_unsigned(15,8));

dist<=std_logic_vector(to_unsigned(1,3));

elsif (val>=7 and val<=14)then

distance<=std_logic_vector(to_unsigned(30,8));

dist<=std_logic_vector(to_unsigned(2,3));

elsif (val>=15 and val<=20)then

distance<=std_logic_vector(to_unsigned(45,8));

dist<=std_logic_vector(to_unsigned(3,3));

elsif (val>=21 and val<=23)then

distance<=std_logic_vector(to_unsigned(60,8));

dist<=std_logic_vector(to_unsigned(4,3));

elsif (val>=24 and val<=27)then

distance<=std_logic_vector(to_unsigned(75,8));

dist<=std_logic_vector(to_unsigned(5,3));

elsif (val>=28 and val<=34)then

distance<=std_logic_vector(to_unsigned(90,8));

dist<=std_logic_vector(to_unsigned(6,3));

elsif (val>=35 and val<=39)then

distance<=std_logic_vector(to_unsigned(105,8));

dist<=std_logic_vector(to_unsigned(7,3));

else

distance<=std_logic_vector(to_unsigned(105,8));

dist<=std_logic_vector(to_unsigned(7,3));

end if;

end process;

st1: clockdivider port map(clk_in=>clk,count_val=>5000,clk_out=>clk_out2);

process(clk_out2)

variable count: integer range 0 to 8 :=0;

begin

if (clk_out2'event and clk_out2='1')then

if(count=0)then

an<="11111011";

dp<='0';

case bcd2 is

when "0000" => seg<="0000001";

when "0001" => seg<="1001111";

when "0010" => seg<="0010010";

when "0011" => seg<="0000110";

when "0100" => seg<="1001100";

when "0101" => seg<="0100100";

when "0110" => seg<="0100000";

when "0111" => seg<="0001111";

when "1000" => seg<="0000000";

when "1001" => seg<="0000100";

when "1010" => seg<="0001000";

when "1011" => seg<="1100000";

when "1100" => seg<="0110001";

when "1101" => seg<="1000010";

when "1110" => seg<="0110000";

when "1111" => seg<="0111000";

end case;

elsif(count=1)then

an<="11110111";

dp<='1';

case bcd1 is

when "0000" => seg<="0000001";

when "0001" => seg<="1001111";

when "0010" => seg<="0010010";

when "0011" => seg<="0000110";

when "0100" => seg<="1001100";

when "0101" => seg<="0100100";

when "0110" => seg<="0100000";

when "0111" => seg<="0001111";

when "1000" => seg<="0000000";

when "1001" => seg<="0000100";

when "1010" => seg<="0001000";

when "1011" => seg<="1100000";

when "1100" => seg<="0110001";

when "1101" => seg<="1000010";

when "1110" => seg<="0110000";

when "1111" => seg<="0111000";

end case;

elsif(count=2)then

an<="11111110";

dp<='1';

case bcd4 is

when "0000" => seg<="0000001";

when "0001" => seg<="1001111";

when "0010" => seg<="0010010";

when "0011" => seg<="0000110";

when "0100" => seg<="1001100";

when "0101" => seg<="0100100";

when "0110" => seg<="0100000";

when "0111" => seg<="0001111";

when "1000" => seg<="0000000";

when "1001" => seg<="0000100";

when "1010" => seg<="0001000";

when "1011" => seg<="1100000";

when "1100" => seg<="0110001";

when "1101" => seg<="1000010";

when "1110" => seg<="0110000";

when "1111" => seg<="0111000";

end case;

elsif(count=3)then

dp<='1';

an<="11111101";

case bcd3 is

when "0000" => seg<="0000001";

when "0001" => seg<="1001111";

when "0010" => seg<="0010010";

when "0011" => seg<="0000110";

when "0100" => seg<="1001100";

when "0101" => seg<="0100100";

when "0110" => seg<="0100000";

when "0111" => seg<="0001111";

when "1000" => seg<="0000000";

when "1001" => seg<="0000100";

when "1010" => seg<="0001000";

when "1011" => seg<="1100000";

when "1100" => seg<="0110001";

when "1101" => seg<="1000010";

when "1110" => seg<="0110000";

when "1111" => seg<="0111000";

end case;

elsif(count=4)then

an<="11101111";

case dbcd3 is

when "0000" => seg<="0000001";

when "0001" => seg<="1001111";

when "0010" => seg<="0010010";

when "0011" => seg<="0000110";

when "0100" => seg<="1001100";

when "0101" => seg<="0100100";

when "0110" => seg<="0100000";

when "0111" => seg<="0001111";

when "1000" => seg<="0000000";

when "1001" => seg<="0000100";

when "1010" => seg<="0001000";

when "1011" => seg<="1100000";

when "1100" => seg<="0110001";

when "1101" => seg<="1000010";

when "1110" => seg<="0110000";

when "1111" => seg<="0111000";

end case;

elsif(count=5)then

an<="11011111";

case dbcd2 is

when "0000" => seg<="0000001";

when "0001" => seg<="1001111";

when "0010" => seg<="0010010";

when "0011" => seg<="0000110";

when "0100" => seg<="1001100";

when "0101" => seg<="0100100";

when "0110" => seg<="0100000";

when "0111" => seg<="0001111";

when "1000" => seg<="0000000";

when "1001" => seg<="0000100";

when "1010" => seg<="0001000";

when "1011" => seg<="1100000";

when "1100" => seg<="0110001";

when "1101" => seg<="1000010";

when "1110" => seg<="0110000";

when "1111" => seg<="0111000";

end case;

elsif(count=6)then

an<="10111111";

case dbcd1 is

when "0000" => seg<="0000001";

when "0001" => seg<="1001111";

when "0010" => seg<="0010010";

when "0011" => seg<="0000110";

when "0100" => seg<="1001100";

when "0101" => seg<="0100100";

when "0110" => seg<="0100000";

when "0111" => seg<="0001111";

when "1000" => seg<="0000000";

when "1001" => seg<="0000100";

when "1010" => seg<="0001000";

when "1011" => seg<="1100000";

when "1100" => seg<="0110001";

when "1101" => seg<="1000010";

when "1110" => seg<="0110000";

when "1111" => seg<="0111000";

end case;

end if;

count :=count+1;

if (count=7)then

count :=0;

end if;

end if;

end process;

end Behavioral;

Code for RSSI calculation:

library IEEE;

use IEEE.STD_LOGIC_1164.ALL;

-- Uncomment the following library declaration if using

-- arithmetic functions with Signed or Unsigned values

use IEEE.NUMERIC_STD.ALL;

-- Uncomment the following library declaration if instantiating

-- any Xilinx leaf cells in this code.

library UNISIM;

use UNISIM.VComponents.all;

entity RSSI_calc is

Port ( clk : in STD_LOGIC;

rst : in STD_LOGIC;

din : in STD_LOGIC_VECTOR(7 downto 0);

rms : out STD_LOGIC_VECTOR (7 downto 0);

db : out STD_LOGIC_VECTOR (7 downto 0));

end RSSI_calc;

architecture Behavioral of RSSI_calc is

signal sum_sig: std_logic_vector(31 downto 0);

signal divisor : STD_LOGIC_VECTOR (15 downto 0);

signal dividend : STD_LOGIC_VECTOR (31 downto 0);

signal quotient :STD_LOGIC_VECTOR (15 downto 0);

signal sqrt_quotient: std_logic_vector(15 downto 0);

signal remainder,data :STD_LOGIC_VECTOR (15 downto 0);

signal db_val: std_logic_vector(15 downto 0);

TYPE State_type IS (S0,S1, S2, S3, S4, S5, S6);

SIGNAL State : State_Type;

COMPONENT blk_mem_gen_0

PORT (

clka : IN STD_LOGIC;

wea : IN STD_LOGIC_VECTOR(0 DOWNTO 0);

addra : IN STD_LOGIC_VECTOR(7 DOWNTO 0);

dina : IN STD_LOGIC_VECTOR(15 DOWNTO 0);

douta : OUT STD_LOGIC_VECTOR(15 DOWNTO 0)

);

END COMPONENT;

begin

db_calc: blk_mem_gen_0

PORT MAP (

clka => clk,

wea => "0",

addra => sqrt_quotient(7 downto 0),

dina => "0000000000000000",

douta => db_val

);

db<=db_val(15 downto 8); --whole number part of the db value

process(clk)

variable mul_ind,sqrt_ind: integer range 0 to (2**16)-1:=0;

variable temp_prod: unsigned (31 downto 0);

variable temp_rem: unsigned (31 downto 0);

variable prod: std_logic_vector(15 downto 0);

variable sum: std_logic_vector(31 downto 0);

variable count: integer range 0 to 1000000000;

begin

if(clk'event and clk='1')then

if (rst='1')then

state<=S0;

sum:="00000000000000000000000000000000";

mul_ind:=0;

count:=0;

sqrt_ind:=0;

else

Case state is

when S0=>

--if(read_from_uart_rx='1') then

count:=count+1;

prod:=std_logic_vector(unsigned(x)*unsigned(x));

sum:=std_logic_vector(unsigned(sum)+unsigned(prod));

--led<=sum(15 downto 0);

led<=prod;

--end if;

if (count<1000)then

state<=S0;

else

sum_sig<=sum;

state<=S1;

end if;

when S1=>

divisor<=std_logic_vector(to_unsigned(count,16));

state<=S2;

when S2=>

dividend<=sum_sig;

state<=S3;

when S3=>

temp_prod:=unsigned(divisor)*to_unsigned(mul_ind,16);

temp_rem:=unsigned(dividend)-temp_prod;

IF(to_integer(temp_rem) < to_integer(unsigned(divisor))) THEN

state<=S4;

else

state<=S3;

mul_ind:=mul_ind+1;

end if;

when S4=>

quotient<=std_logic_vector(to_unsigned(mul_ind,16));

remainder<=std_logic_vector(temp_rem(15 downto 0));

state<=S5 ;

when S5=>

prod:=std_logic_vector(to_unsigned((sqrt_ind*sqrt_ind),16));

if(to_integer(unsigned(prod))>to_integer(unsigned(quotient)))then

state<=S6;

sqrt_ind:=sqrt_ind-1;

else

state<=S5;

sqrt_ind:=sqrt_ind+1;

end if;

when S6=>

sqrt_quotient<=std_logic_vector(to_unsigned(sqrt_ind,16));

state<=S6;

--trig1<='1';

--trig2<='1';

rms<=sqrt_quotient;

end case;

end if;

end if;

end process;

end Behavioral;

Testbench for RSSI calculation:

library IEEE;

use IEEE.STD_LOGIC_1164.ALL;

-- Uncomment the following library declaration if using

-- arithmetic functions with Signed or Unsigned values

use IEEE.NUMERIC_STD.ALL;

-- Uncomment the following library declaration if instantiating

-- any Xilinx leaf cells in this code.

library UNISIM;

use UNISIM.VComponents.all;

entity tb_rssicalc is

-- Port ( );

end tb_rssicalc;

architecture Behavioral of tb_rssicalc is

component total_new

Port ( clk : in STD_LOGIC;

rst : in STD_LOGIC;

s: out std_logic_vector(5 downto 0);

din : in STD_LOGIC_VECTOR(7 downto 0);

energy: out std_logic_vector(31 downto 0);

power: out std_logic_vector(15 downto 0 );

rms : out STD_LOGIC_VECTOR (7 downto 0);

rssi_db : out STD_LOGIC_VECTOR (7 downto 0));

end component;

signal clk,rst: std_logic;

signal din,rms,rssi_db: std_logic_vector(7 downto 0);

signal power: std_logic_vector(15 downto 0);

signal energy: std_logic_vector(31 downto 0);

signal s: std_logic_vector(5 downto 0);

begin

uut: total_new port map(clk,rst,s,din,energy,power,rms,rssi_db);

clk_process :process

begin

clk <= '0';

wait for 10 ns; --for 0.5 ns signal is '0'.

clk <= '1';

wait for 10 ns; --for next 0.5 ns signal is '1'.

end process;

stim_proc: process

begin

rst<='1';

wait for 20 ns;

rst<='0';

--wait for 20 ns;

din<=x"01" ;

wait for 20 ns;

din<=x"02";

wait for 20 ns;

din<=x"03";

wait for 20 ns;

din<=x"04";

wait for 20 ns;

din<=x"05";

wait for 20 ns;

din<=x"06";

wait for 20 ns;

din<=x"07";

wait for 20 ns;

din<=x"08";

wait for 20 ns;

din<=x"09";

wait for 20 ns;

din<=x"0a";

wait;

end process;

end Behavioral;

References:

1. Dong, Qian, and Waltenegus Dargie. "Evaluation of the reliability of RSSI for indoor localization." Wireless

Communications in Unusual and Confined Areas (ICWCUCA), 2012 International Conference on. IEEE, 2012.

2. Elnahrawy, Eiman, Xiaoyan Li, and Richard P. Martin. "The limits of localization using signal strength: A

comparative study." Sensor and Ad Hoc Communications and Networks, 2004. IEEE SECON 2004. 2004 First

Annual IEEE Communications Society Conference on. IEEE, 2004.

3. http://warpproject.org/trac/wiki/HardwareUsersGuides/WARPv3