URL: https://linuxfr.org/news/sortie-de-la-version-0-10-de-yosys Title: Sortie de la version 0.10 de Yosys Authors: martoni palm123, Benoît Sibaud, Pierre Jarillon et Nicolas Boulay Date: 2021-09-27T20:21:13+02:00 License: CC By-SA Tags: open_hardware, yosys, verilog, vhdl et fpga Score: 5 Yosys est devenu le pivot opensource du développement des circuits intégrés [FPGA](https://fr.wikipedia.org/wiki/Circuit_logique_programmable) et [ASIC](https://fr.wikipedia.org/wiki/Application-specific_integrated_circuit). Le 27 septembre 2021 a été publiée la [nouvelle version 0.10 de Yosys](https://github.com/YosysHQ/yosys/releases/tag/yosys-0.10) sur l’hébergeur de gestionnaire de versions GitHub. Cette sortie tardive (la 0.9 date de 2019) est l’occasion de parler de ce logiciel libre de synthèse Verilog, [pivot de la libération des FPGA](https://linuxfr.org/users/martoni/journaux/enfin-une-chaine-de-developpement-completement-open-source-pour-un-fpga) (et des ASIC). Plutôt que de simplement présenter les changements nous allons présenter le logiciel et le principe de la synthèse «[RTL](https://en.wikipedia.org/wiki/Register-transfer_level)». ---- [Changement de la version 0.10 de Yosys](https://github.com/YosysHQ/yosys/releases/tag/yosys-0.10) [Manuel de Yosys ](http://www.clifford.at/yosys/files/yosys_manual.pdf) [Site officiel de Yosys](http://www.clifford.at/yosys/) [Articles précédents sur LinuxFr.org](https://linuxfr.org/tags/yosys/public) ---- Le [manuel de Yosys](http://www.clifford.at/yosys/files/yosys_manual.pdf) représente les différentes couches d’abstractions utilisées en conception numérique. ![Couche d’abstraction utilisées en synthèse numérique](http://fabienm.eu/partage/linuxfr/yosys_synthesis_levels.png) Les couches «System Level» et «High Level» sont généralement des modèles écrits en C/C++/OpenCV/Matlab/... puis convertis en modèles «Behavioral» par un humain. Il existe quelques logiciels dit de «synthèse de haut niveau» qui permettent cette conversion en automatique, mais ça n’est pas la panacée, et (très) souvent verrouillé sur une seule marque de FPGA. Le niveau «Behavioral» est celui dans lequel on décrit le comportement du composant en [**Verilog**](https://fr.wikipedia.org/wiki/Verilog) ou [**VHDL**](https://fr.wikipedia.org/wiki/VHDL). Il est également possible aujourd’hui d’utiliser des langages comme [Clash](https://clash-lang.org/), [Chisel](https://www.chisel-lang.org/) ou [Migen](https://m-labs.hk/gateware/migen/). Ces derniers généreront ensuite du code Verilog au niveau «RTL». Comme son nom l’indique, la couche «RTL» est une description au niveau «transfert de registres». On y décrit le comportement des registres au rythme de l’horloge. Yosys utilise son propre langage nommé RTLIL pour cette étape, mais il est parfaitement possible d’utiliser Verilog ici. Dans la couche «physique» on décrit le système au moyen de portes logiques disponibles dans le FPGA cible. À ce niveau on parlera souvent de «netlist». Cette netlist est souvent décrite au format [EDIF](https://fr.wikipedia.org/wiki/Electronic_Design_Interchange_Format), mais il est possible de la décrire en Verilog ou VHDL. Yosys propose également le format [JSON](https://fr.wikipedia.org/wiki/JavaScript_Object_Notation) bien connu des développeurs JavaScript. Le niveau «switch level» n’est pas vraiment utilisé en synthèse sur FPGA. C’est la description des connexions entre transistors, elle ne fait pas vraiment de sens pour un FPGA dans la mesure où les cellules logiques sont figées dans le FPGA. Arrivé au niveau portes (Physical Gate level) on quitte la synthèse – et donc yosys – pour passer à la mise en paquet (Pack), au placement puis au routage. Et on s’enfonce dans la jungle sombre et humide des logiciels gratuits-mais-pas-trop non libres fournis par les constructeurs. Il existe toutefois un logiciel libre nommé [nextpnr](https://github.com/YosysHQ/nextpnr), mais ça nous éloigne du sujet. Sachez juste que **nextpnr** est parfaitement utilisable pour certaines marques de FPGA (**ICE40, Gowin, ECP5** notamment). Yosys est un logiciel de synthèse **Verilog**, il prend en entrée un source Verilog dans la couche «Behavioral Level» pour descendre dans les couches jusqu’au niveau «Physical Gate». commençons donc par l’exemple de l’inverseur synchrone suivant (fichier `invert.v`): ```Verilog // inverseur module syncinvert( input clock, input reset, input inval, output outval); reg regval; assign outval = regval; always@(posedge clock, posedge reset) begin if(reset) regval <= 1'b0; else regval <= !inval; end endmodule ``` Par défault, Yosys se présente sous la forme d’une console «REPL» (Read Eval Print Loop) et se lance en tapant son nom : ```shell $ yosys /----------------------------------------------------------------------------\ | | | yosys -- Yosys Open SYnthesis Suite | | | | Copyright (C) 2012 - 2020 Claire Xenia Wolf | | | | Permission to use, copy, modify, and/or distribute this software for any | | purpose with or without fee is hereby granted, provided that the above | | copyright notice and this permission notice appear in all copies. | | | | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | | | \----------------------------------------------------------------------------/ Yosys 0.10+0 (git sha1 070cad5f4, clang 8.0.0-svn345496-1~exp1+0~20181029105533.852~1.gbpf10f36 -fPIC -Os) yosys> ``` Premier changement de cette version : l’auteur n’est plus **Clifford Wolf** mais **Claire Xenia Wolf**. Si la date du début du copyright n’a pas changée c’est que les deux sont une seule et même personne, elle a «juste» [changé de prénom](http://www.clifford.at/) et d’état civil. La ligne de commande se comporte comme une ligne de commande shell classique, avec le rappel des commandes par flèche haut/bas, et la complétion avec Ctrl+R et tabulation. On charge son fichier source verilog avec la commande `read_verilog`. ```shell yosys> read_verilog invert.v 1. Executing Verilog-2005 frontend: invert.v Parsing Verilog input from `invert.v' to AST representation. Generating RTLIL representation for module `\syncinvert'. Successfully finished Verilog frontend. ``` Yosys nous informe ici qu’il a bien lu et analysé le fichier source. Le «[gateware](https://www.reddit.com/r/FPGA/comments/b1qiru/definition_of_gateware/)» est bien conforme au standard Verilog-2005 et a été converti dans le langage interne nommé RTLIL (RTL Intermediate Language). On peut lister les modules chargés en mémoire grâce à la commande `ls`. ```shell yosys> ls 1 modules: syncinvert ``` Et afficher une vue graphique du module avec `show`: ```shell yosys> show syncinvert 4. Generating Graphviz representation of design. Writing dot description to `/home/fabien/.yosys_show.dot'. Dumping module syncinvert to page 1. Exec: { test -f '/home/user/.yosys_show.dot.pid' && fuser -s '/home/user/.yosys_show.dot.pid' 2> /dev/null; } || ( echo $$ >&3; exec xdot '/home/fabien/.yosys_show.dot'; ) 3> '/home/user/.yosys_show.dot.pid' & ``` Qui affiche l’image suivante ![Rendu xdot de l’inverseur](http://fabienm.eu/partage/linuxfr/inverter_xdot.png) Cette simple lecture du fichier verilog nous a fait passer la première étape de la synthèse. Nous sommes presque descendus au niveau de la couche «RTL» de la synthèse. Presque, car il faut encore «mapper» la procédure que l’on voit au centre avec la commande `proc`: ```shell yosys> proc 10. Executing PROC pass (convert processes to netlists). 10.1. Executing PROC_CLEAN pass (remove empty switches from decision trees). Cleaned up 0 empty switches. 10.2. Executing PROC_RMDEAD pass (remove dead branches from decision trees). Removed a total of 0 dead cases. 10.3. Executing PROC_PRUNE pass (remove redundant assignments in processes). Removed 0 redundant assignments. Promoted 0 assignments to connections. 10.4. Executing PROC_INIT pass (extract init attributes). 10.5. Executing PROC_ARST pass (detect async resets in processes). 10.6. Executing PROC_MUX pass (convert decision trees to multiplexers). 10.7. Executing PROC_DLATCH pass (convert process syncs to latches). 10.8. Executing PROC_DFF pass (convert process syncs to FFs). 10.9. Executing PROC_MEMWR pass (convert process memory writes to cells). 10.10. Executing PROC_CLEAN pass (remove empty switches from decision trees). Cleaned up 0 empty switches. 10.11. Executing OPT_EXPR pass (perform const folding). Optimizing module syncinvert. ``` Le résultat ressemble beaucoup plus à la [bascule D](https://fr.wikipedia.org/wiki/Bascule_%28circuit_logique%29#Bascule_D) que l’on connaît. ![Rendu xdot de l’inverseur «mappé»](http://fabienm.eu/partage/linuxfr/yosys_mapped_rtl.png) On peut optimiser ce graphe avec la commande `opt`, ce qui supprimera la branche inutile `BUF -> $0\regval[0:0]`. S’ensuit toute une série de commandes d’optimisation comme `memory` pour détecter les tableaux et utiliser des blocs de ram si possible ou `techmap` pour «mapper» les cellules d’une bibliothèque donnée. ```shell yosys> opt; memory; opt; techmap; opt ``` ![Rendu xdot de l’inverseur mappé avec `techmap`](http://fabienm.eu/partage/linuxfr/yosys_techmap.png) Notez que toutes ces commandes étant des commandes d’optimisations, rien n’interdit de les relancer pour améliorer encore l’optimisation (ici les optimisation sont totalement inutiles vu la simplicité du schéma). Beaucoup d’étapes dépendantes de la cible sont ensuite nécessaires pour obtenir une netlist correspondant au composant. Ces étapes étant différentes en fonction de l’architecture cible. Yosys inclut des scripts pour chaque composant supporté. Par exemple, si nous voulons synthétiser pour [icestick](http://www.fabienm.eu/flf/une-led-qui-clignote-sur-icestick-vite-vite-vite/), le FPGA monté sur la carte est un **ice40**, nous pourrons donc utiliser le script nommé `synth_ice40` : ```shell yosys> synth_ice40 [...] 37.47. Printing statistics. === syncinvert === Number of wires: 6 Number of wire bits: 6 Number of public wires: 6 Number of public wire bits: 6 Number of memories: 0 Number of memory bits: 0 Number of processes: 0 Number of cells: 2 SB_DFFR 1 SB_LUT4 1 37.48. Executing CHECK pass (checking for obvious problems). Checking module syncinvert... Found and reported 0 problems. ``` Le lecteur attentif reconnaîtra la [LUT 4 entrées](https://magma-mantle.readthedocs.io/en/stable/ice40/) et la basculeD de l'[ICE40](https://www.latticesemi.com/iCE40) dans le schéma généré : ![Rendu xdot de l’inverseur synthétisé pour ICE40](http://fabienm.eu/partage/linuxfr/yosys_ice40.png) Pour connaitre les scripts de synthèse disponibles dans yosys il suffit d’utiliser la complétion de commande avec `synth_` : ```shell yosys> synth_ synth_achronix synth_coolrunner2 synth_ecp5 synth_gowin synth_ice40 synth_intel_alm synth_nexus synth_sf2 synth_anlogic synth_easic synth_efinix synth_greenpak4 synth_intel synth_machxo2 synth_quicklogic synth_xilinx ``` Ce qui nous donne 16 modèles de FPGA supporté «officiellement» par Yosys. Il n’est pas obligatoire d’avoir un script `synth_` pour pouvoir synthétiser pour un modèle de FPGA du moment que l’on fournit la bibliothèque des primitives. [Pepijn De Vos](http://pepijndevos.nl/2019/07/18/vhdl-to-pcb.html) s’est par exemple amusé à synthétiser vers une bibliothèque de composants en logique discrète (la série des 74-* pour ceux qui connaissent un peu l'électronique). Il a ensuite produit, assemblé et soudé la carte électronique correspondante. Mais! Pepijn est parti d’un gateware écrit en VHDL ! En quoi cela concerne-t-il yosys qui est censé être un logiciel de synthèse **Verilog** ? Pepijn a utilisé pour cela une [extension de yosys](https://github.com/ghdl/ghdl-yosys-plugin) permettant de se connecter au logiciel [GHDL](https://linuxfr.org/news/sortie-de-ghdl-version-1-0-0). Avec cette extension (encore en bêta mais déjà bien avancée), le [VHDL](https://en.wikipedia.org/wiki/VHDL) est décodé avec **GHDL** qui transmet ensuite les informations à Yosys pour la synthèse. Et comme yosys est capable de sortir une version verilog de sa représentation interne RTLIL, on peut s’en servir pour [faire de la conversion VHDL->Verilog sans problème](http://www.fabienm.eu/flf/convertir-du-vhdl-en-verilog-librement-avec-yosys-et-ghdl/). Notre inverseur est désormais synthétisé. Nous pouvons donc l’enregistrer au format de notre choix pour passer ensuite au placement routage. On peut l’écrire au format Verilog par exemple si nous souhaitons le simuler ou tout simplement lire la netlist : ```shell yosys> write_verilog invert_synth.v 41. Executing Verilog backend. Dumping module `\syncinvert'. ``` Ce qui donnera les sources suivantes : ```Verilog /* Generated by Yosys 0.10+0 (git sha1 070cad5f4, clang 8.0.0-svn345496-1~exp1+0~20181029105533.852~1.gbpf10f36 -fPIC -Os) */ (* top = 1 *) (* src = "invert.v:2.1-19.10" *) module syncinvert(clock, reset, inval, outval); (* src = "invert.v:3.11-3.16" *) input clock; (* src = "invert.v:5.11-5.16" *) input inval; (* src = "invert.v:6.12-6.18" *) output outval; (* src = "invert.v:7.5-7.11" *) wire regval; (* src = "invert.v:11.1-17.4" *) wire regval_SB_DFFR_Q_D; (* src = "invert.v:4.11-4.16" *) input reset; (* module_not_derived = 32'd1 *) (* src = "/usr/local/bin/../share/yosys/ice40/cells_map.v:12.34-13.52" *) SB_LUT4 #( .LUT_INIT(16'h00ff) ) inval_SB_LUT4_I3 ( .I0(1'h0), .I1(1'h0), .I2(1'h0), .I3(inval), .O(regval_SB_DFFR_Q_D) ); (* module_not_derived = 32'd1 *) (* src = "invert.v:11.1-17.4|/usr/local/bin/../share/yosys/ice40/ff_map.v:9.57-9.103" *) SB_DFFR regval_SB_DFFR_Q ( .C(clock), .D(regval_SB_DFFR_Q_D), .Q(regval), .R(reset) ); assign outval = regval; endmodule ``` Les sources sont annotées avec des références au verilog initial. On repère bien la bascule SB_DFFR et la SB_LUT4 avec sa configuration. Et dans la mesure du possible, les noms de registres ont été gardés, ce qui rend le fichier assez facile à lire. Pour le placement routage, si on utilise **nextpnr** il faudra «sortir» au format json : ```shell yosys> write_json invert.json 42. Executing JSON backend. ``` Le fichier `invert.json` est beaucoup plus large que la sortie verilog (9779 lignes). Les différents formats de sortie disponibles sont visibles avec la complétion de commande `write_` : ```shell yosys> write_ write_aiger write_btor write_edif write_firrtl write_intersynth write_rtlil write_smt2 write_spice write_verilog write_blif write_cxxrtl write_file write_ilang write_json write_simplec write_smv write_table write_xaiger ``` Cette possibilité de convertir dans différents formats le verilog initial fait de Yosys le couteau suisse du gateware. On peut s’en servir pour faire de la synthèse à destination des FPGA bien sûr, mais il est possible de «mapper» sur d’autres bibliothèques pour faire des PCB «discret» comme on l’a vu avec Pepijn De Vos. Il est également possible de faire de la synthèse à destination des ASIC. Yosys est d’ailleurs utilisé par la chaîne de développement opensource [OpenLane](https://github.com/The-OpenROAD-Project/OpenLane). Enfin, les modèles synthétisés par yosys peuvent servir à faire de la preuve formelle, à partir de [sources verilog](http://www.testandverification.com/wp-content/uploads/2017/Formal_Verification/Clifford_Wolf.pdf) mais également [VHDL](https://vhdlwhiz.com/formal-verification-in-vhdl-using-psl/). En règle générale, il n’est pas nécessaire de connaître les détails des commandes de Yosys. L’utilisation de yosys est enfouie dans les scripts et autres Makefile des outils utilisés. Bref, en quelques années, Yosys est devenu le pivot opensource du développement FPGA et ASIC. Il méritait bien une dépêche sur LinuxFr.org !