www.pudn.com > DaVinci_Qam.zip > qam_gen_packed.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_packed.asm 
Label name      : _qam_gen_packed 
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       02/18/2002      Nishanth      Modified to match  
                                                        silicon cycle count 
                1.0       05/08/2001      Nishanth      Original  
 
Description     : This program receives data from memory pointed to by a  
                  pointer, separates symbols depending on the baud size, which  
                  is also given as a parameter, and feeds it to another  
                  subroutine map which will map the symbol to corresponding  
                  state. The map subroutine receives symbols and maps them into  
                  two dimensional space by finding the corresponding waveform.  
                  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. The product of number of symbols(n) and qam size(number  
                     of bits/baud ,i.e. k) should be an integral multiple of 32  
                     if this program is called more than once for a continuous  
                     stream of data. 
                  2. iptr[] should be aligned to a 4 byte boundary. 
                  3. optr[] should be aligned to a 2 byte boundary. 
 
Prototype       : void qam_gen_packed( 
                        int   *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, B0-B2, L0,L1, P0-P2,P5, LC0,LC1, CC. 
 
Performance     : 
                Code Size   : 256 Bytes (86 Bytes for subfunction map) 
 
                Cycle Count : 254 cycles for   4 symbols and symbol size of 2. 
                              431 cycles for   8 symbols and symbol size of 3. 
                              800 cycles for  16 symbols and symbol size of 4. 
                              1975 cycles for  32 symbols and symbol size of 5. 
                              3746 cycles for  64 symbols and symbol size of 6. 
                              8386 cycles for 128 symbols and symbol size of 7. 
                             15998 cycles for 256 symbols and symbol size of 8. 
 
*******************************************************************************/ 
.section  L1_code; 
.global _qam_gen_packed; 
.align 8; 
     
_qam_gen_packed:        
    R3 = [SP + 12];         // QAM Size (Number of bits/baud) 
    [--SP] = (R7:4, P5:5);  // Saves registers used by subroutine 
    [--SP] = RETS;          // SAVE RETS AS MAP ROUTINE IS CALLED BY THIS ONE. 
     
    I0 = R0;                // Pointer to data stream 
    I1 = R1;                // Output Pointer 
    L0 = 0;                 // Disabling circular buffering 
    L1 = 0; 
    P1 = R2;                // Number of symbols 
     
                            // B0 = m ,Number of bits rep. x 
    R7 = -1; 
    R4 = R3 + R7; 
    R4 >>= 1; 
    P2 = R4; 
    B0 = R4;                // m=(k-1)/2 (used by map) 
     
                            // B1 = Cutt-off value used by map subroutine to  
                            //remap if k is odd 
    R0 = 1; 
    R0 <<= R4;              // 2 raised to m 
    R5 = R0 >> 1;           // 2 raised to m-1 
    R0 >>= 2;               // 2 raised to m-2 
    R5 = R5 + R0; 
    R5 += -1; 
    B1 = R5;                // Cut-off = 2^(m-1) + 2^(m-2) - 1 
     
    P2 += -1;               // Loop counter for gray decoding(m-1) 
     
                            // R2=Mask Reg. to mask mag. of x and y(used by  
                            //recta) 
    R7 = 32;                 
    R0 = R7 - R4;           // R0 = 32 - m 
    R2 = -1; 
    P0 = 16; 
    R2 >>= R0;              // Mask reg. has 'm' ones in LSB 
                            // To find number of symbols in a word 
    DIVS(R7,R3); 
 
    LSETUP(DIV_ST,DIV_ST) LC0 = P0; 
    
DIV_ST: 
        DIVQ(R7,R3); 
    R7 = R7.L(Z); 
    P5 = R7; 
    R7 += -1; 
     
    R0 = 32; 
    R5.L = R7.L*R3.L(IS) || R6 = [I0++]; 
                            // Get first data 
    R5 = R0 - R5; 
     
    R4 = 0;                 // Bits used by previous word, R4 initialized to  
                            //zero 
     
LOOP1:   
    P0 = R7;                // Loop ctr = R7 
    R4 = R5 - R4;           // Difference between R5 and bits used up 
    CC = R4 < R3; 
    IF !CC P0 = P5;         // If difference not less than k, 
    R0 = R4 - R3;           // Subtract k and 
    IF !CC R4 = R0;         // If difference not less than k, 
    R0 = EXTRACT (R6,R3.L)(Z); 
 
    LSETUP(LOOP2_ST,LOOP2_END) LC0 = P0; 
                            // Loop to modulate symbols in a word  
LOOP2_ST:            
        R6 >>= R3;          // Shift data to get next symbol 
        R1 = B0;            // Get the value of m, no: of bits rep. mag. of  
                            // rectangular components 
        P1 += -1;           // Decrement Symbol count 
        CALL map;           // Subroutine to map the symbol to various waveforms 
        CC = P1 == 0; 
        IF CC JUMP FINISH;  // If symbol count is zero, exit from program 
LOOP2_END:           
        R0 = EXTRACT (R6,R3.L)(Z); 
                            // Extracts the symbols from word  
     
    R6 = [I0++];            // Store partial symbol and get next data word 
    CC = R4 == 0; 
    IF CC JUMP LOOP1;       // If no bits were remaining in this word, goto  
                            //loop1 
    B2 = R6;                // Store new data 
    R6 <<= R4;              // Shift no: of bits remaining in previous word  
                            //times 
    R6 = EXTRACT (R6,R3.L)(Z); // Extract symbol 
    R0 = R0 + R6;           // Combining last part of a word and first part of  
                            //next word 
    R6 = B2;                // Restore data 
    R1 = B0;                // Get the value of m, no: of bits rep. mag. of  
                            //rectangular components 
    CALL map;               // Subroutine to map the symbol to various waveforms 
    P1 += -1;               // Decrement Symbol count 
    CC = P1 == 0;        
    IF CC JUMP FINISH;      // If symbol count is zero, exit from program 
    R4 = R3 - R4;           // R4 = bits used by previous word 
    R6 >>= R4;              // Adjust data 
    JUMP LOOP1; 
     
FINISH: 
    RETS = [SP++]; 
    (R7:4, P5:5) = [SP++];  // Restores registers used by subroutine 
    RTS; 
_qam_gen_packed.end:        
  
/******************************************************************************* 
Label name    : map 
 
Description   : This subroutine receives symbols and maps them into two  
                dimensional space by finding the corresponding waveform. 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. This is a subfunction of qam_gen_packed and is optimized  
                     for performance and does not obey C runtime model. 
     
Registers used  : R0-R3, R6, R7, I1, B1, B2, P2, LC1. 
     
Performance     : 
                Code Size   : 86 Bytes. 
                Cycle Count : 34                     if m < 2 
                                36   +   4 * m         else if k is even 
                                38   +   4 * m         else if x > cut-off 
                                39   +   4 * m         else 
                    where k = symbol size,  m = (k-1)/2,  x = input symbol,  
                    cut-off = 2^(m-1) + 2^(m-2) - 1 
*******************************************************************************/ 
.section  L1_code; 
.align 8; 
map: 
     
    [--SP] = (R7:6);        // Saves registers R6-R7 to stack 
     
    B2 = R0;                // Save input symbol as it is required for sign  
                            //extraction 
    R0 >>= 2;               // Sign bits are deleted 
     
    R6 = R0 & R2;           // R6 for x 
    R0 >>= R1;              // Mask and store mag. portions(gray)of x and y of  
                            //  symbol 
    R7 = R0 & R2;           // R7 for y 
    CC = R1 < 2(IU);        // If m<2 no need to find gray -> binary 
    IF CC JUMP NOTR; 
     
    R0 = R6; 
    R1 = R7; 
 
    LSETUP(LOOP3_ST,LOOP3_END)LC1 = P2;      
LOOP3_ST: 
        R0 >>= 1;           // Gray -> binary of x (shift and ex-or m-1 times) 
LOOP3_END: 
        R6 = R6 ^ R0; 
     
    LSETUP(LOOP4_ST,LOOP4_END)LC1 = P2; 
LOOP4_ST: 
        R1 >>= 1;           // Gray -> binary of y (shift and ex-or m-1 times) 
LOOP4_END: 
        R7 = R7 ^ R1; 
     
    CC = BITTST (R3,0);     // if even no need to remap 
    IF !CC JUMP NOTR; 
    R0 = B1;                // Cut-off value 
    CC = R0 < R6; 
    IF !CC JUMP NOTR;       // if x > cut-off, remap 
    R1 = R7; 
    R0 <<= 1;               // x = y 
    R0 += 1;                // Remapping 
    R7 = R0 - R6;           // y = 2(cut-off) + 1 - x(old) 
    R6 = R1; 
NOTR: 
    R6 <<= 1; 
    R6 += 1;                // 2x+1 of both components as that is the magnitude  
                            //in scaled form 
    R7 <<= 1; 
    R7 += 1; 
     
// **********************************Sign assignment ************************** 
MOD2: 
    R0 = B2;                // Get data 
    R1 = -R6; 
    CC = BITTST ( R0, 0); 
    IF CC R6 = R1;          // Sign assignment to x 
                            // If bit0 is set, x is negative 
    R1 = -R7; 
    CC = BITTST ( R0, 1);                    
    IF CC R7 = R1;          // Sign assignment to y 
                            // If bit1 is set, y is negative 
    W [I1++] = R6.L;        // Store x 
    W [I1++] = R7.L;        // Store y 
    (R7:6) = [SP++];        // Restore registers R6-R7 
    RTS; 
                            // Program ends here 
    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. 
map.end: