2、Vivado HLS开发环境搭建:从安装到第一个工程

好,咱们正式开始动手了。这一章我带你走一遍 Vivado HLS 的环境搭建流程。说实话,很多新手在这第一步就栽跟头——不是装错了版本,就是工程路径带中文导致编译报错。别急,跟着我的节奏来,保证你半小时内跑通第一个 HLS 工程。

2.1 Vivado HLS 安装与配置

先说说版本选择。我个人习惯用 Vivado HLS 2020.1 之后的版本,因为对 C++ 标准的支持更完善。你如果只是学习,装个 WebPACK 版就够用,不用非得买 license。

⚠️ 避坑指南
我曾经因为装了 Vivado 2019.2 和 Modelsim 的冲突,折腾了两天。建议你安装前关闭杀毒软件,路径不要有中文和空格。比如 D:/Xilinx/Vivado 就挺好,别搞成 D:/软件/Vivado HLS。

安装步骤其实很简单:

  1. 从 Xilinx 官网下载 Vivado 安装包(包含 HLS 组件)
  2. 运行安装程序,勾选 Vivado HLS 和 Vitis HLS(2020.1 后统一了)
  3. 选择安装路径,建议 SSD 盘,编译会快很多
  4. 等待 20-30 分钟,去泡杯咖啡

装完后记得配置环境变量。打开终端,输入 vivado_hls -version,如果能显示版本号,说明装好了。嗯,这里要注意:Windows 用户最好用 Xilinx SDK Command Prompt 启动,别用普通的 cmd。

2.2 创建第一个 HLS 工程

来,咱们直接上手。打开 Vivado HLS,点击 Create New Project。你会看到这样一个界面:

Project name: first_hls
Location: D:/hls_projects
Top Function: matrix_mult

为什么顶层函数叫 matrix_mult?说白了,HLS 会把你的 C 函数综合成硬件模块,函数名就是模块名。我建议你起名时用下划线分隔,别用驼峰,因为生成的 RTL 文件名会直接拿函数名来用。

接着添加源文件。创建一个 matrix_mult.cpp:

#include "matrix_mult.h"

void matrix_mult(int A[4][4], int B[4][4], int C[4][4]) {
    #pragma HLS INTERFACE s_axilite port=return
    #pragma HLS INTERFACE bram port=A
    #pragma HLS INTERFACE bram port=B
    #pragma HLS INTERFACE bram port=C

    for (int i = 0; i < 4; i++) {
        for (int j = 0; j < 4; j++) {
            C[i][j] = 0;
            for (int k = 0; k < 4; k++) {
                C[i][j] += A[i][k] * B[k][j];
            }
        }
    }
}

再写个测试文件 matrix_mult_tb.cpp:

#include "matrix_mult.h"
#include <iostream>

int main() {
    int A[4][4] = {{1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,16}};
    int B[4][4] = {{1,0,0,0},{0,1,0,0},{0,0,1,0},{0,0,0,1}};
    int C[4][4] = {0};

    matrix_mult(A, B, C);

    // 验证结果
    for (int i = 0; i < 4; i++) {
        for (int j = 0; j < 4; j++) {
            if (C[i][j] != A[i][j]) {
                std::cout << "Error at [" << i << "][" << j << "]" << std::endl;
                return 1;
            }
        }
    }
    std::cout << "Test passed!" << std::endl;
    return 0;
}
💡 我的经验
测试文件一定要写!我见过太多人直接综合,结果上板后跑飞了才发现算法有 bug。HLS 的 C 仿真比 RTL 仿真快 100 倍,先在 C 层面把逻辑调通,能省下大把时间。

2.3 工程目录结构解析

综合完成后,看看工程目录长什么样。你想想看,一个 HLS 工程其实就几个关键文件夹:

目录/文件 作用
solution1/ 默认的解决方案目录,可以创建多个 solution 对比不同优化策略
solution1/csim/ C 仿真结果,里面有 build 目录存放编译中间文件
solution1/syn/ 综合结果,包含 verilog 和 vhdl 子目录
solution1/impl/ 实现结果(布局布线后的报告)
solution1/report/ 综合报告,里面有延迟、资源占用等关键数据
matrix_mult.cpp 你的源文件,HLS 会从这里提取顶层函数
matrix_mult_tb.cpp 测试文件,用于 C 仿真和 RTL 协同仿真

我个人习惯把 report/ 目录下的 csynth.rpt 文件重命名保存,每次优化后对比一下资源变化。说白了,这个报告就是你的成绩单——延迟多少、用了多少 LUT、多少 DSP,一目了然。

2.4 综合与仿真基础

好,到了最核心的部分。在 Vivado HLS 里,综合和仿真是两个完全不同的概念:

  • C 仿真:用你的测试文件在 PC 上跑一遍 C 代码,验证功能正确性
  • C 综合:把 C 函数翻译成 RTL 代码,生成硬件描述
  • RTL 仿真:用 Modelsim 或 Vivado Simulator 跑生成的 Verilog/VHDL 代码
  • RTL 协同仿真:用你的 C 测试文件驱动 RTL 仿真,自动对比结果

操作步骤很简单:

  1. 点击 Project → Run C Simulation,选择你的测试文件
  2. 看控制台输出,如果显示 Test passed! 就说明功能对了
  3. 点击 Solution → Run C Synthesis → Active Solution
  4. 等待几分钟,综合完成后会自动弹出报告
🔑 关键点
综合报告里的 Latency 和 Interval 是两个最重要的指标。Latency 是处理一次输入需要的时钟周期数,Interval 是两次输入之间的间隔。如果你的设计是流水线结构,Interval 会远小于 Latency。

我曾经犯过一个低级错误:综合报告显示资源占用 120%,我以为是代码写错了,折腾了半天才发现是目标芯片选错了。你想想看,你把 Zynq 的代码综合到 Artix 上,资源当然不够用。所以创建工程时一定要选对器件型号。

最后,看看我为你准备的本章知识体系图:

Vivado HLS 开发环境搭建知识体系 安装与配置 创建第一个工程 目录结构解析 综合与仿真基础 版本选择与下载 环境变量配置 License 设置 源文件编写 测试文件编写 顶层函数指定 solution 目录 syn/impl 目录 report 目录 C 仿真 C 综合 RTL 仿真 核心目标:从 C 代码到可上板的 RTL 实现

嗯,这一章的内容就到这。你跟着操作一遍,应该能跑通第一个 HLS 工程了。记住:环境搭建是基础,但别在这上面花太多时间——真正的大头在后面,比如流水线优化、数组分割这些高级技巧。

可可精品资料库