Télécharger la présentation
1
Steven Derrien Équipe R2D2
Conception logicielle et matérielle d’un décodeur MP3 sur la plate-forme NIOS-Stratix Steven Derrien Équipe R2D2
2
Contexte Module CSE en DIIC 2 (TP) TP « décodeur MP3 »
Conception de circuits en VHDL Approche mixte logiciel-matériel Utilisation d’une plate-forme reconfigurable TP « décodeur MP3 » Exploiter les possibilités de la plate-forme NIOS Utiliser des méthodologies de conception Travailler sur une « véritable » application Objectif du mini-projet Obtenir une implémentation « temps-réel » de référence, qui sera utilisé pour les TP. (compat elect, perf, consommation)
3
Chaîne de décodage MP3
4
Travail déjà effectué Portage du code « C » référence
Passage des calculs flottants en entiers Restructuration du code Portage sur le NIOS (pas de SGF) Mise en œuvre sur un OS temps-réel Utilisation de micro-OS II. Découpage de l’application en tâches Communications par files d’attente Version à 4 tâches fonctionnelle
5
Chaîne de décodage MP3 Tâche 1 Tâche 2 Tâche 3 Tâche 4
6
Résultats Etape durée %CPU Huffman 15% Dequantize ? Reorder Stereo
IMDCT 28% SubBand 33% Implémentation 5x trop lente pour du temps-réel. Deux tâches utilisent 80% des ressources CPU Accélération matérielle de IMDCT et SubBand
7
Architecture visée Tâche 2 IMDCT Tâche 1 Tâche 4 SubBand Tâche 3 CNA
Co-processeur (VHDL) FIFO Tâche 2 IMDCT Nios CPU + OS temps-réel FIFO Tâche 1 Co-processeur (VHDL) FIFO Tâche 4 SubBand Tâche 3 FIFO CNA FIFO Bus Avalon
8
Travail à réaliser Filtre IMDCT à finaliser Filtre SubBand à réaliser
Mise au point de bancs de tests Intégration du composant dans l’appli Validation du fonctionnement Filtre SubBand à réaliser Conception VHDL de l’accélérateur Définition de l’interface soft-hard
9
Méthodologie de conception en VHDL
Décomposition UT/UC Définition d’un squelette d’UT Mémoires, registres Opérateurs (*,+) Interconnexions Dérivation du contrôleur Associer à chaque calcul un instant d’exécution et une ressource de traitement. Plusieurs opération en parallèle Respects des dépendances de données Vérifier l’absence de conflits En déduire l’automate de contrôle.
10
Définition de l’interface
On utilisera une interface à base de FIFOs matérielles, qui seront directement connectées au bus Avalon. Le contrôle de flux étant géré par le processeur NIOS 1 adx = 0 2 while(1) { 3 X[adx]=read_fifo(); 4 y=0;i=0; 5 adx=(adx++) % 8; 6 while(i<8) { y=y+X[adx]*C[i]; adx=(adx++) % 8; i++; } write_fifo(y); 11 };
11
Choix des ressources de mémorisation
On alloue un registre pour chaque variable, et on utilise des mémoire (RAM ou ROM) pour stocker les tableaux. 1 adx = 0 2 while(1) { 3 X[adx]=read_fifo(); 4 y=0;i=0; 5 adx=(adx++) % 8; 6 while(i<8) { y=y+X[adx]*C[i]; adx=(adx++) % 8; i++; } write_fifo(y); 11 };
12
Choix des ressources de traitement
On alloue ensuite des unités fonctionnelles à notre chemin de données en fonction des opérations présentes dans le bloc de traitement à accélérer. La duplication de certaines unités de traitement permet parfois de tirer parti d’un parallélisme au niveau instruction. 1 adx = 0 2 while(1) { 3 X[adx]=read_fifo(); 4 y=0;i=0; 5 adx=(adx++) % 8; 6 while(i<8) { y=y+X[adx]*C[i]; adx=(adx++) % 8; i++; } write_fifo(y); 11 };
13
Signaux de contrôles de l’UT
On dispose alors d’une représentation presque complète de l’unité de traitement à laquelle il faut ajouter les signaux de contrôles. 1 adx = 0 2 while(1) { 3 X[adx]=read_fifo(); 4 y=0;i=0; 5 adx=(adx++) % 8; 6 while(i<8) { y=y+X[adx]*C[i]; adx=(adx++) % 8; i++; } write_fifo(y); 11 };
14
Allocation et ordonnancement
On effectue ensuite l’allocation et l’ordonnancement des calculs : À chaque opération, on associe un opérateur matériel, et un instant d’exécution. 1 adx = 0 2 while(1) { 3 X[adx]=read_fifo(); 4 y=0;i=0; 5 adx=(adx++) % 8; 6 while(i<8) { y=y+X[adx]*C[i]; adx=(adx++) % 8; i++; } write_fifo(y); 11 }; T 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 rd_fifo X wr_en adx_rst adx_en i_rst i_en y_rst y_En wr_fifo
15
Dérivation du contrôleur
Une fois l’allocation et l’ordonnancement effectués, on peut dériver l’automate de contrôle qui commandera l’unité de traitement.
16
Exercices Ordonnancement pour des opérateurs pipelinés
Latence Add =1 cycle, Mul=2 cycles Reprendre l’exercice pour un filtre symétrique: 1 adx = 0 2 while(1) { 3 X[adx]=read_fifo(); 4 y=0;i=0; 5 adx=(adx++) % 4; 6 while(i<4) { y=y+(X[adx]+X[7-adx])*C[i]; adx=(adx++) % 4; i++; } write_fifo(y); 11 };
17
Méthodologie Traces d’exécution pour un fichier MP3
Testbench C fonctionnant sur traces Architecture VHDL TestBench pour chaque bloc important Testbench VHDL Simulation des E/S bus, et utilisation des traces TestBench C « in situ » intégrant le co-processeur Mise en œuvre de l’interface logicielle Mesure de performances (speed-up) Intégration à l’application
18
Exercice 1 Reprendre l’exemple SlavePeriph_fifo.vhd
L’intégrer à un système NIOS. Écrire un programme C de test pour le NIOS. Valider le fonctionnement de l’ensemble.
19
Exercice 2 Se baser sur le code de IMDCT pour proposer un squelette d’unité de traitement avec les caractéristiques suivantes : Double multiplieur-accumulateur pipeliné ROM à double port pour iCOS[] et iWin[] ROM et RAM synchrones Réfléchir à un ordonnancement. Exploiter la présence de 2 MAC Attention aux délais : Mémoire synchrone MAC pipeliné
20
Code IMDCT while(1) { block_type=get_fifo();
for(i= 0;i<36;i++) iin[i]=get_fifo(); for(p= 0;p<9;p++){ isum = 0; isum2= 0; addr_a = 19+(p<<1); addr_b = 55+(p<<1); step_a = ((p<<2)+38); step_b = ((p<<2)+110); if (step_b>=144) step_b -= 144; for(m=0;m<18;m++) { isum += iin[m]*iCOS[addr_a]; isum2 += iin[m]*iCOS[addr_b]; addr_a = addr_a + step_a; if (addr_a>=144) addr_a -= 144; addr_b = addr_b + step_b; if (addr_b>=144) addr_b -= 144; } iout[p] = isum*iwin[block_type][p]; iout[17-p] = -isum*iwin[block_type][17-p]; iout[18+p] = isum2*iwin[block_type][18+p]; iout[35-p] = isum2*iwin[block_type][35-p]; for(i= 0;i<36;i++) put_fifo(iout[i]);
21
Unité de traitement pour l’IMDCT
22
Exercice 3 Se baser sur le code de SUBBAND pour compléter l’unité de traitement : Réfléchir à un ordonnancement. Dériver le contrôleur
23
Code SubBand while(1) { bufOffset[channel] = (bufOffset[channel] - 64) & 0x3ff; ibufferPtr = &(ibuf[channel][0]); du début de buffer for (k=0; k<32; k++) bandPtr[k] = get_fifo(); for (i=0; i<64; i++) { isum = 0; for (k=0; k<32; k++) { isum += bandPtr[k]*filterInt[i][k]; } addr_ibuf = i+bufOffset[channel]; ibuffferPtr[addr_ibuf] = isum; for (k=0; k<32; j++) { for (i=0; i<16; i++) { addr_iwin = k + (i<<5); addr_ibuf = k + ((i<<5) + (((i+1)>>1)<<6)) + bufOffset[channel]) & 0x3FF; isum += iwindow[addr_iwin]*ibuffferPtr[addr_ibuf]; put_fifo(isum); channel= 1-channel;
24
Unité de traitement pour SubBand
Présentations similaires
© 2024 SlidePlayer.fr Inc.
All rights reserved.