1、创建vivado工程

“xc7z100ffg900-2”型号
在这里插入图片描述

2、使用 IP Integrator 创建 Processing System

接下来我们将在IP集成器中完成ZYNQ嵌入式系统的搭建

  1. 在左侧导航栏(Flow Navigator)中,单击IP Integrator 下的Create Block Design。然后在弹出的对
    话框中指定所创建的Block Design的名称,在Design name栏中输入“system”,Directory和Specify source
    set 保持默认即可,然后点击“OK”
    在这里插入图片描述
  2. 接下来在Diagram窗口中给设计添加 IP。点击上图中箭头所指示的加号“+”,会打开IP目录(IP
    Catalog),也可以通过快捷键Ctrl + I,或者右键点击Diagram工作区中的空白位置,然后选择“ADD IP”。
    打开IP目录后,在搜索栏中键入“zynq”,找到并双击“ZYNQ7 Processing System”,将ZYNQ7
    处理系统IP添加到设计中
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
  3. 配置PS的DDR3控制器
    在这里插入图片描述
  4. 配置PS的时钟
    在这里插入图片描述
  5. 关于PS中与PL端交互的接口信号
    在这里插入图片描述
    在这里插入图片描述

3、使用 Vitis HLS生成VIT的IP核

#include <ap_fixed.h>
#include <ap_int.h>

// 定义数据类型:16位定点数(6位整数,10位小数)
typedef ap_fixed<16, 6> data_t;

// 定义算子维度 32x32
#define DIM 32

// 顶层函数 - 名字已改为 vit,与你的项目设置匹配
void vit(
    data_t external_input[DIM],  // 外部输入
    data_t output[DIM],          // 计算结果
    ap_uint<2> mode,             // 模式:0-外部, 1-内建Patch1, 2-内建Patch2
    ap_uint<1> *trigger          // TDC 触发信号引脚
) {
    // --- 接口协议定义 ---
    #pragma HLS INTERFACE s_axilite port=external_input bundle=control
    #pragma HLS INTERFACE s_axilite port=output bundle=control
    #pragma HLS INTERFACE s_axilite port=mode bundle=control
    #pragma HLS INTERFACE s_axilite port=return bundle=control
    #pragma HLS INTERFACE ap_none port=trigger

    // --- 1. 静态权重矩阵 (1024个数据) ---
    // 使用宏自动生成 32x32 的填充数据
    static const data_t weights[DIM][DIM] = {
        #define R4(n) n*0.11, n*(-0.21), n*0.31, n*(-0.41)
        #define R8(n) R4(n), R4(n+1)
        #define R16(n) R8(n), R8(n+2)
        #define R32(n) R16(n), R16(n+4)
        R32(1), R32(2), R32(3), R32(4), R32(5), R32(6), R32(7), R32(8),
        R32(9), R32(10), R32(11), R32(12), R32(13), R32(14), R32(15), R32(16),
        R32(-1), R32(-2), R32(-3), R32(-4), R32(-5), R32(-6), R32(-7), R32(-8),
        R32(-9), R32(-10), R32(-11), R32(-12), R32(-13), R32(-14), R32(-15), R32(-16)
    };

    // --- 2. 内建测试 Patch (2组各32个数据) ---
    static const data_t internal_patch1[DIM] = {
        0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0,
        1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0,
        2.1, 2.2, 2.3, 2.4, 2.5, 2.6, 2.7, 2.8, 2.9, 3.0, 3.1, 3.2
    };
    static const data_t internal_patch2[DIM] = {
        -3.2, -3.1, -3.0, -2.9, -2.8, -2.7, -2.6, -2.5, -2.4, -2.3,
        -2.2, -2.1, -2.0, -1.9, -1.8, -1.7, -1.6, -1.5, -1.4, -1.3,
        -1.2, -1.1, -1.0, -0.9, -0.8, -0.7, -0.6, -0.5, -0.4, -0.3, -0.2, -0.1
    };

    // --- 3. 输入缓冲与选择 ---
    data_t current_input[DIM];
    #pragma HLS ARRAY_PARTITION variable=current_input complete

    if (mode == 1) {
        for(int k=0; k<DIM; k++) current_input[k] = internal_patch1[k];
    } else if (mode == 2) {
        for(int k=0; k<DIM; k++) current_input[k] = internal_patch2[k];
    } else {
        for(int k=0; k<DIM; k++) current_input[k] = external_input[k];
    }

    // --- 4. 触发信号拉高:计算正式开始 ---
    *trigger = 1;

    // --- 5. 核心 32x32 矩阵乘法 ---
    // 完全展开循环,确保 1024 个 DSP 单元在相近时间点翻转
    for (int i = 0; i < DIM; i++) {
        #pragma HLS UNROLL
        data_t sum = 0;
        for (int j = 0; j < DIM; j++) {
            #pragma HLS UNROLL
            sum += current_input[j] * weights[i][j];
        }
        output[i] = sum;
    }

    // --- 6. 计算结束:拉低触发信号 ---
    *trigger = 0;
}

导出IP核时由于时间戳溢出报错
需要打补丁,教程见该链接 Xilinx系列bug
然后把这个生成的IP核导入block design

4、生成TDC IP核

在这里插入图片描述

5、生成顶层HDL模块

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

6、软件设计

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
main.c代码如下:

#include <stdio.h>
#include "platform.h"
#include "xil_printf.h"
#include "xvit.h"       // HLS 生成的驱动
#include "xparameters.h" // 包含硬件基地址信息

// 实例定义
XVit VitInst;

int main()
{
    init_platform();
    printf("--- ViT Side-Channel Experiment: Started ---\n\r");

    int status;
    // 1. 初始化 IP 核
    // 注意:这里的 XPAR_VIT_0_DEVICE_ID 需检查 xparameters.h 是否对应
    status = XVit_Initialize(&VitInst, XPAR_VIT_0_DEVICE_ID);
    if (status != XST_SUCCESS) {
        printf("Error: ViT Initialization Failed!\n\r");
        return -1;
    }

    // 2. 准备数据
    // 虽然 HLS 内部是 ap_fixed<16,6>,但 AXI 总线传输的是 32 位 Word (u32)
    u32 my_input[32];
    u32 my_output[32];

    // 初始化输入数据(比如设置为全 1 的定点数表示,或者任意随机值)
    for(int i = 0; i < 32; i++) {
        my_input[i] = 0x0040; // 这是一个示例定点数值
    }

    // 3. 将输入数据写入 IP 核内部缓冲区
    // 对应 xvit.h 第 97 行
    XVit_Write_external_input_Words(&VitInst, 0, my_input, 32);

    // 4. 设置运行模式
    // Mode 0: 外部数据 (my_input)
    // Mode 1: 内置 Patch 1
    // Mode 2: 内置 Patch 2
    XVit_Set_mode(&VitInst, 1);

    // 5. 启动计算 (核心触发点)
    // 执行这一行时,PL 端的 trigger 引脚会立刻拉高,ILA 开始记录 TDC
    XVit_Start(&VitInst);
    printf("ViT Op Triggered. Calculating...\n\r");

    // 6. 等待硬件计算完成
    while (!XVit_IsDone(&VitInst));

    // 7. 读取结果 (使用正确的带 _r 的函数名)
    // 对应 xvit.h 第 108 行
    XVit_Read_output_r_Words(&VitInst, 0, my_output, 32);

    printf("Calculation Finished! Output[0] = %08x\n\r", (unsigned int)my_output[0]);

    cleanup_platform();
    return 0;
}

在这里插入图片描述
在这里插入图片描述

7、下载验证

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

Logo

openvela 操作系统专为 AIoT 领域量身定制,以轻量化、标准兼容、安全性和高度可扩展性为核心特点。openvela 以其卓越的技术优势,已成为众多物联网设备和 AI 硬件的技术首选,涵盖了智能手表、运动手环、智能音箱、耳机、智能家居设备以及机器人等多个领域。

更多推荐