This example shows how to programmatically filter objects and outcomes from coverage results.
First, load the model into memory.
modelName = 'slvnvdemo_covfilt'; load_system(modelName);
Configure the coverage settings for the model by using a
simIn = Simulink.SimulationInput(modelName); simIn = simIn.setModelParameter('CovEnable','on'); simIn = simIn.setModelParameter('CovMetricStructuralLevel','MCDC'); simIn = simIn.setModelParameter('StopTime','20'); simIn = simIn.setModelParameter('CovSaveSingleToWorkspaceVar','on'); simIn = simIn.setModelParameter('CovSaveName','covData');
For a list of coverage parameters, see Coverage Settings.
Simulate the model using the
SimulationInput object as the input.
simOut = sim(simIn);
View the coverage results before applying a filter. You can access the decision coverage results using
saturationInitial = decisioninfo(covData,'slvnvdemo_covfilt/Saturation'); percentSaturationCov = 100 * saturationInitial(1)/saturationInitial(2)
percentSaturationCov = 50
The Saturation block has 50% decision coverage. If you do not intend for this block to be satisfied, you can filter a missing objective outcome so that it is no longer reported as missing coverage. First, you need a selector for the unsatisfied objective outcome that you want to filter.
You can directly create a selector using the appropriate constructor. In this case, you would use
Because the objective being justified is a decision outcome, the first input to the metric selector constructor is
slcoverage.MetricSelectorType.DecisionOutcome. The second input is the block handle. The last two are the index of the objective to justify and the index of the outcome of that objective, respectively. Because the
input > lower limit decision objective is the first objective for the Saturation block, its objective index is
1. Because the
false outcome of this objective is the first outcome, its outcome index is also
metricSel = slcoverage.MetricSelector(slcoverage.MetricSelectorType.DecisionOutcome,... 'slvnvdemo_covfilt/Saturation',1,1)
metricSel = MetricSelector with properties: ObjectiveIndex: 1 OutcomeIndex: 1 Description: 'N/A' Type: DecisionOutcome Id: 'slvnvdemo_covfilt:5' ConstructorCode: 'slcoverage.MetricSelector(slcoverage.MetricSelectorType.DecisionOutcome, 'slvnvdemo_covfilt:5', 1, 1)'
You can also use
slcoverage.Selector.allSelectors to see the available selectors for the Saturation block.
saturationAllSels = slcoverage.Selector.allSelectors('slvnvdemo_covfilt/Saturation')
saturationAllSels = 1x6 heterogeneous Selector (BlockSelector, MetricSelector) array with properties: Description Type Id ConstructorCode
You can also see the objective and outcome indices by using the
allSelectors method. Use the
Description name-value pair to search for
falseSelectors = slcoverage.Selector.allSelectors('slvnvdemo_covfilt/Saturation',... 'Description','F')
falseSelectors = 1x2 MetricSelector array with properties: ObjectiveIndex OutcomeIndex Description Type Id ConstructorCode
There are two false case selectors in the Saturation block. The first selector is
F outcome of input > lower limit.
falseSel = falseSelectors(1)
falseSel = MetricSelector with properties: ObjectiveIndex: 1 OutcomeIndex: 1 Description: 'F outcome of input >= lower limit in Saturate block "Saturation"' Type: DecisionOutcome Id: 'slvnvdemo_covfilt:5' ConstructorCode: 'slcoverage.MetricSelector(slcoverage.MetricSelectorType.DecisionOutcome, 'slvnvdemo_covfilt:5', 1, 1)'
falseSel selector is the same one we constructed manually using
slcoverage.MetricSelector. The objective and outcome indices are properties of the resulting selector object.
Create a filter object by using
slcoverage.Filter. You can set the filter file name and filter description by using the methods
filt = slcoverage.Filter; setFilterName(filt,'slcoverage_filter'); setFilterDescription(filt,'Example Filter');
Create a filter rule by using
slcoverage.FilterRule. The first input to
FilterRule is the selector for the block or outcome you want to filter. This can be a selector you create, or one you retrieve from
The second input is the rationale for filtering the outcome or block. This is specified as a character array.
The third input is the filter mode you want to use. The two coverage filter modes are justify and exclude. Use justify mode to filter individual coverage objective outcomes such as
F outcome of input > lower limit. Use exclude mode to filter entire model elements or blocks, which means that the block and its descendants, if applicable, are ignored. In this example, use justify mode to specify that you want to filter a specific outcome.
rule = slcoverage.FilterRule(metricSel,'rate > 0',slcoverage.FilterMode.Justify);
Add the rule to the filter using
Save the filter to a filter file using the
save method. Then apply the filter file to the
cvdata object by assigning the
filter property to the new filter file.
filt.save('covfilter'); covData.filter = 'covfilter';
Re-generate the coverage results for the Saturation block using the filtered
filteredSaturation = decisioninfo(covData,'slvnvdemo_covfilt/Saturation'); percentSaturationFilt = 100 * filteredSaturation(1)/filteredSaturation(2)
percentSaturationFilt = 75
Decision coverage for the Saturation block is now 75%.
You can apply the same workflow to justify a specific Stateflow action. In this example, we want to justify the
tick MCDC objective that is part of the
after(4, tick) transition.
First, get the Stateflow root object by using
chartID = sfroot;
'after(4, tick)' transition ID by using the
find (Stateflow) method. You can use
find to search for transitions by using the
'-isa' flag with
'Stateflow.Transition'. You can further specify the exact transition by using searching for the label string using additional inputs.
transID = chartID.find('-isa','Stateflow.Transition','LabelString','after(4, tick)');
Get the Simulink ID of the chart by using
transSID = Simulink.ID.getSID(transID);
Get the selector for the MCDC objective outcome that we want to filter by using
allSelectors. Pass the Simulink ID of the Stateflow transition as the first input. Because we want to justify a
tick outcome, search for
"tick" in the description.
sfSelectors = slcoverage.Selector.allSelectors(transSID,'Description','"tick"')
sfSelectors = 1x3 MetricSelector array with properties: ObjectiveIndex OutcomeIndex Description Type Id ConstructorCode
allSelectors returns three possible selectors. The transition we want to filter is the third selector returned.
sfSel = sfSelectors(3)
sfSel = MetricSelector with properties: ObjectiveIndex: 1 OutcomeIndex: 1 Description: 'Condition 1, "tick" outcome of Transition trigger expression in Transition "after(4, tick)" from "Clipped" to "Full"' Type: MCDCOutcome Id: 'slvnvdemo_covfilt:6:5' ConstructorCode: 'slcoverage.MetricSelector(slcoverage.MetricSelectorType.MCDCOutcome, 'slvnvdemo_covfilt:6:5', 1, 1)'
Create the rule, add it to the filter, and save it. The filter file is already applied to the
rule2 = slcoverage.FilterRule(sfSel,'tick never false'); filt.addRule(rule2); filt.save('covfilter');
For more information about the stateflow programmatic API, see Overview of the Stateflow API (Stateflow).
You can filter a block using
slcoverage.BlockSelector. In this case, we want to exclude the Switchable config subsystem, so we use the
SubsystemAllContent selector type and the
slcoverage.FilterMode.Exclude filter mode.
subsysSel = slcoverage.BlockSelector(... slcoverage.BlockSelectorType.SubsystemAllContent,... 'slvnvdemo_covfilt/Switchable config');
Create the filter rule by passing the selector, rationale, and the exclude filter mode as inputs.
rule3 = slcoverage.FilterRule(subsysSel,... 'Unused configuration',... slcoverage.FilterMode.Exclude);
Add the rule to the filter and save it.
Finally, you can view the coverage report by using
cvhtml. The Objects Filtered from Coverage Analysis section shows a summary of the filtered model objects and the rationales. The
'sRT=0' flag can be used to generate the coverage report but not open the report automatically.