www.pudn.com > DaVinci_Qam.zip > qam_gen_pack_lookup.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_pack_lookup.asm 
Label name      : _qam_gen_pack_lookup 
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 then selects the   
                  co-ordinates from the lookup table. 
                  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[], optr[] and lookuptable[] should be aligned to a 4  
                     byte boundary. 
 
Prototype       : void qam_gen_pack_lookup( 
                        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)  
                        short *lookuptable) // (i) : Base address of lookup 
                                                     table 
 
Registers used  : R0-R7, I0,I1, B0,B1, L0,L1, P0-P2,P5, LC0,LC1, CC. 
 
Performance     : 
                Code Size   : 234 Bytes. 
                Cycle Count :  
                       113 cycles for   4 symbols and symbol size of 2. 
                       137 cycles for   8 symbols and symbol size of 3. 
                       195 cycles for  16 symbols and symbol size of 4. 
                       330 cycles for  32 symbols and symbol size of 5. 
                       631 cycles for  64 symbols and symbol size of 6. 
                      1237 cycles for 128 symbols and symbol size of 7. 
                      2689 cycles for 256 symbols and symbol size of 8. 
 
*******************************************************************************/ 
.section  L1_code; 
.global _qam_gen_pack_lookup; 
.align 8; 
     
_qam_gen_pack_lookup:        
    R3 = [SP + 12];         // QAM Size (Number of bits/baud) 
    [--SP] = (R7:4,P5:5);   // Saves registers used by subroutine 
     
    I0 = R0;                // Pointer to data stream 
    I1 = R1;                // Output Pointer 
    R0 = R2.L * R3.L(IS) || R2 = [SP + 36]; 
                            // R0 = Total number of bits , R2 = Base address of  
                            //lookup table 
    L0 = 0;                 // Disabling circular buffering 
    L1 = 0;                                          
     
    R1 = R0 >> 5;           // Number of words = Number of bits / 32 
    P1 = R1; 
    R1 = 31; 
    R0 = R0 & R1; 
    B1 = R0; 
     
                            // To find number of symbols in a word 
    R7 = 32;                // Numerator = 32 
    P0 = 16;                // Loop counter for division 
    DIVS(R7,R3);            // To reset the AQ flag 
 
    LSETUP(DIV_ST,DIV_ST) LC0 = P0; 
DIV_ST: DIVQ(R7,R3);        // Do divq 16 times 
    R7 = R7.L(Z);           // Quotient 
    R7 += -1;               // 32/k - 1 
    P2 = R7; 
     
    R5 = R7.L * R3.L(IS) || R6 = [I0++]; 
                            // (32/k - 1) * k , Get first data 
    R0 = 32; 
    R5 = R0 - R5;           // Remainder  + k   =   32 - ((32/k-1) * k) 
     
    R4 = 0;                 // Assuming the symbol is starting at the start of  
                            //the word 
    R7 += -1; 
     
    CC = P1 <= 0;           // If only one word is required 
    IF CC JUMP LABEL1; 
     
    LSETUP(LOOP1_ST,LOOP1_END)LC0 = P1;                      
LOOP1_ST: 
        P0 = R7;            // Loop ctr = R7 
        R4 = R5 - R4;       // Difference between R5 and bits used up 
        R0 = R4 - R3; 
        CC = R4 < R3; 
        IF !CC P0 = P2; 
        IF !CC R4 = R0; 
        R0 = EXTRACT (R6,R3.L)(Z); 
                            // Extracts the symbols from word  
        R6 >>= R3; 
     
        R0 <<= 2;           // Offset is got by multiplying the new symbol by  
                            //four 
        R1 = R0 + R2;       // Offset is added to the base address 
        P5 = R1;            // P0 points to the (x,y)co-ordinates corresponding  
                            //to new symbol 
     
        LSETUP(LOOP2_ST,LOOP2_END) LC1 = P0; 
                            // Loop to modulate symbols in a word  
LOOP2_ST:   R0 = EXTRACT (R6,R3.L)(Z); 
                            // Shift data to get next symbol  
            R6 >>= R3; 
            R0 = R0 << 2;   // Offset is got by multiplying the new symbol by  
                            //four 
            R1 = [P5];      // Get the (x,y)co-ordinates of previous symbol 
            R1 = R0 + R2(S) || [I1++] = R1; 
                            // Offset is added to the base address  
LOOP2_END:  P5 = R1;        // P0 points to the (x,y)co-ordinates corresponding  
                            //to new symbol 
     
        R0 = EXTRACT (R6,R3.L)(Z) || R6 = [I0++]; 
                            // Shift data to get next symbol 
                            // Store partial symbol and get next data word 
        CC = R4 == 0; 
        IF CC JUMP LOOP1_INTER; 
                            // If no bits were remaining in this word, goto  
                            //loop1  
        B0 = R6;            // Store new data 
        R6 <<= R4;          // Shift no: of bits remaining in previous word  
                            //times 
        R6 = EXTRACT (R6,R3.L) (Z)|| R1 = [P5];     
                            // Extract symbol 
                            // Get the (x,y)co-ordinates of previous symbol 
        R0 = (R0 + R6) << 2;// Combining last part of a word and first part of  
                            //next word 
                            // Offset is got by multiplying the new symbol by  
                            //four 
        R1 = R0 + R2(S) || [I1++] = R1; 
                            // Offset is added to the base address  
        P5 = R1;            // P0 points to the (x,y)co-ordinates corresponding  
                            //to new symbol 
        R6 = B0;            // Restore data 
        R4 = R3 - R4;       // R4 = bits used by previous word 
        R6 >>= R4;          // Adjust data 
LOOP1_INTER: 
        R1 = [P5];          // Get the (x,y)co-ordinates of previous symbol 
LOOP1_END: 
        [I1++] = R1; 
     
LABEL1:  
    R7 = B1; 
    CC = R7 < R3; 
    IF CC JUMP FINISH;      // If no symbols are present in last word, jump 
     
    P0 = 14;                // Loop counter for division 
    DIVS(R7,R3);            // To reset the AQ flag 
 	DIVQ(R7,R3);            // Do divq once outside to avoid stall in  
                            //conditional jump 3 instr. 
                            // above this.     
	DIVQ(R7,R3);                             
    LSETUP(DIV_ST2,DIV_ST2) LC0 = P0; 
    
DIV_ST2: 
    DIVQ(R7,R3);        // Do divq 15 times    
    R0 = R7.L(Z);           // Quotient 
     
    P0 = R0; 
     
     
    R7 = EXTRACT (R6,R3.L)(Z); // Extracts the symbols from word 
    R7 <<= 2;               // Offset is got by multiplying the new symbol by  
                            //four 
    R1 = R7 + R2;           // Offset is added to the base address 
 
    LSETUP(LOOP3_ST,LOOP3_END)LC1 = P0; 
                            // Loop to modulate symbols in the last word  
LOOP3_ST: 
        P5 = R1;            // P0 points to the (x,y)co-ordinates corresponding  
                            //to new symbol 
                             
        R6 >>= R3; 
        R7 = EXTRACT (R6,R3.L)(Z); 
                            // Shift data to get next symbol  
        R7 <<= 2;           // Offset is got by multiplying the new symbol by  
                            //four 
        R1 = [P5];          // Get the (x,y)co-ordinates of previous symbol 
LOOP3_END:   
        R1 = R7 + R2(S) || [I1++] = R1; 
                            // Offset is added to the base address, Output is  
                            //stored  
     
FINISH:      
    (R7:4,P5:5) = [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_pack_lookup.end: