《TMS320C3X系列-DSP原理與開發(fā)技術(shù)》課件第5章_第1頁
《TMS320C3X系列-DSP原理與開發(fā)技術(shù)》課件第5章_第2頁
《TMS320C3X系列-DSP原理與開發(fā)技術(shù)》課件第5章_第3頁
《TMS320C3X系列-DSP原理與開發(fā)技術(shù)》課件第5章_第4頁
《TMS320C3X系列-DSP原理與開發(fā)技術(shù)》課件第5章_第5頁
已閱讀5頁,還剩239頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

第5章基于匯編語言的程序設(shè)計(jì)

5.1匯編語言源程序格式

5.2用匯編語言編程的技巧

5.3流水線操作5.4初始化程序設(shè)計(jì)

5.5典型流程控制程序設(shè)計(jì)舉例

5.6算術(shù)運(yùn)算和數(shù)據(jù)轉(zhuǎn)換程序設(shè)計(jì)

5.7典型的信號(hào)處理算法程序設(shè)計(jì)

本章小結(jié)

思考題與習(xí)題

5.1匯編語言源程序格式

匯編語言源程序以.asm為擴(kuò)展名。匯編語言源程序的每一行都可以由下面4個(gè)部分組成:

[標(biāo)號(hào)][:]助記符[操作數(shù)][;注釋]

標(biāo)號(hào)——供本程序的其它部分或其它程序調(diào)用。助記符——助記符指令、匯編指令、宏指令和宏調(diào)用。操作數(shù)——指令中操作數(shù)或匯編命令中定義的內(nèi)容。

注釋——注釋從分號(hào)“;”開始,可以放在指令或匯編命令的后面,也可以放在單獨(dú)的一行或數(shù)行。注釋是任選項(xiàng)。例:標(biāo)號(hào)助記符源操作數(shù)目的操作數(shù)注釋LOOP:SUBF3,R1;主循環(huán)體5.2用匯編語言編程的技巧

用匯編語言編寫TMS320VC33程序時(shí),為了提高程序的效率,必須充分考慮VC33本身提供的各種軟硬件資源,充分發(fā)揮它們的作用。下面的編程方法有助于提高程序的效率,在實(shí)際編程過程中值得借鑒。

1.利用延遲跳轉(zhuǎn)跳轉(zhuǎn)分為條件跳轉(zhuǎn)和無條件跳轉(zhuǎn)兩類。不管是有條件的標(biāo)準(zhǔn)跳轉(zhuǎn)還是無條件的標(biāo)準(zhǔn)跳轉(zhuǎn),都需要執(zhí)行4個(gè)指令周期。TMS320C3x提供的延遲跳轉(zhuǎn)指令則可以在1個(gè)指令周期內(nèi)完成。在延遲跳轉(zhuǎn)指令后面的三條指令不管跳轉(zhuǎn)條件滿足與否都正常執(zhí)行。若少于3條指令,可采用延遲跳轉(zhuǎn)加NOP指令的方法。例如:

BDLOOP

ADDFR0,R1

FIX?R1

STI?R1,*AR1上述指令就使得跳轉(zhuǎn)至LOOP的指令在STI指令執(zhí)行后執(zhí)行。延遲跳轉(zhuǎn)也可以結(jié)合條件跳轉(zhuǎn),例如:

DBNZDAR2,LOOP

ADDFR0,R1

FIXR1

SITR1,*AR1

上述指令使得跳轉(zhuǎn)持續(xù)執(zhí)行到AR2中所對(duì)應(yīng)地址的數(shù)據(jù)小于0為止。

2.利用單指令重復(fù)或塊重復(fù)

在重復(fù)方式下,可實(shí)現(xiàn)無開銷循環(huán)。RPTS指令用來實(shí)現(xiàn)單指令重復(fù),RPTB指令用來實(shí)現(xiàn)塊指令重復(fù)。采用RPTB指令,塊起始地址被裝入到寄存器RS中,塊結(jié)束地址被裝入到寄存器RE,而重復(fù)執(zhí)行的次數(shù)由重復(fù)計(jì)數(shù)器寄存器RC的數(shù)值決定,重復(fù)的次數(shù)為RC中的數(shù)值加1。另外需要注意的是:采用RPTS指令是禁止中斷的,因此在需要中斷的場合,不能用RPTS指令,可改為塊重復(fù)指令RPTB。

3.利用并行指令

在TMS320C3x的指令集中提供了一些可并行操作的指令,這可增加在單周期內(nèi)執(zhí)行的操作次數(shù)。為了達(dá)到效率最高,應(yīng)注意正確使用尋址方式和安排數(shù)據(jù)。

4.利用寄存器

寄存器是訪問存儲(chǔ)器的一種有效的方式,大量準(zhǔn)確地采用寄存器可方便并行指令的使用,并且當(dāng)在尋址方式中使用寄存器時(shí)有助于避免流水線的沖突。

5.充分利用Cache

TMS320VC33芯片內(nèi)提供了64×32位的高速程序緩沖Cache,對(duì)于存于Cache中的指令,可以節(jié)省取指時(shí)間,從而加快程序運(yùn)行速度。因此,編程時(shí)應(yīng)確保在程序初始化時(shí)使能Cache。

6.合理安排片內(nèi)RAM

TMS320VC33內(nèi)部提供了34K字的RAM,分為4塊,其中RAM0和RAM1每塊為2K字,RAM2和RAM3每塊為16K字。對(duì)這些RAM的存取操作速度特別快,在單個(gè)指令周期內(nèi),可以從內(nèi)部RAM中存取兩次。如果采用CPU和DMA并行操作將數(shù)據(jù)傳送到內(nèi)部RAM中,則可使性能達(dá)到最佳。

7.避免流水線沖突

流水線操作是處理器實(shí)現(xiàn)高速運(yùn)行的重要手段。若用戶程序的執(zhí)行速度沒有問題,則不必考慮這個(gè)問題。但對(duì)于影響程序執(zhí)行速度的關(guān)鍵之處,必須確認(rèn)不是由于流水線沖突而造成的執(zhí)行時(shí)間的增加。確認(rèn)沖突的方法是運(yùn)行模擬器或仿真器的跟蹤功能。

8.利用循環(huán)尋址

循環(huán)尋址尤其在卷積運(yùn)算中有特別功能,可大大方便數(shù)字濾波器的實(shí)現(xiàn)。5.3流?水?線?操?作

流水線操作是體現(xiàn)TMS320C3x系列DSP高性能的主要特征。任何一條指令都要經(jīng)過取指令、譯碼、讀操作數(shù)、執(zhí)行等4個(gè)過程,對(duì)同一條指令不能同時(shí)進(jìn)行上述4個(gè)過程的操作,但可以對(duì)不同的指令同時(shí)進(jìn)行這4種操作,即每一個(gè)CPU周期中,有4條指令分別處于取指令、譯碼、讀操作數(shù)和執(zhí)行階段,這種作業(yè)方式就稱為流水線操作。流水線作業(yè)不僅提高了運(yùn)算和處理速度,而且減少了總線擁擠的現(xiàn)象,提高了CPU的吞吐量。5.3.1流水線結(jié)構(gòu)

TMS320C3x系列DSP流水線結(jié)構(gòu)的四個(gè)主要階段是:

(1)取指令:從寄存器中取指令字并更新程序計(jì)數(shù)器PC的值;

(2)譯碼:對(duì)指令字進(jìn)行譯碼并產(chǎn)生地址。如果是間接尋址指令,還要對(duì)ARn寄存器的內(nèi)容進(jìn)行修改或調(diào)整,而且當(dāng)數(shù)據(jù)存入堆?;蛘邚亩褩棾鰰r(shí),控制堆棧指針的修改;

(3)讀操作數(shù):即從存儲(chǔ)器或寄存器中讀操作數(shù);

(4)執(zhí)行:從寄存器中讀出操作數(shù)后,執(zhí)行相應(yīng)的操作,并向目的地址寫結(jié)果。所有指令都必須經(jīng)過上述4個(gè)階段的處理。圖5.1說明了流水線的結(jié)構(gòu),圖中W、X、Y、Z代表具體指令。由圖可見,在第m個(gè)周期,這4個(gè)階段處于完全的并行狀態(tài),即完全重疊在一起,從而進(jìn)入了正常的流水線作業(yè)過程。圖5.1TMS320C3x流水線的結(jié)構(gòu)流水線操作過程中,DMA也可能要工作,這時(shí),優(yōu)先級(jí)順序由高到低規(guī)定為:執(zhí)行、讀指令、譯碼、取指令、DMA,即執(zhí)行的優(yōu)先級(jí)最高,DMA的優(yōu)先級(jí)最低。盡管DMA控制器的優(yōu)先級(jí)是最低的,但因?yàn)镈MA有它自己的數(shù)據(jù)總線和地址總線,所以可以使其與CPU的沖突減少到最低,通過合理的設(shè)計(jì),甚至可以完全消除沖突。5.3.2流水線沖突

1.跳轉(zhuǎn)沖突

跳轉(zhuǎn)沖突是由無延時(shí)的跳轉(zhuǎn)指令引起的,這些跳轉(zhuǎn)指令包括BR、Bcond、Dbcond、CALL、IDLE、RPTB、RPTS、RETIcond、RETScond。另外,中斷和復(fù)位也會(huì)使程序的流程發(fā)生變化,所以也會(huì)引起這類沖突。由于遇到了跳轉(zhuǎn)指令而產(chǎn)生這類沖突,因而需要跳轉(zhuǎn)到相應(yīng)的地址處理相關(guān)的指令,而在現(xiàn)行流水線上已經(jīng)完成了取指等作業(yè)的指令將不再被進(jìn)行后續(xù)的處理,從而導(dǎo)致了現(xiàn)行流水線的無效,因此必須對(duì)流水線進(jìn)行刷新。例5.1由跳轉(zhuǎn)指令引起的流水線沖突。

BRTHREE ;無條件跳轉(zhuǎn)

MPYF ;沒有執(zhí)行

ADDF ;沒有執(zhí)行

SUBF ;沒有執(zhí)行

AND ;沒有執(zhí)行

THREE: OR;執(zhí)行跳轉(zhuǎn)指令后才取指

STI

指令執(zhí)行過程如圖5.2所示。圖5.2由跳轉(zhuǎn)指令引起的流水線沖突在這個(gè)例子中,MPYF指令的取指與BR指令的譯碼是同時(shí)進(jìn)行的,BR指令譯碼后不再對(duì)緊隨MPYF后面的下一條指令進(jìn)行取指,而是處于等待狀態(tài),以便等BR指令執(zhí)行后得到新的跳轉(zhuǎn)地址或PC值時(shí)再取指,BR指令執(zhí)行的結(jié)果是PC?=?3。顯然,由于跳轉(zhuǎn)指令BR而使正常的流水線作業(yè)的順序被打破了,在流水線上插入了許多“(nop)”。本例及今后的例子中,在取指、譯碼、讀操作數(shù)、執(zhí)行等各個(gè)階段,如果由于某種原因而不能執(zhí)行特定的功能時(shí),都用“(nop)”填充。需要指出的是:能夠引起這類沖突的指令中也包括了RPTS和RPTB,它們同樣可以引起流水線的刷新,原因是這些指令需要對(duì)RS、RE和RC寄存器進(jìn)行裝載。如果對(duì)這些寄存器的裝載沒有使用RPTS和RPTB指令,而是將RS、RE和RC用作為通用寄存器,通過LDI等指令裝載,就不會(huì)產(chǎn)生流水線沖突。總之,當(dāng)RS、RE和RC作為32位通用寄存器使用時(shí)是不會(huì)發(fā)生沖突的。由于中斷嵌套而引起RPTB的嵌套時(shí),在采用重復(fù)方式的時(shí)候有必要直接裝載和存儲(chǔ)這些寄存器。由于在進(jìn)入重復(fù)方式之前最多可以取4條指令,執(zhí)行裝載操作時(shí)需采用一條跳轉(zhuǎn)指令來刷新流水線。當(dāng)一條指令在裝載RC時(shí)且RC正發(fā)生變化,則直接裝載操作的優(yōu)先級(jí)別高于重復(fù)方式的修改操作。

在跳轉(zhuǎn)指令引起的這類沖突中,所述的跳轉(zhuǎn)指令不包括延時(shí)跳轉(zhuǎn)指令,這是因?yàn)檠訒r(shí)跳轉(zhuǎn)本身的含義是要延時(shí)三個(gè)周期后再跳轉(zhuǎn),這就允許緊跟其后的三條指令被取指后再跳轉(zhuǎn),可以保證每個(gè)CPU周期中都有一條指令處于被執(zhí)行的狀態(tài)。例5.2延時(shí)跳轉(zhuǎn)指令可以保證緊跟其后的三條指令被執(zhí)行。

BRDTHREE ;無條件延時(shí)跳轉(zhuǎn)

MPYF ;執(zhí)行

ADDF ;執(zhí)行

SUBF ;執(zhí)行

AND ;不執(zhí)行

THREE:MPYF;在取SUBF之后取指

指令執(zhí)行過程如圖5.3所示。圖5.3延時(shí)跳轉(zhuǎn)指令可以使其后的三條指令被執(zhí)行延時(shí)跳轉(zhuǎn)包括BRD、Bcond和DbcondD,在本例中,雖然由于延時(shí)指令的延時(shí)作用保證了每個(gè)CPU周期都有一條指令被執(zhí)行,但如果在等待三條指令的過程中遇到了中斷,則中斷也將被延時(shí)三個(gè)周期后才響應(yīng),這就造成了中斷響應(yīng)不及時(shí)的問題。對(duì)于一些需要精確定時(shí)間的場合,會(huì)造成很大的誤差。以TMS320VC33為例,如果CPU的指令周期為18?ns,則三個(gè)周期的時(shí)間為54?ns,如果將DSP用于超聲波測量流速的場合,根據(jù)時(shí)間差法求出的流速的最小分辨率將比原來降低3倍,同時(shí)也會(huì)造成測量結(jié)果的不穩(wěn)定。因此,在使用延時(shí)跳轉(zhuǎn)指令時(shí),必須考慮到這一點(diǎn)。

2.寄存器沖突

寄存器沖突是在對(duì)產(chǎn)生地址的寄存器進(jìn)行讀、寫等操作的過程中,如果相應(yīng)的寄存器還沒有做好被使用的準(zhǔn)備而發(fā)生的沖突。這類寄存器可分為三組:

(1)輔助寄存器AR0~AR7,索引寄存器IR0、IR1,程序塊規(guī)模寄存器BK;

(2)數(shù)據(jù)頁指針DP;

(3)系統(tǒng)堆棧指針SP。對(duì)這三組寄存器中的某一個(gè)寄存器進(jìn)行寫操作時(shí),直到寫操作完成之前,譯碼器是不能使用該寄存器所在組中的任何寄存器的,這就造成了譯碼的延時(shí),從而也就造成了執(zhí)行的停頓,即不能保證每個(gè)CPU周期都有一條指令處于被執(zhí)行的狀態(tài)。這里所述的寄存器寫操作是指LDF、LDI、LDII或DB等指令所執(zhí)行的寫操作,不包指令執(zhí)行前或執(zhí)行后對(duì)ARn寄存器內(nèi)容所進(jìn)行的增、減等調(diào)整。例5.3寫ARn指令的后面緊隨著一條用ARn產(chǎn)生地址的指令,這時(shí)會(huì)產(chǎn)生流水線沖突。

LDI 7,AR2 ;7→AR2

NEXT

MPYF *AR2,R0 ;譯碼延時(shí)2個(gè)周期

ADDF

FLOAT

這時(shí)會(huì)產(chǎn)生流水線沖突,如圖5.4所示。圖5.4產(chǎn)生流水線沖突(一)在該例中,先對(duì)輔助寄存器AR2進(jìn)行寫操作,下一條指令用AR2產(chǎn)生地址,由于在完成AR2的寫操作之前不能使用該寄存器,而第二條指令也要用到該寄存器,所以第二條指令的譯碼就延時(shí)了兩個(gè)周期。因?yàn)榈诙l指令的譯碼被延時(shí),所以對(duì)第三條指令的取指便重復(fù)執(zhí)行,在本例中,ADDF指令被取指3次。

前面是對(duì)寄存器進(jìn)行寫操作的例子,對(duì)其進(jìn)行讀操作也會(huì)產(chǎn)生類似的情況。例5.4讀ARn指令的后面緊隨著一條用ARn產(chǎn)生地址的指令而產(chǎn)生流水線沖突。

ADDIAR0,AR1,R1 ;AR0+AR1→R1

NEXT MPYF*++AR2,R0;譯碼延時(shí)一個(gè)周期

ADDF

FLOAT

指令執(zhí)行過程如圖5.5所示。圖5.5產(chǎn)生流水線沖突(二)該例中,第一條指令對(duì)AR0和AR1進(jìn)行讀操作,這兩個(gè)輔助寄存器的內(nèi)容相加后將結(jié)果寫到擴(kuò)展精度寄存器R1中,下一條指令使用了一個(gè)不同的輔助寄存器AR2產(chǎn)生地址,因?yàn)檫@些寄存器處于同一組中,所以在完成讀操作之前,不能使用該組中的任何寄存器,這就產(chǎn)生了流水線沖突。等ADDI指令完成讀操作后,就可對(duì)第二條指令進(jìn)行譯碼了,這就產(chǎn)生了一個(gè)周期的延時(shí)。需要注意的是:①對(duì)IR0、IR1、BK或DP等4個(gè)寄存器進(jìn)行讀操作時(shí)不會(huì)引起延時(shí),而對(duì)其它的寄存器進(jìn)行操作時(shí)均會(huì)發(fā)生延時(shí);②在一條指令中通過輔助寄存器產(chǎn)生地址不認(rèn)為是一次讀操作,如*ARn、*++ARn、*-ARn等。

3.存儲(chǔ)器沖突

當(dāng)物理存儲(chǔ)空間中的存儲(chǔ)器在一個(gè)CPU周期內(nèi)被訪問的次數(shù)超過規(guī)定的次數(shù)時(shí),就會(huì)發(fā)生存儲(chǔ)器沖突。例如:RAM0、RAM1、RAM2、RAM3等存儲(chǔ)器在每個(gè)周期內(nèi)只支持兩次存取操作,外部擴(kuò)展的存儲(chǔ)器每周期只支持一次存取。如果超過這種規(guī)定,就會(huì)發(fā)生沖突。存儲(chǔ)器存取引起的流水線沖突有四種類型:

(1)在一個(gè)周期內(nèi)對(duì)存儲(chǔ)器進(jìn)行多次訪問引起的沖突。由于在一個(gè)CPU周期內(nèi)對(duì)片內(nèi)RAM或外部端口的存取超過了規(guī)定的次數(shù)而阻止了程序的取指,由此引起的等待稱為程序等待。

(2)取指需要多個(gè)周期而引起的沖突。程序取操作已經(jīng)開始,但在一個(gè)周期內(nèi)仍沒有完成。

(3)相鄰兩條指令對(duì)存儲(chǔ)器多次存取及互鎖裝載指令引起的沖突。

(4)外部端口操作及條件調(diào)用和條件陷阱引起的沖突。下面對(duì)這四種類型的沖突分別進(jìn)行討論。

(1)在一個(gè)周期內(nèi)對(duì)存儲(chǔ)器進(jìn)行多次訪問引起的沖突。有兩種情況會(huì)阻止程序取指操作的開始,分別是:①有兩個(gè)CPU數(shù)據(jù)需要在RAM中存取,但同時(shí)又必須對(duì)同一RAM進(jìn)行程序取指,或者正在對(duì)一外部端口進(jìn)行數(shù)據(jù)存取的同時(shí),又必須對(duì)該端口進(jìn)行取指操作;②一個(gè)多周期的CPU數(shù)據(jù)或DMA數(shù)據(jù)需要在外部端口上進(jìn)行存取。例5.5在一個(gè)CPU周期內(nèi)對(duì)存儲(chǔ)器進(jìn)行二次以上的存取而引起的沖突。

ADDF3*AR0,*AR1,R0

FIX

MPYF

ADDF3

NEGB

這時(shí)會(huì)產(chǎn)生流水線沖突,如圖5.6所示。圖5.6產(chǎn)生流水線沖突(三)該例說明了程序等待直到CPU數(shù)據(jù)存取完成。在這種情況下,*AR0和*AR1二者都指向RAM塊0中的數(shù)據(jù),并且MPYF指令取自RAM塊0,導(dǎo)致了在n+2周期中需要對(duì)存儲(chǔ)器存取三次,由于在單周期內(nèi)不能對(duì)RAM塊0進(jìn)行兩次以上的存取操作,所以在n+2周期中MPYF指令不能進(jìn)行取指,必須等待CPU數(shù)據(jù)存取完之后才能開始程序的取指操作。

例5.6由于多周期數(shù)據(jù)的存取產(chǎn)生的程序等待。

ADDF ;代碼在內(nèi)部存儲(chǔ)器

MPYF ;代碼在內(nèi)部存儲(chǔ)器

SUBF ;代碼在內(nèi)部存儲(chǔ)器

CALL ;代碼在外部存儲(chǔ)器

這時(shí)會(huì)產(chǎn)生程序等待,如圖5.7所示。圖5.7產(chǎn)生程序等待該例給出了由于多周期數(shù)據(jù)存取或多周期DMA存取操作而發(fā)生程序等待的例子。ADDF、MPYF和SUBF指令取自內(nèi)部存儲(chǔ)器,DMA是對(duì)外部端口進(jìn)行操作,但在DMA存取的同時(shí),CALL指令的取指采用了與DMA相同的端口,從而造成了在一個(gè)CPU周期內(nèi)對(duì)同一外部端口進(jìn)行兩次存取的情況。由于在同一周期內(nèi)只能對(duì)外部端口進(jìn)行一次存取,從而造成了流水線沖突。

(2)取指需要多個(gè)周期而引起的沖突。當(dāng)取指令需要多于一個(gè)周期的時(shí)間來完成時(shí),就會(huì)發(fā)生沖突。

例5.7多周期取指引起的沖突。

多周期取指引起的沖突如圖5.8所示。圖5.8多周期取指引起的沖突本例中,MPYF和ADDF指令取自支持單周期存取的存儲(chǔ)器,但SUBF指令取自需要插入一個(gè)等待狀態(tài)的存儲(chǔ)器,即需要兩個(gè)周期才能完成取指,這就造成了在一個(gè)CPU周期內(nèi)不能完成單條指令取指的現(xiàn)象,從而導(dǎo)致了流水線沖突。

(3)相鄰兩條指令對(duì)存儲(chǔ)器多次存取及互鎖裝載指令引起的沖突。有三種情況可以導(dǎo)致這種現(xiàn)象的發(fā)生:①一條指令進(jìn)行存儲(chǔ)操作,隨后一條指令進(jìn)行兩次存儲(chǔ)器讀操作;②一條指令執(zhí)行兩次存儲(chǔ)操作,隨后一條指令至少執(zhí)行一次存儲(chǔ)器讀操作;③執(zhí)行一條互鎖裝載(LDII或LDFI)指令,并且XF?=?1。例5.8一條指令進(jìn)行單次存儲(chǔ)器存取,隨后一條指令進(jìn)行兩次讀操作而引起的流水線沖突。

STF0,*AR1 ;R0→*AR1

LDF*AR2,R1 ;*AR2→R1 ;兩條指令并行執(zhí)行

||LDF*AR3,R2 ;*AR3→R2

這時(shí)會(huì)產(chǎn)生流水線沖突,如圖5.9所示。圖5.9產(chǎn)生流水線沖突(四)本例中,W、X、Y代表具體指令。第一條指令STF對(duì)存儲(chǔ)器進(jìn)行一次寫操作,第二條指令為并行指令,需要對(duì)存儲(chǔ)器進(jìn)行兩次讀操作,由于這個(gè)序列需要第n+3周期中試圖完成三次存儲(chǔ)器數(shù)據(jù)存取,但只允許進(jìn)行兩次存取操作,因此只有在第一條指令STF完成了寫操作后,第二條指令才能開始讀操作數(shù),所以LDF‖LDF指令所需的雙重讀操作將延時(shí)一個(gè)周期。例5.9一條指令并行存儲(chǔ),隨后一條指令進(jìn)行一次讀操作而引起的流水線沖突。

STFR0,*AR0 ;R0→*AR0并行執(zhí)行

‖STFR2,*AR1 ;R2→*AR1

ADDF@SUM,R1 ;R1+@SUM→R1

IACK

ASH

這時(shí)會(huì)產(chǎn)生流水線沖突,如圖5.10所示。圖5.10產(chǎn)生流水線沖突(五)該例中,并行指令LDF‖LDF執(zhí)行時(shí),需要進(jìn)行兩次寫操作,所以在該指令被執(zhí)行的第n+3周期中,不能同時(shí)對(duì)緊隨其后的ADDF指令進(jìn)行讀操作數(shù),只有等待第一條指令執(zhí)行后,第二條指令才能讀操作數(shù)。

例5.10互鎖加載操作引起的流水線沖突。

NOT R1,R0

LDII 300h,AR2

ADDI *AR2,R2

CMPI R0,R2

這時(shí)會(huì)產(chǎn)生流水線沖突,如圖5.11所示。圖5.11產(chǎn)生流水線沖突(六)由于互鎖加載使用XF1引腳作為讀操作完成的響應(yīng),加載可能需要擴(kuò)展讀操作周期。

(4)外部端口操作及條件調(diào)用和條件陷阱引起的沖突。這類流水線沖突的三種情況包括:①因?yàn)橥獠慷丝诿Χ荒軋?zhí)行CPU數(shù)據(jù)加載或存儲(chǔ);②外部加載占用一個(gè)以上周期;③條件調(diào)用和陷阱,二者的執(zhí)行時(shí)間比執(zhí)行條件跳轉(zhuǎn)多一個(gè)周期。例5.11外部端口繁忙引起的流水線沖突。

STFR0,@DMA1

LDF@DMA2,R0

這時(shí)會(huì)產(chǎn)生流水線沖突,如圖5.12所示。圖5.12產(chǎn)生流水線沖突(七)在該例中,W、X、Y代表具體指令。因?yàn)橥獠慷丝诘乃俣容^慢,第一次存儲(chǔ)操作要用兩個(gè)周期才能使CPU把數(shù)據(jù)寫到一個(gè)外部端口,但LDF指令所完成的操作是在同一外部端口上進(jìn)行的一次讀操作,只有等待STF指令執(zhí)行完后,LDF指令才能獲得端口。

例5.12讀操作數(shù)需要多個(gè)CPU周期而引起的流水線沖突。

LDF@DMA,R0

這時(shí)會(huì)產(chǎn)生流水線沖突,如圖5.13所示。圖5.13產(chǎn)生流水線沖突(八)本例中,I、J、K代表具體指令。LDF指令在讀操作數(shù)期間,需要兩個(gè)周期才能完成,從外部的低速存儲(chǔ)器中讀操作數(shù)就是典型的例子。

例5.13條件調(diào)用和陷阱。

條件調(diào)用和陷阱如圖5.14所示。圖5.14條件調(diào)用和陷阱本例中,I代表具體指令。條件調(diào)用(CALLcond)和條件陷阱(TRAPcond)指令不同于其他條件跳轉(zhuǎn)指令,其他條件跳轉(zhuǎn)指令只是完成條件加載操作,而這兩條指令則必須完成條件存儲(chǔ)操作,它們比條件跳轉(zhuǎn)指令多占用一個(gè)周期。調(diào)用條件滿足之后,這個(gè)多占用的附加周期用以將返回地址推入堆棧。5.3.3解除寄存器沖突

在5.3.2節(jié)中曾討論了寄存器引起的流水線沖突的例子,下面結(jié)合例5.14、5.15和5.16給出一些常見的消除流水線沖突的具體方法。

例5.14不產(chǎn)生流水線沖突。第一條指令用AR產(chǎn)生地址,并在指令執(zhí)行前對(duì)ARn的內(nèi)容進(jìn)行調(diào)整,該指令的后面緊隨一條用ARn產(chǎn)生地址的指令。

LDF7.0,R0 ;7.0→R0

MPYF*++AR0(IR1),R0

ADDF*AR2,R0

FIX

MPYF

ADDF

這時(shí)不會(huì)產(chǎn)生流水線沖突,如圖5.15所示。圖5.15不產(chǎn)生流水線沖突(一)例5.15無流水線沖突。流水線序列中的一條指令寫ARn,該指令后面的第三條指令用ARn產(chǎn)生地址。

LDI@TABLE,AR2

MPYF@VALUE,R1

ADDFR2,R1

MPYF*AR2++,R1

SUBF

STF

這時(shí)無流水線沖突,如圖5.16所示。圖5.16無流水線沖突例5.16一條指令對(duì)DP進(jìn)行寫操作,在同一流水線上出現(xiàn)的另一條指令以直接尋址方式對(duì)存儲(chǔ)器進(jìn)行讀操作,避免產(chǎn)生流水線沖突。

LDPTABLE_ADDR

POPR0

LDF*–AR3(2),R1

LDI@TABLE_ADDR,AR0

PUSHF?R6

PUSHR4

這時(shí)不會(huì)產(chǎn)生流水線沖突,如圖5.17所示。圖5.17不產(chǎn)生流水線沖突(二)5.4初始化程序設(shè)計(jì)

在操作DSP硬件系統(tǒng)時(shí)必須先初始化,在大多數(shù)場合,對(duì)使用的寄存器和總線也要進(jìn)行初始化。但若DSP芯片的硬件資源被充分利用,則需要對(duì)處理器初始化。執(zhí)行數(shù)字信號(hào)處理算法以前,必須對(duì)處理器初始化,通常初始化可在復(fù)位后的任何時(shí)候進(jìn)行。復(fù)位后,DSP結(jié)束正在執(zhí)行的程序,跳轉(zhuǎn)到裝載存儲(chǔ)復(fù)位向量的地址,并從該點(diǎn)開始執(zhí)行程序。復(fù)位向量通常包含系統(tǒng)初始化地址。通常初始化程序需要執(zhí)行以下幾個(gè)任務(wù):

(1)設(shè)置數(shù)據(jù)頁指針;

(2)設(shè)置堆棧指針;

(3)設(shè)置中斷向量表;

(4)設(shè)置陷阱向量表;

(5)設(shè)置外部存儲(chǔ)器控制寄存器;

(6)清除/使能高速緩沖存儲(chǔ)器。

如果僅使用匯編環(huán)境,初始化程序在硬件復(fù)位時(shí)執(zhí)行,TMS320C3x初始化的源程序略。

下面給出了兩個(gè)具體的實(shí)例,說明重要寄存器和中斷初始化方法。例5.17DP、SP、ST寄存器和主總線初始化。

init:LDP0,DP ;DP初始化

LDI@STACK,SP;SP初始化

LDI1800H,ST;ST初始化

LDI@MCTL,AR0;MCTL主總線控制寄存器地址

LDIMBUS,R0 ;主總線賦初值

LDIR0,*AR0

MCTL .word808064H

STACK .word809e00H

MBUS .set1038H;主總線設(shè)置初值,插入了1個(gè)等待狀態(tài)例5.18定時(shí)器中斷初始化。

定時(shí)參數(shù)的計(jì)算公式為

定時(shí)參數(shù)=外部時(shí)鐘頻率×?÷?采樣頻率

若采樣頻率為8192?Hz,外部時(shí)鐘頻率為12?MHz,即CPU工作在120?MHz,則定時(shí)參數(shù)設(shè)置為732H。initt0: LDI?0,R0

LDI?808H,AR0

LSH?12,AR0

ADDI?20H,AR0

STI?R0,*+AR0(4)

LDIsample_f,R0, ;設(shè)置采樣頻率周期

STI?R0,*+AR0(8)

LDI?3C1H,R0

STIR0,*AR0

RETS

sample_f.set727H ;根據(jù)VC33的工作時(shí)鐘,設(shè)置采樣頻率

定時(shí)中斷啟動(dòng)語句

LDI100H,IE ;定時(shí)器0中斷使能

LDI2000H,ST;啟動(dòng)定時(shí)器中斷

對(duì)于定時(shí)器、串行口以及DMA控制器的初始化程序在第2章的片內(nèi)外設(shè)一節(jié)已給出,可參閱該部分的內(nèi)容。5.5典型流程控制程序設(shè)計(jì)舉例

5.5.1子程序調(diào)用

TMS320C3x有一個(gè)24位的程序計(jì)數(shù)器(PC)和不受限制的堆??臻g。使用CALL和CALLcond指令調(diào)用子程序時(shí),堆棧指針增加,并且存儲(chǔ)下一個(gè)PC值到堆棧中。在子程序結(jié)束時(shí),RETScond指令執(zhí)行有條件返回操作。例5.19如何用一個(gè)子程序?qū)崿F(xiàn)兩個(gè)矢量的點(diǎn)乘。假定兩個(gè)長度為N的矢量,分別用數(shù)組a[0],a[1],,a[N-1]和b[0],b[1],,b[N-1]表示,點(diǎn)乘由下式計(jì)算:

d?=?a[0]·b[0]?+?a[1]·b[1]?+?…?+?a[N-1]·b[N-1]

在子程序中計(jì)算點(diǎn)乘時(shí),首先假定子程序變量已被適當(dāng)初始化,用CALL指令調(diào)用子程序,傳送控制到執(zhí)行子程序的程序存儲(chǔ)器部分,然后在子程序執(zhí)行完成后,由RETS指令將控制返回到調(diào)用程序。子程序調(diào)用(點(diǎn)乘計(jì)算)LDI@blk0,AR0 ;AR0指向矢量aLDI@blk1,AR1 ;AR1指向矢量bLDIN,RC CALLDOT;點(diǎn)乘方程:d?=?a[0]·b[0]?+?a[1]·b[1]?+?…?+?a[N-1]·b[N-1];AR0a(0)的地址;AR1b(0)的地址;RC——向量N的長度;AR0,AR1,RC為輸入寄存器;R0存放結(jié)果globalDOTDOT:PUSHST ;保存狀態(tài)寄存器PUSHR2 ;將R2內(nèi)容放入堆棧PUSHFR2 ;低32位和高32位PUSHAR0 ;保存AR0內(nèi)容PUSHAR1 ;保存AR1內(nèi)容PUSHRC ;保存RCMPYF3*AR0,*AR1,R0 ;a(0)*b(0)→R0LDF0.0,R2 ;初始化R2SUBI2,RC ;設(shè)置RC

=

N-2;DOTPRODUCT(1<=i<N)RPTSRC ;建立單指令重復(fù)MPYF3*++AR0(1),*++AR1(1),R0 ;a(i)*b(i)→R0||ADDF3R0,R2,R2 ;a(i-1)*b(i-1)+R2→R2ADDF3R0,R2,R0 ;a(N-1)*b(N-1)+R2→R0RETURNSEQUENCEPOPRC ;恢復(fù)RCPOPAR1 ;恢復(fù)AR1POPAR0 ;恢復(fù)AR0POPFR2 ;恢復(fù)R2中的高32位POPR2 ;恢復(fù)R2中的低32位POPST ;恢復(fù)STRETS ;子程序返回.end5.5.2中斷服務(wù)程序

TMS320C3x的中斷是矢量化的,并具有一定的優(yōu)先級(jí)。當(dāng)發(fā)生中斷時(shí),相應(yīng)的標(biāo)記置入中斷標(biāo)志寄存器(IF)中。如果中斷允許寄存器(IE)中的相應(yīng)位已置位,狀態(tài)寄存器中全局中斷使能(GIE)位置1,則中斷使能,開始中斷處理。也可以寫中斷標(biāo)志寄存器(IF),允許用戶用軟件強(qiáng)迫產(chǎn)生一個(gè)中斷或不作任何處理清除中斷。要使中斷正確工作,須執(zhí)行下列步驟:①在合適的存儲(chǔ)器中,創(chuàng)建并放置一個(gè)中斷向量表;②創(chuàng)建軟件堆棧;③使能相應(yīng)的中斷;④使能全局中斷;⑤產(chǎn)生中斷信號(hào)。

1.軟件查詢中斷讀中斷標(biāo)志寄存器的目的是看中斷是否發(fā)生,甚至在中斷禁止時(shí)也可以讀。在中斷驅(qū)動(dòng)接口不工作時(shí),查詢非常有用。例5.20表示外部中斷1不工作時(shí),調(diào)用程序的情況。例5.20軟件查詢中斷的用法。

TITLINTERRUPTPOLLING

TSTB2,IF ;查詢中斷INT1是否發(fā)生

CALLZSUBROUTINE ;如果沒有中斷,調(diào)用子程序當(dāng)中斷處理開始時(shí),程序計(jì)數(shù)器PC被壓入堆棧,中斷向量裝入PC中。中斷可用GIE?=?0禁止,程序可以PC裝入的地址繼續(xù)執(zhí)行。由于所有中斷被禁止,該中斷處理可不被打斷地繼續(xù)執(zhí)行,除非中斷服務(wù)程序重新允許中斷。除了十分簡單的中斷服務(wù)程序以外,在執(zhí)行中斷程序時(shí),保護(hù)好處理器的狀態(tài)是十分重要的。執(zhí)行中斷程序之前,必須保護(hù)狀態(tài),且在中斷程序結(jié)束后要恢復(fù)狀態(tài),這個(gè)過程被稱為上下狀態(tài)轉(zhuǎn)換。上下狀態(tài)轉(zhuǎn)換在子程序調(diào)用時(shí)也十分有用,特別是執(zhí)行子程序要用到輔助寄存器和擴(kuò)展精度寄存器時(shí)。

2.上下狀態(tài)轉(zhuǎn)換當(dāng)處理子程序調(diào)用或中斷時(shí),通常需要上下狀態(tài)轉(zhuǎn)換,它可以很復(fù)雜也可以很簡單,這取決于系統(tǒng)的要求。在TMS320C3x中,程序計(jì)數(shù)器自動(dòng)壓入堆棧,如果要將這些重要信息存放在狀態(tài)寄存器、輔助寄存器和擴(kuò)展精度寄存器中,就必須使用專門的存儲(chǔ)指令。堆棧用來保護(hù)寄存器內(nèi)容,利用PUSH指令向高地址擴(kuò)展。如果不希望用SP指向的堆棧,可用一個(gè)輔助寄存器作為堆棧指針產(chǎn)生另一個(gè)獨(dú)立的堆棧。堆棧中被保護(hù)的寄存器有:擴(kuò)展精度寄存器(R0~R7)、輔助寄存器(AR0~AR7)、數(shù)據(jù)頁指針(DP)、變址寄存器(IR0和IR1)、塊大小寄存器(BK)、狀態(tài)寄存器(ST)、有關(guān)中斷的寄存器(IE和IF)、I/O標(biāo)志(IOF)、有關(guān)重復(fù)的寄存器(RS、RE和RC)。在上下狀態(tài)切換時(shí),僅僅保護(hù)在子程序或者中斷服務(wù)程序中改變的寄存器以及受上下程序影響的寄存器。

3.中斷優(yōu)先級(jí)

TMS320C3x的中斷是自動(dòng)設(shè)置優(yōu)先級(jí)的,允許同時(shí)發(fā)生的中斷按預(yù)定的次序服務(wù),不經(jīng)常出現(xiàn)的而且較長的中斷程序可以被經(jīng)常出現(xiàn)的中斷打斷。例5.21中,INT2的中斷服務(wù)程序臨時(shí)修改中斷允許寄存器IE,這樣當(dāng)發(fā)生INT0中斷(不是別的中斷)時(shí),允許處理INT0的中斷,當(dāng)這個(gè)中斷程序處理結(jié)束時(shí),寄存器IE恢復(fù)到它原來的狀態(tài)。注意:REIT指令不僅從堆棧中彈出下一個(gè)程序計(jì)數(shù)器的地址,同時(shí)也置狀態(tài)寄存器的GIE位,這使所有相應(yīng)的中斷使能。例5.21中斷服務(wù)程序。

.globalISR2

ENABLE.set2000h

MASK.set1

PUSHST;保存狀態(tài)寄存器ST

PUSHDP;保存數(shù)據(jù)頁指針DP

PUSHIE;保存中斷使能寄存器IE

PUSHR0;保存R0的低32位

PUSHFR0;保存R0的高32位

PUSHR1;保存R1的低32位

PUSHFR1;保存R1的高32位LDIMASK,IE;INT0中斷使能ORENABLE,ST;開中斷XORENABLE,ST;關(guān)中斷POPFR1 ;恢復(fù)R1的高32位POPR1 ;恢復(fù)R1的低32位POPFR0 ;恢復(fù)R0的高32位POPR0 ;恢復(fù)R0的低32位POPIE ;恢復(fù)中斷使能寄存IEPOPDP ;恢復(fù)數(shù)據(jù)頁指針DPPOPST ;恢復(fù)狀態(tài)寄存器STRETI ;中斷返回,開中斷5.5.3延時(shí)跳轉(zhuǎn)延時(shí)跳轉(zhuǎn)與非延時(shí)跳轉(zhuǎn)的操作過程是類似的,但是它不刷新流水線,而是執(zhí)行緊跟在延時(shí)跳轉(zhuǎn)指令后的三條指令。緊跟在延時(shí)跳轉(zhuǎn)指令后的三條指令不允許為如下類型:跳轉(zhuǎn)(無延時(shí))、對(duì)子程序調(diào)用、從子程序返回、從中斷返回、重復(fù)指令、軟中斷指令TRAP以及空等待指令I(lǐng)DLE。條件延時(shí)跳轉(zhuǎn)指令所用的條件放在指令后面緊靠延時(shí)跳轉(zhuǎn)符號(hào)D的前面。有時(shí)在程序流中必須跳轉(zhuǎn),但是在延時(shí)跳轉(zhuǎn)指令后又少于三條指令,為快速執(zhí)行,仍可取延時(shí)跳轉(zhuǎn)的優(yōu)點(diǎn)。例5.22中,NOP放在無用指令的位置就是起這作用。當(dāng)然這里采用了一個(gè)折中的方法,即用較少執(zhí)行時(shí)間但用了較多的指令字。例5.22執(zhí)行延時(shí)跳轉(zhuǎn)。

LDF*+AR1(5),R2 ;裝載存儲(chǔ)器的內(nèi)容到R2

BGEDSKIP ;如果裝載值>0,則延時(shí)跳轉(zhuǎn)

LDFNR2,R1 ;如果裝載值<0,則裝載到

R1

SUBF3.0,R1 ;R1-3

NOP ;空操作完成,則執(zhí)行延時(shí)跳轉(zhuǎn)

MPYF1.5,R1

SKIP:LDFR1,R35.5.4重復(fù)操作

TMS320C3x具有不需要增加執(zhí)行時(shí)間的重復(fù)循環(huán)方式,對(duì)應(yīng)有兩條指令:重復(fù)塊程序的RPTB指令和重復(fù)單條指令的RPTS指令。還有三個(gè)控制寄存器:重復(fù)起始地址(RS)、重復(fù)結(jié)束地址(RE)和重復(fù)計(jì)數(shù)器(RC),它們包含循環(huán)執(zhí)行的參數(shù)。

1.塊重復(fù)

例5.23塊重復(fù)結(jié)構(gòu)的應(yīng)用舉例。

在此例中,一個(gè)包含64個(gè)元素的數(shù)組通過交換元素位置而使其倒裝,即數(shù)組單元從末尾開始。換言之,如原始數(shù)組排列為

a[1],a[2],…,a[31],a[32],…,a[64]

則最后數(shù)組的排列為

a[64],…,a[32],a[31],…,a[2],a[1]注意:因?yàn)榻粨Q操作是兩個(gè)元素同時(shí)進(jìn)行的,因此需要32次操作,重復(fù)計(jì)數(shù)器RC初始化為31。通常如RC包含值N,則循環(huán)執(zhí)行N+1次。循環(huán)由RPTB指令和EXCH標(biāo)志所決定。例5.24用塊重復(fù)方式循環(huán)。

LDI@ADDR,AR0 ;AR0指向數(shù)組的開始地

LDIAR0,AR1

ADDI63,AR1 ;AR1指向包含64個(gè)元素

的數(shù)組的結(jié)束地址

LDI31,RC ;初始化塊重復(fù)計(jì)數(shù)器

RPTBEXCH ;從本條指令到EXCH指令之間重復(fù)執(zhí)行32次

LDI*AR0,R0 ;裝載一個(gè)存儲(chǔ)器的元素到

R0

||LDI*AR1,R1 ;裝載另一個(gè)存儲(chǔ)器的元素到

R1

EXCH:STIR1,*AR0++(1) ;交換它們的位置

||STIR0,*AR1--(1)根據(jù)塊重復(fù)結(jié)構(gòu)方式的限制,循環(huán)計(jì)數(shù)器在循環(huán)末端按寄存器RS、RE和RC的內(nèi)容修改,因此不能用其它方法在循環(huán)末端修改重復(fù)計(jì)數(shù)器或程序計(jì)數(shù)器。原則上塊重復(fù)程序是可以嵌套的。然而,因?yàn)閮H有一組控制寄存器RS、RE和RC,因而在進(jìn)行內(nèi)循環(huán)之前必須保存這些寄存器。也可以將寄存器作為一個(gè)計(jì)數(shù)器,并用延時(shí)跳轉(zhuǎn),而不用重復(fù)塊嵌套。例5.25用塊重復(fù)程序找147個(gè)數(shù)中的最大值。LDI146,RC ;初始化塊重復(fù)計(jì)數(shù)器RC=146LDI@ADDR,AR0 ;AR0指向數(shù)組的開始地址LDF*AR0++(1),R0 ;初始化最大值為第一個(gè)數(shù)

RPTBLOOPCMPF*AR0++(1),R0 ;與最大值比較LOOP: LDFLT*+AR0(1),R0 ;如果大于前一最大值,則設(shè)置為新的最大值

2.單指令重復(fù)和塊重復(fù)方式相同,單指令重復(fù)操作也用控制寄存器RS、RE和RC,塊重復(fù)的優(yōu)點(diǎn)是指令僅取一次,然后總線供搬移數(shù)據(jù)使用。單指令重復(fù)和塊重復(fù)程序的不同之處是單指令重復(fù)不可中斷,而塊重復(fù)允許中斷。例5.26用單指令重復(fù)方式循環(huán)。在本例中計(jì)算兩個(gè)數(shù)組相應(yīng)元素乘積的和。設(shè)數(shù)組為a[i]和b[i],長度都為N=512,計(jì)算結(jié)果放在寄存器R0中。d?=?a[1]·b[1]?+?a[2]·b[2]?+?…?+?a[N]·b[N]在指令中重復(fù)計(jì)數(shù)器RC的值定為511,則循環(huán)執(zhí)行512次。LDI@ADDR1,AR0 ;AR0指向數(shù)組a(i)LDI@ADDR2,AR1 ;AR1指向數(shù)組b(i)LDF0.0,R0 ;初始化R0MPYF3*AR0++(1),*AR1++(1),R1 ;計(jì)算第一個(gè)值并放入R1RPTS511 ;重復(fù)512次MPYF3*AR0++(1),*AR1++(1),R1 ;計(jì)算下一個(gè)值||ADDF3R1,R0,R0 ;并與前一個(gè)值相加ADDFR1,R0 ;在R0中存放最后的結(jié)果5.5.5位操作

1.位管理

TMS320C3x的普通邏輯運(yùn)算指令(如AND、OR、NOT、ANDN和XOR等)和位移指令結(jié)合起來可用于位管理。此外,還有用來測試位的特殊指令TSTB、TSTB和AND,但AND的結(jié)果不寫入任何寄存器僅用來作為條件標(biāo)志。例5.27和例5.28說明用于位管理和測試的幾條指令。例5.27STB指令用于軟件控制中斷。

TSTB0100b,IF;查詢IF的第2位是否為1

CALLNZINTR;如果是,調(diào)用INTR子程序例5.28將一個(gè)寄存器的某一位移至另一個(gè)寄存器的另一位。;R1中的第I位復(fù)制到R2中的第J位(見圖5.18)

LDI1,R0

LSH*AR0,R0 ;將1移到第I位

TSTBR1,R0 ;查詢R1中的第I位BZDCOUNT;如果第I位等于0,則執(zhí)行延時(shí)跳轉(zhuǎn)LDI1,R0LSH*+AR0(1),R0;將1移到第J位ANDNR0,R2;如果第J位為0,則復(fù)位R2中的第J位ORR0,R2;如果第J位為1,則置位R2中的第J位COUNT…圖5-18位操作示意圖

2.位反轉(zhuǎn)尋址

TMS320C3x具有位反轉(zhuǎn)尋址的能力,可有效地實(shí)現(xiàn)快速傅里葉變換(FFT)。若數(shù)據(jù)以正確的次序傳送,F(xiàn)FT的最后結(jié)果的次序是打亂的(位反轉(zhuǎn)的次序)。為使頻域數(shù)據(jù)以正確次序排列,某些存儲(chǔ)器位置應(yīng)作相應(yīng)的交換。位反轉(zhuǎn)尋址方式提供了不必作交換的方法,即下一次所需存取的數(shù)據(jù)是以位反轉(zhuǎn)方式存取而不是順序存取。位反轉(zhuǎn)尋址的基地址必須位于循環(huán)尋址空間的起始位置。比如,若IR0?=?2n-1,則基地址的最低有效位的零的個(gè)數(shù)n必須滿足2n?>?R,R是循環(huán)尋址空間的大小。在位反轉(zhuǎn)尋址方式中,如實(shí)部和虛部數(shù)據(jù)存在分開的數(shù)組中,則IR0的內(nèi)容是FFT點(diǎn)數(shù)的一半。輔助寄存器尋址由IR0變址完成,但變址是反向進(jìn)位的。例5.29說明了512點(diǎn)復(fù)數(shù)FFT數(shù)據(jù)移動(dòng)的情況,計(jì)算結(jié)果從計(jì)算的位置(AR0指向的位置)移到AR1指向的位置。在本例中,數(shù)據(jù)的實(shí)部XR(i)和虛部XI(i)不是存放在兩個(gè)獨(dú)立的數(shù)組中,而是在一個(gè)數(shù)組中交替存儲(chǔ),由于這樣的排列,數(shù)組長度是2N,而不是N,即IR0的內(nèi)容為512而不是256。排列的順序?yàn)椋篨R(0),XI(0),XR(1),XI(1),…,XR(N-1),XI(N-1)。例5.29位反轉(zhuǎn)尋址。

LDI512,IR0

LDI2,IR1

LDI511,RC ;設(shè)置RC=511

LDF*+AR0(1),R1;裝載第一個(gè)虛部

RPTBLOOP

LDF*AR0++(IR0)B,R0;裝載實(shí)部(指向下一個(gè)位置)

|STFR1,*+AR1(1) ;存儲(chǔ)虛部

LOOP: LDF*+AR0(1),R1;裝載下一個(gè)虛部

||STFR0,*AR1++(IR1) ;并且保存前一個(gè)實(shí)部5.5.6數(shù)據(jù)塊轉(zhuǎn)移由于TMS320C3x可直接尋址大量存儲(chǔ)器,因此數(shù)據(jù)塊或程序塊可存儲(chǔ)在片外低速存儲(chǔ)器中,然后裝入片內(nèi)高速RAM中快速執(zhí)行,數(shù)據(jù)也可從片內(nèi)移到片外以存儲(chǔ)數(shù)據(jù)或作多處理器間的數(shù)據(jù)傳輸。使用DMA在不影響CPU工作的情況下可以進(jìn)行數(shù)據(jù)的直接傳輸,也可以在重復(fù)方式下用裝入和存儲(chǔ)指令來代替DMA進(jìn)行數(shù)據(jù)傳輸。例5.30是512個(gè)浮點(diǎn)數(shù)從外部存儲(chǔ)器傳送到片內(nèi)RAM的情況。例5.30在程序控制下的塊傳送。

extern.word01000h

block1.word0809C00h…

LDI@extern,AR0;源地址

LDI@block1,AR1;目的地址

LDF*AR0++,R0;裝載第一個(gè)數(shù)

RPTS510;下一條指令重復(fù)511次

LDF*AR0++,R0;裝載下一個(gè)數(shù)

||STFR0,*AR1++;存儲(chǔ)前一個(gè)數(shù)

STFR0,*AR1;存儲(chǔ)后一個(gè)數(shù)5.6算術(shù)運(yùn)算和數(shù)據(jù)轉(zhuǎn)換程序設(shè)計(jì)5.6.1整數(shù)和浮點(diǎn)數(shù)除法在TMS320C3x中,除法雖不是用單條指令實(shí)現(xiàn)的,但單指令集可以實(shí)現(xiàn)除法程序。整數(shù)除法和浮點(diǎn)數(shù)除法使用的算法不同,整數(shù)除法利用減法指令SUBC重復(fù)進(jìn)行來完成,而浮點(diǎn)數(shù)除法采用倒數(shù)的方法實(shí)現(xiàn)。在第3章中,浮點(diǎn)數(shù)除法已有敘述,在此只給出整數(shù)除法的算法。

TMS320C3x實(shí)現(xiàn)除法是用SUBC這條特殊減法指令重復(fù)進(jìn)行來完成的,考慮i位有效位(32-i位符號(hào)位)的32位正整數(shù),SUBC指令重復(fù)i-j+1次產(chǎn)生32位結(jié)果,這里低i-j+1位為商數(shù),高31-i?+?j位為除法余數(shù)。

SUBC實(shí)現(xiàn)除法和長除法的方式是一樣的。除數(shù)(假定小于被除數(shù))左移i-j位和被除數(shù)對(duì)準(zhǔn),然后用SUBC指令移動(dòng)除數(shù)從被除數(shù)中減去。若每一次減法的結(jié)果不為負(fù),則被除數(shù)用減法差值代替后,左移1位,且其中最低位放1;若結(jié)果為負(fù),則被除數(shù)簡單地左移1位,整個(gè)操作重復(fù)i-j+1次。比如33被5除的情況,這時(shí)i?=?6,j?=?3,SUBC操作重復(fù)6-3+1?=?4次。當(dāng)用SUBC命令時(shí),除數(shù)和被除數(shù)均為正。例5.31整數(shù)除法。;R1輸入除數(shù);R0輸入被除數(shù);輸出結(jié)果R0/R1

.globalDIVISIGN.setR2TEMPF.setR3TEMP.setIR0COUNT.setIR1XORR0,R1,SIGN;取符號(hào)ABSIR0ABSIR1CMPIR0,R1;比較:除數(shù)>被除數(shù)嗎BGTDZERO;成立,則跳至ZERO標(biāo)號(hào)執(zhí)行FLOATR0,TEMPF;歸一化被除數(shù)PUSHFTEMPF;以浮點(diǎn)格式壓入堆棧POPCOUNT;以整型彈出堆棧LSH-24,COUNT;取被除數(shù)的指數(shù)FLOATR1,TEMPF;歸一化除數(shù)PUSHFTEMPF;以浮點(diǎn)格式壓入堆棧POPTEMP;以整型彈出堆棧LSH-24,TEMP;取除數(shù)的指數(shù)SUBITEMP,COUNT;被除數(shù)指數(shù)和除數(shù)指數(shù)相減LSHCOUNT,R1;除數(shù)移位,移動(dòng)位數(shù)為指數(shù)差值RPTSCOUNTSUBCR1,R0SUBRI31,COUNT;移位(32-(COUNT+1))LSHCOUNT,R0;左移NEGICOUNTLSHCOUNT,R0;右移取結(jié)果NEGIR0,R1;結(jié)果取反ASH-31,SIGN;核對(duì)符號(hào)LDINZR1,R0;如果是1,用取反的結(jié)果CMPI0,R0;從結(jié)果設(shè)置狀態(tài)寄存器中的標(biāo)志位RETS;RETURNZERO:LDI0,R0RETS.end若被除數(shù)小于除數(shù),則要進(jìn)行分?jǐn)?shù)除法,當(dāng)確定商數(shù)精度為多少位之后,可以進(jìn)行這種除法。若希望商數(shù)精度為K位,開始先將被除數(shù)移K位,然后用上面的方法即可,但i應(yīng)為i+k代替,i+k小于32。5.6.2平方根

TMS320C3x計(jì)算平方根所用的迭代方法十分類似于計(jì)算倒數(shù)所用的方法,此方法計(jì)算數(shù)值v平方根的倒數(shù),即1/,由此可以求出平方根()等于這個(gè)倒數(shù)(1/)與原數(shù)值(v)相乘。在第i次迭代中,1/的估算值X[i]由v和前一估算值X[i-1]通過下列公式計(jì)算:

X[i]=X[i-1]×(1.5-(v/2)×X[i-1]×X[i-1])開始運(yùn)算時(shí)需要一個(gè)初始值X[0]。若v=a×2e,初始值可以近似為:X[0]=1.0×2-e/2。例5.32是在TMS320C3x上實(shí)現(xiàn)此方法的例子,這里迭代需要進(jìn)行5次。同樣地,迭代次數(shù)的選擇取決于所要求的精度。例5.32浮點(diǎn)數(shù)的平方根計(jì)算。

LDFv,R0

CALLSQRT;R0存放v和最后的結(jié)果SQRT(v)

.globalSQRT

SQRT: LDFR0,R3;保存v

RETSLE ;如果是非正數(shù),則返回

PUSHFR0POPR1ASH-24,R1 ;取v的指數(shù)放入R1中ADDI1,R1ASH–1,R1 ;R1=e/2NEGIR1ASH24,R1PUSHR1POPFR1 ;R1=x[0]=1.0*2**(-e/2)MPYF0.5,R0 ;R0=v/2MPYFR1,R1,R2 ;R2=x[0]*x[0]MPYFR0,R2 ;R2=(v/2)*x[0]*x[0]SUBRF1.5,R2 ;R2=1.5-(v/2)*x[0]*x[0]MPYFR2,R1 ;R1=x[1]=x[0]*(1.5-(v/2)*x[0]*x[0])RNDR1MPYFR1,R1,R2 ;R2=x[1]*x[1]MPYFR0,R2 ;R2=(v/2)*x[1]*x[1]SUBRF1.5,R2 ;R2=1.5-(v/2)*x[1]*x[1]MPYFR2,R1 ;R1=x[2]=x[1]*(1.5-(v/2)*x[1]*x[1])RNDR1MPYFR1,R1,R2 ;R2=x[2]*x[2]MPYFR0,R2 ;R2=(v/2)*x[2]*x[2]SUBRF1.5,R2 ;R2=1.5-(v/2)*x[2]*x[2]MPYFR2,R1 ;R1=x[3]=x[2]*(1.5-(v/2)*x[2]*x[2])RNDR1MPYFR1,R1,R2 ;R2=x[3]*x[3]MPYFR0,R2 ;R2=(v/2)*x[3]*x[3]SUBRF1.5,R2 ;R2=1.5-(v/2)*x[3]*x[3]MPYFR2,R1 ;R1=x[4]=x[3]*(1.5-(v/2)*x[3]*x[3])RNDR1MPYFR1,R1,R2 ;R2=x[4]*x[4]MPYFR0,R2 ;R2=(v/2)*x[4]*x[4]SUBRF1.5,R2 ;R2=1.5-(v/2)*x[4]*x[4]MPYFR2,R1 ;R1=x[5]=x[4]*(1.5-(v/2)*x[4]*x[4])RNDR1,R0 ;R1中擴(kuò)展精度浮點(diǎn)數(shù)轉(zhuǎn)換為單精度浮點(diǎn)數(shù), ;并放入R0MPYFR3,R0 ;得出RETS.end5.6.3擴(kuò)展精度算法

TMS320C3x提供了32位精度整數(shù)算法和24位尾數(shù)精度的浮點(diǎn)算法。為提高浮點(diǎn)運(yùn)算的精度,8個(gè)擴(kuò)展精度寄存器R0~R7包含8位附加精度位。對(duì)于定點(diǎn)運(yùn)算,因?yàn)闆]有和上述浮點(diǎn)算法相類似的擴(kuò)展方法,所以本節(jié)將討論如何運(yùn)用處理器來實(shí)現(xiàn)定點(diǎn)雙精度算法。實(shí)現(xiàn)本算法的技術(shù)就像普通算法那樣,指令組中有ADDC(帶進(jìn)位位加法)和SUBB(帶借位位減法)指令,可用進(jìn)位位來實(shí)現(xiàn)擴(kuò)展精度算法,進(jìn)位位受ALU運(yùn)算指令和循環(huán)移位指令影響,它也可通過對(duì)狀態(tài)寄存器的相應(yīng)位直接置值來管理。為了操作更合理,溢出方式應(yīng)該復(fù)位(OVM=0),使累加器的結(jié)果不裝入飽和溢出值。例5.33和例5.34是64位加法和64位減法的例子,第一個(gè)操作數(shù)存在寄存器R0(低位字)和R1(高位字)中,第二個(gè)操作數(shù)分別在R2和R3中,結(jié)果存在R0和R1中。例5.3364位加法。;R0存放數(shù)X的低位字;R1存放數(shù)X的高位字;R2存放數(shù)Y的低位字;R3存放數(shù)Y的高位字;R1R0存放結(jié)果

ADDIR2,R0

ADDCR3,R1例5.3464位減法。;R0存放數(shù)X的低位字;R1存放數(shù)X的高位字;R2存放數(shù)Y的低位字;R3存放數(shù)Y的高位字;R1R0存放結(jié)果

SUBIR2,R0

SUBBR3,R1當(dāng)兩個(gè)32位數(shù)相乘時(shí),得到64位乘積,乘法的方法是將被乘數(shù)X和乘數(shù)Y的32位分別分成兩部分(X1,X0)和(X3,X2),每部分16位。運(yùn)算是對(duì)無符號(hào)數(shù)進(jìn)行的,乘積對(duì)符號(hào)位調(diào)準(zhǔn)。例5.35是32位乘32位的例子。例5.3532位乘32位乘法。.globalEXTMPYEXTMPY:XOR3R0,R1,AR0 ;存儲(chǔ)符號(hào)ABSIR0 ;取X的絕對(duì)值A(chǔ)BSIR1 ;取Y的絕對(duì)值LDI16,AR1LSH3AR1,R0,R2 ;R2=X1(X的高16位)AND0FFFFH,R0 ;R0=X0(X的低16位)LSH3AR1,R1,R3 ;R3=Y1(Y的高16位)AND0FFFFH,R1 ;R1=Y0(Y的低16位)MPYI3R0,R1,R4 ;X0*Y0=P1MPYIR3,R0 ;X0*Y1=P2MPYIR2,R1 ;X1*Y0=P3ADDIR0,R1 ;P2+P3MPYIR2,R3 ;X1*Y1=P4LDIR1,R2LSH16,R2 ;P2+P3的低16位CMPI0,AR0 ;核對(duì)乘積的符號(hào)BGEDDONE ;如果>0,乘法完成延時(shí)LSH–16,R1 ;P2+P3的高16位ADDI3R4,R2,R0 ;W0=R0(乘積的低字節(jié))ADDC3R1,R3,R1 ;W1=R1(乘積的低字節(jié))NOTR0ADDI1,R0NOTR1ADDC0,R1DONERETS.end5.7典型的信號(hào)處理算法程序設(shè)計(jì)

5.7.1壓擴(kuò)在遠(yuǎn)程通信領(lǐng)域中,主要關(guān)心的問題之一是在一定的通道帶寬下保持高的語音質(zhì)量,這可以通過對(duì)語音采樣的對(duì)數(shù)量化來實(shí)現(xiàn),一個(gè)8位的對(duì)數(shù)量化器產(chǎn)生的語音質(zhì)量相當(dāng)于13位均勻量化器產(chǎn)生的語音質(zhì)量。對(duì)數(shù)量化用COMPAND(COMpress/exPANDing的縮寫,合起來意為壓擴(kuò))來實(shí)現(xiàn),現(xiàn)在已經(jīng)建立了壓擴(kuò)的兩個(gè)國際標(biāo)準(zhǔn):μ律(用于美國和日本)和A律(用于歐洲)。對(duì)數(shù)量化器是用符號(hào)的幅度形式表示的,在發(fā)送時(shí)沿通信通道傳送。在做了必要的處理后,這些數(shù)據(jù)應(yīng)擴(kuò)展為14位(μ律)或13位(A律)的線性格式。當(dāng)數(shù)據(jù)在數(shù)字信號(hào)處理器中接收后,這些操作開始執(zhí)行。數(shù)據(jù)處理后,被壓縮回8位格式并在通道中連續(xù)傳送。例5.36和例5.37是μ律壓縮和擴(kuò)展程序(即線性到μ律和μ律到線性的轉(zhuǎn)換),例5.38和例5.39是A律壓縮和擴(kuò)展程序。對(duì)于擴(kuò)展可用查表法,查表法折中了存儲(chǔ)空間和執(zhí)行速度的矛盾。由于壓縮后的數(shù)據(jù)是8位字長,因此256項(xiàng)的數(shù)據(jù)表足以包含擴(kuò)展數(shù)據(jù)。比如壓縮數(shù)據(jù)存儲(chǔ)在AR0中,下面兩條指令將擴(kuò)展數(shù)據(jù)放在寄存器R0中:

ADDI@TABL,AR0;@TABL是表基地址

LDI*AR0,R0 ;擴(kuò)展數(shù)據(jù)放在R0中例5.36μ律壓縮。

R0 ;存放被轉(zhuǎn)換的數(shù)據(jù)和最后結(jié)果

.globalMUCMPR

MUCMPR:LDIR0,R1;保存被壓縮數(shù)據(jù)的符號(hào)

ABSIR0,R0

CMPI1FDEh,R0;判斷R0>0x1FDE?

LDIGT1FDEh,R0;若上述判斷成立,則保存這個(gè)結(jié)果

ADDI33,R0 ;加偏置量

FLOATR0 ;歸一化

MPYF0.03125,R0;調(diào)整區(qū)段號(hào)2**(-5)LSH1,R0 ;左移一位PUSHFR0POPR0 ;R0以整型彈出LSH-20,R0 ;R0右移LDI0,

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論