Main Content

Block Replacements for Unsupported Blocks

This example shows how to use Simulink® Design Verifier™ functions to replace unsupported blocks and how to customize test vector generation for specific requirements.

Model with an Unsupported Block

The example model includes a Switch block whose output is controlled by a Sqrt block. For each switch position, the output of the model is calculated by a 1-D Lookup Table block. For this model, the example concentrates on generating test cases that satisfy the following:

1. Achieve 100% lookup table coverage.

2. Test vectors demonstrate each Switch block position when the values of its first and third input ports differ.

open_system('sldvdemo_sqrt_blockrep');

Checking Model Compatibility

Since the sqrt function is not supported, this model is partially compatible with Simulink Design Verifier.

sldvcompat('sldvdemo_sqrt_blockrep');
13-Feb-2024 00:59:09
Checking compatibility for test generation: model 'sldvdemo_sqrt_blockrep'
Compiling model...done
Building model representation...done

13-Feb-2024 00:59:14

'sldvdemo_sqrt_blockrep' is partially compatible for test generation with Simulink Design Verifier.

The model can be analyzed by Simulink Design Verifier. 
It contains unsupported elements that will be stubbed out during analysis. The results of the analysis might be incomplete. 
See the Diagnostic Viewer for more details on the unsupported elements.

Creating a Custom Block Replacement Rule to Work Around the Incompatibility

This model can be analyzed for test generation by automatically stubbing the unsupported Sqrt block. However, test cases cannot be generated for the Switch block positions because Simulink Design Verifier does not understand the Sqrt block and the output of this block is effecting the Switch block. Since you want test cases for the Switch block, you need to replace the Sqrt block with a supported block that is functionally equivalent. The library block sldvdemo_custom_blockreplib shown below constrains the input signal to the range [0 10000] and approximates the sqrt function by using a 1-D Lookup Table block.

The table data was calculated to match the values of sqrt, with a maximum error of 0.2 in the range [0 10000]. Refer to the mask initialization pane of the block Sqrt_Approx in the library sldvdemo_custom_blockreplib for the values of the lookup table data.

The replacement rule is in defined the MATLAB-file sldvdemo_custom_blkrep_rule_sqrt.m. Since the replacement block sldvdemo_custom_blockreplib for the Sqrt block is only valid for double or single types, this rule ensures that these conditions are satisfied before allowing a block replacement.

   function rule = sldvdemo_custom_blkrep_rule_sqrt
       rule = SldvBlockReplacement.blockreprule;
       rule.fileName = mfilename;
       rule.blockType = 'Sqrt';
       rule.replacementPath = sprintf('sldvdemo_custom_blockreplib/Sqrt_Approx');
       rule.replacementMode = 'Normal';
       parameter.OutMin = '$original.OutMin$';
       parameter.OutMax = '$original.OutMax$';
       parameter.OutDataTypeStr = '$original.OutDataTypeStr$';
       rule.parameterMap = parameter;
       rule.isReplaceableCallBack = @replacementTestFunction;
   end
   function out = replacementTestFunction(blockH)
       out = false;
       acceptedOutDataTypeStr = {'double','single',...
                         'Inherit: Inherit via back propagation',...
                         'Inherit: Same as input'};
       I = strmatch(get_param(blockH,'OutDataTypeStr'),acceptedOutDataTypeStr,'exact');
       if ~isempty(I)
           portDataTypes = get_param(blockH,'CompiledPortDataTypes');
           out = any(strcmp(portDataTypes.Inport,{'double','single'})) &&  ...
                 strcmp(portDataTypes.Inport,portDataTypes.Outport);
       end
   end
open_system('sldvdemo_custom_blockreplib');
open_system('sldvdemo_custom_blockreplib/Sqrt_Approx/1-D Lookup Table');

Configuring Simulink® Design Verifier™ Options for Block Replacement

You will run Simulink Design Verifier in test generation mode with block replacements enabled. In order to generate test cases for positions of Switch block, you must use the custom replacement rule sldvdemo_custom_blkrep_rule_sqrt.m.

Since you are also interested in lookup table coverage, you need the built-in block replacement blkrep_rule_lookup_normal.m, which inserts test objectives for each interval and breakpoint value for a 1-D Lookup Table block. Moreover, you need the built-in rule blkrep_rule_switch_normal.m, which requires that each switch position be exercised when the values of the first and third input ports differ.

The analysis will run for a maximum of 30 seconds and produce a harness model. Report generation is also enabled. Other Simulink Design Verifier options are set to their default values.

opts = sldvoptions;
opts.Mode = 'TestGeneration';
opts.MaxProcessTime = 80;
opts.BlockReplacement = 'on';
opts.BlockReplacementRulesList = ['sldvdemo_custom_blkrep_rule_sqrt.m,' ...
                                  'blkrep_rule_lookup_normal.m,'...
                                  'blkrep_rule_switch_normal.m'];
opts.SaveHarnessModel = 'on';
opts.ModelReferenceHarness = 'on';
opts.SaveReport = 'on';

Executing Test Generation with Block Replacements

The sldvrun function analyzes the model using the settings defined in a sldvoptions object opts. The generated report includes a chapter summarizing block replacements performed on the model. Set the warning off from Coverage Toolbox:

warning('off','Simulink:blocks:WarnTuningWhenCoverage')
[status,fileNames] = sldvrun('sldvdemo_sqrt_blockrep', opts, true);

Executing Tests in the Harness Model

Enable the lookup table coverage metric and then run the test cases using the harness model. You can also execute the suite of tests by clicking the "Run all" button on the Signal Editor dialog box after enabling lookup table coverage from the Configuration Parameters dialog. In the Coverage tab, select Enable coverage analysis and then select Coverage metrics > Other metrics > Lookup table.

The coverage report shown below indicates that you can reach 100% lookup table coverage with the test vectors that Simulink Design Verifier generated.

[harnessModelPath,harnessModel] = fileparts(fileNames.HarnessModel);
set_param(harnessModel,'covMetricSettings','dcmte');
sldvdemo_playall(harnessModel);

Clean Up

To complete the example, close all models and remove the files that Simulink Design Verifier generated.

close_system('sldvdemo_custom_blockreplib');
close_system(fileNames.HarnessModel,0);
close_system(fileNames.BlockReplacementModel,0);
close_system('sldvdemo_sqrt_blockrep',0);
delete(fileNames.HarnessModel);
delete(fileNames.BlockReplacementModel);
delete(fileNames.DataFile);