第二章:开发环境搭建——Vivado安装与配置、IP核管理、Verilog基础回顾

好,咱们正式开始动手了。这一章我带你搭好开发环境。说白了,工欲善其事,必先利其器。Vivado 就是我们手里的那把“器”。

很多新手一上来就急着写代码,结果环境没配好,跑个仿真都报错,心态直接崩了。我刚开始用 Vivado 时也踩过不少坑,今天把这些经验都抖出来,你照着做就行。

2.1 Vivado 安装与配置

Vivado 是 Xilinx 家的官方工具,版本迭代很快。我个人习惯用 Vivado 2021.12022.2,这两个版本比较稳定,社区资源也多。

2.1.1 下载与安装

去 Xilinx 官网下载 WebPACK 版本就行,免费的,功能足够我们做脉冲输出和编码器接口。安装时注意几点:

  • 磁盘空间:至少留 100GB,Vivado 全家桶装完大概 60-80GB。
  • 操作系统:Windows 10/11 或 Ubuntu 18.04/20.04 都行。我个人更推荐 Linux,跑大型工程时稳定很多。
  • 安装路径:不要有中文!不要有空格!我见过有人装在“D:\程序\Vivado”下,结果编译报错找半天原因。
⚠️ 避坑指南
我曾经因为磁盘空间不足,安装到一半卡死,强制退出后注册表乱了,最后重装系统才解决。所以,安装前一定检查磁盘剩余空间。

2.1.2 配置要点

装完后,第一件事是配置 Vivado 的环境变量。如果你用 Windows,把安装目录下的 bin 文件夹加到 PATH 里。这样你就能在命令行里直接敲 vivado 启动了。

第二件事,设置 默认工程路径。在 Vivado 的 Settings 里,把 Default Project Directory 改到一个好找的位置。我习惯放在 D:/FPGA_Projects/,每个工程一个文件夹,命名规则是 日期_项目名,比如 20250215_PulseOutput

💡 小技巧
打开 Vivado 后,先点 Help → About → Manage Licenses,确认 License 状态。如果是 WebPACK 版本,不需要额外 License,但如果是申请了 Node-Locked License,记得把 MAC 地址填对。

2.2 IP 核管理

IP 核,说白了就是 Xilinx 帮你写好的功能模块。你想想看,如果每个计数器、每个 FIFO 都要自己从头写,那得累死。Vivado 里集成了大量 IP 核,我们直接拿来用就行。

2.2.1 如何添加 IP 核

在 Vivado 的 IP Catalog 里搜索你要的 IP。比如我们要做脉冲输出,可能会用到 Clocking Wizard(时钟管理)或 Counter(计数器)。

双击 IP 核,会弹出配置界面。这里要注意:配置参数一定要和你的设计匹配。比如 Clocking Wizard 里,输入时钟是 50MHz,你想要输出 100MHz,那就把倍频系数设成 2。

🔑 核心要点
IP 核配置完成后,Vivado 会生成一个 .xci 文件。这个文件就是 IP 核的“身份证”,不要手动删除或改名。我见过有人为了“整理文件”,把 .xci 文件挪了位置,结果工程打不开。

2.2.2 自定义 IP 核

有时候官方 IP 核不够用,比如我们要做一个 编码器四倍频解码模块,官方没有现成的。这时候可以自己封装一个 IP 核。

步骤很简单:

  1. 写好 Verilog 代码,仿真通过。
  2. 在 Vivado 里点 Tools → Create and Package New IP
  3. 选择 Package your current project,把代码打包成 IP。
  4. 以后在其他工程里,直接就能在 IP Catalog 里找到它。

我个人习惯把常用的模块都封装成 IP,比如 PWM 发生器SPI 接口编码器接口。这样新项目启动时,直接拖 IP 核,省时省力。

2.3 硬件描述语言基础回顾

Verilog 和 VHDL,你至少得会一个。我个人更常用 Verilog,因为语法简洁,社区资源多。但如果你公司要求用 VHDL,那也没问题,核心思想是一样的。

2.3.1 Verilog 基础结构

一个完整的 Verilog 模块长这样:

module pulse_generator (
    input  wire       clk,      // 系统时钟
    input  wire       rst_n,    // 异步复位,低有效
    input  wire [7:0] period,   // 脉冲周期
    output reg        pulse_out // 脉冲输出
);

    reg [7:0] cnt;

    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            cnt <= 8'd0;
            pulse_out <= 1'b0;
        end else begin
            if (cnt == period - 1) begin
                cnt <= 8'd0;
                pulse_out <= 1'b1;
            end else begin
                cnt <= cnt + 1;
                pulse_out <= 1'b0;
            end
        end
    end

endmodule

这段代码实现了一个可配置周期的脉冲发生器。注意看 always 块里的写法:posedge clk or negedge rst_n,这是标准的异步复位写法。我刚开始学的时候,总把 negedge rst_n 写成 posedge rst_n,结果复位一直不生效,仿真跑出来全是 X 态。

2.3.2 阻塞赋值 vs 非阻塞赋值

这是新手最容易搞混的地方。简单说:

  • 阻塞赋值(=):用在组合逻辑中,比如 assign 语句或 always @(*) 块里。
  • 非阻塞赋值(<=):用在时序逻辑中,比如 always @(posedge clk) 块里。

为什么会这样?因为非阻塞赋值能避免 竞争冒险。我曾经在一个项目里,把时序逻辑里的 <= 写成了 =,结果仿真波形看起来没问题,上板后计数器乱跳。查了两天才发现是赋值方式错了。

⚠️ 避坑指南
永远不要在同一个 always 块里混用阻塞和非阻塞赋值。这是铁律,没有例外。

2.3.3 参数化设计

好的 Verilog 代码应该是可配置的。比如上面的脉冲发生器,如果把 period 写成固定值 100,那换个场景就得改代码。用 parameter 可以解决这个问题:

module pulse_generator #(
    parameter WIDTH = 8
) (
    input  wire             clk,
    input  wire             rst_n,
    input  wire [WIDTH-1:0] period,
    output reg              pulse_out
);
    // 内部逻辑同上,只是把 8 改成了 WIDTH
endmodule

这样,例化时只要传不同的 WIDTH 值,就能生成不同位宽的计数器。我在做编码器接口时,经常用参数化设计来适配不同分辨率的编码器。

2.4 本章知识体系

下面这张图总结了本章的核心内容,你可以对照着检查自己掌握了多少:

开发环境搭建知识体系 Vivado 安装与配置 • 下载 WebPACK 版本 • 磁盘空间 ≥ 100GB • 路径无中文无空格 • 配置环境变量 • 设置默认工程路径 • 检查 License 状态 IP 核管理 • IP Catalog 搜索 • 配置参数匹配设计 • .xci 文件管理 • 自定义 IP 封装 • 常用模块 IP 化 • 跨工程复用 Verilog 基础回顾 • 模块结构定义 • 阻塞 vs 非阻塞赋值 • 时序逻辑写法 • 组合逻辑写法 • 参数化设计 • 异步复位同步释放 三者缺一不可,环境搭好才能高效开发

嗯,这一章的内容就这些。环境搭好了,语言基础也回顾了,接下来就可以真正开始写脉冲输出模块了。记住,工具只是手段,理解原理才是关键。


专注资料整理