POD (PeripheralOnDemand) est un outils écrit en python permettant de générer un design pour les FPGA d’armadeus sans avoir à faire du VHDL/Verilog. Cet utilitaire permet d’intégrer des «composants virtuels» disponibles sur étagère et de générer le design.
POD peut-être utilisé en ligne de commande pour créer un projet, mais il peut aussi être scripté via l’argument -s de la commande pod :
$ pod -s monscript.pod
On trouve un certain nombre de scripts POD dans le projet armadeus dans le répertoire firmware/pod_scripts/.
Par exemple si nous avons besoin d’utiliser le gsm ou le gps de la carte APF51dev il faudra générer des uarts dans le FPGA au moyen du script apf51_gsm_gps_firmware.pod :
$ pod -s apf51_gsm_gps_firmware.pod
create apf51_gsm_gps_firmware
Project apf51_gsm_gps_firmware created
POD:apf51_gsm_gps_firmware> $ selectplatform standard.apf51
[INFO] : No platform in project
Component platform added as apf51
Component imx51_wb16_wrapper added as imx51_wb16_wrapper00
Component rstgen_syscon added as rstgen_syscon00
Component irq_mngr added as irq_mngr00
POD:apf51_gsm_gps_firmware> $ addinstance components.uart16750 gsm_uart
Component uart16750 added as gsm_uart
POD:apf51_gsm_gps_firmware> $ addinstance components.uart16750 gps_uart
Component uart16750 added as gps_uart
POD:apf51_gsm_gps_firmware> $ connectpin gsm_uart.interrupt.int_o.0 irq_mngr00.irq.irqport.0
POD:apf51_gsm_gps_firmware> $ connectpin gps_uart.interrupt.int_o.0 irq_mngr00.irq.irqport.1
POD:apf51_gsm_gps_firmware> $ connectpin gps_uart.uart.srx_pad_i.0 apf51.fpga.IO_L40P_M3DQ6_3
POD:apf51_gsm_gps_firmware> $ connectpin gps_uart.uart.stx_pad_o.0 apf51.fpga.IO_L42N_GCLK24_M3LDM_3
POD:apf51_gsm_gps_firmware> $ connectpin gsm_uart.uart.srx_pad_i.0 apf51.fpga.IO_L39P_M3LDQS_3
POD:apf51_gsm_gps_firmware> $ connectpin gsm_uart.uart.stx_pad_o.0 apf51.fpga.IO_L41P_GCLK27_M3DQ4_3
POD:apf51_gsm_gps_firmware> $ connectpin gsm_uart.uart.cts_pad_i.0 apf51.fpga.IO_L41N_GCLK26_M3DQ5_3
POD:apf51_gsm_gps_firmware> $ connectpin gsm_uart.uart.rts_pad_o.0 apf51.fpga.IO_L39N_M3LDQSN_3
POD:apf51_gsm_gps_firmware> $ autoconnectbus
setting base address 0x0 for irq_mngr00.swb16
setting base address 0x20 for gsm_uart.swb16
setting base address 0x40 for gps_uart.swb16
No addressing value in this type of bus
Bus connected
POD:apf51_gsm_gps_firmware> $ generateintercon imx51_wb16_wrapper00.mwb16
Intercon with name : imx51_wb16_wrapper00_mwb16_intercon Done
Component imx51_wb16_wrapper00_mwb16 added as imx51_wb16_wrapper00_mwb16_intercon
POD:apf51_gsm_gps_firmware> $ generateintercon rstgen_syscon00.candroutput
Intercon with name : rstgen_syscon00_candroutput_intercon Done
Component rstgen_syscon00_candroutput added as rstgen_syscon00_candroutput_intercon
POD:apf51_gsm_gps_firmware> $ generatetop
Mapping for interface mwb16:
Address | instance.interface | size
---------------------------------------------------------
0x0 | irq_mngr00.swb16 | 8
0x08 | --void-- | 24
0x20 | gsm_uart.swb16 | 32
0x40 | gps_uart.swb16 | 32
---------------------------------------------------------
[INFO] : port gsm_uart.uart.dsr_pad_i is void. It will be set to '0'
[INFO] : port gsm_uart.uart.ri_pad_i is void. It will be set to '1'
[INFO] : port gsm_uart.uart.dcd_pad_i is void. It will be set to '0'
[INFO] : port gps_uart.uart.cts_pad_i is void. It will be set to '0'
[INFO] : port gps_uart.uart.dsr_pad_i is void. It will be set to '0'
[INFO] : port gps_uart.uart.ri_pad_i is void. It will be set to '1'
[INFO] : port gps_uart.uart.dcd_pad_i is void. It will be set to '0'
Top generated with name : top_apf51_gsm_gps_firmware.vhd
POD:apf51_gsm_gps_firmware> $ synthesis.selecttoolchain ise
POD:apf51_gsm_gps_firmware> $ synthesis.generateproject
Make directory for imx51_wb16_wrapper
Make directory for rstgen_syscon
Make directory for irq_mngr
Make directory for uart16750
Make directory for imx51_wb16_wrapper00_mwb16
Make directory for rstgen_syscon00_candroutput
Constraint file generated with name : firmware/pod_scripts/apf51_gsm_gps_firmware/synthesis/apf51_gsm_gps_firmware.ucf
TCL script generated with name : apf51_gsm_gps_firmware.tcl
POD:apf51_gsm_gps_firmware> $ driver.selecttoolchain armadeus
Ce script a permit de générer tout le projet qui est maintenant disponible pour ISE. Pour simplifier son utilisation pod a généré un script tcl firmware/pod_scripts/apf51_gsm_gps_firmware/synthesis/apf51_gsm_gps_firmware.tcl que l’on peut «sourcer» dans la console tcl d’ISE pour générer le bitstream.
Cependant nous devons quand même lancer l’énorme programme qu’est ISE Webpack pour lancer le script. Ce qui est réellement très fastidieux. Jusqu’ici nous étions contraint de le faire à cause d’un bug d’ISE qui empêchait de charger le fichier de contraintes *.ucf correctement.
Ce bug a été patché dans la dernière release de POD et nous pouvons maintenant générer le bitstream en ligne de commande directement. Il suffit pour cela de taper les commandes suivantes :
$ cd apf51_gsm_gps_firmware/synthesis/
# pour l'architecture 32bits, sinon c'est settings64.sh
$ source ISE/14.6/ISE_DS/settings32.sh
$ xtclsh apf51_gsm_gps_firmware.tcl
Le script prend un certain temps à s’exécuter. Une fois terminé nous retrouvons le bitstream dans le répertoire objs/ du projet :
$ ls ../objs/*.bin
../objs/top_apf51_gsm_gps_firmware.bin
Fichier que l’on peut ensuite télécharger directement dans le fpga avec la méthode de son choix.