Plutot que d'utiliser Vivado, il est possible de programmer le Red Pitaya uniquement avec Yosys et NextPnr que l'on peut installer avec :
nix develop github:openxc7/toolchain-nix
Puis on peut écrire un petit programme verilog pour controller le FPGA:
module red_pitaya ( input wire [1:1] adc_clk_i, output wire[7:0] led_o ); reg [32:0] counter; assign led_o = counter[31:24]; always @(posedge adc_clk_i[1]) begin counter <= counter + 1; end PS7 zynq7(); endmodule
PS7 zynq7()
instancie le processeur, sans cette ligne le board crash et reboot après quelques secondes.yosys -q -p "synth_xilinx -flatten -abc9 -arch xc7 -top red_pitaya; write_json build/red_pitaya.json" top.v
Pour programmer des board Xilinx, Nextpnr à besoin d'une base de donnée que l'on peut générer avec :
mkdir db $PYPY3 $NEXTPNR_XILINX_PYTHON_DIR/bbaexport.py \ --device xc7z010clg400-1 --bba xc7z010clg400.bba bbasm -l xc7z010clg400.bba db/xc7z010clg400.bin rm -f xc7z010clg400.bba
nextpnr-xilinx \ --router router1 --chipdb db/xc7z010clg400.bin --xdc red_pitaya.xdc \ --json build/red_pitaya.json --fasm build/red_pitaya.fasm
red_pitaya.xdc
défini les liens entre les pins et les paramètres du fichier verilog.fasm2frames --part xc7z010clg400-1 --db-root $PRJXRAY_DB_DIR/zynq7 \ build/red_pitaya.fasm > build/red_pitaya.frames xc7frames2bit \ --part_file $PRJXRAY_DB_DIR/zynq7/xc7z010clg400-1/part.yaml \ --part_name xc7z010clg400-1 --frm_file build/red_pitaya.frames \ --output_file build/red_pitaya.bit
Le Red Pitaya utilise un SOC avec un FPGA Xilinx et un Arm-Cortex-A9 (deux coeurs) sur lequel tourne un linux. Si le Red Pitaya est programmer avec un firmware antérieur à 2.0 il suffit de se connecter au board en SSH, et d'utiliser la commande:
cat ./red_pitaya.bit > /dev/xdevcfg
pour programmer le FPGA!
Pour communiquer avec le CPU il est possible d'utiliser les ports MAXI0
, MAXI1
et SAXIACP
du module PS7
. Ces ports permettent de communiquer avec le CPU en utilisant le protocole AXI3
. Dans un cas, le FPGA est le slave du CPU ( MAXI*
), cela permet de recevoir des commandes de la part du CPU (par exemple en écrivant dans /dev/mem
à l'adresse 0x40000000
). À l'inverse, on peut écrire dans la RAM et les caches du CPU en utilisant l'interface SACP
(pour Slave Accelerator Coherent Interface) toujours avec le protocole AXI3
, mais en tant que master. Le device tree du cpu défini une région commençant à l'adresse 0x1000000
de taille 0x180000
dans laquelle le FPGA peut écrire sans corrompre la mémoire du CPU en utilisant cette interface.
Pour cela j'utilise la librarie BlueAXI qui permet d'utiliser facilement le protocoles AXI3.