En règle générale on aime bien avoir la version du firmware générée sur lequel tourne notre FPGA. Cependant, pour intégrer une date de compile, une version de logiciel ou autre dans un bitstream, cela ne se fait pas très simplement.
L’exemple ici est certainement quick&dirty, mais c’est une solution possible pour résoudre ce problème. Le système est conçu via le «blocs designer» de vivado et contient un microblaze.
Pour pouvoir ajouter des «registres» spécifiques sans avoir à coder en HDL on intégrera un bloc de ROM nommé «Distributed Memory Generator». Pour intégrer ce bloc dans l’espace mémoire du Microblaze on ajoutera un contrôleur de ram AXI comme le montre la saisie d’écran ci-dessous:
Ce bloc peut être configuré via un fichier texte avec l’extension «.coe» qui contiendra les valeurs.
memory_initialization_radix=10;
memory_initialization_vector=1562 1490616824 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0;
La variable memory_initialization indique la base (ici du décimal) des valeurs données dans le vecteur memory_initialization_vector. Dans cet exemple, trois valeurs sont données : la période de l’horloge du contrôleur de DDR, la date en secondes unix et la version.
Plutôt que d’avoir à modifier notre fichier *.coe à chaque synthèse, nous allons écrire un script tcl qui sera appelé automatiquement par vivado à chaque synthèse/placement-routage. Le TCL est un langage de script que beaucoup de logiciels d’électronique sont capable d’éxecuter, c’est le cas de vivado (tcl version 8.5).
Le répertoire du projet est donné par la commande tcl :
On peut l’afficher au besoin dans la console «Messages» de vivado avec puts :
période du contrôleur de DDR
L’idée ici est d’aller chercher l’information dans le fichier datasheet.txt généré par le fucking MIG. La méthode Quick&Dirty pour récupérer l’info dans le fichier est de découper le texte à coup de split et de lindex pour se focaliser sur la «Design Clock Frequency».
... /*******************************************************/ /* Controller 0 */ /*******************************************************/ Controller Options : Memory : DDR3_SDRAM Interface : AXI Design Clock Frequency : 1562 ps ( 0.00 MHz) Phy to Controller Clock Ratio : 4:1 Input Clock Period : 5077 ps CLKFBOUT_MULT (PLL) : 13 DIVCLK_DIVIDE (PLL) : 2 VCC_AUX IO : 1.8V Memory Type : Components Memory Part : MT41K1G8SN-125 Equivalent Part(s) : -- Data Width : 8 ECC : Disabled Data Mask : enabled ORDERING : Normal ...
La période est ainsi stockée dans la variable $period :
version
Pour la version c’est à nous de définir un «generic» dans le projet avec le nom que nous voulons (par exemple ProjectVersion). Ce generic se définit dans le menu setting du projet, pour cette exemple il sera défini à ‘1’, quelle originalité !
Ce generic se retrouve ensuite dans le fichier xml du projet au format *.xpr. De la même manière que pour la period du contrôleur de DDR, nous allons lire ce fichier au moyen d’une savante boucle de découpage split et lindex:
date
Pour la date c’est beaucoup plus simple puisqu’il existe une commande tcl (>=8.5) qui nous donne les «seconds unix» : clock seconds.
Enregistrement du fichier coe
Il suffit pour cela d’ouvrir en écriture le pathname que nous désinons écrire puis ajouter les valeurs avec puts :
Ajout du crochet (hook)
Pour que notre script tcl soit appelé automatiquement par vivado il faut le définir comme un «hook» de pre-synthèse. Pour cela il faut se rendre dans le menu de configuration de la synthèse:
Puis sélectionner notre script name.tcl dans l’option tcl.pre (pour pre-synthèse).
Le script sera exécuté dans le répertoire :
Il suffit maintenant de lancer la synthèse pour que notre «hook» soit lancé avant la synthèse et remplisse correctement la rom de paramètres de notre design.