Main Content

Include Driver and Monitor in UVM Test Bench

This example uses the uvmbuild function to generate a Universal Verification Methodology (UVM) test bench, which includes a UVM driver and monitor from a Simulink® design and test bench.

Introduction

Transitioning from frame-based behavioral modeling to scalar modeling in Simulink requires conversion blocks to transform signal sample times and sizes. The conversion blocks divide the Simulink test bench in these two domains.

  • Frame-based domain: The part of the test bench that manipulates and operates on data as frames.

  • Scalar-based domain: The part of the test bench that manipulates and operates on data as scalars.

The UVM framework uses transaction level modeling to process transactions from the sequence (stimulus generator) and to verify the resulting transactions in the scoreboard (checker).

When translating a Simulink test bench to a UVM test bench, keeping these domains separate is important. The domain separation enables better componentization and reusability of the test bench components.

Design and Test in Simulink

Write the scalar-based algorithm and add a test bench around it that separates the frame-based domain and the scalar domain using conversion subsystems (for example, buffer and unbuffer, rate transition, or a combination of these blocks). The model consists of a stimulus generation subsystem, a scalar-based design under test (DUT), and a response checking subsystem. Additional conversion subsystems are introduced between the stimulus generation and the DUT to convert the data from frames to scalars and between the DUT and the response checker to convert the data from scalars to frames.

The example uses Simulink to design and test a pipelined divide cordic algorithm and determine a maximum error threshold for a given number of pipeline stages. In this design, seven pipeline stages are tested.

The design contains there two sample times in Simulink.

  • The slow sample time (green) operates in terms of high level transactions agnostic of the lower level algorithm being tested in the DUT. In this example, the transactions consists of three vectors: numerator, denominator, and the results of division from the cordic algorithm.

  • The fast sample time (red) operates in terms of scalars. The pipelined DUT samples two scalars at the red sample time, and the resulting cordic division result comes out after seven red sample time hit when the valid out signal is asserted.

The VectorGenerator subsystem generates different numerator and denominator vector sequences. The size and range of the vectors are defined in the InitFcn callback under Simulink model explorer.

The VectorToScalar subsystem translates the high level transactions (vectors) to a scalar sequence that the DUT is able to understand.

The ScalarToVector subsystem assembles the resulting vector from the scalar sequence it receives from the DUT.

The DivideChecker subsystem verifies that the resulting vector contains the correct result of the division within a certain error threshold. If the error is greater than the threshold, then the simulation outputs a warning. In addition the DivideChecker subsystem outputs three MAT files that you can plot to visualize the results.

The model is shown below:

Open and simulate the model. Because no assertions are fired, no error threshold violations exist.

open_system('drv_and_mon_uvmtb');
r=sim('drv_and_mon_uvmtb');

The simulation writes three MAT files to the disk: num.mat, den.mat, and result_cordic.mat. The files contain the denominators, numerators, and results of the cordic division respectively.

A MATLAB function is provided to generate a 3-D scatter plot from the MAT files. The resulting graph helps visualize the error and further confirms that the error is less than the threshold.

plot_cordic_results('num.mat','den.mat','result_cordic.mat');

Generate UVM Test Bench with Driver and Monitor

Use the uvmbuild function to export your design to a UVM environment and to specify the Simulink subsystems that you want to map to the UVM driver, monitor, or both.

The UVM driver and monitor enable you to separate between frame-based and scalar-based domains. When translated to UVM framework, the frame-based domain is mapped to UVM transactions, and the scalar-based domain is mapped to the time-aware UVM components (driver, dut, and monitor). Standard component definitions separate the pieces of the environment by their role in the simulation. For this example:

  • VectorGenerator subsystem is mapped to the UVM sequence.

  • VectorToScalar subsystem is mapped to the UVM driver.

  • Pipelined_Cordic_Divide subsystem is mapped to the DPI DUT SystemVerilog module.

  • ScalarToVector subsystem is mapped to the UVM monitor.

  • DivideChecker subsystem is mapped to the UVM scoreboard.

To generate a UVM test bench out of the Simulink design, execute this code.

sequence = 'drv_and_mon_uvmtb/VectorGenerator';
driver = 'drv_and_mon_uvmtb/VectorToScalar';
dpi_dut = 'drv_and_mon_uvmtb/Pipelined_Cordic_Divide';
moninor = 'drv_and_mon_uvmtb/ScalarToVector';
scoreboard = 'drv_and_mon_uvmtb/DivideChecker';
uvmbuild(dpi_dut,sequence,scoreboard,'Driver',driver,'Monitor',moninor);
### Starting DPI subsystem generation for UVM test bench
### Starting build procedure for model: Pipelined_Cordic_Divide
### Starting SystemVerilog DPI Component Generation
### Generating DPI H Wrapper /tmp/Bdoc20b_1465442_55673/tpdaf2740a/hdlverifier-ex46125948/Pipelined_Cordic_Divide_build/Pipelined_Cordic_Divide_dpi.h
### Generating DPI C Wrapper /tmp/Bdoc20b_1465442_55673/tpdaf2740a/hdlverifier-ex46125948/Pipelined_Cordic_Divide_build/Pipelined_Cordic_Divide_dpi.c
### Generating UVM module package /tmp/Bdoc20b_1465442_55673/tpdaf2740a/hdlverifier-ex46125948/Pipelined_Cordic_Divide_build/Pipelined_Cordic_Divide_dpi_pkg.sv
### Generating SystemVerilog module /tmp/Bdoc20b_1465442_55673/tpdaf2740a/hdlverifier-ex46125948/Pipelined_Cordic_Divide_build/Pipelined_Cordic_Divide_dpi.sv
### Generating makefiles for: Pipelined_Cordic_Divide_dpi
### Invoking make to build the DPI Shared Library
### Successful completion of build procedure for model: Pipelined_Cordic_Divide

Build Summary

Top model targets built:

Model                    Action                       Rebuild Reason                                    
========================================================================================================
Pipelined_Cordic_Divide  Code generated and compiled  Code generation information file does not exist.  

1 of 1 models built (0 models already up to date)
Build duration: 0h 0m 31.691s
### Starting build procedure for model: VectorGenerator
### Starting SystemVerilog DPI Component Generation
### Generating DPI H Wrapper /tmp/Bdoc20b_1465442_55673/tpdaf2740a/hdlverifier-ex46125948/VectorGenerator_build/VectorGenerator_dpi.h
### Generating DPI C Wrapper /tmp/Bdoc20b_1465442_55673/tpdaf2740a/hdlverifier-ex46125948/VectorGenerator_build/VectorGenerator_dpi.c
### Generating UVM module package /tmp/Bdoc20b_1465442_55673/tpdaf2740a/hdlverifier-ex46125948/VectorGenerator_build/VectorGenerator_dpi_pkg.sv
### Generating SystemVerilog module /tmp/Bdoc20b_1465442_55673/tpdaf2740a/hdlverifier-ex46125948/VectorGenerator_build/VectorGenerator_dpi.sv
### Generating makefiles for: VectorGenerator_dpi
### Invoking make to build the DPI Shared Library
### Successful completion of build procedure for model: VectorGenerator

Build Summary

Top model targets built:

Model            Action                       Rebuild Reason                                    
================================================================================================
VectorGenerator  Code generated and compiled  Code generation information file does not exist.  

1 of 1 models built (0 models already up to date)
Build duration: 0h 0m 13.903s
### Starting build procedure for model: VectorToScalar
### Starting SystemVerilog DPI Component Generation
### Generating DPI H Wrapper /tmp/Bdoc20b_1465442_55673/tpdaf2740a/hdlverifier-ex46125948/VectorToScalar_build/VectorToScalar_dpi.h
### Generating DPI C Wrapper /tmp/Bdoc20b_1465442_55673/tpdaf2740a/hdlverifier-ex46125948/VectorToScalar_build/VectorToScalar_dpi.c
### Generating UVM module package /tmp/Bdoc20b_1465442_55673/tpdaf2740a/hdlverifier-ex46125948/VectorToScalar_build/VectorToScalar_dpi_pkg.sv
### Generating SystemVerilog module /tmp/Bdoc20b_1465442_55673/tpdaf2740a/hdlverifier-ex46125948/VectorToScalar_build/VectorToScalar_dpi.sv
### Generating makefiles for: VectorToScalar_dpi
### Invoking make to build the DPI Shared Library
### Successful completion of build procedure for model: VectorToScalar

Build Summary

Top model targets built:

Model           Action                       Rebuild Reason                                    
===============================================================================================
VectorToScalar  Code generated and compiled  Code generation information file does not exist.  

1 of 1 models built (0 models already up to date)
Build duration: 0h 0m 12.717s
### Starting build procedure for model: ScalarToVector
### Starting SystemVerilog DPI Component Generation
### Generating DPI H Wrapper /tmp/Bdoc20b_1465442_55673/tpdaf2740a/hdlverifier-ex46125948/ScalarToVector_build/ScalarToVector_dpi.h
### Generating DPI C Wrapper /tmp/Bdoc20b_1465442_55673/tpdaf2740a/hdlverifier-ex46125948/ScalarToVector_build/ScalarToVector_dpi.c
### Generating UVM module package /tmp/Bdoc20b_1465442_55673/tpdaf2740a/hdlverifier-ex46125948/ScalarToVector_build/ScalarToVector_dpi_pkg.sv
### Generating SystemVerilog module /tmp/Bdoc20b_1465442_55673/tpdaf2740a/hdlverifier-ex46125948/ScalarToVector_build/ScalarToVector_dpi.sv
### Generating makefiles for: ScalarToVector_dpi
### Invoking make to build the DPI Shared Library
### Successful completion of build procedure for model: ScalarToVector

Build Summary

Top model targets built:

Model           Action                       Rebuild Reason                                    
===============================================================================================
ScalarToVector  Code generated and compiled  Code generation information file does not exist.  

1 of 1 models built (0 models already up to date)
Build duration: 0h 0m 9.9476s
### Starting build procedure for model: DivideChecker
### Starting SystemVerilog DPI Component Generation
### Generating DPI H Wrapper /tmp/Bdoc20b_1465442_55673/tpdaf2740a/hdlverifier-ex46125948/DivideChecker_build/DivideChecker_dpi.h
### Generating DPI C Wrapper /tmp/Bdoc20b_1465442_55673/tpdaf2740a/hdlverifier-ex46125948/DivideChecker_build/DivideChecker_dpi.c
### Generating UVM module package /tmp/Bdoc20b_1465442_55673/tpdaf2740a/hdlverifier-ex46125948/DivideChecker_build/DivideChecker_dpi_pkg.sv
### Generating SystemVerilog module /tmp/Bdoc20b_1465442_55673/tpdaf2740a/hdlverifier-ex46125948/DivideChecker_build/DivideChecker_dpi.sv
### Generating makefiles for: DivideChecker_dpi
### Invoking make to build the DPI Shared Library
### Successful completion of build procedure for model: DivideChecker

Build Summary

Top model targets built:

Model          Action                       Rebuild Reason                                    
==============================================================================================
DivideChecker  Code generated and compiled  Code generation information file does not exist.  

1 of 1 models built (0 models already up to date)
Build duration: 0h 0m 12.731s
### Starting UVM test bench generation for model: drv_and_mon_uvmtb
### Generating UVM transaction object /tmp/Bdoc20b_1465442_55673/tpdaf2740a/hdlverifier-ex46125948/drv_and_mon_uvmtb_uvmbuild/uvm_testbench/uvm_artifacts/mw_Pipelined_Cordic_Divide_trans.sv
### Generating UVM interface /tmp/Bdoc20b_1465442_55673/tpdaf2740a/hdlverifier-ex46125948/drv_and_mon_uvmtb_uvmbuild/uvm_testbench/uvm_artifacts/mw_Pipelined_Cordic_Divide_if.sv
### Generating UVM sequence /tmp/Bdoc20b_1465442_55673/tpdaf2740a/hdlverifier-ex46125948/drv_and_mon_uvmtb_uvmbuild/uvm_testbench/sequence/mw_Pipelined_Cordic_Divide_sequence.sv
### Generating UVM sequence transaction /tmp/Bdoc20b_1465442_55673/tpdaf2740a/hdlverifier-ex46125948/drv_and_mon_uvmtb_uvmbuild/uvm_testbench/sequence/mw_Pipelined_Cordic_Divide_sequence_trans.sv
### Generating UVM driver /tmp/Bdoc20b_1465442_55673/tpdaf2740a/hdlverifier-ex46125948/drv_and_mon_uvmtb_uvmbuild/uvm_testbench/driver/mw_Pipelined_Cordic_Divide_driver.sv
### Generating UVM monitor /tmp/Bdoc20b_1465442_55673/tpdaf2740a/hdlverifier-ex46125948/drv_and_mon_uvmtb_uvmbuild/uvm_testbench/monitor/mw_Pipelined_Cordic_Divide_monitor.sv
### Generating UVM input monitor /tmp/Bdoc20b_1465442_55673/tpdaf2740a/hdlverifier-ex46125948/drv_and_mon_uvmtb_uvmbuild/uvm_testbench/uvm_artifacts/mw_Pipelined_Cordic_Divide_monitor_input.sv
### Generating UVM agent /tmp/Bdoc20b_1465442_55673/tpdaf2740a/hdlverifier-ex46125948/drv_and_mon_uvmtb_uvmbuild/uvm_testbench/uvm_artifacts/mw_Pipelined_Cordic_Divide_agent.sv
### Generating UVM scoreboard /tmp/Bdoc20b_1465442_55673/tpdaf2740a/hdlverifier-ex46125948/drv_and_mon_uvmtb_uvmbuild/uvm_testbench/scoreboard/mw_Pipelined_Cordic_Divide_scoreboard.sv
### Generating UVM scoreboard configuration object /tmp/Bdoc20b_1465442_55673/tpdaf2740a/hdlverifier-ex46125948/drv_and_mon_uvmtb_uvmbuild/uvm_testbench/scoreboard/mw_Pipelined_Cordic_Divide_scoreboard_cfg_obj.sv
### Generating UVM environment /tmp/Bdoc20b_1465442_55673/tpdaf2740a/hdlverifier-ex46125948/drv_and_mon_uvmtb_uvmbuild/uvm_testbench/uvm_artifacts/mw_Pipelined_Cordic_Divide_environment.sv
### Generating UVM test /tmp/Bdoc20b_1465442_55673/tpdaf2740a/hdlverifier-ex46125948/drv_and_mon_uvmtb_uvmbuild/uvm_testbench/uvm_artifacts/mw_Pipelined_Cordic_Divide_test.sv
### Generating UVM top /tmp/Bdoc20b_1465442_55673/tpdaf2740a/hdlverifier-ex46125948/drv_and_mon_uvmtb_uvmbuild/uvm_testbench/top/mw_Pipelined_Cordic_Divide_top.sv
### Generating UVM test package /tmp/Bdoc20b_1465442_55673/tpdaf2740a/hdlverifier-ex46125948/drv_and_mon_uvmtb_uvmbuild/uvm_testbench/top/drv_and_mon_uvmtb_pkg.sv
### Generating UVM test bench simulation script for Mentor Graphics QuestaSim/Modelsim /tmp/Bdoc20b_1465442_55673/tpdaf2740a/hdlverifier-ex46125948/drv_and_mon_uvmtb_uvmbuild/uvm_testbench/top/run_tb_mq.do
### Generating UVM test bench simulation script for Cadence Incisive /tmp/Bdoc20b_1465442_55673/tpdaf2740a/hdlverifier-ex46125948/drv_and_mon_uvmtb_uvmbuild/uvm_testbench/top/run_tb_incisive.sh
### Generating UVM test bench simulation script for Cadence Xcelium /tmp/Bdoc20b_1465442_55673/tpdaf2740a/hdlverifier-ex46125948/drv_and_mon_uvmtb_uvmbuild/uvm_testbench/top/run_tb_xcelium.sh
### Generating UVM test bench simulation script for Synopsys VCS /tmp/Bdoc20b_1465442_55673/tpdaf2740a/hdlverifier-ex46125948/drv_and_mon_uvmtb_uvmbuild/uvm_testbench/top/run_tb_vcs.sh

The UVM driver and monitor are generated in separate directories as shown in this figure.

Run UVM Test Bench

The generated UVM test bench can be executed by going to UVM test bench top module directory drv_and_mon_uvmtb_uvmbuild\uvm_testbench\top and executing one of the generated HDL simulator scripts. For this example, ModelSim/QuestaSim® is used. The commands to execute are shown in this figure.

To confirm that the UVM simulation matches the Simulink test bench, check this requirements.

  • No error threshold violations are thrown. This is verified by looking at the UVM simulation log and checking that no UVM errors exist. The UVM Simulation log is shown in this figure.

  • The UVM scoreboard outputs three MAT files (num.mat, den.mat, and result_cordic.mat) at the end of the UVM simulation. Visually, the 3-D scatted plot generated from the Simulink design must match the plot from the UVM simulation. The plot from the UVM simulation MAT files can be generated using this command:

The resulting UVM simulation 3-D scatter plot is shown in this figure. The plot matches the Simulink design plot shown in previous sections.

Conclusion

Keeping the frame-based and scalar-based behavioral modeling separate in Simulink and UVM framework results in these benefits.

  • The domain separation enables the modeling of frame-based transaction processing at a higher abstractions level without having to introduce lower level conversions the are dependent on the algorithm being developed.

  • The VectorGenerator and DivideChecker subsystems can be reused for different Simulink or UVM projects that have a different algorithm but require the same high level transaction generation and checking.

  • The domain separation enables the DUT algorithm to be multirate.

  • The domain separation enables the high level transaction to operate in a different data type than the DUT. In this example, the DUT has port data types of ufx10_en5, but the VectorGenerator and DivideChecker subsystems are of double data type.

  • If you have Simulink Test® you can optionally map the conversion blocks in the Simulink Test Harness to the UVM driver and monitor. The domain separation enables a more streamlined UVM test bench generation workflow.

The uvmbuild function enables you to separate the frame-based and scalar domains by providing additional optional name-value pairs to specify Simulink subsystems that are mapped to a UVM driver,monitor, or both.