【FPGA】Xilinx Vivado UART IP核配置与AXI-Lite接口实战

发布时间:2026/6/22 18:38:00

【FPGA】Xilinx Vivado UART IP核配置与AXI-Lite接口实战 1. UART通信协议基础与FPGA应用场景串口通信就像两个邻居通过纸条传递信息UART通用异步收发器是最常见的纸条传递方式之一。我刚开始接触FPGA时第一个实战项目就是用Zynq芯片通过串口和电脑对话。这种通信方式虽然速度比不上USB或PCIe但在工业控制、传感器数据采集等场景中依然不可替代——比如去年做的智能农业项目中就是靠UART接收土壤传感器的温湿度数据。UART的数据帧结构特别容易理解起始位低电平像敲门声接着是5-8位数据像纸条内容可选的奇偶校验位相当于核对暗号最后停止位高电平表示对话结束。实际项目中最常遇到的坑就是波特率不匹配有次调试时发现接收全是乱码查了三天才发现电脑端串口助手设的是115200而FPGA程序里写成了9600。这里有个实用技巧在Vivado里配置IP核时建议先用标准波特率如9600或115200等调通后再尝试特殊速率。2. Vivado中UART IP核的配置详解在Vivado 2023.1版本中配置UART IP核时我发现默认参数可能不适合所有场景。比如最近用Artix-7芯片做远程控制器时就遇到了时钟分频的问题。具体操作流程在Block Design中点击Add IP搜索AXI Uartlite后双击添加。关键配置页面有这几个参数需要特别注意时钟频率必须和实际输入时钟一致我曾在评估板上误选了100MHz而实际晶振是50MHz波特率工业设备常用19200这个非标准速率需要手动计算分频系数数据位宽8位兼容性最好但有些老式仪器需要7位奇偶校验FIFO深度默认16字节够用但在高速传输时可增加到32或64配置完成后建议立即在Address Editor里查看分配的基地址。有次项目因为这个地址没对齐导致后续AXI总线访问全部失败。生成的例化模板要特别注意复位信号极性Xilinx的IP核多数是低电平复位但有些第三方IP恰好相反。3. AXI-Lite接口的实战编程技巧AXI-Lite协议就像邮局的挂号信服务每次传输都需要确认回执。在Verilog中实现时我最开始总搞混五个通道的握手信号。经过几个项目磨合总结出这套万能模板// 写操作示例 always (posedge s_axi_aclk) begin if (!s_axi_aresetn) begin awready 1b0; wready 1b0; end else begin // 写地址通道 if (!awready s_axi_awvalid) awready 1b1; // 写数据通道 if (!wready s_axi_wvalid) wready 1b1; // 两个通道都就绪后执行写入 if (awready wready) begin case(s_axi_awaddr[3:0]) 4h0: rx_fifo s_axi_wdata[7:0]; 4h4: tx_fifo s_axi_wdata[7:0]; endcase bvalid 1b1; // 写响应 awready 1b0; // 复位准备信号 wready 1b0; end if (bvalid s_axi_bready) bvalid 1b0; end end调试时最容易忽略的是通道间的时序关系。有次用ILA抓波形发现数据传输失败最后发现是awvalid和wvalid信号没有在同一个时钟周期有效。推荐在代码中加入这些检查点写地址和写数据必须同时有效每次传输后必须等待bready才能开始下次操作读数据要在arvalid有效后的2-3个周期返回4. 系统集成与调试经验分享去年给工厂做设备监控系统时UART通信总在连续工作几小时后异常。后来用下面这个测试方案才定位到问题硬件环回测试将FPGA的TXD直接短接到RXD发送特定测试模式如0x55、0xAA交替。我在代码中加入了这个自检模块// 自检状态机 parameter IDLE 2b00; parameter SEND 2b01; parameter CHECK 2b10; always (posedge clk) begin case(state) IDLE: if(start_test) begin test_data 8h55; state SEND; end SEND: if(tx_done) begin state CHECK; timeout 0; end CHECK: begin if(rx_valid) begin if(rx_data ! test_data) error_count error_count 1; test_data ~test_data; state SEND; end else if(timeout 1000000) begin timeout_count timeout_count 1; state IDLE; end else timeout timeout 1; end endcase end常见故障排查表现象可能原因解决方法能发不能收RX引脚接反交换TXD/RXD线序偶发数据错误波特率偏差3%重新计算时钟分频中断不触发状态寄存器未清除读取RX/TX状态寄存器随机崩溃AXI时序违例添加ILA抓取总线信号在最后集成阶段建议先用示波器测量信号质量。曾遇到RS-232芯片损坏导致信号幅值不足的情况后来养成了在PCB上预留测试点的习惯。对于长距离传输可以在代码中加入软件流控XON/XOFF或者改用RS-485物理层。

相关新闻