Vitis 开发流程中的主机应用的常规结构可拆分为下列步骤(代码示例已一并提供):
- 指定加速器器件 ID 并加载 .xclbin:
auto device = xrt::device(device_index); auto uuid = device.load_xclbin(binaryFile);
- 设置内核 IP 并定义实参缓冲器:
auto ip1 = xrt::ip(device, uuid, "Vadd_A_B:{Vadd_A_B_1}"); // Allocate Buffer in Global Memory auto ip1_boA = xrt::bo(device, vector_size_bytes, 1); auto ip1_boB = xrt::bo(device, vector_size_bytes, 1); // Map the contents of the buffer object into host memory auto bo0_map = ip1_boA.map<int*>(); auto bo1_map = ip1_boB.map<int*>();
- 如果编写的内核用于访问器件存储器,请将数据从主机传输到器件存储器:提示: 编写的内核也用于直接访问主机存储器,前提是平台支持该功能,如主机存储器访问中所述。
// Get the buffer physical address buf_addr[0] = ip1_boA.address(); buf_addr[1] = ip1_boB.address(); // Synchronize buffer content with device side ip1_boA.sync(XCL_BO_SYNC_BO_TO_DEVICE); ip1_boB.sync(XCL_BO_SYNC_BO_TO_DEVICE); // Setting Register A (Input Address) ip1.write_register(A_OFFSET, buf_addr[0]); ip1.write_register(A_OFFSET + 4, buf_addr[0] >> 32); //Setting Register B (Input Address) ip1.write_register(B_OFFSET, buf_addr[1]); ip1.write_register(B_OFFSET + 4, buf_addr[1] >> 32);
- 运行内核并返回结果:
// Start Kernel by writing to the Control Register uint32_t axi_ctrl = IP_START; ip1.write_register(USER_OFFSET, axi_ctrl); // Wait until the IP is done by reading from the Control Register while (axi_ctrl != IP_IDLE) { axi_ctrl = ip1.read_register(USER_OFFSET); } // Sync the output buffer back to the Host memory ip1_boB.sync(XCL_BO_SYNC_BO_FROM_DEVICE);
为了支持用户管理的 RTL 内核,您将使用 XRT 本机 API 来编写自己的主机应用,将 RTL 内核定义为 xrt::ip
对象(如上所示),并通过寄存器读取和写入命令来访问内核。如需了解更多信息,请参阅 主机编程。
编写完主机应用后,您即可使用标准 g++ 编译器来对其进行编译,如 为 x86 执行编译和链接 中所述。