Using MATLAB with Verilog HDL


When designing digital signal processing (DSP) systems using Verilog HDL, verifying the functionality of the design can be very tedious using the ordinary HDL simulators (i.e., ModelSim). Likewise, when a model of the DSP system has been generated in MATLAB, it can be convenient to leverage the same stimulus for the model to the HDL simulation in lieu of developing a stimulus generator in an HDL language.


How to Export Verilog HDL Simulation Data to MATLAB?


Using Verilog HDL's file I/O capabilities, the simulation results of important nodes in a DSP system can be written into a MATLAB file for more detailed analysis. The simplified Verilog HDL code below shows how to generate the MATLAB file:

                        module tb();
                        
                        // I/Os:
                        wire    [35:0]  out;
                        reg     [17:0]  a, b;
                        reg             clk;

                        // *** Local Integer Declarations ***
                        integer         i_cnt;
                        integer         m_file1; // File ID for Matlab File

                        // Instantiate UUT:
                        // dsp performs: out = a*b;
                        dsp uut (.clk (clk), .a (a), .b (b), .out (out));

                        // Generate clock:
                        always #1.65 clk <= ~clk;

                        // initial block
                        initial
                        begin
                        $timeformat(-9, 0, " ns", 8);
                        clk = 0;
                        a = 0;
                        b = 0;
                        i_cnt = 0;
                        @ (posedge clk);
                        m_file1=$fopen("sim_data.m");
                        $fdisplay(m_file1, "%%DSP Verilog HDL testbench results for Matlab Simulation.");
                        $fdisplay(m_file1, "%%This file contains the inputs of a and b, and the outputs out.");
                        $fwrite(m_file1, "\n");
                        
                        $display("Capture 8192 samples of individual values for an 8192-point FFT.");
                        for (i_cnt=0;i_cnt<8192; i_cnt=i_cnt+1)
                        begin
                            a = i_cnt;
                            b = 1-i_cnt;
                            $fdisplay(m_file1,"a(%1.0d) = %1.0d;",i_cnt+1,$signed(a));
                            $fdisplay(m_file1,"b(%1.0d) = %1.0d;",i_cnt+1,$signed(b));
                            $fdisplay(m_file1,"out(%1.0d) = %1.0d;",i_cnt+1,$signed(out));
                            @ (posedge clk);
                        end

                        $fclose(m_file1);
                        $stop;
                        end

                        endmodule
                    

The Verilog HDL code generates a MATLAB file that contains the multiplier a, the multiplicand b, and the product out. The values in the MATLAB file are signed decimal values. The resulting file can now be used in a MATLAB simulation.

                        %-------------------------------------------------------------------------------
                        %
                        % test_sim_data.m script
                        %
                        %-------------------------------------------------------------------------------
                        %
                        % My Company Confidential, Copyright  2017  Research and Development
                        %
                        %-------------------------------------------------------------------------------
                        %
                        % created on:	03/22/2017 
                        % created by:	jwwebb
                        % last edit on:	$DateTime: $ 
                        % last edit by:	$Author: $
                        % revision:     $Revision: $
                        % comments:	    Generated
                        %
                        %-------------------------------------------------------------------------------
                        % Common IP
                        %
                        % This matlab script implements the plotting of various test points
                        % along the data path in the DSP Verilog HDL module.
                        %
                        %-------------------------------------------------------------------------------
                        %% Setup Environment
                        clear;clc;close all;
                        addpath('../data/hdl/');

                        %% Set Plotting Variables:
                        PlotOn = 1;
                        PrintOn = 0;

                        %% Load Data
                        sim_data;

                        %% Prepare X-Axis Data:
                        x=1:length(a);

                        %% Plot the Data: 
                        if PlotOn
                            %% Plot Inputs and Outputs:
                            figure(1);
                            set(gca,'FontSize',14.0);
                            hold on;
                            plot(x,a,'r-s','LineWidth',2.0);
                            plot(x,b,'k-o','LineWidth',2.0);
                            plot(x,out,'b-^','LineWidth',2.0);
                            title('Multiplier I/O','FontSize',14.0);
                            axis([x(1) x(end) min(out)-1 max(out)+1]);
                            grid on;
                            hold off;
                            % Save plot:
                            if PrintOn
                                png_file = sprintf('../images/hdl/multiplier_io.png');
                                print(png_file, '-dpng');
                                eps_file = sprintf('../images/hdl/multiplier_io.eps');
                                print(eps_file, '-depsc');
                            end
                        end
                    
Back to Top

How to Export MATLAB Model Data to Verilog HDL?


Likewise, MATLAB can be used to generate a Verilog HDL file by using its file I/O capabilities. The MATLAB code used to generate a Verilog HDL file is shown below:

                        %-------------------------------------------------------------------------------
                        %
                        % test_sim_data.m script
                        %
                        %-------------------------------------------------------------------------------
                        %
                        % My Company Confidential, Copyright  2017  Research and Development
                        %
                        %-------------------------------------------------------------------------------
                        %
                        % created on:	03/22/2017 
                        % created by:	jwwebb
                        % last edit on:	$DateTime: $ 
                        % last edit by:	$Author: $
                        % revision:     $Revision: $
                        % comments:	    Generated
                        %
                        %-------------------------------------------------------------------------------
                        % Common IP
                        %
                        % This matlab script generates data for use in a Verilog HDL simulation.
                        %
                        %-------------------------------------------------------------------------------
                        %% Setup Environment
                        clear;clc;close all;
                        
                        %% Set Variables:
                        PlotOn = 1;
                        PrintOn = 0;
                        WriteMe = 1;

                        %% Generate impulse response stimulus vector for Verilog HDL simulation:
                        %--------------------------------------------------------------
                        % Write the Verilog HDL File:
                        %--------------------------------------------------------------
                        if WriteMe
                            %----------------------------------------------------------
                            % Open the File Handle:
                            %----------------------------------------------------------
                            filename = sprintf('./stim.v');
                            fid = fopen(filename,'w');
                            %----------------------------------------------------------
                            % Write the File Header:
                            %----------------------------------------------------------
                            fprintf(fid,'module stim      (input wire   [9:0]   addr,\n');
                            fprintf(fid,'                  input wire           clk,\n');
                            fprintf(fid,'                  input wire           rst_n,\n');
                            fprintf(fid,'                  output wire  [17:0]  s_data);\n');
                            fprintf(fid,'\n\n');
                            fprintf(fid,'wire    [17:0]   data_rom [50:0];\n\n');
                            %----------------------------------------------------------
                            % Write the File Data:
                            %----------------------------------------------------------
                            fprintf(fid,'assign data_rom[0] = 18''b%1.0f%1.0f_%1.0f%1.0f%1.0f%1.0f_%1.0f%1.0f%1.0f%1.0f_...
                                                                 %1.0f%1.0f%1.0f%1.0f_%1.0f%1.0f%1.0f%1.0f;\n',...
                                                                 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);

                            data3 = zeros(1,100);
                           
                            for k=1:15,
                              fprintf(fid,'assign data_rom[%1.0f] = 18''b%1.0f%1.0f_%1.0f%1.0f%1.0f%1.0f_...
                                                                     %1.0f%1.0f%1.0f%1.0f_%1.0f%1.0f%1.0f%1.0f_...
                                                                     %1.0f%1.0f%1.0f%1.0f;\n',k,data3(k),data3(k),...
                                                                     data3(k),data3(k),data3(k),data3(k),data3(k),...
                                                                     data3(k),data3(k),data3(k),data3(k),data3(k),
                                                                     data3(k),data3(k),data3(k),data3(k),data3(k),data3(k));      
                            end

                            fprintf(fid,'assign data_rom[16] = 18''b%1.0f%1.0f_%1.0f%1.0f%1.0f%1.0f_%1.0f%1.0f%1.0f%1.0f_...
                                                                  %1.0f%1.0f%1.0f%1.0f_%1.0f%1.0f%1.0f%1.0f;\n',...
                                                                  0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);

                            for k=17:50,
                              fprintf(fid,'assign data_rom[%1.0f] = 18''b%1.0f%1.0f_%1.0f%1.0f%1.0f%1.0f_%1.0f%1.0f%1.0f%1.0f_...
                                                                     %1.0f%1.0f%1.0f%1.0f_%1.0f%1.0f%1.0f%1.0f;\n',k,data3(k),...
                                                                     data3(k),data3(k),data3(k),data3(k),data3(k),data3(k),...
                                                                     data3(k),data3(k),data3(k),data3(k),data3(k),data3(k),...
                                                                     data3(k),data3(k),data3(k),data3(k),data3(k));      
                            end

                            fprintf(fid,'\n\n');
                            fprintf(fid,'//always @ (posedge clk or negedge rst_n)\n');
                            fprintf(fid,'//begin\n');
                            fprintf(fid,'\t//if (!rst_n)\n');
                            fprintf(fid,'\t\t//s_data[17:0] <= 18''h00000;\n');
                            fprintf(fid,'\t//else\n');
                            fprintf(fid,'\t\t//s_data[17:0] <= data_rom[addr];\n');
                            fprintf(fid,'//end\n');

                            fprintf(fid,'\tassign s_data[17:0] = data_rom[addr];\n');

                            fprintf(fid,'\nendmodule\n');
                            %----------------------------------------------------------
                            % Close the File Handle
                            %----------------------------------------------------------
                            fclose(fid);
                        end
                    

The MATLAB code generates a Verilog HDL file containing a ROM with two impulse functions. This ROM can be used to stimulate a FIR filter in ModelSim to verify that the filter coefficients are output in the correct order and value. The Verilog HDL module can be instantiated in the Verilog HDL test bench of the unit under test (UUT).

Back to Top