If my previous article I showed how we can simulate an AMD Versal AI Engine graph in Python using Vitis™ Functional Simulation (VFS) feature. As this flow also supports MATLAB® I thought it might be good to show the same example running on MATLAB.
If you have already been through my previous article and you are not using MATLAB then this might not be interesting for you as this is basically the same article but written for MATLAB target.
Note: This tutorial was created using AMD Vitis 2025.1. Tool flow may vary in other versions of the tool.Vitis™ Functional Simulation (VFS)
Vitis Functional Simulation (VFS) is a new flow introduced by AMD as part of the Vitis tools in 2025.1 which supports simulation management of an AI Engine and/or HLS design under test (DUT) in both MATLAB and Python. This means that if you are an HW engineer working on the AI Engine, you can get the algorithm team to verify your implementation directly from their environment.
VFS manages AI Engine graphs and HLS kernels as simulation objects which are instantiated in a test bench and simulated by running the instance with the provided input data.
The simulation of the AI Engine object is achieved using the X86 simulator and the simulation of the AI Engine object is executed with C-simulation. This means that VFS is only a functional simulator and does not provide any cycle information.
More information about VFS can be found in the AMD Embedded Design Development Using Vitis User Guide (UG1701):
There is also a nice quick take video about VFS on YouTube:
Creating a VFS object from MATLAB™Let now see how we can use VFS to simulate our FFT graph.
You can find the python script I have generate on my GitHub repository:
https://github.com/xflorentw/AI_Engine_Basic/tree/main/02_FFT_AIE-ML/vfs/matlab/fft1024_dsplib_vfs.m
The first thing that we have to do is to import the vfs module. Then we just need to call the aie_graph_handle = vfs.aieGraph(<arg>) method to instantiate a VFS simulation object. As arguments, we basically pass the similar argument that we would pass to the AI Engine compiler when targeting x86 compiler: the top level file (input_file), the targeted platform (platform) or targeted part (part) and the include directories (inclide_paths).
Note: The vfs and varray (that we will use later) libraries are part of the Vitis tools. To use them you will need to have a Vitis 2025.1 installed and set up the tools:
source <install location>/2025.1/Vitis/settings64.shThis is the code corresponding to the instantiation of the VFS simulation object for our graph.
% Get DSP Library path
DSPLIB = getenv("DSPLIB_ROOT");
if isempty(DSPLIB)
disp('DSPLIB_ROOT environment not set. Please download the Vitis_Libraries repository and point to the dsp folder')
disp('https://github.com/Xilinx/Vitis_Libraries')
return;
else
disp('Using DSPLIB from DSPLIB_ROOT environment variable')
end
% ------------------------------------------------------------
% Initialize the AIE graph
% ------------------------------------------------------------
myaiefft = vfs.aieGraph(input_file="../../aie/src/14/graph_FFT_1024.cpp",...
part = 'xcve2302-sfva784-1LP-e-S',...
include_paths = {"../../aie/src/14/",...
strcat(DSPLIB,"/L2/include/aie/"),...
strcat(DSPLIB,"/L1/include/aie/"),...
strcat(DSPLIB,"/L1/src/aie/")});If we run this code in MATLAB from the vfs/matlab folder we get the following output:
Compiling AIE Graph
Compilation directory: AI_Engine_Basic/02_FFT_AIE-ML/vfs/matlab/vfs_work/graph_FFT_1024_47d4a3cc
Compilation command: v++ -c --mode aie --config vfs_work/graph_FFT_1024_47d4a3cc/graph_FFT_1024.cfg --work_dir vfs_work/graph_FFT_1024_47d4a3cc/Work --output vfs_work/graph_FFT_1024_47d4a3cc/libadf.a --target x86sim
Writing log to: AI_Engine_Basic/02_FFT_AIE-ML/vfs/matlab/vfs_work/graph_FFT_1024_47d4a3cc/Work/logs/aie_x86sim.log
Please wait ...
Compilation finished successfully.We can see that the v++ compiler is called to compile the graph targeting x86 and generate the output under AI_Engine_Basic/02_FFT_AIE-ML/vfs/matlab/vfs_work.
Running the VFS simulationBefore running the simulation, we need to create the test vectors.
% ------------------------------------------------------------
% Generate Simulus I/O
% ------------------------------------------------------------
%Parameters
Iterations = 1;
Input_shift = 15;
N_Taps = 1024;
F1_MHz = 50;
F2_MHz = 150;
Fs_MHz = 400;
% Number of sample points
N_Samp = N_Taps * Iterations;
% sample spacing
T = 1.0 / Fs_MHz;
A1 = 0.2;
A2 = 0.4;
% Generate Input Signal
tone1 = A1 * exp(1i*2*pi*F1_MHz/Fs_MHz*[0:N_Samp-1]);
tone2 = A2 * exp(1i*2*pi*F2_MHz/Fs_MHz*[0:N_Samp-1]);
sig_i = tone1 + tone2;
% Quantize:
sig_i_cplx = fi(sig_i,1,16,15,'RoundingMethod','Nearest','OverflowAction','Saturate');
sig_i_cplx = double(sig_i_cplx);Then we can use the aie_graph_handle.run to simulate our graph. Note the use of the VARRAY library, from AMD as well, to help converting the data format from MATLAB to the AI Engine object using formats which are not natively supported by Python such as cint16 or bfloat16.
I am also running the FFT from MATLAB on the same input data to have an output reference
% ------------------------------------------------------------
% FFT
% -----------------------------------------------------------
% Process each frame with AI Engine X86 Simulation and Python
for i = 0 : 1 : Iterations-1
input_data = sig_i_cplx(i*1024+1:(i+1)*1024);
% Run AIE graph processing
y_aie = myaiefft.run(varray.cint16(input_data*2^Input_shift));
aie_data(i*1024+1:(i+1)*1024) = double(y_aie);
% Run MATLAB fft
matlab_data(i*1024+1:(i+1)*1024) = fft(input_data);
endValidating the AI Engine resultsThen as in my the previous tutorial we can check that the results from the MATLAB model and the output from the AI Engine simulator match within an acceptable range
% ------------------------------------------------------------
% Error Check AIE vs Golden
% ------------------------------------------------------------
error_threshold = 1/2^4;
error = 0;
matlab_data = fi(matlab_data,1,16,6,'RoundingMethod','Nearest','OverflowAction','Saturate');
aie_data = fi(aie_data/2^5,1,16,6,'RoundingMethod','Nearest','OverflowAction','Saturate');
for i = 1 : 1 : size(aie_data,2)
if aie_data(i) ~= matlab_data(i)
if abs(aie_data(i) - matlab_data(i)) > error_threshold
fprintf("Error in sample %d\n", i)
fprintf("Golden %f +i%f\n", real(matlab_data(i)), imag(matlab_data(i)))
fprintf("AIE Output %f +i %f\n", real(aie_data(i)),imag(aie_data(i)))
error = error+ 1;
end
end
end
if(error<1)
disp('AI Engine FFT matches the Python FFT within 2 LSB')
else
disp('Test Failed')
fprintf('Nb errors : %d\n',error)
endAnd we can also plot the output data
% Plot outputs
xf = Fs_MHz/N_Taps*(0:N_Taps-1);
subplot(3,1,1); plot((0:1023), real(sig_i(1:1024))); title("Input Signal");
subplot(3,1,2); plot(xf, abs(matlab_data(1:1024))); title("Output FFT (Matlab)");
subplot(3,1,3); plot(xf, abs(aie_data(1:1024))); title("Output FFT (AIE)");Running the full script we get the following output in the terminal confirming that our AI Engine implementation matches our algorithm requirements:
Loaded AIEGraph
AI Engine FFT matches the Python FFT within 2 LSBAnd we get also the following window with the visualization of the FFT result from MATLAB and the AI Engine simulator.
In this article we have seen how we can easily simulate an AI Engine graph from MATLAB using the AMD Vitis Functional Simulation feature from AMD. This is a good way for algorithm teams to verify that an AI Engine implementation matches the algorithm needs just by adding few lines of code in their algorithm MATLAB script.
One thing to note is that VFS is, as mentioned previously, only targeting x86 compiler. It does not support the AI Engine simulator in cycle approximate more (i.e. target = hw). For the cycle approximate simulation you the solution would be to use the input text files as we generated in the previous tutorial. This is a bit less convenient but in theory we are not checking the accuracy any more so we can have a simple set of data and only check for the performances.
If you want to learn more about Vitis Functional Simulation I would recommend the following:
- There is a tutorial about Vitis Functional Simulation on the AMD/Xilinx Vitis_Tutorials GitHub repository which includes multiple example using AI Engine, AI Engine + HLS and HLS only using MATLAB and Python:https://github.com/Xilinx/Vitis-Tutorials/tree/2025.1/Vitis_System_Design/Feature_Tutorials/01-Vitis_Functional_Simulation
- Adam Taylor also recently wrote a nice article about simulating an HLS kernel using VFS:https://www.hackster.io/adam-taylor/vitis-functional-simulation-using-python-125bfa
- AMD, Versal, and Vitis are trademarks or registered trademarks of Advanced Micro Devices, Inc.
- MathWorks and MATLAB are trademarks or registered trademarks of The MathWorks, Inc.
- Other product names used in this publication are for identification purposes only and may be trademarks of their respective companies.








Comments