Archives par mot-clé : Migen

Expérimentations de Migen sur APF27 avec debian

Migen est une tentative open-source de faire du design FPGA en python. La solution initiée par S.Bourdeauducq (principale développeur de milkymist) permet de simuler le design en python pur et de le générer en vérilog pour la synthèse sur le FPGA proprement dite.

Installation sur debian Wheezy

Pour installer Migen, il faut tout d’abord «cloner» le projet git hub avec la commande suivante :


$ git clone https://github.com/m-labs/migen.git

Puis de se rendre dans le répertoire ainsi créé et de taper la commande d’installation suivante:


$ cd migen
$ sudo python3 setup.py install
Migen requires python 3.3 or greater

Premier problème sur debian wheezy : python est trop vieux. Comme le dit le message il nous faut un python 3.3 minimum, et celui de wheezy en est à la version 3.2 🙁

Il va donc nous falloir installer la dernière version 3.4 de python (tant qu’à faire prendre la dernière).


tar -Jxvf Python-3.4.0.tar.xz
cd Python-3.4.0
./configure
make
make test
sudo make install

De là il est facile de s’installer Migen


sudo python3.4 setup.py install

Icarus

Migen génère du code en verilog. Pour pouvoir le simuler il est conseillé d’utiliser  le simulateur libre Icarus, logiciel qui se trouve dans le paquet «verilog» de debian :


sudo apt-get install verilog

Dans le répertoire vpi des sources de migen il faut également générer le plugin permettant de se connecter à icarus :


$ cd migen/vpi/
$ make
$ sudo make install
install -m755 -t /usr/lib/ivl migensim.vpi

Premiers pas avec Migen

Le «helloworld» de l’électronicien, c’est la led qui clignote. La conception sur FPGA se rapprochant plus de l’électronique que du logiciel, ça ne loupe pas : l’exemple donné dans la doc est une led qui clignote !

L’exemple pose plusieurs problème :

testmigen.py :


from migen.fhdl.std import *
from mibuild.platforms import m1
plat = m1.Platform()
led = plat.request("user_led")
m = Module()
counter = Signal(26)
m.comb += led.eq(counter[25])
m.sync += counter.eq(counter + 1)
plat.build_cmdline(m)

Si on exécute tel quel ce code on tombe sur une erreur de path «/opt/Xilinx»


$ python3.4 testmigen.py
Traceback (most recent call last):
File "testmigen.py", line 11, in 
plat.build_cmdline(m)
File "/usr/local/lib/python3.4/site-packages/migen-unknown-py3.4.egg/mibuild/generic_platform.py", line 272, in build_cmdline
self.build(*args, **kwargs)
File "/usr/local/lib/python3.4/site-packages/migen-unknown-py3.4.egg/mibuild/xilinx_ise.py", line 246, in build
self.map_opt, self.par_opt)
File "/usr/local/lib/python3.4/site-packages/migen-unknown-py3.4.egg/mibuild/xilinx_ise.py", line 133, in _run_ise
vers = [ver for ver in os.listdir(ise_path) if _is_valid_version(ise_path, ver)]
FileNotFoundError: [Errno 2] No such file or directory: '/opt/Xilinx'

Car Migen est capable d’aller jusqu’à la génération du design avec le webpack de xilinx. Mais pour cela il faut lui indiquer le bon chemin d’installation de ISE. Le code python de Migen référençant en dur le path, pour éviter de toucher au code, le plus simple est de faire un liens sur /opt/Xilinx.


$ sudo ln -s ~/myxilinxinstallation/ /opt/Xilinx
$ sudo chmod 755 /opt/Xilinx

De cette manière, nous pouvons maintenant lancer le «helloworld» qui va nous générer le bitstream final directement :


$ python3.4 testmigen.py
...
Sun May 4 16:06:25 2014

Running DRC.
DRC detected 0 errors and 0 warnings.
Creating bit map...
Saving bit stream in "top.bit".
Saving bit stream in "top.bin".
Bitstream generation is complete.

Tous les fichiers générés se trouve dans le répertoire «build» :


$ ls build/
build_top.sh top.bin top.drc top_map.ncd top.ngc top.pad top_par.xrpt top.srp top_usage.xml usage_statistics_webtalk.html xst
netlist.lst top.bit top.lso top_map.ngm top.ngc_xst.xrpt top_pad.csv top.pcf top_summary.xml top.v webtalk.log
par_usage_statistics.html top_bitgen.xwbt top_map.map top_map.xrpt top.ngd top_pad.txt top.prj top.ucf top.xpi xlnx_auto_0_xdb
top.bgn top.bld top_map.mrp top.ncd top_ngdbuild.xrpt top.par top.ptwx top.unroutes top.xst _xmsgs

Et la led ne clignote toujours pas !

Deuxième problème de l’exemple : la plate-forme utilisée est une m1, or nous utilisons une apf27.  Il faut que nous importions la bonne plate-forme pour pouvoir faire clignoter notre led. Nous allons donc changer notre script python pour intégrer l’apf27:

#!/usr/local/bin/python3.4
# -*- coding: utf-8 -*-
 
from migen.fhdl.std import *
from mibuild.generic_platform import Pins, IOStandard
from mibuild.platforms import apf27
 
ios = [
    ("user_led", 0, Pins("J2:22"), IOStandard("LVCMOS33"))
]
 
plat = apf27.Platform()
plat.add_extension(ios)
led = plat.request("user_led", 0)  # led pin on apf27dev
m = Module()
counter = Signal(26)
m.comb += led.eq(counter[25])
m.sync += counter.eq(counter + 1)
plat.build_cmdline(m)

Le bitstream généré se nomme top.bit et se trouve dans le répertoire «build» nouvellement créé.

Il suffit ensuite de télécharger top.bit sur le fpga (via uboot ou via Linux au choix)

Et la led clignote !