Skip to content
Carl Karsten edited this page Sep 17, 2024 · 26 revisions

How to make the lights blink

Or, a walk though of the system so you know first hand what is is and how you can use it.

What it is

Access to a real FPGA for you to experiment with.
The rest of this pages guides you though a few examples. You will use your local machine for most of the work, then move the needed files to the pi/arty to see what happens.

What is available

(You can skip this, but everyone wants to know what is "in the box")
  1. FPGA board Arty A7-35T which has a Xilinx Artix-7 https://www.mouser.com/new/digilent/digilent-arty-a7-100t-board/
  2. Raspberry Pi running https://downloads.raspberrypi.org/raspios_lite_armhf/
  3. Handy packages like openFPGALoader - complete list https://github.com/CarlFK/pici/blob/main/ansible/roles/onpi/tasks/apt.yml#L20
  4. A camera pointed at the Arty's LEDs
  5. Web interface:
  • Reset button to power cycle the Pi (which also power cycles the Arty)
  • pi status message window - power on or off, boot messages.
  • Shell access to the Pi - Web SSH for easy one click access. (using a local ssh client is also supported)
  • Live camera video feed - So you can watch the lights blink.

The Pi OS boots from a Read Only file server. Pi file system updates are stored in the pi's ram, which means whatever you do, (including break it) all gets reset when it is power cycled.

Build a bitstream

Do this locally (your computer that you are likely using to read this wiki page.) (Don't try it on the pi, it will faile because there isn't enough ram or local storage.)

  1. Install the F4PGA tools:

https://f4pga-examples.readthedocs.io/en/latest/getting.html

For Select your target FPGA family: select Artix-7

  1. Run these 4 commands explained on https://f4pga-examples.readthedocs.io/en/latest/building-examples.html
export F4PGA_INSTALL_DIR=~/opt/f4pga
export FPGA_FAM="xc7"
source "$F4PGA_INSTALL_DIR/$FPGA_FAM/conda/etc/profile.d/conda.sh"
conda activate $FPGA_FAM
  1. Build the Counter test:

https://f4pga-examples.readthedocs.io/en/latest/xc7/counter_test.html

The upload instructions expect you have a board plugged in locally, so only do the build step:

TARGET="arty_35" make -C counter_test

which will end with:

Module `bitstream-generic` has finished its work!
Target bitstream -> .../f4pga-examples/xc7/counter_test/build/arty_35/top.bit
f4pga: DONE

Put the bitstream on the pi

Go to https://ps1.fpgas.mithis.com

Pick a Pi, hit its Reset button to reboot the pi (which will power cycle the Arty board too.) Watch the boot messages in the status window. When it says "piview ssh" that means the ssh server is ready for connections.

Use scp to copy the file from your local box to the pi's Upload dir. Find the port that is forwarded to the Pi's ssh, example: 10222 (the port is based on 100+N+"22")

scp -P 10222 counter_test/build/arty_35/top.bit pi@ps1.fpgas.mithis.com:Uploads (the password will be displayed in the login banner.)

Load the bitstream onto the Arty

ssh into the pi. Either click the ssh link in the browser to use the wssh client, or use your favorite ssh client. (I suggest adding your public key with ssh-copy-id gh:CarlFK)

do this:

openFPGALoader -b arty Uploads/top.bit

see:

Jtag frequency : requested 10.00MHz  -> real 10.00MHz 
Open file DONE
Parse file DONE
load program
Flash SRAM: [==================================================] 100.00%
Done

Watch the lights blink:

Click the 'play' button on the video player. You should see the LEDs on the Arty board flashing.

Sadly there is a good 30-60 seconds of latency between the camera and the video player. When openFPGALoader is done, look at the prompt hour:min:sec , and wait for that time stamp to show up on the video feed. VLC is slightly better, but only by about 5 seconds, so not really. Someday this will be better: https://github.com/CarlFK/pici/issues/15

The camera's field of view isn't always the best, so you may only see some flicker off to the side.

More examples, boot Linux!

The f4pga-examples docs have more examples. It doesn't make much sense to try the ones that require touching the switches on the board. Some need a tftp server and networking, the pi has this setup already do all you have to do is follow the instructions below to put the files into /srv/tftp.

  • picosoc_demo
  • LiteX
  • Linux LiteX

picosoc_demo

cd f4pga-examples/xc7
TARGET="arty_35" make -C picosoc_demo

After this step:

At completion, the bitstreams are located in the build directory: cd picosoc_demo/build/

copy the file to the pi: scp -P 13422 picosoc_demo/build/arty_35/top.bit pi@fpgas.mithis.com:Uploads

ssh to the pi, openFPGALoader -b arty Uploads/top.bit

LiteX

Read the docs, build the bitstream, copy to pi:

scp -P 13422 build/picorv32/arty_35/gateware/arty.bit pi@fpgas.mithis.com:Uploads

ssh to the pi, use tmux (or screen, or many ssh connections) to have 2 shells to run these two commands:

`tio /dev/ttyUSB1'

tio is a handy Terminal IO client. like it tells you: ^Tq to quit. (don't quit just yet.)

On a freshly rebooted system (pi/arty) you will see the default Arty menu (the BTNs are the buttons on the board, not the keys on your keyboard, so don't try typing BTN.) or a spew of I'm not sure what the previous demo was doing to the serial port. You should see the Litex boot messages once you load it in the 2nd shell:

openFPGALoader -b arty Uploads/arty.bit

Change to the serial terminal shell, see the LitexX ascii art Build your hardware, easily! lots of specs ending with No boot medium found (expected.)

Type help and see lots of things. Two that are interesting:

litex> ident
Ident: LiteX SoC on Arty A7 2024-02-29 21:47:47

and

litex> leds 0x101010
Settings Leds to 0x101010

(different values do different things, but I'm not sure what.)

Linux LiteX

The F4PGA docs get are a bit wonky (I think?) so I logged https://github.com/chipsalliance/f4pga-examples/issues/381 and a patch. Until that issue gets resolved and I remove this, you will need to:

git submodule update --init --recursive

Then build for Arty35, which builds both the bitstream and some files that will be loaded via a tftp client running on the Arty fetching from the pi's tftp server.
upload:

scp -r -P 10522 \
    buildroot emulator build/arty_35/top.bit \
    pi@ps1.fpgas.mithis.com:Uploads
Image                                         100% 4543KB   1.1MB/s   00:03    
rv32.dtb                                      100% 1838    24.9KB/s   00:00    
rootfs.cpio                                   100% 3968KB   1.0MB/s   00:03    
emulator.bin                                  100% 2992    35.4KB/s   00:00    
top.bit                                       100% 2141KB   1.3MB/s   00:01    

On the pi, move the files to the dir being served by tftpd: sudo mv -v Uploads/*/* /srv/tftp/

renamed 'Uploads/buildroot/Image' -> '/srv/tftp/Image'
renamed 'Uploads/buildroot/rootfs.cpio' -> '/srv/tftp/rootfs.cpio'
renamed 'Uploads/buildroot/rv32.dtb' -> '/srv/tftp/rv32.dtb'
renamed 'Uploads/emulator/emulator.bin' -> '/srv/tftp/emulator.bin'

Load the bitstream:

openFPGALoader -b arty Uploads/top.bit

switch to the serial terminal, and you should see Litex banner, ram tests, etc.

Fetching from: UDP/6069
(ascii spinner...)

after about 20 seconds:

--============== Boot ==================--                              [89/180]
Booting from serial...                                                          
Press Q or ESC to abort boot completely.                                        
sL5DdSMmkekro                                                                   
             Timeout                                                            
Loading emulator.bin from flash...                                              
Error: Invalid image length 0xffffffff                                          
Booting from flash...                                                           
Error: Invalid image length 0xffffffff                                          
Booting from network...                                                         
Local IP : 192.168.100.50                                                       
Remote IP: 192.168.100.100                                                      
Fetching from: UDP/6069                                                         
Downloaded 4797084 bytes from Image over TFTP to 0xc0000000
Downloaded 4062720 bytes from rootfs.cpio over TFTP to 0xc0800000               
Downloaded 1838 bytes from rv32.dtb over TFTP to 0xc1000000                     Downloaded 2992 bytes from emulator.bin over TFTP to 0x50000000     
Executing booted program at 0x50000000                                          
                                                                                
--============= Liftoff! ===============--                                      
*** VexRiscv BIOS ***                                                           
                     *** Supervisor ***                                         
                                       [    0.000000] No DTB passed to the kerne
l
[    0.000000] Linux version 5.0.13 (tmichalak@localhost.localdomain) (gcc versi
on 8.3.0 (Buildroot 2020.02-git-00142-ga4d38f029f)) #1 Tue Dec 3 08:55:41 CET 20
19
[    0.000000] earlycon: sbi0 at I/O port 0x0 (options '')
[    0.000000] printk: bootconsole [sbi0] enabled
...
(typical Linux boot messages...)
[    3.944983] This architecture does not have kernel memory protection.
[    3.948797] Run /init as init process
mount: mounting tmpfs on /dev/shm failed: Invalid argument
mount: mounting tmpfs on /tmp failed: Invalid argument
mo111````unt: mounting tmpfs on /run failed: Invalid argument
Starting syslogd: OK
Starting klogd: OK
Running sysctl: OK
Saving random seed: [    6.508843] random: dd: uninitialized urandom read (512 bytes read)
OK
Starting network: OK

Welcome to Buildroot
buildroot login: 

Login as root (no pw) and explore around.

root@buildroot:~# ip a add 192.168.100.2/24 dev eth0
root@buildroot:~# ip link set dev eth0 up
root@buildroot:~# ping 192.168.100.100
PING 192.168.100.100 (192.168.100.100): 56 data bytes
64 bytes from 192.168.100.100: seq=0 ttl=64 time=18.144 ms
64 bytes from 192.168.100.100: seq=1 ttl=64 time=4.538 ms

What next? maybe https://github.com/litex-hub/zephyr-on-litex-vexriscv