Table des matières

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:

Le board d'HackENS est un terrain de jeu avec plein d'IO :

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 :

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:

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

Génération des LUT (look-up-table) avec yosys

yosys -DULX3S -q -p "synth_ecp5 -abc9 -top mkTop -json mkTop.json" rtl/mkTop.v

Rooting avec nextpnr

nextpnr-ecp5 --85k --json mkTop.json \
	--lpf ulx3s.lpf \
	--textcfg mkTop.config

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

ecppack mkTop.config mkTop.bit

Flash du fpga avec fujprog

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
    '';
}