Archives mensuelles : juillet 2021

Test d’une carte Gowin avec LiteX

Après avoir déballé le kit gowin proposé par trenz micro. Il faut trouver quelques chose à faire de plus avancé qu’un simple clignotement de LED. Pour le clignotement de LED et la prise en main des outils, le lecteur se référera à l’article Hackable 32.

Pourquoi ne pas tenter le Linux des FPGA, j’ai nommé LiteX (Prononcez Lahïtixe ) ? LiteX est un framework HDL basé sur Migen pour construire des systèmes matériel facilement en python.

LiteX inclut un langage de description matériel, mais également tous les outils permettant de faire des simulations, la synthèses et générer les bitstreams pour la plupart des FPGA du marché. Bien évidement, en ce qui concerne la synthèse et les bitstreams, LiteX pilote les outils propriétaires des constructeurs. Ce pilotage ne pose généralement pas trop de problème, car tous les outils constructeurs proposent des interfaces en ligne de commande.

La carte que nous allons tenter de faire fonctionner avec LiteX est donc la TEC0117-1 produite par Trenz electronic et munie d’un FPGA gowin .

La carte TEC0117-1 de trenz micro se pilote intégralement avec le port série.

D’après le wiki, la carte n’est pas encore officiellement supporté par LiteX puisqu’elle ne se trouve pas dans la liste du projet LiteX-Boards

Pas dans le tableau de la documentation du moins, car en fouillant dans le code du projet, il semble qu’il y ait déjà un embryon de quelques chose ici. Voila qui est très engageant pour tester la carte.

Voyons donc voir les étapes nous permettant de construire un système avec LiteX.

Installation de LiteX

Le plus simple pour installer LiteX sur son ordinateur est d’aller suivre le guide officiel d’installation.

$ wget https://raw.githubusercontent.com/enjoy-digital/litex/master/litex_setup.py
$ chmod +x litex_setup.py
$ ./litex_setup.py init install --user (--user to install to user directory)

Attention, si comme moi vous avez un pc qui commence à prendre sérieusement de l’âge, sachez que le script litex_setup.py va descendre beaucoup de projets annexes de LiteX. Ça va prendre quelques minutes.

On aura besoin également de gcc compilé pour RISC-V :

$ ./litex_setup.py gcc

Il faudra bien penser à l’exporter à chaque fois qu’on en aura besoin :

$ export PATH=$PATH:$(echo $PWD/riscv64-*/bin/)

Construire le système pour TEC0117

Pour construire un système pour la carte il faut ensuite se rendre dans le répertoire contenant la carte puis lancer le script python correspondant:

$ export PATH=$PATH:$(echo $PWD/riscv64-*/bin/)
$ cd litex-boards/litex_boards/targets
$ python3 trenz_tec0117.py

Pour synthétiser et générer le bitstream il faut d’abord ajouter le lien vers l’ide (1.9.7 minimum) de gowin :

$ export PATH=$PATH:/opt/gowin/1_9_7/IDE/bin/

Puis lancer le build:

$ python litex-boards/litex_boards/targets/trenz_tec0117.py --build
INFO:SoC:        __   _ __      _  __  
INFO:SoC:       / /  (_) /____ | |/_/  
INFO:SoC:      / /__/ / __/ -_)>  <    
INFO:SoC:     /____/_/\__/\__/_/|_|  
INFO:SoC:  Build your hardware, easily!
INFO:SoC:--------------------------------------------------------------------------------

...

Running timing analysis......
[95%] Timing analysis completed
Bitstream generation in progress......
Bitstream generation completed
Running power analysis......
[100%] Power analysis completed
Generate file "/home/fabienm/myapp/litex/build/trenz_tec0117/gateware/impl/pnr/project.power.html" completed
Generate file "/home/fabienm/myapp/litex/build/trenz_tec0117/gateware/impl/pnr/project.pin.html" completed
Generate file "/home/fabienm/myapp/litex/build/trenz_tec0117/gateware/impl/pnr/project.rpt.html" completed
Generate file "/home/fabienm/myapp/litex/build/trenz_tec0117/gateware/impl/pnr/project.rpt.txt" completed
Generate file "/home/fabienm/myapp/litex/build/trenz_tec0117/gateware/impl/pnr/project.tr.html" completed
Fri Jul  9 13:18:07 2021

Le bitstream généré au format *.fs se trouve ensuite dans le répertoire

./build/trenz_tec0117/gateware/impl/pnr/project.fs

On pourra configurer le FPGA directement avec openFPGALoader :

$ openFPGALoader ./build/trenz_tec0117/gateware/impl/pnr/project.fs
Parse ./build/trenz_tec0117/gateware/impl/pnr/project.fs: 
checksum 0x15d3
Done
erase SRAM Done
Flash SRAM: [==================================================] 100.000000%
Done
SRAM Flash: Success

Ou avec la bonne option litex (qui fait appel à openFPGALoader de toute manière):

$ python3 ../litex-boards/litex_boards/targets/trenz_tec0117.py --load
INFO:SoC:        __   _ __      _  __  
INFO:SoC:       / /  (_) /____ | |/_/  
INFO:SoC:      / /__/ / __/ -_)>  <    
INFO:SoC:     /____/_/\__/\__/_/|_|  
INFO:SoC:  Build your hardware, easily!
INFO:SoC:--------------------------------------------------------------------------------
INFO:SoC:Creating SoC... (2021-07-12 19:05:10)
INFO:SoC:--------------------------------------------------------------------------------
INFO:SoC:FPGA device : GW1NR-LV9QN88C6/I5.
INFO:SoC:System clock: 25.00MHz.
INFO:SoCBusHandler:Creating Bus Handler...

...

INFO:SoC:Initializing ROM rom with contents (Size: 0x51cc).
INFO:SoC:Auto-Resizing ROM rom from 0x6000 to 0x51cc.
Parse /home/user/myapp/litex/myapp/build/trenz_tec0117/gateware/impl/pnr/project.fs: 
checksum 0xa3a3
Done
erase SRAM Done
Flash SRAM: [==================================================] 100.000000%
Done
SRAM Flash: Success

La confirmation de la bonne configuration est donnée par le message de la console, mais également par le chenillard de LED rouge.

Console litex>

Le convertisseur USB-uart de la carte possède deux interfaces ttyUSB, la première vient d’être utilisée par openFPGALoader pour charger le bitstream, la seconde permet de se connecter à la console litex :

$ screen /dev/ttyUSB1 115200
litex> reboot


        __   _ __      _  __
       / /  (_) /____ | |/_/
      / /__/ / __/ -_)>  <
     /____/_/\__/\__/_/|_|
   Build your hardware, easily!

 (c) Copyright 2012-2021 Enjoy-Digital
 (c) Copyright 2007-2015 M-Labs

 BIOS built on Jul  9 2021 13:17:06
 BIOS CRC passed (855636f6)

 Migen git sha1: 3ffd64c
 LiteX git sha1: 2b49430f

--=============== SoC ==================--
CPU:            VexRiscv_Lite @ 25MHz
BUS:            WISHBONE 32-bit @ 4GiB
CSR:            32-bit data
ROM:            24KiB
SRAM:           4KiB
L2:             0KiB
SDRAM:          8192KiB 16-bit @ 25MT/s (CL-2 CWL-2)

--========== Initialization ============--
Initializing SDRAM @0x40000000...
Switching SDRAM to software control.
Switching SDRAM to hardware control.
Memtest at 0x40000000 (2.0MiB)...
  Write: 0x40000000-0x40200000 2.0MiB     
   Read: 0x40000000-0x40200000 2.0MiB     
Memtest OK
Memspeed at 0x40000000 (2.0MiB)...
  Write speed: 5.6MiB/s
   Read speed: 6.2MiB/s

--============== Boot ==================--
Booting from serial...
Press Q or ESC to abort boot completely.
sL5DdSMmkekro
             Timeout
No boot medium found

--============= Console ================--

litex> 

La commande help nous donnes les commandes disponibles :

litex> help


LiteX BIOS, available commands:

leds                     - Set Leds value
flush_l2_cache           - Flush L2 cache
flush_cpu_dcache         - Flush CPU data cache
crc                      - Compute CRC32 of a part of the address space
ident                    - Identifier of the system
help                     - Print this help

serialboot               - Boot from Serial (SFL)
reboot                   - Reboot
boot                     - Boot from Memory

mem_speed                - Test memory speed
mem_test                 - Test memory access
mem_copy                 - Copy address space
mem_write                - Write address space
mem_read                 - Read address space
mem_list                 - List available memory regions

sdram_test               - Test SDRAM

Photo traditionnelle

Avec LiteX, une tradition «twitter» veux que l’on fasse une photo du kit démarrant LiteX avec la console démarrée.

Photo trophée de la tec0117 avec LiteX

Et voila \o/

L’entrée en matière est incroyablement facile et fait honneur au slogan «Build your hardware, easily!».

Nous regarderons dans de futur articles ce que l’on peut faire avec.

Utiliser UNISIM avec GHDL et CocoTB

Les constructeurs de FPGA fournissent des modèles VHDL de leurs primitives. Chez Xilinx cela se présente sous la forme d’une librairie nommée UNISIM.

Le logiciel libre de simulation GHDL n’inclut pas les sources VHDL de cette librairie dans son dépôt officiel car ça n’est pas sa propriété. Cependant, GHDL fourni des scripts permettant de les pré-compiler pour son projet.

Nous allons voir ici comment se servir des primitives disponible dans vivado avec une simulation utilisant CocoTB.

Les sources des primitives se trouvent dans le répertoire d’installation de Vivado

data/vhdl/src/unisims/

Il peut être intéressant de mettre les librairies compilé à cette endroit pour y faire référence depuis tous ses projets ensuite :

cd data/vhdl
mkdir ghdl
cd ghdl
/usr/local/lib/ghdl/vendors/compile-xilinx-vivado.sh -a
[...]

Il y a une erreur dans le VHDL de xilinx qu’il faut corriger à la main avant de lancer le script de compilation. Dans le fichier `BUFG_GT_SYNC.vhd`, à la ligne 73 il faut remplacer :

    wait for 1ps;
    wait for 1 ps; -- notez l'espace

Pour compiler la librairie unisim pour vivado on utilisera le script suivant :

/usr/local/lib/ghdl/vendors/compile-xilinx-vivado.sh -a --vhdl2008
Loading environment...
Not all Xilinx primitives are VHDL-2008 compatible! Setting CONTINUE_ON_ERROR to TRUE.
Analyzing library 'unisim'...
Creating VHDL Library 'unisim'...
Analyzing files into library 'unisim'...
  WARNING: /opt/Xilinx/Vivado/2020.2/data/vhdl/src/unisims/primitive/SYSMONE4.vhd:1536:44:warning: prefix of array attribute must be an object name [-Wattribute]
SCRIPT ERROR: Unfiltered line
v_str_time_length := time'image(now)'length;
SCRIPT ERROR: Unfiltered line
^
  Warnings detected by filtering script.
Analyzing library 'secureip'...
Creating VHDL Library 'secureip'...
Analyzing files into library 'secureip'...
Analyzing library 'unimacro'...
Creating VHDL Library 'unimacro'...
Analyzing files into library 'unimacro'...
Analyzing library 'unifast'...
Creating VHDL Library 'unifast'...
Analyzing files into library 'unifast'...
Analyzing library 'secureip'...
Creating VHDL Library 'secureip'...
Analyzing files into library 'secureip'...
  WARNING: /opt/Xilinx/Vivado/2020.2/data/vhdl/src/unifast/secureip/GTHE2_CHANNEL.vhd:29:1:warning: entity "gthe2_channel" was also defined in file "/opt/Xilinx/Vivado/2020.2/data/vhdl/src/unisims/secureip/GTHE2_CHANNEL.vhd" [-Wlibrary]
SCRIPT ERROR: Unfiltered line
library IEEE;
SCRIPT ERROR: Unfiltered line
^
  Warnings detected by filtering script.
  WARNING: /opt/Xilinx/Vivado/2020.2/data/vhdl/src/unifast/secureip/GTXE2_CHANNEL.vhd:34:1:warning: entity "gtxe2_channel" was also defined in file "/opt/Xilinx/Vivado/2020.2/data/vhdl/src/unisims/secureip/GTXE2_CHANNEL.vhd" [-Wlibrary]
SCRIPT ERROR: Unfiltered line
library IEEE;
SCRIPT ERROR: Unfiltered line
^
  Warnings detected by filtering script.
--------------------------------------------------------------------------------
Compiling Xilinx Vivado libraries [SUCCESSFUL]

La compilation prend un temps infini, compter au moins 5 minutes sur un PC muni de 16 cores. Il suffira ensuite d’ajouter les lignes suivantes à son makefile CocoTB :

UNISIMDIR=$(VIVADODIR)/data/vhdl/ghdl/xilinx-vivado/unisim/v93
EXTRA_ARGS=-P$(UNISIMDIR)

Et roulez jeunesse.