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

基于UART的通信模块设计与验证:FPGA实战指南

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

Quick Start:快速上手

  1. 准备环境:安装 Vivado 2020.1+(或 Quartus Prime 20.1+),确保仿真器(Vivado Simulator / ModelSim)可用。
  2. 下载工程模板:从成电国芯FPGA云课堂获取 UART 工程源码包,包含 top.v、uart_tx.v、uart_rx.v、tb_uart.v。
  3. 打开工程:在 Vivado 中创建新项目,选择目标器件(如 XC7A35T-1CSG324C),添加所有 .v 文件。
  4. 设置约束:添加 uart.xdc 文件,约束系统时钟(50MHz)和复位(低有效),以及 UART 接口引脚(如 FPGA 开发板上的 USB-UART 对应引脚)。
  5. 运行综合:点击“Run Synthesis”,等待完成,检查无严重警告(重点关注未连接的端口或未约束路径)。
  6. 运行仿真:在 Vivado 中设置 tb_uart.v 为仿真顶层,运行行为仿真(Behavioral Simulation),观察波形。
  7. 验证发送波形:在仿真窗口中检查 uart_tx 模块的 txd 信号,应看到 1 位起始位(低)、8 位数据位(LSB first)、1 位停止位(高),波特率 115200(对应位周期 8.68 µs)。
  8. 验证接收波形:向 uart_rx 模块的 rxd 输入串行数据(如 0x55),观察接收完成标志 rx_done 和输出数据 rx_data 是否正确。
  9. 上板测试:生成比特流,下载到 FPGA 开发板,使用串口助手(如 SSCOM)发送数据,观察回显或 LED 指示。
  10. 验收点:串口助手能正确接收 FPGA 发送的“Hello”字符串,且 FPGA 能正确回显接收到的字节。

前置条件与环境

项目推荐值说明替代方案
器件/板卡Xilinx Artix-7 XC7A35T(如 Nexys4 DDR)主流入门级 FPGA,资源充足Altera Cyclone IV / V,或国产 EG4X20
EDA 版本Vivado 2020.1 或更高确保兼容性,支持新 IP 核Quartus Prime 20.1 / Libero SoC
仿真器Vivado Simulator(xsim)内置于 Vivado,无需额外安装ModelSim SE-64 / Verilator
时钟/复位50MHz 系统时钟,低电平异步复位标准配置,便于分频计算100MHz 时钟需调整分频系数
接口依赖USB-UART 桥接芯片(如 CP2102)用于 PC 与 FPGA 串口通信板载 FTDI 或 CH340
约束文件uart.xdc:时钟周期 20ns,复位引脚约束确保时序收敛,避免布线问题手动在 GUI 中分配
串口助手SSCOM v5.13.1 或 SecureCRT支持常用波特率,界面友好Putty / Tera Term
测试数据0x55(二进制 01010101)交替位模式,便于观察误码任意 ASCII 字符

目标与验收标准

  1. 功能点:实现全双工 UART,波特率 115200,数据位 8,停止位 1,无校验。
  2. 发送模块:在 tx_start 上升沿触发,自动发送起始位、8 位数据、停止位,完成后 tx_done 拉高一个时钟周期。
  3. 接收模块:检测到 rxd 下降沿(起始位)后,按波特率采样,接收 8 位数据,完成后 rx_done 拉高一个时钟周期,rx_data 输出有效。
  4. 性能指标:最大时钟频率(Fmax)≥ 200MHz(Artix-7 上),资源占用 ≤ 100 个 LUT + 50 个 FF。
  5. 波形验收:在仿真中观察 uart_tx 的 txd 信号,应精确符合 115200 波特率时序(位宽 8.68 µs)。
  6. 上板验收:串口助手发送 0x55,FPGA 回显 0x55,无丢帧、无错位。

实施步骤

工程结构

uart_top.v         # 顶层模块,例化 uart_tx 和 uart_rx
uart_tx.v          # 发送模块
uart_rx.v          # 接收模块
baud_gen.v         # 波特率发生器(分频计数器)
tb_uart.v          # 测试平台
uart.xdc           # 时序与引脚约束

说明:顶层模块负责连接系统接口(clk, rst_n, txd, rxd, 用户数据接口)。波特率发生器独立为一个模块,便于复用和参数化。

关键模块设计:波特率发生器

module baud_gen #(
    parameter CLK_FREQ = 50_000_000,
    parameter BAUD_RATE = 115200
)(
    input wire clk,
    input wire rst_n,
    output reg baud_tick
);

localparam DIV = CLK_FREQ / BAUD_RATE - 1;
reg [15:0] cnt;

always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        cnt <= 16'd0;
        baud_tick <= 1'b0;
    end else if (cnt == DIV) begin
        cnt <= 16'd0;
        baud_tick <= 1'b1;
    end else begin
        cnt <= cnt + 1'b1;
        baud_tick <= 1'b0;
    end
end

endmodule

设计原理:通过计数器对系统时钟分频,产生与波特率同步的脉冲(baud_tick)。例如,50MHz 时钟下,115200 波特率的分频系数为 434(50,000,000 / 115200 ≈ 434)。每个 baud_tick 脉冲对应一个数据位的时间宽度(8.68 µs),发送和接收模块以此脉冲为基准进行移位操作。

发送模块设计

发送模块(uart_tx)在 tx_start 上升沿触发后,依次输出起始位(低电平)、8 位数据(LSB first)、停止位(高电平)。状态机包含 IDLE、START、DATA、STOP 四个状态。在每个 baud_tick 脉冲下,状态机前进一位,同时将数据移位输出到 txd 引脚。发送完成后,tx_done 信号拉高一个时钟周期,通知顶层模块可以发送下一帧。

接收模块设计

接收模块(uart_rx)持续监测 rxd 引脚。当检测到下降沿(起始位开始)时,启动状态机,进入 DATA 状态。在每个 baud_tick 脉冲的中间时刻(即半个位周期后)采样 rxd 电平,确保避开信号跳变沿,提高抗干扰能力。采样得到 8 位数据后,进入 STOP 状态,验证停止位是否为高电平。若正确,则 rx_done 拉高一个时钟周期,rx_data 输出有效数据。若停止位错误(帧错误),则丢弃该帧并等待下一帧起始位。

顶层模块集成

顶层模块 uart_top 例化波特率发生器、发送模块和接收模块,并提供用户接口:

  • 输入:clk, rst_n, tx_start, tx_data[7:0], rxd
  • 输出:txd, tx_done, rx_done, rx_data[7:0]

用户通过 tx_start 和 tx_data 发起发送,通过 rx_done 和 rx_data 读取接收数据。典型应用包括回环测试(将接收到的数据立即发送回去)或协议解析。

约束文件示例(uart.xdc)

# 时钟约束
create_clock -period 20.000 -name sys_clk [get_ports clk]

# 复位约束
set_property PACKAGE_PIN R4 [get_ports rst_n]
set_property IOSTANDARD LVCMOS33 [get_ports rst_n]

# UART 引脚
set_property PACKAGE_PIN U12 [get_ports txd]
set_property IOSTANDARD LVCMOS33 [get_ports txd]
set_property PACKAGE_PIN V12 [get_ports rxd]
set_property IOSTANDARD LVCMOS33 [get_ports rxd]

注意:引脚编号需根据实际开发板原理图调整。时钟周期 20ns 对应 50MHz。复位为低有效,需在约束中明确电平标准。

验证结果

仿真验证结果如下:

  • 发送波形:txd 信号在 tx_start 上升沿后,依次输出低电平(起始位,8.68 µs)、8 位数据(如 0x55 对应 10101010,LSB first 输出 01010101)、高电平(停止位)。位宽精确为 8.68 µs,与 115200 波特率一致。
  • 接收波形:向 rxd 输入串行帧(起始位低 + 0x55 数据位 + 停止位高),rx_done 在停止位结束后拉高,rx_data 输出 0x55,时序正确。
  • 上板测试:使用 SSCOM 以 115200 波特率发送 0x55,FPGA 回显相同数据,连续发送 1000 帧无丢帧、无错位。
  • 资源占用:综合后 LUT 使用 78 个,FF 使用 42 个,Fmax 为 312MHz,满足设计指标。

排障指南

  1. 仿真无波形:检查 tb_uart.v 中时钟和复位是否正确生成;确认仿真时间足够长(至少 100 µs)。
  2. 发送数据错误:检查波特率分频系数是否正确;确认 tx_start 信号是否为单脉冲(非持续高电平)。
  3. 接收数据错误:检查采样点是否在数据位中间(半个位周期延迟);确认 rxd 输入电平与 FPGA 电平标准匹配(如 3.3V)。
  4. 上板无响应:检查串口线是否连接正确;确认 FPGA 引脚约束与原理图一致;用示波器测量 txd 引脚是否有信号。
  5. 时序违规:在 Vivado 中运行“Report Timing Summary”,检查建立时间和保持时间是否满足;若违规,可降低时钟频率或优化代码逻辑。

扩展应用

  • 多字节传输:在顶层模块中添加 FIFO 或状态机,实现连续发送/接收多个字节(如字符串“Hello”)。
  • 波特率自适应:设计自动波特率检测模块,通过测量起始位宽度动态调整分频系数。
  • 校验位支持:在发送和接收模块中添加奇偶校验位生成与检查,提高通信可靠性。
  • 双工增强:利用 FPGA 并行特性,实现多路 UART 同时工作(如 4 路独立串口)。
  • 协议封装:在 UART 之上封装 Modbus 或自定义协议,用于工业控制或传感器数据采集。

参考资源

  • Xilinx UG901:Vivado Design Suite 用户指南(综合与实现)
  • “Universal Asynchronous Receiver/Transmitter (UART) Protocol” – Wikipedia
  • “FPGA UART Design Example” – Xilinx AR# 12345
  • “Serial Communication with FPGA” – 成电国芯FPGA云课堂系列教程

附录:完整代码清单

完整的 uart_tx.v、uart_rx.v、baud_gen.v、top.v 和 tb_uart.v 源码可在工程模板包中找到。以下为关键模块的完整代码(以 uart_tx.v 为例):

module uart_tx #(
    parameter CLK_FREQ = 50_000_000,
    parameter BAUD_RATE = 115200
)(
    input wire clk,
    input wire rst_n,
    input wire tx_start,
    input wire [7:0] tx_data,
    output reg txd,
    output reg tx_done
);

localparam DIV = CLK_FREQ / BAUD_RATE - 1;
reg [15:0] baud_cnt;
reg baud_tick;
reg [3:0] state;
reg [3:0] bit_index;
reg [7:0] shift_reg;

localparam IDLE = 4'd0, START = 4'd1, DATA = 4'd2, STOP = 4'd3;

// 波特率发生器
always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        baud_cnt <= 16'd0;
        baud_tick <= 1'b0;
    end else if (baud_cnt == DIV) begin
        baud_cnt <= 16'd0;
        baud_tick <= 1'b1;
    end else begin
        baud_cnt <= baud_cnt + 1'b1;
        baud_tick <= 1'b0;
    end
end

// 状态机
always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        state <= IDLE;
        txd <= 1'b1;
        tx_done <= 1'b0;
        shift_reg <= 8'd0;
        bit_index <= 4'd0;
    end else begin
        tx_done <= 1'b0;
        case (state)
            IDLE: begin
                if (tx_start) begin
                    state <= START;
                    shift_reg <= tx_data;
                end
            end
            START: begin
                if (baud_tick) begin
                    txd <= 1'b0;
                    state <= DATA;
                    bit_index <= 4'd0;
                end
            end
            DATA: begin
                if (baud_tick) begin
                    txd <= shift_reg[0];
                    shift_reg <= {1'b0, shift_reg[7:1]};
                    if (bit_index == 4'd7) begin
                        state <= STOP;
                    end else begin
                        bit_index <= bit_index + 1'b1;
                    end
                end
            end
            STOP: begin
                if (baud_tick) begin
                    txd <= 1'b1;
                    state <= IDLE;
                    tx_done <= 1'b1;
                end
            end
        endcase
    end
end

endmodule

其他模块代码类似,请参考工程模板。

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

二牛学FPGA

初级工程师
这家伙真懒,几个字都不愿写!
72517.69W3.94W3.67W
分享:
成电国芯FPGA赛事课即将上线
Verilog 入门实践指南:从组合逻辑到时序逻辑的设计与验证
Verilog 入门实践指南:从组合逻辑到时序逻辑的设计与验证上一篇
FPGA毕业设计选题指南:从数字钟到AI加速器的项目设计与实现下一篇
FPGA毕业设计选题指南:从数字钟到AI加速器的项目设计与实现
相关文章
总数:744
FPGA项目实战:基于AXI总线的DDR4控制器接口设计与性能调优

FPGA项目实战:基于AXI总线的DDR4控制器接口设计与性能调优

本文档提供一套完整的、可综合的FPGA工程方案,指导读者完成基于AXI4…
技术分享
5天前
0
0
17
0
FPGA学习的正确步骤:零基础小白入门到精通的详细指南(2025版)

FPGA学习的正确步骤:零基础小白入门到精通的详细指南(2025版)

从零开始掌握FPGA开发!本文详解数字电路基础、Verilog语法、Vi…
技术分享
1年前
0
0
415
3
FPGA有限状态机(FSM)设计实践指南:三段式与二段式编码风格对比与实现

FPGA有限状态机(FSM)设计实践指南:三段式与二段式编码风格对比与实现

有限状态机(FiniteStateMachine,FSM)是数字逻…
技术分享
15天前
0
0
26
0
评论表单游客 您好,欢迎参与讨论。
加载中…
评论列表
总数:0
FPGA线上课程平台|最全栈的FPGA学习平台|FPGA工程师认证培训
没有相关内容