En ligne de commande ?
Oui, c'est beaucoup plus pratique que le programmateur graphique. Charger un FPGA avec un fichier de bitstream (bitstream) est une tâche récurrente. C'est toujours le même fichier, vers le même FPGA, sur la même carte, branchée au même ordinateur. Et pourtant, les outils graphiques transforment cela en une cérémonie intimidante (et parfois même en jeu-questionnaire lorsqu'ils n'arrivent pas à identifier précisément le composant connecté, et que je suis censé connaître le modèle exact).
En ligne de commande, c'est littéralement une affaire de retrouver la commande dans l'historique de bash et d'appuyer sur Entrée. Et, chose étonnante, l'outil en ligne de commande ne pose pas les questions stupides que pose l'outil graphique.
D'abord, un peu d'exploration
Mettez en place l'environnement :
$ /path/to/quartus/15.1/nios2eds/nios2_command_shell.sh
Pour lister tous les périphériques détectés (le câble est détecté automatiquement) :
$ quartus_pgm --auto
Info: *******************************************************************
Info: Running Quartus Prime Programmer
Info: Version 15.1.0 Build 185 10/21/2015 SJ Lite Edition
Info: Copyright (C) 1991-2015 Altera Corporation. All rights reserved.
[ ... ]
Info: agreement for further details.
Info: Processing started: Sun May 27 15:06:22 2018
Info: Command: quartus_pgm --auto
Info (213045): Using programming cable "USB-BlasterII [2-5.1]"
1) USB-BlasterII [2-5.1]
02B040DD 5CGTFD9(A5|C5|D5|E5)/..
020A40DD 5M2210Z/EPM2210
[ ... ]
Remarquez que lister les périphériques comme ci-dessus n'est pas nécessaire pour charger le bitstream. Cela peut tout au plus servir à déterminer la position du FPGA dans la chaîne JTAG, peut-être. Vraiment quelque chose que l'on fait une fois pour explorer la carte.
jtagd
Il est important de connaître ce démon, qui écoute sur le port TCP/IP 1309. Il est responsable de la communication avec l'adaptateur JTAG via le bus USB, donc aussi bien le programmateur graphique que l'outil en ligne de commande en dépendent. S'il n'y a pas de démon en cours d'exécution, ces deux outils le démarrent.
Mais si vous utilisez plusieurs versions de Quartus, cela peut être une source de confusion, en particulier si vous tentez d'abord de charger un FPGA avec une version plus ancienne, puis une version plus récente. En effet, la version plus récente de Quartus continuera à utiliser l'ancienne version de jtagd. Or, cette ancienne version de jtagd peut ne pas prendre en charge les FPGA que la version plus récente de Quartus connaît. Conclusion : si des choses bizarres se produisent, la commande suivante pourra régler le problème, et ne fera de toute façon pas de mal :
$ killall jtagd
Chargement du FPGA
quartus_pgm affiche l'essentiel de sa sortie en vert. D'une manière générale, s'il n'y a pas de texte en rouge, tout s'est bien passé.
$ quartus_pgm -m jtag -o "p;path/to/file.sof"
Vous pouvez aussi préciser explicitement la position du composant dans la chaîne JTAG (notamment s'il n'est pas le premier). Dans ce cas, on écrit @1, ce qui signifie que c'est le premier dispositif de la chaîne JTAG. S'il est le deuxième, choisissez @2, etc.
$ quartus_pgm -m jtag -o "p;path/to/file.sof@1"
Info: *******************************************************************
Info: Running Quartus Prime Programmer
Info: Version 15.1.0 Build 185 10/21/2015 SJ Lite Edition
Info: Copyright (C) 1991-2015 Altera Corporation. All rights reserved.
Info: Your use of Altera Corporation's design tools, logic functions
Info: and other software and tools, and its AMPP partner logic
Info: functions, and any output files from any of the foregoing
Info: (including device programming or simulation files), and any
Info: associated documentation or information are expressly subject
Info: to the terms and conditions of the Altera Program License
Info: Subscription Agreement, the Altera Quartus Prime License Agreement,
Info: the Altera MegaCore Function License Agreement, or other
Info: applicable license agreement, including, without limitation,
Info: that your use is for the sole purpose of programming logic
Info: devices manufactured by Altera and sold by Altera or its
Info: authorized distributors. Please refer to the applicable
Info: agreement for further details.
Info: Processing started: Sun May 27 15:35:02 2018
Info: Command: quartus_pgm -m jtag -o p;path/to/file.sof@1
Info (213045): Using programming cable "USB-BlasterII [2-5.1]"
Info (213011): Using programming file p;path/to/file.sof@1 with checksum 0x061958E1 for device 5CGTFD9E5F35@1
Info (209060): Started Programmer operation at Sun May 27 15:35:05 2018
Info (209016): Configuring device index 1
Info (209017): Device 1 contains JTAG ID code 0x02B040DD
Info (209007): Configuration succeeded -- 1 device(s) configured
Info (209011): Successfully performed operation(s)
Info (209061): Ended Programmer operation at Sun May 27 15:35:09 2018
Info: Quartus Prime Programmer was successful. 0 errors, 0 warnings
Info: Peak virtual memory: 432 megabytes
Info: Processing ended: Sun May 27 15:35:09 2018
Info: Elapsed time: 00:00:07
Info: Total CPU time (on all processors): 00:00:03
Si quelque chose tourne mal — mauvais composant, échec de l'analyse de la chaîne JTAG ou autre, impossible de le rater, car des erreurs s'affichent en rouge. Ce qui est bien avec l'interface en ligne de commande, c'est que chaque tentative reprend tout depuis le début. Il suffit donc d'allumer la carte et de réessayer.
Carte de développement Cyclone 10 GX FPGA
Cette carte m'a causé quelques soucis supplémentaires, alors voici quelques mots à son sujet. Lorsque cette carte est branchée à un ordinateur, elle apparaît comme 09fb:6810. Cependant, après avoir tenté de charger le FPGA (notons le « @2 » à la fin) avec :
$ quartus_pgm -m jtag -o "p;thecode.sof@2"
Error (213019): Can't scan JTAG chain. Error code 86.
L'identifiant du périphérique change alors pour 09fb:6010. Il y a donc clairement une reprogrammation du firmware (le journal système montre une déconnexion puis une reconnexion avec le nouvel identifiant). La carte est détectée comme GX0000406 par l'outil graphique de programmation de Quartus, mais cliquer sur « Auto Detect » donne « Unable to scan device chain. Hardware is not connected ».
Bon, et si on essayait une analyse ?
$ quartus_pgm --auto
[ ... ]
Info (213045): Using programming cable "10CGX0000406 [1-5.1.2]"
1) 10CGX0000406 [1-5.1.2]
Unable to read device chain - Hardware not attached
Dans mon cas, le problème venait apparemment du fait que le jtagd en cours d'exécution avait été démarré par une version plus ancienne de Quartus, qui ne reconnaissait pas les composants Cyclone 10. Suivez donc le conseil ci-dessus et tuez-le. Ensuite, la programmation avec la commande ci-dessus a fonctionné avec Quartus Pro 17.1 :
$ quartus_pgm --auto
[...]
Info (213045): Using programming cable "USB-BlasterII [1-5.1.2]"
1) USB-BlasterII [1-5.1.2]
031820DD 10M08SA(.|ES)/10M08SC
02E120DD 10CX220Y