diff options
author | Achilleas Anastasopoulos | 2011-02-19 11:42:42 -0500 |
---|---|---|
committer | Achilleas Anastasopoulos | 2011-02-19 11:42:42 -0500 |
commit | 00c5b9c5923b774b0a0a7ddd89737f4a64fd1903 (patch) | |
tree | ebcf5cf282d7ce8f98fe3482f34d07d6539a551c /gr-trellis | |
parent | f737dc447be394e509907acec90a6a4492e16995 (diff) | |
download | gnuradio-00c5b9c5923b774b0a0a7ddd89737f4a64fd1903.tar.gz gnuradio-00c5b9c5923b774b0a0a7ddd89737f4a64fd1903.tar.bz2 gnuradio-00c5b9c5923b774b0a0a7ddd89737f4a64fd1903.zip |
added sccc turbo decoder block + example test_sccc_turbo1.py
Diffstat (limited to 'gr-trellis')
-rwxr-xr-x | gr-trellis/src/examples/test_sccc_turbo.py | 8 | ||||
-rwxr-xr-x | gr-trellis/src/examples/test_sccc_turbo1.py | 99 | ||||
-rw-r--r-- | gr-trellis/src/lib/.gitignore | 24 | ||||
-rw-r--r-- | gr-trellis/src/lib/core_algorithms.cc | 150 | ||||
-rw-r--r-- | gr-trellis/src/lib/generate_trellis.py | 2 | ||||
-rw-r--r-- | gr-trellis/src/lib/trellis_sccc_decoder_combined_XX.cc.t | 5 |
6 files changed, 265 insertions, 23 deletions
diff --git a/gr-trellis/src/examples/test_sccc_turbo.py b/gr-trellis/src/examples/test_sccc_turbo.py index bb20e937c..703ee410b 100755 --- a/gr-trellis/src/examples/test_sccc_turbo.py +++ b/gr-trellis/src/examples/test_sccc_turbo.py @@ -91,13 +91,14 @@ def run_test (fo,fi,interleaver,Kb,bitspersymbol,K,dimensionality,constellation, def main(args): nargs = len (args) - if nargs == 4: + if nargs == 5: 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 + 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_tcm.py fsm_name_out fsm_fname_in Es/No_db repetitions\n') + 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 @@ -122,7 +123,6 @@ def main(args): Es = Es + constellation[i]**2 Es = Es / (len(constellation)/dimensionality) N0=Es/pow(10.0,esn0_db/10.0); # calculate 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 diff --git a/gr-trellis/src/examples/test_sccc_turbo1.py b/gr-trellis/src/examples/test_sccc_turbo1.py new file mode 100755 index 000000000..59b2c2bfe --- /dev/null +++ b/gr-trellis/src/examples/test_sccc_turbo1.py @@ -0,0 +1,99 @@ +#!/usr/bin/env python + +from gnuradio import gr +from gnuradio import trellis +from gnuradio import eng_notation +import math +import sys +import random +import fsm_utils + + +def run_test (fo,fi,interleaver,Kb,bitspersymbol,K,dimensionality,constellation,Es,N0,IT,seed): + tb = gr.top_block () + + # TX + src = gr.lfsr_32k_source_s() + src_head = gr.head (gr.sizeof_short,Kb/16) # packet size in shorts + s2fsmi = gr.packed_to_unpacked_ss(bitspersymbol,gr.GR_MSB_FIRST) # unpack shorts to symbols compatible with the outer FSM input cardinality + enc = trellis.sccc_encoder_ss(fo,0,fi,0,interleaver,K) + mod = gr.chunks_to_symbols_sf(constellation,dimensionality) + + # CHANNEL + add = gr.add_ff() + noise = gr.noise_source_f(gr.GR_GAUSSIAN,math.sqrt(N0/2),seed) + + # RX + dec = trellis.sccc_decoder_combined_fs(fo,0,-1,fi,0,-1,interleaver,K,IT,trellis.TRELLIS_MIN_SUM,dimensionality,constellation,trellis.TRELLIS_EUCLIDEAN) + fsmi2s = gr.unpacked_to_packed_ss(bitspersymbol,gr.GR_MSB_FIRST) # pack FSM input symbols to shorts + dst = gr.check_lfsr_32k_s() + + #tb.connect (src,src_head,s2fsmi,enc_out,inter,enc_in,mod) + tb.connect (src,src_head,s2fsmi,enc,mod) + tb.connect (mod,(add,0)) + tb.connect (noise,(add,1)) + #tb.connect (add,head) + #tb.connect (tail,fsmi2s,dst) + tb.connect (add,dec,fsmi2s,dst) + + tb.run() + + #print enc_out.ST(), enc_in.ST() + + ntotal = dst.ntotal () + nright = dst.nright () + runlength = dst.runlength () + return (ntotal,ntotal-nright) + + +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_tcm.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) + + +if __name__ == '__main__': + main (sys.argv[1:]) diff --git a/gr-trellis/src/lib/.gitignore b/gr-trellis/src/lib/.gitignore index 35b6584c6..1ded7cffe 100644 --- a/gr-trellis/src/lib/.gitignore +++ b/gr-trellis/src/lib/.gitignore @@ -113,12 +113,24 @@ /trellis_viterbi_combined_ss.i /trellis_viterbi_combined_ib.cc /trellis_viterbi_combined_sb.cc -/trellis_sccc_decoder_combined_ii.h -/trellis_sccc_decoder_combined_ii.i -/trellis_sccc_decoder_combined_ii.cc -/trellis_sccc_decoder_combined_ss.h -/trellis_sccc_decoder_combined_ss.i -/trellis_sccc_decoder_combined_ss.cc +/trellis_sccc_decoder_combined_fb.h +/trellis_sccc_decoder_combined_fb.i +/trellis_sccc_decoder_combined_fb.cc +/trellis_sccc_decoder_combined_fs.h +/trellis_sccc_decoder_combined_fs.i +/trellis_sccc_decoder_combined_fs.cc +/trellis_sccc_decoder_combined_fi.h +/trellis_sccc_decoder_combined_fi.i +/trellis_sccc_decoder_combined_fi.cc +/trellis_sccc_decoder_combined_cb.h +/trellis_sccc_decoder_combined_cb.i +/trellis_sccc_decoder_combined_cb.cc +/trellis_sccc_decoder_combined_cs.h +/trellis_sccc_decoder_combined_cs.i +/trellis_sccc_decoder_combined_cs.cc +/trellis_sccc_decoder_combined_ci.h +/trellis_sccc_decoder_combined_ci.i +/trellis_sccc_decoder_combined_ci.cc /trellis_generated.i /generate-stamp /stamp-* diff --git a/gr-trellis/src/lib/core_algorithms.cc b/gr-trellis/src/lib/core_algorithms.cc index 6c7187cff..b81e14965 100644 --- a/gr-trellis/src/lib/core_algorithms.cc +++ b/gr-trellis/src/lib/core_algorithms.cc @@ -20,7 +20,7 @@ * Boston, MA 02110-1301, USA. */ -#include <float.h> +#include <cstring> #include <stdexcept> #include "core_algorithms.h" #include "calc_metric.h" @@ -790,33 +790,167 @@ void sccc_decoder_combined( ) { -// to be implemented +//allocate space for priori, prioro and posti of inner FSM +std::vector<float> ipriori(blocklength*FSMi.I(),0.0); +std::vector<float> iprioro(blocklength*FSMi.O()); +std::vector<float> iposti(blocklength*FSMi.I()); + +//allocate space for priori, prioro and posto of outer FSM +std::vector<float> opriori(blocklength*FSMo.I(),0.0); +std::vector<float> oprioro(blocklength*FSMo.O()); +std::vector<float> oposti(blocklength*FSMo.I()); +std::vector<float> oposto(blocklength*FSMo.O()); + +// turn observations to neg-log-priors +for(int k=0;k<blocklength;k++) + calc_metric(FSMi.O(), D, TABLE, &(observations[k*D]), &(iprioro[k*FSMi.O()]),METRIC_TYPE); + +for(int rep=0;rep<repetitions;rep++) { + // run inner SISO + siso_algorithm(FSMi.I(),FSMi.S(),FSMi.O(), + FSMi.NS(), FSMi.OS(), FSMi.PS(), FSMi.PI(), + blocklength, + STi0,STiK, + true, false, + p2mymin, + &(ipriori[0]), &(iprioro[0]), &(iposti[0]) + ); + + //interleave soft info inner -> outer + for(int k=0;k<blocklength;k++) { + int ki = INTERLEAVER.DEINTER()[k]; + //for(int i=0;i<FSMi.I();i++) { + //oprioro[k*FSMi.I()+i]=iposti[ki*FSMi.I()+i]; + //} + memcpy(&(oprioro[k*FSMi.I()]),&(iposti[ki*FSMi.I()]),FSMi.I()*sizeof(float)); + } + + // run outer SISO + + if(rep<repetitions-1) { // do not produce posti + siso_algorithm(FSMo.I(),FSMo.S(),FSMo.O(), + FSMo.NS(), FSMo.OS(), FSMo.PS(), FSMo.PI(), + blocklength, + STo0,SToK, + false, true, + p2mymin, + &(opriori[0]), &(oprioro[0]), &(oposto[0]) + ); + + //interleave soft info outer --> inner + for(int k=0;k<blocklength;k++) { + int ki = INTERLEAVER.DEINTER()[k]; + //for(int i=0;i<FSMi.I();i++) { + //ipriori[ki*FSMi.I()+i]=oposto[k*FSMi.I()+i]; + //} + memcpy(&(ipriori[ki*FSMi.I()]),&(oposto[k*FSMi.I()]),FSMi.I()*sizeof(float)); + } + } + else // produce posti but not posto + + siso_algorithm(FSMo.I(),FSMo.S(),FSMo.O(), + FSMo.NS(), FSMo.OS(), FSMo.PS(), FSMo.PI(), + blocklength, + STo0,SToK, + true, false, + p2mymin, + &(opriori[0]), &(oprioro[0]), &(oposti[0]) + ); + + /* + viterbi_algorithm(FSMo.I(),FSMo.S(),FSMo.O(), + FSMo.NS(), FSMo.OS(), FSMo.PS(), FSMo.PI(), + blocklength, + STo0,SToK, + &(oprioro[0]), data + ); + */ + +} + + +// generate hard decisions +for(int k=0;k<blocklength;k++) { + float min=INF; + int mini=0; + for(int i=0;i<FSMo.I();i++) { + if(oposti[k*FSMo.I()+i]<min) { + min=oposti[k*FSMo.I()+i]; + mini=i; + } + } + data[k]=(To)mini; +} + + } //------- template -void sccc_decoder_combined<short,short>( +void sccc_decoder_combined<float,unsigned char>( + const fsm &FSMo, int STo0, int SToK, + const fsm &FSMi, int STi0, int STiK, + const interleaver &INTERLEAVER, int blocklength, int repetitions, + float (*p2mymin)(float,float), + int D, const std::vector<float> &TABLE, + trellis_metric_type_t METRIC_TYPE, + const float *observations, unsigned char *data +); + +template +void sccc_decoder_combined<float,short>( + const fsm &FSMo, int STo0, int SToK, + const fsm &FSMi, int STi0, int STiK, + const interleaver &INTERLEAVER, int blocklength, int repetitions, + float (*p2mymin)(float,float), + int D, const std::vector<float> &TABLE, + trellis_metric_type_t METRIC_TYPE, + const float *observations, short *data +); + +template +void sccc_decoder_combined<float,int>( const fsm &FSMo, int STo0, int SToK, const fsm &FSMi, int STi0, int STiK, const interleaver &INTERLEAVER, int blocklength, int repetitions, float (*p2mymin)(float,float), - int D, const std::vector<short> &TABLE, + int D, const std::vector<float> &TABLE, trellis_metric_type_t METRIC_TYPE, - const short *observations, short *data + const float *observations, int *data ); template -void sccc_decoder_combined<int,int>( +void sccc_decoder_combined<gr_complex,unsigned char>( const fsm &FSMo, int STo0, int SToK, const fsm &FSMi, int STi0, int STiK, const interleaver &INTERLEAVER, int blocklength, int repetitions, float (*p2mymin)(float,float), - int D, const std::vector<int> &TABLE, + int D, const std::vector<gr_complex> &TABLE, trellis_metric_type_t METRIC_TYPE, - const int *observations, int *data + const gr_complex *observations, unsigned char *data ); +template +void sccc_decoder_combined<gr_complex,short>( + const fsm &FSMo, int STo0, int SToK, + const fsm &FSMi, int STi0, int STiK, + const interleaver &INTERLEAVER, int blocklength, int repetitions, + float (*p2mymin)(float,float), + int D, const std::vector<gr_complex> &TABLE, + trellis_metric_type_t METRIC_TYPE, + const gr_complex *observations, short *data +); +template +void sccc_decoder_combined<gr_complex,int>( + const fsm &FSMo, int STo0, int SToK, + const fsm &FSMi, int STi0, int STiK, + const interleaver &INTERLEAVER, int blocklength, int repetitions, + float (*p2mymin)(float,float), + int D, const std::vector<gr_complex> &TABLE, + trellis_metric_type_t METRIC_TYPE, + const gr_complex *observations, int *data +); diff --git a/gr-trellis/src/lib/generate_trellis.py b/gr-trellis/src/lib/generate_trellis.py index 82cacba70..691276cc8 100644 --- a/gr-trellis/src/lib/generate_trellis.py +++ b/gr-trellis/src/lib/generate_trellis.py @@ -41,7 +41,7 @@ other_signatures = ( ['s','i','f','c'], ['b','s','i'], ['sb','ss','si','ib','is','ii','fb','fs','fi','cb','cs','ci'], - ['ss','ii'], + ['fb','fs','fi','cb','cs','ci'], ) diff --git a/gr-trellis/src/lib/trellis_sccc_decoder_combined_XX.cc.t b/gr-trellis/src/lib/trellis_sccc_decoder_combined_XX.cc.t index f354197dd..ce8df037a 100644 --- a/gr-trellis/src/lib/trellis_sccc_decoder_combined_XX.cc.t +++ b/gr-trellis/src/lib/trellis_sccc_decoder_combined_XX.cc.t @@ -94,10 +94,7 @@ void { assert (noutput_items % d_blocklength == 0); int input_required = d_D * noutput_items ; - unsigned ninputs = ninput_items_required.size(); - for (unsigned int i = 0; i < ninputs; i++) { - ninput_items_required[i] = input_required; - } + ninput_items_required[0] = input_required; } |