Found on the web:

Found on the web:
[Dépêche publiée initialement sur LinuxFR.]
En début d’année 2019 se posait la question de savoir si ce serait l’année de la libération des FPGA. En ce début d’année 2020, essayons de faire un bilan.
FPGA, ASC, HDL, RISC‑Ⅴ et PCB sont les chapitres que nous allons découvrir dans la suite de cet article. Si vous connaissez déjà ces sigles et acronymes, vous allez adorer ; mais si vous ne les connaissez pas, c’est indispensable car ces vocables sont à la base de la culture universelle de notre siècle.
Nous sommes actuellement arrivés à un moment clé pour le matériel informatique. Il en est au même point que le logiciel libre en était en 2000, quand il est devenu mature. Le mouvement est lancé et les projets deviennent utilisables. On ne rêve plus…
À condition de choisir son FPGA cible, il est aujourd’hui possible de faire son développement intégralement à base de logiciels libres. Tout cela principalement grâce à Yosys et Nextpnr.
Yosys est un logiciel libre de synthèse [[Verilog]]. Il permet de convertir un modèle Verilog en une netlist. La netlist est tout simplement un schéma électronique comme on peut en faire avec un logiciel de saisie de schéma. On relie entre eux des connecteurs d’entrées‐sorties de composants pour réaliser un circuit électronique.
Cependant, en général, un logiciel de synthèse cible des FPGA ou des ASIC qui ont leurs propres bibliothèques de composants. Et la netlist générée est au format texte, même si une fonction de Yosys permet d’afficher le « schéma » au moyen de Graphviz.
Yosys augmente le nombre des FPGA officiellement pris en charge avec les FPGA de Gowin. L’ingénierie inverse du Gowin n’est pas encore terminée mais elle est déjà utilisable. C’est tout le travail de Pepijn De Vos avec son Project Apicula.
Plusieurs gammes de FPGA de Lattice sont désormais prises en charge. En plus du ICE40 initial, les ECP5 sont maintenant parfaitement utilisables et les nouveaux CrossLink (Nexus) sont en cours de « reverse engineering » (rétro‑ingénierie, voir ci‑dessous) avec le Project Oxide de David Sha.
Hormis la partie placement routage et bitstream, les FPGA de la série 7 de Xilinx sont assez bien gérés par Yosys (mais Yosys ne fait pas le placement‐routage). Et Google a fait un petit cadeau à la communauté libre en annonçant financer la prise en charge des (pas si) vieux Spartan3 et Spartan6.
Nextpnr est un logiciel libre permettant de faire le [placement‐routage(https://fr.wikipedia.org/wiki/Placement-routage). Le principe est assez simple, un FPGA disposant d’une matrice de composants gravés sur la puce, il faut décider quel composant de la netlist générée par le logiciel de synthèse ira sur quel composant présent dans le FPGA. Une fois les composants placés, il faut router les entrées‐sorties en réalisant les connexions.
Nextpnr est aujourd’hui parfaitement utilisable pour les FPGA ICE40 et ECP5 de Lattice. Pour les FPGA de Gowin, cela ne saurait tarder à mon avis.
Pour configurer un FPGA (établir les liens entre les bascules) il faut télécharger un bitstream. Le format de ce bitstream n’est documenté par aucun constructeur de FPGA. Nous sommes obligés de passer par les outils (gratuits, en général) fournis par le constructeur pour le générer.
Bien que n’étant pas documenté, le format n’est pas non plus chiffré, il est donc parfaitement possible de l’étudier par ingénierie inverse pour le documenter.
De plus en plus de projets de FPGA par ingénierie inverse de bitstream voient le jour. Votre serviteur tente de maintenir une liste de ces projets sur son blog en donnant l’état d’avancement des projets.
On décompte au moins neuf projets plus ou moins avancés de rétro‑ingénierie :
Notons que la marque Lattice est très représentée, alors que Microsemi est absent (à ma connaissance) de ces projets.
Les ASIC ne sont pas des FPGA. Une fois que l’on a envoyé nos fichiers de production au fondeur, les composants ne sont plus modifiables. Et comme la facture est en général particulièrement salée pour produire une série, il faut en produire beaucoup et surtout ne pas se planter.
Une (vénérable) suite de logiciels libres appelée QFlow existe depuis plus de trente ans pour concevoir ces circuits intégrés spécialisés. Mais le site officiel fait particulièrement peur, et laisse croire que le logiciel est à l’abandon depuis bien longtemps.
Il n’en est rien, ce logiciel est toujours maintenu et est utilisé par de plus en plus de concepteurs ASIC pour produire des puces libres. On pense notamment au Raven à base de PicoRV32 (RISC‑Ⅴ) qui avait été décrit dans les colonnes de LinuxFr.org. On pense également au projet de FPGA libre kFPGA décrit également dans ces colonnes.
Un autre composant à destination des amateurs de rétro‑informatique est en cours de production par Staf Verhaegen avec le projet Chip4Makers. L’idée de Staf est que la production de composants ASIC coûte très cher à l’unité, il n’est donc pas possible de concurrencer les composants du marché avec un composant conçu « dans son garage ».
Cependant, il existe une frange de hobbyistes prête à payer plus cher pour retrouver leur vieux processeur 6502 ou Z80. Ce sont donc ces processeurs que Staf a inclus dans un unique composant, et la pré‑série a été produite d’après un de ses tweets. Les sources du composant en question sont disponibles sur sa projet GitLab.
D’autres instituts et fondations s’intéressent de très près à l’émergence d’outils libres pour réaliser des microprocesseurs et ASIC. On pense notamment à :
Yosys était jusqu’ici réservé à la synthèse Verilog. Mais grâce au travail de Tristan Gingold et Pepijn De Vos (principalement), il est désormais possible d’utiliser Yosys en conjonction de GHDL pour faire de la synthèse GHDL. Le projet est encore en beta‑test, mais Pepijn s’en sert pour faire de la synthèse TTL de ses porte‑grammes VHDL ainsi que de la vérification formelle.
Principalement grâce à Yosys, il est désormais tout à fait possible de faire de la vérification formelle pour valider ses composants. C’est le cheval de bataille de Dan Guisselquist, avec son projet de processeur nommé ZipCPU.
Le langage de haut niveau Chisel est maintenant relativement mature. Le projet fait partie de la fondation Linux et la conférence annuelle CCC (non pas Chaos Communication Camps mais Chisel Community Conference) est soutenu par des gros industriels comme Western Digital ou Cadence.
Toute la gamme des processeurs développés par SiFive est écrite avec Chisel, Google a utilisé le langage Chisel pour son processeur d’intelligence embarqué Edge TPU.
Le langage nMigen basé, lui, sur Python essaime aussi pas mal, mais surtout dans le milieu de la recherche.
CλaSH est sortie en version 1.0. Cela faisait des années qu’il se traînait avec des version 0.x, le passage à 1.0 est un signe de maturité. CλaSH est basé sur le langage au paradigme fonctionnel [[Haskell]]. Je ne peux hélas pas vous en dire plus aujourd’hui car je n’ai par réussi à percer le secret de cette logique de matheux qu’est le paradigme fonctionnel. :)
Cocotb a désormais un vrai rythme de développement et est utilisé en production pour de « grosse » IP comme l’USB. La version 1.3 est sortie en ce début d’année. Cocotb est un module Python permettant d’écrire des bancs de test HDL. Cocotb a la particularité de se connecter à un simulateur « du marché » pour lire et écrire les valeurs de signaux. Cela permet de garder son simulateur HDL parfois acquis à grands frais.
Verilator, le simulateur Verilog le plus rapide du « marché » (plus rapide que tous les simulateurs commerciaux) continue à être activement développé. Les récents commits permettent aujourd’hui de l’utiliser avec Cocotb. Et son passage à la version 4.0 permet une pleine utilisation des multiples cœurs de nos PC actuels, améliorant encore ses performances.
On peut aujourd’hui dire sans sourcilier que l’année de libération des processeurs est passée grâce au jeu d’instructions RISC‑Ⅴ.
Il n’est plus nécessaire de présenter ce jeu d’instructions aujourd’hui, et nous pouvons nous procurer tout un tas de microcontrôleurs basés sur RISC‑Ⅴ pour une somme d’argent (plus ou moins) modique.
Voici une petite liste de microprocesseurs RISC‑Ⅴ disponibles sur le marché :
Hormis l’U540 et, dans une certaine mesure, le K210, tous ces processeurs sont des microcontrôleurs orientés basse consommation. La question qui est sur toutes les lèvres aujourd’hui, c’est : RISC‑Ⅴ va‑t‑il percer dans le monde du serveur et du calcul parallèle ?
Kicad est un logiciel de conception électronique pour fabriquer des circuits imprimés, également appelés PCB. C’est un logiciel initialement développé par un français (cocorico) qui inclut toute la suite de logiciels nécessaires à l’électronicien :
Kicad est longtemps resté un logiciel anecdotique (mais parfaitement fonctionnel), jusqu’à ce que le CERN s’y intéresse et finance des ingénieurs pour améliorer la partie routage. Aujourd’hui, Kicad est soutenu par la Fondation Linux et a lui aussi sa conférence annuelle prestigieuse : la KiCon.
Pour conclure, nous pouvons affirmer que la libération des FPGA est maintenant bien engagée. Et nous assistons aujourd’hui à l’émergence du matériel libre du point de vue du cœur de la puce : le silicium.
La liberté dans ce monde stagnait depuis des dizaines d’années, mais les choses décollent aujourd’hui. Et on entend le même refrain contre le Libre que l’on entendait dans les années 2000 sur le logiciel. Pour quelqu’un qui chercherait un projet libre sur lequel se lancer pour faire ses armes, comme pour la conquête de l’ouest, l’espace est encore vierge et c’est le moment de se lancer.
Sipeed continue dans sa course à l’échalote des kit FPGA low cost en proposant un kit Gowin à $4.90. Évidemment à ce prix là c’était trop tentant d’en prendre un. Bon en vrai vu que les frais de port ne sont pas négligeable j’ai également pris l’écran proposé et je m’en suis finalement sortie pour une vingtaine d’€. Ce qui reste néanmoins raisonnable.
Le kit est fourni avec des headers males (pattes) non soudés. Ils ne sont pas nécessaire pour faire clignoter la LED ou pour jouer avec l’écran, mais c’est quand même utile.
Premier boulot en recevant le truc donc : souder les headers.
Le FPGA soudé sur la carte est un GW1N-LV1, assez petit donc, mais il reste raisonnable puisque de la même taille que le ice40 soudé sur le icestick. C’est d’ailleurs le kit utilisé actuellement par Pepijn de Vos son projet d’ingénierie inverse nommé Apicula (mais chuuut le projet n’est pas encore public !).
Le branchement se fait au moyen d’un câble USB-C non fourni. Au premier branchement, la LED rouge qui semble être celle de l’alimentation s’allume et la led RGB du centre se met à clignoter en allumant les trois couleurs à la suite.
Les messages noyau m’affichent le traditionnel double tty typique d’un convertisseur USB-Série habituel (CH552T, un microcontrôleur chinois):
$ sudo dmesg -c
[365812.686837] usb 3-2: new full-speed USB device number 25 using xhci_hcd
[365812.838484] usb 3-2: New USB device found, idVendor=0403, idProduct=6010, bcdDevice= 5.00
[365812.838490] usb 3-2: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[365812.838492] usb 3-2: Product: Sipeed-Debug
[365812.838494] usb 3-2: Manufacturer: Kongou Hikari
[365812.838496] usb 3-2: SerialNumber: 85522A1A47
[365812.840468] ftdi_sio 3-2:1.0: FTDI USB Serial Device converter detected
[365812.840534] usb 3-2: Detected FT2232C
[365812.841192] usb 3-2: FTDI USB Serial Device converter now attached to ttyUSB0
[365812.841373] ftdi_sio 3-2:1.1: FTDI USB Serial Device converter detected
[365812.841427] usb 3-2: Detected FT2232C
[365812.841727] usb 3-2: FTDI USB Serial Device converter now attached to ttyUSB1
On remarquera que cette fois le numéro de série n’est pas en chinois 😉
La connexion au ttyUSB0 (en 115200) fournie un echo du clavier un peu bizarre :
�n�a�u�r�s�i�t�e�n�a�s�u�t�i�e�n�a�s�u�t�i�e�n�s�a�u�t�i�e�n�r�a�s�u�t�i�e�n�r�s�a�u�t�i�e�n�r�s�a�t�u�i�e
Et le ttyUSB1 semble ne pas «fonctionner».
Il est fort probable que le kit soit entièrement utilisable avec des logiciels libre à Noël lors de la grand messe allemande : le Chaos Communication Congress à Liepnitz.
Pour le moment nous allons nous contenter de l’IDE chinois fourni, que j’avais déjà installé pour le little bee. Pour le code, il y a des exemples fournis sur le github de sipeed. Pour la documentation c’est par ici. Et comme d’habitude avec les trucs chinois, quand la doc en anglais semble trop limitée, ne pas hésiter à aller faire un tour sur la version chinoise à coup de google traduction.
Si le floorplanning ne veut pas se lancer c’est qu’il faut bien configurer sa variable LD_LIBRARY_PATH avant de lancer l’appli:
$ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/flf/myapp/gowin/IDE/lib
$ ./gw_ide -gui
– Nano board pinout (blog)
Cocotb take care of the core of cosimulation library. But for our design test some bus-test library are required. They are managed separately.
Here is a list of cocotb modules libraries
For testing USB 1.1 version.
Read/write simulation master on wishbone bus
For uart testing
For SPI
To test some fifo interfaces
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 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.
Some tips for python HDL test module Cocotb.
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.
Question asked on stackoverflow.
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
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")
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 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.
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
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).
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.
Il est possible de charger le bitstream avec openFPGALoader sans problème de nos jours :
$ openFPGALoader -b fireant counter/outflow/counter.hex
Jtag frequency : requested 6.00MHz -> real 6.00MHz
Parse file DONE
Detail:
Jedec ID : ef
memory type : 40
memory capacity : 14
00
Detail:
Jedec ID : ef
memory type : 40
memory capacity : 14
flash chip unknown: use basic protection detection
Erasing: [==================================================] 100.00%
Done
Writing: [==================================================] 100.00%
Done
Wait for CDONE DONE
[ToBeEdited]
This page lists some tips for Chisel that I could glean here and there.
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
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
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
See the good response from Jack Koening on stackoverflow.
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()
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)
val initRegOfVec = RegInit(VecInit(Seq.fill(4)(0.U(32.W))))
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(_ ## _)
Question asked on stackoverflow. Same question on stackoverflow but with ‘1’ initialization.
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))
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 simplicity it’s also possible to use the Scaties website in live.
See :
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.
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]