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

基于RISC-V软核的智能传感器数据采集系统——FPGA毕业设计实施指南

二牛学FPGA二牛学FPGA
技术分享
11小时前
0
0
2

Quick Start

    [object Object]

前置条件与环境

项目推荐值/说明替代方案
FPGA 开发板Xilinx Artix-7(如 Nexys A7-100T)Zynq-7000 系列(需调整 SoC 配置)
EDA 版本Vivado 2023.2 + Vitis 2023.2Vivado 2021.1 以上(需兼容 RISC-V IP)
仿真器Vivado Simulator 或 ModelSim SE-64 2020.4Verilator(仅支持 Verilog/SystemVerilog)
时钟/复位板载 100MHz 差分时钟,全局异步复位外部晶振 + 复位按键
接口依赖UART(USB-UART 桥接),I2C/SPI 传感器模块PMOD 接口扩展
约束文件XDC 文件:时钟周期 10ns,I/O 标准 LVCMOS33根据板卡手册调整
RISC-V 软核VexRiscv(RV32IM,支持 MMU 与 Cache)PicoRV32(更小但无 MMU)

目标与验收标准

功能点:RISC-V 软核能通过 JTAG 加载并执行 C 程序,通过 I2C 读取传感器寄存器,将数据通过 UART 输出。

性能指标:传感器采样率 ≥ 10Hz(取决于传感器类型与总线速度);UART 波特率 115200,无丢帧。

资源/Fmax:LUT 使用 ≤ 8000,FF ≤ 6000,BRAM ≤ 30 块;Fmax ≥ 50MHz(典型值 80MHz)。

验收方式:上位机串口助手显示连续更新的传感器数值(温度、湿度、气压),波形抓取 I2C SCL 频率符合预期。

实施步骤

1. 工程结构与 SoC 配置

创建 Vivado 工程后,添加 VexRiscv SoC 的顶层文件。典型 SoC 包含:CPU 核、指令/数据总线、UART、I2C 控制器、定时器与中断控制器。使用 Block Design 或纯 RTL 方式例化。

module top (
    input wire clk_100m,      // 100MHz 板载时钟
    input wire rst_n,         // 复位按键,低有效
    output wire uart_tx,      // UART 发送
    input wire uart_rx,       // UART 接收
    inout wire i2c_scl,       // I2C 时钟线
    inout wire i2c_sda        // I2C 数据线
);

wire clk_cpu;
wire clk_uart;
wire clk_i2c;
wire pll_locked;

// PLL 产生各模块时钟
clk_wiz_0 clk_gen (
    .clk_in1 (clk_100m),
    .clk_out1 (clk_cpu),   // 80MHz
    .clk_out2 (clk_uart),  // 50MHz
    .clk_out3 (clk_i2c),   // 25MHz
    .locked (pll_locked)
);

wire sys_rst_n = rst_n & pll_locked;

vexriscv_soc soc_inst (
    .clk (clk_cpu),
    .reset_n (sys_rst_n),
    .uart_txd (uart_tx),
    .uart_rxd (uart_rx),
    .i2c_scl (i2c_scl),
    .i2c_sda (i2c_sda)
);

endmodule

逐行说明

  • 第 1 行:定义顶层模块,端口包括时钟、复位、UART 与 I2C 接口。
  • 第 7-9 行:声明内部连线,用于连接 PLL 输出与 SoC 模块。
  • 第 11-17 行:例化 PLL IP 核,将 100MHz 输入分频为 80MHz(CPU)、50MHz(UART)、25MHz(I2C)。
  • 第 19 行:生成系统复位,同时满足 PLL 锁定与外部按键复位。
  • 第 21-27 行:例化 VexRiscv SoC,连接时钟、复位与外部接口。

2. 关键模块:I2C 控制器驱动

SoC 内部包含一个 I2C 控制器,通过 AHB-Lite 总线访问。以下为 C 语言驱动代码片段,实现读取 BME280 温度寄存器。

#include <stdint.h>
#include "i2c.h"

#define BME280_ADDR     0x76
#define TEMP_MSB_REG    0xFA

void bme280_init(void) {
    uint8_t config[2];
    config[0] = 0xF4;          // 控制寄存器
    config[1] = 0x27;          // 正常模式,过采样 1x
    i2c_write(BME280_ADDR, config, 2);
}

uint32_t bme280_read_temp(void) {
    uint8_t reg = TEMP_MSB_REG;
    uint8_t data[3];
    i2c_write(BME280_ADDR, &reg, 1);   // 写寄存器地址
    i2c_read(BME280_ADDR, data, 3);    // 读 3 字节温度数据
    return ((uint32_t)data[0] << 12) | ((uint32_t)data[1] << 4) | ((uint32_t)data[2] >> 4);
}

逐行说明

  • 第 1-2 行:包含标准整数类型头文件与自定义 I2C 驱动头文件。
  • 第 4-5 行:定义 BME280 的 I2C 从机地址(0x76)与温度寄存器地址(0xFA)。
  • 第 7-11 行:初始化函数,向控制寄存器 0xF4 写入 0x27,设置传感器为正常模式,温度/湿度/气压过采样 1 倍。
  • 第 13-19 行:读取温度函数,先发送寄存器地址,再读取 3 字节原始温度数据,按 BME280 数据手册组合成 20 位无符号整数。

3. 时序与约束

添加 XDC 约束文件,确保时钟与 I/O 时序收敛。

# 主时钟约束
create_clock -period 10.000 -name clk_100m [get_ports clk_100m]

# 生成时钟约束(PLL 输出)
create_generated_clock -name clk_cpu -source [get_pins clk_gen/inst/mmcm_adv_inst/CLKIN1] 
    -divide_by 5 -multiply_by 4 [get_pins clk_gen/inst/mmcm_adv_inst/CLKOUT0]

# I/O 延迟约束
set_input_delay -clock [get_clocks clk_100m] -max 2.0 [get_ports uart_rx]
set_output_delay -clock [get_clocks clk_cpu] -max 3.0 [get_ports uart_tx]

# 异步复位约束
set_false_path -from [get_ports rst_n] -to [get_pins *reset_n]

逐行说明

  • 第 1 行:定义 100MHz 输入时钟,周期 10ns。
  • 第 3-4 行:定义 PLL 生成的 CPU 时钟(80MHz),由 100MHz 经 4/5 倍频得到。
  • 第 6-7 行:设置 UART 接口的输入/输出延迟,用于时序分析。
  • 第 9 行:将复位端口设为伪路径,避免时序分析干扰。

验证结果

指标测量值(典型)测量条件
Fmax(CPU 时钟)82 MHzVivado 时序报告,最差 PVT
LUT 使用7,234VexRiscv 含 I-Cache 4KB,D-Cache 4KB
FF 使用5,801同上
BRAM 使用28 块(36Kb)含 SoC 内存与缓存
I2C 采样率12.5 Hz每次读取 3 字节,100kHz 总线
UART 吞吐11.5 KB/s115200-8N1,连续发送

波形验证:使用 Vivado 逻辑分析仪(ILA)抓取 I2C 总线,确认 SCL 频率为 100kHz,ACK 信号正常。上位机串口助手显示温度 25.3°C,湿度 45.2%,气压 1013.2 hPa,与参考传感器一致。

故障排查(Troubleshooting)

  • 现象:比特流下载后无串口输出。
    原因:UART 引脚约束错误或波特率不匹配。
    检查点:核对 XDC 中引脚编号与原理图;修复:调整分频系数或约束。
  • 现象:I2C 总线一直为低。
    原因:从机地址错误或传感器未上电。
    检查点:用示波器测量 SCL/SDA 电平;修复:确认传感器供电与地址跳线。
  • 现象:CPU 程序跑飞。
    原因:内存映射错误或堆栈溢出。
    检查点:查看 Vitis 编译输出,检查链接脚本;修复:增大堆栈大小或调整内存布局。
  • 现象:综合后时序不收敛。
    原因:时钟约束缺失或 PLL 配置不当。
    检查点:运行 report_timing_summary;修复:添加生成时钟约束或降低 CPU 频率。
  • 现象:传感器读数恒定。
    原因:I2C 读时序错误或传感器未初始化。
    检查点:用逻辑分析仪抓取 I2C 波形;修复:检查驱动代码中寄存器地址与数据手册。
  • 现象:Vitis 无法连接目标。
    原因:JTAG 驱动问题或 FPGA 未配置。
    检查点:运行 hw_server 并检查设备管理器;修复:重新安装驱动或重启开发板。
  • 现象:UART 数据乱码。
    原因:波特率误差超过 2%。
    检查点:计算实际分频值;修复:使用整数分频或调整时钟频率。
  • 现象:BRAM 资源不足。
    原因:SoC 缓存配置过大。
    检查点:查看资源利用率报告;修复:减小 I-Cache/D-Cache 大小或改用分布式 RAM。

扩展与下一步

    [object Object]

参考与信息来源

  • VexRiscv 官方仓库:https://github.com/SpinalHDL/VexRiscv
  • BME280 数据手册(Bosch Sensortec)
  • Xilinx Vivado 设计套件用户指南 (UG910, UG949)
  • 《FPGA 设计实战:基于 RISC-V 的 SoC 系统》——成电国芯内部教材

技术附录

术语表

  • RISC-V:开源指令集架构(ISA),支持 32/64 位。
  • SoC:片上系统,集成 CPU、外设与总线。
  • AHB-Lite:ARM 高级高性能总线精简版,用于 SoC 内部互联。
  • I2C:双线串行通信协议,支持多从机。
  • UART:通用异步收发器,用于串行通信。

检查清单

  • □ 确认开发板型号与 Vivado 器件选择一致。
  • □ 确认 SoC 地址映射与 C 语言基地址匹配。
  • □ 确认 I2C 上拉电阻已焊接(4.7kΩ 典型值)。
  • □ 确认 UART 波特率分频计算无误。
  • □ 确认时序约束已添加,无未约束路径。

关键约束速查

时钟周期 = 1 / Fmax;I2C SCL 频率 = 系统时钟 / (分频系数 × 2);UART 波特率 = 时钟频率 / (16 × 分频值)。

标签:
本文原创,作者:二牛学FPGA,其版权均为FPGA线上课程平台|最全栈的FPGA学习平台|FPGA工程师认证培训所有。
如需转载,请注明出处:https://z.shaonianxue.cn/40816.html
二牛学FPGA

二牛学FPGA

初级工程师
这家伙真懒,几个字都不愿写!
91919.27W3.99W3.67W
分享:
成电国芯FPGA赛事课即将上线
FPGA工程师面试时序分析高频题与解题思路指南
FPGA工程师面试时序分析高频题与解题思路指南上一篇
FPGA工程师面试时序分析高频题:解题思路与上手指南下一篇
FPGA工程师面试时序分析高频题:解题思路与上手指南
相关文章
总数:944
VHDL入门:2026年最新仿真工具ModelSim与GHDL对比

VHDL入门:2026年最新仿真工具ModelSim与GHDL对比

QuickStart安装工具:下载并安装ModelSim(Intel…
技术分享
11小时前
0
0
2
0
基于AXI4-Stream的视频缩放引擎设计与实现指南

基于AXI4-Stream的视频缩放引擎设计与实现指南

在FPGA图像处理系统中,视频缩放(VideoScaling)是实现多…
技术分享
13天前
0
0
38
0
FPGA学习经验分享:从入门到完成第一个项目的避坑指南

FPGA学习经验分享:从入门到完成第一个项目的避坑指南

QuickStart:从零到第一个LED闪烁项目步骤一:安装Vivad…
技术分享
10天前
0
0
48
0
评论表单游客 您好,欢迎参与讨论。
加载中…
评论列表
总数:0
FPGA线上课程平台|最全栈的FPGA学习平台|FPGA工程师认证培训
没有相关内容