예제 #1
0
        /*
         * Allocate and initialize the trellis object
         *
         * Initialization consists of generating the outputs and output value of a
         * given state. Due to trellis symmetry, only one of the transition paths
         * is used by the butterfly operation in the forward recursion, so only one
         * set of N outputs is required per state variable.
         */
        static vtrellis generate_trellis(lte_conv_code code)
        {
            vtrellis trellis;
            short *  o;

            int ns   = NUM_STATES(code.k);
            int olen = (code.n == 2) ? 2 : 4;

            trellis               = new vtrellis();
            trellis.num_states    = ns;
            trellis.sumsBuffer    = UnsafeBuffer.Create(ns, sizeof(short));
            trellis.sums          = (short *)trellis.sumsBuffer;
            trellis.outputsBuffer = UnsafeBuffer.Create(ns * olen, sizeof(short));
            trellis.outputs       = (short *)trellis.outputsBuffer;
            trellis.valsBuffer    = UnsafeBuffer.Create(ns, sizeof(sbyte));
            trellis.vals          = (sbyte *)trellis.valsBuffer;

            /* Populate the trellis state objects */
            for (int i = 0; i < ns; i++)
            {
                o = &trellis.outputs[olen * i];

                if (code.rgen != 0)
                {
                    gen_rec_state_info(code, &trellis.vals[i], i, o);
                }
                else
                {
                    gen_state_info(code, &trellis.vals[i], i, o);
                }
            }

            return(trellis);
        }
예제 #2
0
        /*
         * Populate recursive trellis state
         */
        static void gen_rec_state_info(lte_conv_code code, sbyte *val, int reg, short *o)
        {
            int i;
            int prev, rec, mask;

            /* Previous '0' and '1' states */
            prev = vstate_lshift(reg, code.k, 0);

            /* Compute recursive input value (not the value shifted into register) */
            rec = (reg >> (code.k - 2)) & 0x01;

            if ((int)__builtin_parity(prev & code.rgen) == rec)
            {
                *val = 0;
            }
            else
            {
                *val = 1;
            }

            /* Compute outputs and unpack to NRZ */
            prev = prev | rec << (code.k - 1);

            if (code.k == 5)
            {
                mask = 0x0f;
            }
            else
            {
                mask = 0x3f;
            }

            /* Check for recursive outputs */
            for (i = 0; i < code.n; i++)
            {
                if ((code.gen[i] & mask) != 0)
                {
                    o[i] = (short)(__builtin_parity(prev & code.gen[i]) * 2 - 1);
                }
                else
                {
                    o[i] = (short)(*val * 2 - 1);
                }
            }
        }
예제 #3
0
        public ConvDec(int len)
        {
            //Make settings
            code = new lte_conv_code
            {
                n = 3,

                k = 7,

                len = len,

                gen = new int[] { 91, 121, 117, 0 },

                term = CONV_TERM.TAIL_BITING,
            };

            //Create
            vdec = alloc_vdec(code);
        }
예제 #4
0
        static void reset_vdec(vdecoder dec, lte_conv_code code)
        {
            dec.n         = code.n;
            dec.k         = code.k;
            dec.recursive = code.rgen != 0 ? 1 : 0;
            dec.intrvl    = short.MaxValue / (dec.n * sbyte.MaxValue) - dec.k;

            if (dec.n != 3 || dec.k != 7)
            {
                throw new Exception();
            }

            if (code.term == CONV_TERM.FLUSH)
            {
                dec.len = code.len + code.k - 1;
            }
            else
            {
                dec.len = code.len + TAIL_BITING_EXTRA * 2;
            }
        }
예제 #5
0
        /*
         * Allocate decoder object
         *
         * Subtract the constraint length K on the normalization interval to
         * accommodate the initialization path metric at state zero.
         */
        static vdecoder alloc_vdec(lte_conv_code code)
        {
            int i, ns;

            ns = NUM_STATES(code.k);

            vdecoder dec = new vdecoder();

            dec.n         = code.n;
            dec.k         = code.k;
            dec.recursive = code.rgen != 0 ? 1 : 0;
            dec.intrvl    = short.MaxValue / (dec.n * sbyte.MaxValue) - dec.k;

            if (dec.n != 3 || dec.k != 7)
            {
                throw new Exception();
            }

            if (code.term == CONV_TERM.FLUSH)
            {
                dec.len = code.len + code.k - 1;
            }
            else
            {
                dec.len = code.len + TAIL_BITING_EXTRA * 2;
            }

            dec.trellis = generate_trellis(code);

            dec.pathsBuffer = UnsafeBuffer.Create(sizeof(short *) * dec.len * ns);
            dec.pathsPtr    = (short *)dec.pathsBuffer;
            dec.paths       = new short *[dec.len];
            for (i = 0; i < dec.len; i++)
            {
                dec.paths[i] = &dec.pathsPtr[i * ns];
            }

            return(dec);
        }
예제 #6
0
        /*
         * Populate non-recursive trellis state
         *
         * For a given state defined by the k-1 length shift register, find the
         * value of the input bit that drove the trellis to that state. Then
         * generate the N outputs of the generator polynomial at that state.
         */
        static void gen_state_info(lte_conv_code code,
                                   sbyte *val, int reg, short *o)
        {
            int i;
            int prev;

            /* Previous '0' state */
            prev = vstate_lshift(reg, code.k, 0);

            /* Compute output and unpack to NRZ */
            *val = (sbyte)((reg >> (code.k - 2)) & 0x01);
            prev = prev | (int)*val << (code.k - 1);

            for (i = 0; i < code.n; i++)
            {
                o[i] = (short)(__builtin_parity(prev & code.gen[i]) * 2 - 1);
            }

            /*Console.WriteLine($"{__builtin_parity(0)}, {__builtin_parity(1)}, {__builtin_parity(2)}");
             * for (i = 0; i < code.n; i++)
             *      Console.WriteLine(o[i]);
             * Console.ReadLine();*/
        }