从零到上板:用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输入系统时钟50MHzrst_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 3b0; spi_mosi_sync 3b0; 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 end2.2 数据移位控制根据CPHA配置数据需要在时钟的特定边沿更新always (*) begin case({CPOL, CPHA}) 2b00: data_update_edge ~spi_clk_int (clk_cnt CLK_DIV-1); 2b01: 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 8h00; bit_cnt 0; end else if(data_update_edge) begin shift_reg {shift_reg[6:0], 1b0}; bit_cnt bit_cnt 1; end end3. 从机接收模块设计要点3.1 边沿检测电路从机需要精确检测SPI时钟的有效边沿进行数据采样// 上升沿检测 assign pos_edge (spi_clk_sync[2:1] 2b01); // 下降沿检测 assign neg_edge (spi_clk_sync[2:1] 2b10); always (*) begin case({CPOL, CPHA}) 2b00: sample_en pos_edge; 2b01: sample_en neg_edge; // 其他模式组合... endcase end3.2 数据对齐与校验接收到的串行数据需要转换为并行格式并添加有效性校验always (posedge sys_clk or negedge rst_n) begin if(!rst_n) begin rx_data 8h00; rx_valid 1b0; end else if(spi_cs_sync[3]) begin rx_valid 1b0; // CS无效时清除有效标志 end else if(sample_en) begin rx_data {rx_data[6:0], spi_mosi_sync[3]}; if(bit_cnt 7) rx_valid 1b1; end end4. 系统集成与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核时需注意设置足够深的采样存储至少4096点添加关键信号spi_clk、spi_mosi、spi_miso、spi_cs配置触发条件如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的波形对比功能可以直观验证发送与接收数据的比特对齐情况。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2576026.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!