分享

C28x系列DSP寻址方式详解

 heroshishiran 2012-03-23
C28x系列DSP寻址方式详解
作者:佚名  来源:700.com  发布时间:2007-2-6 14:50:49  发布人:dlwangjin

    DSP发展动态
1.TMS320C2000 TMS320C2000系列包括C24x和C28x系列。C24x系列建议使用LF24xx系列替代C24x系列,LF24xx系列的价格比C24x便宜,性能高于C24x,而且LF24xxA具有加密功能。 C28x系列主要用于大存储设备管理,高性能的控制场合。
2.TMS320C3x TMS320C3x系列包括C3x和VC33,主要推荐使用VC33。C3x系列是TI浮点DSP的基础,不可能停产,但价格不会进一步下调。
3.TMS320C5x TMS320C5x系列已不推荐使用,建议使用C24x或C5000系列替代。
4.TMS320C5000 TMS320C5000系列包括C54x和C55x系列。其中VC54xx还不断有新的器件出现,如:TMS320VC5471(DSP+ARM7)。 C55x系列是TI的第三代DSP,功耗为VC54xx的1/6,性能为VC54xx的5倍,是一个正在发展的系列。 C5000系列是目前TI DSP的主流DSP,它涵盖了从低档到中高档的应用领域,目前也是用户最多的系列。
5.TMS320C6000 TMS320C6000系列包括C62xx、C67xx和C64xx。此系列是TI的高档DSP系列。其中C62xx系列是定点的DSP,系列芯片种类较丰富,是主要的应用系列。 C67xx系列是浮点的DSP,用于需要高速浮点处理的领域。 C64xx系列是新发展,性能是C62xx的10倍。
6.OMAP系列 是TI专门用于多媒体领域的芯片,它是C55+ARM9,性能卓越,非常适合于手持设备、Internet终端等多媒体应用。
感谢作者总结
C28x系列DSP有四种基本寻址方式:
直接寻址 - 16位的寄存器DP用作,固定页指针(段指针),DP中存放当前变量所在页的首地址,指令中的6位或7位二进制数给出变量的偏移量(段偏移量)。用于访问固定地址的数据结构,如片上外设或C/C++中的全局变量和静态变量。

栈寻址-通过使用栈指针SP访问变量,在C28x中栈是从低地址向高地址增长的,SP始终指向下一个可用的空栈单元。SP值减去指令中6位二进制数给出的偏移量为变量地址,或者该偏移量给出分别在压栈(或出栈)操作时SP需要后加(或先减)的量。

间接寻址 - 32位的辅助寄存器XAR0~XAR7用作通用32位数据指针。指令可以进行直接的后加、先减/后减,或者通过三位二进制立即数给出对哪个寄存器操作,也可以用另外一个16位辅助寄存器内容给出当前用的寄存器。

寄存器寻址 - 直接对寄存器内容操作,寄存器可以是操作的源或目的地。这就使得C28x架构可以直接进行寄存器对寄存器的操作。

DSP其它的寻址方式:

数据/程序/IO空间立即寻址 - 存储器地址操作数直接嵌入在指令中。

程序空间间接寻址 - 某些指令可以使用某个间接指针来访问程序空间。因为C28x CPU中存储器之一致的,因此这种寻址模式可以完成在同一条指令中同时读两个操作数的操作。
说明:寻址模式由指令中的八位编码给出,状态寄存器ST1中的寻址模式选择位AMODE给出了编译器所使用的编码方式。
AMODE=0 - 复位时默认的寻址模式,也是C28x的C/C++编译器使用的默认模式。但某些寻址方式C2xLP器件不兼容,此时段偏移量由六位二进制数给出(C2xLP器件是七位的),因此仅支持部分C2xLP器件的间接寻址方式。
AMODE=1 - 包含了C2xLP器件全兼容的寻址模式。此时段偏移量为七位二进制数给出,支持C2xLP器件所有的寻址方式。

注意:(1)C28x器件和C2xLP器件间接寻址指令的不同在于,C28x的指令中辅助寄存器指针是隐含的,也就是指令中标明了对哪个寄存器操作。而在Cx2LP的指令中,对哪个寄存器操作是由3位的辅助寄存器指针ARP(在ST1中)给出的,并且可以同时给出下一条指令要使用辅助寄存器指针(第三个操作数);(2)在C28x的指令中,目的操作数总是在源操作数的左边。请看下例:

假如要完成这样的操作,把XAR4所指的数据读出加到AL中,随后把XAR4的内容加一,C28x的指令为:ADD AL,*XAR4++;C2xLP的指令可以为:ADD AL,*++(此时ARP=4)。而C2xLP的指令ADD AL,*++,ARP5则在完成上述操作的同时,把ARP的内容更新为5,即令ARP指向ARP5。

具体的区别请参见TI的文档spru430d中第五章的表5-1。
操作符*和@的作用:*表示取后面的变量值或寄存器的内容作为地址,取该地址所指向的存储空间的内容作为操作数。@表示直接取后面的变量值或寄存器的内容作为操作数。

如何改变编译器的处理模式:

编译器总是默认为AMODE=0,通过两种方式改变编译器的处理方式,一种是命令行参数法,当使用-v28时使编译器默认为AMODE=0模式,当使用-v28 -m20时默认为AMODE=1模式。另一种是源文件中指定法,如下面的文件(假设编译器命令行参数为-v28)

; 文件开始

...

...

...

SETC AMODE ; AMODE位置一

.lp_amode ; 通知编译器检查C27x/C28x的语法,该段代码只能用AMODE=1的寻址方式

...
...
...
CLRC AMODE ; AMODE位清零

.c28_amode ; 通知编译器检查C28x的语法,该段代码只能用AMODE=0的寻址方式
...
...
...
; 文件结束

DSP指令实例:

DSP直接寻址(只能寻址C28x的低4M数据地址空间):

(1)@6位二进制立即数方式,适用于AMODE=0,地址高10位为0,地址次高16位为DP的低16位,地址低6位为6位二进制立即数,可寻址DP以上的0到63字的地址范围:

; VarA和VarB在同一个长度为64字的分页中,VarC和VarD同在另外一个长度为64字的分页中

MOVW DP,#VarA ; 把变量VarA所在页的首地址载入段指针DP中
ADD AL,@VarA ; 把变量VarA的内容加到AL中
MOV @VarB,AL ; 把AL的内容写进变量VarB中
MOVW DP,#VarC ;
SUB AL,@VarC ;
MOV @VarD,AL ;

(2)@7位二进制立即数方式,适用于AMODE=1,地址高10位为0,地址次高15位为DP的低15:1位,地址低7位为7位二进制立即数,可寻址DP以上的0到127字的地址范围:

SETC AMODE
.lp_amode

MOVW DP,#VarA
ADD AL,@@VarA
MOV @@VarB,AL
MOVW DP,#VarC
SUB AL,@@VarC
MOV @@VarD,AL
栈寻址(只能寻址C28x的低64k数据地址空间):
(2) *-SP[6位二进制立即数]方式,适用于AMODE=0,高16位地址为0,低16位地址为SP-6位二进制立即数,SP不变,可寻址低于SP的0到63个字地址范围:

ADD AL,*-SP[5] ; 栈顶减5个字所指向的内容(16位)加到AL中,SP不变
MOV *-SP[8],AL ; AL的内容(16位)写到栈顶减8个字所指向的位置,SP不变
ADDL ACC,*-SP[12] ; 栈顶减12个字所指向的内容(32位)加到ACC中,SP不变
MOVL *-SP[34],ACC ; ACC的内容(32位)写到栈顶减32个字所指向的位置,SP不变
(2) *SP++方式,适用于AMODE=x,16位操作时SP=SP+1,32位操作时SP=SP+2,高16位地址为0,低16位地址为SP:

MOV *SP++,AL ; AL的内容(16位)压入栈顶
MOVL *SP++,P ; P的内容(32位)压入栈顶
(3) *--SP方式,适用于AMODE=x,16位操作时SP=SP-1,32位操作时SP=SP-2,高16位地址为0,低16位地址为SP:

ADD AL,*--SP ; 栈顶内容弹出并加到AL中(16位)
MOVL ACC,*--SP ; 栈顶内容弹出到ACC中(32位)

C28x间接寻址:

(1)*XARn++方式,适用于AMODE=x,ARP=n,32位地址为XARn,16位操作时XARn=XARn+1,32位操作时XARn=XARn+2:
MOVL XAR2,#Array1 ; 载入Array1的首地址到XAR2中
MOVL XAR3,#Array2 ; 载入Array2的首地址到XAR3中
MOV @AR0,#N-1 ; 载入循环计数N到AR0中
Loop:
MOVL ACC,*XAR2++ ; 载入XAR2指向的内容到ACC中,XAR2后加1
MOVL *XAR3++,ACC ; ACC的内容写入XAR3指向的地址,XAR3后加1
BANZ Loop,AR0-- ; 循环到AR0 == 0,AR0后加1

(2)*--XARn方式,适用于AMODE=x,ARP=n,32位地址为XARn,16位操作时XARn=XARn-1,32位操作时XARn=XARn-2:
MOVL XAR2,#Array1+N*2 ; 载入Array1的末地址到XAR2中
MOVL XAR3,#Array2+N*2 ; 载入Array1的末地址到XAR2中
MOV @AR0,#N-1 ; 载入循环计数N到AR0中
Loop:

MOVL ACC,*--XAR2 ; XAR2先减1,载入XAR2所指向的内容到ACC中
MOVL *--XAR3,ACC ; XAR3先减,ACC内容写入XAR3所指的位置
BANZ Loop,AR0-- ; 循环到 AR0 == 0, AR0后加1

(3)*+XARn[AR0或(AR1)]方式,适用于AMODE=x,ARP=n,32位地址为XARn+AR0(或AR1),XAR0(或XAR1)的低16位作为无符号数加到XARn中,忽略高16位,可能会产生到XARn高16位的溢出:

MOVW DP,#Array1Ptr ; 指向Array1Ptr的段
MOVL XAR2,@Array1Ptr ; 载入Array1的首地址到XAR2中
MOVB XAR0,#16 ; AR0 = 16, AR0H = 0
MOVB XAR1,#68 ; AR1 = 68, AR1H = 0
MOVL ACC,*+XAR2[AR0] ; 把Array1[16]和Array1[68]内容互换,首先载入Array1[16]内容到ACC
MOVL P,*+XAR2[AR1] ; 把Array1[68]内容到P
MOVL *+XAR2[AR1],ACC ; 写入ACC内容到Array1[68]
MOVL *+XAR2[AR0],P ; 写入P内容到Array1[16],完成互换
(4)*+XARn[3位二进制立即数]方式,适用于AMODE=x,ARP=n,32位地址为XARn+无符号3位二进制立即数,*XARn等价于*+XARn[0]:

MOVW DP,#Array1Ptr ; 指向Array1Ptr的段
MOVL XAR2,@Array1Ptr ; 载入Array1的首地址到XAR2
MOVL ACC,*+XAR2[2] ; 把Array1[2]和Array1[5]内容互换,首先载入Array1[2]内容到ACC
MOVL P,*+XAR2[5] ; 把Array1[5]内容到P
MOVL *+XAR2[5],ACC ; 写入ACC内容到Array1[5]
MOVL *+XAR2[2],P ; 写入P内容到Array1[2],完成互换

循环间接寻址:

DSP寄存器寻址
(1)32位操作,使用寄存器@ACC,@XT,@P,@XARn,当@ACC作为目的操作数时,可能会影响Z,N,V,C,OVC标志位。
(2)16位操作,使用寄存器@AL,@AH,@PL,@PH,@TH,@SP,@ARn,当@AL或@AH作为目的操作数时,可能会影响Z,N,V,C,OVC标志位。对应的高16位或低16位不受影响。

数据/程序/IO空间立即寻址:
(1) *(16位二进制立即数)方式,地址的高16位为0,低16位为16位二进制立即数。当该指令连续使用时,每次地址都会后加。只能寻址低64k数据空间。可用指令:

MOV loc16,*(0:16bit) ; [loc16] = [0:16bit]
MOV *(0:16bit),loc16 ; [loc16] = [0:16bit]
(2) *(PA)方式,地址的高16位为0,低16位为PA中的16位二进制立即数。当该指令连续使用时,每次地址都会后加。该模式寻址时,在访问IO空间时,IO选通信号被置位。用数据地址线访问IO空间。可用指令:

OUT *(PA),loc16 ; IOspace[0:PA] = [loc16]
UOUT *(PA),loc16 ; IOspace[0:PA] = [loc16] (unprotected)
IN loc16,*(PA) ; [loc16] = IOspace[0:PA]

(3) 0:pma方式,22位的地址高6位为0,低16位为16位二进制立即数pma,当该指令连续使用时,每次地址都会后加。只能寻址低64k程序空间。可用指令:
MAC P,loc16,0:pma ; ACC = ACC + P << PM,P = [loc16] * ProgSpace[0:pma]

(4) *(pma)方式,22位的地址高6位为0,低16位为16位二进制立即数pma,当该指令连续使用时,每次地址都会后加。只能寻址低64k程序空间。可用指令:

XPREAD loc16,*(pma) ; [loc16] = ProgSpace[0x3F:pma]

XMAC P,loc16,*(pma) ; ACC = ACC + P << PM,P = [loc16] * ProgSpace[0x3F:pma]

XMACD P,loc16,*(pma) ; ACC = ACC + P << PM,P = [loc16] * ProgSpace[0x3F:pma],[loc16+1] = [loc16]

DSP程序空间间接寻址:

(1) *(AL)方式,22位的地址高6位为0x3F,低16位为AL,当该指令连续使用时,AL的内容被复制到一个影子寄存器中,并在每次地址后加,AL的内容不变。只能寻址低64k程序空间。可用指令:

XPREAD loc16,*AL ; [loc16] = ProgSpace[0x3F:AL]
XPWRITE *AL,loc16 ; ProgSpace[0x3F:AL] = [loc16]

(2) *XAR7方式,22位地址为XAR7,当在指令XPREAD或XPWRITE中连续使用时,XAR7的内容被复制到一个影子寄存器中,并每次地址后加,XAR7的内容不变。其它指令则不会。可用指令:

MAC P,loc16,*XAR7 ; ACC = ACC + P << PM,P = [loc16] * ProgSpace[*XAR7]
DMAC ACC:P,loc32,*XAR7 ; ACC = ([loc32].MSW * ProgSpace[*XAR7].MSW) >> PM,
; P = ([loc32].LSW * ProgSpace[*XAR7].MSW) >> PM
QMACL P,loc32,*XAR7 ; ACC = ACC + P >> PM,
; P = ([loc32] * ProgSpace[*XAR7]) >> 32
IMACL P,loc32,*XAR7 ; ACC = ACC + P,
; P = ([loc32] * ProgSpace[*XAR7]) << PM
PREAD loc16,*XAR7 ; [loc16] = ProgSpace[*XAR7]
PWRITE *XAR7,loc16 ; ProgSpace[*XAR7] = [loc16]

(2) *XAR7++方式,22位地址为XAR7, 16位操作时XAR7=XAR7+1,32位操作时XAR7=XAR7+2,指令重复时,地址后加。可用指令:

MAC P,loc16,*XAR7++ ; ACC = ACC + P << PM,P = [loc16] * ProgSpace[*XAR7++]

DMAC ACC:P,loc32,*XAR7++ ; ACC=([loc32].MSW * ProgSpace[*XAR7++].MSW)>>PM,

; P=([loc32].LSW * ProgSpace[*XAR7++].MSW)>>PM

QMACL P,loc32,*XAR7++ ; ACC = ACC + P >> PM, P = ([loc32] * ProgSpace[*XAR7++]) >> 32

IMACL P,loc32,*XAR7++ ; ACC = ACC + P, P = ([loc32] * ProgSpace[*XAR7++]) << PM

DSP字节寻址:
*+XARn[AR0],*+XARn[AR0],*+XARn[3位二进制立即数],32位地址为XARn+偏移量(AR0/AR1/3位二进制立即数),如果偏移量为偶数值,则访问16位存储器位置的低有效位,高有效位不变;如果为奇数,则访问16位存储器位置的高有效位,低有效位不变。其它所有寻址模式,只访问访问寻址位置的低有效位,不改变高有效位。可用指令:

MOVB AX.LSB,loc16 ; if( address mode == *+XARn[AR0/AR1/3bit] )

; if( offset == even )
; AX.LSB = [loc16].LSB;
; AX.MSB = 0x00;
; if( offset == odd )
; AX.LSB = [loc16].MSB;
; AX.MSB = 0x00;

; else
; AX.LSB = [loc16].LSB;
; AX.MSB = 0x00;
MOVB AX.MSB,loc16 ; if( address mode == *+XARn[AR0/AR1/3bit] )
; if( offset == even )
; AX.LSB = untouched;
; AX.MSB = [loc16].LSB;
; if( offset == odd )
; AX.LSB = untouched;
; AX.MSB = [loc16].MSB;
; else
; AX.LSB = untouched;

; AX.MSB = [loc16].LSB;

MOVB loc16,AX.LSB ; if( address mode == *+XARn[AR0/AR1/3bit] )

; if( offset == even )

; [loc16].LSB = AX.LSB

; [loc16].MSB = untouched;

; if( offset == odd )

; [loc16].LSB = untouched;

; [loc16].MSB = AX.LSB;

; else

; [loc16].LSB = AX.LSB;

; [loc16].MSB = untouched;

MOVB loc16,AX.MSB ; if( address mode == *+XARn[AR0/AR1/3bit] )

; if( offset == even )

; [loc16].LSB = AX.MSB

; [loc16].MSB = untouched;

; if( offset == odd )

; [loc16].LSB = untouched;

; [loc16].MSB = AX.MSB;

; else

; [loc16].LSB = AX.MSB;

; [loc16].MSB = untouched;

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多