mirror of https://github.com/YosysHQ/abc.git
178 lines
5.4 KiB
C
178 lines
5.4 KiB
C
/**CFile****************************************************************
|
|
|
|
FileName [kLiveConstraints.c]
|
|
|
|
SystemName [ABC: Logic synthesis and verification system.]
|
|
|
|
PackageName [Liveness property checking.]
|
|
|
|
Synopsis [Constraint analysis module for the k-Liveness algorithm
|
|
invented by Koen Classen, Niklas Sorensson.]
|
|
|
|
Author [Sayak Ray]
|
|
|
|
Affiliation [UC Berkeley]
|
|
|
|
Date [Ver. 1.0. Started - October 31, 2012.]
|
|
|
|
Revision [$Id: liveness.c,v 1.00 2009/01/01 00:00:00 alanmi Exp $]
|
|
|
|
***********************************************************************/
|
|
|
|
#include <stdio.h>
|
|
#include "base/main/main.h"
|
|
#include "aig/aig/aig.h"
|
|
#include "aig/saig/saig.h"
|
|
#include <string.h>
|
|
#include "base/main/mainInt.h"
|
|
#include "proof/pdr/pdr.h"
|
|
|
|
ABC_NAMESPACE_IMPL_START
|
|
|
|
Aig_Obj_t *createConstrained0LiveCone( Aig_Man_t *pNewAig, Vec_Ptr_t *signalList )
|
|
{
|
|
Aig_Obj_t *pConsequent, *pConsequentCopy, *pAntecedent, *p0LiveCone, *pObj;
|
|
int i, numSigAntecedent;
|
|
|
|
numSigAntecedent = Vec_PtrSize( signalList ) - 1;
|
|
|
|
pAntecedent = Aig_ManConst1( pNewAig );
|
|
pConsequent = (Aig_Obj_t *)Vec_PtrEntry( signalList, numSigAntecedent );
|
|
pConsequentCopy = Aig_NotCond( (Aig_Obj_t *)(Aig_Regular(pConsequent)->pData), Aig_IsComplement( pConsequent ) );
|
|
|
|
for(i=0; i<numSigAntecedent; i++ )
|
|
{
|
|
pObj = (Aig_Obj_t *)Vec_PtrEntry( signalList, i );
|
|
assert( Aig_Regular(pObj)->pData );
|
|
pAntecedent = Aig_And( pNewAig, pAntecedent, Aig_NotCond((Aig_Obj_t *)(Aig_Regular(pObj)->pData), Aig_IsComplement(pObj)) );
|
|
}
|
|
|
|
p0LiveCone = Aig_Or( pNewAig, Aig_Not(pAntecedent), pConsequentCopy );
|
|
|
|
return p0LiveCone;
|
|
}
|
|
|
|
Vec_Ptr_t *collectCSSignals( Abc_Ntk_t *pNtk, Aig_Man_t *pAig )
|
|
{
|
|
int i;
|
|
Aig_Obj_t *pObj, *pConsequent = NULL;
|
|
Vec_Ptr_t *vNodeArray;
|
|
|
|
vNodeArray = Vec_PtrAlloc(1);
|
|
|
|
Saig_ManForEachPo( pAig, pObj, i )
|
|
{
|
|
if( strstr( Abc_ObjName(Abc_NtkPo( pNtk, i )), "csLiveConst_" ) != NULL )
|
|
Vec_PtrPush( vNodeArray, Aig_NotCond((Aig_Obj_t *)Aig_ObjFanin0(pObj), Aig_ObjFaninC0(pObj)) );
|
|
else if( strstr( Abc_ObjName(Abc_NtkPo( pNtk, i )), "csLiveTarget_" ) != NULL )
|
|
pConsequent = Aig_NotCond((Aig_Obj_t *)Aig_ObjFanin0(pObj), Aig_ObjFaninC0(pObj));
|
|
}
|
|
assert( pConsequent );
|
|
Vec_PtrPush( vNodeArray, pConsequent );
|
|
return vNodeArray;
|
|
}
|
|
|
|
Aig_Man_t *createNewAigWith0LivePo( Aig_Man_t *pAig, Vec_Ptr_t *signalList, int *index0Live )
|
|
{
|
|
Aig_Man_t *pNewAig;
|
|
Aig_Obj_t *pObj, *pObjNewPoDriver;
|
|
int i;
|
|
|
|
//assert( Vec_PtrSize( signalList ) > 1 );
|
|
|
|
//****************************************************************
|
|
// Step1: create the new manager
|
|
// Note: The new manager is created with "2 * Aig_ManObjNumMax(p)"
|
|
// nodes, but this selection is arbitrary - need to be justified
|
|
//****************************************************************
|
|
pNewAig = Aig_ManStart( Aig_ManObjNumMax(pAig) );
|
|
pNewAig->pName = (char *)malloc( strlen( pAig->pName ) + strlen("_0Live") + 1 );
|
|
sprintf(pNewAig->pName, "%s_%s", pAig->pName, "0Live");
|
|
pNewAig->pSpec = NULL;
|
|
|
|
//****************************************************************
|
|
// Step 2: map constant nodes
|
|
//****************************************************************
|
|
pObj = Aig_ManConst1( pAig );
|
|
pObj->pData = Aig_ManConst1( pNewAig );
|
|
|
|
//****************************************************************
|
|
// Step 3: create true PIs
|
|
//****************************************************************
|
|
Saig_ManForEachPi( pAig, pObj, i )
|
|
{
|
|
pObj->pData = Aig_ObjCreateCi( pNewAig );
|
|
}
|
|
|
|
//****************************************************************
|
|
// Step 5: create register outputs
|
|
//****************************************************************
|
|
Saig_ManForEachLo( pAig, pObj, i )
|
|
{
|
|
pObj->pData = Aig_ObjCreateCi( pNewAig );
|
|
}
|
|
|
|
//********************************************************************
|
|
// Step 7: create internal nodes
|
|
//********************************************************************
|
|
Aig_ManForEachNode( pAig, pObj, i )
|
|
{
|
|
pObj->pData = Aig_And( pNewAig, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) );
|
|
}
|
|
|
|
Saig_ManForEachPo( pAig, pObj, i )
|
|
{
|
|
pObj->pData = Aig_ObjCreateCo( pNewAig, Aig_ObjChild0Copy(pObj) );
|
|
}
|
|
|
|
pObjNewPoDriver = createConstrained0LiveCone( pNewAig, signalList );
|
|
Aig_ObjCreateCo( pNewAig, pObjNewPoDriver );
|
|
*index0Live = i;
|
|
|
|
Saig_ManForEachLi( pAig, pObj, i )
|
|
{
|
|
pObj->pData = Aig_ObjCreateCo( pNewAig, Aig_ObjChild0Copy(pObj) );
|
|
}
|
|
|
|
Aig_ManSetRegNum( pNewAig, Aig_ManRegNum(pAig) );
|
|
Aig_ManCleanup( pNewAig );
|
|
|
|
assert( Aig_ManCheck( pNewAig ) );
|
|
return pNewAig;
|
|
}
|
|
|
|
Vec_Ptr_t *checkMonotoneSignal()
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
Vec_Ptr_t *gatherMonotoneSignals(Aig_Man_t *pAig)
|
|
{
|
|
int i;
|
|
Aig_Obj_t *pObj;
|
|
|
|
Aig_ManForEachNode( pAig, pObj, i )
|
|
{
|
|
Aig_ObjPrint( pAig, pObj );
|
|
printf("\n");
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
Aig_Man_t *generateWorkingAig( Aig_Man_t *pAig, Abc_Ntk_t *pNtk, int *pIndex0Live )
|
|
{
|
|
Vec_Ptr_t *vSignalVector;
|
|
Aig_Man_t *pAigNew;
|
|
|
|
vSignalVector = collectCSSignals( pNtk, pAig );
|
|
assert(vSignalVector);
|
|
pAigNew = createNewAigWith0LivePo( pAig, vSignalVector, pIndex0Live );
|
|
Vec_PtrFree(vSignalVector);
|
|
|
|
return pAigNew;
|
|
}
|
|
|
|
ABC_NAMESPACE_IMPL_END
|
|
|