%% Generating Functional Coverage in SystemVerilog from System Test |verify| Calls
% This example demonstrates how to test a projector control system using
% model simulation, and how to generate a SystemVerilog DPI component for
% some of the controller's high level requirements that are specified in a
% Test Sequence block. This will allow the requirement verification used
% for model simulation to be reused in the HDL simulator with minimal
% effort.
%
% The model was taken from the example 
% <docid:sltest_ug#example-sltestProjectorCtrlRealTimeExample (docid for: Projector Controller Testing Using verify and Real-Time Tests)> shipped
% with Simulink Test(TM), and simplified to show only requirement scenario 4.
%
% To learn more about verify statements, see
% <docid:sltest_ug#mw_ec6fffe9-a36b-425b-8a95-686774dcb42c Assess Model Simulation Using verify Statements>.
% 

%% Other Prerequisites
% In addition to the stated product requirements, this example requires:
%
% * A supported HDL simulator.  See <docid:hdlv_gs#bvgi6s_ (docid for: UVM and DPI Component Generation Requirements)>.
% * A supported C compiler. See <docid:rtw_ug#br5rle_ (docid for: Select and Configure C or C++ Compiler)>.
%

%% Overview
% The test verifies the controller against its requirements using test
% sequences that exercise the top-level controller model. The controller
% uses a push button input and a temperature sensor input, and outputs
% signals controlling the fan, fan speed, and projector lamp.
% 
% The objective is to generate a SystemVerilog DPI component that captures
% high level requirement number 4 of the controller. For more information
% about the requirements refer to the word document
% |sltestProjectorCtrlReqs.docx| in the example referred above.
%
% Requirement 4 tries to turn on and off the projector when the projector
% temperature (Tproj) is high. The scenario has the following steps in the
% Test Sequence block:
%
% # Set projector temperature to 50 degree Celsius.
% # Try to turn on.
% # The system should not turn on.
% # Set the temperature to 50 degree Celsius.
% # Try to turn off.
% # The system should turn off.
%
% The picture below shows the test bench for the above requirement and how
% |verify| is used to check that the projector turns on or off depending on
% the scenario.
%
% <<../svdpi_tsverify_tsreq4.png>>
%

%% Set Up Model for Code Generation
%
% The model and test bench are preconfigured with one of the SystemVerilog
% DPI system target files (systemverilog_dpi_grt.tlc). Open the test
% harness |Req_scenario_4| by executing:
%
%% 
%   testFile = 'svdpi_sltestProjectorCtrlTests.mldatx';
%   testHarness = 'Req_scenario_4';
%   model = 'svdpi_sltestProjectorController';
%   open_system(model)
%
%%
%   sltest.harness.open(model,testHarness)
%

%% Generate SystemVerilog DPI Component
%
% # In the *Req_scenario_4* test bench, right click the *Req_4* subsystem block  
% which contains the test sequence block and select.
% *C/C++ Code -> Build This Subsystem*.
% # Click *Build* in the dialog box that appears.
% # The build generates C code for the *Req_4* subsystem, and a SystemVerilog
% DPI wrapper and package file named
% "Req_4_build/Req_4_dpi.sv" and 
% "Req_4_build/Req_4_dpi_pkg.sv".
%
% Note that some verification warnings will be triggered, this will be
% explained later.
%
% Alternatively you can generate the component by executing:
%
%%
%   rtwbuild('Req_scenario_4/Req_4');
%

%% Run Generated Testbench in HDL Simulator
%
% For this example ModelsSim/QuestaSim simulator will be used. For 
% detailed instructions on how to run the testbench refer to
% <docid:hdlv_ug#example-svdpi_pid (docid for: Getting Started with SystemVerilog DPI Component Generation)>.
% 
%%
%   cd Req_4_build/dpi_tb
%   ! vsim -c -do run_tb_mq.do  # Run ModelSim/QuestaSim in console mode
%   cd ../..
%
% Examine the HDL simulation output and notice the following:
% 
% * An info message shows that functional coverage will be gathered for 2 verify calls in the component
% * There is an error flagged regarding a failure of the controller to shut
% off when the temperature is above a limit.
% * The test is marked as PASSED because the SystemVerilog simulation
% results match the Simulink simulation results.
% * The functional coverage shows that coverage is achieved for the first
% verify call but is not achieved for the second.
% * The overall functional coverage goal is not met.
%
% <<../svdpi_tsverify_error_in_mq.png>>
%
% The error is consistent with the simulation results in Simulink (below). 
% Opening the Test Manager reveals that the controller fails to shut off
% when the on_off button is pressed when the temperature is above a limit.
% To open test manager you can execute:
%
%%
%   sltest.testmanager.load(testFile);
%   sltest.testmanager.view;
%
% Resolving the failure would require to modify the OnOff check subsystem
% in the main model.  The other requirement, |verify_sc4_on|, is satisfied, 
% as shown in both the Simulink Test and SystemVerilog coverage results.
%
% <<../svdpi_tsverify_testmngr_and_warn.png>>
%

%% Tracing a SystemVerilog Error Back to Simulink
%
% If you want to trace the verify statement that generated the error back
% to Simulink you need to find the Simulink Identifier (SID) from the 
% error message as shown below:
%
% <<../svdpi_tsverify_sid.png>>
%
% Once you find the SID for the step id in the test sequence block you can
% use Simulink programmatic APIs to highlight the corresponding block. For more information, see
% <docid:simulink_ug#bso67kd Simulink Identifiers>.
% Execute the following command:
%
%%
%   Simulink.ID.hilite('Req_scenario_4:32:60');
%
% This will highlight the relevant block as shown below.
%
% <<../svdpi_tsverify_hilite.png>>
%

%% Filter a Specific Verify Assessment
%
% To filter any verify assessment status checks in the HDL simulator,
% supply the SID of the assessment you want to filter as a plusargs
% argument to the HDL simulator. Such a filter will means no errors and no
% coverage will be checked for that assessment. For instance you can filter
% the error that |verify_sc4_off| gives by supplying the argument
% "+Req_scenario_4:32:60" to the HDL simulator. You can do this through an
% environment variable so you don't have to modify the generated script.
%
%%
%   % Clear environment variables that influence the SV simulation
%   setenv EXTRA_SVDPI_COMP_ARGS
%   setenv EXTRA_SVDPI_SIM_ARGS 
%
%   % Filter the failing verify()
%   setenv EXTRA_SVDPI_SIM_ARGS +Req_scenario_4:32:60=-1
%   cd Req_4_build/dpi_tb
%   ! vsim -c -do run_tb_mq.do  # Run ModelSim/QuestaSim in console mode
%   cd ../..
%
% Notice that the HDL simulation now shows:
%
% * A warning that one of the verify assessments is being filtered
% * An info message that coverage will be gathered for the other assessment
% * There are no longer any errors.
% * The test is marked as PASSED because the SystemVerilog simulation
% results match the Simulink simulation results.
% * The functional coverage shows that coverage is achieved for the enabled
% assessment
% * The overall functional coverage goal is met.
%
% <<../svdpi_tsverify_filtered_in_mq.png>>
%

%% Increase the Coverage Goal of a Specific Verify Assessment
%
% You can also change the desired functional coverage goal for any
% assessment by supplying a positive value to the plus arg.  The default
% goal is to see at least 1 PASS status for the verify call.  If you wanted
% to ensure that there were at least 2 verify PASS status checks you would
% supply a "2" as the plus arg value.
%
%%
%   % Clear environment variables that influence the SV simulation
%   setenv EXTRA_SVDPI_COMP_ARGS
%   setenv EXTRA_SVDPI_SIM_ARGS 
%
%   % Filter the failing |verify| and set a coverage goal of 2 for the other |verify|
%   setenv EXTRA_SVDPI_SIM_ARGS '+Req_scenario_4:32:60=-1 +Req_scenario_4:32:39=2'
%   cd Req_4_build/dpi_tb
%   ! vsim -c -do run_tb_mq.do  # Run ModelSim/QuestaSim in console mode
%   cd ../..
%
% Notice that the HDL simulation now shows that the non-filtered |verify|
% is not meeting the coverage goal of at least 2 PASSes and therefore the
% test as a whole is not either.
% 
% <<../svdpi_tsverify_atleast2_in_mq.png>>
%

%% Log Pass, Fail, and Untested Status for All Verify Assessments
%
% You can add log output for all status checks for all unfiltered |verify|
% calls by adding the +VERBOSE_VERIFY plus arg.  This might be useful if
% you need to check on the timing and distribution of the UNTESTED, PASS,
% and FAIL verify status values.
%
%%
%   % Clear environment variables that influence the SV simulation
%   setenv EXTRA_SVDPI_COMP_ARGS
%   setenv EXTRA_SVDPI_SIM_ARGS 
%
%   % Log every status check.
%   setenv EXTRA_SVDPI_SIM_ARGS +VERBOSE_VERIFY
%   cd Req_4_build/dpi_tb
%   ! vsim -c -do run_tb_mq.do  # Run ModelSim/QuestaSim in console mode
%   cd ../..
%
% Notice that the HDL simulation now shows each UNTESTED and PASS status
% check value as a SystemVerilog |info| message and each FAIL status a
% SystemVerilog error.
% 
% <<../svdpi_tsverify_verbose.png>>
%

%% Conclusion
%
% SystemVerilog DPI component generation and the Test Sequence block from
% Simulink Test(TM) can be used to migrate verification logic from Simulink
% to a HDL simulator with minimal effort.
%
% Copyright 2019-2020 The MathWorks, Inc.