Verilog simulation Flags

Apparently, there is no Verilog standard to say «hey we are on simulation here». Each software have it’s own flag for that.

Xilinx iSim

`ifdef XILINX_ISIM
  // code for simulation with isim
`else
  // code for synthesis
`endif

Mentor Modelsim

`ifdef MODEL_TECH
  // code for simulation with modelsim
`else
  // code for synthesis
`endif

Icarus Verilog

?

Cocotb

`ifdef COCOTB_SIM
  // code for simulation with cocotb (should be cumulated with other simulator I think)
`else
  // code for synthesis
`endif

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")

Réception du FireAnt

J’en avait déjà parlé dans les colonnes de ce blog. Une nouvelle société produit un FPGA nommé Trion T8. Ce FPGA est la base d’une petite carte de développement proposée par les HongKongais de XIPS Technology sur le site crowdsupply.

Évidemment je n’ai pas résisté à participer à la campagne. Quelques manifestations à HongKong et quelques déboire avec Fedex puis Mondial Relais, voici enfin le kit tant attendu arrivé chez moi.

Le carton était un peu disproportionné non ?

Le kit est arrivé dans un énorme carton, mais c’est presque habituel dans ce genre de cas. J’avais pris sans les headers soudés mais ils sont tout de même fournis. J’ai juste eu à les souder moi même.

Au branchement une led rouge qui semble être celle de l’alimentation s’allume. Les 4 LED oranges se mettent elles à compter en binaire.

Le FireAnt sous tension de l’interface USB

Dans les messages noyau nous avons la traditionnelle interface ttyUSB0 du FTDI :

$ dmesg
[97997.987953] usb 3-1: USB disconnect, device number 11
[97997.988359] ftdi_sio ttyUSB0: FTDI USB Serial Device converter now disconnected from ttyUSB0
[97997.988397] ftdi_sio 3-1:1.0: device disconnected
[98000.296737] usb 3-1: new high-speed USB device number 12 using xhci_hcd
[98000.445226] usb 3-1: New USB device found, idVendor=0403, idProduct=6014, bcdDevice= 9.00
[98000.445231] usb 3-1: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[98000.445233] usb 3-1: Product: Single RS232-HS
[98000.445235] usb 3-1: Manufacturer: FTDI
[98000.446052] ftdi_sio 3-1:1.0: FTDI USB Serial Device converter detected
[98000.446118] usb 3-1: Detected FT232H
[98000.446278] usb 3-1: FTDI USB Serial Device converter now attached to ttyUSB0
Efinity software

J’avais déjà reçu la license de la part de Efinix et Xips technology, du coup mon blinking led design était près à télécharger. Le bitstream est au format *.hex et se flash super facilement avec le Efinity programmer (tools -> programmer).

Le flashage passe comme une lettre à la poste (… heu mieux que la poste en fait 😉

Par contre ma led ne clignote pas, je pense avoir encore quelques soucis avec les configs d’I/O et de PLL pour l’instant. Je doit encore me former à l’Efinity Interface Designer de Efinix qui est assez déroutant par rapport aux autres IDE.

[ToBeEdited]

Chisel Tips

This page lists some tips for Chisel that I could glean here and there.

Bidirectional signal

Bidirectionnal signals are not possible inside an FPGA or an ASIC. But it can be usefull on the boundary to drive signal like tristate buffer.

To use Bidirectionnal signal use Analog() in conjonction with RawModule or BlackBox :

class TopDesign extends RawModule {
  val tristatebuf = Analog(1.W)
...
}

Connexion is made with bulk connector ‘<>’ :

tristatebuf <> myblackbox.io.tristate

dontTouch : keep register names in verilog

Tip from stackoverflow.

Sometimes, we have to keep register in verilog emitted code. But Chisel obtimize it and it often disapear. To keep it, use dontTouch() :

  val version = dontTouch(RegInit(1.U(8.W)))

Get following in verilog module:

  reg [7:0] version; // @[wbgpio.scala 20:34]
...
    if (reset) begin
      version <= 8'h1;
    end

DontCare output signals

All module output must be defined to avoid this kind of warning :

[error] (run-main-0) firrtl.passes.CheckInitialization$RefNotInitializedException:  : [module ChisNesPad]  Reference io is not fully initialized.
[error]    : io.data.valid <= VOID
[error] firrtl.passes.CheckInitialization$RefNotInitializedException:  : [module ChisNesPad]  Reference io is not fully initialized.
[error]    : io.data.valid <= VOID
[error] Nonzero exit code: 1
[error] (Compile / runMain) Nonzero exit code: 1
[error] Total time: 12 s, completed 10 déc. 2019 13:25:11

But at the begining of a design, we don’t know what to write. To avoid this error we can use DontCare object :

  io.data.valid := DontCare

Keep signal and variables names in Verilog

See the good response from Jack Koening on stackoverflow.

UInt() to Vec()

An UInt() can be converted to a Vec of Bool() with asBools:

val foo = Vec(5, Bool())
val bar = UInt(5.W)

foo := bar.asBools
Initialize Vec() of Reg()

Split an UInt() in a Vec() of «sub» UInt()

Question asked on stackoverflow.

If we have a 16 bits register declared like that.

val counterReg = RegInit(0.U(16.W))

And we want to do indexed dibit assignment on module output like that :

//..
  val io = IO(new Bundle {
     val dibit = Output(UInt(2.W))
  })
//..
var indexReg = RegInit(0.U(4.W))
//..
io.dibit = vectorizedCounter(indexReg) //xxx doesn't work

We could do it like that:

io.dibit := (counterReg >> indexReg)(1, 0)

Initialize Vec() of Reg()

 val initRegOfVec = RegInit(VecInit(Seq.fill(4)(0.U(32.W))))

Concatenate value in one UInt()

Of course we can use Cat(), but it take only 2 parameters. With ‘##’ we can chain more signals:

val a = Reg(UInt(1.W))
val b = Reg(UInt(1.W))
val c = Reg(UInt(1.W))
val y = Reg(UInt(3.W))

y := a ## b ## c

With a Vec() declared like it :

val outputReg = RegInit(0.U((dibitCount*2).W)
val valueVecReg = RegInit(VecInit(Seq.fill(dibitCount)(0.U(2.W))))

ouptutReg := valueVecReg.reduce(_ ## _)

Initialize Bundle

Question asked on stackoverflow.

If we have a Bundle declared like that :

class RValue (val cSize: Int = 16) extends Bundle {
  val rvalue = Output(UInt(cSize.W))
  val er     = Output(UInt((cSize/2).W))
  val part   = Output(Bool()) /* set if value is partial */
}

And we want to make a register with initialized value we can use the new interface named BundleLiterals:

import chisel3.experimental.BundleLiterals._
...
val valueReg = RegInit((new RValue(cSize)).Lit(
          _.rvalue -> 1.U,
          _.er -> 2.U,
          _.part -> true.B)

Or if we just want to initialize to all 0 values we can do that :

val valueReg = RegInit(0.U.asTypeOf(new RValue(cSize))

Test some chisel code in console

Question asked on stackoverflow.

It can be usefull to be able to test code in console before launching the big compilation. It’s possible in directory where your project build.sbt is :

$ cd myproject/
$ sbt
sbt:myproject> console
scala>

And once in the scala console chisel import can be done :

scala> import chisel3._
import chisel3._
scala> val plop = "b0010101010001".U(13.W)
plop: chisel3.UInt = UInt<13>(1361)

Type Ctrl+D to quit.

For more Chisel Cookbook

See :

Réception du kit AnalogMax-01

Arrow propose un kit de développement nommé AnalogMax pour 80$ environ. L’entreprise qui fabrique la carte est Trenz Electronic qui réalise également le kit gowin.

Cette fois la carte est arrivée par lettre, et non par gros colis.

Le FPGA est relativement gros et la carte possède un certain nombre de périphérique analogiques sympathique comme un détecteur de fumée, un capteur de température, quelque canaux ADC et DAC ainsi que des GPIO.

Au branchement du kit sur l’usb on a juste la led verte allumée. L’appuie sur le bouton à droite allume une des huit leds de la rangée, et l’appui sur l’autre bouton allume l’autre led rouge et inscrit un message sur l’uart (115200):

UHSA R1.0

[TO BE EDITED]

Retour de Conférence ORConf 2019

Je remercie mon entreprise Armadeus Systems de m’avoir permit d’assister à cette septième conférence OpenRisc 2019.

Libérez vos flip-flop !

L’ORConf est organisée par la fondation FOSSi qui promeut la liberté dans le matériel, que l’on parle d’outils ou de composants matériel. L’objet de la première conférence fut justement sur l’histoire de cette organisation.

FOSSi foundation est une évolution de l’association opencore, les fondateurs de FOSSi n’étaient pas satisfait de cette structure et de l’organisation de la gestion des projets. La fondation FOSSi a pour but de promouvoir le logiciel libre et le matériel libre et de servir de support aux différents projets libres. Elle apporte un soutien logistique pour l’hébergement elle sert d’interface avec le projet google summer of code. Sa mission est également d’organiser des événements comme l’ORConf pour faciliter les rencontres entre les différents acteurs du matériel libre.

C’est la première fois que la conférence se déroulait en France, à Bordeaux dans les locaux de l’école d’ingénieur ENSEIRB-MATMECA. Une école que je connais bien puisque c’est l’école dans laquelle j’ai passé mon diplôme d’ingénieur 😉

Une fois l’introduction de la fondation passée, la journée du vendredi s’est enchaînée avec une présentation de la Chips Alliance pas Zvonimir Z bandic employé de Western Digital puis avec une discussion autour des licences open sources du CERN à destination spécifiquement du matériel.

Nous avons eu la chance d’avoir une présentation de la fondation RISC-V par Calista Redmond – récemment nommée CEO de l’organisation – pour nous parler de la révolution en cours.

Mais les conférences ne sont pas réservées au jeux d’instruction RISC-V, nous avons pu avoir un aperçu d’un processeur autour du jeux d’instructions OpenPower (de plus en plus libre) ainsi que du processeur OpenRisc (le samedi) développé sur le temps libre de Stafford Horne principalement (temps pas si libre que ça puisqu’il a des enfants;).

Après quelques discussions à propos des outils disponibles autour du VHDL pour la vérification de la syntaxe et des règles de codage la journée du vendredi s’est terminée par une présentation de l’avancée des outils libres pour le développement sur ASIC par Luis Eduardo Rueda Gruerrero de Symbiotic EDA. Luis participe au développement d’un processeurs RISC-V 32bits nommé ASICone en ayant – comme son nom l’indique– la fabrication d’un silicium avec le plus possible de logiciels libres comme objectif. Le développement intégralement open source est encore compliqué, notamment en ce qui concerne l’analyse de la consommation, l’arbre d’horloge ainsi que la description des librairies de composants.

Cette demi-journée fut bien chargée en informations annonçant bien la suite le samedi.

Beaucoup de choses à digérer de la journée de samedi. À titre personnel je retiens surtout les avancées de Cocotb version 1.2 dont le mainteneur est un membre de la fondation FOSSI. En plus du support complet de Python3 et les directives «async», cocotb 1.2 permet désormais d’être utilisé sans Makefile car intégré complètement dans le système de packaging Python.

Mais le futur de Cocotb semble très intéressant avec le support de verilator comme simulateur. Le travail pour le support de verilator était surtout à faire coté verilator et non Cocotb, mais un patch semble être sur les rails chez Wilson.

Malgré son nom très «vacances à la plage», cocotb est le nouveau système permettant d’écrire des testbenchs qui est de plus en plus utilisé en entreprise aujourd’hui. Il remplace allègrement les UVM, VUNIT qui font si mal à la tête.

Jeremy Bennett nous a présenté un nouveau banc de test nommée emBench en cours de définition pour que les différentes architectures de processeurs puissent comparer leurs zizi. L’objectif étant d’avoir un testbench libre et gratuit pour pouvoir l’exécuter sur toutes les plate-formes et faire de beaux tableaux comparatif.

L’après midi fut marqué par une série de «ligthning talks» de 3 minutes chacune. Avec les avancées du développement de SymbiFlow (impressionnantes) notamment pour le support de l’artix7 ainsi que par une présentation de Clash qui vient de passer à sa version 1.0. Sans oublier la présentation des cœurs RISC-V pour ASIC développés par la société russe syntacore et les avancées du langage Chisel3.

À noter aussi la remarquable performance de Pepin de Vos avec sa présentation intégralement réalisés sur un softCore tournant sur FPGA (GOWIN). Il est désormais possible grâce au travail de Tristan Gringold de synthétiser du VHDL avec Yosys. C’est ce qu’a utilisé Pepin pour réaliser son système à base de logique 7400. Cependant le nombre de composant étant trop important il s’est contenté d’une synthèse sur FPGA pour cette présentation.

Pour que toute la chaîne de développement sur FPGA soit libérée, un bon logiciel de placement routage est nécessaire. C’est le rôle du nouveau logiciel Nextpnr que David Shah nous a présenté. Le développement de nextpnr avance bien. N’hésitez pas à le soutenir sur patreon.

Enfin, la journée s’est terminé sur les berges de la Garonne par un dîner concert dans la guinguette «chez alriq». Cela qui m’a permis de passer de l’autre coté du fleuve, ce qui ne m’était jamais arrivé durant mes trois ans de scolarité à Bordeaux !

Pour le restaurant, c’est Google qui régale

Le dimanche ne fut pas sans repos non plus et fut marqué par une conférence très dynamique de Jose E. Marchesi et son nouveau logiciel d’édition de binaire (ELF, mp3, …) poke. Une présentation très vivante et passionnante, tout le monde achète 😉

Les interfaces (connecteurs) présenté par Alan J.Wood sont aussi très intéressantes. L’objectif des connecteurs mixMOD et Blackedge présentés est de pouvoir s’adapter aux PMOD très présent dans les kits de développement FPGA tout en ajoutant des pins analogique. L’idée est d’avoir un standard pour bricoler dans son garage et pour équiper les salles de TP pour l’éducation.

N’oublions pas la présentation de l’impressionnant travail abattu par l’université de Zurich avec leur projet PULP. Le travail de l’équipe PULP est de concevoir et produire des ASIC pour l’embarqué à base d’architectures parallèle. L’objectif est de publier en open source le plus possible les outils utilisés. Leur processeur nommé Arnold est particulièrement remarquable car il intègre une matrice FPGA nommée eFPGA fournie par QuickLogic. Pour l’instant les outils de synthèse et de placement routage sont en source fermés, mais il est prévu de fournir des outils libre pour cette matrice.

Todd Strader nous a parlé de son projet de protection d’IP Verilog à base de verilator permettant d’éviter l’horrible système de chiffrement des IP proposé habituellement par les constructeurs et empêchant l’utilisation de simulateur libre. Tout en ayant une sécurité très relative quand au piratage de la dite IP chiffrée.

Dan Gisselquist nous a démontré que la plupart des IP proposées par les fondeurs à base de bus AXI ne respectent pas le standard et sont souvent buggé ! Ces bug ressortent très facilement grâce à la vérification formelle.

Et enfin, n’oublions pas la présentation de la nouvelle entreprise local Hiventive et son système de coordination de simulateurs en ligne.

Pour conclure, cette conférence fut très intense en présentations. Beaucoup d’acteurs du matériel libre étaient présent. Un des grand intérêt de cette conférence était aussi de pouvoir rencontrer en personne des acteurs que l’on ne côtoyait avant qu’a travers des messagerie.

Une question reste sur toutes les langues : Où se passera l’ORConf 2020 ?

[Edit: 12 novembre 2019]

Les vidéos des conférences sont désormais disponible sur youtube.

Liste de projets basés sur Chisel

Voici une liste de projets open-sources basés sur le langage de description matériel Chisel.

Processeurs

  • sodor: Un microprocesseur RISC-V pour l’éducation
  • rocket-chip: le générateur de processeurs RISC-V utilisé par SiFive
  • BOOM: The Berkeley Out-of-Order RISC-V Processor
  • leros: Un microcontrôleur microscopique optimisé pour les FPGA

Interfaces

  • spi2wb: Un maître Wishbone piloté par SPI
  • mdio: un maître MDIO (pour les Phy ethernet)
  • FastVDMA: une DMA rapide

Accélérateurs

  • Edge TPU : Il semblerait que cet accélérateur matériel développé par Google ait été conçu avec chisel3 d’après cette conférence.

Register size in bits

How to calculate register size in bits N

Chisel3 : log2Ceil()

import chisel3.util.log2Ceil

val Nsize = log2Ceil(N + 1)

Verilog : $clog2()

 parameter NSIZE = $clog2(N + 1);

VHDL : ceil(log2()

use IEEE.math_real."ceil";
use IEEE.math_real."log2";

Nsize := integer(ceil(log2(real(N + 1))));

Python: math.ceil(math.log(N+1, 2))

import math
Nsize = math.ceil(math.log(N + 1, 2))

CλaSH: ?

SystemC/C++: ceil(log2())

#include <math.h>       /* ceil and log */
Nsize = ceil(log2(N+1));

Le point Gowin

Oui je sais c’est nul 😉

Arrivée dans un énorme carton, la carte électronique se trouve dans le tout petit «tube» blanc.

Je viens donc de recevoir ma carte petite abeille (littlebee) munie d’un FPGA du chinois GOWIN.

La carte «LittleBee» munie d’un FPGA de chez Gowin

La carte produite et vendue par la société allemande Trenz Electronic permet de se faire la main avec le composant pour moins de 40€ (un peu plus avec les frais de ports UPS …).

Branchement

Au branchement à la sortie du carton les huit leds rouge s’allument ainsi qu’une led verte que je suppose de «power».

Les messages noyau nous donnent deux ports séries ttyUSBx :

$ dmesg
[630417.919258] usb 3-1: new high-speed USB device number 35 using xhci_hcd
[630418.059577] usb 3-1: New USB device found, idVendor=0403, idProduct=6010
[630418.059581] usb 3-1: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[630418.059583] usb 3-1: Product: Dual RS232-HS
[630418.059584] usb 3-1: Manufacturer: FTDI
[630418.060116] ftdi_sio 3-1:1.0: FTDI USB Serial Device converter detected
[630418.060155] usb 3-1: Detected FT2232H
[630418.060352] usb 3-1: FTDI USB Serial Device converter now attached to ttyUSB0
[630418.060499] ftdi_sio 3-1:1.1: FTDI USB Serial Device converter detected
[630418.060528] usb 3-1: Detected FT2232H
[630418.060648] usb 3-1: FTDI USB Serial Device converter now attached to ttyUSB1

Si on se connecte au port série ttyUSB1 on obtient un affichage de la résolution du problème des philosophes.

Philosopher 0 [P: 3] THINKING [ 750 ms ]
Philosopher 1 [P: 2] HOLDING ONE FORK
Philosopher 2 [P: 1] EATING [ 450 ms ]
Philosopher 3 [P: 0] STARVING nabled
Philosopher 4 [C:-1] HOLDING ONE FORK get back,
Philosopher 5 [C:-2] EATING [ 375 ms ]

Il est probable que nous ayons ici un RISC-V dans le tiroir.

La connexion d’un terminal sur le port ttyUSB0 ne donne rien par contre.

IDE

Voila pour le déballage, maintenant il va falloir installer les outils pour faire clignoter ces leds !

[To Be Edited …]