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 Native API を使用してホスト アプリケーションを記述し、RTL カーネルを上記のような xrt::ip
オブジェクトとして定義し、レジスタの読み出しおよび書き込みコマンドを使用してカーネルにアクセスします。詳細は、ホスト プログラミング を参照してください。
ホスト アプリケーションを記述したら、x86 用のコンパイルおよびリンク で説明するように、標準の g++ コンパイラを使用してコンパイルできます。