def main(args): nargs = len(args) if nargs == 3: fname_out = args[0] esn0_db = float(args[1]) rep = int(args[2]) else: sys.stderr.write( 'usage: test_turbo_equalization.py fsm_name_out Es/No_db repetitions\n' ) sys.exit(1) # system parameters Kb = 64 * 16 # packet size in bits (multiple of 16) modulation = fsm_utils.pam4 # see fsm_utlis.py for available predefined modulations channel = fsm_utils.c_channel # see fsm_utlis.py for available predefined test channels fo = trellis.fsm(fname_out) # get the outer FSM specification from a file fi = trellis.fsm(len(modulation[1]), len(channel)) # generate the FSM automatically if fo.O() != fi.I(): sys.stderr.write( 'Incompatible cardinality between outer and inner FSM.\n') sys.exit(1) bitspersymbol = int(round(math.log(fo.I()) / math.log(2))) # bits per FSM input symbol K = Kb / bitspersymbol # packet size in trellis steps interleaver = trellis.interleaver(K, 666) # construct a random interleaver tot_channel = fsm_utils.make_isi_lookup( modulation, channel, True) # generate the lookup table (normalize energy to 1) dimensionality = tot_channel[0] tot_constellation = tot_channel[1] if len(tot_constellation) / dimensionality != fi.O(): sys.stderr.write( 'Incompatible FSM output cardinality and lookup table size.\n') sys.exit(1) N0 = pow(10.0, -esn0_db / 10.0) # noise variance IT = 3 # number of turbo iterations tot_s = 0 # total number of transmitted shorts terr_s = 0 # total number of shorts in error terr_p = 0 # total number of packets in error for i in range(rep): (s, e) = run_test( fo, fi, interleaver, Kb, bitspersymbol, K, channel, modulation, dimensionality, tot_constellation, 1, N0, IT, -long(666 + i) ) # run experiment with different seed to get different noise realizations tot_s = tot_s + s terr_s = terr_s + e terr_p = terr_p + (terr_s != 0) if ((i + 1) % 10 == 0): # display progress print i + 1, terr_p, '%.2e' % ((1.0 * terr_p) / (i + 1)), tot_s, terr_s, '%.2e' % ( (1.0 * terr_s) / tot_s) # estimate of the (short or bit) error rate print rep, terr_p, '%.2e' % ((1.0 * terr_p) / (i + 1)), tot_s, terr_s, '%.2e' % ( (1.0 * terr_s) / tot_s)
def __init__(self, vlen_in=1, vlen_out=1, n_tailbits=1, denom_mother_code_rate=1, gen_poly=0, bits_per_symbol=1, map_tab=0, pp_0=0, interl_seq_0_2=(0,1), interl_seq_1_2=(0,1), pp_1_tail=0, pp_1=0, pp_0_tail=0, M_total=0, part_len_top=3, part_len_bot=3): gr.hier_block2.__init__( self, "MLC 16QAM", gr.io_signature(1, 1, gr.sizeof_char*1), gr.io_signature(1, 1, gr.sizeof_gr_complex*1), ) ################################################## # Parameters ################################################## self.vlen_in = vlen_in self.vlen_out = vlen_out self.n_tailbits = n_tailbits self.denom_mother_code_rate = denom_mother_code_rate self.gen_poly = gen_poly self.bits_per_symbol = bits_per_symbol self.map_tab = map_tab self.pp_0 = pp_0 self.interl_seq_0_2 = interl_seq_0_2 self.interl_seq_1_2 = interl_seq_1_2 self.pp_1_tail = pp_1_tail self.pp_1 = pp_1 self.pp_0_tail = pp_0_tail self.M_total = M_total self.part_len_top = part_len_top self.part_len_bot = part_len_bot ################################################## # Blocks ################################################## self.trellis_encoder_xx_top = trellis.encoder_bb(trellis.fsm(1, denom_mother_code_rate, gen_poly), 0, 0) if False else trellis.encoder_bb(trellis.fsm(1, denom_mother_code_rate, gen_poly), 0) self.trellis_encoder_xx_bot = trellis.encoder_bb(trellis.fsm(1, denom_mother_code_rate, gen_poly), 0, 0) if False else trellis.encoder_bb(trellis.fsm(1, denom_mother_code_rate, gen_poly), 0) self.drm_qam_map_bc_0 = drm.qam_map_bc(map_tab, bits_per_symbol, vlen_out, 2) self.drm_punct_bb_top = drm.punct_bb(pp_0, pp_0_tail, (part_len_top + n_tailbits) * denom_mother_code_rate, vlen_out * 2, n_tailbits * denom_mother_code_rate) self.drm_punct_bb_bot = drm.punct_bb(pp_1, pp_1_tail, (part_len_bot + n_tailbits) * denom_mother_code_rate, vlen_out * 2, n_tailbits * denom_mother_code_rate) self.drm_partitioning_16_bb_0 = drm.partitioning_bb(vlen_in, M_total) self.drm_interleaver_bb_top = drm.interleaver_bb((interl_seq_0_2)) self.drm_interleaver_bb_bot = drm.interleaver_bb((interl_seq_1_2)) self.drm_add_tailbits_bb_top = drm.add_tailbits_bb(part_len_top, n_tailbits) self.drm_add_tailbits_bb_bot = drm.add_tailbits_bb(part_len_bot, n_tailbits) self.blocks_unpack_k_bits_bb_top = blocks.unpack_k_bits_bb(denom_mother_code_rate) self.blocks_unpack_k_bits_bb_bot = blocks.unpack_k_bits_bb(denom_mother_code_rate) ################################################## # Connections ################################################## self.connect((self.blocks_unpack_k_bits_bb_bot, 0), (self.drm_punct_bb_bot, 0)) self.connect((self.blocks_unpack_k_bits_bb_top, 0), (self.drm_punct_bb_top, 0)) self.connect((self.drm_add_tailbits_bb_bot, 0), (self.trellis_encoder_xx_bot, 0)) self.connect((self.drm_add_tailbits_bb_top, 0), (self.trellis_encoder_xx_top, 0)) self.connect((self.drm_interleaver_bb_bot, 0), (self.drm_qam_map_bc_0, 1)) self.connect((self.drm_interleaver_bb_top, 0), (self.drm_qam_map_bc_0, 0)) self.connect((self.drm_partitioning_16_bb_0, 1), (self.drm_add_tailbits_bb_bot, 0)) self.connect((self.drm_partitioning_16_bb_0, 0), (self.drm_add_tailbits_bb_top, 0)) self.connect((self.drm_punct_bb_bot, 0), (self.drm_interleaver_bb_bot, 0)) self.connect((self.drm_punct_bb_top, 0), (self.drm_interleaver_bb_top, 0)) self.connect((self.drm_qam_map_bc_0, 0), (self, 0)) self.connect((self, 0), (self.drm_partitioning_16_bb_0, 0)) self.connect((self.trellis_encoder_xx_bot, 0), (self.blocks_unpack_k_bits_bb_bot, 0)) self.connect((self.trellis_encoder_xx_top, 0), (self.blocks_unpack_k_bits_bb_top, 0))
def __init__(self, ftype): super(trellis_pccc_decoder_combined_tb, self).__init__() func = eval("trellis.pccc_decoder_combined_" + ftype) dsttype = gr.sizeof_int if ftype[1] == "b": dsttype = gr.sizeof_char elif ftype[1] == "s": dsttype = gr.sizeof_short elif ftype[1] == "i": dsttype = gr.sizeof_int src_func = eval("blocks.vector_source_" + ftype[0]) data = [1 * 200] src = src_func(data) self.dst = blocks.null_sink(dsttype * 1) constellation = [ 1, 1, 1, 1, 1, -1, 1, -1, 1, 1, -1, -1, -1, 1, 1, -1, 1, -1, -1, -1, 1, -1, -1, -1 ] vbc = func(trellis.fsm(), 0, -1, trellis.fsm(), 0, -1, trellis.interleaver(), 10, 10, trellis.TRELLIS_MIN_SUM, 2, constellation, digital.TRELLIS_EUCLIDEAN, 1.0) ################################################## # Connections ################################################## self.connect((src, 0), (vbc, 0)) self.connect((vbc, 0), (self.dst, 0))
def set_denom_mother_code_rate(self, denom_mother_code_rate): self.denom_mother_code_rate = denom_mother_code_rate self.trellis_encoder_xx_top_0.set_FSM( trellis.fsm(1, self.denom_mother_code_rate, self.gen_poly)) self.trellis_encoder_xx_top.set_FSM( trellis.fsm(1, self.denom_mother_code_rate, self.gen_poly)) self.trellis_encoder_xx_bot.set_FSM( trellis.fsm(1, self.denom_mother_code_rate, self.gen_poly))
def set_gen_poly(self, gen_poly): self.gen_poly = gen_poly self.trellis_encoder_xx_top_0.set_FSM( trellis.fsm(1, self.denom_mother_code_rate, self.gen_poly)) self.trellis_encoder_xx_top.set_FSM( trellis.fsm(1, self.denom_mother_code_rate, self.gen_poly)) self.trellis_encoder_xx_bot.set_FSM( trellis.fsm(1, self.denom_mother_code_rate, self.gen_poly))
def set_fsm1(self, fsm1): self.fsm1 = fsm1 self.trellis_viterbi_combined_xx_1.set_FSM( trellis.fsm(self.prefix + self.fsm1)) self.trellis_viterbi_combined_xx_0_0.set_FSM( trellis.fsm(self.prefix + self.fsm1)) self.trellis_encoder_xx_2.set_FSM(trellis.fsm(self.prefix + self.fsm1)) self.trellis_encoder_xx_0.set_FSM(trellis.fsm(self.prefix + self.fsm1))
def set_fsm2(self, fsm2): self.fsm2 = fsm2 self.trellis_viterbi_combined_xx_2.set_FSM( trellis.fsm(self.prefix + self.fsm2)) self.trellis_viterbi_combined_xx_0.set_FSM( trellis.fsm(self.prefix + self.fsm2)) self.trellis_encoder_xx_2_0.set_FSM( trellis.fsm(self.prefix + self.fsm2)) self.trellis_encoder_xx_1.set_FSM(trellis.fsm(self.prefix + self.fsm2))
def main(args): nargs = len(args) if nargs == 3: fname_out = args[0] esn0_db = float(args[1]) rep = int(args[2]) else: sys.stderr.write("usage: test_turbo_equalization.py fsm_name_out Es/No_db repetitions\n") sys.exit(1) # system parameters Kb = 64 * 16 # packet size in bits (multiple of 16) modulation = fsm_utils.pam4 # see fsm_utlis.py for available predefined modulations channel = fsm_utils.c_channel # see fsm_utlis.py for available predefined test channels fo = trellis.fsm(fname_out) # get the outer FSM specification from a file fi = trellis.fsm(len(modulation[1]), len(channel)) # generate the FSM automatically if fo.O() != fi.I(): sys.stderr.write("Incompatible cardinality between outer and inner FSM.\n") sys.exit(1) bitspersymbol = int(round(math.log(fo.I()) / math.log(2))) # bits per FSM input symbol K = Kb / bitspersymbol # packet size in trellis steps print "size = ", K interleaver = trellis.interleaver(K, 666) # construct a random interleaver tot_channel = fsm_utils.make_isi_lookup( modulation, channel, True ) # generate the lookup table (normalize energy to 1) dimensionality = tot_channel[0] tot_constellation = tot_channel[1] if len(tot_constellation) / dimensionality != fi.O(): sys.stderr.write("Incompatible FSM output cardinality and lookup table size.\n") sys.exit(1) N0 = pow(10.0, -esn0_db / 10.0) # noise variance IT = 3 # number of turbo iterations tot_s = 0 # total number of transmitted shorts terr_s = 0 # total number of shorts in error terr_p = 0 # total number of packets in error for i in range(rep): (s, e) = run_test( fo, fi, interleaver, Kb, bitspersymbol, K, dimensionality, tot_constellation, 1, N0, IT, -long(666 + i) ) # run experiment with different seed to get different noise realizations print s tot_s = tot_s + s terr_s = terr_s + e terr_p = terr_p + (terr_s != 0) if (i + 1) % 10 == 0: # display progress print i + 1, terr_p, "%.2e" % ((1.0 * terr_p) / (i + 1)), tot_s, terr_s, "%.2e" % ((1.0 * terr_s) / tot_s) # estimate of the (short or bit) error rate print rep, terr_p, "%.2e" % ((1.0 * terr_p) / (i + 1)), tot_s, terr_s, "%.2e" % ((1.0 * terr_s) / tot_s)
def main(args): nargs = len(args) if nargs == 5: fname_out = args[0] fname_in = args[1] esn0_db = float(args[2]) # Es/No in dB IT = int(args[3]) rep = int(args[4]) # number of times the experiment is run to collect enough errors else: sys.stderr.write("usage: test_sccc_turbo.py fsm_name_out fsm_fname_in Es/No_db iterations repetitions\n") sys.exit(1) # system parameters Kb = 1024 * 16 # packet size in bits (make it multiple of 16 so it can be packed in a short) fo = trellis.fsm(fname_out) # get the outer FSM specification from a file fi = trellis.fsm(fname_in) # get the innner FSM specification from a file bitspersymbol = int(round(math.log(fo.I()) / math.log(2))) # bits per FSM input symbol if fo.O() != fi.I(): sys.stderr.write("Incompatible cardinality between outer and inner FSM.\n") sys.exit(1) K = Kb / bitspersymbol # packet size in trellis steps interleaver = trellis.interleaver(K, 666) # construct a random interleaver modulation = fsm_utils.psk8 # see fsm_utlis.py for available predefined modulations dimensionality = modulation[0] constellation = modulation[1] if len(constellation) / dimensionality != fi.O(): sys.stderr.write("Incompatible FSM output cardinality and modulation size.\n") sys.exit(1) # calculate average symbol energy Es = 0 for i in range(len(constellation)): Es = Es + constellation[i] ** 2 Es = Es / (len(constellation) / dimensionality) N0 = Es / pow(10.0, esn0_db / 10.0) # calculate noise variance tot_s = 0 # total number of transmitted shorts terr_s = 0 # total number of shorts in error terr_p = 0 # total number of packets in error for i in range(rep): (s, e) = run_test( fo, fi, interleaver, Kb, bitspersymbol, K, dimensionality, constellation, Es, N0, IT, -long(666 + i) ) # run experiment with different seed to get different noise realizations tot_s = tot_s + s terr_s = terr_s + e terr_p = terr_p + (terr_s != 0) if (i + 1) % 10 == 0: # display progress print i + 1, terr_p, "%.2e" % ((1.0 * terr_p) / (i + 1)), tot_s, terr_s, "%.2e" % ((1.0 * terr_s) / tot_s) # estimate of the (short or bit) error rate print rep, terr_p, "%.2e" % ((1.0 * terr_p) / (i + 1)), tot_s, terr_s, "%.2e" % ((1.0 * terr_s) / tot_s)
def make_gmsk(samples_per_symbol, BT): # M, K, P, h, L are fixed for GMSK M = 2 # number of bits per symbol K = 1 P = 2 # h=K/P, K and P are relatively prime h = (1.0 * K) / P L = 3 Q = samples_per_symbol frac = 0.99 # fractional energy component deemed necessary to consider in the trellis, for finding dimensionality fsm = trellis.fsm(P, M, L) tt = numpy.arange(0, L * Q) / (1.0 * Q) - L / 2.0 p = ( 0.5 * scipy.stats.erfc(2 * math.pi * BT * (tt - 0.5) / math.sqrt(math.log(2.0)) / math.sqrt(2.0)) - 0.5 * scipy.stats.erfc(2 * math.pi * BT * (tt + 0.5) / math.sqrt(math.log(2.0)) / math.sqrt(2.0)) ) / 2.0 p = p / sum(p) * Q / 2.0 q = numpy.cumsum(p) / Q q = q / q[-1] / 2.0 (f0T, SS, S, F, Sf, Ff, N) = fsm_utils.make_cpm_signals(K, P, M, L, q, frac) constellation = numpy.reshape(numpy.transpose(Sf), N * fsm.O()) Ffa = numpy.insert(Ff, Q, numpy.zeros(N), axis=0) MF = numpy.fliplr(numpy.transpose(Ffa)) return (fsm, constellation, MF, N, f0T)
def make_gmsk(samples_per_symbol, BT): #M, K, P, h, L are fixed for GMSK M = 2 #number of bits per symbol K = 1 P = 2 #h=K/P, K and P are relatively prime h = (1.0 * K) / P L = 3 Q = samples_per_symbol frac = 0.99 #fractional energy component deemed necessary to consider in the trellis, for finding dimensionality fsm = trellis.fsm(P, M, L) tt = numpy.arange(0, L * Q) / (1.0 * Q) - L / 2.0 p = (0.5 * scipy.stats.erfc(2 * math.pi * BT * (tt - 0.5) / math.sqrt( math.log(2.0)) / math.sqrt(2.0)) - 0.5 * scipy.stats.erfc( 2 * math.pi * BT * (tt + 0.5) / math.sqrt(math.log(2.0)) / math.sqrt(2.0))) / 2.0 p = p / sum(p) * Q / 2.0 q = numpy.cumsum(p) / Q q = q / q[-1] / 2.0 (f0T, SS, S, F, Sf, Ff, N) = fsm_utils.make_cpm_signals(K, P, M, L, q, frac) constellation = numpy.reshape(numpy.transpose(Sf), N * fsm.O()) Ffa = numpy.insert(Ff, Q, numpy.zeros(N), axis=0) MF = numpy.fliplr(numpy.transpose(Ffa)) return (fsm, constellation, MF, N, f0T)
def test_convolutional_encoder(self): """ Tests convolutional encoder """ src_data = make_transport_stream() constellation = [.7, .7, .7, -.7, -.7, .7, -.7, -.7] src = gr.vector_source_b(src_data) unpack = gr.packed_to_unpacked_bb(1, gr.GR_MSB_FIRST) enc = dvb_convolutional_encoder_bb.convolutional_encoder_bb() repack1 = gr.unpacked_to_packed_bb(1, gr.GR_MSB_FIRST) repack2 = gr.packed_to_unpacked_bb(2, gr.GR_MSB_FIRST) mapper = gr.chunks_to_symbols_bf(constellation, dvb_swig.dimensionality) viterbi = trellis.viterbi_combined_fb( trellis.fsm(dvb_swig.k, dvb_swig.n, dvb_convolutional_encoder_bb.G), dvb_swig.K, -1, -1, dvb_swig.dimensionality, constellation, digital.TRELLIS_EUCLIDEAN) pack = gr.unpacked_to_packed_bb(1, gr.GR_MSB_FIRST) dst = gr.vector_sink_b() self.tb.connect(src, unpack, enc, repack1, repack2, mapper) self.tb.connect(mapper, viterbi, pack, dst) self.tb.run() result_data = dst.data() self.assertEqual(tuple(src_data[:len(result_data)]), result_data)
def set_modulation(self, modulation): self.modulation = modulation self.set_tot_mod( fu.make_isi_lookup(self.modulation, self.channel, False)) self.set_fsm(trellis.fsm(len(self.modulation[1]), len(self.channel))) self.digital_chunks_to_symbols_xx_0_0.set_symbol_table( (self.modulation[1]))
def main(args): nargs = len (args) if nargs == 4: fname_out=args[0] fname_in=args[1] esn0_db=float(args[2]) # Es/No in dB rep=int(args[3]) # number of times the experiment is run to collect enough errors else: sys.stderr.write ('usage: test_tcm.py fsm_name_out fsm_fname_in Es/No_db repetitions\n') sys.exit (1) # system parameters Kb=1024*16 # packet size in bits (make it multiple of 16 so it can be packed in a short) fo=trellis.fsm(fname_out) # get the outer FSM specification from a file fi=trellis.fsm(fname_in) # get the innner FSM specification from a file bitspersymbol = int(round(math.log(fo.I())/math.log(2))) # bits per FSM input symbol if fo.O() != fi.I(): sys.stderr.write ('Incompatible cardinality between outer and inner FSM.\n') sys.exit (1) K=Kb/bitspersymbol # packet size in trellis steps interleaver=trellis.interleaver(K,666) # construct a random interleaver modulation = fsm_utils.psk8 # see fsm_utlis.py for available predefined modulations dimensionality = modulation[0] constellation = modulation[1] if len(constellation)/dimensionality != fi.O(): sys.stderr.write ('Incompatible FSM output cardinality and modulation size.\n') sys.exit (1) # calculate average symbol energy Es = 0 for i in range(len(constellation)): Es = Es + constellation[i]**2 Es = Es / (len(constellation)/dimensionality) N0=Es/pow(10.0,esn0_db/10.0); # calculate noise variance tot_s=0 # total number of transmitted shorts terr_s=0 # total number of shorts in error terr_p=0 # total number of packets in error for i in range(rep): (s,e)=run_test(fo,fi,interleaver,Kb,bitspersymbol,K,dimensionality,constellation,N0,-long(666+i)) # run experiment with different seed to get different noise realizations tot_s=tot_s+s terr_s=terr_s+e terr_p=terr_p+(terr_s!=0) if ((i+1)%100==0) : # display progress print i+1,terr_p, '%.2e' % ((1.0*terr_p)/(i+1)),tot_s,terr_s, '%.2e' % ((1.0*terr_s)/tot_s) # estimate of the (short or bit) error rate print rep,terr_p, '%.2e' % ((1.0*terr_p)/(i+1)),tot_s,terr_s, '%.2e' % ((1.0*terr_s)/tot_s)
def __init__(self, ftype): super(trellis_sccc_decoder_tb, self).__init__() func = eval("trellis.sccc_decoder_" + ftype) dsttype = gr.sizeof_int if ftype == "b": dsttype = gr.sizeof_char elif ftype == "s": dsttype = gr.sizeof_short elif ftype == "i": dsttype = gr.sizeof_int data = [1 * 200] src = blocks.vector_source_f(data) self.dst = blocks.null_sink(dsttype * 1) vbc = func(trellis.fsm(), 0, -1, trellis.fsm(1, 3, [91, 121, 117]), 0, -1, trellis.interleaver(), 10, 10, trellis.TRELLIS_MIN_SUM) self.connect((src, 0), (vbc, 0)) self.connect((vbc, 0), (self.dst, 0))
def __init__(self): gr.hier_block2.__init__(self, "bch_viterbi_vfvb", gr.io_signature(1, 1, gr.sizeof_float * 120), # Input signature gr.io_signature(1, 1, gr.sizeof_char * 40)) # Output signature # Define blocks and connect them # Repeat input vector one time to get viterbi decoder state right (tail-biting stuff) #self.rpt = blocks.repeat(gr.sizeof_float * 120, 2) # viterbi decoder requires stream as input #self.vtos = blocks.vector_to_stream(1 * gr.sizeof_float, 120) # self.vtss = blocks.vector_to_streams(1* gr.sizeof_float, 120, "bch_viterbi_vector_to_streams_0") self.vtss = blocks.vector_to_streams(1* gr.sizeof_float, 120) #self.app = blocks.streams_to_stream(1* gr.sizeof_float, 138, "bch_viterbi_streams_to_stream_0") self.app = blocks.streams_to_stream(1* gr.sizeof_float, 138) self.connect(self, self.vtss) for i in range(18): self.connect( (self.vtss, 120-18+i), (self.app, i) ) for i in range(120): self.connect( (self.vtss, i), (self.app, i+18) ) # Correct FSM instantiation: k=num_input_bits, n=num_output_bits, Tuple[dim(k*n)] (decimal notation) self.fsm = trellis.fsm(1, 3, [91, 121, 117]) # Values for viterbi decoder K = 46 # steps for one coding block SO = 0 # initial state SK = -1 # final state (in this case unknown, therefore -1) D = 3 # dimensionality # D = 3 follows from the fact that 1 {0,1} input symbol of the encoder produces 3 {0,1} output symbols. # (packed into one byte {0,1,...,7} ) # with NRZ coding follows: # 0 --> 1 # 1 --> -1 # This leads to the following constellation input # | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | constellation = [1, 1, 1, 1, 1, -1, 1, -1, 1, 1, -1, -1, -1, 1, 1, -1, 1, -1, -1, -1, 1, -1, -1, -1] # print "len(constellation)/D = " + str(len(constellation)/D) + "\tfsm.O = " + str(self.fsm.O()) # Viterbi_combined input: FSM, K, SO, SK, D, TABLE, TYPE # FSM = Finite State Machine # K = number of output symbols produced by the FSM # SO = initial state of the FSM # SK = final state of the FSM (unknown in this example) # D = dimensionality # TABLE = constellation of the input symbols # self.vit = trellis.viterbi_combined_fb(self.fsm, K, SO, SK, D, constellation, 200, "bch_viterbi_combined_fb_0") self.vit = trellis.viterbi_combined_fb(self.fsm, K, SO, SK, D, constellation, 200) self.connect(self.app, self.vit) # connect all streams which are crated yet #self.connect(self,self.rpt,self.vtos,self.vit) # self.keep = blocks.keep_m_in_n(gr.sizeof_char, 40, 46, 6, "bch_viterbi_keep_m_in_n_0") self.keep = blocks.keep_m_in_n(gr.sizeof_char, 40, 46, 6) # self.tovec = blocks.stream_to_vector(1, 40, "bch_viterbi_stream_to_vector_0") self.tovec = blocks.stream_to_vector(1, 40) self.connect(self.vit, self.keep, self.tovec, self)
def __init__(self): gr.hier_block2.__init__(self, "dvb_convolutional_encoder_bb", gr.io_signature(1, 1, gr.sizeof_char), # Input signature gr.io_signature(1, 1, gr.sizeof_char)) # Output signature self.encoder = trellis.encoder_bb(trellis.fsm(dvb_swig.k, dvb_swig.n, G), dvb_swig.dimensionality) self.unpack = gr.unpack_k_bits_bb(dvb_swig.dimensionality) self.connect(self, self.encoder, self.unpack, self)
def __init__(self, N): self.N = N # Generate some random bits rndm = random.Random() rndm.seed(0) self.coding = 1 self.interleave = 0 self.fo = trellis.fsm(1, 2, [91, 121])
def __init__(self): gr.hier_block2.__init__( self, "bch_viterbi_vfvb", gr.io_signature(1, 1, gr.sizeof_float * 120), # Input signature gr.io_signature(1, 1, gr.sizeof_char * 40)) # Output signature # Define blocks and connect them # Repeat input vector one time to get viterbi decoder state right (tail-biting stuff) #self.rpt = blocks.repeat(gr.sizeof_float * 120, 2) # viterbi decoder requires stream as input #self.vtos = blocks.vector_to_stream(1 * gr.sizeof_float, 120) self.vtss = blocks.vector_to_streams(1 * gr.sizeof_float, 120) self.app = blocks.streams_to_stream(1 * gr.sizeof_float, 138) self.connect(self, self.vtss) for i in range(18): self.connect((self.vtss, 120 - 18 + i), (self.app, i)) for i in range(120): self.connect((self.vtss, i), (self.app, i + 18)) # Correct FSM instantiation: k=num_input_bits, n=num_output_bits, Tuple[dim(k*n)] (decimal notation) self.fsm = trellis.fsm(1, 3, [91, 121, 117]) # Values for viterbi decoder K = 46 # steps for one coding block SO = 0 # initial state SK = -1 # final state (in this case unknown, therefore -1) D = 3 # dimensionality # D = 3 follows from the fact that 1 {0,1} input symbol of the encoder produces 3 {0,1} output symbols. # (packed into one byte {0,1,...,7} ) # with NRZ coding follows: # 0 --> 1 # 1 --> -1 # This leads to the following constellation input # | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | constellation = [ 1, 1, 1, 1, 1, -1, 1, -1, 1, 1, -1, -1, -1, 1, 1, -1, 1, -1, -1, -1, 1, -1, -1, -1 ] # print "len(constellation)/D = " + str(len(constellation)/D) + "\tfsm.O = " + str(self.fsm.O()) # Viterbi_combined input: FSM, K, SO, SK, D, TABLE, TYPE # FSM = Finite State Machine # K = number of output symbols produced by the FSM # SO = initial state of the FSM # SK = final state of the FSM (unknown in this example) # D = dimensionality # TABLE = constellation of the input symbols self.vit = trellis.viterbi_combined_fb(self.fsm, K, SO, SK, D, constellation, 200) self.connect(self.app, self.vit) # connect all streams which are crated yet #self.connect(self,self.rpt,self.vtos,self.vit) self.keep = blocks.keep_m_in_n(gr.sizeof_char, 40, 46, 6) self.tovec = blocks.stream_to_vector(1, 40) self.connect(self.vit, self.keep, self.tovec, self)
def __init__(self, N): self.N = N # Generate some random bits rndm = random.Random() rndm.seed(0) self.coding = 1 self.interleave = 0 self.fo=trellis.fsm(1,2,[91,121])
def __init__(self, ): # """ # docstring # """ gr.hier_block2.__init__(self, "viterbi_vfvb", gr.io_signature(1,1, gr.sizeof_float*120), # sizeof (<+float+>)), # Input signature gr.io_signature(1,1, gr.sizeof_char*40 )) #sizeof (<+float+>))) # Output signature #print "\nlte_viterbi_vfvb START" #tpp=gr.tag_propagation_policy() ################################# # Define blocks # Repeat input vector one time to get viterbi decoder state right (tail-biting stuff) self.rpt = gr.repeat(gr.sizeof_float*120,2) # viterbi decoder requires stream as input self.vtos = gr.vector_to_stream(1*gr.sizeof_float,120) # Correct FSM instantiation: k=num_input_bits, n=num_output_bits, Tuple[dim(k*n)] (decimal notation) self.fsm = trellis.fsm(1,3,[91,121,117]) # Values for viterbi decoder K = 80 # steps for one coding block SO = 0 # initial state SK = -1 # final state (in this case unknown, therefore -1) D = 3 # dimensionality # D = 3 follows from the fact that 1 {0,1} input symbol of the encoder produces 3 {0,1} output symbols. # (packed into one byte {0,1,...,7} ) # with NRZ coding follows: # 0 --> 1 # 1 --> -1 # This leads to the following constellation input # | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | constellation = [1,1,1,1,1,-1,1,-1,1,1,-1,-1,-1,1,1,-1,1,-1,-1,-1,1,-1,-1,-1] # print "len(constellation)/D = " + str(len(constellation)/D) + "\tfsm.O = " + str(self.fsm.O()) # Viterbi_combined input: FSM, K, SO, SK, D, TABLE, TYPE # FSM = Finite State Machine # K = number of output symbols produced by the FSM # SO = initial state of the FSM # SK = final state of the FSM (unknown in this example) # D = dimensionality # TABLE = constellation of the input symbols self.vit = trellis.viterbi_combined_fb(self.fsm,K,SO,SK,D,constellation,200) # stream output of viterbi decoder to vector self.stov2 = gr.stream_to_vector(1*gr.sizeof_char,80) # second half of the viterbi output carries desired information. (tail-biting stuff) my_map=range(40) for i in my_map: my_map[i]=i+40 self.map = lte.vector_resize_vbvb(my_map,80,40) self.connect(self,self.rpt,self.vtos,self.vit,self.stov2,self.map,self)
def main(args): nargs = len(args) if nargs == 3: fname = args[0] esn0_db = float(args[1]) # Es/No in dB rep = int( args[2] ) # number of times the experiment is run to collect enough errors else: sys.stderr.write( 'usage: test_tcm_combined.py fsm_fname Es/No_db repetitions\n') sys.exit(1) # system parameters f = trellis.fsm( fname ) # get the FSM specification from a file (will hopefully be automated in the future...) Kb = 1024 * 16 # packet size in bits (make it multiple of 16) bitspersymbol = int(round(math.log(f.I()) / math.log(2))) # bits per FSM input symbol K = Kb / bitspersymbol # packet size in trellis steps modulation = fsm_utils.psk4 # see fsm_utils.py for available predefined modulations dimensionality = modulation[0] constellation = modulation[1] if len(constellation) / dimensionality != f.O(): sys.stderr.write( 'Incompatible FSM output cardinality and modulation size.\n') sys.exit(1) # calculate average symbol energy Es = 0 for i in range(len(constellation)): Es = Es + constellation[i]**2 Es = Es / (len(constellation) / dimensionality) N0 = Es / pow(10.0, esn0_db / 10.0) # noise variance tot_s = 0 # total number of transmitted shorts terr_s = 0 # total number of shorts in error terr_p = 0 # total number of packets in error for i in range(rep): (s, e) = run_test( f, Kb, bitspersymbol, K, dimensionality, constellation, N0, -long(666 + i) ) # run experiment with different seed to get different noise realizations tot_s = tot_s + s terr_s = terr_s + e terr_p = terr_p + (terr_s != 0) if ((i + 1) % 100 == 0): # display progress print i + 1, terr_p, '%.2e' % ((1.0 * terr_p) / (i + 1)), tot_s, terr_s, '%.2e' % ( (1.0 * terr_s) / tot_s) # estimate of the (short or bit) error rate print rep, terr_p, '%.2e' % ((1.0 * terr_p) / (i + 1)), tot_s, terr_s, '%.2e' % ( (1.0 * terr_s) / tot_s)
def __init__(self): gr.hier_block2.__init__( self, "dvb_convolutional_encoder_bb", gr.io_signature(1, 1, gr.sizeof_char), # Input signature gr.io_signature(1, 1, gr.sizeof_char)) # Output signature self.encoder = trellis.encoder_bb( trellis.fsm(dvb_swig.k, dvb_swig.n, G), dvb_swig.dimensionality) self.unpack = gr.unpack_k_bits_bb(dvb_swig.dimensionality) self.connect(self, self.encoder, self.unpack, self)
def main(args): nargs = len(args) if nargs == 2: esn0_db = float(args[0]) rep = int(args[1]) else: sys.stderr.write( 'usage: test_viterbi_equalization1.py Es/No_db repetitions\n') sys.exit(1) # system parameters Kb = 2048 # packet size in bits modulation = fsm_utils.pam4 # see fsm_utlis.py for available predefined modulations channel = fsm_utils.c_channel # see fsm_utlis.py for available predefined test channels f = trellis.fsm(len(modulation[1]), len(channel)) # generate the FSM automatically bitspersymbol = int(round(math.log(f.I()) / math.log(2))) # bits per FSM input symbol K = Kb / bitspersymbol # packet size in trellis steps tot_channel = fsm_utils.make_isi_lookup( modulation, channel, True) # generate the lookup table (normalize energy to 1) dimensionality = tot_channel[0] tot_constellation = tot_channel[1] N0 = pow(10.0, -esn0_db / 10.0) # noise variance if len(tot_constellation) / dimensionality != f.O(): sys.stderr.write( 'Incompatible FSM output cardinality and lookup table size.\n') sys.exit(1) tot_s = 0 # total number of transmitted shorts terr_s = 0 # total number of shorts in error terr_p = 0 # total number of packets in error for i in range(rep): (s, e) = run_test( f, Kb, bitspersymbol, K, channel, modulation, dimensionality, tot_constellation, N0, -long(666 + i) ) # run experiment with different seed to get different data and noise realizations tot_s = tot_s + s terr_s = terr_s + e terr_p = terr_p + (terr_s != 0) if ((i + 1) % 100 == 0): # display progress print i + 1, terr_p, '%.2e' % ((1.0 * terr_p) / (i + 1)), tot_s, terr_s, '%.2e' % ( (1.0 * terr_s) / tot_s) # estimate of the (short or symbol) error rate print rep, terr_p, '%.2e' % ((1.0 * terr_p) / (i + 1)), tot_s, terr_s, '%.2e' % ( (1.0 * terr_s) / tot_s)
def main(): parser = OptionParser(option_class=eng_option) parser.add_option("-f", "--fsm_file", type="string", default="fsm_files/awgn1o2_4.fsm", help="Filename containing the fsm specification, e.g. -f fsm_files/awgn1o2_4.fsm (default=fsm_files/awgn1o2_4.fsm)") parser.add_option("-e", "--esn0", type="eng_float", default=10.0, help="Symbol energy to noise PSD level ratio in dB, e.g., -e 10.0 (default=10.0)") parser.add_option("-r", "--repetitions", type="int", default=100, help="Number of packets to be generated for the simulation, e.g., -r 100 (default=100)") (options, args) = parser.parse_args () if len(args) != 0: parser.print_help() raise SystemExit(1) fname=options.fsm_file esn0_db=float(options.esn0) rep=int(options.repetitions) # system parameters f=trellis.fsm(fname) # get the FSM specification from a file # alternatively you can specify the fsm from its generator matrix #f=trellis.fsm(1,2,[5,7]) Kb=1024*16 # packet size in bits (make it multiple of 16 so it can be packed in a short) bitspersymbol = int(round(math.log(f.I()) / math.log(2))) # bits per FSM input symbol K=Kb / bitspersymbol # packet size in trellis steps modulation = fsm_utils.psk4 # see fsm_utlis.py for available predefined modulations dimensionality = modulation[0] constellation = modulation[1] if len(constellation) / dimensionality != f.O(): sys.stderr.write ('Incompatible FSM output cardinality and modulation size.\n') sys.exit (1) # calculate average symbol energy Es = 0 for i in range(len(constellation)): Es = Es + constellation[i]**2 Es = Es / (len(constellation)//dimensionality) N0=Es / pow(10.0,esn0_db/10.0); # calculate noise variance tot_b=0 # total number of transmitted bits terr_b=0 # total number of bits in error terr_p=0 # total number of packets in error for i in range(rep): (b,e,pattern)=run_test(f,Kb,bitspersymbol,K,dimensionality,constellation,N0,-(666+i)) # run experiment with different seed to get different noise realizations tot_b=tot_b+b terr_b=terr_b+e terr_p=terr_p+(e!=0) if ((i+1)%100==0) : # display progress print(i+1,terr_p, '%.2e' % ((1.0*terr_p) / (i+1)),tot_b,terr_b, '%.2e' % ((1.0*terr_b) / tot_b)) if e!=0: print("rep=",i, e) for k in range(Kb): if pattern[k]!=0: print(k) # estimate of the bit error rate print(rep,terr_p, '%.2e' % ((1.0*terr_p) / (i+1)),tot_b,terr_b, '%.2e' % ((1.0*terr_b) / tot_b))
def test_001_viterbi(self): """ Runs some coding/decoding tests with a few different FSM specs. """ for name, args in fsm_args.items(): constellation = constells[args[2]] fsms = trellis.fsm(*args) noise = 0.1 tb = trellis_tb(constellation, fsms, noise) tb.run() # Make sure all packets successfully transmitted. self.assertEqual(tb.dst.ntotal(), tb.dst.nright())
def test_001_viterbi(self): """ Runs some coding/decoding tests with a few different FSM specs. """ for name, args in list(fsm_args.items()): constellation = constells[args[2]] fsms = trellis.fsm(*args) noise = 0.1 tb = trellis_tb(constellation, fsms, noise) tb.run() # Make sure all packets successfully transmitted. self.assertEqual(tb.dst.ntotal(), tb.dst.nright())
def set_prefix(self, prefix): self.prefix = prefix self.trellis_viterbi_combined_xx_2.set_FSM( trellis.fsm(self.prefix + self.fsm2)) self.trellis_viterbi_combined_xx_1.set_FSM( trellis.fsm(self.prefix + self.fsm1)) self.trellis_viterbi_combined_xx_0_0.set_FSM( trellis.fsm(self.prefix + self.fsm1)) self.trellis_viterbi_combined_xx_0.set_FSM( trellis.fsm(self.prefix + self.fsm2)) self.trellis_encoder_xx_2_0.set_FSM( trellis.fsm(self.prefix + self.fsm2)) self.trellis_encoder_xx_2.set_FSM(trellis.fsm(self.prefix + self.fsm1)) self.trellis_encoder_xx_1.set_FSM(trellis.fsm(self.prefix + self.fsm2)) self.trellis_encoder_xx_0.set_FSM(trellis.fsm(self.prefix + self.fsm1))
def __init__(self, pkt_len, nb_pkt, EbN0dB, fsm): gr.top_block.__init__(self, "Transmitter, channel and metrics computation") ################################################## # Variables ################################################## self.pkt_len = pkt_len Rc = 0.5 self.const = const = digital.constellation_bpsk().base() var_c = 1 Nb = 1 Eb = var_c / (2.0 * Nb * Rc) N0 = Eb * 10**(-EbN0dB / 10.0) noisevar = 2 * N0 ################################################## # Blocks ################################################## self.bits_src = blocks.vector_source_b( map(int, numpy.random.randint(0, 2, nb_pkt * pkt_len)), False) self.trellis_encoder = trellis.encoder_bb(trellis.fsm(fsm), 0, pkt_len) self.unpack = blocks.unpack_k_bits_bb(2) self.to_symbols = digital.chunks_to_symbols_bc((const.points()), 1) self.noise_src = analog.noise_source_c(analog.GR_GAUSSIAN, noisevar, 0) self.noise_adder = blocks.add_vcc(1) self.metrics_computer = trellis.metrics_c( 4, 2, ([-1, -1, -1, 1, 1, -1, 1, 1]), digital.TRELLIS_EUCLIDEAN) self.dst = blocks.vector_sink_f() ################################################## # Connections ################################################## self.connect((self.bits_src, 0), (self.trellis_encoder, 0)) self.connect((self.trellis_encoder, 0), (self.unpack, 0)) self.connect((self.unpack, 0), (self.to_symbols, 0)) self.connect((self.to_symbols, 0), (self.noise_adder, 0)) self.connect((self.noise_src, 0), (self.noise_adder, 1)) self.connect((self.noise_adder, 0), (self.metrics_computer, 0)) self.connect((self.metrics_computer, 0), (self.dst, 0))
def __init__(self, vlen_in=1, vlen_out=1, n_tailbits=6, denom_mother_code_rate=6, gen_poly=(91, 121, 101, 91, 121, 101), N=1, bits_per_symbol=0, pp=0, pp_tail=0, interl_seq=range(2), map_tab=0): gr.hier_block2.__init__( self, "DRM MLC 4-QAM", gr.io_signature(1, 1, gr.sizeof_char*vlen_in), gr.io_signature(1, 1, gr.sizeof_gr_complex*vlen_out), ) ################################################## # Parameters ################################################## self.vlen_in = vlen_in self.vlen_out = vlen_out self.n_tailbits = n_tailbits self.denom_mother_code_rate = denom_mother_code_rate self.gen_poly = gen_poly self.N = N self.bits_per_symbol = bits_per_symbol self.pp = pp self.pp_tail = pp_tail self.interl_seq = interl_seq self.map_tab = map_tab ################################################## # Blocks ################################################## self.trellis_encoder_xx_0 = trellis.encoder_bb(trellis.fsm(1, denom_mother_code_rate, gen_poly), 0) self.gr_vector_to_stream_0 = gr.vector_to_stream(gr.sizeof_char*1, vlen_in + n_tailbits) self.gr_unpack_k_bits_bb_0 = gr.unpack_k_bits_bb(denom_mother_code_rate) self.gr_stream_to_vector_0 = gr.stream_to_vector(gr.sizeof_char*1, (vlen_in + n_tailbits) * denom_mother_code_rate) self.drm_qam_map_vbvc_0 = drm.qam_map_vbvc(map_tab, bits_per_symbol, vlen_out, 1) self.drm_punct_vbvb_0 = drm.punct_vbvb(pp, pp_tail, (vlen_in + n_tailbits) * denom_mother_code_rate, vlen_out * 2, n_tailbits * denom_mother_code_rate) self.drm_interleaver_vbvb_0 = drm.interleaver_vbvb((interl_seq)) self.add_tailbits_vbvb_0 = drm.add_tailbits_vbvb(vlen_in, n_tailbits) ################################################## # Connections ################################################## self.connect((self, 0), (self.add_tailbits_vbvb_0, 0)) self.connect((self.add_tailbits_vbvb_0, 0), (self.gr_vector_to_stream_0, 0)) self.connect((self.gr_vector_to_stream_0, 0), (self.trellis_encoder_xx_0, 0)) self.connect((self.trellis_encoder_xx_0, 0), (self.gr_unpack_k_bits_bb_0, 0)) self.connect((self.gr_unpack_k_bits_bb_0, 0), (self.gr_stream_to_vector_0, 0)) self.connect((self.gr_stream_to_vector_0, 0), (self.drm_punct_vbvb_0, 0)) self.connect((self.drm_punct_vbvb_0, 0), (self.drm_interleaver_vbvb_0, 0)) self.connect((self.drm_interleaver_vbvb_0, 0), (self.drm_qam_map_vbvc_0, 0)) self.connect((self.drm_qam_map_vbvc_0, 0), (self, 0))
def main(args): nargs = len(args) if nargs == 3: fname = args[0] esn0_db = float(args[1]) # Es/No in dB # number of times the experiment is run to collect enough errors rep = int(args[2]) else: sys.stderr.write( 'usage: test_tcm.py fsm_fname Es/No_db repetitions\n') sys.exit(1) # system parameters f = trellis.fsm(fname) # get the FSM specification from a file # packet size in bits (make it multiple of 16 so it can be packed in a short) Kb = 1024 * 16 # bits per FSM input symbol bitspersymbol = int(round(math.log(f.I()) / math.log(2))) K = Kb / bitspersymbol # packet size in trellis steps modulation = fsm_utils.psk4 # see fsm_utlis.py for available predefined modulations dimensionality = modulation[0] constellation = modulation[1] if len(constellation) / dimensionality != f.O(): sys.stderr.write( 'Incompatible FSM output cardinality and modulation size.\n') sys.exit(1) # calculate average symbol energy Es = 0 for i in range(len(constellation)): Es = Es + constellation[i]**2 Es = Es / (len(constellation) // dimensionality) N0 = Es / pow(10.0, esn0_db / 10.0) # noise variance tot_s = 0 terr_s = 0 for i in range(rep): # run experiment with different seed to get different noise realizations (s, e) = run_test(f, Kb, bitspersymbol, K, dimensionality, constellation, N0, -int(666 + i)) tot_s = tot_s + s terr_s = terr_s + e if (i % 100 == 0): print(i, s, e, tot_s, terr_s, '%e' % ((1.0 * terr_s) / tot_s)) # estimate of the (short) error rate print(tot_s, terr_s, '%e' % ((1.0 * terr_s) / tot_s))
def main(args): nargs = len(args) if nargs == 2: esn0_db = float(args[0]) rep = int(args[1]) else: sys.stderr.write("usage: test_viterbi_equalization.py Es/No_db repetitions\n") sys.exit(1) # system parameters Kb = 128 * 16 # packet size in bits (multiple of 16) modulation = fsm_utils.pam4 # see fsm_utlis.py for available predefined modulations channel = fsm_utils.c_channel # see fsm_utlis.py for available predefined test channels f = trellis.fsm(len(modulation[1]), len(channel)) # generate the FSM automatically bitspersymbol = int(round(math.log(f.I()) / math.log(2))) # bits per FSM input symbol K = Kb / bitspersymbol # packet size in trellis steps tot_channel = fsm_utils.make_isi_lookup( modulation, channel, True ) # generate the lookup table (normalize energy to 1) dimensionality = tot_channel[0] tot_constellation = tot_channel[1] N0 = pow(10.0, -esn0_db / 10.0) # noise variance if len(tot_constellation) / dimensionality != f.O(): sys.stderr.write("Incompatible FSM output cardinality and lookup table size.\n") sys.exit(1) tot_s = 0 # total number of transmitted shorts terr_s = 0 # total number of shorts in error terr_p = 0 # total number of packets in error for i in range(rep): (s, e) = run_test( f, Kb, bitspersymbol, K, dimensionality, tot_constellation, N0, -long(666 + i) ) # run experiment with different seed to get different noise realizations tot_s = tot_s + s terr_s = terr_s + e terr_p = terr_p + (terr_s != 0) if (i + 1) % 100 == 0: # display progress print i + 1, terr_p, "%.2e" % ((1.0 * terr_p) / (i + 1)), tot_s, terr_s, "%.2e" % ((1.0 * terr_s) / tot_s) # estimate of the (short or bit) error rate print rep, terr_p, "%.2e" % ((1.0 * terr_p) / (i + 1)), tot_s, terr_s, "%.2e" % ((1.0 * terr_s) / tot_s)
def __init__(self, vlen_in=1, vlen_out=1, n_tailbits=1, denom_mother_code_rate=1, map_tab=0, interl_seq=(0,1), bits_per_symbol=1, pp=0, pp_tail=0, gen_poly=0): gr.hier_block2.__init__( self, "MLC 4QAM", gr.io_signature(1, 1, gr.sizeof_char*1), gr.io_signature(1, 1, gr.sizeof_gr_complex*1), ) ################################################## # Parameters ################################################## self.vlen_in = vlen_in self.vlen_out = vlen_out self.n_tailbits = n_tailbits self.denom_mother_code_rate = denom_mother_code_rate self.map_tab = map_tab self.interl_seq = interl_seq self.bits_per_symbol = bits_per_symbol self.pp = pp self.pp_tail = pp_tail self.gen_poly = gen_poly ################################################## # Blocks ################################################## self.trellis_encoder_xx_0 = trellis.encoder_bb(trellis.fsm(1, denom_mother_code_rate, gen_poly), 0, 0) if False else trellis.encoder_bb(trellis.fsm(1, denom_mother_code_rate, gen_poly), 0) self.drm_qam_map_bc_0 = drm.qam_map_bc(map_tab, bits_per_symbol, vlen_out, 1) self.drm_punct_bb_0 = drm.punct_bb(pp, pp_tail, (vlen_in + n_tailbits) * denom_mother_code_rate, vlen_out * 2, n_tailbits * denom_mother_code_rate) self.drm_interleaver_bb_0 = drm.interleaver_bb(((interl_seq))) self.blocks_unpack_k_bits_bb_0 = blocks.unpack_k_bits_bb(denom_mother_code_rate) self.add_tailbits_bb_0 = drm.add_tailbits_bb(vlen_in, n_tailbits) ################################################## # Connections ################################################## self.connect((self.add_tailbits_bb_0, 0), (self.trellis_encoder_xx_0, 0)) self.connect((self.blocks_unpack_k_bits_bb_0, 0), (self.drm_punct_bb_0, 0)) self.connect((self.drm_interleaver_bb_0, 0), (self.drm_qam_map_bc_0, 0)) self.connect((self.drm_punct_bb_0, 0), (self.drm_interleaver_bb_0, 0)) self.connect((self.drm_qam_map_bc_0, 0), (self, 0)) self.connect((self, 0), (self.add_tailbits_bb_0, 0)) self.connect((self.trellis_encoder_xx_0, 0), (self.blocks_unpack_k_bits_bb_0, 0))
def test_001_t(self): # Trellislength K = 3072 # Bit in one packet n = 2 # Bit in codeword k = 5 # Constraint length start_state = 0 end_state = -1 # Endstate not defined fsm = fsm_args["awgn1o2_16"] ## setup dummy data os = numpy.array(fsm[4], dtype=int) # Encoder output matrix data = numpy.random.randint(0, 2, K) # Create 0s and 1s sym_table = digital.constellation_qpsk() # Setup blocks data_src = blocks.vector_source_s(map(int, data)) src_head = blocks.head(gr.sizeof_short * 1, K) # TX Sim encoder = trellis.encoder_ss(trellis.fsm(*fsm), 0) modulator = digital.chunks_to_symbols_sc(sym_table.points(), 1) # Decoder viterbi_cel = celec.gen_viterbi_fi(n, k, K, start_state, end_state, sym_table.points(), os) # Sinks rx_sink = blocks.vector_sink_b(1) # Connections self.tb.connect(data_src, src_head, encoder) self.tb.connect(encoder, modulator) self.tb.connect(modulator, viterbi_cel) self.tb.connect(viterbi_cel, rx_sink) self.tb.run() # # Check data rx_output = numpy.array(rx_sink.data()) for k in range(0, K): self.assertEqual(int(rx_output[k]), int(data[k]))
def main(args): nargs = len (args) if nargs == 3: fname=args[0] esn0_db=float(args[1]) # Es/No in dB rep=int(args[2]) # number of times the experiment is run to collect enough errors else: sys.stderr.write ('usage: test_tcm.py fsm_fname Es/No_db repetitions\n') sys.exit (1) # system parameters f=trellis.fsm(fname) # get the FSM specification from a file P=4 # how many parallel streams? Kb=1024*16 # packet size in bits (make it multiple of 16 so it can be packed in a short) bitspersymbol = int(round(math.log(f.I())/math.log(2))) # bits per FSM input symbol K=Kb/bitspersymbol # packet size in trellis steps modulation = fsm_utils.psk4 # see fsm_utlis.py for available predefined modulations dimensionality = modulation[0] constellation = modulation[1] if len(constellation)/dimensionality != f.O(): sys.stderr.write ('Incompatible FSM output cardinality and modulation size.\n') sys.exit (1) # calculate average symbol energy Es = 0 for i in range(len(constellation)): Es = Es + constellation[i]**2 Es = Es / (len(constellation)/dimensionality) N0=Es/pow(10.0,esn0_db/10.0); # calculate noise variance tot_s=0 # total number of transmitted shorts terr_s=0 # total number of shorts in error terr_p=0 # total number of packets in error for i in range(rep): (s,e)=run_test(f,Kb,bitspersymbol,K,dimensionality,constellation,N0,-long(666+i),P) # run experiment with different seed to get different noise realizations tot_s=tot_s+s terr_s=terr_s+e terr_p=terr_p+(terr_s!=0) if ((i+1)%100==0) : # display progress print i+1,terr_p, '%.2e' % ((1.0*terr_p)/(i+1)),tot_s,terr_s, '%.2e' % ((1.0*terr_s)/tot_s) # estimate of the (short or bit) error rate print rep,terr_p, '%.2e' % ((1.0*terr_p)/(i+1)),tot_s,terr_s, '%.2e' % ((1.0*terr_s)/tot_s)
def test_001_t (self): # Trellislength K = 3072 # Bit in one packet n = 2 # Bit in codeword k = 5 # Constraint length start_state = 0 end_state = -1 # Endstate not defined fsm = fsm_args["awgn1o2_16"] ## setup dummy data os = numpy.array(fsm[4], dtype=int) # Encoder output matrix data = numpy.random.randint(0,2,K) # Create 0s and 1s sym_table = digital.constellation_qpsk() # Setup blocks data_src = blocks.vector_source_s(map(int, data)) src_head = blocks.head(gr.sizeof_short*1, K) # TX Sim encoder = trellis.encoder_ss(trellis.fsm(*fsm), 0) modulator = digital.chunks_to_symbols_sc(sym_table.points(), 1) # Decoder viterbi_cel = celec.gen_viterbi_fi(n, k, K, start_state, end_state, sym_table.points(), os) # Sinks rx_sink = blocks.vector_sink_b(1) # Connections self.tb.connect(data_src, src_head, encoder) self.tb.connect(encoder, modulator) self.tb.connect(modulator, viterbi_cel) self.tb.connect(viterbi_cel, rx_sink) self.tb.run () # # Check data rx_output = numpy.array(rx_sink.data()) for k in range(0, K): self.assertEqual(int(rx_output[k]), int(data[k]))
def fsm_radix(f,n): I=f.I()**n S=f.S() O=f.O()**n nsm=list([0]*I*S) osm=list([0]*I*S) for s in range(f.S()): for i in range(I): ii=dec2base(i,f.I(),n) oo=list([0]*n) ns=s for k in range(n): oo[k]=f.OS()[ns*f.I()+ii[k]] ns=f.NS()[ns*f.I()+ii[k]] nsm[s*I+i]=ns osm[s*I+i]=base2dec(oo,f.O()) f=trellis.fsm(I,S,O,nsm,osm) return f
def test_convolutional_encoder(self): """ Tests convolutional encoder """ src_data = make_transport_stream() constellation = [.7, .7,.7,-.7,-.7,.7,-.7,-.7] src = gr.vector_source_b(src_data) unpack = gr.packed_to_unpacked_bb(1, gr.GR_MSB_FIRST) enc = dvb_convolutional_encoder_bb.convolutional_encoder_bb() repack1 = gr.unpacked_to_packed_bb(1, gr.GR_MSB_FIRST) repack2 = gr.packed_to_unpacked_bb(2, gr.GR_MSB_FIRST) mapper = gr.chunks_to_symbols_bf(constellation, dvb_swig.dimensionality) viterbi = trellis.viterbi_combined_fb(trellis.fsm(dvb_swig.k, dvb_swig.n, dvb_convolutional_encoder_bb.G), dvb_swig.K, -1, -1, dvb_swig.dimensionality, constellation, trellis.TRELLIS_EUCLIDEAN) pack = gr.unpacked_to_packed_bb(1, gr.GR_MSB_FIRST) dst = gr.vector_sink_b() self.tb.connect(src, unpack, enc, repack1, repack2, mapper) self.tb.connect(mapper, viterbi, pack, dst) self.tb.run() result_data = dst.data() self.assertEqual(tuple(src_data[:len(result_data)]), result_data)
def fsm_concatenate(f1,f2): if f1.O() > f2.I(): print "Not compatible FSMs\n" I=f1.I() S=f1.S()*f2.S() O=f2.O() nsm=list([0]*I*S) osm=list([0]*I*S) for s1 in range(f1.S()): for s2 in range(f2.S()): for i in range(f1.I()): ns1=f1.NS()[s1*f1.I()+i] o1=f1.OS()[s1*f1.I()+i] ns2=f2.NS()[s2*f2.I()+o1] o2=f2.OS()[s2*f2.I()+o1] s=s1*f2.S()+s2 ns=ns1*f2.S()+ns2 nsm[s*I+i]=ns osm[s*I+i]=o2 f=trellis.fsm(I,S,O,nsm,osm) return f
def __init__(self, options): gr.hier_block2.__init__(self, "transmit_path", gr.io_signature(0, 0, 0), gr.io_signature(1, 1, gr.sizeof_gr_complex)) common_options.defaults(options) config = self.config = station_configuration() config.data_subcarriers = options.subcarriers config.cp_length = options.cp_length config.frame_data_blocks = options.data_blocks config._verbose = options.verbose config.fft_length = options.fft_length config.dc_null = options.dc_null config.training_data = default_block_header(config.data_subcarriers, config.fft_length, config.dc_null, options) config.coding = options.coding config.bandwidth = options.bandwidth config.gui_frame_rate = options.gui_frame_rate config.fbmc = options.fbmc config.frame_id_blocks = 1 # FIXME # digital rms amplitude sent to USRP rms_amp = options.rms_amplitude self._options = copy.copy(options) 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.frame_data_part + \ config.training_data.no_pilotsyms config.subcarriers = config.data_subcarriers + \ config.training_data.pilot_subcarriers config.virtual_subcarriers = config.fft_length - config.subcarriers - config.dc_null # default values if parameters not set if rms_amp is None: rms_amp = math.sqrt(config.subcarriers) config.rms_amplitude = rms_amp # 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" ## shortcuts blen = config.block_length flen = config.frame_length dsubc = config.data_subcarriers vsubc = config.virtual_subcarriers # Adaptive Transmitter Concept used_id_bits = config.used_id_bits = 8 #TODO: no constant in source code rep_id_bits = config.rep_id_bits = config.data_subcarriers / used_id_bits #BPSK if config.data_subcarriers % used_id_bits <> 0: raise SystemError, "Data subcarriers need to be multiple of %d" % ( used_id_bits) # adapt OFDM frame rate and GUI display frame rate self.keep_frame_n = int( 1.0 / (config.frame_length * (config.cp_length + config.fft_length) / config.bandwidth) / config.gui_frame_rate) ## Allocation Control self.allocation_src = allocation_src( config.data_subcarriers, config.frame_data_blocks, config.coding, "tcp://*:3333", "tcp://" + options.rx_hostname + ":3322") if options.static_allocation: #DEBUG # how many bits per subcarrier 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 modulbitspermode = [1, 2, 2, 4, 4, 6, 6, 6, 8] # Coding bits per mode bitcount_vec = [ (int)(config.data_subcarriers * config.frame_data_blocks * bitspermode[mode - 1]) ] modul_bitcount_vec = [ config.data_subcarriers * config.frame_data_blocks * modulbitspermode[mode - 1] ] bitcount_src = blocks.vector_source_i(bitcount_vec, True, 1) modul_bitcount_src = blocks.vector_source_i( modul_bitcount_vec, True, 1) bitloading = mode else: bitloading = 1 bitcount_vec = [ config.data_subcarriers * config.frame_data_blocks * bitloading ] bitcount_src = blocks.vector_source_i(bitcount_vec, True, 1) modul_bitcount_src = bitcount_src # id's for frames id_vec = range(0, 256) id_src = blocks.vector_source_s(id_vec, True, 1) # bitloading for ID symbol and then once for data symbols #bitloading_vec = [1]*dsubc+[0]*(dsubc/2)+[2]*(dsubc/2) #test_allocation = [bitloading]*(int)(config.data_subcarriers/8)+ [0]*(int)(config.data_subcarriers/4*3) + [bitloading]*(int)(config.data_subcarriers/8) #bitloading_vec = [1]*dsubc+[bitloading]*dsubc test_allocation = [bitloading] * dsubc bitloading_vec = [bitloading] * dsubc + test_allocation bitloading_src = blocks.vector_source_b(bitloading_vec, True, dsubc) # bitcount for frames #bitcount_vec = [config.data_subcarriers*config.frame_data_blocks*bitloading] bitcount_vec = [config.frame_data_blocks * sum(test_allocation)] bitcount_src = blocks.vector_source_i(bitcount_vec, True, 1) # power loading, here same for all symbols #power_vec = [1]*(int)(config.data_subcarriers/8)+ [0]*(int)(config.data_subcarriers/4*3) + [1]*(int)(config.data_subcarriers/8) power_vec = [1] * config.data_subcarriers power_src = blocks.vector_source_f(power_vec, True, dsubc) # mux control stream to mux id and data bits mux_vec = [0] * dsubc + [1] * bitcount_vec[0] mux_ctrl = blocks.vector_source_b(mux_vec, True, 1) else: id_src = (self.allocation_src, 0) bitcount_src = (self.allocation_src, 4) bitloading_src = (self.allocation_src, 2) power_src = (self.allocation_src, 1) if options.coding: modul_bitcount_src = (self.allocation_src, 5) else: modul_bitcount_src = bitcount_src mux_ctrl = ofdm.tx_mux_ctrl(dsubc) self.connect(modul_bitcount_src, mux_ctrl) #Initial allocation self.allocation_src.set_allocation([2] * config.data_subcarriers, [1] * config.data_subcarriers) self.allocation_src.set_allocation_scheme(0) if options.benchmarking: self.allocation_src.set_allocation( [4] * config.data_subcarriers, [1] * config.data_subcarriers) if options.lab_special_case: self.allocation_src.set_allocation( [0] * (config.data_subcarriers / 4) + [2] * (config.data_subcarriers / 2) + [0] * (config.data_subcarriers / 4), [1] * config.data_subcarriers) if options.log: log_to_file(self, id_src, "data/id_src.short") log_to_file(self, bitcount_src, "data/bitcount_src.int") log_to_file(self, bitloading_src, "data/bitloading_src.char") log_to_file(self, power_src, "data/power_src.cmplx") ## GUI probe output zmq_probe_bitloading = zeromq.pub_sink(gr.sizeof_char, dsubc, "tcp://*:4445") # also skip ID symbol bitloading with keep_one_in_n (side effect) # factor 2 for bitloading because we have two vectors per frame, one for id symbol and one for all payload/data symbols # factor config.frame_data_part for power because there is one vector per ofdm symbol per frame self.connect(bitloading_src, blocks.keep_one_in_n(gr.sizeof_char * dsubc, 2 * 40), zmq_probe_bitloading) zmq_probe_power = zeromq.pub_sink(gr.sizeof_float, dsubc, "tcp://*:4444") #self.connect(power_src, blocks.keep_one_in_n(gr.sizeof_gr_complex*dsubc,40), blocks.complex_to_real(dsubc), zmq_probe_power) self.connect(power_src, blocks.keep_one_in_n(gr.sizeof_float * dsubc, 40), zmq_probe_power) ## Workaround to avoid periodic structure seed(1) whitener_pn = [ randint(0, 1) for i in range(used_id_bits * rep_id_bits) ] ## ID Encoder id_enc = self._id_encoder = repetition_encoder_sb( used_id_bits, rep_id_bits, whitener_pn) self.connect(id_src, id_enc) if options.log: id_enc_f = gr.char_to_float() self.connect(id_enc, id_enc_f) log_to_file(self, id_enc_f, "data/id_enc_out.float") ## Reference Data Source ber_ref_src = ber_reference_source(self._options) self.connect(id_src, (ber_ref_src, 0)) self.connect(bitcount_src, (ber_ref_src, 1)) if options.log: log_to_file(self, ber_ref_src, "data/ber_rec_src_tx.char") if options.log: log_to_file(self, btrig, "data/bitmap_trig.char") ## Bitmap Update Trigger for puncturing if not options.nopunct: bmaptrig_stream_puncturing = [ 1 ] + [0] * (config.frame_data_blocks / 2 - 1) btrig_puncturing = self._bitmap_trigger_puncturing = blocks.vector_source_b( bmaptrig_stream_puncturing, True) bmapsrc_stream_puncturing = [1] * dsubc + [2] * dsubc bsrc_puncturing = self._bitmap_src_puncturing = blocks.vector_source_b( bmapsrc_stream_puncturing, True, dsubc) if options.log and options.coding and not options.nopunct: log_to_file(self, btrig_puncturing, "data/bitmap_trig_puncturing.char") ## Frame Trigger ftrig_stream = [1] + [0] * (config.frame_data_part - 1) ftrig = self._frame_trigger = blocks.vector_source_b( ftrig_stream, True) ## Data Multiplexer # Input 0: control stream # Input 1: encoded ID stream # Inputs 2..n: data streams dmux = self._data_multiplexer = stream_controlled_mux_b() self.connect(mux_ctrl, (dmux, 0)) self.connect(id_enc, (dmux, 1)) if options.coding: fo = trellis.fsm(1, 2, [91, 121]) encoder = self._encoder = trellis.encoder_bb(fo, 0) unpack = self._unpack = blocks.unpack_k_bits_bb(2) self.connect(ber_ref_src, encoder, unpack) if options.interleave: int_object = trellis.interleaver(2000, 666) interlv = trellis.permutation(int_object.K(), int_object.INTER(), 1, gr.sizeof_char) if not options.nopunct: bmaptrig_stream_puncturing = [ 1 ] + [0] * (config.frame_data_blocks / 2 - 1) btrig_puncturing = self._bitmap_trigger_puncturing = blocks.vector_source_b( bmaptrig_stream_puncturing, True) puncturing = self._puncturing = puncture_bb( config.data_subcarriers) self.connect(bitloading_src, (puncturing, 1)) self.connect(self._bitmap_trigger_puncturing, (puncturing, 2)) self.connect(unpack, puncturing) last_block = puncturing if options.interleave: self.connect(last_block, interlv) last_block = interlv if options.benchmarking: self.connect(last_block, blocks.head(gr.sizeof_char, options.N), (dmux, 2)) else: self.connect(last_block, (dmux, 2)) else: if options.benchmarking: self.connect(unpack, blocks.head(gr.sizeof_char, options.N), (dmux, 2)) else: self.connect(unpack, (dmux, 2)) else: if options.benchmarking: self.connect(ber_ref_src, blocks.head(gr.sizeof_char, options.N), (dmux, 2)) else: self.connect(ber_ref_src, (dmux, 2)) if options.log: dmux_f = gr.char_to_float() self.connect(dmux, dmux_f) log_to_file(self, dmux_f, "data/dmux_out.float") ## Modulator mod = self._modulator = generic_mapper_bcv(config.data_subcarriers, config.coding, config.frame_data_part) self.connect(dmux, (mod, 0)) self.connect(bitloading_src, (mod, 1)) #log_to_file(self, mod, "data/mod_out.compl") if options.log: log_to_file(self, mod, "data/mod_out.compl") modi = blocks.complex_to_imag(config.data_subcarriers) modr = blocks.complex_to_real(config.data_subcarriers) self.connect(mod, modi) self.connect(mod, modr) log_to_file(self, modi, "data/mod_imag_out.float") log_to_file(self, modr, "data/mod_real_out.float") ## Power allocator pa = self._power_allocator = multiply_frame_fc(config.frame_data_part, config.data_subcarriers) self.connect(mod, (pa, 0)) self.connect(power_src, (pa, 1)) if options.log: log_to_file(self, pa, "data/pa_out.compl") # Standard Transmitter Parts ## Pilot subcarriers psubc = self._pilot_subcarrier_inserter = pilot_subcarrier_inserter() self.connect(pa, psubc) if options.log: log_to_file(self, psubc, "data/psubc_out.compl") ## Add virtual subcarriers if config.fft_length > config.subcarriers: vsubc = self._virtual_subcarrier_extender = \ vector_padding_dc_null(config.subcarriers, config.fft_length,config.dc_null) self.connect(psubc, vsubc) else: vsubc = self._virtual_subcarrier_extender = psubc if options.log: log_to_file(self, vsubc, "data/vsubc_out.compl") ## IFFT, no window, block shift ifft = self._ifft = fft_blocks.fft_vcc(config.fft_length, False, [], True) self.connect(vsubc, ifft) if options.log: log_to_file(self, ifft, "data/ifft_out.compl") ## Pilot blocks (preambles) pblocks = self._pilot_block_inserter = pilot_block_inserter(5, False) self.connect(ifft, pblocks) if options.log: log_to_file(self, pblocks, "data/pilot_block_ins_out.compl") ## Cyclic Prefix cp = self._cyclic_prefixer = cyclic_prefixer(config.fft_length, config.block_length) self.connect(pblocks, cp) lastblock = cp if options.log: log_to_file(self, cp, "data/cp_out.compl") #Digital Amplifier for resource allocation #if not options.coding: rep = blocks.repeat(gr.sizeof_gr_complex, config.frame_length * config.block_length) amp = blocks.multiply_cc() self.connect(lastblock, (amp, 0)) self.connect((self.allocation_src, 3), rep, (amp, 1)) lastblock = amp ## Digital Amplifier #amp = self._amplifier = gr.multiply_const_cc(1) amp = self._amplifier = ofdm.multiply_const_ccf(1.0) self.connect(lastblock, amp) self.set_rms_amplitude(rms_amp) if options.log: log_to_file(self, amp, "data/amp_tx_out.compl") ## Tx parameters bandwidth = options.bandwidth or 2e6 bits = 8 * config.data_subcarriers * config.frame_data_blocks # max. QAM256 samples_per_frame = config.frame_length * config.block_length tb = samples_per_frame / bandwidth # set dummy carrier frequency if none available due to baseband mode if (options.tx_freq is None): options.tx_freq = 0.0 self.tx_parameters = {'carrier_frequency':options.tx_freq/1e9,'fft_size':config.fft_length, 'cp_size':config.cp_length \ , 'subcarrier_spacing':options.bandwidth/config.fft_length/1e3 \ , 'data_subcarriers':config.data_subcarriers, 'bandwidth':options.bandwidth/1e6 \ , 'frame_length':config.frame_length \ , 'symbol_time':(config.cp_length + config.fft_length)/options.bandwidth*1e6, 'max_data_rate':(bits/tb)/1e6} ## Setup Output self.connect(amp, self) # Display some information about the setup if config._verbose: self._print_verbage()
#header_formatter = digital.packet_header_default(bits_per_header, length_tag_name,num_tag_name,header_mod.bits_per_symbol()); #tcm_indicator_symbols_per_frame=4; #Zhe added, 4 bits are used as tcm mode indicator, it is used as a part of header. # Achilles' comment: this may change later when filler bits are introduced... print "bits_per_header=",bits_per_header print "symbols_per_header=",symbols_per_header #print "tcm_indicator_symbols_per_frame=",tcm_indicator_symbols_per_frame print "\n" #trellis coding and modulation info payload_mod = [digital.constellation_qpsk(),digital.constellation_8psk()] pdir=prefix+"/python/fsm_files/" fsm=[pdir+"awgn2o2_1.fsm", pdir+"awgn2o3_8ungerboecka.fsm"] uncoded_fsm=[trellis.fsm(2,2,[1,0,0,1]),trellis.fsm(3,3,[1,0,0,0,1,0,0,0,1])] bits_per_coded_symbol=[int(math.log(trellis.fsm(fsm[i]).O(),2)) for i in range(len(payload_mod))] #coding_rate=[Fraction(int(math.log(trellis.fsm(fsm[i]).I(),2)), int(math.log(trellis.fsm(fsm[i]).O(),2))) for i in range(len(fsm))] if bits_per_coded_symbol!=[payload_mod[i].bits_per_symbol() for i in range(len(payload_mod))]: print "Error in selecting trellis code and modulation pairs." print "bits_per_coded_symbol =", bits_per_coded_symbol, " for [uncoded QPSK, rate 2/3 cc &8PSK] respectively.\n" #print "coding rates for trellis codes =", coding_rate, " for [uncoded QPSK, rate 2/3 cc &8PSK] respectively.\n" #payload info payload_bytes_per_frame = 50; # set by user symbols_per_frame = 260; # symbols per frame set by user
def __init__(self, options): gr.hier_block2.__init__( self, "fbmc_transmit_path", gr.io_signature(0, 0, 0), gr.io_signature(1, 1, gr.sizeof_gr_complex) ) common_options.defaults(options) config = self.config = station_configuration() config.data_subcarriers = options.subcarriers config.cp_length = 0 config.frame_data_blocks = options.data_blocks config._verbose = options.verbose config.fft_length = options.fft_length config.dc_null = options.dc_null config.training_data = default_block_header(config.data_subcarriers, config.fft_length, config.dc_null, options) config.coding = options.coding config.fbmc = options.fbmc config.adaptive_fbmc = options.adaptive_fbmc config.frame_id_blocks = 1 # FIXME # digital rms amplitude sent to USRP rms_amp = options.rms_amplitude self._options = copy.copy(options) 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.subcarriers = config.data_subcarriers + config.training_data.pilot_subcarriers config.virtual_subcarriers = config.fft_length - config.subcarriers - config.dc_null # default values if parameters not set if rms_amp is None: rms_amp = math.sqrt(config.subcarriers) config.rms_amplitude = rms_amp # 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" ## shortcuts blen = config.block_length flen = config.frame_length dsubc = config.data_subcarriers vsubc = config.virtual_subcarriers # Adaptive Transmitter Concept used_id_bits = config.used_id_bits = 8 # TODO: no constant in source code rep_id_bits = config.rep_id_bits = config.data_subcarriers / used_id_bits # BPSK if config.data_subcarriers % used_id_bits <> 0: raise SystemError, "Data subcarriers need to be multiple of %d" % (used_id_bits) ## Allocation Control self.allocation_src = allocation_src( config.data_subcarriers, config.frame_data_blocks, config.coding, "tcp://*:3333", "tcp://" + options.rx_hostname + ":3322", ) if options.static_allocation: # DEBUG # how many bits per subcarrier 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 modulbitspermode = [1, 2, 2, 4, 4, 6, 6, 6, 8] # Coding bits per mode bitcount_vec = [(int)(config.data_subcarriers * config.frame_data_blocks * bitspermode[mode - 1])] modul_bitcount_vec = [config.data_subcarriers * config.frame_data_blocks * modulbitspermode[mode - 1]] bitcount_src = blocks.vector_source_i(bitcount_vec, True, 1) modul_bitcount_src = blocks.vector_source_i(modul_bitcount_vec, True, 1) bitloading = mode else: bitloading = 1 bitcount_vec = [config.data_subcarriers * config.frame_data_blocks * bitloading] bitcount_src = blocks.vector_source_i(bitcount_vec, True, 1) modul_bitcount_src = bitcount_src # id's for frames id_vec = range(0, 256) id_src = blocks.vector_source_s(id_vec, True, 1) # bitloading for ID symbol and then once for data symbols # bitloading_vec = [1]*dsubc+[0]*(dsubc/2)+[2]*(dsubc/2) test_allocation = ( [bitloading] * (int)(config.data_subcarriers / 8) + [0] * (int)(config.data_subcarriers / 4 * 3) + [bitloading] * (int)(config.data_subcarriers / 8) ) # bitloading_vec = [1]*dsubc+[bitloading]*dsubc bitloading_vec = [1] * dsubc + test_allocation bitloading_src = blocks.vector_source_b(bitloading_vec, True, dsubc) # bitcount for frames # bitcount_vec = [config.data_subcarriers*config.frame_data_blocks*bitloading] bitcount_vec = [config.frame_data_blocks * sum(test_allocation)] bitcount_src = blocks.vector_source_i(bitcount_vec, True, 1) # power loading, here same for all symbols power_vec = ( [1] * (int)(config.data_subcarriers / 8) + [0] * (int)(config.data_subcarriers / 4 * 3) + [1] * (int)(config.data_subcarriers / 8) ) power_src = blocks.vector_source_f(power_vec, True, dsubc) # mux control stream to mux id and data bits mux_vec = [0] * dsubc + [1] * bitcount_vec[0] mux_ctrl = blocks.vector_source_b(mux_vec, True, 1) else: id_src = (self.allocation_src, 0) bitcount_src = (self.allocation_src, 4) bitloading_src = (self.allocation_src, 2) power_src = (self.allocation_src, 1) if options.coding: modul_bitcount_src = (self.allocation_src, 5) else: modul_bitcount_src = bitcount_src mux_ctrl = ofdm.tx_mux_ctrl(dsubc) self.connect(modul_bitcount_src, mux_ctrl) # Initial allocation self.allocation_src.set_allocation([4] * config.data_subcarriers, [1] * config.data_subcarriers) if options.benchmarking: self.allocation_src.set_allocation([4] * config.data_subcarriers, [1] * config.data_subcarriers) if options.lab_special_case: self.allocation_src.set_allocation( [0] * (config.data_subcarriers / 4) + [2] * (config.data_subcarriers / 2) + [0] * (config.data_subcarriers / 4), [1] * config.data_subcarriers, ) if options.log: log_to_file(self, id_src, "data/id_src.short") log_to_file(self, bitcount_src, "data/bitcount_src.int") log_to_file(self, bitloading_src, "data/bitloading_src.char") log_to_file(self, power_src, "data/power_src.cmplx") ## GUI probe output zmq_probe_bitloading = zeromq.pub_sink(gr.sizeof_char, dsubc, "tcp://*:4445") # also skip ID symbol bitloading with keep_one_in_n (side effect) # factor 2 for bitloading because we have two vectors per frame, one for id symbol and one for all payload/data symbols # factor config.frame_data_part for power because there is one vector per ofdm symbol per frame self.connect(bitloading_src, blocks.keep_one_in_n(gr.sizeof_char * dsubc, 2 * 40), zmq_probe_bitloading) zmq_probe_power = zeromq.pub_sink(gr.sizeof_float, dsubc, "tcp://*:4444") # self.connect(power_src, blocks.keep_one_in_n(gr.sizeof_gr_complex*dsubc,40), blocks.complex_to_real(dsubc), zmq_probe_power) self.connect(power_src, blocks.keep_one_in_n(gr.sizeof_float * dsubc, 40), zmq_probe_power) ## Workaround to avoid periodic structure seed(1) whitener_pn = [randint(0, 1) for i in range(used_id_bits * rep_id_bits)] ## ID Encoder id_enc = self._id_encoder = repetition_encoder_sb(used_id_bits, rep_id_bits, whitener_pn) self.connect(id_src, id_enc) if options.log: id_enc_f = gr.char_to_float() self.connect(id_enc, id_enc_f) log_to_file(self, id_enc_f, "data/id_enc_out.float") ## Reference Data Source ber_ref_src = ber_reference_source(self._options) self.connect(id_src, (ber_ref_src, 0)) self.connect(bitcount_src, (ber_ref_src, 1)) if options.log: log_to_file(self, ber_ref_src, "data/ber_rec_src_tx.char") if options.log: log_to_file(self, btrig, "data/bitmap_trig.char") ## Frame Trigger ftrig_stream = [1] + [0] * (config.frame_data_part - 1) ftrig = self._frame_trigger = blocks.vector_source_b(ftrig_stream, True) ## Data Multiplexer # Input 0: control stream # Input 1: encoded ID stream # Inputs 2..n: data streams dmux = self._data_multiplexer = stream_controlled_mux_b() self.connect(mux_ctrl, (dmux, 0)) self.connect(id_enc, (dmux, 1)) if options.coding: fo = trellis.fsm(1, 2, [91, 121]) encoder = self._encoder = trellis.encoder_bb(fo, 0) unpack = self._unpack = blocks.unpack_k_bits_bb(2) self.connect(ber_ref_src, encoder, unpack) if options.interleave: int_object = trellis.interleaver(2000, 666) interlv = trellis.permutation(int_object.K(), int_object.INTER(), 1, gr.sizeof_char) if not options.nopunct: bmaptrig_stream_puncturing = [1] + [0] * (config.frame_data_blocks / 2 - 1) btrig_puncturing = self._bitmap_trigger_puncturing = blocks.vector_source_b( bmaptrig_stream_puncturing, True ) puncturing = self._puncturing = puncture_bb(config.data_subcarriers) self.connect(bitloading_src, (puncturing, 1)) self.connect(self._bitmap_trigger_puncturing, (puncturing, 2)) self.connect(unpack, puncturing) last_block = puncturing if options.interleave: self.connect(last_block, interlv) last_block = interlv if options.benchmarking: self.connect(last_block, blocks.head(gr.sizeof_char, options.N), (dmux, 2)) else: self.connect(last_block, (dmux, 2)) else: if options.benchmarking: self.connect(unpack, blocks.head(gr.sizeof_char, options.N), (dmux, 2)) else: self.connect(unpack, (dmux, 2)) else: if options.benchmarking: self.connect(ber_ref_src, blocks.head(gr.sizeof_char, options.N), (dmux, 2)) else: self.connect(ber_ref_src, (dmux, 2)) if options.log: dmux_f = gr.char_to_float() self.connect(dmux, dmux_f) log_to_file(self, dmux_f, "data/dmux_out.float") ## Modulator mod = self._modulator = generic_mapper_bcv(config.data_subcarriers, config.coding, config.frame_data_part) self.connect(dmux, (mod, 0)) self.connect(bitloading_src, (mod, 1)) if options.log: log_to_file(self, mod, "data/mod_out.compl") modi = blocks.complex_to_imag(config.data_subcarriers) modr = blocks.complex_to_real(config.data_subcarriers) self.connect(mod, modi) self.connect(mod, modr) log_to_file(self, modi, "data/mod_imag_out.float") log_to_file(self, modr, "data/mod_real_out.float") ## Power allocator pa = self._power_allocator = multiply_frame_fc(config.frame_data_part, config.data_subcarriers) self.connect(mod, (pa, 0)) self.connect(power_src, (pa, 1)) if options.log: log_to_file(self, pa, "data/pa_out.compl") if options.fbmc: psubc = pa else: psubc = self._pilot_subcarrier_inserter = pilot_subcarrier_inserter() self.connect(pa, psubc) if options.log: log_to_file(self, psubc, "data/psubc_out.compl") subcarriers = config.subcarriers # fbmc_pblocks_timing = self._fbmc_timing_pilot_block_inserter = fbmc_timing_pilot_block_inserter(5,False) oqam_prep = self._oqam_prep = fbmc_oqam_preprocessing_vcvc(config.subcarriers, 0, 0) self.connect(psubc, oqam_prep) fbmc_pblocks = self._fbmc_pilot_block_inserter = fbmc_pilot_block_inserter(5, False) self.connect(oqam_prep, fbmc_pblocks) # log_to_file(self, fbmc_pblocks, "data/fbmc_pblocks_out.compl") # fbmc_insert_pream = self._fbmc_insert_pream = fbmc_insert_preamble_vcvc(M, syms_per_frame, preamble) # log_to_file(self, oqam_prep, "data/oqam_prep.compl") # log_to_file(self, psubc, "data/psubc_out.compl") # fbmc_pblocks = fbmc_pblocks_timing # log_to_file(self, fbmc_pblocks, "data/fbmc_pblocks_out.compl") beta_mult = self._beta_mult = fbmc_beta_multiplier_vcvc(config.subcarriers, 4, 4 * config.fft_length - 1, 0) self.connect(fbmc_pblocks, beta_mult) log_to_file(self, beta_mult, "data/beta_mult.compl") ## Add virtual subcarriers if config.fft_length > subcarriers: vsubc = self._virtual_subcarrier_extender = vector_padding_dc_null( config.subcarriers, config.fft_length, config.dc_null ) self.connect(beta_mult, vsubc) else: vsubc = self._virtual_subcarrier_extender = beta_mult if options.log: log_to_file(self, vsubc, "data/vsubc_out.compl") ## IFFT, no window, block shift ifft = self._ifft = fft_blocks.fft_vcc(config.fft_length, False, [], True) self.connect(vsubc, ifft) if options.log: log_to_file(self, ifft, "data/ifft_out.compl") # FBMC separate stream + filterbanks separate_oqam = self._separate_oqam = fbmc_separate_vcvc(config.fft_length, 2) poly_netw_1 = self._poly_netw_1 = fbmc_polyphase_network_vcvc( config.fft_length, 4, 4 * config.fft_length - 1, False ) poly_netw_2 = self._poly_netw_2 = fbmc_polyphase_network_vcvc( config.fft_length, 4, 4 * config.fft_length - 1, False ) overlap_p2s = self._overlap_p2s = fbmc_overlapping_parallel_to_serial_vcc(config.fft_length) self.connect(ifft, (separate_oqam, 0), poly_netw_1) self.connect((separate_oqam, 1), poly_netw_2) self.connect(poly_netw_1, (overlap_p2s, 0)) self.connect(poly_netw_2, (overlap_p2s, 1)) ## Pilot blocks (preambles) # pblocks = self._pilot_block_inserter = pilot_block_inserter2(5,False) # self.connect( overlap_p2s, blocks.stream_to_vector(gr.sizeof_gr_complex,config.fft_length/2), pblocks ) # log_to_file(self, pblocks, "data/fbmc_pilot_block_ins_out.compl") if options.log: log_to_file(self, pblocks, "data/pilot_block_ins_out.compl") ## Cyclic Prefix # cp = self._cyclic_prefixer = cyclic_prefixer(config.fft_length, # config.block_length) # cp= blocks.vector_to_stream(gr.sizeof_gr_complex, config.fft_length/2) # self.connect(pblocks, cp ) # self.connect( overlap_p2s,blocks.stream_to_vector(gr.sizeof_gr_complex,config.fft_length/2), cp ) lastblock = overlap_p2s if options.log: log_to_file(self, overlap_p2s, "data/overlap_p2s_out.compl") # Digital Amplifier for resource allocation if config.adaptive_fbmc: rep = blocks.repeat(gr.sizeof_gr_complex, config.frame_length * config.block_length) amp = blocks.multiply_cc() self.connect(lastblock, (amp, 0)) self.connect((self.allocation_src, 3), rep, (amp, 1)) lastblock = amp else: self.connect((self.allocation_src, 3), blocks.null_sink(gr.sizeof_gr_complex)) ## Digital Amplifier # amp = self._amplifier = gr.multiply_const_cc(1) amp = self._amplifier = ofdm.multiply_const_ccf(1.0) self.connect(lastblock, amp) self.set_rms_amplitude(rms_amp) # log_to_file(self, amp, "data/amp_tx_out.compl") if options.log: log_to_file(self, amp, "data/amp_tx_out.compl") ## Tx parameters bandwidth = options.bandwidth or 2e6 bits = 8 * config.data_subcarriers * config.frame_data_blocks # max. QAM256 samples_per_frame = config.frame_length * config.block_length tb = samples_per_frame / bandwidth # set dummy carrier frequency if none available due to baseband mode if options.tx_freq is None: options.tx_freq = 0.0 self.tx_parameters = { "carrier_frequency": options.tx_freq / 1e9, "fft_size": config.fft_length, "cp_size": config.cp_length, "subcarrier_spacing": options.bandwidth / config.fft_length / 1e3, "data_subcarriers": config.data_subcarriers, "bandwidth": options.bandwidth / 1e6, "frame_length": config.frame_length, "symbol_time": (config.cp_length + config.fft_length) / options.bandwidth * 1e6, "max_data_rate": (bits / tb) / 1e6, } ## Setup Output self.connect(amp, self) # Display some information about the setup if config._verbose: self._print_verbage()
def test_004_fsm(self): """ Test to make sure fsm works with a single state fsm.""" # Just checking that it initializes properly. f = trellis.fsm(*fsm_args["rep2"])
def __init__(self, vlen_in=1, vlen_out=1, n_tailbits=6, denom_mother_code_rate=6, gen_poly=(91, 121, 101, 91, 121, 101), bits_per_symbol=0, N=1, map_tab=0, pp_0=0, pp_0_tail=0, pp_1=0, pp_1_tail=0, part_len_top=1, part_len_bot=1, M_total=0, interl_seq_0_2=range(2), interl_seq_1_2=range(2)): gr.hier_block2.__init__( self, "DRM MLC 16-QAM", gr.io_signature(1, 1, gr.sizeof_char*vlen_in), gr.io_signature(1, 1, gr.sizeof_gr_complex*vlen_out), ) ################################################## # Parameters ################################################## self.vlen_in = vlen_in self.vlen_out = vlen_out self.n_tailbits = n_tailbits self.denom_mother_code_rate = denom_mother_code_rate self.gen_poly = gen_poly self.bits_per_symbol = bits_per_symbol self.N = N self.map_tab = map_tab self.pp_0 = pp_0 self.pp_0_tail = pp_0_tail self.pp_1 = pp_1 self.pp_1_tail = pp_1_tail self.part_len_top = part_len_top self.part_len_bot = part_len_bot self.M_total = M_total self.interl_seq_0_2 = interl_seq_0_2 self.interl_seq_1_2 = interl_seq_1_2 ################################################## # Blocks ################################################## self.trellis_encoder_xx_0_0 = trellis.encoder_bb(trellis.fsm(1, denom_mother_code_rate, gen_poly), 0) self.trellis_encoder_xx_0 = trellis.encoder_bb(trellis.fsm(1, denom_mother_code_rate, gen_poly), 0) self.gr_vector_to_stream_1_0 = gr.vector_to_stream(gr.sizeof_char*1, part_len_bot+ n_tailbits) self.gr_vector_to_stream_1 = gr.vector_to_stream(gr.sizeof_char*1, part_len_top + n_tailbits) self.gr_unpack_k_bits_bb_0_0 = gr.unpack_k_bits_bb(denom_mother_code_rate) self.gr_unpack_k_bits_bb_0 = gr.unpack_k_bits_bb(denom_mother_code_rate) self.gr_stream_to_vector_0_0 = gr.stream_to_vector(gr.sizeof_char*1, (part_len_bot + n_tailbits) * denom_mother_code_rate) self.gr_stream_to_vector_0 = gr.stream_to_vector(gr.sizeof_char*1, (part_len_top + n_tailbits) * denom_mother_code_rate) self.drm_qam_map_vbvc_0 = drm.qam_map_vbvc(map_tab, bits_per_symbol, vlen_out, 2) self.drm_punct_vbvb_0_0 = drm.punct_vbvb(pp_1, pp_1_tail, (part_len_bot + n_tailbits) * denom_mother_code_rate, vlen_out * 2, n_tailbits * denom_mother_code_rate) self.drm_punct_vbvb_0 = drm.punct_vbvb(pp_0, pp_0_tail, (part_len_top + n_tailbits) * denom_mother_code_rate, vlen_out * 2, n_tailbits * denom_mother_code_rate) self.drm_partitioning_16_vbvb_0 = drm.partitioning_vbvb(vlen_in, M_total) self.drm_interleaver_vbvb_0_0 = drm.interleaver_vbvb((interl_seq_1_2)) self.drm_interleaver_vbvb_0 = drm.interleaver_vbvb((interl_seq_0_2)) self.add_tailbits_vbvb_0_0 = drm.add_tailbits_vbvb(part_len_bot, n_tailbits) self.add_tailbits_vbvb_0 = drm.add_tailbits_vbvb(part_len_top, n_tailbits) ################################################## # Connections ################################################## self.connect((self.drm_interleaver_vbvb_0, 0), (self.drm_qam_map_vbvc_0, 0)) self.connect((self.drm_qam_map_vbvc_0, 0), (self, 0)) self.connect((self.trellis_encoder_xx_0, 0), (self.gr_unpack_k_bits_bb_0, 0)) self.connect((self.gr_stream_to_vector_0, 0), (self.drm_punct_vbvb_0, 0)) self.connect((self.gr_unpack_k_bits_bb_0, 0), (self.gr_stream_to_vector_0, 0)) self.connect((self.drm_punct_vbvb_0, 0), (self.drm_interleaver_vbvb_0, 0)) self.connect((self.trellis_encoder_xx_0_0, 0), (self.gr_unpack_k_bits_bb_0_0, 0)) self.connect((self.gr_stream_to_vector_0_0, 0), (self.drm_punct_vbvb_0_0, 0)) self.connect((self.gr_unpack_k_bits_bb_0_0, 0), (self.gr_stream_to_vector_0_0, 0)) self.connect((self.drm_punct_vbvb_0_0, 0), (self.drm_interleaver_vbvb_0_0, 0)) self.connect((self.drm_interleaver_vbvb_0_0, 0), (self.drm_qam_map_vbvc_0, 1)) self.connect((self.gr_vector_to_stream_1, 0), (self.trellis_encoder_xx_0, 0)) self.connect((self.gr_vector_to_stream_1_0, 0), (self.trellis_encoder_xx_0_0, 0)) self.connect((self, 0), (self.drm_partitioning_16_vbvb_0, 0)) self.connect((self.add_tailbits_vbvb_0, 0), (self.gr_vector_to_stream_1, 0)) self.connect((self.add_tailbits_vbvb_0_0, 0), (self.gr_vector_to_stream_1_0, 0)) self.connect((self.drm_partitioning_16_vbvb_0, 1), (self.add_tailbits_vbvb_0_0, 0)) self.connect((self.drm_partitioning_16_vbvb_0, 0), (self.add_tailbits_vbvb_0, 0))
def set_denom_mother_code_rate(self, denom_mother_code_rate): self.denom_mother_code_rate = denom_mother_code_rate self.trellis_encoder_xx_top_0.set_FSM(trellis.fsm(1, self.denom_mother_code_rate, self.gen_poly)) self.trellis_encoder_xx_top.set_FSM(trellis.fsm(1, self.denom_mother_code_rate, self.gen_poly)) self.trellis_encoder_xx_bot.set_FSM(trellis.fsm(1, self.denom_mother_code_rate, self.gen_poly))
def __init__(self, dab_params, verbose=False, debug=False): """ Hierarchical block for FIC decoding @param dab_params DAB parameter object (grdab.parameters.dab_parameters) """ gr.hier_block2.__init__(self, "fic", gr.io_signature(1, 1, gr.sizeof_float * dab_params.num_carriers * 2), gr.io_signature(1, 1, gr.sizeof_char * 32)) self.dp = dab_params self.verbose = verbose self.debug = debug # FIB selection and block partitioning self.select_fic_syms = grdab.select_vectors(gr.sizeof_float, self.dp.num_carriers * 2, self.dp.num_fic_syms, 0) self.repartition_fic = grdab.repartition_vectors(gr.sizeof_float, self.dp.num_carriers * 2, self.dp.fic_punctured_codeword_length, self.dp.num_fic_syms, self.dp.num_cifs) # unpuncturing self.unpuncture = grdab.unpuncture_vff(self.dp.assembled_fic_puncturing_sequence, 0) # convolutional coding # self.fsm = trellis.fsm(self.dp.conv_code_in_bits, self.dp.conv_code_out_bits, self.dp.conv_code_generator_polynomials) self.fsm = trellis.fsm(1, 4, [0133, 0171, 0145, 0133]) # OK (dumped to text and verified partially) self.conv_v2s = blocks.vector_to_stream(gr.sizeof_float, self.dp.fic_conv_codeword_length) # self.conv_decode = trellis.viterbi_combined_fb(self.fsm, 20, 0, 0, 1, [1./sqrt(2),-1/sqrt(2)] , trellis.TRELLIS_EUCLIDEAN) table = [ 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1 ] assert (len(table) / 4 == self.fsm.O()) table = [(1 - 2 * x) / sqrt(2) for x in table] self.conv_decode = trellis.viterbi_combined_fb(self.fsm, 774, 0, 0, 4, table, trellis.TRELLIS_EUCLIDEAN) #self.conv_s2v = blocks.stream_to_vector(gr.sizeof_char, 774) self.conv_prune = grdab.prune(gr.sizeof_char, self.dp.fic_conv_codeword_length / 4, 0, self.dp.conv_code_add_bits_input) # energy dispersal self.prbs_src = blocks.vector_source_b(self.dp.prbs(self.dp.energy_dispersal_fic_vector_length), True) #self.energy_v2s = blocks.vector_to_stream(gr.sizeof_char, self.dp.energy_dispersal_fic_vector_length) self.add_mod_2 = blocks.xor_bb() self.energy_s2v = blocks.stream_to_vector(gr.sizeof_char, self.dp.energy_dispersal_fic_vector_length) self.cut_into_fibs = grdab.repartition_vectors(gr.sizeof_char, self.dp.energy_dispersal_fic_vector_length, self.dp.fib_bits, 1, self.dp.energy_dispersal_fic_fibs_per_vector) # connect all self.nullsink = blocks.null_sink(gr.sizeof_char) self.pack = blocks.unpacked_to_packed_bb(1, gr.GR_MSB_FIRST) self.fibout = blocks.stream_to_vector(1, 32) # self.filesink = gr.file_sink(gr.sizeof_char, "debug/fic.dat") self.fibsink = grdab.fib_sink_vb() # self.connect((self,0), (self.select_fic_syms,0), (self.repartition_fic,0), self.unpuncture, self.conv_v2s, self.conv_decode, self.conv_s2v, self.conv_prune, self.energy_v2s, self.add_mod_2, self.energy_s2v, (self.cut_into_fibs,0), gr.vector_to_stream(1,256), gr.unpacked_to_packed_bb(1,gr.GR_MSB_FIRST), self.filesink) self.connect((self, 0), (self.select_fic_syms, 0), (self.repartition_fic, 0), self.unpuncture, self.conv_v2s, self.conv_decode, #self.conv_s2v, self.conv_prune, #self.energy_v2s, self.add_mod_2, self.energy_s2v, (self.cut_into_fibs, 0), blocks.vector_to_stream(1, 256), self.pack, self.fibout, self.fibsink) self.connect(self.fibout, self) self.connect(self.prbs_src, (self.add_mod_2, 1)) if self.debug: self.connect((self, 0), blocks.file_sink(gr.sizeof_float * self.dp.num_carriers * 2, "debug/transmission_frame.dat")) self.connect((self, 1), blocks.file_sink(gr.sizeof_char, "debug/transmission_frame_trigger.dat")) self.connect(self.select_fic_syms, blocks.file_sink(gr.sizeof_float * self.dp.num_carriers * 2, "debug/fic_select_syms.dat")) self.connect(self.repartition_fic, blocks.file_sink(gr.sizeof_float * self.dp.fic_punctured_codeword_length, "debug/fic_repartitioned.dat")) self.connect(self.unpuncture, blocks.file_sink(gr.sizeof_float * self.dp.fic_conv_codeword_length, "debug/fic_unpunctured.dat")) self.connect(self.conv_decode, blocks.file_sink(gr.sizeof_char, "debug/fic_decoded.dat")) self.connect(self.conv_prune, blocks.file_sink(gr.sizeof_char, "debug/fic_decoded_pruned.dat")) #self.connect(self.conv_decode, blocks.file_sink(gr.sizeof_char * self.dp.energy_dispersal_fic_vector_length, "debug/fic_energy_dispersal_undone.dat")) self.connect(self.pack, blocks.file_sink(gr.sizeof_char, "debug/fic_energy_undone.dat"))
def set_gen_poly(self, gen_poly): self.gen_poly = gen_poly self.trellis_encoder_xx_top_0.set_FSM(trellis.fsm(1, self.denom_mother_code_rate, self.gen_poly)) self.trellis_encoder_xx_top.set_FSM(trellis.fsm(1, self.denom_mother_code_rate, self.gen_poly)) self.trellis_encoder_xx_bot.set_FSM(trellis.fsm(1, self.denom_mother_code_rate, self.gen_poly))
def __init__(self, dab_params, address, size, protection, verbose=False, debug=False): gr.hier_block2.__init__(self, "msc_decode", # Input signature gr.io_signature(1, 1, gr.sizeof_float * dab_params.num_carriers * 2), # Output signature gr.io_signature(1, 1, gr.sizeof_char)) self.dp = dab_params self.address = address self.size = size self.protect = protection self.verbose = verbose self.debug = debug # calculate n factor (multiple of 8kbits etc.) self.n = self.size / self.dp.subch_size_multiple_n[self.protect] # calculate puncturing factors (EEP, table 33, 34) self.msc_I = self.n * 192 if (self.n > 1 or self.protect != 1): self.puncturing_L1 = [6 * self.n - 3, 2 * self.n - 3, 6 * self.n - 3, 4 * self.n - 3] self.puncturing_L2 = [3, 4 * self.n + 3, 3, 2 * self.n + 3] self.puncturing_PI1 = [24, 14, 8, 3] self.puncturing_PI2 = [23, 13, 7, 2] # calculate length of punctured codeword (11.3.2) self.msc_punctured_codeword_length = self.puncturing_L1[self.protect] * 4 * self.dp.puncturing_vectors_ones[ self.puncturing_PI1[self.protect]] + self.puncturing_L2[self.protect] * 4 * \ self.dp.puncturing_vectors_ones[ self.puncturing_PI2[self.protect]] + 12 self.assembled_msc_puncturing_sequence = self.puncturing_L1[self.protect] * 4 * self.dp.puncturing_vectors[ self.puncturing_PI1[self.protect]] + self.puncturing_L2[self.protect] * 4 * self.dp.puncturing_vectors[ self.puncturing_PI2[self.protect]] + self.dp.puncturing_tail_vector self.msc_conv_codeword_length = 4*self.msc_I + 24 # 4*I + 24 () # exception in table else: self.msc_punctured_codeword_length = 5 * 4 * self.dp.puncturing_vectors_ones[13] + 1 * 4 * \ self.dp.puncturing_vectors_ones[ 12] + 12 #sanity check assert(6*self.n == self.puncturing_L1[self.protect] + self.puncturing_L2[self.protect]) # MSC selection and block partitioning # select OFDM carriers with MSC self.select_msc_syms = grdab.select_vectors(gr.sizeof_float, self.dp.num_carriers * 2, self.dp.num_msc_syms, self.dp.num_fic_syms) # repartition MSC data in CIFs (left out due to heavy burden for scheduler and not really necessary) #self.repartition_msc_to_CIFs = grdab.repartition_vectors_make(gr.sizeof_float, self.dp.num_carriers * 2, # self.dp.cif_bits, self.dp.num_msc_syms, # self.dp.num_cifs) #repartition MSC to CUs self.repartition_msc_to_cus = grdab.repartition_vectors_make(gr.sizeof_float, self.dp.num_carriers*2, self.dp.msc_cu_size, self.dp.num_msc_syms, self.dp.num_cus * self.dp.num_cifs) # select CUs of one subchannel of each CIF and form logical frame vector self.select_subch = grdab.select_subch_vfvf_make(self.dp.msc_cu_size, self.dp.msc_cu_size * self.size, self.address, self.dp.num_cus) # time deinterleaving self.time_v2s = blocks.vector_to_stream_make(gr.sizeof_float, self.dp.msc_cu_size * self.size) self.time_deinterleaver = grdab.time_deinterleave_ff_make(self.dp.msc_cu_size * self.size, self.dp.scrambling_vector) # unpuncture self.conv_v2s = blocks.vector_to_stream(gr.sizeof_float, self.msc_punctured_codeword_length) self.unpuncture = grdab.unpuncture_ff_make(self.assembled_msc_puncturing_sequence, 0) # convolutional decoding self.fsm = trellis.fsm(1, 4, [0133, 0171, 0145, 0133]) # OK (dumped to text and verified partially) table = [ 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1 ] assert (len(table) / 4 == self.fsm.O()) table = [(1 - 2 * x) / sqrt(2) for x in table] self.conv_decode = trellis.viterbi_combined_fb(self.fsm, self.msc_I + self.dp.conv_code_add_bits_input, 0, 0, 4, table, trellis.TRELLIS_EUCLIDEAN) self.conv_s2v = blocks.stream_to_vector(gr.sizeof_char, self.msc_I + self.dp.conv_code_add_bits_input) self.conv_prune = grdab.prune(gr.sizeof_char, self.msc_conv_codeword_length / 4, 0, self.dp.conv_code_add_bits_input) #energy descramble self.prbs_src = blocks.vector_source_b(self.dp.prbs(self.msc_I), True) self.energy_v2s = blocks.vector_to_stream(gr.sizeof_char, self.msc_I) self.add_mod_2 = blocks.xor_bb() #self.energy_s2v = blocks.stream_to_vector(gr.sizeof_char, self.msc_I) #pack bits self.pack_bits = blocks.unpacked_to_packed_bb_make(1, gr.GR_MSB_FIRST) # connect blocks self.connect((self, 0), (self.select_msc_syms), #(self.repartition_msc_to_CIFs, 0), (self.repartition_msc_to_cus), (self.select_subch, 0), #(self.repartition_cus_to_logical_frame, 0), self.time_v2s, self.time_deinterleaver, #self.conv_v2s, self.unpuncture, self.conv_decode, #self.conv_s2v, self.conv_prune, #self.energy_v2s, self.add_mod_2, self.pack_bits, #self.energy_s2v, #better output stream or vector?? (self)) self.connect(self.prbs_src, (self.add_mod_2, 1)) #debug if debug is True: #msc_select_syms self.sink_msc_select_syms = blocks.file_sink_make(gr.sizeof_float * self.dp.num_carriers * 2, "debug/msc_select_syms.dat") self.connect(self.select_msc_syms, self.sink_msc_select_syms) #msc repartition cus self.sink_repartition_msc_to_cus = blocks.file_sink_make(gr.sizeof_float * self.dp.msc_cu_size, "debug/msc_repartitioned_to_cus.dat") self.connect((self.repartition_msc_to_cus), self.sink_repartition_msc_to_cus) #data of one sub channel not decoded self.sink_select_subch = blocks.file_sink_make(gr.sizeof_float * self.dp.msc_cu_size * self.size, "debug/select_subch.dat") self.connect(self.select_subch, self.sink_select_subch) #sub channel time_deinterleaved self.sink_subch_time_deinterleaved = blocks.file_sink_make(gr.sizeof_float, "debug/subch_time_deinterleaved.dat") self.connect(self.time_deinterleaver, self.sink_subch_time_deinterleaved) #sub channel unpunctured self.sink_subch_unpunctured = blocks.file_sink_make(gr.sizeof_float, "debug/subch_unpunctured.dat") self.connect(self.unpuncture, self.sink_subch_unpunctured) # sub channel convolutional decoded self.sink_subch_decoded = blocks.file_sink_make(gr.sizeof_char, "debug/subch_decoded.dat") self.connect(self.conv_decode, self.sink_subch_decoded) # sub channel convolutional decoded self.sink_subch_pruned = blocks.file_sink_make(gr.sizeof_char, "debug/subch_pruned.dat") self.connect(self.conv_prune, self.sink_subch_pruned) # sub channel energy dispersal undone unpacked self.sink_subch_energy_disp_undone = blocks.file_sink_make(gr.sizeof_char, "debug/subch_energy_disp_undone_unpacked.dat") self.connect(self.add_mod_2, self.sink_subch_energy_disp_undone) # sub channel energy dispersal undone packed self.sink_subch_energy_disp_undone_packed = blocks.file_sink_make(gr.sizeof_char, "debug/subch_energy_disp_undone_packed.dat") self.connect(self.pack_bits, self.sink_subch_energy_disp_undone_packed)
def run_test(seed,blocksize): tb = gr.top_block() ################################################## # Variables ################################################## M = 2 K = 1 P = 2 h = (1.0*K)/P L = 3 Q = 4 frac = 0.99 f = trellis.fsm(P,M,L) # CPFSK signals #p = numpy.ones(Q)/(2.0) #q = numpy.cumsum(p)/(1.0*Q) # GMSK signals BT=0.3; tt=numpy.arange(0,L*Q)/(1.0*Q)-L/2.0; #print tt p=(0.5*scipy.special.erfc(2*math.pi*BT*(tt-0.5)/math.sqrt(math.log(2.0))/math.sqrt(2.0))-0.5*scipy.special.erfc(2*math.pi*BT*(tt+0.5)/math.sqrt(math.log(2.0))/math.sqrt(2.0)))/2.0; p=p/sum(p)*Q/2.0; #print p q=numpy.cumsum(p)/Q; q=q/q[-1]/2.0; #print q (f0T,SS,S,F,Sf,Ff,N) = fsm_utils.make_cpm_signals(K,P,M,L,q,frac) #print N #print Ff Ffa = numpy.insert(Ff,Q,numpy.zeros(N),axis=0) #print Ffa MF = numpy.fliplr(numpy.transpose(Ffa)) #print MF E = numpy.sum(numpy.abs(Sf)**2,axis=0) Es = numpy.sum(E)/f.O() #print Es constellation = numpy.reshape(numpy.transpose(Sf),N*f.O()) #print Ff #print Sf #print constellation #print numpy.max(numpy.abs(SS - numpy.dot(Ff , Sf))) EsN0_db = 10.0 N0 = Es * 10.0**(-(1.0*EsN0_db)/10.0) #N0 = 0.0 #print N0 head = 4 tail = 4 numpy.random.seed(seed*666) data = numpy.random.randint(0, M, head+blocksize+tail+1) #data = numpy.zeros(blocksize+1+head+tail,'int') for i in range(head): data[i]=0 for i in range(tail+1): data[-i]=0 ################################################## # Blocks ################################################## random_source_x_0 = blocks.vector_source_b(data.tolist(), False) digital_chunks_to_symbols_xx_0 = digital.chunks_to_symbols_bf((-1, 1), 1) filter_interp_fir_filter_xxx_0 = filter.interp_fir_filter_fff(Q, p) analog_frequency_modulator_fc_0 = analog.frequency_modulator_fc(2*math.pi*h*(1.0/Q)) blocks_add_vxx_0 = blocks.add_vcc(1) analog_noise_source_x_0 = analog.noise_source_c(analog.GR_GAUSSIAN, (N0/2.0)**0.5, -long(seed)) blocks_multiply_vxx_0 = blocks.multiply_vcc(1) analog_sig_source_x_0 = analog.sig_source_c(Q, analog.GR_COS_WAVE, -f0T, 1, 0) # only works for N=2, do it manually for N>2... filter_fir_filter_xxx_0_0 = filter.fir_filter_ccc(Q, MF[0].conjugate()) filter_fir_filter_xxx_0_0_0 = filter.fir_filter_ccc(Q, MF[1].conjugate()) blocks_streams_to_stream_0 = blocks.streams_to_stream(gr.sizeof_gr_complex*1, int(N)) blocks_skiphead_0 = blocks.skiphead(gr.sizeof_gr_complex*1, int(N*(1+0))) viterbi = trellis.viterbi_combined_cb(f, head+blocksize+tail, 0, -1, int(N), constellation, digital.TRELLIS_EUCLIDEAN) blocks_vector_sink_x_0 = blocks.vector_sink_b() ################################################## # Connections ################################################## tb.connect((random_source_x_0, 0), (digital_chunks_to_symbols_xx_0, 0)) tb.connect((digital_chunks_to_symbols_xx_0, 0), (filter_interp_fir_filter_xxx_0, 0)) tb.connect((filter_interp_fir_filter_xxx_0, 0), (analog_frequency_modulator_fc_0, 0)) tb.connect((analog_frequency_modulator_fc_0, 0), (blocks_add_vxx_0, 0)) tb.connect((analog_noise_source_x_0, 0), (blocks_add_vxx_0, 1)) tb.connect((blocks_add_vxx_0, 0), (blocks_multiply_vxx_0, 0)) tb.connect((analog_sig_source_x_0, 0), (blocks_multiply_vxx_0, 1)) tb.connect((blocks_multiply_vxx_0, 0), (filter_fir_filter_xxx_0_0, 0)) tb.connect((blocks_multiply_vxx_0, 0), (filter_fir_filter_xxx_0_0_0, 0)) tb.connect((filter_fir_filter_xxx_0_0, 0), (blocks_streams_to_stream_0, 0)) tb.connect((filter_fir_filter_xxx_0_0_0, 0), (blocks_streams_to_stream_0, 1)) tb.connect((blocks_streams_to_stream_0, 0), (blocks_skiphead_0, 0)) tb.connect((blocks_skiphead_0, 0), (viterbi, 0)) tb.connect((viterbi, 0), (blocks_vector_sink_x_0, 0)) tb.run() dataest = blocks_vector_sink_x_0.data() #print data #print numpy.array(dataest) perr = 0 err = 0 for i in range(blocksize): if data[head+i] != dataest[head+i]: #print i err += 1 if err != 0 : perr = 1 return (err,perr)
#tcm_indicator_symbols_per_frame=4; #Zhe added, 4 bits are used as tcm mode indicator, it is used as a part of header. # Achilles' comment: this may change later when filler bits are introduced... print "bits_per_header=", bits_per_header print "symbols_per_header=", symbols_per_header #print "tcm_indicator_symbols_per_frame=",tcm_indicator_symbols_per_frame print "\n" #trellis coding and modulation info payload_mod = [digital.constellation_qpsk(), digital.constellation_8psk()] pdir = prefix + "/python/fsm_files/" fsm = [pdir + "awgn2o2_1.fsm", pdir + "awgn2o3_8ungerboecka.fsm"] uncoded_fsm = [ trellis.fsm(2, 2, [1, 0, 0, 1]), trellis.fsm(3, 3, [1, 0, 0, 0, 1, 0, 0, 0, 1]) ] bits_per_coded_symbol = [ int(math.log(trellis.fsm(fsm[i]).O(), 2)) for i in range(len(payload_mod)) ] #coding_rate=[Fraction(int(math.log(trellis.fsm(fsm[i]).I(),2)), int(math.log(trellis.fsm(fsm[i]).O(),2))) for i in range(len(fsm))] if bits_per_coded_symbol != [ payload_mod[i].bits_per_symbol() for i in range(len(payload_mod)) ]: print "Error in selecting trellis code and modulation pairs." print "bits_per_coded_symbol =", bits_per_coded_symbol, " for [uncoded QPSK, rate 2/3 cc &8PSK] respectively.\n"
def __init__(self, vlen_in=1, vlen_out=1, n_tailbits=6, denom_mother_code_rate=6, gen_poly=(91, 121, 101, 91, 121, 101), bits_per_symbol=0, N=1, map_tab=0, pp_0=0, pp_0_tail=0, pp_1=0, pp_1_tail=0, part_len_top=1, part_len_bot=1, M_total=0, interl_seq_0_2=range(2), interl_seq_1_2=range(2)): gr.hier_block2.__init__( self, "DRM MLC 16-QAM", gr.io_signature(1, 1, gr.sizeof_char * vlen_in), gr.io_signature(1, 1, gr.sizeof_gr_complex * vlen_out), ) ################################################## # Parameters ################################################## self.vlen_in = vlen_in self.vlen_out = vlen_out self.n_tailbits = n_tailbits self.denom_mother_code_rate = denom_mother_code_rate self.gen_poly = gen_poly self.bits_per_symbol = bits_per_symbol self.N = N self.map_tab = map_tab self.pp_0 = pp_0 self.pp_0_tail = pp_0_tail self.pp_1 = pp_1 self.pp_1_tail = pp_1_tail self.part_len_top = part_len_top self.part_len_bot = part_len_bot self.M_total = M_total self.interl_seq_0_2 = interl_seq_0_2 self.interl_seq_1_2 = interl_seq_1_2 ################################################## # Blocks ################################################## self.trellis_encoder_xx_0_0 = trellis.encoder_bb( trellis.fsm(1, denom_mother_code_rate, gen_poly), 0) self.trellis_encoder_xx_0 = trellis.encoder_bb( trellis.fsm(1, denom_mother_code_rate, gen_poly), 0) self.gr_vector_to_stream_1_0 = gr.vector_to_stream( gr.sizeof_char * 1, part_len_bot + n_tailbits) self.gr_vector_to_stream_1 = gr.vector_to_stream( gr.sizeof_char * 1, part_len_top + n_tailbits) self.gr_unpack_k_bits_bb_0_0 = gr.unpack_k_bits_bb( denom_mother_code_rate) self.gr_unpack_k_bits_bb_0 = gr.unpack_k_bits_bb( denom_mother_code_rate) self.gr_stream_to_vector_0_0 = gr.stream_to_vector( gr.sizeof_char * 1, (part_len_bot + n_tailbits) * denom_mother_code_rate) self.gr_stream_to_vector_0 = gr.stream_to_vector( gr.sizeof_char * 1, (part_len_top + n_tailbits) * denom_mother_code_rate) self.drm_qam_map_vbvb_0 = drm.qam_map_vbvb(map_tab, bits_per_symbol, vlen_out, 2) self.drm_punct_vbvb_0_0 = drm.punct_vbvb( pp_1, pp_1_tail, (part_len_bot + n_tailbits) * denom_mother_code_rate, vlen_out * 2, n_tailbits * denom_mother_code_rate) self.drm_punct_vbvb_0 = drm.punct_vbvb( pp_0, pp_0_tail, (part_len_top + n_tailbits) * denom_mother_code_rate, vlen_out * 2, n_tailbits * denom_mother_code_rate) self.drm_partitioning_16_vbvb_0 = drm.partitioning_vbvb( vlen_in, M_total) self.drm_interleaver_vbvb_0_0 = drm.interleaver_vbvb((interl_seq_1_2)) self.drm_interleaver_vbvb_0 = drm.interleaver_vbvb((interl_seq_0_2)) self.add_tailbits_vbvb_0_0 = drm.add_tailbits_vbvb( part_len_bot, n_tailbits) self.add_tailbits_vbvb_0 = drm.add_tailbits_vbvb( part_len_top, n_tailbits) ################################################## # Connections ################################################## self.connect((self.drm_interleaver_vbvb_0, 0), (self.drm_qam_map_vbvb_0, 0)) self.connect((self.drm_qam_map_vbvb_0, 0), (self, 0)) self.connect((self.trellis_encoder_xx_0, 0), (self.gr_unpack_k_bits_bb_0, 0)) self.connect((self.gr_stream_to_vector_0, 0), (self.drm_punct_vbvb_0, 0)) self.connect((self.gr_unpack_k_bits_bb_0, 0), (self.gr_stream_to_vector_0, 0)) self.connect((self.drm_punct_vbvb_0, 0), (self.drm_interleaver_vbvb_0, 0)) self.connect((self.trellis_encoder_xx_0_0, 0), (self.gr_unpack_k_bits_bb_0_0, 0)) self.connect((self.gr_stream_to_vector_0_0, 0), (self.drm_punct_vbvb_0_0, 0)) self.connect((self.gr_unpack_k_bits_bb_0_0, 0), (self.gr_stream_to_vector_0_0, 0)) self.connect((self.drm_punct_vbvb_0_0, 0), (self.drm_interleaver_vbvb_0_0, 0)) self.connect((self.drm_interleaver_vbvb_0_0, 0), (self.drm_qam_map_vbvb_0, 1)) self.connect((self.gr_vector_to_stream_1, 0), (self.trellis_encoder_xx_0, 0)) self.connect((self.gr_vector_to_stream_1_0, 0), (self.trellis_encoder_xx_0_0, 0)) self.connect((self, 0), (self.drm_partitioning_16_vbvb_0, 0)) self.connect((self.add_tailbits_vbvb_0, 0), (self.gr_vector_to_stream_1, 0)) self.connect((self.add_tailbits_vbvb_0_0, 0), (self.gr_vector_to_stream_1_0, 0)) self.connect((self.drm_partitioning_16_vbvb_0, 1), (self.add_tailbits_vbvb_0_0, 0)) self.connect((self.drm_partitioning_16_vbvb_0, 0), (self.add_tailbits_vbvb_0, 0))
def set_prefix(self, prefix): self.prefix = prefix self.set_fsm(trellis.fsm(self.prefix + "diff_manchester.fsm"))
def __init__(self): grc_wxgui.top_block_gui.__init__(self, title="Dvbs Tx") ################################################## # Variables ################################################## self.symbol_rate = symbol_rate = 4500000 self.samp_rate = samp_rate = symbol_rate * 2 self.rrc_taps = rrc_taps = 20 ################################################## # Blocks ################################################## self.wxgui_fftsink2_0 = fftsink2.fft_sink_c( self.GetWin(), baseband_freq=435000000, y_per_div=10, y_divs=10, ref_level=0, ref_scale=2.0, sample_rate=samp_rate, fft_size=1024, fft_rate=15, average=True, avg_alpha=None, title="FFT Plot", peak_hold=False, ) self.Add(self.wxgui_fftsink2_0.win) self.trellis_encoder_xx_0 = trellis.encoder_bb(trellis.fsm(1, 2, (0171, 0133)), 0) self.osmosdr_sink_0 = osmosdr.sink( args="numchan=" + str(1) + " " + "" ) self.osmosdr_sink_0.set_sample_rate(samp_rate) self.osmosdr_sink_0.set_center_freq(435e6, 0) self.osmosdr_sink_0.set_freq_corr(0, 0) self.osmosdr_sink_0.set_gain(2, 0) self.osmosdr_sink_0.set_if_gain(0, 0) self.osmosdr_sink_0.set_bb_gain(-4, 0) self.osmosdr_sink_0.set_antenna("", 0) self.osmosdr_sink_0.set_bandwidth(6000000, 0) self.fft_filter_xxx_0 = filter.fft_filter_ccc(1, (firdes.root_raised_cosine(1.79, samp_rate, samp_rate/2, 0.35, rrc_taps)), 1) self.fft_filter_xxx_0.declare_sample_delay(0) self.dvbs_reed_solomon_enc_bb_0 = dvbs.reed_solomon_enc_bb() self.dvbs_randomizer_bb_0 = dvbs.randomizer_bb() self.dvbs_puncture_bb_0 = dvbs.puncture_bb(dvbs.C1_2) self.dvbs_modulator_bc_0 = dvbs.modulator_bc() self.dvbs_interleaver_bb_0 = dvbs.interleaver_bb() self.blocks_unpack_k_bits_bb_0 = blocks.unpack_k_bits_bb(2) self.blocks_packed_to_unpacked_xx_0 = blocks.packed_to_unpacked_bb(1, gr.GR_MSB_FIRST) self.blocks_pack_k_bits_bb_0 = blocks.pack_k_bits_bb(2) self.blocks_file_source_0 = blocks.file_source(gr.sizeof_char*1, "/home/re/xfer/adv.ts", False) ################################################## # Connections ################################################## self.connect((self.blocks_file_source_0, 0), (self.dvbs_randomizer_bb_0, 0)) self.connect((self.dvbs_randomizer_bb_0, 0), (self.dvbs_reed_solomon_enc_bb_0, 0)) self.connect((self.dvbs_reed_solomon_enc_bb_0, 0), (self.dvbs_interleaver_bb_0, 0)) self.connect((self.dvbs_interleaver_bb_0, 0), (self.blocks_packed_to_unpacked_xx_0, 0)) self.connect((self.blocks_packed_to_unpacked_xx_0, 0), (self.trellis_encoder_xx_0, 0)) self.connect((self.trellis_encoder_xx_0, 0), (self.blocks_unpack_k_bits_bb_0, 0)) self.connect((self.blocks_unpack_k_bits_bb_0, 0), (self.dvbs_puncture_bb_0, 0)) self.connect((self.dvbs_puncture_bb_0, 0), (self.blocks_pack_k_bits_bb_0, 0)) self.connect((self.dvbs_modulator_bc_0, 0), (self.fft_filter_xxx_0, 0)) self.connect((self.blocks_pack_k_bits_bb_0, 0), (self.dvbs_modulator_bc_0, 0)) self.connect((self.fft_filter_xxx_0, 0), (self.osmosdr_sink_0, 0)) self.connect((self.fft_filter_xxx_0, 0), (self.wxgui_fftsink2_0, 0))
def set_fsm(self, fsm): self.fsm = fsm self.trellis_viterbi_x_0.set_FSM(trellis.fsm(self.fsm))
def __init__(self, samp_rate=512e3): gr.hier_block2.__init__( self, "RDS demodulator", gr.io_signaturev( 2, 2, [gr.sizeof_gr_complex * 1, gr.sizeof_gr_complex * 1]), gr.io_signaturev(2, 2, [gr.sizeof_char * 1, gr.sizeof_gr_complex * 1]), ) ################################################## # Parameters ################################################## self.samp_rate = samp_rate ################################################## # Variables ################################################## self.bitrate = bitrate = 1187.5 self.syms_rate = syms_rate = 2 * bitrate self.samp_per_sym = samp_per_sym = 4 self.prefix = prefix = "radio/" self.variable_constellation_0 = variable_constellation_0 = digital.constellation_bpsk( ).base() self.fsm = fsm = trellis.fsm(prefix + "diff_manchester.fsm") self.decim = decim = int(samp_rate / (samp_per_sym * syms_rate)) self.RRC_filtr_taps = RRC_filtr_taps = firdes.root_raised_cosine( 10, samp_rate, syms_rate, 1, int(6 * samp_rate / syms_rate)) ################################################## # Blocks ################################################## self.trellis_viterbi_x_0 = trellis.viterbi_b(trellis.fsm(fsm), 10000, 0, -1) self.trellis_metrics_x_0 = trellis.metrics_c( fsm.O(), 2, (-1, -1, -1, 1, 1, -1, 1, 1), digital.TRELLIS_EUCLIDEAN) self.fir_filter_xxx_0 = filter.fir_filter_ccf(decim, (RRC_filtr_taps)) self.fir_filter_xxx_0.declare_sample_delay(0) self.digital_lms_dd_equalizer_cc_0_0 = digital.lms_dd_equalizer_cc( 1, 0.1, 1, variable_constellation_0) self.digital_clock_recovery_mm_xx_0 = digital.clock_recovery_mm_cc( samp_rate / decim / syms_rate, 0.25 * 0.175 * 0.175, 0.5, 0.175, 0.005) self.blocks_multiply_xx_1 = blocks.multiply_vcc(1) ################################################## # Connections ################################################## self.connect((self.blocks_multiply_xx_1, 0), (self.fir_filter_xxx_0, 0)) self.connect((self.digital_clock_recovery_mm_xx_0, 0), (self.digital_lms_dd_equalizer_cc_0_0, 0)) self.connect((self.digital_lms_dd_equalizer_cc_0_0, 0), (self, 1)) self.connect((self.digital_lms_dd_equalizer_cc_0_0, 0), (self.trellis_metrics_x_0, 0)) self.connect((self.fir_filter_xxx_0, 0), (self.digital_clock_recovery_mm_xx_0, 0)) self.connect((self, 0), (self.blocks_multiply_xx_1, 1)) self.connect((self, 1), (self.blocks_multiply_xx_1, 0)) self.connect((self.trellis_metrics_x_0, 0), (self.trellis_viterbi_x_0, 0)) self.connect((self.trellis_viterbi_x_0, 0), (self, 0))
###################################################################### # C test channel (J. Proakis, Digital Communications, McGraw-Hill Inc., 2001) c_channel = [0.227, 0.460, 0.688, 0.460, 0.227] if __name__ == '__main__': f1=trellis.fsm('fsm_files/awgn1o2_4.fsm') #f2=trellis.fsm('fsm_files/awgn2o3_4.fsm') #print f1.I(), f1.S(), f1.O() #print f1.NS() #print f1.OS() #print f2.I(), f2.S(), f2.O() #print f2.NS() #print f2.OS() ##f1.write_trellis_svg('f1.svg',4) #f2.write_trellis_svg('f2.svg',4) #f=fsm_concatenate(f1,f2) #f=fsm_radix(f1,2) #print "----------\n" #print f.I(), f.S(), f.O() #print f.NS()