Pourquoi encapsuler un module UART en IP Core ?
Lors du développement FPGA, les modules de base comme l’UART sont souvent réutilisés d’un projet à l’autre. La méthode traditionnelle – copier/coller du code source – engendre plusieurs problèmes :
- Gestion des versions : un bug corrigé dans une copie n’est pas propagé aux autres projets.
- Configuration fragile : changer le baudrate oblige à modifier manuellement chaque fichier.
- Collaboration difficile : chaque nouveau développeur doit comprendre une interface différente.
Comparaison entre copie de code et IP Core personnalisé :
| Méthode | Cohérence version | Configuration paramétrique | Collaboration | Productivité |
|---|---|---|---|---|
| Copier/coller du code | Faible | Modification manuelle | Répétition des explications | Basse |
| IP Core personnalisé | Automatique | Graphique (GUI) | Glisser-déposer | Haute |
// Exemple traditionnel : doit être copié dans chaque projet
module uart_receiver #(
parameter integer BAUD = 9_600,
parameter integer CLK_FREQ = 50_000_000
)(
input wire clk,
input wire rst_n,
input wire rx_serial,
output reg rx_valid,
output reg [7:0] rx_data
);
// ... implémentation ...
endmodule
Astuce : après encapsulation, les paramètres sont configurables via l’interface graphique de Vivado, sans toucher au code HDL.
Préparation du module source
Création du projet de base
Assurez-vous que votre module UART fonctionne correcetment en simulation et sur la carte. Un bon IP Core doit :
- Avoir des interfaces clairement séparées (signaux système vs signaux fonctionnels).
- Utiliser des paramètres (ex. fréquence d’horloge, baudrate) pour faciliter la configuration.
- Être temporisé correctement (registres de synchronisation si nécessaire).
# Exemple de commande Tcl pour créer le projet (équivalent GUI)
create_project uart_ip ./uart_ip -part xc7z020clg400-1
Normalisation des ports
Pour améliorer la réutilisabilité, renommez les signaux avec un préfixe cohérent et ajoutez un port d’activation si besoin.
// Module optimisé pour l’IP Core
module uart_rx_ip #(
parameter integer BAUDRATE = 115200,
parameter integer CLK_FREQ_HZ = 100_000_000
)(
// Signaux globaux
input wire sys_clk,
input wire sys_rst_n,
// Interface série
input wire uart_rxd,
// Interface utilisateur
output reg rx_data_valid,
output reg [7:0] rx_data_byte,
output wire rx_busy
);
// ... implémentation ...
endmodule
Processus complet d’encapsulation
Création du squelette d’IP Core
Dans Vivado 2018.3, suivez :
- Menu
Tools > Create and Package New IP - Sélectionnez
Package your current project - Choisissez un répertoire de destination dédié.
Cochez l’option « Include .xci files » pour inclure toutes les dépendances.
Configuration des paramètres et interfaces
Les onglets clés de l’éditeur d’IP :
- Identification : donnez un nom unique (ex.
my_uart_rx), un nom d’affichage (UART Receiver Core), et une description. - Customization Parameters : exposez les paramètres du module sous forme de champs configurables avec valeurs par défaut et plages.
- Ports and Interfaces : vérifiez les directions des ports ; vous pouvez ajouter des protocoles standard (AXI-Stream, etc.).
Exemple de paramètres exposés :
| Nom du paramètre | Nom affiché | Valeur par défaut | Plage | Description |
|---|---|---|---|---|
| BAUDRATE | Baud rate | 115200 | 9600-921600 | Taux de transmission série |
| CLK_FREQ_HZ | Clock frequency (Hz) | 100000000 | 1M-200M | Fréquence de l’horloge système |
Génération et validation
- Cliquez sur
Review and Packagepour vérifier le résumé. - Confirmez avec
Package IP. - Recherchez votre IP dans le catalogue IP (
IP Catalog).
# Vérification en ligne de commande Tcl
report_ip_status -name ip_status
Techniques avancées
Partage de l’IP entre projets
- Ouvrez les Settings du projet cible.
- Allez dans
IP > Repositoryet ajoutez le dossier contenant votre IP.
Mise à jour de version
- Dans l’interface Package IP, choisissez
Edit IP. - Modifiez le code, puis incrémentez le numéro de version.
- Tous les projets utilisant cette IP recevront une notification de mise à jour.
Intégration des modèles de simulation
- Dans l’onglet File Groups, ajoutez les fichiers de simulation (behavioral, timing).
- Repackagez l’IP ; la simulation des projets consommateurs utilisera automatiquement ces modèles.
// Exemple de testbench en Verilog
initial begin
uart_drv.init(115200);
uart_drv.send(8'hA5);
@(posedge rx_data_valid);
if (rx_data_byte !== 8'hA5)
$error("Échec de réception");
end
Retour d’expérience
Après avoir encapsulé plusieurs IP Core (UART, SPI, PWM), voici quelques bonnes pratiques :
- Nommage cohérent : préfixez tous les signaux avec le nom du module pour éviter les collisions.
- Validation des paramètres : ajoutez des contrôles dans la GUI pour empêcher les valeurs invalides.
- Documentation : décrivez chaque paramètre et chaque port dans les propriétés de l’IP.
- Gestion de versions : en cas de modification majeure, créez une nouvelle IP plutôt que d’écraser l’ancienne.
Un oubli de mise à jour de version a causé une situation où trois développeurs utilisaient des versions différentes du même noyau UART. Depuis, nous incluons la date et la version dans le nom (ex. uart_rx_v20230701).
Pour les IP complexes, créez un projet de test dédié associé à l’IP ; exécutez une régression complète après chaque modification. Vivado permet de lier ce projet de test lors du packaging, automatisant la vérification.