A new directory gets created with the name specified in the Code Directory field in the Vitis Model Composer Hub block. There are various sub-directories in the code directory but the src_aie/ directory and the Makefile which are highlighted in figure below, are of interest for this section. The details about other sub-directories are explained in subsequent topics.
File/Directory | File/Sub-directory | Description |
---|---|---|
src_aie | Subsystem_Name.h | Header file that specifies the AI Engine dataflow graph. Note:
Subsystem_Name is a unique string derived from the
top-level subsystem specified in the Model Composer
model.
|
Subsystem_Name.cpp | Test bench to simulate the dataflow graph specified in Subsystem_Name.h. | |
Makefile | This file contains the aiecompiler options specified from Model Composer Hub block. | |
Makefile |
This file contains the commands to compile and simulate the dataflow graph. For more details on how to use the |
The files generated by Vitis Model Composer in the src_aie directory reflect the contents and hierarchy of the subsystem that gets compiled. In this case, assume the subsystem is aie_system which is derived from the design in Vitis Model Composer Tutorial (UG1498). The following figure shows the interconnection of imported kernel functions as blocks, encapsulated as a subsystem.
The generated code for the subsystem aie_system is as follows.
aie_system.h
#ifndef __XMC_AIE_SYSTEM_H__
#define __XMC_AIE_SYSTEM_H__
#include <adf.h>
#include "kernels/inc/hb_27_2i.h"
#include "kernels/inc/polar_clip.h"
#include "kernels/inc/hb_27_2d.h"
class Aie_system_base : public adf::graph {
public:
adf::kernel fir_27t_sym_hb_2i_0;
adf::kernel polar_clip_0;
adf::kernel fir_27taps_symm_hb_dec2_0;
public:
adf::input_port In1;
adf::output_port Out1;
Aie_system_base() {
// create kernel fir_27t_sym_hb_2i_0
fir_27t_sym_hb_2i_0 = adf::kernel::create(fir_27t_sym_hb_2i);
adf::source(fir_27t_sym_hb_2i_0) = "kernels/src/hb_27_2i.cpp";
// create kernel polar_clip_0
polar_clip_0 = adf::kernel::create(polar_clip);
adf::source(polar_clip_0) = "kernels/src/polar_clip.cpp";
// create kernel fir_27taps_symm_hb_dec2_0
fir_27taps_symm_hb_dec2_0 = adf::kernel::create(fir_27taps_symm_hb_dec2);
adf::source(fir_27taps_symm_hb_dec2_0) = "kernels/src/hb_27_2d.cpp";
// create kernel constraints fir_27t_sym_hb_2i_0
adf::runtime<ratio>( fir_27t_sym_hb_2i_0 ) = 0.9;
// create kernel constraints polar_clip_0
adf::runtime<ratio>( polar_clip_0 ) = 0.9;
// create kernel constraints fir_27taps_symm_hb_dec2_0
adf::runtime<ratio>( fir_27taps_symm_hb_dec2_0 ) = 0.9;
// create nets to specify connections
adf::connect< adf::window<512,64> > net0 (In1, fir_27t_sym_hb_2i_0.in[0]);
adf::connect< adf::window<1024>, adf::stream > net1 (fir_27t_sym_hb_2i_0.out[0], polar_clip_0.in[0]);
adf::connect< adf::stream, adf::window<1024,128> > net2 (polar_clip_0.out[0], fir_27taps_symm_hb_dec2_0.in[0]);
adf::connect< adf::window<512> > net3 (fir_27taps_symm_hb_dec2_0.out[0], Out1);
}
};
class Aie_system : public adf::graph {
public:
Aie_system_base mygraph;
public:
adf::input_plio In1;
adf::output_plio Out1;
Aie_system() {
In1 = adf::input_plio::create("In1",
adf::plio_32_bits,
"./data/input/In1.txt");
Out1 = adf::output_plio::create("Out1",
adf::plio_32_bits,
"Out1.txt");
adf::connect< > (In1.out[0], mygraph.In1);
adf::connect< > (mygraph.Out1, Out1.in[0]);
}
};
#endif // __XMC_AIE_SYSTEM_H__
Vitis Model Composer automatically generates the graph header file aie_system.h which contains the dataflow graph corresponding to the subsystem name specified in the Hub block. The connection between the AI Engine kernel or graph as well as the configuration parameters such as window size, window margin and so on, which are specified in the AI Engine kernel block, are automatically reflected in the generated graph code.
Vitis Model Composer also generates the aie_system.cpp file, which is a control program that
has the main()
function defined to initialize, run,
and end the simulation using the control APIs.
aie_system.cpp
#include "aie_system.h"
// instantiate cardano dataflow graph
Aie_system mygraph;
// initialize and run the dataflow graph
#if defined(__AIESIM__) || defined(__X86SIM__)
int main(void) {
mygraph.init();
mygraph.run();
mygraph.end();
return 0;
}
#endif
Limitations
-
AI Engine code cannot be generated if a
top-level subsystem's
output
port is connected to a synchronous runtime parameter port. - The value of an input runtime parameter port can only be updated once at the beginning when running the generated graph.