summaryrefslogtreecommitdiff
path: root/gr-trellis
diff options
context:
space:
mode:
authorAchilleas Anastasopoulos2011-02-19 11:42:42 -0500
committerAchilleas Anastasopoulos2011-02-19 11:42:42 -0500
commit00c5b9c5923b774b0a0a7ddd89737f4a64fd1903 (patch)
treeebcf5cf282d7ce8f98fe3482f34d07d6539a551c /gr-trellis
parentf737dc447be394e509907acec90a6a4492e16995 (diff)
downloadgnuradio-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-xgr-trellis/src/examples/test_sccc_turbo.py8
-rwxr-xr-xgr-trellis/src/examples/test_sccc_turbo1.py99
-rw-r--r--gr-trellis/src/lib/.gitignore24
-rw-r--r--gr-trellis/src/lib/core_algorithms.cc150
-rw-r--r--gr-trellis/src/lib/generate_trellis.py2
-rw-r--r--gr-trellis/src/lib/trellis_sccc_decoder_combined_XX.cc.t5
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;
}