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:
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:
When doing the
git clone https://github.com/adafruit/circuitpython.git cd circuitpython git submodule sync git submodule update --init make -C mpy-cross
git submodule update --initin 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:
When doing the
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
git submodule update --initfrom 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
Edit: note that a case insensitive directory setting may allow
cd ./ports/litex make BOARD=fomu
BOARD=FOMUto work. ymmv. The safest one to use is a lower-case:
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'
riscv64-unknown-elf-gcc --versionto 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:
You may wish to put the
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
export PATH=$PATH:/opt/riscv/binin your
Do NOT run
make linuxif you want
riscv64-unknown-linux-gnufiles, not elf!.
My first attempt at install failed. After hours of downloading and building, the errors started here (and yes, I also incorrectly specified
and eventually culminated here:
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: 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'
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 :
/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: *** [/mnt/c/workspace/riscv-gnu-toolchain/build-glibc-linux-rv64imafdc-lp64d/elf/ld.so] Error 1 make: Leaving directory '/mnt/c/workspace/riscv-gnu-toolchain/riscv-glibc/elf' Makefile:258: recipe for target 'elf/subdir_lib' failed make: *** [elf/subdir_lib] Error 2 make: Leaving directory '/mnt/c/workspace/riscv-gnu-toolchain/riscv-glibc' Makefile:9: recipe for target 'all' failed make: *** [all] Error 2 make: 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
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:
There are many directories. Be patient...
cd \workspace\riscv-gnu-toolchain\ for /f %f in ('dir /ad /s /b') do fsutil.exe file setCaseSensitiveInfo %f enable
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:
This does a full rebuild, taking again a very long time. Did I mention being patient?
cd /mnt/c/workspace/riscv-gnu-toolchain make
If you can run
/opt/riscv/bin/riscv64-unknown-elf-gcc --versionbut see a lot of errors when doing a
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:
/opt/riscv/lib/gcc/riscv64-unknown-elf/9.2.0/include/stdint.h:9:16: fatal error: stdint.h: No such file or directory
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:
So I did another one of these, this time for the circuitpython directory:
/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
for /f %f in ('dir /ad /s /b') do fsutil.exe file setCaseSensitiveInfo %f enable
and things got even worse:
So I tried to clean it, same error:
$ make BOARD=FOMU Makefile:30: *** Invalid BOARD specified. Stop.
Turns out that was case sensitive, so then it is:
$ make BOARD=FOMU clean Makefile:30: *** Invalid BOARD specified. Stop.
Ok, at the point, readers must really, really wonder why I use Windows. I know, I know. But I'm persistent.
make BOARD=fomu clean make BOARD=fomu
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:
And... TADA! A successful Circuit Python build for the FPGA FOMU!! Whew.
# 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
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
Copyright (c) gojimmypi all rights reserved. Blogger Image Move Cleaned: 5/3/2021 1:35:54 PM