Indexing Best Practices for HDL Code Generation
In MATLAB®, array indices start from 1 and follow a 1-based indexing approach. However, HDL code uses 0-based indexing, where array indices start from 0. When you generate HDL code from a MATLAB algorithm, HDL Coder™ converts 1-based MATLAB indexing to 0-based HDL indexing, which may result in excess logic that can consume more hardware area. Using these best practices can optimize your code and reduce the amount of hardware area used.
Minimize Automatic Index Conversions
Because HDL Coder converts 1-based MATLAB indexing to 0-based HDL indexing when you generate code, HDL Coder may generate excess logic in the VHDL®, Verilog®, or SystemVerilog code to assist with this conversion. This excess logic leads to increased hardware area consumption.
To minimize the number of automatic conversions HDL Coder introduces when translating your MATLAB algorithm to HDL code and meet
your hardware area requirements, you can store a zero-based index in index
variables. For this method to work effectively, you must cast the index variables to
int32
type. When you perform an index operation, add 1 to the
value of int32
cast index. HDL Coder optimizes the automatic conversion.
Unoptimized MATLAB Code | Optimized MATLAB Code |
---|---|
arr = [3 5 7 9]; num = length(arr); % Index ii is 1-based for ii = 1:num % 1-based index when indexing disp(arr(ii)) end |
arr = [3 5 7 9]; num = length(arr); % Index ii is 0-based for ii = int32(0):num-1 % Add 1 to the value of the int32 cast 0-based index when indexing disp(arr(ii+1)) end |
Example of Area Consumption Optimization
This MATLAB algorithm enhances the contrast of images by transforming the values in an intensity image so that the histogram of the output image is approximately flat. Apply the indexing best practice to the algorithm. For more information on this algorithm, see Image Enhancement by Histogram Equalization. When you convert the unoptimized algorithm to HDL code, the conversion process can lead to excess logic. Compare the hardware area usage of the unoptimized algorithm to the optimized algorithm.
Unoptimized MATLAB Algorithm | Optimized MATLAB Algorithm |
---|---|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % mlhdlc_heq.m % Histogram Equalization Algorithm %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function [x_out, y_out, pixel_out] = ... mlhdlc_heq(x_in, y_in, pixel_in, width, height) % Copyright 2011-2024 The MathWorks, Inc. persistent histogram persistent transferFunc persistent histInd persistent cumSum if isempty(histogram) histogram = zeros(1, 2^14); transferFunc = zeros(1, 2^14); histInd = 0; cumSum = 0; end % Figure out indexes based on where we are in the frame if y_in < height && x_in < width % valid pixel data histInd = pixel_in + 1; elseif y_in == height && x_in == 0 % first column of height+1 histInd = 1; elseif y_in >= height % vertical blanking period histInd = min(histInd + 1, 2^14); elseif y_in < height % horizontal blanking - do nothing histInd = 1; end % Read histogram (must be outside conditional logic) histValRead = histogram(histInd); % Read transfer function (must be outside conditional logic) transValRead = transferFunc(histInd); % If valid part of frame add one to pixel bin % and keep transfer func val if y_in < height && x_in < width histValWrite = histValRead + 1; % Add pixel to bin transValWrite = transValRead; % Write back same value cumSum = 0; elseif y_in >= height % In blanking time index through all bins and reset to zero histValWrite = 0; transValWrite = cumSum + histValRead; cumSum = transValWrite; else histValWrite = histValRead; transValWrite = transValRead; end % Write histogram (must be outside conditional logic) histogram(histInd) = histValWrite; % Write transfer function (must be outside conditional logic) transferFunc(histInd) = transValWrite; pixel_out = transValRead; x_out = x_in; y_out = y_in; |
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % mlhdlc_heq_bp.m % Histogram Equalization Algorithm %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function [x_out, y_out, pixel_out] = ... mlhdlc_heq_bp(x_in, y_in, pixel_in, width, height) % Copyright 2011-2024 The MathWorks, Inc. persistent histogram persistent transferFunc persistent histInd persistent cumSum if isempty(histogram) histogram = zeros(1, 2^14); transferFunc = zeros(1, 2^14); histInd = 0; cumSum = 0; end % Adjust histInd index variable to be 0-based if y_in < height && x_in < width histInd = pixel_in; elseif y_in == height && x_in == 0 histInd = 0; elseif y_in >= height histInd = min(histInd + 1, 2^14-1); elseif y_in < height histInd = 0; end % Add 1 to the value of the 0-based histInd when indexing histValRead = histogram(int32(histInd)+1); % Add 1 to the value of the 0-based histInd when indexing transValRead = transferFunc(int32(histInd)+1); if y_in < height && x_in < width histValWrite = histValRead + 1; transValWrite = transValRead; cumSum = 0; elseif y_in >= height histValWrite = 0; transValWrite = cumSum + histValRead; cumSum = transValWrite; else histValWrite = histValRead; transValWrite = transValRead; end % Add 1 to the value of the 0-based histInd when indexing histogram(int32(histInd)+1) = histValWrite; % Add 1 to the value of the 0-based histInd when indexing transferFunc(int32(histInd)+1) = transValWrite; pixel_out = transValRead; x_out = x_in; y_out = y_in; |
Run the command
mlhdlc_demo_setup('heq')
in the MATLAB Command Window. This command copies the filesmlhdlc_heq.m
andmlhdlc_heq_tb.m
into a temporary working folder.Create a new MATLAB function in the temporary working folder named
mlhdlc_heq_bp.m
. Copy the optimized MATLAB algorithm from the table into the function.Create a new MATLAB script in the temporary working folder named
mlhdlc_heq_bp_tb.m
. Copy the contents of themlhdlc_heq_tb.m
testbench intomlhdlc_heq_bp_tb.m
. Change the line with the function callmlhdlc_heq
tomlhdlc_heq_bp
in order for themlhdlc_heq_bp_tb.m
testbench to exercise the function design of the optimized MATLAB algorithm,mlhdlc_heq_bp
.Generate HDL code from the unoptimized algorithm,
mlhdlc_heq
. For more information on how to generate HDL code from the command line, see Generate HDL Code from MATLAB Code Using the Command Line Interface.fixptcfg = coder.config('fixpt'); fixptcfg.TestBenchName = 'mlhdlc_heq_tb'; hdlcfg = coder.config('hdl'); hdlcfg.TestBenchName = 'mlhdlc_heq_tb'; hdlcfg.MapPersistentVarsToRAM = 0; hdlcfg.TargetLanguage = 'VHDL'; codegen -float2fixed fixptcfg -config hdlcfg mlhdlc_heq
Open the generated VHDL file and observe the automatic conversion HDL Coder introduces when translating the 1-based MATLAB algorithm to 0-based VHDL indexing. For example, compare the index operations from the MATLAB algorithm to the generated VHDL code.
Unoptimized MATLAB Algorithm Generated VHDL Code ... ... %Read histogram (must be outside conditional logic) histValRead = histogram(histInd); %Read transfer function (must be outside conditional logic) transValRead = transferFunc(histInd); ... ...
... ... --Read histogram (must be outside conditional logic) sub_cast := signed(resize(histInd_temp, 32)); -- HDL Coder automatically converts between the 1- and 0-based indicies histValRead := mlhdlc_heq_fixpt_histogram(to_integer(sub_cast - 1)); --Read transfer function (must be outside conditional logic) sub_cast_0 := signed(resize(histInd_temp, 32)); -- HDL Coder automatically converts between the 1- and 0-based indicies transValRead := mlhdlc_heq_fixpt_transferFunc(to_integer(sub_cast_0 - 1)); ... ...
Generate HDL code from the optimized MATLAB algorithm that follows the best practice,
mlhdlc_heq_bp
. Set thefixptcfg
andhdlcfg
object parameters and run thecodegen
command.fixptcfg = coder.config('fixpt'); fixptcfg.TestBenchName = 'mlhdlc_heq_bp_tb'; hdlcfg = coder.config('hdl'); hdlcfg.TestBenchName = 'mlhdlc_heq_bp_tb'; hdlcfg.MapPersistentVarsToRAM = 0; hdlcfg.TargetLanguage = 'VHDL'; codegen -float2fixed fixptcfg -config hdlcfg mlhdlc_heq_bp
Open the generated VHDL file. For example, compare the index operations from the optimized MATLAB algorithm to the generated VHDL code. Observe how the generated VHDL code includes less logic.
Optimized MATLAB Algorithm Generated VHDL Code ... ... % Add 1 to the value of the 0-based histInd when indexing histValRead = histogram(histInd+1); % Add 1 to the value of the 0-based histInd when indexing transValRead = transferFunc(histInd+1); ... ...
... ... -- Add 1 to the value of the 0-based histInd when indexing -- HDL Coder optimizes the automatic conversion histValRead := mlhdlc_heq_bp_fixpt_histogram(to_integer(histInd_temp)); -- Add 1 to the value of the 0-based histInd when indexing -- HDL Coder optimizes the automatic conversion transValRead := mlhdlc_heq_bp_fixpt_transferFunc(to_integer(histInd_temp)); ... ...
Set the
fixptcfg
andhdlcfg
object parameters and run thecodegen
command to place and route the HDL code from the unoptimized and optimized MATLAB algorithms. For more information, see Synthesis and Analysis. For example, set thefixptcfg
andhdlcfg
object parameters and run thecodegen
command to place and route the HDL code from the optimized algorithm,mlhdlc_heq_bp
.fixptcfg = coder.config('fixpt'); fixptcfg.TestBenchName = 'mlhdlc_heq_bp_tb'; hdlcfg = coder.config('hdl'); hdlcfg.TestBenchName = 'mlhdlc_heq_bp_tb'; hdlcfg.MapPersistentVarsToRAM = 1; hdlcfg.TargetLanguage = 'VHDL'; hdlcfg.SynthesisTool = 'Xilinx Vivado'; hdlcfg.SynthesisToolChipFamily = 'Zynq'; hdlcfg.SynthesisToolDeviceName = 'xc7z020'; hdlcfg.SynthesisToolPackageName = 'clg400'; hdlcfg.SynthesisToolSpeedValue = '-1'; hdlcfg.SynthesizeGeneratedCode = true; codegen -float2fixed fixptcfg -config hdlcfg mlhdlc_heq_bp
VHDL code generated from the optimized MATLAB algorithm uses less hardware area, as HDL Coder introduces fewer automatic index conversions to compensate for the differences in indexing. This table compares the place and route results for the unoptimized and optimized MATLAB algorithms obtained from the synthesis tool.
Place and Route Result for Unoptimized MATLAB Algorithm Place and Route Result for Optimized MATLAB Algorithm Parsed resource report file: mlhdlc_heq_fixpt_utilization_synth.rpt. Resource Usage Available Utilization (%) ___________________ _______ __________ _______________ {'Slice LUTs' } {'171'} {'53200' } {'0.32' } {'Slice Registers'} {'277'} {'106400'} {'0.26' }
Parsed resource report file: mlhdlc_heq_bp_fixpt_utilization_synth.rpt. Resource Usage Available Utilization (%) ___________________ _______ __________ _______________ {'Slice LUTs' } {'147'} {'53200' } {'0.28' } {'Slice Registers'} {'262'} {'106400'} {'0.25' }