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

FPGA中SPI接口的Verilog实现与仿真验证指南

二牛学FPGA二牛学FPGA
技术分享
4小时前
0
0
3

Quick Start

  1. 安装Vivado 2020.1或更高版本,确保支持XC7A35T(Artix-7)器件。
  2. 新建工程,选择器件 xc7a35tcsg324-1。
  3. 创建顶层模块 spi_master.v,包含标准SPI接口(SCLK、MOSI、MISO、CS)。
  4. 编写SPI主控状态机,支持CPOL=0、CPHA=0模式(模式0)。
  5. 添加仿真激励文件 spi_master_tb.v,模拟从设备回环(MISO回连到MOSI)。
  6. 运行行为仿真,观察SCLK、CS、MOSI、MISO波形,验证数据发送与接收一致。
  7. 运行综合与实现,检查资源占用和时序(Fmax目标≥100 MHz)。
  8. 下载到开发板,使用逻辑分析仪或示波器抓取SPI信号,确认功能正常。

前置条件与环境

项目推荐值说明替代方案
器件/板卡Xilinx Artix-7 XC7A35T主控芯片其他7系列或UltraScale+,需调整约束
EDA版本Vivado 2020.1 或更高开发工具ISE 14.7(仅支持Spartan-6及以下)
仿真器Vivado Simulator(xsim)仿真工具ModelSim/Questa(需编译库)
时钟/复位系统时钟50 MHz,异步复位高有效时钟与复位可改用PLL生成其他频率
接口依赖标准SPI四线(SCLK、MOSI、MISO、CS)接口类型三线半双工需修改状态机
约束文件XDC文件:set_property PACKAGE_PIN ...;create_clock -period 20.000 [get_ports clk]时序约束

目标与验收标准

  • 功能点:支持SPI模式0(CPOL=0,CPHA=0),8位数据帧,全双工通信。
  • 性能指标:SCLK频率可配置(默认1 MHz),Fmax≥100 MHz(系统时钟)。
  • 资源占用:LUT≤100,FF≤80,无BRAM/DSP(纯逻辑实现)。
  • 验收方式:仿真波形显示MOSI与MISO数据一致(回环测试);上板后逻辑分析仪捕获正确时序。

实施步骤

工程结构与关键模块

工程结构如下:src/下包含spi_master.vspi_slave_sim.v(仿真用);sim/下包含spi_master_tb.v。关键模块:spi_master.v实现状态机(IDLE→LOAD→SHIFT→DONE);spi_slave_sim.v模拟从设备回环。

// spi_master.v - 核心状态机片段
localparam IDLE = 2'b00, LOAD = 2'b01, SHIFT = 2'b10, DONE = 2'b11;
reg [1:0] state, next_state;
reg [3:0] bit_cnt;
reg [7:0] shift_reg;

always @(posedge clk or posedge rst) begin
    if (rst) state <= IDLE;
    else state <= next_state;
end

always @(*) begin
    case (state)
        IDLE: if (start) next_state = LOAD; else next_state = IDLE;
        LOAD: next_state = SHIFT;
        SHIFT: if (bit_cnt == 4'd7) next_state = DONE; else next_state = SHIFT;
        DONE: next_state = IDLE;
        default: next_state = IDLE;
    endcase
end

注意:状态机中LOAD阶段将并行数据加载到移位寄存器,SHIFT阶段在每个SCLK边沿移出一位并移入一位。

时序与约束

SCLK生成:使用系统时钟分频,计数器值 = (clk_freq / (2 * sclk_freq)) - 1。约束:XDC中声明SCLK为虚拟时钟(非直接约束),重点约束系统时钟和输入输出延迟。

# XDC 约束示例
create_clock -period 20.000 [get_ports clk]
set_output_delay -clock [get_clocks clk] -max 4.000 [get_ports {sclk mosi cs}]
set_input_delay -clock [get_clocks clk] -max 4.000 [get_ports miso]

注意:输出延迟应基于外部从设备建立时间要求,输入延迟基于从设备输出延迟。

验证

编写testbench:初始化时钟、复位,发送多个8位数据(如0xA5、0x5A),检查MISO回环数据。预期结果:仿真波形中,MOSI输出与MISO输入在SCLK上升沿后稳定,且数据一致。

// testbench 片段
initial begin
    clk = 0;
    forever #10 clk = ~clk; // 50MHz
    rst = 1;
    #100 rst = 0;
    @(posedge clk);
    start = 1;
    tx_data = 8'hA5;
    @(posedge clk);
    start = 0;
    wait(done); // 等待传输完成
    // 检查 rx_data == 8'hA5
end

常见坑与排查

  • 坑1:SCLK相位错误导致数据错位。检查CPOL/CPHA设置,确保模式0下SCLK空闲为低,数据在上升沿捕获。
  • 坑2:CS信号时序不满足要求。CS应在SCLK第一个边沿前拉低,最后一个边沿后拉高,且保持时间足够。
  • 坑3:仿真中MISO未正确驱动。确保从设备仿真模型在SCLK下降沿更新MISO,上升沿采样。

原理与设计说明

SPI是一种同步全双工串行接口,主设备控制时钟和片选。设计核心是状态机与分频逻辑。状态机采用三段式(状态寄存器、次态逻辑、输出逻辑)以提高时序性能。分频器使用计数器产生SCLK,注意SCLK边沿与数据移位的对齐:在模式0下,数据在SCLK上升沿被捕获(从设备输出在下降沿变化),因此主设备应在下降沿更新MOSI,上升沿采样MISO。这种设计权衡了资源与Fmax:使用纯逻辑实现避免了BRAM,但分频计数器会随SCLK频率降低而增加位宽。易用性方面,通过参数化SCLK分频系数和数据位宽,可适应不同从设备。

验证与结果

指标测量条件
Fmax(系统时钟)125 MHzVivado时序报告,最差路径
LUT占用45综合后资源报告
FF占用32综合后资源报告
SCLK频率1 MHz分频系数=25(50 MHz系统时钟)
数据传输延迟8 µs/字节包含CS建立/保持时间

仿真波形显示:CS拉低后,SCLK产生8个脉冲,MOSI依次输出0xA5(二进制10100101),MISO在同一时刻回环返回相同数据,done信号拉高。

故障排查

  • 现象:仿真中MOSI数据为全0。原因:未正确加载tx_data。检查点:LOAD阶段是否将tx_data赋值给shift_reg。修复:在LOAD状态下添加 shift_reg <= tx_data
  • 现象:MISO始终为高阻。原因:从设备仿真模型未驱动MISO。检查点:testbench中MISO是否连接。修复:在从设备模型中添加 assign miso = (cs) ? 1'bz : shift_reg[7];
  • 现象:时序违例。原因:组合逻辑路径过长。检查点:状态机输出逻辑是否使用阻塞赋值。修复:使用非阻塞赋值,并添加流水线寄存器。
  • 现象:上板后CS无法拉低。原因:GPIO配置错误。检查点:XDC中引脚约束是否正确。修复:核对原理图,设置IOSTANDARD。
  • 现象:SCLK频率不对。原因:分频系数计算错误。检查点:计数器最大值。修复:使用公式 clk_cnt_max = (clk_freq / (2 * sclk_freq)) - 1
  • 现象:数据位序错误(MSB/LSB)。原因:移位方向错误。检查点:移位寄存器是左移还是右移。修复:使用 shift_reg <= {shift_reg[6:0], miso} 实现MSB优先。
  • 现象:仿真中done信号未拉高。原因:状态机未进入DONE状态。检查点:bit_cnt计数是否到7。修复:确保SHIFT状态下bit_cnt递增条件正确。
  • 现象:多字节传输时CS未保持。原因:状态机在DONE后立即拉高CS。检查点:CS控制逻辑。修复:在DONE状态后添加至少一个时钟周期的CS保持。

扩展与下一步

  • 扩展1:参数化数据位宽(8/16/32位),通过参数DATA_WIDTH实现。
  • 扩展2:支持多从设备选择,增加CS译码逻辑。
  • 扩展3:加入FIFO缓冲,实现背靠背数据传输,提升吞吐量。
  • 扩展4:跨平台移植到Intel/Altera器件,注意时钟管理和I/O标准差异。
  • 扩展5:添加断言(SVA)验证SPI时序,确保设计健壮性。
  • 扩展6:使用形式验证工具(如OneSpin)检查状态机死锁。

参考与信息来源

  • Xilinx UG901: Vivado Design Suite User Guide (Synthesis)
  • Xilinx UG903: Vivado Design Suite User Guide (Implementation)
  • SPI Block Guide V04.01, Motorola
  • FPGA Prototyping by Verilog Examples, Pong P. Chu

技术附录

术语表

  • SPI:Serial Peripheral Interface,串行外设接口。
  • CPOL:Clock Polarity,时钟极性。
  • CPHA:Clock Phase,时钟相位。

检查清单

  • [ ] 状态机完整覆盖所有状态
  • [ ] 仿真通过回环测试
  • [ ] 时序满足建立/保持时间
  • [ ] 资源占用在目标范围内

关键约束速查

# 系统时钟约束
create_clock -period 20.000 [get_ports clk]
# 输出延迟(基于从设备 t_setup)
set_output_delay -clock [get_clocks clk] -max 4.000 [get_ports {sclk mosi cs}]
# 输入延迟(基于从设备 t_co)
set_input_delay -clock [get_clocks clk] -max 4.000 [get_ports miso]
标签:
本文原创,作者:二牛学FPGA,其版权均为FPGA线上课程平台|最全栈的FPGA学习平台|FPGA工程师认证培训所有。
如需转载,请注明出处:https://z.shaonianxue.cn/37492.html
二牛学FPGA

二牛学FPGA

初级工程师
这家伙真懒,几个字都不愿写!
61017.52W3.94W3.67W
分享:
成电国芯FPGA赛事课即将上线
Verilog中case语句的综合优化与优先级编码器设计
Verilog中case语句的综合优化与优先级编码器设计上一篇
Vivado 时序例外约束实践指南:set_false_path 与 set_multicycle_path 的设计与验证下一篇
Vivado 时序例外约束实践指南:set_false_path 与 set_multicycle_path 的设计与验证
相关文章
总数:658
FPGA工程师零基础到精通学习路线(2025最新版)

FPGA工程师零基础到精通学习路线(2025最新版)

一、入门先搞定HDL语言(Verilog/VHDL)重点提醒:…
技术分享
1年前
0
0
377
0
基于Zynq的智能小车控制与图像处理系统:FPGA毕业设计实施指南

基于Zynq的智能小车控制与图像处理系统:FPGA毕业设计实施指南

QuickStart本指南旨在帮助你在最短时间内搭建并运行一个基于Zy…
技术分享
1天前
0
0
8
0
FPGA静态时序分析(STA)实践指南:建立时间与保持时间的设计验证

FPGA静态时序分析(STA)实践指南:建立时间与保持时间的设计验证

静态时序分析(StaticTimingAnalysis,STA)是…
技术分享
6天前
0
0
32
0
评论表单游客 您好,欢迎参与讨论。
加载中…
评论列表
总数:0
FPGA线上课程平台|最全栈的FPGA学习平台|FPGA工程师认证培训
没有相关内容