Verify Generated Code for a Component

This example shows how to verify generated code for a model component. You use 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) or processor-in-the-loop (PIL) mode using the Code Generation Verification (CGV) API and then compare the results.

The component you verify is a Model block named control, which is part of the power_window_control_system subsystem in the slvnvdemo_powerwindow model.

The Model block references the slvnvdemo_powerwindow_controller model.

The referenced model implements controller logic with a Stateflow® chart.

Prepare the Component for Verification

Begin by creating a harness model containing input signals that simulate the controller in the plant model:

1. Open the slvnvdemo_powerwindow example model, and load the referenced model.


2. Simulate the Model block and log the input signals to the Model block:

   modelController = 'slvnvdemo_powerwindow/power_window_control_system/control';
   evalc('loggedSignalsPlant = slvnvlogsignals(modelController)');

slvnvlogsignals stores the logged signals in the loggedSignalsPlant variable.

3. Generate a harness model for adding test cases.

   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.

4. Get the name of the harness model:

   [~,harnessModel] = fileparts(harnessModelFilePath);

5. Leave all models open for the next steps.

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 100% coverage.

Add a test case to the Signal Builder block in the harness model using the signalbuilder function. The test case specifies input signals to the component.

1. Load the file containing the test case data into the MATLAB workspace:


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

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

   signalBuilderBlock = slvnvdemo_signalbuilder_block(harnessModel);
       newTestTime, newTestData,...
       '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 simultaneously, merge the two data files into a single file:

1. Combine the test case data:

   mergedTestCases = slvnvmergedata(loggedSignalsPlant, loggedSignalsHarness);

2. View the merged data:


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

Record Coverage for Component

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',...

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%

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

Execute Component in Simulation Mode

To verify that the generated code 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:

   slmodel = 'slvnvdemo_powerwindow_controller';
   evalc('cgvSim=slvnvruncgvtest(slmodel, 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 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:

   evalc('cgvSil = slvnvruncgvtest(slmodel, mergedTestCases, runcgvopts)');

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

3. Display a comparison of the results in cgvSil to the results in cgvSim (the results from the simulation mode execution). Use the 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, ~ ] = ...
 , silout);
   fprintf('\nTest Case(%d): %d Signals match, %d Signals mismatch', ...
           i, length(matchNames), length(mismatchNames));

For more information about software-in-the-loop (SIL) simulations, see What Are SIL and PIL Simulations?