Soon on groupgets.com according to Michel Welling.

Soon on groupgets.com according to Michel Welling.

Formal prove is a great method to find bugs into our gateware. But for many years, this was reserved to big companies with lot of $$. Some years ago, Clifford opened the method with it’s synthesis software Yosys. Explanation about formal prove with Yosys-smtbmc and can be found in this presentation. Dan Guisselquist (ZipCPU) give lot of great tutorials on formal prove with Verilog and SystemVerilog design on it’s blog. It’s a good start to learn formal prove.
But, Yosys-smtbmc is made for Verilog (and a bit of SystemVerilog). It’s too bad but it’s the only open source formal tool available for gateware.
How can we prove our VHDL, Clash or Chisel gateware ?
One of the solution consist of writing a TOP component in SystemVerilog that integrate the assume/assert/cover method and instantiate our DUT in it. It’s the way Pepijn De Vos choose for verifying it’s VHDL gateware. Its VHDL code is converted into Verilog with the new GHDL feature not-yet-finished and a systemVerilog top component instantiate the VHDL gateware converted in verilog by GHDL synthesis feature.
That’s an interesting way to do it and it can be done in the same way with Chisel. But it’s a bit limited to input/output ports of our gateware. If we want to add some property about internal counters or flags or others internals states machines registers, we have to export it with some conditional preprocessor value like follows:
`ifdef FORMAL
// Declare some signal output ports
`endif
It’s became little bit difficult to do that with chisel and its blackbox system. Then if we want to include formal property under the verilog generated module, we have to open the generated verilog code and write it directly.
It’s not a lasting solution. Because each time we regenerate Verilog code from Chisel, each time we have to re-write formal properties. It’s rapidly become a pain !
To (temporarily) fix this problem a little python tools has been written by Martoni for injecting rules automatically under generated Verilog module. We will see how it’s work in this article with a simple project named ChisNesPad.
ChisNesPad is a little project that aim to drive Super Nintendo Pad with an FPGA.

The gamepad pinout is relativelly easy to find on the web.

For FPGA point of view 3 signals interest us :
Internally, the game pad is composed of two 4021 chips serialized.
The directory structure of the project is following :
/
|-- build.sbt <- scala build configuration
|-- src/ <- all chisel sources
| |-- main/
| |-- scala/
| |-- chisnespad.scala <- Chisel module we will prove
| |-- snespadled.scala <- "top" module to test with
| tang nano (gowin)
|-- formal/ <- formal directory where systemVerilog
| and sby yosys configuration are.
|-- platform/ <- some usefull file for synthesis with
final platform (gowin).
To generate Verilog file we just have to launch following command in main project directory:
sbt 'runMain chisnespad.ChisNesPad'
The generated file will be named ChisNesPad.v
smtbmcify tool is a python3 module that can be found on this github project. It can be installed on the dev machine as follow:
$ git clone https://github.com/Martoni/chisverilogutils
$ cd chisverilogutils/smtbmcify
$ python -m pip install -e .
A command named smtbmcify will then be available on system :
$ smtbmcify -h
Usages:
$ python smtbmcify.py [options]
-h, --help print this help message
-v, --verilog=module.v verilog module to read
-f, --formal=formal.sv formals rules
-o, --output=name.sv output filename, default is moduleFormal.sv
To use smtbmc formal tools with smtbmcify we will need two more source/configuration files :
ChisNesPadRules.sv That contain SystemVerilog formals propertiesChisNesPadRules.sby That contain yosys-smtbmc script configurationThese two files must be saved in formal/ directory. sby files are SymbiYosys configuration files, installation instruction of SymbiYosys can be found here.
For simply testing, the rule (written in file ChisNesPadRules.sv) we want to « inject » is following:
//BeginModule:ChisNesPad
always@(posedge clock) begin
assume(io_dlatch == 1'b1);
assert(stateReg == 2'b00);
end
//EndModule:ChisNesPad
With this rule, we assert that if io.dlatch output is 1, the internal stateReg will be set to sInit state (00).
The comments BeginModule and EndModule must be set with the exact chisel module name :
//...
class ChisNesPad (val mainClockFreq: Int = 100,
val clockFreq: Int = 1,
val regLen: Int = 16) extends Module {
val io = IO(new Bundle{
//...
Hence, the tool smtbmcify will find the module in verilog generated module and inject the rules at the end of it:
$ cd formal
$ smtbmcify -v ../ChisNesPad.v -f ChisNesPadRules.sv -o ChisNesPadFormal.sv
...
end else begin
validReg <= _T_19;
end
_T_21 <= stateReg == 2'h1;
_T_23 <= stateReg == 2'h0;
end
//BeginModule:ChisNesPad
always@(posedge clock) begin
assume(io_dlatch == 1'b1);
assert(stateReg == 2'b00);
end
//EndModule:ChisNesPad
endmodule
The module name is mandatory because a Chisel Verilog generated module can contain several module.
Some naming convention should be know to write systemverilog rules:
io.dlatch chisel signal is replaced with io_dlatch.To launch the formal engine we are using a sby script like it (named ChisNesPad.sby:
[options]
mode bmc
depth 30
[engines]
smtbmc
[script]
read -formal ChisNesPadFormal.sv
prep -top ChisNesPad
[files]
ChisNesPadFormal.sv
The launch command is :
$ sby ChisNesPad.sby
SBY 21:12:00 [ChisNesPad] Copy 'ChisNesPadFormal.sv' to 'ChisNesPad/src/ChisNesPadFormal.sv'.
SBY 21:12:00 [ChisNesPad] engine_0: smtbmc
SBY 21:12:00 [ChisNesPad] base: starting process "cd ChisNesPad/src; yosys -ql ../model/design.log ../model/design.ys"
SBY 21:12:00 [ChisNesPad] base: finished (returncode=0)
SBY 21:12:00 [ChisNesPad] smt2: starting process "cd ChisNesPad/model; yosys -ql design_smt2.log design_smt2.ys"
SBY 21:12:00 [ChisNesPad] smt2: finished (returncode=0)
SBY 21:12:00 [ChisNesPad] engine_0: starting process "cd ChisNesPad; yosys-smtbmc --presat --unroll --noprogress -t 30 --append 0 --dump-vcd engine_0/trace.vcd --dump-vlogtb engine_0/trace_tb.v --dump-smtc engine_0/trace.smtc model/design_smt2.smt2"
SBY 21:12:01 [ChisNesPad] engine_0: ## 0:00:00 Solver: yices
SBY 21:12:01 [ChisNesPad] engine_0: ## 0:00:00 Checking assumptions in step 0..
SBY 21:12:01 [ChisNesPad] engine_0: ## 0:00:00 Checking assertions in step 0..
[...]
SBY 21:12:01 [ChisNesPad] engine_0: ## 0:00:00 Checking assumptions in step 29..
SBY 21:12:01 [ChisNesPad] engine_0: ## 0:00:00 Checking assertions in step 29..
SBY 21:12:01 [ChisNesPad] engine_0: ## 0:00:00 Status: passed
SBY 21:12:01 [ChisNesPad] engine_0: finished (returncode=0)
SBY 21:12:01 [ChisNesPad] engine_0: Status returned by engine: pass
SBY 21:12:01 [ChisNesPad] summary: Elapsed clock time [H:MM:SS (secs)]: 0:00:00 (0)
SBY 21:12:01 [ChisNesPad] summary: Elapsed process time [H:MM:SS (secs)]: 0:00:00 (0)
SBY 21:12:01 [ChisNesPad] summary: engine_0 (smtbmc) returned pass
SBY 21:12:01 [ChisNesPad] DONE (PASS, rc=0)
This simple rule finish with success (PASS) and create a directory with all generated file under it.
Rapidly, we will need a Makefile to launch each step of this procedure and to clean generated file.
Of course, all code described so far is available on the github ChisNesPad project.
Ok the test we done so far PASS without problem. Let’s find a bug adding this rules in ChisNesPadRules.sv :
always@(posedge clock) begin
assert(regCount <= 16);
end
This rule generate a FAIL :
$ make
cd ..;sbt "runMain chisnespad.ChisNesPad"
[info] Loading project definition from /home/fabien/myapp/chisNesPad/project
[info] Loading settings for project chisnespad from build.sbt ...
[info] Set current project to chisNesPad (in build file:/home/fabien/myapp/chisNesPad/)
[warn] Multiple main classes detected. Run 'show discoveredMainClasses' to see the list
[info] running chisnespad.ChisNesPad
Generating Verilog sources for ChisNesPad Module
[info] [0.004] Elaborating design...
[info] [1.735] Done elaborating.
Total FIRRTL Compile Time: 1396.1 ms
[success] Total time: 5 s, completed Feb 3, 2020 9:49:48 PM
smtbmcify -v ../ChisNesPad.v -f ChisNesPadRules.sv -o ChisNesPadFormal.sv
Generating file ChisNesPadFormal.sv
1 module will be filled :
ChisNesPad
rm -rf ChisNesPad
sby ChisNesPad.sby
SBY 21:49:48 [ChisNesPad] Copy 'ChisNesPadFormal.sv' to 'ChisNesPad/src/ChisNesPadFormal.sv'.
SBY 21:49:48 [ChisNesPad] engine_0: smtbmc
SBY 21:49:48 [ChisNesPad] base: starting process "cd ChisNesPad/src; yosys -ql ../model/design.log ../model/design.ys"
SBY 21:49:49 [ChisNesPad] base: finished (returncode=0)
SBY 21:49:49 [ChisNesPad] smt2: starting process "cd ChisNesPad/model; yosys -ql design_smt2.log design_smt2.ys"
SBY 21:49:49 [ChisNesPad] smt2: finished (returncode=0)
SBY 21:49:49 [ChisNesPad] engine_0: starting process "cd ChisNesPad; yosys-smtbmc --presat --unroll --noprogress -t 30 --append 0 --dump-vcd engine_0/trace.vcd --dump-vlogtb engine_0/trace_tb.v --dump-smtc engine_0/trace.smtc model/design_smt2.smt2"
SBY 21:49:49 [ChisNesPad] engine_0: ## 0:00:00 Solver: yices
SBY 21:49:49 [ChisNesPad] engine_0: ## 0:00:00 Checking assumptions in step 0..
SBY 21:49:49 [ChisNesPad] engine_0: ## 0:00:00 Checking assertions in step 0..
SBY 21:49:49 [ChisNesPad] engine_0: ## 0:00:00 Checking assumptions in step 1..
SBY 21:49:49 [ChisNesPad] engine_0: ## 0:00:00 Checking assertions in step 1..
SBY 21:49:49 [ChisNesPad] engine_0: ## 0:00:00 BMC failed!
SBY 21:49:49 [ChisNesPad] engine_0: ## 0:00:00 Assert failed in ChisNesPad: ChisNesPadFormal.sv:230
SBY 21:49:49 [ChisNesPad] engine_0: ## 0:00:00 Writing trace to VCD file: engine_0/trace.vcd
SBY 21:49:49 [ChisNesPad] engine_0: ## 0:00:00 Writing trace to Verilog testbench: engine_0/trace_tb.v
SBY 21:49:49 [ChisNesPad] engine_0: ## 0:00:00 Writing trace to constraints file: engine_0/trace.smtc
SBY 21:49:49 [ChisNesPad] engine_0: ## 0:00:00 Status: failed (!)
SBY 21:49:49 [ChisNesPad] engine_0: finished (returncode=1)
SBY 21:49:49 [ChisNesPad] engine_0: Status returned by engine: FAIL
SBY 21:49:49 [ChisNesPad] summary: Elapsed clock time [H:MM:SS (secs)]: 0:00:00 (0)
SBY 21:49:49 [ChisNesPad] summary: Elapsed process time [H:MM:SS (secs)]: 0:00:00 (0)
SBY 21:49:49 [ChisNesPad] summary: engine_0 (smtbmc) returned FAIL
SBY 21:49:49 [ChisNesPad] summary: counterexample trace: ChisNesPad/engine_0/trace.vcd
SBY 21:49:49 [ChisNesPad] DONE (FAIL, rc=2)
make: *** [Makefile:10: ChisNesPad/PASS] Error 2
An error is found at second step. A vcd trace is generated that we can see with gtkwave:
$ gtkwave ChisNesPad/engine_0/trace.vcd

We can also get verilog testbench that reproduce the bug under the same directory (trace_tb.v).
The problem here is that we didn’t define initial reset condition as explained in ZipCPU course. To solve this problem we have to change the rule adding initial rules (reset should be set at the begining) and assert counter value only when reset is not set :
initial
assume(reset==1'b1);
always@(posedge clock) begin
if(reset == 1'b0)
assert(regCount <= 16);
end
With that rules, it pass :
$ make
cd ..;sbt "runMain chisnespad.ChisNesPad"
[info] Loading project definition from /home/fabien/myapp/chisNesPad/project
[info] Loading settings for project chisnespad from build.sbt ...
[info] Set current project to chisNesPad (in build file:/home/fabien/myapp/chisNesPad/)
[warn] Multiple main classes detected. Run 'show discoveredMainClasses' to see the list
[info] running chisnespad.ChisNesPad
Generating Verilog sources for ChisNesPad Module
[info] [0.004] Elaborating design...
[info] [1.612] Done elaborating.
Total FIRRTL Compile Time: 1324.0 ms
[success] Total time: 5 s, completed Feb 3, 2020 10:04:37 PM
smtbmcify -v ../ChisNesPad.v -f ChisNesPadRules.sv -o ChisNesPadFormal.sv
Generating file ChisNesPadFormal.sv
1 module will be filled :
ChisNesPad
rm -rf ChisNesPad
sby ChisNesPad.sby
SBY 22:04:38 [ChisNesPad] Copy 'ChisNesPadFormal.sv' to 'ChisNesPad/src/ChisNesPadFormal.sv'.
SBY 22:04:38 [ChisNesPad] engine_0: smtbmc
SBY 22:04:38 [ChisNesPad] base: starting process "cd ChisNesPad/src; yosys -ql ../model/design.log ../model/design.ys"
SBY 22:04:38 [ChisNesPad] base: finished (returncode=0)
SBY 22:04:38 [ChisNesPad] smt2: starting process "cd ChisNesPad/model; yosys -ql design_smt2.log design_smt2.ys"
SBY 22:04:38 [ChisNesPad] smt2: finished (returncode=0)
SBY 22:04:38 [ChisNesPad] engine_0: starting process "cd ChisNesPad; yosys-smtbmc --presat --unroll --noprogress -t 30 --append 0 --dump-vcd engine_0/trace.vcd --dump-vlogtb engine_0/trace_tb.v --dump-smtc engine_0/trace.smtc model/design_smt2.smt2"
SBY 22:04:38 [ChisNesPad] engine_0: ## 0:00:00 Solver: yices
SBY 22:04:38 [ChisNesPad] engine_0: ## 0:00:00 Checking assumptions in step 0..
[...]
SBY 22:04:39 [ChisNesPad] engine_0: ## 0:00:00 Checking assertions in step 29..
SBY 22:04:39 [ChisNesPad] engine_0: ## 0:00:00 Status: passed
SBY 22:04:39 [ChisNesPad] engine_0: finished (returncode=0)
SBY 22:04:39 [ChisNesPad] engine_0: Status returned by engine: pass
SBY 22:04:39 [ChisNesPad] summary: Elapsed clock time [H:MM:SS (secs)]: 0:00:00 (0)
SBY 22:04:39 [ChisNesPad] summary: Elapsed process time [H:MM:SS (secs)]: 0:00:00 (0)
SBY 22:04:39 [ChisNesPad] summary: engine_0 (smtbmc) returned pass
SBY 22:04:39 [ChisNesPad] DONE (PASS, rc=0)
This is just a little introduction on how to use yosys-smtbmc and symbiYosys to formally prove your chisel design.
Maybe this formal rules injector will be integrated in Chisel a day ?
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]