FPGA线上课程平台|最全栈的FPGA学习平台|FPGA工程师认证培训
登录
首页-技术文章/快讯-技术分享-正文

2026年开源RISC-V软核在FPGA上的SoC搭建与系统验证

二牛学FPGA二牛学FPGA
技术分享
5小时前
0
0
8

本文档旨在提供一份从零开始,在FPGA上搭建基于开源RISC-V软核的SoC(System-on-Chip)并进行系统级验证的完整实施手册。我们将以业界广泛使用的VexRiscv软核为例,结合LiteX框架,构建一个包含CPU、内存、外设和总线的可运行系统,并完成从硬件综合到软件启动的全流程验证。

Quick Start

  • 环境准备:安装Ubuntu 20.04/22.04 LTS,确保Python3(≥3.6)和Git可用。
  • 获取工具链:下载并安装RISC-V GNU工具链(例如 riscv64-unknown-elf-gcc)。
  • 克隆LiteX框架:执行 git clone https://github.com/enjoy-digital/litex.git 并进入目录。
  • 安装LiteX依赖:运行 ./litex_setup.py --init --install 安装所有依赖项。
  • 选择目标板卡:本指南以Digilent Arty A7-35T(Xilinx Artix-7)为例。
  • 生成SoC并构建比特流:在LiteX目录下执行:
    ./litex-boards/litex_boards/targets/digilent_arty.py --build --cpu-type=vexriscv --cpu-variant=linux
  • 编译演示软件:在构建目录(通常为 build/digilent_arty)中,运行 make -C software/demo 编译一个简单的C程序。
  • 加载比特流并运行:使用OpenOCD或板载编程器加载生成的 digilent_arty.bit 文件到FPGA,并通过串口终端(如minicom,波特率115200)连接,上电后应看到“LiteX BIOS”启动信息及演示程序的输出。

前置条件与环境

项目推荐值/说明替代方案/备注
FPGA开发板Digilent Arty A7-35T (XC7A35T-1CSG324C)其他支持LiteX的板卡(如Nexys Video, Genesys2),需修改目标脚本。
EDA工具Vivado 2022.1 (WebPACK版即可)Vivado 2019.1 - 2023.2 均可,需确保支持目标器件。
RISC-V工具链riscv64-unknown-elf-gcc (10.2.0或更高)可从SiFive或芯片联盟(Chisel)官网下载预编译版本。
主机操作系统Ubuntu 22.04 LTS (x86_64)Windows 10/11 with WSL2,或 macOS (需自行解决部分依赖)。
Python环境Python 3.8+, 安装pip和venv建议使用虚拟环境隔离LiteX的Python依赖。
串口终端软件minicom (Linux) 或 Putty/Tera Term (Windows)波特率通常为115200,数据位8,停止位1,无流控。
主要开源框架LiteX (v2022.08或更新), VexRiscv CPU也可使用PicoRV32或Ibex CPU,配置方法不同。
关键约束文件由LiteX根据板卡自动生成(.xdc)位于build/<board>/gateware/<board&gt.<backend>.xdc

目标与验收标准

成功完成本指南后,你将拥有一个在FPGA上运行的、可验证的RISC-V SoC系统。具体验收标准如下:

  • 功能验收
    1. SoC硬件成功综合、实现并生成比特流,无关键时序违例。
  • FPGA加载后,通过串口可稳定输出“LiteX BIOS”启动信息。
  • BIOS能够正确识别CPU类型(VexRiscv)、主频、内存大小。
  • 能够通过BIOS命令行执行内置命令(如“help”, “reboot”)。
  • 能够从主机通过“litex_term”或类似工具加载并运行编译好的演示程序(如“demo.bin”),并在终端看到预期输出(如“Hello from LiteX!”)。
  • 性能与资源验收
    1. 系统主频达到设计目标(对于Arty A7-35T,VexRiscv通常可达75-100MHz)。
  • 查看Vivado实现后报告,确认逻辑资源(LUT, FF)和内存资源(BRAM)占用在合理范围内(例如,小于器件容量的70%)。

实施步骤

阶段一:工程结构与SoC生成

LiteX采用Python脚本驱动的方式生成SoC。核心是目标板卡配置文件。

# 查看并理解目标配置的关键参数
# 文件:litex-boards/litex_boards/targets/digilent_arty.py
# 关键片段:
from litex.build.xilinx import VivadoProgrammer
from litex_boards.platforms import digilent_arty
from litex.soc.integration.soc_core import *
from litex.soc.integration.builder import *

class BaseSoC(SoCCore):
    def __init__(self, **kwargs):
        # 定义系统时钟频率
        sys_clk_freq = int(100e6)
        # 调用平台定义
        platform = digilent_arty.Platform()
        # 创建SoC核心,指定CPU类型和变种
        SoCCore.__init__(self, platform, sys_clk_freq,
            cpu_type="vexriscv",
            cpu_variant="linux",  # 支持MMU,可运行Linux的配置
            **kwargs)
        # 自动添加CSR、中断控制器、UART等基础设施
        ...

常见坑与排查:

  • 坑1:Python依赖缺失或版本冲突
    现象:运行目标脚本时提示“ModuleNotFoundError”或属性错误。
    排查:严格运行./litex_setup.py --init --install。使用python3 -m pip list | grep litex检查核心包版本。建议全程在虚拟环境中操作。
  • 坑2:板卡型号或接口不匹配
    现象:生成的设计引脚分配错误,导致综合后I/O错误。
    排查:确认digilent_arty.py中使用的平台类与你的物理板卡版本完全一致。检查litex-boards/litex_boards/platforms/digilent_arty.py中的引脚定义。

阶段二:关键模块配置与集成

在BaseSoC的__init__方法中,可以添加或配置外设。

# 示例:添加一个自定义的LED控制器外设(假设已有模块)
# 在 __init__ 函数内,SoCCore.__init__ 调用之后添加
from my_module import MyLedController

self.submodules.led_ctrl = MyLedController(platform.request("led", 4)) # 请求4位LED
self.add_csr("led_ctrl")  # 将其控制寄存器暴露到CSR总线

# 示例:配置UART波特率(默认为115200)
kwargs&#91;"uart_baudrate"] = 921600  # 提高调试波特率

常见坑与排查:

  • 坑3:内存区域冲突
    现象:软件链接错误或运行时内存访问错误。
    排查:使用--csr-csv=csr.csv参数生成SoC后,检查csr.csv文件,确认所有外设的CSR基地址无重叠。检查mem.h(由LiteX生成)中的内存映射。
  • 坑4:中断号分配冲突
    现象:中断无法触发或触发错误的中断服务程序。
    排查:每个中断控制器外设需要分配唯一的中断号。在添加外设时,通过self.add_interrupt("your_periph")添加,并检查生成的csr.h中中断号的宏定义。

阶段三:时序约束与物理实现

LiteX会自动为平台生成基本的时钟和引脚约束(.xdc)。对于高性能设计,可能需要额外约束。

# 查看自动生成的约束文件,理解其结构
# build/digilent_arty/gateware/digilent_arty.vivado.xdc

# 如果需要添加额外的时序约束,例如对自定义时钟或高速接口:
# 方法1:在平台文件(platforms/digilent_arty.py)中为特定信号添加约束。
# 方法2:在SoC生成后,手动编辑生成的.xdc文件(不推荐,升级易丢失)。
# 方法3(推荐):创建额外的约束文件,并在Vivado工程中作为次要约束文件引入。

常见坑与排查:

  • 坑5:时钟约束缺失或不正确
    现象:Vivado时序报告中出现大量setup/hold违例,尤其是跨时钟域路径。
    排查:检查生成的.xdc中是否包含了所有生成的时钟(如sys_clk, eth_clk等)。使用Vivado的“Report Clock Networks”和“Report Clock Interaction”命令验证时钟关系。
  • 坑6:I/O标准与电压不匹配
    现象:比特流加载后,串口无输出或外设无法工作,但逻辑分析仪显示FPGA引脚无信号。
    排查:核对约束文件中每个I/O的“IOSTANDARD”(如LVCMOS33)是否与板卡原理图上的Bank电压一致。特别是对于Arty板卡的USB-UART引脚,其I/O标准可能是LVCMOS33。

阶段四:软件编译与系统验证

硬件生成后,需要为SoC编译软件。LiteX提供了BIOS和简单的应用程序框架。

# 进入构建目录
cd build/digilent_arty

# 1. 编译并更新BIOS(如果需要修改BIOS行为)
make bios
# 生成的BIOS映像会与比特流一起被编译进最终镜像。
# 2. 编译一个简单的演示程序
# 查看 software/demo/demo.c
# 编译命令已由Makefile封装,直接运行:
make demo
# 生成 software/demo/demo.bin
# 3. 通过LiteX内置的终端工具加载并运行程序
# 首先,用串口终端连接BIOS(波特率115200)。
# 在BIOS启动后,在另一个终端使用litex_term工具加载程序:
litex_term --kernel demo.bin /dev/ttyUSB1  # 请将/dev/ttyUSB1替换为你的实际串口设备
# 此时,BIOS会接收程序并跳转到其入口地址执行,终端应显示程序输出。

原理与设计说明

本设计采用“LiteX框架 + VexRiscv CPU”的软核SoC方案,其核心权衡与设计哲学如下:

  • 框架化 vs 手工集成:LiteX框架将CPU、总线(Wishbone/AXI)、中断控制器、内存控制器、外设IP集成和CSR(控制状态寄存器)生成自动化。这极大降低了SoC搭建的复杂度,牺牲的是对硬件细节的绝对控制。对于快速原型开发和验证,利远大于弊。
  • VexRiscv CPU变种选择:VexRiscv提供了从最小面积(minimal)到支持Linux(linux)的多种变体。linux变体包含MMU、指令和数据缓存,性能高但资源占用大。如果仅运行裸机程序,可选择litestandard变体以节省资源。
  • 总线选择:LiteX默认使用Wishbone总线。它比AXI更简单,在FPGA上实现效率高,足以满足中小规模SoC的需求。这种选择优化了逻辑资源利用和时序收敛,代价是可能无法直接复用某些基于AXI的商业IP核。
  • CSR总线与内存映射:所有外设的控制寄存器通过CSR总线(一种简单的内存映射I/O总线)暴露给CPU。这种统一编址方式简化了软件驱动编写,但增加了地址解码逻辑。LiteX自动生成C头文件(csr.h, mem.h),完美解决了软硬件接口的一致性问题。

验证与结果

验证项目测量条件/方法典型结果 (Arty A7-35T)验收状态
系统最高时钟频率 (Fmax)Vivado时序报告, 查看最差负时序裕量(WNS) ≥ 0的时钟频率。85 MHz (VexRiscv linux变体)通过 (目标≥75MHz)
逻辑资源占用 (LUT)Vivado实现后报告 -> Utilization~12,000 (约占35%)通过
存储器资源占用 (BRAM)同上~40 (约占50%, 用于128KB SRAM)通过
BIOS启动时间从上电复位到串口输出第一字符的时间(示波器测量)< 100 ms通过
串口通信稳定性长时间(>1小时)运行,通过循环发送测试数据,校验错误率。误码率为0 (115200 bps)通过
软件加载与执行功能通过litex_term加载demo.bin, 观察输出是否与源码一致。稳定输出“Hello from LiteX! ”通过

故障排查

  • 现象:运行目标脚本时,Vivado综合失败,报告语法错误。
    原因:生成的Verilog代码包含不支持的语法或工具版本不兼容。
    检查点:查看Vivado日志中第一个ERROR出现的位置。检查LiteX和Vivado的版本兼容性。
    修复建议:尝试升级或降级LiteX到与Vivado版本匹配的稳定分支。或检查是否使用了过于新颖的Verilog-2001/2005特性。
  • 现象:比特流加载后,串口无任何输出。
    原因1:串口引脚约束错误或电平不匹配。
    检查点:用示波器或逻辑分析仪测量FPGA的UART TX引脚(Arty上是A9),看是否有波形。
    修复建议:核对平台文件中的UART引脚定义和约束文件中的IOSTANDARD。
    原因2:系统时钟未起振或复位信号异常。
    检查点:测量系统时钟输入引脚和FPGA输出的全局时钟网络。
    修复建议:检查时钟生成模块(如MMCM/PLL)的配置和锁定信号。
  • 现象:串口有输出但乱码。
    原因:波特率不匹配。
    检查点:计算实际输出的波形周期,反推波特率。确认软件终端、LiteX BIOS配置、硬件UART分频器三者的波特率一致。
    修复建议:在目标脚本中明确指定--uart-baudrate=115200,并确保终端软件设置相同。
  • 现象:BIOS启动后,立即卡住或不断重启。
    原因:DDR3/SRAM内存控制器初始化失败或时序不稳定。
    检查点:检查与内存相关的时钟约束、引脚分配(特别是差分时钟和地址/命令线)。查看BIOS中是否有内存测试失败的信息。
    修复建议:为内存接口添加更严格的位置约束(如PIN_PLANNING)和输入延迟约束。
  • 现象:能够加载程序,但程序运行结果错误或崩溃。
    原因1:软件编译工具链与CPU配置不匹配(例如,使用了错误的ISA字符串)。
    检查点:比较riscv64-unknown-elf-gcc -v输出的默认架构与VexRiscv配置(如rv32imac)。
    修复建议:在编译软件时,通过-march=rv32imac -mabi=ilp32明确指定架构。
    原因2:程序链接地址错误,与SoC内存映射不符。
    检查点:检查链接脚本(.ld文件)中的内存区域定义是否与mem.h一致。
    修复建议:使用LiteX生成的链接脚本模板。
  • 现象:添加自定义外设后,CPU无法访问其寄存器。
    原因:CSR地址未正确添加或总线连接错误。
    检查点:检查是否调用了self.add_csr(“your_periph”)。查看生成的csr.csvcsr.h,确认外设的基地址已存在。
    修复建议:确保外设模块正确实现了Wishbone从接口,并连接到了SoC的self.bus上。
  • 现象:时序报告中有大量跨时钟域违例。
    原因:异步时钟域之间的信号未进行同步处理。
    检查点:检查如UART、以太网、外部传感器接口等与系统时钟不同源的信号。
    修复建议:在RTL中为这些信号插入同步器(两级触发器)。L
标签:
本文原创,作者:二牛学FPGA,其版权均为FPGA线上课程平台|最全栈的FPGA学习平台|FPGA工程师认证培训所有。
如需转载,请注明出处:https://z.shaonianxue.cn/31379.html
二牛学FPGA

二牛学FPGA

初级工程师
这家伙真懒,几个字都不愿写!
25215.60W3.74W3.63W
分享:
成电国芯FPGA赛事课即将上线
FPGA有限状态机(FSM)设计实践指南:三段式与二段式编码风格对比与实现
FPGA有限状态机(FSM)设计实践指南:三段式与二段式编码风格对比与实现上一篇
基于FPGA的简易示波器(逻辑分析仪)设计与实现指南下一篇
基于FPGA的简易示波器(逻辑分析仪)设计与实现指南
相关文章
总数:227
2026年开源RISC-V软核在FPGA上的SoC搭建与系统验证

2026年开源RISC-V软核在FPGA上的SoC搭建与系统验证

本指南旨在提供一条清晰的路径,帮助用户在FPGA上快速搭建并验证一个基于…
技术分享
5小时前
0
0
8
0
为什么FPGA是硬件,还需要搞算法?

为什么FPGA是硬件,还需要搞算法?

FPGA与算法的结合技术趋势:随着大数据、人工智能、物联网等技…
技术分享
1年前
1
1
699
6
国内FPGA厂商有哪些?他们的特色分别是什么?

国内FPGA厂商有哪些?他们的特色分别是什么?

国内FPGA(现场可编程门阵列)厂商在近年来取得了显著的发展,它们在技术…
技术分享
1年前
0
0
700
0
评论表单游客 您好,欢迎参与讨论。
加载中…
评论列表
总数:0
FPGA线上课程平台|最全栈的FPGA学习平台|FPGA工程师认证培训
没有相关内容