diff options
Diffstat (limited to 'src/base/wln/wlnNdr.c')
-rw-r--r-- | src/base/wln/wlnNdr.c | 332 |
1 files changed, 332 insertions, 0 deletions
diff --git a/src/base/wln/wlnNdr.c b/src/base/wln/wlnNdr.c new file mode 100644 index 0000000..c87100a --- /dev/null +++ b/src/base/wln/wlnNdr.c @@ -0,0 +1,332 @@ +/**CFile**************************************************************** + + FileName [wlnNdr.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Word-level network.] + + Synopsis [Constructing WLN network from NDR data structure.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - September 23, 2018.] + + Revision [$Id: wlnNdr.c,v 1.00 2018/09/23 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "wln.h" +#include "aig/miniaig/ndr.h" + +ABC_NAMESPACE_IMPL_START + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void * Wln_NtkToNdr( Wln_Ntk_t * p ) +{ + Vec_Int_t * vFanins; + int i, k, iObj, iFanin; + // create a new module + void * pDesign = Ndr_Create( 1 ); + int ModId = Ndr_AddModule( pDesign, 1 ); + // add primary inputs + Wln_NtkForEachPi( p, iObj, i ) + { + Ndr_AddObject( pDesign, ModId, ABC_OPER_CI, 0, + Wln_ObjRangeEnd(p, iObj), Wln_ObjRangeBeg(p, iObj), Wln_ObjIsSigned(p, iObj), + 0, NULL, 1, &iObj, NULL ); // no fanins + } + // add internal nodes + vFanins = Vec_IntAlloc( 10 ); + Wln_NtkForEachObjInternal( p, iObj ) + { + Vec_IntClear( vFanins ); + Wln_ObjForEachFanin( p, iObj, iFanin, k ) + Vec_IntPush( vFanins, iFanin ); + Ndr_AddObject( pDesign, ModId, Wln_ObjType(p, iObj), 0, + Wln_ObjRangeEnd(p, iObj), Wln_ObjRangeBeg(p, iObj), Wln_ObjIsSigned(p, iObj), + Vec_IntSize(vFanins), Vec_IntArray(vFanins), 1, &iObj, + Wln_ObjIsConst(p, iObj) ? Wln_ObjConstString(p, iObj) : NULL ); + } + Vec_IntFree( vFanins ); + // add primary outputs + Wln_NtkForEachPo( p, iObj, i ) + { + Ndr_AddObject( pDesign, ModId, ABC_OPER_CO, 0, + Wln_ObjRangeEnd(p, iObj), Wln_ObjRangeBeg(p, iObj), Wln_ObjIsSigned(p, iObj), + 1, &iObj, 0, NULL, NULL ); + } + return pDesign; +} +void Wln_WriteNdr( Wln_Ntk_t * p, char * pFileName ) +{ + void * pDesign = Wln_NtkToNdr( p ); + Ndr_Write( pFileName, pDesign ); + Ndr_Delete( pDesign ); + printf( "Dumped the current design into file \"%s\".\n", pFileName ); +} +void Wln_NtkToNdrTest( Wln_Ntk_t * p ) +{ + // transform + void * pDesign = Wln_NtkToNdr( p ); + + // collect names + char ** ppNames = ABC_ALLOC( char *, Wln_NtkObjNum(p) + 1 ); int i; + Wln_NtkForEachObj( p, i ) + ppNames[i] = Abc_UtilStrsav(Wln_ObjName(p, i)); + + // verify by writing Verilog + Ndr_WriteVerilog( NULL, pDesign, ppNames ); + Ndr_Write( "test.ndr", pDesign ); + + // cleanup + Ndr_Delete( pDesign ); + Wln_NtkForEachObj( p, i ) + ABC_FREE( ppNames[i] ); + ABC_FREE( ppNames ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Ndr_ObjGetRange( Ndr_Data_t * p, int Obj, int * End, int * Beg ) +{ + int * pArray, nArray = Ndr_ObjReadArray( p, Obj, NDR_RANGE, &pArray ); + int Signed = 0; *End = *Beg = 0; + if ( nArray == 0 ) + return 0; + if ( nArray == 3 ) + Signed = 1; + if ( nArray == 1 ) + *End = *Beg = pArray[0]; + else + *End = pArray[0], *Beg = pArray[1]; + return Signed; +} +void Ndr_NtkPrintObjects( Wln_Ntk_t * pNtk ) +{ + int k, iObj, iFanin; + printf( "Node IDs and their fanins:\n" ); + Wln_NtkForEachObj( pNtk, iObj ) + { + printf( "%5d = ", iObj ); + Wln_ObjForEachFanin( pNtk, iObj, iFanin, k ) + printf( "%5d ", iFanin ); + for ( ; k < 4; k++ ) + printf( " " ); + printf( " Name Id %d ", Wln_ObjNameId(pNtk, iObj) ); + if ( Wln_ObjIsPi(pNtk, iObj) ) + printf( " pi " ); + if ( Wln_ObjIsPo(pNtk, iObj) ) + printf( " po " ); + printf( "\n" ); + } +} +void Wln_NtkCheckIntegrity( void * pData ) +{ + Ndr_Data_t * p = (Ndr_Data_t *)pData; + Vec_Int_t * vMap = Vec_IntAlloc( 100 ); + int Mod = 2, Obj; + Ndr_ModForEachObj( p, Mod, Obj ) + { + int NameId = Ndr_ObjReadBody( p, Obj, NDR_OUTPUT ); + if ( NameId == -1 ) + { + int Type = Ndr_ObjReadBody( p, Obj, NDR_OPERTYPE ); + if ( Type != ABC_OPER_CO ) + printf( "Internal object %d of type %s has no output name.\n", Obj, Abc_OperName(Type) ); + continue; + } + if ( Vec_IntGetEntry(vMap, NameId) > 0 ) + printf( "Output name %d is used more than once (obj %d and obj %d).\n", NameId, Vec_IntGetEntry(vMap, NameId), Obj ); + Vec_IntSetEntry( vMap, NameId, Obj ); + } + Ndr_ModForEachObj( p, Mod, Obj ) + { + int Type = Ndr_ObjReadBody( p, Obj, NDR_OPERTYPE ); + int i, * pArray, nArray = Ndr_ObjReadArray( p, Obj, NDR_INPUT, &pArray ); + for ( i = 0; i < nArray; i++ ) + if ( Vec_IntGetEntry(vMap, pArray[i]) == 0 && !(Type == ABC_OPER_DFFRSE && (i >= 5 || i <= 7)) ) + printf( "Input name %d appearing as fanin %d of obj %d is not used as output name in any object.\n", pArray[i], i, Obj ); + } + Vec_IntFree( vMap ); +} +Wln_Ntk_t * Wln_NtkFromNdr( void * pData ) +{ + Ndr_Data_t * p = (Ndr_Data_t *)pData; + Vec_Int_t * vName2Obj, * vFanins = Vec_IntAlloc( 100 ); + Vec_Ptr_t * vConstStrings = Vec_PtrAlloc( 100 ); + int Mod = 2, i, k, iFanin, iObj, Obj, * pArray, nDigits, fFound, NameId, NameIdMax; + Wln_Ntk_t * pTemp, * pNtk = Wln_NtkAlloc( "top", Ndr_DataObjNum(p, Mod) ); + Wln_NtkCheckIntegrity( pData ); + //pNtk->pSpec = Abc_UtilStrsav( pFileName ); + // construct network and save name IDs + Wln_NtkCleanNameId( pNtk ); + Wln_NtkCleanInstId( pNtk ); + Ndr_ModForEachPi( p, Mod, Obj ) + { + int End, Beg, Signed = Ndr_ObjGetRange(p, Obj, &End, &Beg); + int iObj = Wln_ObjAlloc( pNtk, ABC_OPER_CI, Signed, End, Beg ); + int NameId = Ndr_ObjReadBody( p, Obj, NDR_OUTPUT ); + int InstId = Ndr_ObjReadBody( p, Obj, NDR_NAME ); + Wln_ObjSetNameId( pNtk, iObj, NameId ); + if ( InstId > 0 ) Wln_ObjSetInstId( pNtk, iObj, InstId ); + } + Ndr_ModForEachNode( p, Mod, Obj ) + { + int End, Beg, Signed = Ndr_ObjGetRange(p, Obj, &End, &Beg); + int Type = Ndr_ObjReadBody( p, Obj, NDR_OPERTYPE ); + int nArray = Ndr_ObjReadArray( p, Obj, NDR_INPUT, &pArray ); + Vec_Int_t F = {nArray, nArray, pArray}, * vTemp = &F; + int iObj = Wln_ObjAlloc( pNtk, Type, Signed, End, Beg ); + int NameId = Ndr_ObjReadBody( p, Obj, NDR_OUTPUT ); + int InstId = Ndr_ObjReadBody( p, Obj, NDR_NAME ); + Vec_IntClear( vFanins ); + Vec_IntAppend( vFanins, vTemp ); + assert( Type != ABC_OPER_DFF ); + if ( Wln_ObjIsSlice(pNtk, iObj) ) + Wln_ObjSetSlice( pNtk, iObj, Hash_Int2ManInsert(pNtk->pRanges, End, Beg, 0) ); + else if ( Wln_ObjIsConst(pNtk, iObj) ) + Vec_PtrPush( vConstStrings, (char *)Ndr_ObjReadBodyP(p, Obj, NDR_FUNCTION) ); +// else if ( Type == ABC_OPER_BIT_MUX && Vec_IntSize(vFanins) == 3 ) +// ABC_SWAP( int, Wln_ObjFanins(pNtk, iObj)[1], Wln_ObjFanins(pNtk, iObj)[2] ); + Wln_ObjAddFanins( pNtk, iObj, vFanins ); + Wln_ObjSetNameId( pNtk, iObj, NameId ); + if ( InstId > 0 ) Wln_ObjSetInstId( pNtk, iObj, InstId ); + if ( Type == ABC_OPER_ARI_SMUL ) + { + assert( Wln_ObjFaninNum(pNtk, iObj) == 2 ); + Wln_ObjSetSigned( pNtk, Wln_ObjFanin0(pNtk, iObj) ); + Wln_ObjSetSigned( pNtk, Wln_ObjFanin1(pNtk, iObj) ); + } + } + // mark primary outputs + Ndr_ModForEachPo( p, Mod, Obj ) + { + int End, Beg, Signed = Ndr_ObjGetRange(p, Obj, &End, &Beg); + int nArray = Ndr_ObjReadArray( p, Obj, NDR_INPUT, &pArray ); + int iObj = Wln_ObjAlloc( pNtk, ABC_OPER_CO, Signed, End, Beg ); + int NameId = Ndr_ObjReadBody( p, Obj, NDR_OUTPUT ); + int InstId = Ndr_ObjReadBody( p, Obj, NDR_NAME ); + assert( nArray == 1 && NameId == -1 && InstId == -1 ); + Wln_ObjAddFanin( pNtk, iObj, pArray[0] ); + } + Vec_IntFree( vFanins ); + // remove instance names if they are not given + //Vec_IntPrint( &pNtk->vInstIds ); + if ( Vec_IntCountPositive(&pNtk->vInstIds) == 0 ) + Vec_IntErase( &pNtk->vInstIds ); + // map name IDs into object IDs + vName2Obj = Vec_IntInvert( &pNtk->vNameIds, 0 ); + Wln_NtkForEachObj( pNtk, i ) + Wln_ObjForEachFanin( pNtk, i, iFanin, k ) + Wln_ObjSetFanin( pNtk, i, k, Vec_IntEntry(vName2Obj, iFanin) ); + Vec_IntFree(vName2Obj); + // create fake object names + NameIdMax = Vec_IntFindMax(&pNtk->vNameIds); + nDigits = Abc_Base10Log( NameIdMax+1 ); + pNtk->pManName = Abc_NamStart( NameIdMax+1, 10 ); + for ( i = 1; i <= NameIdMax; i++ ) + { + char pName[20]; sprintf( pName, "s%0*d", nDigits, i ); + NameId = Abc_NamStrFindOrAdd( pNtk->pManName, pName, &fFound ); + assert( !fFound && i == NameId ); + } + // add const strings + i = 0; + Wln_NtkForEachObj( pNtk, iObj ) + if ( Wln_ObjIsConst(pNtk, iObj) ) + Wln_ObjSetConst( pNtk, iObj, Abc_NamStrFindOrAdd(pNtk->pManName, (char *)Vec_PtrEntry(vConstStrings, i++), NULL) ); + assert( i == Vec_PtrSize(vConstStrings) ); + Vec_PtrFree( vConstStrings ); + //Ndr_NtkPrintObjects( pNtk ); + //Wln_WriteVer( pNtk, "temp_ndr.v", 0, 0 ); + // derive topological order + pNtk = Wln_NtkDupDfs( pTemp = pNtk ); + Wln_NtkFree( pTemp ); + //Ndr_NtkPrintObjects( pNtk ); + //pNtk->fMemPorts = 1; // the network contains memory ports + //pNtk->fEasyFfs = 1; // the network contains simple flops + return pNtk; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Wln_Ntk_t * Wln_ReadNdr( char * pFileName ) +{ + void * pData = Ndr_Read( pFileName ); + Wln_Ntk_t * pNtk = Wln_NtkFromNdr( pData ); + //char * ppNames[10] = { NULL, "a", "b", "c", "d", "e", "f", "g", "h", "i" }; + //Ndr_WriteVerilog( NULL, pData, ppNames ); + Ndr_Delete( pData ); + return pNtk; +} +void Wln_ReadNdrTest() +{ + Wln_Ntk_t * pNtk = Wln_ReadNdr( "D:\\temp\\brijesh\\for_alan_dff_warning\\work_fir_filter_fir_filter_proc_out.ndr" ); + //Wln_Ntk_t * pNtk = Wln_ReadNdr( "flop.ndr" ); + Wln_WriteVer( pNtk, "test__test.v" ); + Wln_NtkPrint( pNtk ); + Wln_NtkStaticFanoutTest( pNtk ); + Wln_NtkFree( pNtk ); +} +void Wln_NtkRetimeTest( char * pFileName ) +{ + void * pData = Ndr_Read( pFileName ); + Wln_Ntk_t * pNtk = Wln_NtkFromNdr( pData ); + Ndr_Delete( pData ); + if ( !Wln_NtkHasInstId(pNtk) ) + printf( "The design has no delay information.\n" ); + else + { + Vec_Int_t * vMoves = Wln_NtkRetime( pNtk ); + Vec_IntPrint( vMoves ); + Vec_IntFree( vMoves ); + } + Wln_NtkFree( pNtk ); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + |