Optimize Eye Height In SerDes System Model
This example shows how to optimize performance metrics of a Simulink model using an optimization feature called msbOptimizer
from the Mixed-Signal Blockset™.
msbOptimizer
uses a solver called surrogateopt
from Global Optimization Toolbox™ for optimization. Any Simulink model can be optimized for best performance using the steps mentioned here. In this example, you will optimize eye metrics of a SerDes system. Eye metrics are an indication of the signal's quality and reliability and hence important parameters for serial communication.
Open the model eyeMeasurement_1Eye
which can found in this example folder. The model comprises a stimulus gnerator, transmitter (Tx), analog channel and a receiver (Rx). This model will be used to optimize the parameter TapWeights (DFE tap weights) of DFECDR
block inside Rx to meet eye performance metrics. It was originally created in the SerDes Designer app and then exported to Simulink®. For more information, see Design SerDes Systems and Export IBIS-AMI Models.
model='eyeMeasurement_1Eye';
open_system(model);
Eye Measurement
Run simulation with an initial set of DFE tap weigts to obtain the time-domain metrics before optimization. To generate time-domain metrics including the eye measurement summary, double click on the Configuration
block and select Plot time domain analysis after simulation.
weights=[0.06 -0.01 -0.04 -0.01]; tapWeights=['[',num2str(weights),']']; set_param([model '/Rx/DFECDR'],'TapWeights',tapWeights); sim(model);
The eye is almost closed and not optimal. You can also access the eye measurement summary which is exported to the model workspace using following function calls. In the next step, set up prerequisites for msbOptimizer
to optimize DFE tap weights for optimal eye height.
mws=get_param(bdroot,'ModelWorkspace'); results=mws.getVariable('SerDesResults'); metrics=results.TimeDomain.summary
metrics=9×2 cell array
{'Eye Height (V)' } {[1.5058e-06]}
{'Eye Width (ps)' } {[7.9261e-04]}
{'Eye Area (V*ps)'} {[7.3412e-05]}
{'COM' } {[6.8135e-05]}
{'VEC' } {[ 60]}
{'Minimum BER' } {[5.2632e-05]}
{'Ignore Symbols' } {[ 1000]}
{'Total Symbols' } {[ 20000]}
{'SER' } {[ 0.0034]}
Optimization setup
msbOptimizer
supports optimization within the Simulink environment and requires setting up output table, variable table and objective function.
Output Table
Create a table with output parameters and specifications to be met during optimization. The performance specificaitons considered in this example are Eye Height, Eye Width and Symbol Error Rate (SER).
outputTable=table(); outputTable.Test=["eye1";"eye1";"eye1"]; outputTable.Name={'Eye Height';'Eye Width';'SER'}; outputTable.Weight=[100;90;50]; outputTable.Units={'V';'ps';''}; outputTable.Spec={'> 0.12';'> 82';'< 1e-04'}
outputTable=3×5 table
Test Name Weight Units Spec
______ ______________ ______ __________ ___________
"eye1" {'Eye Height'} 100 {'V' } {'> 0.12' }
"eye1" {'Eye Width' } 90 {'ps' } {'> 82' }
"eye1" {'SER' } 50 {0x0 char} {'< 1e-04'}
Variable Table
Create a table of optimization variables and their ranges. In this example you will be optimizing the DFE tap weights in the Rx
block to meet the performance metrics specified in the output table.
variableTable=table(); variableTable.parameters={'w1';'w2';'w3';'w4'}; variableTable.values=["-0.2:0.001:0.2";"-0.1:0.001:0.1";"-0.1:0.001:0.1";"-0.1:0.001:0.1"]
variableTable=4×2 table
parameters values
__________ ________________
{'w1'} "-0.2:0.001:0.2"
{'w2'} "-0.1:0.001:0.1"
{'w3'} "-0.1:0.001:0.1"
{'w4'} "-0.1:0.001:0.1"
Objective Function
The objectve function sets values for optimization variables in the model, runs simulations in Simulink and extracts the performance metrics from the simulations. For this example you need to define an objective function to perform the folltowing steps:
Set the DFE tap weights using set_param()
Run simulations
Create a table of simulation results.
You will pass a handle from this objective function to the msbOptimizer
object in the next section.
function out=getEyeMetrics(x,parameterNames,paramScaleFactor,constraints,designName) % Pass the function handle to your custom % getMetrics() function as a Name-Value pair argument while instantiating the msbOptimizer. % E.g.,designOptimizer=msbOptimizer('simEnvironment','simulink','objectiveFunction',funcHandle), % where funcHandle=@(x) getMetrics(x,variableNames,variableScaleFactor,constraintTable,modelName) out.Fval =NaN(size(x,1),1); out.Ineq =NaN(size(x,1),height(constraints)-1); xHeight=size(x,1); simIn(1:xHeight)=Simulink.SimulationInput(designName); weights=zeros(1,numel(parameterNames)); resultsTable=table(); fprintf("\nRunning %d simulations in Simulink...\n",size(x,1)); for ii=1:xHeight ji=1; %set variable values in the next for loop for variable=parameterNames try simIn(ii)=setVariable(simIn(ii),variable,paramScaleFactor(ji).*x(ii,ji)); weights(ji)=paramScaleFactor(ji).*x(ii,ji); catch error(message('msblks:msblksMessages:optimSimulatorError')); end ji=ji+1; end tapWeights=['[',num2str(weights),']']; % 1. SET DFE TAP WEIGHTS set_param('eyeMeasurement_1Eye/Rx/DFECDR','TapWeights',tapWeights); try % 2. RUN SIMULATIONS sim(simIn(ii)); save_system('eyeMeasurement_1Eye'); % 3. EXTRACT METRICS AND CREATE A TABLE OF SIMULAITON RESULTS mws=get_param(bdroot,'ModelWorkspace'); results=mws.getVariable('SerDesResults'); metrics=results.TimeDomain.summary; eyeTable=cell2table(metrics); eyeTable=eyeTable(contains(eyeTable.metrics1, {'Eye Height','Eye Width','SER'}),:); resultsTable1=table(); resultsTable1.Output(1)="Eye Height"; resultsTable1.Output(2)="Eye Width"; resultsTable1.Output(3)="SER"; resultsTable1.Point=NaN(height(resultsTable1),1); resultsTable1.DataPoint=NaN(height(resultsTable1),1); resultsTable1.Result=eyeTable{:,2}; catch disp("Error during simulation. Setting results to 0.") resultsTable1=table(); resultsTable1.Output=zeros(3,1); resultsTable1.Result=zeros(3,1); resultsTable1.Point=zeros(3,1); resultsTable1.DataPoint=zeros(3,1); end if ~isempty(resultsTable) resultsTable=[resultsTable; resultsTable1]; else resultsTable=resultsTable1; end end % Create a struct called out which is required by surrogateopt [fval,ineq]=msblks.optimization.surrogateOptHelper.getFvalIneq(size(x,1),resultsTable,constraints); out.Fval=fval; out.Ineq=ineq; end
Run Optimization
To run optimization, first instantiate an object of msbOptimizer
class with the SimulationEnvironment
option set to simulink,
and other options set as shown below.
m=msbOptimizer('SimulationEnvironment','simulink',... 'DesignName',model,... 'OutputsSetup',outputTable,... 'VariableSetup',variableTable);
Create the function handle objFunction
from the objective function that was defined in the previous section. Pass the objective function handle as an argument to the optimizeDesign
method in the next step.
objFunction=@(x) getEyeMetrics(x,m.ParameterNames,m.ParameterScaleFactor,m.Constraints,m.DesignName);
Optimize the DFE tap weights for the specified time-domain metrics using the optimizeDesign
method of the msbOptimizer
object. You can specify the maximum number of simulations that will be run using MaxNumberSims
. You can set the number of simulations per iteration using NumParallelSims
. Disable ProgressPlot
by setting it to false
since there are also plots generated by Time-Domain Analysis.
[bestSolution1,bestMetrics1]=m.optimizeDesign('ObjectiveFunction',objFunction,'ProgressPlot',false,... 'NumParallelSims',5,'MinSurrogatePoints',15,'MaxNumberSims',45)
Detected 0 specifications with minimize or maximize criteria. Choosing 'SER' as the goal. Maximum number of simulations: 45 Number of parallel simulations: 5 Running 5 simulations in Simulink... Running 5 simulations in Simulink... Running 5 simulations in Simulink... Running 5 simulations in Simulink... Running 5 simulations in Simulink... Running 5 simulations in Simulink... Running 5 simulations in Simulink... Running 5 simulations in Simulink... Running 5 simulations in Simulink... Optimizer was unable to meet some or all the specifications. You can continue optimization from the current state by using the checkpoint file. E.g., if your object is called 'optimizer', run the following command: [solution, bestMetrics] = optimizer.optimizeDesign('useCheckPoint',true)
bestSolution1=4×2 table
Name Value
____ ______
"w1" -0.03
"w2" -0.002
"w3" -0.005
"w4" -0.01
bestMetrics1=3×4 table
Name FinalMetrics Specs Units
______________ ____________ ___________ __________
{'Eye Height'} 0.11109 {'> 0.12' } {'V' }
{'Eye Width' } 81.255 {'> 82' } {'ps' }
{'SER' } 0 {'< 1e-04'} {0x0 char}
Using InitialPoints
Observe that the performance metrics are close to but not quite at the target specifications set by the output table. You can continue the optimization process by passing the argument InitialPoints
which lets the optimization solver start from a set of initial points defined by the previously run iterations. This information is saved in Trials
property of msbOptimizer, which must be passed as a Name-Value pair argument for InitialPoints
to the optimizeDesign
method as shown below.
[bestSolution2,bestMetrics2]=m.optimizeDesign('InitialPoints',m.Trials,'ObjectiveFunction',objFunction,'ProgressPlot',false,... 'NumParallelSims',5,'MinSurrogatePoints',15,'MaxNumberSims',45)
Detected 0 specifications with minimize or maximize criteria. Choosing 'SER' as the goal. Maximum number of simulations: 45 Number of parallel simulations: 5 Running 5 simulations in Simulink... Running 5 simulations in Simulink... Running 5 simulations in Simulink... Optimizer was able to meet all the specifications.
bestSolution2=4×2 table
Name Value
____ ______
"w1" -0.039
"w2" -0.004
"w3" -0.007
"w4" -0.008
bestMetrics2=3×4 table
Name FinalMetrics Specs Units
______________ ____________ ___________ __________
{'Eye Height'} 0.12027 {'> 0.12' } {'V' }
{'Eye Width' } 83.208 {'> 82' } {'ps' }
{'SER' } 0 {'< 1e-04'} {0x0 char}
Verification
You can see that all the performance metrics are met after the second round of optimization run. Although MaxNumberSims
was set to 45
, optimizer stopped after 15
simulations since all the performance specifications were met. Verify that the tap weights stored in bestSolution
provide the required performance by setting the tap weights to the optimized values and observing the eye metrics. You can see that the eye metrics meet the specifications set in the output table.
weights=bestSolution2.Value'; tapWeights=['[',num2str(weights),']']; set_param([model '/Rx/DFECDR'],'TapWeights',tapWeights); sim(model);
See Also
Related Topics
- Design SerDes System and Export IBIS-AMI Model (SerDes Toolbox)