Verify Generated Code for a Component

About the Example Model

This example uses the slvnvdemo_powerwindow example model to show how to verify a component in the context of the model that contains that component. As you work through this example, you use the Simulink® Verification and Validation™ component verification functions to create test cases and measure coverage for a referenced model. In addition, you execute the referenced model in both simulation mode and Software-in-the-Loop (SIL) mode using the Code Generation Verification (CGV) API and then compare the results.

    Note:   You must have the following product licenses to run this example:

    • Stateflow®

    • Embedded Coder®

    • Simulink Coder™

The component you verify is a Model block named control. This component resides inside the power_window_control_system subsystem in the top level of the slvnvdemo_powerwindow model.

The Model block references the slvnvdemo_powerwindow_controller model.

The referenced model contains a Stateflow chart control, which implements the logic for the power window controller.

Prepare the Component for Verification

To verify the referenced model slvnvdemo_powerwindow_controller, you need to create a harness model that contains the input signals that simulate the controller in the plant model. Perform the following steps:

  1. Open the slvnvdemo_powerwindow example model:

    slvnvdemo_powerwindowslvnvdemo_powerwindow
  2. Open the power_window_control_system subsystem.

  3. The Model block named control in the power_window_control_system subsystem references the component you verify during this example—slvnvdemo_powerwindow_controller. Load the referenced model:

    load_system('slvnvdemo_powerwindow_controller');load_system('slvnvdemo_powerwindow_controller');
  4. Simulate the Model block that references slvnvdemo_powerwindow_controller and log the input signals to the Model block:

    loggedSignalsPlant = ...
        slvnvlogsignals(...
            'slvnvdemo_powerwindow/power_window_control_system/control');

    slvnvlogsignals stores the logged signals in loggedSignalsPlant.

  5. Generate an empty harness model so that you can create new test cases manually:

    harnessModelFilePath = ...
        slvnvmakeharness('slvnvdemo_powerwindow_controller');
    

    slvnvmakeharness creates a harness model named slvnvdemo_powerwindow_controller_harness. The harness model includes:

    • Test Unit — A Model block that references the slvnvdemo_powerwindow_controller model.

    • Inputs — A Signal Builder block that contains one test case. That test case specifies the values of the input signals logged when the model slvnvdemo_powerwindow was simulated.

    • Test Case Explanation — A DocBlock block that describes the test case.

    • Size-Type — A Subsystem block that transmits signals from the Inputs block to the Test Unit block. The output signals from this block match the input signals for the Model block you are verifying.

    • moveUp and moveDown — Two output ports that match the output ports from the Model block.

  6. Save the name of the harness model for use later in this example:

    [~,harnessModel] = fileparts(harnessModelFilePath);
  7. Leave all models open for the next part of this example.

Next, create a test case that tests values for input signals to the component.

Create and Log Test Cases

Add a test case for your component to help you get closer to achieving 100% coverage.

For this example, use the signalbuilder function to add a new test case to the Signal Builder block in the harness model. The new test case specifies new values for the input signals to the component:

  1. Load the file that contains the data for the new test case into the MATLAB® workspace:

    load('slvnvdemo_powerwindow_controller_newtestcase.mat');

    The workspace variables newTestData and newTestTime contain the test-case data.

  2. Add the new test case to the Signal Builder block in the harness model.

    signalBuilderBlock = slvnvdemo_signalbuilder_block(harnessModel);
    signalbuilder(signalBuilderBlock,'Append',...
        newTestTime, newTestData,...
        {'endstop','obstacle','driver(1)','driver(2)','driver(3)',...
        'passenger(1)','passenger(2)','passenger(3)'},'New Test Case');
  3. Simulate the harness model with both test cases, then log the signals to the referenced model, and save the results:

    loggedSignalsHarness = slvnvlogsignals(harnessModel);
    

Next, record coverage for the slvnv_powerwindow_controller model.

Merge Test Case Data

You have two sets of test case data:

  • loggedSignalsPlant — Logged signals to the Model block control

  • loggedSignalsHarness — Logged signals to the test cases you added to the empty harness

To simulate all the test data at the same time, merge the two data files into a single data file:

  1. Combine the test case data:

    mergedTestCases = slvnvmergedata(loggedSignalsPlant,...
         loggedSignalsHarness);
  2. View the merged data:

    disp(mergedTestCases);

Next, simulate the referenced model with the merged data and recover coverage for the referenced model, slvnv_powerwindow_controller.

Record Coverage for Component

Model coverage is a measure of how thoroughly a test case tests a model and the percentage of pathways that a test case exercises. To record coverage for the slvnv_powerwindow_controller model:

  1. Create a default options object, required by the slvnvruntest function:

    runopts = slvnvruntestopts;
  2. Specify to simulate the model, and record coverage:

    runopts.coverageEnabled = true;
  3. Simulate the model using the logged input signals:

    [~, covdata] = slvnvruntest('slvnvdemo_powerwindow_controller',...
        mergedTestCases,runopts);
  4. Display the HTML coverage report:

    cvhtml('Coverage with Test Cases from Harness', covdata);

    The slvnv_powerwindow_controller model achieved:

    • Decision coverage: 44%

    • Condition coverage: 45%

    • MCDC coverage: 10%

      Note:   For more information about decision coverage, condition coverage, and MCDC coverage, see Types of Model Coverage.

If you do not achieve the desired coverage, continue to modify the test cases in the Signal Builder in the harness model, log the input signals to the harness model, and repeat the preceding steps until you achieve the desired coverage.

To achieve additional coverage to bring your model closer to 100% coverage, modify or add test cases using the Signal Builder block in the harness model, as described in Create and Log Test Cases.

Execute Component in Simulation Mode

To verify that the generated code for the model produces the same results as simulating the model, use the Code Generation Verification (CGV) API methods. When you perform this procedure, the simulation compiles and executes the model code using the merged test cases:

  1. Create a default options object for slvnvruncgvtest:

    runcgvopts = slvnvruntestopts('cgv');
  2. Specify to execute the model in simulation mode:

    runcgvopts.cgvConn = 'sim';
  3. Execute the slvnv_powerwindow_controller model using the two test cases and the runopts object:

    cgvSim = slvnvruncgvtest('slvnvdemo_powerwindow_controller', ...
        mergedTestCases, runcgvopts);

These steps save the results in the workspace variable cgvSim.

Next, execute the same model with the same test cases in Software-in-the-Loop (SIL) mode and compare the results from both simulations.

For more information about Normal simulation mode, see Execute the Model.

Execute Component in Software-in-the-Loop (SIL) Mode

When you execute a model in Software-in-the-Loop (SIL) mode, the simulation compiles and executes the generated code on your host computer.

To execute a model in SIL mode, you must have an Embedded Coder license.

In this section, you execute the slvnvdemo_powerwindow_controller model in SIL mode and compare the results to the previous section, where you executed the model in simulation mode:

  1. Specify to execute the model in SIL mode:

    runcgvopts.cgvConn = 'sil';
  2. Execute the slvnv_powerwindow_controller model using the merged test cases and the runopts object:

    cgvSil = slvnvruncgvtest('slvnvdemo_powerwindow_controller', ...
        mergedTestCases, runcgvopts);

    The workspace variable cgvSil contains the results of the SIL mode execution.

  3. Compare the results in cgvSil to the results in to cgvSim (the results from the simulation mode execution). Use the cgv.CGV.compare method to compare the results from the two simulations:

    for i=1:length(loggedSignalsHarness.TestCases)
        simout = cgvSim.getOutputData(i);
        silout = cgvSil.getOutputData(i);
        [matchNames, ~, mismatchNames, ~ ] = ...
            cgv.CGV.compare(simout, silout);
  4. Display the results of the comparison in the MATLAB command window:

    fprintf('\nTest Case(%d):  %d Signals match, ...
            %d Signals mismatch', i, length(matchNames), ...
            length(mismatchNames));
    end
    

For more information about Software-in-the-Loop (SIL) simulations, see What are SIL and PIL Simulations?

Was this topic helpful?