Reduce Area and Latency of HLS Code That Uses Row-Major Array Layout
This example shows how to reduce the area and latency of the generated HLS code that uses row-major array layout.
The HLS tools provide several array optimization techniques that improve the performance of the MATLAB® design and improve the quality of results. Examples of such optimizations include array partitioning, reshaping, and stencil optimization. Most of these optimizations require that the array elements must be accessed sequentially. This is where the array layout becomes important, especially in the case of multidimensional arrays.
When a matrix is stored in row-major layout in memory, but the array is accessed in column-major order explicitly in the MATLAB code, the array accesses are not sequential. In such situations, to enable the array optimizations that the HLS tools provide, you must instruct the code generator to produce code that accesses arrays in row-major fashion. For more information see, Row-Major and Column-Major Array Layouts.
MATLAB Algorithm
To understand the row-major array layout, consider the MATLAB function convolution.m
. The function performs a convolution operation on an RGB image by moving a filter (kernel) across the image, calculating a weighted sum of pixel values, and applying it to each pixel to create a new image.
type("convolution.m")
function result = convolution(rgbImage, kernel) coder.hdl.literaltext('#pragma HLS inline'); coder.hdl.interface('rgbImage', "AXI4 Master"); coder.hdl.interface('kernel', "AXI4 Master"); [image_height, image_width] = size(rgbImage); [filter_height, filter_width] = size(kernel); factor = 1.0/(filter_height*filter_width); bias = 0; result = coder.nullcopy(rgbImage); for y = 1:image_height for x = 1:image_width coder.hdl.literaltext("#pragma HLS pipeline II=1"); coder.hdl.literaltext("#pragma HLS array_stencil variable=rgbImage"); sum = zeros(1,1,'int32'); for row = 1:filter_height for col = 1:filter_width xoffset = (x+col-floor(filter_width/2)); yoffset = (y+row-floor(filter_height/2)); % clamp pixels to 0 when outside of image if ~(xoffset<1 || xoffset>image_width || yoffset<1 || yoffset>image_height) pixel = rgbImage(yoffset,xoffset); sum = cast(pixel*kernel(row,col),'like',sum) + sum; end end outPixel = cast(min(max(factor*sum + bias, 0),255),'like',result); result(y,x) = outPixel; end end end end
MATLAB testbench:
type("convolution_tb.m")
% Load your image image = randi(255, 480,640,3); % Check the data type of the image data_type = class(image); [imageHeight, imageWidth, numChannels] = size(image); % Define convolution kernel (filter) kernel = ones(7, 7); data_type_ones = class(kernel); % Separate color channels redChannel = image(:, :, 1); greenChannel = image(:, :, 2); blueChannel = image(:, :, 3); convolvedRGBImage_red = convolution(redChannel, kernel); convolvedRGBImage_green = convolution(greenChannel, kernel); convolvedRGBImage_blue = convolution(blueChannel, kernel);
Implement Row-Major Array Layout
By default, MATLAB stores the array elements of the RBG image in column-major array layout. This example requires row-major array layout to allow sequential array access to apply the stencil optimization.
To generate HLS code, set up the Xilinx® Vitis™ HLS tool path by using the function hdlsetuphlstoolpath
. The function sets the Xilinx Vitis HLS and Xilinx Vivado® paths to the system path.
Use these commands to generate HLS code and synthesize the generated code using row-major array layout.
fixptCfg = coder.config("fixpt"); fixptCfg.TestBenchName = "convolution_tb"; hdlCfg = coder.config("hdl"); hdlCfg.Workflow = "High Level Synthesis"; hdlCfg.TestBenchName = "convolution_tb"; hdlCfg.SynthesisTool = "Xilinx Vitis HLS"; hdlCfg.SynthesizeGeneratedCode = true; hdlCfg.SynthesisToolChipFamily = "Artix7"; hdlCfg.SynthesisToolDeviceName = "xa7a100t"; hdlCfg.SynthesisToolPackageName = "csg324"; hdlCfg.SynthesisToolSpeedValue = "-1I"; codegen -config hdlCfg -float2fixed fixptCfg convolution -report
=================================================== Design Name: convolution Test Bench Name: convolution_tb =================================================== Input types not specified for design(s) 'convolution', inferring types by simulating the first test bench: 'convolution_tb' in the base workspace. ============= Step1: Analyze floating-point code ============== Code generation successful. ============= Step1a: Verify Floating Point ============== ### Analyzing the design 'convolution' ### Analyzing the test bench(es) 'convolution_tb' ### Begin Floating Point Simulation (Instrumented) ### Floating Point Simulation Completed in 3.8170 sec(s) ### Elapsed Time: 4.7181 sec(s) ============= Step2: Propose Types based on Range Information ============== ============= Step3: Generate Fixed Point Code ============== ### Generating Fixed Point MATLAB Code convolution_fixpt using Proposed Types ### Generating Fixed Point MATLAB Design Wrapper convolution_wrapper_fixpt ### Generating Mex file for ' convolution_wrapper_fixpt ' Code generation successful: View report ### Generating Type Proposal Report for 'convolution' convolution_report.html =================================================== Code generation successful. ### Begin MATLAB to HLS Code Generation... ### Working on DUT: convolution_fixpt. ### Using TestBench: convolution_tb. ### Begin HLS Code Generation ### Generating Resource Utilization Report resource_report.html. ### Working on convolution_fixptClass.hpp as convolution_fixptClass.hpp. ### Working on convolution_fixpt_wrapper.cpp as convolution_fixpt_wrapper.cpp. ### To rerun codegen evaluate the following commands... --------------------- cgi = load('C:\ExampleManager9ef2d6\user.Bdoc.27_1\hdlcoder-ex61199335\codegen\convolution\hdlsrc\codegen_info.mat'); cfg = cgi.CodeGenInfo.codegenSettings; fxpCfg = cgi.CodeGenInfo.fxpCfg; codegen -float2fixed fxpCfg -config cfg -report --------------------- ### Synthesizing the design "convolution_fixpt". ### Generating Xilinx Vitis HLS project: C:\ExampleManager9ef2d6\user.Bdoc.27_1\hdlcoder-ex61199335\codegen\convolution\hdlsrc ### Generating syn_script.tcl file: syn_script.tcl ### Generating synthesis report syn_log.txt. ### Synthesis successful. ### Generating HLS Conformance Report convolution_fixpt_hdl_conformance_report.html. ### HLS Conformance check complete with 0 errors, 0 warnings, and 0 messages. ### Code generation successful: View report
Review Synthesis Quality of Results
To view detailed synthesis results open the Xilinx Vitis HLS project
generated in the current working directory.
This table shows the synthesis quality of results for both row-major and column-major layouts.
Property | Column-major layout | Row-major layout |
Latency (cycle) | 15052874 | 314043 |
BRAM | 1 | 7 |
DSP | 1 | 1 |
FF | 9707 | 8003 |
LUT | 15577 | 9578 |
See Also
coder.columnMajor
| coder.rowMajor
| coder.isRowMajor
| coder.isColumnMajor