📄 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:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -