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 __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, "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, ): # """ # 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 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 __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 __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 __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 = int(self.puncturing_L1[ self.protect]) * 4 * self.dp.puncturing_vectors[ self.puncturing_PI1[self.protect]] + int( 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, [0o133, 0o171, 0o145, 0o133 ]) # 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(int(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 __init__(self): gr.top_block.__init__(self, "Viterbi Equalization") Qt.QWidget.__init__(self) self.setWindowTitle("Viterbi Equalization") try: self.setWindowIcon(Qt.QIcon.fromTheme('gnuradio-grc')) except: pass self.top_scroll_layout = Qt.QVBoxLayout() self.setLayout(self.top_scroll_layout) self.top_scroll = Qt.QScrollArea() self.top_scroll.setFrameStyle(Qt.QFrame.NoFrame) self.top_scroll_layout.addWidget(self.top_scroll) self.top_scroll.setWidgetResizable(True) self.top_widget = Qt.QWidget() self.top_scroll.setWidget(self.top_widget) self.top_layout = Qt.QVBoxLayout(self.top_widget) self.top_grid_layout = Qt.QGridLayout() self.top_layout.addLayout(self.top_grid_layout) self.settings = Qt.QSettings("GNU Radio", "viterbi_equalization") self.restoreGeometry(self.settings.value("geometry").toByteArray()) ################################################## # Variables ################################################## self.modulation = modulation = fu.pam4 self.channel = channel = fu.c_channel self.tot_mod = tot_mod = fu.make_isi_lookup(modulation, channel, False) self.fsm = fsm = trellis.fsm(len(modulation[1]), len(channel)) self.bpsym = bpsym = int(round(math.log(fsm.I()) / math.log(2))) self.EsN0_dB = EsN0_dB = 2 self.Es = Es = numpy.mean((numpy.square(numpy.abs(tot_mod[1])))) self.noisevar = noisevar = 10**(-EsN0_dB / 10.0) * Es / 2.0 self.block = block = bpsym * 1000 self.R = R = 100e3 ################################################## # Blocks ################################################## self.trellis_viterbi_combined_xx_0 = trellis.viterbi_combined_fb( trellis.fsm(fsm), block / bpsym, -1, -1, tot_mod[0], (tot_mod[1]), digital.TRELLIS_EUCLIDEAN) self.qtgui_number_sink_0 = qtgui.number_sink(gr.sizeof_float, 0, qtgui.NUM_GRAPH_HORIZ, 1) self.qtgui_number_sink_0.set_update_time(0.10) self.qtgui_number_sink_0.set_title("BER") labels = ['BER', '', '', '', '', '', '', '', '', ''] units = ['', '', '', '', '', '', '', '', '', ''] colors = [("black", "black"), ("black", "black"), ("black", "black"), ("black", "black"), ("black", "black"), ("black", "black"), ("black", "black"), ("black", "black"), ("black", "black"), ("black", "black")] factor = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1] for i in xrange(1): self.qtgui_number_sink_0.set_min(i, 0) self.qtgui_number_sink_0.set_max(i, 1) self.qtgui_number_sink_0.set_color(i, colors[i][0], colors[i][1]) if len(labels[i]) == 0: self.qtgui_number_sink_0.set_label(i, "Data {0}".format(i)) else: self.qtgui_number_sink_0.set_label(i, labels[i]) self.qtgui_number_sink_0.set_unit(i, units[i]) self.qtgui_number_sink_0.set_factor(i, factor[i]) self.qtgui_number_sink_0.enable_autoscale(False) self._qtgui_number_sink_0_win = sip.wrapinstance( self.qtgui_number_sink_0.pyqwidget(), Qt.QWidget) self.top_layout.addWidget(self._qtgui_number_sink_0_win) self.fir_filter_xxx_0 = filter.fir_filter_fff(1, (fu.c_channel)) self.fir_filter_xxx_0.declare_sample_delay(0) self.digital_chunks_to_symbols_xx_0_0 = digital.chunks_to_symbols_bf( (modulation[1]), modulation[0]) self.blocks_unpack_k_bits_bb_0 = blocks.unpack_k_bits_bb(bpsym) self.blocks_throttle_0 = blocks.throttle(gr.sizeof_char * 1, R, True) self.blocks_pack_k_bits_bb_0 = blocks.pack_k_bits_bb(bpsym) self.blocks_null_sink_1 = blocks.null_sink(gr.sizeof_float * 1) self.blocks_add_xx_1 = blocks.add_vff(1) self.blks2_error_rate_0 = grc_blks2.error_rate( type='BER', win_size=block * 100, bits_per_symbol=1, ) self.analog_random_source_x_0 = blocks.vector_source_b( map(int, numpy.random.randint(0, 2, 1007)), True) self.analog_noise_source_x_0 = analog.noise_source_f( analog.GR_GAUSSIAN, noisevar**0.5, -42) self._EsN0_dB_range = Range(-10, 30, 1, 2, 200) self._EsN0_dB_win = RangeWidget(self._EsN0_dB_range, self.set_EsN0_dB, 'Es/N0 (dB)', "counter_slider", float) self.top_layout.addWidget(self._EsN0_dB_win) ################################################## # Connections ################################################## self.connect((self.analog_noise_source_x_0, 0), (self.blocks_add_xx_1, 1)) self.connect((self.analog_random_source_x_0, 0), (self.blks2_error_rate_0, 0)) self.connect((self.analog_random_source_x_0, 0), (self.blocks_throttle_0, 0)) self.connect((self.blks2_error_rate_0, 0), (self.qtgui_number_sink_0, 0)) self.connect((self.blocks_add_xx_1, 0), (self.blocks_null_sink_1, 0)) self.connect((self.blocks_add_xx_1, 0), (self.trellis_viterbi_combined_xx_0, 0)) self.connect((self.blocks_pack_k_bits_bb_0, 0), (self.digital_chunks_to_symbols_xx_0_0, 0)) self.connect((self.blocks_throttle_0, 0), (self.blocks_pack_k_bits_bb_0, 0)) self.connect((self.blocks_unpack_k_bits_bb_0, 0), (self.blks2_error_rate_0, 1)) self.connect((self.digital_chunks_to_symbols_xx_0_0, 0), (self.fir_filter_xxx_0, 0)) self.connect((self.fir_filter_xxx_0, 0), (self.blocks_add_xx_1, 0)) self.connect((self.trellis_viterbi_combined_xx_0, 0), (self.blocks_unpack_k_bits_bb_0, 0))
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]) # print "\nFSM attributes" # print "FSM.I() = " + str(self.fsm.I()) # input states # print "FSM.S() = " + str(self.fsm.S()) # FSM states # print "FSM.O() = " + str(self.fsm.O()) # output states # print "FSM.NS() = " + str(self.fsm.NS()) # next states of the FSM itself # print "FSM.OS() = " + str(self.fsm.OS()) # output states # print "FSM.PS() = " + str(self.fsm.PS()) # previous states (not available in this example?) # print "FSM.PI() = " + str(self.fsm.PI()) # previous input states (not available in this example?) # print "FSM.TMi() = " + str(self.fsm.TMi()) # print "FSM.TMI() = " + str(self.fsm.TMl()) # Values for viterbi decoder K = 40 # 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) # print "\nViterbi_combined_fb attributes" # print "K = " + str(self.vit.K()) # print "SO = " + str(self.vit.SO()) # initial state # print "SK = " + str(self.vit.SK()) # final state # print "D = " + str(self.vit.D()) # print "TYPE = " + str(self.vit.TYPE()) # for i in range(len(self.vit.TABLE())/D): # print "TABLE =\t" + str(self.vit.TABLE()[i*D]) + "\t" + str(self.vit.TABLE()[i*D+1]) + "\t" + str(self.vit.TABLE()[i*D+2]) # 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)