Generate Modular HDL and HLS Code from an LMS Filter Algorithm
R2026bThis example shows how to generate modular HDL and HLS code from a MATLAB® function that implements an adaptive noise canceler using a Least Mean Square (LMS) filter algorithm.
LMS filters are a class of adaptive filters used in system identification, noise cancellation, and echo cancellation applications. The filter adapts its coefficients in real time to minimize the mean squared error between a desired signal and the filter output, enabling retrieval of an original signal from a noisy observation.
Examine the MATLAB Design and Test Bench
Set up the MATLAB function and test bench for this example. In the MATLAB Command Window, enter:
mlhdlc_demo_setup("mlhdlc_lms_fcn");MATLAB function
model_runme.mscript, which includes the commands to generate HDL code
Copy the test bench to your working folder by entering:
copyfile(fullfile(matlabroot,"toolbox","hdlcoder","hdldesignpatterns","matlabhdl","dsp","mlhdlc_lms_fir_id_tb.m"), pwd);
The MATLAB function, mlhdlc_lms_fcn, takes an input signal,
a desired signal, a step size, and a reset flag, and returns a filtered signal,
an error signal, and the current filter coefficients. The function uses
subfunctions mtapped_delay_fcn,
mtreesum_fcn, and update_weight_fcn to
perform the tapped delay line, tree-structured summation, and weight update,
respectively.
To view the function, enter:
open mlhdlc_lms_fcn.m;The test bench file, mlhdlc_lms_fir_id_tb, creates an FIR
filter system, generates a random input signal, and streams data through the LMS
filter design to verify convergence. To view the test bench,
enter:
open mlhdlc_lms_fir_id_tb.m;Simulate the Design
To check for run-time errors, simulate the design by running the test bench. In the MATLAB Command Window, enter:
mlhdlc_lms_fir_id_tb;
Generate HDL Code
The mlhdlc_lms_fcn_runme script specifies the target files,
enables the settings required for this example, and generates HDL code.
The script specifies the MATLAB function and test bench, then creates a
fixed-point configuration object and an HDL configuration object by using the
coder.config function. The script associates the test
bench with both configuration
objects.
designName = "mlhdlc_lms_fcn"; designTB = "mlhdlc_lms_fir_id_tb"; fixptCfg = coder.config("fixpt"); fixptCfg.TestBenchName = designTB; cfg = coder.config("hdl"); cfg.TestBenchName = designTB;
The script specifies the synthesis tool, chip family, device name, package name, and speed value:
cfg.SynthesisTool = "Xilinx Vivado"; cfg.SynthesisToolChipFamily = "Artix7"; cfg.SynthesisToolDeviceName = "xa7a100t"; cfg.SynthesisToolPackageName = "csg324"; cfg.SynthesisToolSpeedValue = "-1I";
The script then generates code:
codegen("-float2fixed", "fixptCfg", "-config", "cfg", designName, ... "-launchreport");
Run the Script
First, modify the mlhdlc_lms_fcn_runme script. The
script disables synthesis by default. Set the value for the
SynthesizeGeneratedCode property to
true:
cfg.SynthesizeGeneratedCode = true;
Update the settings for your synthesis tool:
cfg.SynthesisTool = "Xilinx Vivado"; cfg.SynthesisToolChipFamily = "Artix7"; cfg.SynthesisToolDeviceName = "xa7a100t"; cfg.SynthesisToolPackageName = "csg324"; cfg.SynthesisToolSpeedValue = "-1I";
Then, generate code by running the script:
mlhdlc_lms_fcn_runme
After code generation completes, the report opens. Examine the generated HDL code in the report.
Generate Modular HDL Code for Functions
By default, HDL Coder inlines the body of all MATLAB functions that are called
inside the body of the top-level design function. This inlining generates a
single file that contains the HDL code for all functions. To generate modular
HDL code with a separate VHDL® entity or Verilog® module for each function, enable
the InstantiateFunctions HDL configuration object
property:
cfg.InstantiateFunctions = true;
Then generate code:
codegen("-float2fixed", "fixptCfg", "-config", "cfg", designName, ... "-launchreport");
When you enable this property, HDL Coder generates a separate HDL file for
each function in the design. For example, with this LMS filter design, HDL Coder
generates separate modules for the mtapped_delay_fcn,
mtreesum_fcn, and update_weight_fcn
functions.
To control inlining for individual functions, use the
coder.inline pragma inside the function
body:
coder.inline("never"); % Prevent inlining (always instantiate) coder.inline("always"); % Always inline (never instantiate) coder.inline("default"); % Let the code generator decide
Generate HLS Code
To generate HLS code from the same design, create a fixed-point configuration
object and an HLS configuration object by using the
coder.config function. Specify the MATLAB function and
test bench, and associate the test bench with both configuration
objects.
designName = "mlhdlc_lms_fcn"; designTB = "mlhdlc_lms_fir_id_tb"; fixptCfg = coder.config("fixpt"); fixptCfg.TestBenchName = designTB; cfg = coder.config("hls"); cfg.TestBenchName = designTB;
Enable HLS test bench generation and simulation.
cfg.GenerateHLSTestBench = true; cfg.SimulateGeneratedCode = true;
Specify the synthesis tool, chip family, device name, package name, and speed value:
cfg.SynthesisTool = "Xilinx Vitis HLS"; cfg.SynthesisToolChipFamily = "Artix7"; cfg.SynthesisToolDeviceName = "xa7a100t"; cfg.SynthesisToolPackageName = "csg324"; cfg.SynthesisToolSpeedValue = "-1I";
Generate code:
codegen("-float2fixed", "fixptCfg", "-config", "cfg", designName, ... "-launchreport");
After code generation completes, the report opens. Examine the generated HLS code in the report.