Generate and Synthesize HDL Code for Symmetric FIR Filter Using the HDL Workflow Advisor
This example shows you how to create an HDL Coder™ project and use the MATLAB HDL Workflow Advisor to generate code from a MATLAB® design, verify the MATLAB design with an HDL test bench, and synthesize the generated HDL code. This example uses ModelSim® as the HDL simulation tool and Xilinx® Vivado® as the third-party synthesis tool. For more information on generating HDL code and performing FPGA synthesis programmatically, see Programmatically Generate, Verify, and Synthesize HDL Code from MATLAB Code.
Examine the MATLAB Design
The MATLAB design mlhdlc_sfir is a simple symmetric FIR filter. Open the MATLAB design.
design_name = "mlhdlc_sfir"; testbench_name = "mlhdlc_sfir_tb"; open(design_name);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % MATLAB design: Symmetric FIR Filter % % Introduction: % % We can reduce the complexity of the FIR filter by leveraging its % symmetry. Symmetry for an n-tap filter implies, coefficient h0 = % coefficient hn-1, coefficient, h1 = coefficient hn-2, etc. In this case, % the number of multipliers can be approximately halved. The key is to add % the two data values that need to be multiplied with the same coefficient % prior to performing the multiplication. % % Key Design pattern covered in this example: % (1) Filter states represented using the persistent variables % (2) Filter coefficients passed in as parameters % Copyright 2011-2026 The MathWorks, Inc. %#codegen function [y_out, delayed_xout] = mlhdlc_sfir(x_in,h_in1,h_in2,h_in3,h_in4) % Symmetric FIR Filter % declare and initialize the delay registers persistent ud1 ud2 ud3 ud4 ud5 ud6 ud7 ud8; if isempty(ud1) ud1 = 0; ud2 = 0; ud3 = 0; ud4 = 0; ud5 = 0; ud6 = 0; ud7 = 0; ud8 = 0; end % access the previous value of states/registers a1 = ud1 + ud8; a2 = ud2 + ud7; a3 = ud3 + ud6; a4 = ud4 + ud5; % multiplier chain m1 = h_in1 * a1; m2 = h_in2 * a2; m3 = h_in3 * a3; m4 = h_in4 * a4; % adder chain a5 = m1 + m2; a6 = m3 + m4; % filtered output y_out = a5 + a6; % delayout input signal delayed_xout = ud8; % update the delay line ud8 = ud7; ud7 = ud6; ud6 = ud5; ud5 = ud4; ud4 = ud3; ud3 = ud2; ud2 = ud1; ud1 = x_in; end
Examine the MATLAB Test Bench
The mlhdlc_sfir_tb test bench defines low-pass filter coefficients and applies a representative input range. The test bench runs the design with these inputs to test the filter response. For more information on MATLAB test bench requirements and best practices, see Using Test Benches With HDL and HLS Code Generation.
Open the test bench.
open(testbench_name);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % MATLAB test bench for the FIR filter %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Copyright 2011-2026 The MathWorks, Inc. clear mlhdlc_sfir; T = 2; dt = 0.001; N = T/dt+1; sample_time = 0:dt:T; df = 1/dt; sample_freq = linspace(-1/2,1/2,N).*df; % input signal with noise x_in = cos(2.*pi.*(sample_time).*(1+(sample_time).*75)).'; % filter coefficients h1 = -0.1339; h2 = -0.0838; h3 = 0.2026; h4 = 0.4064; len = length(x_in); y_out = zeros(1,len); x_out = zeros(1,len); for ii=1:len data = x_in(ii); % call to the design "mlhdlc_sfir" that is targeted for hardware [y_out(ii), x_out(ii)] = mlhdlc_sfir(data, h1, h2, h3, h4); end figure("Name", string(mfilename) + "_plot"); subplot(3,1,1); plot(1:len,x_in,"-b"); xlabel("Time (ms)") ylabel("Amplitude") title("Input Signal (with noise)") subplot(3,1,2); plot(1:len,y_out,"-b"); xlabel("Time (ms)") ylabel("Amplitude") title("Output Signal (filtered)") freq_fft = @(x) abs(fftshift(fft(x))); subplot(3,1,3); semilogy(sample_freq,freq_fft(x_in),"-b"); hold on semilogy(sample_freq,freq_fft(y_out),"-r") hold off xlabel("Frequency (Hz)") ylabel("Amplitude (dB)") title("Input and Output Signals (Frequency domain)") legend({"FilterIn", "FilterOut"},"Location","South") axis([-500 500 1 100])
Test the MATLAB Design
Verify that mlhdlc_sfir processes a sample stream without error and meets filtering requirements before generating HDL code. Run the design with mlhdlc_sfir_tb to produce a chirp input and provide low-pass filter coefficients. The test bench streams samples to mlhdlc_sfir, then plots the time- and frequency-domain behavior of the input and output signals.
The comparison plot shows that the filtered output is smoother than the input in the time domain. In the frequency domain, the magnitude of the filtered output is lower than the input at higher frequencies. The test bench results confirm mlhdlc_sfir implements a low-pass filter as expected according to the filter coefficients.
mlhdlc_sfir_tb

Set Up the Third-Party Synthesis Tool and HDL Simulator
Next, set up your third-party synthesis tool and HDL simulator. For a list of supported third-party tool versions, see HDL Language Support and Supported Third-Party Tools and Hardware.
This example uses Xilinx Vivado. To set the path to the third-party synthesis tool, use the hdlsetuptoolpath function. In the MATLAB Command Window, use this command, and replace the path with your installation path:
hdlsetuptoolpath("ToolName","Xilinx Vivado","ToolPath",... vivadopath);
To check your Xilinx Vivado synthesis tool setup, launch Xilinx Vivado by running this command:
!vivado
To simulate the generated HDL code using an HDL test bench, use an HDL simulator, such as ModelSim®. For more information on setting up third-party FPGA synthesis tools and HDL simulators, see Set Up Tools.
Note
Do not use spaces in file names or paths to prevent code generation failures. You can use the workDir name-value argument of the openExample function to open this example in a directory with a shorter name and no spaces or special characters. For example, this code sets the current working directory as your temporary folder directory for your system and opens the example.
tempdir
openExample("hdlcoder/BasicHDLCodeGenAndFPGASynthesisFromMATLABExample",workDir=tempdir)
Create an HDL Coder Project
To create an HDL Coder project:
1. In the MATLAB Command Window, create an HDL Coder project by running this command:
coder -hdlcoder -new sfir_project
2. Click Add MATLAB function. In the dialog box, select the MATLAB design, mlhdlc_sfir. Add only the top-level MATLAB function.
3. Click Add files. In the dialog box, select the test bench mlhdlc_sfir_tb.
4. In the MATLAB Function section, click Autodefine types to define the input types. In the dialog box, click Run. In the Autodefine Input Types window, click Use These Types. HDL Coder runs the test bench to infer the input data types of the MATLAB design mlhdlc_sfir.
5. Open the HDL Workflow Advisor by clicking Workflow Advisor.

Create a Fixed-Point Version of the MATLAB Design
Next, convert floating-point data types in the MATLAB design to fixed-point data types by proposing fixed-point fraction lengths and adding a safety margin. In the Fixed-Point Conversion task, you can use the Default word length property to specify the word lengths for floating-point data types. For this example, set the Default word length to 14.
To add a safety margin to the simulation-derived ranges and base fixed-point data type proposals on the expanded range, use the Safety Margin for Simulation Min/Max property. For this example, click Advanced, then set Safety Margin for Simulation Min/Max to 10.
Right-click the Fixed-Point Conversion task and select Run This Task.
For more information on floating-point to fixed-point conversion, see Floating-Point to Fixed-Point Conversion.
Define Code Generation Target and Platform
To deploy generated HDL code on a target platform, specify the target and third-party synthesis tool before you generate HDL code.
In the Select Code Generation Target task, set these parameters:
Set Workflow to
Generic ASIC/FPGA.Set Synthesis tool to
Xilinx Vivado. If you do not see the synthesis tool, click Refresh list.Set Target frequency (MHz) to
200.
When you set Synthesis tool to Xilinx Vivado, the HDL Workflow Advisor exposes these properties and sets them to these settings:
The Chip family is set to
Artix UltraScale+.The Device is set to
xaau7p-fcva289-1-i.
Right-click the Select Code Generation Target task and select Run This Task.
Set Code Generation Options and Generate HDL Code
Next, set HDL code generation options and generate code. In the HDL Code Generation task, set these options.
To generate Verilog code, in the Target tab, set Language to Verilog.
To generate a code generation report with comments and traceability links:
In the Target tab, select Generate report.
In the Coding Style tab, select Include MATLAB source code as comments.
To optimize your design by using distributed pipelining:
In the Optimizations tab, set Input pipelining and Output pipelining to
1.In the Optimizations tab, select Distribute pipeline registers.
To learn more about distributed pipelining optimization, see Specify Distributed Pipelining Settings.
Click Run.
After you generate the Verilog code, in the bottom of the right pane, click the View report link to open the HDL code generation report in the HDL Coder Report Viewer. For more information on HDL code generation reports, see Code Generation Reports.
Generate an HDL Test Bench and Simulate the Generated Code
Next, generate an HDL test bench, run the HDL test bench using an HDL simulator, and verify whether the HDL simulation matches the numerics and latency of the fixed-point MATLAB simulation. For more information on verifying generated HDL code with an HDL test bench, see Verify Code with HDL Test Bench.
In the Verification > Verify with HDL Test Bench task:
In the Output Settings tab, select Generate test bench.
Select Simulate generated test bench.
Set Simulation tool to
ModelSim.To generate the HDL test bench code and test bench data in separate files, in the Test Bench Options tab, select Multi file test bench.
Click Run.
Synthesize Generated HDL Code
Next, use HDL Coder to facilitate the synthesis of the generated HDL code on the target platform and generate area and timing reports for your design based on the target device.
To synthesize the generated HDL code:
1. Right-click the Synthesis and Analysis > Create Project task and select Run This Task.
This task creates a Xilinx Vivado synthesis project for the HDL code. Xilinx Vivado uses this project to synthesize the design.
2. Right-click the Synthesis and Analysis > Run Synthesis task and select Run This Task.
This task launches the synthesis tool in the background, opens the synthesis project, compiles the HDL code, synthesizes the design, and generates the netlists and area and timing reports.
3. Right-click the Synthesis and Analysis > Run Implementation task and select Run This Task.
This task launches the synthesis tool in the background, runs place and route on the design, and generates pre- and post-route timing information for use in critical path analysis and back annotation of your source design.