In this mode the top level application can be written inside graph.cpp file. The application contains an instance of ADF graph and a main function within which API’s are called to initialize, run and end the graph. It may also have additional API’s to update Run time parameters. Additionally for hw emulation / hw run modes, the ‘main()’ function can be guarded by a #ifdef to ensure graph is only initialized once, or run only once. The following example code is the simple application defined in Creating a Data Flow Graph (Including Kernels) with the additional guard macro __AIESIM__ and __X86SIM__.
// Virtual platform ports
PLIO* in1 = new PLIO("DataIn1", adf::plio_64_bits, "data/input.txt");
PLIO* out1 = new PLIO("DataOut1", adf::plio_64_bits, "data/output.txt");
simulation::platform<1, 1> platform(in1, out1);
// Graph object
myGraph filter_graph;
// Virtual platform connectivity
connect<> net0(platform.src[0], filter_graph.inptr);
connect<> net1(filter_graph.outptr, platform.sink[0]);
#define SRS_SHIFT 10
float kData[9] = {0.0625, 0.1250, 0.0625, 0.125, 0.25, 0.125, 0.0625, 0.125, 0.0625};
#if defined(__AIESIM__) || defined(__X86SIM__)
int main(int argc, char** argv) {
filter_graph.init();
filter_graph.update(filter_graph.kernelCoefficients, float2fixed_coeff<10, 16>(kData).data(), 16);
filter_graph.run(1);
filter_graph.end();
return 0;
}
#endif
In case GMIO based ports are used
#if defined(__AIESIM__) || defined(__X86SIM__)
int main(int argc, char** argv) {
...
...
int16_t* inputData = (int16_t*)GMIO::malloc(BLOCK_SIZE_in_Bytes);
int16_t* outputData = (int16_t*)GMIO::malloc(BLOCK_SIZE_in_Bytes);
//Prepare input data
...
...
filter_graph.init();
filter_graph.update(filter_graph.kernelCoefficients, float2fixed_coeff<10, 16>(kData).data(), 16);
filter_graph.run(1);
//GMIO Data transfer calls
gmioIn[0].gm2aie_nb(inputData, BLOCK_SIZE_in_Bytes);
gmioOut[0].aie2gm_nb(outputData, BLOCK_SIZE_in_Bytes);
gmioOut[0].wait();
printf("after grph wait\n");
filter_graph.end();
...
}
#endif