URL:
https://linuxfr.org/news/apicula-lancement-de-la-liberation-du-fpga-gowin-gw1n
Title: Apicula : lancement de la libération du FPGA Gowin GW1N
Authors: martoni
BAud, Davy Defaud, zurvan, Ysabeau, Pierre Jarillon et theojouedubanjo
Date: 2019-12-20T15:04:10+01:00
License: CC by-sa
Tags:
Score: 4
Le lecteur assidu de _LinuxFr.org_ sait déjà sans doute ce qu’est un [FPGA](
https://fr.wikipedia.org/wiki/Circuit_logique_programmable#FPGA). Rappelons‑en cependant brièvement la définition.
Les FPGA sont des composants constitués de « champs de portes programmables ». L’idée est de graver un certain nombre d’éléments logiques simples sous forme de matrice et de laisser au développeur le loisir de reconfigurer à l’infini les connexions entre ces portes. Une fois les connexions configurées, on se retrouve avec un composant numérique sur mesure qui ne ressemble à aucun composant disponible chez les fournisseurs classiques. C’est très pratique quand on a besoin d’architectures bâtardes, ou quand justement on développe un composant numérique : ça permet de reconfigurer à l’infini pour déverminer et évaluer les performances.
[Pepijn de Vos](
http://pepijndevos.nl/) a effectué un stage pour [Symbiotic EDA](
https://www.symbioticeda.com/). Et l’ingénierie inverse du GW1N était son sujet de stage. Il a rendu son rapport avant Noël sur [GitHub](
https://github.com/pepijndevos/internshipreport) et a publié le code source du projet [Apicula](
https://github.com/pepijndevos/apicula/).
Vous voulez en savoir plus, lisez la suite…
----
[GitHub du projet](
https://github.com/pepijndevos/apicula)
----
Parlons maintenant du grand drame des FPGA : ils sont complètement verrouillés car, pour reconfigurer ces fameuses connexions, il faut leur téléverser un fichier nommé _bitstream_ qu’aucun constructeur de FPGA ne documente. Ce drame conduit les libristes que nous sommes à se taper des installations d’outils propriétaires particulièrement volumineux (surtout dans le cas de Xilinx et Altera) et pas toujours très stables. Tout ça pour générer le fameux _bitstream_.
Le format du _bitstream_ n’est pourtant pas chiffré. [Depuis plus d’une décennie, on sait](
http://www.fabienm.eu/flf/wp-content/uploads/2014/11/Note2008.pdf) qu’il est parfaitement possible d’en faire l’ingénierie inverse. Mais rien n’avait bougé jusqu’en 2015 quand Clifford (qui se prénomme maintenant [Claire](
http://www.clifford.at/)) Wolf a sorti sa suite open source pour le Lattice [iCE40](
https://en.wikipedia.org/wiki/ICE_(FPGA)#iCE40_(40_nm)) : [IceStorm](
http://www.clifford.at/icestorm/). Le projet IceStorm avait pour but d’analyser toute la gamme des FPGA iCE40 pour en documenter le format du _bitstream_. Projet qui a parfaitement abouti et essaimé : toute la gamme des iCE40 est désormais accessible au moyen d’outils open source, ainsi que la gamme des [ECP5](
https://www.latticesemi.com/Products/FPGAandCPLD/ECP5) avec le [Projet Trellis](
https://github.com/SymbiFlow/prjtrellis).
Presque tous les modèles de FPGA ont leur [projet d’ingénierie inverse](
http://www.fabienm.eu/flf/materiel/liberation-des-fpga/) aujourd’hui. Tous ne sont pas terminés, loin s’en faut. Néanmoins, quelques‑uns avancent, comme le projet [Apicula](
https://github.com/pepijndevos/apicula/) de Pepijn de Vos ciblant les FPGA du constructeur chinois [Gowin](
https://www.gowinsemi.com/en/). Dire que le projet Apicula est abouti serait un raccourci un peu rapide, il manque encore en effet un certain nombre de blocs à décoder. Cependant, il est possible aujourd’hui de réaliser un projet très simple (UNE LED QUI CLIGNOTE \o/) grâce au travail effectué.
# Le Gowin GW1N
Voici l’architecture du GW1N donnée dans la [documentation du composant](
http://dl.sipeed.com/TANG/Nano/HDK/GW1N-Datasheet(English)/GW1N%20series%20of%20FPGA%20Products%20Data%20Sheet.pdf) :
 _Oui, toi aussi, cher lecteur, tu te demandes bien l’intérêt de ce zoom. ;)_
On voit différents éléments dans ce schéma, de la mémoire vive, des [PLL](
https://fr.wikipedia.org/wiki/Boucle_%C3%A0_phase_asservie "phase‑locked loop — boucle à phase asservie") pour générer les horloges, des multiplieurs câblés ([DSP](
https://fr.wikipedia.org/wiki/Processeur_de_signal_num%C3%A9rique "Digital Signal Processor — processeur de signal numérique")), des blocs d’entrées‑sorties (IOB) et surtout — ce que l’on voit le plus — des CFU (_Configurable Function Unit_).
Chez Gowin, le CFU est l’élément de base constitué ainsi :

Les deux éléments qui nous intéressent ici sont : la [LUT](
https://fr.wikipedia.org/wiki/Table_de_correspondance) (_Look Up Table_) et le REG (registre). Ces deux éléments sont la base de la logique synchrone.
Le registre recopie son entrée sur la sortie au front montant de l’horloge, la sortie restant stable le reste du temps.
La LUT, comme son nom anglais l’indique, est une [table de vérité](
https://fr.wikipedia.org/wiki/Table_de_v%C3%A9rit%C3%A9), qui, dans le cas de ce petit FPGA, comporte quatre entrées binaires et une sortie. La configuration du FPGA viendra remplir cette table de vérité pour réaliser une fonction logique. Le registre se trouvant derrière se charge ensuite de verrouiller le résultat au rythme de l’horloge.
Si l’on arrive à déchiffrer le _bitstream_ pour pouvoir configurer ces LUT, ces registres ainsi que les blocs d’entrées‑sorties (IOB), alors on a (presque) gagné : on peut réaliser un composant simple mais fonctionnel.
Et c’est ce qu’a réalisé Pepijn de Vos, on peut donc dire qu’il a amorcé la libération du GW1N de Gowin !
Le projet n’est cependant pas terminé, il faut encore déchiffrer les autres blocs pour permettre l’utilisation complète du FPGA. Il faut également réussir à documenter les temps de propagation des signaux entre les différents blocs. L’information de ces temps de propagation permet au logiciel de placement routage ([nextpnr](
https://github.com/YosysHQ/nextpnr), pour ne citer que le plus célèbre en libre) de faire son travail correctement.
# Mais alors, cette LED clignotante, elle vient ?
Minute, papillon ! Dans un premier temps, il va falloir trouver une carte électronique munie d’un FPGA de Gowin. Nous allons ensuite nous servir des données déjà produites par le projet Apicula pour faire la synthèse avec [Yosys](
http://www.clifford.at/yosys/), puis le placement‐routage avec nextpnr.
Pour le moment, deux kits de développement ont été utilisés dans le projet Apicula :
- le kit [LittleBee TEC0117](
https://shop.trenz-electronic.de/en/TEC0117-01-FPGA-Module-with-GOWIN-LittleBee-and-8-MByte-internal-SDRAM), des Allemands de Trenz Electronic (~ 30 €) ;
- le kit [Tang Nano](
http://www.fabienm.eu/flf/longan-nano-deballage/), des Chinois de [Sipeed](
https://www.sipeed.com/) (~ 5 €).
Nous allons tester avec le kit allemand TEC0117, mais le Tang Nano ne change pas grand’chose à la procédure (et il est moins cher).
On doit installer :
- [Yosys](
https://github.com/YosysHQ/yosys), le logiciel de synthèse [[Verilog]]. Pour le détail des dépendances et autres subtilités d’installation, voir le site officiel. Sinon, pour résumer :
```bash
git clone
https://github.com/YosysHQ/yosys.git
cd yosys
make
sudo make install
```
- [nextpnr](
https://github.com/YosysHQ/nextpnr), le logiciel de placement routage. Il faut le compiler avec le paramètre «generic». Les deux autres paramètres possible à ma connaissance sont `ice40` et `ecp5` (les deux gammes de FPGA vraiment prises en charge par nextpnr) :
```bash
git clone
https://github.com/YosysHQ/nextpnr.git
cd nextpnr/
cmake -DARCH=generic .
make
sudo make install
```
_Dans mon cas, j’ai dû forcer l’utilisation de Python 3.7 dans le fichier `CMakeLists.txt` : `find_package(PythonInterp 3.7 REQUIRED);` pour pouvoir exécuter les scripts en argument avec Python 3.7._
- [Apicula](
https://github.com/pepijndevos/apicula/), dont il faut cloner le dépôt Git :
```bash
git clone
https://github.com/pepijndevos/apicula.git
cd apicula
```
- pour l’instant la « base de données » des éléments trouvés par ingénierie inverse n’est pas « commité » dans le projet Apicula, il faut donc avoir une installation de l’[EDI officiel de Gowin](
https://gowinsemi.com/en/support/home/) ; les scripts du projet Apicula iront fouiller dans les données de l’IDE pour générer un fichier intelligible en JSON et pickle (Python), il n’est cependant pas nécessaire d’avoir la licence ;
- il faut également aller chercher le « _pinout_ » de nos FPGA sur le site officiel de Gowin et le mettre dans son répertoire local nommé `~/Documents/gowinsemi` :
- [GW1NR-9](
https://www.gowinsemi.com/en/search/?search=GW1NR-9+pinout), pour le kit TEC0117,
- [GW1N-1](
https://www.gowinsemi.com/en/search/?search=GW1N-1+pinout), pour le Tang Nano.
Maintenant que nous avons les outils installés, lançons l’exemple générique du projet Apicula :
- d’abord, on génère la base de données des éléments du FPGA :
```bash
export GOWINHOME=/chemin/de/linstallation/gowin/IDE/
export DEVICE="GW1NR-9" # TEC0117
python dat19_h4x.py # makes $DEVICE.json
python tiled_fuzzer.py # makes $DEVICE.pickle
```
- muni de cette base de données, on peut se lancer dans la synthèse du (pas si) simple porte‑gramme de clignotement de LED donné en Verilog ci‑dessous :
```verilog
module top;
wire clk;
(* BEL="R29C29_IOBA", keep *)
GENERIC_IOB #(.INPUT_USED(1), .OUTPUT_USED(0)) clk_ibuf (.O(clk));
wire [7:0] leds;
(* BEL="R1C8_IOBA", keep *)
GENERIC_IOB #(.INPUT_USED(0), .OUTPUT_USED(1)) led7_obuf (.I(leds[7]));
(* BEL="R1C8_IOBB", keep *)
GENERIC_IOB #(.INPUT_USED(0), .OUTPUT_USED(1)) led6_obuf (.I(leds[6]));
(* BEL="R1C10_IOBA", keep *)
GENERIC_IOB #(.INPUT_USED(0), .OUTPUT_USED(1)) led5_obuf (.I(leds[5]));
(* BEL="R1C10_IOBB", keep *)
GENERIC_IOB #(.INPUT_USED(0), .OUTPUT_USED(1)) led4_obuf (.I(leds[4]));
(* BEL="R1C11_IOBA", keep *)
GENERIC_IOB #(.INPUT_USED(0), .OUTPUT_USED(1)) led3_obuf (.I(leds[3]));
(* BEL="R1C11_IOBB", keep *)
GENERIC_IOB #(.INPUT_USED(0), .OUTPUT_USED(1)) led2_obuf (.I(leds[2]));
(* BEL="R1C12_IOBA", keep *)
GENERIC_IOB #(.INPUT_USED(0), .OUTPUT_USED(1)) led1_obuf (.I(leds[1]));
(* BEL="R1C12_IOBB", keep *)
GENERIC_IOB #(.INPUT_USED(0), .OUTPUT_USED(1)) led0_obuf (.I(leds[0]));
reg [25:0] ctr;
always @(posedge clk)
ctr <= ctr + 1'b1;
assign leds = ctr[25:18];
endmodule
```
_Un habitué des LED qui clignotent en Verilog reconnaîtra tout de suite le compteur dans les dernières lignes (`always`, `reg`…) mais sera peut‑être perturbé par la déclaration des entrées‑sorties. Il faut juste avoir en tête que le projet n’est pas terminé et qu’il faut se taper le placement‐routage des entrées‑sorties « à la main », d’où les directives `(* ... *)` et les modules `GENERIC_IOB()`._
- le script pour la synthèse et le placement routage est donné dans l’exemple :
```shell
$ cd generic
$ bash simple.sh blinky.v # TEC0117
$ cd ..
$ python gowin_pack.py generic/pnrblinky.json
$ python gowin_unpack.py pack.fs
$ yosys -p "read_verilog -lib +/gowin/cells_sim.v; clean -purge; show" unpack.v
```
- on doit se retrouver avec un _bitstream_ nommé `pack.fs` que l’on peut téléverser dans le FPGA au moyen de l’utilitaire libre [openFPGALoader](
https://github.com/trabucayre/openFPGALoader) maintenu par _Trabucayre_ (Gwenhael Goavec‑Merou) :
```
openFPGALoader -m -b littleBee pack.fs # FOSS programmer
Parse pack.fs:
Done
erase SRAM Done
Flash SRAM: [==================================================] 100.000000%
Done
SRAM Flash: FAIL
```
_Le `FAIL` est connu et vient d’une sombre histoire de somme de contrôle que openFPGALoader ne sait pas encore calculer et qu’Apicula ne fournit pas. Un ticket est ouvert sur le sujet dans le projet, [_Trabucayre_ sera ravi d’accepter des correctifs](
https://github.com/trabucayre/openFPGALoader/issues/14)._
Et les huit LED doivent clignoter. Enfin, disons plutôt qu’elles comptent en binaire. Pour voir la vidéo des LED clignotantes, c’est sur [YouTube](
https://studio.youtube.com/video/yc2yBYlCCI4/edit).
# Architectures de développement hétéroclites
Comme nous avons des outils _open source_, il est possible de développer sur des ordinateurs à base d’architectures différentes de x86. Voici un petit exemple de téléchargement d’un _bitstream_ sur Tang Nano au moyen d’un Raspberry _Pi_ (architecture ARM). Le _bitstream_ en question permet de piloter un écran à cristaux liquides.
Chose impossible à faire avec les Vivado, Diamond et autres Quartus.

# C’est encore très expérimental
Comme nous venons de le voir, le projet Apicula est encore très expérimental. Cependant, tous les ingrédients sont là et la preuve de fonctionnement est faite. Donc, à condition de mettre un minimum les mains dans le cambouis, on peut désormais générer des _bitstreams_ pour les GW1Nx avec des outils _open source_.
# Super ! Comment je fais pour contribuer ?
Autant d’enthousiasme fait plaisir à voir. Pour contribuer, le mieux est d’acquérir l’une des deux cartes citées dans cette dépêche et d’installer le logiciel officiel de Gowin.
Ensuite, différentes commandes permettant de mettre le pied à l’étrier de l’ingénierie inverse sont données sur le [`README.md` du projet Apicula](
https://github.com/pepijndevos/apicula/).
Sinon, n’hésitez pas à laisser une _issue_ sur le projet [GitHub](
https://github.com/pepijndevos/apicula/issues) ou d’interpeller Pepijn directement sur le « [silo social Twitter](
https://twitter.com/pepijndevos) ». Pepijn est super content de voir des gens s’intéresser au projet et répond très vite.