Skip to main content
欢迎来到PAWPAW技术文档网站了解更多信息

项目软件结构

本教程中构建的每个固件都是相同基本应用的变体。该应用程序在 xcore Explorer 开发板上运行,从主机机器读取一个 wav 文件,通过数字 FIR 滤波器处理 wav 文件的音频,并将处理后的音频写入主机机器上的新 wav 文件。

代码库

本教程有三个与之关联的 Git 代码库。

xmath_walkthrough 代码库包含教程的内容(包括文档和应用逻辑),并通过 west.yml 定义了工作空间的布局。

lib_xcore_math 代码库是一个用于在 xcore XS3 上进行快速算术运算的优化函数库。本教程的很大一部分是为了演示如何使用该库的各个部分。

xmos_cmake_toolchain 代码库包含了告诉 CMake 如何使用 xcore 工具链的样板.cmake文件。

xmath_walkthroughxmos_cmake_toolchain 代码库被克隆到教程工作空间的根目录。lib_xcore_math 代码库被克隆到 xmath_walkthrough 目录中(这简化了 CMake 项目的结构)。

本教程只使用了一个外部库,即 lib_xcore_math

lib_xcore_math 库包含了许多用于加速 xcore.ai 上的算术运算的函数。xcore.ai 设备使用 XMOS XS3 架构,引入了 XMOS 专有的向量处理单元(VPU)。VPU 是 xcore 上的专用硬件,提供了类似 SIMD 的数据并行处理能力。

该库包含许多低级函数,用于以各种方式(主要是 16 位和 32 位)快速处理数据向量,具体见向量 API。VPU 速度非常快,但它仅实现整数运算。为此,该库还提供了一个块浮点数(BFP)API,允许使用 VPU 进行定点精度(而不是定点范围)运算。

lib_xcore_math 还提供了用于快速傅里叶变换线性数字滤波器和一个小型标量算术 API的接口。

本教程的目的不是演示 lib_xcore_math 中的所有功能。相反,它旨在演示如何在 xcore.ai 上实现和优化浮点算法,并帮助用户理解所涉及的算术逻辑。因此,本教程只会介绍 lib_xcore_math 提供的一小部分 API,重点是数字 FIR 滤波器的特定情况。

CMake 项目

本教程使用 CMake 项目构建 xcore.ai 设备固件。

为了简化各个组件(脚本、数据、构建产物、应用程序输出)的协调,本教程要求 CMake 项目的构建目录位于教程工作空间的根目录。

以下部分简要描述了 CMake 项目的结构。有关配置 CMake 项目和构建本教程的二进制文件的说明,请参阅 构建

xcore.ai 固件的 CMake 源目录是克隆的 xmath_walkthrough 代码库的根目录。

它为本教程的每个阶段定义了一个可执行目标。这些目标被称为 part1Apart1B、...、part4Clib_xcore_math 库也被添加到了 CMake 项目中,因为应用程序固件依赖于该库。

应用程序

在 xcore.ai 设备上运行的固件是一个相对简单的应用程序,大致执行以下操作:

Tile 0 (wav_io_task):

  1. 打开并从主机机器读取(完整的)input.wav 文件。
  2. 使用 xcore 通道将一帧输入音频传输到 Tile 1。
  3. 等待从 Tile 1 传输回来的一帧处理后的音频。
  4. 重复执行步骤 2 和 3,直到所有输入音频被处理完毕。
  5. 从 Tile 1 的第二个线程(也使用 xcore 通道)获取一些简单的性能信息。
  6. 将处理后的音频写入主机上的输出 wav 文件。
  7. 退出。

Tile 1 (filter_task):

  1. 等待从 Tile 0 传输过来的一帧输入音频。
  2. 对输入音频应用当前阶段的滤波逻辑,将一帧填充为滤波后的输出样本。
  3. 使用 xcore 通道将处理后的音频帧传输到 Tile 0。
  4. 无限循环执行步骤 1 到 3。

Tile 1 (timer_report_task):

  1. 等待 wav_io_task 启动一个简单的来回握手。
  2. 使用通道将收集到的定时信息报告给 Tile 1。

img/sw-flow.png

该应用程序是一个双 Tile 应用程序,运行以下线程(除了 Part 4A)。

Tile入口点描述
tile[0]wav_io_task()处理 wav 文件的解码和分帧。
tile[1]filter_task()对输入音频进行滤波以产生输出。
tile[1]timer_report_task()将性能信息报告给 tile[0]

注意:在必要时,本教程使用线程的入口点函数名称作为简写来引用设备上运行的线程。从上下文中应该清楚是指入口点函数还是硬件线程本身。

本教程不解释 wav_io_tasktimer_report_task 线程的实现。相反,它专注于仅解释 filter_task() 的行为和实现。通过检查代码,可以轻松了解其他线程的行为。