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

📄 viterbi_asm_decoder.asm

📁 非常简洁的Viterbi译码汇编程序
💻 ASM
📖 第 1 页 / 共 2 页
字号:
 || [Xt] ADD Xs,Xq,Xs      
 || [Xt] ADD Ix,3,Ix     ; 增加索引
 || CMPGT Yi,Ys,Yt       
 || [Yt] ADD Ys,Yq,Ys       
 || [Yt] ADD Iy,Nx,Iy       
 .endloop         
 
 ADD Ix,Iy,Id0      ; 计算区域
 || ADD Ix,Iy,Id1        
 || ADDAH MCurr0,8,MCurr0   ; 指向路径状态
 || ADDAH TT,10,MCurr1    ; 指向B组寄存器
 
 LDW *MCurr0[Id0],T0    ; 取X0, Y0 
 || LDW *MCurr1[Id1],T1    ; 取X1, Y1 
 || ADD Id0,2,Id0       
 
 LDW *MCurr0[Id0],T2    ; 取状态0和1 
 
 SHL Xi,16,XY      ; 连接Xi Yi到XY 
 || CLR Yi,16,31,TT       
 || LDH *+MNext0[2],Ys    ; 为下一个循环准备
 
 OR XY,TT,XY      ; 连接Xi Yi到XY
 || LDH *+MNext0[3],Xs    ; 为下一个循环准备  

 LDH *+MNext0[4],Yq    ; 为下一个循环准备  
 
 SUB2 T0,XY,T0     ; 计算X Y对 X0 Y0的微分 
 || SUB2 T1,XY,T1     ; 计算X Y 对X1 Y1的微分
 || LDH *+MNext0[5],Xq    ; 为下一个循环准备  

 MPY T0,T0,P2      ; 计算(Yi - Y0) ^ 2. 
 || MPY T1,T1,P3     ; 计算(Yi - Y1) ^ 2. 
 || LDH *+MNext0[6],Ny    ; 为下一个循环准备  
 || [Cc] SUB Cc,1,Cc     ; 循环计数器减 
 
 MPYH T0,T0,P0     ; 计算(Xi - X0) ^ 2. 
 || MPYH T1,T1,P1     ; 计算Get (Yi - Y0) ^ 2. 
 || LDH *+MNext0[7],Nx    ; 为下一个循环准备  
 || [Cc] B Cloop      ; 下一个循环
 
 NOP       ; 延迟
 
 ADD P0,P2,T0      ; 计算距离X0 Y0的平方
 || ADD P1,P3,T1     ; 计算距离X1 Y1的平方
 || MV T2,T3      ; 状态0和1 

 CMPGT T0,T1,TT     ; 计算最大距离
 || EXTU T3,16,16,S0     ; 分开状态0和1
 || EXTU T2,0,16,S1       
 
 [TT] MV T1,T0      ; 距离X0 Y0为大值
 || [TT] MV S1,S0     ; 使用距离X1 Y1
 
 STW T0,*DistP++     ; 保存结果
 || STH S0,*StateP++       
 || MV MNext0,MCurr0    ; 为下一个循环准备  
 || ZERO Ix      ; 寄存器索引
 || ZERO Iy      
        ; Viterbi译码第三步
        ; 寻找最短距离,存储到Dist0和Dist1
        ; 计算延迟状态并存储
        ; 输入为距离和状态
        ; 输出为Dist0,Dist1,DS0~DS7和延迟路径
        
TMB0  .set A0      ; 表指针
TMB1  .set B0       ; 表指针
T200A  .set A2       ; 保存16进制200 
T200B  .set B2      ; 保存16进制200 
DistP0  .set A4       ; 距离指针
DistP1  .set B4       ; 距离指针
Ix0   .set A5       ; 索引 
Ix1   .set B5       ; 索引
DSP0  .set A6       ; 延迟状态指针 
DSP1  .set B6      ; 延迟状态指针
Stp0   .set A8       ; 状态指针0
Stp1  .set B8       ; 状态指针1 
St0   .set A9       ; 状态0 
St1   .set B9       ; 状态1 
LU0  .set A10       ; 查找表行 0 
LU1  .set B10       ; 查找表行1 
LU2  .set A11       ; 查找表行2 
LU3  .set B11       ; 查找表行3 

Step3: 
 MVK Distance,DistP0    ; 指向距离0到 3 
 || MVK Distance,DistP1    ; 指向距离4 到7 
 
 MVKH Distance,DistP0     
 || MVKH Distance,DistP1    
 
 LDW *+DistP0[0],Dist0    ; 计算距离0 
 || LDW *+DistP1[4],Dist1    ; 计算距离4 
 || MVK TMBack,TMB0    ; 获得表指针 
 || MVK TMBack,TMB1    ; 获得表指针
 
 LDW *+DistP0[1],Q0    ; 计算距离1 
 || LDW *+DistP1[5],Q1    ; 计算距离5 
 || MVKH TMBack,TMB0    
 || MVKH TMBack,TMB1    
 
 LDW *+TMB0[0],LU0    ; 读查找表 
 || LDW *+TMB1[1],LU1    ; 读查找表
 || MVK State,Stp0     ; 计算状态指针 
 || MVK State,Stp1     ; 计算状态指针

 LDW *+DistP0[2],Q0    ; 计算距离2 
 || LDW *+DistP1[6],Q1   ; 计算距离6 
 || MVKH State,Stp0    ; 计算状态指针
 || MVKH State,Stp1    ; 计算状态指针

 LDW *+TMB0[2],LU2    ; 读查找表
 || LDW *+TMB1[3],LU3    ; 读查找表
 
 MVK 0x200,T200A     
 || MVK 0x200,T200B    
 || LDW *+DistP0[3],Q0    ; 计算距离3 
 || LDW *+DistP1[7],Q1    ; 计算距离7 
 
 CMPGT Dist0,Q0,TT0    ; 如果距离1 < lowest 
 || MVK 0x39C,Ix0     ; 提取位0~3
 || CMPGT Dist1,Q1,TT1    ; 如果距离5 < lowest 
 || MVK 0x39C,Ix1     ; 提取位0~3
 || LDH *Stp0[0],St0    
 || LDH *Stp1[4],St1    
 
 [TT0] MV Q0,Dist0     ; 保持最短距离
 || [TT0] MVK 0x31C,Ix0    ; 提取位4~7 
 || [TT0] LDH *Stp0[1],St0    
 || [TT1] MV Q1,Dist1     ; 保持最短距离
 || [TT1] MVK 0x31C,Ix1    ; 提取位4~7
 || [TT1] LDH *Stp1[5],St1   
 
 CMPGT Dist0,Q0,TT0    ; 如果距离2 < lowest 
 || CMPGT Dist1,Q1,TT1    ; 如果距离6 < lowest 
 
 [TT0] MV Q0,Dist0     ; 保持最短距离
 || [TT0] MVK 0x29C,Ix0    ; 提取位8~11
 || [TT0] LDH *Stp0[2],St0    
 || [TT1] MV Q1,Dist1     ; 保持最短距离
 || [TT1] MVK 0x29C,Ix1    ; 提取位8~11
 || [TT1] LDH *Stp1[6],St1    
 
 CMPGT Dist0,Q0,TT0    ; 如果距离3 < lowest 
 || CMPGT Dist1,Q1,TT1    ; 如果距离7 < lowest 
 || MV DStCurr,DSP0     ; 初始化指针到A side 
 || MV DStCurr,DSP1     ; 初始化指针到B side
 
 [TT0] MV Q0,Dist0     ; 保持最短距离
 || [TT0] MVK 0x21C,Ix0    ; 提取位12~15
 || [TT0] LDH *Stp0[3],St0    
 || [TT1] MV Q1,Dist1     ; 保持最短距离
 || [TT1] MVK 0x21C,Ix1    ; 提取位12~15
 || [TT1] LDH *Stp1[7],St1    
 
 EXTU LU0,Ix0,DS0     ; 不提取
 || EXTU LU1,Ix1,DS1    ; 不提取

 EXTU LU2,Ix0,DS2      
 || EXTU LU3,Ix1,DS3    
 || SUB Ix0,T200A,Ix0    ; 提取位16以上位
 || SUB Ix1,T200B,Ix1     ; 提取位16以上位
 || STH DS0,*+DSP0[0]    ; 保存延迟状态0 
 || STH DS1,*+DSP1[1]    ; 保存延迟状态1 
 
 EXTU LU0,Ix0,DS4     
 || EXTU LU1,Ix1,DS5    
 || STH DS2,*+DSP0[2]    ; 保存延迟状态2 
 || STH DS3,*+DSP1[3]    ; 保存延迟状态3 
 
 EXTU LU2,Ix0,DS6     
 || EXTU LU3,Ix1,DS7    
 || STH DS4,*+DSP0[4]    ; 保存延迟状态4 
 || STH DS5,*+DSP1[5]    ; 保存延迟状态5 

 STH DS6,*+DSP0[6]     ; 保存延迟状态6 
 || STH DS7,*+DSP1[7]    ; 保存延迟状态7 
 || MVK AccDist,AccP0    
 || MVK AccDist,AccP1    

 STH St0,*+DSP0[8]     ; 保存路径状态索引
 || STH St1,*+DSP1[9]    ; 保存路径状态索引
 || MVKH AccDist,AccP0    
 || MVKH AccDist,AccP1    
        ; Viterbi译码第四步
        ; 计算累积距离
        ; 输入为Dist0,Dist1,DS0~DS7
        ; 输出为AccDist和G0~G7

AccP0  .set A4      ; 累积距离指针
AccP1  .set B4      ; 累积距离指针

Step4: 
 LDW *+AccP0[DS0],G0    ; 读累积距离
 || LDW *+AccP1[DS1],G1    
 
 LDW *+AccP0[DS2],G2    ; 读累积距离
 || LDW *+AccP1[DS3],G3    
 
 LDW *+AccP0[DS4],G4    ; 读累积距离
 || LDW *+AccP1[DS5],G5    
 
 LDW *+AccP0[DS6],G6    ; 读累积距离
 || LDW *+AccP1[DS7],G7    
 || MVK 1,ONE      ; ONE表示1 
 
 SHR Dist0,3,Dist0     ; 距离除8 
 || SHR Dist1,3,Dist1     

 SHR G0,3,W0      ; 累积距离除8
 || SHR G1,3,W1     
 
 SUB G0,W0,G0     
 || SUB G1,W1,G1     
 || SHR G2,3,W0     ; 累积距离除8
 || SHR G3,3,W1    
 || MPY ONE,0,Q0     ; Q0索引为0 
 || MPY ONE,1,Q1     ; Q1索引为1 
 
 ADD G0,Dist0,G0     ; 距离加
 || ADD G1,Dist1,G1     
 || SUB G2,W0,G2     
 || SUB G3,W1,G3     
 || SHR G4,3,W0     ; 累积距离除8
 || SHR G5,3,W1     

 STW G0,*+AccP0[0]     ; 保存累积距离
 || STW G1,*+AccP1[1]    
 || ADD G2,Dist0,G2     ; 距离加
 || ADD G3,Dist1,G3     
 || SUB G4,W0,G4     
 || SUB G5,W1,G5     
 
 STW G2,*+AccP0[2]     ; 保存累积距离
 || STW G3,*+AccP1[3]    
 || ADD G4,Dist0,G4     ; 距离加
 || ADD G5,Dist1,G5     
 || SHR G6,3,W0     ; 累积距离除8
 || SHR G7,3,W1     
 
 STW G4,*+AccP0[4]     ; 保存累积距离
 || STW G5,*+AccP1[5]    
 || SUB G6,W0,G6     
 || SUB G7,W1,G7     
 || CMPGT G0,G2,TT0    ; 找最小距离
 || CMPGT G1,G3,TT1    

 ADD G6,Dist0,G6     ; 距离加
 || ADD G7,Dist1,G7    
 || [TT0] MV G2,G0     ; 保存最小距离 
 || [TT0] MPY ONE,2,Q0    ; 更新索引 
 || [TT1] MV G3,G1     ; 保存最小距离
 || [TT1] MPY ONE,3,Q1    ; 更新索引
 
 STW G6,*+AccP0[6]     ; 保存累积距离
 || STW G7,*+AccP1[7]    
 || CMPGT G0,G1,TT0    ; 找最小距离
 || MPY ONE,4,W0    
 || MPY ONE,5,W1     
        ; Viterbi译码第五步
        ; 首次寻找最小累积距离
        ; 使用延迟路径回溯寻找路径状态
        ; 输入为G0~G7,D延迟路径
        ; 输出为TTT
II   .set B0      ; 临时变量
IDD   .set A4      ; 索引
DStptr  .set A5      ; 延迟状态指针
JJ   .set A7      ; 临时变量
JJ0   .set B8      ; 临时变量
ONE  .set A12      ; One表示1 

Step5: 
 [TT0] MV G1,G0     ; 计算当前4个中的最小值
 || [!TT0] MV Q0,Q1     
 || CMPGT G4,G6,TT0    ; 计算下4个中的最小值
 || CMPGT G5,G7,TT1    

 [TT0] MV G6,G4     ; 保存最小值
 || [TT0] MPY ONE,6,W0    ; 更新索引
 || [TT1] MV G7,G5     ; 保存最小值
 || [TT1] MPY ONE,7,W1    ; 更新索引
 || MVK MCurr,MCurrx    ; 计算回溯指针
 
 CMPGT G4,G5,TT0     ; 寻找最小值
 || MVKH MCurr,MCurrx    

 [TT0] MV G5,G4     ; 上4个中的最小值
 || [!TT0] MV W0,W1     
 || MVK DelayPath,JJ0    ; 准备循环缓冲区JJ
 
 CMPGT G0,G4,TT0     ; 计算最小值实部
 || MV Q1,IDD       
 || MVKH DelayPath,JJ0    ; 准备循环缓冲区JJ
 
 [TT0] MV W1,IDD     ;  得到IDD 
 || MV DStCurr,JJ     
 || MVK 14,II      ; 回溯计数器
 || LDW *MCurrx,MCurrx    ; 载入指针

IILoop: 
 [II] B IILoop      ; 回溯
 
 LDH *+JJ[IDD],IDD     ; 保持跟踪
 || MVK Diff,DFTP     ; 计算表diff指针 

 CMPGT JJ,JJ0,TT0     
 || MVKH Diff,DFTP     ; 计算表diff指针
 
 [TT0] SUBAH JJ,10,JJ    ; 调整循环缓冲区JJ
 || [!TT0] MVK DelayPath+300,JJ   ; 调整循环缓冲区JJ
 
 [!TT0] MVKH DelayPath+300,JJ  ; 调整循环缓冲区JJ
 
 SUB II,1,II      ; 计数器减
 
 AND IDD,1,IDD     
 || LDW *+MCurrx[1],Ext1 
 || MVK Tdr,TDRP     ; 计算Tdr指针
 
 ADD 8,IDD,IDD     
 || LDW *+MCurrx[2],Ext2    
 || MVKH Tdr,TDRP     ; 计算Tdr指针 
 
 LDH *+JJ[IDD],TTT     
 || MVK DelayPath+300,JJ0    ; 准备循环缓冲区DStCurr
 || MVK DStCurrbss,DStptr    ; 计算DStCurr指针

 MVKH DelayPath+300,JJ0    ; 准备循环缓冲区DStCurr
 || MVKH DStCurrbss,DStptr   ; 计算DStCurr指针
 || LDW *TDRP,TDR     ; 读Tdr 
 
 CMPLT DStCurr,JJ0,TT0    
 || LDW *+MCurrx[3],Sht    ; 计算移位索引
 
 [TT0] ADDAH DStCurr,10,DStCurr  ; 调整循环缓冲区DStCurr 
 || [!TT0] MVK DelayPath,DStCurr  ; 调整循环缓冲区DStCurr
 || LDW *+B15[1],B3     ; 返回序列
 
 [!TT0] MVKH DelayPath,DStCurr  ; 调整循环缓冲区DStCurr 
 || LDW *DFTP,DFT     ; 读表diff 
        ; Viterbi译码第六步
        ; 处理结果
        ; 输入为TTT
        ; 输出为A4返回值
MCurrx  .set A0      ; 调整表指针
PP   .set A0      ; 临时变量
Ext2  .set A2      ; 提取索引2
TDR  .set B2      ; Tdr值
SSS   .set A3      ; 临时变量
Sht   .set A4      ; 移位累加
TDRP  .set B4      ; Tdr指针
Ext1  .set A6      ; 提起索引1
DFT  .set A7      ; 表Diff 值
DFTP  .set A9      ; 表Diff指针

Step6: 
 STW DStCurr,*DStptr    ; 保存DStCurr 
 || EXTU TTT,Ext1,PP     ; 分开TTT成两片
 
 SHL PP,2,PP      ; 计算diff表索引
 || STW PP,*TDRP     ; 更新Tdr值 
 
 OR PP,TDR,PP      ; 计算diff表索引
 || EXTU TTT,Ext2,SSS    ; 分开TTT成两片

 SHL PP,1,PP      
 || MV B15,A9      ; 返回序列
 || B B3       ; 返回序列
 
 SHR DFT,PP,DFT      
 || LDW *+A9[2],A10     ; 返回序列
 || LDW *+B15[3],B10    ; 返回序列
 
 CLR DFT,2,31,DFT     ; 保持最低2位 
 || LDW *+A9[4],A11     ; 返回序列
 || LDW *+B15[5],B11    ; 返回序列
 
 SHL DFT,Sht,DFT     ; 连接SSS
 || LDW *+A9[6],A12     ; 返回序列
 || LDW *+B15[7],B12    ; 返回序列
 
 OR DFT,SSS,A4     ; 连接SSS 
 || LDW *+A9[8],A13     ; 返回序列
 || LDW *+B15[9],B13    ; 返回序列
 
 ADDAW B15,9,B15     ; 分配存储器
 
Step7:        ; 返回,恢复寄存器A10~A13,B10~B13,A3
 .end   
 

⌨️ 快捷键说明

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