Statistics
| Branch: | Tag: | Revision:

root / gr-trellis / src / python / qa_trellis.py @ 765c9f6e

History | View | Annotate | Download (4.8 kB)

1
#!/usr/bin/env python
2
#
3
# Copyright 2004,2010 Free Software Foundation, Inc.
4
# 
5
# This file is part of GNU Radio
6
# 
7
# GNU Radio is free software; you can redistribute it and/or modify
8
# it under the terms of the GNU General Public License as published by
9
# the Free Software Foundation; either version 3, or (at your option)
10
# any later version.
11
# 
12
# GNU Radio is distributed in the hope that it will be useful,
13
# but WITHOUT ANY WARRANTY; without even the implied warranty of
14
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
# GNU General Public License for more details.
16
# 
17
# You should have received a copy of the GNU General Public License
18
# along with GNU Radio; see the file COPYING.  If not, write to
19
# the Free Software Foundation, Inc., 51 Franklin Street,
20
# Boston, MA 02110-1301, USA.
21
# 
22
23
import math
24
25
26
from gnuradio import gr, gr_unittest, blks2
27
# It's pretty ugly that we can't import trellis from gnuradio in this test
28
# but because it runs on the non-installed python code it's all a mess.
29
import trellis
30
31
fsm_args = {"awgn1o2_4": (2, 4, 4,
32
                          (0, 2, 0, 2, 1, 3, 1, 3),
33
                          (0, 3, 3, 0, 1, 2, 2, 1),
34
                          ),
35
            "rep2": (2, 1, 4, (0, 0), (0, 3)),
36
            "nothing": (2, 1, 2, (0, 0), (0, 1)),
37
            }
38
39
constells = {2: blks2.bpsk_constellation(),
40
             4: blks2.qpsk_constellation(),
41
             }
42
43
class test_trellis (gr_unittest.TestCase):
44
45
    def test_001_fsm (self):
46
        f = trellis.fsm(*fsm_args["awgn1o2_4"])
47
        self.assertEqual(fsm_args["awgn1o2_4"],(f.I(),f.S(),f.O(),f.NS(),f.OS()))
48
49
    def test_002_fsm (self):
50
        f = trellis.fsm(*fsm_args["awgn1o2_4"])
51
        g = trellis.fsm(f)
52
        self.assertEqual((g.I(),g.S(),g.O(),g.NS(),g.OS()),(f.I(),f.S(),f.O(),f.NS(),f.OS()))
53
54
    def test_003_fsm (self):
55
        f = trellis.fsm("awgn1o2_4.fsm")
56
        self.assertEqual(fsm_args["awgn1o2_4"],(f.I(),f.S(),f.O(),f.NS(),f.OS()))
57
58
    def test_004_fsm(self):
59
        """ Test to make sure fsm works with a single state fsm."""
60
        # Just checking that it initializes properly.
61
        f = trellis.fsm(*fsm_args["rep2"])
62
63
    def test_001_interleaver (self):
64
        K = 5
65
        IN = (1,2,3,4,0)
66
        DIN = (4,0,1,2,3)
67
        i = trellis.interleaver(K,IN)
68
        self.assertEqual((K,IN,DIN),(i.K(),i.INTER(),i.DEINTER()))
69
70
    def test_001_viterbi(self):
71
        """
72
        Runs some coding/decoding tests with a few different FSM
73
        specs.
74
        """
75
        for name, args in fsm_args.items():
76
            constellation = constells[args[2]]
77
            fsms = trellis.fsm(*args)
78
            noise = 0.1
79
            tb = trellis_tb(constellation, fsms, noise)
80
            tb.run()
81
            # Make sure all packets succesfully transmitted.
82
            self.assertEqual(tb.dst.ntotal(), tb.dst.nright())
83
84
85
class trellis_tb(gr.top_block):
86
    """
87
    A simple top block for use testing gr-trellis.
88
    """
89
    def __init__(self, constellation, f, N0=0.25, seed=-666L):
90
        """
91
        constellation - a constellation object used for modulation.
92
        f - a finite state machine specification used for coding.
93
        N0 - noise level
94
        seed - random seed
95
        """
96
        super(trellis_tb, self).__init__()
97
        # packet size in bits (make it multiple of 16 so it can be packed in a short)
98
        packet_size = 1024*16
99
        # bits per FSM input symbol
100
        bitspersymbol = int(round(math.log(f.I())/math.log(2))) # bits per FSM input symbol
101
        # packet size in trellis steps
102
        K = packet_size/bitspersymbol
103
104
        # TX
105
        src = gr.lfsr_32k_source_s()
106
        # packet size in shorts
107
        src_head = gr.head (gr.sizeof_short, packet_size/16)
108
        # unpack shorts to symbols compatible with the FSM input cardinality
109
        s2fsmi = gr.packed_to_unpacked_ss(bitspersymbol, gr.GR_MSB_FIRST) 
110
        # initial FSM state = 0
111
        enc = trellis.encoder_ss(f, 0) 
112
        mod = gr.chunks_to_symbols_sc(constellation.points(), 1)
113
114
        # CHANNEL
115
        add = gr.add_cc()
116
        noise = gr.noise_source_c(gr.GR_GAUSSIAN,math.sqrt(N0/2),seed)
117
118
        # RX
119
        # data preprocessing to generate metrics for Viterbi
120
        metrics = trellis.constellation_metrics_cf(constellation.base(), trellis.TRELLIS_EUCLIDEAN) 
121
        # Put -1 if the Initial/Final states are not set.
122
        va = trellis.viterbi_s(f, K, 0, -1)
123
        # pack FSM input symbols to shorts
124
        fsmi2s = gr.unpacked_to_packed_ss(bitspersymbol, gr.GR_MSB_FIRST) 
125
        # check the output
126
        self.dst = gr.check_lfsr_32k_s()
127
    
128
        self.connect (src, src_head, s2fsmi, enc, mod)
129
        self.connect (mod, (add, 0))
130
        self.connect (noise, (add, 1))
131
        self.connect (add, metrics, va, fsmi2s, self.dst)
132
133
134
if __name__ == '__main__':
135
    gr_unittest.run(test_trellis, "test_trellis.xml")