Add real ADSP-2191 assembly examples + open21xx assembler test

This commit is contained in:
Siggi
2026-04-12 18:10:08 +00:00
parent d325e04765
commit d7f0569a47
34 changed files with 6283 additions and 0 deletions

View File

@@ -0,0 +1,80 @@
****************************************************************************
Viterbi.asm Soft Decision GSM Viterbi Decoder
Analog Devices, Inc.
DSP Division
Three Technology Way
P.O. Box 9106
Norwood, MA 02062
21-JUNE-2001 BJM
This directory contains an example ADSP-2191 single-core subroutine
that implements a soft decision half-rate, soft-decision, GSM Viterbi decoder.
Files contained in this directory:
VITERBI.dpj VisualDSP project file
VITERBI.asm ADSP-2191 source for Viterbi
ADSP-2191.ldf Linker description file
GSM_REC.dat Soft decision data for Viterbi
_________________________________________________________________
CONTENTS
I. FUNCTION/ALGORITHM DESCRIPTION
II. IMPLEMENTATION DESCRIPTION
III. DESCRIPTION OF INPUT DATA
I. FUNCTION/ALGORITHM DESCRIPTION
The project Viterbi.dpj contains an implementation of a single-core
subroutine that implements a half-rate, soft-decision, GSM Vitertbi decoder.
II. IMPLEMENTATION DESCRIPTION
1. METRIC UPDATE:
-----------------
The metric update section accumulates branch distance metrics into path metrics.
The lowest path metric at the end of processing is considered to denote the
path most likely to contain the correct decoding of the input.
Each element of the state_trans[] array represents a state transition.
Each of the 16-bits in an element of state_trans[] represents one of the
16 possible new states, and indicates which of two possible states
is the most likely previous state.
2. TRACE BACK:
--------------
The traceback traces back through the state_trans[] array. Starting
with a new state, the bits of "state" are rotated to compute the
position of the bit in the current state_trans[] array element that
represents this new state. This bit indicates which state was previous.
We update the state to the previous state using this bit.
During any state transition, the most significant of the four bits in
"state" is the most recent input bit to the convolutional encoder.
This is the bit which is added to the output of the decoder.
III. DESCRIPTION OF INPUT DATA
1. INPUT SAMPLES:
-----------------
The Viterbi decoder routine expects input data which conforms to the following criteria:
The class 1 bits are encoded with the 1/2 rate convolutional code defined by
the polynomials:
G0 = 1 + D3+ D4
G1 = 1 + D + D3+ D4
Encoded outputs are transmitted as signed antipodal analog signals. They are received at
the decoder and quantized. The quantized number is represented in a 2's
compliment giving the range of -8 to 7. The process of quantizing a binary analog signal
with a multi-bit qunatizer is called soft decision. This soft decision is stored in the
array 'SOFT_DEC_INPUT'.

View File

@@ -0,0 +1,115 @@
ARCHITECTURE(ADSP-2191)
$OBJECTS = $COMMAND_LINE_OBJECTS;
// This memory map is set up to facilite testing of the tool
// chain -- code and data area are as large as possible.
MEMORY
{
seg_dmy { TYPE(PM RAM) START(0x000000) END(0x000003) WIDTH(24) }
seg_itab { TYPE(PM RAM) START(0x000004) END(0x00003f) WIDTH(24) }
seg_code { TYPE(PM RAM) START(0x000040) END(0x003fff) WIDTH(24) }
seg_buf2 { TYPE(DM RAM) START(0x008000) END(0x0088ff) WIDTH(16) }
seg_buf1 { TYPE(DM RAM) START(0x008900) END(0x0095ff) WIDTH(16) }
seg_data1 { TYPE(DM RAM) START(0x009600) END(0x00afff) WIDTH(16) }
seg_data2 { TYPE(PM RAM) START(0x004000) END(0x006bff) WIDTH(24) }
seg_heap { TYPE(DM RAM) START(0x00f200) END(0x00f9ff) WIDTH(16) }
seg_stack { TYPE(DM RAM) START(0x00fa00) END(0x00ffff) WIDTH(16) }
}
PROCESSOR p0
{
LINK_AGAINST( $COMMAND_LINE_LINK_AGAINST)
OUTPUT( $COMMAND_LINE_OUTPUT_FILE )
SECTIONS
{
sec_dmy
{
INPUT_SECTIONS( $OBJECTS(IVreset))
} > seg_dmy
sec_itab
{
INPUT_SECTIONS( $OBJECTS(IVpwrdwn))
. = .+0x1;
INPUT_SECTIONS( $OBJECTS(IVkernel))
. = .+0x1;
INPUT_SECTIONS( $OBJECTS(IVstackint))
. = .+0x1;
INPUT_SECTIONS( $OBJECTS(IVmailboxint))
. = .+0x1;
INPUT_SECTIONS( $OBJECTS(IVtimerint))
. = .+0x1;
INPUT_SECTIONS( $OBJECTS(IVringint))
. = .+0x1;
INPUT_SECTIONS( $OBJECTS(IVpcibmint))
. = .+0x1;
INPUT_SECTIONS( $OBJECTS(IVdspdspint))
. = .+0x1;
INPUT_SECTIONS( $OBJECTS(IVfifo0tmitint))
. = .+0x1;
INPUT_SECTIONS( $OBJECTS(IVfifo0rcveint))
. = .+0x1;
INPUT_SECTIONS( $OBJECTS(IVfifo1tmitint))
. = .+0x1;
INPUT_SECTIONS( $OBJECTS(IVfifo1rcveint))
. = .+0x1;
INPUT_SECTIONS( $OBJECTS(IVint13))
. = .+0x1;
INPUT_SECTIONS( $OBJECTS(IVint14))
. = .+0x1;
INPUT_SECTIONS( $OBJECTS(IVac97frint))
. = .+0x1;
} > seg_itab
seg_code
{
INPUT_SECTIONS( $OBJECTS(program) )
} >seg_code
sec_buf1
{
INPUT_SECTIONS($OBJECTS(seg_buf1) )
}>seg_buf1
sec_buf2
{
INPUT_SECTIONS($OBJECTS(seg_buf2) )
}>seg_buf2
sec_data1
{
INPUT_SECTIONS( $OBJECTS(data1) )
} >seg_data1
sec_data2
{
INPUT_SECTIONS( $OBJECTS(data2) )
INPUT_SECTIONS( $OBJECTS(program2) )
} >seg_data2
// support for initialization, including C++
sec_ctor
{
INPUT_SECTIONS( $OBJECTS(ctor))
} >seg_data1
// provide linker variables describing the stack (grows down)
// ldf_stack_limit is the lowest address in the stack
// ldf_stack_base is the highest address in the stack
sec_stack
{
ldf_stack_limit = .;
ldf_stack_base = . + MEMORY_SIZEOF(seg_stack) - 1;
} >seg_stack
sec_heap
{
.heap = .;
.heap_size = MEMORY_SIZEOF(seg_heap);
.heap_end = . + MEMORY_SIZEOF(seg_heap) - 1;
} >seg_heap
}
}

View File

@@ -0,0 +1,80 @@
****************************************************************************
Viterbi.asm Soft Decision GSM Viterbi Decoder
Analog Devices, Inc.
DSP Division
Three Technology Way
P.O. Box 9106
Norwood, MA 02062
21-JUNE-2001 BJM
This directory contains an example ADSP-2191 single-core subroutine
that implements a soft decision half-rate, soft-decision, GSM Viterbi decoder.
Files contained in this directory:
VITERBI.dpj VisualDSP project file
VITERBI.asm ADSP-2191 source for Viterbi
ADSP-2191.ldf Linker description file
GSM_REC.dat Soft decision data for Viterbi
_________________________________________________________________
CONTENTS
I. FUNCTION/ALGORITHM DESCRIPTION
II. IMPLEMENTATION DESCRIPTION
III. DESCRIPTION OF INPUT DATA
I. FUNCTION/ALGORITHM DESCRIPTION
The project Viterbi.dpj contains an implementation of a single-core
subroutine that implements a half-rate, soft-decision, GSM Vitertbi decoder.
II. IMPLEMENTATION DESCRIPTION
1. METRIC UPDATE:
-----------------
The metric update section accumulates branch distance metrics into path metrics.
The lowest path metric at the end of processing is considered to denote the
path most likely to contain the correct decoding of the input.
Each element of the state_trans[] array represents a state transition.
Each of the 16-bits in an element of state_trans[] represents one of the
16 possible new states, and indicates which of two possible states
is the most likely previous state.
2. TRACE BACK:
--------------
The traceback traces back through the state_trans[] array. Starting
with a new state, the bits of "state" are rotated to compute the
position of the bit in the current state_trans[] array element that
represents this new state. This bit indicates which state was previous.
We update the state to the previous state using this bit.
During any state transition, the most significant of the four bits in
"state" is the most recent input bit to the convolutional encoder.
This is the bit which is added to the output of the decoder.
III. DESCRIPTION OF INPUT DATA
1. INPUT SAMPLES:
-----------------
The Viterbi decoder routine expects input data which conforms to the following criteria:
The class 1 bits are encoded with the 1/2 rate convolutional code defined by
the polynomials:
G0 = 1 + D3+ D4
G1 = 1 + D + D3+ D4
Encoded outputs are transmitted as signed antipodal analog signals. They are received at
the decoder and quantized. The quantized number is represented in a 2's
compliment giving the range of -8 to 7. The process of quantizing a binary analog signal
with a multi-bit qunatizer is called soft decision. This soft decision is stored in the
array 'SOFT_DEC_INPUT'.

View File

@@ -0,0 +1,378 @@
4,
0,
-3,
-6,
1,
-4,
-5,
-4,
3,
-2,
2,
-6,
1,
-6,
1,
-6,
-1,
-4,
0,
-4,
4,
1,
-5,
6,
3,
3,
-1,
1,
0,
-5,
0,
-1,
-7,
0,
-5,
-3,
-2,
5,
-6,
2,
0,
-4,
2,
-1,
1,
5,
4,
5,
0,
1,
3,
0,
6,
6,
-5,
-3,
-1,
-1,
5,
2,
6,
3,
4,
0,
-6,
-6,
-1,
2,
2,
-1,
-4,
-1,
1,
2,
3,
2,
-5,
6,
6,
-4,
0,
-6,
-5,
-6,
6,
-5,
1,
-7,
-7,
-6,
6,
4,
4,
6,
-7,
6,
-4,
3,
2,
-2,
0,
-1,
-2,
0,
-6,
5,
0,
-4,
-2,
6,
0,
-4,
0,
3,
-2,
3,
-3,
-7,
-6,
0,
1,
-3,
0,
-1,
5,
4,
-5,
6,
2,
-3,
-7,
3,
2,
6,
5,
2,
0,
2,
6,
-3,
3,
2,
0,
2,
-7,
4,
6,
6,
-5,
-4,
0,
4,
1,
-7,
4,
6,
4,
6,
0,
-6,
0,
-4,
2,
4,
2,
0,
-2,
-1,
0,
5,
2,
0,
-2,
5,
2,
-6,
3,
-4,
5,
0,
6,
0,
0,
2,
6,
-7,
1,
5,
-4,
-2,
-2,
-5,
1,
6,
-5,
-7,
-4,
1,
0,
1,
-3,
5,
1,
6,
-7,
-6,
1,
-6,
3,
-5,
-7,
-3,
-2,
0,
6,
-5,
-4,
1,
-2,
6,
0,
1,
2,
3,
-4,
-6,
6,
4,
4,
3,
6,
5,
5,
0,
-7,
-7,
0,
5,
4,
-3,
-2,
-3,
6,
6,
-6,
-1,
-4,
-2,
-7,
2,
0,
4,
1,
-7,
2,
-7,
3,
1,
2,
5,
0,
-5,
-4,
-6,
-7,
4,
-3,
5,
-5,
5,
-2,
-5,
-4,
2,
2,
-5,
3,
-1,
-1,
3,
2,
-5,
5,
0,
6,
3,
-3,
-3,
3,
5,
-5,
-6,
6,
-6,
1,
6,
-7,
-4,
5,
6,
5,
-4,
6,
3,
-6,
-4,
3,
2,
3,
-3,
4,
0,
1,
0,
-7,
4,
1,
3,
-5,
-5,
-6,
-3,
5,
3,
-4,
-7,
6,
-2,
2,
3,
4,
3,
0,
4,
0,
2,
5,
4,
2,
-5,
3,
-4,
-6,
-6,
-2,
-2,
-3,
6,
-4,
-3,
-7,
4,
-1,
0,
-5,
-3,
2,
5,
4,
-5,
5,
5,
-7,
-5,
-7,
-2,
-1,
-4,
0,
2,
4,
-6,
-1,
-2,
4,
1,
-4,
-7

View File

@@ -0,0 +1,189 @@
/**************************************************************
File Name: Viterbi.asm
Date Modified: 6/23/01 BJM
Description:
ADSP-2192 single core subroutine that implements the
1/2 rate GSM soft decision Viterbi decoder.
Assumptions:
The class 1 bits are encoded with the 1/2 rate convolutional code defined by
the polynomials:
G0 = 1 + D3+ D4
G1 = 1 + D + D3+ D4
Encoded outputs are transmitted as signed antipodal analog signals. They are recieved at
the decoder and quantized. The quantized number is represented in a 2's
compliment giving the range of -8 to 7. The process of quantizing a binary analog signal
with a multi-bit qunatizer is called soft decision. This soft decision is represented by
the array 'SOFT_DEC_INPUT'
Registers Affected:
I0,I1,I2,I3,I4
M0,M1,M2,M3,M4,M5,M6,M7
L0,L1,L2,L3,L4
B1,B3,B4
AX0,AX1,AY0,AY1
AR,AF,SR,SI,SE
MX0
Cycle Count:
30751 Cycles
Memory Usage:
Instructions Words (24-bits):
107 instruction words
Data Words (16 or 24-bits):
2*N_out = Number of soft decisions (16-bit)
N_out = Number of state transitions (16-bit)
16 = Number of New and Old metrics (16-bit)
N_Words = Decoded output of GSM frame (16-bit)
8 = Metric Table (16-bit)
Notes:
**************************************************************/
#define N_out 189
#define N_words 12
#define N_mod_16 13
/* DM data */
.section/data data1;
.VAR soft_dec_input[2*N_out] = "gsm_rec.dat";
.VAR state_trans[N_out];
.VAR old_acc_metric[16];
.VAR new_acc_metric[16];
.VAR decoded_output[N_words+4];
.VAR met_table[8];
/* PM interrupt vector code */
.section/pm IVreset;
JUMP start; NOP; NOP; NOP; /* Interupt vector table */
/* Program memory code */
.section/pm program;
start:
I0 = soft_dec_input; /* Initialize soft_dec_input pointer */
L0 = 0; /* Initialize for modulo addressing */
I1 = old_acc_metric; /* Initialize old_acc_metric pointer */
L1 = length(old_acc_metric); /* Initialize old_acc_metric circular buffer */
AX0 = I1;
reg(B1) = AX0; /* Initialize pointer to old_acc_metric */
I2 = state_trans; /* Initialize state_trans pointer */
L2 = 0; /* Initialize for modulo addressing */
I3 = met_table; /* Initialize met_table pointer */
L3 = length(met_table); /* Initialize met_table circular buffer */
AX0 = I3;
reg(B3) = AX0; /* Initialize pointer to met_table */
I4 = new_acc_metric; /* Initialize new_acc_metric pointer */
L4 = length(new_acc_metric); /* Initialize new_acc_metric circular buffer */
AX0 = I4;
reg(B4) = AX0; /* Initialize pointer to new_acc_metric */
M0 = -8;
M1 = 1;
M2 = -16;
M3 = 0;
M4 = 8;
M5 = -7;
M6 = -8;
M7 = -1;
SE = 1; /* Setup bit shift */
SI = 0X8000;
SR0 = 0;
SR1 = 0;
CNTR = 16;
DO zero_metric UNTIL CE;
zero_metric: dm(I1,M1) = M3; /* Initialize accumulated metric array */
CNTR = N_out; /* FOR (k=0; k<N_out; k++) */
DO add_compare UNTIL CE;
AX0 = dm(I0,M1);
AY0 = dm(I0,M1);
AR = AX0 + AY0;
dm(I3,M1) = AR, AR = -AR;
dm(I3,M1) = AR, AR = -AR;
dm(I3,M1) = AR, AR = -AR;
dm(I3,M1) = AR, AR = AX0 - AY0;
dm(I3,M1) = AR, AR = -AR;
dm(I3,M1) = AR, AR = -AR;
dm(I3,M1) = AR, AR = -AR;
dm(I3,M1) = AR;
CNTR = 8; /* FOR (i=0; i<8; i++) */
DO calc_metric UNTIL CE;
AY0 = dm(I3,M1);
AX1 = dm(I1,M1);
AF = AX1 + AY0, AX0 = dm(I1,M1); /* AF = old_acc_metric[2*i] + Met_table */
AR = AX0 - AY0; /* AR = old_acc_metric[2*i+1] - Met_table */
SR = LSHIFT SR1 (HI); /* State_trans[k] = state_trans[k] << by 1 */
NONE = AR - AF;
IF GT SR = SR OR LSHIFT SI (LO); /* Then state_trans[k] = state_trans[k]<<1 | 1 */
IF LT AR = PASS AF;
dm(I4,M4) = AR, AF = AX1 - AY0; /* AF = old_acc_metric[2*i] - Met_table */
AR = AX0 + AY0; /* AR = old_acc_metric[2*i+1] + (-Met_table) */
SR = LSHIFT SR1 (HI); /* State_trans[k] = state_trans[k] << by 1 */
NONE = AR - AF;
IF GT SR = SR OR LSHIFT SI (LO); /* Then state_trans[k] = state_trans[k]<<1 | 1 */
IF LT AR = PASS AF;
calc_metric: dm(I4,M5) = AR; /* New_acc_metric[i+2] = AR */
modify(I4,M6); /* Reset I4 to new_acc_metirc */
AX1 = I1; /* AX1 = old_acc_metric */
I1 = I4; /* Old_acc_metric = new_acc_metric */
AX0 = I1;
reg(B1) = AX0; /* Initialize pointer to old_acc_metric */
I4 = AX1; /* New_acc_metric = AX1 */
reg(B4) = AX1; /* Initialize pointer to new_acc_metric */
add_compare: dm(I2,M1) = SR1; /* Store state_trans[k] */
M1 = -1;
I3 = decoded_output + N_words; /* Initialize decoded_output + N_words pointer */
L3 = 0; /* Initialize for modulo addressing */
AY0 = -15;
AY1 = 15;
MR0 = N_out - 1;
MR1 = 0;
SI = dm(I2,M1); /* Save previous state_trans */
AX0 = 0;
MX0 = N_mod_16; /* First word only has 13 valid bits */
CNTR = N_words;
DO trace_back UNTIL CE;
CNTR = MX0;
DO state_bits UNTIL CE;
SR = LSHIFT MR1 by 1(LO); /* SR0 = State << 1 */
AR = CLRBIT 4 OF SR0;
AX1 = AR;
AF = TSTBIT 4 OF SR0;
IF NE AR = SETBIT 0 OF AR;
AR = AR + AY0, SI = dm(I2,M1); /* Bit_Pos = 15 - rotate(State) */
SE = AR;
SR = LSHIFT SI (LO);
AR = TSTBIT 0 OF SR0;
AR = AR OR AX1; /* AR = state_trans[k] >> Bit_Pos */
MR2 = AR, AR = MR0 AND AY1;
SR = LSHIFT MR1 by - 3(LO);
SE = AR;
AR = TSTBIT 0 OF SR0;
SI = AR;
SR = LSHIFT SI (LO);
AR = AX0 OR SR0;
AX0 = AR;
AR = MR0 -1; /* Decoded_output |= ((State & 8) >> 3) << (k & 15) */
MR0 = AR;
state_bits:
MR1 = MR2; /* State = new_acc_metric */
MX0 = 16;
dm(I3,M1) = AX0;
trace_back:
AX0 = 0;
looping: JUMP looping; /* Loop upon itself */