首页 > 其他分享 >PS端UpSample函数实现

PS端UpSample函数实现

时间:2023-08-22 20:00:58浏览次数:32  
标签:PS 函数 int UpSample 发送 数据 PL

PS端UpSample函数实现

目的

  • 在PS端dingyi一个函数,实现对PL端的UpSample模块的调用,完成对输入数据的上采样操作
  • UpSample模块的功能是将输入的13x13x128的数据上采样为26x26x128的数据,保持通道数不变
  • UpSample模块在YOLO网络中只有一层,位于第19层

步骤

  • 在PS端定义函数upsample_task

    • 在状态机中判断i==11时调用该函数
    • 在该函数中分为三个步骤:
      • 发送数据给PL端
      • 发送UpSample命令给PL端
      • 接收PL端返回的数据
  • 发送数据给PL端

    • 使用DMA写操作,将layer18的输出数据(13x13x128)发送给PL端
    • 发送地址为0x3000000,发送长度为0x548(1352字节)
    • 发送前需要发送ZeroPointIn命令,将ZeroPointIn设置为0(因为不需要减去ZeroPoint
  • 发送UpSample命令给PL端

    • 使用FUTURE_WRITE操作,将0x00000001写入0x40000000地址(对应计算器2的命令寄存器)
    • 这个命令会触发PL端的UpSample模块开始工作
  • 接收PL端返回的数据

    • 使用DMA读操作,从PL端读取上采样后的数据(26x26x128)
    • 读取地址为0x3100000,读取长度为0x1520(5408字节)
    • 由于输入通道数为128,需要分16次循环读取,每次读取8个通道的数据
    • 每次循环后,更新发送地址和接收地址

    由于输入数据有128个通道,而每次只能发送8个通道的数据,所以需要循环16次执行第二步中的三个子步骤,并且每次更新发送和接收的地址

例子

  • 假设layer18的输出数据为:
通道 数据
0 [1, 2, 3, …, 169]
1 [170, 171, 172, …, 338]
127 [21506, 21507, 21508, …, 21674]
  • 则发送给PL端的数据为:
地址 数据
0x3000000 [1, 2, 3, …, 169]
0x3000054 [170, 171, 172, …, 338]
0x30004FC [21506, 21507, 21508, …, 21674]
  • PL端接收到数据后,根据UpSample命令,将每个元素复制四次,形成26x26的矩阵,例如:
输入 输出
[1, 2, …, 13] [1, 1, 2, 2, …, 12, 12, 13, 13]
[157, …, 169] [157, 157, …, 168, 168, 169, 169]
  • PL端将上采样后的数据放到AXI接口上,等待PS端读取,例如:
地址 数据
0x3100000 [1, 1, …, 13, 13]
0x310151C [21662, …,21674]
  • PS端从PL端读取数据,每次读取8个通道的数据,共16次循环,例如:
循环次数 发送地址 接收地址 数据长度
i=0 0x3000000 0x3100000 0x1520
i=1 0x3000548 0x3101520 0x1520
i=15 0x3004FC8 0x3114F20 0x1520

image

流程(a):

graph TD A[修改 PL 端代码] --> B[生成bit文件] B --> C[定义 PS 端函数] C --> D[判断当前层] D -->|是| E[调用 UpSample 函数] D -->|否| F[执行状态机操作] E --> G[发送数据给 PL 端] G --> H[发送 UpSample 命令] H --> I[接收 PL 端数据] I --> J[存储到 layer 19 缓存] J --> K[验证结果]

流程(b):

sequenceDiagram participant PS participant PL Note over PS: 初始化参数和地址 loop i = 0 to 15 PS->>PL: 发送第 i 组数据 (8 个通道, 13x13) PS->>PL: 发送 Zero point 命令 (Zero point in = 0) PS->>PL: 发送 UpSample 命令 PL->>PS: 返回第 i 组数据 (8 个通道, 26x26) end Note over PS: 检查结果并导出 bit 文件
  • PL 端的 UpSample 模块代码:在 PL 端编写 UpSample 模块,该模块可以接收 PS 端发送的 13x13 的数据,并将其上采样为 26x26 的数据,然后通过 AXI 接口输出。修改一些参数和频率,以及生成比特文件
  • PS 端的 UpSample 函数代码:在 PS 端编写 UpSample 函数,该函数可以将输入的 128 个通道的 13x13 的数据分成 16 组,每组 8 个通道,然后依次发送给 PL 端的 UpSample 模块,并接收返回的 26x26 的数据。设置一些地址和长度,以及发送 Zero point 命令
  • PS 端的 UpSample 函数调试:在 VITIS 中设置调试选项,下载比特文件,运行程序,并检查结果。比较 PS 端接收到的数据和期望的数据之间的差异

代码框架:

void upsample_task() {
    // 定义配置参数
    int input_channel = 128;
    int output_channel = 128;
    int input_size = 13;
    int output_size = 26;

    // 定义发送和接收地址
    int tx_addr = TX_BASE_ADDR; // 假设 TX_BASE_ADDR 是 0x3000000
    int rx_addr = RX_BASE_ADDR; // 假设 RX_BASE_ADDR 是 0x3100000

    // 定义发送和接收长度
    int tx_len = input_size * input_size * 8; // 每次发送8个通道的数据
    int rx_len = output_size * output_size * 8; // 每次接收8个通道的数据

    // 定义命令和中断信号
    int upsample_cmd = 0x00000001; // 表示执行UpSample操作
    int zero_point_in_cmd = 0x00000000; // 表示Zero point in为0
    int interrupt_sig; // 表示中断信号

    // 使用 for 循环处理所有通道的数据
    for (int i = 0; i < input_channel / 8; i++) {
        // 发送数据给 PL 端
        dma_write(tx_addr, tx_len, input_data); // 假设 input_data 是 PS 端的输入数据
        // 发送命令给 PL 端
        axi_lite_write(0x43C00000, upsample_cmd); // 假设 0x43C00000 是 PL 端的命令地址
        axi_lite_write(0x43C00004, zero_point_in_cmd); // 假设 0x43C00004 是 PL 端的 Zero point in 地址
        // 接收数据从 PL 端
        dma_read(rx_addr, rx_len, output_data); // 假设 output_data 是 PS 端的输出数据
        // 接收中断信号从 PL 端
        axi_lite_read(0x43C00008, interrupt_sig); // 假设 0x43C00008 是 PL 端的中断信号地址
        // 更新发送和接收地址
        tx_addr += tx_len;
        rx_addr += rx_len;
    }
}

标签:PS,函数,int,UpSample,发送,数据,PL
From: https://www.cnblogs.com/LiamJacob/p/17649556.html

相关文章

  • IDS和IPS基础知识
    一.IDS和IPSIDS(IntrusionDetectionSystems):入侵检测系统,是一种网络安全设备或应用软件,可以依照一定的安全策略,对网络、系统的运行状况进行监视,可以发现各种攻击行为并发出安全警报。IPS(IntrusionPreventionSystem):入侵防御系统,具有IDS的监控检测功能之外,还可以深度感知检......
  • 无涯教程-PHP - eregi_replace()函数
    eregi_replace()-语法stringeregi_replace(stringpattern,stringreplacement,stringoriginalstring);eregi_replace()函数的操作与ereg_replace()完全相同,只是在字符串中搜索模式不区分大小写。eregi_replace()-返回值发生替换后,将返回修改后的字符串。如果未......
  • 16.exec函数详解
    16.exec函数详解1.exec函数说明fork函数是用于创建一个子进程,该子进程几乎是父进程的副本,而有时我们希望子进程去执行另外的程序,exec函数族就提供了一个在进程中启动另一个程序执行的方法。它可以根据指定的文件名或目录名找到可执行文件,并用它来取代原调用进程的数据段、代码段......
  • 14.linux命令ps
    14.linux命令ps1.psaux对进程进行监测和控制,首先必须要了解当前进程的情况,也就是需要查看当前进程,而ps命令(ProcessStatus)就是最基本同时也是非常强大的进程查看命令。使用该命令可以确定有哪些进程正在运行和运行的状态、进程是否结束、进程有没有僵尸、哪些进程占用了过......
  • 13.Linux中fork函数详解(附图解与代码实现)
    13.Linux中fork函数详解(附图解与代码实现)我们先来看个代码,判断一下这个代码的输出结果会是什么样的,先不要去看运行结果,判断好后再去看看是否和你的预期结果一致。#include<stdio.h>#include<unistd.h>#include<stdlib.h>#include<string.h>intmain(void){ pid_tpid; ......
  • C++11 lambda函数
    在数理逻辑或计算机科学领域中lambda是被用来表示一种匿名函数,这种匿名函数代表了一种所谓的λ演算(lambdacalculus)。intmain(){intgirls=3,boys=4;autototalChild=[](intx,inty)->int{returnx+y;};returntotalChild(girls,boys);}该函数接受两个参数......
  • 无涯教程-PHP - ereg()函数
    ereg()-语法intereg(stringpattern,stringoriginalstring,[arrayregs]);ereg()函数在string指定的字符串中搜索pattern指定的字符串,如果找到pattern,则返回true,否则返回false。搜索对于字母字符区分大小写。可选的输入参数regs包含一个由正则表达式中的括号分组的所有......
  • 5.5 汇编语言:函数调用约定
    函数是任何一门高级语言中必须要存在的,使用函数式编程可以让程序可读性更高,充分发挥了模块化设计思想的精髓,今天我将带大家一起来探索函数的实现机理,探索编译器到底是如何对函数这个关键字进行实现的,并使用汇编语言模拟实现函数编程中的参数传递调用规范等。说到函数我们必须要提......
  • 15 JavaScript ES6中的箭头函数
    15JavaScriptES6中的箭头函数什么是箭头函数ES6中允许使用=>来定义函数。箭头函数相当于匿名函数,并简化了函数定义。基本语法//箭头函数letfn=(name)=>{//函数体return`Hello${name}!`;};//等同于letfn=function(name){//函数体......
  • 5.5 汇编语言:函数调用约定
    函数是任何一门高级语言中必须要存在的,使用函数式编程可以让程序可读性更高,充分发挥了模块化设计思想的精髓,今天我将带大家一起来探索函数的实现机理,探索编译器到底是如何对函数这个关键字进行实现的,并使用汇编语言模拟实现函数编程中的参数传递调用规范等。说到函数我们必须要提......