Afficher la pageAnciennes révisionsLiens de retourHaut de page Cette page est en lecture seule. Vous pouvez afficher le texte source, mais ne pourrez pas le modifier. Contactez votre administrateur si vous pensez qu'il s'agit d'une erreur. <!DOCTYPE markdown> # Comment utiliser le FPGA d'hackens (ULX3S) Un FPGA est un océan de portes reprogrammable. Plus puissant qu'un microcontrôlleur, on peut installer dessus un CPU ou du hardware spécialisé. Pour un example d'utilisation voir: - https://ulx3s.github.io/ - https://github.com/ulx3s/blink/tree/main - https://blog.dave.tf/post/getting-started-fpga/ Le board d'HackENS est un terrain de jeu avec plein d'IO : - de la SDRAM - une carte SD - un ESP32 - des boutons - des leds - un port jack - un port hdmi - ... ## Génération des fichiers verilog à partir de Bluespec Bluespec est un langage de description de hardware de haut niveau, il permet de décrire des circuits sous forme d'un ensemble de règles que le compilateur ordonnance. On peut ainsi faire clignoter une LED avec le programme suivant : ```bsc interface Top; (* always_ready, always_enabled *) method Bit#(8) led; endinterface (* synthesize *) module mkTop(Top); Reg#(Bit#(32)) counter <- mkReg(0); rule incr_counter; counter <= counter + 1; endrule method led = truncateLSB(counter); endmodule ``` et le compiler sous forme de fichiers verilog avec cette commande: ```bash bsc \ -verilog \ -vdir rtl -bdir build -info-dir build \ -no-warn-action-shadowing -check-assert \ -keep-fires -aggressive-conditions -show-schedule \ -cpp +RTS -K128M -RTS -show-range-conflict \ -p :+ -g mkTop -u Main.bsv ``` - ``` -p :+``` liste des dossiers dont les fichiers .bs et .bsv sont importés, le + représente la librarie standard - ``` Top``` est le fichier principale - ``` mkTop``` est le module principale - ``` keep-fires``` utilise le sceduling intuitif: active chaque règle dés que possible, certaines règles peuvent tout de même rester inactives en cas de conflit avec une autre règle - ``` aggressive-conditions``` défini l'ordonnancement en cas de ``` ... ? ... : ...```, ainsi, ``` cond ? fifo1.first : fifo2.first``` sera ordonnancer avec la condition de garde ``` cond ? fifo1.notEmpty : fifo2.notEmpty``` plutôt que ``` fifo1.notEmpty || fifo2.notEmpty``` sans utiliser cet argument. Ainsi, les conditions de garde sont plus difficiles à calculer, mais aussi plus intuitives. ## Génération des LUT (look-up-table) avec yosys ```make yosys -DULX3S -q -p "synth_ecp5 -abc9 -top mkTop -json mkTop.json" rtl/mkTop.v ``` - ``` rtl/mkTop.v``` est la liste des fichiers verilog, dans ce cas le fichier générer par Bluespec - ``` mkTop``` est le module verilog principale - ``` mkTop.json``` est la sortie de yosys - ``` -abc9``` est l'algorithme de génération des LUT par défault, parfois il crash (je pense à cause des inout qui ne sont pas entièrement supporter), dans ce cas utiliser ``` -noabc9``` semble marcher ## Rooting avec nextpnr ```make nextpnr-ecp5 --85k --json mkTop.json \ --lpf ulx3s.lpf \ --textcfg mkTop.config ``` - ``` ulx3s.lpf``` fichier qui map les variables verilog sur les pins - ``` --85k``` nombre de LUT du FPGA - on peut ajouter ``` -gui``` pour avoir une interface graphique et voir le placement sur le FPGA Pour cet exemple, ulx3s.lpf décrit les pins de la LED, l'horloge et du signal de réinitialisation : ``` BLOCK RESETPATHS; BLOCK ASYNCPATHS; ## ULX3S v2.0 and v2.1 # The clock "usb" and "gpdi" sheet LOCATE COMP "CLK" SITE "G2"; IOBUF PORT "CLK" PULLMODE=NONE IO_TYPE=LVCMOS33; FREQUENCY PORT "CLK" 40 MHZ; # JTAG and SPI FLASH voltage 3.3V and options to boot from SPI flash # write to FLASH possible any time from JTAG: SYSCONFIG CONFIG_IOVOLTAGE=3.3 COMPRESS_CONFIG=ON MCCLK_FREQ=62 MASTER_SPI_PORT=ENABLE SLAVE_SPI_PORT=DISABLE SLAVE_PARALLEL_PORT=DISABLE; # write to FLASH possible from user bitstream, not possible form JTAG: # SYSCONFIG CONFIG_IOVOLTAGE=3.3 COMPRESS_CONFIG=ON MCCLK_FREQ=62 MASTER_SPI_PORT=DISABLE SLAVE_SPI_PORT=DISABLE SLAVE_PARALLEL_PORT=DISABLE; LOCATE COMP "RST_N" SITE "D6"; # BTN_PWRn (inverted logic) IOBUF PORT "RST_N" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; ## LED indicators "blinkey" and "gpio" sheet LOCATE COMP "led[7]" SITE "H3"; LOCATE COMP "led[6]" SITE "E1"; LOCATE COMP "led[5]" SITE "E2"; LOCATE COMP "led[4]" SITE "D1"; LOCATE COMP "led[3]" SITE "D2"; LOCATE COMP "led[2]" SITE "C1"; LOCATE COMP "led[1]" SITE "C2"; LOCATE COMP "led[0]" SITE "B2"; IOBUF PORT "led[0]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; IOBUF PORT "led[1]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; IOBUF PORT "led[2]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; IOBUF PORT "led[3]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; IOBUF PORT "led[4]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; IOBUF PORT "led[5]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; IOBUF PORT "led[6]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; IOBUF PORT "led[7]" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; ``` ## Génération du bitstream avec ecppack ```make ecppack mkTop.config mkTop.bit ``` ## Flash du fpga avec fujprog ```make fujprog mkTop.bit ``` Il faut que le tty du fpga soit accessible par l'utilisateur courant! ## Nix On peut tout installer avec ce nix-shell: ``` { pkgs ? import <nixpkgs> {} }: pkgs.mkShell { buildInputs = [ pkgs.bluespec pkgs.verilator pkgs.verilog pkgs.gtkwave pkgs.openfpgaloader pkgs.yosys pkgs.nextpnrWithGui pkgs.trellis ]; shellHook = '' export BLUESPECDIR=${pkgs.bluespec}/lib ''; } ``` howtos/fpga.txt Dernière modification : 2025/09/20 14:04de hackens-pub