|
Les processeurs
pour le traitement du signal |
D'une façon générale les microprocesseurs de traitement du signal récents sont dotés :



L'arithmétique bit reverse permet de gérer des buffers circulaires avec addition reverse (arithmétique modulo N).
Exemple : le TMS320C30 dispose d'un mode d'adressage permettant d'accéder à un tableau de N éléments dans un ordre bit reverse. Ce mode d'adressage indirect utilise comme pointeur un des registre ARn (n=0 à 7). Celui-ci reçoit l'adresse de base du tableau en mémoire et doit donc commencer à une adresse multiple de N. Le registre d'index IR0 reçoit N/2. La construction de l'adresse est alors notée : *ARn++(IR0)B
Si l'on suppose que N=8 et que l'adresse du tableau est donnée par AR1=1100 1000, les instructions successives *AR1++(IR0)B vont engendrer pour AR1 les valeurs suivantes :
AR1 = 1100 1000, 1100 1100, 1100 1010, 1100 1110, ...
On note le renversement binaire effectué sur les trois bits de poids faible. Considérons en exemple un renversement binaire(2) (bit reversal) sur un tableau. Celui-ci peut être réalisé de la façon suivante :
LDI @N,RC ; N = taille de la FFT
SUB 1,RC ; on va de 0 à N-1
LDI @N, IR0
LSH -1,IR0 ; IR0=N/2
LDI @tab,AR0 ; adresse tableau
LDI @tab,AR1
RPTB boucle ; on répète la boucle
CMPI AR0,AR1 ; on ne permute que si AR0<AR1
BGE suite ; la première fois, on va à suite
;
LDF *AR0,R0 ; échange -------------------
|| LDF *AR1,R1 ; instruction parallèle
STF R0,*AR1
|| STF R1,*AR0 ; instruction parallèle -----
suite: NOP *AR0++
boucle: NOP *AR1++(IR0)B ; calcul adresse avec renversement

Les données xi et les coefficients
du filtre hi sont rangés en mémoire X et Y
respectivement à partir d'un multiple entier de 2m
où 2m>=N. A chaque registre Ri
est associé un registre Mi dont le contenu joue sur le mode
d'adressage : si Mi est nul l'adressage est fait en mode bit
reverse, s'il est égal à $FFFF l'adressage est
linéaire, sinon l'adressage se fait modulo (Mi)+1.

mov #N-1,m0 ; on initialise les m0 et m4
mov m0,m4 ; (registres modulo)
mov #xAdr,r0 ; r0 et r4 servent de pointeur
mov #hAdr,r4 ; dans les mémoires X et Y; instruction parallèle : l'accumulateur A est mis à zéro et on ; transfère les deux premiers mots (xn et h0) dans les registres X0 et Y0 ; du multiplicateur clr a x:(r0)+,x0 y:(r4)+,y0 rep #N-1 ; on répète la multiplication/ ; accumulation N-1 fois mac x0,y0,a x:(r0)+,x0 y:(r4)+,y0
macr x0,y0,a ; dernière multiplication/accumulation ; assortie d'un arrondi sur le résultat

La
programmation de cette convolution donne lieu sur processeur Texas
320C25 aux instructions suivantes :
CNFP ; configure le bloc B0 en mémoire de progr.Après chaque multiplication-accumulation la donnée pointée par le registre d'indirection (ici AR1) est décalée d'une case mémoire (adresse+1).
LARP AR1 ; registre d'indirection = AR1
LRLK AR1,>3FF ; AR1 pointe sur la fin du bloc B1 (données)
; rangés dans l'ordre X(n) à X(n-N+1)
RPTK n ; n=N-1
MACD >FF00,*- ; on utilise un registre auxiliaire
; d'indirection. >FF00 = adresse des coeff.
; rangés de h(N-1) à h(0)
APAC ; derniere accumulation
Considérons donc l'organisation suivante des données avant MACD :

- Situation initiale :






et
et de cinq instructions permettant de lire (LDFI
pour lecture d'un nombre flottant et LDII pour un entier),
écrire (SDFI et STII) ou de se synchroniser (SIGI)
:
. La lecture effective s'effectue
lorsque
et
sont à zéro. L'attente de ces deux signaux s'effectue par
insertion de Wait States dans le cycle instruction. Le seul cas
où les lignes
et
ne sont pas utilisées est le cas
où l'accès se fait sur la mémoire interne.
L'accès aux unités périphériques internes
donne lieu aussi à synchronisation. LDFI et LDII
sont interruptibles pendant l'attente sur
,
à la condition que
soit à
zéro. Ceci permet de se sortir de situations éventuelles
d'interblocage (deadlocks).
. L'écriture a lieu lorsque la
ligne
passe à zéro. Les
instructions STFI et STII sont indivisibles
(ininterruptibles).
puis passe en
attente jusqu'à ce que la ligne
passe à 0. En fin de cycle,
est mis
à 1. SIGI est interruptible sous les mêmes
conditions que LDII et LDFI. Il permet d'affectuer la
synchronisation des traitements de deux processeurs directement
connectés.
peut
être programmée directement par accès au registre
IOF. Ainsi l'instruction OR 4,IOF force la ligne
à 1.
Ces instructions permettent d'assurer une exclusion mutuelle dans l'accès à la mémoire partagée par réalisation de technique d'attente active ou de sémaphores.
La première opération, dans une conversion entier vers flottant, est la normalisation. Ainsi, chez Analog Devices, l'instruction norm permet-elle d'effectuer un décalage "vers la gauche" d'un nombre de fois égal au "nombre de bits de signe moins 1". Ce nombre est fourni par l'instruction exp (une autre instruction - block exponent adjust - facilite la recherche du plus grand exposant dans un ensemble de valeur : expadj).
Exemple :
SE = EXP AR0 (HI); charge le registre SE avec la valeurSi au départ on a 1111 1100 1010 0000 (-86410), SE est chargé avec la valeur -5 et le résultat obtenu est 1001 0100 0000 0000 0000 0000 0000 0000.
; de l'exposant
; (en fait sa valeur opposée) de AR0
SR = NORM SI (HI); fait la normalisation
Exemple("Analog Devices-ADSP-2100, Applications Handbook Vol.1") : un nombre codé en flottant simple précision au standard IEEE-754 a le format suivant :
correspondant à
où <signe> est codé sur 1 bit, <exposant> sur 8 bits et <mantisse> sur 23 bits.
La représentation virgule fixe généralement utilisée est désignée par le sigle "1.15" soit 1 chiffre avant la virgule, qui correspond au bit de signe, et 15 chiffres après, le tout en complément à 2. Les nombres x ainsi codés correspondent à la plage de valeurs :
Le passage en flottant consiste à :
Les deux cas traîtés à part sont les valeurs 0 et -1. AX0 contient la donnée en virgule fixe. En sortie on a dans SR1 (poids fort) et SR0 (poids faible) le code flottant.
vf2flot : AY0=H#8000; {cas du -1}
AY1=126; {pour le codage de l'exposant}
AR=AX0-AY0; {AX0 =? -1}
IF NE JUMP pasm1;
AR=H#BF80; {codage de -1}
SR=LSHIFT AR BY 0 (HI);
RTS;
pasm1: AR=PASS AX0;
AF=ABS AR;
IF NE JUMP pas0;
SR=LSHIFT AR BY 0 (HI);
RTS;
pas0: IF NEG JUMP negatif;
SI=H#0000; {bit de signe a 0}
JUMP suite;
negatif: SI=H#8000; {bit de signe a 1}
suite: AR=PASS AF;
SE=EXP AR (HI);
SR=NORM AR (HI);
AX1=SE;
AR=AX1+AY1; {exposant+126}
SR=LSHIFT SR1 BY +2 (HI); {bit de signe et bit cache a 0}
SR=LSHIFT SR1 BY -9 (HI); {champ signe et exposant}
SR=SR OR LSHIFT SI BY 0 (HI);
SR=SR OR LSHIFT AR BY 7 (HI);
RTS
Exemple : soit la valeur -0,510=1,100...0 en virgule fixe
1.15. Le traitement précédent donne :

Exemple : le TMS320C40 est doté de trois instructions de branchement retardés : BcondD (branchement conditionnel) , BRD (branchement inconditionnel) et DBcondD (décrément et branchement conditionnel). Les trois instructions (k=3) qui suivent sont obligatoirement exécutées. Aucune d'elle ne doit être un branchement, au risque de laisser le pipe-line dans un état imprévisible.

Exemple : considérons la suite d'instructions suivante dans les microprocesseurs TMS320C30 ou TMS320C40 :
LDI *AR0,R0 ; LDI src1(INDIRECTION),dst1(REGISTRE)La première instruction utilise une indirection sur le registre d'adresse AR0; la seconde une indirection avec pré-déplacement de 1 sur AR0. Ces deux instructions sont simultanément codées sur un même mot de 32 bits de la façon suivante :
|| LDI *+AR0(1),R1 ; LDI src2(INDIRECTION),dst2(REGISTRE)
31 | 29 | 24 | 21 | 18 | 15 | 10 | 7 | 2Exemple : sur le même processeur :
-------------------------------------------------------------------------------
1 1 | 0 0 0 1 1 | 0 0 0 | 0 0 1 | 0 0 0 | 0 0 0 0 0 | 0 0 0 | 1 1 0 0 0 | 0 0 0
-------------------------------------------------------------------------------
| op. | src1 | | src2 | mode | reg. | mode | reg.
-------------------------------------------------------------------------------
| | | | | dest2 | dest1
-------------------------------------------------------------------------------
|| | LDI | R0 | R1 | | *+AR0(1) | *AR0
STI R1,*AR0 ; STI src1(REGISTRE),dst1(INDIRECTION)La première instruction utilise une indirection sur le registre d'adresse AR0; la seconde une indirection sur AR0 avec pré-indexation sur IR1.
|| STI R4,*+AR1(IR1) ; STI src2(REGISTRE),dst2(INDIRECTION)
31 | 29 | 24 | 21 | 18 | 15 | 10 | 7 | 2Exemple : sur le même processeur :
-------------------------------------------------------------------------------
1 1 | 0 0 0 0 1 | 0 0 1 | 0 0 0 | 1 0 0 | 1 0 0 0 0 | 0 0 1 | 1 1 0 0 0 | 0 0 0
-------------------------------------------------------------------------------
| op. | src1 | | src2 | mode | reg. | mode | reg.
-------------------------------------------------------------------------------
| | | | | dest2 | dest1
-------------------------------------------------------------------------------
|| | STI | R1 | | R4 | *+AR1(IR1) | *AR0
STF R0,*+AR0(1) ; STF src1(REGISTRE),dst1(INDIRECTION)La première instruction utilise une indirection sur le registre d'adresse AR0 avec pré-deplacement de 1; la seconde une indirection sur AR0 avec post-indexation sur IR0 et modification de AR0.
|| STF R0,*AR0++(IR0) ; STF src2(REGISTRE),dst2(INDIRECTION)
31 | 29 | 24 | 21 | 18 | 15 | 10 | 7 | 2Exemple : nous avons vu dans le DSP56000 un exemple d'instruction parallèle où l'on fait simultanément une mise à zéro de l'accumulateur A et deux transferts. Le codage de cette instruction se fait en un mot de 24 bits. Le pipe-line du DSP56000 est dit visible. Il faut prendre en compte les problèmes d'accès à la mémoire (il faut un cycle de plus) et de conflits de dépendance. Le pipe-line possède trois niveaux : fetch, decode, execute. Le calcul des adresses se fait pendant la phase de décodage.
-------------------------------------------------------------------------------
1 1 | 0 0 0 0 0 | 0 0 0 | 0 0 0 | 0 0 0 | 0 1 1 0 0 | 0 0 0 | 0 0 0 0 0 | 0 0 0
-------------------------------------------------------------------------------
| op. | src1 | | src2 | mode | reg. | mode | reg.
-------------------------------------------------------------------------------
| | | | | dest2 | dest1
-------------------------------------------------------------------------------
|| | STI | R0 | | R0 | *AR0++(IR0) | *+AR0(1)
1. Dans le premier cas, la séquence suivante :
clr a x:(r0)+,y0pose un problème d'accès à la mémoire X. La programmation doit en être :
move x:(r3)+,x0
clr a x:(r0)+,y0pour indiquer qu'on laisse une phase de retard.
move x:(r3)+,x0
2. Dans le second cas, une séquence telle que :
move x0,r1provoque un conflit dû au fait que l'exécution du transfert x0->r1 et le calcul d'adresse x:(r1) se font dans la même phase. La séquence doit être programmée :
move x:(r1),a
move x0,r1
nop ; ou tout autre instruction n'entrant pas en
; conflit avec la suivante.
move x:(r1),a

Exemple : le TMS320C40 est doté d'un cache de 128 mots de 32 bits. Il est organisé comme un cache à accès direct avec une ligne de 32 mots. Sa particularité provient du fait que la mise à jour se fait sur la base du mot et non de la ligne de 32 mots. Chaque mot est accompagné d'un bit de validité (ici appelé Present Bit).
