news 2026/5/2 20:17:30

从零到上板:用FPGA实现SPI主从机完整数据回环(Vivado ILA抓波形实战)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
从零到上板:用FPGA实现SPI主从机完整数据回环(Vivado ILA抓波形实战)

从零到上板:用FPGA实现SPI主从机完整数据回环(Vivado ILA抓波形实战)

在嵌入式系统开发中,SPI协议因其高速、全双工的特性成为芯片间通信的首选方案之一。本文将带您完成一个完整的FPGA开发流程:从Verilog代码编写、功能仿真到实际上板调试,最终通过Vivado的ILA工具实时捕获SPI总线波形,验证主从机数据回环的正确性。不同于单纯的模块仿真,我们聚焦于系统级集成与硬件调试技巧,适合已经掌握SPI基础理论、需要实战经验的开发者。

1. SPI主从机系统架构设计

1.1 整体框架规划

一个完整的SPI回环系统需要包含以下核心模块:

  • 主机发送模块:负责生成SCK时钟、MOSI数据流和CS片选信号
  • 从机接收模块:同步捕获主机发送的数据
  • 数据回环通路:将接收数据反馈给主机形成闭环验证
  • 调试接口:集成ILA核用于实时信号捕获

关键信号定义如下表:

信号名称方向描述
sys_clk输入系统时钟(50MHz)
rst_n输入低电平有效的全局复位
spi_clk主机输出SPI串行时钟(可配置极性)
spi_mosi主机输出主机输出从机输入数据线
spi_miso从机输出主机输入从机输出数据线
spi_cs主机输出从机片选信号(低电平有效)

1.2 时钟域处理要点

由于SPI时钟(SCK)由主机动态生成,而从机需要同步捕获该时钟域的数据,必须特别注意跨时钟域处理:

// 三级寄存器同步链消除亚稳态 always @(posedge sys_clk or negedge rst_n) begin if(!rst_n) begin spi_clk_sync <= 3'b0; spi_mosi_sync <= 3'b0; end else begin spi_clk_sync <= {spi_clk_sync[1:0], spi_clk}; spi_mosi_sync <= {spi_mosi_sync[1:0], spi_mosi}; end end

提示:对于高速SPI通信(>10MHz),建议使用IDDR原语处理时钟边沿检测

2. 主机发送模块实现细节

2.1 可配置时钟生成

主机模块需要根据系统时钟分频产生SPI时钟,关键参数包括:

  • CPOL:时钟空闲状态极性(0=低电平,1=高电平)
  • CPHA:数据采样相位(0=第一个边沿,1=第二个边沿)

时钟分频计数器实现如下:

localparam CLK_DIV = SYS_CLK_FREQ / SPI_CLK_FREQ / 2; always @(posedge sys_clk or negedge rst_n) begin if(!rst_n) begin clk_cnt <= 0; spi_clk_int <= CPOL; end else if(spi_en) begin if(clk_cnt == CLK_DIV-1) begin clk_cnt <= 0; spi_clk_int <= ~spi_clk_int; end else begin clk_cnt <= clk_cnt + 1; end end else begin spi_clk_int <= CPOL; end end

2.2 数据移位控制

根据CPHA配置,数据需要在时钟的特定边沿更新:

always @(*) begin case({CPOL, CPHA}) 2'b00: data_update_edge = ~spi_clk_int & (clk_cnt == CLK_DIV-1); 2'b01: data_update_edge = spi_clk_int & (clk_cnt == CLK_DIV-1); // 其他模式组合... endcase end always @(posedge sys_clk or negedge rst_n) begin if(!rst_n) begin shift_reg <= 8'h00; bit_cnt <= 0; end else if(data_update_edge) begin shift_reg <= {shift_reg[6:0], 1'b0}; bit_cnt <= bit_cnt + 1; end end

3. 从机接收模块设计要点

3.1 边沿检测电路

从机需要精确检测SPI时钟的有效边沿进行数据采样:

// 上升沿检测 assign pos_edge = (spi_clk_sync[2:1] == 2'b01); // 下降沿检测 assign neg_edge = (spi_clk_sync[2:1] == 2'b10); always @(*) begin case({CPOL, CPHA}) 2'b00: sample_en = pos_edge; 2'b01: sample_en = neg_edge; // 其他模式组合... endcase end

3.2 数据对齐与校验

接收到的串行数据需要转换为并行格式,并添加有效性校验:

always @(posedge sys_clk or negedge rst_n) begin if(!rst_n) begin rx_data <= 8'h00; rx_valid <= 1'b0; end else if(spi_cs_sync[3]) begin rx_valid <= 1'b0; // CS无效时清除有效标志 end else if(sample_en) begin rx_data <= {rx_data[6:0], spi_mosi_sync[3]}; if(bit_cnt == 7) rx_valid <= 1'b1; end end

4. 系统集成与ILA调试实战

4.1 回环测试顶层设计

将主从机模块集成到顶层,建立数据回环通路:

spi_master #( .CPOL(0), .CPHA(0) ) u_master ( .sys_clk(sys_clk), .rst_n(rst_n), .spi_clk(spi_clk), .spi_mosi(spi_mosi), .spi_miso(spi_miso), .spi_cs(spi_cs) ); spi_slave #( .CPOL(0), .CPHA(0) ) u_slave ( .sys_clk(sys_clk), .rst_n(rst_n), .spi_clk(spi_clk), .spi_mosi(spi_mosi), .spi_miso(spi_miso), .spi_cs(spi_cs), .rx_data(rx_data), .rx_valid(rx_valid) );

4.2 ILA核配置技巧

在Vivado中添加ILA核时需注意:

  1. 设置足够深的采样存储(至少4096点)
  2. 添加关键信号:spi_clk、spi_mosi、spi_miso、spi_cs
  3. 配置触发条件:如rx_valid上升沿

TCL配置示例:

create_debug_core u_ila ila set_property C_DATA_DEPTH 8192 [get_debug_cores u_ila] set_property C_TRIGIN_EN false [get_debug_cores u_ila] add_probe spi_clk [get_debug_ports u_ila/clk] add_probe spi_mosi [get_debug_ports u_ila/probe0] add_probe rx_valid [get_debug_ports u_ila/probe1]

4.3 上板调试常见问题

  • 时钟偏移问题:如果采样数据不稳定,尝试调整ILA采样时钟相位
  • 触发条件设置:复杂触发可使用触发状态机(TSM)
  • 数据对齐异常:检查CPOL/CPHA配置是否与从设备一致

实际捕获的波形示例:

CS __----____________________________________ CLK _-_-_-_-_-_-_-_-_________________________ MOSI _X_X_X_X_X_X_X_X_________________________ MISO _X_X_X_X_X_X_X_X_________________________ | | | | | | | | 0 1 2 3 4 5 6 7 (bit位置)

在Xilinx Artix-7开发板上实测时,发现当SPI时钟超过25MHz时,需要插入IO延迟约束才能保证稳定采样。通过ILA的波形对比功能,可以直观验证发送与接收数据的比特对齐情况。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/2 20:16:30

深度解析VisualCppRedist AIO:Windows系统VC++运行库终极管理方案

深度解析VisualCppRedist AIO&#xff1a;Windows系统VC运行库终极管理方案 【免费下载链接】vcredist AIO Repack for latest Microsoft Visual C Redistributable Runtimes 项目地址: https://gitcode.com/gh_mirrors/vc/vcredist 在Windows系统管理和应用开发领域&am…

作者头像 李华
网站建设 2026/5/2 20:14:13

5个技巧掌握CompressO:跨平台媒体压缩的完整实战指南

5个技巧掌握CompressO&#xff1a;跨平台媒体压缩的完整实战指南 【免费下载链接】compressO Convert any video/image into a tiny size. 100% free & open-source. Available for Mac, Windows & Linux. 项目地址: https://gitcode.com/gh_mirrors/co/compressO …

作者头像 李华
网站建设 2026/5/2 20:14:09

告别音频混乱!Audio Router实现Windows多程序音频分流终极方案

告别音频混乱&#xff01;Audio Router实现Windows多程序音频分流终极方案 【免费下载链接】audio-router Routes audio from programs to different audio devices. 项目地址: https://gitcode.com/gh_mirrors/au/audio-router 你是否曾为Windows系统无法单独控制每个程…

作者头像 李华