mirror of https://github.com/YosysHQ/abc.git
328 lines
10 KiB
C
328 lines
10 KiB
C
/**CFile****************************************************************
|
|
|
|
FileName [wlcAbc.c]
|
|
|
|
SystemName [ABC: Logic synthesis and verification system.]
|
|
|
|
PackageName [Verilog parser.]
|
|
|
|
Synopsis [Parses several flavors of word-level Verilog.]
|
|
|
|
Author [Alan Mishchenko]
|
|
|
|
Affiliation [UC Berkeley]
|
|
|
|
Date [Ver. 1.0. Started - August 22, 2014.]
|
|
|
|
Revision [$Id: wlcAbc.c,v 1.00 2014/09/12 00:00:00 alanmi Exp $]
|
|
|
|
***********************************************************************/
|
|
|
|
#include "wlc.h"
|
|
#include "base/abc/abc.h"
|
|
|
|
ABC_NAMESPACE_IMPL_START
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
/// DECLARATIONS ///
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
/// FUNCTION DEFINITIONS ///
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis []
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
void Wlc_NtkPrintInputInfo( Wlc_Ntk_t * pNtk )
|
|
{
|
|
Wlc_Obj_t * pObj;
|
|
int i, k, nRange, nBeg, nEnd, nBits = 0;
|
|
FILE * output;
|
|
|
|
output = fopen("abc_blast_input.info","w");
|
|
|
|
Wlc_NtkForEachCi( pNtk, pObj, i )
|
|
{
|
|
nRange = Wlc_ObjRange(pObj);
|
|
nBeg = pObj->Beg;
|
|
nEnd = pObj->End;
|
|
|
|
for ( k = 0; k < nRange; k++ )
|
|
{
|
|
int index = nEnd > nBeg ? nBeg + k : nEnd + k;
|
|
char c = pObj->Type != WLC_OBJ_FO ? 'i' : pNtk->pInits[nBits + k];
|
|
fprintf(output,"%s[%d] : %c \n", Wlc_ObjName(pNtk, Wlc_ObjId(pNtk, pObj)), index , c );
|
|
}
|
|
if (pObj->Type == WLC_OBJ_FO)
|
|
nBits += nRange;
|
|
}
|
|
|
|
Wlc_NtkForEachPo( pNtk, pObj, i )
|
|
{
|
|
nRange = Wlc_ObjRange(pObj);
|
|
nBeg = pObj->Beg;
|
|
nEnd = pObj->End;
|
|
|
|
for ( k = 0; k < nRange; k++ )
|
|
{
|
|
int index = nEnd > nBeg ? nBeg + k : nEnd + k;
|
|
fprintf(output,"%s[%d] : o \n", Wlc_ObjName(pNtk, Wlc_ObjId(pNtk, pObj)), index);
|
|
}
|
|
}
|
|
|
|
fclose(output);
|
|
return;
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis []
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
void Wlc_NtkPrintInvStats( Wlc_Ntk_t * pNtk, Vec_Int_t * vCounts, int fVerbose )
|
|
{
|
|
Wlc_Obj_t * pObj;
|
|
int i, k, nNum, nRange, nBits = 0;
|
|
Wlc_NtkForEachCi( pNtk, pObj, i )
|
|
{
|
|
if ( pObj->Type != WLC_OBJ_FO )
|
|
continue;
|
|
nRange = Wlc_ObjRange(pObj);
|
|
for ( k = 0; k < nRange; k++ )
|
|
{
|
|
nNum = Vec_IntEntry(vCounts, nBits + k);
|
|
if ( nNum )
|
|
break;
|
|
}
|
|
if ( k == nRange )
|
|
{
|
|
nBits += nRange;
|
|
continue;
|
|
}
|
|
printf( "%s[%d:%d] : ", Wlc_ObjName(pNtk, Wlc_ObjId(pNtk, pObj)), pObj->End, pObj->Beg );
|
|
for ( k = 0; k < nRange; k++ )
|
|
{
|
|
nNum = Vec_IntEntry( vCounts, nBits + k );
|
|
if ( nNum == 0 )
|
|
continue;
|
|
printf( " [%d] -> %d", k, nNum );
|
|
}
|
|
printf( "\n");
|
|
nBits += nRange;
|
|
}
|
|
//printf( "%d %d\n", Vec_IntSize(vCounts), nBits );
|
|
assert( Vec_IntSize(vCounts) == nBits );
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis []
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
Abc_Ntk_t * Wlc_NtkGetInv( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv )
|
|
{
|
|
extern Vec_Int_t * Pdr_InvCounts( Vec_Int_t * vInv );
|
|
extern Vec_Str_t * Pdr_InvPrintStr( Vec_Int_t * vInv, Vec_Int_t * vCounts );
|
|
|
|
Vec_Int_t * vCounts = Pdr_InvCounts( vInv );
|
|
Vec_Str_t * vSop = Pdr_InvPrintStr( vInv, vCounts );
|
|
|
|
Wlc_Obj_t * pObj;
|
|
int i, k, nNum, nRange, nBits = 0;
|
|
Abc_Ntk_t * pMainNtk = NULL;
|
|
Abc_Obj_t * pMainObj, * pMainTemp;
|
|
char Buffer[5000];
|
|
// start the network
|
|
pMainNtk = Abc_NtkAlloc( ABC_NTK_LOGIC, ABC_FUNC_SOP, 1 );
|
|
// duplicate the name and the spec
|
|
pMainNtk->pName = Extra_UtilStrsav(pNtk ? pNtk->pName : "inv");
|
|
// create primary inputs
|
|
if ( pNtk == NULL )
|
|
{
|
|
int Entry, nInputs = Abc_SopGetVarNum( Vec_StrArray(vSop) );
|
|
Vec_IntForEachEntry( vCounts, Entry, i )
|
|
{
|
|
if ( Entry == 0 )
|
|
continue;
|
|
pMainObj = Abc_NtkCreatePi( pMainNtk );
|
|
sprintf( Buffer, "pi%d", i );
|
|
Abc_ObjAssignName( pMainObj, Buffer, NULL );
|
|
}
|
|
if ( Abc_NtkPiNum(pMainNtk) != nInputs )
|
|
{
|
|
printf( "Mismatch between number of inputs and the number of literals in the invariant.\n" );
|
|
Abc_NtkDelete( pMainNtk );
|
|
return NULL;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Wlc_NtkForEachCi( pNtk, pObj, i )
|
|
{
|
|
if ( pObj->Type != WLC_OBJ_FO )
|
|
continue;
|
|
nRange = Wlc_ObjRange(pObj);
|
|
for ( k = 0; k < nRange; k++ )
|
|
{
|
|
nNum = Vec_IntEntry(vCounts, nBits + k);
|
|
if ( nNum )
|
|
break;
|
|
}
|
|
if ( k == nRange )
|
|
{
|
|
nBits += nRange;
|
|
continue;
|
|
}
|
|
//printf( "%s[%d:%d] : ", Wlc_ObjName(pNtk, Wlc_ObjId(pNtk, pObj)), pObj->End, pObj->Beg );
|
|
for ( k = 0; k < nRange; k++ )
|
|
{
|
|
nNum = Vec_IntEntry( vCounts, nBits + k );
|
|
if ( nNum == 0 )
|
|
continue;
|
|
//printf( " [%d] -> %d", k, nNum );
|
|
pMainObj = Abc_NtkCreatePi( pMainNtk );
|
|
sprintf( Buffer, "%s[%d]", Wlc_ObjName(pNtk, Wlc_ObjId(pNtk, pObj)), k );
|
|
Abc_ObjAssignName( pMainObj, Buffer, NULL );
|
|
|
|
}
|
|
//printf( "\n");
|
|
nBits += nRange;
|
|
}
|
|
}
|
|
//printf( "%d %d\n", Vec_IntSize(vCounts), nBits );
|
|
assert( pNtk == NULL || Vec_IntSize(vCounts) == nBits );
|
|
// create node
|
|
pMainObj = Abc_NtkCreateNode( pMainNtk );
|
|
Abc_NtkForEachPi( pMainNtk, pMainTemp, i )
|
|
Abc_ObjAddFanin( pMainObj, pMainTemp );
|
|
pMainObj->pData = Abc_SopRegister( (Mem_Flex_t *)pMainNtk->pManFunc, Vec_StrArray(vSop) );
|
|
Vec_IntFree( vCounts );
|
|
Vec_StrFree( vSop );
|
|
// create PO
|
|
pMainTemp = Abc_NtkCreatePo( pMainNtk );
|
|
Abc_ObjAddFanin( pMainTemp, pMainObj );
|
|
Abc_ObjAssignName( pMainTemp, "inv", NULL );
|
|
return pMainNtk;
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Translate current network into an invariant.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
Vec_Int_t * Wlc_NtkGetPut( Abc_Ntk_t * pNtk, Gia_Man_t * pGia )
|
|
{
|
|
int nRegs = Gia_ManRegNum(pGia);
|
|
Vec_Int_t * vRes = NULL;
|
|
if ( Abc_NtkPoNum(pNtk) != 1 )
|
|
printf( "The number of outputs is other than 1.\n" );
|
|
else if ( Abc_NtkNodeNum(pNtk) != 1 )
|
|
printf( "The number of internal nodes is other than 1.\n" );
|
|
else
|
|
{
|
|
Abc_Nam_t * pNames = NULL;
|
|
Abc_Obj_t * pFanin, * pNode = Abc_ObjFanin0( Abc_NtkCo(pNtk, 0) );
|
|
char * pName, * pCube, * pSop = (char *)pNode->pData;
|
|
Vec_Int_t * vFanins = Vec_IntAlloc( Abc_ObjFaninNum(pNode) );
|
|
int i, k, Value, nLits, Counter = 0;
|
|
if ( pGia->vNamesIn )
|
|
{
|
|
// hash the names
|
|
pNames = Abc_NamStart( 100, 16 );
|
|
Vec_PtrForEachEntry( char *, pGia->vNamesIn, pName, i )
|
|
{
|
|
Value = Abc_NamStrFindOrAdd( pNames, pName, NULL );
|
|
assert( Value == i+1 );
|
|
//printf( "%s(%d) ", pName, i );
|
|
}
|
|
//printf( "\n" );
|
|
}
|
|
Abc_ObjForEachFanin( pNode, pFanin, i )
|
|
{
|
|
assert( Abc_ObjIsCi(pFanin) );
|
|
pName = Abc_ObjName(pFanin);
|
|
if ( pNames )
|
|
{
|
|
Value = Abc_NamStrFind(pNames, pName) - 1 - Gia_ManPiNum(pGia);
|
|
if ( Value < 0 )
|
|
{
|
|
if ( Counter++ == 0 )
|
|
printf( "Cannot read input name \"%s\" of fanin %d.\n", pName, i );
|
|
Value = i;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for ( k = (int)strlen(pName)-1; k >= 0; k-- )
|
|
if ( pName[k] < '0' || pName[k] > '9' )
|
|
break;
|
|
if ( k == (int)strlen(pName)-1 )
|
|
{
|
|
if ( Counter++ == 0 )
|
|
printf( "Cannot read input name \"%s\" of fanin %d.\n", pName, i );
|
|
Value = i;
|
|
}
|
|
else
|
|
Value = atoi(pName + k + 1);
|
|
}
|
|
Vec_IntPush( vFanins, Value );
|
|
}
|
|
if ( Counter )
|
|
printf( "Cannot read names for %d inputs of the invariant.\n", Counter );
|
|
if ( pNames )
|
|
Abc_NamStop( pNames );
|
|
assert( Vec_IntSize(vFanins) == Abc_ObjFaninNum(pNode) );
|
|
vRes = Vec_IntAlloc( 1000 );
|
|
Vec_IntPush( vRes, Abc_SopGetCubeNum(pSop) );
|
|
Abc_SopForEachCube( pSop, Abc_ObjFaninNum(pNode), pCube )
|
|
{
|
|
nLits = 0;
|
|
Abc_CubeForEachVar( pCube, Value, k )
|
|
if ( Value != '-' )
|
|
nLits++;
|
|
Vec_IntPush( vRes, nLits );
|
|
Abc_CubeForEachVar( pCube, Value, k )
|
|
if ( Value != '-' )
|
|
Vec_IntPush( vRes, Abc_Var2Lit(Vec_IntEntry(vFanins, k), (int)Value == '0') );
|
|
}
|
|
Vec_IntPush( vRes, nRegs );
|
|
Vec_IntFree( vFanins );
|
|
}
|
|
return vRes;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
/// END OF FILE ///
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
ABC_NAMESPACE_IMPL_END
|
|
|