Professional Documents
Culture Documents
457
na
Figure 10.30
Figure 10.31
10.12
In this section we show how to integrate the generated C/C++ code from a MATLAB
function with an existing C/C++ code or a C/C++ development environment. To do this we
perform the following steps:
1. Choose an algorithm and represent it as a MATLAB
function.
2. Create a MATLAB testbench. A testbench is a calling script that executes the function
with different parameters, records the output of each test case, and records how much
time it takes to complete these test cases. Execute the testbench to generate reference
numerical results and reference execution times.
3. Generate C code from the function. Choose static C library as the code-generation output
type. All the source and header files (*.c and *.h) will be generated in a directory.
4. Compose a C/C++ main function that calls the generated C code.
5. Use a simple Makefile to compile and link the C main function and the generated C code
of the function. The result will be an executable that can run on a computer. This
executable is the C testbench.
6. Run the generated executable (the C testbench) outside the MATLAB environment. Verify that the C testbench generates the same numerical results as the reference MATLAB
testbench. Finally, compare the execution time of the C testbench to a MATLAB
testbench processing the same test cases.
10.12.1
Algorithm
To start the process of integrating MATLAB code with an external C code, we first need to
choose an algorithm. We have selected a simplified form of the Physical Downlink Control
Channel (PDCCH) processing algorithm [3]. In Chapter 9 we examined 17 different
versions of the PDCCH algorithm. In this section we have chosen version 9, the MEX
function of the eighth version of the algorithm, which incorporates all available System
objects in the Communications System Toolbox. Version 9 has been shown to simulate
faster than the first eight versions in the absence of parallel multicore processing. The
MATLAB function that captures the eighth version of the algorithm is as follows:
Algorithm
MATLAB function
function [ber, bits]=zPDCCH_v8(EbNo, maxNumErrs, maxNumBits)
%% Constants
FRM=2048;
M=4; k=log2(M); codeRate=1/3;
snr = EbNo + 10*log10(k) + 10*log10(codeRate);
trellis=poly2trellis(7, [133 171 165]);
L=FRM+24;C=6; Index=[L+1:(3*L/2) (L/2+1):L];
%% Initializations
numErrs = results(2);
numBits = results(3);
nS
= nS + 2; nS = mod(nS, 20);
end
%% Clean up & collect results
ber = results(1); bits= results(3);
reset(BitError);
In order to manage the files and directories associated with C-code generation properly,
we create a new directory in our computer and place all the MATLAB files in it. In this
example, we create a directory called C:\Examples\PDCCH and copy all the files needed
to run the eighth version of the algorithm to it. The MATLAB script performing these tasks
is as fol- lows:
Algorithm
MATLAB script: MATLAB_testbench_directory
%% Create new directory in C:\ drive
PARENTDIR='C:\';
NEWDIR='Examples\PDCCH';
mkdir(PARENTDIR,NEWDIR);
%% Make that your destination directory
DESTDIR=fullfile(PARENTDIR,NEWDIR);
%% Copy 10 necessary files to destination directory
copyfile('Alamouti_DecoderS.m',DESTDIR);
copyfile('Alamouti_EncoderS.m',DESTDIR);
copyfile('fcn_Descrambler.m',DESTDIR);
copyfile('fcn_RateDematcher.m',DESTDIR);
copyfile('fcn_RateMatcher.m',DESTDIR);
copyfile('fcn_Scrambler.m',DESTDIR);
copyfile('MIMOFadingChanS.m',DESTDIR);
copyfile('TransmitDiversityCombinerS.m',DESTDIR);
copyfile('TransmitDiversityEncoderS.m',DESTDIR);
copyfile('zPDCCH_v8.m',DESTDIR);
%% Go to destination directory
cd(DESTDIR);
10.12.2
At this step we execute two scripts: a build script that generates a MEX function for the
func- tion zPDCCH_v8.m and a calling script, which constitutes our MATLAB testbench.
These scripts can be created in the same destination directory as the MATLAB functions are
stored
in (C:\Examples\PDCCCH). Using the first script (MATLAB_build_version9.m), we can generate the MEX function of the eighth version of the PDCCH algorithm. The codegen
command for this build script is as follows:
Algorithm
MATLAB script: MATLAB_build_version9
MaxSNR=8;
MaxNumBits=1e7;
MaxNumErrs=MaxNumBits;
fprintf(1,'\nGenerating MEX function for PDCCH algorithm ...\n');
codegen args { MaxSNR, MaxNumErrs, MaxNumBits} zPDCCH_v8 o
zPDCCH_v9 fprintf(1,'Done.\n\n');
MEX_FCN_NAME='zPDCCH_v9';
fprintf(1,'Output MEX function name: %s \n',MEX_FCN_NAME);
Algorithm
MATLAB testbench: MATLAB_testbench_version9
MaxSNR=8;
MaxNumBits=1e7;
MaxNumErrs=1e7;
ber_vector=zeros(MaxSNR,1);
fprintf(1,'\nMATLAB testbench for PDCCH algorithm\n');
fprintf(1,'Maximum number of errors : %9d\n', MaxNumErrs);
fprintf(1,'Maximum number of bits : %9d\n\n', MaxNumBits);
tic;
for snr=1:MaxSNR
fprintf(1,'Iteration number %d\r',snr);
EbNo=snr/2;
ber= zPDCCH_v9(EbNo, MaxNumErrs, MaxNumBits);
ber_vector(snr)=ber;
end
time_8=toc;
fprintf(1,'\nTime to complete %d iterations = %6.4f (sec)\n\n', MaxSNR, time_8);
for snr = 1:MaxSNR
fprintf(1,'Iteration %2d EbNo %3.1f BER %e\n', snr, snr/2, ber_vector(snr));
end
When we execute this testbench, the results shown in Figure 10.32 are displayed in the
MATLAB command window. Note that we have obtained reference BER values and
simula- tion times by running the MATLAB testbench. We will compare these values with
the results obtained by running the C testbench, which we will create shortly.
Figure 10.32
MATLAB testbench, furnishing reference values for execution time and output values
10.12.3
Generating C Code
In this step, we generate C code from the function zPDCCH_v8.m using the codegen
command. To generate a static C library we can use either the codegen command or the
MATLAB Coder Project. When using the codegen command line we need only specify lib
as the configuration option, as illustrated in the following script:
Algorithm
MATLAB script: MATLAB_build_version9
MaxSNR=8;
MaxNumBits=2e6;
MaxNumErrs=MaxNumBits;
fprintf(1,'Generating source files (*.c) and header files (*.h) for PDCCH algorithm ...');
codegen args { MaxSNR, MaxNumErrs, MaxNumBits} zPDCCH_v8 config:lib
-report fprintf(1,'Done.');
FCN_NAME='zPDCCH_v8';
Location=fullfile(pwd,'codegen','lib',FCN_NAME);
fprintf(1,'All generated files are in the following directory: \n%s\n', Location);
Upon completion, the codegen command prints a message in the MATLAB command line
that includes a hyperlink to the generated C code. When we click on the hyperlink, we open
the Code Generation Report (Figure 10.33).
All of the C source files and header files are stored in a unique folder under the
Destination directory. In this example, the destination directory is C:\Examples\PDCCH and
all the source files are in a subdirectory called codegen\lib\zPDCCH_v8. Figure 10.34 shows
all the source and header files generated, listed by the ls command.
10.12.4
Entry-Point Functions in C
Having already generated C code from our MATLAB function, the rest of the development
process can be performed completely outside the MATLAB environment. In order to
generate a C executable, otherwise known as a C testbench, all we have to do is to write a
C main function and call the generated entry-point functions in it.
In our example, the entry-point function in MATLAB is zPDCCH_v8.m. The generated
C code will therefore have three header files, which define the entry-point C function
prototypes for: (i) the main entry-point function, (ii) the initialization function, and (iii)
the termination function. These files are zPDCCH_v8.h, zPDCCH_v8_initialize.h, and
zPDCCH_v8_terminate.h, respectively.
Figure 10.33
Code Generation Report: showing generated code for the zPDCCH_v8 algorithm
Figure 10.34