Example #1
0
 def stdtest_01(self,bps):
   # no reuse, bps bits per symbol
   vsyms = 10
   vlen = 10
   bits = vsyms*vlen*bps
   
   refdata = [randint(0,1) for i in range(bits)]
   cmap = [bps]*(vsyms*vlen)
   
   src = gr.vector_source_b(refdata)
   dst = gr.vector_sink_b()
   
   src_map = gr.vector_source_b(cmap)
   s2v = gr.stream_to_vector(gr.sizeof_char, vlen)
   self.tb.connect(src_map,s2v)
   
   dut1 = ofdm.generic_mapper_bcv(vlen)
   dut2 = ofdm.generic_demapper_vcb(vlen)
   
   self.tb.connect(src,dut1,dut2,dst)
   self.tb.connect(s2v,(dut1,1))
   self.tb.connect(s2v,(dut2,1))
   
   self.tb.run()
   
   self.assertEqual(list(dst.data()),refdata)
Example #2
0
 def setup_test05(self):
     print "... benchmarking 8-PSK demapper"
     self.nobits = 4
     self.data_subcarriers = 200
     
     self.blks = self.N*(10 + 1)
     self.tb = gr.top_block()
         
     #self.bitmap = [self.nobits]*self.data_subcarriers
     self.demodulator = generic_demapper_vcb(self.data_subcarriers,10)
     const =  self.demodulator.get_constellation( self.nobits )
     assert( len( const ) == 2**self.nobits )
            
 
     self.bitdata = [random()+1j*random() for i in range(self.blks*self.data_subcarriers)]
     self.src = blocks.vector_source_c(self.bitdata,False, self.data_subcarriers)
     #self.src = symbol_random_src( const, self.data_subcarriers )
     
     self.bitmap = [0]*self.data_subcarriers + [self.nobits]*self.data_subcarriers      
     self.bitmap_src = blocks.vector_source_b(self.bitmap,True, self.data_subcarriers)
     
     #self.bmaptrig_stream = [1, 2]+[0]*(11-2)
     #self.bitmap_trigger = blocks.vector_source_b(self.bmaptrig_stream, True)
     
     self.snk = blocks.null_sink(gr.sizeof_char)
             
     self.tb.connect(self.src,self.demodulator,self.snk)
     self.tb.connect(self.bitmap_src,(self.demodulator,1))
Example #3
0
    def stdtest_01(self, bps):
        # no reuse, bps bits per symbol
        vsyms = 10
        vlen = 10
        bits = vsyms * vlen * bps

        refdata = [randint(0, 1) for i in range(bits)]
        cmap = [bps] * (vsyms * vlen)

        src = gr.vector_source_b(refdata)
        dst = gr.vector_sink_b()

        src_map = gr.vector_source_b(cmap)
        s2v = gr.stream_to_vector(gr.sizeof_char, vlen)
        self.tb.connect(src_map, s2v)

        dut1 = ofdm.generic_mapper_bcv(vlen)
        dut2 = ofdm.generic_demapper_vcb(vlen)

        self.tb.connect(src, dut1, dut2, dst)
        self.tb.connect(s2v, (dut1, 1))
        self.tb.connect(s2v, (dut2, 1))

        self.tb.run()

        self.assertEqual(list(dst.data()), refdata)
Example #4
0
  def __init__(self,data_subcarriers):
    gr.hier_block2.__init__(self,
      "ofdm_bpsk_demodulator",
      gr.io_signature( 1, 1, gr.sizeof_gr_complex * data_subcarriers ),
      gr.io_signature( 1, 1, gr.sizeof_char ) )

    modmap = [1]*data_subcarriers
    map_src = blocks.vector_source_b(modmap,True,data_subcarriers)

    trig_src = blocks.vector_source_b([1],True)

    demod = generic_demapper_vcb(data_subcarriers)

    self.connect(self,demod,self)
    self.connect(map_src,(demod,1))
    self.connect(trig_src,(demod,2))
Example #5
0
 def std_test (self, vlen, data, bitmap, trig):
   dut = ofdm.generic_demapper_vcb(vlen,1000000)
   
   sym_src = blocks.vector_source_c(data,False, vlen)
   bmap_src = blocks.vector_source_b(bitmap,False, vlen)
   #trig_src = gr.vector_source_b(trig,False)
   dst = blocks.vector_sink_b()
   
   self.fg.connect(sym_src,(dut,0))
   self.fg.connect(bmap_src,(dut,1))
   #self.fg.connect(trig_src,(dut,2))
   self.fg.connect(dut,dst)
   
   self.fg.run()
   
   return list(dst.data())
Example #6
0
    def std_test(self, vlen, data, bitmap, trig):
        dut = ofdm.generic_demapper_vcb(vlen, 1000000)

        sym_src = blocks.vector_source_c(data, False, vlen)
        bmap_src = blocks.vector_source_b(bitmap, False, vlen)
        #trig_src = gr.vector_source_b(trig,False)
        dst = blocks.vector_sink_b()

        self.fg.connect(sym_src, (dut, 0))
        self.fg.connect(bmap_src, (dut, 1))
        #self.fg.connect(trig_src,(dut,2))
        self.fg.connect(dut, dst)

        self.fg.run()

        return list(dst.data())
  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
Example #8
0
  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
Example #9
0
    def __init__(self, bits_per_subc, vlen, nblocks=1):
        gr.hier_block2.__init__(
            self, "data_block_src", gr.io_signature(0, 0, 0),
            gr.io_signature(1, 1, gr.sizeof_gr_complex * vlen))

        demapper = ofdm.generic_demapper_vcb(1)
        sigconst = dict()
        for i in range(1, max(bits_per_subc) + 1):
            sigconst[i] = demapper.get_constellation(i)

        self.sigconst = sigconst

        self.nblocks = nblocks
        self.vlen = vlen
        self.bpsubc = bits_per_subc

        self.gen_bit_data(nblocks, vlen, bits_per_subc)
        self.build_blocks()
        self.connect_blocks()
  def __init__( self, bits_per_subc, vlen, nblocks = 1 ):
    gr.hier_block2.__init__( self,
          "data_block_src",
          gr.io_signature(0,0,0),
          gr.io_signature( 1, 1, gr.sizeof_gr_complex * vlen ) )

    demapper = ofdm.generic_demapper_vcb(1)
    sigconst = dict()
    for i in range(1, max( bits_per_subc ) + 1 ):
      sigconst[i] = demapper.get_constellation( i )

    self.sigconst = sigconst

    self.nblocks = nblocks
    self.vlen = vlen
    self.bpsubc = bits_per_subc

    self.gen_bit_data(nblocks, vlen, bits_per_subc)
    self.build_blocks()
    self.connect_blocks()
Example #11
0
 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 ) )
Example #12
0
  def __init__(self, options):
    gr.hier_block2.__init__(self, "fbmc_receive_path",
        gr.io_signature(1,1,gr.sizeof_gr_complex),
        gr.io_signature(0,0,0))

    print "This is  FBMC receive path 1x1"

    common_options.defaults(options)

    config = self.config = station_configuration()

    config.data_subcarriers     = dsubc = options.subcarriers
    config.cp_length            = 0
    config.frame_data_blocks    = options.data_blocks
    config._verbose             = options.verbose #TODO: update
    config.fft_length           = options.fft_length
    config.dc_null             = options.dc_null
    config.training_data        = default_block_header(dsubc,
                                          config.fft_length,config.dc_null,options)
    config.coding              = options.coding
    config.ber_window           = options.ber_window

    config.periodic_parts       = 8

    config.frame_id_blocks      = 1 # FIXME

    self._options               = copy.copy(options) #FIXME: do we need this?
    
    config.fbmc                 = options.fbmc

    

    config.block_length = config.fft_length + config.cp_length
    config.frame_data_part = config.frame_data_blocks + config.frame_id_blocks
    config.frame_length = config.training_data.fbmc_no_preambles + 2*config.frame_data_part 
    
    config.postpro_frame_length = config.frame_data_part + \
                          config.training_data.no_pilotsyms
    config.subcarriers = dsubc + \
                         config.training_data.pilot_subcarriers
    config.virtual_subcarriers = config.fft_length - config.subcarriers - config.dc_null

    total_subc = config.subcarriers
    


    # check some bounds
    if config.fft_length < config.subcarriers:
      raise SystemError, "Subcarrier number must be less than FFT length"
    if config.fft_length < config.cp_length:
      raise SystemError, "Cyclic prefix length must be less than FFT length"



    #self.input =  gr.kludge_copy(gr.sizeof_gr_complex)
    #self.connect( self, self.input )
    self.input = self
    self.ideal = options.ideal
    self.ideal2 = options.ideal2


    ## Inner receiver

    ## Timing & Frequency Synchronization
    ## Channel estimation + Equalization
    ## Phase Tracking for sampling clock frequency offset correction
    inner_receiver = self.inner_receiver = fbmc_inner_receiver( options, options.log )
    self.connect( self.input, inner_receiver )
    ofdm_blocks = ( inner_receiver, 2 )
    frame_start = ( inner_receiver, 1 )
    disp_ctf = ( inner_receiver, 0 )
    #self.snr_est_preamble = ( inner_receiver, 3 )
    #terminate_stream(self,snr_est_preamble)
    disp_cfo =  ( inner_receiver, 3 )
    
    if self.ideal is False and self.ideal2 is False:
        self.zmq_probe_freqoff = zeromq.pub_sink(gr.sizeof_float, 1, "tcp://*:5557")
        self.connect(disp_cfo, self.zmq_probe_freqoff)
    else:
        self.connect(disp_cfo, blocks.null_sink(gr.sizeof_float))




    # for ID decoder
    used_id_bits = config.used_id_bits = 8 #TODO: constant in source code!
    rep_id_bits = config.rep_id_bits = dsubc/used_id_bits #BPSK
    if options.log:
      print "rep_id_bits %d" % (rep_id_bits)
    if dsubc % used_id_bits <> 0:
      raise SystemError,"Data subcarriers need to be multiple of 10"

    ## Workaround to avoid periodic structure
    seed(1)
    whitener_pn = [randint(0,1) for i in range(used_id_bits*rep_id_bits)]





    ## NOTE!!! BIG HACK!!!
    ## first preamble ain't equalized ....
    ## for Milan's SNR estimator






    ## Outer Receiver

    ## Make new inner receiver compatible with old outer receiver
    ## FIXME: renew outer receiver

    self.ctf = disp_ctf

    #frame_sampler = ofdm_frame_sampler(options)
    frame_sampler = fbmc_frame_sampler(options)

    self.connect( ofdm_blocks, frame_sampler)
    self.connect( frame_start, (frame_sampler,1) )


#
#    ft = [0] * config.frame_length
#    ft[0] = 1
#
#    # The next block ensures that only complete frames find their way into
#    # the old outer receiver. The dynamic frame start trigger is hence
#    # replaced with a static one, fixed to the frame length.
#
#    frame_sampler = ofdm.vector_sampler( gr.sizeof_gr_complex * total_subc,
#                                              config.frame_length )
#    self.symbol_output = blocks.vector_to_stream( gr.sizeof_gr_complex * total_subc,
#                                              config.frame_length )
#    delayed_frame_start = blocks.delay( gr.sizeof_char, config.frame_length - 1 )
#    damn_static_frame_trigger = blocks.vector_source_b( ft, True )
#
#    if options.enable_erasure_decision:
#      frame_gate = vector_sampler(
#        gr.sizeof_gr_complex * total_subc * config.frame_length, 1 )
#      self.connect( ofdm_blocks, frame_sampler, frame_gate,
#                    self.symbol_output )
#    else:
#      self.connect( ofdm_blocks, frame_sampler, self.symbol_output )
#
#    self.connect( frame_start, delayed_frame_start, ( frame_sampler, 1 ) )

    if options.enable_erasure_decision:
      frame_gate = frame_sampler.frame_gate

    self.symbol_output = frame_sampler

    orig_frame_start = frame_start
    frame_start = (frame_sampler,1)
    self.frame_trigger = frame_start
    #terminate_stream(self, self.frame_trigger)








    ## Pilot block filter
    pb_filt = self._pilot_block_filter = fbmc_pilot_block_filter()
    self.connect(self.symbol_output,pb_filt)
    self.connect(self.frame_trigger,(pb_filt,1))

    self.frame_data_trigger = (pb_filt,1)
    
    #self.symbol_output = pb_filt
    

    #if options.log:
      #log_to_file(self, pb_filt, "data/pb_filt_out.compl")


    if config.fbmc:
        pda_in = pb_filt

    else:
        ## Pilot subcarrier filter
        ps_filt = self._pilot_subcarrier_filter = pilot_subcarrier_filter()
        self.connect(self.symbol_output,ps_filt)

        if options.log:
            log_to_file(self, ps_filt, "data/ps_filt_out.compl")
            
        pda_in = ps_filt

    


    ## Workaround to avoid periodic structure
    # for ID decoder
    seed(1)
    whitener_pn = [randint(0,1) for i in range(used_id_bits*rep_id_bits)]

    

    if not options.enable_erasure_decision:

      ## ID Block Filter
      # Filter ID block, skip data blocks
      id_bfilt = self._id_block_filter = vector_sampler(
            gr.sizeof_gr_complex * dsubc, 1 )
      if not config.frame_id_blocks == 1:
        raise SystemExit, "# ID Blocks > 1 not supported"

      self.connect(   pda_in     ,   id_bfilt      )
      self.connect( self.frame_data_trigger, ( id_bfilt, 1 ) ) # trigger

      #log_to_file( self, id_bfilt, "data/id_bfilt.compl" )

      ## ID Demapper and Decoder, soft decision
      self.id_dec = self._id_decoder = ofdm.coded_bpsk_soft_decoder( dsubc,
          used_id_bits, whitener_pn )
      self.connect( id_bfilt, self.id_dec )
      

      print "Using coded BPSK soft decoder for ID detection"


    else: # options.enable_erasure_decision:

      id_bfilt = self._id_block_filter = vector_sampler(
        gr.sizeof_gr_complex * total_subc, config.frame_id_blocks )

      id_bfilt_trig_delay = 0
      for x in range( config.frame_length ):
        if x in config.training_data.pilotsym_pos:
          id_bfilt_trig_delay += 1
        else:
          break
      print "Position of ID block within complete frame: %d" %(id_bfilt_trig_delay)

      assert( id_bfilt_trig_delay > 0 ) # else not supported

      id_bfilt_trig = blocks.delay( gr.sizeof_char, id_bfilt_trig_delay )

      self.connect( ofdm_blocks, id_bfilt )
      self.connect( orig_frame_start, id_bfilt_trig, ( id_bfilt, 1 ) )

      self.id_dec = self._id_decoder = ofdm.coded_bpsk_soft_decoder( total_subc,
          used_id_bits, whitener_pn, config.training_data.shifted_pilot_tones )
      self.connect( id_bfilt, self.id_dec )

      print "Using coded BPSK soft decoder for ID detection"

      # The threshold block either returns 1.0 if the llr-value from the
      # id decoder is below the threshold, else 0.0. Hence we convert this
      # into chars, 0 and 1, and use it as trigger for the sampler.

      min_llr = ( self.id_dec, 1 )
      erasure_threshold = gr.threshold_ff( 10.0, 10.0, 0 ) # FIXME is it the optimal threshold?
      erasure_dec = gr.float_to_char()
      id_gate = vector_sampler( gr.sizeof_short, 1 )
      ctf_gate = vector_sampler( gr.sizeof_float * total_subc, 1 )


      self.connect( self.id_dec ,       id_gate )
      self.connect( self.ctf,      ctf_gate )

      self.connect( min_llr,       erasure_threshold,  erasure_dec )
      self.connect( erasure_dec, ( frame_gate, 1 ) )
      self.connect( erasure_dec, ( id_gate,    1 ) )
      self.connect( erasure_dec, ( ctf_gate,   1 ) )

      self.id_dec = self._id_decoder = id_gate
      self.ctf = ctf_gate



      print "Erasure decision for IDs is enabled"




    if options.log:
      id_dec_f = gr.short_to_float()
      self.connect(self.id_dec,id_dec_f)
      log_to_file(self, id_dec_f, "data/id_dec_out.float")


    if options.log:
      log_to_file(self, id_bfilt, "data/id_blockfilter_out.compl")


    # TODO: refactor names




    if options.log:
      map_src_f = gr.char_to_float(dsubc)
      self.connect(map_src,map_src_f)
      log_to_file(self, map_src_f, "data/map_src_out.float")

    ## Allocation Control
    if options.static_allocation: #DEBUG
        
        if options.coding:
            mode = 1 # Coding mode 1-9
            bitspermode = [0.5,1,1.5,2,3,4,4.5,5,6] # Information bits per mode
            bitcount_vec = [(int)(config.data_subcarriers*config.frame_data_blocks*bitspermode[mode-1])]
            bitloading = mode
        else:
            bitloading = 1
            bitcount_vec = [config.data_subcarriers*config.frame_data_blocks*bitloading]
        #bitcount_vec = [config.data_subcarriers*config.frame_data_blocks]
        self.bitcount_src = blocks.vector_source_i(bitcount_vec,True,1)
        # 0s for ID block, then data
        #bitloading_vec = [0]*dsubc+[0]*(dsubc/2)+[2]*(dsubc/2)
        bitloading_vec = [0]*dsubc+[bitloading]*dsubc
        bitloading_src = blocks.vector_source_b(bitloading_vec,True,dsubc)
        power_vec = [1]*config.data_subcarriers
        power_src = blocks.vector_source_f(power_vec,True,dsubc)
    else:
        self.allocation_buffer = ofdm.allocation_buffer(config.data_subcarriers, config.frame_data_blocks, "tcp://"+options.tx_hostname+":3333",config.coding)
        self.bitcount_src = (self.allocation_buffer,0)
        bitloading_src = (self.allocation_buffer,1)
        power_src = (self.allocation_buffer,2)
        self.connect(self.id_dec, self.allocation_buffer)
        if options.benchmarking:
            self.allocation_buffer.set_allocation([4]*config.data_subcarriers,[1]*config.data_subcarriers)

    if options.log:
        log_to_file(self, self.bitcount_src, "data/bitcount_src_rx.int")
        log_to_file(self, bitloading_src, "data/bitloading_src_rx.char")
        log_to_file(self, power_src, "data/power_src_rx.cmplx")
        log_to_file(self, self.id_dec, "data/id_dec_rx.short")

    ## Power Deallocator
    pda = self._power_deallocator = multiply_frame_fc(config.frame_data_part, dsubc)
    self.connect(pda_in,(pda,0))
    self.connect(power_src,(pda,1))

    ## Demodulator
#    if 0:
#          ac_vector = [0.0+0.0j]*208
#          ac_vector[0] = (2*10**(-0.452))
#          ac_vector[3] = (10**(-0.651))
#          ac_vector[7] = (10**(-1.151))
#          csi_vector_inv=abs(numpy.fft.fft(numpy.sqrt(ac_vector)))**2
#          dm_csi = numpy.fft.fftshift(csi_vector_inv) # TODO

    dm_csi = [1]*dsubc # TODO
    dm_csi = blocks.vector_source_f(dm_csi,True)
    ## Depuncturer
    dp_trig = [0]*(config.frame_data_blocks/2)
    dp_trig[0] = 1
    dp_trig = blocks.vector_source_b(dp_trig,True) # TODO



    if(options.coding):
        fo=ofdm.fsm(1,2,[91,121])
        if options.interleave:
            int_object=trellis.interleaver(2000,666)
            deinterlv = trellis.permutation(int_object.K(),int_object.DEINTER(),1,gr.sizeof_float)
        
        demod = self._data_demodulator = generic_softdemapper_vcf(dsubc, config.frame_data_part, config.coding)
        #self.connect(dm_csi,blocks.stream_to_vector(gr.sizeof_float,dsubc),(demod,2))
        if(options.ideal):
            self.connect(dm_csi,blocks.stream_to_vector(gr.sizeof_float,dsubc),(demod,2))
        else:
            dm_csi_filter = self.dm_csi_filter = filter.single_pole_iir_filter_ff(0.01,dsubc)
            self.connect(self.ctf, self.dm_csi_filter,(demod,2))
            #log_to_file(self, dm_csi_filter, "data/softs_csi.float")
        #self.connect(dm_trig,(demod,3))
    else:
        demod = self._data_demodulator = generic_demapper_vcb(dsubc, config.frame_data_part)
    if options.benchmarking:
        # Do receiver benchmarking until the number of frames x symbols are collected
        self.connect(pda,blocks.head(gr.sizeof_gr_complex*dsubc, options.N*config.frame_data_blocks),demod)
    else:        
        self.connect(pda,demod)
    self.connect(bitloading_src,(demod,1))

    if(options.coding):
        ## Depuncturing
        if not options.nopunct:
            depuncturing = depuncture_ff(dsubc,0)
            frametrigger_bitmap_filter = blocks.vector_source_b([1,0],True)
            self.connect(bitloading_src,(depuncturing,1))
            self.connect(dp_trig,(depuncturing,2))

        ## Decoding
        chunkdivisor = int(numpy.ceil(config.frame_data_blocks/5.0))
        print "Number of chunks at Viterbi decoder: ", chunkdivisor
        decoding = self._data_decoder = ofdm.viterbi_combined_fb(fo,dsubc,-1,-1,2,chunkdivisor,[-1,-1,-1,1,1,-1,1,1],ofdm.TRELLIS_EUCLIDEAN)

        
        if options.log and options.coding:
            log_to_file(self, decoding, "data/decoded.char")
            if not options.nopunct:
                log_to_file(self, depuncturing, "data/vit_in.float")

        if not options.nopunct:
            if options.interleave:
                self.connect(demod,deinterlv,depuncturing,decoding)
            else:
                self.connect(demod,depuncturing,decoding)
        else:
            self.connect(demod,decoding)
        self.connect(self.bitcount_src, multiply_const_ii(1./chunkdivisor), (decoding,1))

    if options.scatterplot or options.scatter_plot_before_phase_tracking:
        if self.ideal2 is False:
            scatter_vec_elem = self._scatter_vec_elem = ofdm.vector_element(dsubc,40)
            scatter_s2v = self._scatter_s2v = blocks.stream_to_vector(gr.sizeof_gr_complex,config.frame_data_blocks)
    
            scatter_id_filt = skip(gr.sizeof_gr_complex*dsubc,config.frame_data_blocks)
            scatter_id_filt.skip_call(0)
            scatter_trig = [0]*config.frame_data_part
            scatter_trig[0] = 1
            scatter_trig = blocks.vector_source_b(scatter_trig,True)
            self.connect(scatter_trig,(scatter_id_filt,1))
            self.connect(scatter_vec_elem,scatter_s2v)
    
            if not options.scatter_plot_before_phase_tracking:
                print "Enabling Scatterplot for data subcarriers"
                self.connect(pda,scatter_id_filt,scatter_vec_elem)
                  # Work on this
                  #scatter_sink = ofdm.scatterplot_sink(dsubc)
                  #self.connect(pda,scatter_sink)
                  #self.connect(map_src,(scatter_sink,1))
                  #self.connect(dm_trig,(scatter_sink,2))
                  #print "Enabled scatterplot gui interface"
                self.zmq_probe_scatter = zeromq.pub_sink(gr.sizeof_gr_complex,config.frame_data_blocks, "tcp://*:5560")
                self.connect(scatter_s2v, blocks.keep_one_in_n(gr.sizeof_gr_complex*config.frame_data_blocks,20), self.zmq_probe_scatter)
            else:
                print "Enabling Scatterplot for data before phase tracking"
                inner_rx = inner_receiver.before_phase_tracking
                #scatter_sink2 = ofdm.scatterplot_sink(dsubc,"phase_tracking")
                op = copy.copy(options)
                op.enable_erasure_decision = False
                new_framesampler = ofdm_frame_sampler(op)
                self.connect( inner_rx, new_framesampler )
                self.connect( orig_frame_start, (new_framesampler,1) )
                new_ps_filter = pilot_subcarrier_filter()
                new_pb_filter = fbmc_pilot_block_filter()
    
                self.connect( (new_framesampler,1), (new_pb_filter,1) )
                self.connect( new_framesampler, new_pb_filter,
                             new_ps_filter, scatter_id_filt, scatter_vec_elem )
    
                #self.connect( new_ps_filter, scatter_sink2 )
                #self.connect( map_src, (scatter_sink2,1))
                #self.connect( dm_trig, (scatter_sink2,2))


    if options.log:
      if(options.coding):
          log_to_file(self, demod, "data/data_stream_out.float")
      else:
          data_f = gr.char_to_float()
          self.connect(demod,data_f)
          log_to_file(self, data_f, "data/data_stream_out.float")



    if options.sfo_feedback:
      used_id_bits = 8
      rep_id_bits = config.data_subcarriers/used_id_bits

      seed(1)
      whitener_pn = [randint(0,1) for i in range(used_id_bits*rep_id_bits)]

      id_enc = ofdm.repetition_encoder_sb(used_id_bits,rep_id_bits,whitener_pn)
      self.connect( self.id_dec, id_enc )

      id_mod = ofdm_bpsk_modulator(dsubc)
      self.connect( id_enc, id_mod )

      id_mod_conj = gr.conjugate_cc(dsubc)
      self.connect( id_mod, id_mod_conj )

      id_mult = blocks.multiply_vcc(dsubc)
      self.connect( id_bfilt, ( id_mult,0) )
      self.connect( id_mod_conj, ( id_mult,1) )

#      id_mult_avg = filter.single_pole_iir_filter_cc(0.01,dsubc)
#      self.connect( id_mult, id_mult_avg )

      id_phase = gr.complex_to_arg(dsubc)
      self.connect( id_mult, id_phase )

      log_to_file( self, id_phase, "data/id_phase.float" )

      est=ofdm.LS_estimator_straight_slope(dsubc)
      self.connect(id_phase,est)

      slope=blocks.multiply_const_ff(1e6/2/3.14159265)
      self.connect( (est,0), slope )

      log_to_file( self, slope, "data/slope.float" )
      log_to_file( self, (est,1), "data/offset.float" )

    # ------------------------------------------------------------------------ #




    # Display some information about the setup
    if config._verbose:
      self._print_verbage()

    ## debug logging ##
    if options.log:
#      log_to_file(self,self.ofdm_symbols,"data/unequalized_rx_ofdm_symbols.compl")
#      log_to_file(self,self.ofdm_symbols,"data/unequalized_rx_ofdm_symbols.float",mag=True)


      fftlen = 256
      my_window = window.hamming(fftlen) #.blackmanharris(fftlen)
      rxs_sampler = vector_sampler(gr.sizeof_gr_complex,fftlen)
      rxs_sampler_vect = concatenate([[1],[0]*49])
      rxs_trigger = blocks.vector_source_b(rxs_sampler_vect.tolist(),True)
      rxs_window = blocks.multiply_const_vcc(my_window)
      rxs_spectrum = gr.fft_vcc(fftlen,True,[],True)
      rxs_mag = gr.complex_to_mag(fftlen)
      rxs_avg = filter.single_pole_iir_filter_ff(0.01,fftlen)
      #rxs_logdb = blocks.nlog10_ff(20.0,fftlen,-20*log10(fftlen))
      rxs_logdb = gr.kludge_copy( gr.sizeof_float * fftlen )
      rxs_decimate_rate = gr.keep_one_in_n(gr.sizeof_float*fftlen,1)
      self.connect(rxs_trigger,(rxs_sampler,1))
      self.connect(self.input,rxs_sampler,rxs_window,
                   rxs_spectrum,rxs_mag,rxs_avg,rxs_logdb, rxs_decimate_rate)
      log_to_file( self, rxs_decimate_rate, "data/psd_input.float" )


    #output branches
    self.publish_rx_performance_measure()
Example #13
0
  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