具体步骤

最近得到一块正点原子达芬奇Pro FPGA板,想不到能干啥,网上找了个教程能直接构建板子对应的riscv核心工程,也有配套的工具链,所以就尝试了一下。

1. 环境

  • WSL2 Ubuntu 24.04
  • Python 虚拟环境:python3.12
  • 依赖:sbt、dtc、build-essential、dosfstools、device-tree-compiler

1.1 安装系统依赖

sudo apt update
sudo apt install -y build-essential git wget cpio unzip rsync bc libssl-dev \
                    device-tree-compiler dosfstools openocd
# sbt 用于编译 VexRiscv SMP 网表
echo "deb https://repo.scala-sbt.org/scalasbt/debian all main" | sudo tee /etc/apt/sources.list.d/sbt.list
curl -sL "https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x2EE0EA64E40A89B84B2DF73499E82A75642AC823" | sudo apt-key add
sudo apt update && sudo apt install -y sbt

1.2 创建 Python 虚拟环境

sudo apt install -y python3-venv python3-pip
python3 -m venv ~/litex/.venv
source ~/litex/.venv/bin/activate
pip install --upgrade pip

1.3 安装 LiteX 及子模块

wget https://raw.githubusercontent.com/enjoy-digital/litex/master/litex_setup.py
chmod +x litex_setup.py
./litex_setup.py --init --install --user --config=full

1.4 验证安装

source ~/litex/.venv/bin/activate
python -c "import litex, migen, litedram, litesdcard; print('LiteX OK')"
python -m litex_boards.targets.alientek_davincipro --help

2. 添加 a7-200 板卡变体

由于项目中只适配了 a7-35与a7-100两个板卡,所以需要手动添加我手上的 a7-200 板卡。

2.1 修改 platform

文件:litex-boards/litex_boards/platforms/alientek_davincipro.py

assert variant in ["a7-35", "a7-100", "a7-200"]
kgates  = variant.split("-")[-1]
package = "fbg" if kgates == "200" else "fgg"
Xilinx7SeriesPlatform.__init__(self, f"xc7a{kgates}t{package}484-2", ...)

2.2 修改 target

文件:litex-boards/litex_boards/targets/alientek_davincipro.py

parser.add_target_argument("--variant", default="a7-35",
                           help="Board variant (a7-35, a7-100 or a7-200).")

3. 生成 8 核 SMP SoC

3.1 克隆 linux-on-litex-vexriscv

cd ~/litex
git clone --depth 1 https://github.com/litex-hub/linux-on-litex-vexriscv.git

3.2 添加板卡条目

文件:linux-on-litex-vexriscv/boards.py

class Alientek_davincipro(Board):
    soc_kwargs = {"variant": "a7-200"}
    def __init__(self):
        from litex_boards.targets import alientek_davincipro
        Board.__init__(self, alientek_davincipro.BaseSoC, soc_capabilities={
            "serial",
            "sdcard",
            "leds",
            "buttons",
        })

3.3 生成 SoC

cd ~/litex/linux-on-litex-vexriscv
source ~/litex/.venv/bin/activate
python3 make.py --board alientek_davincipro --cpu-count 8

产物:build/alientek_davincipro/

4. 编译 Linux 镜像

cd ~/litex
git clone --depth 1 --branch 2025.02 https://github.com/buildroot/buildroot.git
cd buildroot
export PATH=$(echo "$PATH" | tr ':' '\n' | grep -v '^/mnt/' | paste -sd:)
make BR2_EXTERNAL=../linux-on-litex-vexriscv/buildroot/ \
     BR2_DEFCONFIG=../linux-on-litex-vexriscv/build/alientek_davincipro/buildroot_defconfig \
     litex_vexriscv_defconfig
make -j$(nproc)

产物:output/images/ 下的 Image、rootfs.cpio.gz、fw_jump.bin

5. 组装启动文件

cd ~/litex/linux-on-litex-vexriscv/build/alientek_davincipro
mkdir -p images
cp ../../buildroot/output/images/Image images/
cp ../../buildroot/output/images/rootfs.cpio.gz images/
cp ../../buildroot/output/images/fw_jump.bin images/opensbi.bin
cp alientek_davincipro.dtb images/rv32.dtb
cp ../../images/boot.json images/

6. 修复 Vivado 工程路径

这一步是为了修复 Vivado 工程路径,我使用WSL生成工程,在windows上运行vivado,原本的绝对路径无法正常工作,这一步会修改为相对路径。

cd ~/litex/linux-on-litex-vexriscv/build/alientek_davincipro/gateware
sed -i 's|read_verilog {/home/yori/litex/pythondata-cpu-vexriscv-smp/pythondata_cpu_vexriscv_smp/verilog/Ram_1w_1rs_Generic.v}|read_verilog {Ram_1w_1rs_Generic.v}|' alientek_davincipro.tcl
sed -i 's|read_verilog {/home/yori/litex/linux-on-litex-vexriscv/build/alientek_davincipro/gateware/|read_verilog {|' alientek_davincipro.tcl
cp /home/yori/litex/pythondata-cpu-vexriscv-smp/pythondata_cpu_vexriscv_smp/verilog/Ram_1w_1rs_Generic.v .

7. 生成比特流

将 gateware/ 目录拷到 Windows,Vivado Tcl Console:

cd {D:/path/to/gateware}
source alientek_davincipro.tcl

综合实现后用 Hardware Manager 烧入 alientek_davincipro.bit。

8. 制作 SD 卡

注意:WSL想要连接USB设备,需要先安装 usbipd 包。

winget install --interactive --exact dorssel.usbipd-win

在 Windows 上插入 SD 卡后,先在power shell中执行:

查找id

usbipd list

接入wsl

usbipd bind --busid 3-4 --force # 绑定设备,本样例为 3-4
usbipd attach --wsl --busid 3-4

断开wsl连接

usbipd detach --busid 3-4
usbipd unbind --busid 3-4

8.1 格式化

lsblk -o NAME,SIZE,TYPE,FSTYPE,MODEL   # 确认设备,本例 /dev/sde
sudo umount /dev/sde1
sudo wipefs -a /dev/sde
sudo dd if=/dev/zero of=/dev/sde bs=1M count=10
printf 'o\nn\np\n1\n\n\nt\nc\na\nw\n' | sudo fdisk /dev/sde
sudo mkfs.vfat -F 32 -n LITEXBOOT /dev/sde1

8.2 拷贝启动文件

sudo mount /dev/sde1 /mnt/sdboot
sudo cp ~/litex/linux-on-litex-vexriscv/build/alientek_davincipro/images/{Image,rootfs.cpio.gz,opensbi.bin,rv32.dtb,boot.json} /mnt/sdboot/
sync && sudo umount /mnt/sdboot

9. 上板启动

BIOS 提示符输入(默认会自动启动 SD 卡中的启动文件):

sdcardboot

登录:用户名 root,无密码。

提示

提示: 若出现各类FAT32问题,基本都是SD卡格式化或文件问题,请检查SD卡是否正确格式化并写入文件。

10. 验证 8 核

cat /proc/cpuinfo
nproc
cat /proc/interrupts

绑核压测:

for i in 0 1 2 3 4 5 6 7; do
    taskset -c $i sh -c 'while true; do :; done' &
done
cat /proc/loadavg
cat /proc/stat | grep '^cpu[0-7]'
kill $(jobs -p)

11. 运行自定义程序

编译:

litex/buildroot/output/host/bin/riscv32-buildroot-linux-gnu-gcc -static hello.c -o hello

拷到 SD 卡并执行:

mount -t vfat /dev/mmcblk0p1 /mnt
cp /mnt/hello /tmp/
/tmp/hello