Main Content

Use Templates to Create SystemVerilog DPI and UVM Components

This example shows how to generate SystemVerilog direct programming interface (DPI) and universal verification methodology (UVM) components from MATLAB® functions using built-in templates. This example also reviews the generated SystemVerilog and how it relates to the template. This example teaches you basic template capabilities, that you can use to create a custom template.

HDL Verifier™ provides built-in templates that cover most use cases. If you require a different template, create a custom template using concepts shown in this example.

Introduction

In this example, you use a sine wave MATLAB function as a design under test (DUT), and follow the steps to generate a SystemVerilog DPI component by using the built-in sequential DPI template. After generating a SystemVerilog DPI component, you generate a UVM scoreboard by using the built-in UVM scoreboard template to check the output of the DUT. From this example, you learn how to:

  • Define a template variable by using the dictionary.

  • Assign a value to a template variable.

  • Override a template variable from the svdpiConfiguration object.

  • Represent a collection of ports as a group in the template.

Generate SystemVerilog DPI Component

The sequential module template generates the Systemverilog DPI component from a sine wave MATLAB function.

Default ports in the sequential module template for a DPI component. They are control singals (clock and reset), inputs, and outputs.

To generate your component from the template, first create a svdpiConfiguration object.

svcfg=svdpiConfiguration
svcfg = 
  svdpiConfiguration with properties:

             ComponentKind: 'sequential-module'
        CoderConfiguration: [1x1 coder.EmbeddedCodeConfig]
         ComponentTypeName: ''
         TestBenchTypeName: ''
        MATLABFunctionName: ''
                PortGroups: []
    ComponentTemplateFiles: {'/mathworks/devel/bat/filer/batfs1904-0/Bdoc24a.2528353/build/matlab/toolbox/hdlverifier/dpigenerator/rtw/SequentialModuleML.svt'}
    TestBenchTemplateFiles: {'/mathworks/devel/bat/filer/batfs1904-0/Bdoc24a.2528353/build/matlab/toolbox/hdlverifier/dpigenerator/rtw/SequentialTestBenchML.svt'}
        TemplateDictionary: []

By default, the component kind is set to 'sequential-module'

The 'sequential-module' uses the SequentialModuleML.svt template file to generate the component. You can find the templates at this location.

templateLocation = fileparts(svcfg.ComponentTemplateFiles{1});

Next, generate the component using dpigen function.

dpigen sineWaveGen -testbench sineWaveGen_tb -args {0,0} -config svcfg
### Generating DPI-C Wrapper /tmp/Bdoc24a_2528353_571106/tpf5a098f3/hdlverifier-ex18925523/codegen/dll/sineWaveGen/sineWaveGen_dpi.c
### Generating DPI-C Wrapper header file /tmp/Bdoc24a_2528353_571106/tpf5a098f3/hdlverifier-ex18925523/codegen/dll/sineWaveGen/sineWaveGen_dpi.h
### Generating source code file /tmp/Bdoc24a_2528353_571106/tpf5a098f3/hdlverifier-ex18925523/codegen/dll/sineWaveGen/sineWaveGen_pkg.sv from template text.
### Generating source code file /tmp/Bdoc24a_2528353_571106/tpf5a098f3/hdlverifier-ex18925523/codegen/dll/sineWaveGen/sineWaveGen.sv from template text.
### Generating makefiles for: sineWaveGen_dpi
### Running simulation to capture input and expected outputs for a standalone test bench.
### This may take some time...
Code generation successful.

### ...DONE with vector capture.
### Generating source code file /tmp/Bdoc24a_2528353_571106/tpf5a098f3/hdlverifier-ex18925523/codegen/dll/sineWaveGen/dpi_tb/sineWaveGen_tb.sv from template text.
### Generating source code file /tmp/Bdoc24a_2528353_571106/tpf5a098f3/hdlverifier-ex18925523/codegen/dll/sineWaveGen/dpi_tb/run_tb_mq.do from template text.
### Generating source code file /tmp/Bdoc24a_2528353_571106/tpf5a098f3/hdlverifier-ex18925523/codegen/dll/sineWaveGen/dpi_tb/run_tb_xcelium.sh from template text.
### Generating source code file /tmp/Bdoc24a_2528353_571106/tpf5a098f3/hdlverifier-ex18925523/codegen/dll/sineWaveGen/dpi_tb/run_tb_vcs.sh from template text.
### Generating source code file /tmp/Bdoc24a_2528353_571106/tpf5a098f3/hdlverifier-ex18925523/codegen/dll/sineWaveGen/dpi_tb/run_tb_vivado.sh from template text.
### Generating source code file /tmp/Bdoc24a_2528353_571106/tpf5a098f3/hdlverifier-ex18925523/codegen/dll/sineWaveGen/dpi_tb/run_tb_vivado.bat from template text.
### Compiling the DPI Component
Code generation successful.

Define and Assign Template Variables

After generating your DPI component, review the generated SystemVerilog files, and relate them to the template. Open these two template files.

edit(svcfg.ComponentTemplateFiles{1});
edit(fullfile(fileparts(svcfg.ComponentTemplateFiles{1}),'SystemVerilogTemplateLibrary.svt'));

Open the SystemVerilog DPI component file that you generated.

edit(fullfile('codegen','dll','sineWaveGen','sineWaveGen.sv'));

To understand how to assign values to template variables, compare the generated component file to the template file. The sineWaveGen.sv file is created from the following section of the SequentialModuleML.svt template file. It contains a template variable named <SVTLCommonHeader>.

SVTL common header variable.

The SequentialModuleML.svt template file also includes the contents of the SystemVerilogTemplateLibrary.svt.

Include SystemVerilogTemplateLibrary.svt

HDL Verifier™ defines the SVTLCommonHeader template variable in the local dictionary of the SystemVerilogTemplateLibrary.svt file. The syntax of the local dictionary is %<BEGIN_LOCAL_DICTIONARY> ... %<END_LOCAL_DICTIONARY>.

A dictionary entry has the form of template_variable_name = template_variable_value. In this example, the definition for SVTLCommonHeader requires multiple lines so it uses a %<BEGIN_VARIABLE_DEFINITION> ... %<END_VARIABLE_DEFINITION> code block. Use this format for multi-line definitions.

Define template variable in the local dictionary.

After defining the template variable in the dictionary, you use the variable in your template file with the format of %<variable_name>. In this example, the variable is %<SVTLCommonHeader>. During code generation, the template variable is replaced by its defined content. In this DPI component, the sineWaveGen.sv includes the content of the SVTLCommonHeader template variable.

SVTLCommonHeader is replaced by its defined content.

Generate UVM Scoreboard

A UVM scoreboard is a UVM component. Typically, the scoreboard accepts inputs from the DUT through a monitor, and from a golden reference model (predictor). For more information about the UVM test bench, see UVM Component Generation Overview.

In this part of the example, you generate a UVM scoreboard, which compares the output of the sine wave generator (DUT) with the output of a golden reference. To monitor the output, the scoreboard uses a normalized sine wave function as a golden reference, and the amplitude of the DUT sine wave as a parameter of the scoreboard configuration object.

On the MATLAB command line, set the component kind to 'uvm-scoreboard'.

clear svcfg;
svcfg=svdpiConfiguration;
svcfg.ComponentKind = 'uvm-scoreboard'
svcfg = 
  svdpiConfiguration with properties:

             ComponentKind: 'uvm-scoreboard'
        CoderConfiguration: [1x1 coder.EmbeddedCodeConfig]
         ComponentTypeName: ''
         TestBenchTypeName: ''
        MATLABFunctionName: ''
                PortGroups: []
    ComponentTemplateFiles: {'/mathworks/devel/bat/filer/batfs1904-0/Bdoc24a.2528353/build/matlab/toolbox/hdlverifier/dpigenerator/rtw/ScoreboardComponentML.svt'}
    TestBenchTemplateFiles: {'/mathworks/devel/bat/filer/batfs1904-0/Bdoc24a.2528353/build/matlab/toolbox/hdlverifier/dpigenerator/rtw/ScoreboardTestBenchML.svt'}
        TemplateDictionary: []

Open the scoreboard template file.

edit(svcfg.ComponentTemplateFiles{:});

The dictionary defines the template variables. The default value of template variable InputTransTypeName is scoreboard_input_trans. You can use svdpiConfiguration object to override the value of this template variable.

override the value of a template variable

To override the value of InputTransTypeName to sineWaveTrans, enter this command:

svcfg.TemplateDictionary = {'InputTransTypeName','sineWaveTrans'};

This scoreboard template has three port groups: PREDICTOR_INPUTS, MONITOR_INPUTS, and CONFIG_OBJECT_INPUTS. Before generating the code use the svdpiConfiguration to specify which port belongs to which port group. For this example, the sineWaveCheck.m file has 5 inputs: in1FromMon, in2FromMon, inFromPred, amp1, and amp2. The in1FromMon, and in2FromMon inputs belong to the MONITOR_INPUTS group. The inFromPred input belongs to the PREDICTOR_INPUTS group. The amp1, and amp2 inputs belong to the CONFIG_OBJECT_INPUTS group. Assign each input to its respective port group.

addPortGroup(svcfg,'MONITOR_INPUTS',{'in1FromMon','in2FromMon'});
addPortGroup(svcfg,'PREDICTOR_INPUTS',{'inFromPred'});
addPortGroup(svcfg,'CONFIG_OBJECT_INPUTS',{'amp1','amp2'});

Generate a UVM scoreboard component.

dpigen sineWaveCheck -testbench sineWaveCheck_tb -args {zeros(1,100),zeros(1,100),zeros(1,100),0,0} -config svcfg
### Generating DPI-C Wrapper /tmp/Bdoc24a_2528353_571106/tpf5a098f3/hdlverifier-ex18925523/codegen/dll/sineWaveCheck/sineWaveCheck_dpi.c
### Generating DPI-C Wrapper header file /tmp/Bdoc24a_2528353_571106/tpf5a098f3/hdlverifier-ex18925523/codegen/dll/sineWaveCheck/sineWaveCheck_dpi.h
### Generating source code file /tmp/Bdoc24a_2528353_571106/tpf5a098f3/hdlverifier-ex18925523/codegen/dll/sineWaveCheck/sineWaveCheck_pkg.sv from template text.
### Generating source code file /tmp/Bdoc24a_2528353_571106/tpf5a098f3/hdlverifier-ex18925523/codegen/dll/sineWaveCheck/sineWaveTrans.sv from template text.
### Generating source code file /tmp/Bdoc24a_2528353_571106/tpf5a098f3/hdlverifier-ex18925523/codegen/dll/sineWaveCheck/scoreboard_output_trans.sv from template text.
### Generating source code file /tmp/Bdoc24a_2528353_571106/tpf5a098f3/hdlverifier-ex18925523/codegen/dll/sineWaveCheck/scoreboard_cfgobj.sv from template text.
### Generating source code file /tmp/Bdoc24a_2528353_571106/tpf5a098f3/hdlverifier-ex18925523/codegen/dll/sineWaveCheck/sineWaveCheck.sv from template text.
### Generating makefiles for: sineWaveCheck_dpi
### Running simulation to capture input and expected outputs for a standalone test bench.
### This may take some time...
Code generation successful.

### ...DONE with vector capture.
### Generating source code file /tmp/Bdoc24a_2528353_571106/tpf5a098f3/hdlverifier-ex18925523/codegen/dll/sineWaveCheck/dpi_tb/sineWaveCheck_tb.sv from template text.
### Generating source code file /tmp/Bdoc24a_2528353_571106/tpf5a098f3/hdlverifier-ex18925523/codegen/dll/sineWaveCheck/dpi_tb/sineWaveCheck_tb_pkg.sv from template text.
### Generating source code file /tmp/Bdoc24a_2528353_571106/tpf5a098f3/hdlverifier-ex18925523/codegen/dll/sineWaveCheck/dpi_tb/run_tb_mq.do from template text.
### Generating source code file /tmp/Bdoc24a_2528353_571106/tpf5a098f3/hdlverifier-ex18925523/codegen/dll/sineWaveCheck/dpi_tb/run_tb_xcelium.sh from template text.
### Generating source code file /tmp/Bdoc24a_2528353_571106/tpf5a098f3/hdlverifier-ex18925523/codegen/dll/sineWaveCheck/dpi_tb/run_tb_vcs.sh from template text.
### Generating source code file /tmp/Bdoc24a_2528353_571106/tpf5a098f3/hdlverifier-ex18925523/codegen/dll/sineWaveCheck/dpi_tb/run_tb_vivado.sh from template text.
### Generating source code file /tmp/Bdoc24a_2528353_571106/tpf5a098f3/hdlverifier-ex18925523/codegen/dll/sineWaveCheck/dpi_tb/run_tb_vivado.bat from template text.
### Compiling the DPI Component
Code generation successful.

Open the generated scoreboard component file.

edit(fullfile('codegen','dll','sineWaveCheck','sineWaveCheck.sv'))

HDL Verifier assigns the value of InputTransTypeName as sineWaveTrans in the generated sineWaveCheck.sv, and so all the related items use sineWaveTrans.

HDL Verifier defines port groups in %<BEGIN_FOREACH_PORT PortGroup> ... %<END_FOREACH_PORT> code block. This code block iterates on all the ports in PortGroup to emit code. In this example, the code block iterates all the ports in the monitor port group and uses its port name to create SystemVerilog code.

Make sure that ModelSim® is on the system path, and then enter this directive to navigate to the test bench directory.

cd(fullfile('codegen','dll','sineWaveCheck','dpi_tb'))

Run the test bench and verify the generated scoreboard component in ModelSim.

!vsim < run_tb_mq.do

Note that the test passed in HDL simulation.

# UVM_INFO @ 0: reporter [RNTST] Running test sineWaveCheck_tb_test...

# UVM_INFO ./sineWaveCheck_tb.sv(98) @ 40: uvm_test_top [WRITING_INPUTS] writing scoreboard inputs

# UVM_INFO ./sineWaveCheck_tb.sv(104) @ 41: uvm_test_top [GETTING_RESULT] getting scoreboard result

# **************TEST COMPLETED (PASSED)**************

# ** Note: $finish : ./sineWaveCheck_tb.sv(223)

# Time: 42 ns Iteration: 0 Instance: /sineWaveCheck_tb

# End time: 16:48:55 on Jan 18,2023, Elapsed time: 0:00:02

# Errors: 0, Warnings: 0

Summary

This example shows how to generate SystemVerilog DPI and UVM components from MATLAB functions using built-in templates. From this example, you learn how to:

  • define template variables by using the dictionary

  • override the default value of a template variable by using the svdpiConfiguration object

  • represent a collection of ports as a group in the template

You can use these methods to create your own template or copy and modify the built-in template to suit your needs. For more information about the template language syntax see Template Engine Language Syntax.

See Also

Related Topics