The tool creates a new directory with the name you specified in the Code Directory field in the Vitis Model Composer Hub block. There are various sub-directories in the code directory but the ip/<subsystem name>/src/ directory and the Makefile which are highlighted in figure below, are of interest for this section. Subsequent topics provide details about other sub-directories.
| File/Directory | File/Sub-directory | Description |
|---|---|---|
| ip/Subsystem_Name/src | 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 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 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 Tutorials. 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. This 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
outputport is connected to a synchronous runtime parameter port. - The value of an input runtime parameter port can only be updated one time - at the beginning when running the generated graph.