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