C Code Optimization Using MATLAB Coder app for Hexagon DSP
This example demonstrates the workflow of generating optimized C code from MATLAB® Coder app for the Qualcomm Hexagon Simulator using the Embedded Coder® Support Package for Qualcomm® Hexagon® Processors and the Qualcomm Hexagon QHL Code Replacement Library (CRL). The example utilizes a dsp.FIRFilter System object to filter two sine waves with different frequencies.
Supported Hardware
Qualcomm Hexagon Simulator
Qualcomm Hexagon Android Board
Prerequisites
Launch the hardware setup and install the Qualcomm SDK. For more information, see Launch Hardware Setup.
Required Hardware
To run this example, you need the following hardware:
Supported Qualcomm Hexagon Simulator
Generate Code using MATLAB Coder app
Open MATLAB Coder App and Select Source Files
On the MATLAB toolstrip Apps tab, under Code Generation, click the MATLAB Coder app icon. The app opens the Create MATLAB Coder Project dialog box.
Provide the name of the project file and the folder in which you want to place the file. The MATLAB Coder toolstrip tab and the MATLAB Coder panel opens.
Either click the Add Entry Points button in the Inputs section of the MATLAB Coder panel or the Entry Points button in the toolstrip.
Enter or select the name of the entry-point function ex_fir_hexagon_ml. An entry-point function is a top-level MATLAB function from which you generate code.
Define Input Types
The code generator determines the class, size, and complexity of all variables in the MATLAB files at code generation time, also known as compile time. Therefore, you must specify the properties of all entry-point function inputs. To specify input properties, you can:
Specify properties directly (manually).
Instruct the app to automatically determine input properties by providing a script (in this example, ex_fir_hexagon_test) that calls the entry-point functions with sample inputs.
In the top of the Entry Points tab, set the Automatically Define Input Types parameter to
Using Script
.Enter or select the test file ex_fir_hexagon_test.m.
Click Run.
Check for Run-Time Issues
This step generates a MEX file from your entry-point functions, runs the MEX function, and reports any issues. A MEX function is generated code that can be called from within MATLAB. It is recommended to perform this step because it allows you to detect and fix run-time errors in the generated C code. By default, the MEX function includes memory integrity checks, which perform array bounds and dimension checking to detect violations of memory integrity in the code generated for MATLAB functions.
This step is optional and can be skipped if the CRL is being used.
Click the Run Generated MEX toolstrip button.
Specify a test file that calls the entry-point function with example inputs. For this example, use the test file test that you used to define the input types.
The app automatically generates and runs a MEX function. If the app detects issues during the MEX function generation or execution, it provides warning and error messages in the Command Window.
Generate C Code
Configure this code generation settings:
Set Settings > Hardware Board to Qualcomm Hexagon Simulator.
Set Settings > View all Settings > Code replacement library to Qualcomm Hexagon QHL.
Check Settings > View all Settings > Debugging > Always create a report.
Check Settings > View all Settings > Debugging > Code replacements.
Set hardware configuration settings from Settings > View all Settings > Hardware > Device > Processor Version to 'V68'. Similarly, Clocking > DSP Clock (MHz) to 300.
After updating the code generation settings, in the toolstrip, click on Generate Code > Generate Code and Build to initiate the code generation process.
The Output section of the MATLAB Coder panel indicates that code generation succeeds and displays links to the generated output folder and the code generation report.
Numerical Verification of Generated Code
To manually verify numerical accuracy, follow a workflow similar to the codegen command line. To initiate the verification process, in the toolstrip, click Run Using PIL and provide a test file. This action generates the <codegen function>_pil.mex
file, which shares the same interface as ex_fir_hexagon_ml.m
. You can then compare the outputs of these functions when provided with the same inputs.
After the above step, you can run the below code:
% numSamples = 120; % sin1 = dsp.SineWave('Amplitude',1,'Frequency',1000,... % 'SampleRate',16000, 'SamplesPerFrame', numSamples,... % 'OutputDataType', 'single'); % sin2 = dsp.SineWave('Amplitude',4,'Frequency',5000,... % 'SampleRate',16000, 'SamplesPerFrame', numSamples,... % 'OutputDataType', 'single'); % % numSteps = 200; % frameLength = sin1.SamplesPerFrame; % yRef = zeros(frameLength,1,numSteps,'single'); % y = zeros(frameLength,1,numSteps,'single'); % % for k = 1:numSteps % x1k = sin1(); % generate 1KHz sine wave % x5k = sin2(); % generate 5KHz sine wave % n = randn(size(x1k), 'single')*sqrt(.05); % generate noise signal % u = x1k+x5k+n; % % Run with MATLAB code on host machine % yRef(:,:,k) = ex_fir_hexagon_ml(u); % % Run with generated code on target % y(:,:,k) = ex_fir_hexagon_ml_pil(u); % end % clear ex_fir_hexagon_ml; % clear ex_fir_hexagon_ml_pil;
After the execution, you can compare the outputs of the PIL against the reference using any norm function.
% % norm comparison of y & yRef % absoluteError = norm(y(:)-yRef(:),'inf'); % fprintf("Absolute error = %g \n",absoluteError);
Alternatively, you can use the verifyEqual
function from the matlab.unittest.TestCase.forInteractiveUse
test class. This function allows you to compare the outputs against the given absolute and relative tolerances, concluding the overall results.
% reltol = single(1e-5); % abstol = single(1e-5); % matlab.unittest.TestCase.forInteractiveUse.verifyEqual(y,yRef, ... % 'RelTol',reltol, 'AbsTol', abstol);
Analyze Performance using Code Profile Analyzer
The MATLAB Coder App provides users with the ability to profile the generated code and offers various utilities for performance analysis. To perform profiling, follow this steps:
In the toolstrip, click Run Using PIL. A drop-down menu opens.
Enable the options Enable entry point execution profiling and Enable function execution profiling.
Set Verification mode option to Use generated Code.
Select the script which calls the target function.
This enables the coder to generate <codegen function>_pil.mex file, which runs in MATLAB and interacts with the target to deploy and execute target-specific code. It's important to note that the verification process may take time, depending on the complexity of the test script.
After the verification process is complete, you can click on Stop. This action will enable a link in the Command Window, allowing you to view the profiling information. By clicking on the link, you can access and analyze the profiling results for further performance evaluation.
Click the profiling report link to generate the report.
This will display various metrics of the profiled time, such as average execution time, etc.
Considering the maximum execution time of the ex_fir_hexagon_ml
function, which is 17,072 cycles, repeating the code profiling with the Code Replacement Library set to None resulted in the same function taking 42,188 cycles. This indicates that enabling the CRL improved the cycle performance of ex_fir_hexagon_ml
by approximately 50%.
Note: For Qualcomm Hexagon QHL CRL, explicit alignment specification for buffers is necessary only when the input/output variables are directly used in the operators, functions and system-objects.