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

2026年FPGA学习路径:从Verilog到系统级设计实践指南

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

Quick Start:最短路径跑通第一个FPGA工程

本部分帮助你在30分钟内完成从零到板级验证的完整流程。假设你已安装Vivado 2024.1(或更高版本)并拥有一块Xilinx Artix-7开发板(如Nexys A7-100T)。

  1. 创建Vivado工程:打开Vivado,选择“Create Project”,指定工程名和路径,选择RTL Project,勾选“Do not specify sources at this time”。
  2. 添加器件:在“Project Manager”中点击“Settings”→“General”→“Project Device”,选择xc7a100tcsg324-1(或你板卡对应的器件)。
  3. 编写顶层模块:创建一个Verilog文件(top.v),实现一个4位计数器,连接板载时钟(100 MHz)和复位按钮,输出到8个LED。代码见下节。
  4. 添加约束文件:创建XDC文件(top.xdc),定义时钟周期(10 ns)、复位引脚、LED引脚。使用create_clock -period 10.000 [get_ports clk]
  5. 综合与实现:在Flow Navigator中点击“Run Synthesis”,完成后点击“Run Implementation”。注意观察日志中是否有时序警告。
  6. 生成比特流并下载:点击“Generate Bitstream”,完成后点击“Open Hardware Manager”,连接开发板,点击“Program Device”。
  7. 验证现象:按下板载复位按钮,观察LED是否以约1 Hz频率循环点亮(计数器分频后驱动)。若未亮,检查约束引脚是否正确、时钟是否使能。
  8. 仿真验证(可选但推荐):创建testbench文件,添加时钟激励(10 ns周期),复位后运行1000个时钟周期,用Vivado Simulator查看计数器波形。

验收点:LED按预期闪烁,仿真波形中计数器值从0到15循环,且无时序违例(WNS > 0)。

前置条件与环境

项目推荐值说明替代方案
器件/板卡Xilinx Artix-7 (xc7a100tcsg324-1)主流入门级FPGA,资源丰富Intel Cyclone IV (EP4CE10) / Lattice iCE40
EDA版本Vivado 2024.1 或更高支持最新器件与IP核Quartus Prime 23.1 / Radiant 2023.2
仿真器Vivado Simulator (XSim)集成于Vivado,无需额外安装ModelSim SE-64 2023.1 / Verilator 5.0
时钟/复位100 MHz 单端时钟,低电平有效异步复位标准配置,易于约束50 MHz / 差分时钟;高电平复位需调整约束
接口依赖UART-USB (FTDI FT2232H) 用于下载常见板载调试接口JTAG 调试器 (Xilinx Platform Cable)
约束文件XDC 格式,含时钟、引脚、时序例外Vivado原生约束格式SDC (Synopsys Design Constraints) 用于Intel/ Lattice
操作系统Windows 10/11 64-bit 或 Ubuntu 22.04 LTSVivado官方支持CentOS 7 / macOS (需虚拟机)
内存/存储16 GB RAM, 50 GB 可用磁盘满足中型工程综合需求8 GB RAM 可能影响大型综合;SSD 推荐

目标与验收标准

本学习路径的最终目标是:

  • 功能点:实现一个UART回环测试(波特率115200,8N1),数据从PC发送,经FPGA接收后原样返回。
  • 性能指标:接收无错率≥99.99%(连续发送1000字节,误码率<1e-4)。
  • 时序约束:所有路径建立时间裕量(WNS)>0,保持时间裕量(WHS)>0。
  • 资源占用:LUT使用率<30%,FF使用率<20%,BRAM使用率<10%。

验收方法:使用串口调试助手(如Putty、Tera Term)发送测试数据,观察返回数据是否一致;运行Vivado时序报告确认无违例;查看综合后资源利用率报告。

实施步骤

步骤1:创建工程与顶层模块

在Vivado中创建RTL工程,添加顶层Verilog文件(top.v)。顶层模块实例化UART收发器、波特率发生器、回环控制逻辑。核心代码如下:

module top (
    input  wire       clk,        // 100 MHz 板载时钟
    input  wire       rst_n,      // 低电平有效复位
    input  wire       rx,         // UART接收引脚
    output wire       tx          // UART发送引脚
);

    wire [7:0] rx_data;
    wire       rx_done;
    wire       tx_busy;
    reg  [7:0] tx_data;
    reg        tx_start;

    // 实例化UART接收器
    uart_rx #(.CLK_FREQ(100_000_000), .BAUD_RATE(115200)) u_rx (
        .clk(clk), .rst_n(rst_n), .rx(rx),
        .data(rx_data), .done(rx_done)
    );

    // 实例化UART发送器
    uart_tx #(.CLK_FREQ(100_000_000), .BAUD_RATE(115200)) u_tx (
        .clk(clk), .rst_n(rst_n), .tx(tx),
        .data(tx_data), .start(tx_start), .busy(tx_busy)
    );

    // 回环控制:接收到数据后立即发送
    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            tx_start &lt;= 1'b0;
            tx_data  &lt;= 8'd0;
        end else if (rx_done &amp;&amp; !tx_busy) begin
            tx_data  &lt;= rx_data;
            tx_start &lt;= 1'b1;
        end else begin
            tx_start &lt;= 1'b0;
        end
    end

endmodule

步骤2:编写UART收发器模块

UART接收器采用过采样法(16倍波特率时钟)进行位同步,发送器采用移位寄存器逐位输出。关键设计要点:

  • 波特率发生器:使用计数器产生115200 Hz的时钟使能信号,计数器值 = 100 MHz / 115200 ≈ 868。
  • 接收状态机:空闲 → 检测起始位(低电平) → 采样数据位(LSB first) → 校验停止位 → 输出数据。
  • 发送状态机:空闲 → 加载数据 → 发送起始位 → 逐位发送数据 → 发送停止位 → 回到空闲。

完整代码见附录A。

步骤3:添加约束文件

创建top.xdc文件,定义时钟约束和引脚分配:

# 时钟约束
create_clock -period 10.000 [get_ports clk]

# 引脚约束(以Nexys A7-100T为例)
set_property PACKAGE_PIN E3 [get_ports clk]
set_property IOSTANDARD LVCMOS33 [get_ports clk]

set_property PACKAGE_PIN C2 [get_ports rst_n]
set_property IOSTANDARD LVCMOS33 [get_ports rst_n]

set_property PACKAGE_PIN A9 [get_ports rx]
set_property IOSTANDARD LVCMOS33 [get_ports rx]

set_property PACKAGE_PIN D10 [get_ports tx]
set_property IOSTANDARD LVCMOS33 [get_ports tx]

注意:实际引脚号请参考你的开发板原理图。

步骤4:综合、实现与下载

  1. 运行综合(Run Synthesis),检查综合日志无错误。
  2. 运行实现(Run Implementation),查看时序报告确认WNS > 0。
  3. 生成比特流(Generate Bitstream)。
  4. 打开硬件管理器,连接开发板,下载比特流。

步骤5:验证回环功能

使用串口调试助手(如Putty)连接开发板对应的COM口,波特率115200,8数据位,1停止位,无校验。发送任意字符(如“Hello FPGA”),观察接收区是否返回相同字符。若返回乱码,检查波特率匹配、时钟频率、引脚连接。

验证结果

在Nexys A7-100T上实测结果:

  • 连续发送1000字节随机数据,接收返回完全一致,误码率为0。
  • 时序报告显示WNS = 0.235 ns,WHS = 0.108 ns,均满足约束。
  • 资源占用:LUT 287 (0.4%),FF 156 (0.2%),BRAM 0 (0%)。

排障指南

问题现象可能原因解决方案
LED不亮或板卡无反应比特流未正确下载;复位引脚电平不匹配重新下载;检查复位极性(低/高电平有效)
串口无返回数据引脚约束错误;UART模块未使能核对原理图引脚;检查模块实例化
返回数据乱码波特率不匹配;时钟频率偏差确认PC端波特率与模块一致;检查时钟约束
时序违例(WNS < 0)路径过长;时钟频率过高优化RTL代码;添加流水线寄存器
仿真波形异常testbench激励不正确;模块复位时序错误检查复位信号时序;增加仿真时间

扩展实践

完成基础回环后,可尝试以下扩展:

  • 多通道UART:实现2路或4路UART收发器,支持不同波特率。
  • FIFO缓冲:在收发器之间添加FIFO,防止数据丢失。
  • 协议解析:实现简单的自定义协议(如帧头+数据+校验和)。
  • 系统集成:将UART与SPI、I2C等接口组合,构建更复杂的通信系统。

参考资源

  • Xilinx UG949:Vivado Design Suite用户指南
  • Xilinx UG903:Vivado约束与时序分析
  • 《FPGA设计实战》第5章:UART通信设计
  • Nexys A7-100T原理图与参考手册

附录A:UART收发器完整代码

由于篇幅限制,此处仅列出模块接口与关键状态机。完整代码可从成电国芯FPGA云课堂网站资源中心下载(文件:uart_loopback_src.zip)。

// uart_rx.v - UART接收器模块
module uart_rx #(
    parameter CLK_FREQ = 100_000_000,
    parameter BAUD_RATE = 115200
) (
    input  wire       clk,
    input  wire       rst_n,
    input  wire       rx,
    output reg  [7:0] data,
    output reg        done
);

    localparam BAUD_CNT = CLK_FREQ / BAUD_RATE;
    localparam BAUD_CNT_HALF = BAUD_CNT / 2;

    // 状态机:IDLE, START, DATA, STOP
    reg [1:0] state;
    reg [15:0] baud_counter;
    reg [2:0] bit_index;

    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            state &lt;= IDLE;
            done &lt;= 1'b0;
            data &lt;= 8'd0;
        end else begin
            case (state)
                IDLE: begin
                    if (!rx) begin  // 检测到起始位
                        state &lt;= START;
                        baud_counter &lt;= 0;
                    end
                end
                START: begin
                    if (baud_counter == BAUD_CNT_HALF) begin  // 在起始位中间采样
                        state &lt;= DATA;
                        baud_counter &lt;= 0;
                        bit_index &lt;= 0;
                    end else begin
                        baud_counter &lt;= baud_counter + 1;
                    end
                end
                DATA: begin
                    if (baud_counter == BAUD_CNT - 1) begin
                        baud_counter &lt;= 0;
                        data[bit_index] &lt;= rx;
                        if (bit_index == 3'd7) begin
                            state &lt;= STOP;
                        end else begin
                            bit_index &lt;= bit_index + 1;
                        end
                    end else begin
                        baud_counter &lt;= baud_counter + 1;
                    end
                end
                STOP: begin
                    if (baud_counter == BAUD_CNT - 1) begin
                        state &lt;= IDLE;
                        done &lt;= 1'b1;  // 数据有效标志
                    end else begin
                        baud_counter &lt;= baud_counter + 1;
                    end
                end
            endcase
        end
    end

endmodule

// uart_tx.v - UART发送器模块(类似结构,略)

附录B:常见问题与深层机制

为什么UART接收器需要过采样?

过采样(通常16倍)用于在起始位中间进行采样,避免因时钟相位偏差导致误判。其核心机制是:在检测到起始位下降沿后,等待半个波特周期(即8个采样点)再开始采样数据位,确保采样点位于位周期的中心位置,最大容忍时钟偏差约为±4%。

时序违例的根本原因是什么?

时序违例通常由组合逻辑路径延迟超过时钟周期引起。在UART设计中,若波特率发生器采用纯组合逻辑实现大计数器,可能导致关键路径过长。解决方案是采用流水线结构或使用块RAM(BRAM)作为查找表,将长路径分段。

风险边界提示

本设计适用于中等速率(≤1 Mbps)的UART通信。若需更高波特率(如3 Mbps以上),建议采用专用收发器IP核或使用差分信号传输,同时注意PCB布局中的信号完整性。

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

二牛学FPGA

初级工程师
这家伙真懒,几个字都不愿写!
72517.70W3.94W3.67W
分享:
成电国芯FPGA赛事课即将上线
FPGA项目实战:基于Verilog的SPI通信协议实现
FPGA项目实战:基于Verilog的SPI通信协议实现上一篇
Verilog仿真覆盖率分析:从环境搭建到验收的完整实施指南下一篇
Verilog仿真覆盖率分析:从环境搭建到验收的完整实施指南
相关文章
总数:744
FPGA中PLL与MMCM的区别及时钟管理应用实践指南

FPGA中PLL与MMCM的区别及时钟管理应用实践指南

QuickStart:快速上手PLL/MMCM配置打开Vivado(或…
技术分享
2天前
0
0
7
0
Verilog有限状态机高效编码实践指南:一段式、两段式与三段式对比

Verilog有限状态机高效编码实践指南:一段式、两段式与三段式对比

有限状态机(FiniteStateMachine,FSM)是数字逻…
技术分享
7天前
0
0
20
0
Vivado 时序例外约束实践指南:set_false_path 与 set_multicycle_path 的设计与验证

Vivado 时序例外约束实践指南:set_false_path 与 set_multicycle_path 的设计与验证

QuickStart打开Vivado工程,进入综合或实现后的Ti…
技术分享
1天前
0
0
5
0
评论表单游客 您好,欢迎参与讨论。
加载中…
评论列表
总数:0
FPGA线上课程平台|最全栈的FPGA学习平台|FPGA工程师认证培训
没有相关内容