A very basic BPSK BER test is being performed (only AWGN is considered). The test is accomplished by using the gr-mapper OOT. The first simulation is based on a simple BPSK mapper (1->1, 0->-1) shown below.
The results are very close to theoretical BER as shown below In the simulation, SNR is specified by varying the noise voltage of the Gaussian noise source. Eb = RMS = sqrt((1^2 + 1^2)/2) = 1. Thus, Noise Voltage = sqrt(No) = math.sqrt(1/math.pow(10,SNR/10.0)). More information can be found at this link
I'm now focusing on adding a matched filter accomplished by one RRC filter at transmitter and receiver as shown below. This flowgraph has very poor BER performance.
Upon close examination of the filtered BPSK signal, the magnitude is no longer 1 (actual value is around 0.15) and hence the value of Eb being used is not accurate. To further verify my conclusion, I used the gnuradio filter design tool. The tool shows that to get a magnitude of 1, the gain has to be set around 7 (at this value, the BER is somehow close to theory).
The code for the pulse-shaper (debug_pulseshape_pam_2) is shown below
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <gnuradio/io_signature.h>
#include "debug_pulseshape_pam_2_impl.h"
#include <gnuradio/blocks/char_to_float.h>
#include <gnuradio/digital/map_bb.h>
#include <gnuradio/filter/interp_fir_filter_fff.h>
namespace gr {
namespace baseband {
debug_pulseshape_pam_2::sptr
debug_pulseshape_pam_2::make(std::vector<float> taps,float sps)
{
return gnuradio::get_initial_sptr
(new debug_pulseshape_pam_2_impl(taps, sps));
}
/*
* The private constructor
*/
debug_pulseshape_pam_2_impl::debug_pulseshape_pam_2_impl(std::vector<float> taps,float sps)
: gr::hier_block2("debug_pulseshape_pam_2",
gr::io_signature::make(1, 1, sizeof(unsigned char)),
gr::io_signature::make(1, 1, sizeof(float)))
{
//Initializing the map block
std::vector<int> map;
map.push_back(-1);
map.push_back(1);
gr::digital::map_bb::sptr mapper(gr::digital::map_bb::make(map));
//Initializing char_to_float block
gr::blocks::char_to_float::sptr float_char(gr::blocks::char_to_float::make());
//Initializing add const block
//gr::blocks::add_const_ff::sptr const_add(gr::blocks::add_const_ff::make(-0.5));
//Initializing an interpolating FIR filter
gr::filter::interp_fir_filter_fff::sptr fir(gr::filter::interp_fir_filter_fff::make(int(sps),taps));
connect(self(),0,mapper,0);
connect(mapper,0,float_char,0);
connect(float_char,0, fir, 0);
connect(fir, 0, self(), 0);
}
/*
* Our virtual destructor.
*/
debug_pulseshape_pam_2_impl::~debug_pulseshape_pam_2_impl()
{
}
} /* namespace baseband */
} /* namespace gr */
Please do not hesitate to ask for more information if needed.
Regards,
I was able to solve the problem finally. Turned out the noise has to be divided by the number of samples per symbol.