Showing posts with label FOMU. Show all posts
Showing posts with label FOMU. Show all posts

Saturday, April 11, 2020

Circuit Python on the FOMU in WSL (plus the pains of building your own RISC-V toolchain)


I started down the road of learning FPGA Circuit Python last month, with the (admittedly overly-ambitious) goal of getting Circuit Python working on the ULX3S. I was inspired to revisit this today when I saw Adafruit Blog - CircuitPython 5.2.0 Released - that specifically mentioned LiteX for Circuit Python!! In this case, for the FOMU.

TL;DR - WSL is by default NOT Case Sensitive. Use fsutil.exe in a DOS admin window to change this for each directory. To compile, riscv64-unknown-elf-gcc is needed, but the RISC-V GitHub GNU Repo does not work here to build Circuit Python. Use the FOMU toolchain. The make parameter should be lower case: make BOARD=fomu

If you are interested in Circuit Python, check out this CircuitBrains Deluxe on Crowd Supply.

See Adafruit instructions on building Circuit Python. All of the downloads for Circuit Python are available online. Well, all but of course the FOMU that I am most interested in. Hopefully it will be there soon, so for now we are doing this the hard way. (no fun if it is too easy, right?)

I could not find any documentation on the FOMU build, so I had to dig and search for keywords. The initial part of fetching from GitHub is pretty standard, so we'll start there:

git clone https://github.com/adafruit/circuitpython.git
cd circuitpython
git submodule sync
git submodule update --init
make -C mpy-cross
When doing the git submodule update --init in DOS (I sometimes do that, since my git clones are in C:\workspace - even though I compile in WSL from /mnt/c/workspace/)... I saw these errors:
git submodule update --init
Submodule 'extmod/ulab' (https://github.com/v923z/micropython-ulab/) registered for path 'extmod/ulab'
...etc
Submodule path 'lib/nrfutil': checked out '9e7dfb28a5c6f3d7a19340971b32e0c2b4128ecf'
Submodule path 'lib/tinyusb': checked out '1f95f439e11f519e69d75a4a8b7b9f28eaf5060e'
error: unable to create file tests/decomp-bad-inputs/00/id:000000,sig:11,src:000000,op:flip1,pos:10: Invalid argument
...etc
error: unable to create file tests/decomp-bad-inputs/00/id:000012,sig:11,src:000000,op:arith8,pos:11,val:+6: Invalid argument
error: unable to create file tests/decomp-bad-inputs/00/id:000013,sig:11,src:000000,op:arith8,pos:12,val:-9: Invalid argument
error: unable to create file tests/decomp-bad-inputs/00/id:000014,sig:11,src:000000,op:havoc,rep:16: Invalid argument
error: unable to create file tests/decomp-bad-inputs/00/id:000015,sig:11,src:000000,op:havoc,rep:2: Invalid argument
... many, many more similar errors
When doing the git submodule update --init from WSL just a few moments later, I did not see those errors. Perhaps there's some issue with Windows file names. (edit: I learned later this is likely a case sensitivity issue, see below).

For the FOMU, there's a Makefile in ./ports/litex
cd ./ports/litex
make BOARD=fomu
Edit: note that a case insensitive directory setting may allow BOARD=FOMU to work. ymmv. The safest one to use is a lower-case: BOARD=fomu.

If you see an error like this:
xargs: riscv64-unknown-elf-gcc: No such file or directory
../../py/mkrules.mk:81: recipe for target 'build-FOMU/genhdr/qstr.i.last' failed
make: *** [build-FOMU/genhdr/qstr.i.last] Error 127
make: *** Deleting file 'build-FOMU/genhdr/qstr.i.last'
Then try riscv64-unknown-elf-gcc --version to see if this RISC-V compiler is installed (perhaps you need to install the compiler). sadly, this is a different version of the compiler than is used in my ULX3S toolchain builder, that uses rv32i installed to /opt/riscv32i. Of course it does. Sometimes I wonder if this is all a hard drive manufacturer conspiracy to use as much disk space as possible. ;)

If like me you don't have the right compiler installed, make sure you have plenty of disk space:
This process will start by downloading about 200 MiB of upstream sources, then will patch, build, and install the toolchain. If a local cache of the upstream sources exists in $(DISTDIR), it will be used; the default location is /var/cache/distfiles. Your computer will need about 8 GiB of disk space to complete the process.

Here's what I did in WSL:
sudo apt-get install autoconf automake autotools-dev curl python3 libmpc-dev libmpfr-dev libgmp-dev gawk build-essential bison flex texinfo gperf libtool patchutils bc zlib1g-dev libexpat-dev
git clone --recursive https://github.com/riscv/riscv-gnu-toolchain  
cd riscv-gnu-toolchain  
./configure --prefix=/opt/riscv
sudo mkdir /opt/riscv
sudo chown $USER /opt/riscv
if [ "$(echo $PATH | grep  /opt/riscv/bin)" == "" ]; then export PATH=$PATH:/opt/riscv/bin; fi
make
You may wish to put the export PATH=$PATH:/opt/riscv/bin in your ./bash.rc file.

Do NOT run make linux if you want riscv64-unknown-elf-gcc files! The linux option creates riscv64-unknown-linux-gnu files, not elf!.

My first attempt at install failed. After hours of downloading and building, the errors started here (and yes, I also incorrectly specified linux):

mv -f /mnt/c/workspace/riscv-gnu-toolchain/build-glibc-linux-rv64imafdc-lp64d/elf/rtld-libc.aT /mnt/c/workspace/riscv-gnu-toolchain/build-glibc-linux-rv64imafdc-lp64d/elf/rtld-libc.a
make[4]: Leaving directory '/mnt/c/workspace/riscv-gnu-toolchain/riscv-glibc/elf'
riscv64-unknown-linux-gnu-gcc    -nostdlib -nostartfiles -r -o /mnt/c/workspace/riscv-gnu-toolchain/build-glibc-linux-rv64imafdc-lp64d/elf/librtld.os '-Wl,-(' /mnt/c/workspace/riscv-gnu-toolchain/build-glibc-linux-rv64imafdc-lp64d/elf/dl-allobjs.os /mnt/c/workspace/riscv-gnu-toolchain/build-glibc-linux-rv64imafdc-lp64d/elf/rtld-libc.a -lgcc '-Wl,-)' \
          -Wl,-Map,/mnt/c/workspace/riscv-gnu-toolchain/build-glibc-linux-rv64imafdc-lp64d/elf/librtld.os.map
riscv64-unknown-linux-gnu-gcc    -nostdlib -nostartfiles -shared -o /mnt/c/workspace/riscv-gnu-toolchain/build-glibc-linux-rv64imafdc-lp64d/elf/ld.so.new               \
          -Wl,-z,combreloc -Wl,-z,relro -Wl,--hash-style=both -Wl,-z,defs       \
          /mnt/c/workspace/riscv-gnu-toolchain/build-glibc-linux-rv64imafdc-lp64d/elf/librtld.os -Wl,--version-script=/mnt/c/workspace/riscv-gnu-toolchain/build-glibc-linux-rv64imafdc-lp64d/ld.map            \
          -Wl,-soname=ld-linux-riscv64-lp64d.so.1                       \
          -Wl,-defsym=_begin=0
/opt/riscv/lib/gcc/riscv64-unknown-linux-gnu/9.2.0/../../../../riscv64-unknown-linux-gnu/bin/ld: /mnt/c/workspace/riscv-gnu-toolchain/build-glibc-linux-rv64imafdc-lp64d/elf/librtld.os: in function `process_envvars':
/mnt/c/workspace/riscv-gnu-toolchain/riscv-glibc/elf/rtld.c:2484: undefined reference to `__GI___open64_nocancel'
/opt/riscv/lib/gcc/riscv64-unknown-linux-gnu/9.2.0/../../../../riscv64-unknown-linux-gnu/bin/ld: /mnt/c/workspace/riscv-gnu-toolchain/build-glibc-linux-rv64imafdc-lp64d/elf/librtld.os: in function `dl_main':
/mnt/c/workspace/riscv-gnu-toolchain/riscv-glibc/elf/rtld.c:1317: undefined reference to `__access'
/opt/riscv/lib/gcc/riscv64-unknown-linux-gnu/9.2.0/../../../../riscv64-unknown-linux-gnu/bin/ld: /mnt/c/workspace/riscv-gnu-toolchain/riscv-glibc/elf/rtld.c:2103: undefined reference to `__access'
/opt/riscv/lib/gcc/riscv64-unknown-linux-gnu/9.2.0/../../../../riscv64-unknown-linux-gnu/bin/ld: /mnt/c/workspace/riscv-gnu-toolchain/riscv-glibc/elf/rtld.c:1564: undefined reference to `__GI___close_nocancel'
and eventually culminated here:

/opt/riscv/lib/gcc/riscv64-unknown-linux-gnu/9.2.0/../../../../riscv64-unknown-linux-gnu/bin/ld: final link failed: bad value
collect2: error: ld returned 1 exit status
Makefile:496: recipe for target '/mnt/c/workspace/riscv-gnu-toolchain/build-glibc-linux-rv64imafdc-lp64d/elf/ld.so' failed
make[3]: *** [/mnt/c/workspace/riscv-gnu-toolchain/build-glibc-linux-rv64imafdc-lp64d/elf/ld.so] Error 1
make[3]: Leaving directory '/mnt/c/workspace/riscv-gnu-toolchain/riscv-glibc/elf'
Makefile:258: recipe for target 'elf/subdir_lib' failed
make[2]: *** [elf/subdir_lib] Error 2
make[2]: Leaving directory '/mnt/c/workspace/riscv-gnu-toolchain/riscv-glibc'
Makefile:9: recipe for target 'all' failed
make[1]: *** [all] Error 2
make[1]: Leaving directory '/mnt/c/workspace/riscv-gnu-toolchain/build-glibc-linux-rv64imafdc-lp64d'
Makefile:234: recipe for target 'stamps/build-glibc-linux-rv64imafdc-lp64d' failed
make: *** [stamps/build-glibc-linux-rv64imafdc-lp64d] Error 2
I was about to open a GitHub issue, and then thought - hm... perhaps I just read the rest of the README, eh? I know, I know, actually RTFM'ing takes away all the fun, but it is rather embarrassing when someone tells you to read the fine manual in response to asking for help. Sure enough, I found this:
If building a linux toolchain on a MacOS system, or on a Windows system using the Linux subsystem or cygwin, you must ensure that the filesystem is case-sensitive. A build on a case-insensitive filesystem will fail when building glibc because *.os and *.oS files will clobber each other during the build eventually resulting in confusing link errors. @tnt aka smunaut has a RISC-V USB project in the works.
In order to install RISC-V for WSL I found this article that noted after Windows 10 version 17093 there's a command fsutil.exe for setting case sensitivity:

fsutil.exe file setCaseSensitiveInfo riscv-gnu-toolchain enable

Note this needs to be run in a DOS Window, not WSL, and with Administrative permissions:


BUT! Note the command is only for the specified directory, and the attribute is NOT inherited  (and certainly does not get applied to each existing sub-directory). So we need to iterate through all sub-directories individually. Yes, I'm sure many readers are rolling their eyes at this point, asking why I am doing this in WSL and not a "real" Linux machine or even a VM; what am I doing in Windows? I ask myself that sometimes, too. Well, I just think WSL is just too cool! Plus, I suppose that I like the challenge. So anyway, here's what I did to set case sensitivity:

cd \workspace\riscv-gnu-toolchain\
for /f %f in ('dir /ad /s /b') do fsutil.exe file setCaseSensitiveInfo %f enable
There are many directories. Be patient...

As a reminder, that command is meant to be executed interactively. If placed into a batch file, the percent symbols need to be doubled up.

Now that everything in the riscv-gnu-toolchain directory is case sensitive, I ran make again:

cd /mnt/c/workspace/riscv-gnu-toolchain
make
This does a full rebuild, taking again a very long time. Did I mention being patient?

If you can run /opt/riscv/bin/riscv64-unknown-elf-gcc --version but see a lot of errors when doing a make BOARD=fomu like:
/opt/riscv/lib/gcc/riscv64-unknown-elf/9.2.0/include/stdint.h:9:16: fatal error: stdint.h: No such file or directory
That means the RISC-V make either failed... or you didn't wait until it finished. (for me, it was the latter; did I mention being patient?) Once the RISC-V make is complete, the FOMU code can be built:
cd /mnt/c/workspace/circuitpython/ports/litex
make BOARD=FOMU

Which resulted in this output:

$ make BOARD=FOMU
Use make V=1, make V=2 or set BUILD_VERBOSE similarly in your environment to increase build verbosity.
QSTR updated
make: msgfmt: Command not found
../../py/py.mk:338: recipe for target 'build-FOMU/genhdr/en_US.mo' failed
make: *** [build-FOMU/genhdr/en_US.mo] Error 127

so ok, a quick google yields something useful on stackoverflow

apt-get install gettext

and so even after than, I saw even more errors like this:
/opt/riscv/lib/gcc/riscv64-unknown-elf/9.2.0/../../../../riscv64-unknown-elf/bin/ld: build-FOMU/lib/libm/math.o: in function `floorf':
/mnt/c/workspace/circuitpython/ports/litex/../../lib/libm/math.c:790: undefined reference to `__addsf3'
/opt/riscv/lib/gcc/riscv64-unknown-elf/9.2.0/../../../../riscv64-unknown-elf/bin/ld: /mnt/c/workspace/circuitpython/ports/litex/../../lib/libm/math.c:795: undefined reference to `__addsf3'
/opt/riscv/lib/gcc/riscv64-unknown-elf/9.2.0/../../../../riscv64-unknown-elf/bin/ld: build-FOMU/lib/libm/math.o:/mnt/c/workspace/circuitpython/ports/litex/../../lib/libm/math.c:817: more undefined references to `__addsf3' follow
/opt/riscv/lib/gcc/riscv64-unknown-elf/9.2.0/../../../../riscv64-unknown-elf/bin/ld: build-FOMU/firmware.elf(.text): relocation ".L15+0x0 (type R_RISCV_RVC_JUMP)" goes out of range
/opt/riscv/lib/gcc/riscv64-unknown-elf/9.2.0/../../../../riscv64-unknown-elf/bin/ld: /opt/riscv/lib/gcc/riscv64-unknown-elf/9.2.0/libgcc.a(divsf3.o): file class ELFCLASS64 incompatible with ELFCLASS32
/opt/riscv/lib/gcc/riscv64-unknown-elf/9.2.0/../../../../riscv64-unknown-elf/bin/ld: final link failed: file in wrong format
collect2: error: ld returned 1 exit status
Makefile:177: recipe for target 'build-FOMU/firmware.elf' failed
make: *** [build-FOMU/firmware.elf] Error 1
So I did another one of these, this time for the circuitpython directory:

for /f %f in ('dir /ad /s /b') do fsutil.exe file setCaseSensitiveInfo %f enable

and things got even worse:
$ make BOARD=FOMU
Makefile:30: *** Invalid BOARD specified.  Stop.
So I tried to clean it, same error:
$ make BOARD=FOMU clean
Makefile:30: *** Invalid BOARD specified.  Stop.
Turns out that was case sensitive, so then it is:
make BOARD=fomu clean
make BOARD=fomu
Ok, at the point, readers must really, really wonder why I use Windows. I know, I know. But I'm persistent.

It still failed. I gave up and asked for help.
I didn't get an answer to "should I use the FOMU toolchain instead of the RISC-V, so I thought I'd try it:

# fetch and extract
wget https://github.com/im-tomu/fomu-toolchain/releases/download/v1.5.6/fomu-toolchain-linux_x86_64-v1.5.6.tar.gz 
tar -xzf fomu-toolchain-linux_x86_64-v1.5.6.tar.gz
sudo mv fomu-toolchain-linux_x86_64-v1.5.6 /opt/fomu-toolchain-linux_x86_64-v1.5.6

# set the path
if [ "$(echo $PATH | grep fomu-toolchain-linux_x86_64-v1.5.6)" == "" ]; then export PATH=$PATH:/opt/fomu-toolchain-linux_x86_64-v1.5.6/bin; fi

# verify it is in the path:
which riscv64-unknown-elf-gcc
riscv64-unknown-elf-gcc --version

cd /mnt/c/workspace/circuitpython/ports/litex
make BOARD=fomu  clean

And... TADA! A successful Circuit Python build for the FPGA FOMU!! Whew.

gojimmypi:/mnt/c/workspace/circuitpython/ports/litex
$ make BOARD=fomu
Use make V=1, make V=2 or set BUILD_VERBOSE similarly in your environment to increase build verbosity.
/opt/fomu-toolchain-linux_x86_64-v1.5.6/bin/../lib/gcc/riscv64-unknown-elf/8.3.0/../../../../riscv64-unknown-elf/bin/ld: warning: section `.bss' type changed to PROGBITS

739752 bytes free in flash firmware space out of 1048576 bytes (1024.0kB).
116920 bytes free in ram for stack and heap out of 131072 bytes (128.0kB).

Create build-fomu/firmware.dfu
python3 ../../tools/dfu.py -b build-fomu/firmware.bin -D 0x1209:0x5bf0 "build-fomu/firmware.dfu"

Other notes (thanks @pdp7): Using Python for creating hardware

Migen Step by Step Tutorial

LiteX is a fork of MiSoC

MiSoc and LiteX are both based on Migen


Sunday, March 8, 2020

RISC-V Circuit Python on ULX3S starting with the Hacker FOMU as an example

Some notes on setting up a soft RISC-V CPU to run Circuit Python.

I started with the ambitious idea of wanting Circuit Python to work on the Radiona ULX3S. Easily said...

Really short TL;DR this ended up being mostly a blog about the (mysteries and difficulties of installing) toolchain. See this to get started.

TL;DR; Circuit Python is a "C" app that needs a CPU to run on. The Feather M0 is an ARM processor option known to work well with Circuit Python.  We'll need to configure the ECP5 FPGA to be a soft CPU on the ULX3S, as Circuit Python no longer supports the current ESP32 as of version 4, but the ESP32-S2 will be supportedFomu is an FPGA that's had some work towards Circuit Python. There are multiple Fomu versions. Need to first install foboot. Then the rxrbln fork of Claire Wolf's RISC-V toolchain for the ULX3S ECP5. Note make -j$(nproc) build-tools installs all 4 toolchains, when we probably only want riscv32i. There's an open Adafruit issue regarding Fomu port of CircuitPython #2604. Be careful using a hub. Install FPGA toolchain; see this gist and this repo. Note that 4GB is now the minimum RAM to build prjtrellis, 5GB to build nextpnr-ecp5, and at least 30GB disk.

First, I'd like to extend my thanks to Tim "mithro" Ansell for giving me a pair of Hacker Fomu's at Hackaday 2019. I'm so glad I had a chance to meet him. What an awesome guy!

Many of my notes here are quite similar to my previous, multi-part post on setting up a RISC-V on the tinyFPGA-BX.  See also Luke's picosoc example code here.

There are multiple FOMU versions. My FOMU that I received from Tim looks like this and is the hacker version, using the bash command export FOMU_REV=hacker:



The Adafruit FOMU (#4332) is the production version:


I started following along the timvideos getting started but didn't have a lot of success.

The tutorial references and links to foboot 1.8.1 (evt-installable.dfu) I eventually noticed in the list of releases and a note that the Hacker version did not have support until Version 1.8.8. Of course it didn't. No fun if it's too easy. :)



I also ordered an even more robust, known-good CircuitPython board, the Adafruit Feather M0 Express. This started me down yet another rabbit hole (specifically this) as the fomu didn't play well when sharing a USB hub.

Also - in my case, for some reason the Ubuntu VM no longer had an IP address after rebooting the host. Apparently others have had the same problem. Indeed I needed to add this to my /etc/network/interfaces after confirming ens33 was the name of my network adapter with the ip address command. Nothing is ever as easy as it is supposed to be. The fun never stops! ;)


# The primary network interface
auto ens33
iface ens33 inet dhcp
confirm that ens33 is the proper device.

Update: it seems that Ubuntu only "forgets" the IP address assignment if the VM is paused. During reboots or initial install - the network interface works properly with no edits to the interface file.

Oh - and more that the default 20GB disk space is needed (40GB is safe, but perhaps as little as 35GB) if doing this in a VM. Ubuntu does not automatically recognize a bigger disk after it has been expanded, so gparted needs to be installed as explained on stackexchange. Simply right-click and select "Resize/Move". Be sure to click on the little green check mark to apply changes.


cd ~

# does dfu-util work?
dfu-util -l

# if "Cannot open DFU device 1209:5bf0" try sudo
sudo dfu-util -l

# can't find dfu-util with sudo?
whereis dfu-util

# here we go
sudo /home/gojimmypi/ecp5-toolchain-linux_x86_64-v1.6.2/bin/dfu-util -l

# upgrade foumu
cd workspace
mkdir fomu
cd fomu
wget https://github.com/im-tomu/foboot/raw/master/releases/v1.8.1/evt-installable.dfu
sudo /home/gojimmypi/ecp5-toolchain-linux_x86_64-v1.6.2/bin/dfu-util -D evt-installable.dfu

If successful, should give output like this:

dfu-util 0.9

Copyright 2005-2009 Weston Schmidt, Harald Welte and OpenMoko Inc.
Copyright 2010-2019 Tormod Volden and Stefan Schmidt
This program is Free Software and has ABSOLUTELY NO WARRANTY
Please report bugs to http://sourceforge.net/p/dfu-util/tickets/

Match vendor ID from file: 1209
Match product ID from file: 5bf0
Opening DFU capable USB device...
ID 1209:5bf0
Run-time device DFU version 0101
Claiming USB DFU Interface...
Setting Alternate Setting #0 ...
Determining device status: state = dfuIDLE, status = 0
dfuIDLE, continuing
DFU mode device DFU version 0101
Device returned transfer size 1024
Copying data from PC to DFU device
Download [=========================] 100%       106814 bytes
Download done.
state(7) = dfuMANIFEST, status(0) = No error condition is present
state(8) = dfuMANIFEST-WAIT-RESET, status(0) = No error condition is present
Done!

To more gracefully setup permissions see the fomu docs. Basically:
# add this line to /etc/udev/rules.d/99-fomu.rules
SUBSYSTEM=="usb", ATTRS{idVendor}=="1209", ATTRS{idProduct}=="5bf0", MODE="0664", GROUP="plugdev"

And then:

sudo groupadd plugdev
sudo usermod -a -G plugdev $USER
id $USER
sudo udevadm control --reload-rules
sudo udevadm trigger

# logoff then back on


Next, we want to have the rxrbln ULX3S version of PicoRV32:
# on a completely new system:
THISRISCV=riscv32i
THIS_RISCV_PATH=/opt/$THISRISCV/bin
MIN_ULX3S_MEMORY=5050000

if [ $(free | grep Mem | awk '{ print $2 }') -lt $MIN_ULX3S_MEMORY ]; then
  echo ""
  echo "System memory found:"
  free
  echo ""
  read -p "Warning, at least $MIN_ULX3S_MEMORY bytes of memory is needed. Press$
fi


sudo apt-get update --assume-yes 
sudo apt-get upgrade --assume-yes
sudo apt-get install git --assume-yes

cd ~
mkdir -p ~/workspace
cd workspace

git clone https://github.com/rxrbln/picorv32.git

cd picorv32

sudo apt-get install make        --assume-yes
sudo apt-get install make-guile  --assume-yes
sudo apt-get install libgmp3-dev --assume-yes
sudo apt-get install libmpfr-dev --assume-yes
sudo apt-get install libmpc-dev  --assume-yes

sudo apt-get install autoconf automake autotools-dev curl libmpc-dev \
        libmpfr-dev libgmp-dev gawk build-essential bison flex texinfo \
    gperf libtool patchutils bc zlib1g-dev git libexpat1-dev --assume-yes


make download-tools

# install *all four* riscv flavor toolchains:
# make -j$(nproc) build-tools

# or install only riscv32i:
sudo mkdir /opt/riscv32i
sudo chown $USER /opt/riscv32i

git clone https://github.com/riscv/riscv-gnu-toolchain riscv-gnu-toolchain-rv32i
cd riscv-gnu-toolchain-rv32i
git checkout 411d134

# if you see fatal: clone of 'git://  ... 
# users sitting behind a firewall may need these:
git config --global url.https://github.com/.insteadOf git://github.com/
git config --global url.https://git.qemu.org/git/.insteadOf git://git.qemu-project.org/
git config --global url.https://anongit.freedesktop.org/git/.insteadOf git://anongit.freedesktop.org/
git config --global url.https://github.com/riscv.insteadOf git://github.com/riscv

# this next statement takes a long time. be patient:
git submodule update --init --recursive

mkdir build; cd build
../configure --with-arch=rv32i --prefix=/opt/riscv32i
make -j$(nproc)

# see if it is working:
/opt/riscv32i/bin/riscv32-unknown-elf-gcc --version

# add to path
if [ "$(cat ~/.bashrc | grep  $THIS_RISCV_PATH)" == "" ]; then
  echo PATH=$PATH:$THIS_RISCV_PATH >> ~/.bashrc
  echo "~/.bashrc updated with this line:"
  echo PATH=$PATH:$THIS_RISCV_PATH
else
  echo "Found $THIS_RISCV_PATH in ~/.bashrc - path not changed."
fi

if [ "$(echo $PATH | grep  $THIS_RISCV_PATH)" == "" ]; then
  export PATH=$PATH:$THIS_RISCV_PATH
  echo "Updated current path: $PATH"
else
  echo "Path not updated. PATH=$PATH"
fi

cd ~/workspace
git clone https://gist.github.com/gojimmypi/f96cd86b2b8595b4cf3be4baf493c5a7 ulx3s_fpga_toolchain
cd ulx3s_fpga_toolchain
chmod +x ULX3S_WSL_Toolchain.sh
./ULX3S_WSL_Toolchain.sh



Run scripts with the source command if you don't want to start a new shell, or manually set path. You may wish to put this line at the end of your ~/.bashrc file:
#add path to riscv32i compiler
PATH=/opt/riscv32i/bin:$PATH

Once the RISC-V toolchain is installed, there's some sample code in the picosoc directory. Fortunately rxrbln has already made some modifications in the Makefile for the ULX3S. The C code is compiled with:

make ulx3s_fw.img


To upload the code to the ULX3S:

make ulx3sprog


Note from the Makefile there are 2 key steps: #1 to put the ulx3s.bit soft CPU onto the FPGA, then #2 put the firmware into FLASH memory:
/usr/src/f32c-ujprog/ujprog/ujprog -j FLASH -f 0x200000 ulx3s_fw.img
/usr/src/f32c-ujprog/ujprog/ujprog -t ulx3s.bit # -j FLASH 


The default install directory for ujprog is /usr/local/bin/ujprog however the rxrbln Makefile expects it to be /usr/src/f32c-ujprog/ujprog/ujprog
so we'll just create a quick symlink
sudo mkdir -p /usr/src/f32c-ujprog/ujprog/
sudo ln -s /usr/local/bin/ujprog /usr/src/f32c-ujprog/ujprog/ujprog
yosys/nextpnr/ https://gist.github.com/gojimmypi/243fc3a6eead72ae3db8fd32f2567c96


In the end, I put together a full ULX3S toolchain installer. Next blog I go into details of actually getting the soft CPU and RISC-V code onto the ULX3S.


Other stuff:

TODO - do we really want a 2+ year old RV32I toolchain? (note git checkout 411d134)



 * https://workshop.fomu.im/en/latest/

See also:

A cobbled-together profiler for CircuitPython.

Find gojimmypi at gojimmypi.github.io

I'm currently working on my new blog home at  gojimmypi.github.io After implementing a variety of features such as dark mode , syntax hi...