📄 gsm.asm
字号:
;************************************************************************
Convolutional Encoder and Viterbi decoder for GSM
;************************************************************************
.mmregs
.def INPUT_DATA, ENCODED_DATA, STATE, TEMP
.def METRICS, OUTPUT_DATA, STATE_TRANS, SUM, DIFF
METRICS .usect "metrics", 32 ; old and new metrics in one block
; must be placed on a 64 word boundry
.bss STATE,6 ; direct addressing, make variables
TEMP .set STATE+1 ; are on one page
SUM .set STATE+2 ; SUM and DIFF must be defined in
DIFF .set STATE+3 ; in this order: SUM then DIFF
ONE .set STATE+4 ; used in decoder for mask
DATA .set STATE+5 ; used in the encoder
.bss STATE_TRANS, 189 ; the array of state transitions
; stored from the TRN register
; during the Viterbi decoding
.bss ENCODED_DATA, 189*2 ; 189*2 conv. encoded bits in
; in signed antipodal format
.bss OUTPUT_DATA, 12 ; the output packed data
.data
INPUT_DATA ; 12 words of packed input, 189 bits
.word 00167h
.word 0C0EFh
.word 03456h
.word 0FADEh
.word 0ACDCh
.word 02345h
.word 0BABEh
.word 0789Ah
.word 0FADEh
.word 0C0DEh
.word 0DEC1h
.word 02345h
.sect "vectors" ; set up a reset vector
B begin
begin .text
STM #1400h, SP ; there is no RAM at 1400 but ok since
; SP is auto dec. at each push
LD #STATE, DP
ST #01, ONE ; mask used during decoder trace
;**************************************************************************
; Convolutional encoder for GSM
; 1/2 rate constraint length 5
;**************************************************************************
; Equations for encoder
; G0 = input + delay3 + delay4 (modulo two)
; G1 = input + delay1 + delay3 + delay4 (modulo two)
;
; Note: for this example code, the output is in signed antipodal values.
; ex: if G0 = 0 then the signed antipodal value is 7.
; G0 = 1 then the signed antipodal value is -7.
; AR1=Current packed input word pointer
; AR2=
; AR3=# of words to process
; AR4=conv. encoded output array pointer
; AR5=points to TEMP
; AR6=one half word to process loop counter
; AR7=
CONVOLUTIONAL_ENCODER
STM #INPUT_DATA+11, AR1 ; Sets up input word pointer
STM #11-1, AR3 ; # of full words to process in first loop
STM #ENCODED_DATA, AR4 ; encoded output data
STM #TEMP, AR5 ; pointer to temp
STM #1, AR6 ; one half word to process loop counter
RSBX SXM ; sign extention is off
SSBX C16 ; put the accumulators into 16 bit add mode
STM #16-1, BRC ; # of bits in a word
conv_loop:
LD *AR1, A
STL A, DATA ; make a copy of the input
RPTB inner_loop_end-1 ;
LD DATA, A ; load the current data word
ROR A ; put the LSB into C bit
STL A, DATA ; Store shifted data word
LD STATE, A ; load the current conv encoder state
XC 2, C ; if Carry is set then set state LSB
OR #0010000b, A ; the input was a one so set the bit
STL A, -1, STATE ; store the new state delayed by one
STLM A, BH ; put state in high B acc
AND #01Bh, A ; AND G1 mask with A
AND #013h,16,B ; AND G0 mask with high part of B
ADD B,A ; A has G0 in upper and G1 in lower
LD #0, B ; zero out B
ADD A,0,B ; accumulate bit 0
ADD A,-1,B ; accumulate bit 1
ADD A,-2,B ; accumulate bit 2
ADD A,-3,B ; accumulate bit 3
ADD A,-4,B ; accumulate bit 4
STH B,*AR5 ; store G0 bits
BIT *AR5, 15-0 ; test G0
STL B,*AR5 ; store G1 bits
LD #7h, A ; load for a zero G0 bit
XC 2,TC
LD #-7, A ; if G0 is a one, LD -8, we are using
; signed antipodal values here
BIT *AR5, 15-0 ; test G1
STL A, *AR4+ ; store G0 signed antipodal value to the output
LD #7h, A ; load for a zero G1 bit
XC 2,TC
LD #-7, A ; if G1 is a one, LD -8, we are using
; signed antipodal values here
STL A, *AR4+ ; store G1 signed antipodal value to the output
inner_loop_end
MAR *AR1- ; point to the next word to process
BANZD conv_loop,*AR3- ;
STM #16-1, BRC ; # of bits in a word
; process 16 bits in each word for the first
; 12 words, 176 bits
; BANZ takes effect here
MAR *AR3+ ; make AR3 = 0, through the above loop
BANZD conv_loop,*AR6- ; process one half word
; AR1 already points to the next word to process
STM #13-1, BRC ; # of bits in the last word to process in the
; 12th word = 13 bits
; BANZ takes effect here
***************************************************************************
* Viterbi decoder for GSM
***************************************************************************
;
; AR0=bits to process loop counter
; AR1=points to state transition array
; AR2=points to conv coded array (input to the decoder)
; AR3=points to new metrics + 8 array
; AR4=points to new metrics array
; AR5=points old metrics array
; AR6=points to output array
; AR7=point to SUM and DIFFERENCE
VITERBI_DECODER
SSBX OVM ; overflow mode off
STM #32, BK ; the circular buffer size is 32
STM #189-1, AR0 ; bits to process loop counter
STM #STATE_TRANS, AR1 ;
STM #ENCODED_DATA, AR2 ;
STM #METRICS+16+8, AR3 ; new metrics + 8
STM #METRICS+16, AR4 ; new metrics array
STM #METRICS, AR5 ; old metrics
STM #OUTPUT_DATA, AR6 ; packed output data
STM #SUM, AR7 ; points to SUM and DIFF
ST #0100, *AR5+% ; give state zero an initial bias
LD #0000h, A ; all other states are set to zero
RPT #31-1 ;
STL A, *AR5+%
BUTTERFLY_LOOP
; in this section we will perform the
; 189 * 8 viterbi butterflys for GSM
; decoder
; update the local distance
LD *AR2+, A ; A = SD(2*i)
SUB *AR2, A, B ; B = SD(2*i)-SD(2*i+1)
STL B, DIFF ; store to DIFF
ADD *AR2+, A, B ; B = SD(2*i)+SD(2*i+1)
STL B, SUM ; store the SUM
; process first 4 butterflys using SUM
STM #2-1, BRC ; 4 butterflys
RPTBD SUM_BFLY_END-1
LD *AR7+, T ; load SUM to the T reg
; AR7 points to DIFF for next time
NOP ; fill the rest of the delay slot
; forward butterfly
DADST *AR5, A ; A = Old_Met(2*j)+T // Old_met(2*j+1)-T
DSADT *AR5+%, B ; B = Old_Met(2*j)-T // Old_met(2*j+1)+T
CMPS A,*AR4+% ; New_Met(j) = MAX(Old_Met(2*j)+T,
; Old_Met(2*j+1)-T)
; TRN = TRN << 1
CMPS B,*AR3+% ; New_Met(j+8) = MAX(Old_Met(2*j)-T,
; Old_Met(2*j+1)+T)
; TRN = TRN << 1
; reverse butterfly
DSADT *AR5, A ; A = Old_Met(2*j)-T // Old_met(2*j+1)+T
DADST *AR5+%, B ; B = Old_Met(2*j)+T // Old_met(2*j+1)-T
CMPS A,*AR4+% ; New_Met(j) = MAX(Old_Met(2*j)+T,
; Old_Met(2*j+1)-T)
; TRN = TRN << 1
CMPS B,*AR3+% ; New_Met(j+8) = MAX(Old_Met(2*j)-T,
; Old_Met(2*j+1)+T)
; TRN = TRN << 1
SUM_BFLY_END
; process last 4 butterflys using DIFF
STM #2-1, BRC ; 4 butterflys
RPTBD DIFF_BFLY_END-1
LD *AR7-, T ; load DIFF to the T reg
; AR7 points to SUM for next time
NOP ; fill the rest of the delay slot
; forward butterfly
DADST *AR5, A ; A = Old_Met(2*j)+T // Old_met(2*j+1)-T
DSADT *AR5+%, B ; B = Old_Met(2*j)-T // Old_met(2*j+1)+T
CMPS A,*AR4+% ; New_Met(j) = MAX(Old_Met(2*j)+T,
; Old_Met(2*j+1)-T)
; TRN = TRN << 1
CMPS B,*AR3+% ; New_Met(j+8) = MAX(Old_Met(2*j)-T,
; Old_Met(2*j+1)+T)
; TRN = TRN << 1
; reverse butterfly
DSADT *AR5, A ; A = Old_Met(2*j)-T // Old_met(2*j+1)+T
DADST *AR5+%, B ; B = Old_Met(2*j)+T // Old_met(2*j+1)-T
CMPS A,*AR4+% ; New_Met(j) = MAX(Old_Met(2*j)+T,
; Old_Met(2*j+1)-T)
; TRN = TRN << 1
CMPS B,*AR3+% ; New_Met(j+8) = MAX(Old_Met(2*j)-T,
; Old_Met(2*j+1)+T)
; TRN = TRN << 1
DIFF_BFLY_END
MAR *+AR3(8)% ; advance pointer by 8
ST TRN, *AR1+ ; store the transition register
BANZD BUTTERFLY_LOOP, *AR0- ; keep processing bits
MAR *+AR4(8)% ; advance pointer by 8
; BANZ takes place here
***************************************************************************
* Trace back routine
***************************************************************************
; A accumulator = STATE value
; B accumulator = temp storage
;
; AR0=
; AR1=number of output words to compute
; AR2=pointer to STATE_TRANS array
; AR3=pointer to end of output array
; AR4=
; AR5=
; AR6=
; AR7=
TRACE_BACK_INIT
RSBX OVM ; overflow mode off
STM #STATE_TRANS+189-1,AR2 ; address of end of transition table
STM #12-1,AR1 ; number of output words to compute
STM #OUTPUT_DATA,AR3 ; address pointer for output_data f buffer)
LD #0,A ; final state is zero because of 4 tail bits example)
; init A to zero
STM #9-1,BRC ; process only 9 bits for the first loop
; this will allign the output array
TRACE_BACK
; do i=0,188
RPTB TRACE_BACK16_END-1; do j=0,15
; Calculate bit position in transition word
SFTL A,-(5-2),B ; B = A>>(K-2)
AND @ONE,B ; B = B&1 = msb of STATE
ADD A,1,B ; B = B+A<<1 = 2*STATE + msb of STATE
STLM B,T ; T = B (bit position)
; Calculate correct transition word
NOP ; one cycle of latency between STLM and BITT
BITT *AR2- ; Test bit in transition word art
; move pointer to next transition word
ROLTC A ; Rotate decision in A, create new state
; enddo (j loop)
TRACE_BACK16_END
STL A,*AR3+ ; Store packed output
BANZD TRACE_BACK,*AR1- ; repeat j loop if frame not finished
STM #15,BRC ; Init block repeat counter for next word
; enddo (i loop)
VITERBI_DECODE_END
DONE B DONE
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -