www.pudn.com > viterbi_wlan_c54.rar > wlan_dec.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