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.
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] PreserveStructures: 0 ScalarizePorts: 0 ComponentTypeName: '' TestBenchTypeName: '' MATLABFunctionName: '' PortGroups: [] ComponentTemplateFiles: {'/mathworks/devel/bat/filer/batfs2566-0/Bdoc24b.2725827/build/runnable/matlab/toolbox/hdlverifier/dpigenerator/rtw/SequentialModuleML.svt'} TestBenchTemplateFiles: {'/mathworks/devel/bat/filer/batfs2566-0/Bdoc24b.2725827/build/runnable/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/Bdoc24b_2725827_2344545/tpaad494f6/hdlverifier-ex18925523/codegen/dll/sineWaveGen/sineWaveGen_dpi.c ### Generating DPI-C Wrapper header file /tmp/Bdoc24b_2725827_2344545/tpaad494f6/hdlverifier-ex18925523/codegen/dll/sineWaveGen/sineWaveGen_dpi.h ### Generating source code file /tmp/Bdoc24b_2725827_2344545/tpaad494f6/hdlverifier-ex18925523/codegen/dll/sineWaveGen/sineWaveGen_pkg.sv from template text. ### Generating source code file /tmp/Bdoc24b_2725827_2344545/tpaad494f6/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/Bdoc24b_2725827_2344545/tpaad494f6/hdlverifier-ex18925523/codegen/dll/sineWaveGen/dpi_tb/sineWaveGen_tb.sv from template text. ### Generating source code file /tmp/Bdoc24b_2725827_2344545/tpaad494f6/hdlverifier-ex18925523/codegen/dll/sineWaveGen/dpi_tb/run_tb_mq.do from template text. ### Generating source code file /tmp/Bdoc24b_2725827_2344545/tpaad494f6/hdlverifier-ex18925523/codegen/dll/sineWaveGen/dpi_tb/run_tb_xcelium.sh from template text. ### Generating source code file /tmp/Bdoc24b_2725827_2344545/tpaad494f6/hdlverifier-ex18925523/codegen/dll/sineWaveGen/dpi_tb/run_tb_vcs.sh from template text. ### Generating source code file /tmp/Bdoc24b_2725827_2344545/tpaad494f6/hdlverifier-ex18925523/codegen/dll/sineWaveGen/dpi_tb/run_tb_vivado.sh from template text. ### Generating source code file /tmp/Bdoc24b_2725827_2344545/tpaad494f6/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
>.
The SequentialModuleML.svt
template file also includes the contents of the 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.
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.
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] PreserveStructures: 0 ScalarizePorts: 0 ComponentTypeName: '' TestBenchTypeName: '' MATLABFunctionName: '' PortGroups: [] ComponentTemplateFiles: {'/mathworks/devel/bat/filer/batfs2566-0/Bdoc24b.2725827/build/runnable/matlab/toolbox/hdlverifier/dpigenerator/rtw/ScoreboardComponentML.svt'} TestBenchTemplateFiles: {'/mathworks/devel/bat/filer/batfs2566-0/Bdoc24b.2725827/build/runnable/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.
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/Bdoc24b_2725827_2344545/tpaad494f6/hdlverifier-ex18925523/codegen/dll/sineWaveCheck/sineWaveCheck_dpi.c ### Generating DPI-C Wrapper header file /tmp/Bdoc24b_2725827_2344545/tpaad494f6/hdlverifier-ex18925523/codegen/dll/sineWaveCheck/sineWaveCheck_dpi.h ### Generating source code file /tmp/Bdoc24b_2725827_2344545/tpaad494f6/hdlverifier-ex18925523/codegen/dll/sineWaveCheck/sineWaveCheck_pkg.sv from template text. ### Generating source code file /tmp/Bdoc24b_2725827_2344545/tpaad494f6/hdlverifier-ex18925523/codegen/dll/sineWaveCheck/sineWaveTrans.sv from template text. ### Generating source code file /tmp/Bdoc24b_2725827_2344545/tpaad494f6/hdlverifier-ex18925523/codegen/dll/sineWaveCheck/scoreboard_output_trans.sv from template text. ### Generating source code file /tmp/Bdoc24b_2725827_2344545/tpaad494f6/hdlverifier-ex18925523/codegen/dll/sineWaveCheck/scoreboard_cfgobj.sv from template text. ### Generating source code file /tmp/Bdoc24b_2725827_2344545/tpaad494f6/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/Bdoc24b_2725827_2344545/tpaad494f6/hdlverifier-ex18925523/codegen/dll/sineWaveCheck/dpi_tb/sineWaveCheck_tb.sv from template text. ### Generating source code file /tmp/Bdoc24b_2725827_2344545/tpaad494f6/hdlverifier-ex18925523/codegen/dll/sineWaveCheck/dpi_tb/sineWaveCheck_tb_pkg.sv from template text. ### Generating source code file /tmp/Bdoc24b_2725827_2344545/tpaad494f6/hdlverifier-ex18925523/codegen/dll/sineWaveCheck/dpi_tb/run_tb_mq.do from template text. ### Generating source code file /tmp/Bdoc24b_2725827_2344545/tpaad494f6/hdlverifier-ex18925523/codegen/dll/sineWaveCheck/dpi_tb/run_tb_xcelium.sh from template text. ### Generating source code file /tmp/Bdoc24b_2725827_2344545/tpaad494f6/hdlverifier-ex18925523/codegen/dll/sineWaveCheck/dpi_tb/run_tb_vcs.sh from template text. ### Generating source code file /tmp/Bdoc24b_2725827_2344545/tpaad494f6/hdlverifier-ex18925523/codegen/dll/sineWaveCheck/dpi_tb/run_tb_vivado.sh from template text. ### Generating source code file /tmp/Bdoc24b_2725827_2344545/tpaad494f6/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.