# Processeur de signal numérique

Un Processeur de signal numérique (de l'anglais « Digital Signal Processor » DSP), qu'on pourrait traduire par « processeur de signal numérique », « processeur de traitement de signal numérique » ou « processeur de traitement numérique de signal ») est un microprocesseur optimisé pour exécuter des applications de traitement numérique du signal (filtrage, extraction de signaux, etc.) le plus rapidement possible.
Les DSP sont utilisés dans la plupart des applications du traitement numérique du signal en temps réel. On les trouve dans les modems (modem RTC, modem ADSL), tout type d'appareil audio électronique, les téléphones mobiles, les appareils multimédia (lecteur MP3), les récepteurs GPS… Ils sont également utilisés dans des systèmes vidéo, les chaînes de traitement de son, partout où l'on reçoit un signal complexe que l'on doit modifier à l'aide du filtrage. Au début des années 1990, ils avaient été utilisés dans certains ordinateurs comme le NeXT Cube et l'Atari Falcon.

## Traitement numérique du signal

Le traitement numérique du signal implique la réalisation de nombreuses opérations mathématiques. En comparaison, un logiciel de traitement de texte ou une base de données va plutôt passer son temps à manipuler des données en mémoire. Cela implique que des ordinateurs conçus pour la bureautique ou d'autres applications générales ne sont pas optimisés pour exécuter des algorithmes de traitement du signal, comme le filtrage numérique ou la réalisation d'une analyse de Fourier.
| | Manipulation de données | Calculs mathématiques |
| Applications typiques | Traitement de texte Base de données Tableur Système d'exploitation | Traitement numérique du signal Contrôle de vitesse Simulation scientifique Simulation électronique |
| Opérations principales | Mouvement de données (A → B) Test de condition (si A=B alors …) | Addition (A + B = C) Multiplication (A x B = C) |
En ce qui concerne les filtres, les DSP en simplifient grandement la réalisation pour plusieurs raisons :
* résultat prédictible et hautement répétable (caractéristique des circuits numériques, par opposition aux circuits analogiques) ;
* nombre de composants externes réduit ;
* changement de filtre dynamique par simple programmation ;
* filtrage à phase linéaire.

## Instructions arithmétiques

Un DSP fournit des instructions usuelles comme la multiplication, l'addition, la soustraction, etc. Mais, le jeu d'instructions d'un DSP est aussi optimisé de façon à exécuter des opérations très courantes dans les algorithmes de traitement de signal les plus usuels.
Par exemple, de nombreux algorithmes de traitement du signal ont besoin d'effectuer des multiplications suivies d'une addition. Les DSP accélèrent ce genre de calcul en fournissant des instructions capables de multiplier deux nombres et d'en additionner un troisième en une seule fois (fonction très utilisée dans les calculs d'asservissement et de filtrage). L'instruction de ce type la plus connue est l'instruction Multiply And Accumulate. D'autres instructions similaires existent, comme l'instruction Fused Multiply And Accumulate. Les DSP sont capables d'effectuer ces opérations en un seul cycle d'horloge. Certains modèles sont même capables de réaliser plusieurs de ces opérations en un cycle d'horloge.
La majorité des DSP calculent exclusivement avec des nombres entiers. L'absence d'unité arithmétique en nombre flottant rend le composant meilleur marché tout en permettant une grande vitesse de traitement des données. Un additionneur entier est en effet beaucoup plus simple qu'un additionneur à virgule flottante. Les nombres entiers permettent d'obtenir une précision suffisante pour la plupart des applications.
Cependant, certains DSP possèdent des unités de calcul en virgule flottante comme le TMS320C67x ou le ADSP-TS20x. Des applications scientifiques ou, d'une manière générale, des applications qui nécessitent une grande précision relative des résultats ou une large dynamique des valeurs peuvent imposer le choix d'un DSP à virgule flottante.
Les instructions de manipulation de bit sont aussi très courantes. Ces instructions servent à manipuler la représentation binaire des nombres traités par le processeur. Elles rassemblent des instructions bit à bit comme des ET, OU, NOT bit à bit, mais aussi des décalages, des rotations, des instructions de permutation de bits, et bien d'autres.
Les DSP les plus récents incorporent des instructions SIMD, capables d'effectuer une même opération sur plusieurs données indépendantes à la fois. Ces instructions très utiles dans le traitement de signal, dont la plupart des algorithmes doivent manipuler des tableaux, qui sont des structures de données linéaires, dans lesquelles on effectue souvent des parcours répétitifs en traitant chaque donnée plus ou moins indépendamment. La ligne de démarcation entre les DSP et les microprocesseurs à usages généraux n'est pas toujours claire, ces derniers ayant incorporé ces instructions SIMD depuis un moment. Ainsi par exemple, l'extension MMX des processeurs Pentium MMX comprend, selon Intel, « 57 nouvelles instructions puissantes assignées au traitement efficace des données vidéo, audio et graphique. Ces instructions sont destinées aux séquences répétitives et parallèles qui sont souvent présentes dans les applications multimédia. »
Les DSP récents sont majoritairement des processeurs d'architecture VLIW.

### Arithmétique saturée

La représentation des résultats et leur précision jouent un rôle essentiel dans la majorité des algorithmes de traitement de signal. Et les DSP doivent être conçus en conséquence. Pour donner un exemple, ceux-ci doivent gérer les dépassements d'entier de plusieurs façons différentes.
Il arrive qu'un calcul donne un résultat qui demande plus de bits que disponible pour être représenté. Par exemple, si un processeur a des registres de 32 bits, il ne pourra pas stocker un nombre comme 5 000 000 000, qui a besoin de 33 bits. Ce genre de situation s'appelle un dépassement d'entier. Sur les processeurs généralistes, ces situations sont gérées via l'arithmétique modulaire. Pour faire simple, le résultat stocké dans les registres sera identique au vrai résultat, à part que les bits de poids fort (les bits en trop) seront perdus. Cela a un défaut majeur : l'addition (ou la multiplication) de deux nombres très grands peut donner un nombre très petit. Et cela peut donner des résultats assez bizarres : un son trop fort peut devenir soudainement très faible au lieu de saturer (mais inaudible car bien trop courte).
Pour éviter cela, les DSP permettent de gérer ces situations différemment en utilisant l'arithmétique saturée. Avec cette arithmétique, si un résultat devient trop grand pour être stocké dans un registre, le résultat est arrondi à la plus grande valeur que peut contenir ce registre.
Les DSP peuvent gérer les dépassements d'entier des deux façons. La manière de réagir peut être précisée par la valeur de certains bits, placés dans certains registres du processeur, comme pour d'autres paramètres. Une autre façon de faire aurait été de fournir les instructions de calcul en double : une version qui gère la situation avec l'arithmétique modulaire, et une autre avec l’arithmétique saturée. Mais cela aurait eu des désavantages, entre autres demander de doubler le nombre d'instructions.

### Block Floating Point

Pour plus d’efficacité dans certaines applications numériques, les DSP peuvent gérer nativement un format de données spécial : les nombres flottants par blocs. Comme leur nom l’indique, il s'agit de nombres flottants, c'est-à-dire de nombres à virgules dont le nombre de décimales après la virgule peut varier. Ceux-ci sont représentés en mémoire sous la forme d'un bit de signe, d'une mantisse, et d'un exposant.
Dans certains cas, il arrive que les nombres flottants à manipuler dans différents calculs aient tous le même exposant. Les nombres flottants par blocs permettent de mutualiser cet exposant entre plusieurs nombres flottants. L'exposant est ainsi stocké une seule fois en mémoire, et n'est pas dupliqué. Par exemple, s'il faut encoder 8 nombres flottants dans ce format, il faudra utiliser un mot mémoire pour l'exposant, et 8 autres pour les mantisses et les signes de chaque nombres. Avec des flottants normaux, il faudrait utiliser 8 mots mémoires pour les mantisses et les signes, et 8 autres pour les exposants.
Bien sûr, nos DSP supportent des instructions pour ces flottants par blocs. Ils contiennent notamment des instructions de calcul sur de tels flottants. Ils contiennent aussi une instruction pour charger l'exposant dans un registre, les calculs effectués dans ce format sont alors automatiquement effectués avec cet exposant. On trouve aussi des instructions de conversions entre les divers formats de flottants.

## Hardware Looping

Les DSP sont aussi fortement optimisés pour exécuter des boucles le plus rapidement possible. En effet, il n'est pas rare que les programmes de traitement du signal utilisent des boucles, notamment pour parcourir des tableaux. Accélérer ces boucles est donc un enjeu majeur de la conception des DSP.
Pour accélérer ces boucles, les DSP fournissent des instructions spéciales, capables d'effectuer un test et un branchement en un seul cycle d'horloge.

### Gestion du compteur de boucle

Les DSP sont capables de gérer des boucles FOR en un seul cycle d'horloge. Ces boucles s’exécutent un nombre fixé de fois, fixé par un indice. Cet indice est incrémenté ou décrémenté à chaque itération de la boucle. Nos DSP possèdent des instructions capables d'effectuer un branchement, ainsi qu'une décrémentation / incrémentation de cet indice. Pour faciliter l'implémentation de ces instructions, cet indice est souvent placé dans des registres spécialisés, dont le seul rôle est de stocker ces compteurs.

### Instructions auto-répétantes

Autre fonctionnalité d’accélération des boucles : les instructions auto-répétantes. Dans certains cas, il n'est pas rare que les boucles d'un programme ne fassent s'appliquer une seule et unique instruction sur tous les éléments d'un tableau. C'est par exemple le cas pour l'addition de tous les éléments d'un tableau. Ou encore, la multiplication de tous les éléments d'un tableau entre eux.
Certains DSP sont capables d'effectuer des boucles en une seule instruction. Ces instructions effectuent cette opération, ainsi que toutes les instructions de gestion de la boucle en un seul cycle d'horloge. Qui plus est, elles se répètent automatiquement toutes seules, tant qu'elles ne rencontrent pas la condition de sortie de boucle.
Pour gagner en performance, cette instruction est stockée dans une petite mémoire temporaire, afin d'éviter d'avoir à charger celle-ci depuis la mémoire à chaque exécution (chaque tour de boucle).

### Loop Buffer

Cette fonctionnalité a parfois été améliorée en permettant d'effectuer cette répétition non seulement sur des instructions uniques, mais aussi sur de petites suites d'instructions. Pour ce faire, ils peuvent utiliser une petite mémoire cache pour exécuter de petites boucles rapidement et sans accéder à la mémoire. Cette mémoire a souvent une taille limitée à quelques instructions : 16 à 32 environ.

## Modes d'adressages spécialisés

Les DSP supportent souvent des modes d'adressages assez particuliers, qu'on ne retrouve pas sur les autres jeux d'instructions. Ces modes d'adressages sont spécialisés dans des situations qu'on ne trouve que dans le traitement de signal.

### Indirect à registre avec post ou pré-incrément/décrément

Les données manipulées par nos DSP sont très souvent rassemblées dans des tableaux, qui sont parcourus du début à la fin (ou de la fin vers le début). Pour accélérer ces parcours de tableaux, les DSP incorporent des modes d'adressages spécialisés. Ils utilisent notamment le mode d'adressage post-incrémenté (décrémenté). Avec ce mode d'adressage, l'adresse de l’élément du tableau à lire ou écrire est stockée dans un registre. À chaque fois qu'une instruction accède à l'adresse contenue dans ce registre, cette adresse est incrémentée ou décrémentée de façon à pointer sur le prochain élément dans le tableau. Ce mode d'adressage permet d'effectuer cette incrémentation ou décrémentation automatiquement. Ils implémentent aussi une variante de ce mode d'adressage dans lequel l'incrémentation ou décrémentation s'effectue avant l'utilisation effective de l'adresse.

### Adressage Modulo

Les DSP implémentent des modes d'adressages servant à faciliter l’utilisation de files, des structures de données spéciales, utilisées occasionnellement par les programmeurs de DSP. Ces structures sont des zones de mémoire dans lesquelles on stocke des données dans un certain ordre. On peut y ajouter de nouvelles données, et en retirer. Quand on retire une donnée, c'est la donnée la plus ancienne qui quitte la file.
Ces files sont implémentées avec un tableau, auquel on ajoute deux adresses mémoires : une pour indiquer le début de la file, et l'autre la fin. Le début de la file correspond à l'endroit en mémoire où l'on va insérer les nouvelles données. La fin de la file correspond à la position de la donnée la plus ancienne en mémoire.
À chaque ajout de donnée, l'adresse de la donnée la plus récente est augmentée de la taille de la donnée, afin de réserver la place pour la donnée à ajouter. De même, lors d'une suppression, le pointeur de la donnée la plus ancienne est aussi augmenté, afin de libérer la plus place qu'il occupait.
Ce tableau a une taille fixe. Si jamais celui-ci se remplit jusqu'à la dernière case, (ici la 5e), il se peut malgré tout qu'il reste de la place au début du tableau : des retraits ont libéré de la place. L'insertion des données reprend au tout début du tableau.
Ce mode de fonctionnement nécessite de vérifier à chaque insertion si l'on a atteint la fin du tableau, avec l'aide d'une comparaison entre adresses. De plus, si l'on arrive à la fin du tableau, l'adresse de la donnée la plus récemment ajoutée doit être remise à la bonne valeur : celle pointant sur le début du tableau.
Le mode d'adressage modulo a été inventé pour supprimer la comparaison et la gestion logicielle des débordements. Avec ce mode d'adressage, les deux adresses sont adressées en utilisant le mode d'adressage indirect à registre post ou pré-indexé : l'incrémentation de l'adresse au retrait ou à l'ajout est effectuée automatiquement. Ce mode d'adressage vérifie automatiquement que l'adresse ne déborde pas du tableau lors d'une insertion. Si cette adresse « déborde », le processeur la fait pointer au début du tableau. Suivant le DSP, ce mode d'adressage est géré plus ou moins différemment.
La première méthode utilise des registres modulos. Ces registres vont stocker la taille du tableau servant à implémenter notre file. Chacun de ces registres est associé à un registre d'adresse : si jamais on utilise l'adressage modulo dans ce registre d'adresse, le processeur utilisera le contenu du registre modulo pour faire ce qu'il faut. Pour gérer l'adresse de début, le processeur va imposer quelques contraintes sur l'adresse de départ de ce tableau. Cette adresse est souvent alignée à des adresses bien précises, souvent un multiple de 64, 128, ou 256. L'adresse de début de la file est donc le multiple de 64, 128, 256 strictement inférieur le plus proche de l'adresse manipulée.
Autre solution : utiliser deux registres : un pour stocker l'adresse de début du tableau, et un autre pour sa longueur. Certains processeurs DSP utilisent un registre pour stocker l'adresse de début, et un autre pour l'adresse de fin.

### Adressage bit-reverse

Les DSP supportent un dernier mode d'adressage : l'adressage bit-reverse. Ce mode d'adressage sert à accélérer les calculs de transformées de Fourier rapides. Ces calculs de transformée de Fourier étant courants en traitement de signal, un mode d'adressage spécial lui est réservé.
Cet algorithme a la fâcheuse tendance à produire ses résultats dans un ordre différent des données de départ. En gros, cet algorithme va prendre des données, stockées dans un tableau, et va fournir des résultats, eux aussi écrits dans un tableau. L'ordre de calcul des résultats dans le tableau d'arrivée suit une logique particulière. Les bits de l'adresse du résultat sont partiellement inversés comparé aux bits de l'adresse normale.
Par exemple, pour un tableau de 8 cases, numérotées 0, 1, 2, 3, 4, 5, 6, 7, les données arrivent dans cet ordre : 0, 4, 2, 6, 1, 5, 3, 7.
| Ordre normal | Ordre FFT |
| 000 | 000 |
| 001 | 100 |
| 010 | 010 |
| 011 | 110 |
| 100 | 001 |
| 101 | 101 |
| 110 | 011 |
| 111 | 111 |
Les DSP disposent donc d'un mode d’adressage qui inverse tout ou partie des bits d'une adresse mémoire, afin de gérer plus facilement les calculs de FFT. Une autre technique consiste à calculer nos adresses différemment. Lors de l'ajout d'un indice à notre adresse, la direction de propagation de la retenue de l'addition est inversée. Certains DSP disposent d'instructions pour faire ce genre de calculs.

## Jeu de registres

L'ensemble des registres supportés par un DSP est souvent assez hétérogène. Tous les DSP utilisent un faible nombre de registres, pour des raisons de coûts et d’échauffement thermique. De plus, ces registres sont souvent très spécialisés.

### Spécialisation des registres

Par exemple, un DSP aura souvent des registres entiers séparés des registres flottants. Certains registres ne pourront ainsi stocker que des nombres entiers, et d'autres uniquement des flottants. Comme autre exemple, certains registres sont spécialisés dans le stockage des adresses mémoires. On peut aussi trouver des registres spécialisés pour retenir des indices de tableaux, ou des compteurs de boucles.
De plus, certaines instructions du processeurs, ainsi que l'usage de certains modes d'adressages, ne sont possibles que sur certains types de registres. Par exemple, certaines instructions ne peuvent manipuler que les registres entiers et pas les autres. Cette spécialisation des registres pose de nombreux problèmes pour les compilateurs, qui peuvent donner lieu à une génération de code sous-optimale.

### Accumulateurs

De nombreuses applications de traitement de signal ont besoin d'une grande précision. Pour que cela ne devienne pas rapidement une source d'erreur dans les calculs, les DSP sont dotés de registres accumulateurs très grands, capables de retenir des résultats de calcul intermédiaires sans perte de précision.
Les DSP utilisent donc des registres accumulateurs très larges. Par exemple, l'UAL (unité arithmétique et logique) des DSP de la famille DSP56k de Motorola dispose de quatre registres d'entrée de 24 bits, deux registres accumulateurs de 48 bits et deux extensions de 8 bits des registres accumulateurs. Ces dernières permettent d'obtenir une précision de 56 bits sur les registres accumulateurs, laquelle offre une bonne précision aux calculs successifs et simplifie la gestion des erreurs pour le programmeur.

## Accès mémoires

L'accès à la mémoire est aussi particulièrement optimisé sur les DSP. Nos DSP sont en effet capables d'effectuer plusieurs accès mémoires simultanés. Ils peuvent ainsi effectuer plusieurs lectures ou écritures en parallèle. Pour donner un exemple, certains DSP permettent d'aller lire une donnée en mémoire pour l'enregistrer dans une autre adresse mémoire, en un seul cycle. Il s'agit d'une forme limitée d'échange entre deux locations mémoires.
Sur certains DSP, ce sont les instructions arithmétiques et logiques qui effectuent plusieurs accès à la mémoire. Par exemple, peut charger une instruction MAC, charger ses trois opérandes, et stocker le résultat en mémoire en un seul cycle d'horloge.
Dans d'autres cas, les instructions d'accès mémoires sont séparées des instructions arithmétiques et logiques : seules certaines instructions peuvent aller lire ou écrire plusieurs données simultanément. On appelle ces instructions des parallels moves.
Pour gérer ces accès mémoires simultanés, un DSP est souvent relié à plusieurs mémoires, ou à des mémoires multiports.
Ces DSP sont construits autour d'une architecture Harvard, dans laquelle les bus d'accès à la mémoire programme sont séparés des bus d'accès aux données. Cela leur permet ainsi de lire une instruction tout en chargeant des opérandes (utile sur les DSP pipelinés).
Un DSP ne possède généralement pas de mémoires caches pour les données. Il arrive qu'il ait des mémoires caches pour les instructions, afin d’accélérer l’exécution de certaines boucles, mais c'est relativement rare.

## Caractéristiques

Un DSP est un processeur dont l'architecture est optimisée pour effectuer des calculs complexes en un cycle d'horloge, mais aussi pour accéder très facilement à un grand nombre d'entrées-sorties (numériques ou analogiques).
Il possède aussi quelques caractéristiques assez spécialisées :
* seulement des processus parallèles, pas de multitâche. Des contraintes sont imposées car les DSP n'ont qu'une gestion rudimentaire des interruptions quand ils en ont une ;
* la possibilité d'être utilisé comme un périphérique accédant directement à la mémoire dans un environnement hôte ;
* peut acquérir les données numériques d'un convertisseur analogique-numérique (CAN ou ADC), appliquer un traitement à ces données et les restituer au monde extérieur grâce à un convertisseur numérique-analogique (CNA ou DAC) ;
* pas de mémoire virtuelle, pour diminuer les couts de fabrication et la latence des accès mémoires.
Les DSP peuvent être combinés avec d'autres composants dans le même boîtier. Par exemple, un ou plusieurs DSP peuvent être combinés avec un microprocesseur classique et des convertisseurs ADC et DAC. Ce type d'assemblage (circuits intégrés dédiés) permet de réduire les coûts dans des fabrications de grande série. Les fonctions de traitement de signal peuvent également être réalisées à l'aide de FPGA, qui peuvent incorporer des « cœurs DSP » (en général des MAC). La reconfiguration matérielle permet alors d'accroître le parallélisme des opérations. Les différents types d'architecture disponibles permettent d'adapter les circuits de traitement aux besoins spécifiques de l'application.
Les DSP proposent des performances étonnantes. Par exemple, le DSP AD1460 qui est composé de 4 ADSP-21060 dans le même boîtier a une puissance de calcul maximum de 460 MFLOPS (460 millions d'opérations en virgule flottante par seconde). Un autre modèle, l'ADSP-21160 qui opère à 100 MHz, comporte un bus accéléré de mémoire dont la bande passante est de 1,6 gigaoctets par seconde, 2 bus de données en 64 bits et 4 accumulateurs de 80 bits pour les calculs sur des entiers. Grâce à cela, l'ADSP-21160 est capable d'exécuter une transformation de Fourier sur un signal défini par 1 024 points en seulement 46 μs.

## Programmation

Dans un appareil équipé de DSP, la vitesse d'exécution des calculs dans le DSP est généralement la partie déterminante de la vitesse d'exécution du travail effectué par la machine. Il s'agit souvent de programmes très courts, de quelques centaines de lignes au maximum dont certaines parties (boucles) doivent être optimisées au maximum. C'est pourquoi beaucoup de programmeurs de DSP utilisent l'assembleur et analysent en détail le schéma d'exécution du code par la machine.
Cependant, certains DSP ont une architecture tellement complexe qu'il devient long et difficile pour le programmeur d'optimiser manuellement l'exécution. Il peut alors écrire son programme en C et laisser au compilateur le soin de réaliser l'optimisation du code. S'il le souhaite, le programmeur pourra alors analyser le code généré par le compilateur et y apporter les dernières retouches permettant d'obtenir du DSP la meilleure performance possible.
Le choix entre ces deux langages se fera donc en fonction de la complexité du programme, de la vitesse de traitement souhaitée, du nombre de programmeurs qui travailleront sur le projet et du coût du produit. D'autres facteurs comme l'expérience personnelle et les outils que propose le constructeur doivent aussi être considérés.

## Fabricants

Il existe différents fabricants de DSP sur le marché :
* Analog Devices propose entre autres des DSP incorporant comme périphériques des ADC et des DAC ;
* Qualcomm, pour les DSP de téléphones mobiles ;
* Lucent ;
* Microchip propose deux familles dénommées Digital Signal Controler (dsPIC30F et dsPIC33F), qui sont des microcontrôleurs avec des capacités de calcul renforcées et des périphériques de conversion analogique-numérique ;
* NXP offre une gamme de solutions pour le traitement et le contrôle des signaux numériques optimisées pour des applications allant des marchés généraux embarqués au contrôle des moteurs et à la conversion de puissance. (Familles MSC8xx et DSP56Fxx)
* Texas Instruments a une gamme étendue, comportant en particulier les familles C6000, C5000 et C2000 ;
* STMicroelectronics.