L’entité BiquadFilter
réalise un filtre numérique à réponse impulsionnelle infinie
(IIR pour Infinite Impulse Response).
Il s’agit plus précisément d’un filtre biquadratique
dont la sortie est calculée de la manière suivante :
Selon la valeur des coefficients (, , , , ), un tel filtre pourra avoir une réponse de type passe-bas, passe-haut, ou passe-bande.
Dans le cadre de ce projet, nous avons calculé pour vous les coefficients de
tous les filtres. Vous les trouverez dans le paquetage Vocoder_pkg
.
Nous nous sommes inspirés des algorithmes fournis dans la page
Biquad formulas
sur le blog EarLevel Engineering.
Pour la réalisation en VHDL, nous choisissons d’exprimer l’équation du filtre dans la forme directe transposée de type 2 :
À titre d’exercice, vous pouvez vérifier que ces trois équations sont équivalentes à celle proposée au début de cette section.
BiquadFilter
Les paramètres génériques de cette entité permettent de configurer sa réponse en fréquence :
Paramètre | Type | Rôle |
---|---|---|
A1 |
Virgule fixe (vocoder_coef_t ) |
Le coefficient du filtre |
A2 |
Virgule fixe (vocoder_coef_t ) |
Le coefficient du filtre |
B0 |
Virgule fixe (vocoder_coef_t ) |
Le coefficient du filtre |
B1 |
Virgule fixe (vocoder_coef_t ) |
Le coefficient du filtre |
B2 |
Virgule fixe (vocoder_coef_t ) |
Le coefficient du filtre |
L’entité BiquadFilter
traite un flux de données en utilisant le protocole ready/valid.
Elle joue à la fois les rôles de consommateur et de producteur :
Port | Direction | Type | Rôle |
---|---|---|---|
clk_i |
Entrée | Logique | Le signal d’horloge global du système |
reset_i |
Entrée | Logique | La commande de réinitialisation du système |
valid_i |
Entrée | Logique | Indique qu’un nouvel échantillon est disponible en entrée |
ready_o |
Sortie | Logique | Indique que ce filtre est prêt à recevoir un nouvel échantillon d’entrée |
data_i |
Entrée | Virgule fixe (vocoder_data_t ) |
La valeur d’un échantillon à traiter |
valid_o |
Sortie | Logique | Indique qu’un nouvel échantillon est disponible en sortie |
ready_i |
Entrée | Logique | Indique que le consommateur relié à ce filtre est prêt à recevoir un nouvel échantillon |
data_o |
Sortie | Virgule fixe (vocoder_data_t ) |
La valeur d’un échantillon filtré |
Nous fournissons une version complète du filtre qui fonctionne en simulation. La gestion du protocole ready/valid est assurée par une machine à trois états sur le modèle présenté dans la page Connecter producteurs et consommateurs.
Dans la version que nous fournissons, tous les calculs sont effectués en une
période d’horloge dans l’état BUSY_STATE
.
Les types de données et l’écriture des opérations ont été choisis pour tirer parti des cellules de traitement du signal DSP48E1 présentes dans les FPGA de Xilinx. Ces cellules sont spécialement conçues pour réaliser des opérations de multiplication rapides et des calculs associant multiplication et addition de la forme :
Cette combinaison d’opérations est appelée Multiplication-ACumulation (MAC)
car dans les algorithmes de traitement du signal, elle est souvent utilisée
pour calculer des sommes de produits. Dans l’exemple ci-dessous, la variable p
« accumule » les produits des éléments de a
et b
:
pour i de 0 à N-1 répéter
p ← p + a(i) * b(i)
fin répéter
La cellule DSP48E1 peut également calculer des expressions de la forme :
Les tailles des opérandes et du résultat sont les suivantes :
Opérande | Taille max. (bits) |
---|---|
A | 30 |
B | 18 |
C | 48 |
D | 25 |
P | 48 |
On peut mettre ces tailles en relation avec celles des types de données définis
dans le paquetage Vocoder_pkg
.
Dans le filtre, ils sont destinés à être utilisés comme ceci :
Type | Taille (bits) | Rôle |
---|---|---|
vocoder_coef_t |
18 | B |
biquad_data_t |
25 | C ou D |
Pour plus de détails, vous pouvez consulter la documentation officielle de Xilinx.
Le fichier BiquadFilterTestbench.vhd
contient un banc de test pour
l’entité BiquadFilter
.
Ce banc de test relie la sortie d’un oscillateur avec l’entrée d’un filtre passe-bande.
Vous pouvez régler les caractéristiques de ces deux instances en modifiant des
constantes dans le fichier BiquadFilterTestbench_pkg.vhd
:
FILTER_CHANNEL
sélectionne l’un des filtres passe-bandes parmis ceux
précalculés dans le paquetage Vocoder_pkg
.OSC_STEP
règle le pas de l’oscillateur.Au cours de la simulation, on s’attend à obtenir une autre sinusoïde en sortie
du filtre.
L’amplitude de la sortie sera maximale si la fréquence de l’oscillateur
se situe au centre de la bande passante du filtre,
c’est-à-dire pour OSC_STEP = FILTER_CHANNEL + 1
.
Pour exécuter la simulation, nous fournissons un script qui automatise le démarrage du simulateur et l’exécution d’une séquence de commandes :
src/BiquadFilter
et sélectionnez le fichier BiquadFilterTestbench.tcl
.data_i
et data_o
.Dans le fichier BiquadFilterDemo.vhd
, nous nous sommes inspirés de l’exemple
I2SDemo
en supprimant la mémoire RightRom
et en insérant un filtre entre la
sortie de LeftRom
et l’entrée correspondant à la voie droite du transmetteur I2S.
Ainsi, au cours du fonctionnement de ce circuit, vous devriez entendre l’extrait audio « week-end » original dans l’oreille gauche, et le même extrait filtré dans l’oreille droite.
Dans le panneau Tcl Console, indiquez que l’entité BiquadFilterDemo
est l’entité principale du circuit :
set_property top BiquadFilterDemo [get_filesets sources_1]
Générez le fichier binaire à charger dans le FPGA : Flow Navigator → Program and Debug → Generate Bitstream.
Vivado va enchaîner toutes les étapes d’analyse des fichiers sources, de synthèse logique, de placement et routage, pour terminer par la génération d’un fichier binaire à charger dans le FPGA.
À la fin des opérations, la boîte de dialogue Bitstream Generation Completed s’affiche. Choisissez Open Hardware Manager.
Vérifiez que l’interrupteur d’alimentation de votre carte Basys3 est en position OFF. Le cavalier situé à côté de l’interrupteur doit être en position USB.
Branchez le module PmodI2S sur le connecteur JA (en haut sur le côté gauche de la carte) et branchez un casque stéréo ou des enceintes sur le connecteur jack.
Vous ne connaissez pas à l’avance le volume de la sortie audio. Ne mettez pas vos écouteurs sur les oreilles avant d’être sûr que le son n’est pas trop fort.
Reliez le connecteur micro-USB de la carte à un port USB de votre PC. Mettez la carte sous tension.
En haut du panneau Hardware Manager, pressez Open target et choisissez Auto Connect.
Pressez ensuite Program Device.
Avant d’aller plus loin, nous allons nous intéresser aux ressources matérielles utilisées par ce circuit.
Affichez le schéma RTL : Flow Navigator → RTL Analysis → Open Elaborated Design → Schematic.
Dans le schéma, repérez l’instance filter_inst
et ouvrez-la.
Identifiez ensuite les opérations d’addition, de soustraction et de multiplication
utilisées.
Ce schéma présente le circuit en termes d’opérations élémentaires : arithmétiques, logiques, de sélection, de mémorisation. En réalité, après synthèse et optimisation, certaines opérations pourront être fusionnées ou associées dans un même composant.
Affichez le schéma du circuit synthétisé : Flow Navigator → Synthesis → Open Synthesized Design → Schematic.
Dans ce nouveau schéma, repérez l’instance filter_inst
, ouvrez-la
et identifiez les composants DSP48E1.
Combien y en a-t-il ? Est-ce cohérent avec la description VHDL ?
Dans la barre d’outils en haut de la fenêtre, pressez le bouton Project Summary, dont l’icône est une lettre Sigma (Σ).
La rubrique Utilization donne un aperçu du taux d’occupation du FPGA. Vous pouvez l’afficher sous forme de diagramme ou sous forme de tableau. Repérez le nombre de ressources DSP utilisées après implémentation.
Sachant que notre application vocodeur travaillera sur 12 voies, avec un filtre passe-bande et un filtre passe-bas par voie, y a-t-il assez de cellules DSP48E1 dans notre FPGA ?
Proposez une solution et modifiez l’architecture du filtre de manière à utiliser moins de cellules DSP48E1.
Simulez et synthétisez BiquadFilterDemo
avec la nouvelle version du filtre.
Après synthèse, vous ne constaterez peut-être pas de diminution du nombre de cellules DSP48E1 utilisées. En effet, les algorithmes d’optimisation de Vivado prennent en compte de nombreux critères et, sur ce circuit précis, la réduction du nombre de cellules DSP n’apporte peut-être pas de gain significatif.