Archives de catégorie : outils

openFPGALoader: One program to configure them all.

openFPGALoader is an open source C++ utility prog used to program/configure FPGA.

The goal of this project is to have one command line program to configure all types of FPGA regardless of probe or development kit is used.

For the moment the following FPGA are supported :

But the project is growing fast, no doubt that other FPGA will be supported soon.

Not only it’s easier to use than GUI, but it really fastest. With a MachXO3 6900 and digilent HS3 probe it take about 10 seconds on my computer :

$ time openFPGALoader -cdigilent_hs3 bitstream.jed
Open file bitstream.jed DONE
Parse file DONE
Enable configuration: DONE
SRAM erase: DONE
Enable configuration: DONE
Flash erase: DONE
Writing: [==================================================] 100.000000%
Done
Verifying: [==================================================] 100.000000%
Done
Write program Done: DONE
Disable configuration: DONE
Refresh: DONE

real	0m10,274s
user	0m0,728s
sys	0m1,676s

With official lattice diamond programer it take me 50 seconds.

Cocotb Tips

Some tips for python HDL test module Cocotb.

Read and Write signal

Write:

clk.value = 1
dut.input_signal <= 12
dut.sub_block.memory.array[4] <= 2

Read:

count = dut.counter.value
print(count.binstr)
print(count.integer)
print(count.n_bits)
print(int(dut.counter))

See it under the official documentation.

Yielding a coroutine in a select list fashion

Question asked on stackoverflow.

Using latest python version with virtualenv

If you compile python yourself, don’t forget to add option --enable-shared at configure time (./configure --enable-shared)

$ virtualenv --python=/usr/local/bin/python3.7 ~/envp37
$ source ~/envp37/bin/activate
$ python -m pip install cocotb

Do not forget to re-source your environnement each time you open a new terminal :

$ source ~/envp37/bin/activate

Logging messages and main test class template

This is a template for declaring a class used for test in function @cocotb.test() :

import logging
from cocotb import SimLog
...

class MyDUTNameTest(object):
    """ Test class for MyDUTName"""
    LOGLEVEL = logging.INFO
    # clock frequency is 50Mhz
    PERIOD = (20, "ns")

    def __init__(self):
        if sys.version_info[0] < 3: # because python 2.7 is obsolete
            raise Exception("Must be using Python 3")
        self._dut = dut
        self.log = SimLog("RmiiDebug.{}".format(self.__class__.__name__))
        self.log.setLevel(self.LOGLEVEL)
        self._dut._log.setLevel(self.LOGLEVEL)
        self.clock = Clock(self._dut.clock, self.PERIOD[0], self.PERIOD[1])
        self._clock_thread = cocotb.fork(self.clock.start())

# ....

@cocotb.test()
def my_test(dut):
    mdutn = MyDUTNameTest()
    mdutn.log.info("Launching my test")

Déballage du kit de développement Lichee Tang muni d’un FPGA Chinois Anlogic

La société chinoise SiPeed propose un kit de développement permettant d’évaluer le FPGA chinois EG4S20BG256 produit par Anlogic. Le kit peut être commandé pour une vingtaine de dollars sur le site de vente en ligne Seeed spécialisé dans les kits de développement en électronique «grand public».

Contenu du kit SiPeed coté FPGA
Contenu du kit Lichee Tang botto

Au branchement du kit Debian/Linux détecte un convertisseur USB-JTAG de chez Anlogic:

$ sudo dmesg -c
[30017.300586] usb 3-2: new full-speed USB device number 5 using xhci_hcd
[30017.441796] usb 3-2: New USB device found, idVendor=0547, idProduct=1002
[30017.441801] usb 3-2: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[30017.441804] usb 3-2: Product: USB-JTAG-Cable
[30017.441807] usb 3-2: Manufacturer: Anlogic

L’environnement de développement est disponible en téléchargement (~100Mo) sous forme d’une archive rar ici. Le fichier se décompresse avec la commande unrar:

$ unrar x ../TD_RELEASE_SEPTEMBER2018_RHEL.rar

Il faut ensuite mettre en exécutable le répertoire bin:

$ chmod +x bin/*

Et on peut ensuite lancer l’IDE:

$ cd bin ; ./td -gui

La fenêtre suivante s’ouvre alors :

L’environnement de développement Tang Dynasty lancé sur Debian

C’est l’environement de développement le plus simple à installer que j’ai pu voir depuis que je bricole des FPGA. Même si la procédure d’installation est quand même étrange (un obscure .rar à télécharger puis à décompresser).

Pour synthétiser un premier design on va avoir besoin d’un minimum de documentation sur la schématique de la carte ainsi que sur le pinout du FPGA. On trouvera les schémas du kit en format pdf ici.

On trouve des exemples de code pour le kit sur github, notamment pour faire clignoter une led. La base du Hello World en électronique.

Pour tester la led qui clignote on crée un nouveau projet avec le fpga EG4S20BG256. On ajoute ensuite le source pour la led se trouvant dans le répertoire Tang_FPGA_Examples/0.LED/src/led.v

L’extension du fichiers de contrainte est en *.adc pour l’exemple de led le fichier se trouve dans le répertoire Tang_FPGA_Examples/0.LED/constraint/io.adc

Une fois les deux fichiers ci-dessus ajouté à notre projet on peut lancer la procédure complète pour générer le bitstream en double-cliquant sur l’icône «Generate Bitstream» dans l’encart «FPGA Flow» de l’ide.

La génération du bitstream est très rapide. Pour le télécharger ensuite dans le FPGA il faut bien sûr que le kit soit connecté à l’usb.

Le configurateur se lance en allant dans le menu Tools -> Download.

Chez moi j’ai du lancer l’ide en sudo pour éviter un plantage fatal, à ce moment. Le configurateur se présente comme ci-dessous :

Il faut ajouter le fichier bitstream au moyen du bouton de gauche «Add» puis cliquer sur la ligne du tableur pour «dégriser» le bouton «run», qui permet de télécharger le bitstream pour configurer le FPGA.

Pour conclure, je pensais beaucoup plus souffrir à mettre en route ce kit à la documentation majoritairement en chinois. Mais la note de blog de JAEB et le projet d’exemples sur github m’ont beaucoup aidé à faire clignoter cette led tricolore rapidement. À l’avenir il faudra regarder si ce FPGA est vraiment nouveau ou si ça n’est pas une copie d’un constructeur bien connu. On doit pouvoir vérifier ça avec le bitstream généré.

Au bout de quelques temps, la licence du logiciel expire. Il n’est plus possible de synthétiser avec. Un site chinois donne le truc pour que ça remarche. Pour éviter ce piratage, il semble être maintenant possible d’utiliser Yosys pour la partie synthèse !

Pour aller plus loin:

Installing Libero on Debian 9

This is just an install success story of Libero on Debian 9 (stretch).  For the Risc-V contest, I recently acquired the Microsemi IGLOO2 development kit named FUTUREM2GL-EVB  distributed by Futur-Electronic.

The development software for the IGLOO2 is named Libero and according to Microsemi, should works on Linux. But officially support only RedHat, CentOS and SuSE … not Debian. Microsemi provide a Linux installation guide to install it. It’s useful but should be adapted for Debian.

Download and install Libero

The first thinks to do is to download the installing file for Linux (and not the SP1 file which is only an update).  Once downloaded we just have to launch it, if it’s not executable we can change rights with chmod command.

$ chmod 666 Libero_SoC_v11.9_Linux.bin
$ ./Libero_SoC_v11.9_Linux.bin

An install windows will raise and we can follow directives.

Licensing

Once installed, we need to install the license. For that, we need to know our mac address :

$ ip addr show dev eth0
[...]
link/ether 12:34:56:78:9a:bc [...]

The key that should be given to Microsemi is in upper case without ‘:’ :

$ ipython

In [1]: "12:34:56:78:9a:bc".replace(':','').upper()                                                                                                                                                             
Out[1]: '123456789ABC'

With this key we can then ask for a license file on microsemi website. The official Linux guide talk about license.dat file, but for me it was license.zip … Both are zip file in fact. We can then unflat it with unzip command:

$ unzip License.zip 
Archive:  License.zip
  inflating: License.dat

The unflated file is a text file that should be edited with you text edito as explained in guide (page 6).

License server

The license server deamon must be downoaded on official microsemi website. Choose «Linux deamon» in table. It’s an archive of several binaries that should be unflated :

$ cd
$ tar -zxvf Linux_Licensing_Daemon.tar.gz
Linux_Licensing_Daemon/
Linux_Licensing_Daemon/actlmgrd
Linux_Licensing_Daemon/lmgrd
Linux_Licensing_Daemon/lmhostid
Linux_Licensing_Daemon/lmutil
Linux_Licensing_Daemon/mgcld
Linux_Licensing_Daemon/snpslmd
Linux_Licensing_Daemon/syncad
Linux_Licensing_Daemon/synplctyd

Export shell variables

Before launching software, we have to export some paths in our .bashrc :

#Libero 
LIBERO_LICENSE_FOLDER=/home/giselle/flexlm
LD_LIBRARY_PATH=/usr/lib/i386-linux-gnu/:/usr/lib/x86_64-linux-gnu/
# For Floating License from a License Server
export LM_LICENSE_FILE=1702@gisellelaptop:$LM_LICENSE_FILE
export SNPSLMD_LICENSE_FILE=1702@gisellelaptop:$SNPSLMD_LICENSE_FILE
# <1702> is the port number
# martonilp is the license server host name
#For Node-Locked License
export LM_LICENSE_FILE=$LIBERO_LICENSE_FOLDER/license.dat:$LM_LICENSE_FILE
export SNPSLMD_LICENSE_FILE=$LIBERO_LICENSE_FOLDER/license.dat:$SNPSLMD_LICENSE_FILE
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/lib
export DISPLAY=:0
export PATH=/opt/microsemi/Libero_SoC_v11.9/Libero/bin:$PATH

On my computer, Microsemi softwares are installed in /opt/ directory.

Launching Libero

First launch license server :

$ cd
$./flexlm/lmgrd -c ~/flexlm/License.dat -log /tmp/lmgrd.log

Once license server launched we can run Libero :

$ libero
/opt/microsemi/Libero_SoC_v11.9/Libero/bin/libero_bin: /opt/microsemi/Libero_SoC_v11.9/Libero/lib/libz.so.1: no version information available (required by /usr/lib/i386-linux-gnu/libpng16.so.16)

I had a little problem with libz provided with libero package, then I removed it and linked libz of my distribution :

$ apt-file search libz.so
lib32z1: /usr/lib32/libz.so.1
lib32z1: /usr/lib32/libz.so.1.2.8
lib32z1-dev: /usr/lib32/libz.so
zlib1g: /lib/x86_64-linux-gnu/libz.so.1
zlib1g: /lib/x86_64-linux-gnu/libz.so.1.2.8
zlib1g-dev: /usr/lib/x86_64-linux-gnu/libz.so
...
$ cd /opt/microsemi/Libero_SoC_v11.9/Libero/lib
$ mv libz.so.1 oldlibz.so.1
$ ln -s /lib/x86_64-linux-gnu/libz.so.1 libz.so.1

And then managed to launch it :

$ libero

Hurrah \o/ that works

But it’s unfortunately not finished.

First, when I tryied to synthesize I had this message in error window :

/opt/microsemi/Libero_SoC_v11.9/Synplify/bin/synplify_pro: 137: [: unexpected operator
/opt/microsemi/Libero_SoC_v11.9/Synplify/bin/synplify_pro: 151: [: !=: argument expected
/opt/microsemi/Libero_SoC_v11.9/Synplify/bin/synplify_pro: 324: /opt/microsemi/Libero_SoC_v11.9/Synplify/bin/config/execute: Syntax error: "(" unexpected (expecting ";;")

The problem come from the shell Debian uses by default :

$ ls -lha /bin/sh
lrwxrwxrwx 1 root root 4 oct.  29 20:50 /bin/sh -> dash

This shell doesn’t work like bash and generate some error in synplify scripts. To solve it I simply changed the /bin/sh link to /bin/bash :

$ cd /bin/
$ sudo mv sh shold
$ sudo ln -s bash sh

And I managed to synthesize my design.

But it’s not finished ! Once my bitstream generated I would like to download it on the IGLOO2 on kit. For that, we have to install correctly drivers for FlashPro5.
Directives are given in the official Microsemi Linux install guide, but udev syntax is false on Debian :

BUS=="usb",SYSFS{idProduct}=="2008",SYSFS{idVendor}=="1514",MODE="0660",GROUP="",SYMLINK+="FlashPro5"
BUS=="usb",SYSFS{idProduct}=="6001",SYSFS{idVendor}=="0403",MODE="0660",GROUP="",SYMLINK+="FTDI232"

Right rules are following :

# FlashPro5
SUBSYSTEM=="usb", ATTR{idVendor}=="1514", ATTR{idProduct}=="2008", MODE="0666", GROUP="plugdev"
SUBSYSTEM=="usb", ATTR{idVendor}=="0403", ATTR{idProduct}=="6001", MODE="0666", GROUP="plugdev"

Should be written in /etc/udev/rules.d/70-microsemi.rules file.

Then fully works  and they lived happily and urged a lot of children

Verilator 4.002

La version 4.002 de Verilator a été annoncée à la conférence ORConf2018 en Pologne.

Verilator est sans conteste le simulateur HDL open source le plus rapide du « marché ». Il permet de simuler des porte‐grammes écrits en Verilog synthétisable.

Le nouveau logo de Verilator

La suite sur la dépêche linuxfr

Un composant électronique TapTempo avec Chisel3

Le «défi TapTempo» a été lancé sur LinuxFr il y a quelques semaines. L’objectif est de réaliser la mesure du tempo de l’appui sur une touche et de l’afficher simplement dans la console le résultat. La mesure du tempo s’effectue par défaut sur 5 appuis consécutif et affiche une moyenne en bpm (Beats Per Minute). L’idée est de réaliser la fonction dans divers langages informatiques pour que chacun puisse promouvoir son langage favoris. Beaucoup de langages ont été représenté jusqu’à présent, mais aucun langages de description matériel n’avait encore été proposé.

Pour palier ce gros manquement dans les langages représenté je vous propose ici de réaliser TapTempo en Chisel (version 3).

Architecture générale

L’idée ici n’est donc plus d’écrire un programme pour calculer le tempo mais de décrire l’architecture d’un composant matériel permettant de réaliser la fonction. Le matériel visé sera un FPGA, nous laissons de coté le développement sur ASIC. Même si une fois terminé il ne devrait pas y avoir de problème pour être porté sur un ASIC, si quelqu’un a suffisamment d’argent pour le claquer dans ce genre d’ânerie 😉

Le bloc fonctionnel de notre composant sera donc constitué d’une entrée button recevant le signal de l’appui sur un bouton permettant de faire le tempo. Dans un premier temps nous laisserons de coté les problèmes de métastabilité ainsi que de rebond. L’implémentation réel dans un FPGA nécessitera obligatoirement l’ajout d’un étage de synchronisation du signal d’entrée avec l’horloge ainsi que d’un bloc «anti-rebond», aucun bouton réel n’étant capable de faire un signal vraiment propre.

La sortie du bloc sera constitué d’un entier non signé bpm dont nous allons discuter la taille ci-dessous.

Et comme nous somme dans un FPGA il est indispensable de concevoir notre fonction synchrone d’une horloge, et souhaitable d’avoir un reset général.

Structure interne

La structure interne de TapTempo est donnée ci-dessous:

L’idée est de compter des ticks générés par timepulse au moyen du compteur count. Quand un appui sur le bouton est détecté, le compteur se remet à zéro et la valeur est enregistrée dans le tableau countx. À chaque coup d’horloge l’addition des 4 valeurs count est réalisée puis on divise par 4. La division par 4 est réalisable dans un FPGA au moyen d’un simple décalage à droite de 2. Vient la partie la plus compliqué : se servir de cette période moyenne pour diviser TMINUTE et obtenir la valeur du tempo en bmp.

Un peu de dimensionnement

On ne fonctionne pas dans un FPGA comme on fonctionne avec un pc, quand on fait des opérations sur des nombres il faut les dimensionner. Et il est fortement recommander d’utiliser des entiers, car le calcul flottant nécessite tout de suite une quantité de ressources phénoménale.

Notre objectif est de mesurer une cadence musicale en bpm que l’on puisse «taper à la main», si l’on regarde l’article wikipedia consacré au Tempo, on se rend vite compte qu’attendre les 200bpm est déjà pas mal. Disons que pour prendre une très large marge nous mettons la marge supérieur à 270bpm. Nous aurons donc en sortie une variable entière sur 9bits ( int(ln2(270))+1).

À 270bpm, le temps entre deux tempos est de ~222ms ce qui nous donnerais une fréquence de pulse de 4.5Hz. Cependant, si nous voulons une précision de 1bpm il va falloir augmenter cette fréquence , pour avoir un chiffre rond nous prendrons un temps de 1ms, soit une fréquence de 1kHz. Ce qui est un peu juste pour 270bpm, mais conviendra à la démonstration.

Décomposons le code

Le code se trouve sur le dépôt github suivant.  Nous allons décrire la description du module à proprement parlé qui se trouve ici.

Dans l’entête du module nous allons retrouver le port d’entrée button ainsi que le port de sortie bpm. Point d’horloge ni de reset ici puisqu’en Chisel ces signaux sont implicite.

// default clock 100Mhz -> T = 10ns
class TapTempo(tclk_ns: Int, bpm_max: Int = 270) extends Module {
val io = IO(new Bundle {
// val bpm = Output(UInt(8.W))
val bpm = Output(UInt(9.W))
val button = Input(Bool())
})

Quelques constantes qui nous servirons ensuite :

  /* Constant parameters */
  val MINUTE_NS = 60*1000*1000*1000L
  val PULSE_NS = 1000*1000
  val TCLK_NS = tclk_ns
  val BPM_MAX = bpm_max

  /* usefull function */
  def risingedge(x: Bool) = x && !RegNext(x)

Pour notre générateur de pulses il suffit d’utiliser une classe présente dans la bibliothèque «util» de chisel : Counter. Qui comme son nom l’indique … compte !

import chisel3.util.Counter
[...]
  val (pulsecount, timepulse) = Counter(true.B, PULSE_NS/tclk_ns)
[...]

Ce compteur prend en paramètre un signal de comptage (ici true.B -> compte tout le temps) ainsi que la valeur max à atteindre.
L’instanciation de l’objet retourne un compteur ainsi qu’un signal qui passe à ‘1’ quand le compteur se remet à zero (quand il dépasse la valeur max).

Ce signal timepulse sera ensuite utilisé par un deuxième compteur 16 bits tp_count que nous allons écrire «à la main» cette fois.
On défini d’abord le registre de 16bits que l’ont initialise à 0 (0.asUInt(16.W))

  val tp_count = RegInit(0.asUInt(16.W))

Puis on écrit le code décrivant le «comptage»:

  when(timepulse) {
    tp_count := tp_count + 1.U
  }
  when(risingedge(io.button)){
    // enregistrement de la valeur du compteur.
    countx(count_mux) := tp_count
    count_mux := Mux(count_mux === 3.U, 0.U, count_mux + 1.U)
    // remise à zéro du compteur
    tp_count := 0.U
  }

Ce deuxième compteur compte les pulse «timepulse» et se remet à 0 lorsqu’un front montant est détecté sur le bouton (quand on appuis sur le bouton).

Pour stocker les 4 valeurs permettant de réaliser une valeurs nous déclarons un vecteur de registres de 19 bits (pour gérer les retenues quand nous ferons l’addition):

  val countx = RegInit(Vec(Seq.fill(4)(0.asUInt(19.W))))

Ainsi que le «pointeur» :

  val count_mux = RegInit(0.asUInt(2.W))

La gestion de l’incrémentation du pointeur ainsi que de l’enregistrement du compteur se trouve dans le code du «compteur de pulse» que nous avons vu plus haut:

    // enregistrement de la valeur du compteur.
    countx(count_mux) := tp_count
    count_mux := Mux(count_mux === 3.U, 0.U, count_mux + 1.U)

Pour faire la somme rien de plus simple, il suffit de faire ‘+’ :

  val sum = Wire(UInt(19.W))
[...]
  sum := countx(0) + countx(1) + countx(2) + countx(3)

Et la division par 4 se résume à un décalage:

  val sum_by_4 = sum(18, 2)

Et nous arrivons à la partie la plus compliquée du design : diviser. Diviser est quelque chose de très compliqué dans un FPGA, on peut réaliser un design permettant d’effectuer une divisions en plusieurs cycles d’horloge, mais c’est tout de suite une très grosse usine à gaz.

Pour la division permettant de faire la moyenne des échantillons nous nous en étions sortie en faisant une division par une puissance de 2, qui se résume de fait à un simple décalage. Mais cette fois on ne pourra pas s’en sortir avec ce genre de pirouette. Car notre division à réaliser est la suivante :

   Nombre de pulse dans une minute
-------------------------------------  = valeur en bpm
moyenne des pulses mesuré (sum_by_4)

Pour nous en sortir la première idée serait de faire une table de valeurs pré-calculée pour chaque valeurs de  sum_by_4. Ce qui se fait très simplement en scala avec une séquence :

val x = Seq.tabulate(pow(2,16).toInt-1)(n => ((MINUTE_NS/PULSE_NS)/(n+1)).U)

Sauf que le nombre de valeurs est particulièrement grand (2^16) et qu’on pourrait certainement factoriser un peut tout ça.

Pour réduire la taille ne notre tableau il faut prendre le problème à l’envers: combien de valeurs possible puis-je avoir en sortie ?

La réponse est simplement 269 puisque je peux aller de 1 à 270bpm. Nous allons donc réaliser un vecteur de 270 valeurs contenant la valeurs minimum du compteurs permettant d’atteindre notre résultat. Et nous mettrons ces valeurs dans 270 registres.

  val bpm_calc = RegInit(Vec(x(0) +: Seq.tabulate(bpm_max)(n => x(n))))

Pour obtenir la valeur finale il faut ensuite générer 270 inéquations ayant pour résultat un vecteur de 270 bits :

  for(i <- 0 to (bpm_max-1)) {
    bpm_ineq(i) := Mux(sum_by_4 < bpm_calc(i), 1.U, 0.U)
  }

Le résultat correspondra ensuite à l’index du dernier bit à 1 dans ce vecteur.

Pour récupérer cet index, une fonction très utile est fournie dans la bibliothèque «util» de chisel : le PriorityEncoder. Qui permet d’obtenir l’index du plus petit bit à 1 dans un vecteur… sauf que nous on veut le plus grand !

Mais ce n’est pas très grave, il suffit de retourner le vecteur avec Reverse puis de faire une soustraction pour avoir le résultat :

  io.bpm := bpm_max.U - PriorityEncoder(Reverse(bpm_ineq.asUInt()))

Simulation

Le test permettant de simuler le design se trouve dans le fichier TapTempoUnitTest.scala

Il peut être lancé avec la commande sbt suivante :

sbt 'test:runMain taptempo.TapTempoMain --backend-name verilator'

Et les traces VCD générées sont disponible dans le répertoire ./test_run_dir/taptempo.TapTempoMain962904038/TapTempo.vcd

Visualisable simplement avec gtkwave.

gtkwave ./test_run_dir/taptempo.TapTempoMain962904038/TapTempo.vcd

Trace vcd de la simulation TapTempo

À suivre

Pour être vraiment complet il faudrait ajouter la gestion des rebonds ainsi que la synchronisation du signal d’entrée puis tester la synthèse. Mais ce sont de nouvelles aventure qui continuerons peut-être dans un prochaine épisode 🙂 .

SymbiFlow, vers la synthèse libre pour la Série7 de Xilinx

Le projet IceStorm permettant générer des bitstreams à partir du verilog vers les FPGA ICE40 de Lattice étant maintenant très avancé, W.Clifford se lance avec d’autres dans le reverse-ingineering des FPGA de la Série 7 de Xilinx.

Pour cela, un nouveau projet nommé SymbiFlow est créé pour fédérer les différents outils permettant de développer autour des FPGA de Xilinx. L’objectif à terme étant d’intégrer également les ICE40 à SymbiFlow.

Le projet inclut un sous projet nommé sobrement «Project X-Ray» permettant de documenter les différents éléments du FPGA Artix7 sous forme de carte en ASCII et HTML. Se sous-projet vise à documenter le FPGA mais également à fournir des outils permettant de piloter Vivado avec des design simplistes permettant de générer des statistiques sur les bitstreams générés et approfondir la documentation.

Un des gros changement de SymbiFlow par rapport à Icestorm est la volontés de migrer le placement-routage de arachne-pnr vers VPR. Un sous-projet de VTR développé depuis bien plus longtemps que Arachne-pnr.

Vu le succès remporté par le projet IceStorm, avec la quasi totalité des FPGA ICE40 documenté ainsi que leurs timings, on peut espérer voir arriver rapidement une chaîne de développement libre pour les FPGA de la Série 7 de xilinx. Et voir ainsi le développement open-source sur FPGA devenir une réalité.

 

NVC, l’autre simulateur VHDL libre

Dans le domaine de la simulation libre du VHDL, on connait bien le simulateur GHDL qui est basé sur GCC, on connaît un petit peu le simulateur FreeHDL inclus dans le logiciel graphique de simulation électronique Qucs, mais on connaît moins le simulateur NVC qui pourtant est en train de faire son petit bonhomme de chemin.

NVC est écrit en langage C pur et compilé par défaut avec le compilateur LLVM concurrent de GCC. L’avantage de NVC par rapport à GHDL: c’est un programme indépendant de son compilateur là où ghdl n’est qu’une couche de GCC. Ce qui simplifie grandement la compilation de l’outils.

NVC n’a pas encore atteint sa première version stable, cependant le rythme des commits laisse penser que cela va venir. Et surtout il est déjà utilisable en l’état dans sa version git «master» .

L’outil a été intégré dans la partie VHDL du blp, il s’utilise de la même manière que ghdl avec une phase d’élaboration puis d’analyse avant d’être lancé en simulation.

Pour simuler le testbench permettant de tester le module anti-rebond du blp nous ferons les commandes suivantes dans le répertoire vhdl :

  • analyse
nvc -a ../test/test_button_deb.vhd ../src/button_deb.vhd
  • élaboration
nvc -e button_deb_tb
  • simulation (run)
nvc -r button_deb_tb -w

L’option de simulation -w permet de générer un fichier de sortie (*.fst) pour être lu par gtkwave.

IceStudio, du schéma au verilog

IceStudio est un logiciel graphique permettant de concevoir un design FPGA à la manière d’un schéma électronique.

Le logiciel est encore largement expérimentale (version 0.2) et centré sur les FPGA ice40 de chez lattice.

En fait, IceStudio se veut une extension graphique au projet IceStorm — chaine de synthèse/place&route/bitstream opensource —.

Architecturé en javascript autour de Nodejs, le logiciel permet de dessiner son projet au moyen de blocs reliés entre eux par des signaux.

icestudio-0.2-crono_

Les blocs peuvent être pris dans une librairie fourni avec le logiciel, mais il est également possible de créer des blocs «vierges» dans lesquels on écrira le code verilog correspondant au comportement souhaité.

icestudio-0.2-counter-inspection

Le format de sauvegarde du projet est en  JSON, un outils de conversion permet ensuite de le transformer en code Verilog pour la synthèse.

Installation

Pour l’installer nous aurons besoin du paquet «npm» :

sudo apt-get install npm

Puis de télécharger le projet git:

git clone https://github.com/FPGAwars/icestudio.git

Et enfin de lancer la commande d’installation comme décrite dans le README.md:

cd icestudio
npm install

Pour l’exécuter lancer simplement

npm start

Et si comme pour votre serviteur, cela ne marche pas du tout 😉 allez plutôt chercher la release sur https://github.com/FPGAwars/icestudio/releases. Dézippez la

unzip Icestudio-0.2.0-beta2-linux64.zip

Puis lancez le simplement :

./Icestudio

Le projet est encore jeune mais très prometteur.  Espérons que nous verrons rapidement l’intégration de nouvelles plateformes/FPGA, voir une version FPGA-Agnostic.

 

De beaux chronogrammes avec Wavedrom

wavedrom est une librairie html/javascript permettant de faire de superbes rendu de chronogrammes.

La syntaxe en JSON est relativement simple et permet de créer très rapidement des chronogrammes dans sa page web.

<script type="WaveDrom">
{ signal : [
{ name: "clk", wave: "p......" },
{ name: "bus", wave: "x.34.5x", data: "head body tail" },
{ name: "wire", wave: "0.1..0." },
]}
</script>

Si l’on souhaite faire une utilisation hors ligne de wavedrom il est possible de télécharger l’éditeur sur le site. L’éditeur permet de faire des modifications du code json avec le rendu en live. Il permet également d’enregistrer le rendu sous un format image pour que l’on puisse incorporer le chronogramme dans son document.

wavedromeditor

Très pratique pour écrire ses documents de spécification.