Add real ADSP-2191 assembly examples + open21xx assembler test
This commit is contained in:
189
examples/adsp-2191_viterbi_decoder/VITERBI.asm
Normal file
189
examples/adsp-2191_viterbi_decoder/VITERBI.asm
Normal 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 */
|
||||
|
||||
|
||||
Reference in New Issue
Block a user