⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wlan_dec.asm

📁 卷积码和viterbi译码的TI C54代码
💻 ASM
字号:
;****************************************************************
; Filename:    wlan_dec.asm
; Function:    viterbi decoder
; Version:     1.00
; Processor:   C54xx
; Author:      LiuKai		vikingpro@163.com
; Description: Implements the 802.11 convolutional decoder
;              C-callable
;
; Useage:      wlan_viterbi_dec(ushort frame_sz,
;                             	int *m,
;                             	int *sd,
;                             	int *trans
;                             	int *output)
;
;  Viterbi decoder for 802.11
;
;  Frame processing--starts traceback at state 0, assuming 6 tail bits
;  have been added.
;
;
;****************************************************************

	.mmregs

; Far-mode adjustment
; -------------------

         .if __far_mode
OFFSET   .set  2
         .else
OFFSET   .set  1
         .endif


FRAME_SZ       .set 2

REG_SAVE_SZ    .set 2

PARAM_OFFSET   .set FRAME_SZ + REG_SAVE_SZ + OFFSET       
      
      .asg    0 + REG_SAVE_SZ + FRAME_SZ, RETURN_ADDR ; 
      .asg    0 + PARAM_OFFSET, metric_sz
      .asg    1 + PARAM_OFFSET, old_m
      .asg    2 + PARAM_OFFSET, sd
      .asg    3 + PARAM_OFFSET, trans    
      .asg    4 + PARAM_OFFSET, output
      .asg    5 + PARAM_OFFSET, m
      .asg    6 + PARAM_OFFSET, new_m
      
; Local variables
; --------------      
       
       .asg    0, DIFF
       .asg    0, ONE
       .asg    1, SUM

; Register usage
; --------------
	.asg    AR0, temp
	.asg	AR1, trans_ptr
	.asg	AR2, sd_ptr
	.asg	AR3, m_ptr
	.asg	AR4, newm_ptr
	.asg	AR5, oldm_ptr
	.asg	AR6, out_ptr

	.asg	BRC, rptb_cnt

;**************************************************************************
	.global _wlan_viterbi_dec
_wlan_viterbi_dec


; Preserve registers
; ------------------
	pshm	ar1
	pshm	ar6

;                                    
; And establish local frame                               
; Set sign extension mode                                 
; Set FRCT bit:                                           
;----------------------------------------------------------------


	FRAME	#-(FRAME_SZ)	    ; 1 cycle

        SSBX    SXM                 ; sign extension on
        SSBX    C16                 ; accumulators in dual 16 bit mode


;
; Copy arguments to their local locations as necessary        
;----------------------------------------------------------------

   	  LD *sp(old_m), B
   	  ADD *sp(metric_sz), -1, B
   	  STL B, *sp(new_m)
   	  ADD *sp(metric_sz),-2, B
   	  STL B, *sp(m)
   
   
      MVDK   *sp(trans), trans_ptr               ; 2 cycles
      MVDK   *sp(sd), sd_ptr                     ; 2 cycles
      MVDK   *sp(m), m_ptr                       ; 2 cycles
      MVDK   *sp(new_m), newm_ptr                ; 2 cycles
      MVDK   *sp(old_m), oldm_ptr                ; 2 cycles
      MVDK   *sp(output), out_ptr                ; 2 cycles

    
;
; Set loop count by subtracting 1 from frame_sz and      
; storing into block repeat count register                   
;----------------------------------------------------------------

        SUB     #1, A                            ; 2 cycles
        STLM    A, rptb_cnt                      ; 1 cycle
        STLM    A, temp

BFLY_DIR .macro  
         DADST   *oldm_ptr, A             ; A = Old_Met(2*j)+T // Old_met(2*j+1)-T
         DSADT   *oldm_ptr+%, B           ; B = Old_Met(2*j)-T // Old_met(2*j+1)+T
         CMPS    A,*newm_ptr+%            ; New_Met(j) = MAX(Old_Met(2*j)+T,Old_Met(2*j+1)-T)
                                     	  ; TRN = TRN << 1
                                     	  ; If (Old_Met(2*j)+T =< Old_Met(2*j+1)-T) Then TRN[0]=1
         CMPS    B,*m_ptr+%            	  ; New_Met(j+8) = MAX(Old_Met(2*j)-T,Old_Met(2*j+1)+T)
                                     	  ; TRN = TRN << 1
                                     	  ; If (Old_Met(2*j)-T =< Old_Met(2*j+1)+T) Then TRN[0]=1
         .endm

BFLY_REV .macro
         DSADT   *oldm_ptr, A             ; A = Old_Met(2*j)-T // Old_met(2*j+1)+T
         DADST   *oldm_ptr+%, B           ; B = Old_Met(2*j)+T // Old_met(2*j+1)-T
         CMPS    A,*newm_ptr+%            ; New_Met(j) = MAX(Old_Met(2*j)-T,Old_Met(2*j+1)+T)
                                     	  ; TRN = TRN << 1
                                     	  ; If (Old_Met(2*j)-T =< Old_Met(2*j+1)+T) Then TRN[0]=1
         CMPS    B,*m_ptr+%            	  ; New_Met(j+8) = MAX(Old_Met(2*j)+T,Old_Met(2*j+1)-T)
                                     	  ; TRN = TRN << 1
                                     	  ; If (Old_Met(2*j)+T =< Old_Met(2*j+1)-T) Then TRN[0]=1
         .endm
;***************************************************************************
VITERBI_DECODER

        STM     #128,BK              ; the circular buffer size is 2*status = 2*64
        NOP
        ST      #0100, *oldm_ptr+%       ; give state zero an initial bias, 0100 is octal
        NOP
        NOP
        LD      #0000h, A           ; all other states are set to zero
        RPT     #127-1               
        STL    A, *oldm_ptr+%

        RPTB    DECODE_END-1        ; do i=0,188
         LD		*AR2+,16,A
         SUB	*AR2,16,A,B
         STH	B,*sp(DIFF)
         ADD	*AR2+,16,A,B
         STH	B,*sp(SUM)
         
         ; 0~3, 32~35
         LD     *sp(SUM), T         ;  new_metric(0)&(32)
         BFLY_DIR                   ;  new(0)  = MAX[ old(0)+sum, old(1)-sum ]
         			    ;  new(32) = MAX[ old(0)-sum, old(1)+sum ]                    
         			    		         			              			    
         LD     *sp(DIFF), T	    ;	new_metric(1)&(33)
         BFLY_REV                   ;   new(1)  = MAX[ old(2)-diff, old(3)+diff ]
         			    ;   new(33) = MAX[ old(2)+diff, old(3)-diff ]         			    
         			     
         LD     *sp(SUM), T         ;  new_metric(2)&(34)
         BFLY_DIR		    ;  new(2)  = MAX[ old(4)+sum, old(5)-sum ]
         			    ;  new(34) = MAX[ old(4)-sum, old(5)+sum ]
         			    
         LD     *sp(DIFF), T	    ;  new_metric(3)&(35)
         BFLY_REV                   ;  new(3)  = MAX[ old(6)-diff, old(7)+diff ]
         			    ;  new(35) = MAX[ old(6)+diff, old(7)-diff ]
         			    	    
         ; 4~7, 36~39 
	 LD     *sp(SUM), T	    ;  new_metric(4)&(36)
         BFLY_REV                   ;  new(4)  = MAX[ old(8)-sum, old(9)+sum ]
         			    ;  new(36) = MAX[ old(8)+sum, old(9)-sum ]
         			    
         			    
         LD     *sp(DIFF), T	    ;  new_metric(5)&(37)
         BFLY_DIR                   ;  new(5)  = MAX[ old(10)+diff, old(11)-diff ]
         			    ;  new(37) = MAX[ old(10)-diff, old(11)+diff ]
         			    	
         			    		    
         LD     *sp(SUM), T	    ;  new_metric(6)&(38)
         BFLY_REV                   ;  new(6)  = MAX[ old(12)-sum, old(13)+sum ]
         			    ;  new(38) = MAX[ old(12)+sum, old(13)-sum ]
         			    
         			    
         LD     *sp(DIFF), T	    ;  new_metric(7)&(39)
         BFLY_DIR                   ;  new(7)  = MAX[ old(14)+diff, old(15)-diff ]
         			    ;  new(39) = MAX[ old(14)-diff, old(15)+diff ]
         			    			    
         ST    TRN, *AR1+           ;  store the transition register
         ;=========================================================

         ; 8~11, 40~43
         LD     *sp(SUM), T	    ;  new_metric(8)&(40)
         BFLY_REV                   ;  
         			             			    
         LD     *sp(DIFF), T	    ;  new_metric(9)&(41)
         BFLY_DIR                   ;           			    	
         			    		    
         LD     *sp(SUM), T	    ;  new_metric(10)&(42)
         BFLY_REV                   ;           			    
         			    
         LD     *sp(DIFF), T	    ;  new_metric(11)&(43)
         BFLY_DIR                   ;  old(22), old(23)
                  
         ; 12~15, 44~47
         LD     *sp(SUM), T         ;  new_metric(12)&(44)
         BFLY_DIR                   ;        			     
         			    
         LD     *sp(DIFF), T	    ;  new_metric(13)&(45)
         BFLY_REV                   ;            			    
         			     
         LD     *sp(SUM), T         ;  new_metric(14)&(46)
         BFLY_DIR		    ; 
         			    
         LD     *sp(DIFF), T	    ;  new_metric(15)&(47)
         BFLY_REV                   ;  old(30), old(31
         
         ST    TRN, *AR1+           ;  store the transition register
         ;==========================================================

         ; 16~19, 48~51
         LD     *sp(DIFF), T	    ;  new_metric(16)&(48)
         BFLY_DIR                   ;  old(32), old(33) 
         
         LD     *sp(SUM), T	    	;  new_metric(17)&(49)
         BFLY_REV                   ;
         
         LD     *sp(DIFF), T	    ;  new_metric(18)&(50)
         BFLY_DIR                   ;  
         
         LD     *sp(SUM), T	    ;  new_metric(19)&(51)
         BFLY_REV		    ;
                  
         ; 20~23, 52~55
         LD     *sp(DIFF), T	    ;  new_metric(20)&(52)
         BFLY_REV                   ;  old(40), old(41)
         
         LD     *sp(SUM), T	    ;  new_metric(21)&(53)
         BFLY_DIR                   ; 
         
         LD     *sp(DIFF), T	    ;  new_metric(22)&(54)
         BFLY_REV                   ;  
         
         LD     *sp(SUM), T	    ;  new_metric(23)&(55)
         BFLY_DIR                   ; 
         
         ST    TRN, *AR1+           ;  store the transition register
         ;==========================================================

         ; 24~27, 56~59
         LD     *sp(DIFF), T	    ;  new_metric(24)&(56)
         BFLY_REV                   ;  old(48), old(49)
         
         LD     *sp(SUM), T	    	;  new_metric(25)&(57)
         BFLY_DIR                   ; 
         
         LD     *sp(DIFF), T	    ;  new_metric(26)&(58)
         BFLY_REV                   ;  
         
         LD     *sp(SUM), T	    ;  new_metric(27)&(59)
         BFLY_DIR
         
         ; 28~31, 60~63
         LD     *sp(DIFF), T	    ;  new_metric(28)&(60)
         BFLY_DIR                   ;  old(56), old(57)
         
         LD     *sp(SUM), T	    	;  new_metric(29)&(61)
         BFLY_REV                   ;
         
         LD     *sp(DIFF), T	    ;  new_metric(30)&(62)
         BFLY_DIR                   ;  
         
         LD     *sp(SUM), T	    	;  new_metric(31)&(63)
         BFLY_REV
         
         MAR   *+m_ptr(32)%         ;  advance pointer by 32
         MAR   *+newm_ptr(32)%      ;  advance pointer by 32
         ST    TRN, *AR1+           ;  store the transition register

DECODE_END                          ; end do (i loop)

;**************************************************************************
;  Trace back routine
;**************************************************************************
;  A accumulator = STATE value
;  B accumulator = temp storage
;  ONE = 1
;  AR1 = number of output words to compute
;  AR2 = pointer to STATE_TRANS array
;  m_ptr = pointer to end of output array
;  K = constraint length, K = 7 in 802.11 
;  MASK = 2^(K-5) - 1 = 3 = 011( binary)
;**************************************************************************
TRACE_BACK_INIT
        ST      #1, *sp(ONE)
        LDM     temp, B
        SUB		#6,B			; K-1 = 6
        SFTL	B,-4,A
        STLM	A,AR1			; init i counter (# output words)
        SFTL    A,4
        SUB		A,B
        STLM	B,BRC			; init bit counter (only 9 bits for 1st loop
        
        LDM     temp, B
        ADD		#1,	B
        SFTL    B,2,A			; A = B * 2
        ADD     *sp(trans), A		; address of end of transition table
        STLM    A, AR2                  ; AR2 =  #STATE_TRANS+ bits*4 -1 
        LD      #0,A                    ; init STATE to zero (final state=0 due to tail bits)
		
TRACE_BACK                              ; Do i=1,0
        RPTB    TBACK_END-1             ;   Do j=15,0
                                        ;      Calculate bit position in transition word
         SFTL   A,-5,B                  ;       B = STATE>>(K-2) , K=7
         AND    *sp(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)
         								;       address of end of transition table
         SFTL 	A,-3,B 	 				;		B = A/8 = State/8
	 AND 	#3,B 					; 	B = B&MASK = (K-5)lsb’s of State/8
	 STLM 	B,AR0 					; 	AR0 = index for transition word
	 MAR 	*+AR2(-4) 				; 	reset pointer to start of table, 2^(K-5) = 4
	 MAR 	*AR2+0 					; 	add offset to point to correct transition word
	 BITT 	*AR2-0 					; 	Test bit in transition word, reset to table star
	 	
         ROLTC  A                       ;      Rotate decision into STATE
TBACK_END                               ;   enddo (j loop) 
        STL     A,*out_ptr+             ;   store packed output
        BANZD   TRACE_BACK,*AR1-        ;   repeat j loop if frame not finished
        STM     #15,BRC                 ;   init bit counter for next word
                                        ; enddo (i loop)

_end:
;      
; Restore stack to previous value, FRAME, etc..            
;----------------------------------------------------------------

RETURN:
 

 
	FRAME  #(FRAME_SZ)				  ; 1 cycle
      	popm	ar6
	popm	ar1

        .if __far_mode
           FRETD                                          ; 4 cycles
        .else
	   RETD                                           ; 3.0 cycles
        .endif
        RSBX     FRCT                                     ; delay slot 1 cycle
	  NOP

;END


;end of file. please do not remove. it is left here to ensure that no lines of code are removed by any editor

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -