📄 inherentbistexperiment.java~
字号:
/*
* InherentBISTExperiment.java
*
* Created on 18 January 2002, 00:34
*/
package jaga.pj.circuits.experiment;
import jaga.experiment.*;
import jaga.*;
import debug.DebugLib;
/** To evolve circuits that include a BIST line all through their evolutioary
* life. <b> Up to now, only single SSA faults are simulated. <b> For efficiency, this has a
* messy interface with the FaultyCircuit class in the way this tells it
* where/what faults are. This is why this class needs to know about bitsPerVar
* when being an abstract experiment it shouldn't.
* This class also is in charge of the fault model and can be told to allow for
* a maximum of simultaneous faults of different kinds..
*
* @author Michael Garvie
*/
public class InherentBISTExperiment implements jaga.experiment.Experiment {
Experiment experiment;
int bitsPerVar;
final static int DEFAULT_INPUT_SAMPLE_SEPARATION = 10;
final static double FAULT_DETECT_T_SETUP = 0.05;
final static double PENALTY_PER_FAULT = 0.90;
static int lastInputSampleSeparation;
static SampleData[] lastGeneratedInputs;
/** Constant defining Single Stuck At faults */
public final static int SSA = 0;
int[] faultFrequencies;
/** Creates new InherentBISTExperiment
* @param experiment defines what circuit we should evolve to include BIST.
* @param faultFrequencies max number of simultaneous faults of each kind
* we should aim to detect. Positions in array are defined by constants in
* this class such as 'SSA'.
* @param bitsPerVar defines how many bits are used to define a gate in the
* circuit, must be same as in circuit deployment. This breaks the modular
* decomposition in exchange for efficiency.. a bit messy.
*/
public InherentBISTExperiment( Experiment experiment, int[] faultFrequencies, int bitsPerVar ) {
this.experiment = experiment;
this.faultFrequencies = faultFrequencies;
this.bitsPerVar = bitsPerVar;
}
/** returns a fitness associated to a given input/output pair for
* this experiment. The fitness is a double and is in adjusted
* fitness format. From 0 to 1, 1 being perfectly fit.
* @param in array of inputs
* @param out array of outputs
*/
public double getFitness(SampleData[] in,SampleData[] out)
{
int numElements = ( 1 << bitsPerVar ) - experiment.getNumOfInputs();
int numFaults = numElements * 2 + 1; // two types of faults for each plus no faults.
int stdTestLen = in[ 0 ].length() / numFaults; // we generated same input when testing each fault.
int inputSampleSeparation = in[ 0 ].getSampleSeparation();
int stdTestLenOut = stdTestLen * inputSampleSeparation; // output is sampled more often.
int bitsPerFault = bitsPerVar + 1; // to define a fault say where and stuck at what. (fault 2^bitsPerVar corresponds to an input element and means no faults)
int totalFaultBits = bitsPerFault * faultFrequencies[ SSA ]; // how many input lines dedicated to fault definitions.
double faultPenalty = 1; // acc of penalties for introduced faults.
// 0. Initialize bitset to store what E should've been and what was
BitSet desE = new BitSet( numFaults );
// 1. get perfect fitness chunk
SampleData[] noFaultsIn = ESLib.getChunks( in, 0, stdTestLen, totalFaultBits, in.length - 1 );
SampleData[] noFaultsOut = ESLib.getChunks( out, 0, stdTestLenOut, 0, out.length - 2 ); // last output is E
DebugLib.trcLogger.entry( com.ibm.logging.IRecordType.TYPE_ENTRY, this.getClass().getName(), "getFitness", "nfil=" + noFaultsIn.length + " nfol=" + noFaultsOut.length );
double noFaultsFitness = experiment.getFitness( noFaultsIn, noFaultsOut );
SampleData[] currFaultIn;
SampleData[] currFaultOut;
// desQ( 0 ) always 0.
//desE.clear( 0 );
for( int flp = 1; flp < numFaults; flp++ )
{
currFaultIn = ESLib.getChunks( in, flp * stdTestLen, stdTestLen, totalFaultBits, in.length - 1);
currFaultOut = ESLib.getChunks( out, flp * stdTestLenOut, stdTestLenOut, 0, out.length - 2 );
double currFaultFit = experiment.getFitness( currFaultIn, currFaultOut );
// **!! remember maybe add that extra detects better than missing detects
if( currFaultFit < noFaultsFitness - 0.01 )
{
// Fault has reduced fitness!
desE.set( flp );
faultPenalty *= PENALTY_PER_FAULT;
}else
{
//desE.clear( flp );
// ** do clever stuff if fitness improves
if( currFaultFit > noFaultsFitness + 0.2 && currFaultFit > 0.5 )
{
DebugLib.println( "Fault introduced increased fitness from " + noFaultsFitness + " to " + currFaultFit );
}
}
}
double detectCorrelation = Math.abs( ExperimentLib.getCorrelationFitness( FAULT_DETECT_T_SETUP, numFaults, stdTestLenOut, ESLib.stretch( desE, stdTestLenOut ), out[ out.length - 1 ] ) );
DebugLib.trcLogger.entry( com.ibm.logging.IRecordType.TYPE_ENTRY, this.getClass().getName(), "getFitness", "nf=" + noFaultsFitness + " dc=" + detectCorrelation );
double fitness = 0.9 * noFaultsFitness + 0.1 * detectCorrelation;
fitness *= faultPenalty;
return fitness;
}
/** generates an array of inputs suitable for this experiment
* using default input sample separation. <p>
*
*/
public SampleData[] generateInput()
{
return generateInput( DEFAULT_INPUT_SAMPLE_SEPARATION );
}
/** generates an array of inputs suitable for this experiment.
* @param inputSampleSeparation relative frequency of input to output samples. If this is n, then n outputs will be sampled for every change in inputs.
*
* The first ( bitsPerVar + 1 ) * faultFrequencies[ SSA ] input lines are
* used to define the faults to de deployment. <p>
* The experiment's natural test pattern will be repeated once for no faults
* and once for every type of fault under this model. So for eg: where a fault
* can affect one of n elements and r elements are allowed to fail we must
* test: <tt> <p>
* ( n ) ( n ) ( n ) fault combinations ( n ) <u> n! </u><p>
* ( 0 ) + ( 1 ) + .. + ( r ) where bin coeff. ( r ) = r! (n-r)! <p> </tt>
*
* <p> Only single SSA implemented.
*/
public SampleData[] generateInput(int inputSampleSeparation)
{
SampleData[] rv;
if( inputSampleSeparation == lastInputSampleSeparation )
{
// must clone the array! It vill be destroyed if not..
rv = new SampleData[ lastGeneratedInputs.length ];
for( int il = 0; il < lastGeneratedInputs.length; il++ )
{
rv[ il ] = ( SampleData ) lastGeneratedInputs[ il ].clone();
}
}else
{
// 1. First get standard test outputs.
SampleData[] standardInputs = experiment.generateInput( inputSampleSeparation );
int expNumInputs = experiment.getNumOfInputs(); // = standardInputs.length
int stdTestLength = standardInputs[ 0 ].length();
// 2. Now generate fault information lines.
// 2.1 Only 1 SSA for now
int maxElement = ( 1 << bitsPerVar );
int numElements = maxElement - expNumInputs;
/*
for( int nrfl = 0; nrfl < faultFrequencies[ SSA ]; nrfl++ )
{
int faultCombs = ExperimentLib.binomialCoefficient( numElements, nrfl );
for( int afl = 0; afl < faultCombs; afl++ )
{
}
*/
// 2.1.1 First error free is with error at element ( maxElement - 1 )
// which corresponds to an input line.
int nrSimFaults = 1 + numElements * 2; // every el can be SSA 2 values.
int faultDefLines = ( bitsPerVar + 1 ); // * faultFrequencies[ SSA ] for more.
SampleData[] faultDefs = new SampleData[ faultDefLines ];
for( int sdl = 0; sdl < faultDefLines; sdl++ )
{
faultDefs[ sdl ] = new SampleData( 1, nrSimFaults );
faultDefs[ sdl ].set( 0 );
}
// 2.1.2 Other errors encode number of element where stuck at.
for( int fnl = 0; fnl < numElements * 2; fnl++ )
{
ESLib.setLine( faultDefs, fnl + 1, fnl );
}
// 3. Merge both.
int totalNumInputs = faultDefLines + expNumInputs;
rv = new SampleData[ totalNumInputs ];
int totalInputLength = stdTestLength * nrSimFaults;
for( int sdl = 0; sdl < totalNumInputs; sdl++ )
{
rv[ sdl ] = new SampleData( inputSampleSeparation, totalInputLength );
}
for( int fnl = 0; fnl < nrSimFaults; fnl++ )
{
for( int eil = 0; eil < stdTestLength; eil++ )
{
int currentLine = fnl * stdTestLength + eil;
for( int fbl = 0; fbl < faultDefLines; fbl++ )
{
rv[ fbl ].setTo( currentLine, faultDefs[ fbl ].get( fnl ) );
}
for( int stl = 0; stl < expNumInputs; stl++ )
{
rv[ faultDefLines + stl ].setTo( currentLine, standardInputs[ stl ].get( eil ) );
}
}
}
lastGeneratedInputs = rv;
lastInputSampleSeparation = inputSampleSeparation;
}
return rv;
}
/** @return Number of inputs of circuit to be evolved. Extra inputs will be
* sent to the deployment to represent faults.
*/
public int getNumOfInputs()
{
return experiment.getNumOfInputs(); // * faultFrequencies[ SSA ] for more.
}
/** @return Number of outputs of circuit to be evolved.
*/
public int getNumOfOutputs()
{
return experiment.getNumOfOutputs() + 1;
}
public String toString( int[] a )
{
String narrator = "{ ";
for( int i = 0; i < a.length - 1; i++ )
{
narrator += a[ i ] + ", ";
}
narrator += a[ a.length - 1 ] + " }";
return narrator;
}
public String toString()
{
String narrator = "InherentBISTExperiment with faultFrequencies:" + toString( faultFrequencies );
narrator += "\n Purpose Experiment: " + experiment;
return narrator;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -