abc/src/aig/ntl/ntlInsert.c

231 lines
8.1 KiB
C

/**CFile****************************************************************
FileName [ntlInsert.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Netlist representation.]
Synopsis [Procedures to insert mapping into a design.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: ntlInsert.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "ntl.h"
#include "kit.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Inserts the given mapping into the netlist.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Ntl_ManInsert( Ntl_Man_t * p, Vec_Ptr_t * vMapping, Aig_Man_t * pAig )
{
char Buffer[100];
Vec_Ptr_t * vCopies;
Vec_Int_t * vCover;
Ntl_Mod_t * pRoot;
Ntl_Obj_t * pNode;
Ntl_Net_t * pNet, * pNetCo;
Ntl_Lut_t * pLut;
int i, k, nDigits;
// map the AIG back onto the design
Ntl_ManForEachCiNet( p, pNet, i )
pNet->pFunc = Aig_ManPi( pAig, i );
Ntl_ManForEachCoNet( p, pNet, i )
pNet->pFunc = Aig_ObjChild0( Aig_ManPo( pAig, i ) );
// remove old nodes
pRoot = Vec_PtrEntry( p->vModels, 0 );
Ntl_ModelForEachNode( pRoot, pNode, i )
Vec_PtrWriteEntry( pRoot->vObjs, pNode->Id, NULL );
// start mapping of AIG nodes into their copies
vCopies = Vec_PtrStart( Aig_ManObjNumMax(pAig) );
Ntl_ManForEachCiNet( p, pNet, i )
Vec_PtrWriteEntry( vCopies, pNet->pFunc->Id, pNet );
// create a new node for each LUT
vCover = Vec_IntAlloc( 1 << 16 );
nDigits = Aig_Base10Log( Vec_PtrSize(vMapping) );
Vec_PtrForEachEntry( vMapping, pLut, i )
{
pNode = Ntl_ModelCreateNode( pRoot, pLut->nFanins );
pNode->pSop = Ntl_SopFromTruth( p, pLut->pTruth, pLut->nFanins, vCover );
if ( !Kit_TruthIsConst0(pLut->pTruth, pLut->nFanins) && !Kit_TruthIsConst1(pLut->pTruth, pLut->nFanins) )
{
for ( k = 0; k < pLut->nFanins; k++ )
{
pNet = Vec_PtrEntry( vCopies, pLut->pFanins[k] );
if ( pNet == NULL )
{
printf( "Ntl_ManInsert(): Internal error: Net not found.\n" );
return 0;
}
Ntl_ObjSetFanin( pNode, pNet, k );
}
}
sprintf( Buffer, "lut%0*d", nDigits, i );
if ( (pNet = Ntl_ModelFindNet( pRoot, Buffer )) )
{
printf( "Ntl_ManInsert(): Internal error: Intermediate net name is not unique.\n" );
return 0;
}
pNet = Ntl_ModelFindOrCreateNet( pRoot, Buffer );
if ( !Ntl_ModelSetNetDriver( pNode, pNet ) )
{
printf( "Ntl_ManInsert(): Internal error: Net has more than one fanin.\n" );
return 0;
}
Vec_PtrWriteEntry( vCopies, pLut->Id, pNet );
}
Vec_IntFree( vCover );
// mark CIs and outputs of the registers
Ntl_ManForEachCiNet( p, pNetCo, i )
pNetCo->nVisits = 101;
// update the CO pointers
Ntl_ManForEachCoNet( p, pNetCo, i )
{
if ( pNetCo->nVisits == 101 )
continue;
pNetCo->nVisits = 101;
pNet = Vec_PtrEntry( vCopies, Aig_Regular(pNetCo->pFunc)->Id );
pNode = Ntl_ModelCreateNode( pRoot, 1 );
pNode->pSop = Aig_IsComplement(pNetCo->pFunc)? Ntl_ManStoreSop( p, "0 1\n" ) : Ntl_ManStoreSop( p, "1 1\n" );
Ntl_ObjSetFanin( pNode, pNet, 0 );
// update the CO driver net
pNetCo->pDriver = NULL;
if ( !Ntl_ModelSetNetDriver( pNode, pNetCo ) )
{
printf( "Ntl_ManInsert(): Internal error: PO net has more than one fanin.\n" );
return 0;
}
}
Vec_PtrFree( vCopies );
return 1;
}
/**Function*************************************************************
Synopsis [Inserts the given mapping into the netlist.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Ntl_ManInsertNtk( Ntl_Man_t * p, Ntk_Man_t * pNtk )
{
char Buffer[100];
Vec_Int_t * vTruth;
Vec_Int_t * vCover;
Ntl_Mod_t * pRoot;
Ntl_Obj_t * pNode;
Ntl_Net_t * pNet, * pNetCo;
Ntk_Obj_t * pObj, * pFanin;
int i, k, nDigits;
unsigned * pTruth;
assert( Vec_PtrSize(p->vCis) == Ntk_ManCiNum(pNtk) );
assert( Vec_PtrSize(p->vCos) == Ntk_ManCoNum(pNtk) );
// set the correspondence between the PI/PO nodes
Ntl_ManForEachCiNet( p, pNet, i )
Ntk_ManCi( pNtk, i )->pCopy = pNet;
// Ntl_ManForEachCoNet( p, pNet, i )
// Ntk_ManCo( pNtk, i )->pCopy = pNet;
// remove old nodes
pRoot = Vec_PtrEntry( p->vModels, 0 );
Ntl_ModelForEachNode( pRoot, pNode, i )
Vec_PtrWriteEntry( pRoot->vObjs, pNode->Id, NULL );
// create a new node for each LUT
vTruth = Vec_IntAlloc( 1 << 16 );
vCover = Vec_IntAlloc( 1 << 16 );
nDigits = Aig_Base10Log( Ntk_ManNodeNum(pNtk) );
Ntk_ManForEachNode( pNtk, pObj, i )
{
pNode = Ntl_ModelCreateNode( pRoot, Ntk_ObjFaninNum(pObj) );
pTruth = Hop_ManConvertAigToTruth( pNtk->pManHop, pObj->pFunc, Ntk_ObjFaninNum(pObj), vTruth, 0 );
pNode->pSop = Ntl_SopFromTruth( p, pTruth, Ntk_ObjFaninNum(pObj), vCover );
if ( !Kit_TruthIsConst0(pTruth, Ntk_ObjFaninNum(pObj)) && !Kit_TruthIsConst1(pTruth, Ntk_ObjFaninNum(pObj)) )
{
Ntk_ObjForEachFanin( pObj, pFanin, k )
{
pNet = pFanin->pCopy;
if ( pNet == NULL )
{
printf( "Ntl_ManInsert(): Internal error: Net not found.\n" );
return 0;
}
Ntl_ObjSetFanin( pNode, pNet, k );
}
}
sprintf( Buffer, "lut%0*d", nDigits, i );
if ( (pNet = Ntl_ModelFindNet( pRoot, Buffer )) )
{
printf( "Ntl_ManInsert(): Internal error: Intermediate net name is not unique.\n" );
return 0;
}
pNet = Ntl_ModelFindOrCreateNet( pRoot, Buffer );
if ( !Ntl_ModelSetNetDriver( pNode, pNet ) )
{
printf( "Ntl_ManInsert(): Internal error: Net has more than one fanin.\n" );
return 0;
}
pObj->pCopy = pNet;
}
Vec_IntFree( vCover );
Vec_IntFree( vTruth );
// mark CIs and outputs of the registers
Ntl_ManForEachCiNet( p, pNetCo, i )
pNetCo->nVisits = 101;
// update the CO pointers
Ntl_ManForEachCoNet( p, pNetCo, i )
{
if ( pNetCo->nVisits == 101 )
continue;
pNetCo->nVisits = 101;
// get the corresponding PO and its driver
pObj = Ntk_ManCo( pNtk, i );
pFanin = Ntk_ObjFanin0( pObj );
// get the net driving the driver
pNet = pFanin->pCopy; //Vec_PtrEntry( vCopies, Aig_Regular(pNetCo->pFunc)->Id );
pNode = Ntl_ModelCreateNode( pRoot, 1 );
pNode->pSop = pObj->fCompl /*Aig_IsComplement(pNetCo->pFunc)*/? Ntl_ManStoreSop( p, "0 1\n" ) : Ntl_ManStoreSop( p, "1 1\n" );
Ntl_ObjSetFanin( pNode, pNet, 0 );
// update the CO driver net
pNetCo->pDriver = NULL;
if ( !Ntl_ModelSetNetDriver( pNode, pNetCo ) )
{
printf( "Ntl_ManInsert(): Internal error: PO net has more than one fanin.\n" );
return 0;
}
}
return 1;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////