www.pudn.com > DaVinci_Qam.zip > qam_gen_unpacked.asm


/******************************************************************************* 
Copyright(c) 2000 - 2002 Analog Devices. All Rights Reserved. 
Developed by Joint Development Software Application Team, IPDC, Bangalore, India 
for Blackfin DSPs  ( Micro Signal Architecture 1.0 specification). 
 
By using this module you agree to the terms of the Analog Devices License 
Agreement for DSP Software.  
******************************************************************************** 
Module name     : qam_gen_unpacked.asm 
Label name      : _qam_gen_unpacked 
Version         : 2.0 
 
Change History  : 
 
                Version   Date            Author        Comments 
                2.0       01/09/2007                    Tested with VDSP++4.5 
							compiler 7.2.3.2 
		1.3       11/18/2002      Swarnalatha   Tested with VDSP++ 3.0 
                                                        compiler 6.2.2 on  
                                                        ADSP-21535 Rev.0.2 
                1.2       11/13/2002      Swarnalatha   Tested with VDSP++ 3.0 
                                                        on ADSP-21535 Rev. 0.2 
                1.1       01/20/2002      Nishanth      Modified to match  
                                                        silicon cycle count 
                1.0       05/08/2001      Nishanth      Original  
 
Description     : This program receives symbols from memory pointed to by  
                  input pointer and map the symbol to corresponding state.  
                  This subroutine is using rectangular constellation. The  
                  magnitude is in the scaled form. The distance between adjacent 
                  points is considered as 2. 
                    x co-ordinate is stored first and then y co-ordinate. 
 
Assumptions     : 1. There should be atleast one symbol. 
                  2. iptr[] and optr[] should be aligned to a 2 byte boundary. 
                  3. iptr[] and optr[] should be in different minibanks. 
 
Prototype       : void qam_gen_unpacked( 
                        short *iptr, // (i) : Input pointer  
                        short *optr, // (o) : Output pointer  
                        int   n,     // (i) : Number of symbols  
                        short k)     // (i) : QAM Size(Number of bits/symbol)  
 
Registers used  : R0-R7, I0,I1, L0,L1, P0-P2, LC0,LC1, CC. 
 
Performance     : 
      Code Size   : 150 Bytes. 
      Cycle Count : 33   +   26 * n           for symbol sizes of 2,3,4 
                    33   +   n * (27 + 2*k)   or 
                    33   +   n * (28 + 2*k)   for odd symbol sizes other than 3 
                    33   +   n * (24 + 2*k)   for even symbol sizes other than  
                                              2,4 
 
                       137 cycles for   4 symbols and symbol size of 2. 
                       241 cycles for   8 symbols and symbol size of 3. 
                       449 cycles for  16 symbols and symbol size of 4. 
                      1241 cycles for  32 symbols and symbol size of 5. 
                      2337 cycles for  64 symbols and symbol size of 6. 
                      5377 cycles for 128 symbols and symbol size of 7. 
                     10273 cycles for 256 symbols and symbol size of 8. 
 
*******************************************************************************/ 
.section  L1_code; 
.global _qam_gen_unpacked; 
.align 8; 
     
_qam_gen_unpacked:        
    R3 = [SP + 12];         // QAM Size (Number of bits/baud) 
    [--SP] = (R7:4);        // Saves registers used by subroutine 
     
    I0 = R0;                // Pointer to data stream 
    L0 = 0;                 // Disabling circular buffering 
    I1 = R1;                // Output Pointer 
    L1 = 0;                 // Disabling circular buffering 
    P1 = R2;                // Number of symbols 
     
                            // R4 = m ,Number of bits representing x co-ordinate 
    R2 = -1; 
    R4 = R3 + R2;           // R4 = k-1 
    R4 >>= 1;               // R4 = m = (k-1)/2 
     
    P0 = R4;                // P0 = m 
     
                            // R5 = Cutt-off value to decide whether to remap  
                            // or not (if k is odd) 
    R0 = 1; 
    R0 <<= R4;              // 2 raised to m 
    R7 = R0 >> 1;           // 2 raised to m-1 
    R0 >>= 2;               // 2 raised to m-2 
    R7 = R7 + R0; 
    R5 = R7 + R2;           // Cut-off = 2^(m-1) + 2^(m-2) - 1 
     
    P0 += -1;               // Loop counter for gray coding = m-1 
     
                            // R2 = Mask Register to extract magnitude of x and  
                            // y co-ordinates from symbol 
    R7 = 32;                 
    R1 = R7 - R4(S) || R0.L = W[I0++]; 
                            // R7 = 32 - m, Get first data  
    R2 >>= R1;              // Mask register has 'm' ones in LSB 
     
    LSETUP(LOOP1_ST,LOOP1_END) LC0 = P1; 
                            // Loop for number of symbols 
LOOP1_ST: 
        P2 = R0;            // Save input symbol as it is required for sign  
                            // extraction 
     
        R0 >>= 2;           // Sign bits are deleted 
        R7 = R0 & R2;       // R7 for x 
        R0 >>= R4;          // Mask and store magnitude portions(gray)of x and  
                            // y of symbol 
        R6 = R0 & R2;       // R6 for y 
     
        CC = R4 < 2(IU);    // If m<2 no need to find gray -> binary 
        IF CC JUMP NOTR; 
     
        R1 = R7; 
        CC = BITTST (R3,0); // If even no need to remap; This instruction is  
                            // brought up as a 
                            // workaround to avoid one extra cycle taken by the  
                            // above 
                            // conditional jump when n = 2, P0 = -1. 
 
        LSETUP(X_GRAY_ST,X_GRAY_END)LC1 = P0; 
                            // Loop executed m-1 times 
X_GRAY_ST:  R1 >>= 1;       // Gray -> binary of x (shift and ex-or m-1 times) 
X_GRAY_END: R7 = R7 ^ R1; 
     
        R1 = R6; 
 
        LSETUP(Y_GRAY_ST,Y_GRAY_END)LC1 = P0; 
                            // Loop executed m-1 times 
Y_GRAY_ST:  R1 >>= 1;       // Gray -> binary of y (shift and ex-or m-1 times) 
Y_GRAY_END: R6 = R6 ^ R1; 
     
     
        IF !CC JUMP NOTR; 
        CC = R5 < R7; 
        IF !CC JUMP NOTR;   // If x > cut-off, remap 
     
        R1 = R6; 
        R0 = R5 << 1;       // x = y 
        R0 += 1;            // Remapping 
        R6 = R0 - R7;       // y = 2(cut-off) + 1 - x(old) 
        R7 = R1;                         
     
NOTR: 
        R7 <<= 1; 
        R7 += 1;            // 2x+1 of both components as that is the magnitude  
                            // in scaled form 
        R6 <<= 1; 
        R6 += 1; 
     
// **********************Sign assignment ************************************* 
        R0 = P2;            // Get data 
        R1 = -R7;           // Negated x 
        CC = BITTST ( R0, 0); 
        IF CC R7 = R1;      // If bit0 is set, x is negative 
     
        R1 = -R6;           // Negated y 
        CC = BITTST ( R0, 1);                    
        IF CC R6 = R1;      // If bit1 is set, y is negative 
     
        W [I1++] = R7.L;    // Store x 
LOOP1_END: 
        W [I1++] = R6.L || R0.L = W[I0++]; 
                            // Store y and get next data 
     
    (R7:4) = [SP++];        // Restores registers used by subroutine 
    RTS; 
 
    NOP;                    // If link or unlink happens to be the next  
                            //instruction after RTS in memory, RTS takes one  
                            //extra cycle than expected. NOP is put to avoid  
                            //this. 
_qam_gen_unpacked.end: