Skip to content

Instantly share code, notes, and snippets.

@federunco
Last active December 2, 2025 09:49
Show Gist options
  • Select an option

  • Save federunco/f2bde2e25342c6284b68ce4ecf305e5d to your computer and use it in GitHub Desktop.

Select an option

Save federunco/f2bde2e25342c6284b68ce4ecf305e5d to your computer and use it in GitHub Desktop.

Running Quartus + Questa on Apple Silicon

The current methods to run an Intel FPGA workflow on Apple Silicon involve two possibile approaches:

  • Using a WoA Virtual Machine: Performance is terrible (already in amd64 Windows platforms is terrible, adding two virtualization layers on top of it leads to eternal compilation times) + space wasted for all the Microsoft bloatware
  • Using a Docker Container: Performance is better than WoA, but the USB drivers are not working

Running Linux on UTM with Rosetta enabled should tackle these problems

Disclaimer for Baremetal installation

This guide could possibly work also when installing Debian directly on the Mac with Asahi Linux, but it is not recommended for beginners: with the standard installation procedure the Linux Kernel uses a default page size of 16K, and the rosetta binary is not designed to run with this page size. By recompiling the Linux Kernel to use 4K page sizes it should work flawlessly, but expect slower perfomance and/or higher power usage on the overall system. Easier methods exist when using Asahi (especially the Fedora Remix), such as FEX-Emu, but I don't have tested them personally.

Configuring the virtual machine

Enabling persistent Rosetta 2 on Linux Guest

  • Install support for binfmt utils:
sudo apt install binfmt-support
  • Create the directory /opt/rosetta
  • Create a new service file for the Rosetta service on /etc/systemd/system/rosetta.service:
[Unit]
Description=Enable Rosetta 2 Translation Layer

[Service]
Type=oneshot
ExecStart=/bin/sh /opt/rosetta/rosetta_start.sh

[Install]
WantedBy=multi-user.target
  • Enable the Rosetta service on boot:
systemctl enable rosetta.service

Depending on whether you choose using AVF or QEMU, the setup of Rosetta slightly changes:

Apple Virtualization Framework

  • Create the required directory for the Rosetta mount:
sudo mkdir /media/rosetta
  • Create /opt/rosetta/rosetta_start.sh and copy the following script:
#!/bin/sh
sudo mount -t virtiofs rosetta /media/rosetta
sudo /usr/sbin/update-binfmts --install rosetta /media/rosetta/rosetta \
     --magic "\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x3e\x00" \
     --mask "\xff\xff\xff\xff\xff\xfe\xfe\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff" \
     --credentials yes --preserve yes --fix-binary yes
  • Reboot the virtual machine

QEMU

  • On your macOS Host, run:
softwareupdate --install-rosetta --agree-to-license
grep RosettaUpdateAuto.pkg /var/log/install.log

From the last command, you should get where the latest install package for Rosetta has been downloaded.

  • cd to a known directory, and extract the install package:
pkgutil --expand-full /Library/Updates/Rosetta/SoftwareUpdate/RosettaUpdateAuto.pkg ./Rosetta
cd ./Rosetta/RosettaUpdateAuto.pkg/Payload/Library/Apple/usr/libexec/oah/RosettaLinux
  • Patch with radare2 the rosetta binary by following this guide
  • Copy the patched rosetta binary with scp to your guest VM in /opt/rosetta/rosetta
  • Create /opt/rosetta/rosetta_start.sh and copy the following script:
#!/bin/sh
sudo /usr/sbin/update-binfmts --install rosetta /opt/rosetta/rosetta \
     --magic "\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x3e\x00" \
     --mask "\xff\xff\xff\xff\xff\xfe\xfe\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff" \
     --credentials yes --preserve yes --fix-binary yes
  • Reboot the virtual machine

Installing dependencies

  • Enable multiarch repos
sudo dpkg --add-architecture amd64
  • Install the required libraries for Quartus
sudo apt update
sudo apt install libbz2-1.0:amd64 libglib2.0-0:amd64 libnsl-dev:amd64 libfontconfig:amd64 libx11-xcb1:amd64 libxext6:amd64 libsm6:amd64 libdbus-1-3:amd64 libxft2:amd64 libxtst6:amd64 libxi6:amd64 libgtk2.0-0:amd64 libcrypt1:amd64 libgtk-3-0:amd64

These libraries where tested for Quartus 24.1std, if for other versions Quartus crashes (cli outputs aborted (core dumped)), use strace to debug for missing libraries

Installing and patching Quartus

The installation script for Quartus checks if SSE3 instruction are supported on the current CPU, the main problem is that this script doesn't run on the Rosetta environment, failing the checks.

Version 24.1std

  • Run the following commands to install Quartus (please note that this is an unattended install of the lite version with only Cyclone V device support enabled, change CLI parameters and/or the wget url to install your desider edition, refer to ./setup.sh --help for the options available). Watch out for the free space on the /tmp directory (newer Debian Systems on default installations assign 1 GB to the /tmp directory)
sudo mkdir /eda
cd /tmp 
wget https://downloads.intel.com/akdlm/software/acdsinst/24.1std/1077/ib_tar/Quartus-lite-24.1std.0.1077-linux.tar
tar xf Quartus-lite-24.1std.0.1077-linux.tar
sudo ./setup.sh --mode unattended --accept_eula 1 --installdir /eda/quartus/24.1std --disable-components quartus_help,arria_lite,cyclone,cyclone10lp,max,max10,riscfree --create_desktop_shortcuts 1
  • Patch the installation:
sudo cp /eda/quartus/24.1std/quartus/adm/qenv.sh /eda/quartus/24.1std/quartus/adm/qenv.sh.bak
sudo sed -i '/# We don'\''t support processors without SSE extensions (e.g. Pentium II and older CPUs)./i\
if test `uname -m` = "aarch64" ; then\
  export QUARTUS_BIT_TYPE=64\
fi
' /eda/quartus/24.1std/quartus/adm/qenv.sh
sudo sed -i '/# We don'\''t support processors without SSE extensions (e.g. Pentium II and older CPUs)./,/##### Determine what bitness executables we should use/ {
    /^[^#]/ s/^/# /
}' "/eda/quartus/24.1std/quartus/adm/qenv.sh"
  • Install the patched sqlite3 library:
wget https://github.com/federunco/federunco/raw/refs/heads/main/libccl_sqlite3.so
sudo cp /eda/quartus/24.1std/quartus/linux64/libccl_sqlite3.so /eda/quartus/24.1std/quartus/linux64/libccl_sqlite3.so.bak
sudo cp libccl_sqlite3.so /eda/quartus/24.1std/quartus/linux64/libccl_sqlite3.so

Other versions (tested for 23.1std)

  • Download the desired version of Quartus (e.g. the Lite edition)
  • Run the Quartus installer with the following arguments: ./qinst-lite-linux-23.1std.1-993.run --confirm
  • When asked to run the installer, DO NOT ENTER ANYTHING, copy the extracted installer located in /tmp in a known directory
  • Select to not run the installer, the script should clean the tmp directory
  • Edit the script located in ./adm/qenv.sh and add the following before the line containing # We don't support processors without SSE extensions (e.g. Pentium II and older CPUs).
if test `uname -m` = "aarch64" ; then
	export QUARTUS_BIT_TYPE=64
fi
  • In the current terminal window, run this command to skip CPU checks during installation: export QUARTUS_CPUID_BYPASS=1
  • Run the installation script, a GUI window should appear (if the installer throws Illegal Instruction, please run it in CLI mode)

After the installation has completed, open the installation directory (should be located in the home directory) and edit ./23.1std/quartus/adm/qenv.sh:

  • Add the following before the line containing # We don't support processors without SSE extensions (e.g. Pentium II and older CPUs).
if test `uname -m` = "aarch64" ; then
	export QUARTUS_BIT_TYPE=64
fi
  • Comment out the lines between # We don't support processors without SSE extensions (e.g. Pentium II and older CPUs). and ##### Determine what bitness executables we should use

Installing the license file

  • Obtain all the required licenses for the current setup from the Self-Service portal
  • Copy the generated license file in a known directory (best to keep it in the same install folder, for example /eda/licenses)
  • Edit .bashrc, adding the following contents at the end of the file (adjust paths accordingly to your configuration:
export LM_LICENSE_FILE='/eda/licenses/[your_license_file].dat' 
export PATH=$PATH:/eda/quartus/24.1std/questa_fse/linux_x86_64/ 
export PATH=$PATH:/eda/quartus/24.1std/quartus/bin/
  • Source .bashrc Now Quartus can be run with the command quartus, while Questa can be run by using vsim on a terminal window.

Post-installation

Reclaim free space on the Virtual Hard Disk

During installation some temporary files might not have been fully removed from the virtual hard disk, resulting in unnecessary disk usage on the host system. The unused space can be reclaimed by running the fstrim command by releasing unallocated blocks:

sudo fstrim / -v

Make USB Blaster work in QEMU Virtual Machine (thanks to @maehne)

  • Create a new rule for UDEV (e.g. /etc/udev/rules.d/51-usb-blaster.rules) and paste the following contents:
# USB-Blaster
SUBSYSTEM=="usb", ATTRS{idVendor}=="09fb", ATTRS{idProduct}=="6001", MODE="0660", TAG+="uaccess"
SUBSYSTEM=="usb", ATTRS{idVendor}=="09fb", ATTRS{idProduct}=="6002", MODE="0660", TAG+="uaccess"
SUBSYSTEM=="usb", ATTRS{idVendor}=="09fb", ATTRS{idProduct}=="6003", MODE="0660", TAG+="uaccess"

# USB-Blaster II
SUBSYSTEM=="usb", ATTRS{idVendor}=="09fb", ATTRS{idProduct}=="6010", MODE="0660", TAG+="uaccess"
SUBSYSTEM=="usb", ATTRS{idVendor}=="09fb", ATTRS{idProduct}=="6810", MODE="0660", TAG+="uaccess"
  • Reload all UDEV rules immediately:
sudo udevadm control --reload-rules
sudo udevadm trigger

If during flashing the Programmer hangs, kill the jtag daemon with sudo killall jtagd and reconnect the USB cable to the machine.

Benchmarks

The same project was compiled on different machines with the same Fitter Seed (pipelined SystemVerilog FIR Filter, Cyclone V, 50 MHz clock constraint), obtaining the following compilation times:

  • Windows Server on i7 10th Gen: 10min 3s
  • Macbook Air M2 - WoA on UTM: 17min 14s
  • Macbook Air M2 - Docker: 8min 10s
  • Macbook Air M2 - Debian + Rosetta: 6min 43s
@maehne
Copy link

maehne commented Sep 17, 2025

Glad that I could help.

Also, consider ammending your comment about setting preserve to -off, I think you meant yes on MacOS > 13

Thanks for the pointer to this typo. I fixed it above.

@maehne
Copy link

maehne commented Sep 17, 2025

Edit: potentially something to do with libudev: https://hackaday.io/project/123606-clone-buino-dual/log/145420-beware-of-quartus-jtag-programmer-on-linux

It seems jtagd (at least from Quartus Prime Std lite 24.1) tries to load either libudev.so.0 or libudev.so.1. So, this would require more testing by people affected by this issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment