def __init__( self, vlen, startup ): gr.hier_block2.__init__( self, "vector_acc_se", gr.io_signature( 1, 1, gr.sizeof_gr_complex * vlen ), gr.io_signature( 1, 1, gr.sizeof_float ) ) squared_error_subc = gr.complex_to_mag_squared( vlen ) squared_error_block = ofdm.vector_sum_vff( vlen ) accumulated_squared_error = ofdm.accumulator_ff() if startup > 0: startup_skip = gr.skiphead( gr.sizeof_gr_complex * vlen, startup ) self.connect( self, startup_skip, squared_error_subc, squared_error_block, accumulated_squared_error, self ) else: self.connect( self, squared_error_subc, squared_error_block, accumulated_squared_error, self )
def __init__( self, vlen, frame_length, no_frames, no_preambles, bits_per_subc, bitdata_per_frame ): gr.hier_block2.__init__( self, "ofdm_ber_estimator", gr.io_signature( 1, 1, gr.sizeof_gr_complex * vlen ), gr.io_signature(0,0,0) ) bpsubc = [0] * ( vlen * no_preambles ) assert( len( bits_per_subc ) == vlen ) bpsubc.extend( bits_per_subc ) bits_per_frame = sum( bpsubc ) * ( frame_length - no_preambles ) bm_update_trigger = [0] * frame_length for i in range( no_preambles + 1 ): bm_update_trigger[i] = 1 bm_update_trigger = gr.vector_source_b( bm_update_trigger, True ) demapper = ofdm.generic_demapper_vcb( vlen ) bitmap_src = gr.vector_source_b( bpsubc, True, vlen ) data_ref_src = gr.vector_source_b( bitdata_per_frame, True ) compare = gr.xor_bb() bitstream_c2f = gr.char_to_float() acc_biterr = ofdm.accumulator_ff() window_length = bits_per_frame * no_frames self.N = window_length dst = limit_stream_get_last_item( acc_biterr, window_length ) self.connect( self, demapper, compare, bitstream_c2f, acc_biterr, dst ) self.connect( bitmap_src, ( demapper, 1 ) ) self.connect( bm_update_trigger, ( demapper, 2 ) ) self.connect( data_ref_src, ( compare, 1 ) ) self.vector_sources = [ bm_update_trigger, bitmap_src ] self.acc = acc_biterr self.data_ref_src = data_ref_src self.compare = compare self.dst = dst
def sim ( self, arity, snr_db, N ): vlen = 1 N = int( N ) snr = 10.0**(snr_db/10.0) sigpow = 1.0 noise_pow = sigpow / snr demapper = ofdm.generic_demapper_vcb( vlen ) const = demapper.get_constellation( arity ) assert( len( const ) == 2**arity ) symsrc = ofdm.symbol_random_src( const, vlen ) noise_src = ofdm.complex_white_noise( 0.0, sqrt( noise_pow ) ) channel = blocks.add_cc() bitmap_src = blocks.vector_source_b( [arity] * vlen, True, vlen ) bm_trig_src = blocks.vector_source_b( [1], True ) ref_bitstream = blocks.unpack_k_bits_bb( arity ) bitstream_xor = blocks.xor_bb() bitstream_c2f = blocks.char_to_float() acc_biterr = ofdm.accumulator_ff() skiphead = blocks.skiphead( gr.sizeof_float, N-1 ) limit = blocks.head( gr.sizeof_float, 1 ) dst = blocks.vector_sink_f() tb = gr.top_block ( "test_block" ) tb.connect( (symsrc,0), (channel,0) ) tb.connect( noise_src, (channel,1) ) tb.connect( channel, (demapper,0), (bitstream_xor,0) ) tb.connect( bitmap_src, (demapper,1) ) tb.connect( bm_trig_src, (demapper,2) ) tb.connect( (symsrc,1), ref_bitstream, (bitstream_xor,1) ) tb.connect( bitstream_xor, bitstream_c2f, acc_biterr ) tb.connect( acc_biterr, skiphead, limit, dst ) tb.run() bit_errors = numpy.array( dst.data() ) assert( len( bit_errors ) == 1 ) bit_errors = bit_errors[0] return bit_errors / N
def __init__ ( self, fft_length ): gr.hier_block2.__init__(self, "recursive_timing_metric", gr.io_signature(1,1,gr.sizeof_gr_complex), gr.io_signature(1,1,gr.sizeof_float)) self.input = gr.kludge_copy(gr.sizeof_gr_complex) self.connect(self, self.input) # P(d) = sum(0 to L-1, conj(delayed(r)) * r) conj = gr.conjugate_cc() mixer = gr.multiply_cc() mix_delay = delay(gr.sizeof_gr_complex,fft_length/2+1) mix_diff = gr.sub_cc() nominator = accumulator_cc() inpdelay = delay(gr.sizeof_gr_complex,fft_length/2) self.connect(self.input, inpdelay, conj, (mixer,0)) self.connect(self.input, (mixer,1)) self.connect(mixer,(mix_diff,0)) self.connect(mixer, mix_delay, (mix_diff,1)) self.connect(mix_diff,nominator) rmagsqrd = gr.complex_to_mag_squared() rm_delay = delay(gr.sizeof_float,fft_length+1) rm_diff = gr.sub_ff() denom = accumulator_ff() self.connect(self.input,rmagsqrd,rm_diff,gr.multiply_const_ff(0.5),denom) self.connect(rmagsqrd,rm_delay,(rm_diff,1)) ps = gr.complex_to_mag_squared() rs = gr.multiply_ff() self.connect(nominator,ps) self.connect(denom,rs) self.connect(denom,(rs,1)) div = gr.divide_ff() self.connect(ps,div) self.connect(rs,(div,1)) self.connect(div,self)
def __init__(self, fft_length): gr.hier_block2.__init__(self, "recursive_timing_metric", gr.io_signature(1, 1, gr.sizeof_gr_complex), gr.io_signature(1, 1, gr.sizeof_float)) self.input = gr.kludge_copy(gr.sizeof_gr_complex) self.connect(self, self.input) # P(d) = sum(0 to L-1, conj(delayed(r)) * r) conj = gr.conjugate_cc() mixer = gr.multiply_cc() mix_delay = delay(gr.sizeof_gr_complex, fft_length / 2 + 1) mix_diff = gr.sub_cc() nominator = accumulator_cc() inpdelay = delay(gr.sizeof_gr_complex, fft_length / 2) self.connect(self.input, inpdelay, conj, (mixer, 0)) self.connect(self.input, (mixer, 1)) self.connect(mixer, (mix_diff, 0)) self.connect(mixer, mix_delay, (mix_diff, 1)) self.connect(mix_diff, nominator) rmagsqrd = gr.complex_to_mag_squared() rm_delay = delay(gr.sizeof_float, fft_length + 1) rm_diff = gr.sub_ff() denom = accumulator_ff() self.connect(self.input, rmagsqrd, rm_diff, gr.multiply_const_ff(0.5), denom) self.connect(rmagsqrd, rm_delay, (rm_diff, 1)) ps = gr.complex_to_mag_squared() rs = gr.multiply_ff() self.connect(nominator, ps) self.connect(denom, rs) self.connect(denom, (rs, 1)) div = gr.divide_ff() self.connect(ps, div) self.connect(rs, (div, 1)) self.connect(div, self)
def test_symbol_src ( self, arity ): vlen = 1 N = int( 1e7 ) demapper = ofdm.generic_demapper_vcb( vlen ) const = demapper.get_constellation( arity ) assert( len( const ) == 2**arity ) symsrc = ofdm.symbol_random_src( const, vlen ) # tx = transmitter_hier_bc(M=M,K=K,qam_size=qam_size,syms_per_frame=syms_per_frame,theta_sel=theta_sel,exclude_preamble=exclude_preamble,sel_preamble=None) acc = ofdm.accumulator_cc() skiphead = blocks.skiphead( gr.sizeof_gr_complex, N-1 ) limit = blocks.head( gr.sizeof_gr_complex, 1 ) dst = blocks.vector_sink_c() c2mag = blocks.complex_to_mag_squared() acc_c2m = ofdm.accumulator_ff() skiphead_c2m = blocks.skiphead( gr.sizeof_float, N-1 ) limit_c2m = blocks.head( gr.sizeof_float, 1 ) dst_c2m = blocks.vector_sink_f() tb = gr.top_block ( "test__block" ) tb.connect( symsrc, acc, skiphead, limit, dst ) tb.connect( symsrc, c2mag, acc_c2m, skiphead_c2m, limit_c2m, dst_c2m ) tb.run() data = numpy.array( dst.data() ) data_c2m = numpy.array( dst_c2m.data() ) m = data / N av_pow = data_c2m / N assert( abs( m ) < 0.01 ) assert( abs( 1.0 - av_pow ) < 0.5 ) print "Uniform distributed random symbol source has" print "\tno offset for N=%d, relative error: %f" % (arity, abs( m ) ) print "\tAverage signal power equal 1.0, relative error: %f\t\tOK" \ % ( abs( 1.0 - av_pow ) )
def test_001(self): vlen = 256 subc = 208 L = 8 cplen = 12 blocklen = vlen + cplen framelength = 11 bits_per_subc = [2] * vlen data_blocks = 10 N = int(1e8) profiling = False pre0, fd = morellimengali_designer.create(subc, vlen, L) ofdm_frames = \ ofdm_frame_src( vlen, data_blocks, pre0, cplen, framelength, bits_per_subc ) uut = autocorrelator(vlen / 2, vlen / 2) ref = recursive_timing_metric(vlen) limit_stream = gr.head(gr.sizeof_float, N) self.tb.connect(ofdm_frames, uut, limit_stream, gr.null_sink(gr.sizeof_float)) # limit_stream.enable_detailed_profiling( profiling ) # uut.s2.enable_detailed_profiling( profiling ) if not profiling: limit_stream2 = gr.head(gr.sizeof_float, N) compare = gr.sub_ff() err_acc = ofdm.accumulator_ff() skip_err = gr.skiphead(gr.sizeof_float, N - 1) last_err_val = gr.head(gr.sizeof_float, 1) err_sink = gr.vector_sink_f() self.tb.connect(ofdm_frames, ref, limit_stream2, gr.null_sink(gr.sizeof_float)) self.tb.connect(uut, (compare, 0)) self.tb.connect(ref, (compare, 1)) self.tb.connect(compare, err_acc) self.tb.connect(err_acc, skip_err) self.tb.connect(skip_err, last_err_val) self.tb.connect(last_err_val, err_sink) # log_to_file( self.tb, limit_stream, "data/autocorr_uut.float" ) # log_to_file( self.tb, limit_stream2, "data/autocorr_ref.float" ) # r = time_it( self.tb ) self.tb.run() # print "Expected throughput: %s Samples/s" % ( eng_notation.num_to_str( float(N) / r ) ) if not profiling: e = numpy.array(err_sink.data())[0] print "Err: %.7f" % (e)
def test_001(self): vlen = 256 subc = 208 L = 8 cplen = 12 blocklen = vlen + cplen framelength = 11 bits_per_subc = [2]*vlen data_blocks = 10 N = int( 1e8 ) profiling = False pre0,fd = morellimengali_designer.create( subc, vlen, L ) ofdm_frames = \ ofdm_frame_src( vlen, data_blocks, pre0, cplen, framelength, bits_per_subc ) uut = autocorrelator( vlen/2, vlen/2 ) ref = recursive_timing_metric( vlen ) limit_stream = gr.head( gr.sizeof_float, N ) self.tb.connect( ofdm_frames, uut, limit_stream, gr.null_sink( gr.sizeof_float ) ) # limit_stream.enable_detailed_profiling( profiling ) # uut.s2.enable_detailed_profiling( profiling ) if not profiling: limit_stream2 = gr.head( gr.sizeof_float, N ) compare = gr.sub_ff() err_acc = ofdm.accumulator_ff() skip_err = gr.skiphead( gr.sizeof_float, N-1 ) last_err_val = gr.head( gr.sizeof_float, 1 ) err_sink = gr.vector_sink_f() self.tb.connect( ofdm_frames, ref, limit_stream2, gr.null_sink( gr.sizeof_float ) ) self.tb.connect( uut, ( compare, 0 ) ) self.tb.connect( ref, ( compare, 1 ) ) self.tb.connect( compare, err_acc ) self.tb.connect( err_acc, skip_err ) self.tb.connect( skip_err, last_err_val ) self.tb.connect( last_err_val, err_sink ) # log_to_file( self.tb, limit_stream, "data/autocorr_uut.float" ) # log_to_file( self.tb, limit_stream2, "data/autocorr_ref.float" ) # r = time_it( self.tb ) self.tb.run() # print "Expected throughput: %s Samples/s" % ( eng_notation.num_to_str( float(N) / r ) ) if not profiling: e = numpy.array( err_sink.data() )[0] print "Err: %.7f" % ( e )
def sim ( self, arity, snr_db, N ): vlen = 10 N = int( N ) snr = 10.0**(snr_db/10.0) sigpow = 1.0 noise_pow = sigpow / snr #skipping first symbol due to demapper implementation (demmaper assumes that the first symbol is ID and do not decode ui) skiphead_src = blocks.skiphead( gr.sizeof_char, vlen+3)#vlen+3 ) demapper = ofdm.generic_demapper_vcb( vlen,N/vlen+1 ) const = demapper.get_constellation( arity ) assert( len( const ) == 2**arity ) symsrc = ofdm.symbol_random_src( const, vlen ) #noise_src = ofdm.complex_white_noise( 0.0, sqrt( noise_pow ) ) noise_src = analog.fastnoise_source_c(analog.GR_GAUSSIAN, 0.0, 0, 8192) channel = blocks.add_cc() ch_model = channels.channel_model( noise_voltage=0.0, frequency_offset=0.0, epsilon=1.0, #taps = (0.998160541385960,0.0605566335500750,0.00290305927764350), taps = (1,0), noise_seed=8192, block_tags=False ) bitmap_src = blocks.vector_source_b( [arity] * vlen, True, vlen ) #bm_trig_src = blocks.vector_source_b( [1], True ) ref_bitstream = blocks.unpack_k_bits_bb( arity ) bitstream_xor = blocks.xor_bb() bitstream_c2f = blocks.char_to_float() acc_biterr = ofdm.accumulator_ff() skiphead = blocks.skiphead( gr.sizeof_float, N-1 ) limit = blocks.head( gr.sizeof_float, 1 ) dst = blocks.vector_sink_f() rec_dst = blocks.vector_sink_b() ref_dst = blocks.vector_sink_b() tb = gr.top_block ( "test_block" ) #tb.connect( (symsrc,0),blocks.vector_to_stream(gr.sizeof_gr_complex ,vlen),blocks.head(gr.sizeof_gr_complex,N/arity),blocks.null_sink(gr.sizeof_gr_complex)) #tb.connect( (symsrc,0),fft.fft_vcc(vlen,False,[],True),blocks.vector_to_stream(gr.sizeof_gr_complex ,vlen), ch_model, (channel,0) ) tb.connect( (symsrc,0),blocks.vector_to_stream(gr.sizeof_gr_complex ,vlen), ch_model, (channel,0) ) tb.connect( noise_src, (channel,1) ) #tb.connect( channel, blocks.stream_to_vector(gr.sizeof_gr_complex ,vlen),fft.fft_vcc(vlen,True,[],True), (demapper,0), (bitstream_xor,0) ) tb.connect( channel, blocks.stream_to_vector(gr.sizeof_gr_complex ,vlen), (demapper,0), (bitstream_xor,0) ) tb.connect( bitmap_src, (demapper,1) ) #tb.connect( bm_trig_src, (demapper,2) ) tb.connect( (symsrc,1),blocks.vector_to_stream(gr.sizeof_char ,vlen),skiphead_src, ref_bitstream, (bitstream_xor,1) ) tb.connect( bitstream_xor, bitstream_c2f, acc_biterr ) tb.connect( acc_biterr, skiphead, limit, dst ) tb.connect( demapper, rec_dst ) tb.connect( ref_bitstream, ref_dst ) tb.run() bit_errors = numpy.array( dst.data() ) assert( len( bit_errors ) == 1 ) bit_errors = bit_errors[0] rec_data = list(rec_dst.data()) ref_data = list(ref_dst.data()) print "ref_data: ", ref_data[:2000] print "size ref_data: ", len(ref_data)#[:2320 print "rec_data: ", rec_data[:500] print "size rec_data: ", len(rec_data)#[:2320 return bit_errors / N