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