---
title: 2026年开源RISC-V软核在FPGA上的SoC搭建与系统验证
url: "https://www.fpgalearn.com/31379.html"
kind: article
id: 31379
excerpt: 本文档旨在提供一份从零开始，在FPGA上搭建基于开源RISC-V软核的SoC（System-on-Chip）并进行系统级验证的完整实施手册。我们将以业界广泛使用…
published_at: 2026-04-11
author: 二牛学FPGA
tags: fpga, RISC-V, SoC
word_count: 6824
source: "https://www.fpgalearn.com"
---

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

> 标签：fpga、RISC-V、SoC
> 本文档旨在提供一份从零开始，在FPGA上搭建基于开源RISC-V软核的SoC（System-on-Chip）并进行系统级验证的完整实施手册。我们将以业界广泛使用…

> 本文档旨在提供一份从零开始，在FPGA上搭建基于开源RISC-V软核的SoC（System-on-Chip）并进行系统级验证的完整实施手册。我们将以业界广泛使用…

本文档旨在提供一份从零开始，在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//gateware/.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["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、指令和数据缓存，性能高但资源占用大。如果仅运行裸机程序，可选择`lite`或`standard`变体以节省资源。
- **总线选择**：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.csv`和`csr.h`，确认外设的基地址已存在。
**修复建议**：确保外设模块正确实现了Wishbone从接口，并连接到了SoC的`self.bus`上。
- **现象**：时序报告中有大量跨时钟域违例。
**原因**：异步时钟域之间的信号未进行同步处理。
**检查点**：检查如UART、以太网、外部传感器接口等与系统时钟不同源的信号。
**修复建议**：在RTL中为这些信号插入同步器（两级触发器）。L
