mirror of https://github.com/YosysHQ/abc.git
231 lines
8.1 KiB
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 ///
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|