HDL Code Generation from a MATLAB Algorithm

About the Algorithm in This Example

For the purpose of this example, you generate and synthesize HDL code for a MATLAB® algorithm that implements a simple filter. However, you can use HDL Coder™ to generate HDL code from MATLAB algorithms for many applications.

This tutorial uses these files:

  • mlhdlc_sfir.m — Simple filter function from which you generate HDL code.

  • mlhdlc_sfir_tb.m — Test bench that the HDL Coder project uses to exercise the filter using a representative input range.

mlhdlc_sfir Function Code

The following code provides the complete mlhdlc_sfir function definition.

%#codegen
function [y_out, delayed_xout] = mlhdlc_sfir(x_in, h_in1, h_in2, h_in3, h_in4)
% Symmetric FIR Filter

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

a1 = ud1 + ud8; a2 = ud2 + ud7;
a3 = ud3 + ud6; a4 = ud4 + ud5;

m1 = h_in1 * a1; m2 = h_in2 * a2;
m3 = h_in3 * a3; m4 = h_in4 * a4;

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

mlhdlc_sfir_tb.m Test Bench

The mlhdlc_sfir_tb test bench creates an input signal and calls the mlhdlc_sfir filter, passing in the input data.

clear all;
 
% input signal with noise
x_in = cos(2.*pi.*(0:0.001:2).*(1+(0:0.001:2).*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', [mfilename, '_plot']);
subplot(2,1,1); plot(1:len,x_in); 
subplot(2,1,2); plot(1:len,y_out);

Copying Files Locally

Before you begin generating code, set up a working folder and copy the tutorial files to this folder.

  1. Start MATLAB.

  2. Create a folder named filter_sfir, for example:

    mkdir filter_sfir

    The folder must not be within the MATLAB directory structure. You must be able to write to this folder.

  3. Copy the tutorial files, mlhdlc_sfir.m and mlhdlc_sfir_tb.m, to this folder.

Checking Your Synthesis Tool Setup

Before using HDL Coder to synthesize HDL code, you must set up your synthesis tool path.

To check your Xilinx® ISE synthesis tool setup, try launching the tool with the following command:

!ise

To check your Altera® Quartus synthesis tool setup, try launching the tool with the following command:

!quartus

If the tool does not open, or opens the wrong version, see Synthesis Tool Path Setup.

Testing the Original MATLAB Algorithm

Before generating HDL code for this MATLAB algorithm, simulate your MATLAB design to verify that it runs, and to provide a baseline for comparison with the generated HDL code.

  1. Make the filter_sfir folder your working folder, for example:

    cd filter_sfir
  2. Run the test bench. At the MATLAB command line, enter:

    mlhdlc_sfir_tb

    The test bench runs and plots the input signal and the filtered output.

Setting Up an HDL Coder Project

  1. On the Apps tab, on the far right of the Apps section, click the arrow .

  2. Under Code Generation, click HDL Coder.

  3. Enter mydesign for the project name.

    HDL Coder creates the project, mydesign.prj, in the local working folder, and opens the project in the right side of the MATLAB workspace.

  4. Under MATLAB Function, click Add MATLAB function.

  5. In the Add Files dialog box, select mlhdlc_sfir.m and click Open.

    HDL Coder adds the file to the project.

  6. Under MATLAB Test Bench, click Add MATLAB test bench.

  7. In the Add Files dialog box, select mlhdlc_sfir_tb.m and click Open.

    HDL Coder adds the test bench file to the project.

    You are now ready to convert the code from floating-point to fixed-point.

Creating Fixed-Point Versions of the Algorithm and Test Bench

  1. In the project, at the bottom of the pane, click the Workflow Advisor button to open the HDL Coder Workflow Advisor.

  2. Select the Define Input Types task and click Run.

    HDL Coder simulates the algorithm and test bench, and automatically defines input types.

  3. On the left, select the Fixed-Point Conversion task. The Fixed-Point Conversion tool opens in the right pane.

    1. At the top left, click Run Simulation.

      After the simulation, each input, output, and persistent variable has a Sim Min, Sim Max, and Proposed Type in the table.

      When proposing fraction lengths for floating-point data types, HDL Coder uses the Default word length. In this tutorial, the Default word length is 14. The advisor provides a default Safety Margin for Simulation Min/Max of 0%. The advisor adjusts the range of the data by this safety factor. For example, a value of 4 specifies that you want a range of at least 4 percent larger.

      In this example, we use only the simulation ranges to infer fixed-point types. Compute Derived Ranges gives you the option of using static range analysis. To learn more about options in the fixed-point conversion workflow, see Automated Fixed-Point Conversion.

    2. At the top, in the Verification section, click Validate Types.

      HDL Coder validates the build with the proposed fixed-point types and generates a fixed-point design.

    3. At the top, in the Verification section, click the down-arrow for Test Numerics and select Log inputs and outputs for comparison plots. Click the top part of the Test Numerics button.

      HDL Coder simulates the fixed-point design with the original test bench compares the output to the original floating-point design output.

    4. Click the down-arrow to the right of the Verification Output tab and select Type Validation Output. Click mlhdlc_sfir_fixpt to see the fixed-point MATLAB code for the mlhdlc_sfir function.

      %#codegen
      function [y_out,delayed_xout] = mlhdlc_sfir_fixpt(x_in,h_in1,h_in2,h_in3,h_in4)
      
      fm = fimath('RoundingMethod', 'Floor', 'OverflowAction', 'Wrap', 'ProductMode',
       'FullPrecision', 'MaxProductWordLength', 128, 'SumMode', 'FullPrecision',
       'MaxSumWordLength', 128);
      % Symmetric FIR Filter
      % declare and initialize the delay registers
      persistent ud1 ud2 ud3 ud4 ud5 ud6 ud7 ud8
      if isempty( ud1 )
          ud1 = fi(0, 1, 14, 12, fm);
          ud2 = fi(0, 1, 14, 12, fm);
          ud3 = fi(0, 1, 14, 12, fm);
          ud4 = fi(0, 1, 14, 12, fm);
          ud5 = fi(0, 1, 14, 12, fm);
          ud6 = fi(0, 1, 14, 12, fm);
          ud7 = fi(0, 1, 14, 12, fm);
          ud8 = fi(0, 1, 14, 12, fm);
      end
      % access the previous value of states/registers
      a1 = fi(ud1 + ud8, 1, 14, 11, fm);
      a2 = fi(ud2 + ud7, 1, 14, 11, fm);
      a3 = fi(ud3 + ud6, 1, 14, 11, fm);
      a4 = fi(ud4 + ud5, 1, 14, 11, fm);
      % multiplier chain
      m1 = fi(h_in1*a1, 1, 14, 14, fm);
      m2 = fi(h_in2*a2, 1, 14, 15, fm);
      m3 = fi(h_in3*a3, 1, 14, 14, fm);
      m4 = fi(h_in4*a4, 1, 14, 13, fm);
      % adder chain
      a5 = fi(m1 + m2, 1, 14, 14, fm);
      a6 = fi(m3 + m4, 1, 14, 12, fm);
      % filtered output
      y_out = fi(a5 + a6, 1, 14, 12, fm);
      % delayout input signal
      delayed_xout = fi(ud8, 1, 14, 12, fm);
      % update the delay line
      ud8 = fi(ud7, 1, 14, 12, fm);
      ud7 = fi(ud6, 1, 14, 12, fm);
      ud6 = fi(ud5, 1, 14, 12, fm);
      ud5 = fi(ud4, 1, 14, 12, fm);
      ud4 = fi(ud3, 1, 14, 12, fm);
      ud3 = fi(ud2, 1, 14, 12, fm);
      ud2 = fi(ud1, 1, 14, 12, fm);
      ud1 = fi(x_in, 1, 14, 12, fm);
      end
      

    5. Click the View report link.

      You can explore the fixed-point code further in the Code Generation Report.

Generating HDL Code

  1. In the HDL Workflow Advisor left pane, select HDL Code Generation and click Run to generate HDL code with the default options.

    The message window has a links to the generated HDL code and the resource report. Click the links to view the code and resource report.

      Tip   You can use the Target, Coding Style, Clocks and Ports, Optimizations, Advanced, and Script Options tabs to set code generation options. To learn about the options, click the ? button.

  2. In the HDL Workflow Advisor left pane, select HDL Verification > Verify with HDL Test Bench.

  3. Enable Generate HDL test bench and disable Skip this step. Enable Simulate generated HDL test bench and select a simulation tool. Click Run.

    The task generates an HDL test bench, then simulates the fixed-point design using the selected simulation tool, and generates a compilation report and a simulation report.

  4. Click Synthesis and Analysis and disable Skip this step.

    1. Select Create Project.

    2. On the right, select a Synthesis tool from the list and click Run.

      This task creates a synthesis project for the HDL code. HDL Coder uses this project in the next task to synthesize the design.

  5. Select and run Run Logic Synthesis.

    This task:

    • Launches the synthesis tool in the background.

    • Opens the synthesis project created in the previous task, compiles HDL code, synthesizes the design, and emits netlists and related files.

    • Generates a synthesis report.

  6. Select and run Place and Route.

    This task:

    • Launches the synthesis tool in the background.

    • Runs a Place and Route process that takes the circuit description produced by the previous mapping process, and emits a circuit description suitable for programming an FPGA.

    • Emits pre- and post-routing timing information for use in critical path analysis and back annotation of your source model.

    • Displays results.

Was this topic helpful?