diff options
79 files changed, 10518 insertions, 911 deletions
@@ -16,7 +16,7 @@ OS := $(shell uname -s) MODULES := \ $(wildcard src/ext*) \ src/base/abc src/base/abci src/base/cmd src/base/io src/base/main src/base/exor \ - src/base/ver src/base/wlc src/base/acb src/base/bac src/base/cba src/base/pla src/base/test \ + src/base/ver src/base/wlc src/base/wln src/base/acb src/base/bac src/base/cba src/base/pla src/base/test \ src/map/mapper src/map/mio src/map/super src/map/if \ src/map/amap src/map/cov src/map/scl src/map/mpm \ src/misc/extra src/misc/mvc src/misc/st src/misc/util src/misc/nm \ @@ -119,11 +119,16 @@ GCC_MINOR=$(word 2,$(subst .,$(space),$(GCC_VERSION))) $(info $(MSG_PREFIX)Found GCC_VERSION $(GCC_VERSION)) ifeq ($(findstring $(GCC_MAJOR),0 1 2 3),) -$(info $(MSG_PREFIX)Found GCC_MAJOR>=4) +ifeq ($(GCC_MAJOR),4) +$(info $(MSG_PREFIX)Found GCC_MAJOR==4) ifeq ($(findstring $(GCC_MINOR),0 1 2 3 4 5),) $(info $(MSG_PREFIX)Found GCC_MINOR>=6) CFLAGS += -Wno-unused-but-set-variable endif +else +$(info $(MSG_PREFIX)Found GCC_MAJOR>=5) +CFLAGS += -Wno-unused-but-set-variable +endif endif endif @@ -1106,6 +1106,38 @@ SOURCE=.\src\base\acb\acbSets.h SOURCE=.\src\base\acb\acbUtil.c # End Source File # End Group +# Begin Group "wln" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\src\base\wln\wln.c +# End Source File +# Begin Source File + +SOURCE=.\src\base\wln\wln.h +# End Source File +# Begin Source File + +SOURCE=.\src\base\wln\wlnNdr.c +# End Source File +# Begin Source File + +SOURCE=.\src\base\wln\wlnNtk.c +# End Source File +# Begin Source File + +SOURCE=.\src\base\wln\wlnObj.c +# End Source File +# Begin Source File + +SOURCE=.\src\base\wln\wlnRetime.c +# End Source File +# Begin Source File + +SOURCE=.\src\base\wln\wlnWriteVer.c +# End Source File +# End Group # End Group # Begin Group "bdd" @@ -1135,10 +1167,18 @@ SOURCE=.\src\bdd\extrab\extraBddKmap.c # End Source File # Begin Source File +SOURCE=.\src\bdd\extrab\extraBddMaxMin.c +# End Source File +# Begin Source File + SOURCE=.\src\bdd\extrab\extraBddMisc.c # End Source File # Begin Source File +SOURCE=.\src\bdd\extrab\extraBddSet.c +# End Source File +# Begin Source File + SOURCE=.\src\bdd\extrab\extraBddSymm.c # End Source File # Begin Source File @@ -2919,6 +2959,10 @@ SOURCE=.\src\opt\dau\dauCore.c # End Source File # Begin Source File +SOURCE=.\src\opt\dau\dauCount.c +# End Source File +# Begin Source File + SOURCE=.\src\opt\dau\dauDivs.c # End Source File # Begin Source File @@ -2947,6 +2991,14 @@ SOURCE=.\src\opt\dau\dauNonDsd.c # End Source File # Begin Source File +SOURCE=.\src\opt\dau\dauNpn.c +# End Source File +# Begin Source File + +SOURCE=.\src\opt\dau\dauNpn2.c +# End Source File +# Begin Source File + SOURCE=.\src\opt\dau\dauTree.c # End Source File # End Group @@ -3655,6 +3707,10 @@ SOURCE=.\src\misc\extra\extraUtilFile.c # End Source File # Begin Source File +SOURCE=.\src\misc\extra\extraUtilMaj.c +# End Source File +# Begin Source File + SOURCE=.\src\misc\extra\extraUtilMemory.c # End Source File # Begin Source File @@ -3667,6 +3723,10 @@ SOURCE=.\src\misc\extra\extraUtilMult.c # End Source File # Begin Source File +SOURCE=.\src\misc\extra\extraUtilPath.c +# End Source File +# Begin Source File + SOURCE=.\src\misc\extra\extraUtilPerm.c # End Source File # Begin Source File diff --git a/src/aig/gia/giaDup.c b/src/aig/gia/giaDup.c index 01c01f39..923fbbad 100644 --- a/src/aig/gia/giaDup.c +++ b/src/aig/gia/giaDup.c @@ -2815,6 +2815,30 @@ Gia_Man_t * Gia_ManDupAndOr( Gia_Man_t * p, int nOuts, int fUseOr, int fCompl ) /**Function************************************************************* + Synopsis [Transforms output names.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Ptr_t * Gia_ManMiterNames( Vec_Ptr_t * p ) +{ + char * pName1, * pName2, pBuffer[1000]; int i; + Vec_Ptr_t * pNew = Vec_PtrAlloc( Vec_PtrSize(p)/2 ); + assert( Vec_PtrSize(p) % 2 == 0 ); + Vec_PtrForEachEntryDouble( char *, char *, p, pName1, pName2, i ) + { + sprintf( pBuffer, "%s_xor_%s", pName1, pName2 ); + Vec_PtrPush( pNew, Abc_UtilStrsav(pBuffer) ); + } + return pNew; +} + +/**Function************************************************************* + Synopsis [Transforms the circuit into a regular miter.] Description [] @@ -2851,6 +2875,10 @@ Gia_Man_t * Gia_ManTransformMiter( Gia_Man_t * p ) Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) ); pNew = Gia_ManCleanup( pTemp = pNew ); Gia_ManStop( pTemp ); + if ( p->vNamesIn ) + pNew->vNamesIn = Vec_PtrDupStr(p->vNamesIn); + if ( p->vNamesOut ) + pNew->vNamesOut = Gia_ManMiterNames(p->vNamesOut); return pNew; } Gia_Man_t * Gia_ManTransformMiter2( Gia_Man_t * p ) diff --git a/src/aig/gia/giaLf.c b/src/aig/gia/giaLf.c index 45a22db0..b1a82346 100644 --- a/src/aig/gia/giaLf.c +++ b/src/aig/gia/giaLf.c @@ -1542,7 +1542,7 @@ int Lf_ManSetMapRefs( Lf_Man_t * p ) } if ( p->pGia->pManTime != NULL ) { - assert( Gia_ManBufNum(p->pGia) ); + assert( !Gia_ManBufNum(p->pGia) ); Tim_ManIncrementTravId( (Tim_Man_t*)p->pGia->pManTime ); if ( p->pPars->fDoAverage ) for ( i = 0; i < Gia_ManCoNum(p->pGia); i++ ) diff --git a/src/aig/gia/giaMfs.c b/src/aig/gia/giaMfs.c index 23038eff..da48570b 100644 --- a/src/aig/gia/giaMfs.c +++ b/src/aig/gia/giaMfs.c @@ -354,7 +354,8 @@ Gia_Man_t * Gia_ManInsertMfs( Gia_Man_t * p, Sfm_Ntk_t * pNtk, int fAllBoxes ) if ( Gia_ObjLutIsMux(p, Vec_IntEntry(vMfs2Old, iMfsId)) ) { int MapSize = Vec_IntSize(vMapping2); - int nVarsNew, Res = Abc_TtSimplify( pTruth, Vec_IntArray(vLeaves), Vec_IntSize(vLeaves), &nVarsNew ); + int nVarsNew; + Abc_TtSimplify( pTruth, Vec_IntArray(vLeaves), Vec_IntSize(vLeaves), &nVarsNew ); Vec_IntShrink( vLeaves, nVarsNew ); iLitNew = Gia_ManFromIfLogicCreateLut( pNew, pTruth, vLeaves, vCover, vMapping, vMapping2 ); if ( MapSize < Vec_IntSize(vMapping2) ) diff --git a/src/aig/gia/giaMini.c b/src/aig/gia/giaMini.c index 41c6a702..0ba2c4f1 100644 --- a/src/aig/gia/giaMini.c +++ b/src/aig/gia/giaMini.c @@ -589,6 +589,74 @@ int * Abc_FrameReadMiniLutNameMapping( Abc_Frame_t * pAbc ) return pRes; } +/**Function************************************************************* + + Synopsis [Returns equivalences of MiniAig nodes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Gia_ManMapEquivAfterScorr( Gia_Man_t * p, Vec_Int_t * vMap ) +{ + Vec_Int_t * vRes = Vec_IntStartFull( Vec_IntSize(vMap) ); + Vec_Int_t * vGia2Mini = Vec_IntStartFull( Gia_ManObjNum(p) ); + Gia_Obj_t * pObj, * pRepr; + int i, iObjLit, iReprLit, fCompl, iReprGia, iReprMini; + Vec_IntForEachEntry( vMap, iObjLit, i ) + { + if ( iObjLit == -1 ) + continue; + iReprGia = Gia_ObjReprSelf( p, Abc_Lit2Var(iObjLit) ); + iReprMini = Vec_IntEntry( vGia2Mini, iReprGia ); + if ( iReprMini == -1 ) + { + Vec_IntWriteEntry( vGia2Mini, iReprGia, i ); + continue; + } + if ( iReprMini == i ) + continue; + assert( iReprMini < i ); + Vec_IntWriteEntry( vRes, i, iReprMini ); + } + Vec_IntFree( vGia2Mini ); + Gia_ManSetPhase( p ); + Vec_IntForEachEntry( vRes, iReprMini, i ) + { + if ( iReprMini == -1 ) + continue; + iObjLit = Vec_IntEntry(vMap, i); + iReprLit = Vec_IntEntry(vMap, iReprMini); + pObj = Gia_ManObj( p, Abc_Lit2Var(iObjLit) ); + pRepr = Gia_ManObj( p, Abc_Lit2Var(iReprLit) ); + fCompl = Abc_LitIsCompl(iObjLit) ^ Abc_LitIsCompl(iReprLit) ^ pObj->fPhase ^ pRepr->fPhase; + Vec_IntWriteEntry( vRes, i, Abc_Var2Lit(iReprMini, fCompl) ); + } + return vRes; +} +int * Abc_FrameReadMiniAigEquivClasses( Abc_Frame_t * pAbc ) +{ + Vec_Int_t * vRes; + int * pRes; + if ( pAbc->pGiaMiniAig == NULL ) + printf( "GIA derived from MiniAig is not available.\n" ); + if ( pAbc->vCopyMiniAig == NULL ) + printf( "Mapping of MiniAig nodes is not available.\n" ); + if ( pAbc->pGia2 == NULL ) + printf( "Internal GIA with equivalence classes is not available.\n" ); + if ( pAbc->pGia2->pReprs == NULL ) + printf( "Equivalence classes of internal GIA are not available.\n" ); + if ( Gia_ManObjNum(pAbc->pGia2) != Gia_ManObjNum(pAbc->pGiaMiniAig) ) + printf( "Internal GIA with equivalence classes is not directly derived from MiniAig.\n" ); + // derive the set of equivalent node pairs + vRes = Gia_ManMapEquivAfterScorr( pAbc->pGia2, pAbc->vCopyMiniAig ); + pRes = Vec_IntReleaseArray( vRes ); + Vec_IntFree( vRes ); + return pRes; +} //////////////////////////////////////////////////////////////////////// /// END OF FILE /// diff --git a/src/aig/gia/giaNf.c b/src/aig/gia/giaNf.c index 9a374dda..eaaf24e9 100644 --- a/src/aig/gia/giaNf.c +++ b/src/aig/gia/giaNf.c @@ -2407,11 +2407,13 @@ Gia_Man_t * Nf_ManPerformMapping( Gia_Man_t * pGia, Jf_Par_t * pPars ) } Nf_ManFixPoDrivers( p ); pNew = Nf_ManDeriveMapping( p ); +/* if ( pPars->fAreaOnly ) { int Sbm_ManTestSat( void * pMan ); Sbm_ManTestSat( p ); } +*/ Nf_StoDelete( p ); return pNew; } diff --git a/src/aig/miniaig/abcOper.h b/src/aig/miniaig/abcOper.h index 5719d883..6ee043af 100644 --- a/src/aig/miniaig/abcOper.h +++ b/src/aig/miniaig/abcOper.h @@ -60,7 +60,7 @@ typedef enum { ABC_OPER_BIT_NXOR, // 18 ABC_OPER_BIT_SHARP, // 19 ABC_OPER_BIT_SHARPL, // 20 - ABC_OPER_BIT_MUX, // 21 + ABC_OPER_BIT_MUX, // 21 fanins are: {Ctrl, Data1, Data0} ABC_OPER_BIT_MAJ, // 22 ABC_OPER_ABC, // 23 @@ -86,7 +86,7 @@ typedef enum { ABC_OPER_LOGIC_XOR, // 41 ABC_OPER_LOGIC_XNOR, // 42 - ABC_OPER_SEL_NMUX, // 43 + ABC_OPER_SEL_NMUX, // 43 fanins are: {Ctrl, Data0, Data1, Data2, ...} ABC_OPER_SEL_SEL, // 44 ABC_OPER_SEL_PSEL, // 45 ABC_OPER_SEL_ENC, // 46 @@ -217,11 +217,14 @@ static inline char * Abc_OperName( int Type ) if ( Type == ABC_OPER_SHIFT_ROTL ) return "rotL"; if ( Type == ABC_OPER_SHIFT_ROTR ) return "rotR"; + if ( Type == ABC_OPER_DFFRSE ) return "DFFRSE"; + if ( Type == ABC_OPER_SLICE ) return "[:]"; if ( Type == ABC_OPER_CONCAT ) return "{}"; if ( Type == ABC_OPER_ZEROPAD ) return "zPad"; if ( Type == ABC_OPER_SIGNEXT ) return "sExt"; + if ( Type == ABC_OPER_CONST ) return "const"; if ( Type == ABC_OPER_TABLE ) return "table"; if ( Type == ABC_OPER_LAST ) return NULL; assert( 0 ); diff --git a/src/aig/miniaig/ndr.h b/src/aig/miniaig/ndr.h index a1f657ba..b33d9c6d 100644 --- a/src/aig/miniaig/ndr.h +++ b/src/aig/miniaig/ndr.h @@ -207,9 +207,15 @@ static inline void Ndr_DataPushArray( Ndr_Data_t * p, int Type, int nArray, int } static inline void Ndr_DataPushString( Ndr_Data_t * p, int Type, char * pFunc ) { + int nBuffInts; + int * pBuff; if ( !pFunc ) return; - Ndr_DataPushArray( p, Type, ((int)strlen(pFunc) + 4) / 4, (int *)pFunc ); + nBuffInts = ((int)strlen(pFunc) + 4) / 4; + pBuff = (int *)calloc( 1, 4*nBuffInts ); + memcpy( pBuff, pFunc, strlen(pFunc) ); + Ndr_DataPushArray( p, Type, nBuffInts, pBuff ); + free( pBuff ); } //////////////////////////////////////////////////////////////////////// @@ -972,7 +978,7 @@ static inline void Ndr_ModuleTestFlop() static inline void Ndr_ModuleTestSelSel() { // map name IDs into char strings - char * ppNames[12] = { NULL, "sel", "c", "d0", "d1", "d2", "d3", "out" }; + //char * ppNames[12] = { NULL, "sel", "c", "d0", "d1", "d2", "d3", "out" }; // name IDs int NameIdC = 2; int NameIdD0 = 3; @@ -1005,6 +1011,74 @@ static inline void Ndr_ModuleTestSelSel() Ndr_Delete( pDesign ); } +// This testing procedure creates and writes into a Verilog file +// the following design composed of one decoder + +// module dec ( input [1:0] in, output [3:0] out ); +// wire out0 = ~in[1] & ~in[0] ; +// wire out1 = ~in[1] & in[0] ; +// wire out2 = in[1] & ~in[0] ; +// wire out3 = in[1] & in[0] ; +// assign out = { out3, out2, out1, out0 } ; +// endmodule + +static inline void Ndr_ModuleTestDec() +{ + // map name IDs into char strings + //char * ppNames[12] = { NULL, "dec", "in", "out" }; + // name IDs + int NameIdIn = 2; + int NameIdOut = 3; + + // create a new module + void * pDesign = Ndr_Create( 1 ); + + int ModuleID = Ndr_AddModule( pDesign, 1 ); + + // add objects to the modele + Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CI, 0, 1, 0, 0, 0, NULL, 1, &NameIdIn, NULL ); + Ndr_AddObject( pDesign, ModuleID, ABC_OPER_SEL_DEC, 0, 3, 0, 0, 1, &NameIdIn, 1, &NameIdOut, NULL ); + Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CO, 0, 3, 0, 0, 1, &NameIdOut, 0, NULL, NULL ); + + Ndr_Write( "dec.ndr", pDesign ); + Ndr_Delete( pDesign ); +} + +// This testing procedure creates and writes into a Verilog file +// the following design composed of one adder/subtractor + +// module addsub ( input mode, input cin, input [2:0] a, input [2:0] b, output [3:0] out ); +// assign out = mode ? a+b+cin : a-b-cin ; +// endmodule + +static inline void Ndr_ModuleTestAddSub() +{ + // map name IDs into char strings + //char * ppNames[12] = { NULL, "addsub", "mode", "cin", "a", "b", "out" }; + // name IDs + int NameIdInMode = 2; + int NameIdInCin = 3; + int NameIdInA = 4; + int NameIdInB = 5; + int NameIdOut = 6; + int Fanins[8] = { 2, 3, 4, 5 }; + + // create a new module + void * pDesign = Ndr_Create( 1 ); + + int ModuleID = Ndr_AddModule( pDesign, 1 ); + + // add objects to the modele + Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CI, 0, 0, 0, 0, 0, NULL, 1, &NameIdInMode, NULL ); + Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CI, 0, 0, 0, 0, 0, NULL, 1, &NameIdInCin, NULL ); + Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CI, 0, 2, 0, 0, 0, NULL, 1, &NameIdInA, NULL ); + Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CI, 0, 2, 0, 0, 0, NULL, 1, &NameIdInB, NULL ); + Ndr_AddObject( pDesign, ModuleID, ABC_OPER_ARI_ADDSUB, 0, 3, 0, 0, 4, Fanins, 1, &NameIdOut, NULL ); + Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CO, 0, 3, 0, 0, 1, &NameIdOut, 0, NULL, NULL ); + + Ndr_Write( "addsub.ndr", pDesign ); + Ndr_Delete( pDesign ); +} ABC_NAMESPACE_HEADER_END diff --git a/src/base/abc/abc.h b/src/base/abc/abc.h index 8ac5040d..dd189c6d 100644 --- a/src/base/abc/abc.h +++ b/src/base/abc/abc.h @@ -600,7 +600,7 @@ extern ABC_DLL int Abc_NtkCheckUniqueCiNames( Abc_Ntk_t * pNtk ); extern ABC_DLL int Abc_NtkCheckUniqueCoNames( Abc_Ntk_t * pNtk ); extern ABC_DLL int Abc_NtkCheckUniqueCioNames( Abc_Ntk_t * pNtk ); /*=== abcCollapse.c ==========================================================*/ -extern ABC_DLL Abc_Ntk_t * Abc_NtkCollapse( Abc_Ntk_t * pNtk, int fBddSizeMax, int fDualRail, int fReorder, int fVerbose ); +extern ABC_DLL Abc_Ntk_t * Abc_NtkCollapse( Abc_Ntk_t * pNtk, int fBddSizeMax, int fDualRail, int fReorder, int fReverse, int fVerbose ); extern ABC_DLL Abc_Ntk_t * Abc_NtkCollapseSat( Abc_Ntk_t * pNtk, int nCubeLim, int nBTLimit, int nCostMax, int fCanon, int fReverse, int fCnfShared, int fVerbose ); extern ABC_DLL Gia_Man_t * Abc_NtkClpGia( Abc_Ntk_t * pNtk ); /*=== abcCut.c ==========================================================*/ @@ -657,6 +657,7 @@ extern ABC_DLL void Abc_ObjPatchFanoutFanin( Abc_Obj_t * pObj, int extern ABC_DLL Abc_Obj_t * Abc_ObjInsertBetween( Abc_Obj_t * pNodeIn, Abc_Obj_t * pNodeOut, Abc_ObjType_t Type ); extern ABC_DLL void Abc_ObjTransferFanout( Abc_Obj_t * pObjOld, Abc_Obj_t * pObjNew ); extern ABC_DLL void Abc_ObjReplace( Abc_Obj_t * pObjOld, Abc_Obj_t * pObjNew ); +extern ABC_DLL void Abc_ObjReplaceByConstant( Abc_Obj_t * pNode, int fConst1 ); extern ABC_DLL int Abc_ObjFanoutFaninNum( Abc_Obj_t * pFanout, Abc_Obj_t * pFanin ); /*=== abcFanOrder.c ==========================================================*/ extern ABC_DLL int Abc_NtkMakeLegit( Abc_Ntk_t * pNtk ); @@ -761,7 +762,7 @@ extern ABC_DLL Abc_Ntk_t * Abc_NtkToNetlistBench( Abc_Ntk_t * pNtk ); /*=== abcNtbdd.c ==========================================================*/ extern ABC_DLL Abc_Ntk_t * Abc_NtkDeriveFromBdd( void * dd, void * bFunc, char * pNamePo, Vec_Ptr_t * vNamesPi ); extern ABC_DLL Abc_Ntk_t * Abc_NtkBddToMuxes( Abc_Ntk_t * pNtk ); -extern ABC_DLL void * Abc_NtkBuildGlobalBdds( Abc_Ntk_t * pNtk, int fBddSizeMax, int fDropInternal, int fReorder, int fVerbose ); +extern ABC_DLL void * Abc_NtkBuildGlobalBdds( Abc_Ntk_t * pNtk, int fBddSizeMax, int fDropInternal, int fReorder, int fReverse, int fVerbose ); extern ABC_DLL void * Abc_NtkFreeGlobalBdds( Abc_Ntk_t * pNtk, int fFreeMan ); extern ABC_DLL int Abc_NtkSizeOfGlobalBdds( Abc_Ntk_t * pNtk ); /*=== abcNtk.c ==========================================================*/ diff --git a/src/base/abc/abcFanio.c b/src/base/abc/abcFanio.c index caa57a4e..519debb1 100644 --- a/src/base/abc/abcFanio.c +++ b/src/base/abc/abcFanio.c @@ -337,6 +337,30 @@ void Abc_ObjReplace( Abc_Obj_t * pNodeOld, Abc_Obj_t * pNodeNew ) /**Function************************************************************* + Synopsis [Replaces a node by a constant.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_ObjReplaceByConstant( Abc_Obj_t * pNode, int fConst1 ) +{ + Abc_Obj_t * pNodeNew; + assert( Abc_NtkIsLogic(pNode->pNtk) ); + assert( !Abc_ObjIsCo(pNode) ); + pNodeNew = fConst1 ? Abc_NtkCreateNodeConst1(pNode->pNtk) : Abc_NtkCreateNodeConst0(pNode->pNtk); + // transfer the fanouts to the old node + Abc_ObjTransferFanout( pNode, pNodeNew ); + // remove the old node + if ( Abc_ObjIsNode(pNode) ) + Abc_NtkDeleteObj_rec( pNode, 1 ); +} + +/**Function************************************************************* + Synopsis [Returns the index of the fanin in the fanin list of the fanout.] Description [] diff --git a/src/base/abc/abcShow.c b/src/base/abc/abcShow.c index 13dd9346..f91397df 100644 --- a/src/base/abc/abcShow.c +++ b/src/base/abc/abcShow.c @@ -85,12 +85,13 @@ void Abc_NodeShowBddOne( DdManager * dd, DdNode * bFunc ) SeeAlso [] ***********************************************************************/ -void Abc_NodeShowBdd( Abc_Obj_t * pNode ) +void Abc_NodeShowBdd( Abc_Obj_t * pNode, int fCompl ) { FILE * pFile; Vec_Ptr_t * vNamesIn; char FileNameDot[200]; char * pNameOut; + DdManager * dd = (DdManager *)pNode->pNtk->pManFunc; assert( Abc_NtkIsBddLogic(pNode->pNtk) ); // create the file name @@ -105,7 +106,14 @@ void Abc_NodeShowBdd( Abc_Obj_t * pNode ) // set the node names vNamesIn = Abc_NodeGetFaninNames( pNode ); pNameOut = Abc_ObjName(pNode); - Cudd_DumpDot( (DdManager *)pNode->pNtk->pManFunc, 1, (DdNode **)&pNode->pData, (char **)vNamesIn->pArray, &pNameOut, pFile ); + if ( fCompl ) + Cudd_DumpDot( dd, 1, (DdNode **)&pNode->pData, (char **)vNamesIn->pArray, &pNameOut, pFile ); + else + { + DdNode * bAdd = Cudd_BddToAdd( dd, (DdNode *)pNode->pData ); Cudd_Ref( bAdd ); + Cudd_DumpDot( dd, 1, (DdNode **)&bAdd, (char **)vNamesIn->pArray, &pNameOut, pFile ); + Cudd_RecursiveDeref( dd, bAdd ); + } Abc_NodeFreeNames( vNamesIn ); Abc_NtkCleanCopy( pNode->pNtk ); fclose( pFile ); @@ -113,9 +121,72 @@ void Abc_NodeShowBdd( Abc_Obj_t * pNode ) // visualize the file Abc_ShowFile( FileNameDot ); } +void Abc_NtkShowBdd( Abc_Ntk_t * pNtk, int fCompl ) +{ + char FileNameDot[200]; + char ** ppNamesIn, ** ppNamesOut; + DdManager * dd; DdNode * bFunc; + Vec_Ptr_t * vFuncsGlob; + Abc_Obj_t * pObj; int i; + FILE * pFile; + + assert( Abc_NtkIsStrash(pNtk) ); + dd = (DdManager *)Abc_NtkBuildGlobalBdds( pNtk, 10000000, 1, 1, 0, 0 ); + if ( dd == NULL ) + { + printf( "Construction of global BDDs has failed.\n" ); + return; + } + //printf( "Shared BDD size = %6d nodes.\n", Cudd_ReadKeys(dd) - Cudd_ReadDead(dd) ); + + // complement the global functions + vFuncsGlob = Vec_PtrAlloc( Abc_NtkCoNum(pNtk) ); + Abc_NtkForEachCo( pNtk, pObj, i ) + Vec_PtrPush( vFuncsGlob, Abc_ObjGlobalBdd(pObj) ); + + // create the file name + Abc_ShowGetFileName( pNtk->pName, FileNameDot ); + // check that the file can be opened + if ( (pFile = fopen( FileNameDot, "w" )) == NULL ) + { + fprintf( stdout, "Cannot open the intermediate file \"%s\".\n", FileNameDot ); + return; + } + + // set the node names + ppNamesIn = Abc_NtkCollectCioNames( pNtk, 0 ); + ppNamesOut = Abc_NtkCollectCioNames( pNtk, 1 ); + if ( fCompl ) + Cudd_DumpDot( dd, Abc_NtkCoNum(pNtk), (DdNode **)Vec_PtrArray(vFuncsGlob), ppNamesIn, ppNamesOut, pFile ); + else + { + DdNode ** pbAdds = ABC_ALLOC( DdNode *, Vec_PtrSize(vFuncsGlob) ); + Vec_PtrForEachEntry( DdNode *, vFuncsGlob, bFunc, i ) + { pbAdds[i] = Cudd_BddToAdd( dd, bFunc ); Cudd_Ref( pbAdds[i] ); } + Cudd_DumpDot( dd, Abc_NtkCoNum(pNtk), pbAdds, ppNamesIn, ppNamesOut, pFile ); + Vec_PtrForEachEntry( DdNode *, vFuncsGlob, bFunc, i ) + Cudd_RecursiveDeref( dd, pbAdds[i] ); + ABC_FREE( pbAdds ); + } + ABC_FREE( ppNamesIn ); + ABC_FREE( ppNamesOut ); + fclose( pFile ); + + // cleanup + Abc_NtkFreeGlobalBdds( pNtk, 0 ); + Vec_PtrForEachEntry( DdNode *, vFuncsGlob, bFunc, i ) + Cudd_RecursiveDeref( dd, bFunc ); + Vec_PtrFree( vFuncsGlob ); + Extra_StopManager( dd ); + Abc_NtkCleanCopy( pNtk ); + + // visualize the file + Abc_ShowFile( FileNameDot ); +} #else -void Abc_NodeShowBdd( Abc_Obj_t * pNode ) {} +void Abc_NodeShowBdd( Abc_Obj_t * pNode, int fCompl ) {} +void Abc_NtkShowBdd( Abc_Ntk_t * pNtk, int fCompl ) {} #endif /**Function************************************************************* diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 0e527058..181ca54a 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -86,6 +86,7 @@ static int Abc_CommandPrintMffc ( Abc_Frame_t * pAbc, int argc, cha static int Abc_CommandPrintFactor ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandPrintLevel ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandPrintSupport ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandPrintMint ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandPrintSymms ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandPrintUnate ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandPrintAuto ( Abc_Frame_t * pAbc, int argc, char ** argv ); @@ -154,6 +155,7 @@ static int Abc_CommandTwoExact ( Abc_Frame_t * pAbc, int argc, cha static int Abc_CommandLutExact ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAllExact ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandTestExact ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandMajGen ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandLogic ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandComb ( Abc_Frame_t * pAbc, int argc, char ** argv ); @@ -184,6 +186,7 @@ static int Abc_CommandExtSeqDcs ( Abc_Frame_t * pAbc, int argc, cha static int Abc_CommandReach ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandCone ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandNode ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandCof ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandTopmost ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandTopAnd ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandTrim ( Abc_Frame_t * pAbc, int argc, char ** argv ); @@ -314,6 +317,8 @@ static int Abc_CommandInsWin ( Abc_Frame_t * pAbc, int argc, cha static int Abc_CommandPermute ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandUnpermute ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandCubeEnum ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandPathEnum ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandFunEnum ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandCec ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandDCec ( Abc_Frame_t * pAbc, int argc, char ** argv ); @@ -775,6 +780,7 @@ void Abc_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "Printing", "print_factor", Abc_CommandPrintFactor, 0 ); Cmd_CommandAdd( pAbc, "Printing", "print_level", Abc_CommandPrintLevel, 0 ); Cmd_CommandAdd( pAbc, "Printing", "print_supp", Abc_CommandPrintSupport, 0 ); + Cmd_CommandAdd( pAbc, "Printing", "print_mint", Abc_CommandPrintMint, 0 ); Cmd_CommandAdd( pAbc, "Printing", "print_symm", Abc_CommandPrintSymms, 0 ); Cmd_CommandAdd( pAbc, "Printing", "print_unate", Abc_CommandPrintUnate, 0 ); Cmd_CommandAdd( pAbc, "Printing", "print_auto", Abc_CommandPrintAuto, 0 ); @@ -844,6 +850,7 @@ void Abc_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "Exact synthesis", "lutexact", Abc_CommandLutExact, 0 ); Cmd_CommandAdd( pAbc, "Exact synthesis", "allexact", Abc_CommandAllExact, 0 ); Cmd_CommandAdd( pAbc, "Exact synthesis", "testexact", Abc_CommandTestExact, 0 ); + Cmd_CommandAdd( pAbc, "Exact synthesis", "majgen", Abc_CommandMajGen, 0 ); Cmd_CommandAdd( pAbc, "Various", "logic", Abc_CommandLogic, 1 ); Cmd_CommandAdd( pAbc, "Various", "comb", Abc_CommandComb, 1 ); @@ -874,8 +881,9 @@ void Abc_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "Various", "reach", Abc_CommandReach, 0 ); Cmd_CommandAdd( pAbc, "Various", "cone", Abc_CommandCone, 1 ); Cmd_CommandAdd( pAbc, "Various", "node", Abc_CommandNode, 1 ); + Cmd_CommandAdd( pAbc, "Various", "cof", Abc_CommandCof, 1 ); Cmd_CommandAdd( pAbc, "Various", "topmost", Abc_CommandTopmost, 1 ); - Cmd_CommandAdd( pAbc, "Various", "topand", Abc_CommandTopAnd, 1 ); + Cmd_CommandAdd( pAbc, "Various", "topand", Abc_CommandTopAnd, 1 ); Cmd_CommandAdd( pAbc, "Various", "trim", Abc_CommandTrim, 1 ); Cmd_CommandAdd( pAbc, "Various", "short_names", Abc_CommandShortNames, 0 ); Cmd_CommandAdd( pAbc, "Various", "move_names", Abc_CommandMoveNames, 0 ); @@ -999,6 +1007,8 @@ void Abc_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "Sequential", "permute", Abc_CommandPermute, 1 ); Cmd_CommandAdd( pAbc, "Sequential", "unpermute", Abc_CommandUnpermute, 1 ); Cmd_CommandAdd( pAbc, "Sequential", "cubeenum", Abc_CommandCubeEnum, 0 ); + Cmd_CommandAdd( pAbc, "Sequential", "pathenum", Abc_CommandPathEnum, 0 ); + Cmd_CommandAdd( pAbc, "Sequential", "funenum", Abc_CommandFunEnum, 0 ); Cmd_CommandAdd( pAbc, "Verification", "cec", Abc_CommandCec, 0 ); Cmd_CommandAdd( pAbc, "Verification", "dcec", Abc_CommandDCec, 0 ); @@ -2013,6 +2023,68 @@ usage: SeeAlso [] ***********************************************************************/ +int Abc_CommandPrintMint( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc); + Abc_Obj_t * pObj; + int c; + int fVerbose; + + // set defaults + fVerbose = 0; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "svwh" ) ) != EOF ) + { + switch ( c ) + { + case 'v': + fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + if ( pNtk == NULL ) + { + Abc_Print( -1, "Empty network.\n" ); + return 1; + } + if ( Abc_NtkIsStrash(pNtk) ) + { + Abc_Print( -1, "This command works only for logic networks (run \"clp\").\n" ); + return 1; + } + if ( !Abc_NtkHasBdd(pNtk) ) + { + Abc_Print( -1, "This command works only for logic networks with local functions represented by BDDs.\n" ); + return 1; + } + Abc_NtkForEachNode( pNtk, pObj, c ) + printf( "ObjId %3d : SuppSize = %5d MintCount = %32.0f\n", c, Abc_ObjFaninNum(pObj), + Cudd_CountMinterm((DdManager *)pNtk->pManFunc, (DdNode *)pObj->pData, Abc_ObjFaninNum(pObj)) ); + return 0; + +usage: + Abc_Print( -2, "usage: print_mint [-svwh]\n" ); + Abc_Print( -2, "\t prints the number of on-set minterms in the PO functions\n" ); + Abc_Print( -2, "\t-v : enable verbose output [default = %s].\n", fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-h : print the command usage\n"); + return 1; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ int Abc_CommandPrintSymms( Abc_Frame_t * pAbc, int argc, char ** argv ) { Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc); @@ -2991,15 +3063,22 @@ int Abc_CommandShowBdd( Abc_Frame_t * pAbc, int argc, char ** argv ) { Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc); Abc_Obj_t * pNode; - int c; - extern void Abc_NodeShowBdd( Abc_Obj_t * pNode ); + int c, fCompl = 0, fGlobal = 0; + extern void Abc_NodeShowBdd( Abc_Obj_t * pNode, int fCompl ); + extern void Abc_NtkShowBdd( Abc_Ntk_t * pNtk, int fCompl ); // set defaults Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "h" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "cgh" ) ) != EOF ) { switch ( c ) { + case 'c': + fCompl ^= 1; + break; + case 'g': + fGlobal ^= 1; + break; case 'h': goto usage; default: @@ -3013,12 +3092,20 @@ int Abc_CommandShowBdd( Abc_Frame_t * pAbc, int argc, char ** argv ) return 1; } + if ( fGlobal ) + { + Abc_Ntk_t * pTemp = Abc_NtkIsStrash(pNtk) ? pNtk : Abc_NtkStrash(pNtk, 0, 0, 0); + Abc_NtkShowBdd( pTemp, fCompl ); + if ( pTemp != pNtk ) + Abc_NtkDelete( pTemp ); + return 0; + } + if ( !Abc_NtkIsBddLogic(pNtk) ) { Abc_Print( -1, "Visualizing BDDs can only be done for logic BDD networks (run \"bdd\").\n" ); return 1; } - if ( argc > globalUtilOptind + 1 ) { Abc_Print( -1, "Wrong number of auguments.\n" ); @@ -3042,17 +3129,20 @@ int Abc_CommandShowBdd( Abc_Frame_t * pAbc, int argc, char ** argv ) return 1; } } - Abc_NodeShowBdd( pNode ); + Abc_NodeShowBdd( pNode, fCompl ); return 0; usage: - Abc_Print( -2, "usage: show_bdd [-h] <node>\n" ); - Abc_Print( -2, " visualizes the BDD of a node using DOT and GSVIEW\n" ); + Abc_Print( -2, "usage: show_bdd [-cgh] <node>\n" ); + Abc_Print( -2, " uses DOT and GSVIEW to visualize the global BDDs of primary outputs\n" ); + Abc_Print( -2, " in terms of primary inputs or the local BDD of a node in terms of its fanins\n" ); #ifdef WIN32 Abc_Print( -2, " \"dot.exe\" and \"gsview32.exe\" should be set in the paths\n" ); Abc_Print( -2, " (\"gsview32.exe\" may be in \"C:\\Program Files\\Ghostgum\\gsview\\\")\n" ); #endif - Abc_Print( -2, "\t<node>: the node to consider [default = the driver of the first PO]\n"); + Abc_Print( -2, "\t<node>: (optional) the node to consider [default = the driver of the first PO]\n"); + Abc_Print( -2, "\t-c : toggle visualizing BDD with complemented edges [default = %s].\n", fCompl? "yes": "no" ); + Abc_Print( -2, "\t-g : toggle visualizing the global BDDs of primary outputs [default = %s].\n", fGlobal? "yes": "no" ); Abc_Print( -2, "\t-h : print the command usage\n"); return 1; } @@ -3173,16 +3263,18 @@ int Abc_CommandCollapse( Abc_Frame_t * pAbc, int argc, char ** argv ) int fBddSizeMax; int fDualRail; int fReorder; + int fReverse; int c; pNtk = Abc_FrameReadNtk(pAbc); // set defaults fVerbose = 0; fReorder = 1; + fReverse = 0; fDualRail = 0; fBddSizeMax = ABC_INFINITY; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "Brdvh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "Brodvh" ) ) != EOF ) { switch ( c ) { @@ -3197,15 +3289,18 @@ int Abc_CommandCollapse( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( fBddSizeMax < 0 ) goto usage; break; + case 'r': + fReorder ^= 1; + break; + case 'o': + fReverse ^= 1; + break; case 'd': fDualRail ^= 1; break; case 'v': fVerbose ^= 1; break; - case 'r': - fReorder ^= 1; - break; case 'h': goto usage; default: @@ -3227,11 +3322,11 @@ int Abc_CommandCollapse( Abc_Frame_t * pAbc, int argc, char ** argv ) // get the new network if ( Abc_NtkIsStrash(pNtk) ) - pNtkRes = Abc_NtkCollapse( pNtk, fBddSizeMax, fDualRail, fReorder, fVerbose ); + pNtkRes = Abc_NtkCollapse( pNtk, fBddSizeMax, fDualRail, fReorder, fReverse, fVerbose ); else { pNtk = Abc_NtkStrash( pNtk, 0, 0, 0 ); - pNtkRes = Abc_NtkCollapse( pNtk, fBddSizeMax, fDualRail, fReorder, fVerbose ); + pNtkRes = Abc_NtkCollapse( pNtk, fBddSizeMax, fDualRail, fReorder, fReverse, fVerbose ); Abc_NtkDelete( pNtk ); } if ( pNtkRes == NULL ) @@ -3244,10 +3339,11 @@ int Abc_CommandCollapse( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; usage: - Abc_Print( -2, "usage: collapse [-B <num>] [-rdvh]\n" ); + Abc_Print( -2, "usage: collapse [-B <num>] [-rodvh]\n" ); Abc_Print( -2, "\t collapses the network by constructing global BDDs\n" ); Abc_Print( -2, "\t-B <num>: limit on live BDD nodes during collapsing [default = %d]\n", fBddSizeMax ); Abc_Print( -2, "\t-r : toggles dynamic variable reordering [default = %s]\n", fReorder? "yes": "no" ); + Abc_Print( -2, "\t-o : toggles reverse variable ordering [default = %s]\n", fReverse? "yes": "no" ); Abc_Print( -2, "\t-d : toggles dual-rail collapsing mode [default = %s]\n", fDualRail? "yes": "no" ); Abc_Print( -2, "\t-v : print verbose information [default = %s]\n", fVerbose? "yes": "no" ); Abc_Print( -2, "\t-h : print the command usage\n"); @@ -8217,7 +8313,7 @@ int Abc_CommandTwoExact( Abc_Frame_t * pAbc, int argc, char ** argv ) Bmc_EsPar_t Pars, * pPars = &Pars; Bmc_EsParSetDefault( pPars ); Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "INaogvh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "INTaogvh" ) ) != EOF ) { switch ( c ) { @@ -8243,6 +8339,17 @@ int Abc_CommandTwoExact( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( pPars->nNodes < 0 ) goto usage; break; + case 'T': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-T\" should be followed by an integer.\n" ); + goto usage; + } + pPars->RuntimeLim = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->RuntimeLim < 0 ) + goto usage; + break; case 'a': pPars->fOnlyAnd ^= 1; break; @@ -8290,10 +8397,11 @@ int Abc_CommandTwoExact( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; usage: - Abc_Print( -2, "usage: twoexact [-IN <num>] [-aogvh] <hex>\n" ); + Abc_Print( -2, "usage: twoexact [-INT <num>] [-aogvh] <hex>\n" ); Abc_Print( -2, "\t exact synthesis of multi-input function using two-input gates\n" ); Abc_Print( -2, "\t-I <num> : the number of input variables [default = %d]\n", pPars->nVars ); - Abc_Print( -2, "\t-N <num> : the number of MAJ3 nodes [default = %d]\n", pPars->nNodes ); + Abc_Print( -2, "\t-N <num> : the number of two-input nodes [default = %d]\n", pPars->nNodes ); + Abc_Print( -2, "\t-T <num> : the runtime limit in seconds [default = %d]\n", pPars->RuntimeLim ); Abc_Print( -2, "\t-a : toggle using only AND-gates (without XOR-gates) [default = %s]\n", pPars->fOnlyAnd ? "yes" : "no" ); Abc_Print( -2, "\t-o : toggle using additional optimizations [default = %s]\n", pPars->fFewerVars ? "yes" : "no" ); Abc_Print( -2, "\t-g : toggle using Glucose 3.0 by Gilles Audemard and Laurent Simon [default = %s]\n", pPars->fGlucose ? "yes" : "no" ); @@ -8329,7 +8437,7 @@ int Abc_CommandLutExact( Abc_Frame_t * pAbc, int argc, char ** argv ) Bmc_EsPar_t Pars, * pPars = &Pars; Bmc_EsParSetDefault( pPars ); Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "INKiaogvh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "INKTiaogvh" ) ) != EOF ) { switch ( c ) { @@ -8366,6 +8474,17 @@ int Abc_CommandLutExact( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( pPars->nLutSize < 0 ) goto usage; break; + case 'T': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-T\" should be followed by an integer.\n" ); + goto usage; + } + pPars->RuntimeLim = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->RuntimeLim < 0 ) + goto usage; + break; case 'i': pPars->fUseIncr ^= 1; break; @@ -8421,11 +8540,12 @@ int Abc_CommandLutExact( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; usage: - Abc_Print( -2, "usage: lutexact [-INK <num>] [-iaogvh] <hex>\n" ); + Abc_Print( -2, "usage: lutexact [-INKT <num>] [-iaogvh] <hex>\n" ); Abc_Print( -2, "\t exact synthesis of I-input function using N K-input gates\n" ); Abc_Print( -2, "\t-I <num> : the number of input variables [default = %d]\n", pPars->nVars ); Abc_Print( -2, "\t-N <num> : the number of K-input nodes [default = %d]\n", pPars->nNodes ); Abc_Print( -2, "\t-K <num> : the number of node fanins [default = %d]\n", pPars->nLutSize ); + Abc_Print( -2, "\t-T <num> : the runtime limit in seconds [default = %d]\n", pPars->RuntimeLim ); Abc_Print( -2, "\t-i : toggle using incremental solving [default = %s]\n", pPars->fUseIncr ? "yes" : "no" ); Abc_Print( -2, "\t-a : toggle using only AND-gates when K = 2 [default = %s]\n", pPars->fOnlyAnd ? "yes" : "no" ); Abc_Print( -2, "\t-o : toggle using additional optimizations [default = %s]\n", pPars->fFewerVars ? "yes" : "no" ); @@ -8681,6 +8801,62 @@ usage: SeeAlso [] ***********************************************************************/ +int Abc_CommandMajGen( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + extern int Gem_Enumerate( int nVars, int fDump, int fVerbose ); + int c, nVars = 8, fDump = 0, fVerbose = 0; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "Ndvh" ) ) != EOF ) + { + switch ( c ) + { + case 'N': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-N\" should be followed by an integer.\n" ); + goto usage; + } + nVars = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( nVars < 0 ) + goto usage; + break; + case 'd': + fDump ^= 1; + break; + case 'v': + fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + Gem_Enumerate( nVars, fDump, fVerbose ); + return 0; + +usage: + Abc_Print( -2, "usage: majgen [-N <num>] [-dvh]>\n" ); + Abc_Print( -2, "\t generates networks for majority gates\n" ); + Abc_Print( -2, "\t-N <num> : the maximum number of variables [default = %d]\n", nVars ); + Abc_Print( -2, "\t-d : toggle dumping functions into a file [default = %s]\n", fVerbose ? "yes" : "no" ); + Abc_Print( -2, "\t-v : toggle verbose printout [default = %s]\n", fVerbose ? "yes" : "no" ); + Abc_Print( -2, "\t-h : print the command usage\n" ); + return 1; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ int Abc_CommandLogic( Abc_Frame_t * pAbc, int argc, char ** argv ) { Abc_Ntk_t * pNtk, * pNtkRes; @@ -11067,6 +11243,81 @@ usage: return 1; } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandCof( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + Abc_Ntk_t * pNtk; + Abc_Obj_t * pNode; + int c, Const; + + pNtk = Abc_FrameReadNtk(pAbc); + // set defaults + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "h" ) ) != EOF ) + { + switch ( c ) + { + case 'h': + goto usage; + default: + goto usage; + } + } + + if ( pNtk == NULL ) + { + Abc_Print( -1, "Empty network.\n" ); + return 1; + } + + if ( !Abc_NtkIsLogic(pNtk) ) + { + Abc_Print( -1, "Currently can only be applied to a logic network.\n" ); + return 1; + } + + if ( argc != globalUtilOptind + 2 ) + { + Abc_Print( -1, "Wrong number of auguments.\n" ); + goto usage; + } + pNode = Abc_NtkFindCi( pNtk, argv[globalUtilOptind] ); + if ( pNode == NULL ) + pNode = Abc_NtkFindNode( pNtk, argv[globalUtilOptind] ); + if ( pNode == NULL ) + { + Abc_Print( -1, "Cannot find node \"%s\".\n", argv[globalUtilOptind] ); + return 1; + } + Const = atoi( argv[globalUtilOptind+1] ); + if ( Const != 0 && Const != 1 ) + { + Abc_Print( -1, "Constant should be 0 or 1.\n", argv[globalUtilOptind+1] ); + return 1; + } + Abc_ObjReplaceByConstant( pNode, Const ); + return 0; + +usage: + Abc_Print( -2, "usage: cof [-h] <node> <const>\n" ); + Abc_Print( -2, "\t replaces one node in a logic network by constant 0 or 1\n" ); + Abc_Print( -2, "\t-h : print the command usage\n"); + Abc_Print( -2, "\t<node> : the node to replace\n"); + Abc_Print( -2, "\t<const> : the constant to replace the node with\n"); + Abc_Print( -2, "\tname : the node name\n"); + return 1; +} + /**Function************************************************************* @@ -12057,9 +12308,11 @@ int Abc_CommandGen( Abc_Frame_t * pAbc, int argc, char ** argv ) // Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc); int c; int nVars; // the number of variables + int nArgs; // the number of arguments int nLutSize = -1; // the size of LUTs int nLuts = -1; // the number of LUTs int fAdder; + int fAdderTree; int fSorter; int fMesh; int fMulti; @@ -12076,10 +12329,13 @@ int Abc_CommandGen( Abc_Frame_t * pAbc, int argc, char ** argv ) extern void Abc_GenFpga( char * pFileName, int nLutSize, int nLuts, int nVars ); extern void Abc_GenOneHot( char * pFileName, int nVars ); extern void Abc_GenRandom( char * pFileName, int nPis ); + extern void Abc_GenAdderTree( char * pFileName, int nArgs, int nBits ); // set defaults nVars = 8; + nArgs = 8; fAdder = 0; + fAdderTree = 0; fSorter = 0; fMesh = 0; fMulti = 0; @@ -12088,7 +12344,7 @@ int Abc_CommandGen( Abc_Frame_t * pAbc, int argc, char ** argv ) fRandom = 0; fVerbose = 0; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "NKLasemftrvh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "NAKLabsemftrvh" ) ) != EOF ) { switch ( c ) { @@ -12103,6 +12359,17 @@ int Abc_CommandGen( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( nVars < 0 ) goto usage; break; + case 'A': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-A\" should be followed by an integer.\n" ); + goto usage; + } + nArgs = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( nArgs < 0 ) + goto usage; + break; case 'K': if ( globalUtilOptind >= argc ) { @@ -12128,6 +12395,9 @@ int Abc_CommandGen( Abc_Frame_t * pAbc, int argc, char ** argv ) case 'a': fAdder ^= 1; break; + case 'b': + fAdderTree ^= 1; + break; case 's': fSorter ^= 1; break; @@ -12183,6 +12453,14 @@ int Abc_CommandGen( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_GenOneHot( FileName, nVars ); else if ( fRandom ) Abc_GenRandom( FileName, nVars ); + else if ( fAdderTree ) + { + printf( "Generating adder tree with %d arguments and %d bits.\n", nArgs, nVars ); + Abc_GenAdderTree( FileName, nArgs, nVars ); + sprintf( Command, "%%read %s; %%blast; &put", FileName ); + Cmd_CommandExecute( pAbc, Command ); + return 0; + } else { Abc_Print( -1, "Type of circuit is not specified.\n" ); @@ -12194,12 +12472,14 @@ int Abc_CommandGen( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; usage: - Abc_Print( -2, "usage: gen [-NKL num] [-asemftrvh] <file>\n" ); + Abc_Print( -2, "usage: gen [-NAKL num] [-asemftrvh] <file>\n" ); Abc_Print( -2, "\t generates simple circuits\n" ); Abc_Print( -2, "\t-N num : the number of variables [default = %d]\n", nVars ); + Abc_Print( -2, "\t-A num : the number of agruments (for adder tree) [default = %d]\n", nArgs ); Abc_Print( -2, "\t-K num : the LUT size (to be used with switch -f) [default = %d]\n", nLutSize ); Abc_Print( -2, "\t-L num : the LUT count (to be used with switch -f) [default = %d]\n", nLuts ); Abc_Print( -2, "\t-a : generate ripple-carry adder [default = %s]\n", fAdder? "yes": "no" ); + Abc_Print( -2, "\t-b : generate an adder tree [default = %s]\n", fAdderTree? "yes": "no" ); Abc_Print( -2, "\t-s : generate a sorter [default = %s]\n", fSorter? "yes": "no" ); Abc_Print( -2, "\t-e : generate a mesh [default = %s]\n", fMesh? "yes": "no" ); Abc_Print( -2, "\t-m : generate a multiplier [default = %s]\n", fMulti? "yes": "no" ); @@ -12871,11 +13151,12 @@ int Abc_CommandTestColor( Abc_Frame_t * pAbc, int argc, char ** argv ) ***********************************************************************/ int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv ) { + extern void Dau_NetworkEnumTest(); //Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc); int nCutMax = 1; int nLeafMax = 4; int nDivMax = 2; - int nDecMax = 70; + int nDecMax = 3; int nNumOnes = 4; int fNewAlgo = 0; int fNewOrder = 0; @@ -13029,7 +13310,7 @@ int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv ) */ { // extern void Abc_EnumerateFuncs( int nDecMax, int nDivMax, int fVerbose ); -// Abc_EnumerateFuncs( nDecMax, nDivMax, fVerbose ); +// Abc_EnumerateFuncs( 4, 7, 0 ); } /* if ( fNewAlgo ) @@ -13080,7 +13361,8 @@ int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv ) // Cba_PrsReadBlifTest(); } // Abc_NtkComputePaths( Abc_FrameReadNtk(pAbc) ); -// Psl_FileTest(); + //Dau_NetworkEnumTest(); + //Ext_TruthDiagnoseTest(); return 0; usage: Abc_Print( -2, "usage: test [-CKDNM] [-aovwh] <file_name>\n" ); @@ -22756,6 +23038,183 @@ usage: return 1; } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandPathEnum( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + extern void Abc_EnumerateFrontierTest( int nSize ); + int c, nSize = 4, fZddAlgo = 0, fVerbose = 0; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "Nzvh" ) ) != EOF ) + { + switch ( c ) + { + case 'N': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-N\" should be followed by an integer.\n" ); + goto usage; + } + nSize = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( nSize < 0 ) + goto usage; + break; + case 'z': + fZddAlgo ^= 1; + break; + case 'v': + fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + Abc_Print( -2, "Unknown switch.\n"); + goto usage; + } + } + Abc_EnumerateFrontierTest( nSize ); + return 0; + +usage: + Abc_Print( -2, "usage: pathenum [-N num] [-vh]\n" ); + Abc_Print( -2, "\t enumerates self-avoiding paths on the NxN grid\n" ); + Abc_Print( -2, "\t-N num : the size of the grid to consider [default = %d]\n", nSize ); +// Abc_Print( -2, "\t-z : toggle using ZDD-based algorithm [default = %s]\n", fZddAlgo? "yes": "no" ); + Abc_Print( -2, "\t-v : toggle verbose output [default = %s]\n", fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-h : print the command usage\n"); + return 1; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandFunEnum( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + extern void Dtt_EnumerateLf( int nVars, int nNodeMax, int fDelay, int fMulti, int fVerbose ); + extern void Dau_FunctionEnum( int nInputs, int nVars, int nNodeMax, int fUseTwo, int fReduce, int fVerbose ); + int c, nInputs = 4, nVars = 4, nNodeMax = 32, fUseTwo = 0, fReduce = 0, fSimple = 0, fDelay = 0, fMulti = 0, fVerbose = 0; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "SIMtrldmvh" ) ) != EOF ) + { + switch ( c ) + { + case 'S': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-S\" should be followed by an integer.\n" ); + goto usage; + } + nInputs = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( nInputs < 0 ) + goto usage; + break; + case 'I': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-I\" should be followed by an integer.\n" ); + goto usage; + } + nVars = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( nVars < 0 ) + goto usage; + break; + case 'M': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-M\" should be followed by an integer.\n" ); + goto usage; + } + nNodeMax = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( nNodeMax < 0 ) + goto usage; + break; + case 't': + fUseTwo ^= 1; + break; + case 'r': + fReduce ^= 1; + break; + case 'l': + fSimple ^= 1; + break; + case 'd': + fDelay ^= 1; + break; + case 'm': + fMulti ^= 1; + break; + case 'v': + fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + Abc_Print( -2, "Unknown switch.\n"); + goto usage; + } + } + if ( fSimple || fDelay ) + { + if ( nVars < 3 || nVars > 5 ) + { + Abc_Print( -1, "The number of inputs should be 3 <= I <= 5.\n" ); + goto usage; + } + Dtt_EnumerateLf( nVars, nNodeMax, fDelay, fMulti, fVerbose ); + } + else + { + if ( nVars < 2 || nVars > 6 ) + { + Abc_Print( -1, "The number of inputs should be 2 <= I <= 6.\n" ); + goto usage; + } + if ( nInputs < nVars || nInputs > 6 ) + { + Abc_Print( -1, "The intermediate support size should be I <= S <= 6.\n" ); + goto usage; + } + Dau_FunctionEnum( nInputs, nVars, nNodeMax, fUseTwo, fReduce, fVerbose ); + } + return 0; + +usage: + Abc_Print( -2, "usage: funenum [-SIM num] [-trldmvh]\n" ); + Abc_Print( -2, "\t enumerates minimum 2-input-gate implementations\n" ); + Abc_Print( -2, "\t-S num : the maximum intermediate support size [default = %d]\n", nInputs ); + Abc_Print( -2, "\t-I num : the number of inputs of Boolean functions [default = %d]\n", nVars ); + Abc_Print( -2, "\t-M num : the maximum number of 2-input gates [default = %d]\n", nNodeMax ); + Abc_Print( -2, "\t-t : toggle adding combination of two gates [default = %s]\n", fUseTwo? "yes": "no" ); + Abc_Print( -2, "\t-r : toggle reducing the last level [default = %s]\n", fReduce? "yes": "no" ); + Abc_Print( -2, "\t-l : toggle generating L(f) rather than C(f) [default = %s]\n", fSimple? "yes": "no" ); + Abc_Print( -2, "\t-d : toggle generating D(f) rather than C(f) [default = %s]\n", fDelay? "yes": "no" ); + Abc_Print( -2, "\t-m : toggle generating multiplicity statistics [default = %s]\n", fMulti? "yes": "no" ); + Abc_Print( -2, "\t-v : toggle verbose output [default = %s]\n", fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-h : print the command usage\n"); + return 1; +} + /**Function************************************************************* @@ -42647,11 +43106,11 @@ usage: ***********************************************************************/ int Abc_CommandAbc9Polyn( Abc_Frame_t * pAbc, int argc, char ** argv ) { - extern void Gia_PolynBuild2Test( Gia_Man_t * pGia, int nExtra, int fSigned, int fVerbose, int fVeryVerbose ); - Vec_Int_t * vOrder = NULL; - int c, nExtra = -1, fOld = 0, fSimple = 1, fSigned = 0, fVerbose = 0, fVeryVerbose = 0; + extern void Gia_PolynBuild2Test( Gia_Man_t * pGia, char * pSign, int nExtra, int fSigned, int fVerbose, int fVeryVerbose ); + Vec_Int_t * vOrder = NULL; char * pSign = NULL; + int c, nExtra = 0, fOld = 0, fSimple = 1, fSigned = 0, fVerbose = 0, fVeryVerbose = 0; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "Noasvwh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "NSoasvwh" ) ) != EOF ) { switch ( c ) { @@ -42666,6 +43125,15 @@ int Abc_CommandAbc9Polyn( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( nExtra < 0 ) goto usage; break; + case 'S': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-S\" should be followed by a char string without spaces.\n" ); + goto usage; + } + pSign = argv[globalUtilOptind]; + globalUtilOptind++; + break; case 'o': fOld ^= 1; break; @@ -42692,6 +43160,11 @@ int Abc_CommandAbc9Polyn( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_Print( -1, "Abc_CommandAbc9Esop(): There is no AIG.\n" ); return 0; } + if ( argc >= globalUtilOptind + 1 ) + { + printf( "Trailing symbols on the command line (\"%s\").\n", argv[globalUtilOptind] ); + return 0; + } if ( fOld ) { vOrder = fSimple ? NULL : Gia_PolynReorder( pAbc->pGia, fVerbose, fVeryVerbose ); @@ -42699,11 +43172,11 @@ int Abc_CommandAbc9Polyn( Abc_Frame_t * pAbc, int argc, char ** argv ) Vec_IntFreeP( &vOrder ); } else - Gia_PolynBuild2Test( pAbc->pGia, nExtra, fSigned, fVerbose, fVeryVerbose ); + Gia_PolynBuild2Test( pAbc->pGia, pSign, nExtra, fSigned, fVerbose, fVeryVerbose ); return 0; usage: - Abc_Print( -2, "usage: &polyn [-N num] [-oasvwh]\n" ); + Abc_Print( -2, "usage: &polyn [-N num] [-oasvwh] [-S str]\n" ); Abc_Print( -2, "\t derives algebraic polynomial from AIG\n" ); Abc_Print( -2, "\t-N num : the number of additional primary outputs (-1 = unused) [default = %d]\n", nExtra ); Abc_Print( -2, "\t-o : toggles old computation [default = %s]\n", fOld? "yes": "no" ); @@ -42712,6 +43185,18 @@ usage: Abc_Print( -2, "\t-v : toggles printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); Abc_Print( -2, "\t-w : toggles printing very verbose information [default = %s]\n", fVeryVerbose? "yes": "no" ); Abc_Print( -2, "\t-h : print the command usage\n"); + Abc_Print( -2, "\t\n"); + Abc_Print( -2, "\t-S str : (optional) the output signature as a character string\n" ); + Abc_Print( -2, "\t The format used to represent the output signature is very restrictive.\n" ); + Abc_Print( -2, "\t It should be a string without spaces containing monomials in terms of\n" ); + Abc_Print( -2, "\t inputs (i<num>) and outputs (o<num>) where <num> is 0-based. Coefficients\n" ); + Abc_Print( -2, "\t are degrees of two, represented by log2 of their value: for example, \n" ); + Abc_Print( -2, "\t \"2\" is 2^2 = 4, \"-4\" is -2^4=-16, \"-0\" is -2^0=-1, etc\n" ); + Abc_Print( -2, "\t Two types of signature are accepted:\n" ); + Abc_Print( -2, "\t (1) a sequence of monomials without parentheses (for example, \"-2*o0+1*o1+0*o2\")\n" ); + Abc_Print( -2, "\t (2) a product of two sequences followed by a sum with a sequence\n" ); + Abc_Print( -2, "\t (for example, \"(4*o0+2*o1+1*o2)*(4*i3+2*i4+1*i5)+(4*o3+2*o4+1*o5)\")\n" ); + Abc_Print( -2, "\t Here is the signature of a signed 2-bit multiplier: \"(0*o0+1*o1+2*o2-3*o3)\"\n" ); return 1; } @@ -43362,6 +43847,16 @@ int Abc_CommandAbc9Mfs( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_Print( -1, "Abc_CommandAbc9Mfs(): The current AIG has no mapping.\n" ); return 0; } + if ( Gia_ManLutSizeMax(pAbc->pGia) > 6 ) + { + Abc_Print( -1, "Abc_CommandAbc9Mfs(): The current mapping has nodes with more than 6 inputs. Cannot use \"mfs\".\n" ); + return 0; + } + if ( pAbc->pGia->pAigExtra && Gia_ManPiNum(pAbc->pGia->pAigExtra) > 6 ) + { + Abc_Print( -1, "Abc_CommandAbc9Mfs(): The current white-boxes have more than 6 inputs. Cannot use \"mfs\".\n" ); + return 0; + } pTemp = Gia_ManPerformMfs( pAbc->pGia, pPars ); Abc_FrameUpdateGia( pAbc, pTemp ); return 0; @@ -43379,7 +43874,7 @@ usage: Abc_Print( -2, "\t-d : toggle performing redundancy removal [default = %s]\n", pPars->fRrOnly? "yes": "no" ); Abc_Print( -2, "\t-a : toggle minimizing area or area+edges [default = %s]\n", pPars->fArea? "area": "area+edges" ); Abc_Print( -2, "\t-e : toggle high-effort resubstitution [default = %s]\n", pPars->fMoreEffort? "yes": "no" ); - Abc_Print( -2, "\t-b : toggle preserving all while boxes [default = %s]\n", pPars->fAllBoxes? "yes": "no" ); + Abc_Print( -2, "\t-b : toggle preserving all white boxes [default = %s]\n", pPars->fAllBoxes? "yes": "no" ); Abc_Print( -2, "\t-v : toggle printing optimization summary [default = %s]\n", pPars->fVerbose? "yes": "no" ); Abc_Print( -2, "\t-w : toggle printing detailed stats for each node [default = %s]\n", pPars->fVeryVerbose? "yes": "no" ); Abc_Print( -2, "\t-h : print the command usage\n"); diff --git a/src/base/abci/abcAuto.c b/src/base/abci/abcAuto.c index 18c92657..8f7eead0 100644 --- a/src/base/abci/abcAuto.c +++ b/src/base/abci/abcAuto.c @@ -62,7 +62,7 @@ void Abc_NtkAutoPrint( Abc_Ntk_t * pNtk, int Output, int fNaive, int fVerbose ) Abc_Obj_t * pObj; // compute the global BDDs - if ( Abc_NtkBuildGlobalBdds(pNtk, 10000000, 1, 1, fVerbose) == NULL ) + if ( Abc_NtkBuildGlobalBdds(pNtk, 10000000, 1, 1, 0, fVerbose) == NULL ) return; // get information about the network diff --git a/src/base/abci/abcCas.c b/src/base/abci/abcCas.c index 9abdd792..6615bff0 100644 --- a/src/base/abci/abcCas.c +++ b/src/base/abci/abcCas.c @@ -70,7 +70,7 @@ Abc_Ntk_t * Abc_NtkCascade( Abc_Ntk_t * pNtk, int nLutSize, int fCheck, int fVer assert( Abc_NtkIsStrash(pNtk) ); // compute the global BDDs - if ( Abc_NtkBuildGlobalBdds(pNtk, fBddSizeMax, 1, fReorder, fVerbose) == NULL ) + if ( Abc_NtkBuildGlobalBdds(pNtk, fBddSizeMax, 1, fReorder, 0, fVerbose) == NULL ) return NULL; if ( fVerbose ) diff --git a/src/base/abci/abcCascade.c b/src/base/abci/abcCascade.c index 70f2e891..50e66675 100644 --- a/src/base/abci/abcCascade.c +++ b/src/base/abci/abcCascade.c @@ -1010,7 +1010,7 @@ Abc_Ntk_t * Abc_NtkBddDec( Abc_Ntk_t * pNtk, int fVerbose ) int i; assert( Abc_NtkIsStrash(pNtk) ); assert( Abc_NtkCoNum(pNtk) <= BDD_FUNC_MAX ); - dd = (DdManager *)Abc_NtkBuildGlobalBdds( pNtk, nBddSizeMax, fDropInternal, fReorder, fVerbose ); + dd = (DdManager *)Abc_NtkBuildGlobalBdds( pNtk, nBddSizeMax, fDropInternal, fReorder, 0, fVerbose ); if ( dd == NULL ) { Abc_Print( -1, "Construction of global BDDs has failed.\n" ); diff --git a/src/base/abci/abcCollapse.c b/src/base/abci/abcCollapse.c index 1542c25a..caeea3a1 100644 --- a/src/base/abci/abcCollapse.c +++ b/src/base/abci/abcCollapse.c @@ -118,7 +118,7 @@ int Abc_NtkMinimumBase2( Abc_Ntk_t * pNtk ) SeeAlso [] ***********************************************************************/ -Abc_Obj_t * Abc_NodeFromGlobalBdds( Abc_Ntk_t * pNtkNew, DdManager * dd, DdNode * bFunc ) +Abc_Obj_t * Abc_NodeFromGlobalBdds( Abc_Ntk_t * pNtkNew, DdManager * dd, DdNode * bFunc, int fReverse ) { Abc_Obj_t * pNodeNew, * pTemp; int i; @@ -126,12 +126,12 @@ Abc_Obj_t * Abc_NodeFromGlobalBdds( Abc_Ntk_t * pNtkNew, DdManager * dd, DdNode pNodeNew = Abc_NtkCreateNode( pNtkNew ); // add the fanins in the order, in which they appear in the reordered manager Abc_NtkForEachCi( pNtkNew, pTemp, i ) - Abc_ObjAddFanin( pNodeNew, Abc_NtkCi(pNtkNew, dd->invperm[i]) ); + Abc_ObjAddFanin( pNodeNew, Abc_NtkCi(pNtkNew, fReverse ? Abc_NtkCiNum(pNtkNew)-1-dd->invperm[i] : dd->invperm[i]) ); // transfer the function pNodeNew->pData = Extra_TransferLevelByLevel( dd, (DdManager *)pNtkNew->pManFunc, bFunc ); Cudd_Ref( (DdNode *)pNodeNew->pData ); return pNodeNew; } -Abc_Ntk_t * Abc_NtkFromGlobalBdds( Abc_Ntk_t * pNtk ) +Abc_Ntk_t * Abc_NtkFromGlobalBdds( Abc_Ntk_t * pNtk, int fReverse ) { ProgressBar * pProgress; Abc_Ntk_t * pNtkNew; @@ -147,7 +147,7 @@ Abc_Ntk_t * Abc_NtkFromGlobalBdds( Abc_Ntk_t * pNtk ) assert( Abc_NtkIsStrash(pNtk->pExdc) ); assert( Abc_NtkCoNum(pNtk->pExdc) == 1 ); // compute the global BDDs - if ( Abc_NtkBuildGlobalBdds(pNtk->pExdc, 10000000, 1, 1, 0) == NULL ) + if ( Abc_NtkBuildGlobalBdds(pNtk->pExdc, 10000000, 1, 1, 0, 0) == NULL ) return NULL; // transfer tot the same manager ddExdc = (DdManager *)Abc_NtkGlobalBddMan( pNtk->pExdc ); @@ -188,21 +188,21 @@ Abc_Ntk_t * Abc_NtkFromGlobalBdds( Abc_Ntk_t * pNtk ) Abc_ObjAddFanin( pNode->pCopy, pDriver->pCopy ); continue; } - pNodeNew = Abc_NodeFromGlobalBdds( pNtkNew, dd, (DdNode *)Abc_ObjGlobalBdd(pNode) ); + pNodeNew = Abc_NodeFromGlobalBdds( pNtkNew, dd, (DdNode *)Abc_ObjGlobalBdd(pNode), fReverse ); Abc_ObjAddFanin( pNode->pCopy, pNodeNew ); } Extra_ProgressBarStop( pProgress ); return pNtkNew; } -Abc_Ntk_t * Abc_NtkCollapse( Abc_Ntk_t * pNtk, int fBddSizeMax, int fDualRail, int fReorder, int fVerbose ) +Abc_Ntk_t * Abc_NtkCollapse( Abc_Ntk_t * pNtk, int fBddSizeMax, int fDualRail, int fReorder, int fReverse, int fVerbose ) { Abc_Ntk_t * pNtkNew; abctime clk = Abc_Clock(); assert( Abc_NtkIsStrash(pNtk) ); // compute the global BDDs - if ( Abc_NtkBuildGlobalBdds(pNtk, fBddSizeMax, 1, fReorder, fVerbose) == NULL ) + if ( Abc_NtkBuildGlobalBdds(pNtk, fBddSizeMax, 1, fReorder, fReverse, fVerbose) == NULL ) return NULL; if ( fVerbose ) { @@ -212,7 +212,7 @@ Abc_Ntk_t * Abc_NtkCollapse( Abc_Ntk_t * pNtk, int fBddSizeMax, int fDualRail, i } // create the new network - pNtkNew = Abc_NtkFromGlobalBdds( pNtk ); + pNtkNew = Abc_NtkFromGlobalBdds( pNtk, fReverse ); Abc_NtkFreeGlobalBdds( pNtk, 1 ); if ( pNtkNew == NULL ) return NULL; @@ -236,7 +236,7 @@ Abc_Ntk_t * Abc_NtkCollapse( Abc_Ntk_t * pNtk, int fBddSizeMax, int fDualRail, i #else -Abc_Ntk_t * Abc_NtkCollapse( Abc_Ntk_t * pNtk, int fBddSizeMax, int fDualRail, int fReorder, int fVerbose ) +Abc_Ntk_t * Abc_NtkCollapse( Abc_Ntk_t * pNtk, int fBddSizeMax, int fDualRail, int fReorder, int fReverse, int fVerbose ) { return NULL; } diff --git a/src/base/abci/abcDsd.c b/src/base/abci/abcDsd.c index 4d8f5217..5121a4fc 100644 --- a/src/base/abci/abcDsd.c +++ b/src/base/abci/abcDsd.c @@ -67,7 +67,7 @@ Abc_Ntk_t * Abc_NtkDsdGlobal( Abc_Ntk_t * pNtk, int fVerbose, int fPrint, int fS DdManager * dd; Abc_Ntk_t * pNtkNew; assert( Abc_NtkIsStrash(pNtk) ); - dd = (DdManager *)Abc_NtkBuildGlobalBdds( pNtk, 10000000, 1, 1, fVerbose ); + dd = (DdManager *)Abc_NtkBuildGlobalBdds( pNtk, 10000000, 1, 1, 0, fVerbose ); if ( dd == NULL ) return NULL; if ( fVerbose ) diff --git a/src/base/abci/abcExact.c b/src/base/abci/abcExact.c index 2fbf63dd..b717f5b4 100644 --- a/src/base/abci/abcExact.c +++ b/src/base/abci/abcExact.c @@ -2983,8 +2983,8 @@ void Abc_ExactStoreTest( int fVerbose ) Abc_Ntk_t * pNtk; Abc_Obj_t * pFanins[4]; Vec_Ptr_t * vNames; - char pPerm[4]; - int Cost; + char pPerm[4] = {0}; + int Cost = 0; pNtk = Abc_NtkAlloc( ABC_NTK_LOGIC, ABC_FUNC_SOP, 1 ); pNtk->pName = Extra_UtilStrsav( "exact" ); diff --git a/src/base/abci/abcGen.c b/src/base/abci/abcGen.c index 26ee3f86..e90040ab 100644 --- a/src/base/abci/abcGen.c +++ b/src/base/abci/abcGen.c @@ -821,6 +821,55 @@ void Abc_GenFsm( char * pFileName, int nPis, int nPos, int nStates, int nLines, Vec_StrFree( vCond ); } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_AdderTree( FILE * pFile, int nArgs, int nBits ) +{ + int i, k, nDigits = Abc_Base10Log( nBits ), Log2 = Abc_Base2Log( nArgs ); + assert( nArgs > 1 && nBits > 1 ); + fprintf( pFile, "module adder_tree_%d_%d (\n ", nArgs, nBits ); + for ( i = 0; i < nBits; i++, fprintf(pFile, "\n ") ) + for ( k = 0; k < nArgs; k++ ) + fprintf( pFile, " i%0*d_%0*d,", nDigits, k, nDigits, nBits-1-i ); + fprintf( pFile, " z\n" ); + fprintf( pFile, " );\n" ); + for ( i = 0; i < nBits; i++ ) + { + fprintf( pFile, " input" ); + for ( k = 0; k < nArgs; k++ ) + fprintf( pFile, " i%0*d_%0*d%s", nDigits, k, nDigits, nBits-1-i, k==nArgs-1 ? "":"," ); + fprintf( pFile, ";\n" ); + } + fprintf( pFile, " output [%d:0] z;\n", nBits+Log2-1 ); + for ( i = 0; i < nArgs; i++ ) + { + fprintf( pFile, " wire [%d:0] t%d = {", nBits-1, i ); + for ( k = 0; k < nBits; k++ ) + fprintf( pFile, " i%0*d_%0*d%s", nDigits, i, nDigits, nBits-1-k, k==nBits-1 ? "":"," ); + fprintf( pFile, " };\n" ); + } + for ( i = 0; i < nArgs-1; i++ ) + fprintf( pFile, " wire [%d:0] s%d = t%d + %s%d;\n", nBits+Log2-1, i+1, i+1, i ? "s":"t", i ); + fprintf( pFile, " assign z = s%d;\n", nArgs-1 ); + fprintf( pFile, "endmodule\n\n" ); +} +void Abc_GenAdderTree( char * pFileName, int nArgs, int nBits ) +{ + FILE * pFile = fopen( pFileName, "w" ); + fprintf( pFile, "// %d-argument %d-bit adder-tree generated by ABC on %s\n", nArgs, nBits, Extra_TimeStamp() ); + Abc_AdderTree( pFile, nArgs, nBits ); + fclose( pFile ); +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/base/abci/abcIvy.c b/src/base/abci/abcIvy.c index 59481d3e..e4a5d3b4 100644 --- a/src/base/abci/abcIvy.c +++ b/src/base/abci/abcIvy.c @@ -600,7 +600,7 @@ int Abc_NtkIvyProve( Abc_Ntk_t ** ppNtk, void * pPars ) printf( "Attempting BDDs with node limit %d ...\n", pParams->nBddSizeLimit ); fflush( stdout ); } - pNtk = Abc_NtkCollapse( pNtkTemp = pNtk, pParams->nBddSizeLimit, 0, pParams->fBddReorder, 0 ); + pNtk = Abc_NtkCollapse( pNtkTemp = pNtk, pParams->nBddSizeLimit, 0, pParams->fBddReorder, 0, 0 ); if ( pNtk ) { Abc_NtkDelete( pNtkTemp ); diff --git a/src/base/abci/abcLutmin.c b/src/base/abci/abcLutmin.c index ad686299..2ac44060 100644 --- a/src/base/abci/abcLutmin.c +++ b/src/base/abci/abcLutmin.c @@ -739,7 +739,7 @@ Abc_Ntk_t * Abc_NtkLutmin( Abc_Ntk_t * pNtkInit, int nLutSize, int fVerbose ) else pNtkNew = Abc_NtkStrash( pNtkInit, 0, 1, 0 ); // collapse the network - pNtkNew = Abc_NtkCollapse( pTemp = pNtkNew, 10000, 0, 1, 0 ); + pNtkNew = Abc_NtkCollapse( pTemp = pNtkNew, 10000, 0, 1, 0, 0 ); Abc_NtkDelete( pTemp ); if ( pNtkNew == NULL ) return NULL; diff --git a/src/base/abci/abcNpn.c b/src/base/abci/abcNpn.c index d2d06924..744b6443 100644 --- a/src/base/abci/abcNpn.c +++ b/src/base/abci/abcNpn.c @@ -295,10 +295,6 @@ void Abc_TruthNpnPerform( Abc_TtStore_t * p, int NpnType, int fVerbose ) } else if ( NpnType == 7 ) { - extern unsigned Abc_TtCanonicizeHie(Abc_TtHieMan_t * p, word * pTruth, int nVars, char * pCanonPerm, int fExact ); - extern Abc_TtHieMan_t * Abc_TtHieManStart( int nVars, int nLevels ); - extern void Abc_TtHieManStop(Abc_TtHieMan_t * p ); - int fExact = 0; Abc_TtHieMan_t * pMan = Abc_TtHieManStart( p->nVars, 5 ); for ( i = 0; i < p->nFuncs; i++ ) @@ -318,8 +314,6 @@ void Abc_TruthNpnPerform( Abc_TtStore_t * p, int NpnType, int fVerbose ) typedef unsigned(*TtCanonicizeFunc)(Abc_TtHieMan_t * p, word * pTruth, int nVars, char * pCanonPerm, int flag); unsigned Abc_TtCanonicizeWrap(TtCanonicizeFunc func, Abc_TtHieMan_t * p, word * pTruth, int nVars, char * pCanonPerm, int flag); unsigned Abc_TtCanonicizeAda(Abc_TtHieMan_t * p, word * pTruth, int nVars, char * pCanonPerm, int iThres); - Abc_TtHieMan_t * Abc_TtHieManStart(int nVars, int nLevels); - void Abc_TtHieManStop(Abc_TtHieMan_t * p); int fHigh = 1, iEnumThres = 25; Abc_TtHieMan_t * pMan = Abc_TtHieManStart(p->nVars, 5); diff --git a/src/base/abci/abcNtbdd.c b/src/base/abci/abcNtbdd.c index 0225d800..a55ea227 100644 --- a/src/base/abci/abcNtbdd.c +++ b/src/base/abci/abcNtbdd.c @@ -254,7 +254,7 @@ Abc_Obj_t * Abc_NodeBddToMuxes_rec( DdManager * dd, DdNode * bFunc, Abc_Ntk_t * SeeAlso [] ***********************************************************************/ -void * Abc_NtkBuildGlobalBdds( Abc_Ntk_t * pNtk, int nBddSizeMax, int fDropInternal, int fReorder, int fVerbose ) +void * Abc_NtkBuildGlobalBdds( Abc_Ntk_t * pNtk, int nBddSizeMax, int fDropInternal, int fReorder, int fReverse, int fVerbose ) { ProgressBar * pProgress; Abc_Obj_t * pObj, * pFanin; @@ -287,8 +287,7 @@ void * Abc_NtkBuildGlobalBdds( Abc_Ntk_t * pNtk, int nBddSizeMax, int fDropInter Abc_NtkForEachCi( pNtk, pObj, i ) if ( Abc_ObjFanoutNum(pObj) > 0 ) { - bFunc = dd->vars[i]; -// bFunc = dd->vars[Abc_NtkCiNum(pNtk) - 1 - i]; + bFunc = fReverse ? dd->vars[Abc_NtkCiNum(pNtk) - 1 - i] : dd->vars[i]; Abc_ObjSetGlobalBdd( pObj, bFunc ); Cudd_Ref( bFunc ); } diff --git a/src/base/abci/abcProve.c b/src/base/abci/abcProve.c index c31e9d94..03722926 100644 --- a/src/base/abci/abcProve.c +++ b/src/base/abci/abcProve.c @@ -201,7 +201,7 @@ int Abc_NtkMiterProve( Abc_Ntk_t ** ppNtk, void * pPars ) fflush( stdout ); } clk = Abc_Clock(); - pNtk = Abc_NtkCollapse( pNtkTemp = pNtk, pParams->nBddSizeLimit, 0, pParams->fBddReorder, 0 ); + pNtk = Abc_NtkCollapse( pNtkTemp = pNtk, pParams->nBddSizeLimit, 0, pParams->fBddReorder, 0, 0 ); if ( pNtk ) { Abc_NtkDelete( pNtkTemp ); diff --git a/src/base/abci/abcReach.c b/src/base/abci/abcReach.c index 908b16be..bf705dc9 100644 --- a/src/base/abci/abcReach.c +++ b/src/base/abci/abcReach.c @@ -271,7 +271,7 @@ void Abc_NtkVerifyUsingBdds( Abc_Ntk_t * pNtk, int nBddMax, int nIterMax, int fP assert( Abc_ObjFanoutNum(Abc_NtkPo(pNtk,0)) == 0 ); // PO should go first // compute the global BDDs of the latches - dd = (DdManager *)Abc_NtkBuildGlobalBdds( pNtk, nBddMax, 1, fReorder, fVerbose ); + dd = (DdManager *)Abc_NtkBuildGlobalBdds( pNtk, nBddMax, 1, fReorder, 0, fVerbose ); if ( dd == NULL ) { printf( "The number of intermediate BDD nodes exceeded the limit (%d).\n", nBddMax ); diff --git a/src/base/abci/abcSymm.c b/src/base/abci/abcSymm.c index 096c3ae4..36a5ee3e 100644 --- a/src/base/abci/abcSymm.c +++ b/src/base/abci/abcSymm.c @@ -99,7 +99,7 @@ void Abc_NtkSymmetriesUsingBdds( Abc_Ntk_t * pNtk, int fNaive, int fReorder, int // compute the global functions clk = Abc_Clock(); - dd = (DdManager *)Abc_NtkBuildGlobalBdds( pNtk, 10000000, 1, fReorder, fVerbose ); + dd = (DdManager *)Abc_NtkBuildGlobalBdds( pNtk, 10000000, 1, fReorder, 0, fVerbose ); printf( "Shared BDD size = %d nodes.\n", Abc_NtkSizeOfGlobalBdds(pNtk) ); Cudd_AutodynDisable( dd ); if ( !fGarbCollect ) diff --git a/src/base/abci/abcUnate.c b/src/base/abci/abcUnate.c index 63003237..211f1ca3 100644 --- a/src/base/abci/abcUnate.c +++ b/src/base/abci/abcUnate.c @@ -82,7 +82,7 @@ void Abc_NtkPrintUnateBdd( Abc_Ntk_t * pNtk, int fUseNaive, int fVerbose ) abctime clkBdd, clkUnate; // compute the global BDDs - dd = (DdManager *)Abc_NtkBuildGlobalBdds(pNtk, 10000000, 1, 1, fVerbose); + dd = (DdManager *)Abc_NtkBuildGlobalBdds(pNtk, 10000000, 1, 1, 0, fVerbose); if ( dd == NULL ) return; clkBdd = Abc_Clock() - clk; diff --git a/src/base/abci/abcUnreach.c b/src/base/abci/abcUnreach.c index 679d9eed..ae4bc84b 100644 --- a/src/base/abci/abcUnreach.c +++ b/src/base/abci/abcUnreach.c @@ -67,7 +67,7 @@ int Abc_NtkExtractSequentialDcs( Abc_Ntk_t * pNtk, int fVerbose ) } // compute the global BDDs of the latches - dd = (DdManager *)Abc_NtkBuildGlobalBdds( pNtk, 10000000, 1, 1, fVerbose ); + dd = (DdManager *)Abc_NtkBuildGlobalBdds( pNtk, 10000000, 1, 1, 0, fVerbose ); if ( dd == NULL ) return 0; if ( fVerbose ) diff --git a/src/base/acb/acbFunc.c b/src/base/acb/acbFunc.c index d73d1d59..1efb5807 100644 --- a/src/base/acb/acbFunc.c +++ b/src/base/acb/acbFunc.c @@ -198,7 +198,7 @@ int Acb_WireIsTarget( int Token, Abc_Nam_t * pNames ) } void * Acb_VerilogSimpleParse( Vec_Int_t * vBuffer, Abc_Nam_t * pNames ) { - void * pDesign = NULL; + Ndr_Data_t * pDesign = NULL; Vec_Int_t * vInputs = Vec_IntAlloc(100); Vec_Int_t * vOutputs = Vec_IntAlloc(100); Vec_Int_t * vWires = Vec_IntAlloc(100); diff --git a/src/base/cmd/cmdStarter.c b/src/base/cmd/cmdStarter.c index 47cdd9ed..ffb2b752 100644 --- a/src/base/cmd/cmdStarter.c +++ b/src/base/cmd/cmdStarter.c @@ -176,7 +176,8 @@ void Cmd_RunStarter( char * pFileName, char * pBinary, char * pCommand, int nCor ABC_FREE( Buffer ); fclose( pFile ); return; - } + } + fclose( pFileTemp ); } } diff --git a/src/base/io/io.c b/src/base/io/io.c index 5133ef0d..f155c7b6 100644 --- a/src/base/io/io.c +++ b/src/base/io/io.c @@ -2678,14 +2678,24 @@ usage: ***********************************************************************/ int IoCommandWritePla( Abc_Frame_t * pAbc, int argc, char **argv ) { + extern int Io_WriteMoPlaM( Abc_Ntk_t * pNtk, char * pFileName, int nMints ); char * pFileName; - int c, fUseMoPla = 0; + int c, fUseMoPla = 0, nMints = 0; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "mh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "Mmh" ) ) != EOF ) { switch ( c ) { + case 'M': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-M\" should be followed by an integer.\n" ); + goto usage; + } + nMints = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + break; case 'm': fUseMoPla ^= 1; break; @@ -2705,15 +2715,28 @@ int IoCommandWritePla( Abc_Frame_t * pAbc, int argc, char **argv ) // get the output file name pFileName = argv[globalUtilOptind]; // call the corresponding file writer - Io_Write( pAbc->pNtkCur, pFileName, fUseMoPla ? IO_FILE_MOPLA : IO_FILE_PLA ); + if ( nMints ) + { + if ( Abc_NtkIsBddLogic(pAbc->pNtkCur) ) + Io_WriteMoPlaM( pAbc->pNtkCur, pFileName, nMints ); + else + { + Abc_Ntk_t * pStrash = Abc_NtkStrash( pAbc->pNtkCur, 0, 0, 0 ); + Io_WriteMoPlaM( pStrash, pFileName, nMints ); + Abc_NtkDelete( pStrash ); + } + } + else + Io_Write( pAbc->pNtkCur, pFileName, fUseMoPla ? IO_FILE_MOPLA : IO_FILE_PLA ); return 0; usage: - fprintf( pAbc->Err, "usage: write_pla [-mh] <file>\n" ); - fprintf( pAbc->Err, "\t writes the collapsed network into a PLA file\n" ); - fprintf( pAbc->Err, "\t-m : toggle writing multi-output PLA [default = %s]\n", fUseMoPla? "yes":"no" ); - fprintf( pAbc->Err, "\t-h : print the help massage\n" ); - fprintf( pAbc->Err, "\tfile : the name of the file to write\n" ); + fprintf( pAbc->Err, "usage: write_pla [-M <num>] [-mh] <file>\n" ); + fprintf( pAbc->Err, "\t writes the collapsed network into a PLA file\n" ); + fprintf( pAbc->Err, "\t-M <num> : the number of on-set minterms to write [default = %d]\n", nMints ); + fprintf( pAbc->Err, "\t-m : toggle writing multi-output PLA [default = %s]\n", fUseMoPla? "yes":"no" ); + fprintf( pAbc->Err, "\t-h : print the help massage\n" ); + fprintf( pAbc->Err, "\tfile : the name of the file to write\n" ); return 1; } diff --git a/src/base/io/ioWritePla.c b/src/base/io/ioWritePla.c index 676617a1..8aa9ee19 100644 --- a/src/base/io/ioWritePla.c +++ b/src/base/io/ioWritePla.c @@ -383,14 +383,14 @@ int Io_WriteMoPlaOneIntMinterms( FILE * pFile, Abc_Ntk_t * pNtk, DdManager * dd, ***********************************************************************/ int Io_WriteMoPlaOne( FILE * pFile, Abc_Ntk_t * pNtk ) { - int fVerbose = 1; + int fVerbose = 0; DdManager * dd; DdNode * bFunc; Vec_Ptr_t * vFuncsGlob; Abc_Obj_t * pObj; int i; assert( Abc_NtkIsStrash(pNtk) ); - dd = (DdManager *)Abc_NtkBuildGlobalBdds( pNtk, 10000000, 1, 1, fVerbose ); + dd = (DdManager *)Abc_NtkBuildGlobalBdds( pNtk, 10000000, 1, 1, 0, fVerbose ); if ( dd == NULL ) return 0; if ( fVerbose ) @@ -445,9 +445,136 @@ int Io_WriteMoPla( Abc_Ntk_t * pNtk, char * pFileName ) return 1; } + + +/**Function************************************************************* + + Synopsis [Writes the network in PLA format.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Io_WriteMoPlaOneIntMintermsM( FILE * pFile, Abc_Ntk_t * pNtk, DdManager * dd, DdNode * bFunc, int nMints ) +{ + Abc_Obj_t * pNode; + int * pArray = ABC_CALLOC( int, dd->size ); + DdNode ** pbMints = Cudd_bddPickArbitraryMinterms( dd, bFunc, dd->vars, dd->size, nMints ); + int i, k, nInputs = Abc_NtkCiNum(pNtk); + assert( dd->size == Abc_NtkCiNum(pNtk) ); + + // write the header + fprintf( pFile, ".i %d\n", nInputs ); + fprintf( pFile, ".o %d\n", 1 ); + fprintf( pFile, ".ilb" ); + Abc_NtkForEachCi( pNtk, pNode, i ) + fprintf( pFile, " %s", Abc_ObjName(pNode) ); + fprintf( pFile, "\n" ); + fprintf( pFile, ".ob" ); + fprintf( pFile, " %s", Abc_ObjName(Abc_NtkCo(pNtk, 0)) ); + fprintf( pFile, "\n" ); + fprintf( pFile, ".p %d\n", nMints ); + + // iterate through minterms + for ( k = 0; k < nMints; k++ ) + { + Cudd_BddToCubeArray( dd, pbMints[k], pArray ); + for ( i = 0; i < Abc_NtkCiNum(pNtk); i++ ) + if ( pArray[i] == 0 ) + fprintf( pFile, "%c", '0' ); + else if ( pArray[i] == 1 ) + fprintf( pFile, "%c", '1' ); + else if ( pArray[i] == 2 ) + fprintf( pFile, "%c", '-' ); + fprintf( pFile, " " ); + fprintf( pFile, "%c", '1' ); + fprintf( pFile, "\n" ); + } + fprintf( pFile, ".e\n" ); + + //for ( k = 0; k < nMints; k++ ) + // Cudd_RecursiveDeref( dd, pbMints[k] ); + ABC_FREE( pbMints ); + ABC_FREE( pArray ); + return 1; +} +int Io_WriteMoPlaOneM( FILE * pFile, Abc_Ntk_t * pNtk, int nMints ) +{ + int fVerbose = 0; + DdManager * dd; + DdNode * bFunc; + Vec_Ptr_t * vFuncsGlob; + Abc_Obj_t * pObj; + int i; + if ( Abc_NtkIsStrash(pNtk) ) + { + assert( Abc_NtkIsStrash(pNtk) ); + dd = (DdManager *)Abc_NtkBuildGlobalBdds( pNtk, 10000000, 1, 1, 0, fVerbose ); + if ( dd == NULL ) + return 0; + if ( fVerbose ) + printf( "Shared BDD size = %6d nodes.\n", Cudd_ReadKeys(dd) - Cudd_ReadDead(dd) ); + + // complement the global functions + vFuncsGlob = Vec_PtrAlloc( Abc_NtkCoNum(pNtk) ); + Abc_NtkForEachCo( pNtk, pObj, i ) + Vec_PtrPush( vFuncsGlob, Abc_ObjGlobalBdd(pObj) ); + + // get the output function + bFunc = (DdNode *)Vec_PtrEntry(vFuncsGlob, 0); + if ( bFunc == Cudd_ReadOne(dd) ) + printf( "First primary output has constant 1 function.\n" ); + else if ( Cudd_Not(bFunc) == Cudd_ReadOne(dd) ) + printf( "First primary output has constant 0 function.\n" ); + else + Io_WriteMoPlaOneIntMintermsM( pFile, pNtk, dd, bFunc, nMints ); + Abc_NtkFreeGlobalBdds( pNtk, 0 ); + + // cleanup + Vec_PtrForEachEntry( DdNode *, vFuncsGlob, bFunc, i ) + Cudd_RecursiveDeref( dd, bFunc ); + Vec_PtrFree( vFuncsGlob ); + //Extra_StopManager( dd ); + Cudd_Quit( dd ); + } + else if ( Abc_NtkIsBddLogic(pNtk) ) + { + DdNode * bFunc = (DdNode *)Abc_ObjFanin0(Abc_NtkCo(pNtk, 0))->pData; + dd = (DdManager *)pNtk->pManFunc; + if ( dd->size == Abc_NtkCiNum(pNtk) ) + Io_WriteMoPlaOneIntMintermsM( pFile, pNtk, dd, bFunc, nMints ); + else + { + printf( "Cannot write minterms because the size of the manager for local BDDs is not equal to\n" ); + printf( "the number of primary inputs. (It is likely that the current network is not collapsed.)\n" ); + } + } + return 1; +} +int Io_WriteMoPlaM( Abc_Ntk_t * pNtk, char * pFileName, int nMints ) +{ + FILE * pFile; + assert( Abc_NtkIsStrash(pNtk) || Abc_NtkIsBddLogic(pNtk) ); + pFile = fopen( pFileName, "w" ); + if ( pFile == NULL ) + { + fprintf( stdout, "Io_WriteMoPlaM(): Cannot open the output file.\n" ); + return 0; + } + fprintf( pFile, "# Benchmark \"%s\" written by ABC on %s\n", pNtk->pName, Extra_TimeStamp() ); + Io_WriteMoPlaOneM( pFile, pNtk, nMints ); + fclose( pFile ); + return 1; +} + + #else -int Io_WriteMoPla( Abc_Ntk_t * pNtk, char * pFileName ) { return 1; } +int Io_WriteMoPla( Abc_Ntk_t * pNtk, char * pFileName ) { return 1; } +int Io_WriteMoPlaM( Abc_Ntk_t * pNtk, char * pFileName, int nMints ) { return 1; } #endif diff --git a/src/base/main/abcapis.h b/src/base/main/abcapis.h index af7888e1..9ac2036a 100644 --- a/src/base/main/abcapis.h +++ b/src/base/main/abcapis.h @@ -98,6 +98,9 @@ extern ABC_DLL int * Abc_FrameReadBoxes( Abc_Frame_t * pAbc ); extern ABC_DLL int Abc_FrameReadProbStatus( Abc_Frame_t * pAbc ); extern ABC_DLL void * Abc_FrameReadCex( Abc_Frame_t * pAbc ); +// procedure to return sequential equivalences +extern ABC_DLL int * Abc_FrameReadMiniAigEquivClasses( Abc_Frame_t * pAbc ); + ABC_NAMESPACE_HEADER_END #endif diff --git a/src/base/wlc/wlc.h b/src/base/wlc/wlc.h index 02921722..3a84031e 100644 --- a/src/base/wlc/wlc.h +++ b/src/base/wlc/wlc.h @@ -100,7 +100,8 @@ typedef enum { WLC_OBJ_WRITE, // 55: write port WLC_OBJ_ARI_ADDSUB, // 56: adder-subtractor WLC_OBJ_SEL, // 57: positionally encoded selector - WLC_OBJ_NUMBER // 57: unused + WLC_OBJ_DEC, // 58: decoder + WLC_OBJ_NUMBER // 59: unused } Wlc_ObjType_t; // when adding new types, remember to update table Wlc_Names in "wlcNtk.c" @@ -139,6 +140,7 @@ struct Wlc_Ntk_t_ Vec_Int_t vCis; // combinational inputs Vec_Int_t vCos; // combinational outputs Vec_Int_t vFfs; // flops + Vec_Int_t vFfs2; // flops Vec_Int_t * vInits; // initial values char * pInits; // initial values int nObjs[WLC_OBJ_NUMBER]; // counter of objects of each type @@ -208,6 +210,7 @@ struct Wlc_BstPar_t_ int fAddOutputs; int fMulti; int fBooth; + int fCla; int fNoCleanup; int fCreateMiter; int fDecMuxes; @@ -226,6 +229,7 @@ static inline void Wlc_BstParDefault( Wlc_BstPar_t * pPar ) pPar->fAddOutputs = 0; pPar->fMulti = 0; pPar->fBooth = 0; + pPar->fCla = 0; pPar->fCreateMiter = 0; pPar->fDecMuxes = 0; pPar->fVerbose = 0; @@ -272,6 +276,7 @@ static inline Wlc_Obj_t * Wlc_NtkPo( Wlc_Ntk_t * p, int i ) static inline Wlc_Obj_t * Wlc_NtkCi( Wlc_Ntk_t * p, int i ) { return Wlc_NtkObj( p, Vec_IntEntry(&p->vCis, i) ); } static inline Wlc_Obj_t * Wlc_NtkCo( Wlc_Ntk_t * p, int i ) { return Wlc_NtkObj( p, Vec_IntEntry(&p->vCos, i) ); } static inline Wlc_Obj_t * Wlc_NtkFf( Wlc_Ntk_t * p, int i ) { return Wlc_NtkObj( p, Vec_IntEntry(&p->vFfs, i) ); } +static inline Wlc_Obj_t * Wlc_NtkFf2( Wlc_Ntk_t * p, int i ) { return Wlc_NtkObj( p, Vec_IntEntry(&p->vFfs2, i) ); } static inline int Wlc_ObjIsPi( Wlc_Obj_t * p ) { return p->Type == WLC_OBJ_PI; } static inline int Wlc_ObjIsPo( Wlc_Obj_t * p ) { return p->fIsPo; } @@ -347,6 +352,8 @@ static inline Wlc_Obj_t * Wlc_ObjCo2PoFo( Wlc_Ntk_t * p, int iCoId ) for ( i = 0; (i < Wlc_NtkCoNum(p)) && (((pCo) = Wlc_NtkCo(p, i)), 1); i++ ) #define Wlc_NtkForEachFf( p, pFf, i ) \ for ( i = 0; (i < Vec_IntSize(&p->vFfs)) && (((pFf) = Wlc_NtkFf(p, i)), 1); i++ ) +#define Wlc_NtkForEachFf2( p, pFf, i ) \ + for ( i = 0; (i < Vec_IntSize(&p->vFfs2)) && (((pFf) = Wlc_NtkFf2(p, i)), 1); i++ ) #define Wlc_ObjForEachFanin( pObj, iFanin, i ) \ for ( i = 0; (i < Wlc_ObjFaninNum(pObj)) && (((iFanin) = Wlc_ObjFaninId(pObj, i)), 1); i++ ) diff --git a/src/base/wlc/wlcBlast.c b/src/base/wlc/wlcBlast.c index b97dfdad..e4088f9c 100644 --- a/src/base/wlc/wlcBlast.c +++ b/src/base/wlc/wlcBlast.c @@ -131,6 +131,12 @@ int Wlc_NtkMuxTree2( Gia_Man_t * pNew, int * pCtrl, int nCtrl, Vec_Int_t * vData Vec_IntPush( vTemp, Abc_LitNot( Gia_ManHashAnd(pNew, iLit, Vec_IntEntry(vData, m)) ) ); return Abc_LitNot( Gia_ManHashAndMulti(pNew, vTemp) ); } +void Wlc_NtkPrintNameArray( Vec_Ptr_t * vNames ) +{ + int i; char * pTemp; + Vec_PtrForEachEntry( char *, vNames, pTemp, i ) + printf( "%2d : %s\n", i, pTemp ); +} /**Function************************************************************* @@ -345,9 +351,9 @@ void Wlc_BlastAdder( Gia_Man_t * pNew, int * pAdd0, int * pAdd1, int nBits, int for ( b = 0; b < nBits; b++ ) Wlc_BlastFullAdder( pNew, pAdd0[b], pAdd1[b], Carry, &Carry, &pAdd0[b] ); } -void Wlc_BlastSubtract( Gia_Man_t * pNew, int * pAdd0, int * pAdd1, int nBits ) // result is in pAdd0 +void Wlc_BlastSubtract( Gia_Man_t * pNew, int * pAdd0, int * pAdd1, int nBits, int Carry ) // result is in pAdd0 { - int b, Carry = 1; + int b; for ( b = 0; b < nBits; b++ ) Wlc_BlastFullAdder( pNew, pAdd0[b], Abc_LitNot(pAdd1[b]), Carry, &Carry, &pAdd0[b] ); } @@ -375,7 +381,7 @@ void Wlc_BlastAdderCLA_rec( Gia_Man_t * pNew, int * pGen, int * pPro, int * pCar Wlc_BlastAdderCLA_one( pNew, pGen2, pPro2, pCar, pGen1, pPro1, pCar+nBits/2 ); // returns *pGen1, *pPro1, pCar[nBits/2] } } -void Wlc_BlastAdderCLA( Gia_Man_t * pNew, int * pAdd0, int * pAdd1, int nBits ) // result is in pAdd0 +void Wlc_BlastAdderCLA_int( Gia_Man_t * pNew, int * pAdd0, int * pAdd1, int nBits, int CarryIn ) // result is in pAdd0 { int * pGen = ABC_CALLOC( int, nBits ); int * pPro = ABC_CALLOC( int, nBits ); @@ -383,12 +389,12 @@ void Wlc_BlastAdderCLA( Gia_Man_t * pNew, int * pAdd0, int * pAdd1, int nBits ) int b, Gen, Pro; if ( nBits == 1 ) { - int Carry = 0; + int Carry = CarryIn; Wlc_BlastFullAdder( pNew, pAdd0[0], pAdd1[0], Carry, &Carry, &pAdd0[0] ); return; } assert( nBits >= 2 ); - pCar[0] = 0; + pCar[0] = CarryIn; for ( b = 0; b < nBits; b++ ) { pGen[b] = Gia_ManHashAnd(pNew, pAdd0[b], pAdd1[b]); @@ -401,6 +407,117 @@ void Wlc_BlastAdderCLA( Gia_Man_t * pNew, int * pAdd0, int * pAdd1, int nBits ) ABC_FREE(pPro); ABC_FREE(pCar); } +void Wlc_BlastAdderCLA( Gia_Man_t * pNew, int * pAdd0, int * pAdd1, int nBits, int fSign, int CarryIn ) // result is in pAdd0 +{ + int i, Log2 = Abc_Base2Log(nBits); + int * pAdd0n = ABC_CALLOC( int, 1<<Log2 ); + int * pAdd1n = ABC_CALLOC( int, 1<<Log2 ); + for ( i = 0; i < nBits; i++ ) + { + pAdd0n[i] = pAdd0[i]; + pAdd1n[i] = pAdd1[i]; + } + for ( ; i < (1<<Log2); i++ ) + { + pAdd0n[i] = fSign ? pAdd0[nBits-1] : 0; + pAdd1n[i] = fSign ? pAdd1[nBits-1] : 0; + } + Wlc_BlastAdderCLA_int( pNew, pAdd0n, pAdd1n, 1<<Log2, CarryIn ); + for ( i = 0; i < nBits; i++ ) + pAdd0[i] = pAdd0n[i]; + ABC_FREE(pAdd0n); + ABC_FREE(pAdd1n); +} + +void Wlc_BlastAdderFast_int( Gia_Man_t * pNew, int * pAdd0, int * pAdd1, int Log2, int CarryIn ) // result is in pAdd0 +{ + int i, b, Gen, Pro, nBits = 1 << Log2; + int * pGen = ABC_CALLOC( int, nBits+1 ); + int * pPro = ABC_CALLOC( int, nBits+1 ); + int * pPro2= ABC_CALLOC( int, nBits+1 ); + if ( nBits == 1 ) + { + int Carry = CarryIn; + Wlc_BlastFullAdder( pNew, pAdd0[0], pAdd1[0], Carry, &Carry, &pAdd0[0] ); + ABC_FREE(pGen); + ABC_FREE(pPro); + ABC_FREE(pPro2); + return; + } + assert( nBits >= 2 ); + pGen[0] = CarryIn; + pPro[0] = 0; + pPro2[0]= 0; + for ( b = 1; b <= nBits; b++ ) + { + pGen[b] = Gia_ManHashAnd(pNew, pAdd0[b-1], pAdd1[b-1]); + pPro[b] = Gia_ManHashXor(pNew, pAdd0[b-1], pAdd1[b-1]); + pPro2[b]= pPro[b]; + } + + // Han-Carlson adder from http://www.aoki.ecei.tohoku.ac.jp/arith/mg/algorithm.html + for ( b = 1; b <= nBits; b += 2 ) + { + Gen = Gia_ManHashOr( pNew, pGen[b], Gia_ManHashAnd(pNew, pPro[b], pGen[b-1]) ); + Pro = Gia_ManHashAnd(pNew, pPro[b], pPro[b-1]); + pPro[b] = Pro; + pGen[b] = Gen; + } + for ( i = 1; i < Log2-1; i++ ) + { + for ( b = 1 + 2*i; b <= nBits; b += 2 ) + { + Gen = Gia_ManHashOr( pNew, pGen[b], Gia_ManHashAnd(pNew, pPro[b], pGen[b-i*2]) ); + Pro = Gia_ManHashAnd(pNew, pPro[b], pPro[b-i*2]); + pPro[b] = Pro; + pGen[b] = Gen; + } + } + for ( b = nBits/2 + 1; b <= nBits; b += 2 ) + { + Gen = Gia_ManHashOr( pNew, pGen[b], Gia_ManHashAnd(pNew, pPro[b], pGen[b-nBits/2]) ); + Pro = Gia_ManHashAnd(pNew, pPro[b], pPro[b-nBits/2]); + pPro[b] = Pro; + pGen[b] = Gen; + } + for ( b = 2; b <= nBits; b += 2 ) + { + Gen = Gia_ManHashOr( pNew, pGen[b], Gia_ManHashAnd(pNew, pPro[b], pGen[b-1]) ); + Pro = Gia_ManHashAnd(pNew, pPro[b], pPro[b-1]); + pPro[b] = Pro; + pGen[b] = Gen; + } + + for ( b = 0; b < nBits; b++ ) + pAdd0[b] = Gia_ManHashXor(pNew, pPro2[b+1], pGen[b]); + pAdd0[nBits] = pGen[nBits]; + + ABC_FREE(pGen); + ABC_FREE(pPro); + ABC_FREE(pPro2); +} +void Wlc_BlastAdderFast( Gia_Man_t * pNew, int * pAdd0, int * pAdd1, int nBits, int fSign, int CarryIn ) // result is in pAdd0 +{ + int i, Log2 = Abc_Base2Log(nBits); + int * pAdd0n = ABC_CALLOC( int, (1<<Log2)+1 ); + int * pAdd1n = ABC_CALLOC( int, (1<<Log2)+1 ); + for ( i = 0; i < nBits; i++ ) + { + pAdd0n[i] = pAdd0[i]; + pAdd1n[i] = pAdd1[i]; + } + for ( ; i < (1<<Log2); i++ ) + { + pAdd0n[i] = fSign ? pAdd0[nBits-1] : 0; + pAdd1n[i] = fSign ? pAdd1[nBits-1] : 0; + } + Wlc_BlastAdderFast_int( pNew, pAdd0n, pAdd1n, Log2, CarryIn ); + for ( i = 0; i <= nBits; i++ ) + pAdd0[i] = pAdd0n[i]; + ABC_FREE(pAdd0n); + ABC_FREE(pAdd1n); +} + void Wlc_BlastMinus( Gia_Man_t * pNew, int * pNum, int nNum, Vec_Int_t * vRes ) { int * pRes = Wlc_VecCopy( vRes, pNum, nNum ); @@ -700,7 +817,7 @@ void Wlc_BlastPrintMatrix( Gia_Man_t * p, Vec_Wec_t * vProds ) Vec_IntFree( vSupp ); Vec_WrdFree( vTemp ); } -void Wlc_BlastReduceMatrix( Gia_Man_t * pNew, Vec_Wec_t * vProds, Vec_Wec_t * vLevels, Vec_Int_t * vRes ) +void Wlc_BlastReduceMatrix( Gia_Man_t * pNew, Vec_Wec_t * vProds, Vec_Wec_t * vLevels, Vec_Int_t * vRes, int fSigned, int fCla ) { Vec_Int_t * vLevel, * vProd; int i, NodeS, NodeC, LevelS, LevelC, Node1, Node2, Node3, Level1, Level2, Level3; @@ -758,9 +875,112 @@ void Wlc_BlastReduceMatrix( Gia_Man_t * pNew, Vec_Wec_t * vProds, Vec_Wec_t * vL } Vec_IntPush( vRes, 0 ); Vec_IntPush( vLevel, 0 ); - Wlc_BlastAdder( pNew, Vec_IntArray(vRes), Vec_IntArray(vLevel), Vec_IntSize(vRes), 0 ); + + if ( fCla ) + Wlc_BlastAdderCLA( pNew, Vec_IntArray(vRes), Vec_IntArray(vLevel), Vec_IntSize(vRes), fSigned, 0 ); + else + Wlc_BlastAdder( pNew, Vec_IntArray(vRes), Vec_IntArray(vLevel), Vec_IntSize(vRes), 0 ); +} + +int Wlc_BlastAddLevel( Gia_Man_t * pNew, int Start ) +{ + int i; + if ( Start == 0 ) + Gia_ManCleanLevels( pNew, 5 * Gia_ManObjNum(pNew) ); + for ( i = Start; i < Gia_ManObjNum(pNew); i++ ) + { + Gia_Obj_t * pObj = Gia_ManObj( pNew, i ); + if ( Gia_ObjIsAnd(pObj) ) + Gia_ObjSetAndLevel( pNew, pObj ); + } + return Gia_ManObjNum(pNew); +} +void Wlc_IntInsert2( Gia_Man_t * pNew, Vec_Int_t * vProd, int iLit ) +{ + int i, Entry, Level = Gia_ObjLevelId(pNew, Abc_Lit2Var(iLit)); + Vec_IntForEachEntryReverse( vProd, Entry, i ) + if ( Gia_ObjLevelId(pNew, Abc_Lit2Var(Entry)) >= Level ) + break; + Vec_IntInsert( vProd, i + 1, iLit ); +// Vec_IntForEachEntry( vProd, Entry, i ) +// printf( "Obj=%d(%d) ", Abc_Lit2Var(Entry), Gia_ObjLevelId(pNew, Abc_Lit2Var(Entry)) ); +// printf( "\n" ); +} +void Wlc_IntSortCostReverse( Gia_Man_t * pNew, int * pArray, int nSize ) +{ + int i, j, best_i; + for ( i = 0; i < nSize-1; i++ ) + { + best_i = i; + for ( j = i+1; j < nSize; j++ ) + if ( Gia_ObjLevelId(pNew, Abc_Lit2Var(pArray[j])) > Gia_ObjLevelId(pNew, Abc_Lit2Var(pArray[best_i])) ) + best_i = j; + ABC_SWAP( int, pArray[i], pArray[best_i] ); + } +} +void Wlc_BlastReduceMatrix2( Gia_Man_t * pNew, Vec_Wec_t * vProds, Vec_Int_t * vRes, int fSigned, int fCla ) +{ + Vec_Int_t * vProd, * vTemp; + int i, NodeS, NodeC, Node1, Node2, Node3; + int Start = Wlc_BlastAddLevel( pNew, 0 ); + int nSize = Vec_WecSize(vProds); + Vec_WecForEachLevel( vProds, vProd, i ) + Wlc_IntSortCostReverse( pNew, Vec_IntArray(vProd), Vec_IntSize(vProd) ); + for ( i = 0; i < nSize; i++ ) + { + while ( 1 ) + { + vProd = Vec_WecEntry( vProds, i ); + if ( Vec_IntSize(vProd) < 3 ) + break; + + Node1 = Vec_IntPop( vProd ); + Node2 = Vec_IntPop( vProd ); + Node3 = Vec_IntPop( vProd ); + + assert( Gia_ObjLevelId(pNew, Abc_Lit2Var(Node3)) >= Gia_ObjLevelId(pNew, Abc_Lit2Var(Node2)) ); + assert( Gia_ObjLevelId(pNew, Abc_Lit2Var(Node2)) >= Gia_ObjLevelId(pNew, Abc_Lit2Var(Node1)) ); + + Wlc_BlastFullAdder( pNew, Node1, Node2, Node3, &NodeC, &NodeS ); + Start = Wlc_BlastAddLevel( pNew, Start ); + + Wlc_IntInsert2( pNew, vProd, NodeS ); + + vProd = Vec_WecEntry( vProds, i+1 ); + Wlc_IntInsert2( pNew, vProd, NodeC ); + } + } + + // make all ranks have two products + for ( i = 0; i < nSize; i++ ) + { + vProd = Vec_WecEntry( vProds, i ); + while ( Vec_IntSize(vProd) < 2 ) + Vec_IntPush( vProd, 0 ); + assert( Vec_IntSize(vProd) == 2 ); + } +// Vec_WecPrint( vProds, 0 ); + + Vec_IntClear( vRes ); + vTemp = Vec_IntAlloc( 100 ); + for ( i = 0; i < nSize; i++ ) + { + vProd = Vec_WecEntry( vProds, i ); + Vec_IntPush( vRes, Vec_IntEntry(vProd, 0) ); + Vec_IntPush( vTemp, Vec_IntEntry(vProd, 1) ); + } + Vec_IntPush( vRes, 0 ); + Vec_IntPush( vTemp, 0 ); + + if ( fCla ) + Wlc_BlastAdderCLA( pNew, Vec_IntArray(vRes), Vec_IntArray(vTemp), Vec_IntSize(vRes), fSigned, 0 ); + else + Wlc_BlastAdder( pNew, Vec_IntArray(vRes), Vec_IntArray(vTemp), Vec_IntSize(vRes), 0 ); + Vec_IntFree( vTemp ); } -void Wlc_BlastMultiplier3( Gia_Man_t * pNew, int * pArgA, int * pArgB, int nArgA, int nArgB, Vec_Int_t * vRes ) + + +void Wlc_BlastMultiplier3( Gia_Man_t * pNew, int * pArgA, int * pArgB, int nArgA, int nArgB, Vec_Int_t * vRes, int fSigned, int fCla ) { Vec_Wec_t * vProds = Vec_WecStart( nArgA + nArgB ); Vec_Wec_t * vLevels = Vec_WecStart( nArgA + nArgB ); @@ -768,11 +988,21 @@ void Wlc_BlastMultiplier3( Gia_Man_t * pNew, int * pArgA, int * pArgB, int nArgA for ( i = 0; i < nArgA; i++ ) for ( k = 0; k < nArgB; k++ ) { - Vec_WecPush( vProds, i+k, Gia_ManHashAnd(pNew, pArgA[i], pArgB[k]) ); + int fCompl = fSigned && ((i == nArgA-1) ^ (k == nArgB-1)); + Vec_WecPush( vProds, i+k, Abc_LitNotCond(Gia_ManHashAnd(pNew, pArgA[i], pArgB[k]), fCompl) ); Vec_WecPush( vLevels, i+k, 0 ); } + if ( fSigned ) + { + Vec_WecPush( vProds, nArgA, 1 ); + Vec_WecPush( vLevels, nArgA, 0 ); + + Vec_WecPush( vProds, nArgA+nArgB-1, 1 ); + Vec_WecPush( vLevels, nArgA+nArgB-1, 0 ); + } - Wlc_BlastReduceMatrix( pNew, vProds, vLevels, vRes ); + Wlc_BlastReduceMatrix( pNew, vProds, vLevels, vRes, fSigned, fCla ); +// Wlc_BlastReduceMatrix2( pNew, vProds, vRes, fSigned, fCla ); Vec_WecFree( vProds ); Vec_WecFree( vLevels ); @@ -797,12 +1027,24 @@ void Wlc_BlastSquare( Gia_Man_t * pNew, int * pNum, int nNum, Vec_Int_t * vTmp, } } - Wlc_BlastReduceMatrix( pNew, vProds, vLevels, vRes ); + Wlc_BlastReduceMatrix( pNew, vProds, vLevels, vRes, 0, 0 ); Vec_WecFree( vProds ); Vec_WecFree( vLevels ); } -void Wlc_BlastBooth( Gia_Man_t * pNew, int * pArgA, int * pArgB, int nArgA, int nArgB, Vec_Int_t * vRes, int fSigned ) +void Wlc_BlastDecoder( Gia_Man_t * pNew, int * pNum, int nNum, Vec_Int_t * vTmp, Vec_Int_t * vRes ) +{ + int i, k, nMints = 1 << nNum; + Vec_IntClear( vRes ); + for ( i = 0; i < nMints; i++ ) + { + int iMint = 1; + for ( k = 0; k < nNum; k++ ) + iMint = Gia_ManHashAnd( pNew, iMint, Abc_LitNotCond(pNum[k], !((i >> k) & 1)) ); + Vec_IntPush( vRes, iMint ); + } +} +void Wlc_BlastBooth( Gia_Man_t * pNew, int * pArgA, int * pArgB, int nArgA, int nArgB, Vec_Int_t * vRes, int fSigned, int fCla ) { Vec_Wec_t * vProds = Vec_WecStart( nArgA + nArgB + 3 ); Vec_Wec_t * vLevels = Vec_WecStart( nArgA + nArgB + 3 ); @@ -871,7 +1113,8 @@ void Wlc_BlastBooth( Gia_Man_t * pNew, int * pArgA, int * pArgB, int nArgA, int //Vec_WecPrint( vProds, 0 ); //Wlc_BlastPrintMatrix( pNew, vProds ); //printf( "Cutoff ID for partial products = %d.\n", Gia_ManObjNum(pNew) ); - Wlc_BlastReduceMatrix( pNew, vProds, vLevels, vRes ); + Wlc_BlastReduceMatrix( pNew, vProds, vLevels, vRes, fSigned, fCla ); +// Wlc_BlastReduceMatrix2( pNew, vProds, vRes, fSigned, fCla ); Vec_WecFree( vProds ); Vec_WecFree( vLevels ); @@ -897,13 +1140,15 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Wlc_BstPar_t * pParIn ) Tim_Man_t * pManTime = NULL; If_LibBox_t * pBoxLib = NULL; Vec_Ptr_t * vTables = NULL; + Vec_Int_t * vFf2Ci = Vec_IntAlloc( 100 ); + Vec_Int_t * vRegClasses = NULL; Gia_Man_t * pTemp, * pNew, * pExtra = NULL; Wlc_Obj_t * pObj, * pObj2; Vec_Int_t * vBits = &p->vBits, * vTemp0, * vTemp1, * vTemp2, * vRes, * vAddOutputs = NULL, * vAddObjs = NULL; int nBits = Wlc_NtkPrepareBits( p ); - int nRange, nRange0, nRange1, nRange2; - int i, k, b, iFanin, iLit, nAndPrev, * pFans0, * pFans1, * pFans2; - int nFFins = 0, nFFouts = 0, curPi = 0, curPo = 0; + int nRange, nRange0, nRange1, nRange2, nRange3; + int i, k, b, iFanin, iLit, nAndPrev, * pFans0, * pFans1, * pFans2, * pFans3; + int nFFins = 0, nFFouts = 0, curPi = 0, curPo = 0, nFf2Regs = 0; int nBitCis = 0, nBitCos = 0, fAdded = 0; Wlc_BstPar_t Par, * pPar = &Par; Wlc_BstParDefault( pPar ); @@ -930,6 +1175,7 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Wlc_BstPar_t * pParIn ) if ( pPar->vBoxIds ) { int nNewCis = 0, nNewCos = 0; + assert( Vec_IntSize(&p->vFfs2) == 0 ); Wlc_NtkForEachObj( p, pObj, i ) pObj->Mark = 0; // count bit-width of regular CIs/COs @@ -961,6 +1207,61 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Wlc_BstPar_t * pParIn ) // create box library pBoxLib = If_LibBoxStart(); } + if ( Vec_IntSize(&p->vFfs2) > 0 ) + { + Vec_Int_t * vSignature; + int nNewCis = 0, nNewCos = 0; + assert( pPar->vBoxIds == 0 ); + // count bit-width of regular CIs/COs + Wlc_NtkForEachCi( p, pObj, i ) + nBitCis += Wlc_ObjRange( pObj ); + Wlc_NtkForEachCo( p, pObj, i ) + nBitCos += Wlc_ObjRange( pObj ); + // count bit-width of additional CIs/COs due to selected multipliers + Wlc_NtkForEachFf2( p, pObj, i ) + { + // currently works only for multipliers + assert( pObj->Type == WLC_OBJ_FF ); + assert( Wlc_ObjRange(pObj) == Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)) ); + nNewCis += Wlc_ObjRange(pObj); + nNewCos += 2*Wlc_ObjRange(pObj) + 3; + nFf2Regs+= Wlc_ObjRange(pObj); + } + // create hierarchy manager + pManTime = Tim_ManStart( nBitCis + nNewCis + nFf2Regs, nBitCos + nNewCos + nFf2Regs ); + curPi = nBitCis + nFf2Regs; + curPo = 0; + // create AIG manager for logic of the boxes + pExtra = Gia_ManStart( Wlc_NtkObjNum(p) ); + Gia_ManHashAlloc( pExtra ); + assert( !pPar->fGiaSimple ); + // create register classes + vRegClasses = Vec_IntAlloc(0); + vSignature = Vec_IntAlloc( 100 ); + Vec_IntPushTwo( vSignature, -1, -1 ); + Wlc_NtkForEachFf2( p, pObj, i ) + { + int iClk0, iClk = Wlc_ObjFaninId( pObj, 1 ); + int iAsyn0, iAsyn = Wlc_ObjFaninId( pObj, 5 ); + nRange = Wlc_ObjRange(pObj); + Vec_IntForEachEntryDouble( vSignature, iClk0, iAsyn0, k ) + if ( iClk == iClk0 && iAsyn == iAsyn0 ) + { + for ( b = 0; b < nRange; b++ ) + Vec_IntPush( vRegClasses, k/2 ); + break; + } + if ( k < Vec_IntSize(vSignature) ) + continue; + for ( b = 0; b < nRange; b++ ) + Vec_IntPush( vRegClasses, k/2 ); + Vec_IntPushTwo( vSignature, iClk, iAsyn ); + } + assert( Vec_IntSize(vRegClasses) == nFf2Regs ); + Vec_IntFree( vSignature ); + // create box library + pBoxLib = If_LibBoxStart(); + } // blast in the topological order Wlc_NtkForEachObj( p, pObj, i ) { @@ -972,9 +1273,11 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Wlc_BstPar_t * pParIn ) nRange0 = Wlc_ObjFaninNum(pObj) > 0 ? Wlc_ObjRange( Wlc_ObjFanin0(p, pObj) ) : -1; nRange1 = Wlc_ObjFaninNum(pObj) > 1 ? Wlc_ObjRange( Wlc_ObjFanin1(p, pObj) ) : -1; nRange2 = Wlc_ObjFaninNum(pObj) > 2 ? Wlc_ObjRange( Wlc_ObjFanin2(p, pObj) ) : -1; - pFans0 = Wlc_ObjFaninNum(pObj) > 0 ? Vec_IntEntryP( vBits, Wlc_ObjCopy(p, Wlc_ObjFaninId0(pObj)) ) : NULL; - pFans1 = Wlc_ObjFaninNum(pObj) > 1 ? Vec_IntEntryP( vBits, Wlc_ObjCopy(p, Wlc_ObjFaninId1(pObj)) ) : NULL; - pFans2 = Wlc_ObjFaninNum(pObj) > 2 ? Vec_IntEntryP( vBits, Wlc_ObjCopy(p, Wlc_ObjFaninId2(pObj)) ) : NULL; + nRange3 = Wlc_ObjFaninNum(pObj) > 3 ? Wlc_ObjRange( Wlc_ObjFanin(p, pObj, 3) ) : -1; + pFans0 = pObj->Type != WLC_OBJ_FF && Wlc_ObjFaninNum(pObj) > 0 ? Vec_IntEntryP( vBits, Wlc_ObjCopy(p, Wlc_ObjFaninId0(pObj)) ) : NULL; + pFans1 = pObj->Type != WLC_OBJ_FF && Wlc_ObjFaninNum(pObj) > 1 ? Vec_IntEntryP( vBits, Wlc_ObjCopy(p, Wlc_ObjFaninId1(pObj)) ) : NULL; + pFans2 = pObj->Type != WLC_OBJ_FF && Wlc_ObjFaninNum(pObj) > 2 ? Vec_IntEntryP( vBits, Wlc_ObjCopy(p, Wlc_ObjFaninId2(pObj)) ) : NULL; + pFans3 = pObj->Type != WLC_OBJ_FF && Wlc_ObjFaninNum(pObj) > 3 ? Vec_IntEntryP( vBits, Wlc_ObjCopy(p, Wlc_ObjFaninId(pObj,3)) ) : NULL; Vec_IntClear( vRes ); assert( nRange > 0 ); if ( pPar->vBoxIds && pObj->Mark ) @@ -1043,7 +1346,7 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Wlc_BstPar_t * pParIn ) if ( pObj->Type == WLC_OBJ_ARI_ADD ) Wlc_BlastAdder( pExtra, pArg0, pArg1, nRange, CarryIn ); // result is in pFan0 (vRes) else - Wlc_BlastSubtract( pExtra, pArg0, pArg1, nRange ); // result is in pFan0 (vRes) + Wlc_BlastSubtract( pExtra, pArg0, pArg1, nRange, 1 ); // result is in pFan0 (vRes) Vec_IntShrink( vRes, nRange ); } else if ( fUseOldMultiplierBlasting ) @@ -1078,13 +1381,15 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Wlc_BstPar_t * pParIn ) // add box to the library sprintf( Buffer, "%s%03d", pObj->Type == WLC_OBJ_ARI_ADD ? "add":"mul", 1+If_LibBoxNum(pBoxLib) ); - pBox = If_BoxStart( Abc_UtilStrsav(Buffer), 1+If_LibBoxNum(pBoxLib), nRange, nRange0 + nRange1 + nRange2, 0, 0, 0 ); + pBox = If_BoxStart( Abc_UtilStrsav(Buffer), 1+If_LibBoxNum(pBoxLib), nRange0 + nRange1 + nRange2, nRange, 0, 0, 0 ); If_LibBoxAdd( pBoxLib, pBox ); for ( k = 0; k < pBox->nPis * pBox->nPos; k++ ) pBox->pDelays[k] = 1; } - else if ( Wlc_ObjIsCi(pObj) ) + else if ( Wlc_ObjIsCi(pObj) || pObj->Type == WLC_OBJ_FF ) // assuming that FFs are ordered immediately after PIs { + if ( pObj->Type == WLC_OBJ_FF ) + Vec_IntPush( vFf2Ci, Gia_ManCiNum(pNew) ); if ( Wlc_ObjRangeIsReversed(pObj) ) { for ( k = 0; k < nRange; k++ ) @@ -1099,6 +1404,10 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Wlc_BstPar_t * pParIn ) } if ( pObj->Type == WLC_OBJ_FO ) nFFouts += Vec_IntSize(vRes); + if ( pObj->Type == WLC_OBJ_FF ) + { + // complement flop output whose init state is 1 + } } else if ( pObj->Type == WLC_OBJ_BUF ) { @@ -1391,12 +1700,31 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Wlc_BstPar_t * pParIn ) int * pArg1 = Wlc_VecLoadFanins( vTemp1, pFans1, nRange1, nRangeMax, Wlc_ObjIsSignedFanin01(p, pObj) ); int CarryIn = Wlc_ObjFaninNum(pObj) == 3 ? pFans2[0] : 0; if ( pObj->Type == WLC_OBJ_ARI_ADD ) - Wlc_BlastAdder( pNew, pArg0, pArg1, nRange, CarryIn ); // result is in pFan0 (vRes) -// Wlc_BlastAdderCLA( pNew, pArg0, pArg1, nRange ); // result is in pFan0 (vRes) + { + if ( pPar->fCla ) + Wlc_BlastAdderCLA( pNew, pArg0, pArg1, nRangeMax, Wlc_ObjIsSignedFanin01(p, pObj), CarryIn ); // result is in pFan0 (vRes) + //Wlc_BlastAdderFast( pNew, pArg0, pArg1, nRangeMax, Wlc_ObjIsSignedFanin01(p, pObj), CarryIn ); // result is in pFan0 (vRes) + else + Wlc_BlastAdder( pNew, pArg0, pArg1, nRangeMax, CarryIn ); // result is in pFan0 (vRes) + } else - Wlc_BlastSubtract( pNew, pArg0, pArg1, nRange ); // result is in pFan0 (vRes) + Wlc_BlastSubtract( pNew, pArg0, pArg1, nRange, 1 ); // result is in pFan0 (vRes) Vec_IntShrink( vRes, nRange ); } + else if ( pObj->Type == WLC_OBJ_ARI_ADDSUB ) + { + int nRangeMax = Abc_MaxInt( nRange, Abc_MaxInt(nRange2, nRange3) ); + int * pArg0 = Wlc_VecLoadFanins( vTemp0, pFans2, nRange2, nRangeMax, Wlc_ObjIsSignedFanin01(p, pObj) ); + int * pArg1 = Wlc_VecLoadFanins( vTemp1, pFans2, nRange2, nRangeMax, Wlc_ObjIsSignedFanin01(p, pObj) ); + int * pArg2 = Wlc_VecLoadFanins( vTemp2, pFans3, nRange3, nRangeMax, Wlc_ObjIsSignedFanin01(p, pObj) ); + int ModeIn = pFans0[0]; + int CarryIn = pFans1[0]; int j; + Wlc_BlastAdder ( pNew, pArg0, pArg2, nRangeMax, CarryIn ); // result is in pArg0 (vTemp0) + Wlc_BlastSubtract( pNew, pArg1, pArg2, nRangeMax, Abc_LitNot(CarryIn) ); // result is in pArg1 (vTemp1) + Vec_IntClear( vRes ); + for ( j = 0; j < nRange; j++ ) + Vec_IntPush( vRes, Gia_ManHashMux(pNew, ModeIn, pArg0[j], pArg1[j]) ); + } else if ( pObj->Type == WLC_OBJ_ARI_MULTI ) { if ( fUseOldMultiplierBlasting ) @@ -1416,10 +1744,11 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Wlc_BstPar_t * pParIn ) if ( Wlc_NtkCountConstBits(pArg0, nRangeMax) < Wlc_NtkCountConstBits(pArg1, nRangeMax) ) ABC_SWAP( int *, pArg0, pArg1 ); if ( pPar->fBooth ) - Wlc_BlastBooth( pNew, pArg0, pArg1, nRange0, nRange1, vRes, fSigned ); + Wlc_BlastBooth( pNew, pArg0, pArg1, nRange0, nRange1, vRes, fSigned, pPar->fCla ); + else if ( pPar->fCla ) + Wlc_BlastMultiplier3( pNew, pArg0, pArg1, nRange0, nRange1, vRes, Wlc_ObjIsSignedFanin01(p, pObj), pPar->fCla ); else Wlc_BlastMultiplier( pNew, pArg0, pArg1, nRangeMax, nRangeMax, vTemp2, vRes, fSigned ); - //Wlc_BlastMultiplier3( pNew, pArg0, pArg1, nRange0, nRange1, vRes ); if ( nRange > Vec_IntSize(vRes) ) Vec_IntFillExtra( vRes, nRange, fSigned ? Vec_IntEntryLast(vRes) : 0 ); else @@ -1475,6 +1804,15 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Wlc_BstPar_t * pParIn ) else Vec_IntShrink( vRes, nRange ); } + else if ( pObj->Type == WLC_OBJ_DEC ) + { + int * pArg0 = Wlc_VecLoadFanins( vTemp0, pFans0, nRange0, nRange0, 0 ); + Wlc_BlastDecoder( pNew, pArg0, nRange0, vTemp2, vRes ); + if ( nRange > Vec_IntSize(vRes) ) + Vec_IntFillExtra( vRes, nRange, 0 ); + else + Vec_IntShrink( vRes, nRange ); + } else if ( pObj->Type == WLC_OBJ_TABLE ) Wlc_BlastTable( pNew, Wlc_ObjTable(p, pObj), pFans0, nRange0, nRange, vRes ); else assert( 0 ); @@ -1499,6 +1837,102 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Wlc_BstPar_t * pParIn ) Vec_IntFree( vTemp1 ); Vec_IntFree( vTemp2 ); Vec_IntFree( vRes ); + // create flop boxes + Wlc_NtkForEachFf2( p, pObj, i ) + { + If_Box_t * pBox; + char Buffer[100]; + float * pTable; + Vec_Int_t * vTemp0 = Vec_IntAlloc( 100 ); + Vec_Int_t * vTemp1 = Vec_IntAlloc( 100 ); + int iLit, nRange = Wlc_ObjRange(pObj); + int * pFans0, * pFans1, * pFans2, * pFans3; + int iReset, iSet, iEnable; + int nRangeIn = 2*nRange + 3; // D, reset, set, enable, Q + int iSre = Wlc_ObjFaninId(pObj, 6); + + assert( pObj->Type == WLC_OBJ_FF ); + + // create new box + if ( vTables == NULL ) + Tim_ManSetDelayTables( pManTime, (vTables = Vec_PtrAlloc(100)) ); + Tim_ManCreateBox( pManTime, curPo, nRangeIn, curPi, nRange, Vec_PtrSize(vTables), 0 ); + curPi += nRange; + curPo += nRangeIn; + + // create delay table + pTable = ABC_ALLOC( float, 3 + nRange * nRangeIn ); + pTable[0] = Vec_PtrSize(vTables); + pTable[1] = nRangeIn; + pTable[2] = nRange; + for ( k = 0; k < nRange * nRangeIn; k++ ) + pTable[3 + k] = 1.0; + Vec_PtrPush( vTables, pTable ); + + // create combinational outputs in the normal manager + pFans0 = Wlc_ObjFaninNum(pObj) > 0 ? Vec_IntEntryP( vBits, Wlc_ObjCopy(p, Wlc_ObjFaninId0(pObj)) ) : NULL; + pFans1 = Wlc_ObjFaninNum(pObj) > 1 ? Vec_IntEntryP( vBits, Wlc_ObjCopy(p, Wlc_ObjFaninId1(pObj)) ) : NULL; + pFans2 = Wlc_ObjFaninNum(pObj) > 2 ? Vec_IntEntryP( vBits, Wlc_ObjCopy(p, Wlc_ObjFaninId2(pObj)) ) : NULL; + pFans3 = Wlc_ObjFaninNum(pObj) > 3 ? Vec_IntEntryP( vBits, Wlc_ObjCopy(p, Wlc_ObjFaninId(pObj,3)) ) : NULL; + for ( k = 0; k < nRange; k++ ) + Gia_ManAppendCo( pNew, pFans0[k] ); + Gia_ManAppendCo( pNew, pFans1[0] ); + Gia_ManAppendCo( pNew, pFans2[0] ); + Gia_ManAppendCo( pNew, pFans3[0] ); + for ( k = 0; k < nRange; k++ ) + Gia_ManAppendCo( pNew, Gia_Obj2Lit(pNew, Gia_ManCi(pNew, Vec_IntEntry(vFf2Ci, i)+k)) ); + + // make sure there is enough primary inputs in the manager + for ( k = Gia_ManPiNum(pExtra); k < nRangeIn; k++ ) + Gia_ManAppendCi( pExtra ); + // create combinational inputs + for ( k = 0; k < nRange; k++ ) + Vec_IntPush( vTemp0, Gia_Obj2Lit(pExtra, Gia_ManPi(pExtra, k)) ); + iReset = Gia_Obj2Lit(pExtra, Gia_ManPi(pExtra, nRange+0)); + iSet = Gia_Obj2Lit(pExtra, Gia_ManPi(pExtra, nRange+1)); + iEnable = Gia_Obj2Lit(pExtra, Gia_ManPi(pExtra, nRange+2)); + for ( k = 0; k < nRange; k++ ) + Vec_IntPush( vTemp1, Gia_Obj2Lit(pExtra, Gia_ManPi(pExtra, nRangeIn-nRange+k)) ); + + // bit-blast in the external manager + for ( k = 0; k < nRange; k++ ) + { + // enable + //iLitFlop = Gia_LitNotCond( Gia_ObjCopy(pObj), Gia_FlopIsOne(pObj) ); + //iLit = Gia_ManHashMux( Gia_ObjGia(pObj), Gia_FlopEnableCopy(pObj), iLit, iLitFlop ); + iLit = Gia_ManHashMux( pExtra, iEnable, Vec_IntEntry(vTemp0, k), Vec_IntEntry(vTemp1, k) ); + if ( iSre ) + { + // reset + //iLit = Gia_ManHashAnd( Gia_ObjGia(pObj), iLit, Gia_LitNot(Gia_FlopResetCopy(pObj)) ); + iLit = Gia_ManHashAnd( pExtra, iLit, Abc_LitNot(iReset) ); + // set + //iLit = Gia_ManHashOr( Gia_ObjGia(pObj), iLit, Gia_FlopSetCopy(pObj) ); + iLit = Gia_ManHashOr( pExtra, iLit, iSet ); + } + else + { + // set + //iLit = Gia_ManHashOr( Gia_ObjGia(pObj), iLit, Gia_FlopSetCopy(pObj) ); + iLit = Gia_ManHashOr( pExtra, iLit, iSet ); + // reset + //iLit = Gia_ManHashAnd( Gia_ObjGia(pObj), iLit, Gia_LitNot(Gia_FlopResetCopy(pObj)) ); + iLit = Gia_ManHashAnd( pExtra, iLit, Abc_LitNot(iReset) ); + } + // create outputs in the external manager + Gia_ManAppendCo( pExtra, iLit ); + } + + // add box to the library + sprintf( Buffer, "%s%03d", "ff_comb", 1+If_LibBoxNum(pBoxLib) ); + pBox = If_BoxStart( Abc_UtilStrsav(Buffer), 1+If_LibBoxNum(pBoxLib), nRangeIn, nRange, 0, 0, 0 ); + If_LibBoxAdd( pBoxLib, pBox ); + for ( k = 0; k < pBox->nPis * pBox->nPos; k++ ) + pBox->pDelays[k] = 1; + Vec_IntFree( vTemp0 ); + Vec_IntFree( vTemp1 ); + } + Vec_IntFree( vFf2Ci ); // create COs if ( pPar->fCreateMiter ) { @@ -1588,8 +2022,19 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Wlc_BstPar_t * pParIn ) //Vec_IntErase( vBits ); //Vec_IntErase( &p->vCopies ); // set the number of registers - assert( nFFins == nFFouts ); - Gia_ManSetRegNum( pNew, nFFins ); + if ( Vec_IntSize(&p->vFfs2) > 0 ) + { + assert( nFFins == 0 && nFFouts == 0 ); + // complement flop inputs whose init state is 1 + for ( i = 0; i < nFf2Regs; i++ ) + Gia_ManAppendCo( pNew, Gia_ManAppendCi(pNew) ); + //Gia_ManSetRegNum( pNew, nFf2Regs ); + } + else + { + assert( nFFins == nFFouts ); + Gia_ManSetRegNum( pNew, nFFins ); + } // finalize AIG if ( !pPar->fGiaSimple && !pPar->fNoCleanup ) { @@ -1614,6 +2059,24 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Wlc_BstPar_t * pParIn ) } } // finalize AIG with boxes + if ( Vec_IntSize(&p->vFfs2) > 0 ) + { + curPo += nBitCos + nFf2Regs; + assert( curPi == Tim_ManCiNum(pManTime) ); + assert( curPo == Tim_ManCoNum(pManTime) ); + // finalize the extra AIG + pExtra = Gia_ManCleanup( pTemp = pExtra ); + Gia_ManStop( pTemp ); + assert( Gia_ManPoNum(pExtra) == Gia_ManCiNum(pNew) - nBitCis - nFf2Regs ); + // attach + pNew->pAigExtra = pExtra; + pNew->pManTime = pManTime; + // normalize AIG + pNew = Gia_ManDupNormalize( pTemp = pNew, 0 ); + Gia_ManTransferTiming( pNew, pTemp ); + Gia_ManStop( pTemp ); + //Tim_ManPrint( pManTime ); + } if ( pPar->vBoxIds ) { curPo += nBitCos; @@ -1622,7 +2085,7 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Wlc_BstPar_t * pParIn ) // finalize the extra AIG pExtra = Gia_ManCleanup( pTemp = pExtra ); Gia_ManStop( pTemp ); - assert( Gia_ManPoNum(pExtra) == Gia_ManCiNum(pNew) - nBitCis ); + assert( Gia_ManPoNum(pExtra) == Gia_ManCiNum(pNew) - nBitCis - nFf2Regs ); // attach pNew->pAigExtra = pExtra; pNew->pManTime = pManTime; @@ -1676,6 +2139,38 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Wlc_BstPar_t * pParIn ) Vec_PtrPush( pNew->vNamesIn, Abc_UtilStrsav(Buffer) ); } } + Wlc_NtkForEachFf2( p, pObj, i ) + { + char * pName = Wlc_ObjName(p, Wlc_ObjId(p, pObj)); + nRange = Wlc_ObjRange( pObj ); + if ( fSkipBitRange && nRange == 1 ) + { + char Buffer[1000]; + sprintf( Buffer, "%s_fo", pName ); + Vec_PtrPush( pNew->vNamesIn, Abc_UtilStrsav(Buffer) ); + } + else + for ( k = 0; k < nRange; k++ ) + { + char Buffer[1000]; + sprintf( Buffer, "%s_fo[%d]", pName, k ); + Vec_PtrPush( pNew->vNamesIn, Abc_UtilStrsav(Buffer) ); + } + } + Wlc_NtkForEachFf2( p, pObj, i ) + { + char * pName = Wlc_ObjName(p, Wlc_ObjId(p, pObj)); + nRange = Wlc_ObjRange( pObj ); + if ( fSkipBitRange && nRange == 1 ) + Vec_PtrPush( pNew->vNamesIn, Abc_UtilStrsav(pName) ); + else + for ( k = 0; k < nRange; k++ ) + { + char Buffer[1000]; + sprintf( Buffer, "%s[%d]", pName, k ); + Vec_PtrPush( pNew->vNamesIn, Abc_UtilStrsav(Buffer) ); + } + } if ( p->pInits && fAdded ) Vec_PtrPush( pNew->vNamesIn, Abc_UtilStrsav("abc_reset_flop") ); if ( pPar->vBoxIds ) @@ -1696,6 +2191,43 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Wlc_BstPar_t * pParIn ) assert( Vec_PtrSize(pNew->vNamesIn) == Gia_ManCiNum(pNew) ); // create output names pNew->vNamesOut = Vec_PtrAlloc( Gia_ManCoNum(pNew) ); + Wlc_NtkForEachFf2( p, pObj, i ) + { + int iFanin; + Wlc_ObjForEachFanin( pObj, iFanin, b ) + { + char * pName = Wlc_ObjName(p, iFanin); + nRange = Wlc_ObjRange( Wlc_NtkObj(p, iFanin) ); + if ( fSkipBitRange && nRange == 1 ) + Vec_PtrPush( pNew->vNamesOut, Abc_UtilStrsav(pName) ); + else + for ( k = 0; k < nRange; k++ ) + { + char Buffer[1000]; + sprintf( Buffer, "%s[%d]", pName, k ); + Vec_PtrPush( pNew->vNamesOut, Abc_UtilStrsav(Buffer) ); + } + if ( b == 3 ) + break; + } + { + char * pName = Wlc_ObjName(p, Wlc_ObjId(p, pObj)); + nRange = Wlc_ObjRange( pObj ); + if ( fSkipBitRange && nRange == 1 ) + { + char Buffer[1000]; + sprintf( Buffer, "%s_in", pName ); + Vec_PtrPush( pNew->vNamesOut, Abc_UtilStrsav(Buffer) ); + } + else + for ( k = 0; k < nRange; k++ ) + { + char Buffer[1000]; + sprintf( Buffer, "%s_in[%d]", pName, k ); + Vec_PtrPush( pNew->vNamesOut, Abc_UtilStrsav(Buffer) ); + } + } + } if ( pPar->vBoxIds ) { Wlc_NtkForEachObjVec( pPar->vBoxIds, p, pObj, i ) @@ -1786,6 +2318,24 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Wlc_BstPar_t * pParIn ) Vec_PtrPush( pNew->vNamesOut, Abc_UtilStrsav(Buffer) ); } } + Wlc_NtkForEachFf2( p, pObj, i ) + { + char * pName = Wlc_ObjName(p, Wlc_ObjId(p, pObj)); + nRange = Wlc_ObjRange( pObj ); + if ( fSkipBitRange && nRange == 1 ) + { + char Buffer[1000]; + sprintf( Buffer, "%s_fi", pName ); + Vec_PtrPush( pNew->vNamesOut, Abc_UtilStrsav(Buffer) ); + } + else + for ( k = 0; k < nRange; k++ ) + { + char Buffer[1000]; + sprintf( Buffer, "%s_fi[%d]", pName, k ); + Vec_PtrPush( pNew->vNamesOut, Abc_UtilStrsav(Buffer) ); + } + } assert( Vec_PtrSize(pNew->vNamesOut) == Gia_ManCoNum(pNew) ); // replace the current library @@ -1815,11 +2365,14 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Wlc_BstPar_t * pParIn ) ABC_FREE( pNameGeneric ); printf( "Dumped two parts of the miter into files \"%s\" and \"%s\".\n", pFileName0, pFileName1 ); } + //Wlc_NtkPrintNameArray( pNew->vNamesIn ); + //Wlc_NtkPrintNameArray( pNew->vNamesOut ); if ( pPar->vBoxIds ) { - Vec_PtrFreeP( &pNew->vNamesIn ); - Vec_PtrFreeP( &pNew->vNamesOut ); + Vec_PtrFreeFree( pNew->vNamesIn ); pNew->vNamesIn = NULL; + Vec_PtrFreeFree( pNew->vNamesOut ); pNew->vNamesOut = NULL; } + pNew->vRegClasses = vRegClasses; return pNew; } diff --git a/src/base/wlc/wlcCom.c b/src/base/wlc/wlcCom.c index 711763c7..5b99cb00 100644 --- a/src/base/wlc/wlcCom.c +++ b/src/base/wlc/wlcCom.c @@ -38,7 +38,9 @@ static int Abc_CommandPdrAbs ( Abc_Frame_t * pAbc, int argc, char ** argv ) static int Abc_CommandAbs2 ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandMemAbs ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandBlast ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandBlastMem ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandGraft ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandRetime ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandProfile ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandShortNames ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandShow ( Abc_Frame_t * pAbc, int argc, char ** argv ); @@ -82,7 +84,9 @@ void Wlc_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "Word level", "%abs2", Abc_CommandAbs2, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%memabs", Abc_CommandMemAbs, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%blast", Abc_CommandBlast, 0 ); + Cmd_CommandAdd( pAbc, "Word level", "%blastmem", Abc_CommandBlastMem, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%graft", Abc_CommandGraft, 0 ); + Cmd_CommandAdd( pAbc, "Word level", "%retime", Abc_CommandRetime, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%profile", Abc_CommandProfile, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%short_names", Abc_CommandShortNames, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%show", Abc_CommandShow, 0 ); @@ -967,12 +971,12 @@ usage: int Abc_CommandBlast( Abc_Frame_t * pAbc, int argc, char ** argv ) { Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc); - Gia_Man_t * pNew = NULL; int c; + Gia_Man_t * pNew = NULL; int c, fMiter = 0, fDumpNames = 0; Wlc_BstPar_t Par, * pPar = &Par; Wlc_BstParDefault( pPar ); pPar->nOutputRange = 2; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "ORAMcombdsvh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "ORAMcombadstnvh" ) ) != EOF ) { switch ( c ) { @@ -1032,12 +1036,22 @@ int Abc_CommandBlast( Abc_Frame_t * pAbc, int argc, char ** argv ) case 'b': pPar->fBooth ^= 1; break; + case 'a': + pPar->fCla ^= 1; + break; case 'd': pPar->fCreateMiter ^= 1; break; case 's': pPar->fDecMuxes ^= 1; break; + case 't': + pPar->fCreateMiter ^= 1; + fMiter ^= 1; + break; + case 'n': + fDumpNames ^= 1; + break; case 'v': pPar->fVerbose ^= 1; break; @@ -1080,10 +1094,31 @@ int Abc_CommandBlast( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_Print( 1, "Abc_CommandBlast(): Bit-blasting has failed.\n" ); return 0; } + // generate miter + if ( fMiter ) + { + Gia_Man_t * pTemp = pNew; + pNew = Gia_ManTransformMiter( pNew ); + Gia_ManStop( pTemp ); + Abc_Print( 1, "Bit-blasting created a traditional multi-output miter by XORing POs pair-wise.\n" ); + if ( fDumpNames ) + { + int i; char * pName; + FILE * pFile = fopen( "pio_name_map.txt", "wb" ); + if ( pNew->vNamesIn ) + Vec_PtrForEachEntry( char *, pNew->vNamesIn, pName, i ) + fprintf( pFile, "i%d %s\n", i, pName ); + if ( pNew->vNamesOut ) + Vec_PtrForEachEntry( char *, pNew->vNamesOut, pName, i ) + fprintf( pFile, "o%d %s\n", i, pName ); + fclose( pFile ); + Abc_Print( 1, "Finished dumping file \"pio_name_map.txt\" containing PI/PO name mapping.\n" ); + } + } Abc_FrameUpdateGia( pAbc, pNew ); return 0; usage: - Abc_Print( -2, "usage: %%blast [-ORAM num] [-combdsvh]\n" ); + Abc_Print( -2, "usage: %%blast [-ORAM num] [-combadstnvh]\n" ); Abc_Print( -2, "\t performs bit-blasting of the word-level design\n" ); Abc_Print( -2, "\t-O num : zero-based index of the first word-level PO to bit-blast [default = %d]\n", pPar->iOutput ); Abc_Print( -2, "\t-R num : the total number of word-level POs to bit-blast [default = %d]\n", pPar->nOutputRange ); @@ -1093,8 +1128,11 @@ usage: Abc_Print( -2, "\t-o : toggle using additional POs on the word-level boundaries [default = %s]\n", pPar->fAddOutputs? "yes": "no" ); Abc_Print( -2, "\t-m : toggle creating boxes for all multipliers in the design [default = %s]\n", pPar->fMulti? "yes": "no" ); Abc_Print( -2, "\t-b : toggle generating radix-4 Booth multipliers [default = %s]\n", pPar->fBooth? "yes": "no" ); - Abc_Print( -2, "\t-d : toggle creating dual-output miter [default = %s]\n", pPar->fCreateMiter? "yes": "no" ); + Abc_Print( -2, "\t-a : toggle generating carry-look-ahead adder [default = %s]\n", pPar->fCla? "yes": "no" ); + Abc_Print( -2, "\t-d : toggle creating dual-output multi-output miter [default = %s]\n", pPar->fCreateMiter? "yes": "no" ); Abc_Print( -2, "\t-s : toggle creating decoded MUXes [default = %s]\n", pPar->fDecMuxes? "yes": "no" ); + Abc_Print( -2, "\t-t : toggle creating regular multi-output miter [default = %s]\n", fMiter? "yes": "no" ); + Abc_Print( -2, "\t-n : toggle dumping signal names into a text file [default = %s]\n", fDumpNames? "yes": "no" ); Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", pPar->fVerbose? "yes": "no" ); Abc_Print( -2, "\t-h : print the command usage\n"); return 1; @@ -1111,6 +1149,52 @@ usage: SeeAlso [] ******************************************************************************/ +int Abc_CommandBlastMem( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + extern Wlc_Ntk_t * Wlc_NtkMemBlast( Wlc_Ntk_t * p ); + Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc); + int c, fVerbose = 0; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF ) + { + switch ( c ) + { + case 'v': + fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + if ( pNtk == NULL ) + { + Abc_Print( 1, "Abc_CommandBlastMem(): There is no current design.\n" ); + return 0; + } + pNtk = Wlc_NtkMemBlast( pNtk ); + Wlc_AbcUpdateNtk( pAbc, pNtk ); + return 0; +usage: + Abc_Print( -2, "usage: %%blastmem [-vh]\n" ); + Abc_Print( -2, "\t performs blasting of memory read/write ports\n" ); + Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-h : print the command usage\n"); + return 1; +} + +/**Function******************************************************************** + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ int Abc_CommandGraft( Abc_Frame_t * pAbc, int argc, char ** argv ) { extern Wlc_Ntk_t * Wlc_NtkGraftMulti( Wlc_Ntk_t * p, int fVerbose ); @@ -1157,6 +1241,63 @@ usage: SeeAlso [] ******************************************************************************/ +int Abc_CommandRetime( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + extern void Wln_NtkRetimeTest( char * pFileName ); + FILE * pFile; + char * pFileName = NULL; + int c, fVerbose = 0; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF ) + { + switch ( c ) + { + case 'v': + fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + if ( argc != globalUtilOptind + 1 ) + { + printf( "Abc_CommandRetime(): Input file name should be given on the command line.\n" ); + return 0; + } + // get the file name + pFileName = argv[globalUtilOptind]; + if ( (pFile = fopen( pFileName, "r" )) == NULL ) + { + Abc_Print( 1, "Cannot open input file \"%s\". ", pFileName ); + if ( (pFileName = Extra_FileGetSimilarName( pFileName, ".ndr", NULL, NULL, NULL, NULL )) ) + Abc_Print( 1, "Did you mean \"%s\"?", pFileName ); + Abc_Print( 1, "\n" ); + return 0; + } + fclose( pFile ); + Wln_NtkRetimeTest( pFileName ); + return 0; +usage: + Abc_Print( -2, "usage: %%retime [-vh]\n" ); + Abc_Print( -2, "\t performs retiming for the NDR design\n" ); + Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-h : print the command usage\n"); + return 1; +} + +/**Function******************************************************************** + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ int Abc_CommandProfile( Abc_Frame_t * pAbc, int argc, char ** argv ) { Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc); @@ -1672,7 +1813,7 @@ int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv ) //Wlc_NtkSimulateTest( (Wlc_Ntk_t *)pAbc->pAbcWlc ); //pNtk = Wlc_NtkDupSingleNodes( pNtk ); //Wlc_AbcUpdateNtk( pAbc, pNtk ); - Ndr_ModuleTestSelSel(); + //Wln_ReadNdrTest(); //pNtk = Wlc_NtkMemAbstractTest( pNtk ); //Wlc_AbcUpdateNtk( pAbc, pNtk ); return 0; diff --git a/src/base/wlc/wlcMem.c b/src/base/wlc/wlcMem.c index b310afb6..ccc319e5 100644 --- a/src/base/wlc/wlcMem.c +++ b/src/base/wlc/wlcMem.c @@ -35,6 +35,133 @@ ABC_NAMESPACE_IMPL_START /**Function************************************************************* + Synopsis [Memory blasting.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Wlc_NtkMemBlast_rec( Wlc_Ntk_t * pNew, Wlc_Ntk_t * p, int iObj, Vec_Int_t * vFanins ) +{ + Wlc_Obj_t * pObj; + int i, iFanin; + if ( Wlc_ObjCopy(p, iObj) ) + return; + pObj = Wlc_NtkObj( p, iObj ); + Wlc_ObjForEachFanin( pObj, iFanin, i ) + Wlc_NtkMemBlast_rec( pNew, p, iFanin, vFanins ); + if ( pObj->Type == WLC_OBJ_WRITE ) + { + Vec_Int_t * vTemp = Vec_IntAlloc( 1 ); + Vec_Int_t * vBits = Vec_IntAlloc( 100 ); + Wlc_Obj_t * pMem = Wlc_ObjFanin0(p, pObj); + Wlc_Obj_t * pAddr = Wlc_ObjFanin1(p, pObj); + Wlc_Obj_t * pData = Wlc_ObjFanin2(p, pObj); + int DataW = Wlc_ObjRange(pData); + int AddrW = Wlc_ObjRange(pAddr); + int nRegs = 1 << AddrW, iObjNew, iObjDec; + assert( nRegs * DataW == Wlc_ObjRange(pMem) ); + assert( Wlc_ObjRange(pObj) == Wlc_ObjRange(pMem) ); + // create decoder + iObjDec = Wlc_ObjAlloc( pNew, WLC_OBJ_DEC, 0, nRegs-1, 0 ); + Vec_IntFill( vTemp, 1, Wlc_ObjCopy(p, Wlc_ObjId(p, pAddr)) ); + Wlc_ObjAddFanins( pNew, Wlc_NtkObj(pNew, iObjDec), vTemp ); + // create decoder bits + for ( i = 0; i < nRegs; i++ ) + { + int iObj2 = Wlc_ObjAlloc( pNew, WLC_OBJ_BIT_SELECT, 0, i, i ); + Vec_IntFill( vTemp, 1, iObjDec ); + Vec_IntPushTwo( vTemp, i, i ); + Wlc_ObjAddFanins( pNew, Wlc_NtkObj(pNew, iObj2), vTemp ); + Vec_IntPush( vBits, iObj2 ); + } + // create data words + Vec_IntClear( vFanins ); + for ( i = 0; i < nRegs; i++ ) + { + int iObj2 = Wlc_ObjAlloc( pNew, WLC_OBJ_BIT_SELECT, 0, i*DataW+DataW-1, i*DataW ); + Vec_IntFill( vTemp, 1, Wlc_ObjCopy(p, Wlc_ObjId(p, pMem)) ); + Vec_IntPushTwo( vTemp, i*DataW+DataW-1, i*DataW ); + Wlc_ObjAddFanins( pNew, Wlc_NtkObj(pNew, iObj2), vTemp ); + Vec_IntPush( vFanins, iObj2 ); + } + // create MUXes of data words controlled by decoder bits + for ( i = 0; i < nRegs; i++ ) + { + int iObj2 = Wlc_ObjAlloc( pNew, WLC_OBJ_MUX, 0, DataW-1, 0 ); + Vec_IntFill( vTemp, 1, Vec_IntEntry(vBits, i) ); + Vec_IntPushTwo( vTemp, Wlc_ObjCopy(p, Wlc_ObjId(p, pData)), Vec_IntEntry(vFanins, i) ); + Wlc_ObjAddFanins( pNew, Wlc_NtkObj(pNew, iObj2), vTemp ); + Vec_IntWriteEntry( vFanins, i, iObj2 ); + } + // concatenate the results + iObjNew = Wlc_ObjAlloc( pNew, WLC_OBJ_BIT_CONCAT, 0, nRegs*DataW-1, 0 ); + Wlc_ObjAddFanins( pNew, Wlc_NtkObj(pNew, iObjNew), vFanins ); + Wlc_ObjSetCopy( p, iObj, iObjNew ); + Vec_IntFree( vTemp ); + Vec_IntFree( vBits ); + } + else if ( pObj->Type == WLC_OBJ_READ ) + { + Vec_Int_t * vTemp = Vec_IntAlloc( 1 ); + Wlc_Obj_t * pMem = Wlc_ObjFanin0(p, pObj); + Wlc_Obj_t * pAddr = Wlc_ObjFanin1(p, pObj); + int DataW = Wlc_ObjRange(pObj); + int AddrW = Wlc_ObjRange(pAddr); + int nRegs = 1 << AddrW, iObjNew; + assert( nRegs * DataW == Wlc_ObjRange(pMem) ); + Vec_IntClear( vFanins ); + Vec_IntPush( vFanins, Wlc_ObjCopy(p, Wlc_ObjId(p, pAddr)) ); + for ( i = 0; i < nRegs; i++ ) + { + int iObj2 = Wlc_ObjAlloc( pNew, WLC_OBJ_BIT_SELECT, 0, i*DataW+DataW-1, i*DataW ); + Vec_IntFill( vTemp, 1, Wlc_ObjCopy(p, Wlc_ObjId(p, pMem)) ); + Vec_IntPushTwo( vTemp, i*DataW+DataW-1, i*DataW ); + Wlc_ObjAddFanins( pNew, Wlc_NtkObj(pNew, iObj2), vTemp ); + Vec_IntPush( vFanins, iObj2 ); + } + iObjNew = Wlc_ObjAlloc( pNew, WLC_OBJ_MUX, 0, DataW-1, 0 ); + Wlc_ObjAddFanins( pNew, Wlc_NtkObj(pNew, iObjNew), vFanins ); + Wlc_ObjSetCopy( p, iObj, iObjNew ); + Vec_IntFree( vTemp ); + } + else + Wlc_ObjDup( pNew, p, iObj, vFanins ); +} +Wlc_Ntk_t * Wlc_NtkMemBlast( Wlc_Ntk_t * p ) +{ + Wlc_Ntk_t * pNew; + Wlc_Obj_t * pObj; + Vec_Int_t * vFanins; + int i; + Wlc_NtkCleanCopy( p ); + vFanins = Vec_IntAlloc( 100 ); + pNew = Wlc_NtkAlloc( p->pName, p->nObjsAlloc ); + pNew->fSmtLib = p->fSmtLib; + pNew->fMemPorts = p->fMemPorts; + pNew->fEasyFfs = p->fEasyFfs; + Wlc_NtkForEachCi( p, pObj, i ) + Wlc_ObjDup( pNew, p, Wlc_ObjId(p, pObj), vFanins ); + Wlc_NtkForEachCo( p, pObj, i ) + Wlc_NtkMemBlast_rec( pNew, p, Wlc_ObjId(p, pObj), vFanins ); + Wlc_NtkForEachCo( p, pObj, i ) + Wlc_ObjSetCo( pNew, Wlc_ObjCopyObj(pNew, p, pObj), pObj->fIsFi ); + if ( p->vInits ) + pNew->vInits = Vec_IntDup( p->vInits ); + if ( p->pInits ) + pNew->pInits = Abc_UtilStrsav( p->pInits ); + Vec_IntFree( vFanins ); + if ( p->pSpec ) + pNew->pSpec = Abc_UtilStrsav( p->pSpec ); + return pNew; +} + + +/**Function************************************************************* + Synopsis [Collect memory nodes.] Description [] @@ -827,7 +954,7 @@ int Wlc_NtkMemAbstract( Wlc_Ntk_t * p, int nIterMax, int fDumpAbs, int fPdrVerbo Vec_Wec_t * vRefines = Vec_WecAlloc( 100 ); Vec_Int_t * vNodeFrames = Vec_IntAlloc( 100 ); Vec_Int_t * vMemObjs, * vMemFanins, * vFirstTotal, * vRefine; - int RetValue, iFirstMemPi, iFirstCi, iFirstMemCi, nDcBits, nIters; + int RetValue = -1, iFirstMemPi, iFirstCi, iFirstMemCi, nDcBits, nIters; vMemObjs = Wlc_NtkCollectMemory( p ); vMemFanins = Wlc_NtkCollectMemFanins( p, vMemObjs ); diff --git a/src/base/wlc/wlcNdr.c b/src/base/wlc/wlcNdr.c index 3e6600c3..16c7d778 100644 --- a/src/base/wlc/wlcNdr.c +++ b/src/base/wlc/wlcNdr.c @@ -71,6 +71,7 @@ int Ndr_TypeNdr2Wlc( int Type ) if ( Type == ABC_OPER_LOGIC_XOR ) return WLC_OBJ_LOGIC_XOR; // 30: logic XOR if ( Type == ABC_OPER_SEL_NMUX ) return WLC_OBJ_MUX; // 08: multiplexer if ( Type == ABC_OPER_SEL_SEL ) return WLC_OBJ_SEL; // 57: selector + if ( Type == ABC_OPER_SEL_DEC ) return WLC_OBJ_DEC; // 58: decoder if ( Type == ABC_OPER_COMP_EQU ) return WLC_OBJ_COMP_EQU; // 31: compare equal if ( Type == ABC_OPER_COMP_NOTEQU ) return WLC_OBJ_COMP_NOTEQU; // 32: compare not equal if ( Type == ABC_OPER_COMP_LESS ) return WLC_OBJ_COMP_LESS; // 33: compare less @@ -129,6 +130,7 @@ int Ndr_TypeWlc2Ndr( int Type ) if ( Type == WLC_OBJ_LOGIC_OR ) return ABC_OPER_LOGIC_OR; // 29: logic OR if ( Type == WLC_OBJ_LOGIC_XOR ) return ABC_OPER_LOGIC_XOR; // 30: logic XOR if ( Type == WLC_OBJ_SEL ) return ABC_OPER_SEL_SEL; // 57: selector + if ( Type == WLC_OBJ_DEC ) return ABC_OPER_SEL_DEC; // 58: decoder if ( Type == WLC_OBJ_COMP_EQU ) return ABC_OPER_COMP_EQU; // 31: compare equal if ( Type == WLC_OBJ_COMP_NOTEQU ) return ABC_OPER_COMP_NOTEQU; // 32: compare not equal if ( Type == WLC_OBJ_COMP_LESS ) return ABC_OPER_COMP_LESS; // 33: compare less @@ -342,9 +344,10 @@ void Wlc_NtkCheckIntegrity( void * pData ) } 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 ) + 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 ); @@ -396,6 +399,8 @@ Wlc_Ntk_t * Wlc_NtkFromNdr( void * pData ) Vec_IntPush( &pNtk->vFfs, Vec_IntEntry(vFanins, 0) ); continue; } + if ( Type == ABC_OPER_DFFRSE ) + Vec_IntPush( &pNtk->vFfs2, iObj ); if ( Type == ABC_OPER_SLICE ) Vec_IntPushTwo( vFanins, End, Beg ); else if ( Type == ABC_OPER_CONST ) @@ -467,6 +472,7 @@ Wlc_Ntk_t * Wlc_NtkFromNdr( void * pData ) assert( !fFound && i == NameId ); } //Ndr_NtkPrintNodes( pNtk ); + //Wlc_WriteVer( pNtk, "temp_ndr.v", 0, 0 ); // derive topological order pNtk = Wlc_NtkDupDfs( pTemp = pNtk, 0, 1 ); Wlc_NtkFree( pTemp ); diff --git a/src/base/wlc/wlcNtk.c b/src/base/wlc/wlcNtk.c index b8a4b9b1..4ac0c66c 100644 --- a/src/base/wlc/wlcNtk.c +++ b/src/base/wlc/wlcNtk.c @@ -87,7 +87,10 @@ static char * Wlc_Names[WLC_OBJ_NUMBER+1] = { "table", // 53: bit table "READ", // 54: mem read port "WRITE", // 55: mem write port - NULL // 56: unused + "addsub", // 56: adder/subtractor + "sel", // 57: selector + "dec", // 58: decoder + NULL // 58: unused }; char * Wlc_ObjTypeName( Wlc_Obj_t * p ) { return Wlc_Names[p->Type]; } @@ -261,6 +264,7 @@ void Wlc_NtkFree( Wlc_Ntk_t * p ) ABC_FREE( p->vCis.pArray ); ABC_FREE( p->vCos.pArray ); ABC_FREE( p->vFfs.pArray ); + ABC_FREE( p->vFfs2.pArray ); Vec_IntFreeP( &p->vInits ); ABC_FREE( p->vTravIds.pArray ); ABC_FREE( p->vNameIds.pArray ); @@ -283,6 +287,7 @@ int Wlc_NtkMemUsage( Wlc_Ntk_t * p ) Mem += 4 * p->vCis.nCap; Mem += 4 * p->vCos.nCap; Mem += 4 * p->vFfs.nCap; + Mem += 4 * p->vFfs2.nCap; Mem += sizeof(Wlc_Obj_t) * p->nObjsAlloc; Mem += Abc_NamMemUsed(p->pManName); Mem += Mem_FlexReadMemUsage(p->pMemFanin); @@ -637,6 +642,11 @@ void Wlc_NtkPrintNode( Wlc_Ntk_t * p, Wlc_Obj_t * pObj ) printf( "FO\n" ); return; } + if ( pObj->Type != WLC_OBJ_CONST && Wlc_ObjFaninNum(pObj) == 0 ) + { + printf( "Unknown object without fanins\n" ); + return; + } if ( pObj->Type != WLC_OBJ_CONST ) { printf( "%6d%s %5s ", Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)), Wlc_ObjIsSigned(Wlc_ObjFanin0(p, pObj)) ? "s" : " ", Wlc_Names[(int)pObj->Type] ); @@ -858,10 +868,13 @@ void Wlc_NtkDupDfs_rec( Wlc_Ntk_t * pNew, Wlc_Ntk_t * p, int iObj, Vec_Int_t * v { Wlc_Obj_t * pObj; int i, iFanin; + if ( iObj == 0 ) + return; if ( Wlc_ObjCopy(p, iObj) ) return; //printf( "Visiting node %d\n", iObj ); pObj = Wlc_NtkObj( p, iObj ); + assert( pObj->Type != WLC_OBJ_FF ); Wlc_ObjForEachFanin( pObj, iFanin, i ) Wlc_NtkDupDfs_rec( pNew, p, iFanin, vFanins ); Wlc_ObjDup( pNew, p, iObj, vFanins ); @@ -898,9 +911,9 @@ Wlc_Ntk_t * Wlc_NtkDupDfsSimple( Wlc_Ntk_t * p ) Wlc_Ntk_t * Wlc_NtkDupDfs( Wlc_Ntk_t * p, int fMarked, int fSeq ) { Wlc_Ntk_t * pNew; - Wlc_Obj_t * pObj; + Wlc_Obj_t * pObj, * pObjNew; Vec_Int_t * vFanins; - int i; + int i, k, iObj, iFanin; vFanins = Vec_IntAlloc( 100 ); Wlc_NtkCleanCopy( p ); pNew = Wlc_NtkAlloc( p->pName, p->nObjsAlloc ); @@ -915,12 +928,28 @@ Wlc_Ntk_t * Wlc_NtkDupDfs( Wlc_Ntk_t * p, int fMarked, int fSeq ) Wlc_ObjDup( pNew, p, Wlc_ObjId(p, pObj), vFanins ); pObj->Type = Type; } + Wlc_NtkForEachFf2( p, pObj, i ) + { + int iObjNew = Wlc_ObjAlloc( pNew, pObj->Type, Wlc_ObjIsSigned(pObj), pObj->End, pObj->Beg ); + Wlc_ObjSetCopy( p, Wlc_ObjId(p, pObj), iObjNew ); + Vec_IntPush( &pNew->vFfs2, iObjNew ); + } Wlc_NtkForEachCo( p, pObj, i ) if ( !fMarked || pObj->Mark ) Wlc_NtkDupDfs_rec( pNew, p, Wlc_ObjId(p, pObj), vFanins ); Wlc_NtkForEachCo( p, pObj, i ) if ( !fMarked || pObj->Mark ) Wlc_ObjSetCo( pNew, Wlc_ObjCopyObj(pNew, p, pObj), fSeq ? pObj->fIsFi : 0 ); + Wlc_NtkForEachFf2( p, pObj, i ) + { + iObj = Wlc_ObjId(p, pObj); + Wlc_ObjForEachFanin( pObj, iFanin, k ) + Wlc_NtkDupDfs_rec( pNew, p, iFanin, vFanins ); + Wlc_ObjCollectCopyFanins( p, iObj, vFanins ); + pObjNew = Wlc_NtkObj( pNew, Wlc_ObjCopy(p, iObj) ); + Wlc_ObjAddFanins( pNew, pObjNew, vFanins ); + pObjNew->fXConst = pObj->fXConst; + } Vec_IntFree( vFanins ); if ( fSeq ) { diff --git a/src/base/wlc/wlcReadVer.c b/src/base/wlc/wlcReadVer.c index 9974dd44..34966777 100644 --- a/src/base/wlc/wlcReadVer.c +++ b/src/base/wlc/wlcReadVer.c @@ -1277,7 +1277,7 @@ startword: } else if ( Wlc_PrsStrCmp( pStart, "ABC_DFFRSE" ) ) { - int NameId[8], fFound, nBits = 1, fFlopIn, fFlopOut, fFlopClk, fFlopRst, fFlopSet, fFlopEna, fFlopAsync, fFlopInit; + int NameId[10] = {0}, fFound, fFlopIn, fFlopClk, fFlopRst, fFlopSet, fFlopEna, fFlopAsync, fFlopSre, fFlopInit, fFlopOut; pStart += strlen("ABC_DFF"); while ( 1 ) { @@ -1286,13 +1286,14 @@ startword: break; pStart = Wlc_PrsSkipSpaces( pStart+1 ); fFlopIn = (pStart[0] == 'd'); - fFlopOut = (pStart[0] == 'q'); fFlopClk = (pStart[0] == 'c'); fFlopRst = (pStart[0] == 'r'); - fFlopSet = (pStart[0] == 's'); + fFlopSet = (pStart[0] == 's' && pStart[1] == 'e'); fFlopEna = (pStart[0] == 'e'); fFlopAsync = (pStart[0] == 'a'); + fFlopSre = (pStart[0] == 's' && pStart[1] == 'r'); fFlopInit = (pStart[0] == 'i'); + fFlopOut = (pStart[0] == 'q'); pStart = Wlc_PrsFindSymbol( pStart, '(' ); if ( pStart == NULL ) return Wlc_PrsWriteErrorMessage( p, pStart, "Cannot read opening parenthesis in the flop description." ); @@ -1301,8 +1302,6 @@ startword: return Wlc_PrsWriteErrorMessage( p, pStart, "Cannot read name inside flop description." ); if ( fFlopIn ) NameId[0] = Abc_NamStrFindOrAdd( p->pNtk->pManName, pName, &fFound ); - else if ( fFlopOut ) - NameId[7] = Abc_NamStrFindOrAdd( p->pNtk->pManName, pName, &fFound ); else if ( fFlopClk ) NameId[1] = Abc_NamStrFindOrAdd( p->pNtk->pManName, pName, &fFound ); else if ( fFlopRst ) @@ -1313,8 +1312,12 @@ startword: NameId[4] = Abc_NamStrFindOrAdd( p->pNtk->pManName, pName, &fFound ); else if ( fFlopAsync ) NameId[5] = Abc_NamStrFindOrAdd( p->pNtk->pManName, pName, &fFound ); - else if ( fFlopInit ) + else if ( fFlopSre ) NameId[6] = Abc_NamStrFindOrAdd( p->pNtk->pManName, pName, &fFound ); + else if ( fFlopInit ) + NameId[7] = Abc_NamStrFindOrAdd( p->pNtk->pManName, pName, &fFound ); + else if ( fFlopOut ) + NameId[8] = Abc_NamStrFindOrAdd( p->pNtk->pManName, pName, &fFound ); else assert( 0 ); if ( !fFound ) @@ -1323,7 +1326,7 @@ startword: if ( NameId[0] == -1 || NameId[7] == -1 ) return Wlc_PrsWriteErrorMessage( p, pStart, "Name of flop input or flop output is missing." ); // create output - pObj = Wlc_NtkObj( p->pNtk, NameId[7] ); + pObj = Wlc_NtkObj( p->pNtk, NameId[8] ); Wlc_ObjUpdateType( p->pNtk, pObj, WLC_OBJ_FF ); Vec_IntClear( p->vFanins ); Vec_IntPush( p->vFanins, NameId[0] ); @@ -1333,6 +1336,7 @@ startword: Vec_IntPush( p->vFanins, NameId[4] ); Vec_IntPush( p->vFanins, NameId[5] ); Vec_IntPush( p->vFanins, NameId[6] ); + Vec_IntPush( p->vFanins, NameId[7] ); Wlc_ObjAddFanins( p->pNtk, pObj, p->vFanins ); } else if ( Wlc_PrsStrCmp( pStart, "ABC_DFF" ) ) @@ -1571,6 +1575,10 @@ Wlc_Ntk_t * Wlc_ReadVer( char * pFileName, char * pStr ) // derive topological order if ( p->pNtk ) { + Wlc_Obj_t * pObj; int i; + Wlc_NtkForEachObj( p->pNtk, pObj, i ) + if ( pObj->Type == WLC_OBJ_FF ) + Vec_IntPush( &p->pNtk->vFfs2, Wlc_ObjId(p->pNtk, pObj) ); pNtk = Wlc_NtkDupDfs( p->pNtk, 0, 1 ); pNtk->pSpec = Abc_UtilStrsav( pFileName ); } diff --git a/src/base/wlc/wlcWriteVer.c b/src/base/wlc/wlcWriteVer.c index dbf24e68..30f10e14 100644 --- a/src/base/wlc/wlcWriteVer.c +++ b/src/base/wlc/wlcWriteVer.c @@ -192,7 +192,7 @@ void Wlc_WriteVerInt( FILE * pFile, Wlc_Ntk_t * p, int fNoFlops ) continue; fprintf( pFile, " assign " ); } - else if ( (pObj->Type == WLC_OBJ_MUX && Wlc_ObjFaninNum(pObj) > 3) || pObj->Type == WLC_OBJ_FF ) + else if ( (pObj->Type == WLC_OBJ_MUX && Wlc_ObjFaninNum(pObj) > 3) || pObj->Type == WLC_OBJ_SEL ) fprintf( pFile, "reg %s ", Range ); else fprintf( pFile, "wire %s ", Range ); @@ -275,12 +275,62 @@ void Wlc_WriteVerInt( FILE * pFile, Wlc_Ntk_t * p, int fNoFlops ) fprintf( pFile, " : %s = ", Wlc_ObjName(p, i) ); fprintf( pFile, "%s ;\n", Wlc_ObjName(p, Wlc_ObjFaninId(pObj, k)) ); } + fprintf( pFile, " " ); + fprintf( pFile, "default" ); + fprintf( pFile, " : %s = ", Wlc_ObjName(p, i) ); + fprintf( pFile, "%d\'b", Wlc_ObjRange(pObj) ); + for ( j = Wlc_ObjRange(pObj)-1; j >= 0; j-- ) + fprintf( pFile, "%d", 0 ); + fprintf( pFile, " ;\n" ); fprintf( pFile, " " ); fprintf( pFile, "endcase\n" ); fprintf( pFile, " " ); fprintf( pFile, "end\n" ); continue; } + else if ( pObj->Type == WLC_OBJ_DEC ) + { + int nRange = Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)); + assert( (1 << nRange) == Wlc_ObjRange(pObj) ); + fprintf( pFile, "%s ;\n", Wlc_ObjName(p, i) ); + for ( k = 0; k < Wlc_ObjRange(pObj); k++ ) + { + fprintf( pFile, " " ); + fprintf( pFile, "wire " ); + fprintf( pFile, "%s_", Wlc_ObjName(p, i) ); + for ( j = 0; j < nRange; j++ ) + fprintf( pFile, "%d", (k >> (nRange-1-j)) & 1 ); + fprintf( pFile, " = " ); + for ( j = 0; j < nRange; j++ ) + fprintf( pFile, "%s%s%s[%d]", + j ? " & ":"", ((k >> (nRange-1-j)) & 1) ? " ":"~", + Wlc_ObjName(p, Wlc_ObjFaninId(pObj, 0)), nRange-1-j ); + fprintf( pFile, " ;\n" ); + } + fprintf( pFile, " " ); + fprintf( pFile, "assign %s = { ", Wlc_ObjName(p, i) ); + for ( k = Wlc_ObjRange(pObj)-1; k >= 0; k-- ) + { + fprintf( pFile, "%s%s_", k < Wlc_ObjRange(pObj)-1 ? ", ":"", Wlc_ObjName(p, i) ); + for ( j = 0; j < nRange; j++ ) + fprintf( pFile, "%d", (k >> (nRange-1-j)) & 1 ); + } + fprintf( pFile, " } ;\n" ); + continue; + } + else if ( pObj->Type == WLC_OBJ_ARI_ADDSUB ) + { + // out = mode ? a+b+cin : a-b-cin + fprintf( pFile, "%s ;\n", Wlc_ObjName(p, i) ); + fprintf( pFile, " " ); + fprintf( pFile, "assign " ); + fprintf( pFile, "%s = %s ? %s + %s + %s : %s - %s - %s ;\n", + Wlc_ObjName(p, i), Wlc_ObjName(p, Wlc_ObjFaninId0(pObj)), + Wlc_ObjName(p, Wlc_ObjFaninId2(pObj)), Wlc_ObjName(p, Wlc_ObjFaninId(pObj,3)), Wlc_ObjName(p, Wlc_ObjFaninId1(pObj)), + Wlc_ObjName(p, Wlc_ObjFaninId2(pObj)), Wlc_ObjName(p, Wlc_ObjFaninId(pObj,3)), Wlc_ObjName(p, Wlc_ObjFaninId1(pObj)) + ); + continue; + } else if ( pObj->Type == WLC_OBJ_READ || pObj->Type == WLC_OBJ_WRITE ) { if ( p->fMemPorts ) @@ -311,13 +361,7 @@ void Wlc_WriteVerInt( FILE * pFile, Wlc_Ntk_t * p, int fNoFlops ) } else if ( pObj->Type == WLC_OBJ_FF ) { - char * pInNames[8] = {"d", "clk", "reset", "set", "enable", "async", "sre", "init"}; fprintf( pFile, "%s ;\n", Wlc_ObjName(p, i) ); - fprintf( pFile, " " ); - fprintf( pFile, "%s (", "ABC_DFFRSE" ); - Wlc_ObjForEachFanin( pObj, iFanin, k ) - fprintf( pFile, " .%s(%s),", pInNames[k], Wlc_ObjName(p, iFanin) ); - fprintf( pFile, " .%s(%s) ) ;\n", "q", Wlc_ObjName(p, i) ); continue; } else @@ -425,7 +469,8 @@ void Wlc_WriteVerInt( FILE * pFile, Wlc_Ntk_t * p, int fNoFlops ) fprintf( pFile, "#" ); else { - assert( 0 ); + //assert( 0 ); + printf( "Failed to write node \"%s\" with unknown operator type (%d).\n", Wlc_ObjName(p, i), pObj->Type ); fprintf( pFile, "???\n" ); continue; } @@ -510,6 +555,18 @@ void Wlc_WriteVerInt( FILE * pFile, Wlc_Ntk_t * p, int fNoFlops ) } assert( !p->vInits || iFanin == (int)strlen(p->pInits) ); } + // write DFFs in the end + fprintf( pFile, "\n" ); + Wlc_NtkForEachFf2( p, pObj, i ) + { + char * pInNames[8] = {"d", "clk", "reset", "set", "enable", "async", "sre", "init"}; + fprintf( pFile, " " ); + fprintf( pFile, "%s (", "ABC_DFFRSE" ); + Wlc_ObjForEachFanin( pObj, iFanin, k ) + if ( iFanin ) fprintf( pFile, " .%s(%s),", pInNames[k], Wlc_ObjName(p, iFanin) ); + fprintf( pFile, " .%s(%s) ) ;\n", "q", Wlc_ObjName(p, Wlc_ObjId(p, pObj)) ); + } + fprintf( pFile, "\n" ); fprintf( pFile, "endmodule\n\n" ); } void Wlc_WriteVer( Wlc_Ntk_t * p, char * pFileName, int fAddCos, int fNoFlops ) diff --git a/src/base/wln/module.make b/src/base/wln/module.make new file mode 100644 index 00000000..6689baf0 --- /dev/null +++ b/src/base/wln/module.make @@ -0,0 +1,6 @@ +SRC += src/base/wln/wln.c \ + src/base/wln/wlnNdr.c \ + src/base/wln/wlnNtk.c \ + src/base/wln/wlnObj.c \ + src/base/wln/wlnRetime.c \ + src/base/wln/wlnWriteVer.c diff --git a/src/base/wln/wln.c b/src/base/wln/wln.c new file mode 100644 index 00000000..2fbe26e0 --- /dev/null +++ b/src/base/wln/wln.c @@ -0,0 +1,51 @@ +/**CFile**************************************************************** + + FileName [wln.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Word-level network.] + + Synopsis [] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - September 23, 2018.] + + Revision [$Id: wln.c,v 1.00 2018/09/23 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "wln.h" + +ABC_NAMESPACE_IMPL_START + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/base/wln/wln.h b/src/base/wln/wln.h new file mode 100644 index 00000000..c862b262 --- /dev/null +++ b/src/base/wln/wln.h @@ -0,0 +1,259 @@ +/**CFile**************************************************************** + + FileName [wlc.h] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Verilog parser.] + + Synopsis [External declarations.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - August 22, 2014.] + + Revision [$Id: wlc.h,v 1.00 2014/09/12 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#ifndef ABC__base__wln__wln_h +#define ABC__base__wln__wln_h + + +//////////////////////////////////////////////////////////////////////// +/// INCLUDES /// +//////////////////////////////////////////////////////////////////////// + +#include "aig/gia/gia.h" +#include "misc/vec/vecHash.h" +#include "misc/extra/extra.h" +#include "misc/util/utilNam.h" +#include "misc/util/utilTruth.h" +#include "aig/miniaig/abcOper.h" + +//////////////////////////////////////////////////////////////////////// +/// PARAMETERS /// +//////////////////////////////////////////////////////////////////////// + +ABC_NAMESPACE_HEADER_START + +//////////////////////////////////////////////////////////////////////// +/// BASIC TYPES /// +//////////////////////////////////////////////////////////////////////// + +typedef struct Wln_Vec_t_ Wln_Vec_t; +struct Wln_Vec_t_ +{ + int nCap; + int nSize; + union { int Array[2]; + int * pArray[1]; }; +}; + +typedef struct Wln_Ntk_t_ Wln_Ntk_t; +struct Wln_Ntk_t_ +{ + char * pName; // model name + char * pSpec; // input file name + int fSmtLib; // derived from SMT-LIB + Vec_Int_t vCis; // combinational inputs + Vec_Int_t vCos; // combinational outputs + Vec_Int_t vFfs; // flops + Vec_Int_t vTypes; // object types + Wln_Vec_t * vFanins; // object fanins (exceptions: const, select) + Vec_Int_t vRanges; // object ranges + Hash_IntMan_t * pRanges; // object ranges + Vec_Int_t vNameIds; // object name IDs + Vec_Int_t vInstIds; // object name IDs + Abc_Nam_t * pManName; // object names + Vec_Str_t vSigns; // object signedness + int nTravIds; // counter of traversal IDs + Vec_Int_t vTravIds; // trav IDs of the objects + Vec_Int_t vCopies; // object first bits + Vec_Int_t vBits; // object mapping into AIG nodes + Vec_Int_t vLevels; // object levels + Vec_Int_t vRefs; // object reference counters + Vec_Int_t vFanout; // static fanout + Vec_Int_t vFaninAttrs; // static fanin attributes + Vec_Int_t vFaninLists; // static fanin attributes + Vec_Ptr_t * vTables; // tables + int nObjs[ABC_OPER_LAST]; // counter of objects of each type + int nAnds[ABC_OPER_LAST]; // counter of AND gates after blasting +}; + +static inline int Wln_NtkObjNum( Wln_Ntk_t * p ) { return Vec_IntSize(&p->vTypes); } +static inline int Wln_NtkCiNum( Wln_Ntk_t * p ) { return Vec_IntSize(&p->vCis); } +static inline int Wln_NtkCoNum( Wln_Ntk_t * p ) { return Vec_IntSize(&p->vCos); } +static inline int Wln_NtkFfNum( Wln_Ntk_t * p ) { return Vec_IntSize(&p->vFfs); } +static inline int Wln_NtkPiNum( Wln_Ntk_t * p ) { return Wln_NtkCiNum(p) - Wln_NtkFfNum(p); } +static inline int Wln_NtkPoNum( Wln_Ntk_t * p ) { return Wln_NtkCoNum(p) - Wln_NtkFfNum(p); } + +static inline int Wln_NtkCi( Wln_Ntk_t * p, int i ) { return Vec_IntEntry(&p->vCis, i); } +static inline int Wln_NtkCo( Wln_Ntk_t * p, int i ) { return Vec_IntEntry(&p->vCos, i); } +static inline int Wln_NtkFf( Wln_Ntk_t * p, int i ) { return Vec_IntEntry(&p->vFfs, i); } + +static inline int Wln_ObjType( Wln_Ntk_t * p, int i ) { return Vec_IntEntry(&p->vTypes, i); } +static inline int Wln_ObjIsNone( Wln_Ntk_t * p, int i ) { return Wln_ObjType(p, i) == ABC_OPER_NONE; } +static inline int Wln_ObjIsCi( Wln_Ntk_t * p, int i ) { return Wln_ObjType(p, i) == ABC_OPER_CI; } +static inline int Wln_ObjIsCo( Wln_Ntk_t * p, int i ) { return Wln_ObjType(p, i) == ABC_OPER_CO; } +static inline int Wln_ObjIsCio( Wln_Ntk_t * p, int i ) { return Wln_ObjType(p, i) == ABC_OPER_CI || Wln_ObjType(p, i)==ABC_OPER_CO; } +static inline int Wln_ObjIsFon( Wln_Ntk_t * p, int i ) { return Wln_ObjType(p, i) == ABC_OPER_FON; } +static inline int Wln_ObjIsFf( Wln_Ntk_t * p, int i ) { return Wln_ObjType(p, i) == ABC_OPER_DFFRSE; } +static inline int Wln_ObjIsConst( Wln_Ntk_t * p, int i ) { return Wln_ObjType(p, i) == ABC_OPER_CONST; } +static inline int Wln_ObjIsSlice( Wln_Ntk_t * p, int i ) { return Wln_ObjType(p, i) == ABC_OPER_SLICE; } +static inline int Wln_ObjIsRotate( Wln_Ntk_t * p, int i ) { return Wln_ObjType(p, i) == ABC_OPER_SHIFT_ROTL || Wln_ObjType(p, i) == ABC_OPER_SHIFT_ROTR; } +static inline int Wln_ObjIsTable( Wln_Ntk_t * p, int i ) { return Wln_ObjType(p, i) == ABC_OPER_TABLE; } + +static inline int Wln_ObjFaninNum( Wln_Ntk_t * p, int i ) { return p->vFanins[i].nSize; } +static inline int * Wln_ObjFanins( Wln_Ntk_t * p, int i ) { return Wln_ObjFaninNum(p, i) > 2 ? p->vFanins[i].pArray[0] : p->vFanins[i].Array; } +static inline int Wln_ObjFanin( Wln_Ntk_t * p, int i, int f ) { return Wln_ObjFaninNum(p, i) > 2 ? p->vFanins[i].pArray[0][f] : p->vFanins[i].Array[f]; } +static inline void Wln_ObjSetFanin( Wln_Ntk_t * p, int i, int f, int v ) { Wln_ObjFanins( p, i )[f] = v; } +static inline int Wln_ObjFanin0( Wln_Ntk_t * p, int i ) { return Wln_ObjFanin( p, i, 0 ); } +static inline int Wln_ObjFanin1( Wln_Ntk_t * p, int i ) { return Wln_ObjFanin( p, i, 1 ); } +static inline int Wln_ObjFanin2( Wln_Ntk_t * p, int i ) { return Wln_ObjFanin( p, i, 2 ); } + +static inline int Wln_ObjRangeId( Wln_Ntk_t * p, int i ) { return Vec_IntEntry( &p->vRanges, i ); } +static inline int Wln_ObjRangeEnd( Wln_Ntk_t * p, int i ) { return Hash_IntObjData0( p->pRanges, Wln_ObjRangeId(p, i) ); } +static inline int Wln_ObjRangeBeg( Wln_Ntk_t * p, int i ) { return Hash_IntObjData1( p->pRanges, Wln_ObjRangeId(p, i) ); } +static inline int Wln_ObjRangeIsReversed( Wln_Ntk_t * p, int i ) { return Wln_ObjRangeEnd(p, i) < Wln_ObjRangeBeg(p, i); } +static inline int Wln_ObjRange( Wln_Ntk_t * p, int i ) { return 1 + Abc_AbsInt(Wln_ObjRangeEnd(p, i)-Wln_ObjRangeBeg(p, i)); } + +static inline int Wln_ObjIsSigned( Wln_Ntk_t * p, int i ) { return (int)Vec_StrEntry(&p->vSigns, i); } +static inline void Wln_ObjSetSigned( Wln_Ntk_t * p, int i ) { Vec_StrSetEntry(&p->vSigns, i, (char)1); } +static inline int Wln_ObjIsSignedFanin0( Wln_Ntk_t * p, int i ) { return Wln_ObjIsSigned( p, p->fSmtLib ? i : Wln_ObjFanin0(p, i) ); } +static inline int Wln_ObjIsSignedFanin1( Wln_Ntk_t * p, int i ) { return Wln_ObjIsSigned( p, p->fSmtLib ? i : Wln_ObjFanin1(p, i) ); } +static inline int Wln_ObjIsSignedFanin01( Wln_Ntk_t * p, int i ) { return Wln_ObjIsSignedFanin0( p, i ) && Wln_ObjIsSignedFanin1( p, i ); } +static inline int Wln_ObjSign( Wln_Ntk_t * p, int i ) { return Abc_Var2Lit( Wln_ObjRange(p, i), Wln_ObjIsSigned(p, i) ); } + +static inline void Wln_NtkCleanCopy( Wln_Ntk_t * p ) { Vec_IntFill( &p->vCopies, Vec_IntCap(&p->vTypes), 0 ); } +static inline int Wln_NtkHasCopy( Wln_Ntk_t * p ) { return Vec_IntSize( &p->vCopies ) > 0; } +static inline void Wln_ObjSetCopy( Wln_Ntk_t * p, int i, int c ) { Vec_IntWriteEntry( &p->vCopies, i, c ); } +static inline int Wln_ObjCopy( Wln_Ntk_t * p, int i ) { return Vec_IntEntry( &p->vCopies, i ); } + +static inline void Wln_NtkCleanLevel( Wln_Ntk_t * p ) { Vec_IntFill( &p->vLevels, Vec_IntCap(&p->vTypes), 0 ); } +static inline int Wln_NtkHasLevel( Wln_Ntk_t * p ) { return Vec_IntSize( &p->vLevels ) > 0; } +static inline void Wln_ObjSetLevel( Wln_Ntk_t * p, int i, int l ) { Vec_IntWriteEntry( &p->vLevels, i, l ); } +static inline int Wln_ObjLevel( Wln_Ntk_t * p, int i ) { return Vec_IntEntry( &p->vLevels, i ); } + +static inline void Wln_NtkCleanNameId( Wln_Ntk_t * p ) { Vec_IntFill( &p->vNameIds, Vec_IntCap(&p->vTypes), 0 ); } +static inline int Wln_NtkHasNameId( Wln_Ntk_t * p ) { return Vec_IntSize( &p->vNameIds ) > 0; } +static inline void Wln_ObjSetNameId( Wln_Ntk_t * p, int i, int n ) { Vec_IntWriteEntry( &p->vNameIds, i, n ); } +static inline int Wln_ObjNameId( Wln_Ntk_t * p, int i ) { return Vec_IntEntry( &p->vNameIds, i ); } + +static inline void Wln_NtkCleanInstId( Wln_Ntk_t * p ) { Vec_IntFill( &p->vInstIds, Vec_IntCap(&p->vTypes), 0 ); } +static inline int Wln_NtkHasInstId( Wln_Ntk_t * p ) { return Vec_IntSize( &p->vInstIds ) > 0; } +static inline void Wln_ObjSetInstId( Wln_Ntk_t * p, int i, int n ) { Vec_IntWriteEntry( &p->vInstIds, i, n ); } +static inline int Wln_ObjInstId( Wln_Ntk_t * p, int i ) { return Vec_IntEntry( &p->vInstIds, i ); } + +static inline void Wln_NtkCleanRefs( Wln_Ntk_t * p ) { Vec_IntFill( &p->vRefs, Vec_IntCap(&p->vTypes), 0 ); } +static inline int Wln_NtkHasRefs( Wln_Ntk_t * p ) { return Vec_IntSize( &p->vRefs ) > 0; } +static inline void Wln_ObjSetRefs( Wln_Ntk_t * p, int i, int n ) { Vec_IntWriteEntry( &p->vRefs, i, n ); } +static inline int Wln_ObjRefs( Wln_Ntk_t * p, int i ) { return Vec_IntEntry( &p->vRefs, i ); } +static inline int Wln_ObjRefsInc( Wln_Ntk_t * p, int i ) { return (*Vec_IntEntryP( &p->vRefs, i ))++; } +static inline int Wln_ObjRefsDec( Wln_Ntk_t * p, int i ) { return --(*Vec_IntEntryP( &p->vRefs, i )); } +static inline void Wln_ObjRefsFaninInc( Wln_Ntk_t * p, int i, int k ) { Wln_ObjRefsInc( p, Wln_ObjFanin(p, i, k) ); } +static inline void Wln_ObjRefsFaninDec( Wln_Ntk_t * p, int i, int k ) { Wln_ObjRefsDec( p, Wln_ObjFanin(p, i, k) ); } + +static inline int Wln_ObjFanoutNum( Wln_Ntk_t * p, int i ) { return Vec_IntEntry( &p->vRefs, i ); } +static inline int * Wln_ObjFanouts( Wln_Ntk_t * p, int i ) { return Vec_IntEntryP( &p->vFanout, Vec_IntEntry(&p->vFanout, i) ); } +static inline int Wln_ObjFanout( Wln_Ntk_t * p, int i, int f ) { return Wln_ObjFanouts( p, i )[f]; } +static inline void Wln_ObjSetFanout( Wln_Ntk_t * p, int i, int f, int v ){ Wln_ObjFanouts( p, i )[f] = v; } + +static inline void Wln_NtkIncrementTravId( Wln_Ntk_t * p ) { if (!p->nTravIds++) Vec_IntFill(&p->vTravIds, Vec_IntCap(&p->vTypes), 0); } +static inline void Wln_ObjSetTravIdCurrent( Wln_Ntk_t * p, int i ) { Vec_IntWriteEntry( &p->vTravIds, i, p->nTravIds ); } +static inline int Wln_ObjIsTravIdCurrent( Wln_Ntk_t * p, int i ) { return (Vec_IntEntry(&p->vTravIds, i) == p->nTravIds); } +static inline int Wln_ObjIsTravIdPrevious( Wln_Ntk_t * p, int i ) { return (Vec_IntEntry(&p->vTravIds, i) == p->nTravIds-1); } +static inline int Wln_ObjCheckTravId( Wln_Ntk_t * p, int i ) { if ( Wln_ObjIsTravIdCurrent(p, i) ) return 1; Wln_ObjSetTravIdCurrent(p, i); return 0; } + +static inline int Wln_ObjCioId( Wln_Ntk_t * p, int i ) { assert( Wln_ObjIsCio(p, i) ); return Wln_ObjFanin1(p, i); } +static inline int Wln_ObjIsPi( Wln_Ntk_t * p, int i ) { return Wln_ObjIsCi(p, i) && Wln_ObjCioId(p, i) < Wln_NtkPiNum(p); } +static inline int Wln_ObjIsPo( Wln_Ntk_t * p, int i ) { return Wln_ObjIsCo(p, i) && Wln_ObjCioId(p, i) < Wln_NtkPoNum(p); } +static inline int Wln_ObjIsRo( Wln_Ntk_t * p, int i ) { return Wln_ObjIsCi(p, i) && Wln_ObjCioId(p, i) >= Wln_NtkPiNum(p); } +static inline int Wln_ObjIsRi( Wln_Ntk_t * p, int i ) { return Wln_ObjIsCo(p, i) && Wln_ObjCioId(p, i) >= Wln_NtkPoNum(p); } +static inline int Wln_ObjRoToRi( Wln_Ntk_t * p, int i ) { assert( Wln_ObjIsRo(p, i) ); return Wln_NtkCo(p, Wln_NtkCoNum(p) - Wln_NtkCiNum(p) + Wln_ObjCioId(p, i)); } +static inline int Wln_ObjRiToRo( Wln_Ntk_t * p, int i ) { assert( Wln_ObjIsRi(p, i) ); return Wln_NtkCi(p, Wln_NtkCiNum(p) - Wln_NtkCoNum(p) + Wln_ObjCioId(p, i)); } + +//////////////////////////////////////////////////////////////////////// +/// MACRO DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// ITERATORS /// +//////////////////////////////////////////////////////////////////////// + +#define Wln_NtkForEachObj( p, i ) \ + for ( i = 1; i < Wln_NtkObjNum(p); i++ ) +#define Wln_NtkForEachObjReverse( p, i ) \ + for ( i = Wln_NtkObjNum(p) - 1; i > 0; i-- ) +#define Wln_NtkForEachObjInternal( p, i ) \ + for ( i = 1; i < Wln_NtkObjNum(p); i++ ) if ( Wln_ObjIsCio(p, i) ) {} else + +#define Wln_NtkForEachPi( p, iPi, i ) \ + for ( i = 0; (i < Wln_NtkPiNum(p)) && (((iPi) = Wln_NtkCi(p, i)), 1); i++ ) +#define Wln_NtkForEachPo( p, iPo, i ) \ + for ( i = 0; (i < Wln_NtkPoNum(p)) && (((iPo) = Wln_NtkCo(p, i)), 1); i++ ) +#define Wln_NtkForEachCi( p, iCi, i ) \ + for ( i = 0; (i < Wln_NtkCiNum(p)) && (((iCi) = Wln_NtkCi(p, i)), 1); i++ ) +#define Wln_NtkForEachCo( p, iCo, i ) \ + for ( i = 0; (i < Wln_NtkCoNum(p)) && (((iCo) = Wln_NtkCo(p, i)), 1); i++ ) +#define Wln_NtkForEachFf( p, iFf, i ) \ + for ( i = 0; (i < Wln_NtkFfNum(p)) && (((iFf) = Wln_NtkFf(p, i)), 1); i++ ) + +#define Wln_ObjForEachFanin( p, iObj, iFanin, i ) \ + for ( i = 0; (i < Wln_ObjFaninNum(p, iObj)) && (((iFanin) = Wln_ObjFanin(p, iObj, i)), 1); i++ ) if ( !iFanin ) {} else +#define Wln_ObjForEachFaninReverse( pObj, iFanin, i ) \ + for ( i = Wln_ObjFaninNum(p, iObj) - 1; (i >= 0) && (((iFanin) = Wln_ObjFanin(p, iObj, i)), 1); i-- ) if ( !iFanin ) {} else + +#define Wln_ObjForEachFanoutStatic( p, iObj, iFanout, i ) \ + for ( i = 0; (i < Wln_ObjRefs(p, iObj)) && (((iFanout) = Wln_ObjFanout(p, iObj, i)), 1); i++ ) + + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +/*=== wlcNdr.c ========================================================*/ +extern Wln_Ntk_t * Wln_ReadNdr( char * pFileName ); +extern void Wln_WriteNdr( Wln_Ntk_t * pNtk, char * pFileName ); +extern Wln_Ntk_t * Wln_NtkFromNdr( void * pData ); +extern void * Wln_NtkToNdr( Wln_Ntk_t * pNtk ); +/*=== wlcNtk.c ========================================================*/ +extern Wln_Ntk_t * Wln_NtkAlloc( char * pName, int nObjsMax ); +extern void Wln_NtkFree( Wln_Ntk_t * p ); +extern int Wln_NtkMemUsage( Wln_Ntk_t * p ); +extern void Wln_NtkPrint( Wln_Ntk_t * p ); +extern Wln_Ntk_t * Wln_NtkDupDfs( Wln_Ntk_t * p ); +extern void Wln_NtkCreateRefs( Wln_Ntk_t * p ); +extern void Wln_NtkStartFaninMap( Wln_Ntk_t * p, Vec_Int_t * vFaninMap, int nMulti ); +extern void Wln_NtkStartFanoutMap( Wln_Ntk_t * p, Vec_Int_t * vFanoutMap, Vec_Int_t * vFanoutNums, int nMulti ); +extern void Wln_NtkStaticFanoutStart( Wln_Ntk_t * p ); +extern void Wln_NtkStaticFanoutStop( Wln_Ntk_t * p ); +extern void Wln_NtkStaticFanoutTest( Wln_Ntk_t * p ); +/*=== wlcObj.c ========================================================*/ +extern char * Wln_ObjName( Wln_Ntk_t * p, int iObj ); +extern char * Wln_ObjConstString( Wln_Ntk_t * p, int iObj ); +extern void Wln_ObjUpdateType( Wln_Ntk_t * p, int iObj, int Type ); +extern void Wln_ObjSetConst( Wln_Ntk_t * p, int iObj, int NameId ); +extern void Wln_ObjSetSlice( Wln_Ntk_t * p, int iObj, int SliceId ); +extern void Wln_ObjAddFanin( Wln_Ntk_t * p, int iObj, int i ); +extern int Wln_ObjAddFanins( Wln_Ntk_t * p, int iObj, Vec_Int_t * vFanins ); +extern int Wln_ObjAlloc( Wln_Ntk_t * p, int Type, int Signed, int End, int Beg ); +extern int Wln_ObjClone( Wln_Ntk_t * pNew, Wln_Ntk_t * p, int iObj ); +extern int Wln_ObjCreateCo( Wln_Ntk_t * p, int iFanin ); +extern void Wln_ObjPrint( Wln_Ntk_t * p, int iObj ); +/*=== wlcRetime.c ========================================================*/ +extern Vec_Int_t * Wln_NtkRetime( Wln_Ntk_t * p ); +/*=== wlcWriteVer.c ========================================================*/ +extern void Wln_WriteVer( Wln_Ntk_t * p, char * pFileName ); + + +ABC_NAMESPACE_HEADER_END + +#endif + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + diff --git a/src/base/wln/wlnNdr.c b/src/base/wln/wlnNdr.c new file mode 100644 index 00000000..c87100a2 --- /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 + diff --git a/src/base/wln/wlnNtk.c b/src/base/wln/wlnNtk.c new file mode 100644 index 00000000..39c03964 --- /dev/null +++ b/src/base/wln/wlnNtk.c @@ -0,0 +1,321 @@ +/**CFile**************************************************************** + + FileName [wlnNtk.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Word-level network.] + + Synopsis [Network construction procedures.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - September 23, 2018.] + + Revision [$Id: wlnNtk.c,v 1.00 2018/09/23 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "wln.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Creating networks.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Wln_Ntk_t * Wln_NtkAlloc( char * pName, int nObjsMax ) +{ + Wln_Ntk_t * p; int i; + p = ABC_CALLOC( Wln_Ntk_t, 1 ); + p->pName = pName ? Extra_FileNameGeneric( pName ) : NULL; + Vec_IntGrow( &p->vCis, 111 ); + Vec_IntGrow( &p->vCos, 111 ); + Vec_IntGrow( &p->vFfs, 111 ); + Vec_IntGrow( &p->vTypes, nObjsMax+1 ); + Vec_StrGrow( &p->vSigns, nObjsMax+1 ); + Vec_IntGrow( &p->vRanges, nObjsMax+1 ); + Vec_IntPush( &p->vTypes, -1 ); + Vec_StrPush( &p->vSigns, -1 ); + Vec_IntPush( &p->vRanges, -1 ); + p->vFanins = ABC_CALLOC( Wln_Vec_t, nObjsMax+1 ); + p->pRanges = Hash_IntManStart( 1000 ); + for ( i = 0; i < 65; i++ ) + Hash_Int2ManInsert( p->pRanges, i, i, 0 ); + for ( i = 1; i < 64; i++ ) + Hash_Int2ManInsert( p->pRanges, i, 0, 0 ); + assert( Hash_IntManEntryNum(p->pRanges) == 128 ); + return p; +} +void Wln_NtkFree( Wln_Ntk_t * p ) +{ + int i; + for ( i = 0; i < Wln_NtkObjNum(p); i++ ) + if ( Wln_ObjFaninNum(p, i) > 2 ) + ABC_FREE( p->vFanins[i].pArray[0] ); + ABC_FREE( p->vFanins ); + + if ( p->pRanges ) Hash_IntManStop( p->pRanges ); + if ( p->pManName ) Abc_NamStop( p->pManName ); + + ABC_FREE( p->vCis.pArray ); + ABC_FREE( p->vCos.pArray ); + ABC_FREE( p->vFfs.pArray ); + + ABC_FREE( p->vTypes.pArray ); + ABC_FREE( p->vSigns.pArray ); + ABC_FREE( p->vRanges.pArray ); + ABC_FREE( p->vNameIds.pArray ); + ABC_FREE( p->vInstIds.pArray ); + ABC_FREE( p->vTravIds.pArray ); + ABC_FREE( p->vCopies.pArray ); + ABC_FREE( p->vBits.pArray ); + ABC_FREE( p->vLevels.pArray ); + ABC_FREE( p->vRefs.pArray ); + ABC_FREE( p->vFanout.pArray ); + ABC_FREE( p->vFaninAttrs.pArray ); + ABC_FREE( p->vFaninLists.pArray ); + + ABC_FREE( p->pName ); + ABC_FREE( p->pSpec ); + ABC_FREE( p ); +} +int Wln_NtkMemUsage( Wln_Ntk_t * p ) +{ + int Mem = sizeof(Wln_Ntk_t); + Mem += 4 * p->vCis.nCap; + Mem += 4 * p->vCos.nCap; + Mem += 4 * p->vFfs.nCap; + Mem += 1 * p->vTypes.nCap; + Mem += 4 * p->vRanges.nCap; + Mem += 4 * p->vNameIds.nCap; + Mem += 4 * p->vInstIds.nCap; + Mem += 4 * p->vTravIds.nCap; + Mem += 4 * p->vCopies.nCap; + Mem += 4 * p->vBits.nCap; + Mem += 4 * p->vLevels.nCap; + Mem += 4 * p->vRefs.nCap; + Mem += 4 * p->vFanout.nCap; + Mem += 4 * p->vFaninAttrs.nCap; + Mem += 4 * p->vFaninLists.nCap; + Mem += 20 * Hash_IntManEntryNum(p->pRanges); + Mem += Abc_NamMemUsed(p->pManName); + return Mem; +} +void Wln_NtkPrint( Wln_Ntk_t * p ) +{ + int iObj; + printf( "Printing %d objects of network \"%s\":\n", Wln_NtkObjNum(p), p->pName ); + Wln_NtkForEachObj( p, iObj ) + Wln_ObjPrint( p, iObj ); + printf( "\n" ); +} + +/**Function************************************************************* + + Synopsis [Duplicating network.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Wln_NtkTransferNames( Wln_Ntk_t * pNew, Wln_Ntk_t * p ) +{ + assert( pNew->pManName == NULL && p->pManName != NULL ); + pNew->pManName = p->pManName; + p->pManName = NULL; + assert( !Wln_NtkHasCopy(pNew) && Wln_NtkHasCopy(p) ); + if ( Wln_NtkHasNameId(p) ) + { + int i; + assert( !Wln_NtkHasNameId(pNew) && Wln_NtkHasNameId(p) ); + Wln_NtkCleanNameId( pNew ); + Wln_NtkForEachObj( p, i ) + if ( Wln_ObjCopy(p, i) && i < Vec_IntSize(&p->vNameIds) && Wln_ObjNameId(p, i) ) + Wln_ObjSetNameId( pNew, Wln_ObjCopy(p, i), Wln_ObjNameId(p, i) ); + Vec_IntErase( &p->vNameIds ); + } + if ( Wln_NtkHasInstId(p) ) + { + int i; + assert( !Wln_NtkHasInstId(pNew) && Wln_NtkHasInstId(p) ); + Wln_NtkCleanInstId( pNew ); + Wln_NtkForEachObj( p, i ) + if ( Wln_ObjCopy(p, i) && i < Vec_IntSize(&p->vInstIds) && Wln_ObjInstId(p, i) ) + Wln_ObjSetInstId( pNew, Wln_ObjCopy(p, i), Wln_ObjInstId(p, i) ); + Vec_IntErase( &p->vInstIds ); + } +} +int Wln_ObjDup( Wln_Ntk_t * pNew, Wln_Ntk_t * p, int iObj ) +{ + int i, iFanin, iObjNew = Wln_ObjClone( pNew, p, iObj ); + Wln_ObjForEachFanin( p, iObj, iFanin, i ) + Wln_ObjAddFanin( pNew, iObjNew, Wln_ObjCopy(p, iFanin) ); + if ( Wln_ObjIsConst(p, iObj) ) + Wln_ObjSetConst( pNew, iObjNew, Wln_ObjFanin0(p, iObj) ); + else if ( Wln_ObjIsSlice(p, iObj) || Wln_ObjIsRotate(p, iObj) || Wln_ObjIsTable(p, iObj) ) + Wln_ObjSetFanin( p, iObjNew, 1, Wln_ObjFanin1(p, iObj) ); + Wln_ObjSetCopy( p, iObj, iObjNew ); + return iObjNew; +} +int Wln_NtkDupDfs_rec( Wln_Ntk_t * pNew, Wln_Ntk_t * p, int iObj ) +{ + int i, iFanin; + if ( iObj == 0 ) + return 0; + if ( Wln_ObjCopy(p, iObj) ) + return Wln_ObjCopy(p, iObj); + //printf( "Visiting node %d\n", iObj ); + assert( !Wln_ObjIsFf(p, iObj) ); + Wln_ObjForEachFanin( p, iObj, iFanin, i ) + Wln_NtkDupDfs_rec( pNew, p, iFanin ); + return Wln_ObjDup( pNew, p, iObj ); +} +Wln_Ntk_t * Wln_NtkDupDfs( Wln_Ntk_t * p ) +{ + int i, k, iObj, iFanin; + Wln_Ntk_t * pNew = Wln_NtkAlloc( p->pName, Wln_NtkObjNum(p) ); + pNew->fSmtLib = p->fSmtLib; + if ( p->pSpec ) pNew->pSpec = Abc_UtilStrsav( p->pSpec ); + Wln_NtkCleanCopy( p ); + Wln_NtkForEachCi( p, iObj, i ) + Wln_ObjDup( pNew, p, iObj ); + Wln_NtkForEachFf( p, iObj, i ) + Wln_ObjSetCopy( p, iObj, Wln_ObjClone(pNew, p, iObj) ); + Wln_NtkForEachCo( p, iObj, i ) + Wln_NtkDupDfs_rec( pNew, p, iObj ); + Wln_NtkForEachFf( p, iObj, i ) + Wln_ObjForEachFanin( p, iObj, iFanin, k ) + Wln_ObjAddFanin( pNew, Wln_ObjCopy(p, iObj), Wln_NtkDupDfs_rec(pNew, p, iFanin) ); + if ( Wln_NtkHasNameId(p) ) + Wln_NtkTransferNames( pNew, p ); + return pNew; +} + +/**Function************************************************************* + + Synopsis [Create fanin/fanout map.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Wln_NtkCreateRefs( Wln_Ntk_t * p ) +{ + int k, iObj, iFanin; + Wln_NtkCleanRefs( p ); + Wln_NtkForEachObj( p, iObj ) + Wln_ObjForEachFanin( p, iObj, iFanin, k ) + Wln_ObjRefsInc( p, iFanin ); +} +int Wln_NtkFaninNum( Wln_Ntk_t * p ) +{ + int iObj, nEdges = 0; + Wln_NtkForEachObj( p, iObj ) + nEdges += Wln_ObjFaninNum(p, iObj); + return nEdges; +} +void Wln_NtkStartFaninMap( Wln_Ntk_t * p, Vec_Int_t * vFaninMap, int nMulti ) +{ + int iObj, iOffset = Wln_NtkObjNum(p); + Vec_IntFill( vFaninMap, iOffset + nMulti * Wln_NtkFaninNum(p), 0 ); + Wln_NtkForEachObj( p, iObj ) + { + Vec_IntWriteEntry( vFaninMap, iObj, iOffset ); + iOffset += nMulti * Wln_ObjFaninNum(p, iObj); + } + assert( iOffset == Vec_IntSize(vFaninMap) ); +} +void Wln_NtkStartFanoutMap( Wln_Ntk_t * p, Vec_Int_t * vFanoutMap, Vec_Int_t * vFanoutNums, int nMulti ) +{ + int iObj, iOffset = Wln_NtkObjNum(p); + Vec_IntFill( vFanoutMap, iOffset + nMulti * Vec_IntSum(vFanoutNums), 0 ); + Wln_NtkForEachObj( p, iObj ) + { + Vec_IntWriteEntry( vFanoutMap, iObj, iOffset ); + iOffset += nMulti * Wln_ObjRefs(p, iObj); + } + assert( iOffset == Vec_IntSize(vFanoutMap) ); +} + +/**Function************************************************************* + + Synopsis [Static fanout.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Wln_NtkStaticFanoutStart( Wln_Ntk_t * p ) +{ + int k, iObj, iFanin; + Vec_Int_t * vRefsCopy = Vec_IntAlloc(0); + Wln_NtkCreateRefs( p ); + Wln_NtkStartFanoutMap( p, &p->vFanout, &p->vRefs, 1 ); + ABC_SWAP( Vec_Int_t, *vRefsCopy, p->vRefs ); + // add fanouts + Wln_NtkCleanRefs( p ); + Wln_NtkForEachObj( p, iObj ) + Wln_ObjForEachFanin( p, iObj, iFanin, k ) + Wln_ObjSetFanout( p, iFanin, Wln_ObjRefsInc(p, iFanin), iObj ); + // double-check the current number of fanouts added + Wln_NtkForEachObj( p, iObj ) + assert( Wln_ObjRefs(p, iObj) == Vec_IntEntry(vRefsCopy, iObj) ); + Vec_IntFree( vRefsCopy ); +} +void Wln_NtkStaticFanoutStop( Wln_Ntk_t * p ) +{ + Vec_IntErase( &p->vRefs ); + Vec_IntErase( &p->vFanout ); +} +void Wln_NtkStaticFanoutTest( Wln_Ntk_t * p ) +{ + int k, iObj, iFanout; + printf( "Printing fanouts of %d objects of network \"%s\":\n", Wln_NtkObjNum(p), p->pName ); + Wln_NtkStaticFanoutStart( p ); + Wln_NtkForEachObj( p, iObj ) + { + Wln_ObjPrint( p, iObj ); + printf( " Fanouts : " ); + Wln_ObjForEachFanoutStatic( p, iObj, iFanout, k ) + printf( "%5d ", iFanout ); + printf( "\n" ); + } + Wln_NtkStaticFanoutStop( p ); + printf( "\n" ); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/base/wln/wlnObj.c b/src/base/wln/wlnObj.c new file mode 100644 index 00000000..ec373304 --- /dev/null +++ b/src/base/wln/wlnObj.c @@ -0,0 +1,151 @@ +/**CFile**************************************************************** + + FileName [wlnObj.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Word-level network.] + + Synopsis [Object construction procedures.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - September 23, 2018.] + + Revision [$Id: wlnObj.c,v 1.00 2018/09/23 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "wln.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Creating objects.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +char * Wln_ObjName( Wln_Ntk_t * p, int iObj ) +{ + static char Buffer[100]; + if ( Wln_NtkHasNameId(p) && Wln_ObjNameId(p, iObj) ) + return Abc_NamStr( p->pManName, Wln_ObjNameId(p, iObj) ); + sprintf( Buffer, "n%d", iObj ); + return Buffer; +} +char * Wln_ObjConstString( Wln_Ntk_t * p, int iObj ) +{ + assert( Wln_ObjIsConst(p, iObj) ); + return Abc_NamStr( p->pManName, Wln_ObjFanin0(p, iObj) ); +} +void Wln_ObjUpdateType( Wln_Ntk_t * p, int iObj, int Type ) +{ + assert( Wln_ObjIsNone(p, iObj) ); + p->nObjs[Wln_ObjType(p, iObj)]--; + Vec_IntWriteEntry( &p->vTypes, iObj, Type ); + p->nObjs[Wln_ObjType(p, iObj)]++; +} +void Wln_ObjSetConst( Wln_Ntk_t * p, int iObj, int NameId ) +{ + assert( Wln_ObjIsConst(p, iObj) ); + Wln_ObjSetFanin( p, iObj, 0, NameId ); +} +void Wln_ObjSetSlice( Wln_Ntk_t * p, int iObj, int SliceId ) +{ + assert( Wln_ObjIsSlice(p, iObj) ); + Wln_ObjSetFanin( p, iObj, 1, SliceId ); +} +void Wln_ObjAddFanin( Wln_Ntk_t * p, int iObj, int i ) +{ + Wln_Vec_t * pVec = p->vFanins + iObj; + if ( Wln_ObjFaninNum(p, iObj) < 2 ) + pVec->Array[pVec->nSize++] = i; + else if ( Wln_ObjFaninNum(p, iObj) == 2 ) + { + int * pArray = ABC_ALLOC( int, 4 ); + pArray[0] = pVec->Array[0]; + pArray[1] = pVec->Array[1]; + pArray[2] = i; + pVec->pArray[0] = pArray; + pVec->nSize = 3; + pVec->nCap = 4; + } + else + { + if ( pVec->nSize == pVec->nCap ) + pVec->pArray[0] = ABC_REALLOC( int, pVec->pArray[0], (pVec->nCap = 2*pVec->nSize) ); + assert( pVec->nSize < pVec->nCap ); + pVec->pArray[0][pVec->nSize++] = i; + } +} +int Wln_ObjAddFanins( Wln_Ntk_t * p, int iObj, Vec_Int_t * vFanins ) +{ + int i, iFanin; + Vec_IntForEachEntry( vFanins, iFanin, i ) + Wln_ObjAddFanin( p, iObj, iFanin ); + return iObj; +} +int Wln_ObjAlloc( Wln_Ntk_t * p, int Type, int Signed, int End, int Beg ) +{ + int iObj = Vec_IntSize(&p->vTypes); + if ( iObj == Vec_IntCap(&p->vTypes) ) + { + p->vFanins = ABC_REALLOC( Wln_Vec_t, p->vFanins, 2 * iObj ); + memset( p->vFanins + iObj, 0, sizeof(Wln_Vec_t) * iObj ); + Vec_IntGrow( &p->vTypes, 2 * iObj ); + } + assert( iObj == Vec_StrSize(&p->vSigns) ); + assert( iObj == Vec_IntSize(&p->vRanges) ); + Vec_IntPush( &p->vTypes, Type ); + Vec_StrPush( &p->vSigns, (char)Signed ); + Vec_IntPush( &p->vRanges, Hash_Int2ManInsert(p->pRanges, End, Beg, 0) ); + if ( Wln_ObjIsCi(p, iObj) ) Wln_ObjSetFanin( p, iObj, 1, Vec_IntSize(&p->vCis) ), Vec_IntPush( &p->vCis, iObj ); + if ( Wln_ObjIsCo(p, iObj) ) Wln_ObjSetFanin( p, iObj, 1, Vec_IntSize(&p->vCos) ), Vec_IntPush( &p->vCos, iObj ); + if ( Wln_ObjIsFf(p, iObj) ) Vec_IntPush( &p->vFfs, iObj ); + p->nObjs[Type]++; + return iObj; +} +int Wln_ObjClone( Wln_Ntk_t * pNew, Wln_Ntk_t * p, int iObj ) +{ + return Wln_ObjAlloc( pNew, Wln_ObjType(p, iObj), Wln_ObjIsSigned(p, iObj), Wln_ObjRangeEnd(p, iObj), Wln_ObjRangeBeg(p, iObj) ); +} +int Wln_ObjCreateCo( Wln_Ntk_t * p, int iFanin ) +{ + int iCo = Wln_ObjClone( p, p, iFanin ); + Wln_ObjUpdateType( p, iCo, ABC_OPER_CO ); + Wln_ObjAddFanin( p, iCo, iFanin ); + return iCo; +} +void Wln_ObjPrint( Wln_Ntk_t * p, int iObj ) +{ + int k, iFanin, Type = Wln_ObjType(p, iObj); + printf( "Obj %6d : Type = %6s Fanins = %d : ", iObj, Abc_OperName(Type), Wln_ObjFaninNum(p, iObj) ); + Wln_ObjForEachFanin( p, iObj, iFanin, k ) + printf( "%5d ", iFanin ); + printf( "\n" ); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/base/wln/wlnRetime.c b/src/base/wln/wlnRetime.c new file mode 100644 index 00000000..459af2d9 --- /dev/null +++ b/src/base/wln/wlnRetime.c @@ -0,0 +1,487 @@ +/**CFile**************************************************************** + + FileName [wlnRetime.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Word-level network.] + + Synopsis [Retiming.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - September 23, 2018.] + + Revision [$Id: wlnRetime.c,v 1.00 2018/09/23 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "wln.h" +#include "misc/vec/vecHsh.h" + +ABC_NAMESPACE_IMPL_START + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +typedef struct Wln_Ret_t_ Wln_Ret_t; +struct Wln_Ret_t_ +{ + Wln_Ntk_t * pNtk; // static netlist + Vec_Int_t vFanins; // fanins and edge places + Vec_Int_t vFanouts; // fanouts and edge places + Vec_Int_t vEdgeLinks; // edge links + Vec_Int_t vFfClasses; // flop classes + Vec_Int_t vNodeDelays; // object delays + Vec_Int_t vPathDelays; // delays from sources to sinks + Vec_Int_t vSources; // critical sources + Vec_Int_t vSinks; // critical sinks + Vec_Int_t vFront; // retiming frontier + Vec_Int_t vMoves; // retiming moves (paired with delay) + int nClasses; // the number of flop classes + int DelayMax; // critical delay at any time +}; + +static inline int * Wln_RetFanins( Wln_Ret_t * p, int i ) { return Vec_IntEntryP( &p->vFanins, Vec_IntEntry(&p->vFanins, i) ); } +static inline int * Wln_RetFanouts( Wln_Ret_t * p, int i ) { return Vec_IntEntryP( &p->vFanouts, Vec_IntEntry(&p->vFanouts, i) ); } + +#define Wln_RetForEachFanin( p, iObj, iFanin, pLink, i ) \ + for ( i = 0; (i < Wln_ObjFaninNum(p->pNtk, iObj)) && \ + (((iFanin) = Wln_RetFanins(p, iObj)[2*i]), 1) && \ + ((pLink) = (Wln_RetFanins(p, iObj)+2*i+1)); i++ ) if ( !iFanin ) {} else + +#define Wln_RetForEachFanout( p, iObj, iFanout, pLink, i ) \ + for ( i = 0; (i < Wln_ObjRefs(p->pNtk, iObj)) && \ + (((iFanout) = Wln_RetFanouts(p, iObj)[2*i]), 1) && \ + ((pLink) = Vec_IntEntryP(&p->vFanins, Wln_RetFanouts(p, iObj)[2*i+1])); i++ ) if ( !iFanout ) {} else + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Retiming manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Wln_RetComputeFfClasses( Wln_Ntk_t * pNtk, Vec_Int_t * vClasses ) +{ + int i, k, iObj, nClasses; + Hsh_VecMan_t * p = Hsh_VecManStart( 10 ); + Vec_Int_t * vFlop = Vec_IntAlloc( 6 ); + Vec_IntFill( vClasses, Wln_NtkObjNum(pNtk), -1 ); + Wln_NtkForEachFf( pNtk, iObj, i ) + { + Vec_IntClear( vFlop ); + for ( k = 1; k <= 6; k++ ) + Vec_IntPush( vFlop, Wln_ObjFanin(pNtk, iObj, k) ); + Vec_IntWriteEntry( vClasses, iObj, Hsh_VecManAdd(p, vFlop) ); + } + nClasses = Hsh_VecSize( p ); + Hsh_VecManStop( p ); + Vec_IntFree( vFlop ); + printf( "Detected %d flop classes.\n", nClasses ); + return nClasses; +} +Wln_Ret_t * Wln_RetAlloc( Wln_Ntk_t * pNtk ) +{ + Wln_Ret_t * p; int k, iObj, iFanin; + Vec_Int_t * vRefsCopy = Vec_IntAlloc(0); + p = ABC_CALLOC( Wln_Ret_t, 1 ); + p->pNtk = pNtk; + Wln_NtkCreateRefs( pNtk ); + Wln_NtkStartFaninMap( pNtk, &p->vFanins, 2 ); + Wln_NtkStartFanoutMap( pNtk, &p->vFanouts, &pNtk->vRefs, 2 ); + ABC_SWAP( Vec_Int_t, *vRefsCopy, pNtk->vRefs ); + Wln_NtkCleanRefs( pNtk ); + Vec_IntGrow( &p->vEdgeLinks, 10*Wln_NtkFfNum(pNtk) ); + Vec_IntPushTwo( &p->vEdgeLinks, -1, -1 ); + Wln_NtkForEachObj( pNtk, iObj ) + Wln_ObjForEachFanin( pNtk, iObj, iFanin, k ) + { + int * pFanins = Wln_RetFanins( p, iObj ); + int * pFanouts = Wln_RetFanouts( p, iFanin ); + int Index = Wln_ObjRefsInc( pNtk, iFanin ); + pFanins[2*k+0] = iFanin; + pFanins[2*k+1] = Wln_ObjIsFf(pNtk, iFanin) ? Vec_IntSize(&p->vEdgeLinks) : 0; + pFanouts[2*Index+0] = iObj; + pFanouts[2*Index+1] = Vec_IntEntry(&p->vFanins, iObj) + 2*k + 1; + if ( Wln_ObjIsFf(pNtk, iFanin) ) + Vec_IntPushTwo( &p->vEdgeLinks, 0, iFanin ); + } + // double-check the current number of fanouts added + Wln_NtkForEachObj( pNtk, iObj ) + assert( Wln_ObjRefs(pNtk, iObj) == Vec_IntEntry(vRefsCopy, iObj) ); + Vec_IntFree( vRefsCopy ); + // other data + p->nClasses = Wln_RetComputeFfClasses( pNtk, &p->vFfClasses ); + ABC_SWAP( Vec_Int_t, p->vNodeDelays, pNtk->vInstIds ); + Vec_IntGrow( &p->vSources, 1000 ); + Vec_IntGrow( &p->vSinks, 1000 ); + Vec_IntGrow( &p->vFront, 1000 ); + Vec_IntGrow( &p->vMoves, 1000 ); + return p; +} +void Wln_RetFree( Wln_Ret_t * p ) +{ + ABC_FREE( p->vFanins.pArray ); + ABC_FREE( p->vFanouts.pArray ); + ABC_FREE( p->vEdgeLinks.pArray ); + ABC_FREE( p->vFfClasses.pArray ); + ABC_FREE( p->vNodeDelays.pArray ); + ABC_FREE( p->vPathDelays.pArray ); + ABC_FREE( p->vSources.pArray ); + ABC_FREE( p->vSinks.pArray ); + ABC_FREE( p->vFront.pArray ); + ABC_FREE( p->vMoves.pArray ); + ABC_FREE( p ); +} +int Wln_RetMemUsage( Wln_Ret_t * p ) +{ + int Mem = sizeof(Wln_Ret_t); + Mem += 4 * p->vFanins.nCap; + Mem += 4 * p->vFanouts.nCap; + Mem += 4 * p->vEdgeLinks.nCap; + Mem += 4 * p->vFfClasses.nCap; + Mem += 4 * p->vNodeDelays.nCap; + Mem += 4 * p->vPathDelays.nCap; + Mem += 4 * p->vSources.nCap; + Mem += 4 * p->vSinks.nCap; + Mem += 4 * p->vFront.nCap; + Mem += 4 * p->vMoves.nCap; + return Mem; +} + +/**Function************************************************************* + + Synopsis [Delay propagation.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Wln_RetMarkChanges_rec( Wln_Ret_t * p, int iObj ) +{ + int k, iFanout, * pLink, * pDelay = Vec_IntEntryP( &p->vPathDelays, iObj ); + if ( *pDelay < 0 ) + return; + *pDelay = -1; + Wln_RetForEachFanout( p, iObj, iFanout, pLink, k ) + if ( !pLink[0] ) + Wln_RetMarkChanges_rec( p, iFanout ); +} +int Wln_RetPropDelay_rec( Wln_Ret_t * p, int iObj ) +{ + int k, iFanin, * pLink, * pDelay = Vec_IntEntryP( &p->vPathDelays, iObj ); + if ( *pDelay >= 0 ) + return *pDelay; + Wln_RetForEachFanin( p, iObj, iFanin, pLink, k ) + if ( pLink[0] ) + *pDelay = Abc_MaxInt(*pDelay, 0); + else + *pDelay = Abc_MaxInt(*pDelay, Wln_RetPropDelay_rec(p, iFanin)); + *pDelay += Vec_IntEntry( &p->vNodeDelays, iObj ); + return *pDelay; +} +int Wln_RetPropDelay( Wln_Ret_t * p, Vec_Int_t * vFront ) +{ + int i, iObj, DelayMax = 0; + if ( vFront ) + { + Vec_IntForEachEntry( vFront, iObj, i ) + Wln_RetMarkChanges_rec( p, iObj ); + } + else + { + Vec_IntFill( &p->vPathDelays, Wln_NtkObjNum(p->pNtk), -1 ); + Wln_NtkForEachCi( p->pNtk, iObj, i ) + Vec_IntWriteEntry( &p->vPathDelays, iObj, 0 ); + } + Vec_IntClear( &p->vSinks ); + Wln_NtkForEachObj( p->pNtk, iObj ) + if ( !Wln_ObjIsCo(p->pNtk, iObj) ) + { + int Delay = Wln_RetPropDelay_rec(p, iObj); + if ( DelayMax == Delay ) + Vec_IntPush( &p->vSinks, iObj ); + else if ( DelayMax < Delay ) + { + DelayMax = Delay; + Vec_IntFill( &p->vSinks, 1, iObj ); + } + } + return DelayMax; +} + +void Wln_RetFindSources_rec( Wln_Ret_t * p, int iObj ) +{ + int k, iFanin, * pLink, FaninDelay, fTerm = 1; + if ( Wln_ObjIsCi(p->pNtk, iObj) || Wln_ObjCheckTravId(p->pNtk, iObj) ) + return; + FaninDelay = Vec_IntEntry( &p->vPathDelays, iObj ) - Vec_IntEntry( &p->vNodeDelays, iObj ); + Wln_RetForEachFanin( p, iObj, iFanin, pLink, k ) + { + if ( !pLink[0] ) + continue; + fTerm = 0; + if ( Vec_IntEntry(&p->vPathDelays, iFanin) == FaninDelay ) + Wln_RetFindSources_rec( p, iFanin ); + } + if ( fTerm ) + Vec_IntPush( &p->vSources, iObj ); +} +void Wln_RetFindSources( Wln_Ret_t * p ) +{ + int i, iObj; + Vec_IntClear( &p->vSources ); + Wln_NtkIncrementTravId( p->pNtk ); + Vec_IntForEachEntry( &p->vSinks, iObj, i ) + Wln_RetFindSources_rec( p, iObj ); +} + +/**Function************************************************************* + + Synopsis [Retimability check.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int * Wln_RetHeadToTail( Wln_Ret_t * p, int * pHead ) +{ + int * pLink; + assert( pHead[0] ); + pLink = Vec_IntEntryP( &p->vEdgeLinks, pHead[0] ); + if ( pLink[0] == 0 ) + return pHead; + return Wln_RetHeadToTail( p, pLink ); +} + +static inline int Wln_RetCheckForwardOne( Wln_Ret_t * p, int iObj ) +{ + int k, iFanin, * pLink, iFlop, Class = -1; + Wln_RetForEachFanin( p, iObj, iFanin, pLink, k ) + { + if ( !pLink[0] ) + return 0; + iFlop = Vec_IntEntry( &p->vEdgeLinks, pLink[0] + 1 ); + assert( Wln_ObjIsFf( p->pNtk, iFlop ) ); + if ( Class == -1 ) + Class = Vec_IntEntry( &p->vFfClasses, iFlop ); + else if ( Class != Vec_IntEntry( &p->vFfClasses, iFlop ) ) + return 0; + } + return 1; +} +int Wln_RetCheckForward( Wln_Ret_t * p, Vec_Int_t * vSet ) +{ + int i, iObj; + Vec_IntForEachEntry( vSet, iObj, i ) + if ( !Wln_RetCheckForwardOne( p, iObj ) ) + return 0; + return 1; +} + +static inline int Wln_RetCheckBackwardOne( Wln_Ret_t * p, int iObj ) +{ + int k, iFanin, * pLink, iFlop, Class = -1; + Wln_RetForEachFanout( p, iObj, iFanin, pLink, k ) + { + if ( !pLink[0] ) + return 0; + pLink = Wln_RetHeadToTail( p, pLink ); + iFlop = Vec_IntEntry( &p->vEdgeLinks, pLink[0] + 1 ); + assert( Wln_ObjIsFf( p->pNtk, iFlop ) ); + if ( Class == -1 ) + Class = Vec_IntEntry( &p->vFfClasses, iFlop ); + else if ( Class != Vec_IntEntry( &p->vFfClasses, iFlop ) ) + return 0; + } + return 1; +} +int Wln_RetCheckBackward( Wln_Ret_t * p, Vec_Int_t * vSet ) +{ + int i, iObj; + Vec_IntForEachEntry( vSet, iObj, i ) + if ( !Wln_RetCheckBackwardOne( p, iObj ) ) + return 0; + return 1; +} + + +/**Function************************************************************* + + Synopsis [Moving flops.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Wln_RetRemoveOneFanin( Wln_Ret_t * p, int iObj ) +{ + int k, iFanin, * pLink, iFlop, iFlop1 = -1; + int * pFanins = Wln_RetFanins( p, iObj ); + Wln_RetForEachFanin( p, iObj, iFanin, pLink, k ) + { + assert( pLink[0] ); + pFanins[2*k+1] = Vec_IntEntry( &p->vEdgeLinks, pLink[0] ); + iFlop = Vec_IntEntry( &p->vEdgeLinks, pLink[0] + 1 ); + assert( Wln_ObjIsFf( p->pNtk, iFlop ) ); + if ( iFlop1 == -1 ) + iFlop1 = iFlop; + } + return iFlop1; +} +int Wln_RetRemoveOneFanout( Wln_Ret_t * p, int iObj ) +{ + int k, iFanin, * pLink, iFlop, iFlop1 = -1; + //int * pFanins = Wln_RetFanins( p, iObj ); + Wln_RetForEachFanout( p, iObj, iFanin, pLink, k ) + { + assert( pLink[0] ); + pLink = Wln_RetHeadToTail( p, pLink ); + iFlop = Vec_IntEntry( &p->vEdgeLinks, pLink[0] + 1 ); + pLink[0] = 0; + assert( Wln_ObjIsFf( p->pNtk, iFlop ) ); + if ( iFlop1 == -1 ) + iFlop1 = iFlop; + } + return iFlop1; +} +void Wln_RetInsertOneFanin( Wln_Ret_t * p, int iObj, int iFlop ) +{ + int k, iFanin, * pLink; + int * pFanins = Wln_RetFanins( p, iObj ); + assert( Wln_ObjIsFf( p->pNtk, iFlop ) ); + Wln_RetForEachFanin( p, iObj, iFanin, pLink, k ) + { + int iHead = pFanins[2*k+1]; + pFanins[2*k+1] = Vec_IntSize(&p->vEdgeLinks); + Vec_IntPushTwo( &p->vEdgeLinks, iHead, iFlop ); + } +} +void Wln_RetInsertOneFanout( Wln_Ret_t * p, int iObj, int iFlop ) +{ + int k, iFanin, * pLink; + assert( Wln_ObjIsFf( p->pNtk, iFlop ) ); + Wln_RetForEachFanout( p, iObj, iFanin, pLink, k ) + { + if ( pLink[0] ) + pLink = Wln_RetHeadToTail( p, pLink ); + pLink = Vec_IntEntryP( &p->vEdgeLinks, pLink[0] ); + assert( pLink[0] == 0 ); + pLink[0] = Vec_IntSize(&p->vEdgeLinks); + Vec_IntPushTwo( &p->vEdgeLinks, 0, iFlop ); + } +} +void Wln_RetRetimeForward( Wln_Ret_t * p, Vec_Int_t * vSet ) +{ + int i, iObj, iFlop; + Vec_IntForEachEntry( vSet, iObj, i ) + { + iFlop = Wln_RetRemoveOneFanin( p, iObj ); + Wln_RetInsertOneFanout( p, iObj, iFlop ); + } +} +void Wln_RetRetimeBackward( Wln_Ret_t * p, Vec_Int_t * vSet ) +{ + int i, iObj, iFlop; + Vec_IntForEachEntry( vSet, iObj, i ) + { + iFlop = Wln_RetRemoveOneFanout( p, iObj ); + Wln_RetInsertOneFanin( p, iObj, iFlop ); + } +} +void Wln_RetAddToMoves( Wln_Ret_t * p, Vec_Int_t * vSet, int Delay, int fForward ) +{ + int i, iObj; + if ( vSet == NULL ) + { + Vec_IntPushTwo( &p->vMoves, 0, Delay ); + return; + } + Vec_IntForEachEntry( vSet, iObj, i ) + { + int NameId = Vec_IntEntry( &p->pNtk->vNameIds, iObj ); + Vec_IntPushTwo( &p->vMoves, fForward ? NameId : -NameId, Delay ); + } +} + +/**Function************************************************************* + + Synopsis [Retiming computation.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Wln_NtkRetime( Wln_Ntk_t * pNtk ) +{ + Wln_Ret_t * p = Wln_RetAlloc( pNtk ); + Vec_Int_t * vSources = &p->vSources; + Vec_Int_t * vSinks = &p->vSinks; + Vec_Int_t * vFront = &p->vFront; + Vec_Int_t * vMoves = Vec_IntAlloc(0); + p->DelayMax = Wln_RetPropDelay( p, NULL ); + Wln_RetFindSources( p ); + Wln_RetAddToMoves( p, NULL, p->DelayMax, 0 ); + while ( Vec_IntSize(vSources) || Vec_IntSize(vSinks) ) + { + int fForward = Vec_IntSize(vSources) && Wln_RetCheckForward( p, vSources ); + int fBackward = Vec_IntSize(vSinks) && Wln_RetCheckBackward( p, vSinks ); + if ( !fForward && !fBackward ) + { + printf( "Cannot retime forward and backward.\n" ); + break; + } + Vec_IntSort( vSources, 0 ); + Vec_IntSort( vSinks, 0 ); + if ( Vec_IntTwoCountCommon(vSources, vSinks) ) + { + printf( "Cannot reduce delay by retiming.\n" ); + break; + } + Vec_IntClear( vFront ); + if ( (fForward && !fBackward) || (fForward && fBackward && Vec_IntSize(vSources) < Vec_IntSize(vSinks)) ) + Wln_RetRetimeForward( p, vSources ), Vec_IntAppend( vFront, vSources ), fForward = 1, fBackward = 0; + else + Wln_RetRetimeBackward( p, vSinks ), Vec_IntAppend( vFront, vSources ), fForward = 0, fBackward = 1; + p->DelayMax = Wln_RetPropDelay( p, vFront ); + Wln_RetAddToMoves( p, vFront, p->DelayMax, fForward ); + Wln_RetFindSources( p ); + if ( 2*Vec_IntSize(&p->vEdgeLinks) > Vec_IntCap(&p->vEdgeLinks) ) + Vec_IntGrow( &p->vEdgeLinks, 4*Vec_IntSize(&p->vEdgeLinks) ); + } + ABC_SWAP( Vec_Int_t, *vMoves, p->vMoves ); + Wln_RetFree( p ); + return vMoves; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/base/wln/wlnWriteVer.c b/src/base/wln/wlnWriteVer.c new file mode 100644 index 00000000..1c37e311 --- /dev/null +++ b/src/base/wln/wlnWriteVer.c @@ -0,0 +1,494 @@ +/**CFile**************************************************************** + + FileName [wlnWriteVer.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Word-level network.] + + Synopsis [Writing Verilog.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - September 23, 2018.] + + Revision [$Id: wlnWriteVer.c,v 1.00 2018/09/23 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "wln.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Wln_WriteTableOne( FILE * pFile, int nFans, int nOuts, word * pTable, int Id ) +{ + int m, nMints = (1<<nFans); +// Abc_TtPrintHexArrayRev( stdout, pTable, nMints ); printf( "\n" ); + assert( nOuts > 0 && nOuts <= 64 && (64 % nOuts) == 0 ); + fprintf( pFile, "module table%d(ind, val);\n", Id ); + fprintf( pFile, " input [%d:0] ind;\n", nFans-1 ); + fprintf( pFile, " output [%d:0] val;\n", nOuts-1 ); + fprintf( pFile, " reg [%d:0] val;\n", nOuts-1 ); + fprintf( pFile, " always @(ind)\n" ); + fprintf( pFile, " begin\n" ); + fprintf( pFile, " case (ind)\n" ); + for ( m = 0; m < nMints; m++ ) + fprintf( pFile, " %d\'h%x: val = %d\'h%x;\n", nFans, m, nOuts, (unsigned)((pTable[(nOuts * m) >> 6] >> ((nOuts * m) & 63)) & Abc_Tt6Mask(nOuts)) ); + fprintf( pFile, " endcase\n" ); + fprintf( pFile, " end\n" ); + fprintf( pFile, "endmodule\n" ); + fprintf( pFile, "\n" ); +} +void Wln_WriteTables( FILE * pFile, Wln_Ntk_t * p ) +{ + Vec_Int_t * vNodes; + word * pTable; + int i, iObj; + if ( p->vTables == NULL || Vec_PtrSize(p->vTables) == 0 ) + return; + // map tables into their nodes + vNodes = Vec_IntStart( Vec_PtrSize(p->vTables) ); + Wln_NtkForEachObj( p, iObj ) + if ( Wln_ObjType(p, iObj) == ABC_OPER_TABLE ) + Vec_IntWriteEntry( vNodes, Wln_ObjFanin1(p, iObj), iObj ); + // write tables + Vec_PtrForEachEntry( word *, p->vTables, pTable, i ) + { + int iNode = Vec_IntEntry( vNodes, i ); + int iFanin = Wln_ObjFanin0( p, iNode ); + Wln_WriteTableOne( pFile, Wln_ObjRange(p, iFanin), Wln_ObjRange(p, iNode), pTable, i ); + } + Vec_IntFree( vNodes ); +} + +/**Function************************************************************* + + Synopsis [This was used to add POs to each node except PIs and MUXes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Wln_WriteAddPos( Wln_Ntk_t * p ) +{ + int iObj; + Wln_NtkForEachObj( p, iObj ) + if ( !Wln_ObjIsCio(p, iObj) ) + Wln_ObjCreateCo( p, iObj ); +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Wln_WriteVerIntVec( FILE * pFile, Wln_Ntk_t * p, Vec_Int_t * vVec, int Start ) +{ + char * pName; + int LineLength = Start; + int NameCounter = 0; + int AddedLength, i, iObj; + Vec_IntForEachEntry( vVec, iObj, i ) + { + pName = Wln_ObjName( p, iObj ); + // get the line length after this name is written + AddedLength = strlen(pName) + 2; + if ( NameCounter && LineLength + AddedLength + 3 > 70 ) + { // write the line extender + fprintf( pFile, "\n " ); + // reset the line length + LineLength = Start; + NameCounter = 0; + } + fprintf( pFile, " %s%s", pName, (i==Vec_IntSize(vVec)-1)? "" : "," ); + LineLength += AddedLength; + NameCounter++; + } +} +void Wln_WriteVerInt( FILE * pFile, Wln_Ntk_t * p ) +{ + int k, j, iObj, iFanin; + char Range[100]; + fprintf( pFile, "module %s ( ", p->pName ); + fprintf( pFile, "\n " ); + if ( Wln_NtkCiNum(p) > 0 ) + { + Wln_WriteVerIntVec( pFile, p, &p->vCis, 3 ); + fprintf( pFile, ",\n " ); + } + if ( Wln_NtkCoNum(p) > 0 ) + Wln_WriteVerIntVec( pFile, p, &p->vCos, 3 ); + fprintf( pFile, " );\n" ); + Wln_NtkForEachObj( p, iObj ) + { + int End = Wln_ObjRangeEnd(p, iObj); + int Beg = Wln_ObjRangeBeg(p, iObj); + int nDigits = Abc_Base10Log(Abc_AbsInt(End)+1) + Abc_Base10Log(Abc_AbsInt(Beg)+1) + (int)(End < 0) + (int)(Beg < 0); + sprintf( Range, "%s[%d:%d]%*s", (!p->fSmtLib && Wln_ObjIsSigned(p, iObj)) ? "signed ":" ", End, Beg, 8-nDigits, "" ); + fprintf( pFile, " " ); + if ( Wln_ObjIsCi(p, iObj) ) + fprintf( pFile, "input " ); + else if ( Wln_ObjIsCo(p, iObj) ) + fprintf( pFile, "output " ); + else + fprintf( pFile, " " ); + if ( Wln_ObjIsCio(p, iObj) ) + { + fprintf( pFile, "wire %s %s ;\n", Range, Wln_ObjName(p, iObj) ); + if ( Wln_ObjIsCi(p, iObj) ) + continue; + fprintf( pFile, " assign " ); + fprintf( pFile, "%-16s = %s ;\n", Wln_ObjName(p, iObj), Wln_ObjName(p, Wln_ObjFanin0(p, iObj)) ); + continue; + } + if ( Wln_ObjType(p, iObj) == ABC_OPER_SEL_NMUX || Wln_ObjType(p, iObj) == ABC_OPER_SEL_SEL ) + fprintf( pFile, "reg %s ", Range ); + else + fprintf( pFile, "wire %s ", Range ); + if ( Wln_ObjType(p, iObj) == ABC_OPER_TABLE ) + { + // wire [3:0] s4972; table0 s4972_Index(s4971, s4972); + fprintf( pFile, "%s ; table%d", Wln_ObjName(p, iObj), Wln_ObjFanin1(p, iObj) ); + fprintf( pFile, " s%d_Index(%s, ", iObj, Wln_ObjName(p, Wln_ObjFanin0(p, iObj)) ); + fprintf( pFile, "%s)", Wln_ObjName(p, iObj) ); + } + else if ( Wln_ObjIsConst(p, iObj) ) + fprintf( pFile, "%-16s = %s", Wln_ObjName(p, iObj), Wln_ObjConstString(p, iObj) ); + else if ( Wln_ObjType(p, iObj) == ABC_OPER_SHIFT_ROTR || Wln_ObjType(p, iObj) == ABC_OPER_SHIFT_ROTL ) + { + // wire [27:0] s4960 = (s57 >> 17) | (s57 << 11); + int Num0 = Wln_ObjFanin1(p, iObj); + int Num1 = Wln_ObjRange(p, iObj) - Num0; + assert( Num0 > 0 && Num0 < Wln_ObjRange(p, iObj) ); + fprintf( pFile, "%-16s = ", Wln_ObjName(p, iObj) ); + if ( Wln_ObjType(p, iObj) == ABC_OPER_SHIFT_ROTR ) + fprintf( pFile, "(%s >> %d) | (%s << %d)", Wln_ObjName(p, Wln_ObjFanin0(p, iObj)), Num0, Wln_ObjName(p, Wln_ObjFanin0(p, iObj)), Num1 ); + else + fprintf( pFile, "(%s << %d) | (%s >> %d)", Wln_ObjName(p, Wln_ObjFanin0(p, iObj)), Num0, Wln_ObjName(p, Wln_ObjFanin0(p, iObj)), Num1 ); + } + else if ( Wln_ObjType(p, iObj) == ABC_OPER_SEL_NMUX ) + { + fprintf( pFile, "%s ;\n", Wln_ObjName(p, iObj) ); + fprintf( pFile, " " ); + fprintf( pFile, "always @( " ); + Wln_ObjForEachFanin( p, iObj, iFanin, k ) + fprintf( pFile, "%s%s", k ? " or ":"", Wln_ObjName(p, Wln_ObjFanin(p, iObj, k)) ); + fprintf( pFile, " )\n" ); + fprintf( pFile, " " ); + fprintf( pFile, "begin\n" ); + fprintf( pFile, " " ); + fprintf( pFile, "case ( %s )\n", Wln_ObjName(p, Wln_ObjFanin(p, iObj, 0)) ); + Wln_ObjForEachFanin( p, iObj, iFanin, k ) + { + if ( !k ) continue; + fprintf( pFile, " " ); + fprintf( pFile, "%d : %s = ", k-1, Wln_ObjName(p, iObj) ); + fprintf( pFile, "%s ;\n", Wln_ObjName(p, Wln_ObjFanin(p, iObj, k)) ); + } + fprintf( pFile, " " ); + fprintf( pFile, "endcase\n" ); + fprintf( pFile, " " ); + fprintf( pFile, "end\n" ); + continue; + } + else if ( Wln_ObjType(p, iObj) == ABC_OPER_SEL_SEL ) + { + fprintf( pFile, "%s ;\n", Wln_ObjName(p, iObj) ); + fprintf( pFile, " " ); + fprintf( pFile, "always @( " ); + Wln_ObjForEachFanin( p, iObj, iFanin, k ) + fprintf( pFile, "%s%s", k ? " or ":"", Wln_ObjName(p, Wln_ObjFanin(p, iObj, k)) ); + fprintf( pFile, " )\n" ); + fprintf( pFile, " " ); + fprintf( pFile, "begin\n" ); + fprintf( pFile, " " ); + fprintf( pFile, "case ( %s )\n", Wln_ObjName(p, Wln_ObjFanin(p, iObj, 0)) ); + Wln_ObjForEachFanin( p, iObj, iFanin, k ) + { + if ( !k ) continue; + fprintf( pFile, " " ); + fprintf( pFile, "%d\'b", Wln_ObjFaninNum(p, iObj)-1 ); + for ( j = Wln_ObjFaninNum(p, iObj)-1; j > 0; j-- ) + fprintf( pFile, "%d", (int)(j==k) ); + fprintf( pFile, " : %s = ", Wln_ObjName(p, iObj) ); + fprintf( pFile, "%s ;\n", Wln_ObjName(p, Wln_ObjFanin(p, iObj, k)) ); + } + fprintf( pFile, " " ); + fprintf( pFile, "default" ); + fprintf( pFile, " : %s = ", Wln_ObjName(p, iObj) ); + fprintf( pFile, "%d\'b", Wln_ObjRange(p, iObj) ); + for ( j = Wln_ObjRange(p, iObj)-1; j >= 0; j-- ) + fprintf( pFile, "%d", 0 ); + fprintf( pFile, " ;\n" ); + fprintf( pFile, " " ); + fprintf( pFile, "endcase\n" ); + fprintf( pFile, " " ); + fprintf( pFile, "end\n" ); + continue; + } + else if ( Wln_ObjType(p, iObj) == ABC_OPER_SEL_DEC ) + { + int nRange = Wln_ObjRange(p, Wln_ObjFanin0(p, iObj)); + assert( (1 << nRange) == Wln_ObjRange(p, iObj) ); + fprintf( pFile, "%s ;\n", Wln_ObjName(p, iObj) ); + for ( k = 0; k < Wln_ObjRange(p, iObj); k++ ) + { + fprintf( pFile, " " ); + fprintf( pFile, "wire " ); + fprintf( pFile, "%s_", Wln_ObjName(p, iObj) ); + for ( j = 0; j < nRange; j++ ) + fprintf( pFile, "%d", (k >> (nRange-1-j)) & 1 ); + fprintf( pFile, " = " ); + for ( j = 0; j < nRange; j++ ) + fprintf( pFile, "%s%s%s[%d]", + j ? " & ":"", ((k >> (nRange-1-j)) & 1) ? " ":"~", + Wln_ObjName(p, Wln_ObjFanin(p, iObj, 0)), nRange-1-j ); + fprintf( pFile, " ;\n" ); + } + fprintf( pFile, " " ); + fprintf( pFile, "assign %s = { ", Wln_ObjName(p, iObj) ); + for ( k = Wln_ObjRange(p, iObj)-1; k >= 0; k-- ) + { + fprintf( pFile, "%s%s_", k < Wln_ObjRange(p, iObj)-1 ? ", ":"", Wln_ObjName(p, iObj) ); + for ( j = 0; j < nRange; j++ ) + fprintf( pFile, "%d", (k >> (nRange-1-j)) & 1 ); + } + fprintf( pFile, " } ;\n" ); + continue; + } + else if ( Wln_ObjType(p, iObj) == ABC_OPER_ARI_ADDSUB ) + { + // out = mode ? a+b+cin : a-b-cin + fprintf( pFile, "%s ;\n", Wln_ObjName(p, iObj) ); + fprintf( pFile, " " ); + fprintf( pFile, "assign " ); + fprintf( pFile, "%s = %s ? %s + %s + %s : %s - %s - %s ;\n", + Wln_ObjName(p, iObj), Wln_ObjName(p, Wln_ObjFanin0(p, iObj)), + Wln_ObjName(p, Wln_ObjFanin2(p, iObj)), Wln_ObjName(p, Wln_ObjFanin(p, iObj,3)), Wln_ObjName(p, Wln_ObjFanin1(p, iObj)), + Wln_ObjName(p, Wln_ObjFanin2(p, iObj)), Wln_ObjName(p, Wln_ObjFanin(p, iObj,3)), Wln_ObjName(p, Wln_ObjFanin1(p, iObj)) + ); + continue; + } + else if ( Wln_ObjType(p, iObj) == ABC_OPER_RAMR || Wln_ObjType(p, iObj) == ABC_OPER_RAMW ) + { + if ( 1 ) + { + fprintf( pFile, "%s ;\n", Wln_ObjName(p, iObj) ); + fprintf( pFile, " " ); + fprintf( pFile, "%s (", Wln_ObjType(p, iObj) == ABC_OPER_RAMR ? "ABC_READ" : "ABC_WRITE" ); + Wln_ObjForEachFanin( p, iObj, iFanin, k ) + fprintf( pFile, " .%s(%s),", k==0 ? "mem_in" : (k==1 ? "addr": "data"), Wln_ObjName(p, iFanin) ); + fprintf( pFile, " .%s(%s) ) ;\n", Wln_ObjType(p, iObj) == ABC_OPER_RAMR ? "data" : "mem_out", Wln_ObjName(p, iObj) ); + continue; + } + else + { + int nBitsMem = Wln_ObjRange(p, Wln_ObjFanin(p, iObj, 0) ); + //int nBitsAddr = Wln_ObjRange(p, Wln_ObjFanin(p, iObj, 1) ); + int nBitsDat = Wln_ObjType(p, iObj) == ABC_OPER_RAMR ? Wln_ObjRange(p, iObj) : Wln_ObjRange(p, Wln_ObjFanin(p, iObj, 2)); + int Depth = nBitsMem / nBitsDat; + assert( nBitsMem % nBitsDat == 0 ); + fprintf( pFile, "%s ;\n", Wln_ObjName(p, iObj) ); + fprintf( pFile, " " ); + fprintf( pFile, "%s_%d (", Wln_ObjType(p, iObj) == ABC_OPER_RAMR ? "CPL_MEM_READ" : "CPL_MEM_WRITE", Depth ); + Wln_ObjForEachFanin( p, iObj, iFanin, k ) + fprintf( pFile, " .%s(%s),", k==0 ? "mem_data_in" : (k==1 ? "addr_in": "data_in"), Wln_ObjName(p, iFanin) ); + fprintf( pFile, " .%s(%s) ) ;\n", "data_out", Wln_ObjName(p, iObj) ); + continue; + } + } + else if ( Wln_ObjType(p, iObj) == ABC_OPER_DFFRSE ) + { + fprintf( pFile, "%s ;\n", Wln_ObjName(p, iObj) ); + continue; + } + else + { + fprintf( pFile, "%-16s = ", Wln_ObjName(p, iObj) ); + if ( Wln_ObjType(p, iObj) == ABC_OPER_BIT_BUF ) + fprintf( pFile, "%s", Wln_ObjName(p, Wln_ObjFanin0(p, iObj)) ); + else if ( Wln_ObjType(p, iObj) == ABC_OPER_BIT_MUX ) + { + fprintf( pFile, "%s ? ", Wln_ObjName(p, Wln_ObjFanin0(p, iObj)) ); + fprintf( pFile, "%s : ", Wln_ObjName(p, Wln_ObjFanin1(p, iObj)) ); + fprintf( pFile, "%s", Wln_ObjName(p, Wln_ObjFanin2(p, iObj)) ); + } + else if ( Wln_ObjType(p, iObj) == ABC_OPER_ARI_MIN ) + fprintf( pFile, "-%s", Wln_ObjName(p, Wln_ObjFanin0(p, iObj)) ); + else if ( Wln_ObjType(p, iObj) == ABC_OPER_BIT_INV ) + fprintf( pFile, "~%s", Wln_ObjName(p, Wln_ObjFanin0(p, iObj)) ); + else if ( Wln_ObjType(p, iObj) == ABC_OPER_LOGIC_NOT ) + fprintf( pFile, "!%s", Wln_ObjName(p, Wln_ObjFanin0(p, iObj)) ); + else if ( Wln_ObjType(p, iObj) == ABC_OPER_RED_AND ) + fprintf( pFile, "&%s", Wln_ObjName(p, Wln_ObjFanin0(p, iObj)) ); + else if ( Wln_ObjType(p, iObj) == ABC_OPER_RED_OR ) + fprintf( pFile, "|%s", Wln_ObjName(p, Wln_ObjFanin0(p, iObj)) ); + else if ( Wln_ObjType(p, iObj) == ABC_OPER_RED_XOR ) + fprintf( pFile, "^%s", Wln_ObjName(p, Wln_ObjFanin0(p, iObj)) ); + else if ( Wln_ObjType(p, iObj) == ABC_OPER_RED_NAND ) + fprintf( pFile, "~&%s", Wln_ObjName(p, Wln_ObjFanin0(p, iObj)) ); + else if ( Wln_ObjType(p, iObj) == ABC_OPER_RED_NOR ) + fprintf( pFile, "~|%s", Wln_ObjName(p, Wln_ObjFanin0(p, iObj)) ); + else if ( Wln_ObjType(p, iObj) == ABC_OPER_RED_NXOR ) + fprintf( pFile, "~^%s", Wln_ObjName(p, Wln_ObjFanin0(p, iObj)) ); + else if ( Wln_ObjType(p, iObj) == ABC_OPER_SLICE ) + fprintf( pFile, "%s [%d:%d]", Wln_ObjName(p, Wln_ObjFanin0(p, iObj)), Wln_ObjRangeEnd(p, iObj), Wln_ObjRangeBeg(p, iObj) ); + else if ( Wln_ObjType(p, iObj) == ABC_OPER_SIGNEXT ) + fprintf( pFile, "{ {%d{%s[%d]}}, %s }", Wln_ObjRange(p, iObj) - Wln_ObjRange(p, Wln_ObjFanin0(p, iObj)), Wln_ObjName(p, Wln_ObjFanin0(p, iObj)), Wln_ObjRange(p, Wln_ObjFanin0(p, iObj)) - 1, Wln_ObjName(p, Wln_ObjFanin0(p, iObj)) ); + else if ( Wln_ObjType(p, iObj) == ABC_OPER_ZEROPAD ) + fprintf( pFile, "{ {%d{1\'b0}}, %s }", Wln_ObjRange(p, iObj) - Wln_ObjRange(p, Wln_ObjFanin0(p, iObj)), Wln_ObjName(p, Wln_ObjFanin0(p, iObj)) ); + else if ( Wln_ObjType(p, iObj) == ABC_OPER_CONCAT ) + { + fprintf( pFile, "{" ); + Wln_ObjForEachFanin( p, iObj, iFanin, k ) + fprintf( pFile, " %s%s", Wln_ObjName(p, Wln_ObjFanin(p, iObj, k)), k == Wln_ObjFaninNum(p, iObj)-1 ? "":"," ); + fprintf( pFile, " }" ); + } + else + { + fprintf( pFile, "%s ", Wln_ObjName(p, Wln_ObjFanin(p, iObj, 0)) ); + if ( Wln_ObjType(p, iObj) == ABC_OPER_SHIFT_R ) + fprintf( pFile, ">>" ); + else if ( Wln_ObjType(p, iObj) == ABC_OPER_SHIFT_RA ) + fprintf( pFile, ">>>" ); + else if ( Wln_ObjType(p, iObj) == ABC_OPER_SHIFT_L ) + fprintf( pFile, "<<" ); + else if ( Wln_ObjType(p, iObj) == ABC_OPER_SHIFT_LA ) + fprintf( pFile, "<<<" ); + else if ( Wln_ObjType(p, iObj) == ABC_OPER_BIT_AND ) + fprintf( pFile, "&" ); + else if ( Wln_ObjType(p, iObj) == ABC_OPER_BIT_OR ) + fprintf( pFile, "|" ); + else if ( Wln_ObjType(p, iObj) == ABC_OPER_BIT_XOR ) + fprintf( pFile, "^" ); + else if ( Wln_ObjType(p, iObj) == ABC_OPER_BIT_NAND ) + fprintf( pFile, "~&" ); + else if ( Wln_ObjType(p, iObj) == ABC_OPER_BIT_NOR ) + fprintf( pFile, "~|" ); + else if ( Wln_ObjType(p, iObj) == ABC_OPER_BIT_NXOR ) + fprintf( pFile, "~^" ); + else if ( Wln_ObjType(p, iObj) == ABC_OPER_LOGIC_IMPL ) + fprintf( pFile, "=>" ); + else if ( Wln_ObjType(p, iObj) == ABC_OPER_LOGIC_AND ) + fprintf( pFile, "&&" ); + else if ( Wln_ObjType(p, iObj) == ABC_OPER_LOGIC_OR ) + fprintf( pFile, "||" ); + else if ( Wln_ObjType(p, iObj) == ABC_OPER_LOGIC_XOR ) + fprintf( pFile, "^^" ); + else if ( Wln_ObjType(p, iObj) == ABC_OPER_COMP_EQU ) + fprintf( pFile, "==" ); + else if ( Wln_ObjType(p, iObj) == ABC_OPER_COMP_NOTEQU ) + fprintf( pFile, "!=" ); + else if ( Wln_ObjType(p, iObj) == ABC_OPER_COMP_LESS ) + fprintf( pFile, "<" ); + else if ( Wln_ObjType(p, iObj) == ABC_OPER_COMP_MORE ) + fprintf( pFile, ">" ); + else if ( Wln_ObjType(p, iObj) == ABC_OPER_COMP_LESSEQU ) + fprintf( pFile, "<=" ); + else if ( Wln_ObjType(p, iObj) == ABC_OPER_COMP_MOREEQU ) + fprintf( pFile, ">=" ); + else if ( Wln_ObjType(p, iObj) == ABC_OPER_ARI_ADD ) + fprintf( pFile, "+" ); + else if ( Wln_ObjType(p, iObj) == ABC_OPER_ARI_SUB ) + fprintf( pFile, "-" ); + else if ( Wln_ObjType(p, iObj) == ABC_OPER_ARI_MUL ) + fprintf( pFile, "*" ); + else if ( Wln_ObjType(p, iObj) == ABC_OPER_ARI_DIV ) + fprintf( pFile, "/" ); + else if ( Wln_ObjType(p, iObj) == ABC_OPER_ARI_REM ) + fprintf( pFile, "%%" ); + else if ( Wln_ObjType(p, iObj) == ABC_OPER_ARI_MOD ) + fprintf( pFile, "%%" ); + else if ( Wln_ObjType(p, iObj) == ABC_OPER_ARI_POW ) + fprintf( pFile, "**" ); + else if ( Wln_ObjType(p, iObj) == ABC_OPER_ARI_SQRT ) + fprintf( pFile, "@" ); + else if ( Wln_ObjType(p, iObj) == ABC_OPER_ARI_SQUARE ) + fprintf( pFile, "#" ); + else + { + //assert( 0 ); + printf( "Failed to write node \"%s\" with unknown operator type (%d).\n", Wln_ObjName(p, iObj), Wln_ObjType(p, iObj) ); + fprintf( pFile, "???\n" ); + continue; + } + fprintf( pFile, " %s", Wln_ObjName(p, Wln_ObjFanin(p, iObj, 1)) ); + if ( Wln_ObjFaninNum(p, iObj) == 3 && Wln_ObjType(p, iObj) == ABC_OPER_ARI_ADD ) + fprintf( pFile, " + %s", Wln_ObjName(p, Wln_ObjFanin(p, iObj, 2)) ); + } + } + fprintf( pFile, " ;%s\n", (p->fSmtLib && Wln_ObjIsSigned(p, iObj)) ? " // signed SMT-LIB operator" : "" ); + } + iFanin = 0; + // write DFFs in the end + fprintf( pFile, "\n" ); + Wln_NtkForEachFf( p, iObj, j ) + { + char * pInNames[8] = {"d", "clk", "reset", "set", "enable", "async", "sre", "init"}; + fprintf( pFile, " " ); + fprintf( pFile, "%s (", "ABC_DFFRSE" ); + Wln_ObjForEachFanin( p, iObj, iFanin, k ) + if ( iFanin ) fprintf( pFile, " .%s(%s),", pInNames[k], Wln_ObjName(p, iFanin) ); + fprintf( pFile, " .%s(%s) ) ;\n", "q", Wln_ObjName(p, iObj) ); + } + fprintf( pFile, "\n" ); + fprintf( pFile, "endmodule\n\n" ); +} +void Wln_WriteVer( Wln_Ntk_t * p, char * pFileName ) +{ + FILE * pFile; + pFile = fopen( pFileName, "w" ); + if ( pFile == NULL ) + { + fprintf( stdout, "Wln_WriteVer(): Cannot open the output file \"%s\".\n", pFileName ); + return; + } + fprintf( pFile, "// Benchmark \"%s\" written by ABC on %s\n", p->pName, Extra_TimeStamp() ); + fprintf( pFile, "\n" ); + Wln_WriteTables( pFile, p ); +// if ( fAddCos ) +// Wln_WriteAddPos( p ); + Wln_WriteVerInt( pFile, p ); + fprintf( pFile, "\n" ); + fclose( pFile ); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/bdd/extrab/extraBdd.h b/src/bdd/extrab/extraBdd.h index 3dbc6264..d5dfc85b 100644 --- a/src/bdd/extrab/extraBdd.h +++ b/src/bdd/extrab/extraBdd.h @@ -198,10 +198,52 @@ extern DdNode * Extra_bddAndPermute( DdManager * ddF, DdNode * bF, DdManager extern int Extra_bddCountCubes( DdManager * dd, DdNode ** pFuncs, int nFuncs, int fMode, int nLimit, int * pGuide ); extern void Extra_zddDumpPla( DdManager * dd, DdNode * zCover, int nVars, char * pFileName ); +/* build the set of all tuples of K variables out of N */ +extern DdNode * Extra_bddTuples( DdManager * dd, int K, DdNode * bVarsN ); +extern DdNode * extraBddTuples( DdManager * dd, DdNode * bVarsK, DdNode * bVarsN ); + #ifndef ABC_PRB #define ABC_PRB(dd,f) printf("%s = ", #f); Extra_bddPrint(dd,f); printf("\n") #endif +/*=== extraMaxMin.c ==============================================================*/ + +/* maximal/minimimal */ +extern DdNode * Extra_zddMaximal (DdManager *dd, DdNode *S); +extern DdNode * extraZddMaximal (DdManager *dd, DdNode *S); +extern DdNode * Extra_zddMinimal (DdManager *dd, DdNode *S); +extern DdNode * extraZddMinimal (DdManager *dd, DdNode *S); +/* maximal/minimal of the union of two sets of subsets */ +extern DdNode * Extra_zddMaxUnion (DdManager *dd, DdNode *S, DdNode *T); +extern DdNode * extraZddMaxUnion (DdManager *dd, DdNode *S, DdNode *T); +extern DdNode * Extra_zddMinUnion (DdManager *dd, DdNode *S, DdNode *T); +extern DdNode * extraZddMinUnion (DdManager *dd, DdNode *S, DdNode *T); +/* dot/cross products */ +extern DdNode * Extra_zddDotProduct (DdManager *dd, DdNode *S, DdNode *T); +extern DdNode * extraZddDotProduct (DdManager *dd, DdNode *S, DdNode *T); +extern DdNode * Extra_zddCrossProduct (DdManager *dd, DdNode *S, DdNode *T); +extern DdNode * extraZddCrossProduct (DdManager *dd, DdNode *S, DdNode *T); +extern DdNode * Extra_zddMaxDotProduct (DdManager *dd, DdNode *S, DdNode *T); +extern DdNode * extraZddMaxDotProduct (DdManager *dd, DdNode *S, DdNode *T); + +/*=== extraBddSet.c ==============================================================*/ + +/* subset/supset operations */ +extern DdNode * Extra_zddSubSet (DdManager *dd, DdNode *X, DdNode *Y); +extern DdNode * extraZddSubSet (DdManager *dd, DdNode *X, DdNode *Y); +extern DdNode * Extra_zddSupSet (DdManager *dd, DdNode *X, DdNode *Y); +extern DdNode * extraZddSupSet (DdManager *dd, DdNode *X, DdNode *Y); +extern DdNode * Extra_zddNotSubSet (DdManager *dd, DdNode *X, DdNode *Y); +extern DdNode * extraZddNotSubSet (DdManager *dd, DdNode *X, DdNode *Y); +extern DdNode * Extra_zddNotSupSet (DdManager *dd, DdNode *X, DdNode *Y); +extern DdNode * extraZddNotSupSet (DdManager *dd, DdNode *X, DdNode *Y); +extern DdNode * Extra_zddMaxNotSupSet (DdManager *dd, DdNode *X, DdNode *Y); +extern DdNode * extraZddMaxNotSupSet (DdManager *dd, DdNode *X, DdNode *Y); +/* check whether the empty combination belongs to the set of subsets */ +extern int Extra_zddEmptyBelongs (DdManager *dd, DdNode* zS); +/* check whether the set consists of one subset only */ +extern int Extra_zddIsOneSubset (DdManager *dd, DdNode* zS); + /*=== extraBddKmap.c ================================================================*/ /* displays the Karnaugh Map of a function */ diff --git a/src/bdd/extrab/extraBddMaxMin.c b/src/bdd/extrab/extraBddMaxMin.c new file mode 100644 index 00000000..22d2b00a --- /dev/null +++ b/src/bdd/extrab/extraBddMaxMin.c @@ -0,0 +1,1067 @@ +/**CFile*********************************************************************** + + FileName [zMaxMin.c] + + PackageName [extra] + + Synopsis [Experimental version of some ZDD operators.] + + Description [External procedures included in this module: + <ul> + <li> Extra_zddMaximal(); + <li> Extra_zddMinimal(); + <li> Extra_zddMaxUnion(); + <li> Extra_zddMinUnion(); + <li> Extra_zddDotProduct(); + <li> Extra_zddCrossProduct(); + <li> Extra_zddMaxDotProduct(); + </ul> + Internal procedures included in this module: + <ul> + <li> extraZddMaximal(); + <li> extraZddMinimal(); + <li> extraZddMaxUnion(); + <li> extraZddMinUnion(); + <li> extraZddDotProduct(); + <li> extraZddCrossProduct(); + <li> extraZddMaxDotProduct(); + </ul> + StaTc procedures included in this module: + <ul> + </ul> + + DotProduct and MaxDotProduct were introduced + by O.Coudert to solve problems arising in two-level planar routing + See O. Coudert, C.-J. R. Shi. Exact Multi-Layer Topological Planar + Routing. Proc. of IEEE Custom Integrated Circuit Conference '96, + pp. 179-182. + ] + + SeeAlso [] + + Author [Alan Mishchenko] + + Copyright [] + + ReviSon [$zMaxMin.c, v.1.2, November 26, 2000, alanmi $] + +******************************************************************************/ + +#include "extraBdd.h" + +ABC_NAMESPACE_IMPL_START + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaTcStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* StaTc Function prototypes */ +/*---------------------------------------------------------------------------*/ + +/**AutomaTcEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported Functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Computes the maximal of a set represented by its ZDD.] + + Description [] + + SideEffects [] + + SeeAlso [Extra_zddMinimal] + +******************************************************************************/ +DdNode * +Extra_zddMaximal( + DdManager * dd, + DdNode * S) +{ + DdNode *res; + do { + dd->reordered = 0; + res = extraZddMaximal(dd, S); + } while (dd->reordered == 1); + return(res); + +} /* end of Extra_zddMaximal */ + + +/**Function******************************************************************** + + Synopsis [Computes the minimal of a set represented by its ZDD.] + + Description [] + + SideEffects [] + + SeeAlso [Extra_zddMaximal] + +******************************************************************************/ +DdNode * +Extra_zddMinimal( + DdManager * dd, + DdNode * S) +{ + DdNode *res; + do { + dd->reordered = 0; + res = extraZddMinimal(dd, S); + } while (dd->reordered == 1); + return(res); + +} /* end of Extra_zddMinimal */ + + +/**Function******************************************************************** + + Synopsis [Computes the maximal of the union of two sets represented by ZDDs.] + + Description [] + + SideEffects [] + + SeeAlso [Extra_zddMaximal Extra_zddMimimal Extra_zddMinUnion] + +******************************************************************************/ +DdNode * +Extra_zddMaxUnion( + DdManager * dd, + DdNode * S, + DdNode * T) +{ + DdNode *res; + do { + dd->reordered = 0; + res = extraZddMaxUnion(dd, S, T); + } while (dd->reordered == 1); + return(res); + +} /* end of Extra_zddMaxUnion */ + + +/**Function******************************************************************** + + Synopsis [Computes the minimal of the union of two sets represented by ZDDs.] + + Description [] + + SideEffects [] + + SeeAlso [Extra_zddMaximal Extra_zddMimimal Extra_zddMaxUnion] + +******************************************************************************/ +DdNode * +Extra_zddMinUnion( + DdManager * dd, + DdNode * S, + DdNode * T) +{ + DdNode *res; + do { + dd->reordered = 0; + res = extraZddMinUnion(dd, S, T); + } while (dd->reordered == 1); + return(res); + +} /* end of Extra_zddMinUnion */ + + +/**Function******************************************************************** + + Synopsis [Computes the dot product of two sets of subsets represented by ZDDs.] + + Description [The dot product is defined as a set of pair-wise unions of subsets + belonging to the arguments.] + + SideEffects [] + + SeeAlso [Extra_zddCrossProduct] + +******************************************************************************/ +DdNode * +Extra_zddDotProduct( + DdManager * dd, + DdNode * S, + DdNode * T) +{ + DdNode *res; + do { + dd->reordered = 0; + res = extraZddDotProduct(dd, S, T); + } while (dd->reordered == 1); + return(res); + +} /* end of Extra_zddDotProduct */ + + +/**Function******************************************************************** + + Synopsis [Computes the cross product of two sets of subsets represented by ZDDs.] + + Description [The cross product is defined as a set of pair-wise intersections of subsets + belonging to the arguments.] + + SideEffects [] + + SeeAlso [Extra_zddDotProduct] + +******************************************************************************/ +DdNode * +Extra_zddCrossProduct( + DdManager * dd, + DdNode * S, + DdNode * T) +{ + DdNode *res; + do { + dd->reordered = 0; + res = extraZddCrossProduct(dd, S, T); + } while (dd->reordered == 1); + return(res); + +} /* end of Extra_zddCrossProduct */ + + +/**Function******************************************************************** + + Synopsis [Computes the maximal of the DotProduct of the union of two sets represented by ZDDs.] + + Description [] + + SideEffects [] + + SeeAlso [Extra_zddDotProduct Extra_zddMaximal Extra_zddMinCrossProduct] + +******************************************************************************/ +DdNode * +Extra_zddMaxDotProduct( + DdManager * dd, + DdNode * S, + DdNode * T) +{ + DdNode *res; + do { + dd->reordered = 0; + res = extraZddMaxDotProduct(dd, S, T); + } while (dd->reordered == 1); + return(res); + +} /* end of Extra_zddMaxDotProduct */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal Functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Extra_zddMaximal.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DdNode * +extraZddMaximal( + DdManager * dd, + DdNode * zSet) +{ + DdNode *zRes; + statLine(dd); + + /* consider terminal cases */ + if ( zSet == z0 || zSet == z1 ) + return zSet; + + /* check cache */ + zRes = cuddCacheLookup1Zdd(dd, extraZddMaximal, zSet); + if (zRes) + return(zRes); + else + { + DdNode *zSet0, *zSet1, *zRes0, *zRes1; + + /* compute maximal for subsets without the top-most element */ + zSet0 = extraZddMaximal(dd, cuddE(zSet)); + if ( zSet0 == NULL ) + return NULL; + cuddRef( zSet0 ); + + /* compute maximal for subsets with the top-most element */ + zSet1 = extraZddMaximal(dd, cuddT(zSet)); + if ( zSet1 == NULL ) + { + Cudd_RecursiveDerefZdd(dd, zSet0); + return NULL; + } + cuddRef( zSet1 ); + + /* remove subsets without this element covered by subsets with this element */ + zRes0 = extraZddNotSubSet(dd, zSet0, zSet1); + if ( zRes0 == NULL ) + { + Cudd_RecursiveDerefZdd(dd, zSet0); + Cudd_RecursiveDerefZdd(dd, zSet1); + return NULL; + } + cuddRef( zRes0 ); + Cudd_RecursiveDerefZdd(dd, zSet0); + + /* subset with this element remains unchanged */ + zRes1 = zSet1; + + /* create the new node */ + zRes = cuddZddGetNode( dd, zSet->index, zRes1, zRes0 ); + if ( zRes == NULL ) + { + Cudd_RecursiveDerefZdd( dd, zRes0 ); + Cudd_RecursiveDerefZdd( dd, zRes1 ); + return NULL; + } + cuddDeref( zRes0 ); + cuddDeref( zRes1 ); + + /* insert the result into cache */ + cuddCacheInsert1(dd, extraZddMaximal, zSet, zRes); + return zRes; + } +} /* end of extraZddMaximal */ + + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Extra_zddMinimal.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DdNode * +extraZddMinimal( + DdManager * dd, + DdNode * zSet) +{ + DdNode *zRes; + statLine(dd); + + /* consider terminal cases */ + if ( zSet == z0 ) + return zSet; + /* the empty combinaTon, if present, is the only minimal combinaTon */ + if ( Extra_zddEmptyBelongs(dd, zSet) ) + return z1; + + /* check cache */ + zRes = cuddCacheLookup1Zdd(dd, extraZddMinimal, zSet); + if (zRes) + return(zRes); + else + { + DdNode *zSet0, *zSet1, *zRes0, *zRes1; + + /* compute minimal for subsets without the top-most element */ + zSet0 = extraZddMinimal(dd, cuddE(zSet)); + if ( zSet0 == NULL ) + return NULL; + cuddRef( zSet0 ); + + /* compute minimal for subsets with the top-most element */ + zSet1 = extraZddMinimal(dd, cuddT(zSet)); + if ( zSet1 == NULL ) + { + Cudd_RecursiveDerefZdd(dd, zSet0); + return NULL; + } + cuddRef( zSet1 ); + + /* subset without this element remains unchanged */ + zRes0 = zSet0; + + /* remove subsets with this element that contain subsets without this element */ + zRes1 = extraZddNotSupSet(dd, zSet1, zSet0); + if ( zRes1 == NULL ) + { + Cudd_RecursiveDerefZdd(dd, zSet0); + Cudd_RecursiveDerefZdd(dd, zSet1); + return NULL; + } + cuddRef( zRes1 ); + Cudd_RecursiveDerefZdd(dd, zSet1); + + /* create the new node */ + zRes = cuddZddGetNode( dd, zSet->index, zRes1, zRes0 ); + if ( zRes == NULL ) + { + Cudd_RecursiveDerefZdd( dd, zRes0 ); + Cudd_RecursiveDerefZdd( dd, zRes1 ); + return NULL; + } + cuddDeref( zRes0 ); + cuddDeref( zRes1 ); + + /* insert the result into cache */ + cuddCacheInsert1(dd, extraZddMinimal, zSet, zRes); + return zRes; + } +} /* end of extraZddMinimal */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Extra_zddMaxUnion.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DdNode * +extraZddMaxUnion( + DdManager * dd, + DdNode * S, + DdNode * T) +{ + DdNode *zRes; + int TopS, TopT; + statLine(dd); + + /* consider terminal cases */ + if ( S == z0 ) + return T; + if ( T == z0 ) + return S; + if ( S == T ) + return S; + if ( S == z1 ) + return T; + if ( T == z1 ) + return S; + + /* the operation is commutative - normalize the problem */ + TopS = dd->permZ[S->index]; + TopT = dd->permZ[T->index]; + + if ( TopS > TopT || (TopS == TopT && S > T) ) + return extraZddMaxUnion(dd, T, S); + + /* check cache */ + zRes = cuddCacheLookup2Zdd(dd, extraZddMaxUnion, S, T); + if (zRes) + return zRes; + else + { + DdNode *zSet0, *zSet1, *zRes0, *zRes1; + + if ( TopS == TopT ) + { + /* compute maximal for subsets without the top-most element */ + zSet0 = extraZddMaxUnion(dd, cuddE(S), cuddE(T) ); + if ( zSet0 == NULL ) + return NULL; + cuddRef( zSet0 ); + + /* compute maximal for subsets with the top-most element */ + zSet1 = extraZddMaxUnion(dd, cuddT(S), cuddT(T) ); + if ( zSet1 == NULL ) + { + Cudd_RecursiveDerefZdd(dd, zSet0); + return NULL; + } + cuddRef( zSet1 ); + } + else /* if ( TopS < TopT ) */ + { + /* compute maximal for subsets without the top-most element */ + zSet0 = extraZddMaxUnion(dd, cuddE(S), T ); + if ( zSet0 == NULL ) + return NULL; + cuddRef( zSet0 ); + + /* subset with this element is just the cofactor of S */ + zSet1 = cuddT(S); + cuddRef( zSet1 ); + } + + /* remove subsets without this element covered by subsets with this element */ + zRes0 = extraZddNotSubSet(dd, zSet0, zSet1); + if ( zRes0 == NULL ) + { + Cudd_RecursiveDerefZdd(dd, zSet0); + Cudd_RecursiveDerefZdd(dd, zSet1); + return NULL; + } + cuddRef( zRes0 ); + Cudd_RecursiveDerefZdd(dd, zSet0); + + /* subset with this element remains unchanged */ + zRes1 = zSet1; + + /* create the new node */ + zRes = cuddZddGetNode( dd, S->index, zRes1, zRes0 ); + if ( zRes == NULL ) + { + Cudd_RecursiveDerefZdd( dd, zRes0 ); + Cudd_RecursiveDerefZdd( dd, zRes1 ); + return NULL; + } + cuddDeref( zRes0 ); + cuddDeref( zRes1 ); + + /* insert the result into cache */ + cuddCacheInsert2(dd, extraZddMaxUnion, S, T, zRes); + return zRes; + } +} /* end of extraZddMaxUnion */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Extra_zddMinUnion.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DdNode * +extraZddMinUnion( + DdManager * dd, + DdNode * S, + DdNode * T) +{ + DdNode *zRes; + int TopS, TopT; + statLine(dd); + + /* consider terminal cases */ + if ( S == z0 ) + return T; + if ( T == z0 ) + return S; + if ( S == T ) + return S; + /* the empty combination, if present, is the only minimal combination */ + if ( Extra_zddEmptyBelongs(dd, S) || Extra_zddEmptyBelongs(dd, T) ) + return z1; + + /* the operation is commutative - normalize the problem */ + TopS = dd->permZ[S->index]; + TopT = dd->permZ[T->index]; + + if ( TopS > TopT || (TopS == TopT && S > T) ) + return extraZddMinUnion(dd, T, S); + + /* check cache */ + zRes = cuddCacheLookup2Zdd(dd, extraZddMinUnion, S, T); + if (zRes) + return(zRes); + else + { + DdNode *zSet0, *zSet1, *zRes0, *zRes1; + if ( TopS == TopT ) + { + /* compute maximal for subsets without the top-most element */ + zSet0 = extraZddMinUnion(dd, cuddE(S), cuddE(T) ); + if ( zSet0 == NULL ) + return NULL; + cuddRef( zSet0 ); + + /* compute maximal for subsets with the top-most element */ + zSet1 = extraZddMinUnion(dd, cuddT(S), cuddT(T) ); + if ( zSet1 == NULL ) + { + Cudd_RecursiveDerefZdd(dd, zSet0); + return NULL; + } + cuddRef( zSet1 ); + } + else /* if ( TopS < TopT ) */ + { + /* compute maximal for subsets without the top-most element */ + zSet0 = extraZddMinUnion(dd, cuddE(S), T ); + if ( zSet0 == NULL ) + return NULL; + cuddRef( zSet0 ); + + /* subset with this element is just the cofactor of S */ + zSet1 = cuddT(S); + cuddRef( zSet1 ); + } + + /* subset without this element remains unchanged */ + zRes0 = zSet0; + + /* remove subsets with this element that contain subsets without this element */ + zRes1 = extraZddNotSupSet(dd, zSet1, zSet0); + if ( zRes1 == NULL ) + { + Cudd_RecursiveDerefZdd(dd, zSet0); + Cudd_RecursiveDerefZdd(dd, zSet1); + return NULL; + } + cuddRef( zRes1 ); + Cudd_RecursiveDerefZdd(dd, zSet1); + + /* create the new node */ + zRes = cuddZddGetNode( dd, S->index, zRes1, zRes0 ); + if ( zRes == NULL ) + { + Cudd_RecursiveDerefZdd( dd, zRes0 ); + Cudd_RecursiveDerefZdd( dd, zRes1 ); + return NULL; + } + cuddDeref( zRes0 ); + cuddDeref( zRes1 ); + + /* insert the result into cache */ + cuddCacheInsert2(dd, extraZddMinUnion, S, T, zRes); + return zRes; + } +} /* end of extraZddMinUnion */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Extra_zddDotProduct.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DdNode * +extraZddDotProduct( + DdManager * dd, + DdNode * S, + DdNode * T) +{ + DdNode *zRes; + int TopS, TopT; + statLine(dd); + + /* consider terminal cases */ + if ( S == z0 || T == z0 ) + return z0; + if ( S == z1 ) + return T; + if ( T == z1 ) + return S; + + /* the operation is commutative - normalize the problem */ + TopS = dd->permZ[S->index]; + TopT = dd->permZ[T->index]; + + if ( TopS > TopT || (TopS == TopT && S > T) ) + return extraZddDotProduct(dd, T, S); + + /* check cache */ + zRes = cuddCacheLookup2Zdd(dd, extraZddDotProduct, S, T); + if (zRes) + return zRes; + else + { + DdNode *zSet0, *zSet1, *zRes0, *zRes1, *zTemp; + if ( TopS == TopT ) + { + /* compute the union of two cofactors of T (T0+T1) */ + zTemp = cuddZddUnion(dd, cuddE(T), cuddT(T) ); + if ( zTemp == NULL ) + return NULL; + cuddRef( zTemp ); + + /* compute DotProduct with the top element for subsets (S1, T0+T1) */ + zSet0 = extraZddDotProduct(dd, cuddT(S), zTemp ); + if ( zSet0 == NULL ) + { + Cudd_RecursiveDerefZdd(dd, zTemp); + return NULL; + } + cuddRef( zSet0 ); + Cudd_RecursiveDerefZdd(dd, zTemp); + + /* compute DotProduct with the top element for subsets (S0, T1) */ + zSet1 = extraZddDotProduct(dd, cuddE(S), cuddT(T) ); + if ( zSet1 == NULL ) + { + Cudd_RecursiveDerefZdd(dd, zSet0); + return NULL; + } + cuddRef( zSet1 ); + + /* compute the union of these two partial results (zSet0 + zSet1) */ + zRes1 = cuddZddUnion(dd, zSet0, zSet1 ); + if ( zRes1 == NULL ) + { + Cudd_RecursiveDerefZdd(dd, zSet0); + Cudd_RecursiveDerefZdd(dd, zSet1); + return NULL; + } + cuddRef( zRes1 ); + Cudd_RecursiveDerefZdd(dd, zSet0); + Cudd_RecursiveDerefZdd(dd, zSet1); + + /* compute DotProduct for subsets without the top-most element */ + zRes0 = extraZddDotProduct(dd, cuddE(S), cuddE(T) ); + if ( zRes0 == NULL ) + { + Cudd_RecursiveDerefZdd(dd, zRes1); + return NULL; + } + cuddRef( zRes0 ); + } + else /* if ( TopS < TopT ) */ + { + /* compute DotProduct with the top element for subsets (S1, T) */ + zRes1 = extraZddDotProduct(dd, cuddT(S), T ); + if ( zRes1 == NULL ) + return NULL; + cuddRef( zRes1 ); + + /* compute DotProduct for subsets without the top-most element */ + zRes0 = extraZddDotProduct(dd, cuddE(S), T ); + if ( zRes0 == NULL ) + { + Cudd_RecursiveDerefZdd(dd, zRes1); + return NULL; + } + cuddRef( zRes0 ); + } + + /* create the new node */ + zRes = cuddZddGetNode( dd, S->index, zRes1, zRes0 ); + if ( zRes == NULL ) + { + Cudd_RecursiveDerefZdd( dd, zRes0 ); + Cudd_RecursiveDerefZdd( dd, zRes1 ); + return NULL; + } + cuddDeref( zRes0 ); + cuddDeref( zRes1 ); + + /* insert the result into cache */ + cuddCacheInsert2(dd, extraZddDotProduct, S, T, zRes); + return zRes; + } +} /* end of extraZddDotProduct */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Extra_zddCrossProduct.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DdNode * +extraZddCrossProduct( + DdManager * dd, + DdNode * S, + DdNode * T) +{ + DdNode *zRes; + int TopS, TopT; + statLine(dd); + + /* consider terminal cases */ + if ( S == z0 || T == z0 ) + return z0; + if ( S == z1 || T == z1 ) + return z1; + + /* the operation is commutative - normalize the problem */ + TopS = dd->permZ[S->index]; + TopT = dd->permZ[T->index]; + + if ( TopS > TopT || (TopS == TopT && S > T) ) + return extraZddCrossProduct(dd, T, S); + + /* check cache */ + zRes = cuddCacheLookup2Zdd(dd, extraZddCrossProduct, S, T); + if (zRes) + return zRes; + else + { + DdNode *zSet0, *zSet1, *zRes0, *zRes1, *zTemp; + + if ( TopS == TopT ) + { + /* compute the union of two cofactors of T (T0+T1) */ + zTemp = cuddZddUnion(dd, cuddE(T), cuddT(T) ); + if ( zTemp == NULL ) + return NULL; + cuddRef( zTemp ); + + /* compute CrossProduct without the top element for subsets (S0, T0+T1) */ + zSet0 = extraZddCrossProduct(dd, cuddE(S), zTemp ); + if ( zSet0 == NULL ) + { + Cudd_RecursiveDerefZdd(dd, zTemp); + return NULL; + } + cuddRef( zSet0 ); + Cudd_RecursiveDerefZdd(dd, zTemp); + + /* compute CrossProduct without the top element for subsets (S1, T0) */ + zSet1 = extraZddCrossProduct(dd, cuddT(S), cuddE(T) ); + if ( zSet1 == NULL ) + { + Cudd_RecursiveDerefZdd(dd, zSet0); + return NULL; + } + cuddRef( zSet1 ); + + /* compute the union of these two partial results (zSet0 + zSet1) */ + zRes0 = cuddZddUnion(dd, zSet0, zSet1 ); + if ( zRes0 == NULL ) + { + Cudd_RecursiveDerefZdd(dd, zSet0); + Cudd_RecursiveDerefZdd(dd, zSet1); + return NULL; + } + cuddRef( zRes0 ); + Cudd_RecursiveDerefZdd(dd, zSet0); + Cudd_RecursiveDerefZdd(dd, zSet1); + + /* compute CrossProduct for subsets with the top-most element */ + zRes1 = extraZddCrossProduct(dd, cuddT(S), cuddT(T) ); + if ( zRes1 == NULL ) + { + Cudd_RecursiveDerefZdd(dd, zRes0); + return NULL; + } + cuddRef( zRes1 ); + + /* create the new node */ + zRes = cuddZddGetNode( dd, S->index, zRes1, zRes0 ); + if ( zRes == NULL ) + { + Cudd_RecursiveDerefZdd( dd, zRes0 ); + Cudd_RecursiveDerefZdd( dd, zRes1 ); + return NULL; + } + cuddDeref( zRes0 ); + cuddDeref( zRes1 ); + } + else /* if ( TopS < TopT ) */ + { + /* compute CrossProduct without the top element (S0, T) */ + zSet0 = extraZddCrossProduct(dd, cuddE(S), T ); + if ( zSet0 == NULL ) + return NULL; + cuddRef( zSet0 ); + + /* compute CrossProduct without the top element (S1, T) */ + zSet1 = extraZddCrossProduct(dd, cuddT(S), T ); + if ( zSet1 == NULL ) + { + Cudd_RecursiveDerefZdd(dd, zSet0); + return NULL; + } + cuddRef( zSet1 ); + + /* compute the union of these two partial results (zSet0 + zSet1) */ + zRes = cuddZddUnion(dd, zSet0, zSet1 ); + if ( zRes == NULL ) + { + Cudd_RecursiveDerefZdd(dd, zSet0); + Cudd_RecursiveDerefZdd(dd, zSet1); + return NULL; + } + cuddRef( zRes ); + Cudd_RecursiveDerefZdd(dd, zSet0); + Cudd_RecursiveDerefZdd(dd, zSet1); + cuddDeref( zRes ); + } + + /* insert the result into cache */ + cuddCacheInsert2(dd, extraZddCrossProduct, S, T, zRes); + return zRes; + } +} /* end of extraZddCrossProduct */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Extra_zddMaxDotProduct.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DdNode * +extraZddMaxDotProduct( + DdManager * dd, + DdNode * S, + DdNode * T) +{ + DdNode *zRes; + int TopS, TopT; + statLine(dd); + + /* consider terminal cases */ + if ( S == z0 || T == z0 ) + return z0; + if ( S == z1 ) + return T; + if ( T == z1 ) + return S; + + /* the operation is commutative - normalize the problem */ + TopS = dd->permZ[S->index]; + TopT = dd->permZ[T->index]; + + if ( TopS > TopT || (TopS == TopT && S > T) ) + return extraZddMaxDotProduct(dd, T, S); + + /* check cache */ + zRes = cuddCacheLookup2Zdd(dd, extraZddMaxDotProduct, S, T); + if (zRes) + return zRes; + else + { + DdNode *zSet0, *zSet1, *zRes0, *zRes1, *zTemp; + if ( TopS == TopT ) + { + /* compute the union of two cofactors of T (T0+T1) */ + zTemp = extraZddMaxUnion(dd, cuddE(T), cuddT(T) ); + if ( zTemp == NULL ) + return NULL; + cuddRef( zTemp ); + + /* compute MaxDotProduct with the top element for subsets (S1, T0+T1) */ + zSet0 = extraZddMaxDotProduct(dd, cuddT(S), zTemp ); + if ( zSet0 == NULL ) + { + Cudd_RecursiveDerefZdd(dd, zTemp); + return NULL; + } + cuddRef( zSet0 ); + Cudd_RecursiveDerefZdd(dd, zTemp); + + /* compute MaxDotProduct with the top element for subsets (S0, T1) */ + zSet1 = extraZddMaxDotProduct(dd, cuddE(S), cuddT(T) ); + if ( zSet1 == NULL ) + { + Cudd_RecursiveDerefZdd(dd, zSet0); + return NULL; + } + cuddRef( zSet1 ); + + /* compute the union of these two partial results (zSet0 + zSet1) */ + zRes1 = extraZddMaxUnion(dd, zSet0, zSet1 ); + if ( zRes1 == NULL ) + { + Cudd_RecursiveDerefZdd(dd, zSet0); + Cudd_RecursiveDerefZdd(dd, zSet1); + return NULL; + } + cuddRef( zRes1 ); + Cudd_RecursiveDerefZdd(dd, zSet0); + Cudd_RecursiveDerefZdd(dd, zSet1); + + /* compute MaxDotProduct for subsets without the top-most element */ + zRes0 = extraZddMaxDotProduct(dd, cuddE(S), cuddE(T) ); + if ( zRes0 == NULL ) + { + Cudd_RecursiveDerefZdd(dd, zRes1); + return NULL; + } + cuddRef( zRes0 ); + } + else /* if ( TopS < TopT ) */ + { + /* compute MaxDotProduct with the top element for subsets (S1, T) */ + zRes1 = extraZddMaxDotProduct(dd, cuddT(S), T ); + if ( zRes1 == NULL ) + return NULL; + cuddRef( zRes1 ); + + /* compute MaxDotProduct for subsets without the top-most element */ + zRes0 = extraZddMaxDotProduct(dd, cuddE(S), T ); + if ( zRes0 == NULL ) + { + Cudd_RecursiveDerefZdd(dd, zRes1); + return NULL; + } + cuddRef( zRes0 ); + } + + /* remove subsets without this element covered by subsets with this element */ + zRes0 = extraZddNotSubSet(dd, zTemp = zRes0, zRes1); + if ( zRes0 == NULL ) + { + Cudd_RecursiveDerefZdd(dd, zTemp); + Cudd_RecursiveDerefZdd(dd, zRes1); + return NULL; + } + cuddRef( zRes0 ); + Cudd_RecursiveDerefZdd(dd, zTemp); + + /* create the new node */ + zRes = cuddZddGetNode( dd, S->index, zRes1, zRes0 ); + if ( zRes == NULL ) + { + Cudd_RecursiveDerefZdd( dd, zRes0 ); + Cudd_RecursiveDerefZdd( dd, zRes1 ); + return NULL; + } + cuddDeref( zRes0 ); + cuddDeref( zRes1 ); + + /* insert the result into cache */ + cuddCacheInsert2(dd, extraZddMaxDotProduct, S, T, zRes); + return zRes; + } +} /* end of extraZddMaxDotProduct */ + +/*---------------------------------------------------------------------------*/ +/* Definition of staTc Functions */ +/*---------------------------------------------------------------------------*/ + +ABC_NAMESPACE_IMPL_END diff --git a/src/bdd/extrab/extraBddMisc.c b/src/bdd/extrab/extraBddMisc.c index a5cda242..42003864 100644 --- a/src/bdd/extrab/extraBddMisc.c +++ b/src/bdd/extrab/extraBddMisc.c @@ -2582,6 +2582,163 @@ void Extra_ZddTest() } +/**Function******************************************************************** + + Synopsis [Performs the reordering-sensitive step of Extra_bddTuples().] + + Description [Generates in a bottom-up fashion BDD for all combinations + composed of k variables out of variables belonging to bVarsN.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +DdNode * extraBddTuples( + DdManager * dd, /* the DD manager */ + DdNode * bVarsK, /* the number of variables in tuples */ + DdNode * bVarsN) /* the set of all variables */ +{ + DdNode *bRes, *bRes0, *bRes1; + statLine(dd); + + /* terminal cases */ +/* if ( k < 0 || k > n ) + * return dd->zero; + * if ( n == 0 ) + * return dd->one; + */ + if ( cuddI( dd, bVarsK->index ) < cuddI( dd, bVarsN->index ) ) + return b0; + if ( bVarsN == b1 ) + return b1; + + /* check cache */ + bRes = cuddCacheLookup2(dd, extraBddTuples, bVarsK, bVarsN); + if (bRes) + return(bRes); + + /* ZDD in which is variable is 0 */ +/* bRes0 = extraBddTuples( dd, k, n-1 ); */ + bRes0 = extraBddTuples( dd, bVarsK, cuddT(bVarsN) ); + if ( bRes0 == NULL ) + return NULL; + cuddRef( bRes0 ); + + /* ZDD in which is variable is 1 */ +/* bRes1 = extraBddTuples( dd, k-1, n-1 ); */ + if ( bVarsK == b1 ) + { + bRes1 = b0; + cuddRef( bRes1 ); + } + else + { + bRes1 = extraBddTuples( dd, cuddT(bVarsK), cuddT(bVarsN) ); + if ( bRes1 == NULL ) + { + Cudd_RecursiveDeref( dd, bRes0 ); + return NULL; + } + cuddRef( bRes1 ); + } + + /* consider the case when Res0 and Res1 are the same node */ + if ( bRes0 == bRes1 ) + bRes = bRes1; + /* consider the case when Res1 is complemented */ + else if ( Cudd_IsComplement(bRes1) ) + { + bRes = cuddUniqueInter(dd, bVarsN->index, Cudd_Not(bRes1), Cudd_Not(bRes0)); + if ( bRes == NULL ) + { + Cudd_RecursiveDeref(dd,bRes0); + Cudd_RecursiveDeref(dd,bRes1); + return NULL; + } + bRes = Cudd_Not(bRes); + } + else + { + bRes = cuddUniqueInter( dd, bVarsN->index, bRes1, bRes0 ); + if ( bRes == NULL ) + { + Cudd_RecursiveDeref(dd,bRes0); + Cudd_RecursiveDeref(dd,bRes1); + return NULL; + } + } + cuddDeref( bRes0 ); + cuddDeref( bRes1 ); + + /* insert the result into cache */ + cuddCacheInsert2(dd, extraBddTuples, bVarsK, bVarsN, bRes); + return bRes; + +} /* end of extraBddTuples */ + +/**Function******************************************************************** + + Synopsis [Builds BDD representing the set of fixed-size variable tuples.] + + Description [Creates BDD of all combinations of variables in Support that have k vars in them.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +DdNode * Extra_bddTuples( + DdManager * dd, /* the DD manager */ + int K, /* the number of variables in tuples */ + DdNode * VarsN) /* the set of all variables represented as a BDD */ +{ + DdNode *res; + int autoDyn; + + /* it is important that reordering does not happen, + otherwise, this methods will not work */ + + autoDyn = dd->autoDyn; + dd->autoDyn = 0; + + do { + /* transform the numeric arguments (K) into a DdNode * argument; + * this allows us to use the standard internal CUDD cache */ + DdNode *VarSet = VarsN, *VarsK = VarsN; + int nVars = 0, i; + + /* determine the number of variables in VarSet */ + while ( VarSet != b1 ) + { + nVars++; + /* make sure that the VarSet is a cube */ + if ( cuddE( VarSet ) != b0 ) + return NULL; + VarSet = cuddT( VarSet ); + } + /* make sure that the number of variables in VarSet is less or equal + that the number of variables that should be present in the tuples + */ + if ( K > nVars ) + return NULL; + + /* the second argument in the recursive call stands for <n>; + * create the first argument, which stands for <k> + * as when we are talking about the tuple of <k> out of <n> */ + for ( i = 0; i < nVars-K; i++ ) + VarsK = cuddT( VarsK ); + + dd->reordered = 0; + res = extraBddTuples(dd, VarsK, VarsN ); + + } while (dd->reordered == 1); + dd->autoDyn = autoDyn; + return(res); + +} /* end of Extra_bddTuples */ + + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/bdd/extrab/extraBddSet.c b/src/bdd/extrab/extraBddSet.c new file mode 100644 index 00000000..882c474a --- /dev/null +++ b/src/bdd/extrab/extraBddSet.c @@ -0,0 +1,941 @@ +/**CFile*********************************************************************** + + FileName [zSubSet.c] + + PackageName [extra] + + Synopsis [Experimental version of some ZDD operators.] + + Description [External procedures included in this module: + <ul> + <li> Extra_zddSubSet(); + <li> Extra_zddSupSet(); + <li> Extra_zddNotSubSet(); + <li> Extra_zddNotSupSet(); + <li> Extra_zddMaxNotSupSet(); + <li> Extra_zddEmptyBelongs(); + <li> Extra_zddIsOneSubset(); + </ul> + Internal procedures included in this module: + <ul> + <li> extraZddSubSet(); + <li> extraZddSupSet(); + <li> extraZddNotSubSet(); + <li> extraZddNotSupSet(); + <li> extraZddMaxNotSupSet(); + </ul> + Static procedures included in this module: + <ul> + </ul> + + SubSet, SupSet, NotSubSet, NotSupSet were introduced + by O.Coudert to solve problems arising in two-level SOP + minimization. See O. Coudert, "Two-Level Logic Minimization: + An Overview", Integration. Vol. 17, No. 2, pp. 97-140, Oct 1994. + ] + + SeeAlso [] + + Author [Alan Mishchenko] + + Copyright [] + + Revision [$zSubSet.c, v.1.2, November 16, 2000, alanmi $] + +******************************************************************************/ + +#include "extraBdd.h" + +ABC_NAMESPACE_IMPL_START + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticEnd***************************************************************/ + + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Computes subsets in X that are contained in some of the subsets of Y.] + + Description [] + + SideEffects [] + + SeeAlso [Extra_zddNotSubSet, Extra_zddSupSet, Extra_zddNotSupSet] + +******************************************************************************/ +DdNode * +Extra_zddSubSet( + DdManager * dd, + DdNode * X, + DdNode * Y) +{ + DdNode *res; + int autoDynZ; + + autoDynZ = dd->autoDynZ; + dd->autoDynZ = 0; + + do { + dd->reordered = 0; + res = extraZddSubSet(dd, X, Y); + } while (dd->reordered == 1); + dd->autoDynZ = autoDynZ; + return(res); + +} /* end of Extra_zddSubSet */ + + +/**Function******************************************************************** + + Synopsis [Computes subsets in X that contain some of the subsets of Y.] + + Description [] + + SideEffects [] + + SeeAlso [Extra_zddSubSet, Extra_zddNotSubSet, Extra_zddNotSupSet] + +******************************************************************************/ +DdNode * +Extra_zddSupSet( + DdManager * dd, + DdNode * X, + DdNode * Y) +{ + DdNode *res; + int autoDynZ; + + autoDynZ = dd->autoDynZ; + dd->autoDynZ = 0; + + do { + dd->reordered = 0; + res = extraZddSupSet(dd, X, Y); + } while (dd->reordered == 1); + dd->autoDynZ = autoDynZ; + return(res); + +} /* end of Extra_zddSupSet */ + +/**Function******************************************************************** + + Synopsis [Computes subsets in X that are not contained in any of the subsets of Y.] + + Description [] + + SideEffects [] + + SeeAlso [Extra_zddSubSet, Extra_zddSupSet, Extra_zddNotSupSet] + +******************************************************************************/ +DdNode * +Extra_zddNotSubSet( + DdManager * dd, + DdNode * X, + DdNode * Y) +{ + DdNode *res; + int autoDynZ; + + autoDynZ = dd->autoDynZ; + dd->autoDynZ = 0; + + do { + dd->reordered = 0; + res = extraZddNotSubSet(dd, X, Y); + } while (dd->reordered == 1); + dd->autoDynZ = autoDynZ; + return(res); + +} /* end of Extra_zddNotSubSet */ + + +/**Function******************************************************************** + + Synopsis [Computes subsets in X that do not contain any of the subsets of Y.] + + Description [] + + SideEffects [] + + SeeAlso [Extra_zddSubSet, Extra_zddSupSet, Extra_zddNotSubSet] + +******************************************************************************/ +DdNode * +Extra_zddNotSupSet( + DdManager * dd, + DdNode * X, + DdNode * Y) +{ + DdNode *res; + int autoDynZ; + + autoDynZ = dd->autoDynZ; + dd->autoDynZ = 0; + + do { + dd->reordered = 0; + res = extraZddNotSupSet(dd, X, Y); + } while (dd->reordered == 1); + dd->autoDynZ = autoDynZ; + return(res); + +} /* end of Extra_zddNotSupSet */ + + + +/**Function******************************************************************** + + Synopsis [Computes the maximal of subsets in X not contained in any of the subsets of Y.] + + Description [] + + SideEffects [] + + SeeAlso [Extra_zddSubSet, Extra_zddSupSet, Extra_zddSubSet, Extra_zddNotSupSet] + +******************************************************************************/ +DdNode * +Extra_zddMaxNotSupSet( + DdManager * dd, + DdNode * X, + DdNode * Y) +{ + DdNode *res; + int autoDynZ; + + autoDynZ = dd->autoDynZ; + dd->autoDynZ = 0; + + do { + dd->reordered = 0; + res = extraZddMaxNotSupSet(dd, X, Y); + } while (dd->reordered == 1); + dd->autoDynZ = autoDynZ; + return(res); + +} /* end of Extra_zddMaxNotSupSet */ + + +/**Function******************************************************************** + + Synopsis [Returns 1 if ZDD contains the empty combination; 0 otherwise.] + + Description [] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int +Extra_zddEmptyBelongs( + DdManager *dd, + DdNode* zS ) +{ + while ( zS->index != CUDD_MAXINDEX ) + zS = cuddE( zS ); + return (int)( zS == z1 ); + +} /* end of Extra_zddEmptyBelongs */ + + +/**Function******************************************************************** + + Synopsis [Returns 1 if the set is empty or consists of one subset only.] + + Description [] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int +Extra_zddIsOneSubset( + DdManager * dd, + DdNode * zS ) +{ + while ( zS->index != CUDD_MAXINDEX ) + { + assert( cuddT(zS) != z0 ); + if ( cuddE(zS) != z0 ) + return 0; + zS = cuddT( zS ); + } + return (int)( zS == z1 ); + +} /* end of Extra_zddEmptyBelongs */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Extra_zddSubSet.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DdNode* extraZddSubSet( DdManager *dd, DdNode *X, DdNode *Y ) +{ + DdNode *zRes; + statLine(dd); + /* any comb is a subset of itself */ + if ( X == Y ) + return X; + /* if X is empty, the result is empty */ + if ( X == z0 ) + return z0; + /* combs in X are notsubsets of non-existant combs in Y */ + if ( Y == z0 ) + return z0; + /* the empty comb is contained in all combs of Y */ + if ( X == z1 ) + return z1; + /* only {()} is the subset of {()} */ + if ( Y == z1 ) /* check whether the empty combination is present in X */ + return ( Extra_zddEmptyBelongs( dd, X )? z1: z0 ); + + /* check cache */ + zRes = cuddCacheLookup2Zdd(dd, extraZddSubSet, X, Y); + if (zRes) + return(zRes); + else + { + DdNode *zRes0, *zRes1, *zTemp; + int TopLevelX = dd->permZ[ X->index ]; + int TopLevelY = dd->permZ[ Y->index ]; + + if ( TopLevelX < TopLevelY ) + { + /* compute combs of X without var that are notsubsets of combs with Y */ + zRes = extraZddSubSet( dd, cuddE( X ), Y ); + if ( zRes == NULL ) return NULL; + } + else if ( TopLevelX == TopLevelY ) + { + /* merge combs of Y with and without var */ + zTemp = cuddZddUnion( dd, cuddE( Y ), cuddT( Y ) ); + if ( zTemp == NULL ) + return NULL; + cuddRef( zTemp ); + + /* compute combs of X without var that are notsubsets of combs is Temp */ + zRes0 = extraZddSubSet( dd, cuddE( X ), zTemp ); + if ( zRes0 == NULL ) + { + Cudd_RecursiveDerefZdd( dd, zTemp ); + return NULL; + } + cuddRef( zRes0 ); + Cudd_RecursiveDerefZdd( dd, zTemp ); + + /* combs of X with var that are notsubsets of combs in Y with var */ + zRes1 = extraZddSubSet( dd, cuddT( X ), cuddT( Y ) ); + if ( zRes1 == NULL ) + { + Cudd_RecursiveDerefZdd( dd, zRes0 ); + return NULL; + } + cuddRef( zRes1 ); + + /* compose Res0 and Res1 with the given ZDD variable */ + zRes = cuddZddGetNode( dd, X->index, zRes1, zRes0 ); + if ( zRes == NULL ) + { + Cudd_RecursiveDerefZdd( dd, zRes0 ); + Cudd_RecursiveDerefZdd( dd, zRes1 ); + return NULL; + } + cuddDeref( zRes0 ); + cuddDeref( zRes1 ); + } + else /* if ( TopLevelX > TopLevelY ) */ + { + /* merge combs of Y with and without var */ + zTemp = cuddZddUnion( dd, cuddE( Y ), cuddT( Y ) ); + if ( zTemp == NULL ) return NULL; + cuddRef( zTemp ); + + /* compute combs that are notsubsets of Temp */ + zRes = extraZddSubSet( dd, X, zTemp ); + if ( zRes == NULL ) + { + Cudd_RecursiveDerefZdd( dd, zTemp ); + return NULL; + } + cuddRef( zRes ); + Cudd_RecursiveDerefZdd( dd, zTemp ); + cuddDeref( zRes ); + } + + /* insert the result into cache */ + cuddCacheInsert2(dd, extraZddSubSet, X, Y, zRes); + return zRes; + } +} /* end of extraZddSubSet */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Extra_zddSupSet.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DdNode* extraZddSupSet( DdManager *dd, DdNode *X, DdNode *Y ) +{ + DdNode *zRes; + statLine(dd); + /* any comb is a superset of itself */ + if ( X == Y ) + return X; + /* no comb in X is superset of non-existing combs */ + if ( Y == z0 ) + return z0; + /* any comb in X is the superset of the empty comb */ + if ( Extra_zddEmptyBelongs( dd, Y ) ) + return X; + /* if X is empty, the result is empty */ + if ( X == z0 ) + return z0; + /* if X is the empty comb (and Y does not contain it!), return empty */ + if ( X == z1 ) + return z0; + + /* check cache */ + zRes = cuddCacheLookup2Zdd(dd, extraZddSupSet, X, Y); + if (zRes) + return(zRes); + else + { + DdNode *zRes0, *zRes1, *zTemp; + int TopLevelX = dd->permZ[ X->index ]; + int TopLevelY = dd->permZ[ Y->index ]; + + if ( TopLevelX < TopLevelY ) + { + /* combinations of X without label that are supersets of combinations with Y */ + zRes0 = extraZddSupSet( dd, cuddE( X ), Y ); + if ( zRes0 == NULL ) return NULL; + cuddRef( zRes0 ); + + /* combinations of X with label that are supersets of combinations with Y */ + zRes1 = extraZddSupSet( dd, cuddT( X ), Y ); + if ( zRes1 == NULL ) + { + Cudd_RecursiveDerefZdd( dd, zRes0 ); + return NULL; + } + cuddRef( zRes1 ); + + /* compose Res0 and Res1 with the given ZDD variable */ + zRes = cuddZddGetNode( dd, X->index, zRes1, zRes0 ); + if ( zRes == NULL ) + { + Cudd_RecursiveDerefZdd( dd, zRes0 ); + Cudd_RecursiveDerefZdd( dd, zRes1 ); + return NULL; + } + cuddDeref( zRes0 ); + cuddDeref( zRes1 ); + } + else if ( TopLevelX == TopLevelY ) + { + /* combs of X without var that are supersets of combs of Y without var */ + zRes0 = extraZddSupSet( dd, cuddE( X ), cuddE( Y ) ); + if ( zRes0 == NULL ) return NULL; + cuddRef( zRes0 ); + + /* merge combs of Y with and without var */ + zTemp = cuddZddUnion( dd, cuddE( Y ), cuddT( Y ) ); + if ( zTemp == NULL ) + { + Cudd_RecursiveDerefZdd( dd, zRes0 ); + return NULL; + } + cuddRef( zTemp ); + + /* combs of X with label that are supersets of combs in Temp */ + zRes1 = extraZddSupSet( dd, cuddT( X ), zTemp ); + if ( zRes1 == NULL ) + { + Cudd_RecursiveDerefZdd( dd, zRes0 ); + Cudd_RecursiveDerefZdd( dd, zTemp ); + return NULL; + } + cuddRef( zRes1 ); + Cudd_RecursiveDerefZdd( dd, zTemp ); + + /* compose Res0 and Res1 with the given ZDD variable */ + zRes = cuddZddGetNode( dd, X->index, zRes1, zRes0 ); + if ( zRes == NULL ) + { + Cudd_RecursiveDerefZdd( dd, zRes0 ); + Cudd_RecursiveDerefZdd( dd, zRes1 ); + return NULL; + } + cuddDeref( zRes0 ); + cuddDeref( zRes1 ); + } + else /* if ( TopLevelX > TopLevelY ) */ + { + /* combs of X that are supersets of combs of Y without label */ + zRes = extraZddSupSet( dd, X, cuddE( Y ) ); + if ( zRes == NULL ) return NULL; + } + + /* insert the result into cache */ + cuddCacheInsert2(dd, extraZddSupSet, X, Y, zRes); + return zRes; + } +} /* end of extraZddSupSet */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Extra_zddNotSubSet.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DdNode* extraZddNotSubSet( DdManager *dd, DdNode *X, DdNode *Y ) +{ + DdNode *zRes; + statLine(dd); + /* any comb is a subset of itself */ + if ( X == Y ) + return z0; + /* combs in X are notsubsets of non-existant combs in Y */ + if ( Y == z0 ) + return X; + /* only {()} is the subset of {()} */ + if ( Y == z1 ) /* remove empty combination from X */ + return cuddZddDiff( dd, X, z1 ); + /* if X is empty, the result is empty */ + if ( X == z0 ) + return z0; + /* the empty comb is contained in all combs of Y */ + if ( X == z1 ) + return z0; + + /* check cache */ + zRes = cuddCacheLookup2Zdd(dd, extraZddNotSubSet, X, Y); + if (zRes) + return(zRes); + else + { + DdNode *zRes0, *zRes1, *zTemp; + int TopLevelX = dd->permZ[ X->index ]; + int TopLevelY = dd->permZ[ Y->index ]; + + if ( TopLevelX < TopLevelY ) + { + /* compute combs of X without var that are notsubsets of combs with Y */ + zRes0 = extraZddNotSubSet( dd, cuddE( X ), Y ); + if ( zRes0 == NULL ) + return NULL; + cuddRef( zRes0 ); + + /* combs of X with var cannot be subsets of combs without var in Y */ + zRes1 = cuddT( X ); + + /* compose Res0 and Res1 with the given ZDD variable */ + zRes = cuddZddGetNode( dd, X->index, zRes1, zRes0 ); + if ( zRes == NULL ) + { + Cudd_RecursiveDerefZdd( dd, zRes0 ); + return NULL; + } + cuddDeref( zRes0 ); + } + else if ( TopLevelX == TopLevelY ) + { + /* merge combs of Y with and without var */ + zTemp = cuddZddUnion( dd, cuddE( Y ), cuddT( Y ) ); + if ( zTemp == NULL ) + return NULL; + cuddRef( zTemp ); + + /* compute combs of X without var that are notsubsets of combs is Temp */ + zRes0 = extraZddNotSubSet( dd, cuddE( X ), zTemp ); + if ( zRes0 == NULL ) + { + Cudd_RecursiveDerefZdd( dd, zTemp ); + return NULL; + } + cuddRef( zRes0 ); + Cudd_RecursiveDerefZdd( dd, zTemp ); + + /* combs of X with var that are notsubsets of combs in Y with var */ + zRes1 = extraZddNotSubSet( dd, cuddT( X ), cuddT( Y ) ); + if ( zRes1 == NULL ) + { + Cudd_RecursiveDerefZdd( dd, zRes0 ); + return NULL; + } + cuddRef( zRes1 ); + + /* compose Res0 and Res1 with the given ZDD variable */ + zRes = cuddZddGetNode( dd, X->index, zRes1, zRes0 ); + if ( zRes == NULL ) + { + Cudd_RecursiveDerefZdd( dd, zRes0 ); + Cudd_RecursiveDerefZdd( dd, zRes1 ); + return NULL; + } + cuddDeref( zRes0 ); + cuddDeref( zRes1 ); + } + else /* if ( TopLevelX > TopLevelY ) */ + { + /* merge combs of Y with and without var */ + zTemp = cuddZddUnion( dd, cuddE( Y ), cuddT( Y ) ); + if ( zTemp == NULL ) + return NULL; + cuddRef( zTemp ); + + /* compute combs that are notsubsets of Temp */ + zRes = extraZddNotSubSet( dd, X, zTemp ); + if ( zRes == NULL ) + { + Cudd_RecursiveDerefZdd( dd, zTemp ); + return NULL; + } + cuddRef( zRes ); + Cudd_RecursiveDerefZdd( dd, zTemp ); + cuddDeref( zRes ); + } + + /* insert the result into cache */ + cuddCacheInsert2(dd, extraZddNotSubSet, X, Y, zRes); + return zRes; + } +} /* end of extraZddNotSubSet */ + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Extra_zddNotSupSet.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DdNode* extraZddNotSupSet( DdManager *dd, DdNode *X, DdNode *Y ) +{ + DdNode *zRes; + statLine(dd); + /* any comb is a superset of itself */ + if ( X == Y ) + return z0; + /* no comb in X is superset of non-existing combs */ + if ( Y == z0 ) + return X; + /* any comb in X is the superset of the empty comb */ + if ( Extra_zddEmptyBelongs( dd, Y ) ) + return z0; + /* if X is empty, the result is empty */ + if ( X == z0 ) + return z0; + /* if X is the empty comb (and Y does not contain it!), return it */ + if ( X == z1 ) + return z1; + + /* check cache */ + zRes = cuddCacheLookup2Zdd(dd, extraZddNotSupSet, X, Y); + if (zRes) + return(zRes); + else + { + DdNode *zRes0, *zRes1, *zTemp; + int TopLevelX = dd->permZ[ X->index ]; + int TopLevelY = dd->permZ[ Y->index ]; + + if ( TopLevelX < TopLevelY ) + { + /* combinations of X without label that are supersets of combinations of Y */ + zRes0 = extraZddNotSupSet( dd, cuddE( X ), Y ); + if ( zRes0 == NULL ) + return NULL; + cuddRef( zRes0 ); + + /* combinations of X with label that are supersets of combinations of Y */ + zRes1 = extraZddNotSupSet( dd, cuddT( X ), Y ); + if ( zRes1 == NULL ) + { + Cudd_RecursiveDerefZdd( dd, zRes0 ); + return NULL; + } + cuddRef( zRes1 ); + + /* compose Res0 and Res1 with the given ZDD variable */ + zRes = cuddZddGetNode( dd, X->index, zRes1, zRes0 ); + if ( zRes == NULL ) + { + Cudd_RecursiveDerefZdd( dd, zRes0 ); + Cudd_RecursiveDerefZdd( dd, zRes1 ); + return NULL; + } + cuddDeref( zRes0 ); + cuddDeref( zRes1 ); + } + else if ( TopLevelX == TopLevelY ) + { + /* combs of X without var that are not supersets of combs of Y without var */ + zRes0 = extraZddNotSupSet( dd, cuddE( X ), cuddE( Y ) ); + if ( zRes0 == NULL ) + return NULL; + cuddRef( zRes0 ); + + /* merge combs of Y with and without var */ + zTemp = cuddZddUnion( dd, cuddE( Y ), cuddT( Y ) ); + if ( zTemp == NULL ) + { + Cudd_RecursiveDerefZdd( dd, zRes0 ); + return NULL; + } + cuddRef( zTemp ); + + /* combs of X with label that are supersets of combs in Temp */ + zRes1 = extraZddNotSupSet( dd, cuddT( X ), zTemp ); + if ( zRes1 == NULL ) + { + Cudd_RecursiveDerefZdd( dd, zRes0 ); + Cudd_RecursiveDerefZdd( dd, zTemp ); + return NULL; + } + cuddRef( zRes1 ); + Cudd_RecursiveDerefZdd( dd, zTemp ); + + /* compose Res0 and Res1 with the given ZDD variable */ + zRes = cuddZddGetNode( dd, X->index, zRes1, zRes0 ); + if ( zRes == NULL ) + { + Cudd_RecursiveDerefZdd( dd, zRes0 ); + Cudd_RecursiveDerefZdd( dd, zRes1 ); + return NULL; + } + cuddDeref( zRes0 ); + cuddDeref( zRes1 ); + } + else /* if ( TopLevelX > TopLevelY ) */ + { + /* combs of X that are supersets of combs of Y without label */ + zRes = extraZddNotSupSet( dd, X, cuddE( Y ) ); + if ( zRes == NULL ) return NULL; + } + + /* insert the result into cache */ + cuddCacheInsert2(dd, extraZddNotSupSet, X, Y, zRes); + return zRes; + } +} /* end of extraZddNotSupSet */ + + + +/**Function******************************************************************** + + Synopsis [Performs the recursive step of Extra_zddMaxNotSupSet.] + + Description [] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +DdNode* extraZddMaxNotSupSet( DdManager *dd, DdNode *X, DdNode *Y ) +{ + DdNode *zRes; + statLine(dd); + /* any comb is a superset of itself */ + if ( X == Y ) + return z0; + /* no comb in X is superset of non-existing combs */ + if ( Y == z0 ) + return extraZddMaximal( dd, X ); + /* any comb in X is the superset of the empty comb */ + if ( Extra_zddEmptyBelongs( dd, Y ) ) + return z0; + /* if X is empty, the result is empty */ + if ( X == z0 ) + return z0; + /* if X is the empty comb (and Y does not contain it!), return it */ + if ( X == z1 ) + return z1; + + /* check cache */ + zRes = cuddCacheLookup2Zdd(dd, extraZddMaxNotSupSet, X, Y); + if (zRes) + return(zRes); + else + { + DdNode *zRes0, *zRes1, *zTemp; + int TopLevelX = dd->permZ[ X->index ]; + int TopLevelY = dd->permZ[ Y->index ]; + + if ( TopLevelX < TopLevelY ) + { + /* combinations of X without label that are supersets of combinations with Y */ + zRes0 = extraZddMaxNotSupSet( dd, cuddE( X ), Y ); + if ( zRes0 == NULL ) + return NULL; + cuddRef( zRes0 ); + + /* combinations of X with label that are supersets of combinations with Y */ + zRes1 = extraZddMaxNotSupSet( dd, cuddT( X ), Y ); + if ( zRes1 == NULL ) + { + Cudd_RecursiveDerefZdd( dd, zRes0 ); + return NULL; + } + cuddRef( zRes1 ); + + /* ---------------------------------------------------- */ + /* remove subsets without this element covered by subsets with this element */ + zRes0 = extraZddNotSubSet(dd, zTemp = zRes0, zRes1); + if ( zRes0 == NULL ) + { + Cudd_RecursiveDerefZdd(dd, zTemp); + Cudd_RecursiveDerefZdd(dd, zRes1); + return NULL; + } + cuddRef( zRes0 ); + Cudd_RecursiveDerefZdd(dd, zTemp); + /* ---------------------------------------------------- */ + + /* compose Res0 and Res1 with the given ZDD variable */ + zRes = cuddZddGetNode( dd, X->index, zRes1, zRes0 ); + if ( zRes == NULL ) + { + Cudd_RecursiveDerefZdd( dd, zRes0 ); + Cudd_RecursiveDerefZdd( dd, zRes1 ); + return NULL; + } + cuddDeref( zRes0 ); + cuddDeref( zRes1 ); + } + else if ( TopLevelX == TopLevelY ) + { + /* combs of X without var that are supersets of combs of Y without var */ + zRes0 = extraZddMaxNotSupSet( dd, cuddE( X ), cuddE( Y ) ); + if ( zRes0 == NULL ) + return NULL; + cuddRef( zRes0 ); + + /* merge combs of Y with and without var */ + zTemp = cuddZddUnion( dd, cuddE( Y ), cuddT( Y ) ); + if ( zTemp == NULL ) + { + Cudd_RecursiveDerefZdd( dd, zRes0 ); + return NULL; + } + cuddRef( zTemp ); + + /* combs of X with label that are supersets of combs in Temp */ + zRes1 = extraZddMaxNotSupSet( dd, cuddT( X ), zTemp ); + if ( zRes1 == NULL ) + { + Cudd_RecursiveDerefZdd( dd, zRes0 ); + Cudd_RecursiveDerefZdd( dd, zTemp ); + return NULL; + } + cuddRef( zRes1 ); + Cudd_RecursiveDerefZdd( dd, zTemp ); + + /* ---------------------------------------------------- */ + /* remove subsets without this element covered by subsets with this element */ + zRes0 = extraZddNotSubSet(dd, zTemp = zRes0, zRes1); + if ( zRes0 == NULL ) + { + Cudd_RecursiveDerefZdd(dd, zTemp); + Cudd_RecursiveDerefZdd(dd, zRes1); + return NULL; + } + cuddRef( zRes0 ); + Cudd_RecursiveDerefZdd(dd, zTemp); + /* ---------------------------------------------------- */ + + /* compose Res0 and Res1 with the given ZDD variable */ + zRes = cuddZddGetNode( dd, X->index, zRes1, zRes0 ); + if ( zRes == NULL ) + { + Cudd_RecursiveDerefZdd( dd, zRes0 ); + Cudd_RecursiveDerefZdd( dd, zRes1 ); + return NULL; + } + cuddDeref( zRes0 ); + cuddDeref( zRes1 ); + } + else /* if ( TopLevelX > TopLevelY ) */ + { + /* combs of X that are supersets of combs of Y without label */ + zRes = extraZddMaxNotSupSet( dd, X, cuddE( Y ) ); + if ( zRes == NULL ) return NULL; + } + + /* insert the result into cache */ + cuddCacheInsert2(dd, extraZddMaxNotSupSet, X, Y, zRes); + return zRes; + } +} /* end of extraZddMaxNotSupSet */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + + +ABC_NAMESPACE_IMPL_END diff --git a/src/bdd/extrab/module.make b/src/bdd/extrab/module.make index 62b578f7..cee5ac80 100644 --- a/src/bdd/extrab/module.make +++ b/src/bdd/extrab/module.make @@ -2,7 +2,9 @@ SRC += src/bdd/extrab/extraBddAuto.c \ src/bdd/extrab/extraBddCas.c \ src/bdd/extrab/extraBddImage.c \ src/bdd/extrab/extraBddKmap.c \ + src/bdd/extrab/extraBddMaxMin.c \ src/bdd/extrab/extraBddMisc.c \ + src/bdd/extrab/extraBddSet.c \ src/bdd/extrab/extraBddSymm.c \ src/bdd/extrab/extraBddThresh.c \ src/bdd/extrab/extraBddTime.c \ diff --git a/src/map/amap/amapLib.c b/src/map/amap/amapLib.c index b6350fed..26ef639f 100644 --- a/src/map/amap/amapLib.c +++ b/src/map/amap/amapLib.c @@ -242,8 +242,11 @@ Amap_Gat_t * Amap_LibFindGate( Amap_Lib_t * p, unsigned uTruth ) Amap_Gat_t * pGate; int i; Vec_PtrForEachEntry( Amap_Gat_t *, p->vSorted, pGate, i ) + { + if (( pGate == NULL ) || ( pGate->pFunc == NULL )) continue; if ( pGate->nPins <= 5 && pGate->pFunc[0] == uTruth ) return pGate; + } return NULL; } diff --git a/src/map/amap/amapLiberty.c b/src/map/amap/amapLiberty.c index 13b18df5..d5d2d72a 100644 --- a/src/map/amap/amapLiberty.c +++ b/src/map/amap/amapLiberty.c @@ -209,6 +209,26 @@ int Amap_LibertyCellIsFlop( Amap_Tree_t * p, Amap_Item_t * pCell ) /**Function************************************************************* + Synopsis [Returns cell's function.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Amap_LibertyCellIsDontUse( Amap_Tree_t * p, Amap_Item_t * pCell ) +{ + Amap_Item_t * pAttr; + Amap_ItemForEachChild( p, pCell, pAttr ) + if ( !Amap_LibertyCompare(p, pAttr->Key, "dont_use") ) + return 1; + return 0; +} + +/**Function************************************************************* + Synopsis [Returns pin's function.] Description [] @@ -414,6 +434,12 @@ int Amap_LibertyPrintGenlib( Amap_Tree_t * p, char * pFileName, int fVerbose ) printf( "Amap_LibertyPrintGenlib() skipped sequential cell \"%s\".\n", Amap_LibertyGetString(p, pCell->Head) ); continue; } + if ( Amap_LibertyCellIsDontUse(p, pCell) ) + { + if ( fVerbose ) + printf( "Amap_LibertyPrintGenlib() skipped cell \"%s\" due to dont_use attribute.\n", Amap_LibertyGetString(p, pCell->Head) ); + continue; + } Counter = Amap_LibertyCellCountOutputs( p, pCell ); if ( Counter == 0 ) { @@ -498,6 +524,12 @@ Vec_Str_t * Amap_LibertyPrintGenlibStr( Amap_Tree_t * p, int fVerbose ) printf( "Amap_LibertyPrintGenlib() skipped sequential cell \"%s\".\n", Amap_LibertyGetString(p, pCell->Head) ); continue; } + if ( Amap_LibertyCellIsDontUse(p, pCell) ) + { + if ( fVerbose ) + printf( "Amap_LibertyPrintGenlib() skipped cell \"%s\" due to dont_use attribute.\n", Amap_LibertyGetString(p, pCell->Head) ); + continue; + } Counter = Amap_LibertyCellCountOutputs( p, pCell ); if ( Counter == 0 ) { diff --git a/src/map/scl/sclLiberty.c b/src/map/scl/sclLiberty.c index fc06bc47..cd28a607 100644 --- a/src/map/scl/sclLiberty.c +++ b/src/map/scl/sclLiberty.c @@ -629,6 +629,14 @@ int Scl_LibertyReadCellIsFlop( Scl_Tree_t * p, Scl_Item_t * pCell ) return 1; return 0; } +int Scl_LibertyReadCellIsDontUse( Scl_Tree_t * p, Scl_Item_t * pCell ) +{ + Scl_Item_t * pAttr; + Scl_ItemForEachChild( p, pCell, pAttr ) + if ( !Scl_LibertyCompare(p, pAttr->Key, "dont_use") ) + return 1; + return 0; +} char * Scl_LibertyReadCellArea( Scl_Tree_t * p, Scl_Item_t * pCell ) { Scl_Item_t * pArea; @@ -704,6 +712,11 @@ Vec_Str_t * Scl_LibertyReadGenlibStr( Scl_Tree_t * p, int fVerbose ) if ( fVerbose ) printf( "Scl_LibertyReadGenlib() skipped sequential cell \"%s\".\n", Scl_LibertyReadString(p, pCell->Head) ); continue; } + if ( Scl_LibertyReadCellIsDontUse(p, pCell) ) + { + if ( fVerbose ) printf( "Scl_LibertyReadGenlib() skipped cell \"%s\" due to dont_use attribute.\n", Scl_LibertyReadString(p, pCell->Head) ); + continue; + } if ( Scl_LibertyReadCellIsThreeState(p, pCell) ) { if ( fVerbose ) printf( "Scl_LibertyReadGenlib() skipped three-state cell \"%s\".\n", Scl_LibertyReadString(p, pCell->Head) ); @@ -1417,7 +1430,7 @@ Vec_Str_t * Scl_LibertyReadSclStr( Scl_Tree_t * p, int fVerbose, int fVeryVerbos Vec_Wrd_t * vTruth; char * pFormula, * pName; int i, k, Counter, nOutputs, nCells; - int nSkipped[3] = {0}; + int nSkipped[4] = {0}; // read delay-table templates vTemples = Scl_LibertyReadTemplates( p ); @@ -1451,6 +1464,12 @@ Vec_Str_t * Scl_LibertyReadSclStr( Scl_Tree_t * p, int fVerbose, int fVeryVerbos nSkipped[0]++; continue; } + if ( Scl_LibertyReadCellIsDontUse(p, pCell) ) + { + if ( fVeryVerbose ) printf( "Scl_LibertyReadGenlib() skipped cell \"%s\" due to dont_use attribute.\n", Scl_LibertyReadString(p, pCell->Head) ); + nSkipped[3]++; + continue; + } if ( Scl_LibertyReadCellIsThreeState(p, pCell) ) { if ( fVeryVerbose ) printf( "Scl_LibertyReadGenlib() skipped three-state cell \"%s\".\n", Scl_LibertyReadString(p, pCell->Head) ); @@ -1473,6 +1492,8 @@ Vec_Str_t * Scl_LibertyReadSclStr( Scl_Tree_t * p, int fVerbose, int fVeryVerbos { if ( Scl_LibertyReadCellIsFlop(p, pCell) ) continue; + if ( Scl_LibertyReadCellIsDontUse(p, pCell) ) + continue; if ( Scl_LibertyReadCellIsThreeState(p, pCell) ) continue; if ( (Counter = Scl_LibertyReadCellOutputNum(p, pCell)) == 0 ) @@ -1640,8 +1661,8 @@ Vec_Str_t * Scl_LibertyReadSclStr( Scl_Tree_t * p, int fVerbose, int fVeryVerbos { printf( "Library \"%s\" from \"%s\" has %d cells ", Scl_LibertyReadString(p, Scl_LibertyRoot(p)->Head), p->pFileName, nCells ); - printf( "(%d skipped: %d seq; %d tri-state; %d no func). ", - nSkipped[0]+nSkipped[1]+nSkipped[2], nSkipped[0], nSkipped[1], nSkipped[2] ); + printf( "(%d skipped: %d seq; %d tri-state; %d no func; %d dont_use). ", + nSkipped[0]+nSkipped[1]+nSkipped[2], nSkipped[0], nSkipped[1], nSkipped[2], nSkipped[3] ); Abc_PrintTime( 1, "Time", Abc_Clock() - p->clkStart ); } return vOut; diff --git a/src/misc/extra/extra.h b/src/misc/extra/extra.h index 3dee5f4e..6c0fd74a 100644 --- a/src/misc/extra/extra.h +++ b/src/misc/extra/extra.h @@ -119,6 +119,7 @@ extern char * Extra_StringAppend( char * pStrGiven, char * pStrAdd ); extern void Extra_StringClean( char * pStrGiven, char * pCharKeep ); extern unsigned Extra_ReadBinary( char * Buffer ); extern void Extra_PrintBinary( FILE * pFile, unsigned Sign[], int nBits ); +extern void Extra_PrintBinary2( FILE * pFile, unsigned Sign[], int nBits ); extern int Extra_ReadHex( unsigned Sign[], char * pString, int nDigits ); extern int Extra_ReadHexadecimal( unsigned Sign[], char * pString, int nVars ); extern void Extra_PrintHexadecimal( FILE * pFile, unsigned Sign[], int nVars ); diff --git a/src/misc/extra/extraUtilFile.c b/src/misc/extra/extraUtilFile.c index 6568c305..8f60f421 100644 --- a/src/misc/extra/extraUtilFile.c +++ b/src/misc/extra/extraUtilFile.c @@ -508,6 +508,23 @@ void Extra_PrintBinary( FILE * pFile, unsigned Sign[], int nBits ) // fprintf( pFile, "\n" ); } +void Extra_PrintBinary2( FILE * pFile, unsigned Sign[], int nBits ) +{ + int Remainder, nWords; + int w, i; + + Remainder = (nBits%(sizeof(unsigned)*8)); + nWords = (nBits/(sizeof(unsigned)*8)) + (Remainder>0); + + for ( w = 0; w < nWords; w++ ) + { + int Limit = w == nWords-1 ? Remainder : 32; + for ( i = 0; i < Limit; i++ ) + fprintf( pFile, "%c", '0' + (int)((Sign[w] & (1<<i)) > 0) ); + } + +// fprintf( pFile, "\n" ); +} /**Function************************************************************* diff --git a/src/misc/extra/extraUtilMaj.c b/src/misc/extra/extraUtilMaj.c new file mode 100644 index 00000000..8bdb0818 --- /dev/null +++ b/src/misc/extra/extraUtilMaj.c @@ -0,0 +1,386 @@ +/**CFile**************************************************************** + + FileName [extraUtilMaj.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [extra] + + Synopsis [Path enumeration.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: extraUtilMaj.c,v 1.0 2003/02/01 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> + +#include "misc/vec/vec.h" +#include "misc/vec/vecMem.h" +#include "misc/extra/extra.h" +#include "misc/util/utilTruth.h" +#include "opt/dau/dau.h" + +ABC_NAMESPACE_IMPL_START + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +typedef struct Gem_Man_t_ Gem_Man_t; +typedef struct Gem_Obj_t_ Gem_Obj_t; + +struct Gem_Man_t_ +{ + int nVars; // max variable count + int nWords; // truth tabel word count + int nObjsAlloc; // allocated objects + int nObjs; // used objects + Gem_Obj_t * pObjs; // function objects + Vec_Mem_t * vTtMem; // truth table memory and hash table + word ** pTtElems; // elementary truth tables + int fVerbose; +}; + +struct Gem_Obj_t_ // 8 bytes +{ + unsigned nVars : 4; // variable count + unsigned nNodes : 4; // node count + unsigned History : 8; // (i < j) ? {vi, vj} : {vi, 0} + unsigned Groups : 16; // mask with last vars in each symmetric group + int Predec; // predecessor +}; + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gem_PrintNode( Gem_Man_t * p, int f, char * pLabel, int fUpdate ) +{ + Gem_Obj_t * pObj = p->pObjs + f; + int GroupsMod = pObj->Groups; + if ( !p->fVerbose ) + return; + printf( "Node %6d : %s Pred = %6d Vars = %d Nodes = %d History = %d%d Profile: ", + f, pLabel, pObj->Predec, pObj->nVars, pObj->nNodes, pObj->History & 0xF, pObj->History >> 4 ); + Extra_PrintBinary2( stdout, (unsigned*)&GroupsMod, p->nVars ); printf("%s\n", fUpdate?" *":""); +} +Gem_Man_t * Gem_ManAlloc( int nVars, int fVerbose ) +{ + Gem_Man_t * p; + assert( nVars <= 16 ); + p = ABC_CALLOC( Gem_Man_t, 1 ); + p->nVars = nVars; + p->nWords = Abc_TtWordNum( nVars ); + p->nObjsAlloc = 10000000; + p->nObjs = 2; + p->pObjs = ABC_CALLOC( Gem_Obj_t, p->nObjsAlloc ); + p->pObjs[1].nVars = p->pObjs[1].Groups = 1; // buffer + p->vTtMem = Vec_MemAllocForTT( nVars, 0 ); + p->pTtElems = (word **)Extra_ArrayAlloc( nVars + 4, p->nWords, sizeof(word) ); + p->fVerbose = fVerbose; + Abc_TtElemInit( p->pTtElems, nVars ); + Gem_PrintNode( p, 1, "Original", 0 ); + return p; +} +int Gem_ManFree( Gem_Man_t * p ) +{ + Vec_MemHashFree( p->vTtMem ); + Vec_MemFree( p->vTtMem ); + ABC_FREE( p->pTtElems ); + ABC_FREE( p->pObjs ); + ABC_FREE( p ); + return 1; +} +void Gem_ManRealloc( Gem_Man_t * p ) +{ + int nObjNew = Abc_MinInt( 2 * p->nObjsAlloc, 0x7FFFFFFF ); + assert( p->nObjs == p->nObjsAlloc ); + if ( p->nObjs == 0x7FFFFFFF ) + printf( "Hard limit on the number of nodes (0x7FFFFFFF) is reached. Quitting...\n" ), exit(1); + assert( p->nObjs < nObjNew ); + printf("Extending object storage: %d -> %d.\n", p->nObjsAlloc, nObjNew ); + p->pObjs = ABC_REALLOC( Gem_Obj_t, p->pObjs, nObjNew ); + memset( p->pObjs + p->nObjsAlloc, 0, sizeof(Gem_Obj_t) * (nObjNew - p->nObjsAlloc) ); + p->nObjsAlloc = nObjNew; +} + +/**Function************************************************************* + + Synopsis [Derive groups using symmetry info.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gem_GroupsDerive( word * pTruth, int nVars, word * pCof0, word * pCof1 ) +{ + int v, Res = 1 << (nVars-1); + for ( v = 0; v < nVars-1; v++ ) + if ( !Abc_TtVarsAreSymmetric(pTruth, nVars, v, v+1, pCof0, pCof1) ) + Res |= (1 << v); + return Res; +} + +/**Function************************************************************* + + Synopsis [Extends function f by replacing var i with a new gate.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gem_GroupVarRemove( int Groups, int i ) // remove i-th var +{ + int Mask = i ? Abc_InfoMask( i ) : 0; + assert( i >= 0 ); + assert( (Groups >> i) & 1 ); + return (Groups & Mask) | ((Groups & ~Mask) >> 1); +} +int Gem_GroupVarsInsert1( int Groups, int i, int fGroup ) // insert one bit after i +{ + int Mask = i+1 ? Abc_InfoMask( i+1 ) : 0; + assert( i+1 >= 0 ); + assert( !fGroup || i == -1 || ((Groups >> i) & 1) ); + assert( fGroup == 0 || fGroup == 1 ); + return (Groups & Mask) | ((Groups & ~Mask) << 1) | (fGroup << (i+1)); +} +int Gem_GroupVarsInsert3( int Groups, int i ) // insert group of 3 bits after i +{ + int Mask = i+1 ? Abc_InfoMask( i+1 ) : 0; + assert( i+1 >= 0 ); + assert( i == -1 || (Groups >> i) & 1 ); + return (Groups & Mask) | ((Groups & ~Mask) << 3) | (0x4 << (i+1)); +} +int Gem_GroupUnpack( int Groups, int * pVars ) +{ + int v, nGroups = 0; + for ( v = 0; Groups; v++, Groups >>= 1 ) + if ( Groups & 1 ) + pVars[nGroups++] = v; + return nGroups; +} +int Gem_FuncFindPlace( word * pTruth, int nWords, int Groups, word * pBest, int fOneVar ) +{ + int pLast[16], nGroups = Gem_GroupUnpack( Groups, pLast ); + int g, v, Value, BestPlace = nGroups ? pLast[nGroups - 1] : -1; + assert( nGroups >= 0 ); + Abc_TtCopy( pBest, pTruth, nWords, 0 ); + for ( g = nGroups - 1; g >= 0; g-- ) + { + int Limit = g ? pLast[g-1] : -1; + for ( v = pLast[g]; v > Limit; v-- ) + { + Abc_TtSwapAdjacent( pTruth, nWords, v+0 ); + if ( fOneVar ) + continue; + Abc_TtSwapAdjacent( pTruth, nWords, v+1 ); + Abc_TtSwapAdjacent( pTruth, nWords, v+2 ); + } + Value = memcmp(pBest, pTruth, sizeof(word)*nWords); + if ( Value < 0 ) + { + Abc_TtCopy( pBest, pTruth, nWords, 0 ); + BestPlace = Limit; + } + } + return BestPlace; +} +void Gem_FuncExpand( Gem_Man_t * p, int f, int i ) +{ + Gem_Obj_t * pNew = p->pObjs + p->nObjs, * pObj = p->pObjs + f; + word * pTruth = Vec_MemReadEntry( p->vTtMem, f ); + word * pResult = p->pTtElems[p->nVars]; + word * pCofs[2] = { p->pTtElems[p->nVars+2], p->pTtElems[p->nVars+3] }; + int v, iFunc; + char pCanonPermC[16]; + assert( i < (int)pObj->nVars ); + assert( (int)pObj->nVars + 2 <= p->nVars ); + Abc_TtCopy( pResult, pTruth, p->nWords, 0 ); + // move i variable to the end + for ( v = i; v < (int)pObj->nVars-1; v++ ) + Abc_TtSwapAdjacent( pResult, p->nWords, v ); + // create new symmetric group + assert( v == (int)pObj->nVars-1 ); + Abc_TtCofactor0p( pCofs[0], pResult, p->nWords, v ); + Abc_TtCofactor1p( pCofs[1], pResult, p->nWords, v ); + Abc_TtMaj( pResult, p->pTtElems[v], p->pTtElems[v+1], p->pTtElems[v+2], p->nWords ); + Abc_TtMux( pResult, pResult, pCofs[1], pCofs[0], p->nWords ); + // canonicize + //Extra_PrintHex( stdout, (unsigned*)pResult, pObj->nVars + 2 ); printf("\n"); + Abc_TtCanonicizePerm( pResult, pObj->nVars + 2, pCanonPermC ); + Abc_TtStretch6( pResult, Abc_MaxInt(6, pObj->nVars+2), p->nVars ); + //Extra_PrintHex( stdout, (unsigned*)pResult, pObj->nVars + 2 ); printf("\n\n"); + iFunc = Vec_MemHashInsert( p->vTtMem, pResult ); + if ( iFunc < p->nObjs ) + return; + assert( iFunc == p->nObjs ); + pNew->nVars = pObj->nVars + 2; + pNew->nNodes = pObj->nNodes + 1; + pNew->Groups = Gem_GroupsDerive( pResult, pNew->nVars, pCofs[0], pCofs[1] ); + pNew->Predec = f; + pNew->History = i; + Gem_PrintNode( p, iFunc, "Expand ", 0 ); + + assert( p->nObjs < p->nObjsAlloc ); + if ( ++p->nObjs == p->nObjsAlloc ) + Gem_ManRealloc( p ); +} + +/**Function************************************************************* + + Synopsis [Reduces function f by crossbaring variables i and j.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gem_FuncCheckMajority( Gem_Man_t * p, int f ) +{ + Gem_Obj_t * pObj = p->pObjs + f; + word * pTruth = Vec_MemReadEntry( p->vTtMem, f ); + int Polar = Abc_TtIsFullySymmetric( pTruth, pObj->nVars ); + if ( Polar != -1 ) + { + int nHalfVars = (pObj->nVars+1) >> 1; + int Mask = Abc_Tt6Mask( nHalfVars ); + printf( "Found symmetric %d-variable function: ", pObj->nVars ); + Extra_PrintBinary2( stdout, (unsigned *)&Polar, pObj->nVars + 1 ); + printf( " " ); + if ( (pObj->nVars & 1) && Polar == (Mask << nHalfVars) ) + { + printf( "This is majority-%d.\n", pObj->nVars ); + return 0; + } + printf( "\n" ); + } + return 0; +} +int Gem_FuncReduce( Gem_Man_t * p, int f, int i, int j ) +{ + Gem_Obj_t * pNew = p->pObjs + p->nObjs, * pObj = p->pObjs + f; + word * pTruth = Vec_MemReadEntry( p->vTtMem, f ); + word * pResult = p->pTtElems[p->nVars]; + word * pCofs[2] = { p->pTtElems[p->nVars+2], p->pTtElems[p->nVars+3] }; + int v, iFunc; + char pCanonPermC[16]; + assert( i < j && j < 16 ); + Abc_TtCopy( pResult, pTruth, p->nWords, 0 ); + // move j variable to the end + for ( v = j; v < (int)pObj->nVars-1; v++ ) + Abc_TtSwapAdjacent( pResult, p->nWords, v ); + assert( v == (int)pObj->nVars-1 ); + // move i variable to the end + for ( v = i; v < (int)pObj->nVars-2; v++ ) + Abc_TtSwapAdjacent( pResult, p->nWords, v ); + assert( v == (int)pObj->nVars-2 ); + // create new variable + Abc_TtCofactor0p( pCofs[0], pResult, p->nWords, v+1 ); + Abc_TtCofactor1p( pCofs[1], pResult, p->nWords, v+1 ); + Abc_TtCofactor0( pCofs[0], p->nWords, v ); + Abc_TtCofactor1( pCofs[1], p->nWords, v ); + Abc_TtMux( pResult, p->pTtElems[v], pCofs[1], pCofs[0], p->nWords ); + // canonicize + //Extra_PrintHex( stdout, (unsigned*)pResult, pObj->nVars - 1 ); printf("\n"); + Abc_TtCanonicizePerm( pResult, pObj->nVars - 1, pCanonPermC ); + Abc_TtStretch6( pResult, Abc_MaxInt(6, pObj->nVars-1), p->nVars ); + //Extra_PrintHex( stdout, (unsigned*)pResult, pObj->nVars - 1 ); printf("\n\n"); + iFunc = Vec_MemHashInsert( p->vTtMem, pResult ); + if ( iFunc < p->nObjs ) + return 0; + assert( iFunc == p->nObjs ); + pNew->nVars = pObj->nVars - 1; + pNew->nNodes = pObj->nNodes; + pNew->Groups = Gem_GroupsDerive( pResult, pNew->nVars, pCofs[0], pCofs[1] ); + pNew->Predec = f; + pNew->History = (j << 4) | i; + Gem_PrintNode( p, iFunc, "Crossbar", 0 ); + Gem_FuncCheckMajority( p, iFunc ); + + assert( p->nObjs < p->nObjsAlloc ); + if ( ++p->nObjs == p->nObjsAlloc ) + Gem_ManRealloc( p ); + return 0; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gem_Enumerate( int nVars, int fDump, int fVerbose ) +{ + abctime clk = Abc_Clock(); + Gem_Man_t * p = Gem_ManAlloc( nVars, fVerbose ); + int v, f, i, j, nObjsStop = 1; + for ( v = 1; v <= nVars-2; v++ ) + { + // expand functions by adding a gate + int nObjsStopPrev = nObjsStop; + nObjsStop = p->nObjs; + printf( "Expanding var %2d (functions = %10d) ", v, p->nObjs ); + Abc_PrintTime( 0, "Time", Abc_Clock() - clk ); + for ( f = 0; f < nObjsStop; f++ ) + if ( v == (int)p->pObjs[f].nVars || (v > (int)p->pObjs[f].nVars && f >= nObjsStopPrev) ) + for ( i = 0; i < v; i++ ) + if ( (int)p->pObjs[f].Groups & (1 << i) ) + Gem_FuncExpand( p, f, i ); + // reduce functions by adding a crossbar + printf( "Connecting var %2d (functions = %10d) ", v, p->nObjs ); + Abc_PrintTime( 0, "Time", Abc_Clock() - clk ); + for ( f = nObjsStop; f < p->nObjs; f++ ) + for ( i = 0; i < (int)p->pObjs[f].nVars; i++ ) + if ( (int)p->pObjs[f].Groups & (1 << i) ) + for ( j = i+1; j < (int)p->pObjs[f].nVars; j++ ) + if ( (int)p->pObjs[f].Groups & (1 << j) ) + if ( Gem_FuncReduce( p, f, i, j ) ) + return Gem_ManFree( p ); + } + printf( "Finished (functions = %10d) ", p->nObjs ); + Abc_PrintTime( 0, "Time", Abc_Clock() - clk ); + if ( fDump ) Vec_MemDumpTruthTables( p->vTtMem, "enum", nVars ); + Gem_ManFree( p ); + return 0; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/misc/extra/extraUtilPath.c b/src/misc/extra/extraUtilPath.c new file mode 100644 index 00000000..c7231a05 --- /dev/null +++ b/src/misc/extra/extraUtilPath.c @@ -0,0 +1,607 @@ +/**CFile**************************************************************** + + FileName [extraUtilPath.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [extra] + + Synopsis [Path enumeration.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: extraUtilPath.c,v 1.0 2003/02/01 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> +#include "aig/gia/gia.h" +#include "misc/vec/vecHsh.h" + +#include <math.h> +#include "sat/bmc/bmc.h" +#include "sat/cnf/cnf.h" +#include "sat/bsat/satStore.h" +#include "misc/extra/extra.h" + + +ABC_NAMESPACE_IMPL_START + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Computes AIG representing the set of all paths in the graph.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_NodeVarX( int nSize, int y, int x ) +{ + return Abc_Var2Lit( nSize * y + x, 0 ); +} +int Abc_NodeVarY( int nSize, int y, int x ) +{ + return Abc_Var2Lit( nSize * (nSize + 1) + nSize * x + y, 0 ); +} + +Gia_Man_t * Abc_EnumeratePaths( int nSize ) +{ + Gia_Man_t * pTemp, * pGia = Gia_ManStart( 10000 ); + int * pNodes = ABC_CALLOC( int, nSize+1 ); + int x, y, nVars = 2*nSize*(nSize+1); + for ( x = 0; x < nVars; x++ ) + Gia_ManAppendCi( pGia ); + Gia_ManHashAlloc( pGia ); + // y = 0; x = 0; + pNodes[0] = 1; + // y = 0; x > 0 + for ( x = 1; x <= nSize; x++ ) + pNodes[x] = Gia_ManHashAnd( pGia, pNodes[x-1], Abc_NodeVarX(nSize, 0, x) ); + // y > 0; x >= 0 + for ( y = 1; y <= nSize; y++ ) + { + // y > 0; x = 0 + pNodes[0] = Gia_ManHashAnd( pGia, pNodes[0], Abc_NodeVarY(nSize, y, 0) ); + // y > 0; x > 0 + for ( x = 1; x <= nSize; x++ ) + { + int iHor = Gia_ManHashAnd( pGia, pNodes[x-1], Abc_NodeVarX(nSize, y, x) ); + int iVer = Gia_ManHashAnd( pGia, pNodes[x], Abc_NodeVarY(nSize, y, x) ); + pNodes[x] = Gia_ManHashOr( pGia, iHor, iVer ); + } + } + Gia_ManAppendCo( pGia, pNodes[nSize] ); + pGia = Gia_ManCleanup( pTemp = pGia ); + Gia_ManStop( pTemp ); + ABC_FREE( pNodes ); + return pGia; +} +void Abc_EnumeratePathsTest() +{ + int nSize = 2; + Gia_Man_t * pGia = Abc_EnumeratePaths( nSize ); + Gia_AigerWrite( pGia, "testpath.aig", 0, 0 ); + Gia_ManStop( pGia ); +} + + +/**Function************************************************************* + + Synopsis [Generate NxN grid.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Abc_GraphGrid( int n ) +{ + Vec_Int_t * vEdges = Vec_IntAlloc( 4*n*(n-1) ); // two nodes per edge + int i, k; + for ( i = 0; i < n; i++ ) + { + for ( k = 0; k < n-1; k++ ) + Vec_IntPushTwo( vEdges, i*n+k, i*n+k+1 ); + if ( i == n-1 ) break; + for ( k = 0; k < n; k++ ) + Vec_IntPushTwo( vEdges, i*n+k, i*n+k+n ); + } + //Vec_IntPrint( vEdges ); + return vEdges; +} +Vec_Int_t * Abc_GraphNodeLife( Vec_Int_t * vEdges, int n ) +{ + Vec_Int_t * vLife = Vec_IntStartFull( 2*n*n ); // start/stop per node + int One, Two, i; + Vec_IntForEachEntryDouble( vEdges, One, Two, i ) + { + if ( Vec_IntEntry(vLife, 2*One) == -1 ) + Vec_IntWriteEntry(vLife, 2*One, i/2); + if ( Vec_IntEntry(vLife, 2*Two) == -1 ) + Vec_IntWriteEntry(vLife, 2*Two, i/2); + Vec_IntWriteEntry(vLife, 2*One+1, i/2); + Vec_IntWriteEntry(vLife, 2*Two+1, i/2); + } + //Vec_IntPrint( vLife ); + return vLife; +} +Vec_Wec_t * Abc_GraphFrontiers( Vec_Int_t * vEdges, Vec_Int_t * vLife ) +{ + Vec_Wec_t * vFronts = Vec_WecAlloc( Vec_IntSize(vEdges)/2 ); // front for each edge + Vec_Int_t * vTemp = Vec_IntAlloc( Vec_IntSize(vLife)/2 ); + int e, n; + Vec_WecPushLevel(vFronts); + for ( e = 0; e < Vec_IntSize(vEdges)/2; e++ ) + { + int * pNodes = Vec_IntEntryP(vEdges, 2*e); + for ( n = 0; n < 2; n++ ) + if ( Vec_IntEntry(vLife, 2*pNodes[n]) == e ) // first time + Vec_IntPush( vTemp, pNodes[n] ); + else if ( Vec_IntEntry(vLife, 2*pNodes[n]+1) == e ) // last time + Vec_IntRemove( vTemp, pNodes[n] ); + Vec_IntAppend( Vec_WecPushLevel(vFronts), vTemp ); + } + //Vec_WecPrint( vFronts, 0 ); + Vec_IntFree( vTemp ); + return vFronts; +} + +/**Function************************************************************* + + Synopsis [Print grid.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_GraphPathPrint4( int * pBuffer, Vec_Int_t * vEdges ) +{ + char Box[13][13]; + int x, y; + int e, nEdges = Vec_IntSize(vEdges)/2; + for ( y = 0; y < 13; y++ ) + for ( x = 0; x < 13; x++ ) + if ( y % 4 == 0 && x % 4 == 0 ) + Box[y][x] = '*'; + else + Box[y][x] = ' '; + for ( e = 0; e < nEdges; e++ ) + { + int * pNodes = Vec_IntEntryP(vEdges, 2*e); + int y0 = 4*(pNodes[0]/4); + int x0 = 4*(pNodes[0]%4); + int y1 = 4*(pNodes[1]/4); + int x1 = 4*(pNodes[1]%4); + if ( !pBuffer[e] ) + continue; + if ( y0 == y1 ) + { + for ( x = x0+1; x < x1; x++ ) + Box[y0][x] = '-'; + } + else if ( x0 == x1 ) + { + for ( y = y0+1; y < y1; y++ ) + Box[y][x0] = '|'; + } + else assert( 0 ); + } + for ( y = 0; y < 13; y++, printf("\n") ) + for ( x = 0; x < 13; x++ ) + printf( "%c", Box[y][x] ); + printf( "\n\n=================================\n\n" ); +} +void Abc_GraphPathPrint5( int * pBuffer, Vec_Int_t * vEdges ) +{ + char Box[17][17]; + int x, y; + int e, nEdges = Vec_IntSize(vEdges)/2; + for ( y = 0; y < 17; y++ ) + for ( x = 0; x < 17; x++ ) + if ( y % 4 == 0 && x % 4 == 0 ) + Box[y][x] = '*'; + else + Box[y][x] = ' '; + for ( e = 0; e < nEdges; e++ ) + { + int * pNodes = Vec_IntEntryP(vEdges, 2*e); + int y0 = 4*(pNodes[0]/5); + int x0 = 4*(pNodes[0]%5); + int y1 = 4*(pNodes[1]/5); + int x1 = 4*(pNodes[1]%5); + if ( !pBuffer[e] ) + continue; + if ( y0 == y1 ) + { + for ( x = x0+1; x < x1; x++ ) + Box[y0][x] = '-'; + } + else if ( x0 == x1 ) + { + for ( y = y0+1; y < y1; y++ ) + Box[y][x0] = '|'; + } + else assert( 0 ); + } + for ( y = 0; y < 17; y++, printf("\n") ) + for ( x = 0; x < 17; x++ ) + printf( "%c", Box[y][x] ); + printf( "\n\n=================================\n\n" ); +} + +/**Function************************************************************* + + Synopsis [Count paths.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +double Abc_GraphCountPaths_rec( int Lev, int Node, Vec_Wec_t * vNodes, double ** pCache, int * pBuffer, Vec_Int_t * vEdges ) +{ + double Res0, Res1; +// if ( Node == -2 ) Abc_GraphPathPrint4( pBuffer, vEdges ); + if ( Node == -2 ) + return 1; + if ( Node == -1 ) + return 0; + if ( pCache[Lev][Node] != -1.0 ) + return pCache[Lev][Node]; + pBuffer[Lev] = 0; + Res0 = Abc_GraphCountPaths_rec( Lev+1, Vec_IntEntry( Vec_WecEntry(vNodes, Lev), 2*Node ), vNodes, pCache, pBuffer, vEdges ); + pBuffer[Lev] = 1; + Res1 = Abc_GraphCountPaths_rec( Lev+1, Vec_IntEntry( Vec_WecEntry(vNodes, Lev), 2*Node+1 ), vNodes, pCache, pBuffer, vEdges ); + return (pCache[Lev][Node] = Res0 + Res1); +} +double Abc_GraphCountPaths( Vec_Wec_t * vNodes, Vec_Int_t * vEdges ) +{ + int i, k, pBuffer[1000] = {0}; + double ** pCache = ABC_ALLOC( double *, Vec_WecSize(vNodes) ); + Vec_Int_t * vLevel; double Value; + Vec_WecForEachLevel( vNodes, vLevel, i ) + { + pCache[i] = ABC_ALLOC( double, Vec_IntSize(vLevel) ); + for ( k = 0; k < Vec_IntSize(vLevel); k++ ) + pCache[i][k] = -1.0; + } + Value = Abc_GraphCountPaths_rec( 0, 0, vNodes, pCache, pBuffer, vEdges ); + for ( i = 0; i < Vec_WecSize(vNodes); i++ ) + ABC_FREE( pCache[i] ); + ABC_FREE( pCache ); + return Value; +} + +/**Function************************************************************* + + Synopsis [Build AIG for paths.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_GraphDeriveGia_rec( Gia_Man_t * p, int Lev, int Node, Vec_Wec_t * vNodes, int ** pCache, int * pBuffer, Vec_Int_t * vEdges ) +{ + int Res0, Res1; + if ( Node == -2 ) + return 1; + if ( Node == -1 ) + return 0; + if ( pCache[Lev][Node] != -1 ) + return pCache[Lev][Node]; + pBuffer[Lev] = 0; + Res0 = Abc_GraphDeriveGia_rec( p, Lev+1, Vec_IntEntry( Vec_WecEntry(vNodes, Lev), 2*Node ), vNodes, pCache, pBuffer, vEdges ); + pBuffer[Lev] = 1; + Res1 = Abc_GraphDeriveGia_rec( p, Lev+1, Vec_IntEntry( Vec_WecEntry(vNodes, Lev), 2*Node+1 ), vNodes, pCache, pBuffer, vEdges ); + return ( pCache[Lev][Node] = Gia_ManHashMux(p, Gia_Obj2Lit(p, Gia_ManCi(p, Lev)), Res1, Res0) ); +} +Gia_Man_t * Abc_GraphDeriveGia( Vec_Wec_t * vNodes, Vec_Int_t * vEdges ) +{ + int ** pCache; + int i, Value, pBuffer[1000] = {0}; + Vec_Int_t * vLevel; + // start AIG + Gia_Man_t * pTemp, * p = Gia_ManStart( 1000 ); + p->pName = Abc_UtilStrsav("paths"); + for ( i = 0; i < Vec_IntSize(vEdges)/2; i++ ) + Gia_ManAppendCi(p); + Gia_ManHashAlloc(p); + // alloc cache + pCache = ABC_ALLOC( int *, Vec_WecSize(vNodes) ); + Vec_WecForEachLevel( vNodes, vLevel, i ) + pCache[i] = ABC_FALLOC( int, Vec_IntSize(vLevel) ); + Value = Abc_GraphDeriveGia_rec( p, 0, 0, vNodes, pCache, pBuffer, vEdges ); + for ( i = 0; i < Vec_WecSize(vNodes); i++ ) + ABC_FREE( pCache[i] ); + ABC_FREE( pCache ); + // cleanup + Gia_ManAppendCo( p, Value ); + p = Gia_ManCleanup( pTemp = p ); + Gia_ManStop( pTemp ); + return p; +} +void Abc_GraphDeriveGiaDump( Vec_Wec_t * vNodes, Vec_Int_t * vEdges, int Size ) +{ + char pFileName[100]; + Gia_Man_t * pGia = Abc_GraphDeriveGia( vNodes, vEdges ); + sprintf( pFileName, "grid_%dx%d_e%03d.aig", Size, Size, Vec_IntSize(vEdges)/2 ); + Gia_AigerWrite( pGia, pFileName, 0, 0 ); + Gia_ManStop( pGia ); + printf( "Finished dumping AIG into file \"%s\".\n", pFileName ); +} + +/**Function************************************************************* + + Synopsis [Build frontier.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_GraphBuildState( Vec_Int_t * vState, int e, int x, Vec_Int_t * vEdges, Vec_Int_t * vLife, Vec_Wec_t * vFronts, int * pFront, Vec_Int_t * vStateNew, int fVerbose ) +{ + Vec_Int_t * vFront = Vec_WecEntry( vFronts, e ); + Vec_Int_t * vFront2 = Vec_WecEntry( vFronts, e+1 ); + int * pNodes = Vec_IntEntryP(vEdges, 2*e); + int nNodes = Vec_IntSize(vLife)/2; + int i, n, Node, First, pEquivs[2]; + assert( pNodes[0] < pNodes[1] ); + if ( fVerbose ) printf( "Edge = %d. Arc = %d.\nCurrent state: ", e, x ); + Vec_IntForEachEntry( vFront, Node, i ) + { + pFront[Node] = Vec_IntEntry(vState, i); + if ( fVerbose ) printf( "%d(%d) ", pFront[Node] & 0xFFFF, pFront[Node] >> 16 ); + } + if ( fVerbose ) printf( "\n" ); + for ( n = 0; n < 2; n++ ) + if ( Vec_IntEntry(vLife, 2*pNodes[n]) == e ) // first time + pFront[pNodes[n]] = pNodes[n]; // degree = 0; comp = singleton + if ( x ) + { + if ( (pFront[pNodes[0]] & 0xFFFF) == (pFront[pNodes[1]] & 0xFFFF) ) // the same comp + return -1; // const 0 + for ( n = 0; n < 2; n++ ) + { + int Degree = pFront[pNodes[n]] >> 16; + if ( (pNodes[n] == 0 || pNodes[n] == nNodes-1) ? Degree >= 1 : Degree >= 2 ) + return -1; // const 0 + pFront[pNodes[n]] += (1 << 16); // degree++ + } + } + // remember equivalence classes + pEquivs[0] = pFront[pNodes[0]] & 0xFFFF; + pEquivs[1] = pFront[pNodes[1]] & 0xFFFF; + // remove some nodes from the frontier + for ( n = 0; n < 2; n++ ) + if ( Vec_IntEntry(vLife, 2*pNodes[n]+1) == e ) // last time + { + int Degree = pFront[pNodes[n]] >> 16; + if ( (pNodes[n] == 0 || pNodes[n] == nNodes-1) ? Degree != 1 : Degree != 0 && Degree != 2 ) + return -1; // const 0 + // if it is part of the comp, update + First = -1; + Vec_IntForEachEntry( vFront2, Node, i ) + { + assert( Node != pNodes[n] ); + if ( (pFront[Node] & 0xFFFF) == pEquivs[n] ) + { + if ( First == -1 ) + First = Node; + pFront[Node] = (pFront[Node] & 0xFFFF0000) | First; + } + } + if ( First != -1 ) + pEquivs[n] = First; + } + if ( x ) + { + // union comp + int First = -1; + Vec_IntForEachEntry( vFront2, Node, i ) + if ( (pFront[Node] & 0xFFFF) == pEquivs[0] || (pFront[Node] & 0xFFFF) == pEquivs[1] ) + { + if ( First == -1 ) + First = Node; + pFront[Node] = (pFront[Node] & 0xFFFF0000) | First; + } + } + // create next state + Vec_IntClear( vStateNew ); + if ( fVerbose ) printf( "Next state: " ); + Vec_IntForEachEntry( vFront2, Node, i ) + { + Vec_IntPush( vStateNew, pFront[Node] ); + if ( fVerbose ) printf( "%d(%d) ", pFront[Node] & 0xFFFF, pFront[Node] >> 16 ); + } + if ( fVerbose ) printf( "\n\n" ); + return 1; +} +void Abc_GraphBuildFrontier( int nSize, Vec_Int_t * vEdges, Vec_Int_t * vLife, Vec_Wec_t * vFronts, int fVerbose ) +{ + abctime clk = Abc_Clock(); + double nPaths; + int nEdges = Vec_IntSize(vEdges)/2; + int nNodes = Vec_IntSize(vLife)/2; + Vec_Wec_t * vNodes = Vec_WecAlloc( nEdges ); + Vec_Int_t * vStateNew = Vec_IntAlloc( nNodes ); + Vec_Int_t * vStateCount = Vec_IntAlloc( nEdges ); + int e, s, x, Next, * pFront = ABC_CALLOC( int, nNodes ); + Hsh_VecMan_t * pThis = Hsh_VecManStart( 1000 ); + Hsh_VecMan_t * pNext = Hsh_VecManStart( 1000 ); + Hsh_VecManAdd( pThis, vStateNew ); + for ( e = 0; e < nEdges; e++ ) + { + Vec_Int_t * vNode = Vec_WecPushLevel(vNodes); + int nStates = Hsh_VecSize( pThis ); + Vec_IntPush( vStateCount, nStates ); + if ( fVerbose ) + { + printf( "\n" ); + printf( "Processing edge %d = {%d %d}\n", e, Vec_IntEntry(vEdges, 2*e), Vec_IntEntry(vEdges, 2*e+1) ); + printf( "Frontier: " ); Vec_IntPrint( Vec_WecEntry(vFronts, e) ); + printf( "\n" ); + } + for ( s = 0; s < nStates; s++ ) + { + Vec_Int_t * vState = Hsh_VecReadEntry(pThis, s); + for ( x = 0; x < 2; x++ ) + { + Next = Abc_GraphBuildState(vState, e, x, vEdges, vLife, vFronts, pFront, vStateNew, fVerbose); + if ( Next == 1 ) + { + if ( e == nEdges - 1 ) // last edge + Next = -2; // const1 + else + Next = Hsh_VecManAdd( pNext, vStateNew ); + } + if ( fVerbose ) printf( "Return value = %d\n", Next ); + Vec_IntPush( vNode, Next ); + } + } + Hsh_VecManStop( pThis ); + pThis = pNext; + pNext = Hsh_VecManStart( 1000 ); + } + nPaths = Abc_GraphCountPaths(vNodes, vEdges); + printf( "States = %8d Paths = %24.0f ", Vec_IntSum(vStateCount), nPaths ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); + if ( fVerbose ) + Vec_IntPrint( vStateCount ); + Abc_GraphDeriveGiaDump( vNodes, vEdges, nSize ); + ABC_FREE( pFront ); + Vec_WecFree( vNodes ); + Vec_IntFree( vStateNew ); + Vec_IntFree( vStateCount ); + Hsh_VecManStop( pThis ); + Hsh_VecManStop( pNext ); +} +void Abc_EnumerateFrontierTest( int nSize ) +{ + //int nSize = 3; + int fVerbose = 0; + Vec_Int_t * vEdges = Abc_GraphGrid( nSize ); + Vec_Int_t * vLife = Abc_GraphNodeLife( vEdges, nSize ); + Vec_Wec_t * vFronts = Abc_GraphFrontiers( vEdges, vLife ); + + Abc_GraphBuildFrontier( nSize, vEdges, vLife, vFronts, fVerbose ); + + Vec_WecFree( vFronts ); + Vec_IntFree( vLife ); + Vec_IntFree( vEdges ); +} + + +/**Function************************************************************* + + Synopsis [Performs SAT-based path enumeration.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +double Abc_Word2Double( word w ) +{ + double Res = 0; int i; + for ( i = 0; i < 64; i++ ) + if ( (w >> i) & 1 ) + Res += pow(2,i); + return Res; +} +void Abc_GraphSolve( Gia_Man_t * pGia ) +{ + int nIters = 1000; + Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( pGia, 8, 0, 1, 0, 0 ); + sat_solver * pSat; Vec_Int_t * vLits = Vec_IntAlloc( 100 ); + int i, k, iLit, nVars = Gia_ManCiNum(pGia); + int iCiVarBeg = pCnf->nVars - nVars; + word Total = 0; + word Mint1 = 0; + word Mint2 = 0; + + // restart the SAT solver + pSat = sat_solver_new(); + sat_solver_setnvars( pSat, pCnf->nVars ); + // add timeframe clauses + for ( i = 0; i < pCnf->nClauses; i++ ) + if ( !sat_solver_addclause( pSat, pCnf->pClauses[i], pCnf->pClauses[i+1] ) ) + assert( 0 ); + // create trivial assignment + Vec_IntClear( vLits ); + for ( k = 0; k < nVars; k++ ) + Vec_IntPush( vLits, Abc_Var2Lit(iCiVarBeg+k, 1) ); + // generate random assignment + for ( i = 0; i < nIters; i++ ) + { + int Status = sat_solver_solve_lexsat( pSat, Vec_IntArray(vLits), Vec_IntSize(vLits) ); + if ( Status != l_True ) + break; + assert( Status == l_True ); + // block this assignment + Vec_IntForEachEntry( vLits, iLit, k ) + Vec_IntWriteEntry( vLits, k, Abc_LitNot(iLit) ); + if ( !sat_solver_addclause( pSat, Vec_IntArray(vLits), Vec_IntLimit(vLits) ) ) + break; + Vec_IntForEachEntry( vLits, iLit, k ) + Vec_IntWriteEntry( vLits, k, Abc_LitNot(iLit) ); + // collect new minterm + Mint2 = 0; + Vec_IntForEachEntry( vLits, iLit, k ) + if ( !Abc_LitIsCompl(iLit) ) + Mint2 |= ((word)1) << (nVars-1-k); + if ( Mint1 == 0 ) + Mint1 = Mint2; + // report + //printf( "Iter %3d : ", i ); + //Extra_PrintBinary( stdout, (unsigned *)&Mint2, Abc_MinInt(64, nVars) ); printf( "\n" ); + } + //Mint1 = 0; + Total = (Mint2-Mint1)/nIters; + printf( "Vars = %d Iters = %d Ave = %.0f Total = %.0f ", nVars, nIters, Abc_Word2Double(Mint2-Mint1), Abc_Word2Double(Total) ); + printf( "Estimate = %.0f\n", (pow(2,nVars)-Abc_Word2Double(Mint1))/Abc_Word2Double((Mint2-Mint1)/nIters) ); + + sat_solver_delete( pSat ); + Cnf_DataFree( pCnf ); + Vec_IntFree( vLits ); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/misc/extra/module.make b/src/misc/extra/module.make index c8d70f26..9db290e5 100644 --- a/src/misc/extra/module.make +++ b/src/misc/extra/module.make @@ -4,9 +4,11 @@ SRC += src/misc/extra/extraUtilBitMatrix.c \ src/misc/extra/extraUtilDsd.c \ src/misc/extra/extraUtilEnum.c \ src/misc/extra/extraUtilFile.c \ + src/misc/extra/extraUtilMaj.c \ src/misc/extra/extraUtilMemory.c \ src/misc/extra/extraUtilMisc.c \ src/misc/extra/extraUtilMult.c \ + src/misc/extra/extraUtilPath.c \ src/misc/extra/extraUtilPerm.c \ src/misc/extra/extraUtilProgress.c \ src/misc/extra/extraUtilReader.c \ diff --git a/src/misc/util/utilTruth.h b/src/misc/util/utilTruth.h index 36da1271..3d3f80b8 100644 --- a/src/misc/util/utilTruth.h +++ b/src/misc/util/utilTruth.h @@ -1154,6 +1154,10 @@ static inline int Abc_Tt6HasVar( word t, int iVar ) { return ((t >> (1<<iVar)) & s_Truths6Neg[iVar]) != (t & s_Truths6Neg[iVar]); } +static inline int Abc_Tt6XorVar( word t, int iVar ) +{ + return ((t >> (1<<iVar)) & s_Truths6Neg[iVar]) == ~(t & s_Truths6Neg[iVar]); +} static inline int Abc_TtHasVar( word * t, int nVars, int iVar ) { assert( iVar < nVars ); @@ -3094,6 +3098,99 @@ static inline int Abc_Tt4Check( int t ) return 0; } + +/**Function************************************************************* + + Synopsis [Returns symmetry profile of the function.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Abc_Tt6VarsAreSymmetric( word t, int iVar, int jVar ) +{ + word * s_PMasks = s_PPMasks[iVar][jVar]; + int shift = (1 << jVar) - (1 << iVar); + assert( iVar < jVar ); + return ((t & s_PMasks[1]) << shift) == (t & s_PMasks[2]); +} +static inline int Abc_Tt6VarsAreAntiSymmetric( word t, int iVar, int jVar ) +{ + word * s_PMasks = s_PPMasks[iVar][jVar]; + int shift = (1 << jVar) + (1 << iVar); + assert( iVar < jVar ); + return ((t & (s_PMasks[1] >> (1 << iVar))) << shift) == (t & (s_PMasks[2] << (1 << iVar))); +} +static inline int Abc_TtVarsAreSymmetric( word * pTruth, int nVars, int i, int j, word * pCof0, word * pCof1 ) +{ + int nWords = Abc_TtWordNum( nVars ); + assert( i < nVars && j < nVars ); + Abc_TtCofactor0p( pCof0, pTruth, nWords, i ); + Abc_TtCofactor1p( pCof1, pTruth, nWords, i ); + Abc_TtCofactor1( pCof0, nWords, j ); + Abc_TtCofactor0( pCof1, nWords, j ); + return Abc_TtEqual( pCof0, pCof1, nWords ); +} +static inline int Abc_TtVarsAreAntiSymmetric( word * pTruth, int nVars, int i, int j, word * pCof0, word * pCof1 ) +{ + int nWords = Abc_TtWordNum( nVars ); + assert( i < nVars && j < nVars ); + Abc_TtCofactor0p( pCof0, pTruth, nWords, i ); + Abc_TtCofactor1p( pCof1, pTruth, nWords, i ); + Abc_TtCofactor0( pCof0, nWords, j ); + Abc_TtCofactor1( pCof1, nWords, j ); + return Abc_TtEqual( pCof0, pCof1, nWords ); +} +static inline int Abc_TtIsFullySymmetric( word * pTruth, int nVars ) +{ + int m, v, Polar = 0, Seen = 0; + for ( m = 0; m < (1<<nVars); m++ ) + { + int Count = 0; + int Value = Abc_TtGetBit( pTruth, m ); + for ( v = 0; v < nVars; v++ ) + Count += ((m >> v) & 1); + if ( (Seen >> Count) & 1 ) // seen this count + { + if ( Value != ((Polar >> Count) & 1) ) + return -1; + } + else // new count + { + Seen |= 1 << Count; + if ( Value ) + Polar |= 1 << Count; + } + } + return Polar; +} +static inline void Abc_TtGenFullySymmetric( word * pTruth, int nVars, int Polar ) +{ + int m, v, nWords = Abc_TtWordNum( nVars ); + Abc_TtClear( pTruth, nWords ); + for ( m = 0; m < (1<<nVars); m++ ) + { + int Count = 0; + for ( v = 0; v < nVars; v++ ) + Count += ((m >> v) & 1); + if ( (Polar >> Count) & 1 ) + Abc_TtSetBit( pTruth, m ); + } +} +static inline void Abc_TtTestFullySymmetric() +{ + word pTruth[4]; // 8-var function + int PolarOut, PolarIn = 271; + Abc_TtGenFullySymmetric( pTruth, 8, PolarIn ); + //Abc_TtXorBit( pTruth, 171 ); + PolarOut = Abc_TtIsFullySymmetric( pTruth, 8 ); + assert( PolarIn == PolarOut ); +} + + /*=== utilTruth.c ===========================================================*/ diff --git a/src/misc/vec/vecMem.h b/src/misc/vec/vecMem.h index 72b653b7..c2bd06f0 100644 --- a/src/misc/vec/vecMem.h +++ b/src/misc/vec/vecMem.h @@ -341,10 +341,24 @@ static int * Vec_MemHashLookup( Vec_Mem_t * p, word * pEntry ) return pSpot; return pSpot; } +static void Vec_MemHashProfile( Vec_Mem_t * p ) +{ + int e; + for ( e = 0; e < 1000; e++ ) + { + int Count = 0; + int * pSpot = Vec_IntEntryP( p->vTable, e ); + for ( ; *pSpot != -1; pSpot = Vec_IntEntryP(p->vNexts, *pSpot) ) + Count++; + printf( "%d ", Count ); + } + printf( "\n" ); +} static void Vec_MemHashResize( Vec_Mem_t * p ) { word * pEntry; int i, * pSpot; + //Vec_MemHashProfile( p ); Vec_IntFill( p->vTable, Abc_PrimeCudd(2 * Vec_IntSize(p->vTable)), -1 ); Vec_IntClear( p->vNexts ); Vec_MemForEachEntry( p, pEntry, i ) diff --git a/src/opt/dau/dau.h b/src/opt/dau/dau.h index f392a98f..82e9b83b 100644 --- a/src/opt/dau/dau.h +++ b/src/opt/dau/dau.h @@ -60,6 +60,7 @@ typedef enum { typedef struct Dss_Man_t_ Dss_Man_t; typedef struct Abc_TtHieMan_t_ Abc_TtHieMan_t; +typedef unsigned(*TtCanonicizeFunc)(Abc_TtHieMan_t * p, word * pTruth, int nVars, char * pCanonPerm, int flag); //////////////////////////////////////////////////////////////////////// /// MACRO DEFINITIONS /// @@ -77,7 +78,17 @@ static inline int Dau_DsdReadVar( char * p ) { if ( *p == '!' ) p++; return *p /*=== dauCanon.c ==========================================================*/ extern unsigned Abc_TtCanonicize( word * pTruth, int nVars, char * pCanonPerm ); +extern unsigned Abc_TtCanonicizePerm( word * pTruth, int nVars, char * pCanonPerm ); extern unsigned Abc_TtCanonicizePhase( word * pTruth, int nVars ); +extern int Abc_TtCountOnesInCofsSimple( word * pTruth, int nVars, int * pStore ); +extern unsigned Abc_TtCanonicizeHie(Abc_TtHieMan_t * p, word * pTruth, int nVars, char * pCanonPerm, int fExact ); +extern Abc_TtHieMan_t * Abc_TtHieManStart( int nVars, int nLevels ); +extern void Abc_TtHieManStop(Abc_TtHieMan_t * p ); +extern unsigned Abc_TtCanonicizeWrap(TtCanonicizeFunc func, Abc_TtHieMan_t * p, word * pTruth, int nVars, char * pCanonPerm, int flag); +extern unsigned Abc_TtCanonicizeAda(Abc_TtHieMan_t * p, word * pTruth, int nVars, char * pCanonPerm, int iThres); +extern unsigned Abc_TtCanonicizeHie(Abc_TtHieMan_t * p, word * pTruthInit, int nVars, char * pCanonPerm, int fExact); +/*=== dauCount.c ==========================================================*/ +extern int Abc_TtCountOnesInCofsQuick( word * pTruth, int nVars, int * pStore ); /*=== dauDsd.c ==========================================================*/ extern int * Dau_DsdComputeMatches( char * p ); extern int Dau_DsdDecompose( word * pTruth, int nVarsInit, int fSplitPrime, int fWriteTruth, char * pRes ); diff --git a/src/opt/dau/dauCanon.c b/src/opt/dau/dauCanon.c index d54a5c31..357da500 100644 --- a/src/opt/dau/dauCanon.c +++ b/src/opt/dau/dauCanon.c @@ -64,11 +64,11 @@ static inline int Abc_TtCompare1VarCofs( word * pTruth, int nWords, int iVar ) return Cof0 < Cof1 ? -1 : 1; return 0; } - if ( iVar <= 5 ) - { + if ( iVar <= 5 ) + { word Cof0, Cof1; - int w, shift = (1 << iVar); - for ( w = 0; w < nWords; w++ ) + int w, shift = (1 << iVar); + for ( w = 0; w < nWords; w++ ) { Cof0 = pTruth[w] & s_Truths6Neg[iVar]; Cof1 = (pTruth[w] >> shift) & s_Truths6Neg[iVar]; @@ -76,18 +76,18 @@ static inline int Abc_TtCompare1VarCofs( word * pTruth, int nWords, int iVar ) return Cof0 < Cof1 ? -1 : 1; } return 0; - } - // if ( iVar > 5 ) - { + } + // if ( iVar > 5 ) + { word * pLimit = pTruth + nWords; - int i, iStep = Abc_TtWordNum(iVar); + int i, iStep = Abc_TtWordNum(iVar); assert( nWords >= 2 ); - for ( ; pTruth < pLimit; pTruth += 2*iStep ) - for ( i = 0; i < iStep; i++ ) + for ( ; pTruth < pLimit; pTruth += 2*iStep ) + for ( i = 0; i < iStep; i++ ) if ( pTruth[i] != pTruth[i + iStep] ) return pTruth[i] < pTruth[i + iStep] ? -1 : 1; return 0; - } + } } static inline int Abc_TtCompare1VarCofsRev( word * pTruth, int nWords, int iVar ) { @@ -99,11 +99,11 @@ static inline int Abc_TtCompare1VarCofsRev( word * pTruth, int nWords, int iVar return Cof0 < Cof1 ? -1 : 1; return 0; } - if ( iVar <= 5 ) - { + if ( iVar <= 5 ) + { word Cof0, Cof1; - int w, shift = (1 << iVar); - for ( w = nWords - 1; w >= 0; w-- ) + int w, shift = (1 << iVar); + for ( w = nWords - 1; w >= 0; w-- ) { Cof0 = pTruth[w] & s_Truths6Neg[iVar]; Cof1 = (pTruth[w] >> shift) & s_Truths6Neg[iVar]; @@ -111,18 +111,18 @@ static inline int Abc_TtCompare1VarCofsRev( word * pTruth, int nWords, int iVar return Cof0 < Cof1 ? -1 : 1; } return 0; - } - // if ( iVar > 5 ) - { + } + // if ( iVar > 5 ) + { word * pLimit = pTruth + nWords; - int i, iStep = Abc_TtWordNum(iVar); + int i, iStep = Abc_TtWordNum(iVar); assert( nWords >= 2 ); - for ( pLimit -= 2*iStep; pLimit >= pTruth; pLimit -= 2*iStep ) - for ( i = iStep - 1; i >= 0; i-- ) + for ( pLimit -= 2*iStep; pLimit >= pTruth; pLimit -= 2*iStep ) + for ( i = iStep - 1; i >= 0; i-- ) if ( pLimit[i] != pLimit[i + iStep] ) return pLimit[i] < pLimit[i + iStep] ? -1 : 1; return 0; - } + } } */ @@ -142,35 +142,35 @@ static inline int Abc_TtCheckEqual2VarCofs( word * pTruth, int nWords, int iVar, assert( Num1 < Num2 && Num2 < 4 ); if ( nWords == 1 ) return ((pTruth[0] >> (Num2 * (1 << iVar))) & s_CMasks6[iVar]) == ((pTruth[0] >> (Num1 * (1 << iVar))) & s_CMasks6[iVar]); - if ( iVar <= 4 ) - { - int w, shift = (1 << iVar); - for ( w = 0; w < nWords; w++ ) + if ( iVar <= 4 ) + { + int w, shift = (1 << iVar); + for ( w = 0; w < nWords; w++ ) if ( ((pTruth[w] >> Num2 * shift) & s_CMasks6[iVar]) != ((pTruth[w] >> Num1 * shift) & s_CMasks6[iVar]) ) return 0; return 1; - } - if ( iVar == 5 ) - { + } + if ( iVar == 5 ) + { unsigned * pTruthU = (unsigned *)pTruth; unsigned * pLimitU = (unsigned *)(pTruth + nWords); assert( nWords >= 2 ); - for ( ; pTruthU < pLimitU; pTruthU += 4 ) + for ( ; pTruthU < pLimitU; pTruthU += 4 ) if ( pTruthU[Num2] != pTruthU[Num1] ) return 0; return 1; - } - // if ( iVar > 5 ) - { + } + // if ( iVar > 5 ) + { word * pLimit = pTruth + nWords; - int i, iStep = Abc_TtWordNum(iVar); + int i, iStep = Abc_TtWordNum(iVar); assert( nWords >= 4 ); - for ( ; pTruth < pLimit; pTruth += 4*iStep ) - for ( i = 0; i < iStep; i++ ) + for ( ; pTruth < pLimit; pTruth += 4*iStep ) + for ( i = 0; i < iStep; i++ ) if ( pTruth[i+Num2*iStep] != pTruth[i+Num1*iStep] ) return 0; return 1; - } + } } /**Function************************************************************* @@ -195,11 +195,11 @@ static inline int Abc_TtCompare2VarCofs( word * pTruth, int nWords, int iVar, in return Cof1 < Cof2 ? -1 : 1; return 0; } - if ( iVar <= 4 ) - { + if ( iVar <= 4 ) + { word Cof1, Cof2; - int w, shift = (1 << iVar); - for ( w = 0; w < nWords; w++ ) + int w, shift = (1 << iVar); + for ( w = 0; w < nWords; w++ ) { Cof1 = (pTruth[w] >> Num1 * shift) & s_CMasks6[iVar]; Cof2 = (pTruth[w] >> Num2 * shift) & s_CMasks6[iVar]; @@ -207,30 +207,30 @@ static inline int Abc_TtCompare2VarCofs( word * pTruth, int nWords, int iVar, in return Cof1 < Cof2 ? -1 : 1; } return 0; - } - if ( iVar == 5 ) - { + } + if ( iVar == 5 ) + { unsigned * pTruthU = (unsigned *)pTruth; unsigned * pLimitU = (unsigned *)(pTruth + nWords); assert( nWords >= 2 ); - for ( ; pTruthU < pLimitU; pTruthU += 4 ) + for ( ; pTruthU < pLimitU; pTruthU += 4 ) if ( pTruthU[Num1] != pTruthU[Num2] ) return pTruthU[Num1] < pTruthU[Num2] ? -1 : 1; return 0; - } - // if ( iVar > 5 ) - { + } + // if ( iVar > 5 ) + { word * pLimit = pTruth + nWords; - int i, iStep = Abc_TtWordNum(iVar); + int i, iStep = Abc_TtWordNum(iVar); int Offset1 = Num1*iStep; int Offset2 = Num2*iStep; assert( nWords >= 4 ); - for ( ; pTruth < pLimit; pTruth += 4*iStep ) - for ( i = 0; i < iStep; i++ ) + for ( ; pTruth < pLimit; pTruth += 4*iStep ) + for ( i = 0; i < iStep; i++ ) if ( pTruth[i + Offset1] != pTruth[i + Offset2] ) return pTruth[i + Offset1] < pTruth[i + Offset2] ? -1 : 1; return 0; - } + } } static inline int Abc_TtCompare2VarCofsRev( word * pTruth, int nWords, int iVar, int Num1, int Num2 ) { @@ -243,11 +243,11 @@ static inline int Abc_TtCompare2VarCofsRev( word * pTruth, int nWords, int iVar, return Cof1 < Cof2 ? -1 : 1; return 0; } - if ( iVar <= 4 ) - { + if ( iVar <= 4 ) + { word Cof1, Cof2; - int w, shift = (1 << iVar); - for ( w = nWords - 1; w >= 0; w-- ) + int w, shift = (1 << iVar); + for ( w = nWords - 1; w >= 0; w-- ) { Cof1 = (pTruth[w] >> Num1 * shift) & s_CMasks6[iVar]; Cof2 = (pTruth[w] >> Num2 * shift) & s_CMasks6[iVar]; @@ -255,30 +255,30 @@ static inline int Abc_TtCompare2VarCofsRev( word * pTruth, int nWords, int iVar, return Cof1 < Cof2 ? -1 : 1; } return 0; - } - if ( iVar == 5 ) - { + } + if ( iVar == 5 ) + { unsigned * pTruthU = (unsigned *)pTruth; unsigned * pLimitU = (unsigned *)(pTruth + nWords); assert( nWords >= 2 ); - for ( pLimitU -= 4; pLimitU >= pTruthU; pLimitU -= 4 ) + for ( pLimitU -= 4; pLimitU >= pTruthU; pLimitU -= 4 ) if ( pLimitU[Num1] != pLimitU[Num2] ) return pLimitU[Num1] < pLimitU[Num2] ? -1 : 1; return 0; - } - // if ( iVar > 5 ) - { + } + // if ( iVar > 5 ) + { word * pLimit = pTruth + nWords; - int i, iStep = Abc_TtWordNum(iVar); + int i, iStep = Abc_TtWordNum(iVar); int Offset1 = Num1*iStep; int Offset2 = Num2*iStep; assert( nWords >= 4 ); - for ( pLimit -= 4*iStep; pLimit >= pTruth; pLimit -= 4*iStep ) - for ( i = iStep - 1; i >= 0; i-- ) + for ( pLimit -= 4*iStep; pLimit >= pTruth; pLimit -= 4*iStep ) + for ( i = iStep - 1; i >= 0; i-- ) if ( pLimit[i + Offset1] != pLimit[i + Offset2] ) return pLimit[i + Offset1] < pLimit[i + Offset2] ? -1 : 1; return 0; - } + } } /**Function************************************************************* @@ -292,13 +292,24 @@ static inline int Abc_TtCompare2VarCofsRev( word * pTruth, int nWords, int iVar, SeeAlso [] ***********************************************************************/ -#define DO_SMALL_TRUTHTABLE 0 +void Abc_TtNormalizeSmallTruth(word * pTruth, int nVars) +{ + if (nVars < 6) { + int shift, bits = (1 << nVars); + word base = *pTruth = *pTruth & ((((word)1) << bits) - 1); + for (shift = bits; shift < 64; shift += bits) + *pTruth |= base << shift; + } +} -static inline void Abc_TtNormalizeSmallTruth(word * pTruth, int nVars) +inline void Abc_TtVerifySmallTruth(word * pTruth, int nVars) { -#if DO_SMALL_TRUTHTABLE - if (nVars < 6) - *pTruth &= (1ULL << (1 << nVars)) - 1; +#ifndef NDEBUG + if (nVars < 6) { + word nTruth = *pTruth; + Abc_TtNormalizeSmallTruth(&nTruth, nVars); + assert(*pTruth == nTruth); + } #endif } @@ -306,7 +317,7 @@ static inline int Abc_TtCountOnesInTruth( word * pTruth, int nVars ) { int nWords = Abc_TtWordNum( nVars ); int k, Counter = 0; - Abc_TtNormalizeSmallTruth(pTruth, nVars); + Abc_TtVerifySmallTruth(pTruth, nVars); for ( k = 0; k < nWords; k++ ) if ( pTruth[k] ) Counter += Abc_TtCountOnes( pTruth[k] ); @@ -318,7 +329,7 @@ static inline void Abc_TtCountOnesInCofs( word * pTruth, int nVars, int * pStore int i, k, Counter, nWords; if ( nVars <= 6 ) { - Abc_TtNormalizeSmallTruth(pTruth, nVars); + Abc_TtVerifySmallTruth(pTruth, nVars); for ( i = 0; i < nVars; i++ ) pStore[i] = Abc_TtCountOnes( pTruth[0] & s_Truths6Neg[i] ); return; @@ -351,6 +362,11 @@ static inline void Abc_TtCountOnesInCofs( word * pTruth, int nVars, int * pStore } } } +int Abc_TtCountOnesInCofsSimple( word * pTruth, int nVars, int * pStore ) +{ + Abc_TtCountOnesInCofs( pTruth, nVars, pStore ); + return Abc_TtCountOnesInTruth( pTruth, nVars ); +} /**Function************************************************************* @@ -489,8 +505,9 @@ int Abc_TtCountOnesInCofsFast( word * pTruth, int nVars, int * pStore ) SeeAlso [] ***********************************************************************/ -static inline unsigned Abc_TtSemiCanonicize( word * pTruth, int nVars, char * pCanonPerm, int * pStoreOut ) +static inline unsigned Abc_TtSemiCanonicize( word * pTruth, int nVars, char * pCanonPerm, int * pStoreOut, int fOnlySwap ) { + int fUseOld = 1; int fOldSwap = 0; int pStoreIn[17]; int * pStore = pStoreOut ? pStoreOut : pStoreIn; @@ -499,25 +516,53 @@ static inline unsigned Abc_TtSemiCanonicize( word * pTruth, int nVars, char * pC assert( nVars <= 16 ); for ( i = 0; i < nVars; i++ ) pCanonPerm[i] = i; - // normalize polarity - nOnes = Abc_TtCountOnesInTruth( pTruth, nVars ); - if ( nOnes > nWords * 32 ) + + if ( fUseOld ) { - Abc_TtNot( pTruth, nWords ); - nOnes = nWords*64 - nOnes; - uCanonPhase |= (1 << nVars); + // normalize polarity + nOnes = Abc_TtCountOnesInTruth( pTruth, nVars ); + if ( nOnes > nWords * 32 && !fOnlySwap ) + { + Abc_TtNot( pTruth, nWords ); + nOnes = nWords*64 - nOnes; + uCanonPhase |= (1 << nVars); + } + // normalize phase + Abc_TtCountOnesInCofs( pTruth, nVars, pStore ); + pStore[nVars] = nOnes; + for ( i = 0; i < nVars; i++ ) + { + if ( pStore[i] >= nOnes - pStore[i] || fOnlySwap ) + continue; + Abc_TtFlip( pTruth, nWords, i ); + uCanonPhase |= (1 << i); + pStore[i] = nOnes - pStore[i]; + } } - // normalize phase - Abc_TtCountOnesInCofs( pTruth, nVars, pStore ); - pStore[nVars] = nOnes; - for ( i = 0; i < nVars; i++ ) + else { - if ( pStore[i] >= nOnes - pStore[i] ) - continue; - Abc_TtFlip( pTruth, nWords, i ); - uCanonPhase |= (1 << i); - pStore[i] = nOnes - pStore[i]; + nOnes = Abc_TtCountOnesInCofsQuick( pTruth, nVars, pStore ); + // normalize polarity + if ( nOnes > nWords * 32 && !fOnlySwap ) + { + for ( i = 0; i < nVars; i++ ) + pStore[i] = nWords * 32 - pStore[i]; + Abc_TtNot( pTruth, nWords ); + nOnes = nWords*64 - nOnes; + uCanonPhase |= (1 << nVars); + } + // normalize phase + pStore[nVars] = nOnes; + for ( i = 0; i < nVars; i++ ) + { + if ( pStore[i] >= nOnes - pStore[i] || fOnlySwap ) + continue; + Abc_TtFlip( pTruth, nWords, i ); + uCanonPhase |= (1 << i); + pStore[i] = nOnes - pStore[i]; + } } + // normalize permutation if ( fOldSwap ) { @@ -923,7 +968,7 @@ unsigned Abc_TtCanonicize( word * pTruth, int nVars, char * pCanonPerm ) Abc_TtCopy( pCopy1, pTruth, nWords, 0 ); #endif - uCanonPhase = Abc_TtSemiCanonicize( pTruth, nVars, pCanonPerm, pStoreIn ); + uCanonPhase = Abc_TtSemiCanonicize( pTruth, nVars, pCanonPerm, pStoreIn, 0 ); for ( k = 0; k < 5; k++ ) { int fChanges = 0; @@ -958,6 +1003,53 @@ unsigned Abc_TtCanonicize( word * pTruth, int nVars, char * pCanonPerm ) return uCanonPhase; } +unsigned Abc_TtCanonicizePerm( word * pTruth, int nVars, char * pCanonPerm ) +{ + int pStoreIn[17]; + unsigned uCanonPhase; + int i, k, nWords = Abc_TtWordNum( nVars ); + int fNaive = 1; + +#ifdef CANON_VERIFY + char pCanonPermCopy[16]; + static word pCopy1[1024]; + static word pCopy2[1024]; + Abc_TtCopy( pCopy1, pTruth, nWords, 0 ); +#endif + + assert( nVars <= 16 ); + for ( i = 0; i < nVars; i++ ) + pCanonPerm[i] = i; + + uCanonPhase = Abc_TtSemiCanonicize( pTruth, nVars, pCanonPerm, pStoreIn, 1 ); + for ( k = 0; k < 5; k++ ) + { + int fChanges = 0; + for ( i = nVars - 2; i >= 0; i-- ) + if ( pStoreIn[i] == pStoreIn[i+1] ) + fChanges |= Abc_TtCofactorPerm( pTruth, i, nWords, 1, pCanonPerm, &uCanonPhase, fNaive ); + if ( !fChanges ) + break; + fChanges = 0; + for ( i = 1; i < nVars - 1; i++ ) + if ( pStoreIn[i] == pStoreIn[i+1] ) + fChanges |= Abc_TtCofactorPerm( pTruth, i, nWords, 1, pCanonPerm, &uCanonPhase, fNaive ); + if ( !fChanges ) + break; + } + +#ifdef CANON_VERIFY + Abc_TtCopy( pCopy2, pTruth, nWords, 0 ); + memcpy( pCanonPermCopy, pCanonPerm, sizeof(char) * nVars ); + Abc_TtImplementNpnConfig( pCopy2, nVars, pCanonPermCopy, uCanonPhase ); + if ( !Abc_TtEqual( pCopy1, pCopy2, nWords ) ) + printf( "Canonical form verification failed!\n" ); +#endif + + assert( uCanonPhase == 0 ); + return uCanonPhase; +} + /**Function************************************************************* Synopsis [Semi-canonical form computation.] @@ -1073,83 +1165,92 @@ unsigned Abc_TtCanonicizePhase( word * pTruth, int nVars ) struct Abc_TtHieMan_t_ { - int nLastLevel, nWords; - Vec_Mem_t * vTtMem[TT_MAX_LEVELS]; // truth table memory and hash tables - Vec_Int_t * vRepres[TT_MAX_LEVELS]; // pointers to the representatives from the last hierarchical level - int vTruthId[TT_MAX_LEVELS]; + int nLastLevel, nWords; + Vec_Mem_t * vTtMem[TT_MAX_LEVELS]; // truth table memory and hash tables + Vec_Int_t * vRepres[TT_MAX_LEVELS]; // pointers to the representatives from the last hierarchical level + int vTruthId[TT_MAX_LEVELS]; }; Abc_TtHieMan_t * Abc_TtHieManStart(int nVars, int nLevels) { - Abc_TtHieMan_t * p = NULL; - int i; - if (nLevels > TT_MAX_LEVELS) return p; - p = ABC_CALLOC(Abc_TtHieMan_t, 1); - p->nLastLevel = nLevels - 1; - p->nWords = Abc_TtWordNum(nVars); - for (i = 0; i < nLevels; i++) - { - p->vTtMem[i] = Vec_MemAlloc(p->nWords, 12); - Vec_MemHashAlloc(p->vTtMem[i], 10000); - p->vRepres[i] = Vec_IntAlloc(1); - } - return p; + Abc_TtHieMan_t * p = NULL; + int i; + if (nLevels > TT_MAX_LEVELS) return p; + p = ABC_CALLOC(Abc_TtHieMan_t, 1); + p->nLastLevel = nLevels - 1; + p->nWords = Abc_TtWordNum(nVars); + for (i = 0; i < nLevels; i++) + { + p->vTtMem[i] = Vec_MemAlloc(p->nWords, 12); + Vec_MemHashAlloc(p->vTtMem[i], 10000); + p->vRepres[i] = Vec_IntAlloc(1); + } + return p; } void Abc_TtHieManStop(Abc_TtHieMan_t * p) { - int i; - for (i = 0; i <= p->nLastLevel; i++) - { - Vec_MemHashFree(p->vTtMem[i]); - Vec_MemFreeP(&p->vTtMem[i]); - Vec_IntFree(p->vRepres[i]); - } - ABC_FREE(p); + int i; + for (i = 0; i <= p->nLastLevel; i++) + { + Vec_MemHashFree(p->vTtMem[i]); + Vec_MemFreeP(&p->vTtMem[i]); + Vec_IntFree(p->vRepres[i]); + } + ABC_FREE(p); } int Abc_TtHieRetrieveOrInsert(Abc_TtHieMan_t * p, int level, word * pTruth, word * pResult) { - int i, iSpot, truthId; - word * pRepTruth; - if (level < 0) level += p->nLastLevel + 1; - if (level < 0 || level > p->nLastLevel) return -1; - iSpot = *Vec_MemHashLookup(p->vTtMem[level], pTruth); - if (iSpot == -1) { - p->vTruthId[level] = Vec_MemHashInsert(p->vTtMem[level], pTruth); - if (level < p->nLastLevel) return 0; - iSpot = p->vTruthId[level]; - } - // return the class representative - if (level < p->nLastLevel) - truthId = Vec_IntEntry(p->vRepres[level], iSpot); - else - truthId = iSpot; - for (i = 0; i < level; i++) - Vec_IntSetEntry(p->vRepres[i], p->vTruthId[i], truthId); - - pRepTruth = Vec_MemReadEntry(p->vTtMem[p->nLastLevel], truthId); - if (level < p->nLastLevel) { - Abc_TtCopy(pResult, pRepTruth, p->nWords, 0); - return 1; - } - assert(Abc_TtEqual(pTruth, pRepTruth, p->nWords)); - if (pTruth != pResult) - Abc_TtCopy(pResult, pRepTruth, p->nWords, 0); - return 0; + int i, iSpot, truthId; + word * pRepTruth; + if (!p) return -1; + if (level < 0) level += p->nLastLevel + 1; + if (level < 0 || level > p->nLastLevel) return -1; + iSpot = *Vec_MemHashLookup(p->vTtMem[level], pTruth); + if (iSpot == -1) { + p->vTruthId[level] = Vec_MemHashInsert(p->vTtMem[level], pTruth); + if (level < p->nLastLevel) return 0; + iSpot = p->vTruthId[level]; + } + // return the class representative + if (level < p->nLastLevel) + truthId = Vec_IntEntry(p->vRepres[level], iSpot); + else + truthId = iSpot; + for (i = 0; i < level; i++) + Vec_IntSetEntry(p->vRepres[i], p->vTruthId[i], truthId); + + pRepTruth = Vec_MemReadEntry(p->vTtMem[p->nLastLevel], truthId); + if (level < p->nLastLevel) { + Abc_TtCopy(pResult, pRepTruth, p->nWords, 0); + return 1; + } + assert(Abc_TtEqual(pTruth, pRepTruth, p->nWords)); + if (pTruth != pResult) + Abc_TtCopy(pResult, pRepTruth, p->nWords, 0); + return 0; } unsigned Abc_TtCanonicizeHie( Abc_TtHieMan_t * p, word * pTruthInit, int nVars, char * pCanonPerm, int fExact ) { int fNaive = 1; int pStore[17]; - static word pTruth[1024]; + //static word pTruth[1024]; + word * pTruth = pTruthInit; unsigned uCanonPhase = 0; int nOnes, nWords = Abc_TtWordNum( nVars ); int i, k; assert( nVars <= 16 ); - Abc_TtCopy( pTruth, pTruthInit, nWords, 0 ); + // handle constant + if ( nVars == 0 ) + { + Abc_TtClear( pTruthInit, nWords ); + return 0; + } + + //Abc_TtCopy( pTruth, pTruthInit, nWords, 0 ); for ( i = 0; i < nVars; i++ ) pCanonPerm[i] = i; @@ -1177,7 +1278,7 @@ unsigned Abc_TtCanonicizeHie( Abc_TtHieMan_t * p, word * pTruthInit, int nVars, pStore[i] = nOnes - pStore[i]; } // check cache - if (Abc_TtHieRetrieveOrInsert(p, 1, pTruth, pTruthInit) > 0) return 0; + if (Abc_TtHieRetrieveOrInsert(p, 1, pTruth, pTruthInit) > 0) return 0; // normalize permutation { @@ -1201,7 +1302,7 @@ unsigned Abc_TtCanonicizeHie( Abc_TtHieMan_t * p, word * pTruthInit, int nVars, } } // check cache - if (Abc_TtHieRetrieveOrInsert(p, 2, pTruth, pTruthInit) > 0) return 0; + if (Abc_TtHieRetrieveOrInsert(p, 2, pTruth, pTruthInit) > 0) return 0; // iterate TT permutations for tied variables for ( k = 0; k < 5; k++ ) @@ -1220,7 +1321,7 @@ unsigned Abc_TtCanonicizeHie( Abc_TtHieMan_t * p, word * pTruthInit, int nVars, break; } // check cache - if (Abc_TtHieRetrieveOrInsert(p, 3, pTruth, pTruthInit) > 0) return 0; + if (Abc_TtHieRetrieveOrInsert(p, 3, pTruth, pTruthInit) > 0) return 0; // perform exact NPN using groups if ( fExact ) { @@ -1262,7 +1363,7 @@ unsigned Abc_TtCanonicizeHie( Abc_TtHieMan_t * p, word * pTruthInit, int nVars, } } // update cache - Abc_TtHieRetrieveOrInsert(p, 4, pTruth, pTruthInit); + Abc_TtHieRetrieveOrInsert(p, 4, pTruth, pTruthInit); return 0; } @@ -1281,26 +1382,26 @@ SeeAlso [] typedef struct TiedGroup_ { - char iStart; // index of Abc_TgMan_t::pPerm - char nGVars; // the number of variables in the group - char fPhased; // if the phases of the variables are determined + char iStart; // index of Abc_TgMan_t::pPerm + char nGVars; // the number of variables in the group + char fPhased; // if the phases of the variables are determined } TiedGroup; typedef struct Abc_TgMan_t_ { - word *pTruth; - int nVars; // the number of variables - int nGVars; // the number of variables in groups ( symmetric variables purged ) - int nGroups; // the number of tied groups - unsigned uPhase; // phase of each variable and the function - char pPerm[16]; // permutation of variables, symmetric variables purged, for grouping - char pPermT[16]; // permutation of variables, symmetric variables expanded, actual transformation for pTruth - char pPermTRev[16]; // reverse permutation of pPermT - signed char pPermDir[16]; // for generating the next permutation - TiedGroup pGroup[16]; // tied groups - // symemtric group attributes - char symPhase[16]; // phase type of symemtric groups - signed char symLink[17]; // singly linked list, indicate the variables in symemtric groups + word *pTruth; + int nVars; // the number of variables + int nGVars; // the number of variables in groups ( symmetric variables purged ) + int nGroups; // the number of tied groups + unsigned uPhase; // phase of each variable and the function + char pPerm[16]; // permutation of variables, symmetric variables purged, for grouping + char pPermT[16]; // permutation of variables, symmetric variables expanded, actual transformation for pTruth + char pPermTRev[16]; // reverse permutation of pPermT + signed char pPermDir[16]; // for generating the next permutation + TiedGroup pGroup[16]; // tied groups + // symemtric group attributes + char symPhase[16]; // phase type of symemtric groups + signed char symLink[17]; // singly linked list, indicate the variables in symemtric groups } Abc_TgMan_t; #if !defined(NDEBUG) && !defined(CANON_VERIFY) @@ -1321,59 +1422,58 @@ SeeAlso [] // Johnson¨CTrotter algorithm static int Abc_NextPermSwapC(char * pData, signed char * pDir, int size) { - int i, j, k = -1; - for (i = 0; i < size; i++) - { - j = i + pDir[i]; - if (j >= 0 && j < size && pData[i] > pData[j] && (k < 0 || pData[i] > pData[k])) - k = i; - } - if (k < 0) k = 0; - - for (i = 0; i < size; i++) - if (pData[i] > pData[k]) - pDir[i] = -pDir[i]; - - j = k + pDir[k]; - return j < k ? j : k; + int i, j, k = -1; + for (i = 0; i < size; i++) + { + j = i + pDir[i]; + if (j >= 0 && j < size && pData[i] > pData[j] && (k < 0 || pData[i] > pData[k])) + k = i; + } + if (k < 0) k = 0; + + for (i = 0; i < size; i++) + if (pData[i] > pData[k]) + pDir[i] = -pDir[i]; + + j = k + pDir[k]; + return j < k ? j : k; } -typedef unsigned(*TtCanonicizeFunc)(Abc_TtHieMan_t * p, word * pTruth, int nVars, char * pCanonPerm, int flag); unsigned Abc_TtCanonicizeWrap(TtCanonicizeFunc func, Abc_TtHieMan_t * p, word * pTruth, int nVars, char * pCanonPerm, int flag) { - int nWords = Abc_TtWordNum(nVars); - unsigned uCanonPhase1, uCanonPhase2; - char pCanonPerm2[16]; - static word pTruth2[1024]; - - if (Abc_TtCountOnesInTruth(pTruth, nVars) != (1 << (nVars - 1))) - return func(p, pTruth, nVars, pCanonPerm, flag); - Abc_TtCopy(pTruth2, pTruth, nWords, 1); - Abc_TtNormalizeSmallTruth(pTruth2, nVars); - uCanonPhase1 = func(p, pTruth, nVars, pCanonPerm, flag); - uCanonPhase2 = func(p, pTruth2, nVars, pCanonPerm2, flag); - if (Abc_TtCompareRev(pTruth, pTruth2, nWords) <= 0) - return uCanonPhase1; - Abc_TtCopy(pTruth, pTruth2, nWords, 0); - memcpy(pCanonPerm, pCanonPerm2, nVars); - return uCanonPhase2; + int nWords = Abc_TtWordNum(nVars); + unsigned uCanonPhase1, uCanonPhase2; + char pCanonPerm2[16]; + static word pTruth2[1024]; + + Abc_TtNormalizeSmallTruth(pTruth, nVars); + if (Abc_TtCountOnesInTruth(pTruth, nVars) != nWords * 32) + return func(p, pTruth, nVars, pCanonPerm, flag); + Abc_TtCopy(pTruth2, pTruth, nWords, 1); + uCanonPhase1 = func(p, pTruth, nVars, pCanonPerm, flag); + uCanonPhase2 = func(p, pTruth2, nVars, pCanonPerm2, flag); + if (Abc_TtCompareRev(pTruth, pTruth2, nWords) <= 0) + return uCanonPhase1; + Abc_TtCopy(pTruth, pTruth2, nWords, 0); + memcpy(pCanonPerm, pCanonPerm2, nVars); + return uCanonPhase2; } word gpVerCopy[1024]; static int Abc_TtCannonVerify(word* pTruth, int nVars, char * pCanonPerm, unsigned uCanonPhase) { #ifdef CANON_VERIFY - int nWords = Abc_TtWordNum(nVars); - char pCanonPermCopy[16]; - static word pCopy2[1024]; - Abc_TtCopy(pCopy2, pTruth, nWords, 0); - memcpy(pCanonPermCopy, pCanonPerm, sizeof(char) * nVars); - Abc_TtImplementNpnConfig(pCopy2, nVars, pCanonPermCopy, uCanonPhase); - Abc_TtNormalizeSmallTruth(pCopy2, nVars); - return Abc_TtEqual(gpVerCopy, pCopy2, nWords); + int nWords = Abc_TtWordNum(nVars); + char pCanonPermCopy[16]; + static word pCopy2[1024]; + Abc_TtVerifySmallTruth(pTruth, nVars); + Abc_TtCopy(pCopy2, pTruth, nWords, 0); + memcpy(pCanonPermCopy, pCanonPerm, sizeof(char) * nVars); + Abc_TtImplementNpnConfig(pCopy2, nVars, pCanonPermCopy, uCanonPhase); + return Abc_TtEqual(gpVerCopy, pCopy2, nWords); #else - return 1; + return 1; #endif } @@ -1391,44 +1491,44 @@ SeeAlso [] static void Abc_TginitMan(Abc_TgMan_t * pMan, word * pTruth, int nVars) { - int i; - pMan->pTruth = pTruth; - pMan->nVars = pMan->nGVars = nVars; - pMan->uPhase = 0; - for (i = 0; i < nVars; i++) - { - pMan->pPerm[i] = i; - pMan->pPermT[i] = i; - pMan->pPermTRev[i] = i; - pMan->symPhase[i] = 1; - } + int i; + pMan->pTruth = pTruth; + pMan->nVars = pMan->nGVars = nVars; + pMan->uPhase = 0; + for (i = 0; i < nVars; i++) + { + pMan->pPerm[i] = i; + pMan->pPermT[i] = i; + pMan->pPermTRev[i] = i; + pMan->symPhase[i] = 1; + } } static inline void Abc_TgManCopy(Abc_TgMan_t* pDst, word* pDstTruth, Abc_TgMan_t* pSrc) { - *pDst = *pSrc; - Abc_TtCopy(pDstTruth, pSrc->pTruth, Abc_TtWordNum(pSrc->nVars), 0); - pDst->pTruth = pDstTruth; + *pDst = *pSrc; + Abc_TtCopy(pDstTruth, pSrc->pTruth, Abc_TtWordNum(pSrc->nVars), 0); + pDst->pTruth = pDstTruth; } static inline int Abc_TgCannonVerify(Abc_TgMan_t* pMan) { - return Abc_TtCannonVerify(pMan->pTruth, pMan->nVars, pMan->pPermT, pMan->uPhase); + return Abc_TtCannonVerify(pMan->pTruth, pMan->nVars, pMan->pPermT, pMan->uPhase); } void Abc_TgExpendSymmetry(Abc_TgMan_t * pMan, char * pPerm, char * pDest); static void CheckConfig(Abc_TgMan_t * pMan) { #ifndef NDEBUG - int i; - char pPermE[16]; - Abc_TgExpendSymmetry(pMan, pMan->pPerm, pPermE); - for (i = 0; i < pMan->nVars; i++) - { - assert(pPermE[i] == pMan->pPermT[i]); - assert(pMan->pPermTRev[pMan->pPermT[i]] == i); - } - assert(Abc_TgCannonVerify(pMan)); + int i; + char pPermE[16]; + Abc_TgExpendSymmetry(pMan, pMan->pPerm, pPermE); + for (i = 0; i < pMan->nVars; i++) + { + assert(pPermE[i] == pMan->pPermT[i]); + assert(pMan->pPermTRev[(int)pMan->pPermT[i]] == i); + } + assert(Abc_TgCannonVerify(pMan)); #endif } @@ -1446,84 +1546,84 @@ SeeAlso [] static inline void Abc_TgFlipVar(Abc_TgMan_t* pMan, int iVar) { - int nWords = Abc_TtWordNum(pMan->nVars); - int ivp = pMan->pPermTRev[iVar]; - Abc_TtFlip(pMan->pTruth, nWords, ivp); - pMan->uPhase ^= 1 << ivp; + int nWords = Abc_TtWordNum(pMan->nVars); + int ivp = pMan->pPermTRev[iVar]; + Abc_TtFlip(pMan->pTruth, nWords, ivp); + pMan->uPhase ^= 1 << ivp; } static inline void Abc_TgFlipSymGroupByVar(Abc_TgMan_t* pMan, int iVar) { - for (; iVar >= 0; iVar = pMan->symLink[iVar]) - if (pMan->symPhase[iVar]) - Abc_TgFlipVar(pMan, iVar); + for (; iVar >= 0; iVar = pMan->symLink[iVar]) + if (pMan->symPhase[iVar]) + Abc_TgFlipVar(pMan, iVar); } static inline void Abc_TgFlipSymGroup(Abc_TgMan_t* pMan, int idx) { - Abc_TgFlipSymGroupByVar(pMan, pMan->pPerm[idx]); + Abc_TgFlipSymGroupByVar(pMan, pMan->pPerm[idx]); } static inline void Abc_TgClearSymGroupPhase(Abc_TgMan_t* pMan, int iVar) { - for (; iVar >= 0; iVar = pMan->symLink[iVar]) - pMan->symPhase[iVar] = 0; + for (; iVar >= 0; iVar = pMan->symLink[iVar]) + pMan->symPhase[iVar] = 0; } static void Abc_TgImplementPerm(Abc_TgMan_t* pMan, const char *pPermDest) { - int i, nVars = pMan->nVars; - char *pPerm = pMan->pPermT; - char *pRev = pMan->pPermTRev; - unsigned uPhase = pMan->uPhase & (1 << nVars); - - for (i = 0; i < nVars; i++) - pRev[pPerm[i]] = i; - for (i = 0; i < nVars; i++) - pPerm[i] = pRev[pPermDest[i]]; - for (i = 0; i < nVars; i++) - pRev[pPerm[i]] = i; - - Abc_TtImplementNpnConfig(pMan->pTruth, nVars, pRev, 0); - Abc_TtNormalizeSmallTruth(pMan->pTruth, nVars); - - for (i = 0; i < nVars; i++) - { - if (pMan->uPhase & (1 << pPerm[i])) - uPhase |= (1 << i); - pPerm[i] = pPermDest[i]; - pRev[pPerm[i]] = i; - } - pMan->uPhase = uPhase; + int i, nVars = pMan->nVars; + char *pPerm = pMan->pPermT; + char *pRev = pMan->pPermTRev; + unsigned uPhase = pMan->uPhase & (1 << nVars); + + for (i = 0; i < nVars; i++) + pRev[(int)pPerm[i]] = i; + for (i = 0; i < nVars; i++) + pPerm[i] = pRev[(int)pPermDest[i]]; + for (i = 0; i < nVars; i++) + pRev[(int)pPerm[i]] = i; + + Abc_TtImplementNpnConfig(pMan->pTruth, nVars, pRev, 0); +// Abc_TtVerifySmallTruth(pMan->pTruth, nVars); + + for (i = 0; i < nVars; i++) + { + if (pMan->uPhase & (1 << pPerm[i])) + uPhase |= (1 << i); + pPerm[i] = pPermDest[i]; + pRev[(int)pPerm[i]] = i; + } + pMan->uPhase = uPhase; } static void Abc_TgSwapAdjacentSymGroups(Abc_TgMan_t* pMan, int idx) { - int iVar, jVar, ix; - char pPermNew[16]; - assert(idx < pMan->nGVars - 1); - iVar = pMan->pPerm[idx]; - jVar = pMan->pPerm[idx + 1]; - pMan->pPerm[idx] = jVar; - pMan->pPerm[idx + 1] = iVar; - ABC_SWAP(char, pMan->pPermDir[idx], pMan->pPermDir[idx + 1]); - if (pMan->symLink[iVar] >= 0 || pMan->symLink[jVar] >= 0) - { - Abc_TgExpendSymmetry(pMan, pMan->pPerm, pPermNew); - Abc_TgImplementPerm(pMan, pPermNew); - return; - } - // plain variable swap - ix = pMan->pPermTRev[iVar]; - assert(pMan->pPermT[ix] == iVar && pMan->pPermT[ix + 1] == jVar); - Abc_TtSwapAdjacent(pMan->pTruth, Abc_TtWordNum(pMan->nVars), ix); - pMan->pPermT[ix] = jVar; - pMan->pPermT[ix + 1] = iVar; - pMan->pPermTRev[iVar] = ix + 1; - pMan->pPermTRev[jVar] = ix; - if (((pMan->uPhase >> ix) & 1) != ((pMan->uPhase >> (ix + 1)) & 1)) - pMan->uPhase ^= 1 << ix | 1 << (ix + 1); - assert(Abc_TgCannonVerify(pMan)); + int iVar, jVar, ix; + char pPermNew[16]; + assert(idx < pMan->nGVars - 1); + iVar = pMan->pPerm[idx]; + jVar = pMan->pPerm[idx + 1]; + pMan->pPerm[idx] = jVar; + pMan->pPerm[idx + 1] = iVar; + ABC_SWAP(char, pMan->pPermDir[idx], pMan->pPermDir[idx + 1]); + if (pMan->symLink[iVar] >= 0 || pMan->symLink[jVar] >= 0) + { + Abc_TgExpendSymmetry(pMan, pMan->pPerm, pPermNew); + Abc_TgImplementPerm(pMan, pPermNew); + return; + } + // plain variable swap + ix = pMan->pPermTRev[iVar]; + assert(pMan->pPermT[ix] == iVar && pMan->pPermT[ix + 1] == jVar); + Abc_TtSwapAdjacent(pMan->pTruth, Abc_TtWordNum(pMan->nVars), ix); + pMan->pPermT[ix] = jVar; + pMan->pPermT[ix + 1] = iVar; + pMan->pPermTRev[iVar] = ix + 1; + pMan->pPermTRev[jVar] = ix; + if (((pMan->uPhase >> ix) & 1) != ((pMan->uPhase >> (ix + 1)) & 1)) + pMan->uPhase ^= 1 << ix | 1 << (ix + 1); + assert(Abc_TgCannonVerify(pMan)); } /**Function************************************************************* @@ -1542,33 +1642,33 @@ static word pSymCopy[1024]; static int Abc_TtIsSymmetric(word * pTruth, int nVars, int iVar, int jVar, int fPhase) { - int rv; - int nWords = Abc_TtWordNum(nVars); - Abc_TtCopy(pSymCopy, pTruth, nWords, 0); - Abc_TtSwapVars(pSymCopy, nVars, iVar, jVar); - rv = Abc_TtEqual(pTruth, pSymCopy, nWords) * 2; - if (!fPhase) return rv; - Abc_TtFlip(pSymCopy, nWords, iVar); - Abc_TtFlip(pSymCopy, nWords, jVar); - return rv + Abc_TtEqual(pTruth, pSymCopy, nWords); + int rv; + int nWords = Abc_TtWordNum(nVars); + Abc_TtCopy(pSymCopy, pTruth, nWords, 0); + Abc_TtSwapVars(pSymCopy, nVars, iVar, jVar); + rv = Abc_TtEqual(pTruth, pSymCopy, nWords) * 2; + if (!fPhase) return rv; + Abc_TtFlip(pSymCopy, nWords, iVar); + Abc_TtFlip(pSymCopy, nWords, jVar); + return rv + Abc_TtEqual(pTruth, pSymCopy, nWords); } static int Abc_TtIsSymmetricHigh(Abc_TgMan_t * pMan, int iVar, int jVar, int fPhase) { - int rv, iv, jv, n; - int nWords = Abc_TtWordNum(pMan->nVars); - Abc_TtCopy(pSymCopy, pMan->pTruth, nWords, 0); - for (n = 0, iv = iVar, jv = jVar; iv >= 0 && jv >= 0; iv = pMan->symLink[iv], jv = pMan->symLink[jv], n++) - Abc_TtSwapVars(pSymCopy, pMan->nVars, iv, jv); - assert(iv < 0 && jv < 0); // two symmetric groups must have the same size - rv = Abc_TtEqual(pMan->pTruth, pSymCopy, nWords) * 2; - if (!fPhase) return rv; - for (iv = iVar, jv = jVar; iv >= 0 && jv >= 0; iv = pMan->symLink[iv], jv = pMan->symLink[jv]) - { - if (pMan->symPhase[iv]) Abc_TtFlip(pSymCopy, nWords, iv); - if (pMan->symPhase[jv]) Abc_TtFlip(pSymCopy, nWords, jv); - } - return rv + Abc_TtEqual(pMan->pTruth, pSymCopy, nWords); + int rv, iv, jv, n; + int nWords = Abc_TtWordNum(pMan->nVars); + Abc_TtCopy(pSymCopy, pMan->pTruth, nWords, 0); + for (n = 0, iv = iVar, jv = jVar; iv >= 0 && jv >= 0; iv = pMan->symLink[iv], jv = pMan->symLink[jv], n++) + Abc_TtSwapVars(pSymCopy, pMan->nVars, iv, jv); + assert(iv < 0 && jv < 0); // two symmetric groups must have the same size + rv = Abc_TtEqual(pMan->pTruth, pSymCopy, nWords) * 2; + if (!fPhase) return rv; + for (iv = iVar, jv = jVar; iv >= 0 && jv >= 0; iv = pMan->symLink[iv], jv = pMan->symLink[jv]) + { + if (pMan->symPhase[iv]) Abc_TtFlip(pSymCopy, nWords, iv); + if (pMan->symPhase[jv]) Abc_TtFlip(pSymCopy, nWords, jv); + } + return rv + Abc_TtEqual(pMan->pTruth, pSymCopy, nWords); } /**Function************************************************************* @@ -1577,7 +1677,7 @@ Synopsis [Create groups by cofactor signatures] Description [Similar to Abc_TtSemiCanonicize. Use stable insertion sort to keep the order of the variables in the groups. - Defer permutation. ] + Defer permutation. ] SideEffects [] @@ -1587,53 +1687,53 @@ SeeAlso [] static void Abc_TgCreateGroups(Abc_TgMan_t * pMan) { - int pStore[17]; - int i, j, nOnes; - int nVars = pMan->nVars, nWords = Abc_TtWordNum(nVars); - TiedGroup * pGrp = pMan->pGroup; - assert(nVars <= 16); - // normalize polarity - nOnes = Abc_TtCountOnesInTruth(pMan->pTruth, nVars); - if (nOnes > (1 << (nVars - 1))) - { - Abc_TtNot(pMan->pTruth, nWords); - nOnes = (1 << nVars) - nOnes; - pMan->uPhase |= (1 << nVars); - } - // normalize phase - Abc_TtCountOnesInCofs(pMan->pTruth, nVars, pStore); - pStore[nVars] = nOnes; - for (i = 0; i < nVars; i++) - { - if (pStore[i] >= nOnes - pStore[i]) - continue; - Abc_TtFlip(pMan->pTruth, nWords, i); - pMan->uPhase |= (1 << i); - pStore[i] = nOnes - pStore[i]; - } - - // sort variables - for (i = 1; i < nVars; i++) - { - int a = pStore[i]; char aa = pMan->pPerm[i]; - for (j = i; j > 0 && pStore[j - 1] > a; j--) - pStore[j] = pStore[j - 1], pMan->pPerm[j] = pMan->pPerm[j - 1]; - pStore[j] = a; pMan->pPerm[j] = aa; - } - // group variables -// Abc_SortIdxC(pStore, pMan->pPerm, nVars); - pGrp[0].iStart = 0; - pGrp[0].fPhased = pStore[0] * 2 != nOnes; - for (i = j = 1; i < nVars; i++) - { - if (pStore[i] == pStore[i - 1]) continue; - pGrp[j].iStart = i; - pGrp[j].fPhased = pStore[i] * 2 != nOnes; - pGrp[j - 1].nGVars = i - pGrp[j - 1].iStart; - j++; - } - pGrp[j - 1].nGVars = i - pGrp[j - 1].iStart; - pMan->nGroups = j; + int pStore[17]; + int i, j, nOnes; + int nVars = pMan->nVars, nWords = Abc_TtWordNum(nVars); + TiedGroup * pGrp = pMan->pGroup; + assert(nVars <= 16); + // normalize polarity + nOnes = Abc_TtCountOnesInTruth(pMan->pTruth, nVars); + if (nOnes > nWords * 32) + { + Abc_TtNot(pMan->pTruth, nWords); + nOnes = nWords * 64 - nOnes; + pMan->uPhase |= (1 << nVars); + } + // normalize phase + Abc_TtCountOnesInCofs(pMan->pTruth, nVars, pStore); + pStore[nVars] = nOnes; + for (i = 0; i < nVars; i++) + { + if (pStore[i] >= nOnes - pStore[i]) + continue; + Abc_TtFlip(pMan->pTruth, nWords, i); + pMan->uPhase |= (1 << i); + pStore[i] = nOnes - pStore[i]; + } + + // sort variables + for (i = 1; i < nVars; i++) + { + int a = pStore[i]; char aa = pMan->pPerm[i]; + for (j = i; j > 0 && pStore[j - 1] > a; j--) + pStore[j] = pStore[j - 1], pMan->pPerm[j] = pMan->pPerm[j - 1]; + pStore[j] = a; pMan->pPerm[j] = aa; + } + // group variables +// Abc_SortIdxC(pStore, pMan->pPerm, nVars); + pGrp[0].iStart = 0; + pGrp[0].fPhased = pStore[0] * 2 != nOnes; + for (i = j = 1; i < nVars; i++) + { + if (pStore[i] == pStore[i - 1]) continue; + pGrp[j].iStart = i; + pGrp[j].fPhased = pStore[i] * 2 != nOnes; + pGrp[j - 1].nGVars = i - pGrp[j - 1].iStart; + j++; + } + pGrp[j - 1].nGVars = i - pGrp[j - 1].iStart; + pMan->nGroups = j; } /**Function************************************************************* @@ -1650,135 +1750,135 @@ SeeAlso [] static int Abc_TgGroupSymmetry(Abc_TgMan_t * pMan, TiedGroup * pGrp, int doHigh) { - int i, j, iVar, jVar, nsym = 0; - int fDone[16], scnt[16], stype[16]; - signed char *symLink = pMan->symLink; -// char * symPhase = pMan->symPhase; - int nGVars = pGrp->nGVars; - char * pVars = pMan->pPerm + pGrp->iStart; - int modified, order = 0; - - for (i = 0; i < nGVars; i++) - fDone[i] = 0, scnt[i] = 1; - - do { - modified = 0; - for (i = 0; i < nGVars - 1; i++) - { - iVar = pVars[i]; - if (iVar < 0 || fDone[i]) continue; -// if (!pGrp->fPhased && !Abc_TtHasVar(pMan->pTruth, pMan->nVars, iVar)) continue; - // Mark symmetric variables/groups - for (j = i + 1; j < nGVars; j++) - { - jVar = pVars[j]; - if (jVar < 0 || scnt[j] != scnt[i]) // || pMan->symPhase[jVar] != pMan->symPhase[iVar]) - stype[j] = 0; - else if (scnt[j] == 1) - stype[j] = Abc_TtIsSymmetric(pMan->pTruth, pMan->nVars, iVar, jVar, !pGrp->fPhased); - else - stype[j] = Abc_TtIsSymmetricHigh(pMan, iVar, jVar, !pGrp->fPhased); - } - fDone[i] = 1; - // Merge symmetric groups - for (j = i + 1; j < nGVars; j++) - { - int ii; - jVar = pVars[j]; - switch (stype[j]) - { - case 1: // E-Symmetry - Abc_TgFlipSymGroupByVar(pMan, jVar); - // fallthrough - case 2: // NE-Symmetry - pMan->symPhase[iVar] += pMan->symPhase[jVar]; - break; - case 3: // multiform Symmetry - Abc_TgClearSymGroupPhase(pMan, jVar); - break; - default: // case 0: No Symmetry - continue; - } - - for (ii = iVar; symLink[ii] >= 0; ii = symLink[ii]) - ; - symLink[ii] = jVar; - pVars[j] = -1; - scnt[i] += scnt[j]; - modified = 1; - fDone[i] = 0; - nsym++; - } - } -// if (++order > 3) printf("%d", order); - } while (doHigh && modified); - - return nsym; + int i, j, iVar, jVar, nsym = 0; + int fDone[16], scnt[16], stype[16]; + signed char *symLink = pMan->symLink; +// char * symPhase = pMan->symPhase; + int nGVars = pGrp->nGVars; + char * pVars = pMan->pPerm + pGrp->iStart; + int modified; + + for (i = 0; i < nGVars; i++) + fDone[i] = 0, scnt[i] = 1; + + do { + modified = 0; + for (i = 0; i < nGVars - 1; i++) + { + iVar = pVars[i]; + if (iVar < 0 || fDone[i]) continue; +// if (!pGrp->fPhased && !Abc_TtHasVar(pMan->pTruth, pMan->nVars, iVar)) continue; + // Mark symmetric variables/groups + for (j = i + 1; j < nGVars; j++) + { + jVar = pVars[j]; + if (jVar < 0 || scnt[j] != scnt[i]) // || pMan->symPhase[jVar] != pMan->symPhase[iVar]) + stype[j] = 0; + else if (scnt[j] == 1) + stype[j] = Abc_TtIsSymmetric(pMan->pTruth, pMan->nVars, iVar, jVar, !pGrp->fPhased); + else + stype[j] = Abc_TtIsSymmetricHigh(pMan, iVar, jVar, !pGrp->fPhased); + } + fDone[i] = 1; + // Merge symmetric groups + for (j = i + 1; j < nGVars; j++) + { + int ii; + jVar = pVars[j]; + switch (stype[j]) + { + case 1: // E-Symmetry + Abc_TgFlipSymGroupByVar(pMan, jVar); + // fallthrough + case 2: // NE-Symmetry + pMan->symPhase[iVar] += pMan->symPhase[jVar]; + break; + case 3: // multiform Symmetry + Abc_TgClearSymGroupPhase(pMan, jVar); + break; + default: // case 0: No Symmetry + continue; + } + + for (ii = iVar; symLink[ii] >= 0; ii = symLink[ii]) + ; + symLink[ii] = jVar; + pVars[j] = -1; + scnt[i] += scnt[j]; + modified = 1; + fDone[i] = 0; + nsym++; + } + } +// if (++order > 3) printf("%d", order); + } while (doHigh && modified); + + return nsym; } static void Abc_TgPurgeSymmetry(Abc_TgMan_t * pMan, int doHigh) { - int i, j, k, sum = 0, nVars = pMan->nVars; - signed char *symLink = pMan->symLink; - char gcnt[16] = { 0 }; - char * pPerm = pMan->pPerm; - - for (i = 0; i <= nVars; i++) - symLink[i] = -1; - - // purge unsupported variables - if (!pMan->pGroup[0].fPhased) - { - int iVar = pMan->nVars; - for (j = 0; j < pMan->pGroup[0].nGVars; j++) - { - int jVar = pPerm[j]; - assert(jVar >= 0); - if (!Abc_TtHasVar(pMan->pTruth, nVars, jVar)) - { - symLink[jVar] = symLink[iVar]; - symLink[iVar] = jVar; - pPerm[j] = -1; - gcnt[0]++; - } - } - } - - for (k = 0; k < pMan->nGroups; k++) - gcnt[k] += Abc_TgGroupSymmetry(pMan, pMan->pGroup + k, doHigh); - - for (i = 0; i < nVars && pPerm[i] >= 0; i++) - ; - for (j = i + 1; ; i++, j++) - { - while (j < nVars && pPerm[j] < 0) j++; - if (j >= nVars) break; - pPerm[i] = pPerm[j]; - } - for (k = 0; k < pMan->nGroups; k++) - { - pMan->pGroup[k].nGVars -= gcnt[k]; - pMan->pGroup[k].iStart -= sum; - sum += gcnt[k]; - } - if (pMan->pGroup[0].nGVars == 0) - { - pMan->nGroups--; - memmove(pMan->pGroup, pMan->pGroup + 1, sizeof(TiedGroup) * pMan->nGroups); - assert(pMan->pGroup[0].iStart == 0); - } - pMan->nGVars -= sum; + int i, j, k, sum = 0, nVars = pMan->nVars; + signed char *symLink = pMan->symLink; + char gcnt[16] = { 0 }; + char * pPerm = pMan->pPerm; + + for (i = 0; i <= nVars; i++) + symLink[i] = -1; + + // purge unsupported variables + if (!pMan->pGroup[0].fPhased) + { + int iVar = pMan->nVars; + for (j = 0; j < pMan->pGroup[0].nGVars; j++) + { + int jVar = pPerm[j]; + assert(jVar >= 0); + if (!Abc_TtHasVar(pMan->pTruth, nVars, jVar)) + { + symLink[jVar] = symLink[iVar]; + symLink[iVar] = jVar; + pPerm[j] = -1; + gcnt[0]++; + } + } + } + + for (k = 0; k < pMan->nGroups; k++) + gcnt[k] += Abc_TgGroupSymmetry(pMan, pMan->pGroup + k, doHigh); + + for (i = 0; i < nVars && pPerm[i] >= 0; i++) + ; + for (j = i + 1; ; i++, j++) + { + while (j < nVars && pPerm[j] < 0) j++; + if (j >= nVars) break; + pPerm[i] = pPerm[j]; + } + for (k = 0; k < pMan->nGroups; k++) + { + pMan->pGroup[k].nGVars -= gcnt[k]; + pMan->pGroup[k].iStart -= sum; + sum += gcnt[k]; + } + if (pMan->pGroup[0].nGVars == 0) + { + pMan->nGroups--; + memmove(pMan->pGroup, pMan->pGroup + 1, sizeof(TiedGroup) * pMan->nGroups); + assert(pMan->pGroup[0].iStart == 0); + } + pMan->nGVars -= sum; } void Abc_TgExpendSymmetry(Abc_TgMan_t * pMan, char * pPerm, char * pDest) { - int i = 0, j, k; - for (j = 0; j < pMan->nGVars; j++) - for (k = pPerm[j]; k >= 0; k = pMan->symLink[k]) - pDest[i++] = k; - for (k = pMan->symLink[pMan->nVars]; k >= 0; k = pMan->symLink[k]) - pDest[i++] = k; - assert(i == pMan->nVars); + int i = 0, j, k; + for (j = 0; j < pMan->nGVars; j++) + for (k = pPerm[j]; k >= 0; k = pMan->symLink[k]) + pDest[i++] = k; + for (k = pMan->symLink[pMan->nVars]; k >= 0; k = pMan->symLink[k]) + pDest[i++] = k; + assert(i == pMan->nVars); } @@ -1795,130 +1895,130 @@ SeeAlso [] ***********************************************************************/ static int Abc_TgSymGroupPerm(Abc_TgMan_t* pMan, int idx, TiedGroup* pTGrp) { - word* pTruth = pMan->pTruth; - static word pCopy[1024]; - static word pBest[1024]; - int Config = 0; - int nWords = Abc_TtWordNum(pMan->nVars); - Abc_TgMan_t tgManCopy, tgManBest; - int fSwapOnly = pTGrp->fPhased; - - CheckConfig(pMan); - if (fSwapOnly) - { - Abc_TgManCopy(&tgManCopy, pCopy, pMan); - Abc_TgSwapAdjacentSymGroups(&tgManCopy, idx); - CheckConfig(&tgManCopy); - if (Abc_TtCompareRev(pTruth, pCopy, nWords) < 0) - { - Abc_TgManCopy(pMan, pTruth, &tgManCopy); - return 4; - } - return 0; - } - - // save two copies - Abc_TgManCopy(&tgManCopy, pCopy, pMan); - Abc_TgManCopy(&tgManBest, pBest, pMan); - // PXY - // 001 - Abc_TgFlipSymGroup(&tgManCopy, idx); - CheckConfig(&tgManCopy); - if (Abc_TtCompareRev(pBest, pCopy, nWords) == 1) - Abc_TgManCopy(&tgManBest, pBest, &tgManCopy), Config = 1; - // PXY - // 011 - Abc_TgFlipSymGroup(&tgManCopy, idx + 1); - CheckConfig(&tgManCopy); - if (Abc_TtCompareRev(pBest, pCopy, nWords) == 1) - Abc_TgManCopy(&tgManBest, pBest, &tgManCopy), Config = 3; - // PXY - // 010 - Abc_TgFlipSymGroup(&tgManCopy, idx); - CheckConfig(&tgManCopy); - if (Abc_TtCompareRev(pBest, pCopy, nWords) == 1) - Abc_TgManCopy(&tgManBest, pBest, &tgManCopy), Config = 2; - // PXY - // 110 - Abc_TgSwapAdjacentSymGroups(&tgManCopy, idx); - CheckConfig(&tgManCopy); - if (Abc_TtCompareRev(pBest, pCopy, nWords) == 1) - Abc_TgManCopy(&tgManBest, pBest, &tgManCopy), Config = 6; - // PXY - // 111 - Abc_TgFlipSymGroup(&tgManCopy, idx + 1); - CheckConfig(&tgManCopy); - if (Abc_TtCompareRev(pBest, pCopy, nWords) == 1) - Abc_TgManCopy(&tgManBest, pBest, &tgManCopy), Config = 7; - // PXY - // 101 - Abc_TgFlipSymGroup(&tgManCopy, idx); - CheckConfig(&tgManCopy); - if (Abc_TtCompareRev(pBest, pCopy, nWords) == 1) - Abc_TgManCopy(&tgManBest, pBest, &tgManCopy), Config = 5; - // PXY - // 100 - Abc_TgFlipSymGroup(&tgManCopy, idx + 1); - CheckConfig(&tgManCopy); - if (Abc_TtCompareRev(pBest, pCopy, nWords) == 1) - Abc_TgManCopy(&tgManBest, pBest, &tgManCopy), Config = 4; - // PXY - // 000 - Abc_TgSwapAdjacentSymGroups(&tgManCopy, idx); - CheckConfig(&tgManCopy); - assert(Abc_TtEqual(pTruth, pCopy, nWords)); - if (Config == 0) - return 0; - assert(Abc_TtCompareRev(pTruth, pBest, nWords) == 1); - Abc_TgManCopy(pMan, pTruth, &tgManBest); - return Config; + word* pTruth = pMan->pTruth; + static word pCopy[1024]; + static word pBest[1024]; + int Config = 0; + int nWords = Abc_TtWordNum(pMan->nVars); + Abc_TgMan_t tgManCopy, tgManBest; + int fSwapOnly = pTGrp->fPhased; + + CheckConfig(pMan); + if (fSwapOnly) + { + Abc_TgManCopy(&tgManCopy, pCopy, pMan); + Abc_TgSwapAdjacentSymGroups(&tgManCopy, idx); + CheckConfig(&tgManCopy); + if (Abc_TtCompareRev(pTruth, pCopy, nWords) < 0) + { + Abc_TgManCopy(pMan, pTruth, &tgManCopy); + return 4; + } + return 0; + } + + // save two copies + Abc_TgManCopy(&tgManCopy, pCopy, pMan); + Abc_TgManCopy(&tgManBest, pBest, pMan); + // PXY + // 001 + Abc_TgFlipSymGroup(&tgManCopy, idx); + CheckConfig(&tgManCopy); + if (Abc_TtCompareRev(pBest, pCopy, nWords) == 1) + Abc_TgManCopy(&tgManBest, pBest, &tgManCopy), Config = 1; + // PXY + // 011 + Abc_TgFlipSymGroup(&tgManCopy, idx + 1); + CheckConfig(&tgManCopy); + if (Abc_TtCompareRev(pBest, pCopy, nWords) == 1) + Abc_TgManCopy(&tgManBest, pBest, &tgManCopy), Config = 3; + // PXY + // 010 + Abc_TgFlipSymGroup(&tgManCopy, idx); + CheckConfig(&tgManCopy); + if (Abc_TtCompareRev(pBest, pCopy, nWords) == 1) + Abc_TgManCopy(&tgManBest, pBest, &tgManCopy), Config = 2; + // PXY + // 110 + Abc_TgSwapAdjacentSymGroups(&tgManCopy, idx); + CheckConfig(&tgManCopy); + if (Abc_TtCompareRev(pBest, pCopy, nWords) == 1) + Abc_TgManCopy(&tgManBest, pBest, &tgManCopy), Config = 6; + // PXY + // 111 + Abc_TgFlipSymGroup(&tgManCopy, idx + 1); + CheckConfig(&tgManCopy); + if (Abc_TtCompareRev(pBest, pCopy, nWords) == 1) + Abc_TgManCopy(&tgManBest, pBest, &tgManCopy), Config = 7; + // PXY + // 101 + Abc_TgFlipSymGroup(&tgManCopy, idx); + CheckConfig(&tgManCopy); + if (Abc_TtCompareRev(pBest, pCopy, nWords) == 1) + Abc_TgManCopy(&tgManBest, pBest, &tgManCopy), Config = 5; + // PXY + // 100 + Abc_TgFlipSymGroup(&tgManCopy, idx + 1); + CheckConfig(&tgManCopy); + if (Abc_TtCompareRev(pBest, pCopy, nWords) == 1) + Abc_TgManCopy(&tgManBest, pBest, &tgManCopy), Config = 4; + // PXY + // 000 + Abc_TgSwapAdjacentSymGroups(&tgManCopy, idx); + CheckConfig(&tgManCopy); + assert(Abc_TtEqual(pTruth, pCopy, nWords)); + if (Config == 0) + return 0; + assert(Abc_TtCompareRev(pTruth, pBest, nWords) == 1); + Abc_TgManCopy(pMan, pTruth, &tgManBest); + return Config; } static int Abc_TgPermPhase(Abc_TgMan_t* pMan, int iVar) { - static word pCopy[1024]; - int nWords = Abc_TtWordNum(pMan->nVars); - int ivp = pMan->pPermTRev[iVar]; - Abc_TtCopy(pCopy, pMan->pTruth, nWords, 0); - Abc_TtFlip(pCopy, nWords, ivp); - if (Abc_TtCompareRev(pMan->pTruth, pCopy, nWords) == 1) - { - Abc_TtCopy(pMan->pTruth, pCopy, nWords, 0); - pMan->uPhase ^= 1 << ivp; - return 16; - } - return 0; + static word pCopy[1024]; + int nWords = Abc_TtWordNum(pMan->nVars); + int ivp = pMan->pPermTRev[iVar]; + Abc_TtCopy(pCopy, pMan->pTruth, nWords, 0); + Abc_TtFlip(pCopy, nWords, ivp); + if (Abc_TtCompareRev(pMan->pTruth, pCopy, nWords) == 1) + { + Abc_TtCopy(pMan->pTruth, pCopy, nWords, 0); + pMan->uPhase ^= 1 << ivp; + return 16; + } + return 0; } static void Abc_TgSimpleEnumeration(Abc_TgMan_t * pMan) { - int i, j, k; - int pGid[16]; - - for (k = j = 0; j < pMan->nGroups; j++) - for (i = 0; i < pMan->pGroup[j].nGVars; i++, k++) - pGid[k] = j; - assert(k == pMan->nGVars); - - for (k = 0; k < 5; k++) - { - int fChanges = 0; - for (i = pMan->nGVars - 2; i >= 0; i--) - if (pGid[i] == pGid[i + 1]) - fChanges |= Abc_TgSymGroupPerm(pMan, i, pMan->pGroup + pGid[i]); - for (i = 1; i < pMan->nGVars - 1; i++) - if (pGid[i] == pGid[i + 1]) - fChanges |= Abc_TgSymGroupPerm(pMan, i, pMan->pGroup + pGid[i]); - - for (i = pMan->nVars - 1; i >= 0; i--) - if (pMan->symPhase[i]) - fChanges |= Abc_TgPermPhase(pMan, i); - for (i = 1; i < pMan->nVars; i++) - if (pMan->symPhase[i]) - fChanges |= Abc_TgPermPhase(pMan, i); - if (!fChanges) break; - } - assert(Abc_TgCannonVerify(pMan)); + int i, j, k; + int pGid[16]; + + for (k = j = 0; j < pMan->nGroups; j++) + for (i = 0; i < pMan->pGroup[j].nGVars; i++, k++) + pGid[k] = j; + assert(k == pMan->nGVars); + + for (k = 0; k < 5; k++) + { + int fChanges = 0; + for (i = pMan->nGVars - 2; i >= 0; i--) + if (pGid[i] == pGid[i + 1]) + fChanges |= Abc_TgSymGroupPerm(pMan, i, pMan->pGroup + pGid[i]); + for (i = 1; i < pMan->nGVars - 1; i++) + if (pGid[i] == pGid[i + 1]) + fChanges |= Abc_TgSymGroupPerm(pMan, i, pMan->pGroup + pGid[i]); + + for (i = pMan->nVars - 1; i >= 0; i--) + if (pMan->symPhase[i]) + fChanges |= Abc_TgPermPhase(pMan, i); + for (i = 1; i < pMan->nVars; i++) + if (pMan->symPhase[i]) + fChanges |= Abc_TgPermPhase(pMan, i); + if (!fChanges) break; + } + assert(Abc_TgCannonVerify(pMan)); } /**Function************************************************************* @@ -1935,194 +2035,198 @@ SeeAlso [] // enumeration time = exp((cost-27.12)*0.59) static int Abc_TgEnumerationCost(Abc_TgMan_t * pMan) { - int cSym = 0; - double cPerm = 0.0; - TiedGroup * pGrp = 0; - int i, j, n; - if (pMan->nGroups == 0) return 0; - - for (i = 0; i < pMan->nGroups; i++) - { - pGrp = pMan->pGroup + i; - n = pGrp->nGVars; - if (n > 1) - cPerm += 0.92 + log(n) / 2 + n * (log(n) - 1); - } - if (pMan->pGroup->fPhased) - n = 0; - else - { - char * pVars = pMan->pPerm; - n = pMan->pGroup->nGVars; - for (i = 0; i < n; i++) - for (j = pVars[i]; j >= 0; j = pMan->symLink[j]) - cSym++; - } - // coefficients computed by linear regression - return pMan->nVars + n * 1.09 + cPerm * 1.65 + 0.5; -// return (rv > 60 ? 100000000 : 0) + n * 1000000 + cSym * 10000 + cPerm * 100 + 0.5; + int cSym = 0; + double cPerm = 0.0; + TiedGroup * pGrp = 0; + int i, j, n; + if (pMan->nGroups == 0) return 0; + + for (i = 0; i < pMan->nGroups; i++) + { + pGrp = pMan->pGroup + i; + n = pGrp->nGVars; + if (n > 1) + cPerm += 0.92 + log(n) / 2 + n * (log(n) - 1); + } + if (pMan->pGroup->fPhased) + n = 0; + else + { + char * pVars = pMan->pPerm; + n = pMan->pGroup->nGVars; + for (i = 0; i < n; i++) + for (j = pVars[i]; j >= 0; j = pMan->symLink[j]) + cSym++; + } + // coefficients computed by linear regression + return pMan->nVars + n * 1.09 + cPerm * 1.65 + 0.5; +// return (rv > 60 ? 100000000 : 0) + n * 1000000 + cSym * 10000 + cPerm * 100 + 0.5; } static int Abc_TgIsInitPerm(char * pData, signed char * pDir, int size) { - int i; - if (pDir[0] != -1) return 0; - for (i = 1; i < size; i++) - if (pDir[i] != -1 || pData[i] < pData[i - 1]) - return 0; - return 1; + int i; + if (pDir[0] != -1) return 0; + for (i = 1; i < size; i++) + if (pDir[i] != -1 || pData[i] < pData[i - 1]) + return 0; + return 1; } static void Abc_TgFirstPermutation(Abc_TgMan_t * pMan) { - int i; - for (i = 0; i < pMan->nGVars; i++) - pMan->pPermDir[i] = -1; + int i; + for (i = 0; i < pMan->nGVars; i++) + pMan->pPermDir[i] = -1; #ifndef NDEBUG - for (i = 0; i < pMan->nGroups; i++) - { - TiedGroup * pGrp = pMan->pGroup + i; - int nGvars = pGrp->nGVars; - char * pVars = pMan->pPerm + pGrp->iStart; - signed char * pDirs = pMan->pPermDir + pGrp->iStart; - assert(Abc_TgIsInitPerm(pVars, pDirs, nGvars)); - } + for (i = 0; i < pMan->nGroups; i++) + { + TiedGroup * pGrp = pMan->pGroup + i; + int nGvars = pGrp->nGVars; + char * pVars = pMan->pPerm + pGrp->iStart; + signed char * pDirs = pMan->pPermDir + pGrp->iStart; + assert(Abc_TgIsInitPerm(pVars, pDirs, nGvars)); + } #endif } static int Abc_TgNextPermutation(Abc_TgMan_t * pMan) { - int i, j, nGvars; - TiedGroup * pGrp; - char * pVars; - signed char * pDirs; - for (i = 0; i < pMan->nGroups; i++) - { - pGrp = pMan->pGroup + i; - nGvars = pGrp->nGVars; - if (nGvars == 1) continue; - pVars = pMan->pPerm + pGrp->iStart; - pDirs = pMan->pPermDir + pGrp->iStart; - j = Abc_NextPermSwapC(pVars, pDirs, nGvars); - if (j >= 0) - { - Abc_TgSwapAdjacentSymGroups(pMan, j + pGrp->iStart); - return 1; - } - Abc_TgSwapAdjacentSymGroups(pMan, pGrp->iStart); - assert(Abc_TgIsInitPerm(pVars, pDirs, nGvars)); - } - return 0; + int i, j, nGvars; + TiedGroup * pGrp; + char * pVars; + signed char * pDirs; + for (i = 0; i < pMan->nGroups; i++) + { + pGrp = pMan->pGroup + i; + nGvars = pGrp->nGVars; + if (nGvars == 1) continue; + pVars = pMan->pPerm + pGrp->iStart; + pDirs = pMan->pPermDir + pGrp->iStart; + j = Abc_NextPermSwapC(pVars, pDirs, nGvars); + if (j >= 0) + { + Abc_TgSwapAdjacentSymGroups(pMan, j + pGrp->iStart); + return 1; + } + Abc_TgSwapAdjacentSymGroups(pMan, pGrp->iStart); + assert(Abc_TgIsInitPerm(pVars, pDirs, nGvars)); + } + return 0; } static inline unsigned grayCode(unsigned a) { return a ^ (a >> 1); } -static int grayFlip(unsigned a, int n) +static int grayFlip(unsigned a) { - unsigned d = grayCode(a) ^ grayCode(a + 1); - int i; - for (i = 0; i < n; i++) - if (d == 1U << i) return i; - assert(0); - return -1; -} + int i; + for (i = 0, a++; ; i++) + if (a & (1 << i)) return i; + } static inline void Abc_TgSaveBest(Abc_TgMan_t * pMan, Abc_TgMan_t * pBest) { - if (Abc_TtCompare(pBest->pTruth, pMan->pTruth, Abc_TtWordNum(pMan->nVars)) == 1) - Abc_TgManCopy(pBest, pBest->pTruth, pMan); + if (Abc_TtCompare(pBest->pTruth, pMan->pTruth, Abc_TtWordNum(pMan->nVars)) == 1) + Abc_TgManCopy(pBest, pBest->pTruth, pMan); } static void Abc_TgPhaseEnumeration(Abc_TgMan_t * pMan, Abc_TgMan_t * pBest) { - char pFGrps[16]; - TiedGroup * pGrp = pMan->pGroup; - int i, j, n = pGrp->nGVars; - - Abc_TgSaveBest(pMan, pBest); - if (pGrp->fPhased) return; - - // sort by symPhase - for (i = 0; i < n; i++) - { - char iv = pMan->pPerm[i]; - for (j = i; j > 0 && pMan->symPhase[pFGrps[j-1]] > pMan->symPhase[iv]; j--) - pFGrps[j] = pFGrps[j - 1]; - pFGrps[j] = iv; - } - - for (i = 0; i < (1 << n) - 1; i++) - { - Abc_TgFlipSymGroupByVar(pMan, pFGrps[grayFlip(i, n)]); - Abc_TgSaveBest(pMan, pBest); - } + char pFGrps[16]; + TiedGroup * pGrp = pMan->pGroup; + int i, j, n = pGrp->nGVars; + + Abc_TgSaveBest(pMan, pBest); + if (pGrp->fPhased) return; + + // sort by symPhase + for (i = 0; i < n; i++) + { + char iv = pMan->pPerm[i]; + for (j = i; j > 0 && pMan->symPhase[(int)pFGrps[j-1]] > pMan->symPhase[(int)iv]; j--) + pFGrps[j] = pFGrps[j - 1]; + pFGrps[j] = iv; + } + + for (i = 0; i < (1 << n) - 1; i++) + { + Abc_TgFlipSymGroupByVar(pMan, pFGrps[grayFlip(i)]); + Abc_TgSaveBest(pMan, pBest); + } } static void Abc_TgFullEnumeration(Abc_TgMan_t * pWork, Abc_TgMan_t * pBest) { -// static word pCopy[1024]; -// Abc_TgMan_t tgManCopy; -// Abc_TgManCopy(&tgManCopy, pCopy, pMan); - - Abc_TgFirstPermutation(pWork); - do Abc_TgPhaseEnumeration(pWork, pBest); - while (Abc_TgNextPermutation(pWork)); - pBest->uPhase |= 1U << 30; +// static word pCopy[1024]; +// Abc_TgMan_t tgManCopy; +// Abc_TgManCopy(&tgManCopy, pCopy, pMan); + + Abc_TgFirstPermutation(pWork); + do Abc_TgPhaseEnumeration(pWork, pBest); + while (Abc_TgNextPermutation(pWork)); + pBest->uPhase |= 1 << 30; } unsigned Abc_TtCanonicizeAda(Abc_TtHieMan_t * p, word * pTruth, int nVars, char * pCanonPerm, int iThres) { - int nWords = Abc_TtWordNum(nVars); - unsigned fExac = 0, fHash = 1U << 29; - static word pCopy[1024]; - Abc_TgMan_t tgMan, tgManCopy; - int iCost; - const int MaxCost = 84; // maximun posible cost for function with 16 inputs - const int doHigh = iThres / 100, iEnumThres = iThres % 100; + int nWords = Abc_TtWordNum(nVars); + unsigned fExac = 0, fHash = 1 << 29; + static word pCopy[1024]; + Abc_TgMan_t tgMan, tgManCopy; + int iCost; + const int MaxCost = 84; // maximun posible cost for function with 16 inputs + const int doHigh = iThres / 100, iEnumThres = iThres % 100; + + // handle constant + if ( nVars == 0 ) { + Abc_TtClear( pTruth, nWords ); + return 0; + } + Abc_TtVerifySmallTruth(pTruth, nVars); #ifdef CANON_VERIFY - Abc_TtCopy(gpVerCopy, pTruth, nWords, 0); + Abc_TtCopy(gpVerCopy, pTruth, nWords, 0); #endif - assert(nVars <= 16); - if (p && Abc_TtHieRetrieveOrInsert(p, -5, pTruth, pTruth) > 0) return fHash; - Abc_TginitMan(&tgMan, pTruth, nVars); - Abc_TgCreateGroups(&tgMan); - if (p && Abc_TtHieRetrieveOrInsert(p, -4, pTruth, pTruth) > 0) return fHash; - Abc_TgPurgeSymmetry(&tgMan, doHigh); - - Abc_TgExpendSymmetry(&tgMan, tgMan.pPerm, pCanonPerm); - Abc_TgImplementPerm(&tgMan, pCanonPerm); - assert(Abc_TgCannonVerify(&tgMan)); - - if (p == NULL) { - if (iEnumThres > MaxCost || Abc_TgEnumerationCost(&tgMan) < iEnumThres) { - Abc_TgManCopy(&tgManCopy, pCopy, &tgMan); - Abc_TgFullEnumeration(&tgManCopy, &tgMan); - } - else - Abc_TgSimpleEnumeration(&tgMan); - } - else { - iCost = Abc_TgEnumerationCost(&tgMan); - if (iCost < iEnumThres) fExac = 1U << 30; - if (Abc_TtHieRetrieveOrInsert(p, -3, pTruth, pTruth) > 0) return fHash + fExac; - Abc_TgManCopy(&tgManCopy, pCopy, &tgMan); - Abc_TgSimpleEnumeration(&tgMan); - if (Abc_TtHieRetrieveOrInsert(p, -2, pTruth, pTruth) > 0) return fHash + fExac; - if (fExac) { - Abc_TgManCopy(&tgMan, pTruth, &tgManCopy); - Abc_TgFullEnumeration(&tgManCopy, &tgMan); - } - Abc_TtHieRetrieveOrInsert(p, -1, pTruth, pTruth); - } - memcpy(pCanonPerm, tgMan.pPermT, sizeof(char) * nVars); + assert(nVars <= 16); + if (p && Abc_TtHieRetrieveOrInsert(p, -5, pTruth, pTruth) > 0) return fHash; + Abc_TginitMan(&tgMan, pTruth, nVars); + Abc_TgCreateGroups(&tgMan); + if (p && Abc_TtHieRetrieveOrInsert(p, -4, pTruth, pTruth) > 0) return fHash; + Abc_TgPurgeSymmetry(&tgMan, doHigh); + + Abc_TgExpendSymmetry(&tgMan, tgMan.pPerm, pCanonPerm); + Abc_TgImplementPerm(&tgMan, pCanonPerm); + assert(Abc_TgCannonVerify(&tgMan)); + + if (p == NULL) { + if (iEnumThres > MaxCost || Abc_TgEnumerationCost(&tgMan) < iEnumThres) { + Abc_TgManCopy(&tgManCopy, pCopy, &tgMan); + Abc_TgFullEnumeration(&tgManCopy, &tgMan); + } + else + Abc_TgSimpleEnumeration(&tgMan); + } + else { + iCost = Abc_TgEnumerationCost(&tgMan); + if (iCost < iEnumThres) fExac = 1 << 30; + if (Abc_TtHieRetrieveOrInsert(p, -3, pTruth, pTruth) > 0) return fHash + fExac; + Abc_TgManCopy(&tgManCopy, pCopy, &tgMan); + Abc_TgSimpleEnumeration(&tgMan); + if (Abc_TtHieRetrieveOrInsert(p, -2, pTruth, pTruth) > 0) return fHash + fExac; + if (fExac) { + Abc_TgManCopy(&tgMan, pTruth, &tgManCopy); + Abc_TgFullEnumeration(&tgManCopy, &tgMan); + } + Abc_TtHieRetrieveOrInsert(p, -1, pTruth, pTruth); + } + memcpy(pCanonPerm, tgMan.pPermT, sizeof(char) * nVars); #ifdef CANON_VERIFY - if (!Abc_TgCannonVerify(&tgMan)) - printf("Canonical form verification failed!\n"); + if (!Abc_TgCannonVerify(&tgMan)) + printf("Canonical form verification failed!\n"); #endif - return tgMan.uPhase; + return tgMan.uPhase; } //////////////////////////////////////////////////////////////////////// diff --git a/src/opt/dau/dauCount.c b/src/opt/dau/dauCount.c new file mode 100644 index 00000000..828c5bea --- /dev/null +++ b/src/opt/dau/dauCount.c @@ -0,0 +1,436 @@ +/**CFile**************************************************************** + + FileName [dau.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [DAG-aware unmapping.] + + Synopsis [Counting ones in the truth table.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: dau.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "dauInt.h" + +ABC_NAMESPACE_IMPL_START + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +static word Table[256][32] = //{{0}}; +{ + { ABC_CONST(0x0000000000000000), ABC_CONST(0x0000000000000000), ABC_CONST(0x0000000000000000), ABC_CONST(0x0000000000000000), ABC_CONST(0x0000000000000000), ABC_CONST(0x0000000000000000), ABC_CONST(0x0000000000000000), ABC_CONST(0x0000000000000000), ABC_CONST(0x0000000000000000), ABC_CONST(0x0000000000000000), ABC_CONST(0x0000000000000000), ABC_CONST(0x0000000000000000), ABC_CONST(0x0000000000000000), ABC_CONST(0x0000000000000000), ABC_CONST(0x0000000000000000), ABC_CONST(0x0000000000000000), ABC_CONST(0x0000000000000000), ABC_CONST(0x0000000000000000), ABC_CONST(0x0000000000000000), ABC_CONST(0x0000000000000000), ABC_CONST(0x0000000000000000), ABC_CONST(0x0000000000000000), ABC_CONST(0x0000000000000000), ABC_CONST(0x0000000000000000), ABC_CONST(0x0000000000000000), ABC_CONST(0x0000000000000000), ABC_CONST(0x0000000000000000), ABC_CONST(0x0000000000000000), ABC_CONST(0x0000000000000000), ABC_CONST(0x0000000000000000), ABC_CONST(0x0000000000000000), ABC_CONST(0x0000000000000000) }, + { ABC_CONST(0x0101010101010101), ABC_CONST(0x0101010100010101), ABC_CONST(0x0101010001010101), ABC_CONST(0x0101010000010101), ABC_CONST(0x0101000101010101), ABC_CONST(0x0101000100010101), ABC_CONST(0x0101000001010101), ABC_CONST(0x0101000000010101), ABC_CONST(0x0100010101010101), ABC_CONST(0x0100010100010101), ABC_CONST(0x0100010001010101), ABC_CONST(0x0100010000010101), ABC_CONST(0x0100000101010101), ABC_CONST(0x0100000100010101), ABC_CONST(0x0100000001010101), ABC_CONST(0x0100000000010101), ABC_CONST(0x0101010101010101), ABC_CONST(0x0101010100010101), ABC_CONST(0x0101010001010101), ABC_CONST(0x0101010000010101), ABC_CONST(0x0101000101010101), ABC_CONST(0x0101000100010101), ABC_CONST(0x0101000001010101), ABC_CONST(0x0101000000010101), ABC_CONST(0x0100010101010101), ABC_CONST(0x0100010100010101), ABC_CONST(0x0100010001010101), ABC_CONST(0x0100010000010101), ABC_CONST(0x0100000101010101), ABC_CONST(0x0100000100010101), ABC_CONST(0x0100000001010101), ABC_CONST(0x0100000000010101) }, + { ABC_CONST(0x0101010101010100), ABC_CONST(0x0101010100010100), ABC_CONST(0x0101010001010100), ABC_CONST(0x0101010000010100), ABC_CONST(0x0101000101010100), ABC_CONST(0x0101000100010100), ABC_CONST(0x0101000001010100), ABC_CONST(0x0101000000010100), ABC_CONST(0x0100010101010100), ABC_CONST(0x0100010100010100), ABC_CONST(0x0100010001010100), ABC_CONST(0x0100010000010100), ABC_CONST(0x0100000101010100), ABC_CONST(0x0100000100010100), ABC_CONST(0x0100000001010100), ABC_CONST(0x0100000000010100), ABC_CONST(0x0101010101010100), ABC_CONST(0x0101010100010100), ABC_CONST(0x0101010001010100), ABC_CONST(0x0101010000010100), ABC_CONST(0x0101000101010100), ABC_CONST(0x0101000100010100), ABC_CONST(0x0101000001010100), ABC_CONST(0x0101000000010100), ABC_CONST(0x0100010101010100), ABC_CONST(0x0100010100010100), ABC_CONST(0x0100010001010100), ABC_CONST(0x0100010000010100), ABC_CONST(0x0100000101010100), ABC_CONST(0x0100000100010100), ABC_CONST(0x0100000001010100), ABC_CONST(0x0100000000010100) }, + { ABC_CONST(0x0202020202020201), ABC_CONST(0x0202020200020201), ABC_CONST(0x0202020002020201), ABC_CONST(0x0202020000020201), ABC_CONST(0x0202000202020201), ABC_CONST(0x0202000200020201), ABC_CONST(0x0202000002020201), ABC_CONST(0x0202000000020201), ABC_CONST(0x0200020202020201), ABC_CONST(0x0200020200020201), ABC_CONST(0x0200020002020201), ABC_CONST(0x0200020000020201), ABC_CONST(0x0200000202020201), ABC_CONST(0x0200000200020201), ABC_CONST(0x0200000002020201), ABC_CONST(0x0200000000020201), ABC_CONST(0x0202020202020201), ABC_CONST(0x0202020200020201), ABC_CONST(0x0202020002020201), ABC_CONST(0x0202020000020201), ABC_CONST(0x0202000202020201), ABC_CONST(0x0202000200020201), ABC_CONST(0x0202000002020201), ABC_CONST(0x0202000000020201), ABC_CONST(0x0200020202020201), ABC_CONST(0x0200020200020201), ABC_CONST(0x0200020002020201), ABC_CONST(0x0200020000020201), ABC_CONST(0x0200000202020201), ABC_CONST(0x0200000200020201), ABC_CONST(0x0200000002020201), ABC_CONST(0x0200000000020201) }, + { ABC_CONST(0x0101010101010001), ABC_CONST(0x0101010100010001), ABC_CONST(0x0101010001010001), ABC_CONST(0x0101010000010001), ABC_CONST(0x0101000101010001), ABC_CONST(0x0101000100010001), ABC_CONST(0x0101000001010001), ABC_CONST(0x0101000000010001), ABC_CONST(0x0100010101010001), ABC_CONST(0x0100010100010001), ABC_CONST(0x0100010001010001), ABC_CONST(0x0100010000010001), ABC_CONST(0x0100000101010001), ABC_CONST(0x0100000100010001), ABC_CONST(0x0100000001010001), ABC_CONST(0x0100000000010001), ABC_CONST(0x0101010101010001), ABC_CONST(0x0101010100010001), ABC_CONST(0x0101010001010001), ABC_CONST(0x0101010000010001), ABC_CONST(0x0101000101010001), ABC_CONST(0x0101000100010001), ABC_CONST(0x0101000001010001), ABC_CONST(0x0101000000010001), ABC_CONST(0x0100010101010001), ABC_CONST(0x0100010100010001), ABC_CONST(0x0100010001010001), ABC_CONST(0x0100010000010001), ABC_CONST(0x0100000101010001), ABC_CONST(0x0100000100010001), ABC_CONST(0x0100000001010001), ABC_CONST(0x0100000000010001) }, + { ABC_CONST(0x0202020202020102), ABC_CONST(0x0202020200020102), ABC_CONST(0x0202020002020102), ABC_CONST(0x0202020000020102), ABC_CONST(0x0202000202020102), ABC_CONST(0x0202000200020102), ABC_CONST(0x0202000002020102), ABC_CONST(0x0202000000020102), ABC_CONST(0x0200020202020102), ABC_CONST(0x0200020200020102), ABC_CONST(0x0200020002020102), ABC_CONST(0x0200020000020102), ABC_CONST(0x0200000202020102), ABC_CONST(0x0200000200020102), ABC_CONST(0x0200000002020102), ABC_CONST(0x0200000000020102), ABC_CONST(0x0202020202020102), ABC_CONST(0x0202020200020102), ABC_CONST(0x0202020002020102), ABC_CONST(0x0202020000020102), ABC_CONST(0x0202000202020102), ABC_CONST(0x0202000200020102), ABC_CONST(0x0202000002020102), ABC_CONST(0x0202000000020102), ABC_CONST(0x0200020202020102), ABC_CONST(0x0200020200020102), ABC_CONST(0x0200020002020102), ABC_CONST(0x0200020000020102), ABC_CONST(0x0200000202020102), ABC_CONST(0x0200000200020102), ABC_CONST(0x0200000002020102), ABC_CONST(0x0200000000020102) }, + { ABC_CONST(0x0202020202020101), ABC_CONST(0x0202020200020101), ABC_CONST(0x0202020002020101), ABC_CONST(0x0202020000020101), ABC_CONST(0x0202000202020101), ABC_CONST(0x0202000200020101), ABC_CONST(0x0202000002020101), ABC_CONST(0x0202000000020101), ABC_CONST(0x0200020202020101), ABC_CONST(0x0200020200020101), ABC_CONST(0x0200020002020101), ABC_CONST(0x0200020000020101), ABC_CONST(0x0200000202020101), ABC_CONST(0x0200000200020101), ABC_CONST(0x0200000002020101), ABC_CONST(0x0200000000020101), ABC_CONST(0x0202020202020101), ABC_CONST(0x0202020200020101), ABC_CONST(0x0202020002020101), ABC_CONST(0x0202020000020101), ABC_CONST(0x0202000202020101), ABC_CONST(0x0202000200020101), ABC_CONST(0x0202000002020101), ABC_CONST(0x0202000000020101), ABC_CONST(0x0200020202020101), ABC_CONST(0x0200020200020101), ABC_CONST(0x0200020002020101), ABC_CONST(0x0200020000020101), ABC_CONST(0x0200000202020101), ABC_CONST(0x0200000200020101), ABC_CONST(0x0200000002020101), ABC_CONST(0x0200000000020101) }, + { ABC_CONST(0x0303030303030202), ABC_CONST(0x0303030300030202), ABC_CONST(0x0303030003030202), ABC_CONST(0x0303030000030202), ABC_CONST(0x0303000303030202), ABC_CONST(0x0303000300030202), ABC_CONST(0x0303000003030202), ABC_CONST(0x0303000000030202), ABC_CONST(0x0300030303030202), ABC_CONST(0x0300030300030202), ABC_CONST(0x0300030003030202), ABC_CONST(0x0300030000030202), ABC_CONST(0x0300000303030202), ABC_CONST(0x0300000300030202), ABC_CONST(0x0300000003030202), ABC_CONST(0x0300000000030202), ABC_CONST(0x0303030303030202), ABC_CONST(0x0303030300030202), ABC_CONST(0x0303030003030202), ABC_CONST(0x0303030000030202), ABC_CONST(0x0303000303030202), ABC_CONST(0x0303000300030202), ABC_CONST(0x0303000003030202), ABC_CONST(0x0303000000030202), ABC_CONST(0x0300030303030202), ABC_CONST(0x0300030300030202), ABC_CONST(0x0300030003030202), ABC_CONST(0x0300030000030202), ABC_CONST(0x0300000303030202), ABC_CONST(0x0300000300030202), ABC_CONST(0x0300000003030202), ABC_CONST(0x0300000000030202) }, + { ABC_CONST(0x0101010101010000), ABC_CONST(0x0101010100010000), ABC_CONST(0x0101010001010000), ABC_CONST(0x0101010000010000), ABC_CONST(0x0101000101010000), ABC_CONST(0x0101000100010000), ABC_CONST(0x0101000001010000), ABC_CONST(0x0101000000010000), ABC_CONST(0x0100010101010000), ABC_CONST(0x0100010100010000), ABC_CONST(0x0100010001010000), ABC_CONST(0x0100010000010000), ABC_CONST(0x0100000101010000), ABC_CONST(0x0100000100010000), ABC_CONST(0x0100000001010000), ABC_CONST(0x0100000000010000), ABC_CONST(0x0101010101010000), ABC_CONST(0x0101010100010000), ABC_CONST(0x0101010001010000), ABC_CONST(0x0101010000010000), ABC_CONST(0x0101000101010000), ABC_CONST(0x0101000100010000), ABC_CONST(0x0101000001010000), ABC_CONST(0x0101000000010000), ABC_CONST(0x0100010101010000), ABC_CONST(0x0100010100010000), ABC_CONST(0x0100010001010000), ABC_CONST(0x0100010000010000), ABC_CONST(0x0100000101010000), ABC_CONST(0x0100000100010000), ABC_CONST(0x0100000001010000), ABC_CONST(0x0100000000010000) }, + { ABC_CONST(0x0202020202020101), ABC_CONST(0x0202020200020101), ABC_CONST(0x0202020002020101), ABC_CONST(0x0202020000020101), ABC_CONST(0x0202000202020101), ABC_CONST(0x0202000200020101), ABC_CONST(0x0202000002020101), ABC_CONST(0x0202000000020101), ABC_CONST(0x0200020202020101), ABC_CONST(0x0200020200020101), ABC_CONST(0x0200020002020101), ABC_CONST(0x0200020000020101), ABC_CONST(0x0200000202020101), ABC_CONST(0x0200000200020101), ABC_CONST(0x0200000002020101), ABC_CONST(0x0200000000020101), ABC_CONST(0x0202020202020101), ABC_CONST(0x0202020200020101), ABC_CONST(0x0202020002020101), ABC_CONST(0x0202020000020101), ABC_CONST(0x0202000202020101), ABC_CONST(0x0202000200020101), ABC_CONST(0x0202000002020101), ABC_CONST(0x0202000000020101), ABC_CONST(0x0200020202020101), ABC_CONST(0x0200020200020101), ABC_CONST(0x0200020002020101), ABC_CONST(0x0200020000020101), ABC_CONST(0x0200000202020101), ABC_CONST(0x0200000200020101), ABC_CONST(0x0200000002020101), ABC_CONST(0x0200000000020101) }, + { ABC_CONST(0x0202020202020100), ABC_CONST(0x0202020200020100), ABC_CONST(0x0202020002020100), ABC_CONST(0x0202020000020100), ABC_CONST(0x0202000202020100), ABC_CONST(0x0202000200020100), ABC_CONST(0x0202000002020100), ABC_CONST(0x0202000000020100), ABC_CONST(0x0200020202020100), ABC_CONST(0x0200020200020100), ABC_CONST(0x0200020002020100), ABC_CONST(0x0200020000020100), ABC_CONST(0x0200000202020100), ABC_CONST(0x0200000200020100), ABC_CONST(0x0200000002020100), ABC_CONST(0x0200000000020100), ABC_CONST(0x0202020202020100), ABC_CONST(0x0202020200020100), ABC_CONST(0x0202020002020100), ABC_CONST(0x0202020000020100), ABC_CONST(0x0202000202020100), ABC_CONST(0x0202000200020100), ABC_CONST(0x0202000002020100), ABC_CONST(0x0202000000020100), ABC_CONST(0x0200020202020100), ABC_CONST(0x0200020200020100), ABC_CONST(0x0200020002020100), ABC_CONST(0x0200020000020100), ABC_CONST(0x0200000202020100), ABC_CONST(0x0200000200020100), ABC_CONST(0x0200000002020100), ABC_CONST(0x0200000000020100) }, + { ABC_CONST(0x0303030303030201), ABC_CONST(0x0303030300030201), ABC_CONST(0x0303030003030201), ABC_CONST(0x0303030000030201), ABC_CONST(0x0303000303030201), ABC_CONST(0x0303000300030201), ABC_CONST(0x0303000003030201), ABC_CONST(0x0303000000030201), ABC_CONST(0x0300030303030201), ABC_CONST(0x0300030300030201), ABC_CONST(0x0300030003030201), ABC_CONST(0x0300030000030201), ABC_CONST(0x0300000303030201), ABC_CONST(0x0300000300030201), ABC_CONST(0x0300000003030201), ABC_CONST(0x0300000000030201), ABC_CONST(0x0303030303030201), ABC_CONST(0x0303030300030201), ABC_CONST(0x0303030003030201), ABC_CONST(0x0303030000030201), ABC_CONST(0x0303000303030201), ABC_CONST(0x0303000300030201), ABC_CONST(0x0303000003030201), ABC_CONST(0x0303000000030201), ABC_CONST(0x0300030303030201), ABC_CONST(0x0300030300030201), ABC_CONST(0x0300030003030201), ABC_CONST(0x0300030000030201), ABC_CONST(0x0300000303030201), ABC_CONST(0x0300000300030201), ABC_CONST(0x0300000003030201), ABC_CONST(0x0300000000030201) }, + { ABC_CONST(0x0202020202020001), ABC_CONST(0x0202020200020001), ABC_CONST(0x0202020002020001), ABC_CONST(0x0202020000020001), ABC_CONST(0x0202000202020001), ABC_CONST(0x0202000200020001), ABC_CONST(0x0202000002020001), ABC_CONST(0x0202000000020001), ABC_CONST(0x0200020202020001), ABC_CONST(0x0200020200020001), ABC_CONST(0x0200020002020001), ABC_CONST(0x0200020000020001), ABC_CONST(0x0200000202020001), ABC_CONST(0x0200000200020001), ABC_CONST(0x0200000002020001), ABC_CONST(0x0200000000020001), ABC_CONST(0x0202020202020001), ABC_CONST(0x0202020200020001), ABC_CONST(0x0202020002020001), ABC_CONST(0x0202020000020001), ABC_CONST(0x0202000202020001), ABC_CONST(0x0202000200020001), ABC_CONST(0x0202000002020001), ABC_CONST(0x0202000000020001), ABC_CONST(0x0200020202020001), ABC_CONST(0x0200020200020001), ABC_CONST(0x0200020002020001), ABC_CONST(0x0200020000020001), ABC_CONST(0x0200000202020001), ABC_CONST(0x0200000200020001), ABC_CONST(0x0200000002020001), ABC_CONST(0x0200000000020001) }, + { ABC_CONST(0x0303030303030102), ABC_CONST(0x0303030300030102), ABC_CONST(0x0303030003030102), ABC_CONST(0x0303030000030102), ABC_CONST(0x0303000303030102), ABC_CONST(0x0303000300030102), ABC_CONST(0x0303000003030102), ABC_CONST(0x0303000000030102), ABC_CONST(0x0300030303030102), ABC_CONST(0x0300030300030102), ABC_CONST(0x0300030003030102), ABC_CONST(0x0300030000030102), ABC_CONST(0x0300000303030102), ABC_CONST(0x0300000300030102), ABC_CONST(0x0300000003030102), ABC_CONST(0x0300000000030102), ABC_CONST(0x0303030303030102), ABC_CONST(0x0303030300030102), ABC_CONST(0x0303030003030102), ABC_CONST(0x0303030000030102), ABC_CONST(0x0303000303030102), ABC_CONST(0x0303000300030102), ABC_CONST(0x0303000003030102), ABC_CONST(0x0303000000030102), ABC_CONST(0x0300030303030102), ABC_CONST(0x0300030300030102), ABC_CONST(0x0300030003030102), ABC_CONST(0x0300030000030102), ABC_CONST(0x0300000303030102), ABC_CONST(0x0300000300030102), ABC_CONST(0x0300000003030102), ABC_CONST(0x0300000000030102) }, + { ABC_CONST(0x0303030303030101), ABC_CONST(0x0303030300030101), ABC_CONST(0x0303030003030101), ABC_CONST(0x0303030000030101), ABC_CONST(0x0303000303030101), ABC_CONST(0x0303000300030101), ABC_CONST(0x0303000003030101), ABC_CONST(0x0303000000030101), ABC_CONST(0x0300030303030101), ABC_CONST(0x0300030300030101), ABC_CONST(0x0300030003030101), ABC_CONST(0x0300030000030101), ABC_CONST(0x0300000303030101), ABC_CONST(0x0300000300030101), ABC_CONST(0x0300000003030101), ABC_CONST(0x0300000000030101), ABC_CONST(0x0303030303030101), ABC_CONST(0x0303030300030101), ABC_CONST(0x0303030003030101), ABC_CONST(0x0303030000030101), ABC_CONST(0x0303000303030101), ABC_CONST(0x0303000300030101), ABC_CONST(0x0303000003030101), ABC_CONST(0x0303000000030101), ABC_CONST(0x0300030303030101), ABC_CONST(0x0300030300030101), ABC_CONST(0x0300030003030101), ABC_CONST(0x0300030000030101), ABC_CONST(0x0300000303030101), ABC_CONST(0x0300000300030101), ABC_CONST(0x0300000003030101), ABC_CONST(0x0300000000030101) }, + { ABC_CONST(0x0404040404040202), ABC_CONST(0x0404040400040202), ABC_CONST(0x0404040004040202), ABC_CONST(0x0404040000040202), ABC_CONST(0x0404000404040202), ABC_CONST(0x0404000400040202), ABC_CONST(0x0404000004040202), ABC_CONST(0x0404000000040202), ABC_CONST(0x0400040404040202), ABC_CONST(0x0400040400040202), ABC_CONST(0x0400040004040202), ABC_CONST(0x0400040000040202), ABC_CONST(0x0400000404040202), ABC_CONST(0x0400000400040202), ABC_CONST(0x0400000004040202), ABC_CONST(0x0400000000040202), ABC_CONST(0x0404040404040202), ABC_CONST(0x0404040400040202), ABC_CONST(0x0404040004040202), ABC_CONST(0x0404040000040202), ABC_CONST(0x0404000404040202), ABC_CONST(0x0404000400040202), ABC_CONST(0x0404000004040202), ABC_CONST(0x0404000000040202), ABC_CONST(0x0400040404040202), ABC_CONST(0x0400040400040202), ABC_CONST(0x0400040004040202), ABC_CONST(0x0400040000040202), ABC_CONST(0x0400000404040202), ABC_CONST(0x0400000400040202), ABC_CONST(0x0400000004040202), ABC_CONST(0x0400000000040202) }, + { ABC_CONST(0x0101010101000101), ABC_CONST(0x0101010100000101), ABC_CONST(0x0101010001000101), ABC_CONST(0x0101010000000101), ABC_CONST(0x0101000101000101), ABC_CONST(0x0101000100000101), ABC_CONST(0x0101000001000101), ABC_CONST(0x0101000000000101), ABC_CONST(0x0100010101000101), ABC_CONST(0x0100010100000101), ABC_CONST(0x0100010001000101), ABC_CONST(0x0100010000000101), ABC_CONST(0x0100000101000101), ABC_CONST(0x0100000100000101), ABC_CONST(0x0100000001000101), ABC_CONST(0x0100000000000101), ABC_CONST(0x0101010101000101), ABC_CONST(0x0101010100000101), ABC_CONST(0x0101010001000101), ABC_CONST(0x0101010000000101), ABC_CONST(0x0101000101000101), ABC_CONST(0x0101000100000101), ABC_CONST(0x0101000001000101), ABC_CONST(0x0101000000000101), ABC_CONST(0x0100010101000101), ABC_CONST(0x0100010100000101), ABC_CONST(0x0100010001000101), ABC_CONST(0x0100010000000101), ABC_CONST(0x0100000101000101), ABC_CONST(0x0100000100000101), ABC_CONST(0x0100000001000101), ABC_CONST(0x0100000000000101) }, + { ABC_CONST(0x0202020202010202), ABC_CONST(0x0202020200010202), ABC_CONST(0x0202020002010202), ABC_CONST(0x0202020000010202), ABC_CONST(0x0202000202010202), ABC_CONST(0x0202000200010202), ABC_CONST(0x0202000002010202), ABC_CONST(0x0202000000010202), ABC_CONST(0x0200020202010202), ABC_CONST(0x0200020200010202), ABC_CONST(0x0200020002010202), ABC_CONST(0x0200020000010202), ABC_CONST(0x0200000202010202), ABC_CONST(0x0200000200010202), ABC_CONST(0x0200000002010202), ABC_CONST(0x0200000000010202), ABC_CONST(0x0202020202010202), ABC_CONST(0x0202020200010202), ABC_CONST(0x0202020002010202), ABC_CONST(0x0202020000010202), ABC_CONST(0x0202000202010202), ABC_CONST(0x0202000200010202), ABC_CONST(0x0202000002010202), ABC_CONST(0x0202000000010202), ABC_CONST(0x0200020202010202), ABC_CONST(0x0200020200010202), ABC_CONST(0x0200020002010202), ABC_CONST(0x0200020000010202), ABC_CONST(0x0200000202010202), ABC_CONST(0x0200000200010202), ABC_CONST(0x0200000002010202), ABC_CONST(0x0200000000010202) }, + { ABC_CONST(0x0202020202010201), ABC_CONST(0x0202020200010201), ABC_CONST(0x0202020002010201), ABC_CONST(0x0202020000010201), ABC_CONST(0x0202000202010201), ABC_CONST(0x0202000200010201), ABC_CONST(0x0202000002010201), ABC_CONST(0x0202000000010201), ABC_CONST(0x0200020202010201), ABC_CONST(0x0200020200010201), ABC_CONST(0x0200020002010201), ABC_CONST(0x0200020000010201), ABC_CONST(0x0200000202010201), ABC_CONST(0x0200000200010201), ABC_CONST(0x0200000002010201), ABC_CONST(0x0200000000010201), ABC_CONST(0x0202020202010201), ABC_CONST(0x0202020200010201), ABC_CONST(0x0202020002010201), ABC_CONST(0x0202020000010201), ABC_CONST(0x0202000202010201), ABC_CONST(0x0202000200010201), ABC_CONST(0x0202000002010201), ABC_CONST(0x0202000000010201), ABC_CONST(0x0200020202010201), ABC_CONST(0x0200020200010201), ABC_CONST(0x0200020002010201), ABC_CONST(0x0200020000010201), ABC_CONST(0x0200000202010201), ABC_CONST(0x0200000200010201), ABC_CONST(0x0200000002010201), ABC_CONST(0x0200000000010201) }, + { ABC_CONST(0x0303030303020302), ABC_CONST(0x0303030300020302), ABC_CONST(0x0303030003020302), ABC_CONST(0x0303030000020302), ABC_CONST(0x0303000303020302), ABC_CONST(0x0303000300020302), ABC_CONST(0x0303000003020302), ABC_CONST(0x0303000000020302), ABC_CONST(0x0300030303020302), ABC_CONST(0x0300030300020302), ABC_CONST(0x0300030003020302), ABC_CONST(0x0300030000020302), ABC_CONST(0x0300000303020302), ABC_CONST(0x0300000300020302), ABC_CONST(0x0300000003020302), ABC_CONST(0x0300000000020302), ABC_CONST(0x0303030303020302), ABC_CONST(0x0303030300020302), ABC_CONST(0x0303030003020302), ABC_CONST(0x0303030000020302), ABC_CONST(0x0303000303020302), ABC_CONST(0x0303000300020302), ABC_CONST(0x0303000003020302), ABC_CONST(0x0303000000020302), ABC_CONST(0x0300030303020302), ABC_CONST(0x0300030300020302), ABC_CONST(0x0300030003020302), ABC_CONST(0x0300030000020302), ABC_CONST(0x0300000303020302), ABC_CONST(0x0300000300020302), ABC_CONST(0x0300000003020302), ABC_CONST(0x0300000000020302) }, + { ABC_CONST(0x0202020202010102), ABC_CONST(0x0202020200010102), ABC_CONST(0x0202020002010102), ABC_CONST(0x0202020000010102), ABC_CONST(0x0202000202010102), ABC_CONST(0x0202000200010102), ABC_CONST(0x0202000002010102), ABC_CONST(0x0202000000010102), ABC_CONST(0x0200020202010102), ABC_CONST(0x0200020200010102), ABC_CONST(0x0200020002010102), ABC_CONST(0x0200020000010102), ABC_CONST(0x0200000202010102), ABC_CONST(0x0200000200010102), ABC_CONST(0x0200000002010102), ABC_CONST(0x0200000000010102), ABC_CONST(0x0202020202010102), ABC_CONST(0x0202020200010102), ABC_CONST(0x0202020002010102), ABC_CONST(0x0202020000010102), ABC_CONST(0x0202000202010102), ABC_CONST(0x0202000200010102), ABC_CONST(0x0202000002010102), ABC_CONST(0x0202000000010102), ABC_CONST(0x0200020202010102), ABC_CONST(0x0200020200010102), ABC_CONST(0x0200020002010102), ABC_CONST(0x0200020000010102), ABC_CONST(0x0200000202010102), ABC_CONST(0x0200000200010102), ABC_CONST(0x0200000002010102), ABC_CONST(0x0200000000010102) }, + { ABC_CONST(0x0303030303020203), ABC_CONST(0x0303030300020203), ABC_CONST(0x0303030003020203), ABC_CONST(0x0303030000020203), ABC_CONST(0x0303000303020203), ABC_CONST(0x0303000300020203), ABC_CONST(0x0303000003020203), ABC_CONST(0x0303000000020203), ABC_CONST(0x0300030303020203), ABC_CONST(0x0300030300020203), ABC_CONST(0x0300030003020203), ABC_CONST(0x0300030000020203), ABC_CONST(0x0300000303020203), ABC_CONST(0x0300000300020203), ABC_CONST(0x0300000003020203), ABC_CONST(0x0300000000020203), ABC_CONST(0x0303030303020203), ABC_CONST(0x0303030300020203), ABC_CONST(0x0303030003020203), ABC_CONST(0x0303030000020203), ABC_CONST(0x0303000303020203), ABC_CONST(0x0303000300020203), ABC_CONST(0x0303000003020203), ABC_CONST(0x0303000000020203), ABC_CONST(0x0300030303020203), ABC_CONST(0x0300030300020203), ABC_CONST(0x0300030003020203), ABC_CONST(0x0300030000020203), ABC_CONST(0x0300000303020203), ABC_CONST(0x0300000300020203), ABC_CONST(0x0300000003020203), ABC_CONST(0x0300000000020203) }, + { ABC_CONST(0x0303030303020202), ABC_CONST(0x0303030300020202), ABC_CONST(0x0303030003020202), ABC_CONST(0x0303030000020202), ABC_CONST(0x0303000303020202), ABC_CONST(0x0303000300020202), ABC_CONST(0x0303000003020202), ABC_CONST(0x0303000000020202), ABC_CONST(0x0300030303020202), ABC_CONST(0x0300030300020202), ABC_CONST(0x0300030003020202), ABC_CONST(0x0300030000020202), ABC_CONST(0x0300000303020202), ABC_CONST(0x0300000300020202), ABC_CONST(0x0300000003020202), ABC_CONST(0x0300000000020202), ABC_CONST(0x0303030303020202), ABC_CONST(0x0303030300020202), ABC_CONST(0x0303030003020202), ABC_CONST(0x0303030000020202), ABC_CONST(0x0303000303020202), ABC_CONST(0x0303000300020202), ABC_CONST(0x0303000003020202), ABC_CONST(0x0303000000020202), ABC_CONST(0x0300030303020202), ABC_CONST(0x0300030300020202), ABC_CONST(0x0300030003020202), ABC_CONST(0x0300030000020202), ABC_CONST(0x0300000303020202), ABC_CONST(0x0300000300020202), ABC_CONST(0x0300000003020202), ABC_CONST(0x0300000000020202) }, + { ABC_CONST(0x0404040404030303), ABC_CONST(0x0404040400030303), ABC_CONST(0x0404040004030303), ABC_CONST(0x0404040000030303), ABC_CONST(0x0404000404030303), ABC_CONST(0x0404000400030303), ABC_CONST(0x0404000004030303), ABC_CONST(0x0404000000030303), ABC_CONST(0x0400040404030303), ABC_CONST(0x0400040400030303), ABC_CONST(0x0400040004030303), ABC_CONST(0x0400040000030303), ABC_CONST(0x0400000404030303), ABC_CONST(0x0400000400030303), ABC_CONST(0x0400000004030303), ABC_CONST(0x0400000000030303), ABC_CONST(0x0404040404030303), ABC_CONST(0x0404040400030303), ABC_CONST(0x0404040004030303), ABC_CONST(0x0404040000030303), ABC_CONST(0x0404000404030303), ABC_CONST(0x0404000400030303), ABC_CONST(0x0404000004030303), ABC_CONST(0x0404000000030303), ABC_CONST(0x0400040404030303), ABC_CONST(0x0400040400030303), ABC_CONST(0x0400040004030303), ABC_CONST(0x0400040000030303), ABC_CONST(0x0400000404030303), ABC_CONST(0x0400000400030303), ABC_CONST(0x0400000004030303), ABC_CONST(0x0400000000030303) }, + { ABC_CONST(0x0202020202010101), ABC_CONST(0x0202020200010101), ABC_CONST(0x0202020002010101), ABC_CONST(0x0202020000010101), ABC_CONST(0x0202000202010101), ABC_CONST(0x0202000200010101), ABC_CONST(0x0202000002010101), ABC_CONST(0x0202000000010101), ABC_CONST(0x0200020202010101), ABC_CONST(0x0200020200010101), ABC_CONST(0x0200020002010101), ABC_CONST(0x0200020000010101), ABC_CONST(0x0200000202010101), ABC_CONST(0x0200000200010101), ABC_CONST(0x0200000002010101), ABC_CONST(0x0200000000010101), ABC_CONST(0x0202020202010101), ABC_CONST(0x0202020200010101), ABC_CONST(0x0202020002010101), ABC_CONST(0x0202020000010101), ABC_CONST(0x0202000202010101), ABC_CONST(0x0202000200010101), ABC_CONST(0x0202000002010101), ABC_CONST(0x0202000000010101), ABC_CONST(0x0200020202010101), ABC_CONST(0x0200020200010101), ABC_CONST(0x0200020002010101), ABC_CONST(0x0200020000010101), ABC_CONST(0x0200000202010101), ABC_CONST(0x0200000200010101), ABC_CONST(0x0200000002010101), ABC_CONST(0x0200000000010101) }, + { ABC_CONST(0x0303030303020202), ABC_CONST(0x0303030300020202), ABC_CONST(0x0303030003020202), ABC_CONST(0x0303030000020202), ABC_CONST(0x0303000303020202), ABC_CONST(0x0303000300020202), ABC_CONST(0x0303000003020202), ABC_CONST(0x0303000000020202), ABC_CONST(0x0300030303020202), ABC_CONST(0x0300030300020202), ABC_CONST(0x0300030003020202), ABC_CONST(0x0300030000020202), ABC_CONST(0x0300000303020202), ABC_CONST(0x0300000300020202), ABC_CONST(0x0300000003020202), ABC_CONST(0x0300000000020202), ABC_CONST(0x0303030303020202), ABC_CONST(0x0303030300020202), ABC_CONST(0x0303030003020202), ABC_CONST(0x0303030000020202), ABC_CONST(0x0303000303020202), ABC_CONST(0x0303000300020202), ABC_CONST(0x0303000003020202), ABC_CONST(0x0303000000020202), ABC_CONST(0x0300030303020202), ABC_CONST(0x0300030300020202), ABC_CONST(0x0300030003020202), ABC_CONST(0x0300030000020202), ABC_CONST(0x0300000303020202), ABC_CONST(0x0300000300020202), ABC_CONST(0x0300000003020202), ABC_CONST(0x0300000000020202) }, + { ABC_CONST(0x0303030303020201), ABC_CONST(0x0303030300020201), ABC_CONST(0x0303030003020201), ABC_CONST(0x0303030000020201), ABC_CONST(0x0303000303020201), ABC_CONST(0x0303000300020201), ABC_CONST(0x0303000003020201), ABC_CONST(0x0303000000020201), ABC_CONST(0x0300030303020201), ABC_CONST(0x0300030300020201), ABC_CONST(0x0300030003020201), ABC_CONST(0x0300030000020201), ABC_CONST(0x0300000303020201), ABC_CONST(0x0300000300020201), ABC_CONST(0x0300000003020201), ABC_CONST(0x0300000000020201), ABC_CONST(0x0303030303020201), ABC_CONST(0x0303030300020201), ABC_CONST(0x0303030003020201), ABC_CONST(0x0303030000020201), ABC_CONST(0x0303000303020201), ABC_CONST(0x0303000300020201), ABC_CONST(0x0303000003020201), ABC_CONST(0x0303000000020201), ABC_CONST(0x0300030303020201), ABC_CONST(0x0300030300020201), ABC_CONST(0x0300030003020201), ABC_CONST(0x0300030000020201), ABC_CONST(0x0300000303020201), ABC_CONST(0x0300000300020201), ABC_CONST(0x0300000003020201), ABC_CONST(0x0300000000020201) }, + { ABC_CONST(0x0404040404030302), ABC_CONST(0x0404040400030302), ABC_CONST(0x0404040004030302), ABC_CONST(0x0404040000030302), ABC_CONST(0x0404000404030302), ABC_CONST(0x0404000400030302), ABC_CONST(0x0404000004030302), ABC_CONST(0x0404000000030302), ABC_CONST(0x0400040404030302), ABC_CONST(0x0400040400030302), ABC_CONST(0x0400040004030302), ABC_CONST(0x0400040000030302), ABC_CONST(0x0400000404030302), ABC_CONST(0x0400000400030302), ABC_CONST(0x0400000004030302), ABC_CONST(0x0400000000030302), ABC_CONST(0x0404040404030302), ABC_CONST(0x0404040400030302), ABC_CONST(0x0404040004030302), ABC_CONST(0x0404040000030302), ABC_CONST(0x0404000404030302), ABC_CONST(0x0404000400030302), ABC_CONST(0x0404000004030302), ABC_CONST(0x0404000000030302), ABC_CONST(0x0400040404030302), ABC_CONST(0x0400040400030302), ABC_CONST(0x0400040004030302), ABC_CONST(0x0400040000030302), ABC_CONST(0x0400000404030302), ABC_CONST(0x0400000400030302), ABC_CONST(0x0400000004030302), ABC_CONST(0x0400000000030302) }, + { ABC_CONST(0x0303030303020102), ABC_CONST(0x0303030300020102), ABC_CONST(0x0303030003020102), ABC_CONST(0x0303030000020102), ABC_CONST(0x0303000303020102), ABC_CONST(0x0303000300020102), ABC_CONST(0x0303000003020102), ABC_CONST(0x0303000000020102), ABC_CONST(0x0300030303020102), ABC_CONST(0x0300030300020102), ABC_CONST(0x0300030003020102), ABC_CONST(0x0300030000020102), ABC_CONST(0x0300000303020102), ABC_CONST(0x0300000300020102), ABC_CONST(0x0300000003020102), ABC_CONST(0x0300000000020102), ABC_CONST(0x0303030303020102), ABC_CONST(0x0303030300020102), ABC_CONST(0x0303030003020102), ABC_CONST(0x0303030000020102), ABC_CONST(0x0303000303020102), ABC_CONST(0x0303000300020102), ABC_CONST(0x0303000003020102), ABC_CONST(0x0303000000020102), ABC_CONST(0x0300030303020102), ABC_CONST(0x0300030300020102), ABC_CONST(0x0300030003020102), ABC_CONST(0x0300030000020102), ABC_CONST(0x0300000303020102), ABC_CONST(0x0300000300020102), ABC_CONST(0x0300000003020102), ABC_CONST(0x0300000000020102) }, + { ABC_CONST(0x0404040404030203), ABC_CONST(0x0404040400030203), ABC_CONST(0x0404040004030203), ABC_CONST(0x0404040000030203), ABC_CONST(0x0404000404030203), ABC_CONST(0x0404000400030203), ABC_CONST(0x0404000004030203), ABC_CONST(0x0404000000030203), ABC_CONST(0x0400040404030203), ABC_CONST(0x0400040400030203), ABC_CONST(0x0400040004030203), ABC_CONST(0x0400040000030203), ABC_CONST(0x0400000404030203), ABC_CONST(0x0400000400030203), ABC_CONST(0x0400000004030203), ABC_CONST(0x0400000000030203), ABC_CONST(0x0404040404030203), ABC_CONST(0x0404040400030203), ABC_CONST(0x0404040004030203), ABC_CONST(0x0404040000030203), ABC_CONST(0x0404000404030203), ABC_CONST(0x0404000400030203), ABC_CONST(0x0404000004030203), ABC_CONST(0x0404000000030203), ABC_CONST(0x0400040404030203), ABC_CONST(0x0400040400030203), ABC_CONST(0x0400040004030203), ABC_CONST(0x0400040000030203), ABC_CONST(0x0400000404030203), ABC_CONST(0x0400000400030203), ABC_CONST(0x0400000004030203), ABC_CONST(0x0400000000030203) }, + { ABC_CONST(0x0404040404030202), ABC_CONST(0x0404040400030202), ABC_CONST(0x0404040004030202), ABC_CONST(0x0404040000030202), ABC_CONST(0x0404000404030202), ABC_CONST(0x0404000400030202), ABC_CONST(0x0404000004030202), ABC_CONST(0x0404000000030202), ABC_CONST(0x0400040404030202), ABC_CONST(0x0400040400030202), ABC_CONST(0x0400040004030202), ABC_CONST(0x0400040000030202), ABC_CONST(0x0400000404030202), ABC_CONST(0x0400000400030202), ABC_CONST(0x0400000004030202), ABC_CONST(0x0400000000030202), ABC_CONST(0x0404040404030202), ABC_CONST(0x0404040400030202), ABC_CONST(0x0404040004030202), ABC_CONST(0x0404040000030202), ABC_CONST(0x0404000404030202), ABC_CONST(0x0404000400030202), ABC_CONST(0x0404000004030202), ABC_CONST(0x0404000000030202), ABC_CONST(0x0400040404030202), ABC_CONST(0x0400040400030202), ABC_CONST(0x0400040004030202), ABC_CONST(0x0400040000030202), ABC_CONST(0x0400000404030202), ABC_CONST(0x0400000400030202), ABC_CONST(0x0400000004030202), ABC_CONST(0x0400000000030202) }, + { ABC_CONST(0x0505050505040303), ABC_CONST(0x0505050500040303), ABC_CONST(0x0505050005040303), ABC_CONST(0x0505050000040303), ABC_CONST(0x0505000505040303), ABC_CONST(0x0505000500040303), ABC_CONST(0x0505000005040303), ABC_CONST(0x0505000000040303), ABC_CONST(0x0500050505040303), ABC_CONST(0x0500050500040303), ABC_CONST(0x0500050005040303), ABC_CONST(0x0500050000040303), ABC_CONST(0x0500000505040303), ABC_CONST(0x0500000500040303), ABC_CONST(0x0500000005040303), ABC_CONST(0x0500000000040303), ABC_CONST(0x0505050505040303), ABC_CONST(0x0505050500040303), ABC_CONST(0x0505050005040303), ABC_CONST(0x0505050000040303), ABC_CONST(0x0505000505040303), ABC_CONST(0x0505000500040303), ABC_CONST(0x0505000005040303), ABC_CONST(0x0505000000040303), ABC_CONST(0x0500050505040303), ABC_CONST(0x0500050500040303), ABC_CONST(0x0500050005040303), ABC_CONST(0x0500050000040303), ABC_CONST(0x0500000505040303), ABC_CONST(0x0500000500040303), ABC_CONST(0x0500000005040303), ABC_CONST(0x0500000000040303) }, + { ABC_CONST(0x0101010101000100), ABC_CONST(0x0101010100000100), ABC_CONST(0x0101010001000100), ABC_CONST(0x0101010000000100), ABC_CONST(0x0101000101000100), ABC_CONST(0x0101000100000100), ABC_CONST(0x0101000001000100), ABC_CONST(0x0101000000000100), ABC_CONST(0x0100010101000100), ABC_CONST(0x0100010100000100), ABC_CONST(0x0100010001000100), ABC_CONST(0x0100010000000100), ABC_CONST(0x0100000101000100), ABC_CONST(0x0100000100000100), ABC_CONST(0x0100000001000100), ABC_CONST(0x0100000000000100), ABC_CONST(0x0101010101000100), ABC_CONST(0x0101010100000100), ABC_CONST(0x0101010001000100), ABC_CONST(0x0101010000000100), ABC_CONST(0x0101000101000100), ABC_CONST(0x0101000100000100), ABC_CONST(0x0101000001000100), ABC_CONST(0x0101000000000100), ABC_CONST(0x0100010101000100), ABC_CONST(0x0100010100000100), ABC_CONST(0x0100010001000100), ABC_CONST(0x0100010000000100), ABC_CONST(0x0100000101000100), ABC_CONST(0x0100000100000100), ABC_CONST(0x0100000001000100), ABC_CONST(0x0100000000000100) }, + { ABC_CONST(0x0202020202010201), ABC_CONST(0x0202020200010201), ABC_CONST(0x0202020002010201), ABC_CONST(0x0202020000010201), ABC_CONST(0x0202000202010201), ABC_CONST(0x0202000200010201), ABC_CONST(0x0202000002010201), ABC_CONST(0x0202000000010201), ABC_CONST(0x0200020202010201), ABC_CONST(0x0200020200010201), ABC_CONST(0x0200020002010201), ABC_CONST(0x0200020000010201), ABC_CONST(0x0200000202010201), ABC_CONST(0x0200000200010201), ABC_CONST(0x0200000002010201), ABC_CONST(0x0200000000010201), ABC_CONST(0x0202020202010201), ABC_CONST(0x0202020200010201), ABC_CONST(0x0202020002010201), ABC_CONST(0x0202020000010201), ABC_CONST(0x0202000202010201), ABC_CONST(0x0202000200010201), ABC_CONST(0x0202000002010201), ABC_CONST(0x0202000000010201), ABC_CONST(0x0200020202010201), ABC_CONST(0x0200020200010201), ABC_CONST(0x0200020002010201), ABC_CONST(0x0200020000010201), ABC_CONST(0x0200000202010201), ABC_CONST(0x0200000200010201), ABC_CONST(0x0200000002010201), ABC_CONST(0x0200000000010201) }, + { ABC_CONST(0x0202020202010200), ABC_CONST(0x0202020200010200), ABC_CONST(0x0202020002010200), ABC_CONST(0x0202020000010200), ABC_CONST(0x0202000202010200), ABC_CONST(0x0202000200010200), ABC_CONST(0x0202000002010200), ABC_CONST(0x0202000000010200), ABC_CONST(0x0200020202010200), ABC_CONST(0x0200020200010200), ABC_CONST(0x0200020002010200), ABC_CONST(0x0200020000010200), ABC_CONST(0x0200000202010200), ABC_CONST(0x0200000200010200), ABC_CONST(0x0200000002010200), ABC_CONST(0x0200000000010200), ABC_CONST(0x0202020202010200), ABC_CONST(0x0202020200010200), ABC_CONST(0x0202020002010200), ABC_CONST(0x0202020000010200), ABC_CONST(0x0202000202010200), ABC_CONST(0x0202000200010200), ABC_CONST(0x0202000002010200), ABC_CONST(0x0202000000010200), ABC_CONST(0x0200020202010200), ABC_CONST(0x0200020200010200), ABC_CONST(0x0200020002010200), ABC_CONST(0x0200020000010200), ABC_CONST(0x0200000202010200), ABC_CONST(0x0200000200010200), ABC_CONST(0x0200000002010200), ABC_CONST(0x0200000000010200) }, + { ABC_CONST(0x0303030303020301), ABC_CONST(0x0303030300020301), ABC_CONST(0x0303030003020301), ABC_CONST(0x0303030000020301), ABC_CONST(0x0303000303020301), ABC_CONST(0x0303000300020301), ABC_CONST(0x0303000003020301), ABC_CONST(0x0303000000020301), ABC_CONST(0x0300030303020301), ABC_CONST(0x0300030300020301), ABC_CONST(0x0300030003020301), ABC_CONST(0x0300030000020301), ABC_CONST(0x0300000303020301), ABC_CONST(0x0300000300020301), ABC_CONST(0x0300000003020301), ABC_CONST(0x0300000000020301), ABC_CONST(0x0303030303020301), ABC_CONST(0x0303030300020301), ABC_CONST(0x0303030003020301), ABC_CONST(0x0303030000020301), ABC_CONST(0x0303000303020301), ABC_CONST(0x0303000300020301), ABC_CONST(0x0303000003020301), ABC_CONST(0x0303000000020301), ABC_CONST(0x0300030303020301), ABC_CONST(0x0300030300020301), ABC_CONST(0x0300030003020301), ABC_CONST(0x0300030000020301), ABC_CONST(0x0300000303020301), ABC_CONST(0x0300000300020301), ABC_CONST(0x0300000003020301), ABC_CONST(0x0300000000020301) }, + { ABC_CONST(0x0202020202010101), ABC_CONST(0x0202020200010101), ABC_CONST(0x0202020002010101), ABC_CONST(0x0202020000010101), ABC_CONST(0x0202000202010101), ABC_CONST(0x0202000200010101), ABC_CONST(0x0202000002010101), ABC_CONST(0x0202000000010101), ABC_CONST(0x0200020202010101), ABC_CONST(0x0200020200010101), ABC_CONST(0x0200020002010101), ABC_CONST(0x0200020000010101), ABC_CONST(0x0200000202010101), ABC_CONST(0x0200000200010101), ABC_CONST(0x0200000002010101), ABC_CONST(0x0200000000010101), ABC_CONST(0x0202020202010101), ABC_CONST(0x0202020200010101), ABC_CONST(0x0202020002010101), ABC_CONST(0x0202020000010101), ABC_CONST(0x0202000202010101), ABC_CONST(0x0202000200010101), ABC_CONST(0x0202000002010101), ABC_CONST(0x0202000000010101), ABC_CONST(0x0200020202010101), ABC_CONST(0x0200020200010101), ABC_CONST(0x0200020002010101), ABC_CONST(0x0200020000010101), ABC_CONST(0x0200000202010101), ABC_CONST(0x0200000200010101), ABC_CONST(0x0200000002010101), ABC_CONST(0x0200000000010101) }, + { ABC_CONST(0x0303030303020202), ABC_CONST(0x0303030300020202), ABC_CONST(0x0303030003020202), ABC_CONST(0x0303030000020202), ABC_CONST(0x0303000303020202), ABC_CONST(0x0303000300020202), ABC_CONST(0x0303000003020202), ABC_CONST(0x0303000000020202), ABC_CONST(0x0300030303020202), ABC_CONST(0x0300030300020202), ABC_CONST(0x0300030003020202), ABC_CONST(0x0300030000020202), ABC_CONST(0x0300000303020202), ABC_CONST(0x0300000300020202), ABC_CONST(0x0300000003020202), ABC_CONST(0x0300000000020202), ABC_CONST(0x0303030303020202), ABC_CONST(0x0303030300020202), ABC_CONST(0x0303030003020202), ABC_CONST(0x0303030000020202), ABC_CONST(0x0303000303020202), ABC_CONST(0x0303000300020202), ABC_CONST(0x0303000003020202), ABC_CONST(0x0303000000020202), ABC_CONST(0x0300030303020202), ABC_CONST(0x0300030300020202), ABC_CONST(0x0300030003020202), ABC_CONST(0x0300030000020202), ABC_CONST(0x0300000303020202), ABC_CONST(0x0300000300020202), ABC_CONST(0x0300000003020202), ABC_CONST(0x0300000000020202) }, + { ABC_CONST(0x0303030303020201), ABC_CONST(0x0303030300020201), ABC_CONST(0x0303030003020201), ABC_CONST(0x0303030000020201), ABC_CONST(0x0303000303020201), ABC_CONST(0x0303000300020201), ABC_CONST(0x0303000003020201), ABC_CONST(0x0303000000020201), ABC_CONST(0x0300030303020201), ABC_CONST(0x0300030300020201), ABC_CONST(0x0300030003020201), ABC_CONST(0x0300030000020201), ABC_CONST(0x0300000303020201), ABC_CONST(0x0300000300020201), ABC_CONST(0x0300000003020201), ABC_CONST(0x0300000000020201), ABC_CONST(0x0303030303020201), ABC_CONST(0x0303030300020201), ABC_CONST(0x0303030003020201), ABC_CONST(0x0303030000020201), ABC_CONST(0x0303000303020201), ABC_CONST(0x0303000300020201), ABC_CONST(0x0303000003020201), ABC_CONST(0x0303000000020201), ABC_CONST(0x0300030303020201), ABC_CONST(0x0300030300020201), ABC_CONST(0x0300030003020201), ABC_CONST(0x0300030000020201), ABC_CONST(0x0300000303020201), ABC_CONST(0x0300000300020201), ABC_CONST(0x0300000003020201), ABC_CONST(0x0300000000020201) }, + { ABC_CONST(0x0404040404030302), ABC_CONST(0x0404040400030302), ABC_CONST(0x0404040004030302), ABC_CONST(0x0404040000030302), ABC_CONST(0x0404000404030302), ABC_CONST(0x0404000400030302), ABC_CONST(0x0404000004030302), ABC_CONST(0x0404000000030302), ABC_CONST(0x0400040404030302), ABC_CONST(0x0400040400030302), ABC_CONST(0x0400040004030302), ABC_CONST(0x0400040000030302), ABC_CONST(0x0400000404030302), ABC_CONST(0x0400000400030302), ABC_CONST(0x0400000004030302), ABC_CONST(0x0400000000030302), ABC_CONST(0x0404040404030302), ABC_CONST(0x0404040400030302), ABC_CONST(0x0404040004030302), ABC_CONST(0x0404040000030302), ABC_CONST(0x0404000404030302), ABC_CONST(0x0404000400030302), ABC_CONST(0x0404000004030302), ABC_CONST(0x0404000000030302), ABC_CONST(0x0400040404030302), ABC_CONST(0x0400040400030302), ABC_CONST(0x0400040004030302), ABC_CONST(0x0400040000030302), ABC_CONST(0x0400000404030302), ABC_CONST(0x0400000400030302), ABC_CONST(0x0400000004030302), ABC_CONST(0x0400000000030302) }, + { ABC_CONST(0x0202020202010100), ABC_CONST(0x0202020200010100), ABC_CONST(0x0202020002010100), ABC_CONST(0x0202020000010100), ABC_CONST(0x0202000202010100), ABC_CONST(0x0202000200010100), ABC_CONST(0x0202000002010100), ABC_CONST(0x0202000000010100), ABC_CONST(0x0200020202010100), ABC_CONST(0x0200020200010100), ABC_CONST(0x0200020002010100), ABC_CONST(0x0200020000010100), ABC_CONST(0x0200000202010100), ABC_CONST(0x0200000200010100), ABC_CONST(0x0200000002010100), ABC_CONST(0x0200000000010100), ABC_CONST(0x0202020202010100), ABC_CONST(0x0202020200010100), ABC_CONST(0x0202020002010100), ABC_CONST(0x0202020000010100), ABC_CONST(0x0202000202010100), ABC_CONST(0x0202000200010100), ABC_CONST(0x0202000002010100), ABC_CONST(0x0202000000010100), ABC_CONST(0x0200020202010100), ABC_CONST(0x0200020200010100), ABC_CONST(0x0200020002010100), ABC_CONST(0x0200020000010100), ABC_CONST(0x0200000202010100), ABC_CONST(0x0200000200010100), ABC_CONST(0x0200000002010100), ABC_CONST(0x0200000000010100) }, + { ABC_CONST(0x0303030303020201), ABC_CONST(0x0303030300020201), ABC_CONST(0x0303030003020201), ABC_CONST(0x0303030000020201), ABC_CONST(0x0303000303020201), ABC_CONST(0x0303000300020201), ABC_CONST(0x0303000003020201), ABC_CONST(0x0303000000020201), ABC_CONST(0x0300030303020201), ABC_CONST(0x0300030300020201), ABC_CONST(0x0300030003020201), ABC_CONST(0x0300030000020201), ABC_CONST(0x0300000303020201), ABC_CONST(0x0300000300020201), ABC_CONST(0x0300000003020201), ABC_CONST(0x0300000000020201), ABC_CONST(0x0303030303020201), ABC_CONST(0x0303030300020201), ABC_CONST(0x0303030003020201), ABC_CONST(0x0303030000020201), ABC_CONST(0x0303000303020201), ABC_CONST(0x0303000300020201), ABC_CONST(0x0303000003020201), ABC_CONST(0x0303000000020201), ABC_CONST(0x0300030303020201), ABC_CONST(0x0300030300020201), ABC_CONST(0x0300030003020201), ABC_CONST(0x0300030000020201), ABC_CONST(0x0300000303020201), ABC_CONST(0x0300000300020201), ABC_CONST(0x0300000003020201), ABC_CONST(0x0300000000020201) }, + { ABC_CONST(0x0303030303020200), ABC_CONST(0x0303030300020200), ABC_CONST(0x0303030003020200), ABC_CONST(0x0303030000020200), ABC_CONST(0x0303000303020200), ABC_CONST(0x0303000300020200), ABC_CONST(0x0303000003020200), ABC_CONST(0x0303000000020200), ABC_CONST(0x0300030303020200), ABC_CONST(0x0300030300020200), ABC_CONST(0x0300030003020200), ABC_CONST(0x0300030000020200), ABC_CONST(0x0300000303020200), ABC_CONST(0x0300000300020200), ABC_CONST(0x0300000003020200), ABC_CONST(0x0300000000020200), ABC_CONST(0x0303030303020200), ABC_CONST(0x0303030300020200), ABC_CONST(0x0303030003020200), ABC_CONST(0x0303030000020200), ABC_CONST(0x0303000303020200), ABC_CONST(0x0303000300020200), ABC_CONST(0x0303000003020200), ABC_CONST(0x0303000000020200), ABC_CONST(0x0300030303020200), ABC_CONST(0x0300030300020200), ABC_CONST(0x0300030003020200), ABC_CONST(0x0300030000020200), ABC_CONST(0x0300000303020200), ABC_CONST(0x0300000300020200), ABC_CONST(0x0300000003020200), ABC_CONST(0x0300000000020200) }, + { ABC_CONST(0x0404040404030301), ABC_CONST(0x0404040400030301), ABC_CONST(0x0404040004030301), ABC_CONST(0x0404040000030301), ABC_CONST(0x0404000404030301), ABC_CONST(0x0404000400030301), ABC_CONST(0x0404000004030301), ABC_CONST(0x0404000000030301), ABC_CONST(0x0400040404030301), ABC_CONST(0x0400040400030301), ABC_CONST(0x0400040004030301), ABC_CONST(0x0400040000030301), ABC_CONST(0x0400000404030301), ABC_CONST(0x0400000400030301), ABC_CONST(0x0400000004030301), ABC_CONST(0x0400000000030301), ABC_CONST(0x0404040404030301), ABC_CONST(0x0404040400030301), ABC_CONST(0x0404040004030301), ABC_CONST(0x0404040000030301), ABC_CONST(0x0404000404030301), ABC_CONST(0x0404000400030301), ABC_CONST(0x0404000004030301), ABC_CONST(0x0404000000030301), ABC_CONST(0x0400040404030301), ABC_CONST(0x0400040400030301), ABC_CONST(0x0400040004030301), ABC_CONST(0x0400040000030301), ABC_CONST(0x0400000404030301), ABC_CONST(0x0400000400030301), ABC_CONST(0x0400000004030301), ABC_CONST(0x0400000000030301) }, + { ABC_CONST(0x0303030303020101), ABC_CONST(0x0303030300020101), ABC_CONST(0x0303030003020101), ABC_CONST(0x0303030000020101), ABC_CONST(0x0303000303020101), ABC_CONST(0x0303000300020101), ABC_CONST(0x0303000003020101), ABC_CONST(0x0303000000020101), ABC_CONST(0x0300030303020101), ABC_CONST(0x0300030300020101), ABC_CONST(0x0300030003020101), ABC_CONST(0x0300030000020101), ABC_CONST(0x0300000303020101), ABC_CONST(0x0300000300020101), ABC_CONST(0x0300000003020101), ABC_CONST(0x0300000000020101), ABC_CONST(0x0303030303020101), ABC_CONST(0x0303030300020101), ABC_CONST(0x0303030003020101), ABC_CONST(0x0303030000020101), ABC_CONST(0x0303000303020101), ABC_CONST(0x0303000300020101), ABC_CONST(0x0303000003020101), ABC_CONST(0x0303000000020101), ABC_CONST(0x0300030303020101), ABC_CONST(0x0300030300020101), ABC_CONST(0x0300030003020101), ABC_CONST(0x0300030000020101), ABC_CONST(0x0300000303020101), ABC_CONST(0x0300000300020101), ABC_CONST(0x0300000003020101), ABC_CONST(0x0300000000020101) }, + { ABC_CONST(0x0404040404030202), ABC_CONST(0x0404040400030202), ABC_CONST(0x0404040004030202), ABC_CONST(0x0404040000030202), ABC_CONST(0x0404000404030202), ABC_CONST(0x0404000400030202), ABC_CONST(0x0404000004030202), ABC_CONST(0x0404000000030202), ABC_CONST(0x0400040404030202), ABC_CONST(0x0400040400030202), ABC_CONST(0x0400040004030202), ABC_CONST(0x0400040000030202), ABC_CONST(0x0400000404030202), ABC_CONST(0x0400000400030202), ABC_CONST(0x0400000004030202), ABC_CONST(0x0400000000030202), ABC_CONST(0x0404040404030202), ABC_CONST(0x0404040400030202), ABC_CONST(0x0404040004030202), ABC_CONST(0x0404040000030202), ABC_CONST(0x0404000404030202), ABC_CONST(0x0404000400030202), ABC_CONST(0x0404000004030202), ABC_CONST(0x0404000000030202), ABC_CONST(0x0400040404030202), ABC_CONST(0x0400040400030202), ABC_CONST(0x0400040004030202), ABC_CONST(0x0400040000030202), ABC_CONST(0x0400000404030202), ABC_CONST(0x0400000400030202), ABC_CONST(0x0400000004030202), ABC_CONST(0x0400000000030202) }, + { ABC_CONST(0x0404040404030201), ABC_CONST(0x0404040400030201), ABC_CONST(0x0404040004030201), ABC_CONST(0x0404040000030201), ABC_CONST(0x0404000404030201), ABC_CONST(0x0404000400030201), ABC_CONST(0x0404000004030201), ABC_CONST(0x0404000000030201), ABC_CONST(0x0400040404030201), ABC_CONST(0x0400040400030201), ABC_CONST(0x0400040004030201), ABC_CONST(0x0400040000030201), ABC_CONST(0x0400000404030201), ABC_CONST(0x0400000400030201), ABC_CONST(0x0400000004030201), ABC_CONST(0x0400000000030201), ABC_CONST(0x0404040404030201), ABC_CONST(0x0404040400030201), ABC_CONST(0x0404040004030201), ABC_CONST(0x0404040000030201), ABC_CONST(0x0404000404030201), ABC_CONST(0x0404000400030201), ABC_CONST(0x0404000004030201), ABC_CONST(0x0404000000030201), ABC_CONST(0x0400040404030201), ABC_CONST(0x0400040400030201), ABC_CONST(0x0400040004030201), ABC_CONST(0x0400040000030201), ABC_CONST(0x0400000404030201), ABC_CONST(0x0400000400030201), ABC_CONST(0x0400000004030201), ABC_CONST(0x0400000000030201) }, + { ABC_CONST(0x0505050505040302), ABC_CONST(0x0505050500040302), ABC_CONST(0x0505050005040302), ABC_CONST(0x0505050000040302), ABC_CONST(0x0505000505040302), ABC_CONST(0x0505000500040302), ABC_CONST(0x0505000005040302), ABC_CONST(0x0505000000040302), ABC_CONST(0x0500050505040302), ABC_CONST(0x0500050500040302), ABC_CONST(0x0500050005040302), ABC_CONST(0x0500050000040302), ABC_CONST(0x0500000505040302), ABC_CONST(0x0500000500040302), ABC_CONST(0x0500000005040302), ABC_CONST(0x0500000000040302), ABC_CONST(0x0505050505040302), ABC_CONST(0x0505050500040302), ABC_CONST(0x0505050005040302), ABC_CONST(0x0505050000040302), ABC_CONST(0x0505000505040302), ABC_CONST(0x0505000500040302), ABC_CONST(0x0505000005040302), ABC_CONST(0x0505000000040302), ABC_CONST(0x0500050505040302), ABC_CONST(0x0500050500040302), ABC_CONST(0x0500050005040302), ABC_CONST(0x0500050000040302), ABC_CONST(0x0500000505040302), ABC_CONST(0x0500000500040302), ABC_CONST(0x0500000005040302), ABC_CONST(0x0500000000040302) }, + { ABC_CONST(0x0202020202000201), ABC_CONST(0x0202020200000201), ABC_CONST(0x0202020002000201), ABC_CONST(0x0202020000000201), ABC_CONST(0x0202000202000201), ABC_CONST(0x0202000200000201), ABC_CONST(0x0202000002000201), ABC_CONST(0x0202000000000201), ABC_CONST(0x0200020202000201), ABC_CONST(0x0200020200000201), ABC_CONST(0x0200020002000201), ABC_CONST(0x0200020000000201), ABC_CONST(0x0200000202000201), ABC_CONST(0x0200000200000201), ABC_CONST(0x0200000002000201), ABC_CONST(0x0200000000000201), ABC_CONST(0x0202020202000201), ABC_CONST(0x0202020200000201), ABC_CONST(0x0202020002000201), ABC_CONST(0x0202020000000201), ABC_CONST(0x0202000202000201), ABC_CONST(0x0202000200000201), ABC_CONST(0x0202000002000201), ABC_CONST(0x0202000000000201), ABC_CONST(0x0200020202000201), ABC_CONST(0x0200020200000201), ABC_CONST(0x0200020002000201), ABC_CONST(0x0200020000000201), ABC_CONST(0x0200000202000201), ABC_CONST(0x0200000200000201), ABC_CONST(0x0200000002000201), ABC_CONST(0x0200000000000201) }, + { ABC_CONST(0x0303030303010302), ABC_CONST(0x0303030300010302), ABC_CONST(0x0303030003010302), ABC_CONST(0x0303030000010302), ABC_CONST(0x0303000303010302), ABC_CONST(0x0303000300010302), ABC_CONST(0x0303000003010302), ABC_CONST(0x0303000000010302), ABC_CONST(0x0300030303010302), ABC_CONST(0x0300030300010302), ABC_CONST(0x0300030003010302), ABC_CONST(0x0300030000010302), ABC_CONST(0x0300000303010302), ABC_CONST(0x0300000300010302), ABC_CONST(0x0300000003010302), ABC_CONST(0x0300000000010302), ABC_CONST(0x0303030303010302), ABC_CONST(0x0303030300010302), ABC_CONST(0x0303030003010302), ABC_CONST(0x0303030000010302), ABC_CONST(0x0303000303010302), ABC_CONST(0x0303000300010302), ABC_CONST(0x0303000003010302), ABC_CONST(0x0303000000010302), ABC_CONST(0x0300030303010302), ABC_CONST(0x0300030300010302), ABC_CONST(0x0300030003010302), ABC_CONST(0x0300030000010302), ABC_CONST(0x0300000303010302), ABC_CONST(0x0300000300010302), ABC_CONST(0x0300000003010302), ABC_CONST(0x0300000000010302) }, + { ABC_CONST(0x0303030303010301), ABC_CONST(0x0303030300010301), ABC_CONST(0x0303030003010301), ABC_CONST(0x0303030000010301), ABC_CONST(0x0303000303010301), ABC_CONST(0x0303000300010301), ABC_CONST(0x0303000003010301), ABC_CONST(0x0303000000010301), ABC_CONST(0x0300030303010301), ABC_CONST(0x0300030300010301), ABC_CONST(0x0300030003010301), ABC_CONST(0x0300030000010301), ABC_CONST(0x0300000303010301), ABC_CONST(0x0300000300010301), ABC_CONST(0x0300000003010301), ABC_CONST(0x0300000000010301), ABC_CONST(0x0303030303010301), ABC_CONST(0x0303030300010301), ABC_CONST(0x0303030003010301), ABC_CONST(0x0303030000010301), ABC_CONST(0x0303000303010301), ABC_CONST(0x0303000300010301), ABC_CONST(0x0303000003010301), ABC_CONST(0x0303000000010301), ABC_CONST(0x0300030303010301), ABC_CONST(0x0300030300010301), ABC_CONST(0x0300030003010301), ABC_CONST(0x0300030000010301), ABC_CONST(0x0300000303010301), ABC_CONST(0x0300000300010301), ABC_CONST(0x0300000003010301), ABC_CONST(0x0300000000010301) }, + { ABC_CONST(0x0404040404020402), ABC_CONST(0x0404040400020402), ABC_CONST(0x0404040004020402), ABC_CONST(0x0404040000020402), ABC_CONST(0x0404000404020402), ABC_CONST(0x0404000400020402), ABC_CONST(0x0404000004020402), ABC_CONST(0x0404000000020402), ABC_CONST(0x0400040404020402), ABC_CONST(0x0400040400020402), ABC_CONST(0x0400040004020402), ABC_CONST(0x0400040000020402), ABC_CONST(0x0400000404020402), ABC_CONST(0x0400000400020402), ABC_CONST(0x0400000004020402), ABC_CONST(0x0400000000020402), ABC_CONST(0x0404040404020402), ABC_CONST(0x0404040400020402), ABC_CONST(0x0404040004020402), ABC_CONST(0x0404040000020402), ABC_CONST(0x0404000404020402), ABC_CONST(0x0404000400020402), ABC_CONST(0x0404000004020402), ABC_CONST(0x0404000000020402), ABC_CONST(0x0400040404020402), ABC_CONST(0x0400040400020402), ABC_CONST(0x0400040004020402), ABC_CONST(0x0400040000020402), ABC_CONST(0x0400000404020402), ABC_CONST(0x0400000400020402), ABC_CONST(0x0400000004020402), ABC_CONST(0x0400000000020402) }, + { ABC_CONST(0x0303030303010202), ABC_CONST(0x0303030300010202), ABC_CONST(0x0303030003010202), ABC_CONST(0x0303030000010202), ABC_CONST(0x0303000303010202), ABC_CONST(0x0303000300010202), ABC_CONST(0x0303000003010202), ABC_CONST(0x0303000000010202), ABC_CONST(0x0300030303010202), ABC_CONST(0x0300030300010202), ABC_CONST(0x0300030003010202), ABC_CONST(0x0300030000010202), ABC_CONST(0x0300000303010202), ABC_CONST(0x0300000300010202), ABC_CONST(0x0300000003010202), ABC_CONST(0x0300000000010202), ABC_CONST(0x0303030303010202), ABC_CONST(0x0303030300010202), ABC_CONST(0x0303030003010202), ABC_CONST(0x0303030000010202), ABC_CONST(0x0303000303010202), ABC_CONST(0x0303000300010202), ABC_CONST(0x0303000003010202), ABC_CONST(0x0303000000010202), ABC_CONST(0x0300030303010202), ABC_CONST(0x0300030300010202), ABC_CONST(0x0300030003010202), ABC_CONST(0x0300030000010202), ABC_CONST(0x0300000303010202), ABC_CONST(0x0300000300010202), ABC_CONST(0x0300000003010202), ABC_CONST(0x0300000000010202) }, + { ABC_CONST(0x0404040404020303), ABC_CONST(0x0404040400020303), ABC_CONST(0x0404040004020303), ABC_CONST(0x0404040000020303), ABC_CONST(0x0404000404020303), ABC_CONST(0x0404000400020303), ABC_CONST(0x0404000004020303), ABC_CONST(0x0404000000020303), ABC_CONST(0x0400040404020303), ABC_CONST(0x0400040400020303), ABC_CONST(0x0400040004020303), ABC_CONST(0x0400040000020303), ABC_CONST(0x0400000404020303), ABC_CONST(0x0400000400020303), ABC_CONST(0x0400000004020303), ABC_CONST(0x0400000000020303), ABC_CONST(0x0404040404020303), ABC_CONST(0x0404040400020303), ABC_CONST(0x0404040004020303), ABC_CONST(0x0404040000020303), ABC_CONST(0x0404000404020303), ABC_CONST(0x0404000400020303), ABC_CONST(0x0404000004020303), ABC_CONST(0x0404000000020303), ABC_CONST(0x0400040404020303), ABC_CONST(0x0400040400020303), ABC_CONST(0x0400040004020303), ABC_CONST(0x0400040000020303), ABC_CONST(0x0400000404020303), ABC_CONST(0x0400000400020303), ABC_CONST(0x0400000004020303), ABC_CONST(0x0400000000020303) }, + { ABC_CONST(0x0404040404020302), ABC_CONST(0x0404040400020302), ABC_CONST(0x0404040004020302), ABC_CONST(0x0404040000020302), ABC_CONST(0x0404000404020302), ABC_CONST(0x0404000400020302), ABC_CONST(0x0404000004020302), ABC_CONST(0x0404000000020302), ABC_CONST(0x0400040404020302), ABC_CONST(0x0400040400020302), ABC_CONST(0x0400040004020302), ABC_CONST(0x0400040000020302), ABC_CONST(0x0400000404020302), ABC_CONST(0x0400000400020302), ABC_CONST(0x0400000004020302), ABC_CONST(0x0400000000020302), ABC_CONST(0x0404040404020302), ABC_CONST(0x0404040400020302), ABC_CONST(0x0404040004020302), ABC_CONST(0x0404040000020302), ABC_CONST(0x0404000404020302), ABC_CONST(0x0404000400020302), ABC_CONST(0x0404000004020302), ABC_CONST(0x0404000000020302), ABC_CONST(0x0400040404020302), ABC_CONST(0x0400040400020302), ABC_CONST(0x0400040004020302), ABC_CONST(0x0400040000020302), ABC_CONST(0x0400000404020302), ABC_CONST(0x0400000400020302), ABC_CONST(0x0400000004020302), ABC_CONST(0x0400000000020302) }, + { ABC_CONST(0x0505050505030403), ABC_CONST(0x0505050500030403), ABC_CONST(0x0505050005030403), ABC_CONST(0x0505050000030403), ABC_CONST(0x0505000505030403), ABC_CONST(0x0505000500030403), ABC_CONST(0x0505000005030403), ABC_CONST(0x0505000000030403), ABC_CONST(0x0500050505030403), ABC_CONST(0x0500050500030403), ABC_CONST(0x0500050005030403), ABC_CONST(0x0500050000030403), ABC_CONST(0x0500000505030403), ABC_CONST(0x0500000500030403), ABC_CONST(0x0500000005030403), ABC_CONST(0x0500000000030403), ABC_CONST(0x0505050505030403), ABC_CONST(0x0505050500030403), ABC_CONST(0x0505050005030403), ABC_CONST(0x0505050000030403), ABC_CONST(0x0505000505030403), ABC_CONST(0x0505000500030403), ABC_CONST(0x0505000005030403), ABC_CONST(0x0505000000030403), ABC_CONST(0x0500050505030403), ABC_CONST(0x0500050500030403), ABC_CONST(0x0500050005030403), ABC_CONST(0x0500050000030403), ABC_CONST(0x0500000505030403), ABC_CONST(0x0500000500030403), ABC_CONST(0x0500000005030403), ABC_CONST(0x0500000000030403) }, + { ABC_CONST(0x0303030303010201), ABC_CONST(0x0303030300010201), ABC_CONST(0x0303030003010201), ABC_CONST(0x0303030000010201), ABC_CONST(0x0303000303010201), ABC_CONST(0x0303000300010201), ABC_CONST(0x0303000003010201), ABC_CONST(0x0303000000010201), ABC_CONST(0x0300030303010201), ABC_CONST(0x0300030300010201), ABC_CONST(0x0300030003010201), ABC_CONST(0x0300030000010201), ABC_CONST(0x0300000303010201), ABC_CONST(0x0300000300010201), ABC_CONST(0x0300000003010201), ABC_CONST(0x0300000000010201), ABC_CONST(0x0303030303010201), ABC_CONST(0x0303030300010201), ABC_CONST(0x0303030003010201), ABC_CONST(0x0303030000010201), ABC_CONST(0x0303000303010201), ABC_CONST(0x0303000300010201), ABC_CONST(0x0303000003010201), ABC_CONST(0x0303000000010201), ABC_CONST(0x0300030303010201), ABC_CONST(0x0300030300010201), ABC_CONST(0x0300030003010201), ABC_CONST(0x0300030000010201), ABC_CONST(0x0300000303010201), ABC_CONST(0x0300000300010201), ABC_CONST(0x0300000003010201), ABC_CONST(0x0300000000010201) }, + { ABC_CONST(0x0404040404020302), ABC_CONST(0x0404040400020302), ABC_CONST(0x0404040004020302), ABC_CONST(0x0404040000020302), ABC_CONST(0x0404000404020302), ABC_CONST(0x0404000400020302), ABC_CONST(0x0404000004020302), ABC_CONST(0x0404000000020302), ABC_CONST(0x0400040404020302), ABC_CONST(0x0400040400020302), ABC_CONST(0x0400040004020302), ABC_CONST(0x0400040000020302), ABC_CONST(0x0400000404020302), ABC_CONST(0x0400000400020302), ABC_CONST(0x0400000004020302), ABC_CONST(0x0400000000020302), ABC_CONST(0x0404040404020302), ABC_CONST(0x0404040400020302), ABC_CONST(0x0404040004020302), ABC_CONST(0x0404040000020302), ABC_CONST(0x0404000404020302), ABC_CONST(0x0404000400020302), ABC_CONST(0x0404000004020302), ABC_CONST(0x0404000000020302), ABC_CONST(0x0400040404020302), ABC_CONST(0x0400040400020302), ABC_CONST(0x0400040004020302), ABC_CONST(0x0400040000020302), ABC_CONST(0x0400000404020302), ABC_CONST(0x0400000400020302), ABC_CONST(0x0400000004020302), ABC_CONST(0x0400000000020302) }, + { ABC_CONST(0x0404040404020301), ABC_CONST(0x0404040400020301), ABC_CONST(0x0404040004020301), ABC_CONST(0x0404040000020301), ABC_CONST(0x0404000404020301), ABC_CONST(0x0404000400020301), ABC_CONST(0x0404000004020301), ABC_CONST(0x0404000000020301), ABC_CONST(0x0400040404020301), ABC_CONST(0x0400040400020301), ABC_CONST(0x0400040004020301), ABC_CONST(0x0400040000020301), ABC_CONST(0x0400000404020301), ABC_CONST(0x0400000400020301), ABC_CONST(0x0400000004020301), ABC_CONST(0x0400000000020301), ABC_CONST(0x0404040404020301), ABC_CONST(0x0404040400020301), ABC_CONST(0x0404040004020301), ABC_CONST(0x0404040000020301), ABC_CONST(0x0404000404020301), ABC_CONST(0x0404000400020301), ABC_CONST(0x0404000004020301), ABC_CONST(0x0404000000020301), ABC_CONST(0x0400040404020301), ABC_CONST(0x0400040400020301), ABC_CONST(0x0400040004020301), ABC_CONST(0x0400040000020301), ABC_CONST(0x0400000404020301), ABC_CONST(0x0400000400020301), ABC_CONST(0x0400000004020301), ABC_CONST(0x0400000000020301) }, + { ABC_CONST(0x0505050505030402), ABC_CONST(0x0505050500030402), ABC_CONST(0x0505050005030402), ABC_CONST(0x0505050000030402), ABC_CONST(0x0505000505030402), ABC_CONST(0x0505000500030402), ABC_CONST(0x0505000005030402), ABC_CONST(0x0505000000030402), ABC_CONST(0x0500050505030402), ABC_CONST(0x0500050500030402), ABC_CONST(0x0500050005030402), ABC_CONST(0x0500050000030402), ABC_CONST(0x0500000505030402), ABC_CONST(0x0500000500030402), ABC_CONST(0x0500000005030402), ABC_CONST(0x0500000000030402), ABC_CONST(0x0505050505030402), ABC_CONST(0x0505050500030402), ABC_CONST(0x0505050005030402), ABC_CONST(0x0505050000030402), ABC_CONST(0x0505000505030402), ABC_CONST(0x0505000500030402), ABC_CONST(0x0505000005030402), ABC_CONST(0x0505000000030402), ABC_CONST(0x0500050505030402), ABC_CONST(0x0500050500030402), ABC_CONST(0x0500050005030402), ABC_CONST(0x0500050000030402), ABC_CONST(0x0500000505030402), ABC_CONST(0x0500000500030402), ABC_CONST(0x0500000005030402), ABC_CONST(0x0500000000030402) }, + { ABC_CONST(0x0404040404020202), ABC_CONST(0x0404040400020202), ABC_CONST(0x0404040004020202), ABC_CONST(0x0404040000020202), ABC_CONST(0x0404000404020202), ABC_CONST(0x0404000400020202), ABC_CONST(0x0404000004020202), ABC_CONST(0x0404000000020202), ABC_CONST(0x0400040404020202), ABC_CONST(0x0400040400020202), ABC_CONST(0x0400040004020202), ABC_CONST(0x0400040000020202), ABC_CONST(0x0400000404020202), ABC_CONST(0x0400000400020202), ABC_CONST(0x0400000004020202), ABC_CONST(0x0400000000020202), ABC_CONST(0x0404040404020202), ABC_CONST(0x0404040400020202), ABC_CONST(0x0404040004020202), ABC_CONST(0x0404040000020202), ABC_CONST(0x0404000404020202), ABC_CONST(0x0404000400020202), ABC_CONST(0x0404000004020202), ABC_CONST(0x0404000000020202), ABC_CONST(0x0400040404020202), ABC_CONST(0x0400040400020202), ABC_CONST(0x0400040004020202), ABC_CONST(0x0400040000020202), ABC_CONST(0x0400000404020202), ABC_CONST(0x0400000400020202), ABC_CONST(0x0400000004020202), ABC_CONST(0x0400000000020202) }, + { ABC_CONST(0x0505050505030303), ABC_CONST(0x0505050500030303), ABC_CONST(0x0505050005030303), ABC_CONST(0x0505050000030303), ABC_CONST(0x0505000505030303), ABC_CONST(0x0505000500030303), ABC_CONST(0x0505000005030303), ABC_CONST(0x0505000000030303), ABC_CONST(0x0500050505030303), ABC_CONST(0x0500050500030303), ABC_CONST(0x0500050005030303), ABC_CONST(0x0500050000030303), ABC_CONST(0x0500000505030303), ABC_CONST(0x0500000500030303), ABC_CONST(0x0500000005030303), ABC_CONST(0x0500000000030303), ABC_CONST(0x0505050505030303), ABC_CONST(0x0505050500030303), ABC_CONST(0x0505050005030303), ABC_CONST(0x0505050000030303), ABC_CONST(0x0505000505030303), ABC_CONST(0x0505000500030303), ABC_CONST(0x0505000005030303), ABC_CONST(0x0505000000030303), ABC_CONST(0x0500050505030303), ABC_CONST(0x0500050500030303), ABC_CONST(0x0500050005030303), ABC_CONST(0x0500050000030303), ABC_CONST(0x0500000505030303), ABC_CONST(0x0500000500030303), ABC_CONST(0x0500000005030303), ABC_CONST(0x0500000000030303) }, + { ABC_CONST(0x0505050505030302), ABC_CONST(0x0505050500030302), ABC_CONST(0x0505050005030302), ABC_CONST(0x0505050000030302), ABC_CONST(0x0505000505030302), ABC_CONST(0x0505000500030302), ABC_CONST(0x0505000005030302), ABC_CONST(0x0505000000030302), ABC_CONST(0x0500050505030302), ABC_CONST(0x0500050500030302), ABC_CONST(0x0500050005030302), ABC_CONST(0x0500050000030302), ABC_CONST(0x0500000505030302), ABC_CONST(0x0500000500030302), ABC_CONST(0x0500000005030302), ABC_CONST(0x0500000000030302), ABC_CONST(0x0505050505030302), ABC_CONST(0x0505050500030302), ABC_CONST(0x0505050005030302), ABC_CONST(0x0505050000030302), ABC_CONST(0x0505000505030302), ABC_CONST(0x0505000500030302), ABC_CONST(0x0505000005030302), ABC_CONST(0x0505000000030302), ABC_CONST(0x0500050505030302), ABC_CONST(0x0500050500030302), ABC_CONST(0x0500050005030302), ABC_CONST(0x0500050000030302), ABC_CONST(0x0500000505030302), ABC_CONST(0x0500000500030302), ABC_CONST(0x0500000005030302), ABC_CONST(0x0500000000030302) }, + { ABC_CONST(0x0606060606040403), ABC_CONST(0x0606060600040403), ABC_CONST(0x0606060006040403), ABC_CONST(0x0606060000040403), ABC_CONST(0x0606000606040403), ABC_CONST(0x0606000600040403), ABC_CONST(0x0606000006040403), ABC_CONST(0x0606000000040403), ABC_CONST(0x0600060606040403), ABC_CONST(0x0600060600040403), ABC_CONST(0x0600060006040403), ABC_CONST(0x0600060000040403), ABC_CONST(0x0600000606040403), ABC_CONST(0x0600000600040403), ABC_CONST(0x0600000006040403), ABC_CONST(0x0600000000040403), ABC_CONST(0x0606060606040403), ABC_CONST(0x0606060600040403), ABC_CONST(0x0606060006040403), ABC_CONST(0x0606060000040403), ABC_CONST(0x0606000606040403), ABC_CONST(0x0606000600040403), ABC_CONST(0x0606000006040403), ABC_CONST(0x0606000000040403), ABC_CONST(0x0600060606040403), ABC_CONST(0x0600060600040403), ABC_CONST(0x0600060006040403), ABC_CONST(0x0600060000040403), ABC_CONST(0x0600000606040403), ABC_CONST(0x0600000600040403), ABC_CONST(0x0600000006040403), ABC_CONST(0x0600000000040403) }, + { ABC_CONST(0x0101010101000001), ABC_CONST(0x0101010100000001), ABC_CONST(0x0101010001000001), ABC_CONST(0x0101010000000001), ABC_CONST(0x0101000101000001), ABC_CONST(0x0101000100000001), ABC_CONST(0x0101000001000001), ABC_CONST(0x0101000000000001), ABC_CONST(0x0100010101000001), ABC_CONST(0x0100010100000001), ABC_CONST(0x0100010001000001), ABC_CONST(0x0100010000000001), ABC_CONST(0x0100000101000001), ABC_CONST(0x0100000100000001), ABC_CONST(0x0100000001000001), ABC_CONST(0x0100000000000001), ABC_CONST(0x0101010101000001), ABC_CONST(0x0101010100000001), ABC_CONST(0x0101010001000001), ABC_CONST(0x0101010000000001), ABC_CONST(0x0101000101000001), ABC_CONST(0x0101000100000001), ABC_CONST(0x0101000001000001), ABC_CONST(0x0101000000000001), ABC_CONST(0x0100010101000001), ABC_CONST(0x0100010100000001), ABC_CONST(0x0100010001000001), ABC_CONST(0x0100010000000001), ABC_CONST(0x0100000101000001), ABC_CONST(0x0100000100000001), ABC_CONST(0x0100000001000001), ABC_CONST(0x0100000000000001) }, + { ABC_CONST(0x0202020202010102), ABC_CONST(0x0202020200010102), ABC_CONST(0x0202020002010102), ABC_CONST(0x0202020000010102), ABC_CONST(0x0202000202010102), ABC_CONST(0x0202000200010102), ABC_CONST(0x0202000002010102), ABC_CONST(0x0202000000010102), ABC_CONST(0x0200020202010102), ABC_CONST(0x0200020200010102), ABC_CONST(0x0200020002010102), ABC_CONST(0x0200020000010102), ABC_CONST(0x0200000202010102), ABC_CONST(0x0200000200010102), ABC_CONST(0x0200000002010102), ABC_CONST(0x0200000000010102), ABC_CONST(0x0202020202010102), ABC_CONST(0x0202020200010102), ABC_CONST(0x0202020002010102), ABC_CONST(0x0202020000010102), ABC_CONST(0x0202000202010102), ABC_CONST(0x0202000200010102), ABC_CONST(0x0202000002010102), ABC_CONST(0x0202000000010102), ABC_CONST(0x0200020202010102), ABC_CONST(0x0200020200010102), ABC_CONST(0x0200020002010102), ABC_CONST(0x0200020000010102), ABC_CONST(0x0200000202010102), ABC_CONST(0x0200000200010102), ABC_CONST(0x0200000002010102), ABC_CONST(0x0200000000010102) }, + { ABC_CONST(0x0202020202010101), ABC_CONST(0x0202020200010101), ABC_CONST(0x0202020002010101), ABC_CONST(0x0202020000010101), ABC_CONST(0x0202000202010101), ABC_CONST(0x0202000200010101), ABC_CONST(0x0202000002010101), ABC_CONST(0x0202000000010101), ABC_CONST(0x0200020202010101), ABC_CONST(0x0200020200010101), ABC_CONST(0x0200020002010101), ABC_CONST(0x0200020000010101), ABC_CONST(0x0200000202010101), ABC_CONST(0x0200000200010101), ABC_CONST(0x0200000002010101), ABC_CONST(0x0200000000010101), ABC_CONST(0x0202020202010101), ABC_CONST(0x0202020200010101), ABC_CONST(0x0202020002010101), ABC_CONST(0x0202020000010101), ABC_CONST(0x0202000202010101), ABC_CONST(0x0202000200010101), ABC_CONST(0x0202000002010101), ABC_CONST(0x0202000000010101), ABC_CONST(0x0200020202010101), ABC_CONST(0x0200020200010101), ABC_CONST(0x0200020002010101), ABC_CONST(0x0200020000010101), ABC_CONST(0x0200000202010101), ABC_CONST(0x0200000200010101), ABC_CONST(0x0200000002010101), ABC_CONST(0x0200000000010101) }, + { ABC_CONST(0x0303030303020202), ABC_CONST(0x0303030300020202), ABC_CONST(0x0303030003020202), ABC_CONST(0x0303030000020202), ABC_CONST(0x0303000303020202), ABC_CONST(0x0303000300020202), ABC_CONST(0x0303000003020202), ABC_CONST(0x0303000000020202), ABC_CONST(0x0300030303020202), ABC_CONST(0x0300030300020202), ABC_CONST(0x0300030003020202), ABC_CONST(0x0300030000020202), ABC_CONST(0x0300000303020202), ABC_CONST(0x0300000300020202), ABC_CONST(0x0300000003020202), ABC_CONST(0x0300000000020202), ABC_CONST(0x0303030303020202), ABC_CONST(0x0303030300020202), ABC_CONST(0x0303030003020202), ABC_CONST(0x0303030000020202), ABC_CONST(0x0303000303020202), ABC_CONST(0x0303000300020202), ABC_CONST(0x0303000003020202), ABC_CONST(0x0303000000020202), ABC_CONST(0x0300030303020202), ABC_CONST(0x0300030300020202), ABC_CONST(0x0300030003020202), ABC_CONST(0x0300030000020202), ABC_CONST(0x0300000303020202), ABC_CONST(0x0300000300020202), ABC_CONST(0x0300000003020202), ABC_CONST(0x0300000000020202) }, + { ABC_CONST(0x0202020202010002), ABC_CONST(0x0202020200010002), ABC_CONST(0x0202020002010002), ABC_CONST(0x0202020000010002), ABC_CONST(0x0202000202010002), ABC_CONST(0x0202000200010002), ABC_CONST(0x0202000002010002), ABC_CONST(0x0202000000010002), ABC_CONST(0x0200020202010002), ABC_CONST(0x0200020200010002), ABC_CONST(0x0200020002010002), ABC_CONST(0x0200020000010002), ABC_CONST(0x0200000202010002), ABC_CONST(0x0200000200010002), ABC_CONST(0x0200000002010002), ABC_CONST(0x0200000000010002), ABC_CONST(0x0202020202010002), ABC_CONST(0x0202020200010002), ABC_CONST(0x0202020002010002), ABC_CONST(0x0202020000010002), ABC_CONST(0x0202000202010002), ABC_CONST(0x0202000200010002), ABC_CONST(0x0202000002010002), ABC_CONST(0x0202000000010002), ABC_CONST(0x0200020202010002), ABC_CONST(0x0200020200010002), ABC_CONST(0x0200020002010002), ABC_CONST(0x0200020000010002), ABC_CONST(0x0200000202010002), ABC_CONST(0x0200000200010002), ABC_CONST(0x0200000002010002), ABC_CONST(0x0200000000010002) }, + { ABC_CONST(0x0303030303020103), ABC_CONST(0x0303030300020103), ABC_CONST(0x0303030003020103), ABC_CONST(0x0303030000020103), ABC_CONST(0x0303000303020103), ABC_CONST(0x0303000300020103), ABC_CONST(0x0303000003020103), ABC_CONST(0x0303000000020103), ABC_CONST(0x0300030303020103), ABC_CONST(0x0300030300020103), ABC_CONST(0x0300030003020103), ABC_CONST(0x0300030000020103), ABC_CONST(0x0300000303020103), ABC_CONST(0x0300000300020103), ABC_CONST(0x0300000003020103), ABC_CONST(0x0300000000020103), ABC_CONST(0x0303030303020103), ABC_CONST(0x0303030300020103), ABC_CONST(0x0303030003020103), ABC_CONST(0x0303030000020103), ABC_CONST(0x0303000303020103), ABC_CONST(0x0303000300020103), ABC_CONST(0x0303000003020103), ABC_CONST(0x0303000000020103), ABC_CONST(0x0300030303020103), ABC_CONST(0x0300030300020103), ABC_CONST(0x0300030003020103), ABC_CONST(0x0300030000020103), ABC_CONST(0x0300000303020103), ABC_CONST(0x0300000300020103), ABC_CONST(0x0300000003020103), ABC_CONST(0x0300000000020103) }, + { ABC_CONST(0x0303030303020102), ABC_CONST(0x0303030300020102), ABC_CONST(0x0303030003020102), ABC_CONST(0x0303030000020102), ABC_CONST(0x0303000303020102), ABC_CONST(0x0303000300020102), ABC_CONST(0x0303000003020102), ABC_CONST(0x0303000000020102), ABC_CONST(0x0300030303020102), ABC_CONST(0x0300030300020102), ABC_CONST(0x0300030003020102), ABC_CONST(0x0300030000020102), ABC_CONST(0x0300000303020102), ABC_CONST(0x0300000300020102), ABC_CONST(0x0300000003020102), ABC_CONST(0x0300000000020102), ABC_CONST(0x0303030303020102), ABC_CONST(0x0303030300020102), ABC_CONST(0x0303030003020102), ABC_CONST(0x0303030000020102), ABC_CONST(0x0303000303020102), ABC_CONST(0x0303000300020102), ABC_CONST(0x0303000003020102), ABC_CONST(0x0303000000020102), ABC_CONST(0x0300030303020102), ABC_CONST(0x0300030300020102), ABC_CONST(0x0300030003020102), ABC_CONST(0x0300030000020102), ABC_CONST(0x0300000303020102), ABC_CONST(0x0300000300020102), ABC_CONST(0x0300000003020102), ABC_CONST(0x0300000000020102) }, + { ABC_CONST(0x0404040404030203), ABC_CONST(0x0404040400030203), ABC_CONST(0x0404040004030203), ABC_CONST(0x0404040000030203), ABC_CONST(0x0404000404030203), ABC_CONST(0x0404000400030203), ABC_CONST(0x0404000004030203), ABC_CONST(0x0404000000030203), ABC_CONST(0x0400040404030203), ABC_CONST(0x0400040400030203), ABC_CONST(0x0400040004030203), ABC_CONST(0x0400040000030203), ABC_CONST(0x0400000404030203), ABC_CONST(0x0400000400030203), ABC_CONST(0x0400000004030203), ABC_CONST(0x0400000000030203), ABC_CONST(0x0404040404030203), ABC_CONST(0x0404040400030203), ABC_CONST(0x0404040004030203), ABC_CONST(0x0404040000030203), ABC_CONST(0x0404000404030203), ABC_CONST(0x0404000400030203), ABC_CONST(0x0404000004030203), ABC_CONST(0x0404000000030203), ABC_CONST(0x0400040404030203), ABC_CONST(0x0400040400030203), ABC_CONST(0x0400040004030203), ABC_CONST(0x0400040000030203), ABC_CONST(0x0400000404030203), ABC_CONST(0x0400000400030203), ABC_CONST(0x0400000004030203), ABC_CONST(0x0400000000030203) }, + { ABC_CONST(0x0202020202010001), ABC_CONST(0x0202020200010001), ABC_CONST(0x0202020002010001), ABC_CONST(0x0202020000010001), ABC_CONST(0x0202000202010001), ABC_CONST(0x0202000200010001), ABC_CONST(0x0202000002010001), ABC_CONST(0x0202000000010001), ABC_CONST(0x0200020202010001), ABC_CONST(0x0200020200010001), ABC_CONST(0x0200020002010001), ABC_CONST(0x0200020000010001), ABC_CONST(0x0200000202010001), ABC_CONST(0x0200000200010001), ABC_CONST(0x0200000002010001), ABC_CONST(0x0200000000010001), ABC_CONST(0x0202020202010001), ABC_CONST(0x0202020200010001), ABC_CONST(0x0202020002010001), ABC_CONST(0x0202020000010001), ABC_CONST(0x0202000202010001), ABC_CONST(0x0202000200010001), ABC_CONST(0x0202000002010001), ABC_CONST(0x0202000000010001), ABC_CONST(0x0200020202010001), ABC_CONST(0x0200020200010001), ABC_CONST(0x0200020002010001), ABC_CONST(0x0200020000010001), ABC_CONST(0x0200000202010001), ABC_CONST(0x0200000200010001), ABC_CONST(0x0200000002010001), ABC_CONST(0x0200000000010001) }, + { ABC_CONST(0x0303030303020102), ABC_CONST(0x0303030300020102), ABC_CONST(0x0303030003020102), ABC_CONST(0x0303030000020102), ABC_CONST(0x0303000303020102), ABC_CONST(0x0303000300020102), ABC_CONST(0x0303000003020102), ABC_CONST(0x0303000000020102), ABC_CONST(0x0300030303020102), ABC_CONST(0x0300030300020102), ABC_CONST(0x0300030003020102), ABC_CONST(0x0300030000020102), ABC_CONST(0x0300000303020102), ABC_CONST(0x0300000300020102), ABC_CONST(0x0300000003020102), ABC_CONST(0x0300000000020102), ABC_CONST(0x0303030303020102), ABC_CONST(0x0303030300020102), ABC_CONST(0x0303030003020102), ABC_CONST(0x0303030000020102), ABC_CONST(0x0303000303020102), ABC_CONST(0x0303000300020102), ABC_CONST(0x0303000003020102), ABC_CONST(0x0303000000020102), ABC_CONST(0x0300030303020102), ABC_CONST(0x0300030300020102), ABC_CONST(0x0300030003020102), ABC_CONST(0x0300030000020102), ABC_CONST(0x0300000303020102), ABC_CONST(0x0300000300020102), ABC_CONST(0x0300000003020102), ABC_CONST(0x0300000000020102) }, + { ABC_CONST(0x0303030303020101), ABC_CONST(0x0303030300020101), ABC_CONST(0x0303030003020101), ABC_CONST(0x0303030000020101), ABC_CONST(0x0303000303020101), ABC_CONST(0x0303000300020101), ABC_CONST(0x0303000003020101), ABC_CONST(0x0303000000020101), ABC_CONST(0x0300030303020101), ABC_CONST(0x0300030300020101), ABC_CONST(0x0300030003020101), ABC_CONST(0x0300030000020101), ABC_CONST(0x0300000303020101), ABC_CONST(0x0300000300020101), ABC_CONST(0x0300000003020101), ABC_CONST(0x0300000000020101), ABC_CONST(0x0303030303020101), ABC_CONST(0x0303030300020101), ABC_CONST(0x0303030003020101), ABC_CONST(0x0303030000020101), ABC_CONST(0x0303000303020101), ABC_CONST(0x0303000300020101), ABC_CONST(0x0303000003020101), ABC_CONST(0x0303000000020101), ABC_CONST(0x0300030303020101), ABC_CONST(0x0300030300020101), ABC_CONST(0x0300030003020101), ABC_CONST(0x0300030000020101), ABC_CONST(0x0300000303020101), ABC_CONST(0x0300000300020101), ABC_CONST(0x0300000003020101), ABC_CONST(0x0300000000020101) }, + { ABC_CONST(0x0404040404030202), ABC_CONST(0x0404040400030202), ABC_CONST(0x0404040004030202), ABC_CONST(0x0404040000030202), ABC_CONST(0x0404000404030202), ABC_CONST(0x0404000400030202), ABC_CONST(0x0404000004030202), ABC_CONST(0x0404000000030202), ABC_CONST(0x0400040404030202), ABC_CONST(0x0400040400030202), ABC_CONST(0x0400040004030202), ABC_CONST(0x0400040000030202), ABC_CONST(0x0400000404030202), ABC_CONST(0x0400000400030202), ABC_CONST(0x0400000004030202), ABC_CONST(0x0400000000030202), ABC_CONST(0x0404040404030202), ABC_CONST(0x0404040400030202), ABC_CONST(0x0404040004030202), ABC_CONST(0x0404040000030202), ABC_CONST(0x0404000404030202), ABC_CONST(0x0404000400030202), ABC_CONST(0x0404000004030202), ABC_CONST(0x0404000000030202), ABC_CONST(0x0400040404030202), ABC_CONST(0x0400040400030202), ABC_CONST(0x0400040004030202), ABC_CONST(0x0400040000030202), ABC_CONST(0x0400000404030202), ABC_CONST(0x0400000400030202), ABC_CONST(0x0400000004030202), ABC_CONST(0x0400000000030202) }, + { ABC_CONST(0x0303030303020002), ABC_CONST(0x0303030300020002), ABC_CONST(0x0303030003020002), ABC_CONST(0x0303030000020002), ABC_CONST(0x0303000303020002), ABC_CONST(0x0303000300020002), ABC_CONST(0x0303000003020002), ABC_CONST(0x0303000000020002), ABC_CONST(0x0300030303020002), ABC_CONST(0x0300030300020002), ABC_CONST(0x0300030003020002), ABC_CONST(0x0300030000020002), ABC_CONST(0x0300000303020002), ABC_CONST(0x0300000300020002), ABC_CONST(0x0300000003020002), ABC_CONST(0x0300000000020002), ABC_CONST(0x0303030303020002), ABC_CONST(0x0303030300020002), ABC_CONST(0x0303030003020002), ABC_CONST(0x0303030000020002), ABC_CONST(0x0303000303020002), ABC_CONST(0x0303000300020002), ABC_CONST(0x0303000003020002), ABC_CONST(0x0303000000020002), ABC_CONST(0x0300030303020002), ABC_CONST(0x0300030300020002), ABC_CONST(0x0300030003020002), ABC_CONST(0x0300030000020002), ABC_CONST(0x0300000303020002), ABC_CONST(0x0300000300020002), ABC_CONST(0x0300000003020002), ABC_CONST(0x0300000000020002) }, + { ABC_CONST(0x0404040404030103), ABC_CONST(0x0404040400030103), ABC_CONST(0x0404040004030103), ABC_CONST(0x0404040000030103), ABC_CONST(0x0404000404030103), ABC_CONST(0x0404000400030103), ABC_CONST(0x0404000004030103), ABC_CONST(0x0404000000030103), ABC_CONST(0x0400040404030103), ABC_CONST(0x0400040400030103), ABC_CONST(0x0400040004030103), ABC_CONST(0x0400040000030103), ABC_CONST(0x0400000404030103), ABC_CONST(0x0400000400030103), ABC_CONST(0x0400000004030103), ABC_CONST(0x0400000000030103), ABC_CONST(0x0404040404030103), ABC_CONST(0x0404040400030103), ABC_CONST(0x0404040004030103), ABC_CONST(0x0404040000030103), ABC_CONST(0x0404000404030103), ABC_CONST(0x0404000400030103), ABC_CONST(0x0404000004030103), ABC_CONST(0x0404000000030103), ABC_CONST(0x0400040404030103), ABC_CONST(0x0400040400030103), ABC_CONST(0x0400040004030103), ABC_CONST(0x0400040000030103), ABC_CONST(0x0400000404030103), ABC_CONST(0x0400000400030103), ABC_CONST(0x0400000004030103), ABC_CONST(0x0400000000030103) }, + { ABC_CONST(0x0404040404030102), ABC_CONST(0x0404040400030102), ABC_CONST(0x0404040004030102), ABC_CONST(0x0404040000030102), ABC_CONST(0x0404000404030102), ABC_CONST(0x0404000400030102), ABC_CONST(0x0404000004030102), ABC_CONST(0x0404000000030102), ABC_CONST(0x0400040404030102), ABC_CONST(0x0400040400030102), ABC_CONST(0x0400040004030102), ABC_CONST(0x0400040000030102), ABC_CONST(0x0400000404030102), ABC_CONST(0x0400000400030102), ABC_CONST(0x0400000004030102), ABC_CONST(0x0400000000030102), ABC_CONST(0x0404040404030102), ABC_CONST(0x0404040400030102), ABC_CONST(0x0404040004030102), ABC_CONST(0x0404040000030102), ABC_CONST(0x0404000404030102), ABC_CONST(0x0404000400030102), ABC_CONST(0x0404000004030102), ABC_CONST(0x0404000000030102), ABC_CONST(0x0400040404030102), ABC_CONST(0x0400040400030102), ABC_CONST(0x0400040004030102), ABC_CONST(0x0400040000030102), ABC_CONST(0x0400000404030102), ABC_CONST(0x0400000400030102), ABC_CONST(0x0400000004030102), ABC_CONST(0x0400000000030102) }, + { ABC_CONST(0x0505050505040203), ABC_CONST(0x0505050500040203), ABC_CONST(0x0505050005040203), ABC_CONST(0x0505050000040203), ABC_CONST(0x0505000505040203), ABC_CONST(0x0505000500040203), ABC_CONST(0x0505000005040203), ABC_CONST(0x0505000000040203), ABC_CONST(0x0500050505040203), ABC_CONST(0x0500050500040203), ABC_CONST(0x0500050005040203), ABC_CONST(0x0500050000040203), ABC_CONST(0x0500000505040203), ABC_CONST(0x0500000500040203), ABC_CONST(0x0500000005040203), ABC_CONST(0x0500000000040203), ABC_CONST(0x0505050505040203), ABC_CONST(0x0505050500040203), ABC_CONST(0x0505050005040203), ABC_CONST(0x0505050000040203), ABC_CONST(0x0505000505040203), ABC_CONST(0x0505000500040203), ABC_CONST(0x0505000005040203), ABC_CONST(0x0505000000040203), ABC_CONST(0x0500050505040203), ABC_CONST(0x0500050500040203), ABC_CONST(0x0500050005040203), ABC_CONST(0x0500050000040203), ABC_CONST(0x0500000505040203), ABC_CONST(0x0500000500040203), ABC_CONST(0x0500000005040203), ABC_CONST(0x0500000000040203) }, + { ABC_CONST(0x0202020202000102), ABC_CONST(0x0202020200000102), ABC_CONST(0x0202020002000102), ABC_CONST(0x0202020000000102), ABC_CONST(0x0202000202000102), ABC_CONST(0x0202000200000102), ABC_CONST(0x0202000002000102), ABC_CONST(0x0202000000000102), ABC_CONST(0x0200020202000102), ABC_CONST(0x0200020200000102), ABC_CONST(0x0200020002000102), ABC_CONST(0x0200020000000102), ABC_CONST(0x0200000202000102), ABC_CONST(0x0200000200000102), ABC_CONST(0x0200000002000102), ABC_CONST(0x0200000000000102), ABC_CONST(0x0202020202000102), ABC_CONST(0x0202020200000102), ABC_CONST(0x0202020002000102), ABC_CONST(0x0202020000000102), ABC_CONST(0x0202000202000102), ABC_CONST(0x0202000200000102), ABC_CONST(0x0202000002000102), ABC_CONST(0x0202000000000102), ABC_CONST(0x0200020202000102), ABC_CONST(0x0200020200000102), ABC_CONST(0x0200020002000102), ABC_CONST(0x0200020000000102), ABC_CONST(0x0200000202000102), ABC_CONST(0x0200000200000102), ABC_CONST(0x0200000002000102), ABC_CONST(0x0200000000000102) }, + { ABC_CONST(0x0303030303010203), ABC_CONST(0x0303030300010203), ABC_CONST(0x0303030003010203), ABC_CONST(0x0303030000010203), ABC_CONST(0x0303000303010203), ABC_CONST(0x0303000300010203), ABC_CONST(0x0303000003010203), ABC_CONST(0x0303000000010203), ABC_CONST(0x0300030303010203), ABC_CONST(0x0300030300010203), ABC_CONST(0x0300030003010203), ABC_CONST(0x0300030000010203), ABC_CONST(0x0300000303010203), ABC_CONST(0x0300000300010203), ABC_CONST(0x0300000003010203), ABC_CONST(0x0300000000010203), ABC_CONST(0x0303030303010203), ABC_CONST(0x0303030300010203), ABC_CONST(0x0303030003010203), ABC_CONST(0x0303030000010203), ABC_CONST(0x0303000303010203), ABC_CONST(0x0303000300010203), ABC_CONST(0x0303000003010203), ABC_CONST(0x0303000000010203), ABC_CONST(0x0300030303010203), ABC_CONST(0x0300030300010203), ABC_CONST(0x0300030003010203), ABC_CONST(0x0300030000010203), ABC_CONST(0x0300000303010203), ABC_CONST(0x0300000300010203), ABC_CONST(0x0300000003010203), ABC_CONST(0x0300000000010203) }, + { ABC_CONST(0x0303030303010202), ABC_CONST(0x0303030300010202), ABC_CONST(0x0303030003010202), ABC_CONST(0x0303030000010202), ABC_CONST(0x0303000303010202), ABC_CONST(0x0303000300010202), ABC_CONST(0x0303000003010202), ABC_CONST(0x0303000000010202), ABC_CONST(0x0300030303010202), ABC_CONST(0x0300030300010202), ABC_CONST(0x0300030003010202), ABC_CONST(0x0300030000010202), ABC_CONST(0x0300000303010202), ABC_CONST(0x0300000300010202), ABC_CONST(0x0300000003010202), ABC_CONST(0x0300000000010202), ABC_CONST(0x0303030303010202), ABC_CONST(0x0303030300010202), ABC_CONST(0x0303030003010202), ABC_CONST(0x0303030000010202), ABC_CONST(0x0303000303010202), ABC_CONST(0x0303000300010202), ABC_CONST(0x0303000003010202), ABC_CONST(0x0303000000010202), ABC_CONST(0x0300030303010202), ABC_CONST(0x0300030300010202), ABC_CONST(0x0300030003010202), ABC_CONST(0x0300030000010202), ABC_CONST(0x0300000303010202), ABC_CONST(0x0300000300010202), ABC_CONST(0x0300000003010202), ABC_CONST(0x0300000000010202) }, + { ABC_CONST(0x0404040404020303), ABC_CONST(0x0404040400020303), ABC_CONST(0x0404040004020303), ABC_CONST(0x0404040000020303), ABC_CONST(0x0404000404020303), ABC_CONST(0x0404000400020303), ABC_CONST(0x0404000004020303), ABC_CONST(0x0404000000020303), ABC_CONST(0x0400040404020303), ABC_CONST(0x0400040400020303), ABC_CONST(0x0400040004020303), ABC_CONST(0x0400040000020303), ABC_CONST(0x0400000404020303), ABC_CONST(0x0400000400020303), ABC_CONST(0x0400000004020303), ABC_CONST(0x0400000000020303), ABC_CONST(0x0404040404020303), ABC_CONST(0x0404040400020303), ABC_CONST(0x0404040004020303), ABC_CONST(0x0404040000020303), ABC_CONST(0x0404000404020303), ABC_CONST(0x0404000400020303), ABC_CONST(0x0404000004020303), ABC_CONST(0x0404000000020303), ABC_CONST(0x0400040404020303), ABC_CONST(0x0400040400020303), ABC_CONST(0x0400040004020303), ABC_CONST(0x0400040000020303), ABC_CONST(0x0400000404020303), ABC_CONST(0x0400000400020303), ABC_CONST(0x0400000004020303), ABC_CONST(0x0400000000020303) }, + { ABC_CONST(0x0303030303010103), ABC_CONST(0x0303030300010103), ABC_CONST(0x0303030003010103), ABC_CONST(0x0303030000010103), ABC_CONST(0x0303000303010103), ABC_CONST(0x0303000300010103), ABC_CONST(0x0303000003010103), ABC_CONST(0x0303000000010103), ABC_CONST(0x0300030303010103), ABC_CONST(0x0300030300010103), ABC_CONST(0x0300030003010103), ABC_CONST(0x0300030000010103), ABC_CONST(0x0300000303010103), ABC_CONST(0x0300000300010103), ABC_CONST(0x0300000003010103), ABC_CONST(0x0300000000010103), ABC_CONST(0x0303030303010103), ABC_CONST(0x0303030300010103), ABC_CONST(0x0303030003010103), ABC_CONST(0x0303030000010103), ABC_CONST(0x0303000303010103), ABC_CONST(0x0303000300010103), ABC_CONST(0x0303000003010103), ABC_CONST(0x0303000000010103), ABC_CONST(0x0300030303010103), ABC_CONST(0x0300030300010103), ABC_CONST(0x0300030003010103), ABC_CONST(0x0300030000010103), ABC_CONST(0x0300000303010103), ABC_CONST(0x0300000300010103), ABC_CONST(0x0300000003010103), ABC_CONST(0x0300000000010103) }, + { ABC_CONST(0x0404040404020204), ABC_CONST(0x0404040400020204), ABC_CONST(0x0404040004020204), ABC_CONST(0x0404040000020204), ABC_CONST(0x0404000404020204), ABC_CONST(0x0404000400020204), ABC_CONST(0x0404000004020204), ABC_CONST(0x0404000000020204), ABC_CONST(0x0400040404020204), ABC_CONST(0x0400040400020204), ABC_CONST(0x0400040004020204), ABC_CONST(0x0400040000020204), ABC_CONST(0x0400000404020204), ABC_CONST(0x0400000400020204), ABC_CONST(0x0400000004020204), ABC_CONST(0x0400000000020204), ABC_CONST(0x0404040404020204), ABC_CONST(0x0404040400020204), ABC_CONST(0x0404040004020204), ABC_CONST(0x0404040000020204), ABC_CONST(0x0404000404020204), ABC_CONST(0x0404000400020204), ABC_CONST(0x0404000004020204), ABC_CONST(0x0404000000020204), ABC_CONST(0x0400040404020204), ABC_CONST(0x0400040400020204), ABC_CONST(0x0400040004020204), ABC_CONST(0x0400040000020204), ABC_CONST(0x0400000404020204), ABC_CONST(0x0400000400020204), ABC_CONST(0x0400000004020204), ABC_CONST(0x0400000000020204) }, + { ABC_CONST(0x0404040404020203), ABC_CONST(0x0404040400020203), ABC_CONST(0x0404040004020203), ABC_CONST(0x0404040000020203), ABC_CONST(0x0404000404020203), ABC_CONST(0x0404000400020203), ABC_CONST(0x0404000004020203), ABC_CONST(0x0404000000020203), ABC_CONST(0x0400040404020203), ABC_CONST(0x0400040400020203), ABC_CONST(0x0400040004020203), ABC_CONST(0x0400040000020203), ABC_CONST(0x0400000404020203), ABC_CONST(0x0400000400020203), ABC_CONST(0x0400000004020203), ABC_CONST(0x0400000000020203), ABC_CONST(0x0404040404020203), ABC_CONST(0x0404040400020203), ABC_CONST(0x0404040004020203), ABC_CONST(0x0404040000020203), ABC_CONST(0x0404000404020203), ABC_CONST(0x0404000400020203), ABC_CONST(0x0404000004020203), ABC_CONST(0x0404000000020203), ABC_CONST(0x0400040404020203), ABC_CONST(0x0400040400020203), ABC_CONST(0x0400040004020203), ABC_CONST(0x0400040000020203), ABC_CONST(0x0400000404020203), ABC_CONST(0x0400000400020203), ABC_CONST(0x0400000004020203), ABC_CONST(0x0400000000020203) }, + { ABC_CONST(0x0505050505030304), ABC_CONST(0x0505050500030304), ABC_CONST(0x0505050005030304), ABC_CONST(0x0505050000030304), ABC_CONST(0x0505000505030304), ABC_CONST(0x0505000500030304), ABC_CONST(0x0505000005030304), ABC_CONST(0x0505000000030304), ABC_CONST(0x0500050505030304), ABC_CONST(0x0500050500030304), ABC_CONST(0x0500050005030304), ABC_CONST(0x0500050000030304), ABC_CONST(0x0500000505030304), ABC_CONST(0x0500000500030304), ABC_CONST(0x0500000005030304), ABC_CONST(0x0500000000030304), ABC_CONST(0x0505050505030304), ABC_CONST(0x0505050500030304), ABC_CONST(0x0505050005030304), ABC_CONST(0x0505050000030304), ABC_CONST(0x0505000505030304), ABC_CONST(0x0505000500030304), ABC_CONST(0x0505000005030304), ABC_CONST(0x0505000000030304), ABC_CONST(0x0500050505030304), ABC_CONST(0x0500050500030304), ABC_CONST(0x0500050005030304), ABC_CONST(0x0500050000030304), ABC_CONST(0x0500000505030304), ABC_CONST(0x0500000500030304), ABC_CONST(0x0500000005030304), ABC_CONST(0x0500000000030304) }, + { ABC_CONST(0x0303030303010102), ABC_CONST(0x0303030300010102), ABC_CONST(0x0303030003010102), ABC_CONST(0x0303030000010102), ABC_CONST(0x0303000303010102), ABC_CONST(0x0303000300010102), ABC_CONST(0x0303000003010102), ABC_CONST(0x0303000000010102), ABC_CONST(0x0300030303010102), ABC_CONST(0x0300030300010102), ABC_CONST(0x0300030003010102), ABC_CONST(0x0300030000010102), ABC_CONST(0x0300000303010102), ABC_CONST(0x0300000300010102), ABC_CONST(0x0300000003010102), ABC_CONST(0x0300000000010102), ABC_CONST(0x0303030303010102), ABC_CONST(0x0303030300010102), ABC_CONST(0x0303030003010102), ABC_CONST(0x0303030000010102), ABC_CONST(0x0303000303010102), ABC_CONST(0x0303000300010102), ABC_CONST(0x0303000003010102), ABC_CONST(0x0303000000010102), ABC_CONST(0x0300030303010102), ABC_CONST(0x0300030300010102), ABC_CONST(0x0300030003010102), ABC_CONST(0x0300030000010102), ABC_CONST(0x0300000303010102), ABC_CONST(0x0300000300010102), ABC_CONST(0x0300000003010102), ABC_CONST(0x0300000000010102) }, + { ABC_CONST(0x0404040404020203), ABC_CONST(0x0404040400020203), ABC_CONST(0x0404040004020203), ABC_CONST(0x0404040000020203), ABC_CONST(0x0404000404020203), ABC_CONST(0x0404000400020203), ABC_CONST(0x0404000004020203), ABC_CONST(0x0404000000020203), ABC_CONST(0x0400040404020203), ABC_CONST(0x0400040400020203), ABC_CONST(0x0400040004020203), ABC_CONST(0x0400040000020203), ABC_CONST(0x0400000404020203), ABC_CONST(0x0400000400020203), ABC_CONST(0x0400000004020203), ABC_CONST(0x0400000000020203), ABC_CONST(0x0404040404020203), ABC_CONST(0x0404040400020203), ABC_CONST(0x0404040004020203), ABC_CONST(0x0404040000020203), ABC_CONST(0x0404000404020203), ABC_CONST(0x0404000400020203), ABC_CONST(0x0404000004020203), ABC_CONST(0x0404000000020203), ABC_CONST(0x0400040404020203), ABC_CONST(0x0400040400020203), ABC_CONST(0x0400040004020203), ABC_CONST(0x0400040000020203), ABC_CONST(0x0400000404020203), ABC_CONST(0x0400000400020203), ABC_CONST(0x0400000004020203), ABC_CONST(0x0400000000020203) }, + { ABC_CONST(0x0404040404020202), ABC_CONST(0x0404040400020202), ABC_CONST(0x0404040004020202), ABC_CONST(0x0404040000020202), ABC_CONST(0x0404000404020202), ABC_CONST(0x0404000400020202), ABC_CONST(0x0404000004020202), ABC_CONST(0x0404000000020202), ABC_CONST(0x0400040404020202), ABC_CONST(0x0400040400020202), ABC_CONST(0x0400040004020202), ABC_CONST(0x0400040000020202), ABC_CONST(0x0400000404020202), ABC_CONST(0x0400000400020202), ABC_CONST(0x0400000004020202), ABC_CONST(0x0400000000020202), ABC_CONST(0x0404040404020202), ABC_CONST(0x0404040400020202), ABC_CONST(0x0404040004020202), ABC_CONST(0x0404040000020202), ABC_CONST(0x0404000404020202), ABC_CONST(0x0404000400020202), ABC_CONST(0x0404000004020202), ABC_CONST(0x0404000000020202), ABC_CONST(0x0400040404020202), ABC_CONST(0x0400040400020202), ABC_CONST(0x0400040004020202), ABC_CONST(0x0400040000020202), ABC_CONST(0x0400000404020202), ABC_CONST(0x0400000400020202), ABC_CONST(0x0400000004020202), ABC_CONST(0x0400000000020202) }, + { ABC_CONST(0x0505050505030303), ABC_CONST(0x0505050500030303), ABC_CONST(0x0505050005030303), ABC_CONST(0x0505050000030303), ABC_CONST(0x0505000505030303), ABC_CONST(0x0505000500030303), ABC_CONST(0x0505000005030303), ABC_CONST(0x0505000000030303), ABC_CONST(0x0500050505030303), ABC_CONST(0x0500050500030303), ABC_CONST(0x0500050005030303), ABC_CONST(0x0500050000030303), ABC_CONST(0x0500000505030303), ABC_CONST(0x0500000500030303), ABC_CONST(0x0500000005030303), ABC_CONST(0x0500000000030303), ABC_CONST(0x0505050505030303), ABC_CONST(0x0505050500030303), ABC_CONST(0x0505050005030303), ABC_CONST(0x0505050000030303), ABC_CONST(0x0505000505030303), ABC_CONST(0x0505000500030303), ABC_CONST(0x0505000005030303), ABC_CONST(0x0505000000030303), ABC_CONST(0x0500050505030303), ABC_CONST(0x0500050500030303), ABC_CONST(0x0500050005030303), ABC_CONST(0x0500050000030303), ABC_CONST(0x0500000505030303), ABC_CONST(0x0500000500030303), ABC_CONST(0x0500000005030303), ABC_CONST(0x0500000000030303) }, + { ABC_CONST(0x0404040404020103), ABC_CONST(0x0404040400020103), ABC_CONST(0x0404040004020103), ABC_CONST(0x0404040000020103), ABC_CONST(0x0404000404020103), ABC_CONST(0x0404000400020103), ABC_CONST(0x0404000004020103), ABC_CONST(0x0404000000020103), ABC_CONST(0x0400040404020103), ABC_CONST(0x0400040400020103), ABC_CONST(0x0400040004020103), ABC_CONST(0x0400040000020103), ABC_CONST(0x0400000404020103), ABC_CONST(0x0400000400020103), ABC_CONST(0x0400000004020103), ABC_CONST(0x0400000000020103), ABC_CONST(0x0404040404020103), ABC_CONST(0x0404040400020103), ABC_CONST(0x0404040004020103), ABC_CONST(0x0404040000020103), ABC_CONST(0x0404000404020103), ABC_CONST(0x0404000400020103), ABC_CONST(0x0404000004020103), ABC_CONST(0x0404000000020103), ABC_CONST(0x0400040404020103), ABC_CONST(0x0400040400020103), ABC_CONST(0x0400040004020103), ABC_CONST(0x0400040000020103), ABC_CONST(0x0400000404020103), ABC_CONST(0x0400000400020103), ABC_CONST(0x0400000004020103), ABC_CONST(0x0400000000020103) }, + { ABC_CONST(0x0505050505030204), ABC_CONST(0x0505050500030204), ABC_CONST(0x0505050005030204), ABC_CONST(0x0505050000030204), ABC_CONST(0x0505000505030204), ABC_CONST(0x0505000500030204), ABC_CONST(0x0505000005030204), ABC_CONST(0x0505000000030204), ABC_CONST(0x0500050505030204), ABC_CONST(0x0500050500030204), ABC_CONST(0x0500050005030204), ABC_CONST(0x0500050000030204), ABC_CONST(0x0500000505030204), ABC_CONST(0x0500000500030204), ABC_CONST(0x0500000005030204), ABC_CONST(0x0500000000030204), ABC_CONST(0x0505050505030204), ABC_CONST(0x0505050500030204), ABC_CONST(0x0505050005030204), ABC_CONST(0x0505050000030204), ABC_CONST(0x0505000505030204), ABC_CONST(0x0505000500030204), ABC_CONST(0x0505000005030204), ABC_CONST(0x0505000000030204), ABC_CONST(0x0500050505030204), ABC_CONST(0x0500050500030204), ABC_CONST(0x0500050005030204), ABC_CONST(0x0500050000030204), ABC_CONST(0x0500000505030204), ABC_CONST(0x0500000500030204), ABC_CONST(0x0500000005030204), ABC_CONST(0x0500000000030204) }, + { ABC_CONST(0x0505050505030203), ABC_CONST(0x0505050500030203), ABC_CONST(0x0505050005030203), ABC_CONST(0x0505050000030203), ABC_CONST(0x0505000505030203), ABC_CONST(0x0505000500030203), ABC_CONST(0x0505000005030203), ABC_CONST(0x0505000000030203), ABC_CONST(0x0500050505030203), ABC_CONST(0x0500050500030203), ABC_CONST(0x0500050005030203), ABC_CONST(0x0500050000030203), ABC_CONST(0x0500000505030203), ABC_CONST(0x0500000500030203), ABC_CONST(0x0500000005030203), ABC_CONST(0x0500000000030203), ABC_CONST(0x0505050505030203), ABC_CONST(0x0505050500030203), ABC_CONST(0x0505050005030203), ABC_CONST(0x0505050000030203), ABC_CONST(0x0505000505030203), ABC_CONST(0x0505000500030203), ABC_CONST(0x0505000005030203), ABC_CONST(0x0505000000030203), ABC_CONST(0x0500050505030203), ABC_CONST(0x0500050500030203), ABC_CONST(0x0500050005030203), ABC_CONST(0x0500050000030203), ABC_CONST(0x0500000505030203), ABC_CONST(0x0500000500030203), ABC_CONST(0x0500000005030203), ABC_CONST(0x0500000000030203) }, + { ABC_CONST(0x0606060606040304), ABC_CONST(0x0606060600040304), ABC_CONST(0x0606060006040304), ABC_CONST(0x0606060000040304), ABC_CONST(0x0606000606040304), ABC_CONST(0x0606000600040304), ABC_CONST(0x0606000006040304), ABC_CONST(0x0606000000040304), ABC_CONST(0x0600060606040304), ABC_CONST(0x0600060600040304), ABC_CONST(0x0600060006040304), ABC_CONST(0x0600060000040304), ABC_CONST(0x0600000606040304), ABC_CONST(0x0600000600040304), ABC_CONST(0x0600000006040304), ABC_CONST(0x0600000000040304), ABC_CONST(0x0606060606040304), ABC_CONST(0x0606060600040304), ABC_CONST(0x0606060006040304), ABC_CONST(0x0606060000040304), ABC_CONST(0x0606000606040304), ABC_CONST(0x0606000600040304), ABC_CONST(0x0606000006040304), ABC_CONST(0x0606000000040304), ABC_CONST(0x0600060606040304), ABC_CONST(0x0600060600040304), ABC_CONST(0x0600060006040304), ABC_CONST(0x0600060000040304), ABC_CONST(0x0600000606040304), ABC_CONST(0x0600000600040304), ABC_CONST(0x0600000006040304), ABC_CONST(0x0600000000040304) }, + { ABC_CONST(0x0202020202000101), ABC_CONST(0x0202020200000101), ABC_CONST(0x0202020002000101), ABC_CONST(0x0202020000000101), ABC_CONST(0x0202000202000101), ABC_CONST(0x0202000200000101), ABC_CONST(0x0202000002000101), ABC_CONST(0x0202000000000101), ABC_CONST(0x0200020202000101), ABC_CONST(0x0200020200000101), ABC_CONST(0x0200020002000101), ABC_CONST(0x0200020000000101), ABC_CONST(0x0200000202000101), ABC_CONST(0x0200000200000101), ABC_CONST(0x0200000002000101), ABC_CONST(0x0200000000000101), ABC_CONST(0x0202020202000101), ABC_CONST(0x0202020200000101), ABC_CONST(0x0202020002000101), ABC_CONST(0x0202020000000101), ABC_CONST(0x0202000202000101), ABC_CONST(0x0202000200000101), ABC_CONST(0x0202000002000101), ABC_CONST(0x0202000000000101), ABC_CONST(0x0200020202000101), ABC_CONST(0x0200020200000101), ABC_CONST(0x0200020002000101), ABC_CONST(0x0200020000000101), ABC_CONST(0x0200000202000101), ABC_CONST(0x0200000200000101), ABC_CONST(0x0200000002000101), ABC_CONST(0x0200000000000101) }, + { ABC_CONST(0x0303030303010202), ABC_CONST(0x0303030300010202), ABC_CONST(0x0303030003010202), ABC_CONST(0x0303030000010202), ABC_CONST(0x0303000303010202), ABC_CONST(0x0303000300010202), ABC_CONST(0x0303000003010202), ABC_CONST(0x0303000000010202), ABC_CONST(0x0300030303010202), ABC_CONST(0x0300030300010202), ABC_CONST(0x0300030003010202), ABC_CONST(0x0300030000010202), ABC_CONST(0x0300000303010202), ABC_CONST(0x0300000300010202), ABC_CONST(0x0300000003010202), ABC_CONST(0x0300000000010202), ABC_CONST(0x0303030303010202), ABC_CONST(0x0303030300010202), ABC_CONST(0x0303030003010202), ABC_CONST(0x0303030000010202), ABC_CONST(0x0303000303010202), ABC_CONST(0x0303000300010202), ABC_CONST(0x0303000003010202), ABC_CONST(0x0303000000010202), ABC_CONST(0x0300030303010202), ABC_CONST(0x0300030300010202), ABC_CONST(0x0300030003010202), ABC_CONST(0x0300030000010202), ABC_CONST(0x0300000303010202), ABC_CONST(0x0300000300010202), ABC_CONST(0x0300000003010202), ABC_CONST(0x0300000000010202) }, + { ABC_CONST(0x0303030303010201), ABC_CONST(0x0303030300010201), ABC_CONST(0x0303030003010201), ABC_CONST(0x0303030000010201), ABC_CONST(0x0303000303010201), ABC_CONST(0x0303000300010201), ABC_CONST(0x0303000003010201), ABC_CONST(0x0303000000010201), ABC_CONST(0x0300030303010201), ABC_CONST(0x0300030300010201), ABC_CONST(0x0300030003010201), ABC_CONST(0x0300030000010201), ABC_CONST(0x0300000303010201), ABC_CONST(0x0300000300010201), ABC_CONST(0x0300000003010201), ABC_CONST(0x0300000000010201), ABC_CONST(0x0303030303010201), ABC_CONST(0x0303030300010201), ABC_CONST(0x0303030003010201), ABC_CONST(0x0303030000010201), ABC_CONST(0x0303000303010201), ABC_CONST(0x0303000300010201), ABC_CONST(0x0303000003010201), ABC_CONST(0x0303000000010201), ABC_CONST(0x0300030303010201), ABC_CONST(0x0300030300010201), ABC_CONST(0x0300030003010201), ABC_CONST(0x0300030000010201), ABC_CONST(0x0300000303010201), ABC_CONST(0x0300000300010201), ABC_CONST(0x0300000003010201), ABC_CONST(0x0300000000010201) }, + { ABC_CONST(0x0404040404020302), ABC_CONST(0x0404040400020302), ABC_CONST(0x0404040004020302), ABC_CONST(0x0404040000020302), ABC_CONST(0x0404000404020302), ABC_CONST(0x0404000400020302), ABC_CONST(0x0404000004020302), ABC_CONST(0x0404000000020302), ABC_CONST(0x0400040404020302), ABC_CONST(0x0400040400020302), ABC_CONST(0x0400040004020302), ABC_CONST(0x0400040000020302), ABC_CONST(0x0400000404020302), ABC_CONST(0x0400000400020302), ABC_CONST(0x0400000004020302), ABC_CONST(0x0400000000020302), ABC_CONST(0x0404040404020302), ABC_CONST(0x0404040400020302), ABC_CONST(0x0404040004020302), ABC_CONST(0x0404040000020302), ABC_CONST(0x0404000404020302), ABC_CONST(0x0404000400020302), ABC_CONST(0x0404000004020302), ABC_CONST(0x0404000000020302), ABC_CONST(0x0400040404020302), ABC_CONST(0x0400040400020302), ABC_CONST(0x0400040004020302), ABC_CONST(0x0400040000020302), ABC_CONST(0x0400000404020302), ABC_CONST(0x0400000400020302), ABC_CONST(0x0400000004020302), ABC_CONST(0x0400000000020302) }, + { ABC_CONST(0x0303030303010102), ABC_CONST(0x0303030300010102), ABC_CONST(0x0303030003010102), ABC_CONST(0x0303030000010102), ABC_CONST(0x0303000303010102), ABC_CONST(0x0303000300010102), ABC_CONST(0x0303000003010102), ABC_CONST(0x0303000000010102), ABC_CONST(0x0300030303010102), ABC_CONST(0x0300030300010102), ABC_CONST(0x0300030003010102), ABC_CONST(0x0300030000010102), ABC_CONST(0x0300000303010102), ABC_CONST(0x0300000300010102), ABC_CONST(0x0300000003010102), ABC_CONST(0x0300000000010102), ABC_CONST(0x0303030303010102), ABC_CONST(0x0303030300010102), ABC_CONST(0x0303030003010102), ABC_CONST(0x0303030000010102), ABC_CONST(0x0303000303010102), ABC_CONST(0x0303000300010102), ABC_CONST(0x0303000003010102), ABC_CONST(0x0303000000010102), ABC_CONST(0x0300030303010102), ABC_CONST(0x0300030300010102), ABC_CONST(0x0300030003010102), ABC_CONST(0x0300030000010102), ABC_CONST(0x0300000303010102), ABC_CONST(0x0300000300010102), ABC_CONST(0x0300000003010102), ABC_CONST(0x0300000000010102) }, + { ABC_CONST(0x0404040404020203), ABC_CONST(0x0404040400020203), ABC_CONST(0x0404040004020203), ABC_CONST(0x0404040000020203), ABC_CONST(0x0404000404020203), ABC_CONST(0x0404000400020203), ABC_CONST(0x0404000004020203), ABC_CONST(0x0404000000020203), ABC_CONST(0x0400040404020203), ABC_CONST(0x0400040400020203), ABC_CONST(0x0400040004020203), ABC_CONST(0x0400040000020203), ABC_CONST(0x0400000404020203), ABC_CONST(0x0400000400020203), ABC_CONST(0x0400000004020203), ABC_CONST(0x0400000000020203), ABC_CONST(0x0404040404020203), ABC_CONST(0x0404040400020203), ABC_CONST(0x0404040004020203), ABC_CONST(0x0404040000020203), ABC_CONST(0x0404000404020203), ABC_CONST(0x0404000400020203), ABC_CONST(0x0404000004020203), ABC_CONST(0x0404000000020203), ABC_CONST(0x0400040404020203), ABC_CONST(0x0400040400020203), ABC_CONST(0x0400040004020203), ABC_CONST(0x0400040000020203), ABC_CONST(0x0400000404020203), ABC_CONST(0x0400000400020203), ABC_CONST(0x0400000004020203), ABC_CONST(0x0400000000020203) }, + { ABC_CONST(0x0404040404020202), ABC_CONST(0x0404040400020202), ABC_CONST(0x0404040004020202), ABC_CONST(0x0404040000020202), ABC_CONST(0x0404000404020202), ABC_CONST(0x0404000400020202), ABC_CONST(0x0404000004020202), ABC_CONST(0x0404000000020202), ABC_CONST(0x0400040404020202), ABC_CONST(0x0400040400020202), ABC_CONST(0x0400040004020202), ABC_CONST(0x0400040000020202), ABC_CONST(0x0400000404020202), ABC_CONST(0x0400000400020202), ABC_CONST(0x0400000004020202), ABC_CONST(0x0400000000020202), ABC_CONST(0x0404040404020202), ABC_CONST(0x0404040400020202), ABC_CONST(0x0404040004020202), ABC_CONST(0x0404040000020202), ABC_CONST(0x0404000404020202), ABC_CONST(0x0404000400020202), ABC_CONST(0x0404000004020202), ABC_CONST(0x0404000000020202), ABC_CONST(0x0400040404020202), ABC_CONST(0x0400040400020202), ABC_CONST(0x0400040004020202), ABC_CONST(0x0400040000020202), ABC_CONST(0x0400000404020202), ABC_CONST(0x0400000400020202), ABC_CONST(0x0400000004020202), ABC_CONST(0x0400000000020202) }, + { ABC_CONST(0x0505050505030303), ABC_CONST(0x0505050500030303), ABC_CONST(0x0505050005030303), ABC_CONST(0x0505050000030303), ABC_CONST(0x0505000505030303), ABC_CONST(0x0505000500030303), ABC_CONST(0x0505000005030303), ABC_CONST(0x0505000000030303), ABC_CONST(0x0500050505030303), ABC_CONST(0x0500050500030303), ABC_CONST(0x0500050005030303), ABC_CONST(0x0500050000030303), ABC_CONST(0x0500000505030303), ABC_CONST(0x0500000500030303), ABC_CONST(0x0500000005030303), ABC_CONST(0x0500000000030303), ABC_CONST(0x0505050505030303), ABC_CONST(0x0505050500030303), ABC_CONST(0x0505050005030303), ABC_CONST(0x0505050000030303), ABC_CONST(0x0505000505030303), ABC_CONST(0x0505000500030303), ABC_CONST(0x0505000005030303), ABC_CONST(0x0505000000030303), ABC_CONST(0x0500050505030303), ABC_CONST(0x0500050500030303), ABC_CONST(0x0500050005030303), ABC_CONST(0x0500050000030303), ABC_CONST(0x0500000505030303), ABC_CONST(0x0500000500030303), ABC_CONST(0x0500000005030303), ABC_CONST(0x0500000000030303) }, + { ABC_CONST(0x0303030303010101), ABC_CONST(0x0303030300010101), ABC_CONST(0x0303030003010101), ABC_CONST(0x0303030000010101), ABC_CONST(0x0303000303010101), ABC_CONST(0x0303000300010101), ABC_CONST(0x0303000003010101), ABC_CONST(0x0303000000010101), ABC_CONST(0x0300030303010101), ABC_CONST(0x0300030300010101), ABC_CONST(0x0300030003010101), ABC_CONST(0x0300030000010101), ABC_CONST(0x0300000303010101), ABC_CONST(0x0300000300010101), ABC_CONST(0x0300000003010101), ABC_CONST(0x0300000000010101), ABC_CONST(0x0303030303010101), ABC_CONST(0x0303030300010101), ABC_CONST(0x0303030003010101), ABC_CONST(0x0303030000010101), ABC_CONST(0x0303000303010101), ABC_CONST(0x0303000300010101), ABC_CONST(0x0303000003010101), ABC_CONST(0x0303000000010101), ABC_CONST(0x0300030303010101), ABC_CONST(0x0300030300010101), ABC_CONST(0x0300030003010101), ABC_CONST(0x0300030000010101), ABC_CONST(0x0300000303010101), ABC_CONST(0x0300000300010101), ABC_CONST(0x0300000003010101), ABC_CONST(0x0300000000010101) }, + { ABC_CONST(0x0404040404020202), ABC_CONST(0x0404040400020202), ABC_CONST(0x0404040004020202), ABC_CONST(0x0404040000020202), ABC_CONST(0x0404000404020202), ABC_CONST(0x0404000400020202), ABC_CONST(0x0404000004020202), ABC_CONST(0x0404000000020202), ABC_CONST(0x0400040404020202), ABC_CONST(0x0400040400020202), ABC_CONST(0x0400040004020202), ABC_CONST(0x0400040000020202), ABC_CONST(0x0400000404020202), ABC_CONST(0x0400000400020202), ABC_CONST(0x0400000004020202), ABC_CONST(0x0400000000020202), ABC_CONST(0x0404040404020202), ABC_CONST(0x0404040400020202), ABC_CONST(0x0404040004020202), ABC_CONST(0x0404040000020202), ABC_CONST(0x0404000404020202), ABC_CONST(0x0404000400020202), ABC_CONST(0x0404000004020202), ABC_CONST(0x0404000000020202), ABC_CONST(0x0400040404020202), ABC_CONST(0x0400040400020202), ABC_CONST(0x0400040004020202), ABC_CONST(0x0400040000020202), ABC_CONST(0x0400000404020202), ABC_CONST(0x0400000400020202), ABC_CONST(0x0400000004020202), ABC_CONST(0x0400000000020202) }, + { ABC_CONST(0x0404040404020201), ABC_CONST(0x0404040400020201), ABC_CONST(0x0404040004020201), ABC_CONST(0x0404040000020201), ABC_CONST(0x0404000404020201), ABC_CONST(0x0404000400020201), ABC_CONST(0x0404000004020201), ABC_CONST(0x0404000000020201), ABC_CONST(0x0400040404020201), ABC_CONST(0x0400040400020201), ABC_CONST(0x0400040004020201), ABC_CONST(0x0400040000020201), ABC_CONST(0x0400000404020201), ABC_CONST(0x0400000400020201), ABC_CONST(0x0400000004020201), ABC_CONST(0x0400000000020201), ABC_CONST(0x0404040404020201), ABC_CONST(0x0404040400020201), ABC_CONST(0x0404040004020201), ABC_CONST(0x0404040000020201), ABC_CONST(0x0404000404020201), ABC_CONST(0x0404000400020201), ABC_CONST(0x0404000004020201), ABC_CONST(0x0404000000020201), ABC_CONST(0x0400040404020201), ABC_CONST(0x0400040400020201), ABC_CONST(0x0400040004020201), ABC_CONST(0x0400040000020201), ABC_CONST(0x0400000404020201), ABC_CONST(0x0400000400020201), ABC_CONST(0x0400000004020201), ABC_CONST(0x0400000000020201) }, + { ABC_CONST(0x0505050505030302), ABC_CONST(0x0505050500030302), ABC_CONST(0x0505050005030302), ABC_CONST(0x0505050000030302), ABC_CONST(0x0505000505030302), ABC_CONST(0x0505000500030302), ABC_CONST(0x0505000005030302), ABC_CONST(0x0505000000030302), ABC_CONST(0x0500050505030302), ABC_CONST(0x0500050500030302), ABC_CONST(0x0500050005030302), ABC_CONST(0x0500050000030302), ABC_CONST(0x0500000505030302), ABC_CONST(0x0500000500030302), ABC_CONST(0x0500000005030302), ABC_CONST(0x0500000000030302), ABC_CONST(0x0505050505030302), ABC_CONST(0x0505050500030302), ABC_CONST(0x0505050005030302), ABC_CONST(0x0505050000030302), ABC_CONST(0x0505000505030302), ABC_CONST(0x0505000500030302), ABC_CONST(0x0505000005030302), ABC_CONST(0x0505000000030302), ABC_CONST(0x0500050505030302), ABC_CONST(0x0500050500030302), ABC_CONST(0x0500050005030302), ABC_CONST(0x0500050000030302), ABC_CONST(0x0500000505030302), ABC_CONST(0x0500000500030302), ABC_CONST(0x0500000005030302), ABC_CONST(0x0500000000030302) }, + { ABC_CONST(0x0404040404020102), ABC_CONST(0x0404040400020102), ABC_CONST(0x0404040004020102), ABC_CONST(0x0404040000020102), ABC_CONST(0x0404000404020102), ABC_CONST(0x0404000400020102), ABC_CONST(0x0404000004020102), ABC_CONST(0x0404000000020102), ABC_CONST(0x0400040404020102), ABC_CONST(0x0400040400020102), ABC_CONST(0x0400040004020102), ABC_CONST(0x0400040000020102), ABC_CONST(0x0400000404020102), ABC_CONST(0x0400000400020102), ABC_CONST(0x0400000004020102), ABC_CONST(0x0400000000020102), ABC_CONST(0x0404040404020102), ABC_CONST(0x0404040400020102), ABC_CONST(0x0404040004020102), ABC_CONST(0x0404040000020102), ABC_CONST(0x0404000404020102), ABC_CONST(0x0404000400020102), ABC_CONST(0x0404000004020102), ABC_CONST(0x0404000000020102), ABC_CONST(0x0400040404020102), ABC_CONST(0x0400040400020102), ABC_CONST(0x0400040004020102), ABC_CONST(0x0400040000020102), ABC_CONST(0x0400000404020102), ABC_CONST(0x0400000400020102), ABC_CONST(0x0400000004020102), ABC_CONST(0x0400000000020102) }, + { ABC_CONST(0x0505050505030203), ABC_CONST(0x0505050500030203), ABC_CONST(0x0505050005030203), ABC_CONST(0x0505050000030203), ABC_CONST(0x0505000505030203), ABC_CONST(0x0505000500030203), ABC_CONST(0x0505000005030203), ABC_CONST(0x0505000000030203), ABC_CONST(0x0500050505030203), ABC_CONST(0x0500050500030203), ABC_CONST(0x0500050005030203), ABC_CONST(0x0500050000030203), ABC_CONST(0x0500000505030203), ABC_CONST(0x0500000500030203), ABC_CONST(0x0500000005030203), ABC_CONST(0x0500000000030203), ABC_CONST(0x0505050505030203), ABC_CONST(0x0505050500030203), ABC_CONST(0x0505050005030203), ABC_CONST(0x0505050000030203), ABC_CONST(0x0505000505030203), ABC_CONST(0x0505000500030203), ABC_CONST(0x0505000005030203), ABC_CONST(0x0505000000030203), ABC_CONST(0x0500050505030203), ABC_CONST(0x0500050500030203), ABC_CONST(0x0500050005030203), ABC_CONST(0x0500050000030203), ABC_CONST(0x0500000505030203), ABC_CONST(0x0500000500030203), ABC_CONST(0x0500000005030203), ABC_CONST(0x0500000000030203) }, + { ABC_CONST(0x0505050505030202), ABC_CONST(0x0505050500030202), ABC_CONST(0x0505050005030202), ABC_CONST(0x0505050000030202), ABC_CONST(0x0505000505030202), ABC_CONST(0x0505000500030202), ABC_CONST(0x0505000005030202), ABC_CONST(0x0505000000030202), ABC_CONST(0x0500050505030202), ABC_CONST(0x0500050500030202), ABC_CONST(0x0500050005030202), ABC_CONST(0x0500050000030202), ABC_CONST(0x0500000505030202), ABC_CONST(0x0500000500030202), ABC_CONST(0x0500000005030202), ABC_CONST(0x0500000000030202), ABC_CONST(0x0505050505030202), ABC_CONST(0x0505050500030202), ABC_CONST(0x0505050005030202), ABC_CONST(0x0505050000030202), ABC_CONST(0x0505000505030202), ABC_CONST(0x0505000500030202), ABC_CONST(0x0505000005030202), ABC_CONST(0x0505000000030202), ABC_CONST(0x0500050505030202), ABC_CONST(0x0500050500030202), ABC_CONST(0x0500050005030202), ABC_CONST(0x0500050000030202), ABC_CONST(0x0500000505030202), ABC_CONST(0x0500000500030202), ABC_CONST(0x0500000005030202), ABC_CONST(0x0500000000030202) }, + { ABC_CONST(0x0606060606040303), ABC_CONST(0x0606060600040303), ABC_CONST(0x0606060006040303), ABC_CONST(0x0606060000040303), ABC_CONST(0x0606000606040303), ABC_CONST(0x0606000600040303), ABC_CONST(0x0606000006040303), ABC_CONST(0x0606000000040303), ABC_CONST(0x0600060606040303), ABC_CONST(0x0600060600040303), ABC_CONST(0x0600060006040303), ABC_CONST(0x0600060000040303), ABC_CONST(0x0600000606040303), ABC_CONST(0x0600000600040303), ABC_CONST(0x0600000006040303), ABC_CONST(0x0600000000040303), ABC_CONST(0x0606060606040303), ABC_CONST(0x0606060600040303), ABC_CONST(0x0606060006040303), ABC_CONST(0x0606060000040303), ABC_CONST(0x0606000606040303), ABC_CONST(0x0606000600040303), ABC_CONST(0x0606000006040303), ABC_CONST(0x0606000000040303), ABC_CONST(0x0600060606040303), ABC_CONST(0x0600060600040303), ABC_CONST(0x0600060006040303), ABC_CONST(0x0600060000040303), ABC_CONST(0x0600000606040303), ABC_CONST(0x0600000600040303), ABC_CONST(0x0600000006040303), ABC_CONST(0x0600000000040303) }, + { ABC_CONST(0x0303030303000202), ABC_CONST(0x0303030300000202), ABC_CONST(0x0303030003000202), ABC_CONST(0x0303030000000202), ABC_CONST(0x0303000303000202), ABC_CONST(0x0303000300000202), ABC_CONST(0x0303000003000202), ABC_CONST(0x0303000000000202), ABC_CONST(0x0300030303000202), ABC_CONST(0x0300030300000202), ABC_CONST(0x0300030003000202), ABC_CONST(0x0300030000000202), ABC_CONST(0x0300000303000202), ABC_CONST(0x0300000300000202), ABC_CONST(0x0300000003000202), ABC_CONST(0x0300000000000202), ABC_CONST(0x0303030303000202), ABC_CONST(0x0303030300000202), ABC_CONST(0x0303030003000202), ABC_CONST(0x0303030000000202), ABC_CONST(0x0303000303000202), ABC_CONST(0x0303000300000202), ABC_CONST(0x0303000003000202), ABC_CONST(0x0303000000000202), ABC_CONST(0x0300030303000202), ABC_CONST(0x0300030300000202), ABC_CONST(0x0300030003000202), ABC_CONST(0x0300030000000202), ABC_CONST(0x0300000303000202), ABC_CONST(0x0300000300000202), ABC_CONST(0x0300000003000202), ABC_CONST(0x0300000000000202) }, + { ABC_CONST(0x0404040404010303), ABC_CONST(0x0404040400010303), ABC_CONST(0x0404040004010303), ABC_CONST(0x0404040000010303), ABC_CONST(0x0404000404010303), ABC_CONST(0x0404000400010303), ABC_CONST(0x0404000004010303), ABC_CONST(0x0404000000010303), ABC_CONST(0x0400040404010303), ABC_CONST(0x0400040400010303), ABC_CONST(0x0400040004010303), ABC_CONST(0x0400040000010303), ABC_CONST(0x0400000404010303), ABC_CONST(0x0400000400010303), ABC_CONST(0x0400000004010303), ABC_CONST(0x0400000000010303), ABC_CONST(0x0404040404010303), ABC_CONST(0x0404040400010303), ABC_CONST(0x0404040004010303), ABC_CONST(0x0404040000010303), ABC_CONST(0x0404000404010303), ABC_CONST(0x0404000400010303), ABC_CONST(0x0404000004010303), ABC_CONST(0x0404000000010303), ABC_CONST(0x0400040404010303), ABC_CONST(0x0400040400010303), ABC_CONST(0x0400040004010303), ABC_CONST(0x0400040000010303), ABC_CONST(0x0400000404010303), ABC_CONST(0x0400000400010303), ABC_CONST(0x0400000004010303), ABC_CONST(0x0400000000010303) }, + { ABC_CONST(0x0404040404010302), ABC_CONST(0x0404040400010302), ABC_CONST(0x0404040004010302), ABC_CONST(0x0404040000010302), ABC_CONST(0x0404000404010302), ABC_CONST(0x0404000400010302), ABC_CONST(0x0404000004010302), ABC_CONST(0x0404000000010302), ABC_CONST(0x0400040404010302), ABC_CONST(0x0400040400010302), ABC_CONST(0x0400040004010302), ABC_CONST(0x0400040000010302), ABC_CONST(0x0400000404010302), ABC_CONST(0x0400000400010302), ABC_CONST(0x0400000004010302), ABC_CONST(0x0400000000010302), ABC_CONST(0x0404040404010302), ABC_CONST(0x0404040400010302), ABC_CONST(0x0404040004010302), ABC_CONST(0x0404040000010302), ABC_CONST(0x0404000404010302), ABC_CONST(0x0404000400010302), ABC_CONST(0x0404000004010302), ABC_CONST(0x0404000000010302), ABC_CONST(0x0400040404010302), ABC_CONST(0x0400040400010302), ABC_CONST(0x0400040004010302), ABC_CONST(0x0400040000010302), ABC_CONST(0x0400000404010302), ABC_CONST(0x0400000400010302), ABC_CONST(0x0400000004010302), ABC_CONST(0x0400000000010302) }, + { ABC_CONST(0x0505050505020403), ABC_CONST(0x0505050500020403), ABC_CONST(0x0505050005020403), ABC_CONST(0x0505050000020403), ABC_CONST(0x0505000505020403), ABC_CONST(0x0505000500020403), ABC_CONST(0x0505000005020403), ABC_CONST(0x0505000000020403), ABC_CONST(0x0500050505020403), ABC_CONST(0x0500050500020403), ABC_CONST(0x0500050005020403), ABC_CONST(0x0500050000020403), ABC_CONST(0x0500000505020403), ABC_CONST(0x0500000500020403), ABC_CONST(0x0500000005020403), ABC_CONST(0x0500000000020403), ABC_CONST(0x0505050505020403), ABC_CONST(0x0505050500020403), ABC_CONST(0x0505050005020403), ABC_CONST(0x0505050000020403), ABC_CONST(0x0505000505020403), ABC_CONST(0x0505000500020403), ABC_CONST(0x0505000005020403), ABC_CONST(0x0505000000020403), ABC_CONST(0x0500050505020403), ABC_CONST(0x0500050500020403), ABC_CONST(0x0500050005020403), ABC_CONST(0x0500050000020403), ABC_CONST(0x0500000505020403), ABC_CONST(0x0500000500020403), ABC_CONST(0x0500000005020403), ABC_CONST(0x0500000000020403) }, + { ABC_CONST(0x0404040404010203), ABC_CONST(0x0404040400010203), ABC_CONST(0x0404040004010203), ABC_CONST(0x0404040000010203), ABC_CONST(0x0404000404010203), ABC_CONST(0x0404000400010203), ABC_CONST(0x0404000004010203), ABC_CONST(0x0404000000010203), ABC_CONST(0x0400040404010203), ABC_CONST(0x0400040400010203), ABC_CONST(0x0400040004010203), ABC_CONST(0x0400040000010203), ABC_CONST(0x0400000404010203), ABC_CONST(0x0400000400010203), ABC_CONST(0x0400000004010203), ABC_CONST(0x0400000000010203), ABC_CONST(0x0404040404010203), ABC_CONST(0x0404040400010203), ABC_CONST(0x0404040004010203), ABC_CONST(0x0404040000010203), ABC_CONST(0x0404000404010203), ABC_CONST(0x0404000400010203), ABC_CONST(0x0404000004010203), ABC_CONST(0x0404000000010203), ABC_CONST(0x0400040404010203), ABC_CONST(0x0400040400010203), ABC_CONST(0x0400040004010203), ABC_CONST(0x0400040000010203), ABC_CONST(0x0400000404010203), ABC_CONST(0x0400000400010203), ABC_CONST(0x0400000004010203), ABC_CONST(0x0400000000010203) }, + { ABC_CONST(0x0505050505020304), ABC_CONST(0x0505050500020304), ABC_CONST(0x0505050005020304), ABC_CONST(0x0505050000020304), ABC_CONST(0x0505000505020304), ABC_CONST(0x0505000500020304), ABC_CONST(0x0505000005020304), ABC_CONST(0x0505000000020304), ABC_CONST(0x0500050505020304), ABC_CONST(0x0500050500020304), ABC_CONST(0x0500050005020304), ABC_CONST(0x0500050000020304), ABC_CONST(0x0500000505020304), ABC_CONST(0x0500000500020304), ABC_CONST(0x0500000005020304), ABC_CONST(0x0500000000020304), ABC_CONST(0x0505050505020304), ABC_CONST(0x0505050500020304), ABC_CONST(0x0505050005020304), ABC_CONST(0x0505050000020304), ABC_CONST(0x0505000505020304), ABC_CONST(0x0505000500020304), ABC_CONST(0x0505000005020304), ABC_CONST(0x0505000000020304), ABC_CONST(0x0500050505020304), ABC_CONST(0x0500050500020304), ABC_CONST(0x0500050005020304), ABC_CONST(0x0500050000020304), ABC_CONST(0x0500000505020304), ABC_CONST(0x0500000500020304), ABC_CONST(0x0500000005020304), ABC_CONST(0x0500000000020304) }, + { ABC_CONST(0x0505050505020303), ABC_CONST(0x0505050500020303), ABC_CONST(0x0505050005020303), ABC_CONST(0x0505050000020303), ABC_CONST(0x0505000505020303), ABC_CONST(0x0505000500020303), ABC_CONST(0x0505000005020303), ABC_CONST(0x0505000000020303), ABC_CONST(0x0500050505020303), ABC_CONST(0x0500050500020303), ABC_CONST(0x0500050005020303), ABC_CONST(0x0500050000020303), ABC_CONST(0x0500000505020303), ABC_CONST(0x0500000500020303), ABC_CONST(0x0500000005020303), ABC_CONST(0x0500000000020303), ABC_CONST(0x0505050505020303), ABC_CONST(0x0505050500020303), ABC_CONST(0x0505050005020303), ABC_CONST(0x0505050000020303), ABC_CONST(0x0505000505020303), ABC_CONST(0x0505000500020303), ABC_CONST(0x0505000005020303), ABC_CONST(0x0505000000020303), ABC_CONST(0x0500050505020303), ABC_CONST(0x0500050500020303), ABC_CONST(0x0500050005020303), ABC_CONST(0x0500050000020303), ABC_CONST(0x0500000505020303), ABC_CONST(0x0500000500020303), ABC_CONST(0x0500000005020303), ABC_CONST(0x0500000000020303) }, + { ABC_CONST(0x0606060606030404), ABC_CONST(0x0606060600030404), ABC_CONST(0x0606060006030404), ABC_CONST(0x0606060000030404), ABC_CONST(0x0606000606030404), ABC_CONST(0x0606000600030404), ABC_CONST(0x0606000006030404), ABC_CONST(0x0606000000030404), ABC_CONST(0x0600060606030404), ABC_CONST(0x0600060600030404), ABC_CONST(0x0600060006030404), ABC_CONST(0x0600060000030404), ABC_CONST(0x0600000606030404), ABC_CONST(0x0600000600030404), ABC_CONST(0x0600000006030404), ABC_CONST(0x0600000000030404), ABC_CONST(0x0606060606030404), ABC_CONST(0x0606060600030404), ABC_CONST(0x0606060006030404), ABC_CONST(0x0606060000030404), ABC_CONST(0x0606000606030404), ABC_CONST(0x0606000600030404), ABC_CONST(0x0606000006030404), ABC_CONST(0x0606000000030404), ABC_CONST(0x0600060606030404), ABC_CONST(0x0600060600030404), ABC_CONST(0x0600060006030404), ABC_CONST(0x0600060000030404), ABC_CONST(0x0600000606030404), ABC_CONST(0x0600000600030404), ABC_CONST(0x0600000006030404), ABC_CONST(0x0600000000030404) }, + { ABC_CONST(0x0404040404010202), ABC_CONST(0x0404040400010202), ABC_CONST(0x0404040004010202), ABC_CONST(0x0404040000010202), ABC_CONST(0x0404000404010202), ABC_CONST(0x0404000400010202), ABC_CONST(0x0404000004010202), ABC_CONST(0x0404000000010202), ABC_CONST(0x0400040404010202), ABC_CONST(0x0400040400010202), ABC_CONST(0x0400040004010202), ABC_CONST(0x0400040000010202), ABC_CONST(0x0400000404010202), ABC_CONST(0x0400000400010202), ABC_CONST(0x0400000004010202), ABC_CONST(0x0400000000010202), ABC_CONST(0x0404040404010202), ABC_CONST(0x0404040400010202), ABC_CONST(0x0404040004010202), ABC_CONST(0x0404040000010202), ABC_CONST(0x0404000404010202), ABC_CONST(0x0404000400010202), ABC_CONST(0x0404000004010202), ABC_CONST(0x0404000000010202), ABC_CONST(0x0400040404010202), ABC_CONST(0x0400040400010202), ABC_CONST(0x0400040004010202), ABC_CONST(0x0400040000010202), ABC_CONST(0x0400000404010202), ABC_CONST(0x0400000400010202), ABC_CONST(0x0400000004010202), ABC_CONST(0x0400000000010202) }, + { ABC_CONST(0x0505050505020303), ABC_CONST(0x0505050500020303), ABC_CONST(0x0505050005020303), ABC_CONST(0x0505050000020303), ABC_CONST(0x0505000505020303), ABC_CONST(0x0505000500020303), ABC_CONST(0x0505000005020303), ABC_CONST(0x0505000000020303), ABC_CONST(0x0500050505020303), ABC_CONST(0x0500050500020303), ABC_CONST(0x0500050005020303), ABC_CONST(0x0500050000020303), ABC_CONST(0x0500000505020303), ABC_CONST(0x0500000500020303), ABC_CONST(0x0500000005020303), ABC_CONST(0x0500000000020303), ABC_CONST(0x0505050505020303), ABC_CONST(0x0505050500020303), ABC_CONST(0x0505050005020303), ABC_CONST(0x0505050000020303), ABC_CONST(0x0505000505020303), ABC_CONST(0x0505000500020303), ABC_CONST(0x0505000005020303), ABC_CONST(0x0505000000020303), ABC_CONST(0x0500050505020303), ABC_CONST(0x0500050500020303), ABC_CONST(0x0500050005020303), ABC_CONST(0x0500050000020303), ABC_CONST(0x0500000505020303), ABC_CONST(0x0500000500020303), ABC_CONST(0x0500000005020303), ABC_CONST(0x0500000000020303) }, + { ABC_CONST(0x0505050505020302), ABC_CONST(0x0505050500020302), ABC_CONST(0x0505050005020302), ABC_CONST(0x0505050000020302), ABC_CONST(0x0505000505020302), ABC_CONST(0x0505000500020302), ABC_CONST(0x0505000005020302), ABC_CONST(0x0505000000020302), ABC_CONST(0x0500050505020302), ABC_CONST(0x0500050500020302), ABC_CONST(0x0500050005020302), ABC_CONST(0x0500050000020302), ABC_CONST(0x0500000505020302), ABC_CONST(0x0500000500020302), ABC_CONST(0x0500000005020302), ABC_CONST(0x0500000000020302), ABC_CONST(0x0505050505020302), ABC_CONST(0x0505050500020302), ABC_CONST(0x0505050005020302), ABC_CONST(0x0505050000020302), ABC_CONST(0x0505000505020302), ABC_CONST(0x0505000500020302), ABC_CONST(0x0505000005020302), ABC_CONST(0x0505000000020302), ABC_CONST(0x0500050505020302), ABC_CONST(0x0500050500020302), ABC_CONST(0x0500050005020302), ABC_CONST(0x0500050000020302), ABC_CONST(0x0500000505020302), ABC_CONST(0x0500000500020302), ABC_CONST(0x0500000005020302), ABC_CONST(0x0500000000020302) }, + { ABC_CONST(0x0606060606030403), ABC_CONST(0x0606060600030403), ABC_CONST(0x0606060006030403), ABC_CONST(0x0606060000030403), ABC_CONST(0x0606000606030403), ABC_CONST(0x0606000600030403), ABC_CONST(0x0606000006030403), ABC_CONST(0x0606000000030403), ABC_CONST(0x0600060606030403), ABC_CONST(0x0600060600030403), ABC_CONST(0x0600060006030403), ABC_CONST(0x0600060000030403), ABC_CONST(0x0600000606030403), ABC_CONST(0x0600000600030403), ABC_CONST(0x0600000006030403), ABC_CONST(0x0600000000030403), ABC_CONST(0x0606060606030403), ABC_CONST(0x0606060600030403), ABC_CONST(0x0606060006030403), ABC_CONST(0x0606060000030403), ABC_CONST(0x0606000606030403), ABC_CONST(0x0606000600030403), ABC_CONST(0x0606000006030403), ABC_CONST(0x0606000000030403), ABC_CONST(0x0600060606030403), ABC_CONST(0x0600060600030403), ABC_CONST(0x0600060006030403), ABC_CONST(0x0600060000030403), ABC_CONST(0x0600000606030403), ABC_CONST(0x0600000600030403), ABC_CONST(0x0600000006030403), ABC_CONST(0x0600000000030403) }, + { ABC_CONST(0x0505050505020203), ABC_CONST(0x0505050500020203), ABC_CONST(0x0505050005020203), ABC_CONST(0x0505050000020203), ABC_CONST(0x0505000505020203), ABC_CONST(0x0505000500020203), ABC_CONST(0x0505000005020203), ABC_CONST(0x0505000000020203), ABC_CONST(0x0500050505020203), ABC_CONST(0x0500050500020203), ABC_CONST(0x0500050005020203), ABC_CONST(0x0500050000020203), ABC_CONST(0x0500000505020203), ABC_CONST(0x0500000500020203), ABC_CONST(0x0500000005020203), ABC_CONST(0x0500000000020203), ABC_CONST(0x0505050505020203), ABC_CONST(0x0505050500020203), ABC_CONST(0x0505050005020203), ABC_CONST(0x0505050000020203), ABC_CONST(0x0505000505020203), ABC_CONST(0x0505000500020203), ABC_CONST(0x0505000005020203), ABC_CONST(0x0505000000020203), ABC_CONST(0x0500050505020203), ABC_CONST(0x0500050500020203), ABC_CONST(0x0500050005020203), ABC_CONST(0x0500050000020203), ABC_CONST(0x0500000505020203), ABC_CONST(0x0500000500020203), ABC_CONST(0x0500000005020203), ABC_CONST(0x0500000000020203) }, + { ABC_CONST(0x0606060606030304), ABC_CONST(0x0606060600030304), ABC_CONST(0x0606060006030304), ABC_CONST(0x0606060000030304), ABC_CONST(0x0606000606030304), ABC_CONST(0x0606000600030304), ABC_CONST(0x0606000006030304), ABC_CONST(0x0606000000030304), ABC_CONST(0x0600060606030304), ABC_CONST(0x0600060600030304), ABC_CONST(0x0600060006030304), ABC_CONST(0x0600060000030304), ABC_CONST(0x0600000606030304), ABC_CONST(0x0600000600030304), ABC_CONST(0x0600000006030304), ABC_CONST(0x0600000000030304), ABC_CONST(0x0606060606030304), ABC_CONST(0x0606060600030304), ABC_CONST(0x0606060006030304), ABC_CONST(0x0606060000030304), ABC_CONST(0x0606000606030304), ABC_CONST(0x0606000600030304), ABC_CONST(0x0606000006030304), ABC_CONST(0x0606000000030304), ABC_CONST(0x0600060606030304), ABC_CONST(0x0600060600030304), ABC_CONST(0x0600060006030304), ABC_CONST(0x0600060000030304), ABC_CONST(0x0600000606030304), ABC_CONST(0x0600000600030304), ABC_CONST(0x0600000006030304), ABC_CONST(0x0600000000030304) }, + { ABC_CONST(0x0606060606030303), ABC_CONST(0x0606060600030303), ABC_CONST(0x0606060006030303), ABC_CONST(0x0606060000030303), ABC_CONST(0x0606000606030303), ABC_CONST(0x0606000600030303), ABC_CONST(0x0606000006030303), ABC_CONST(0x0606000000030303), ABC_CONST(0x0600060606030303), ABC_CONST(0x0600060600030303), ABC_CONST(0x0600060006030303), ABC_CONST(0x0600060000030303), ABC_CONST(0x0600000606030303), ABC_CONST(0x0600000600030303), ABC_CONST(0x0600000006030303), ABC_CONST(0x0600000000030303), ABC_CONST(0x0606060606030303), ABC_CONST(0x0606060600030303), ABC_CONST(0x0606060006030303), ABC_CONST(0x0606060000030303), ABC_CONST(0x0606000606030303), ABC_CONST(0x0606000600030303), ABC_CONST(0x0606000006030303), ABC_CONST(0x0606000000030303), ABC_CONST(0x0600060606030303), ABC_CONST(0x0600060600030303), ABC_CONST(0x0600060006030303), ABC_CONST(0x0600060000030303), ABC_CONST(0x0600000606030303), ABC_CONST(0x0600000600030303), ABC_CONST(0x0600000006030303), ABC_CONST(0x0600000000030303) }, + { ABC_CONST(0x0707070707040404), ABC_CONST(0x0707070700040404), ABC_CONST(0x0707070007040404), ABC_CONST(0x0707070000040404), ABC_CONST(0x0707000707040404), ABC_CONST(0x0707000700040404), ABC_CONST(0x0707000007040404), ABC_CONST(0x0707000000040404), ABC_CONST(0x0700070707040404), ABC_CONST(0x0700070700040404), ABC_CONST(0x0700070007040404), ABC_CONST(0x0700070000040404), ABC_CONST(0x0700000707040404), ABC_CONST(0x0700000700040404), ABC_CONST(0x0700000007040404), ABC_CONST(0x0700000000040404), ABC_CONST(0x0707070707040404), ABC_CONST(0x0707070700040404), ABC_CONST(0x0707070007040404), ABC_CONST(0x0707070000040404), ABC_CONST(0x0707000707040404), ABC_CONST(0x0707000700040404), ABC_CONST(0x0707000007040404), ABC_CONST(0x0707000000040404), ABC_CONST(0x0700070707040404), ABC_CONST(0x0700070700040404), ABC_CONST(0x0700070007040404), ABC_CONST(0x0700070000040404), ABC_CONST(0x0700000707040404), ABC_CONST(0x0700000700040404), ABC_CONST(0x0700000007040404), ABC_CONST(0x0700000000040404) }, + { ABC_CONST(0x0101010101000000), ABC_CONST(0x0101010100000000), ABC_CONST(0x0101010001000000), ABC_CONST(0x0101010000000000), ABC_CONST(0x0101000101000000), ABC_CONST(0x0101000100000000), ABC_CONST(0x0101000001000000), ABC_CONST(0x0101000000000000), ABC_CONST(0x0100010101000000), ABC_CONST(0x0100010100000000), ABC_CONST(0x0100010001000000), ABC_CONST(0x0100010000000000), ABC_CONST(0x0100000101000000), ABC_CONST(0x0100000100000000), ABC_CONST(0x0100000001000000), ABC_CONST(0x0100000000000000), ABC_CONST(0x0101010101000000), ABC_CONST(0x0101010100000000), ABC_CONST(0x0101010001000000), ABC_CONST(0x0101010000000000), ABC_CONST(0x0101000101000000), ABC_CONST(0x0101000100000000), ABC_CONST(0x0101000001000000), ABC_CONST(0x0101000000000000), ABC_CONST(0x0100010101000000), ABC_CONST(0x0100010100000000), ABC_CONST(0x0100010001000000), ABC_CONST(0x0100010000000000), ABC_CONST(0x0100000101000000), ABC_CONST(0x0100000100000000), ABC_CONST(0x0100000001000000), ABC_CONST(0x0100000000000000) }, + { ABC_CONST(0x0202020202010101), ABC_CONST(0x0202020200010101), ABC_CONST(0x0202020002010101), ABC_CONST(0x0202020000010101), ABC_CONST(0x0202000202010101), ABC_CONST(0x0202000200010101), ABC_CONST(0x0202000002010101), ABC_CONST(0x0202000000010101), ABC_CONST(0x0200020202010101), ABC_CONST(0x0200020200010101), ABC_CONST(0x0200020002010101), ABC_CONST(0x0200020000010101), ABC_CONST(0x0200000202010101), ABC_CONST(0x0200000200010101), ABC_CONST(0x0200000002010101), ABC_CONST(0x0200000000010101), ABC_CONST(0x0202020202010101), ABC_CONST(0x0202020200010101), ABC_CONST(0x0202020002010101), ABC_CONST(0x0202020000010101), ABC_CONST(0x0202000202010101), ABC_CONST(0x0202000200010101), ABC_CONST(0x0202000002010101), ABC_CONST(0x0202000000010101), ABC_CONST(0x0200020202010101), ABC_CONST(0x0200020200010101), ABC_CONST(0x0200020002010101), ABC_CONST(0x0200020000010101), ABC_CONST(0x0200000202010101), ABC_CONST(0x0200000200010101), ABC_CONST(0x0200000002010101), ABC_CONST(0x0200000000010101) }, + { ABC_CONST(0x0202020202010100), ABC_CONST(0x0202020200010100), ABC_CONST(0x0202020002010100), ABC_CONST(0x0202020000010100), ABC_CONST(0x0202000202010100), ABC_CONST(0x0202000200010100), ABC_CONST(0x0202000002010100), ABC_CONST(0x0202000000010100), ABC_CONST(0x0200020202010100), ABC_CONST(0x0200020200010100), ABC_CONST(0x0200020002010100), ABC_CONST(0x0200020000010100), ABC_CONST(0x0200000202010100), ABC_CONST(0x0200000200010100), ABC_CONST(0x0200000002010100), ABC_CONST(0x0200000000010100), ABC_CONST(0x0202020202010100), ABC_CONST(0x0202020200010100), ABC_CONST(0x0202020002010100), ABC_CONST(0x0202020000010100), ABC_CONST(0x0202000202010100), ABC_CONST(0x0202000200010100), ABC_CONST(0x0202000002010100), ABC_CONST(0x0202000000010100), ABC_CONST(0x0200020202010100), ABC_CONST(0x0200020200010100), ABC_CONST(0x0200020002010100), ABC_CONST(0x0200020000010100), ABC_CONST(0x0200000202010100), ABC_CONST(0x0200000200010100), ABC_CONST(0x0200000002010100), ABC_CONST(0x0200000000010100) }, + { ABC_CONST(0x0303030303020201), ABC_CONST(0x0303030300020201), ABC_CONST(0x0303030003020201), ABC_CONST(0x0303030000020201), ABC_CONST(0x0303000303020201), ABC_CONST(0x0303000300020201), ABC_CONST(0x0303000003020201), ABC_CONST(0x0303000000020201), ABC_CONST(0x0300030303020201), ABC_CONST(0x0300030300020201), ABC_CONST(0x0300030003020201), ABC_CONST(0x0300030000020201), ABC_CONST(0x0300000303020201), ABC_CONST(0x0300000300020201), ABC_CONST(0x0300000003020201), ABC_CONST(0x0300000000020201), ABC_CONST(0x0303030303020201), ABC_CONST(0x0303030300020201), ABC_CONST(0x0303030003020201), ABC_CONST(0x0303030000020201), ABC_CONST(0x0303000303020201), ABC_CONST(0x0303000300020201), ABC_CONST(0x0303000003020201), ABC_CONST(0x0303000000020201), ABC_CONST(0x0300030303020201), ABC_CONST(0x0300030300020201), ABC_CONST(0x0300030003020201), ABC_CONST(0x0300030000020201), ABC_CONST(0x0300000303020201), ABC_CONST(0x0300000300020201), ABC_CONST(0x0300000003020201), ABC_CONST(0x0300000000020201) }, + { ABC_CONST(0x0202020202010001), ABC_CONST(0x0202020200010001), ABC_CONST(0x0202020002010001), ABC_CONST(0x0202020000010001), ABC_CONST(0x0202000202010001), ABC_CONST(0x0202000200010001), ABC_CONST(0x0202000002010001), ABC_CONST(0x0202000000010001), ABC_CONST(0x0200020202010001), ABC_CONST(0x0200020200010001), ABC_CONST(0x0200020002010001), ABC_CONST(0x0200020000010001), ABC_CONST(0x0200000202010001), ABC_CONST(0x0200000200010001), ABC_CONST(0x0200000002010001), ABC_CONST(0x0200000000010001), ABC_CONST(0x0202020202010001), ABC_CONST(0x0202020200010001), ABC_CONST(0x0202020002010001), ABC_CONST(0x0202020000010001), ABC_CONST(0x0202000202010001), ABC_CONST(0x0202000200010001), ABC_CONST(0x0202000002010001), ABC_CONST(0x0202000000010001), ABC_CONST(0x0200020202010001), ABC_CONST(0x0200020200010001), ABC_CONST(0x0200020002010001), ABC_CONST(0x0200020000010001), ABC_CONST(0x0200000202010001), ABC_CONST(0x0200000200010001), ABC_CONST(0x0200000002010001), ABC_CONST(0x0200000000010001) }, + { ABC_CONST(0x0303030303020102), ABC_CONST(0x0303030300020102), ABC_CONST(0x0303030003020102), ABC_CONST(0x0303030000020102), ABC_CONST(0x0303000303020102), ABC_CONST(0x0303000300020102), ABC_CONST(0x0303000003020102), ABC_CONST(0x0303000000020102), ABC_CONST(0x0300030303020102), ABC_CONST(0x0300030300020102), ABC_CONST(0x0300030003020102), ABC_CONST(0x0300030000020102), ABC_CONST(0x0300000303020102), ABC_CONST(0x0300000300020102), ABC_CONST(0x0300000003020102), ABC_CONST(0x0300000000020102), ABC_CONST(0x0303030303020102), ABC_CONST(0x0303030300020102), ABC_CONST(0x0303030003020102), ABC_CONST(0x0303030000020102), ABC_CONST(0x0303000303020102), ABC_CONST(0x0303000300020102), ABC_CONST(0x0303000003020102), ABC_CONST(0x0303000000020102), ABC_CONST(0x0300030303020102), ABC_CONST(0x0300030300020102), ABC_CONST(0x0300030003020102), ABC_CONST(0x0300030000020102), ABC_CONST(0x0300000303020102), ABC_CONST(0x0300000300020102), ABC_CONST(0x0300000003020102), ABC_CONST(0x0300000000020102) }, + { ABC_CONST(0x0303030303020101), ABC_CONST(0x0303030300020101), ABC_CONST(0x0303030003020101), ABC_CONST(0x0303030000020101), ABC_CONST(0x0303000303020101), ABC_CONST(0x0303000300020101), ABC_CONST(0x0303000003020101), ABC_CONST(0x0303000000020101), ABC_CONST(0x0300030303020101), ABC_CONST(0x0300030300020101), ABC_CONST(0x0300030003020101), ABC_CONST(0x0300030000020101), ABC_CONST(0x0300000303020101), ABC_CONST(0x0300000300020101), ABC_CONST(0x0300000003020101), ABC_CONST(0x0300000000020101), ABC_CONST(0x0303030303020101), ABC_CONST(0x0303030300020101), ABC_CONST(0x0303030003020101), ABC_CONST(0x0303030000020101), ABC_CONST(0x0303000303020101), ABC_CONST(0x0303000300020101), ABC_CONST(0x0303000003020101), ABC_CONST(0x0303000000020101), ABC_CONST(0x0300030303020101), ABC_CONST(0x0300030300020101), ABC_CONST(0x0300030003020101), ABC_CONST(0x0300030000020101), ABC_CONST(0x0300000303020101), ABC_CONST(0x0300000300020101), ABC_CONST(0x0300000003020101), ABC_CONST(0x0300000000020101) }, + { ABC_CONST(0x0404040404030202), ABC_CONST(0x0404040400030202), ABC_CONST(0x0404040004030202), ABC_CONST(0x0404040000030202), ABC_CONST(0x0404000404030202), ABC_CONST(0x0404000400030202), ABC_CONST(0x0404000004030202), ABC_CONST(0x0404000000030202), ABC_CONST(0x0400040404030202), ABC_CONST(0x0400040400030202), ABC_CONST(0x0400040004030202), ABC_CONST(0x0400040000030202), ABC_CONST(0x0400000404030202), ABC_CONST(0x0400000400030202), ABC_CONST(0x0400000004030202), ABC_CONST(0x0400000000030202), ABC_CONST(0x0404040404030202), ABC_CONST(0x0404040400030202), ABC_CONST(0x0404040004030202), ABC_CONST(0x0404040000030202), ABC_CONST(0x0404000404030202), ABC_CONST(0x0404000400030202), ABC_CONST(0x0404000004030202), ABC_CONST(0x0404000000030202), ABC_CONST(0x0400040404030202), ABC_CONST(0x0400040400030202), ABC_CONST(0x0400040004030202), ABC_CONST(0x0400040000030202), ABC_CONST(0x0400000404030202), ABC_CONST(0x0400000400030202), ABC_CONST(0x0400000004030202), ABC_CONST(0x0400000000030202) }, + { ABC_CONST(0x0202020202010000), ABC_CONST(0x0202020200010000), ABC_CONST(0x0202020002010000), ABC_CONST(0x0202020000010000), ABC_CONST(0x0202000202010000), ABC_CONST(0x0202000200010000), ABC_CONST(0x0202000002010000), ABC_CONST(0x0202000000010000), ABC_CONST(0x0200020202010000), ABC_CONST(0x0200020200010000), ABC_CONST(0x0200020002010000), ABC_CONST(0x0200020000010000), ABC_CONST(0x0200000202010000), ABC_CONST(0x0200000200010000), ABC_CONST(0x0200000002010000), ABC_CONST(0x0200000000010000), ABC_CONST(0x0202020202010000), ABC_CONST(0x0202020200010000), ABC_CONST(0x0202020002010000), ABC_CONST(0x0202020000010000), ABC_CONST(0x0202000202010000), ABC_CONST(0x0202000200010000), ABC_CONST(0x0202000002010000), ABC_CONST(0x0202000000010000), ABC_CONST(0x0200020202010000), ABC_CONST(0x0200020200010000), ABC_CONST(0x0200020002010000), ABC_CONST(0x0200020000010000), ABC_CONST(0x0200000202010000), ABC_CONST(0x0200000200010000), ABC_CONST(0x0200000002010000), ABC_CONST(0x0200000000010000) }, + { ABC_CONST(0x0303030303020101), ABC_CONST(0x0303030300020101), ABC_CONST(0x0303030003020101), ABC_CONST(0x0303030000020101), ABC_CONST(0x0303000303020101), ABC_CONST(0x0303000300020101), ABC_CONST(0x0303000003020101), ABC_CONST(0x0303000000020101), ABC_CONST(0x0300030303020101), ABC_CONST(0x0300030300020101), ABC_CONST(0x0300030003020101), ABC_CONST(0x0300030000020101), ABC_CONST(0x0300000303020101), ABC_CONST(0x0300000300020101), ABC_CONST(0x0300000003020101), ABC_CONST(0x0300000000020101), ABC_CONST(0x0303030303020101), ABC_CONST(0x0303030300020101), ABC_CONST(0x0303030003020101), ABC_CONST(0x0303030000020101), ABC_CONST(0x0303000303020101), ABC_CONST(0x0303000300020101), ABC_CONST(0x0303000003020101), ABC_CONST(0x0303000000020101), ABC_CONST(0x0300030303020101), ABC_CONST(0x0300030300020101), ABC_CONST(0x0300030003020101), ABC_CONST(0x0300030000020101), ABC_CONST(0x0300000303020101), ABC_CONST(0x0300000300020101), ABC_CONST(0x0300000003020101), ABC_CONST(0x0300000000020101) }, + { ABC_CONST(0x0303030303020100), ABC_CONST(0x0303030300020100), ABC_CONST(0x0303030003020100), ABC_CONST(0x0303030000020100), ABC_CONST(0x0303000303020100), ABC_CONST(0x0303000300020100), ABC_CONST(0x0303000003020100), ABC_CONST(0x0303000000020100), ABC_CONST(0x0300030303020100), ABC_CONST(0x0300030300020100), ABC_CONST(0x0300030003020100), ABC_CONST(0x0300030000020100), ABC_CONST(0x0300000303020100), ABC_CONST(0x0300000300020100), ABC_CONST(0x0300000003020100), ABC_CONST(0x0300000000020100), ABC_CONST(0x0303030303020100), ABC_CONST(0x0303030300020100), ABC_CONST(0x0303030003020100), ABC_CONST(0x0303030000020100), ABC_CONST(0x0303000303020100), ABC_CONST(0x0303000300020100), ABC_CONST(0x0303000003020100), ABC_CONST(0x0303000000020100), ABC_CONST(0x0300030303020100), ABC_CONST(0x0300030300020100), ABC_CONST(0x0300030003020100), ABC_CONST(0x0300030000020100), ABC_CONST(0x0300000303020100), ABC_CONST(0x0300000300020100), ABC_CONST(0x0300000003020100), ABC_CONST(0x0300000000020100) }, + { ABC_CONST(0x0404040404030201), ABC_CONST(0x0404040400030201), ABC_CONST(0x0404040004030201), ABC_CONST(0x0404040000030201), ABC_CONST(0x0404000404030201), ABC_CONST(0x0404000400030201), ABC_CONST(0x0404000004030201), ABC_CONST(0x0404000000030201), ABC_CONST(0x0400040404030201), ABC_CONST(0x0400040400030201), ABC_CONST(0x0400040004030201), ABC_CONST(0x0400040000030201), ABC_CONST(0x0400000404030201), ABC_CONST(0x0400000400030201), ABC_CONST(0x0400000004030201), ABC_CONST(0x0400000000030201), ABC_CONST(0x0404040404030201), ABC_CONST(0x0404040400030201), ABC_CONST(0x0404040004030201), ABC_CONST(0x0404040000030201), ABC_CONST(0x0404000404030201), ABC_CONST(0x0404000400030201), ABC_CONST(0x0404000004030201), ABC_CONST(0x0404000000030201), ABC_CONST(0x0400040404030201), ABC_CONST(0x0400040400030201), ABC_CONST(0x0400040004030201), ABC_CONST(0x0400040000030201), ABC_CONST(0x0400000404030201), ABC_CONST(0x0400000400030201), ABC_CONST(0x0400000004030201), ABC_CONST(0x0400000000030201) }, + { ABC_CONST(0x0303030303020001), ABC_CONST(0x0303030300020001), ABC_CONST(0x0303030003020001), ABC_CONST(0x0303030000020001), ABC_CONST(0x0303000303020001), ABC_CONST(0x0303000300020001), ABC_CONST(0x0303000003020001), ABC_CONST(0x0303000000020001), ABC_CONST(0x0300030303020001), ABC_CONST(0x0300030300020001), ABC_CONST(0x0300030003020001), ABC_CONST(0x0300030000020001), ABC_CONST(0x0300000303020001), ABC_CONST(0x0300000300020001), ABC_CONST(0x0300000003020001), ABC_CONST(0x0300000000020001), ABC_CONST(0x0303030303020001), ABC_CONST(0x0303030300020001), ABC_CONST(0x0303030003020001), ABC_CONST(0x0303030000020001), ABC_CONST(0x0303000303020001), ABC_CONST(0x0303000300020001), ABC_CONST(0x0303000003020001), ABC_CONST(0x0303000000020001), ABC_CONST(0x0300030303020001), ABC_CONST(0x0300030300020001), ABC_CONST(0x0300030003020001), ABC_CONST(0x0300030000020001), ABC_CONST(0x0300000303020001), ABC_CONST(0x0300000300020001), ABC_CONST(0x0300000003020001), ABC_CONST(0x0300000000020001) }, + { ABC_CONST(0x0404040404030102), ABC_CONST(0x0404040400030102), ABC_CONST(0x0404040004030102), ABC_CONST(0x0404040000030102), ABC_CONST(0x0404000404030102), ABC_CONST(0x0404000400030102), ABC_CONST(0x0404000004030102), ABC_CONST(0x0404000000030102), ABC_CONST(0x0400040404030102), ABC_CONST(0x0400040400030102), ABC_CONST(0x0400040004030102), ABC_CONST(0x0400040000030102), ABC_CONST(0x0400000404030102), ABC_CONST(0x0400000400030102), ABC_CONST(0x0400000004030102), ABC_CONST(0x0400000000030102), ABC_CONST(0x0404040404030102), ABC_CONST(0x0404040400030102), ABC_CONST(0x0404040004030102), ABC_CONST(0x0404040000030102), ABC_CONST(0x0404000404030102), ABC_CONST(0x0404000400030102), ABC_CONST(0x0404000004030102), ABC_CONST(0x0404000000030102), ABC_CONST(0x0400040404030102), ABC_CONST(0x0400040400030102), ABC_CONST(0x0400040004030102), ABC_CONST(0x0400040000030102), ABC_CONST(0x0400000404030102), ABC_CONST(0x0400000400030102), ABC_CONST(0x0400000004030102), ABC_CONST(0x0400000000030102) }, + { ABC_CONST(0x0404040404030101), ABC_CONST(0x0404040400030101), ABC_CONST(0x0404040004030101), ABC_CONST(0x0404040000030101), ABC_CONST(0x0404000404030101), ABC_CONST(0x0404000400030101), ABC_CONST(0x0404000004030101), ABC_CONST(0x0404000000030101), ABC_CONST(0x0400040404030101), ABC_CONST(0x0400040400030101), ABC_CONST(0x0400040004030101), ABC_CONST(0x0400040000030101), ABC_CONST(0x0400000404030101), ABC_CONST(0x0400000400030101), ABC_CONST(0x0400000004030101), ABC_CONST(0x0400000000030101), ABC_CONST(0x0404040404030101), ABC_CONST(0x0404040400030101), ABC_CONST(0x0404040004030101), ABC_CONST(0x0404040000030101), ABC_CONST(0x0404000404030101), ABC_CONST(0x0404000400030101), ABC_CONST(0x0404000004030101), ABC_CONST(0x0404000000030101), ABC_CONST(0x0400040404030101), ABC_CONST(0x0400040400030101), ABC_CONST(0x0400040004030101), ABC_CONST(0x0400040000030101), ABC_CONST(0x0400000404030101), ABC_CONST(0x0400000400030101), ABC_CONST(0x0400000004030101), ABC_CONST(0x0400000000030101) }, + { ABC_CONST(0x0505050505040202), ABC_CONST(0x0505050500040202), ABC_CONST(0x0505050005040202), ABC_CONST(0x0505050000040202), ABC_CONST(0x0505000505040202), ABC_CONST(0x0505000500040202), ABC_CONST(0x0505000005040202), ABC_CONST(0x0505000000040202), ABC_CONST(0x0500050505040202), ABC_CONST(0x0500050500040202), ABC_CONST(0x0500050005040202), ABC_CONST(0x0500050000040202), ABC_CONST(0x0500000505040202), ABC_CONST(0x0500000500040202), ABC_CONST(0x0500000005040202), ABC_CONST(0x0500000000040202), ABC_CONST(0x0505050505040202), ABC_CONST(0x0505050500040202), ABC_CONST(0x0505050005040202), ABC_CONST(0x0505050000040202), ABC_CONST(0x0505000505040202), ABC_CONST(0x0505000500040202), ABC_CONST(0x0505000005040202), ABC_CONST(0x0505000000040202), ABC_CONST(0x0500050505040202), ABC_CONST(0x0500050500040202), ABC_CONST(0x0500050005040202), ABC_CONST(0x0500050000040202), ABC_CONST(0x0500000505040202), ABC_CONST(0x0500000500040202), ABC_CONST(0x0500000005040202), ABC_CONST(0x0500000000040202) }, + { ABC_CONST(0x0202020202000101), ABC_CONST(0x0202020200000101), ABC_CONST(0x0202020002000101), ABC_CONST(0x0202020000000101), ABC_CONST(0x0202000202000101), ABC_CONST(0x0202000200000101), ABC_CONST(0x0202000002000101), ABC_CONST(0x0202000000000101), ABC_CONST(0x0200020202000101), ABC_CONST(0x0200020200000101), ABC_CONST(0x0200020002000101), ABC_CONST(0x0200020000000101), ABC_CONST(0x0200000202000101), ABC_CONST(0x0200000200000101), ABC_CONST(0x0200000002000101), ABC_CONST(0x0200000000000101), ABC_CONST(0x0202020202000101), ABC_CONST(0x0202020200000101), ABC_CONST(0x0202020002000101), ABC_CONST(0x0202020000000101), ABC_CONST(0x0202000202000101), ABC_CONST(0x0202000200000101), ABC_CONST(0x0202000002000101), ABC_CONST(0x0202000000000101), ABC_CONST(0x0200020202000101), ABC_CONST(0x0200020200000101), ABC_CONST(0x0200020002000101), ABC_CONST(0x0200020000000101), ABC_CONST(0x0200000202000101), ABC_CONST(0x0200000200000101), ABC_CONST(0x0200000002000101), ABC_CONST(0x0200000000000101) }, + { ABC_CONST(0x0303030303010202), ABC_CONST(0x0303030300010202), ABC_CONST(0x0303030003010202), ABC_CONST(0x0303030000010202), ABC_CONST(0x0303000303010202), ABC_CONST(0x0303000300010202), ABC_CONST(0x0303000003010202), ABC_CONST(0x0303000000010202), ABC_CONST(0x0300030303010202), ABC_CONST(0x0300030300010202), ABC_CONST(0x0300030003010202), ABC_CONST(0x0300030000010202), ABC_CONST(0x0300000303010202), ABC_CONST(0x0300000300010202), ABC_CONST(0x0300000003010202), ABC_CONST(0x0300000000010202), ABC_CONST(0x0303030303010202), ABC_CONST(0x0303030300010202), ABC_CONST(0x0303030003010202), ABC_CONST(0x0303030000010202), ABC_CONST(0x0303000303010202), ABC_CONST(0x0303000300010202), ABC_CONST(0x0303000003010202), ABC_CONST(0x0303000000010202), ABC_CONST(0x0300030303010202), ABC_CONST(0x0300030300010202), ABC_CONST(0x0300030003010202), ABC_CONST(0x0300030000010202), ABC_CONST(0x0300000303010202), ABC_CONST(0x0300000300010202), ABC_CONST(0x0300000003010202), ABC_CONST(0x0300000000010202) }, + { ABC_CONST(0x0303030303010201), ABC_CONST(0x0303030300010201), ABC_CONST(0x0303030003010201), ABC_CONST(0x0303030000010201), ABC_CONST(0x0303000303010201), ABC_CONST(0x0303000300010201), ABC_CONST(0x0303000003010201), ABC_CONST(0x0303000000010201), ABC_CONST(0x0300030303010201), ABC_CONST(0x0300030300010201), ABC_CONST(0x0300030003010201), ABC_CONST(0x0300030000010201), ABC_CONST(0x0300000303010201), ABC_CONST(0x0300000300010201), ABC_CONST(0x0300000003010201), ABC_CONST(0x0300000000010201), ABC_CONST(0x0303030303010201), ABC_CONST(0x0303030300010201), ABC_CONST(0x0303030003010201), ABC_CONST(0x0303030000010201), ABC_CONST(0x0303000303010201), ABC_CONST(0x0303000300010201), ABC_CONST(0x0303000003010201), ABC_CONST(0x0303000000010201), ABC_CONST(0x0300030303010201), ABC_CONST(0x0300030300010201), ABC_CONST(0x0300030003010201), ABC_CONST(0x0300030000010201), ABC_CONST(0x0300000303010201), ABC_CONST(0x0300000300010201), ABC_CONST(0x0300000003010201), ABC_CONST(0x0300000000010201) }, + { ABC_CONST(0x0404040404020302), ABC_CONST(0x0404040400020302), ABC_CONST(0x0404040004020302), ABC_CONST(0x0404040000020302), ABC_CONST(0x0404000404020302), ABC_CONST(0x0404000400020302), ABC_CONST(0x0404000004020302), ABC_CONST(0x0404000000020302), ABC_CONST(0x0400040404020302), ABC_CONST(0x0400040400020302), ABC_CONST(0x0400040004020302), ABC_CONST(0x0400040000020302), ABC_CONST(0x0400000404020302), ABC_CONST(0x0400000400020302), ABC_CONST(0x0400000004020302), ABC_CONST(0x0400000000020302), ABC_CONST(0x0404040404020302), ABC_CONST(0x0404040400020302), ABC_CONST(0x0404040004020302), ABC_CONST(0x0404040000020302), ABC_CONST(0x0404000404020302), ABC_CONST(0x0404000400020302), ABC_CONST(0x0404000004020302), ABC_CONST(0x0404000000020302), ABC_CONST(0x0400040404020302), ABC_CONST(0x0400040400020302), ABC_CONST(0x0400040004020302), ABC_CONST(0x0400040000020302), ABC_CONST(0x0400000404020302), ABC_CONST(0x0400000400020302), ABC_CONST(0x0400000004020302), ABC_CONST(0x0400000000020302) }, + { ABC_CONST(0x0303030303010102), ABC_CONST(0x0303030300010102), ABC_CONST(0x0303030003010102), ABC_CONST(0x0303030000010102), ABC_CONST(0x0303000303010102), ABC_CONST(0x0303000300010102), ABC_CONST(0x0303000003010102), ABC_CONST(0x0303000000010102), ABC_CONST(0x0300030303010102), ABC_CONST(0x0300030300010102), ABC_CONST(0x0300030003010102), ABC_CONST(0x0300030000010102), ABC_CONST(0x0300000303010102), ABC_CONST(0x0300000300010102), ABC_CONST(0x0300000003010102), ABC_CONST(0x0300000000010102), ABC_CONST(0x0303030303010102), ABC_CONST(0x0303030300010102), ABC_CONST(0x0303030003010102), ABC_CONST(0x0303030000010102), ABC_CONST(0x0303000303010102), ABC_CONST(0x0303000300010102), ABC_CONST(0x0303000003010102), ABC_CONST(0x0303000000010102), ABC_CONST(0x0300030303010102), ABC_CONST(0x0300030300010102), ABC_CONST(0x0300030003010102), ABC_CONST(0x0300030000010102), ABC_CONST(0x0300000303010102), ABC_CONST(0x0300000300010102), ABC_CONST(0x0300000003010102), ABC_CONST(0x0300000000010102) }, + { ABC_CONST(0x0404040404020203), ABC_CONST(0x0404040400020203), ABC_CONST(0x0404040004020203), ABC_CONST(0x0404040000020203), ABC_CONST(0x0404000404020203), ABC_CONST(0x0404000400020203), ABC_CONST(0x0404000004020203), ABC_CONST(0x0404000000020203), ABC_CONST(0x0400040404020203), ABC_CONST(0x0400040400020203), ABC_CONST(0x0400040004020203), ABC_CONST(0x0400040000020203), ABC_CONST(0x0400000404020203), ABC_CONST(0x0400000400020203), ABC_CONST(0x0400000004020203), ABC_CONST(0x0400000000020203), ABC_CONST(0x0404040404020203), ABC_CONST(0x0404040400020203), ABC_CONST(0x0404040004020203), ABC_CONST(0x0404040000020203), ABC_CONST(0x0404000404020203), ABC_CONST(0x0404000400020203), ABC_CONST(0x0404000004020203), ABC_CONST(0x0404000000020203), ABC_CONST(0x0400040404020203), ABC_CONST(0x0400040400020203), ABC_CONST(0x0400040004020203), ABC_CONST(0x0400040000020203), ABC_CONST(0x0400000404020203), ABC_CONST(0x0400000400020203), ABC_CONST(0x0400000004020203), ABC_CONST(0x0400000000020203) }, + { ABC_CONST(0x0404040404020202), ABC_CONST(0x0404040400020202), ABC_CONST(0x0404040004020202), ABC_CONST(0x0404040000020202), ABC_CONST(0x0404000404020202), ABC_CONST(0x0404000400020202), ABC_CONST(0x0404000004020202), ABC_CONST(0x0404000000020202), ABC_CONST(0x0400040404020202), ABC_CONST(0x0400040400020202), ABC_CONST(0x0400040004020202), ABC_CONST(0x0400040000020202), ABC_CONST(0x0400000404020202), ABC_CONST(0x0400000400020202), ABC_CONST(0x0400000004020202), ABC_CONST(0x0400000000020202), ABC_CONST(0x0404040404020202), ABC_CONST(0x0404040400020202), ABC_CONST(0x0404040004020202), ABC_CONST(0x0404040000020202), ABC_CONST(0x0404000404020202), ABC_CONST(0x0404000400020202), ABC_CONST(0x0404000004020202), ABC_CONST(0x0404000000020202), ABC_CONST(0x0400040404020202), ABC_CONST(0x0400040400020202), ABC_CONST(0x0400040004020202), ABC_CONST(0x0400040000020202), ABC_CONST(0x0400000404020202), ABC_CONST(0x0400000400020202), ABC_CONST(0x0400000004020202), ABC_CONST(0x0400000000020202) }, + { ABC_CONST(0x0505050505030303), ABC_CONST(0x0505050500030303), ABC_CONST(0x0505050005030303), ABC_CONST(0x0505050000030303), ABC_CONST(0x0505000505030303), ABC_CONST(0x0505000500030303), ABC_CONST(0x0505000005030303), ABC_CONST(0x0505000000030303), ABC_CONST(0x0500050505030303), ABC_CONST(0x0500050500030303), ABC_CONST(0x0500050005030303), ABC_CONST(0x0500050000030303), ABC_CONST(0x0500000505030303), ABC_CONST(0x0500000500030303), ABC_CONST(0x0500000005030303), ABC_CONST(0x0500000000030303), ABC_CONST(0x0505050505030303), ABC_CONST(0x0505050500030303), ABC_CONST(0x0505050005030303), ABC_CONST(0x0505050000030303), ABC_CONST(0x0505000505030303), ABC_CONST(0x0505000500030303), ABC_CONST(0x0505000005030303), ABC_CONST(0x0505000000030303), ABC_CONST(0x0500050505030303), ABC_CONST(0x0500050500030303), ABC_CONST(0x0500050005030303), ABC_CONST(0x0500050000030303), ABC_CONST(0x0500000505030303), ABC_CONST(0x0500000500030303), ABC_CONST(0x0500000005030303), ABC_CONST(0x0500000000030303) }, + { ABC_CONST(0x0303030303010101), ABC_CONST(0x0303030300010101), ABC_CONST(0x0303030003010101), ABC_CONST(0x0303030000010101), ABC_CONST(0x0303000303010101), ABC_CONST(0x0303000300010101), ABC_CONST(0x0303000003010101), ABC_CONST(0x0303000000010101), ABC_CONST(0x0300030303010101), ABC_CONST(0x0300030300010101), ABC_CONST(0x0300030003010101), ABC_CONST(0x0300030000010101), ABC_CONST(0x0300000303010101), ABC_CONST(0x0300000300010101), ABC_CONST(0x0300000003010101), ABC_CONST(0x0300000000010101), ABC_CONST(0x0303030303010101), ABC_CONST(0x0303030300010101), ABC_CONST(0x0303030003010101), ABC_CONST(0x0303030000010101), ABC_CONST(0x0303000303010101), ABC_CONST(0x0303000300010101), ABC_CONST(0x0303000003010101), ABC_CONST(0x0303000000010101), ABC_CONST(0x0300030303010101), ABC_CONST(0x0300030300010101), ABC_CONST(0x0300030003010101), ABC_CONST(0x0300030000010101), ABC_CONST(0x0300000303010101), ABC_CONST(0x0300000300010101), ABC_CONST(0x0300000003010101), ABC_CONST(0x0300000000010101) }, + { ABC_CONST(0x0404040404020202), ABC_CONST(0x0404040400020202), ABC_CONST(0x0404040004020202), ABC_CONST(0x0404040000020202), ABC_CONST(0x0404000404020202), ABC_CONST(0x0404000400020202), ABC_CONST(0x0404000004020202), ABC_CONST(0x0404000000020202), ABC_CONST(0x0400040404020202), ABC_CONST(0x0400040400020202), ABC_CONST(0x0400040004020202), ABC_CONST(0x0400040000020202), ABC_CONST(0x0400000404020202), ABC_CONST(0x0400000400020202), ABC_CONST(0x0400000004020202), ABC_CONST(0x0400000000020202), ABC_CONST(0x0404040404020202), ABC_CONST(0x0404040400020202), ABC_CONST(0x0404040004020202), ABC_CONST(0x0404040000020202), ABC_CONST(0x0404000404020202), ABC_CONST(0x0404000400020202), ABC_CONST(0x0404000004020202), ABC_CONST(0x0404000000020202), ABC_CONST(0x0400040404020202), ABC_CONST(0x0400040400020202), ABC_CONST(0x0400040004020202), ABC_CONST(0x0400040000020202), ABC_CONST(0x0400000404020202), ABC_CONST(0x0400000400020202), ABC_CONST(0x0400000004020202), ABC_CONST(0x0400000000020202) }, + { ABC_CONST(0x0404040404020201), ABC_CONST(0x0404040400020201), ABC_CONST(0x0404040004020201), ABC_CONST(0x0404040000020201), ABC_CONST(0x0404000404020201), ABC_CONST(0x0404000400020201), ABC_CONST(0x0404000004020201), ABC_CONST(0x0404000000020201), ABC_CONST(0x0400040404020201), ABC_CONST(0x0400040400020201), ABC_CONST(0x0400040004020201), ABC_CONST(0x0400040000020201), ABC_CONST(0x0400000404020201), ABC_CONST(0x0400000400020201), ABC_CONST(0x0400000004020201), ABC_CONST(0x0400000000020201), ABC_CONST(0x0404040404020201), ABC_CONST(0x0404040400020201), ABC_CONST(0x0404040004020201), ABC_CONST(0x0404040000020201), ABC_CONST(0x0404000404020201), ABC_CONST(0x0404000400020201), ABC_CONST(0x0404000004020201), ABC_CONST(0x0404000000020201), ABC_CONST(0x0400040404020201), ABC_CONST(0x0400040400020201), ABC_CONST(0x0400040004020201), ABC_CONST(0x0400040000020201), ABC_CONST(0x0400000404020201), ABC_CONST(0x0400000400020201), ABC_CONST(0x0400000004020201), ABC_CONST(0x0400000000020201) }, + { ABC_CONST(0x0505050505030302), ABC_CONST(0x0505050500030302), ABC_CONST(0x0505050005030302), ABC_CONST(0x0505050000030302), ABC_CONST(0x0505000505030302), ABC_CONST(0x0505000500030302), ABC_CONST(0x0505000005030302), ABC_CONST(0x0505000000030302), ABC_CONST(0x0500050505030302), ABC_CONST(0x0500050500030302), ABC_CONST(0x0500050005030302), ABC_CONST(0x0500050000030302), ABC_CONST(0x0500000505030302), ABC_CONST(0x0500000500030302), ABC_CONST(0x0500000005030302), ABC_CONST(0x0500000000030302), ABC_CONST(0x0505050505030302), ABC_CONST(0x0505050500030302), ABC_CONST(0x0505050005030302), ABC_CONST(0x0505050000030302), ABC_CONST(0x0505000505030302), ABC_CONST(0x0505000500030302), ABC_CONST(0x0505000005030302), ABC_CONST(0x0505000000030302), ABC_CONST(0x0500050505030302), ABC_CONST(0x0500050500030302), ABC_CONST(0x0500050005030302), ABC_CONST(0x0500050000030302), ABC_CONST(0x0500000505030302), ABC_CONST(0x0500000500030302), ABC_CONST(0x0500000005030302), ABC_CONST(0x0500000000030302) }, + { ABC_CONST(0x0404040404020102), ABC_CONST(0x0404040400020102), ABC_CONST(0x0404040004020102), ABC_CONST(0x0404040000020102), ABC_CONST(0x0404000404020102), ABC_CONST(0x0404000400020102), ABC_CONST(0x0404000004020102), ABC_CONST(0x0404000000020102), ABC_CONST(0x0400040404020102), ABC_CONST(0x0400040400020102), ABC_CONST(0x0400040004020102), ABC_CONST(0x0400040000020102), ABC_CONST(0x0400000404020102), ABC_CONST(0x0400000400020102), ABC_CONST(0x0400000004020102), ABC_CONST(0x0400000000020102), ABC_CONST(0x0404040404020102), ABC_CONST(0x0404040400020102), ABC_CONST(0x0404040004020102), ABC_CONST(0x0404040000020102), ABC_CONST(0x0404000404020102), ABC_CONST(0x0404000400020102), ABC_CONST(0x0404000004020102), ABC_CONST(0x0404000000020102), ABC_CONST(0x0400040404020102), ABC_CONST(0x0400040400020102), ABC_CONST(0x0400040004020102), ABC_CONST(0x0400040000020102), ABC_CONST(0x0400000404020102), ABC_CONST(0x0400000400020102), ABC_CONST(0x0400000004020102), ABC_CONST(0x0400000000020102) }, + { ABC_CONST(0x0505050505030203), ABC_CONST(0x0505050500030203), ABC_CONST(0x0505050005030203), ABC_CONST(0x0505050000030203), ABC_CONST(0x0505000505030203), ABC_CONST(0x0505000500030203), ABC_CONST(0x0505000005030203), ABC_CONST(0x0505000000030203), ABC_CONST(0x0500050505030203), ABC_CONST(0x0500050500030203), ABC_CONST(0x0500050005030203), ABC_CONST(0x0500050000030203), ABC_CONST(0x0500000505030203), ABC_CONST(0x0500000500030203), ABC_CONST(0x0500000005030203), ABC_CONST(0x0500000000030203), ABC_CONST(0x0505050505030203), ABC_CONST(0x0505050500030203), ABC_CONST(0x0505050005030203), ABC_CONST(0x0505050000030203), ABC_CONST(0x0505000505030203), ABC_CONST(0x0505000500030203), ABC_CONST(0x0505000005030203), ABC_CONST(0x0505000000030203), ABC_CONST(0x0500050505030203), ABC_CONST(0x0500050500030203), ABC_CONST(0x0500050005030203), ABC_CONST(0x0500050000030203), ABC_CONST(0x0500000505030203), ABC_CONST(0x0500000500030203), ABC_CONST(0x0500000005030203), ABC_CONST(0x0500000000030203) }, + { ABC_CONST(0x0505050505030202), ABC_CONST(0x0505050500030202), ABC_CONST(0x0505050005030202), ABC_CONST(0x0505050000030202), ABC_CONST(0x0505000505030202), ABC_CONST(0x0505000500030202), ABC_CONST(0x0505000005030202), ABC_CONST(0x0505000000030202), ABC_CONST(0x0500050505030202), ABC_CONST(0x0500050500030202), ABC_CONST(0x0500050005030202), ABC_CONST(0x0500050000030202), ABC_CONST(0x0500000505030202), ABC_CONST(0x0500000500030202), ABC_CONST(0x0500000005030202), ABC_CONST(0x0500000000030202), ABC_CONST(0x0505050505030202), ABC_CONST(0x0505050500030202), ABC_CONST(0x0505050005030202), ABC_CONST(0x0505050000030202), ABC_CONST(0x0505000505030202), ABC_CONST(0x0505000500030202), ABC_CONST(0x0505000005030202), ABC_CONST(0x0505000000030202), ABC_CONST(0x0500050505030202), ABC_CONST(0x0500050500030202), ABC_CONST(0x0500050005030202), ABC_CONST(0x0500050000030202), ABC_CONST(0x0500000505030202), ABC_CONST(0x0500000500030202), ABC_CONST(0x0500000005030202), ABC_CONST(0x0500000000030202) }, + { ABC_CONST(0x0606060606040303), ABC_CONST(0x0606060600040303), ABC_CONST(0x0606060006040303), ABC_CONST(0x0606060000040303), ABC_CONST(0x0606000606040303), ABC_CONST(0x0606000600040303), ABC_CONST(0x0606000006040303), ABC_CONST(0x0606000000040303), ABC_CONST(0x0600060606040303), ABC_CONST(0x0600060600040303), ABC_CONST(0x0600060006040303), ABC_CONST(0x0600060000040303), ABC_CONST(0x0600000606040303), ABC_CONST(0x0600000600040303), ABC_CONST(0x0600000006040303), ABC_CONST(0x0600000000040303), ABC_CONST(0x0606060606040303), ABC_CONST(0x0606060600040303), ABC_CONST(0x0606060006040303), ABC_CONST(0x0606060000040303), ABC_CONST(0x0606000606040303), ABC_CONST(0x0606000600040303), ABC_CONST(0x0606000006040303), ABC_CONST(0x0606000000040303), ABC_CONST(0x0600060606040303), ABC_CONST(0x0600060600040303), ABC_CONST(0x0600060006040303), ABC_CONST(0x0600060000040303), ABC_CONST(0x0600000606040303), ABC_CONST(0x0600000600040303), ABC_CONST(0x0600000006040303), ABC_CONST(0x0600000000040303) }, + { ABC_CONST(0x0202020202000100), ABC_CONST(0x0202020200000100), ABC_CONST(0x0202020002000100), ABC_CONST(0x0202020000000100), ABC_CONST(0x0202000202000100), ABC_CONST(0x0202000200000100), ABC_CONST(0x0202000002000100), ABC_CONST(0x0202000000000100), ABC_CONST(0x0200020202000100), ABC_CONST(0x0200020200000100), ABC_CONST(0x0200020002000100), ABC_CONST(0x0200020000000100), ABC_CONST(0x0200000202000100), ABC_CONST(0x0200000200000100), ABC_CONST(0x0200000002000100), ABC_CONST(0x0200000000000100), ABC_CONST(0x0202020202000100), ABC_CONST(0x0202020200000100), ABC_CONST(0x0202020002000100), ABC_CONST(0x0202020000000100), ABC_CONST(0x0202000202000100), ABC_CONST(0x0202000200000100), ABC_CONST(0x0202000002000100), ABC_CONST(0x0202000000000100), ABC_CONST(0x0200020202000100), ABC_CONST(0x0200020200000100), ABC_CONST(0x0200020002000100), ABC_CONST(0x0200020000000100), ABC_CONST(0x0200000202000100), ABC_CONST(0x0200000200000100), ABC_CONST(0x0200000002000100), ABC_CONST(0x0200000000000100) }, + { ABC_CONST(0x0303030303010201), ABC_CONST(0x0303030300010201), ABC_CONST(0x0303030003010201), ABC_CONST(0x0303030000010201), ABC_CONST(0x0303000303010201), ABC_CONST(0x0303000300010201), ABC_CONST(0x0303000003010201), ABC_CONST(0x0303000000010201), ABC_CONST(0x0300030303010201), ABC_CONST(0x0300030300010201), ABC_CONST(0x0300030003010201), ABC_CONST(0x0300030000010201), ABC_CONST(0x0300000303010201), ABC_CONST(0x0300000300010201), ABC_CONST(0x0300000003010201), ABC_CONST(0x0300000000010201), ABC_CONST(0x0303030303010201), ABC_CONST(0x0303030300010201), ABC_CONST(0x0303030003010201), ABC_CONST(0x0303030000010201), ABC_CONST(0x0303000303010201), ABC_CONST(0x0303000300010201), ABC_CONST(0x0303000003010201), ABC_CONST(0x0303000000010201), ABC_CONST(0x0300030303010201), ABC_CONST(0x0300030300010201), ABC_CONST(0x0300030003010201), ABC_CONST(0x0300030000010201), ABC_CONST(0x0300000303010201), ABC_CONST(0x0300000300010201), ABC_CONST(0x0300000003010201), ABC_CONST(0x0300000000010201) }, + { ABC_CONST(0x0303030303010200), ABC_CONST(0x0303030300010200), ABC_CONST(0x0303030003010200), ABC_CONST(0x0303030000010200), ABC_CONST(0x0303000303010200), ABC_CONST(0x0303000300010200), ABC_CONST(0x0303000003010200), ABC_CONST(0x0303000000010200), ABC_CONST(0x0300030303010200), ABC_CONST(0x0300030300010200), ABC_CONST(0x0300030003010200), ABC_CONST(0x0300030000010200), ABC_CONST(0x0300000303010200), ABC_CONST(0x0300000300010200), ABC_CONST(0x0300000003010200), ABC_CONST(0x0300000000010200), ABC_CONST(0x0303030303010200), ABC_CONST(0x0303030300010200), ABC_CONST(0x0303030003010200), ABC_CONST(0x0303030000010200), ABC_CONST(0x0303000303010200), ABC_CONST(0x0303000300010200), ABC_CONST(0x0303000003010200), ABC_CONST(0x0303000000010200), ABC_CONST(0x0300030303010200), ABC_CONST(0x0300030300010200), ABC_CONST(0x0300030003010200), ABC_CONST(0x0300030000010200), ABC_CONST(0x0300000303010200), ABC_CONST(0x0300000300010200), ABC_CONST(0x0300000003010200), ABC_CONST(0x0300000000010200) }, + { ABC_CONST(0x0404040404020301), ABC_CONST(0x0404040400020301), ABC_CONST(0x0404040004020301), ABC_CONST(0x0404040000020301), ABC_CONST(0x0404000404020301), ABC_CONST(0x0404000400020301), ABC_CONST(0x0404000004020301), ABC_CONST(0x0404000000020301), ABC_CONST(0x0400040404020301), ABC_CONST(0x0400040400020301), ABC_CONST(0x0400040004020301), ABC_CONST(0x0400040000020301), ABC_CONST(0x0400000404020301), ABC_CONST(0x0400000400020301), ABC_CONST(0x0400000004020301), ABC_CONST(0x0400000000020301), ABC_CONST(0x0404040404020301), ABC_CONST(0x0404040400020301), ABC_CONST(0x0404040004020301), ABC_CONST(0x0404040000020301), ABC_CONST(0x0404000404020301), ABC_CONST(0x0404000400020301), ABC_CONST(0x0404000004020301), ABC_CONST(0x0404000000020301), ABC_CONST(0x0400040404020301), ABC_CONST(0x0400040400020301), ABC_CONST(0x0400040004020301), ABC_CONST(0x0400040000020301), ABC_CONST(0x0400000404020301), ABC_CONST(0x0400000400020301), ABC_CONST(0x0400000004020301), ABC_CONST(0x0400000000020301) }, + { ABC_CONST(0x0303030303010101), ABC_CONST(0x0303030300010101), ABC_CONST(0x0303030003010101), ABC_CONST(0x0303030000010101), ABC_CONST(0x0303000303010101), ABC_CONST(0x0303000300010101), ABC_CONST(0x0303000003010101), ABC_CONST(0x0303000000010101), ABC_CONST(0x0300030303010101), ABC_CONST(0x0300030300010101), ABC_CONST(0x0300030003010101), ABC_CONST(0x0300030000010101), ABC_CONST(0x0300000303010101), ABC_CONST(0x0300000300010101), ABC_CONST(0x0300000003010101), ABC_CONST(0x0300000000010101), ABC_CONST(0x0303030303010101), ABC_CONST(0x0303030300010101), ABC_CONST(0x0303030003010101), ABC_CONST(0x0303030000010101), ABC_CONST(0x0303000303010101), ABC_CONST(0x0303000300010101), ABC_CONST(0x0303000003010101), ABC_CONST(0x0303000000010101), ABC_CONST(0x0300030303010101), ABC_CONST(0x0300030300010101), ABC_CONST(0x0300030003010101), ABC_CONST(0x0300030000010101), ABC_CONST(0x0300000303010101), ABC_CONST(0x0300000300010101), ABC_CONST(0x0300000003010101), ABC_CONST(0x0300000000010101) }, + { ABC_CONST(0x0404040404020202), ABC_CONST(0x0404040400020202), ABC_CONST(0x0404040004020202), ABC_CONST(0x0404040000020202), ABC_CONST(0x0404000404020202), ABC_CONST(0x0404000400020202), ABC_CONST(0x0404000004020202), ABC_CONST(0x0404000000020202), ABC_CONST(0x0400040404020202), ABC_CONST(0x0400040400020202), ABC_CONST(0x0400040004020202), ABC_CONST(0x0400040000020202), ABC_CONST(0x0400000404020202), ABC_CONST(0x0400000400020202), ABC_CONST(0x0400000004020202), ABC_CONST(0x0400000000020202), ABC_CONST(0x0404040404020202), ABC_CONST(0x0404040400020202), ABC_CONST(0x0404040004020202), ABC_CONST(0x0404040000020202), ABC_CONST(0x0404000404020202), ABC_CONST(0x0404000400020202), ABC_CONST(0x0404000004020202), ABC_CONST(0x0404000000020202), ABC_CONST(0x0400040404020202), ABC_CONST(0x0400040400020202), ABC_CONST(0x0400040004020202), ABC_CONST(0x0400040000020202), ABC_CONST(0x0400000404020202), ABC_CONST(0x0400000400020202), ABC_CONST(0x0400000004020202), ABC_CONST(0x0400000000020202) }, + { ABC_CONST(0x0404040404020201), ABC_CONST(0x0404040400020201), ABC_CONST(0x0404040004020201), ABC_CONST(0x0404040000020201), ABC_CONST(0x0404000404020201), ABC_CONST(0x0404000400020201), ABC_CONST(0x0404000004020201), ABC_CONST(0x0404000000020201), ABC_CONST(0x0400040404020201), ABC_CONST(0x0400040400020201), ABC_CONST(0x0400040004020201), ABC_CONST(0x0400040000020201), ABC_CONST(0x0400000404020201), ABC_CONST(0x0400000400020201), ABC_CONST(0x0400000004020201), ABC_CONST(0x0400000000020201), ABC_CONST(0x0404040404020201), ABC_CONST(0x0404040400020201), ABC_CONST(0x0404040004020201), ABC_CONST(0x0404040000020201), ABC_CONST(0x0404000404020201), ABC_CONST(0x0404000400020201), ABC_CONST(0x0404000004020201), ABC_CONST(0x0404000000020201), ABC_CONST(0x0400040404020201), ABC_CONST(0x0400040400020201), ABC_CONST(0x0400040004020201), ABC_CONST(0x0400040000020201), ABC_CONST(0x0400000404020201), ABC_CONST(0x0400000400020201), ABC_CONST(0x0400000004020201), ABC_CONST(0x0400000000020201) }, + { ABC_CONST(0x0505050505030302), ABC_CONST(0x0505050500030302), ABC_CONST(0x0505050005030302), ABC_CONST(0x0505050000030302), ABC_CONST(0x0505000505030302), ABC_CONST(0x0505000500030302), ABC_CONST(0x0505000005030302), ABC_CONST(0x0505000000030302), ABC_CONST(0x0500050505030302), ABC_CONST(0x0500050500030302), ABC_CONST(0x0500050005030302), ABC_CONST(0x0500050000030302), ABC_CONST(0x0500000505030302), ABC_CONST(0x0500000500030302), ABC_CONST(0x0500000005030302), ABC_CONST(0x0500000000030302), ABC_CONST(0x0505050505030302), ABC_CONST(0x0505050500030302), ABC_CONST(0x0505050005030302), ABC_CONST(0x0505050000030302), ABC_CONST(0x0505000505030302), ABC_CONST(0x0505000500030302), ABC_CONST(0x0505000005030302), ABC_CONST(0x0505000000030302), ABC_CONST(0x0500050505030302), ABC_CONST(0x0500050500030302), ABC_CONST(0x0500050005030302), ABC_CONST(0x0500050000030302), ABC_CONST(0x0500000505030302), ABC_CONST(0x0500000500030302), ABC_CONST(0x0500000005030302), ABC_CONST(0x0500000000030302) }, + { ABC_CONST(0x0303030303010100), ABC_CONST(0x0303030300010100), ABC_CONST(0x0303030003010100), ABC_CONST(0x0303030000010100), ABC_CONST(0x0303000303010100), ABC_CONST(0x0303000300010100), ABC_CONST(0x0303000003010100), ABC_CONST(0x0303000000010100), ABC_CONST(0x0300030303010100), ABC_CONST(0x0300030300010100), ABC_CONST(0x0300030003010100), ABC_CONST(0x0300030000010100), ABC_CONST(0x0300000303010100), ABC_CONST(0x0300000300010100), ABC_CONST(0x0300000003010100), ABC_CONST(0x0300000000010100), ABC_CONST(0x0303030303010100), ABC_CONST(0x0303030300010100), ABC_CONST(0x0303030003010100), ABC_CONST(0x0303030000010100), ABC_CONST(0x0303000303010100), ABC_CONST(0x0303000300010100), ABC_CONST(0x0303000003010100), ABC_CONST(0x0303000000010100), ABC_CONST(0x0300030303010100), ABC_CONST(0x0300030300010100), ABC_CONST(0x0300030003010100), ABC_CONST(0x0300030000010100), ABC_CONST(0x0300000303010100), ABC_CONST(0x0300000300010100), ABC_CONST(0x0300000003010100), ABC_CONST(0x0300000000010100) }, + { ABC_CONST(0x0404040404020201), ABC_CONST(0x0404040400020201), ABC_CONST(0x0404040004020201), ABC_CONST(0x0404040000020201), ABC_CONST(0x0404000404020201), ABC_CONST(0x0404000400020201), ABC_CONST(0x0404000004020201), ABC_CONST(0x0404000000020201), ABC_CONST(0x0400040404020201), ABC_CONST(0x0400040400020201), ABC_CONST(0x0400040004020201), ABC_CONST(0x0400040000020201), ABC_CONST(0x0400000404020201), ABC_CONST(0x0400000400020201), ABC_CONST(0x0400000004020201), ABC_CONST(0x0400000000020201), ABC_CONST(0x0404040404020201), ABC_CONST(0x0404040400020201), ABC_CONST(0x0404040004020201), ABC_CONST(0x0404040000020201), ABC_CONST(0x0404000404020201), ABC_CONST(0x0404000400020201), ABC_CONST(0x0404000004020201), ABC_CONST(0x0404000000020201), ABC_CONST(0x0400040404020201), ABC_CONST(0x0400040400020201), ABC_CONST(0x0400040004020201), ABC_CONST(0x0400040000020201), ABC_CONST(0x0400000404020201), ABC_CONST(0x0400000400020201), ABC_CONST(0x0400000004020201), ABC_CONST(0x0400000000020201) }, + { ABC_CONST(0x0404040404020200), ABC_CONST(0x0404040400020200), ABC_CONST(0x0404040004020200), ABC_CONST(0x0404040000020200), ABC_CONST(0x0404000404020200), ABC_CONST(0x0404000400020200), ABC_CONST(0x0404000004020200), ABC_CONST(0x0404000000020200), ABC_CONST(0x0400040404020200), ABC_CONST(0x0400040400020200), ABC_CONST(0x0400040004020200), ABC_CONST(0x0400040000020200), ABC_CONST(0x0400000404020200), ABC_CONST(0x0400000400020200), ABC_CONST(0x0400000004020200), ABC_CONST(0x0400000000020200), ABC_CONST(0x0404040404020200), ABC_CONST(0x0404040400020200), ABC_CONST(0x0404040004020200), ABC_CONST(0x0404040000020200), ABC_CONST(0x0404000404020200), ABC_CONST(0x0404000400020200), ABC_CONST(0x0404000004020200), ABC_CONST(0x0404000000020200), ABC_CONST(0x0400040404020200), ABC_CONST(0x0400040400020200), ABC_CONST(0x0400040004020200), ABC_CONST(0x0400040000020200), ABC_CONST(0x0400000404020200), ABC_CONST(0x0400000400020200), ABC_CONST(0x0400000004020200), ABC_CONST(0x0400000000020200) }, + { ABC_CONST(0x0505050505030301), ABC_CONST(0x0505050500030301), ABC_CONST(0x0505050005030301), ABC_CONST(0x0505050000030301), ABC_CONST(0x0505000505030301), ABC_CONST(0x0505000500030301), ABC_CONST(0x0505000005030301), ABC_CONST(0x0505000000030301), ABC_CONST(0x0500050505030301), ABC_CONST(0x0500050500030301), ABC_CONST(0x0500050005030301), ABC_CONST(0x0500050000030301), ABC_CONST(0x0500000505030301), ABC_CONST(0x0500000500030301), ABC_CONST(0x0500000005030301), ABC_CONST(0x0500000000030301), ABC_CONST(0x0505050505030301), ABC_CONST(0x0505050500030301), ABC_CONST(0x0505050005030301), ABC_CONST(0x0505050000030301), ABC_CONST(0x0505000505030301), ABC_CONST(0x0505000500030301), ABC_CONST(0x0505000005030301), ABC_CONST(0x0505000000030301), ABC_CONST(0x0500050505030301), ABC_CONST(0x0500050500030301), ABC_CONST(0x0500050005030301), ABC_CONST(0x0500050000030301), ABC_CONST(0x0500000505030301), ABC_CONST(0x0500000500030301), ABC_CONST(0x0500000005030301), ABC_CONST(0x0500000000030301) }, + { ABC_CONST(0x0404040404020101), ABC_CONST(0x0404040400020101), ABC_CONST(0x0404040004020101), ABC_CONST(0x0404040000020101), ABC_CONST(0x0404000404020101), ABC_CONST(0x0404000400020101), ABC_CONST(0x0404000004020101), ABC_CONST(0x0404000000020101), ABC_CONST(0x0400040404020101), ABC_CONST(0x0400040400020101), ABC_CONST(0x0400040004020101), ABC_CONST(0x0400040000020101), ABC_CONST(0x0400000404020101), ABC_CONST(0x0400000400020101), ABC_CONST(0x0400000004020101), ABC_CONST(0x0400000000020101), ABC_CONST(0x0404040404020101), ABC_CONST(0x0404040400020101), ABC_CONST(0x0404040004020101), ABC_CONST(0x0404040000020101), ABC_CONST(0x0404000404020101), ABC_CONST(0x0404000400020101), ABC_CONST(0x0404000004020101), ABC_CONST(0x0404000000020101), ABC_CONST(0x0400040404020101), ABC_CONST(0x0400040400020101), ABC_CONST(0x0400040004020101), ABC_CONST(0x0400040000020101), ABC_CONST(0x0400000404020101), ABC_CONST(0x0400000400020101), ABC_CONST(0x0400000004020101), ABC_CONST(0x0400000000020101) }, + { ABC_CONST(0x0505050505030202), ABC_CONST(0x0505050500030202), ABC_CONST(0x0505050005030202), ABC_CONST(0x0505050000030202), ABC_CONST(0x0505000505030202), ABC_CONST(0x0505000500030202), ABC_CONST(0x0505000005030202), ABC_CONST(0x0505000000030202), ABC_CONST(0x0500050505030202), ABC_CONST(0x0500050500030202), ABC_CONST(0x0500050005030202), ABC_CONST(0x0500050000030202), ABC_CONST(0x0500000505030202), ABC_CONST(0x0500000500030202), ABC_CONST(0x0500000005030202), ABC_CONST(0x0500000000030202), ABC_CONST(0x0505050505030202), ABC_CONST(0x0505050500030202), ABC_CONST(0x0505050005030202), ABC_CONST(0x0505050000030202), ABC_CONST(0x0505000505030202), ABC_CONST(0x0505000500030202), ABC_CONST(0x0505000005030202), ABC_CONST(0x0505000000030202), ABC_CONST(0x0500050505030202), ABC_CONST(0x0500050500030202), ABC_CONST(0x0500050005030202), ABC_CONST(0x0500050000030202), ABC_CONST(0x0500000505030202), ABC_CONST(0x0500000500030202), ABC_CONST(0x0500000005030202), ABC_CONST(0x0500000000030202) }, + { ABC_CONST(0x0505050505030201), ABC_CONST(0x0505050500030201), ABC_CONST(0x0505050005030201), ABC_CONST(0x0505050000030201), ABC_CONST(0x0505000505030201), ABC_CONST(0x0505000500030201), ABC_CONST(0x0505000005030201), ABC_CONST(0x0505000000030201), ABC_CONST(0x0500050505030201), ABC_CONST(0x0500050500030201), ABC_CONST(0x0500050005030201), ABC_CONST(0x0500050000030201), ABC_CONST(0x0500000505030201), ABC_CONST(0x0500000500030201), ABC_CONST(0x0500000005030201), ABC_CONST(0x0500000000030201), ABC_CONST(0x0505050505030201), ABC_CONST(0x0505050500030201), ABC_CONST(0x0505050005030201), ABC_CONST(0x0505050000030201), ABC_CONST(0x0505000505030201), ABC_CONST(0x0505000500030201), ABC_CONST(0x0505000005030201), ABC_CONST(0x0505000000030201), ABC_CONST(0x0500050505030201), ABC_CONST(0x0500050500030201), ABC_CONST(0x0500050005030201), ABC_CONST(0x0500050000030201), ABC_CONST(0x0500000505030201), ABC_CONST(0x0500000500030201), ABC_CONST(0x0500000005030201), ABC_CONST(0x0500000000030201) }, + { ABC_CONST(0x0606060606040302), ABC_CONST(0x0606060600040302), ABC_CONST(0x0606060006040302), ABC_CONST(0x0606060000040302), ABC_CONST(0x0606000606040302), ABC_CONST(0x0606000600040302), ABC_CONST(0x0606000006040302), ABC_CONST(0x0606000000040302), ABC_CONST(0x0600060606040302), ABC_CONST(0x0600060600040302), ABC_CONST(0x0600060006040302), ABC_CONST(0x0600060000040302), ABC_CONST(0x0600000606040302), ABC_CONST(0x0600000600040302), ABC_CONST(0x0600000006040302), ABC_CONST(0x0600000000040302), ABC_CONST(0x0606060606040302), ABC_CONST(0x0606060600040302), ABC_CONST(0x0606060006040302), ABC_CONST(0x0606060000040302), ABC_CONST(0x0606000606040302), ABC_CONST(0x0606000600040302), ABC_CONST(0x0606000006040302), ABC_CONST(0x0606000000040302), ABC_CONST(0x0600060606040302), ABC_CONST(0x0600060600040302), ABC_CONST(0x0600060006040302), ABC_CONST(0x0600060000040302), ABC_CONST(0x0600000606040302), ABC_CONST(0x0600000600040302), ABC_CONST(0x0600000006040302), ABC_CONST(0x0600000000040302) }, + { ABC_CONST(0x0303030303000201), ABC_CONST(0x0303030300000201), ABC_CONST(0x0303030003000201), ABC_CONST(0x0303030000000201), ABC_CONST(0x0303000303000201), ABC_CONST(0x0303000300000201), ABC_CONST(0x0303000003000201), ABC_CONST(0x0303000000000201), ABC_CONST(0x0300030303000201), ABC_CONST(0x0300030300000201), ABC_CONST(0x0300030003000201), ABC_CONST(0x0300030000000201), ABC_CONST(0x0300000303000201), ABC_CONST(0x0300000300000201), ABC_CONST(0x0300000003000201), ABC_CONST(0x0300000000000201), ABC_CONST(0x0303030303000201), ABC_CONST(0x0303030300000201), ABC_CONST(0x0303030003000201), ABC_CONST(0x0303030000000201), ABC_CONST(0x0303000303000201), ABC_CONST(0x0303000300000201), ABC_CONST(0x0303000003000201), ABC_CONST(0x0303000000000201), ABC_CONST(0x0300030303000201), ABC_CONST(0x0300030300000201), ABC_CONST(0x0300030003000201), ABC_CONST(0x0300030000000201), ABC_CONST(0x0300000303000201), ABC_CONST(0x0300000300000201), ABC_CONST(0x0300000003000201), ABC_CONST(0x0300000000000201) }, + { ABC_CONST(0x0404040404010302), ABC_CONST(0x0404040400010302), ABC_CONST(0x0404040004010302), ABC_CONST(0x0404040000010302), ABC_CONST(0x0404000404010302), ABC_CONST(0x0404000400010302), ABC_CONST(0x0404000004010302), ABC_CONST(0x0404000000010302), ABC_CONST(0x0400040404010302), ABC_CONST(0x0400040400010302), ABC_CONST(0x0400040004010302), ABC_CONST(0x0400040000010302), ABC_CONST(0x0400000404010302), ABC_CONST(0x0400000400010302), ABC_CONST(0x0400000004010302), ABC_CONST(0x0400000000010302), ABC_CONST(0x0404040404010302), ABC_CONST(0x0404040400010302), ABC_CONST(0x0404040004010302), ABC_CONST(0x0404040000010302), ABC_CONST(0x0404000404010302), ABC_CONST(0x0404000400010302), ABC_CONST(0x0404000004010302), ABC_CONST(0x0404000000010302), ABC_CONST(0x0400040404010302), ABC_CONST(0x0400040400010302), ABC_CONST(0x0400040004010302), ABC_CONST(0x0400040000010302), ABC_CONST(0x0400000404010302), ABC_CONST(0x0400000400010302), ABC_CONST(0x0400000004010302), ABC_CONST(0x0400000000010302) }, + { ABC_CONST(0x0404040404010301), ABC_CONST(0x0404040400010301), ABC_CONST(0x0404040004010301), ABC_CONST(0x0404040000010301), ABC_CONST(0x0404000404010301), ABC_CONST(0x0404000400010301), ABC_CONST(0x0404000004010301), ABC_CONST(0x0404000000010301), ABC_CONST(0x0400040404010301), ABC_CONST(0x0400040400010301), ABC_CONST(0x0400040004010301), ABC_CONST(0x0400040000010301), ABC_CONST(0x0400000404010301), ABC_CONST(0x0400000400010301), ABC_CONST(0x0400000004010301), ABC_CONST(0x0400000000010301), ABC_CONST(0x0404040404010301), ABC_CONST(0x0404040400010301), ABC_CONST(0x0404040004010301), ABC_CONST(0x0404040000010301), ABC_CONST(0x0404000404010301), ABC_CONST(0x0404000400010301), ABC_CONST(0x0404000004010301), ABC_CONST(0x0404000000010301), ABC_CONST(0x0400040404010301), ABC_CONST(0x0400040400010301), ABC_CONST(0x0400040004010301), ABC_CONST(0x0400040000010301), ABC_CONST(0x0400000404010301), ABC_CONST(0x0400000400010301), ABC_CONST(0x0400000004010301), ABC_CONST(0x0400000000010301) }, + { ABC_CONST(0x0505050505020402), ABC_CONST(0x0505050500020402), ABC_CONST(0x0505050005020402), ABC_CONST(0x0505050000020402), ABC_CONST(0x0505000505020402), ABC_CONST(0x0505000500020402), ABC_CONST(0x0505000005020402), ABC_CONST(0x0505000000020402), ABC_CONST(0x0500050505020402), ABC_CONST(0x0500050500020402), ABC_CONST(0x0500050005020402), ABC_CONST(0x0500050000020402), ABC_CONST(0x0500000505020402), ABC_CONST(0x0500000500020402), ABC_CONST(0x0500000005020402), ABC_CONST(0x0500000000020402), ABC_CONST(0x0505050505020402), ABC_CONST(0x0505050500020402), ABC_CONST(0x0505050005020402), ABC_CONST(0x0505050000020402), ABC_CONST(0x0505000505020402), ABC_CONST(0x0505000500020402), ABC_CONST(0x0505000005020402), ABC_CONST(0x0505000000020402), ABC_CONST(0x0500050505020402), ABC_CONST(0x0500050500020402), ABC_CONST(0x0500050005020402), ABC_CONST(0x0500050000020402), ABC_CONST(0x0500000505020402), ABC_CONST(0x0500000500020402), ABC_CONST(0x0500000005020402), ABC_CONST(0x0500000000020402) }, + { ABC_CONST(0x0404040404010202), ABC_CONST(0x0404040400010202), ABC_CONST(0x0404040004010202), ABC_CONST(0x0404040000010202), ABC_CONST(0x0404000404010202), ABC_CONST(0x0404000400010202), ABC_CONST(0x0404000004010202), ABC_CONST(0x0404000000010202), ABC_CONST(0x0400040404010202), ABC_CONST(0x0400040400010202), ABC_CONST(0x0400040004010202), ABC_CONST(0x0400040000010202), ABC_CONST(0x0400000404010202), ABC_CONST(0x0400000400010202), ABC_CONST(0x0400000004010202), ABC_CONST(0x0400000000010202), ABC_CONST(0x0404040404010202), ABC_CONST(0x0404040400010202), ABC_CONST(0x0404040004010202), ABC_CONST(0x0404040000010202), ABC_CONST(0x0404000404010202), ABC_CONST(0x0404000400010202), ABC_CONST(0x0404000004010202), ABC_CONST(0x0404000000010202), ABC_CONST(0x0400040404010202), ABC_CONST(0x0400040400010202), ABC_CONST(0x0400040004010202), ABC_CONST(0x0400040000010202), ABC_CONST(0x0400000404010202), ABC_CONST(0x0400000400010202), ABC_CONST(0x0400000004010202), ABC_CONST(0x0400000000010202) }, + { ABC_CONST(0x0505050505020303), ABC_CONST(0x0505050500020303), ABC_CONST(0x0505050005020303), ABC_CONST(0x0505050000020303), ABC_CONST(0x0505000505020303), ABC_CONST(0x0505000500020303), ABC_CONST(0x0505000005020303), ABC_CONST(0x0505000000020303), ABC_CONST(0x0500050505020303), ABC_CONST(0x0500050500020303), ABC_CONST(0x0500050005020303), ABC_CONST(0x0500050000020303), ABC_CONST(0x0500000505020303), ABC_CONST(0x0500000500020303), ABC_CONST(0x0500000005020303), ABC_CONST(0x0500000000020303), ABC_CONST(0x0505050505020303), ABC_CONST(0x0505050500020303), ABC_CONST(0x0505050005020303), ABC_CONST(0x0505050000020303), ABC_CONST(0x0505000505020303), ABC_CONST(0x0505000500020303), ABC_CONST(0x0505000005020303), ABC_CONST(0x0505000000020303), ABC_CONST(0x0500050505020303), ABC_CONST(0x0500050500020303), ABC_CONST(0x0500050005020303), ABC_CONST(0x0500050000020303), ABC_CONST(0x0500000505020303), ABC_CONST(0x0500000500020303), ABC_CONST(0x0500000005020303), ABC_CONST(0x0500000000020303) }, + { ABC_CONST(0x0505050505020302), ABC_CONST(0x0505050500020302), ABC_CONST(0x0505050005020302), ABC_CONST(0x0505050000020302), ABC_CONST(0x0505000505020302), ABC_CONST(0x0505000500020302), ABC_CONST(0x0505000005020302), ABC_CONST(0x0505000000020302), ABC_CONST(0x0500050505020302), ABC_CONST(0x0500050500020302), ABC_CONST(0x0500050005020302), ABC_CONST(0x0500050000020302), ABC_CONST(0x0500000505020302), ABC_CONST(0x0500000500020302), ABC_CONST(0x0500000005020302), ABC_CONST(0x0500000000020302), ABC_CONST(0x0505050505020302), ABC_CONST(0x0505050500020302), ABC_CONST(0x0505050005020302), ABC_CONST(0x0505050000020302), ABC_CONST(0x0505000505020302), ABC_CONST(0x0505000500020302), ABC_CONST(0x0505000005020302), ABC_CONST(0x0505000000020302), ABC_CONST(0x0500050505020302), ABC_CONST(0x0500050500020302), ABC_CONST(0x0500050005020302), ABC_CONST(0x0500050000020302), ABC_CONST(0x0500000505020302), ABC_CONST(0x0500000500020302), ABC_CONST(0x0500000005020302), ABC_CONST(0x0500000000020302) }, + { ABC_CONST(0x0606060606030403), ABC_CONST(0x0606060600030403), ABC_CONST(0x0606060006030403), ABC_CONST(0x0606060000030403), ABC_CONST(0x0606000606030403), ABC_CONST(0x0606000600030403), ABC_CONST(0x0606000006030403), ABC_CONST(0x0606000000030403), ABC_CONST(0x0600060606030403), ABC_CONST(0x0600060600030403), ABC_CONST(0x0600060006030403), ABC_CONST(0x0600060000030403), ABC_CONST(0x0600000606030403), ABC_CONST(0x0600000600030403), ABC_CONST(0x0600000006030403), ABC_CONST(0x0600000000030403), ABC_CONST(0x0606060606030403), ABC_CONST(0x0606060600030403), ABC_CONST(0x0606060006030403), ABC_CONST(0x0606060000030403), ABC_CONST(0x0606000606030403), ABC_CONST(0x0606000600030403), ABC_CONST(0x0606000006030403), ABC_CONST(0x0606000000030403), ABC_CONST(0x0600060606030403), ABC_CONST(0x0600060600030403), ABC_CONST(0x0600060006030403), ABC_CONST(0x0600060000030403), ABC_CONST(0x0600000606030403), ABC_CONST(0x0600000600030403), ABC_CONST(0x0600000006030403), ABC_CONST(0x0600000000030403) }, + { ABC_CONST(0x0404040404010201), ABC_CONST(0x0404040400010201), ABC_CONST(0x0404040004010201), ABC_CONST(0x0404040000010201), ABC_CONST(0x0404000404010201), ABC_CONST(0x0404000400010201), ABC_CONST(0x0404000004010201), ABC_CONST(0x0404000000010201), ABC_CONST(0x0400040404010201), ABC_CONST(0x0400040400010201), ABC_CONST(0x0400040004010201), ABC_CONST(0x0400040000010201), ABC_CONST(0x0400000404010201), ABC_CONST(0x0400000400010201), ABC_CONST(0x0400000004010201), ABC_CONST(0x0400000000010201), ABC_CONST(0x0404040404010201), ABC_CONST(0x0404040400010201), ABC_CONST(0x0404040004010201), ABC_CONST(0x0404040000010201), ABC_CONST(0x0404000404010201), ABC_CONST(0x0404000400010201), ABC_CONST(0x0404000004010201), ABC_CONST(0x0404000000010201), ABC_CONST(0x0400040404010201), ABC_CONST(0x0400040400010201), ABC_CONST(0x0400040004010201), ABC_CONST(0x0400040000010201), ABC_CONST(0x0400000404010201), ABC_CONST(0x0400000400010201), ABC_CONST(0x0400000004010201), ABC_CONST(0x0400000000010201) }, + { ABC_CONST(0x0505050505020302), ABC_CONST(0x0505050500020302), ABC_CONST(0x0505050005020302), ABC_CONST(0x0505050000020302), ABC_CONST(0x0505000505020302), ABC_CONST(0x0505000500020302), ABC_CONST(0x0505000005020302), ABC_CONST(0x0505000000020302), ABC_CONST(0x0500050505020302), ABC_CONST(0x0500050500020302), ABC_CONST(0x0500050005020302), ABC_CONST(0x0500050000020302), ABC_CONST(0x0500000505020302), ABC_CONST(0x0500000500020302), ABC_CONST(0x0500000005020302), ABC_CONST(0x0500000000020302), ABC_CONST(0x0505050505020302), ABC_CONST(0x0505050500020302), ABC_CONST(0x0505050005020302), ABC_CONST(0x0505050000020302), ABC_CONST(0x0505000505020302), ABC_CONST(0x0505000500020302), ABC_CONST(0x0505000005020302), ABC_CONST(0x0505000000020302), ABC_CONST(0x0500050505020302), ABC_CONST(0x0500050500020302), ABC_CONST(0x0500050005020302), ABC_CONST(0x0500050000020302), ABC_CONST(0x0500000505020302), ABC_CONST(0x0500000500020302), ABC_CONST(0x0500000005020302), ABC_CONST(0x0500000000020302) }, + { ABC_CONST(0x0505050505020301), ABC_CONST(0x0505050500020301), ABC_CONST(0x0505050005020301), ABC_CONST(0x0505050000020301), ABC_CONST(0x0505000505020301), ABC_CONST(0x0505000500020301), ABC_CONST(0x0505000005020301), ABC_CONST(0x0505000000020301), ABC_CONST(0x0500050505020301), ABC_CONST(0x0500050500020301), ABC_CONST(0x0500050005020301), ABC_CONST(0x0500050000020301), ABC_CONST(0x0500000505020301), ABC_CONST(0x0500000500020301), ABC_CONST(0x0500000005020301), ABC_CONST(0x0500000000020301), ABC_CONST(0x0505050505020301), ABC_CONST(0x0505050500020301), ABC_CONST(0x0505050005020301), ABC_CONST(0x0505050000020301), ABC_CONST(0x0505000505020301), ABC_CONST(0x0505000500020301), ABC_CONST(0x0505000005020301), ABC_CONST(0x0505000000020301), ABC_CONST(0x0500050505020301), ABC_CONST(0x0500050500020301), ABC_CONST(0x0500050005020301), ABC_CONST(0x0500050000020301), ABC_CONST(0x0500000505020301), ABC_CONST(0x0500000500020301), ABC_CONST(0x0500000005020301), ABC_CONST(0x0500000000020301) }, + { ABC_CONST(0x0606060606030402), ABC_CONST(0x0606060600030402), ABC_CONST(0x0606060006030402), ABC_CONST(0x0606060000030402), ABC_CONST(0x0606000606030402), ABC_CONST(0x0606000600030402), ABC_CONST(0x0606000006030402), ABC_CONST(0x0606000000030402), ABC_CONST(0x0600060606030402), ABC_CONST(0x0600060600030402), ABC_CONST(0x0600060006030402), ABC_CONST(0x0600060000030402), ABC_CONST(0x0600000606030402), ABC_CONST(0x0600000600030402), ABC_CONST(0x0600000006030402), ABC_CONST(0x0600000000030402), ABC_CONST(0x0606060606030402), ABC_CONST(0x0606060600030402), ABC_CONST(0x0606060006030402), ABC_CONST(0x0606060000030402), ABC_CONST(0x0606000606030402), ABC_CONST(0x0606000600030402), ABC_CONST(0x0606000006030402), ABC_CONST(0x0606000000030402), ABC_CONST(0x0600060606030402), ABC_CONST(0x0600060600030402), ABC_CONST(0x0600060006030402), ABC_CONST(0x0600060000030402), ABC_CONST(0x0600000606030402), ABC_CONST(0x0600000600030402), ABC_CONST(0x0600000006030402), ABC_CONST(0x0600000000030402) }, + { ABC_CONST(0x0505050505020202), ABC_CONST(0x0505050500020202), ABC_CONST(0x0505050005020202), ABC_CONST(0x0505050000020202), ABC_CONST(0x0505000505020202), ABC_CONST(0x0505000500020202), ABC_CONST(0x0505000005020202), ABC_CONST(0x0505000000020202), ABC_CONST(0x0500050505020202), ABC_CONST(0x0500050500020202), ABC_CONST(0x0500050005020202), ABC_CONST(0x0500050000020202), ABC_CONST(0x0500000505020202), ABC_CONST(0x0500000500020202), ABC_CONST(0x0500000005020202), ABC_CONST(0x0500000000020202), ABC_CONST(0x0505050505020202), ABC_CONST(0x0505050500020202), ABC_CONST(0x0505050005020202), ABC_CONST(0x0505050000020202), ABC_CONST(0x0505000505020202), ABC_CONST(0x0505000500020202), ABC_CONST(0x0505000005020202), ABC_CONST(0x0505000000020202), ABC_CONST(0x0500050505020202), ABC_CONST(0x0500050500020202), ABC_CONST(0x0500050005020202), ABC_CONST(0x0500050000020202), ABC_CONST(0x0500000505020202), ABC_CONST(0x0500000500020202), ABC_CONST(0x0500000005020202), ABC_CONST(0x0500000000020202) }, + { ABC_CONST(0x0606060606030303), ABC_CONST(0x0606060600030303), ABC_CONST(0x0606060006030303), ABC_CONST(0x0606060000030303), ABC_CONST(0x0606000606030303), ABC_CONST(0x0606000600030303), ABC_CONST(0x0606000006030303), ABC_CONST(0x0606000000030303), ABC_CONST(0x0600060606030303), ABC_CONST(0x0600060600030303), ABC_CONST(0x0600060006030303), ABC_CONST(0x0600060000030303), ABC_CONST(0x0600000606030303), ABC_CONST(0x0600000600030303), ABC_CONST(0x0600000006030303), ABC_CONST(0x0600000000030303), ABC_CONST(0x0606060606030303), ABC_CONST(0x0606060600030303), ABC_CONST(0x0606060006030303), ABC_CONST(0x0606060000030303), ABC_CONST(0x0606000606030303), ABC_CONST(0x0606000600030303), ABC_CONST(0x0606000006030303), ABC_CONST(0x0606000000030303), ABC_CONST(0x0600060606030303), ABC_CONST(0x0600060600030303), ABC_CONST(0x0600060006030303), ABC_CONST(0x0600060000030303), ABC_CONST(0x0600000606030303), ABC_CONST(0x0600000600030303), ABC_CONST(0x0600000006030303), ABC_CONST(0x0600000000030303) }, + { ABC_CONST(0x0606060606030302), ABC_CONST(0x0606060600030302), ABC_CONST(0x0606060006030302), ABC_CONST(0x0606060000030302), ABC_CONST(0x0606000606030302), ABC_CONST(0x0606000600030302), ABC_CONST(0x0606000006030302), ABC_CONST(0x0606000000030302), ABC_CONST(0x0600060606030302), ABC_CONST(0x0600060600030302), ABC_CONST(0x0600060006030302), ABC_CONST(0x0600060000030302), ABC_CONST(0x0600000606030302), ABC_CONST(0x0600000600030302), ABC_CONST(0x0600000006030302), ABC_CONST(0x0600000000030302), ABC_CONST(0x0606060606030302), ABC_CONST(0x0606060600030302), ABC_CONST(0x0606060006030302), ABC_CONST(0x0606060000030302), ABC_CONST(0x0606000606030302), ABC_CONST(0x0606000600030302), ABC_CONST(0x0606000006030302), ABC_CONST(0x0606000000030302), ABC_CONST(0x0600060606030302), ABC_CONST(0x0600060600030302), ABC_CONST(0x0600060006030302), ABC_CONST(0x0600060000030302), ABC_CONST(0x0600000606030302), ABC_CONST(0x0600000600030302), ABC_CONST(0x0600000006030302), ABC_CONST(0x0600000000030302) }, + { ABC_CONST(0x0707070707040403), ABC_CONST(0x0707070700040403), ABC_CONST(0x0707070007040403), ABC_CONST(0x0707070000040403), ABC_CONST(0x0707000707040403), ABC_CONST(0x0707000700040403), ABC_CONST(0x0707000007040403), ABC_CONST(0x0707000000040403), ABC_CONST(0x0700070707040403), ABC_CONST(0x0700070700040403), ABC_CONST(0x0700070007040403), ABC_CONST(0x0700070000040403), ABC_CONST(0x0700000707040403), ABC_CONST(0x0700000700040403), ABC_CONST(0x0700000007040403), ABC_CONST(0x0700000000040403), ABC_CONST(0x0707070707040403), ABC_CONST(0x0707070700040403), ABC_CONST(0x0707070007040403), ABC_CONST(0x0707070000040403), ABC_CONST(0x0707000707040403), ABC_CONST(0x0707000700040403), ABC_CONST(0x0707000007040403), ABC_CONST(0x0707000000040403), ABC_CONST(0x0700070707040403), ABC_CONST(0x0700070700040403), ABC_CONST(0x0700070007040403), ABC_CONST(0x0700070000040403), ABC_CONST(0x0700000707040403), ABC_CONST(0x0700000700040403), ABC_CONST(0x0700000007040403), ABC_CONST(0x0700000000040403) }, + { ABC_CONST(0x0202020202000001), ABC_CONST(0x0202020200000001), ABC_CONST(0x0202020002000001), ABC_CONST(0x0202020000000001), ABC_CONST(0x0202000202000001), ABC_CONST(0x0202000200000001), ABC_CONST(0x0202000002000001), ABC_CONST(0x0202000000000001), ABC_CONST(0x0200020202000001), ABC_CONST(0x0200020200000001), ABC_CONST(0x0200020002000001), ABC_CONST(0x0200020000000001), ABC_CONST(0x0200000202000001), ABC_CONST(0x0200000200000001), ABC_CONST(0x0200000002000001), ABC_CONST(0x0200000000000001), ABC_CONST(0x0202020202000001), ABC_CONST(0x0202020200000001), ABC_CONST(0x0202020002000001), ABC_CONST(0x0202020000000001), ABC_CONST(0x0202000202000001), ABC_CONST(0x0202000200000001), ABC_CONST(0x0202000002000001), ABC_CONST(0x0202000000000001), ABC_CONST(0x0200020202000001), ABC_CONST(0x0200020200000001), ABC_CONST(0x0200020002000001), ABC_CONST(0x0200020000000001), ABC_CONST(0x0200000202000001), ABC_CONST(0x0200000200000001), ABC_CONST(0x0200000002000001), ABC_CONST(0x0200000000000001) }, + { ABC_CONST(0x0303030303010102), ABC_CONST(0x0303030300010102), ABC_CONST(0x0303030003010102), ABC_CONST(0x0303030000010102), ABC_CONST(0x0303000303010102), ABC_CONST(0x0303000300010102), ABC_CONST(0x0303000003010102), ABC_CONST(0x0303000000010102), ABC_CONST(0x0300030303010102), ABC_CONST(0x0300030300010102), ABC_CONST(0x0300030003010102), ABC_CONST(0x0300030000010102), ABC_CONST(0x0300000303010102), ABC_CONST(0x0300000300010102), ABC_CONST(0x0300000003010102), ABC_CONST(0x0300000000010102), ABC_CONST(0x0303030303010102), ABC_CONST(0x0303030300010102), ABC_CONST(0x0303030003010102), ABC_CONST(0x0303030000010102), ABC_CONST(0x0303000303010102), ABC_CONST(0x0303000300010102), ABC_CONST(0x0303000003010102), ABC_CONST(0x0303000000010102), ABC_CONST(0x0300030303010102), ABC_CONST(0x0300030300010102), ABC_CONST(0x0300030003010102), ABC_CONST(0x0300030000010102), ABC_CONST(0x0300000303010102), ABC_CONST(0x0300000300010102), ABC_CONST(0x0300000003010102), ABC_CONST(0x0300000000010102) }, + { ABC_CONST(0x0303030303010101), ABC_CONST(0x0303030300010101), ABC_CONST(0x0303030003010101), ABC_CONST(0x0303030000010101), ABC_CONST(0x0303000303010101), ABC_CONST(0x0303000300010101), ABC_CONST(0x0303000003010101), ABC_CONST(0x0303000000010101), ABC_CONST(0x0300030303010101), ABC_CONST(0x0300030300010101), ABC_CONST(0x0300030003010101), ABC_CONST(0x0300030000010101), ABC_CONST(0x0300000303010101), ABC_CONST(0x0300000300010101), ABC_CONST(0x0300000003010101), ABC_CONST(0x0300000000010101), ABC_CONST(0x0303030303010101), ABC_CONST(0x0303030300010101), ABC_CONST(0x0303030003010101), ABC_CONST(0x0303030000010101), ABC_CONST(0x0303000303010101), ABC_CONST(0x0303000300010101), ABC_CONST(0x0303000003010101), ABC_CONST(0x0303000000010101), ABC_CONST(0x0300030303010101), ABC_CONST(0x0300030300010101), ABC_CONST(0x0300030003010101), ABC_CONST(0x0300030000010101), ABC_CONST(0x0300000303010101), ABC_CONST(0x0300000300010101), ABC_CONST(0x0300000003010101), ABC_CONST(0x0300000000010101) }, + { ABC_CONST(0x0404040404020202), ABC_CONST(0x0404040400020202), ABC_CONST(0x0404040004020202), ABC_CONST(0x0404040000020202), ABC_CONST(0x0404000404020202), ABC_CONST(0x0404000400020202), ABC_CONST(0x0404000004020202), ABC_CONST(0x0404000000020202), ABC_CONST(0x0400040404020202), ABC_CONST(0x0400040400020202), ABC_CONST(0x0400040004020202), ABC_CONST(0x0400040000020202), ABC_CONST(0x0400000404020202), ABC_CONST(0x0400000400020202), ABC_CONST(0x0400000004020202), ABC_CONST(0x0400000000020202), ABC_CONST(0x0404040404020202), ABC_CONST(0x0404040400020202), ABC_CONST(0x0404040004020202), ABC_CONST(0x0404040000020202), ABC_CONST(0x0404000404020202), ABC_CONST(0x0404000400020202), ABC_CONST(0x0404000004020202), ABC_CONST(0x0404000000020202), ABC_CONST(0x0400040404020202), ABC_CONST(0x0400040400020202), ABC_CONST(0x0400040004020202), ABC_CONST(0x0400040000020202), ABC_CONST(0x0400000404020202), ABC_CONST(0x0400000400020202), ABC_CONST(0x0400000004020202), ABC_CONST(0x0400000000020202) }, + { ABC_CONST(0x0303030303010002), ABC_CONST(0x0303030300010002), ABC_CONST(0x0303030003010002), ABC_CONST(0x0303030000010002), ABC_CONST(0x0303000303010002), ABC_CONST(0x0303000300010002), ABC_CONST(0x0303000003010002), ABC_CONST(0x0303000000010002), ABC_CONST(0x0300030303010002), ABC_CONST(0x0300030300010002), ABC_CONST(0x0300030003010002), ABC_CONST(0x0300030000010002), ABC_CONST(0x0300000303010002), ABC_CONST(0x0300000300010002), ABC_CONST(0x0300000003010002), ABC_CONST(0x0300000000010002), ABC_CONST(0x0303030303010002), ABC_CONST(0x0303030300010002), ABC_CONST(0x0303030003010002), ABC_CONST(0x0303030000010002), ABC_CONST(0x0303000303010002), ABC_CONST(0x0303000300010002), ABC_CONST(0x0303000003010002), ABC_CONST(0x0303000000010002), ABC_CONST(0x0300030303010002), ABC_CONST(0x0300030300010002), ABC_CONST(0x0300030003010002), ABC_CONST(0x0300030000010002), ABC_CONST(0x0300000303010002), ABC_CONST(0x0300000300010002), ABC_CONST(0x0300000003010002), ABC_CONST(0x0300000000010002) }, + { ABC_CONST(0x0404040404020103), ABC_CONST(0x0404040400020103), ABC_CONST(0x0404040004020103), ABC_CONST(0x0404040000020103), ABC_CONST(0x0404000404020103), ABC_CONST(0x0404000400020103), ABC_CONST(0x0404000004020103), ABC_CONST(0x0404000000020103), ABC_CONST(0x0400040404020103), ABC_CONST(0x0400040400020103), ABC_CONST(0x0400040004020103), ABC_CONST(0x0400040000020103), ABC_CONST(0x0400000404020103), ABC_CONST(0x0400000400020103), ABC_CONST(0x0400000004020103), ABC_CONST(0x0400000000020103), ABC_CONST(0x0404040404020103), ABC_CONST(0x0404040400020103), ABC_CONST(0x0404040004020103), ABC_CONST(0x0404040000020103), ABC_CONST(0x0404000404020103), ABC_CONST(0x0404000400020103), ABC_CONST(0x0404000004020103), ABC_CONST(0x0404000000020103), ABC_CONST(0x0400040404020103), ABC_CONST(0x0400040400020103), ABC_CONST(0x0400040004020103), ABC_CONST(0x0400040000020103), ABC_CONST(0x0400000404020103), ABC_CONST(0x0400000400020103), ABC_CONST(0x0400000004020103), ABC_CONST(0x0400000000020103) }, + { ABC_CONST(0x0404040404020102), ABC_CONST(0x0404040400020102), ABC_CONST(0x0404040004020102), ABC_CONST(0x0404040000020102), ABC_CONST(0x0404000404020102), ABC_CONST(0x0404000400020102), ABC_CONST(0x0404000004020102), ABC_CONST(0x0404000000020102), ABC_CONST(0x0400040404020102), ABC_CONST(0x0400040400020102), ABC_CONST(0x0400040004020102), ABC_CONST(0x0400040000020102), ABC_CONST(0x0400000404020102), ABC_CONST(0x0400000400020102), ABC_CONST(0x0400000004020102), ABC_CONST(0x0400000000020102), ABC_CONST(0x0404040404020102), ABC_CONST(0x0404040400020102), ABC_CONST(0x0404040004020102), ABC_CONST(0x0404040000020102), ABC_CONST(0x0404000404020102), ABC_CONST(0x0404000400020102), ABC_CONST(0x0404000004020102), ABC_CONST(0x0404000000020102), ABC_CONST(0x0400040404020102), ABC_CONST(0x0400040400020102), ABC_CONST(0x0400040004020102), ABC_CONST(0x0400040000020102), ABC_CONST(0x0400000404020102), ABC_CONST(0x0400000400020102), ABC_CONST(0x0400000004020102), ABC_CONST(0x0400000000020102) }, + { ABC_CONST(0x0505050505030203), ABC_CONST(0x0505050500030203), ABC_CONST(0x0505050005030203), ABC_CONST(0x0505050000030203), ABC_CONST(0x0505000505030203), ABC_CONST(0x0505000500030203), ABC_CONST(0x0505000005030203), ABC_CONST(0x0505000000030203), ABC_CONST(0x0500050505030203), ABC_CONST(0x0500050500030203), ABC_CONST(0x0500050005030203), ABC_CONST(0x0500050000030203), ABC_CONST(0x0500000505030203), ABC_CONST(0x0500000500030203), ABC_CONST(0x0500000005030203), ABC_CONST(0x0500000000030203), ABC_CONST(0x0505050505030203), ABC_CONST(0x0505050500030203), ABC_CONST(0x0505050005030203), ABC_CONST(0x0505050000030203), ABC_CONST(0x0505000505030203), ABC_CONST(0x0505000500030203), ABC_CONST(0x0505000005030203), ABC_CONST(0x0505000000030203), ABC_CONST(0x0500050505030203), ABC_CONST(0x0500050500030203), ABC_CONST(0x0500050005030203), ABC_CONST(0x0500050000030203), ABC_CONST(0x0500000505030203), ABC_CONST(0x0500000500030203), ABC_CONST(0x0500000005030203), ABC_CONST(0x0500000000030203) }, + { ABC_CONST(0x0303030303010001), ABC_CONST(0x0303030300010001), ABC_CONST(0x0303030003010001), ABC_CONST(0x0303030000010001), ABC_CONST(0x0303000303010001), ABC_CONST(0x0303000300010001), ABC_CONST(0x0303000003010001), ABC_CONST(0x0303000000010001), ABC_CONST(0x0300030303010001), ABC_CONST(0x0300030300010001), ABC_CONST(0x0300030003010001), ABC_CONST(0x0300030000010001), ABC_CONST(0x0300000303010001), ABC_CONST(0x0300000300010001), ABC_CONST(0x0300000003010001), ABC_CONST(0x0300000000010001), ABC_CONST(0x0303030303010001), ABC_CONST(0x0303030300010001), ABC_CONST(0x0303030003010001), ABC_CONST(0x0303030000010001), ABC_CONST(0x0303000303010001), ABC_CONST(0x0303000300010001), ABC_CONST(0x0303000003010001), ABC_CONST(0x0303000000010001), ABC_CONST(0x0300030303010001), ABC_CONST(0x0300030300010001), ABC_CONST(0x0300030003010001), ABC_CONST(0x0300030000010001), ABC_CONST(0x0300000303010001), ABC_CONST(0x0300000300010001), ABC_CONST(0x0300000003010001), ABC_CONST(0x0300000000010001) }, + { ABC_CONST(0x0404040404020102), ABC_CONST(0x0404040400020102), ABC_CONST(0x0404040004020102), ABC_CONST(0x0404040000020102), ABC_CONST(0x0404000404020102), ABC_CONST(0x0404000400020102), ABC_CONST(0x0404000004020102), ABC_CONST(0x0404000000020102), ABC_CONST(0x0400040404020102), ABC_CONST(0x0400040400020102), ABC_CONST(0x0400040004020102), ABC_CONST(0x0400040000020102), ABC_CONST(0x0400000404020102), ABC_CONST(0x0400000400020102), ABC_CONST(0x0400000004020102), ABC_CONST(0x0400000000020102), ABC_CONST(0x0404040404020102), ABC_CONST(0x0404040400020102), ABC_CONST(0x0404040004020102), ABC_CONST(0x0404040000020102), ABC_CONST(0x0404000404020102), ABC_CONST(0x0404000400020102), ABC_CONST(0x0404000004020102), ABC_CONST(0x0404000000020102), ABC_CONST(0x0400040404020102), ABC_CONST(0x0400040400020102), ABC_CONST(0x0400040004020102), ABC_CONST(0x0400040000020102), ABC_CONST(0x0400000404020102), ABC_CONST(0x0400000400020102), ABC_CONST(0x0400000004020102), ABC_CONST(0x0400000000020102) }, + { ABC_CONST(0x0404040404020101), ABC_CONST(0x0404040400020101), ABC_CONST(0x0404040004020101), ABC_CONST(0x0404040000020101), ABC_CONST(0x0404000404020101), ABC_CONST(0x0404000400020101), ABC_CONST(0x0404000004020101), ABC_CONST(0x0404000000020101), ABC_CONST(0x0400040404020101), ABC_CONST(0x0400040400020101), ABC_CONST(0x0400040004020101), ABC_CONST(0x0400040000020101), ABC_CONST(0x0400000404020101), ABC_CONST(0x0400000400020101), ABC_CONST(0x0400000004020101), ABC_CONST(0x0400000000020101), ABC_CONST(0x0404040404020101), ABC_CONST(0x0404040400020101), ABC_CONST(0x0404040004020101), ABC_CONST(0x0404040000020101), ABC_CONST(0x0404000404020101), ABC_CONST(0x0404000400020101), ABC_CONST(0x0404000004020101), ABC_CONST(0x0404000000020101), ABC_CONST(0x0400040404020101), ABC_CONST(0x0400040400020101), ABC_CONST(0x0400040004020101), ABC_CONST(0x0400040000020101), ABC_CONST(0x0400000404020101), ABC_CONST(0x0400000400020101), ABC_CONST(0x0400000004020101), ABC_CONST(0x0400000000020101) }, + { ABC_CONST(0x0505050505030202), ABC_CONST(0x0505050500030202), ABC_CONST(0x0505050005030202), ABC_CONST(0x0505050000030202), ABC_CONST(0x0505000505030202), ABC_CONST(0x0505000500030202), ABC_CONST(0x0505000005030202), ABC_CONST(0x0505000000030202), ABC_CONST(0x0500050505030202), ABC_CONST(0x0500050500030202), ABC_CONST(0x0500050005030202), ABC_CONST(0x0500050000030202), ABC_CONST(0x0500000505030202), ABC_CONST(0x0500000500030202), ABC_CONST(0x0500000005030202), ABC_CONST(0x0500000000030202), ABC_CONST(0x0505050505030202), ABC_CONST(0x0505050500030202), ABC_CONST(0x0505050005030202), ABC_CONST(0x0505050000030202), ABC_CONST(0x0505000505030202), ABC_CONST(0x0505000500030202), ABC_CONST(0x0505000005030202), ABC_CONST(0x0505000000030202), ABC_CONST(0x0500050505030202), ABC_CONST(0x0500050500030202), ABC_CONST(0x0500050005030202), ABC_CONST(0x0500050000030202), ABC_CONST(0x0500000505030202), ABC_CONST(0x0500000500030202), ABC_CONST(0x0500000005030202), ABC_CONST(0x0500000000030202) }, + { ABC_CONST(0x0404040404020002), ABC_CONST(0x0404040400020002), ABC_CONST(0x0404040004020002), ABC_CONST(0x0404040000020002), ABC_CONST(0x0404000404020002), ABC_CONST(0x0404000400020002), ABC_CONST(0x0404000004020002), ABC_CONST(0x0404000000020002), ABC_CONST(0x0400040404020002), ABC_CONST(0x0400040400020002), ABC_CONST(0x0400040004020002), ABC_CONST(0x0400040000020002), ABC_CONST(0x0400000404020002), ABC_CONST(0x0400000400020002), ABC_CONST(0x0400000004020002), ABC_CONST(0x0400000000020002), ABC_CONST(0x0404040404020002), ABC_CONST(0x0404040400020002), ABC_CONST(0x0404040004020002), ABC_CONST(0x0404040000020002), ABC_CONST(0x0404000404020002), ABC_CONST(0x0404000400020002), ABC_CONST(0x0404000004020002), ABC_CONST(0x0404000000020002), ABC_CONST(0x0400040404020002), ABC_CONST(0x0400040400020002), ABC_CONST(0x0400040004020002), ABC_CONST(0x0400040000020002), ABC_CONST(0x0400000404020002), ABC_CONST(0x0400000400020002), ABC_CONST(0x0400000004020002), ABC_CONST(0x0400000000020002) }, + { ABC_CONST(0x0505050505030103), ABC_CONST(0x0505050500030103), ABC_CONST(0x0505050005030103), ABC_CONST(0x0505050000030103), ABC_CONST(0x0505000505030103), ABC_CONST(0x0505000500030103), ABC_CONST(0x0505000005030103), ABC_CONST(0x0505000000030103), ABC_CONST(0x0500050505030103), ABC_CONST(0x0500050500030103), ABC_CONST(0x0500050005030103), ABC_CONST(0x0500050000030103), ABC_CONST(0x0500000505030103), ABC_CONST(0x0500000500030103), ABC_CONST(0x0500000005030103), ABC_CONST(0x0500000000030103), ABC_CONST(0x0505050505030103), ABC_CONST(0x0505050500030103), ABC_CONST(0x0505050005030103), ABC_CONST(0x0505050000030103), ABC_CONST(0x0505000505030103), ABC_CONST(0x0505000500030103), ABC_CONST(0x0505000005030103), ABC_CONST(0x0505000000030103), ABC_CONST(0x0500050505030103), ABC_CONST(0x0500050500030103), ABC_CONST(0x0500050005030103), ABC_CONST(0x0500050000030103), ABC_CONST(0x0500000505030103), ABC_CONST(0x0500000500030103), ABC_CONST(0x0500000005030103), ABC_CONST(0x0500000000030103) }, + { ABC_CONST(0x0505050505030102), ABC_CONST(0x0505050500030102), ABC_CONST(0x0505050005030102), ABC_CONST(0x0505050000030102), ABC_CONST(0x0505000505030102), ABC_CONST(0x0505000500030102), ABC_CONST(0x0505000005030102), ABC_CONST(0x0505000000030102), ABC_CONST(0x0500050505030102), ABC_CONST(0x0500050500030102), ABC_CONST(0x0500050005030102), ABC_CONST(0x0500050000030102), ABC_CONST(0x0500000505030102), ABC_CONST(0x0500000500030102), ABC_CONST(0x0500000005030102), ABC_CONST(0x0500000000030102), ABC_CONST(0x0505050505030102), ABC_CONST(0x0505050500030102), ABC_CONST(0x0505050005030102), ABC_CONST(0x0505050000030102), ABC_CONST(0x0505000505030102), ABC_CONST(0x0505000500030102), ABC_CONST(0x0505000005030102), ABC_CONST(0x0505000000030102), ABC_CONST(0x0500050505030102), ABC_CONST(0x0500050500030102), ABC_CONST(0x0500050005030102), ABC_CONST(0x0500050000030102), ABC_CONST(0x0500000505030102), ABC_CONST(0x0500000500030102), ABC_CONST(0x0500000005030102), ABC_CONST(0x0500000000030102) }, + { ABC_CONST(0x0606060606040203), ABC_CONST(0x0606060600040203), ABC_CONST(0x0606060006040203), ABC_CONST(0x0606060000040203), ABC_CONST(0x0606000606040203), ABC_CONST(0x0606000600040203), ABC_CONST(0x0606000006040203), ABC_CONST(0x0606000000040203), ABC_CONST(0x0600060606040203), ABC_CONST(0x0600060600040203), ABC_CONST(0x0600060006040203), ABC_CONST(0x0600060000040203), ABC_CONST(0x0600000606040203), ABC_CONST(0x0600000600040203), ABC_CONST(0x0600000006040203), ABC_CONST(0x0600000000040203), ABC_CONST(0x0606060606040203), ABC_CONST(0x0606060600040203), ABC_CONST(0x0606060006040203), ABC_CONST(0x0606060000040203), ABC_CONST(0x0606000606040203), ABC_CONST(0x0606000600040203), ABC_CONST(0x0606000006040203), ABC_CONST(0x0606000000040203), ABC_CONST(0x0600060606040203), ABC_CONST(0x0600060600040203), ABC_CONST(0x0600060006040203), ABC_CONST(0x0600060000040203), ABC_CONST(0x0600000606040203), ABC_CONST(0x0600000600040203), ABC_CONST(0x0600000006040203), ABC_CONST(0x0600000000040203) }, + { ABC_CONST(0x0303030303000102), ABC_CONST(0x0303030300000102), ABC_CONST(0x0303030003000102), ABC_CONST(0x0303030000000102), ABC_CONST(0x0303000303000102), ABC_CONST(0x0303000300000102), ABC_CONST(0x0303000003000102), ABC_CONST(0x0303000000000102), ABC_CONST(0x0300030303000102), ABC_CONST(0x0300030300000102), ABC_CONST(0x0300030003000102), ABC_CONST(0x0300030000000102), ABC_CONST(0x0300000303000102), ABC_CONST(0x0300000300000102), ABC_CONST(0x0300000003000102), ABC_CONST(0x0300000000000102), ABC_CONST(0x0303030303000102), ABC_CONST(0x0303030300000102), ABC_CONST(0x0303030003000102), ABC_CONST(0x0303030000000102), ABC_CONST(0x0303000303000102), ABC_CONST(0x0303000300000102), ABC_CONST(0x0303000003000102), ABC_CONST(0x0303000000000102), ABC_CONST(0x0300030303000102), ABC_CONST(0x0300030300000102), ABC_CONST(0x0300030003000102), ABC_CONST(0x0300030000000102), ABC_CONST(0x0300000303000102), ABC_CONST(0x0300000300000102), ABC_CONST(0x0300000003000102), ABC_CONST(0x0300000000000102) }, + { ABC_CONST(0x0404040404010203), ABC_CONST(0x0404040400010203), ABC_CONST(0x0404040004010203), ABC_CONST(0x0404040000010203), ABC_CONST(0x0404000404010203), ABC_CONST(0x0404000400010203), ABC_CONST(0x0404000004010203), ABC_CONST(0x0404000000010203), ABC_CONST(0x0400040404010203), ABC_CONST(0x0400040400010203), ABC_CONST(0x0400040004010203), ABC_CONST(0x0400040000010203), ABC_CONST(0x0400000404010203), ABC_CONST(0x0400000400010203), ABC_CONST(0x0400000004010203), ABC_CONST(0x0400000000010203), ABC_CONST(0x0404040404010203), ABC_CONST(0x0404040400010203), ABC_CONST(0x0404040004010203), ABC_CONST(0x0404040000010203), ABC_CONST(0x0404000404010203), ABC_CONST(0x0404000400010203), ABC_CONST(0x0404000004010203), ABC_CONST(0x0404000000010203), ABC_CONST(0x0400040404010203), ABC_CONST(0x0400040400010203), ABC_CONST(0x0400040004010203), ABC_CONST(0x0400040000010203), ABC_CONST(0x0400000404010203), ABC_CONST(0x0400000400010203), ABC_CONST(0x0400000004010203), ABC_CONST(0x0400000000010203) }, + { ABC_CONST(0x0404040404010202), ABC_CONST(0x0404040400010202), ABC_CONST(0x0404040004010202), ABC_CONST(0x0404040000010202), ABC_CONST(0x0404000404010202), ABC_CONST(0x0404000400010202), ABC_CONST(0x0404000004010202), ABC_CONST(0x0404000000010202), ABC_CONST(0x0400040404010202), ABC_CONST(0x0400040400010202), ABC_CONST(0x0400040004010202), ABC_CONST(0x0400040000010202), ABC_CONST(0x0400000404010202), ABC_CONST(0x0400000400010202), ABC_CONST(0x0400000004010202), ABC_CONST(0x0400000000010202), ABC_CONST(0x0404040404010202), ABC_CONST(0x0404040400010202), ABC_CONST(0x0404040004010202), ABC_CONST(0x0404040000010202), ABC_CONST(0x0404000404010202), ABC_CONST(0x0404000400010202), ABC_CONST(0x0404000004010202), ABC_CONST(0x0404000000010202), ABC_CONST(0x0400040404010202), ABC_CONST(0x0400040400010202), ABC_CONST(0x0400040004010202), ABC_CONST(0x0400040000010202), ABC_CONST(0x0400000404010202), ABC_CONST(0x0400000400010202), ABC_CONST(0x0400000004010202), ABC_CONST(0x0400000000010202) }, + { ABC_CONST(0x0505050505020303), ABC_CONST(0x0505050500020303), ABC_CONST(0x0505050005020303), ABC_CONST(0x0505050000020303), ABC_CONST(0x0505000505020303), ABC_CONST(0x0505000500020303), ABC_CONST(0x0505000005020303), ABC_CONST(0x0505000000020303), ABC_CONST(0x0500050505020303), ABC_CONST(0x0500050500020303), ABC_CONST(0x0500050005020303), ABC_CONST(0x0500050000020303), ABC_CONST(0x0500000505020303), ABC_CONST(0x0500000500020303), ABC_CONST(0x0500000005020303), ABC_CONST(0x0500000000020303), ABC_CONST(0x0505050505020303), ABC_CONST(0x0505050500020303), ABC_CONST(0x0505050005020303), ABC_CONST(0x0505050000020303), ABC_CONST(0x0505000505020303), ABC_CONST(0x0505000500020303), ABC_CONST(0x0505000005020303), ABC_CONST(0x0505000000020303), ABC_CONST(0x0500050505020303), ABC_CONST(0x0500050500020303), ABC_CONST(0x0500050005020303), ABC_CONST(0x0500050000020303), ABC_CONST(0x0500000505020303), ABC_CONST(0x0500000500020303), ABC_CONST(0x0500000005020303), ABC_CONST(0x0500000000020303) }, + { ABC_CONST(0x0404040404010103), ABC_CONST(0x0404040400010103), ABC_CONST(0x0404040004010103), ABC_CONST(0x0404040000010103), ABC_CONST(0x0404000404010103), ABC_CONST(0x0404000400010103), ABC_CONST(0x0404000004010103), ABC_CONST(0x0404000000010103), ABC_CONST(0x0400040404010103), ABC_CONST(0x0400040400010103), ABC_CONST(0x0400040004010103), ABC_CONST(0x0400040000010103), ABC_CONST(0x0400000404010103), ABC_CONST(0x0400000400010103), ABC_CONST(0x0400000004010103), ABC_CONST(0x0400000000010103), ABC_CONST(0x0404040404010103), ABC_CONST(0x0404040400010103), ABC_CONST(0x0404040004010103), ABC_CONST(0x0404040000010103), ABC_CONST(0x0404000404010103), ABC_CONST(0x0404000400010103), ABC_CONST(0x0404000004010103), ABC_CONST(0x0404000000010103), ABC_CONST(0x0400040404010103), ABC_CONST(0x0400040400010103), ABC_CONST(0x0400040004010103), ABC_CONST(0x0400040000010103), ABC_CONST(0x0400000404010103), ABC_CONST(0x0400000400010103), ABC_CONST(0x0400000004010103), ABC_CONST(0x0400000000010103) }, + { ABC_CONST(0x0505050505020204), ABC_CONST(0x0505050500020204), ABC_CONST(0x0505050005020204), ABC_CONST(0x0505050000020204), ABC_CONST(0x0505000505020204), ABC_CONST(0x0505000500020204), ABC_CONST(0x0505000005020204), ABC_CONST(0x0505000000020204), ABC_CONST(0x0500050505020204), ABC_CONST(0x0500050500020204), ABC_CONST(0x0500050005020204), ABC_CONST(0x0500050000020204), ABC_CONST(0x0500000505020204), ABC_CONST(0x0500000500020204), ABC_CONST(0x0500000005020204), ABC_CONST(0x0500000000020204), ABC_CONST(0x0505050505020204), ABC_CONST(0x0505050500020204), ABC_CONST(0x0505050005020204), ABC_CONST(0x0505050000020204), ABC_CONST(0x0505000505020204), ABC_CONST(0x0505000500020204), ABC_CONST(0x0505000005020204), ABC_CONST(0x0505000000020204), ABC_CONST(0x0500050505020204), ABC_CONST(0x0500050500020204), ABC_CONST(0x0500050005020204), ABC_CONST(0x0500050000020204), ABC_CONST(0x0500000505020204), ABC_CONST(0x0500000500020204), ABC_CONST(0x0500000005020204), ABC_CONST(0x0500000000020204) }, + { ABC_CONST(0x0505050505020203), ABC_CONST(0x0505050500020203), ABC_CONST(0x0505050005020203), ABC_CONST(0x0505050000020203), ABC_CONST(0x0505000505020203), ABC_CONST(0x0505000500020203), ABC_CONST(0x0505000005020203), ABC_CONST(0x0505000000020203), ABC_CONST(0x0500050505020203), ABC_CONST(0x0500050500020203), ABC_CONST(0x0500050005020203), ABC_CONST(0x0500050000020203), ABC_CONST(0x0500000505020203), ABC_CONST(0x0500000500020203), ABC_CONST(0x0500000005020203), ABC_CONST(0x0500000000020203), ABC_CONST(0x0505050505020203), ABC_CONST(0x0505050500020203), ABC_CONST(0x0505050005020203), ABC_CONST(0x0505050000020203), ABC_CONST(0x0505000505020203), ABC_CONST(0x0505000500020203), ABC_CONST(0x0505000005020203), ABC_CONST(0x0505000000020203), ABC_CONST(0x0500050505020203), ABC_CONST(0x0500050500020203), ABC_CONST(0x0500050005020203), ABC_CONST(0x0500050000020203), ABC_CONST(0x0500000505020203), ABC_CONST(0x0500000500020203), ABC_CONST(0x0500000005020203), ABC_CONST(0x0500000000020203) }, + { ABC_CONST(0x0606060606030304), ABC_CONST(0x0606060600030304), ABC_CONST(0x0606060006030304), ABC_CONST(0x0606060000030304), ABC_CONST(0x0606000606030304), ABC_CONST(0x0606000600030304), ABC_CONST(0x0606000006030304), ABC_CONST(0x0606000000030304), ABC_CONST(0x0600060606030304), ABC_CONST(0x0600060600030304), ABC_CONST(0x0600060006030304), ABC_CONST(0x0600060000030304), ABC_CONST(0x0600000606030304), ABC_CONST(0x0600000600030304), ABC_CONST(0x0600000006030304), ABC_CONST(0x0600000000030304), ABC_CONST(0x0606060606030304), ABC_CONST(0x0606060600030304), ABC_CONST(0x0606060006030304), ABC_CONST(0x0606060000030304), ABC_CONST(0x0606000606030304), ABC_CONST(0x0606000600030304), ABC_CONST(0x0606000006030304), ABC_CONST(0x0606000000030304), ABC_CONST(0x0600060606030304), ABC_CONST(0x0600060600030304), ABC_CONST(0x0600060006030304), ABC_CONST(0x0600060000030304), ABC_CONST(0x0600000606030304), ABC_CONST(0x0600000600030304), ABC_CONST(0x0600000006030304), ABC_CONST(0x0600000000030304) }, + { ABC_CONST(0x0404040404010102), ABC_CONST(0x0404040400010102), ABC_CONST(0x0404040004010102), ABC_CONST(0x0404040000010102), ABC_CONST(0x0404000404010102), ABC_CONST(0x0404000400010102), ABC_CONST(0x0404000004010102), ABC_CONST(0x0404000000010102), ABC_CONST(0x0400040404010102), ABC_CONST(0x0400040400010102), ABC_CONST(0x0400040004010102), ABC_CONST(0x0400040000010102), ABC_CONST(0x0400000404010102), ABC_CONST(0x0400000400010102), ABC_CONST(0x0400000004010102), ABC_CONST(0x0400000000010102), ABC_CONST(0x0404040404010102), ABC_CONST(0x0404040400010102), ABC_CONST(0x0404040004010102), ABC_CONST(0x0404040000010102), ABC_CONST(0x0404000404010102), ABC_CONST(0x0404000400010102), ABC_CONST(0x0404000004010102), ABC_CONST(0x0404000000010102), ABC_CONST(0x0400040404010102), ABC_CONST(0x0400040400010102), ABC_CONST(0x0400040004010102), ABC_CONST(0x0400040000010102), ABC_CONST(0x0400000404010102), ABC_CONST(0x0400000400010102), ABC_CONST(0x0400000004010102), ABC_CONST(0x0400000000010102) }, + { ABC_CONST(0x0505050505020203), ABC_CONST(0x0505050500020203), ABC_CONST(0x0505050005020203), ABC_CONST(0x0505050000020203), ABC_CONST(0x0505000505020203), ABC_CONST(0x0505000500020203), ABC_CONST(0x0505000005020203), ABC_CONST(0x0505000000020203), ABC_CONST(0x0500050505020203), ABC_CONST(0x0500050500020203), ABC_CONST(0x0500050005020203), ABC_CONST(0x0500050000020203), ABC_CONST(0x0500000505020203), ABC_CONST(0x0500000500020203), ABC_CONST(0x0500000005020203), ABC_CONST(0x0500000000020203), ABC_CONST(0x0505050505020203), ABC_CONST(0x0505050500020203), ABC_CONST(0x0505050005020203), ABC_CONST(0x0505050000020203), ABC_CONST(0x0505000505020203), ABC_CONST(0x0505000500020203), ABC_CONST(0x0505000005020203), ABC_CONST(0x0505000000020203), ABC_CONST(0x0500050505020203), ABC_CONST(0x0500050500020203), ABC_CONST(0x0500050005020203), ABC_CONST(0x0500050000020203), ABC_CONST(0x0500000505020203), ABC_CONST(0x0500000500020203), ABC_CONST(0x0500000005020203), ABC_CONST(0x0500000000020203) }, + { ABC_CONST(0x0505050505020202), ABC_CONST(0x0505050500020202), ABC_CONST(0x0505050005020202), ABC_CONST(0x0505050000020202), ABC_CONST(0x0505000505020202), ABC_CONST(0x0505000500020202), ABC_CONST(0x0505000005020202), ABC_CONST(0x0505000000020202), ABC_CONST(0x0500050505020202), ABC_CONST(0x0500050500020202), ABC_CONST(0x0500050005020202), ABC_CONST(0x0500050000020202), ABC_CONST(0x0500000505020202), ABC_CONST(0x0500000500020202), ABC_CONST(0x0500000005020202), ABC_CONST(0x0500000000020202), ABC_CONST(0x0505050505020202), ABC_CONST(0x0505050500020202), ABC_CONST(0x0505050005020202), ABC_CONST(0x0505050000020202), ABC_CONST(0x0505000505020202), ABC_CONST(0x0505000500020202), ABC_CONST(0x0505000005020202), ABC_CONST(0x0505000000020202), ABC_CONST(0x0500050505020202), ABC_CONST(0x0500050500020202), ABC_CONST(0x0500050005020202), ABC_CONST(0x0500050000020202), ABC_CONST(0x0500000505020202), ABC_CONST(0x0500000500020202), ABC_CONST(0x0500000005020202), ABC_CONST(0x0500000000020202) }, + { ABC_CONST(0x0606060606030303), ABC_CONST(0x0606060600030303), ABC_CONST(0x0606060006030303), ABC_CONST(0x0606060000030303), ABC_CONST(0x0606000606030303), ABC_CONST(0x0606000600030303), ABC_CONST(0x0606000006030303), ABC_CONST(0x0606000000030303), ABC_CONST(0x0600060606030303), ABC_CONST(0x0600060600030303), ABC_CONST(0x0600060006030303), ABC_CONST(0x0600060000030303), ABC_CONST(0x0600000606030303), ABC_CONST(0x0600000600030303), ABC_CONST(0x0600000006030303), ABC_CONST(0x0600000000030303), ABC_CONST(0x0606060606030303), ABC_CONST(0x0606060600030303), ABC_CONST(0x0606060006030303), ABC_CONST(0x0606060000030303), ABC_CONST(0x0606000606030303), ABC_CONST(0x0606000600030303), ABC_CONST(0x0606000006030303), ABC_CONST(0x0606000000030303), ABC_CONST(0x0600060606030303), ABC_CONST(0x0600060600030303), ABC_CONST(0x0600060006030303), ABC_CONST(0x0600060000030303), ABC_CONST(0x0600000606030303), ABC_CONST(0x0600000600030303), ABC_CONST(0x0600000006030303), ABC_CONST(0x0600000000030303) }, + { ABC_CONST(0x0505050505020103), ABC_CONST(0x0505050500020103), ABC_CONST(0x0505050005020103), ABC_CONST(0x0505050000020103), ABC_CONST(0x0505000505020103), ABC_CONST(0x0505000500020103), ABC_CONST(0x0505000005020103), ABC_CONST(0x0505000000020103), ABC_CONST(0x0500050505020103), ABC_CONST(0x0500050500020103), ABC_CONST(0x0500050005020103), ABC_CONST(0x0500050000020103), ABC_CONST(0x0500000505020103), ABC_CONST(0x0500000500020103), ABC_CONST(0x0500000005020103), ABC_CONST(0x0500000000020103), ABC_CONST(0x0505050505020103), ABC_CONST(0x0505050500020103), ABC_CONST(0x0505050005020103), ABC_CONST(0x0505050000020103), ABC_CONST(0x0505000505020103), ABC_CONST(0x0505000500020103), ABC_CONST(0x0505000005020103), ABC_CONST(0x0505000000020103), ABC_CONST(0x0500050505020103), ABC_CONST(0x0500050500020103), ABC_CONST(0x0500050005020103), ABC_CONST(0x0500050000020103), ABC_CONST(0x0500000505020103), ABC_CONST(0x0500000500020103), ABC_CONST(0x0500000005020103), ABC_CONST(0x0500000000020103) }, + { ABC_CONST(0x0606060606030204), ABC_CONST(0x0606060600030204), ABC_CONST(0x0606060006030204), ABC_CONST(0x0606060000030204), ABC_CONST(0x0606000606030204), ABC_CONST(0x0606000600030204), ABC_CONST(0x0606000006030204), ABC_CONST(0x0606000000030204), ABC_CONST(0x0600060606030204), ABC_CONST(0x0600060600030204), ABC_CONST(0x0600060006030204), ABC_CONST(0x0600060000030204), ABC_CONST(0x0600000606030204), ABC_CONST(0x0600000600030204), ABC_CONST(0x0600000006030204), ABC_CONST(0x0600000000030204), ABC_CONST(0x0606060606030204), ABC_CONST(0x0606060600030204), ABC_CONST(0x0606060006030204), ABC_CONST(0x0606060000030204), ABC_CONST(0x0606000606030204), ABC_CONST(0x0606000600030204), ABC_CONST(0x0606000006030204), ABC_CONST(0x0606000000030204), ABC_CONST(0x0600060606030204), ABC_CONST(0x0600060600030204), ABC_CONST(0x0600060006030204), ABC_CONST(0x0600060000030204), ABC_CONST(0x0600000606030204), ABC_CONST(0x0600000600030204), ABC_CONST(0x0600000006030204), ABC_CONST(0x0600000000030204) }, + { ABC_CONST(0x0606060606030203), ABC_CONST(0x0606060600030203), ABC_CONST(0x0606060006030203), ABC_CONST(0x0606060000030203), ABC_CONST(0x0606000606030203), ABC_CONST(0x0606000600030203), ABC_CONST(0x0606000006030203), ABC_CONST(0x0606000000030203), ABC_CONST(0x0600060606030203), ABC_CONST(0x0600060600030203), ABC_CONST(0x0600060006030203), ABC_CONST(0x0600060000030203), ABC_CONST(0x0600000606030203), ABC_CONST(0x0600000600030203), ABC_CONST(0x0600000006030203), ABC_CONST(0x0600000000030203), ABC_CONST(0x0606060606030203), ABC_CONST(0x0606060600030203), ABC_CONST(0x0606060006030203), ABC_CONST(0x0606060000030203), ABC_CONST(0x0606000606030203), ABC_CONST(0x0606000600030203), ABC_CONST(0x0606000006030203), ABC_CONST(0x0606000000030203), ABC_CONST(0x0600060606030203), ABC_CONST(0x0600060600030203), ABC_CONST(0x0600060006030203), ABC_CONST(0x0600060000030203), ABC_CONST(0x0600000606030203), ABC_CONST(0x0600000600030203), ABC_CONST(0x0600000006030203), ABC_CONST(0x0600000000030203) }, + { ABC_CONST(0x0707070707040304), ABC_CONST(0x0707070700040304), ABC_CONST(0x0707070007040304), ABC_CONST(0x0707070000040304), ABC_CONST(0x0707000707040304), ABC_CONST(0x0707000700040304), ABC_CONST(0x0707000007040304), ABC_CONST(0x0707000000040304), ABC_CONST(0x0700070707040304), ABC_CONST(0x0700070700040304), ABC_CONST(0x0700070007040304), ABC_CONST(0x0700070000040304), ABC_CONST(0x0700000707040304), ABC_CONST(0x0700000700040304), ABC_CONST(0x0700000007040304), ABC_CONST(0x0700000000040304), ABC_CONST(0x0707070707040304), ABC_CONST(0x0707070700040304), ABC_CONST(0x0707070007040304), ABC_CONST(0x0707070000040304), ABC_CONST(0x0707000707040304), ABC_CONST(0x0707000700040304), ABC_CONST(0x0707000007040304), ABC_CONST(0x0707000000040304), ABC_CONST(0x0700070707040304), ABC_CONST(0x0700070700040304), ABC_CONST(0x0700070007040304), ABC_CONST(0x0700070000040304), ABC_CONST(0x0700000707040304), ABC_CONST(0x0700000700040304), ABC_CONST(0x0700000007040304), ABC_CONST(0x0700000000040304) }, + { ABC_CONST(0x0303030303000101), ABC_CONST(0x0303030300000101), ABC_CONST(0x0303030003000101), ABC_CONST(0x0303030000000101), ABC_CONST(0x0303000303000101), ABC_CONST(0x0303000300000101), ABC_CONST(0x0303000003000101), ABC_CONST(0x0303000000000101), ABC_CONST(0x0300030303000101), ABC_CONST(0x0300030300000101), ABC_CONST(0x0300030003000101), ABC_CONST(0x0300030000000101), ABC_CONST(0x0300000303000101), ABC_CONST(0x0300000300000101), ABC_CONST(0x0300000003000101), ABC_CONST(0x0300000000000101), ABC_CONST(0x0303030303000101), ABC_CONST(0x0303030300000101), ABC_CONST(0x0303030003000101), ABC_CONST(0x0303030000000101), ABC_CONST(0x0303000303000101), ABC_CONST(0x0303000300000101), ABC_CONST(0x0303000003000101), ABC_CONST(0x0303000000000101), ABC_CONST(0x0300030303000101), ABC_CONST(0x0300030300000101), ABC_CONST(0x0300030003000101), ABC_CONST(0x0300030000000101), ABC_CONST(0x0300000303000101), ABC_CONST(0x0300000300000101), ABC_CONST(0x0300000003000101), ABC_CONST(0x0300000000000101) }, + { ABC_CONST(0x0404040404010202), ABC_CONST(0x0404040400010202), ABC_CONST(0x0404040004010202), ABC_CONST(0x0404040000010202), ABC_CONST(0x0404000404010202), ABC_CONST(0x0404000400010202), ABC_CONST(0x0404000004010202), ABC_CONST(0x0404000000010202), ABC_CONST(0x0400040404010202), ABC_CONST(0x0400040400010202), ABC_CONST(0x0400040004010202), ABC_CONST(0x0400040000010202), ABC_CONST(0x0400000404010202), ABC_CONST(0x0400000400010202), ABC_CONST(0x0400000004010202), ABC_CONST(0x0400000000010202), ABC_CONST(0x0404040404010202), ABC_CONST(0x0404040400010202), ABC_CONST(0x0404040004010202), ABC_CONST(0x0404040000010202), ABC_CONST(0x0404000404010202), ABC_CONST(0x0404000400010202), ABC_CONST(0x0404000004010202), ABC_CONST(0x0404000000010202), ABC_CONST(0x0400040404010202), ABC_CONST(0x0400040400010202), ABC_CONST(0x0400040004010202), ABC_CONST(0x0400040000010202), ABC_CONST(0x0400000404010202), ABC_CONST(0x0400000400010202), ABC_CONST(0x0400000004010202), ABC_CONST(0x0400000000010202) }, + { ABC_CONST(0x0404040404010201), ABC_CONST(0x0404040400010201), ABC_CONST(0x0404040004010201), ABC_CONST(0x0404040000010201), ABC_CONST(0x0404000404010201), ABC_CONST(0x0404000400010201), ABC_CONST(0x0404000004010201), ABC_CONST(0x0404000000010201), ABC_CONST(0x0400040404010201), ABC_CONST(0x0400040400010201), ABC_CONST(0x0400040004010201), ABC_CONST(0x0400040000010201), ABC_CONST(0x0400000404010201), ABC_CONST(0x0400000400010201), ABC_CONST(0x0400000004010201), ABC_CONST(0x0400000000010201), ABC_CONST(0x0404040404010201), ABC_CONST(0x0404040400010201), ABC_CONST(0x0404040004010201), ABC_CONST(0x0404040000010201), ABC_CONST(0x0404000404010201), ABC_CONST(0x0404000400010201), ABC_CONST(0x0404000004010201), ABC_CONST(0x0404000000010201), ABC_CONST(0x0400040404010201), ABC_CONST(0x0400040400010201), ABC_CONST(0x0400040004010201), ABC_CONST(0x0400040000010201), ABC_CONST(0x0400000404010201), ABC_CONST(0x0400000400010201), ABC_CONST(0x0400000004010201), ABC_CONST(0x0400000000010201) }, + { ABC_CONST(0x0505050505020302), ABC_CONST(0x0505050500020302), ABC_CONST(0x0505050005020302), ABC_CONST(0x0505050000020302), ABC_CONST(0x0505000505020302), ABC_CONST(0x0505000500020302), ABC_CONST(0x0505000005020302), ABC_CONST(0x0505000000020302), ABC_CONST(0x0500050505020302), ABC_CONST(0x0500050500020302), ABC_CONST(0x0500050005020302), ABC_CONST(0x0500050000020302), ABC_CONST(0x0500000505020302), ABC_CONST(0x0500000500020302), ABC_CONST(0x0500000005020302), ABC_CONST(0x0500000000020302), ABC_CONST(0x0505050505020302), ABC_CONST(0x0505050500020302), ABC_CONST(0x0505050005020302), ABC_CONST(0x0505050000020302), ABC_CONST(0x0505000505020302), ABC_CONST(0x0505000500020302), ABC_CONST(0x0505000005020302), ABC_CONST(0x0505000000020302), ABC_CONST(0x0500050505020302), ABC_CONST(0x0500050500020302), ABC_CONST(0x0500050005020302), ABC_CONST(0x0500050000020302), ABC_CONST(0x0500000505020302), ABC_CONST(0x0500000500020302), ABC_CONST(0x0500000005020302), ABC_CONST(0x0500000000020302) }, + { ABC_CONST(0x0404040404010102), ABC_CONST(0x0404040400010102), ABC_CONST(0x0404040004010102), ABC_CONST(0x0404040000010102), ABC_CONST(0x0404000404010102), ABC_CONST(0x0404000400010102), ABC_CONST(0x0404000004010102), ABC_CONST(0x0404000000010102), ABC_CONST(0x0400040404010102), ABC_CONST(0x0400040400010102), ABC_CONST(0x0400040004010102), ABC_CONST(0x0400040000010102), ABC_CONST(0x0400000404010102), ABC_CONST(0x0400000400010102), ABC_CONST(0x0400000004010102), ABC_CONST(0x0400000000010102), ABC_CONST(0x0404040404010102), ABC_CONST(0x0404040400010102), ABC_CONST(0x0404040004010102), ABC_CONST(0x0404040000010102), ABC_CONST(0x0404000404010102), ABC_CONST(0x0404000400010102), ABC_CONST(0x0404000004010102), ABC_CONST(0x0404000000010102), ABC_CONST(0x0400040404010102), ABC_CONST(0x0400040400010102), ABC_CONST(0x0400040004010102), ABC_CONST(0x0400040000010102), ABC_CONST(0x0400000404010102), ABC_CONST(0x0400000400010102), ABC_CONST(0x0400000004010102), ABC_CONST(0x0400000000010102) }, + { ABC_CONST(0x0505050505020203), ABC_CONST(0x0505050500020203), ABC_CONST(0x0505050005020203), ABC_CONST(0x0505050000020203), ABC_CONST(0x0505000505020203), ABC_CONST(0x0505000500020203), ABC_CONST(0x0505000005020203), ABC_CONST(0x0505000000020203), ABC_CONST(0x0500050505020203), ABC_CONST(0x0500050500020203), ABC_CONST(0x0500050005020203), ABC_CONST(0x0500050000020203), ABC_CONST(0x0500000505020203), ABC_CONST(0x0500000500020203), ABC_CONST(0x0500000005020203), ABC_CONST(0x0500000000020203), ABC_CONST(0x0505050505020203), ABC_CONST(0x0505050500020203), ABC_CONST(0x0505050005020203), ABC_CONST(0x0505050000020203), ABC_CONST(0x0505000505020203), ABC_CONST(0x0505000500020203), ABC_CONST(0x0505000005020203), ABC_CONST(0x0505000000020203), ABC_CONST(0x0500050505020203), ABC_CONST(0x0500050500020203), ABC_CONST(0x0500050005020203), ABC_CONST(0x0500050000020203), ABC_CONST(0x0500000505020203), ABC_CONST(0x0500000500020203), ABC_CONST(0x0500000005020203), ABC_CONST(0x0500000000020203) }, + { ABC_CONST(0x0505050505020202), ABC_CONST(0x0505050500020202), ABC_CONST(0x0505050005020202), ABC_CONST(0x0505050000020202), ABC_CONST(0x0505000505020202), ABC_CONST(0x0505000500020202), ABC_CONST(0x0505000005020202), ABC_CONST(0x0505000000020202), ABC_CONST(0x0500050505020202), ABC_CONST(0x0500050500020202), ABC_CONST(0x0500050005020202), ABC_CONST(0x0500050000020202), ABC_CONST(0x0500000505020202), ABC_CONST(0x0500000500020202), ABC_CONST(0x0500000005020202), ABC_CONST(0x0500000000020202), ABC_CONST(0x0505050505020202), ABC_CONST(0x0505050500020202), ABC_CONST(0x0505050005020202), ABC_CONST(0x0505050000020202), ABC_CONST(0x0505000505020202), ABC_CONST(0x0505000500020202), ABC_CONST(0x0505000005020202), ABC_CONST(0x0505000000020202), ABC_CONST(0x0500050505020202), ABC_CONST(0x0500050500020202), ABC_CONST(0x0500050005020202), ABC_CONST(0x0500050000020202), ABC_CONST(0x0500000505020202), ABC_CONST(0x0500000500020202), ABC_CONST(0x0500000005020202), ABC_CONST(0x0500000000020202) }, + { ABC_CONST(0x0606060606030303), ABC_CONST(0x0606060600030303), ABC_CONST(0x0606060006030303), ABC_CONST(0x0606060000030303), ABC_CONST(0x0606000606030303), ABC_CONST(0x0606000600030303), ABC_CONST(0x0606000006030303), ABC_CONST(0x0606000000030303), ABC_CONST(0x0600060606030303), ABC_CONST(0x0600060600030303), ABC_CONST(0x0600060006030303), ABC_CONST(0x0600060000030303), ABC_CONST(0x0600000606030303), ABC_CONST(0x0600000600030303), ABC_CONST(0x0600000006030303), ABC_CONST(0x0600000000030303), ABC_CONST(0x0606060606030303), ABC_CONST(0x0606060600030303), ABC_CONST(0x0606060006030303), ABC_CONST(0x0606060000030303), ABC_CONST(0x0606000606030303), ABC_CONST(0x0606000600030303), ABC_CONST(0x0606000006030303), ABC_CONST(0x0606000000030303), ABC_CONST(0x0600060606030303), ABC_CONST(0x0600060600030303), ABC_CONST(0x0600060006030303), ABC_CONST(0x0600060000030303), ABC_CONST(0x0600000606030303), ABC_CONST(0x0600000600030303), ABC_CONST(0x0600000006030303), ABC_CONST(0x0600000000030303) }, + { ABC_CONST(0x0404040404010101), ABC_CONST(0x0404040400010101), ABC_CONST(0x0404040004010101), ABC_CONST(0x0404040000010101), ABC_CONST(0x0404000404010101), ABC_CONST(0x0404000400010101), ABC_CONST(0x0404000004010101), ABC_CONST(0x0404000000010101), ABC_CONST(0x0400040404010101), ABC_CONST(0x0400040400010101), ABC_CONST(0x0400040004010101), ABC_CONST(0x0400040000010101), ABC_CONST(0x0400000404010101), ABC_CONST(0x0400000400010101), ABC_CONST(0x0400000004010101), ABC_CONST(0x0400000000010101), ABC_CONST(0x0404040404010101), ABC_CONST(0x0404040400010101), ABC_CONST(0x0404040004010101), ABC_CONST(0x0404040000010101), ABC_CONST(0x0404000404010101), ABC_CONST(0x0404000400010101), ABC_CONST(0x0404000004010101), ABC_CONST(0x0404000000010101), ABC_CONST(0x0400040404010101), ABC_CONST(0x0400040400010101), ABC_CONST(0x0400040004010101), ABC_CONST(0x0400040000010101), ABC_CONST(0x0400000404010101), ABC_CONST(0x0400000400010101), ABC_CONST(0x0400000004010101), ABC_CONST(0x0400000000010101) }, + { ABC_CONST(0x0505050505020202), ABC_CONST(0x0505050500020202), ABC_CONST(0x0505050005020202), ABC_CONST(0x0505050000020202), ABC_CONST(0x0505000505020202), ABC_CONST(0x0505000500020202), ABC_CONST(0x0505000005020202), ABC_CONST(0x0505000000020202), ABC_CONST(0x0500050505020202), ABC_CONST(0x0500050500020202), ABC_CONST(0x0500050005020202), ABC_CONST(0x0500050000020202), ABC_CONST(0x0500000505020202), ABC_CONST(0x0500000500020202), ABC_CONST(0x0500000005020202), ABC_CONST(0x0500000000020202), ABC_CONST(0x0505050505020202), ABC_CONST(0x0505050500020202), ABC_CONST(0x0505050005020202), ABC_CONST(0x0505050000020202), ABC_CONST(0x0505000505020202), ABC_CONST(0x0505000500020202), ABC_CONST(0x0505000005020202), ABC_CONST(0x0505000000020202), ABC_CONST(0x0500050505020202), ABC_CONST(0x0500050500020202), ABC_CONST(0x0500050005020202), ABC_CONST(0x0500050000020202), ABC_CONST(0x0500000505020202), ABC_CONST(0x0500000500020202), ABC_CONST(0x0500000005020202), ABC_CONST(0x0500000000020202) }, + { ABC_CONST(0x0505050505020201), ABC_CONST(0x0505050500020201), ABC_CONST(0x0505050005020201), ABC_CONST(0x0505050000020201), ABC_CONST(0x0505000505020201), ABC_CONST(0x0505000500020201), ABC_CONST(0x0505000005020201), ABC_CONST(0x0505000000020201), ABC_CONST(0x0500050505020201), ABC_CONST(0x0500050500020201), ABC_CONST(0x0500050005020201), ABC_CONST(0x0500050000020201), ABC_CONST(0x0500000505020201), ABC_CONST(0x0500000500020201), ABC_CONST(0x0500000005020201), ABC_CONST(0x0500000000020201), ABC_CONST(0x0505050505020201), ABC_CONST(0x0505050500020201), ABC_CONST(0x0505050005020201), ABC_CONST(0x0505050000020201), ABC_CONST(0x0505000505020201), ABC_CONST(0x0505000500020201), ABC_CONST(0x0505000005020201), ABC_CONST(0x0505000000020201), ABC_CONST(0x0500050505020201), ABC_CONST(0x0500050500020201), ABC_CONST(0x0500050005020201), ABC_CONST(0x0500050000020201), ABC_CONST(0x0500000505020201), ABC_CONST(0x0500000500020201), ABC_CONST(0x0500000005020201), ABC_CONST(0x0500000000020201) }, + { ABC_CONST(0x0606060606030302), ABC_CONST(0x0606060600030302), ABC_CONST(0x0606060006030302), ABC_CONST(0x0606060000030302), ABC_CONST(0x0606000606030302), ABC_CONST(0x0606000600030302), ABC_CONST(0x0606000006030302), ABC_CONST(0x0606000000030302), ABC_CONST(0x0600060606030302), ABC_CONST(0x0600060600030302), ABC_CONST(0x0600060006030302), ABC_CONST(0x0600060000030302), ABC_CONST(0x0600000606030302), ABC_CONST(0x0600000600030302), ABC_CONST(0x0600000006030302), ABC_CONST(0x0600000000030302), ABC_CONST(0x0606060606030302), ABC_CONST(0x0606060600030302), ABC_CONST(0x0606060006030302), ABC_CONST(0x0606060000030302), ABC_CONST(0x0606000606030302), ABC_CONST(0x0606000600030302), ABC_CONST(0x0606000006030302), ABC_CONST(0x0606000000030302), ABC_CONST(0x0600060606030302), ABC_CONST(0x0600060600030302), ABC_CONST(0x0600060006030302), ABC_CONST(0x0600060000030302), ABC_CONST(0x0600000606030302), ABC_CONST(0x0600000600030302), ABC_CONST(0x0600000006030302), ABC_CONST(0x0600000000030302) }, + { ABC_CONST(0x0505050505020102), ABC_CONST(0x0505050500020102), ABC_CONST(0x0505050005020102), ABC_CONST(0x0505050000020102), ABC_CONST(0x0505000505020102), ABC_CONST(0x0505000500020102), ABC_CONST(0x0505000005020102), ABC_CONST(0x0505000000020102), ABC_CONST(0x0500050505020102), ABC_CONST(0x0500050500020102), ABC_CONST(0x0500050005020102), ABC_CONST(0x0500050000020102), ABC_CONST(0x0500000505020102), ABC_CONST(0x0500000500020102), ABC_CONST(0x0500000005020102), ABC_CONST(0x0500000000020102), ABC_CONST(0x0505050505020102), ABC_CONST(0x0505050500020102), ABC_CONST(0x0505050005020102), ABC_CONST(0x0505050000020102), ABC_CONST(0x0505000505020102), ABC_CONST(0x0505000500020102), ABC_CONST(0x0505000005020102), ABC_CONST(0x0505000000020102), ABC_CONST(0x0500050505020102), ABC_CONST(0x0500050500020102), ABC_CONST(0x0500050005020102), ABC_CONST(0x0500050000020102), ABC_CONST(0x0500000505020102), ABC_CONST(0x0500000500020102), ABC_CONST(0x0500000005020102), ABC_CONST(0x0500000000020102) }, + { ABC_CONST(0x0606060606030203), ABC_CONST(0x0606060600030203), ABC_CONST(0x0606060006030203), ABC_CONST(0x0606060000030203), ABC_CONST(0x0606000606030203), ABC_CONST(0x0606000600030203), ABC_CONST(0x0606000006030203), ABC_CONST(0x0606000000030203), ABC_CONST(0x0600060606030203), ABC_CONST(0x0600060600030203), ABC_CONST(0x0600060006030203), ABC_CONST(0x0600060000030203), ABC_CONST(0x0600000606030203), ABC_CONST(0x0600000600030203), ABC_CONST(0x0600000006030203), ABC_CONST(0x0600000000030203), ABC_CONST(0x0606060606030203), ABC_CONST(0x0606060600030203), ABC_CONST(0x0606060006030203), ABC_CONST(0x0606060000030203), ABC_CONST(0x0606000606030203), ABC_CONST(0x0606000600030203), ABC_CONST(0x0606000006030203), ABC_CONST(0x0606000000030203), ABC_CONST(0x0600060606030203), ABC_CONST(0x0600060600030203), ABC_CONST(0x0600060006030203), ABC_CONST(0x0600060000030203), ABC_CONST(0x0600000606030203), ABC_CONST(0x0600000600030203), ABC_CONST(0x0600000006030203), ABC_CONST(0x0600000000030203) }, + { ABC_CONST(0x0606060606030202), ABC_CONST(0x0606060600030202), ABC_CONST(0x0606060006030202), ABC_CONST(0x0606060000030202), ABC_CONST(0x0606000606030202), ABC_CONST(0x0606000600030202), ABC_CONST(0x0606000006030202), ABC_CONST(0x0606000000030202), ABC_CONST(0x0600060606030202), ABC_CONST(0x0600060600030202), ABC_CONST(0x0600060006030202), ABC_CONST(0x0600060000030202), ABC_CONST(0x0600000606030202), ABC_CONST(0x0600000600030202), ABC_CONST(0x0600000006030202), ABC_CONST(0x0600000000030202), ABC_CONST(0x0606060606030202), ABC_CONST(0x0606060600030202), ABC_CONST(0x0606060006030202), ABC_CONST(0x0606060000030202), ABC_CONST(0x0606000606030202), ABC_CONST(0x0606000600030202), ABC_CONST(0x0606000006030202), ABC_CONST(0x0606000000030202), ABC_CONST(0x0600060606030202), ABC_CONST(0x0600060600030202), ABC_CONST(0x0600060006030202), ABC_CONST(0x0600060000030202), ABC_CONST(0x0600000606030202), ABC_CONST(0x0600000600030202), ABC_CONST(0x0600000006030202), ABC_CONST(0x0600000000030202) }, + { ABC_CONST(0x0707070707040303), ABC_CONST(0x0707070700040303), ABC_CONST(0x0707070007040303), ABC_CONST(0x0707070000040303), ABC_CONST(0x0707000707040303), ABC_CONST(0x0707000700040303), ABC_CONST(0x0707000007040303), ABC_CONST(0x0707000000040303), ABC_CONST(0x0700070707040303), ABC_CONST(0x0700070700040303), ABC_CONST(0x0700070007040303), ABC_CONST(0x0700070000040303), ABC_CONST(0x0700000707040303), ABC_CONST(0x0700000700040303), ABC_CONST(0x0700000007040303), ABC_CONST(0x0700000000040303), ABC_CONST(0x0707070707040303), ABC_CONST(0x0707070700040303), ABC_CONST(0x0707070007040303), ABC_CONST(0x0707070000040303), ABC_CONST(0x0707000707040303), ABC_CONST(0x0707000700040303), ABC_CONST(0x0707000007040303), ABC_CONST(0x0707000000040303), ABC_CONST(0x0700070707040303), ABC_CONST(0x0700070700040303), ABC_CONST(0x0700070007040303), ABC_CONST(0x0700070000040303), ABC_CONST(0x0700000707040303), ABC_CONST(0x0700000700040303), ABC_CONST(0x0700000007040303), ABC_CONST(0x0700000000040303) }, + { ABC_CONST(0x0404040404000202), ABC_CONST(0x0404040400000202), ABC_CONST(0x0404040004000202), ABC_CONST(0x0404040000000202), ABC_CONST(0x0404000404000202), ABC_CONST(0x0404000400000202), ABC_CONST(0x0404000004000202), ABC_CONST(0x0404000000000202), ABC_CONST(0x0400040404000202), ABC_CONST(0x0400040400000202), ABC_CONST(0x0400040004000202), ABC_CONST(0x0400040000000202), ABC_CONST(0x0400000404000202), ABC_CONST(0x0400000400000202), ABC_CONST(0x0400000004000202), ABC_CONST(0x0400000000000202), ABC_CONST(0x0404040404000202), ABC_CONST(0x0404040400000202), ABC_CONST(0x0404040004000202), ABC_CONST(0x0404040000000202), ABC_CONST(0x0404000404000202), ABC_CONST(0x0404000400000202), ABC_CONST(0x0404000004000202), ABC_CONST(0x0404000000000202), ABC_CONST(0x0400040404000202), ABC_CONST(0x0400040400000202), ABC_CONST(0x0400040004000202), ABC_CONST(0x0400040000000202), ABC_CONST(0x0400000404000202), ABC_CONST(0x0400000400000202), ABC_CONST(0x0400000004000202), ABC_CONST(0x0400000000000202) }, + { ABC_CONST(0x0505050505010303), ABC_CONST(0x0505050500010303), ABC_CONST(0x0505050005010303), ABC_CONST(0x0505050000010303), ABC_CONST(0x0505000505010303), ABC_CONST(0x0505000500010303), ABC_CONST(0x0505000005010303), ABC_CONST(0x0505000000010303), ABC_CONST(0x0500050505010303), ABC_CONST(0x0500050500010303), ABC_CONST(0x0500050005010303), ABC_CONST(0x0500050000010303), ABC_CONST(0x0500000505010303), ABC_CONST(0x0500000500010303), ABC_CONST(0x0500000005010303), ABC_CONST(0x0500000000010303), ABC_CONST(0x0505050505010303), ABC_CONST(0x0505050500010303), ABC_CONST(0x0505050005010303), ABC_CONST(0x0505050000010303), ABC_CONST(0x0505000505010303), ABC_CONST(0x0505000500010303), ABC_CONST(0x0505000005010303), ABC_CONST(0x0505000000010303), ABC_CONST(0x0500050505010303), ABC_CONST(0x0500050500010303), ABC_CONST(0x0500050005010303), ABC_CONST(0x0500050000010303), ABC_CONST(0x0500000505010303), ABC_CONST(0x0500000500010303), ABC_CONST(0x0500000005010303), ABC_CONST(0x0500000000010303) }, + { ABC_CONST(0x0505050505010302), ABC_CONST(0x0505050500010302), ABC_CONST(0x0505050005010302), ABC_CONST(0x0505050000010302), ABC_CONST(0x0505000505010302), ABC_CONST(0x0505000500010302), ABC_CONST(0x0505000005010302), ABC_CONST(0x0505000000010302), ABC_CONST(0x0500050505010302), ABC_CONST(0x0500050500010302), ABC_CONST(0x0500050005010302), ABC_CONST(0x0500050000010302), ABC_CONST(0x0500000505010302), ABC_CONST(0x0500000500010302), ABC_CONST(0x0500000005010302), ABC_CONST(0x0500000000010302), ABC_CONST(0x0505050505010302), ABC_CONST(0x0505050500010302), ABC_CONST(0x0505050005010302), ABC_CONST(0x0505050000010302), ABC_CONST(0x0505000505010302), ABC_CONST(0x0505000500010302), ABC_CONST(0x0505000005010302), ABC_CONST(0x0505000000010302), ABC_CONST(0x0500050505010302), ABC_CONST(0x0500050500010302), ABC_CONST(0x0500050005010302), ABC_CONST(0x0500050000010302), ABC_CONST(0x0500000505010302), ABC_CONST(0x0500000500010302), ABC_CONST(0x0500000005010302), ABC_CONST(0x0500000000010302) }, + { ABC_CONST(0x0606060606020403), ABC_CONST(0x0606060600020403), ABC_CONST(0x0606060006020403), ABC_CONST(0x0606060000020403), ABC_CONST(0x0606000606020403), ABC_CONST(0x0606000600020403), ABC_CONST(0x0606000006020403), ABC_CONST(0x0606000000020403), ABC_CONST(0x0600060606020403), ABC_CONST(0x0600060600020403), ABC_CONST(0x0600060006020403), ABC_CONST(0x0600060000020403), ABC_CONST(0x0600000606020403), ABC_CONST(0x0600000600020403), ABC_CONST(0x0600000006020403), ABC_CONST(0x0600000000020403), ABC_CONST(0x0606060606020403), ABC_CONST(0x0606060600020403), ABC_CONST(0x0606060006020403), ABC_CONST(0x0606060000020403), ABC_CONST(0x0606000606020403), ABC_CONST(0x0606000600020403), ABC_CONST(0x0606000006020403), ABC_CONST(0x0606000000020403), ABC_CONST(0x0600060606020403), ABC_CONST(0x0600060600020403), ABC_CONST(0x0600060006020403), ABC_CONST(0x0600060000020403), ABC_CONST(0x0600000606020403), ABC_CONST(0x0600000600020403), ABC_CONST(0x0600000006020403), ABC_CONST(0x0600000000020403) }, + { ABC_CONST(0x0505050505010203), ABC_CONST(0x0505050500010203), ABC_CONST(0x0505050005010203), ABC_CONST(0x0505050000010203), ABC_CONST(0x0505000505010203), ABC_CONST(0x0505000500010203), ABC_CONST(0x0505000005010203), ABC_CONST(0x0505000000010203), ABC_CONST(0x0500050505010203), ABC_CONST(0x0500050500010203), ABC_CONST(0x0500050005010203), ABC_CONST(0x0500050000010203), ABC_CONST(0x0500000505010203), ABC_CONST(0x0500000500010203), ABC_CONST(0x0500000005010203), ABC_CONST(0x0500000000010203), ABC_CONST(0x0505050505010203), ABC_CONST(0x0505050500010203), ABC_CONST(0x0505050005010203), ABC_CONST(0x0505050000010203), ABC_CONST(0x0505000505010203), ABC_CONST(0x0505000500010203), ABC_CONST(0x0505000005010203), ABC_CONST(0x0505000000010203), ABC_CONST(0x0500050505010203), ABC_CONST(0x0500050500010203), ABC_CONST(0x0500050005010203), ABC_CONST(0x0500050000010203), ABC_CONST(0x0500000505010203), ABC_CONST(0x0500000500010203), ABC_CONST(0x0500000005010203), ABC_CONST(0x0500000000010203) }, + { ABC_CONST(0x0606060606020304), ABC_CONST(0x0606060600020304), ABC_CONST(0x0606060006020304), ABC_CONST(0x0606060000020304), ABC_CONST(0x0606000606020304), ABC_CONST(0x0606000600020304), ABC_CONST(0x0606000006020304), ABC_CONST(0x0606000000020304), ABC_CONST(0x0600060606020304), ABC_CONST(0x0600060600020304), ABC_CONST(0x0600060006020304), ABC_CONST(0x0600060000020304), ABC_CONST(0x0600000606020304), ABC_CONST(0x0600000600020304), ABC_CONST(0x0600000006020304), ABC_CONST(0x0600000000020304), ABC_CONST(0x0606060606020304), ABC_CONST(0x0606060600020304), ABC_CONST(0x0606060006020304), ABC_CONST(0x0606060000020304), ABC_CONST(0x0606000606020304), ABC_CONST(0x0606000600020304), ABC_CONST(0x0606000006020304), ABC_CONST(0x0606000000020304), ABC_CONST(0x0600060606020304), ABC_CONST(0x0600060600020304), ABC_CONST(0x0600060006020304), ABC_CONST(0x0600060000020304), ABC_CONST(0x0600000606020304), ABC_CONST(0x0600000600020304), ABC_CONST(0x0600000006020304), ABC_CONST(0x0600000000020304) }, + { ABC_CONST(0x0606060606020303), ABC_CONST(0x0606060600020303), ABC_CONST(0x0606060006020303), ABC_CONST(0x0606060000020303), ABC_CONST(0x0606000606020303), ABC_CONST(0x0606000600020303), ABC_CONST(0x0606000006020303), ABC_CONST(0x0606000000020303), ABC_CONST(0x0600060606020303), ABC_CONST(0x0600060600020303), ABC_CONST(0x0600060006020303), ABC_CONST(0x0600060000020303), ABC_CONST(0x0600000606020303), ABC_CONST(0x0600000600020303), ABC_CONST(0x0600000006020303), ABC_CONST(0x0600000000020303), ABC_CONST(0x0606060606020303), ABC_CONST(0x0606060600020303), ABC_CONST(0x0606060006020303), ABC_CONST(0x0606060000020303), ABC_CONST(0x0606000606020303), ABC_CONST(0x0606000600020303), ABC_CONST(0x0606000006020303), ABC_CONST(0x0606000000020303), ABC_CONST(0x0600060606020303), ABC_CONST(0x0600060600020303), ABC_CONST(0x0600060006020303), ABC_CONST(0x0600060000020303), ABC_CONST(0x0600000606020303), ABC_CONST(0x0600000600020303), ABC_CONST(0x0600000006020303), ABC_CONST(0x0600000000020303) }, + { ABC_CONST(0x0707070707030404), ABC_CONST(0x0707070700030404), ABC_CONST(0x0707070007030404), ABC_CONST(0x0707070000030404), ABC_CONST(0x0707000707030404), ABC_CONST(0x0707000700030404), ABC_CONST(0x0707000007030404), ABC_CONST(0x0707000000030404), ABC_CONST(0x0700070707030404), ABC_CONST(0x0700070700030404), ABC_CONST(0x0700070007030404), ABC_CONST(0x0700070000030404), ABC_CONST(0x0700000707030404), ABC_CONST(0x0700000700030404), ABC_CONST(0x0700000007030404), ABC_CONST(0x0700000000030404), ABC_CONST(0x0707070707030404), ABC_CONST(0x0707070700030404), ABC_CONST(0x0707070007030404), ABC_CONST(0x0707070000030404), ABC_CONST(0x0707000707030404), ABC_CONST(0x0707000700030404), ABC_CONST(0x0707000007030404), ABC_CONST(0x0707000000030404), ABC_CONST(0x0700070707030404), ABC_CONST(0x0700070700030404), ABC_CONST(0x0700070007030404), ABC_CONST(0x0700070000030404), ABC_CONST(0x0700000707030404), ABC_CONST(0x0700000700030404), ABC_CONST(0x0700000007030404), ABC_CONST(0x0700000000030404) }, + { ABC_CONST(0x0505050505010202), ABC_CONST(0x0505050500010202), ABC_CONST(0x0505050005010202), ABC_CONST(0x0505050000010202), ABC_CONST(0x0505000505010202), ABC_CONST(0x0505000500010202), ABC_CONST(0x0505000005010202), ABC_CONST(0x0505000000010202), ABC_CONST(0x0500050505010202), ABC_CONST(0x0500050500010202), ABC_CONST(0x0500050005010202), ABC_CONST(0x0500050000010202), ABC_CONST(0x0500000505010202), ABC_CONST(0x0500000500010202), ABC_CONST(0x0500000005010202), ABC_CONST(0x0500000000010202), ABC_CONST(0x0505050505010202), ABC_CONST(0x0505050500010202), ABC_CONST(0x0505050005010202), ABC_CONST(0x0505050000010202), ABC_CONST(0x0505000505010202), ABC_CONST(0x0505000500010202), ABC_CONST(0x0505000005010202), ABC_CONST(0x0505000000010202), ABC_CONST(0x0500050505010202), ABC_CONST(0x0500050500010202), ABC_CONST(0x0500050005010202), ABC_CONST(0x0500050000010202), ABC_CONST(0x0500000505010202), ABC_CONST(0x0500000500010202), ABC_CONST(0x0500000005010202), ABC_CONST(0x0500000000010202) }, + { ABC_CONST(0x0606060606020303), ABC_CONST(0x0606060600020303), ABC_CONST(0x0606060006020303), ABC_CONST(0x0606060000020303), ABC_CONST(0x0606000606020303), ABC_CONST(0x0606000600020303), ABC_CONST(0x0606000006020303), ABC_CONST(0x0606000000020303), ABC_CONST(0x0600060606020303), ABC_CONST(0x0600060600020303), ABC_CONST(0x0600060006020303), ABC_CONST(0x0600060000020303), ABC_CONST(0x0600000606020303), ABC_CONST(0x0600000600020303), ABC_CONST(0x0600000006020303), ABC_CONST(0x0600000000020303), ABC_CONST(0x0606060606020303), ABC_CONST(0x0606060600020303), ABC_CONST(0x0606060006020303), ABC_CONST(0x0606060000020303), ABC_CONST(0x0606000606020303), ABC_CONST(0x0606000600020303), ABC_CONST(0x0606000006020303), ABC_CONST(0x0606000000020303), ABC_CONST(0x0600060606020303), ABC_CONST(0x0600060600020303), ABC_CONST(0x0600060006020303), ABC_CONST(0x0600060000020303), ABC_CONST(0x0600000606020303), ABC_CONST(0x0600000600020303), ABC_CONST(0x0600000006020303), ABC_CONST(0x0600000000020303) }, + { ABC_CONST(0x0606060606020302), ABC_CONST(0x0606060600020302), ABC_CONST(0x0606060006020302), ABC_CONST(0x0606060000020302), ABC_CONST(0x0606000606020302), ABC_CONST(0x0606000600020302), ABC_CONST(0x0606000006020302), ABC_CONST(0x0606000000020302), ABC_CONST(0x0600060606020302), ABC_CONST(0x0600060600020302), ABC_CONST(0x0600060006020302), ABC_CONST(0x0600060000020302), ABC_CONST(0x0600000606020302), ABC_CONST(0x0600000600020302), ABC_CONST(0x0600000006020302), ABC_CONST(0x0600000000020302), ABC_CONST(0x0606060606020302), ABC_CONST(0x0606060600020302), ABC_CONST(0x0606060006020302), ABC_CONST(0x0606060000020302), ABC_CONST(0x0606000606020302), ABC_CONST(0x0606000600020302), ABC_CONST(0x0606000006020302), ABC_CONST(0x0606000000020302), ABC_CONST(0x0600060606020302), ABC_CONST(0x0600060600020302), ABC_CONST(0x0600060006020302), ABC_CONST(0x0600060000020302), ABC_CONST(0x0600000606020302), ABC_CONST(0x0600000600020302), ABC_CONST(0x0600000006020302), ABC_CONST(0x0600000000020302) }, + { ABC_CONST(0x0707070707030403), ABC_CONST(0x0707070700030403), ABC_CONST(0x0707070007030403), ABC_CONST(0x0707070000030403), ABC_CONST(0x0707000707030403), ABC_CONST(0x0707000700030403), ABC_CONST(0x0707000007030403), ABC_CONST(0x0707000000030403), ABC_CONST(0x0700070707030403), ABC_CONST(0x0700070700030403), ABC_CONST(0x0700070007030403), ABC_CONST(0x0700070000030403), ABC_CONST(0x0700000707030403), ABC_CONST(0x0700000700030403), ABC_CONST(0x0700000007030403), ABC_CONST(0x0700000000030403), ABC_CONST(0x0707070707030403), ABC_CONST(0x0707070700030403), ABC_CONST(0x0707070007030403), ABC_CONST(0x0707070000030403), ABC_CONST(0x0707000707030403), ABC_CONST(0x0707000700030403), ABC_CONST(0x0707000007030403), ABC_CONST(0x0707000000030403), ABC_CONST(0x0700070707030403), ABC_CONST(0x0700070700030403), ABC_CONST(0x0700070007030403), ABC_CONST(0x0700070000030403), ABC_CONST(0x0700000707030403), ABC_CONST(0x0700000700030403), ABC_CONST(0x0700000007030403), ABC_CONST(0x0700000000030403) }, + { ABC_CONST(0x0606060606020203), ABC_CONST(0x0606060600020203), ABC_CONST(0x0606060006020203), ABC_CONST(0x0606060000020203), ABC_CONST(0x0606000606020203), ABC_CONST(0x0606000600020203), ABC_CONST(0x0606000006020203), ABC_CONST(0x0606000000020203), ABC_CONST(0x0600060606020203), ABC_CONST(0x0600060600020203), ABC_CONST(0x0600060006020203), ABC_CONST(0x0600060000020203), ABC_CONST(0x0600000606020203), ABC_CONST(0x0600000600020203), ABC_CONST(0x0600000006020203), ABC_CONST(0x0600000000020203), ABC_CONST(0x0606060606020203), ABC_CONST(0x0606060600020203), ABC_CONST(0x0606060006020203), ABC_CONST(0x0606060000020203), ABC_CONST(0x0606000606020203), ABC_CONST(0x0606000600020203), ABC_CONST(0x0606000006020203), ABC_CONST(0x0606000000020203), ABC_CONST(0x0600060606020203), ABC_CONST(0x0600060600020203), ABC_CONST(0x0600060006020203), ABC_CONST(0x0600060000020203), ABC_CONST(0x0600000606020203), ABC_CONST(0x0600000600020203), ABC_CONST(0x0600000006020203), ABC_CONST(0x0600000000020203) }, + { ABC_CONST(0x0707070707030304), ABC_CONST(0x0707070700030304), ABC_CONST(0x0707070007030304), ABC_CONST(0x0707070000030304), ABC_CONST(0x0707000707030304), ABC_CONST(0x0707000700030304), ABC_CONST(0x0707000007030304), ABC_CONST(0x0707000000030304), ABC_CONST(0x0700070707030304), ABC_CONST(0x0700070700030304), ABC_CONST(0x0700070007030304), ABC_CONST(0x0700070000030304), ABC_CONST(0x0700000707030304), ABC_CONST(0x0700000700030304), ABC_CONST(0x0700000007030304), ABC_CONST(0x0700000000030304), ABC_CONST(0x0707070707030304), ABC_CONST(0x0707070700030304), ABC_CONST(0x0707070007030304), ABC_CONST(0x0707070000030304), ABC_CONST(0x0707000707030304), ABC_CONST(0x0707000700030304), ABC_CONST(0x0707000007030304), ABC_CONST(0x0707000000030304), ABC_CONST(0x0700070707030304), ABC_CONST(0x0700070700030304), ABC_CONST(0x0700070007030304), ABC_CONST(0x0700070000030304), ABC_CONST(0x0700000707030304), ABC_CONST(0x0700000700030304), ABC_CONST(0x0700000007030304), ABC_CONST(0x0700000000030304) }, + { ABC_CONST(0x0707070707030303), ABC_CONST(0x0707070700030303), ABC_CONST(0x0707070007030303), ABC_CONST(0x0707070000030303), ABC_CONST(0x0707000707030303), ABC_CONST(0x0707000700030303), ABC_CONST(0x0707000007030303), ABC_CONST(0x0707000000030303), ABC_CONST(0x0700070707030303), ABC_CONST(0x0700070700030303), ABC_CONST(0x0700070007030303), ABC_CONST(0x0700070000030303), ABC_CONST(0x0700000707030303), ABC_CONST(0x0700000700030303), ABC_CONST(0x0700000007030303), ABC_CONST(0x0700000000030303), ABC_CONST(0x0707070707030303), ABC_CONST(0x0707070700030303), ABC_CONST(0x0707070007030303), ABC_CONST(0x0707070000030303), ABC_CONST(0x0707000707030303), ABC_CONST(0x0707000700030303), ABC_CONST(0x0707000007030303), ABC_CONST(0x0707000000030303), ABC_CONST(0x0700070707030303), ABC_CONST(0x0700070700030303), ABC_CONST(0x0700070007030303), ABC_CONST(0x0700070000030303), ABC_CONST(0x0700000707030303), ABC_CONST(0x0700000700030303), ABC_CONST(0x0700000007030303), ABC_CONST(0x0700000000030303) }, + { ABC_CONST(0x0808080808040404), ABC_CONST(0x0808080800040404), ABC_CONST(0x0808080008040404), ABC_CONST(0x0808080000040404), ABC_CONST(0x0808000808040404), ABC_CONST(0x0808000800040404), ABC_CONST(0x0808000008040404), ABC_CONST(0x0808000000040404), ABC_CONST(0x0800080808040404), ABC_CONST(0x0800080800040404), ABC_CONST(0x0800080008040404), ABC_CONST(0x0800080000040404), ABC_CONST(0x0800000808040404), ABC_CONST(0x0800000800040404), ABC_CONST(0x0800000008040404), ABC_CONST(0x0800000000040404), ABC_CONST(0x0808080808040404), ABC_CONST(0x0808080800040404), ABC_CONST(0x0808080008040404), ABC_CONST(0x0808080000040404), ABC_CONST(0x0808000808040404), ABC_CONST(0x0808000800040404), ABC_CONST(0x0808000008040404), ABC_CONST(0x0808000000040404), ABC_CONST(0x0800080808040404), ABC_CONST(0x0800080800040404), ABC_CONST(0x0800080008040404), ABC_CONST(0x0800080000040404), ABC_CONST(0x0800000808040404), ABC_CONST(0x0800000800040404), ABC_CONST(0x0800000008040404), ABC_CONST(0x0800000000040404) } +}; + + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_TtCountGenerate() +{ + static word s_CMasks6[3] = { + ABC_CONST(0x5555555555555555), + ABC_CONST(0x3333333333333333), + ABC_CONST(0x0F0F0F0F0F0F0F0F) + }; + static int bit_count[256] = { + 0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4,1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5, + 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6, + 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6, + 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, + 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6, + 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, + 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, + 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8 + }; + int i, k, c; + printf("{ "); + for ( i = 0; i < 256; i++, printf(" },\n{ ") ) + for ( k = 0; k < 32; k++ ) + { + printf( "ABC_CONST(0x0%d", bit_count[i] ); + for ( c = 3; c >= 0; c-- ) + printf( "0%d", (((k >> c) & 1) == 0) * bit_count[i] ); + for ( c = 2; c >= 0; c-- ) + printf( "0%d", bit_count[s_CMasks6[c] & i] ); + printf( ")%s", k == 31 ? "":", " ); + } +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_TtCountOnesInCofsQuick_rec( word * pTruth, int nVars, int * pStore ) +{ + if ( nVars <= 8 ) + { + word Res = 0; + unsigned char * pResC = (unsigned char *)&Res; + unsigned char * pTruthC = (unsigned char *)pTruth; + int i, nBytes = nVars <= 6 ? 4 : 1 << (nVars-4), nBytes2 = nBytes << 1; + assert( nVars >= 1 && nVars <= 8 ); + for ( i = 0; i < nBytes; i++ ) + Res += Table[pTruthC[i]][i]; + if ( nVars == 8 ) + pStore[7] += pResC[7]; + for ( ; i < nBytes2; i++ ) + Res += Table[pTruthC[i]][i]; + for ( i = 0; i < nVars-1; i++ ) + pStore[i] += pResC[i]; + if ( nVars < 8 ) + pStore[nVars-1] += pResC[nVars-1]; + return (int)pResC[7]; + } + else + { + int Res1 = Abc_TtCountOnesInCofsQuick_rec( pTruth, nVars-1, pStore ); + int Res2 = Abc_TtCountOnesInCofsQuick_rec( pTruth + (1 << (nVars-7)), nVars-1, pStore ); + pStore[nVars-1] = Res1; + return Res1 + Res2; + } +} +int Abc_TtCountOnesInCofsQuick( word * pTruth, int nVars, int * pStore ) +{ + if ( nVars == 0 ) + return (int)(pTruth[0] & 1); + memset( pStore, 0, sizeof(int)*nVars ); + return Abc_TtCountOnesInCofsQuick_rec( pTruth, nVars, pStore ); +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_TtCountOnesInCofsTest2() +{ + word Truth = ABC_CONST(0x5555555555555555) & ABC_CONST(0x3333333333333333); + + int Store1[8] = {0}, Store2[8] = {0}; + int i, Res1, Res2; + + Res1 = Abc_TtCountOnesInCofsSimple( &Truth, 2, Store1 ); + Res2 = Abc_TtCountOnesInCofsQuick( &Truth, 2, Store2 ); + assert( Res1 == Res2 ); + for ( i = 0; i < 8; i++ ) + assert( Store1[i] == Store2[i] ); + +} +void Abc_TtCountOnesInCofsTest() +{ + word Truth[4] = {0}; + int Store1[8] = {0}, Store2[8] = {0}; + int n, i, k, Res1, Res2; + srand( time(NULL) ); + for ( n = 0; n < 1000000; n++ ) + { + for ( i = 0; i < 4; i++ ) + for ( k = 0; k < 8; k++ ) + Truth[i] ^= (word)(rand() & 0xFF) << (k << 3); + Res1 = Abc_TtCountOnesInCofsSimple( Truth, 8, Store1 ); + Res2 = Abc_TtCountOnesInCofsQuick( Truth, 8, Store2 ); + assert( Res1 == Res2 ); + for ( i = 0; i < 8; i++ ) + assert( Store1[i] == Store2[i] ); + } +} + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/opt/dau/dauGia.c b/src/opt/dau/dauGia.c index 424ec53f..eebfa9a8 100644 --- a/src/opt/dau/dauGia.c +++ b/src/opt/dau/dauGia.c @@ -449,6 +449,10 @@ int Dsm_ManTruthToGia( void * p, word * pTruth, Vec_Int_t * vLeaves, Vec_Int_t * Abc_TtCopy( pTruthCopy, pTruth, Abc_TtWordNum(Vec_IntSize(vLeaves)), 0 ); m_Calls++; assert( Vec_IntSize(vLeaves) <= DAU_DSD_MAX_VAR ); + if ( Vec_IntSize(vLeaves) == 0 ) + return (int)(pTruth[0] & 1); + if ( Vec_IntSize(vLeaves) == 1 ) + return Abc_LitNotCond( Vec_IntEntry(vLeaves, 0), (int)(pTruth[0] & 1) ); // collect delay information if ( fDelayBalance && fUseMuxes ) { diff --git a/src/opt/dau/dauNpn.c b/src/opt/dau/dauNpn.c new file mode 100644 index 00000000..b57ade67 --- /dev/null +++ b/src/opt/dau/dauNpn.c @@ -0,0 +1,816 @@ +/**CFile**************************************************************** + + FileName [dau.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [DAG-aware unmapping.] + + Synopsis [] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: dau.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "dauInt.h" +#include "misc/util/utilTruth.h" +#include "misc/extra/extra.h" +#include "bool/lucky/lucky.h" + +ABC_NAMESPACE_IMPL_START + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//#define USE4VARS 1 + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Dau_TruthEnum() +{ + int fUseTable = 1; + abctime clk = Abc_Clock(); +#ifdef USE4VARS + int nVars = 4; + int nSizeW = 1 << 14; + char * pFileName = "tableW14.data"; +#else + int nVars = 5; + int nSizeW = 1 << 30; + char * pFileName = "tableW30.data"; +#endif + int nPerms = Extra_Factorial( nVars ); + int nMints = 1 << nVars; + int * pPerm = Extra_PermSchedule( nVars ); + int * pComp = Extra_GreyCodeSchedule( nVars ); + word nFuncs = ((word)1 << (((word)1 << nVars)-1)); + word * pPres = ABC_CALLOC( word, 1 << ((1<<nVars)-7) ); + unsigned * pTable = fUseTable ? (unsigned *)ABC_CALLOC(word, nSizeW) : NULL; + Vec_Int_t * vNpns = Vec_IntAlloc( 1000 ); + word tMask = Abc_Tt6Mask( 1 << nVars ); + word tTemp, tCur; + int i, k; + if ( pPres == NULL ) + { + printf( "Cannot alloc memory for marks.\n" ); + return; + } + if ( pTable == NULL ) + printf( "Cannot alloc memory for table.\n" ); + for ( tCur = 0; tCur < nFuncs; tCur++ ) + { + if ( (tCur & 0x3FFFF) == 0 ) + { + printf( "Finished %08x. Classes = %6d. ", (int)tCur, Vec_IntSize(vNpns) ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); + fflush(stdout); + } + if ( Abc_TtGetBit(pPres, (int)tCur) ) + continue; + //Extra_PrintBinary( stdout, (unsigned *)&tCur, 16 ); printf( " %04x\n", (int)tCur ); + //Dau_DsdPrintFromTruth( &tCur, 4 ); printf( "\n" ); + Vec_IntPush( vNpns, (int)tCur ); + tTemp = tCur; + for ( i = 0; i < nPerms; i++ ) + { + for ( k = 0; k < nMints; k++ ) + { + if ( tCur < nFuncs ) + { + if ( pTable ) pTable[(int)tCur] = tTemp; + Abc_TtSetBit( pPres, (int)tCur ); + } + if ( (tMask & ~tCur) < nFuncs ) + { + if ( pTable ) pTable[(int)(tMask & ~tCur)] = tTemp; + Abc_TtSetBit( pPres, (int)(tMask & ~tCur) ); + } + tCur = Abc_Tt6Flip( tCur, pComp[k] ); + } + tCur = Abc_Tt6SwapAdjacent( tCur, pPerm[i] ); + } + assert( tTemp == tCur ); + } + printf( "Computed %d NPN classes of %d variables. ", Vec_IntSize(vNpns), nVars ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); + fflush(stdout); + Vec_IntFree( vNpns ); + ABC_FREE( pPres ); + ABC_FREE( pPerm ); + ABC_FREE( pComp ); + // write into file + if ( pTable ) + { + FILE * pFile = fopen( pFileName, "wb" ); + int RetValue = fwrite( pTable, 8, nSizeW, pFile ); + RetValue = 0; + fclose( pFile ); + ABC_FREE( pTable ); + } +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +unsigned * Dau_ReadFile( char * pFileName, int nSizeW ) +{ + abctime clk = Abc_Clock(); + FILE * pFile = fopen( pFileName, "rb" ); + unsigned * p = (unsigned *)ABC_CALLOC(word, nSizeW); + int RetValue = pFile ? fread( p, sizeof(word), nSizeW, pFile ) : 0; + RetValue = 0; + if ( pFile ) + { + printf( "Finished reading file \"%s\".\n", pFileName ); + fclose( pFile ); + } + else + printf( "Cannot open input file \"%s\".\n", pFileName ); + Abc_PrintTime( 1, "File reading", Abc_Clock() - clk ); + return p; +} +int Dau_AddFunction( word tCur, int nVars, unsigned * pTable, Vec_Int_t * vNpns, Vec_Int_t * vNpns_ ) +{ + int Digit = (1 << nVars)-1; + word tMask = Abc_Tt6Mask( 1 << nVars ); + word tNorm = (tCur >> Digit) & 1 ? ~tCur : tCur; + unsigned t = (unsigned)(tNorm & tMask); + unsigned tRep = pTable[t] & 0x7FFFFFFF; + unsigned tRep2 = pTable[tRep]; + assert( ((tNorm >> Digit) & 1) == 0 ); + if ( (tRep2 >> 31) == 0 ) // first time + { + Vec_IntPush( vNpns, tRep2 ); + if ( Abc_TtSupportSize(&tCur, nVars) < nVars ) + Vec_IntPush( vNpns_, tRep2 ); + pTable[tRep] = tRep2 | (1 << 31); + return tRep2; + } + return 0; +} +void Dau_NetworkEnum() +{ + abctime clk = Abc_Clock(); + int Limit = 2; + int UseTwo = 0; +#ifdef USE4VARS + int nVars = 4; + int nSizeW = 1 << 14; + char * pFileName = "tableW14.data"; +#else + int nVars = 5; + int nSizeW = 1 << 30; + char * pFileName = "tableW30.data"; +#endif + unsigned * pTable = Dau_ReadFile( pFileName, nSizeW ); + Vec_Wec_t * vNpns = Vec_WecStart( 32 ); + Vec_Wec_t * vNpns_ = Vec_WecStart( 32 ); + int i, v, u, g, k, m, n, Res, Entry; + unsigned Inv = (unsigned)Abc_Tt6Mask(1 << (nVars-1)); + // create constant function and buffer/inverter function + pTable[0] |= (1 << 31); + pTable[Inv] |= (1 << 31); + Vec_IntPushTwo( Vec_WecEntry(vNpns, 0), 0, Inv ); + Vec_IntPushTwo( Vec_WecEntry(vNpns_, 0), 0, Inv ); + printf("Nodes = %2d. New = %6d. Total = %6d. New = %6d. Total = %6d. ", + 0, Vec_IntSize(Vec_WecEntry(vNpns, 0)), Vec_WecSizeSize(vNpns), + Vec_IntSize(Vec_WecEntry(vNpns_, 0)), Vec_WecSizeSize(vNpns_) ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); + // numerate other functions based on how many nodes they have + for ( n = 1; n < 32; n++ ) + { + Vec_Int_t * vFuncsN2 = n > 1 ? Vec_WecEntry( vNpns, n-2 ) : NULL; + Vec_Int_t * vFuncsN1 = Vec_WecEntry( vNpns, n-1 ); + Vec_Int_t * vFuncsN = Vec_WecEntry( vNpns, n ); + Vec_Int_t * vFuncsN_ = Vec_WecEntry( vNpns_,n ); + Vec_IntForEachEntry( vFuncsN1, Entry, i ) + { + word uTruth = (((word)Entry) << 32) | (word)Entry; + int nSupp = Abc_TtSupportSize( &uTruth, nVars ); + assert( nSupp == 6 || !Abc_Tt6HasVar(uTruth, nVars-1-nSupp) ); + //printf( "Exploring function %4d with %d vars: ", i, nSupp ); + //printf( " %04x\n", (int)uTruth ); + //Dau_DsdPrintFromTruth( &uTruth, 4 ); + for ( v = 0; v < nSupp; v++ ) + { + word tGate, tCur; + word Cof0 = Abc_Tt6Cofactor0( uTruth, nVars-1-v ); + word Cof1 = Abc_Tt6Cofactor1( uTruth, nVars-1-v ); + for ( g = 0; g < Limit; g++ ) + { + if ( nSupp < nVars ) + { + if ( g == 0 ) + { + tGate = s_Truths6[nVars-1-v] & s_Truths6[nVars-1-nSupp]; + tCur = (tGate & Cof1) | (~tGate & Cof0); + Dau_AddFunction( tCur, nVars, pTable, vFuncsN, vFuncsN_ ); + + tCur = (tGate & Cof0) | (~tGate & Cof1); + Dau_AddFunction( tCur, nVars, pTable, vFuncsN, vFuncsN_ ); + } + else + { + tGate = s_Truths6[nVars-1-v] ^ s_Truths6[nVars-1-nSupp]; + tCur = (tGate & Cof1) | (~tGate & Cof0); + Dau_AddFunction( tCur, nVars, pTable, vFuncsN, vFuncsN_ ); + } + } + } + for ( g = 0; g < Limit; g++ ) + { + // add one cross bar + for ( k = 0; k < nSupp; k++ ) if ( k != v ) + { + if ( g == 0 ) + { + tGate = s_Truths6[nVars-1-v] & s_Truths6[nVars-1-k]; + tCur = (tGate & Cof1) | (~tGate & Cof0); + Dau_AddFunction( tCur, nVars, pTable, vFuncsN, vFuncsN_ ); + + tCur = (tGate & Cof0) | (~tGate & Cof1); + Dau_AddFunction( tCur, nVars, pTable, vFuncsN, vFuncsN_ ); + + tGate = s_Truths6[nVars-1-v] & ~s_Truths6[nVars-1-k]; + tCur = (tGate & Cof1) | (~tGate & Cof0); + Dau_AddFunction( tCur, nVars, pTable, vFuncsN, vFuncsN_ ); + + tCur = (tGate & Cof0) | (~tGate & Cof1); + Dau_AddFunction( tCur, nVars, pTable, vFuncsN, vFuncsN_ ); + } + else + { + tGate = s_Truths6[nVars-1-v] ^ s_Truths6[nVars-1-k]; + tCur = (tGate & Cof1) | (~tGate & Cof0); + Dau_AddFunction( tCur, nVars, pTable, vFuncsN, vFuncsN_ ); + } + } + } + for ( g = 0; g < Limit; g++ ) + { + // add two cross bars + for ( k = 0; k < nSupp; k++ ) if ( k != v ) + for ( m = k+1; m < nSupp; m++ ) if ( m != v ) + { + if ( g == 0 ) + { + tGate = s_Truths6[nVars-1-m] & s_Truths6[nVars-1-k]; + tCur = (tGate & Cof1) | (~tGate & Cof0); + Dau_AddFunction( tCur, nVars, pTable, vFuncsN, vFuncsN_ ); + + tCur = (tGate & Cof0) | (~tGate & Cof1); + Dau_AddFunction( tCur, nVars, pTable, vFuncsN, vFuncsN_ ); + + tGate = s_Truths6[nVars-1-m] & ~s_Truths6[nVars-1-k]; + tCur = (tGate & Cof1) | (~tGate & Cof0); + Dau_AddFunction( tCur, nVars, pTable, vFuncsN, vFuncsN_ ); + + tCur = (tGate & Cof0) | (~tGate & Cof1); + Dau_AddFunction( tCur, nVars, pTable, vFuncsN, vFuncsN_ ); + + tGate = ~s_Truths6[nVars-1-m] & s_Truths6[nVars-1-k]; + tCur = (tGate & Cof1) | (~tGate & Cof0); + Dau_AddFunction( tCur, nVars, pTable, vFuncsN, vFuncsN_ ); + + tCur = (tGate & Cof0) | (~tGate & Cof1); + Dau_AddFunction( tCur, nVars, pTable, vFuncsN, vFuncsN_ ); + + tGate = ~s_Truths6[nVars-1-m] & ~s_Truths6[nVars-1-k]; + tCur = (tGate & Cof1) | (~tGate & Cof0); + Dau_AddFunction( tCur, nVars, pTable, vFuncsN, vFuncsN_ ); + + tCur = (tGate & Cof0) | (~tGate & Cof1); + Dau_AddFunction( tCur, nVars, pTable, vFuncsN, vFuncsN_ ); + } + else + { + tGate = s_Truths6[nVars-1-m] ^ s_Truths6[nVars-1-k]; + tCur = (tGate & Cof1) | (~tGate & Cof0); + Dau_AddFunction( tCur, nVars, pTable, vFuncsN, vFuncsN_ ); + } + } + } + } + } + if ( UseTwo && vFuncsN2 ) + Vec_IntForEachEntry( vFuncsN2, Entry, i ) + { + word uTruth = (((word)Entry) << 32) | (word)Entry; + int nSupp = Abc_TtSupportSize( &uTruth, nVars ); + assert( nSupp == 6 || !Abc_Tt6HasVar(uTruth, nVars-1-nSupp) ); + //printf( "Exploring function %4d with %d vars: ", i, nSupp ); + //printf( " %04x\n", (int)uTruth ); + //Dau_DsdPrintFromTruth( &uTruth, 4 ); + for ( v = 0; v < nSupp; v++ ) +// for ( u = v+1; u < nSupp; u++ ) if ( u != v ) + for ( u = 0; u < nSupp; u++ ) if ( u != v ) + { + word tGate1, tGate2, tCur; + word Cof0 = Abc_Tt6Cofactor0( uTruth, nVars-1-v ); + word Cof1 = Abc_Tt6Cofactor1( uTruth, nVars-1-v ); + + word Cof00 = Abc_Tt6Cofactor0( Cof0, nVars-1-u ); + word Cof01 = Abc_Tt6Cofactor1( Cof0, nVars-1-u ); + word Cof10 = Abc_Tt6Cofactor0( Cof1, nVars-1-u ); + word Cof11 = Abc_Tt6Cofactor1( Cof1, nVars-1-u ); + + tGate1 = s_Truths6[nVars-1-v] & s_Truths6[nVars-1-u]; + tGate2 = s_Truths6[nVars-1-v] ^ s_Truths6[nVars-1-u]; + + Cof0 = (tGate2 & Cof00) | (~tGate2 & Cof01); + Cof1 = (tGate2 & Cof10) | (~tGate2 & Cof11); + + tCur = (tGate1 & Cof1) | (~tGate1 & Cof0); + Res = Dau_AddFunction( tCur, nVars, pTable, vFuncsN, vFuncsN_ ); + if ( Res ) + printf( "Found function %d\n", Res ); + + tCur = (tGate1 & Cof0) | (~tGate1 & Cof1); + Res = Dau_AddFunction( tCur, nVars, pTable, vFuncsN, vFuncsN_ ); + if ( Res ) + printf( "Found function %d\n", Res ); + } + } + printf("Nodes = %2d. New = %6d. Total = %6d. New = %6d. Total = %6d. ", + n, Vec_IntSize(vFuncsN), Vec_WecSizeSize(vNpns), Vec_IntSize(vFuncsN_), Vec_WecSizeSize(vNpns_) ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); + fflush(stdout); + if ( Vec_IntSize(vFuncsN) == 0 ) + break; + } +// printf( "Functions with 7 nodes:\n" ); +// Vec_IntForEachEntry( Vec_WecEntry(vNpns_,7), Entry, i ) +// printf( "%04x ", Entry ); +// printf( "\n" ); + + Vec_WecFree( vNpns ); + Vec_WecFree( vNpns_ ); + ABC_FREE( pTable ); + Abc_PrintTime( 1, "Total time", Abc_Clock() - clk ); + fflush(stdout); +} +void Dau_NetworkEnumTest() +{ + //Dau_TruthEnum(); + Dau_NetworkEnum(); +} + + + +/**Function************************************************************* + + Synopsis [Count the number of symmetric pairs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Dau_CountSymms( word t, int nVars ) +{ + word Cof0, Cof1; + int i, j, nPairs = 0; + for ( i = 0; i < nVars; i++ ) + for ( j = i+1; j < nVars; j++ ) + nPairs += Abc_TtVarsAreSymmetric(&t, nVars, i, j, &Cof0, &Cof1); + return nPairs; +} +int Dau_CountSymms2( word t, int nVars ) +{ + word Cof0, Cof1; + int i, j, SymVars = 0; + for ( i = 0; i < nVars; i++ ) + for ( j = i+1; j < nVars; j++ ) + if ( Abc_TtVarsAreSymmetric(&t, nVars, i, j, &Cof0, &Cof1) ) + SymVars |= (1 << j); + return SymVars; +} +int Dau_CountCompl1( word t, int v, int nVars ) +{ + word tNew = Abc_Tt6Flip(t, v); + int k; + if ( tNew == ~t ) + return 1; + for ( k = 0; k < nVars; k++ ) if ( k != v ) + if ( tNew == Abc_Tt6Flip(t, k) ) + return 1; + return 0; +} +int Dau_CountCompl( word t, int nVars ) +{ + int i, nPairs = 0; + for ( i = 0; i < nVars; i++ ) + nPairs += Dau_CountCompl1(t, i, nVars); + return nPairs; +} + +/**Function************************************************************* + + Synopsis [Performs exact canonicization of semi-canonical classes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Wrd_t * Dau_ExactNpnForClasses( Vec_Mem_t * vTtMem, Vec_Int_t * vNodSup, int nVars, int nInputs ) +{ + Vec_Wrd_t * vCanons = Vec_WrdStart( Vec_IntSize(vNodSup) ); + word pAuxWord[1024], pAuxWord1[1024]; + word uTruth; int i, Entry; + permInfo * pi = setPermInfoPtr(nVars); + Vec_IntForEachEntry( vNodSup, Entry, i ) + { + if ( (Entry & 0xF) > nVars ) + continue; + uTruth = *Vec_MemReadEntry( vTtMem, i ); + simpleMinimal(&uTruth, pAuxWord, pAuxWord1, pi, nVars); + Vec_WrdWriteEntry( vCanons, i, uTruth ); + } + freePermInfoPtr(pi); + return vCanons; +} +void Dau_ExactNpnPrint( Vec_Mem_t * vTtMem, Vec_Int_t * vNodSup, int nVars, int nInputs, int nNodesMax ) +{ + abctime clk = Abc_Clock(); int n, nTotal = 0; + Vec_Wrd_t * vCanons = Dau_ExactNpnForClasses( vTtMem, vNodSup, nVars, nInputs ); + Vec_Mem_t * vTtMem2 = Vec_MemAlloc( Vec_MemEntrySize(vTtMem), 10 ); + Vec_MemHashAlloc( vTtMem2, 1<<10 ); + Abc_PrintTime( 1, "Exact NPN computation time", Abc_Clock() - clk ); + printf( "Final results:\n" ); + for ( n = 0; n <= nNodesMax; n++ ) + { + int i, Entry, Entry2, nEntries2, Counter = 0, Counter2 = 0; + Vec_IntForEachEntry( vNodSup, Entry, i ) + { + if ( (Entry & 0xF) > nVars || (Entry >> 16) != n ) + continue; + Counter++; + nEntries2 = Vec_MemEntryNum(vTtMem2); + Entry2 = Vec_MemHashInsert( vTtMem2, Vec_WrdEntryP(vCanons, i) ); + if ( nEntries2 == Vec_MemEntryNum(vTtMem2) ) // found in the table - not new + continue; + Counter2++; + } + nTotal += Counter2; + printf( "Nodes = %2d. ", n ); + printf( "Semi-canonical = %8d. ", Counter ); + printf( "Canonical = %8d. ", Counter2 ); + printf( "Total = %8d.", nTotal ); + printf( "\n" ); + } + Vec_MemHashFree( vTtMem2 ); + Vec_MemFreeP( &vTtMem2 ); + Vec_WrdFree( vCanons ); + fflush(stdout); +} + +/**Function************************************************************* + + Synopsis [Saving hash tables.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Dau_TablesSave( int nInputs, int nVars, Vec_Mem_t * vTtMem, Vec_Int_t * vNodSup, int nFronts, abctime clk ) +{ + FILE * pFile; + char FileName[100]; + int i, nWords = Abc_TtWordNum(nInputs); + // NPN classes + sprintf( FileName, "npn%d%d.ttd", nInputs, nVars ); + pFile = fopen( FileName, "wb" ); + for ( i = 0; i < Vec_MemEntryNum(vTtMem); i++ ) + fwrite( Vec_MemReadEntry(vTtMem, i), 8, nWords, pFile ); + fwrite( Vec_IntArray(vNodSup), 4, Vec_IntSize(vNodSup), pFile ); + fclose( pFile ); +// printf( "Dumped files with %10d classes after exploring %10d frontiers.\n", +// Vec_IntSize(vNodSup), nFronts ); + printf( "Dumped file \"%s\" with %10d classes after exploring %10d frontiers. ", + FileName, Vec_IntSize(vNodSup), nFronts ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); + fflush(stdout); +} + +/**Function************************************************************* + + Synopsis [Dump functions by the number of nodes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Dau_DumpFuncs( Vec_Mem_t * vTtMem, Vec_Int_t * vNodSup, int nVars, int nMax ) +{ + FILE * pFile[20]; + int Counters[20] = {0}; + int n, i; + assert( nVars == 4 || nVars == 5 ); + for ( n = 0; n <= nMax; n++ ) + { + char FileName[100]; + sprintf( FileName, "func%d_min%d.tt", nVars, n ); + pFile[n] = fopen( FileName, "wb" ); + } + for ( i = 0; i < Vec_MemEntryNum(vTtMem); i++ ) + { + word * pTruth = Vec_MemReadEntry( vTtMem, i ); + int NodSup = Vec_IntEntry( vNodSup, i ); + if ( (NodSup & 0xF) != nVars ) + continue; + Counters[NodSup >> 16]++; + if ( nVars == 4 ) + fprintf( pFile[NodSup >> 16], "%04x\n", (int)(0xFFFF & pTruth[0]) ); + else if ( nVars == 5 ) + fprintf( pFile[NodSup >> 16], "%08x\n", (int)(0xFFFFFFFF & pTruth[0]) ); + } + for ( n = 0; n <= nMax; n++ ) + { + printf( "Dumped %8d %d-node %d-input functions into file.\n", Counters[n], n, nVars ); + fclose( pFile[n] ); + } +} + +/**Function************************************************************* + + Synopsis [Function enumeration.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Dau_CountFuncs( Vec_Int_t * vNodSup, int iStart, int iStop, int nVars ) +{ + int i, Entry, Count = 0; + Vec_IntForEachEntryStartStop( vNodSup, Entry, i, iStart, iStop ) + Count += ((Entry & 0xF) <= nVars); + return Count; +} +int Dau_PrintStats( int nNodes, int nInputs, int nVars, Vec_Int_t * vNodSup, int iStart, int iStop, word nSteps, int Count2, abctime clk ) +{ + int nNew; + printf("N =%2d | ", nNodes ); + printf("C =%12.0f ", (double)(iword)nSteps ); + printf("New%d =%10d ", nInputs, iStop-iStart ); + printf("All%d =%10d | ", nInputs, iStop ); + printf("New%d =%8d ", nVars, nNew = Dau_CountFuncs(vNodSup, iStart, iStop, nVars) ); + printf("All%d =%8d ", nVars, Dau_CountFuncs(vNodSup, 0, iStop, nVars) ); + printf("Two =%6d ", Count2 ); + //Abc_PrintTime( 1, "T", Abc_Clock() - clk ); + Abc_Print(1, "%9.2f sec\n", 1.0*(Abc_Clock() - clk)/(CLOCKS_PER_SEC)); + fflush(stdout); + return nNew; +} + + +int Dau_InsertFunction( Abc_TtHieMan_t * pMan, word * pCur, int nNodes, int nInputs, int nVars0, int nVars, + Vec_Mem_t * vTtMem, Vec_Int_t * vNodSup, int nFronts, abctime clk ) +{ + int DumpDelta = 1000000; + char Perm[16] = {0}; + int nVarsNew = Abc_TtMinBase( pCur, NULL, nVars, nInputs ); + //unsigned Phase = Abc_TtCanonicizeHie( pMan, pCur, nVarsNew, Perm, 1 ); + unsigned Phase = Abc_TtCanonicizeWrap( Abc_TtCanonicizeAda, pMan, pCur, nVarsNew, Perm, 99 ); + int nEntries = Vec_MemEntryNum(vTtMem); + int Entry = Vec_MemHashInsert( vTtMem, pCur ); + if ( nEntries == Vec_MemEntryNum(vTtMem) ) // found in the table - not new + return 0; + Entry = 0; + Phase = 0; + // this is a new class + Vec_IntPush( vNodSup, (nNodes << 16) | nVarsNew ); + assert( Vec_MemEntryNum(vTtMem) == Vec_IntSize(vNodSup) ); + if ( Vec_IntSize(vNodSup) % DumpDelta == 0 ) + Dau_TablesSave( nInputs, nVars0, vTtMem, vNodSup, nFronts, clk ); + return 1; +} +void Dau_FunctionEnum( int nInputs, int nVars, int nNodeMax, int fUseTwo, int fReduce, int fVerbose ) +{ + abctime clk = Abc_Clock(); + int nWords = Abc_TtWordNum(nInputs); word nSteps = 0; + Abc_TtHieMan_t * pMan = Abc_TtHieManStart( nInputs, 5 ); + Vec_Mem_t * vTtMem = Vec_MemAlloc( nWords, 16 ); + Vec_Int_t * vNodSup = Vec_IntAlloc( 1 << 16 ); + int v, u, k, m, n, Entry, nNew, Limit[32] = {1, 2}; + word Truth[4] = {0}; + assert( nVars >= 3 && nVars <= nInputs && nInputs <= 6 ); + Vec_MemHashAlloc( vTtMem, 1<<16 ); + // add constant 0 + Vec_MemHashInsert( vTtMem, Truth ); + Vec_IntPush( vNodSup, 0 ); // nodes=0, supp=0 + // add buffer/inverter + Abc_TtIthVar( Truth, 0, nInputs ); + Abc_TtNot( Truth, nWords ); + Vec_MemHashInsert( vTtMem, Truth ); + Vec_IntPush( vNodSup, 1 ); // nodes=0, supp=1 + Dau_PrintStats( 0, nInputs, nVars, vNodSup, 0, 2, nSteps, 0, clk ); + // numerate other functions based on how many nodes they have + for ( n = 1; n <= nNodeMax; n++ ) + { + int Count2 = 0; + int fExpand = !(fReduce && n == nNodeMax); + for ( Entry = Limit[n-1]; Entry < Limit[n]; Entry++ ) + { + word * pTruth = Vec_MemReadEntry( vTtMem, Entry ); + int NodSup = Vec_IntEntry(vNodSup, Entry); + int nSupp = 0xF & NodSup; + int SymVars = Dau_CountSymms2( pTruth[0], nSupp ); + assert( n-1 == (NodSup >> 16) ); + assert( !Abc_Tt6HasVar(*pTruth, nSupp) ); + //printf( "Exploring function %4d with %d vars: ", i, nSupp ); + //printf( " %04x\n", (int)uTruth ); + //Dau_DsdPrintFromTruth( &uTruth, 4 ); + for ( v = 0; v < nSupp; v++ ) if ( (SymVars & (1 << v)) == 0 ) + { + word tGate, tCur; + word Cof0 = Abc_Tt6Cofactor0( *pTruth, v ); + word Cof1 = Abc_Tt6Cofactor1( *pTruth, v ); + // add one extra variable to support + if ( nSupp < nInputs && fExpand ) + { + tGate = s_Truths6[v] & s_Truths6[nSupp]; + tCur = (tGate & Cof1) | (~tGate & Cof0); + Dau_InsertFunction( pMan, &tCur, n, nInputs, nVars, nSupp+1, vTtMem, vNodSup, Entry, clk ); + + tCur = (tGate & Cof0) | (~tGate & Cof1); + Dau_InsertFunction( pMan, &tCur, n, nInputs, nVars, nSupp+1, vTtMem, vNodSup, Entry, clk ); + + + tGate = s_Truths6[v] ^ s_Truths6[nSupp]; + tCur = (tGate & Cof1) | (~tGate & Cof0); + Dau_InsertFunction( pMan, &tCur, n, nInputs, nVars, nSupp+1, vTtMem, vNodSup, Entry, clk ); + + nSteps += 3; + } + // add one cross bar + if ( fExpand ) + for ( k = 0; k < nSupp; k++ ) if ( k != v && ((SymVars & (1 << k)) == 0 || k == v+1) ) + { + tGate = s_Truths6[v] & s_Truths6[k]; + tCur = (tGate & Cof1) | (~tGate & Cof0); + Dau_InsertFunction( pMan, &tCur, n, nInputs, nVars, nSupp, vTtMem, vNodSup, Entry, clk ); + + tCur = (tGate & Cof0) | (~tGate & Cof1); + Dau_InsertFunction( pMan, &tCur, n, nInputs, nVars, nSupp, vTtMem, vNodSup, Entry, clk ); + + tGate = s_Truths6[v] & ~s_Truths6[k]; + tCur = (tGate & Cof1) | (~tGate & Cof0); + Dau_InsertFunction( pMan, &tCur, n, nInputs, nVars, nSupp, vTtMem, vNodSup, Entry, clk ); + + tCur = (tGate & Cof0) | (~tGate & Cof1); + Dau_InsertFunction( pMan, &tCur, n, nInputs, nVars, nSupp, vTtMem, vNodSup, Entry, clk ); + + + tGate = s_Truths6[v] ^ s_Truths6[k]; + tCur = (tGate & Cof1) | (~tGate & Cof0); + Dau_InsertFunction( pMan, &tCur, n, nInputs, nVars, nSupp, vTtMem, vNodSup, Entry, clk ); + + nSteps += 5; + } + // add two cross bars + for ( k = 0; k < nSupp; k++ ) if ( k != v )//&& ((SymVars & (1 << k)) == 0) ) + for ( m = k+1; m < nSupp; m++ ) if ( m != v )//&& ((SymVars & (1 << m)) == 0 || m == k+1) ) + { + tGate = s_Truths6[m] & s_Truths6[k]; + tCur = (tGate & Cof1) | (~tGate & Cof0); + Dau_InsertFunction( pMan, &tCur, n, nInputs, nVars, nSupp, vTtMem, vNodSup, Entry, clk ); + + tCur = (tGate & Cof0) | (~tGate & Cof1); + Dau_InsertFunction( pMan, &tCur, n, nInputs, nVars, nSupp, vTtMem, vNodSup, Entry, clk ); + + tGate = s_Truths6[m] & ~s_Truths6[k]; + tCur = (tGate & Cof1) | (~tGate & Cof0); + Dau_InsertFunction( pMan, &tCur, n, nInputs, nVars, nSupp, vTtMem, vNodSup, Entry, clk ); + + tCur = (tGate & Cof0) | (~tGate & Cof1); + Dau_InsertFunction( pMan, &tCur, n, nInputs, nVars, nSupp, vTtMem, vNodSup, Entry, clk ); + + tGate = ~s_Truths6[m] & s_Truths6[k]; + tCur = (tGate & Cof1) | (~tGate & Cof0); + Dau_InsertFunction( pMan, &tCur, n, nInputs, nVars, nSupp, vTtMem, vNodSup, Entry, clk ); + + tCur = (tGate & Cof0) | (~tGate & Cof1); + Dau_InsertFunction( pMan, &tCur, n, nInputs, nVars, nSupp, vTtMem, vNodSup, Entry, clk ); + + tGate = ~s_Truths6[m] & ~s_Truths6[k]; + tCur = (tGate & Cof1) | (~tGate & Cof0); + Dau_InsertFunction( pMan, &tCur, n, nInputs, nVars, nSupp, vTtMem, vNodSup, Entry, clk ); + + tCur = (tGate & Cof0) | (~tGate & Cof1); + Dau_InsertFunction( pMan, &tCur, n, nInputs, nVars, nSupp, vTtMem, vNodSup, Entry, clk ); + + + tGate = s_Truths6[m] ^ s_Truths6[k]; + tCur = (tGate & Cof1) | (~tGate & Cof0); + Dau_InsertFunction( pMan, &tCur, n, nInputs, nVars, nSupp, vTtMem, vNodSup, Entry, clk ); + + tGate = s_Truths6[m] ^ s_Truths6[k]; + tCur = (tGate & Cof0) | (~tGate & Cof1); + Dau_InsertFunction( pMan, &tCur, n, nInputs, nVars, nSupp, vTtMem, vNodSup, Entry, clk ); + + nSteps += 10; + } + } + } + if ( fUseTwo && n > 2 && fExpand ) + for ( Entry = Limit[n-2]; Entry < Limit[n-1]; Entry++ ) + { + word * pTruth = Vec_MemReadEntry( vTtMem, Entry ); + int NodSup = Vec_IntEntry(vNodSup, Entry); + int nSupp = 0xF & NodSup; int g1, g2; + assert( n-2 == (NodSup >> 16) ); + assert( !Abc_Tt6HasVar(*pTruth, nSupp) ); + for ( v = 0; v < nSupp; v++ ) + for ( u = 0; u < nSupp; u++ ) if ( u != v ) + { + word Cof0 = Abc_Tt6Cofactor0( *pTruth, v ); + word Cof1 = Abc_Tt6Cofactor1( *pTruth, v ); + + word Cof00 = Abc_Tt6Cofactor0( Cof0, u ); + word Cof01 = Abc_Tt6Cofactor1( Cof0, u ); + word Cof10 = Abc_Tt6Cofactor0( Cof1, u ); + word Cof11 = Abc_Tt6Cofactor1( Cof1, u ); + + word tGates[5], tCur; + tGates[0] = s_Truths6[v] & s_Truths6[u]; + tGates[1] = s_Truths6[v] & ~s_Truths6[u]; + tGates[2] = ~s_Truths6[v] & s_Truths6[u]; + tGates[3] = s_Truths6[v] | s_Truths6[u]; + tGates[4] = s_Truths6[v] ^ s_Truths6[u]; + + for ( g1 = 0; g1 < 5; g1++ ) + for ( g2 = g1+1; g2 < 5; g2++ ) + { + Cof0 = (tGates[g1] & Cof01) | (~tGates[g1] & Cof00); + Cof1 = (tGates[g1] & Cof11) | (~tGates[g1] & Cof10); + + tCur = (tGates[g2] & Cof1) | (~tGates[g2] & Cof0); + Count2 += Dau_InsertFunction( pMan, &tCur, n, nInputs, nVars, nSupp, vTtMem, vNodSup, Entry, clk ); + } + } + } + Limit[n+1] = Vec_IntSize(vNodSup); + nNew = Dau_PrintStats( n, nInputs, nVars, vNodSup, Limit[n], Limit[n+1], nSteps, Count2, clk ); + if ( nNew == 0 ) + break; + } + Dau_TablesSave( nInputs, nVars, vTtMem, vNodSup, Vec_IntSize(vNodSup), clk ); + Abc_PrintTime( 1, "Total time", Abc_Clock() - clk ); + //Dau_DumpFuncs( vTtMem, vNodSup, nVars, nNodeMax ); + //Dau_ExactNpnPrint( vTtMem, vNodSup, nVars, nInputs, n ); + Abc_TtHieManStop( pMan ); + Vec_MemHashFree( vTtMem ); + Vec_MemFreeP( &vTtMem ); + Vec_IntFree( vNodSup ); + fflush(stdout); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + +ABC_NAMESPACE_IMPL_END + diff --git a/src/opt/dau/dauNpn2.c b/src/opt/dau/dauNpn2.c new file mode 100644 index 00000000..bca65ad0 --- /dev/null +++ b/src/opt/dau/dauNpn2.c @@ -0,0 +1,507 @@ +/**CFile**************************************************************** + + FileName [dau.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [DAG-aware unmapping.] + + Synopsis [] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: dau.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "dauInt.h" +#include "misc/util/utilTruth.h" +#include "misc/extra/extra.h" + +ABC_NAMESPACE_IMPL_START + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +typedef struct Dtt_Man_t_ Dtt_Man_t; +struct Dtt_Man_t_ +{ + int nVars; // variable number + int nPerms; // number of permutations + int nComps; // number of complementations + int * pPerms; // permutations + int * pComps; // complementations + word * pPres; // function marks + Vec_Int_t * vFanins; // node fanins + Vec_Int_t * vTruths; // node truth tables + Vec_Int_t * vConfigs; // configurations + Vec_Int_t * vClasses; // node NPN classes + Vec_Int_t * vTruthNpns; // truth tables of the classes + Vec_Wec_t * vFunNodes; // nodes by NPN class + Vec_Int_t * vTemp; // temporary + Vec_Int_t * vTemp2; // temporary + unsigned FunMask; // function mask + unsigned CmpMask; // function mask + unsigned BinMask; // hash mask + unsigned * pBins; // hash bins + Vec_Int_t * vUsedBins; // used bins + int Counts[32]; // node counts + int nClasses; // count of classes + unsigned * pTable; // mapping of funcs into their classes + int * pNodes; // the number of nodes in min-node network + int * pTimes; // the number of different min-node networks + char * pVisited; // visited classes + Vec_Int_t * vVisited; // the number of visited classes +}; + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +unsigned * Dau_ReadFile2( char * pFileName, int nSizeW ) +{ + abctime clk = Abc_Clock(); + FILE * pFile = fopen( pFileName, "rb" ); + unsigned * p = (unsigned *)ABC_CALLOC(word, nSizeW); + int RetValue = pFile ? fread( p, sizeof(word), nSizeW, pFile ) : 0; + RetValue = 0; + if ( pFile ) + { + printf( "Finished reading file \"%s\".\n", pFileName ); + fclose( pFile ); + } + else + printf( "Cannot open input file \"%s\".\n", pFileName ); + Abc_PrintTime( 1, "File reading", Abc_Clock() - clk ); + return p; +} +void Dtt_ManRenum( int nVars, unsigned * pTable, int * pnClasses ) +{ + unsigned i, Limit = 1 << ((1 << nVars)-1), Count = 0; + for ( i = 0; i < Limit; i++ ) + if ( pTable[i] == i ) + pTable[i] = Count++; + else + { + assert( pTable[i] < i ); + pTable[i] = pTable[pTable[i]]; + } + printf( "The total number of NPN classes = %d.\n", Count ); + *pnClasses = Count; +} +unsigned * Dtt_ManLoadClasses( int nVars, int * pnClasses ) +{ + unsigned * pTable = NULL; + if ( nVars == 4 ) + pTable = Dau_ReadFile2( "tableW14.data", 1 << 14 ); + else if ( nVars == 5 ) + pTable = Dau_ReadFile2( "tableW30.data", 1 << 30 ); + else assert( 0 ); + Dtt_ManRenum( nVars, pTable, pnClasses ); + return pTable; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Dtt_ManAddVisited( Dtt_Man_t * p, unsigned Truth2, int n ) +{ + unsigned Truth = Truth2 & p->CmpMask ? ~Truth2 : Truth2; + unsigned Class = p->pTable[Truth & p->FunMask]; + assert( Class < (unsigned)p->nClasses ); + if ( p->pNodes[Class] < n ) + return; + assert( p->pNodes[Class] == n ); + if ( p->pVisited[Class] ) + return; + p->pVisited[Class] = 1; + Vec_IntPush( p->vVisited, Class ); +} +void Dtt_ManProcessVisited( Dtt_Man_t * p ) +{ + int i, Class; + Vec_IntForEachEntry( p->vVisited, Class, i ) + { + assert( p->pVisited[Class] ); + p->pVisited[Class] = 0; + p->pTimes[Class]++; + } + Vec_IntClear( p->vVisited ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Dtt_Man_t * Dtt_ManAlloc( int nVars, int fMulti ) +{ + Dtt_Man_t * p = ABC_CALLOC( Dtt_Man_t, 1 ); + p->nVars = nVars; + p->nPerms = Extra_Factorial( nVars ); + p->nComps = 1 << nVars; + p->pPerms = Extra_PermSchedule( nVars ); + p->pComps = Extra_GreyCodeSchedule( nVars ); + p->pPres = ABC_CALLOC( word, 1 << (p->nComps - 7) ); + p->vFanins = Vec_IntAlloc( 2*617000 ); + p->vTruths = Vec_IntAlloc( 617000 ); + p->vConfigs = Vec_IntAlloc( 617000 ); + p->vClasses = Vec_IntAlloc( 617000 ); + p->vTruthNpns = Vec_IntAlloc( 617000 ); + p->vFunNodes = Vec_WecStart( 16 ); + p->vTemp = Vec_IntAlloc( 4000 ); + p->vTemp2 = Vec_IntAlloc( 4000 ); + p->FunMask = nVars == 5 ? ~0 : (nVars == 4 ? 0xFFFF : 0xFF); + p->CmpMask = nVars == 5 ? 1 << 31 : (nVars == 4 ? 1 << 15 : 1 << 7); + p->BinMask = 0x3FFF; + p->pBins = ABC_FALLOC( unsigned, p->BinMask + 1 ); + p->vUsedBins = Vec_IntAlloc( 4000 ); + if ( !fMulti ) return p; + p->pTable = Dtt_ManLoadClasses( p->nVars, &p->nClasses ); + p->pNodes = ABC_CALLOC( int, p->nClasses ); + p->pTimes = ABC_CALLOC( int, p->nClasses ); + p->pVisited = ABC_CALLOC( char, p->nClasses ); + p->vVisited = Vec_IntAlloc( 1000 ); + return p; +} +void Dtt_ManFree( Dtt_Man_t * p ) +{ + Vec_IntFreeP( &p->vVisited ); + ABC_FREE( p->pTable ); + ABC_FREE( p->pNodes ); + ABC_FREE( p->pTimes ); + ABC_FREE( p->pVisited ); + Vec_IntFreeP( &p->vFanins ); + Vec_IntFreeP( &p->vTruths ); + Vec_IntFreeP( &p->vConfigs ); + Vec_IntFreeP( &p->vClasses ); + Vec_IntFreeP( &p->vTruthNpns ); + Vec_WecFreeP( &p->vFunNodes ); + Vec_IntFreeP( &p->vTemp ); + Vec_IntFreeP( &p->vTemp2 ); + Vec_IntFreeP( &p->vUsedBins ); + ABC_FREE( p->pPerms ); + ABC_FREE( p->pComps ); + ABC_FREE( p->pPres ); + ABC_FREE( p->pBins ); + ABC_FREE( p ); +} + +/**Function************************************************************* + + Synopsis [Collect representatives of the same class.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline unsigned Dtt_ManHashKey( Dtt_Man_t * p, unsigned Truth ) +{ + static unsigned s_P[4] = { 1699, 5147, 7103, 8147 }; + unsigned char * pD = (unsigned char*)&Truth; + return pD[0] * s_P[0] + pD[1] * s_P[1] + pD[2] * s_P[2] + pD[3] * s_P[3]; +} +int Dtt_ManCheckHash( Dtt_Man_t * p, unsigned Truth ) +{ + unsigned Hash = Dtt_ManHashKey(p, Truth); + unsigned * pSpot = p->pBins + (Hash & p->BinMask); + for ( ; ~*pSpot; Hash++, pSpot = p->pBins + (Hash & p->BinMask) ) + if ( *pSpot == Truth ) // equal + return 0; + Vec_IntPush( p->vUsedBins, pSpot - p->pBins ); + *pSpot = Truth; + return 1; +} +Vec_Int_t * Dtt_ManCollect( Dtt_Man_t * p, unsigned Truth, Vec_Int_t * vFuns ) +{ + int i, k, Entry; + word tCur = ((word)Truth << 32) | (word)Truth; + Vec_IntClear( vFuns ); + for ( i = 0; i < p->nPerms; i++ ) + { + for ( k = 0; k < p->nComps; k++ ) + { +// unsigned tTemp = (unsigned)(tCur & 1 ? ~tCur : tCur); + unsigned tTemp = (unsigned)(tCur & p->CmpMask ? ~tCur : tCur); + if ( Dtt_ManCheckHash( p, tTemp ) ) + Vec_IntPush( vFuns, tTemp ); + tCur = Abc_Tt6Flip( tCur, p->pComps[k] ); + } + tCur = Abc_Tt6SwapAdjacent( tCur, p->pPerms[i] ); + } + assert( tCur == (((word)Truth << 32) | (word)Truth) ); + // clean hash table + Vec_IntForEachEntry( p->vUsedBins, Entry, i ) + p->pBins[Entry] = ~0; + Vec_IntClear( p->vUsedBins ); + //printf( "%d ", Vec_IntSize(vFuns) ); + return vFuns; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Dtt_ManGetFun( Dtt_Man_t * p, unsigned tFun ) +{ + tFun = tFun & p->CmpMask ? ~tFun : tFun; + return Abc_TtGetBit( p->pPres, tFun & p->FunMask ); +} +static inline void Dtt_ManSetFun( Dtt_Man_t * p, unsigned tFun ) +{ + tFun = tFun & p->CmpMask ? ~tFun : tFun; + //assert( !Dtt_ManGetFun(p, fFun & p->FunMask ); + Abc_TtSetBit( p->pPres, tFun & p->FunMask ); +} +void Dtt_ManAddFunction( Dtt_Man_t * p, int n, int FanI, int FanJ, int Type, unsigned Truth ) +{ + Vec_Int_t * vFuncs = Dtt_ManCollect( p, Truth, p->vTemp2 ); + unsigned Min = Vec_IntFindMin( vFuncs ); + int i, nObjs = Vec_IntSize(p->vFanins)/2; + int nNodesI = 0xF & (Vec_IntEntry(p->vConfigs, FanI) >> 3); + int nNodesJ = 0xF & (Vec_IntEntry(p->vConfigs, FanJ) >> 3); + int nNodes = nNodesI + nNodesJ + 1; + assert( nObjs == Vec_IntSize(p->vTruths) ); + assert( nObjs == Vec_IntSize(p->vConfigs) ); + assert( nObjs == Vec_IntSize(p->vClasses) ); + Vec_WecPush( p->vFunNodes, n, nObjs ); + Vec_IntPushTwo( p->vFanins, FanI, FanJ ); + Vec_IntPush( p->vTruths, Truth ); + Vec_IntPush( p->vConfigs, (nNodes << 3) | Type ); + Vec_IntPush( p->vClasses, Vec_IntSize(p->vTruthNpns) ); + Vec_IntPush( p->vTruthNpns, Min ); + Vec_IntForEachEntry( vFuncs, Min, i ) + Dtt_ManSetFun( p, Min ); + assert( nNodes < 32 ); + p->Counts[nNodes]++; + + if ( p->pTable == NULL ) + return; + Truth = Truth & p->CmpMask ? ~Truth : Truth; + Truth &= p->FunMask; + assert( p->pNodes[p->pTable[Truth]] == 0 ); + p->pNodes[p->pTable[Truth]] = n; +} + +int Dtt_PrintStats( int nNodes, int nVars, Vec_Wec_t * vFunNodes, word nSteps, abctime clk, int fDelay, word nMultis ) +{ + int nNew = Vec_IntSize(Vec_WecEntry(vFunNodes, nNodes)); + printf("%c =%2d | ", fDelay ? 'D':'N', nNodes ); + printf("C =%12.0f | ", (double)(iword)nSteps ); + printf("New%d =%10d ", nVars, nNew + (int)(nNodes==0) ); + printf("All%d =%10d | ", nVars, Vec_WecSizeSize(vFunNodes)+1 ); + printf("Multi =%10d | ", (int)nMultis ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); + //Abc_Print(1, "%9.2f sec\n", 1.0*(Abc_Clock() - clk)/(CLOCKS_PER_SEC)); + fflush(stdout); + return nNew; +} +void Dtt_PrintDistrib( Dtt_Man_t * p ) +{ + int i; + printf( "NPN classes for each node count (N):\n" ); + for ( i = 0; i < 32; i++ ) + if ( p->Counts[i] ) + printf( "N = %2d : NPN = %6d\n", i, p->Counts[i] ); +} +void Dtt_PrintMulti2( Dtt_Man_t * p ) +{ + int i, n; + for ( n = 0; n <= 7; n++ ) + { + printf( "n=%d : ", n); + for ( i = 0; i < p->nClasses; i++ ) + if ( p->pNodes[i] == n ) + printf( "%d ", p->pTimes[i] ); + printf( "\n" ); + } +} +void Dtt_PrintMulti1( Dtt_Man_t * p ) +{ + int i, n, Entry, Count, Prev; + for ( n = 0; n < 16; n++ ) + { + Vec_Int_t * vTimes = Vec_IntAlloc( 100 ); + Vec_Int_t * vUsed = Vec_IntAlloc( 100 ); + for ( i = 0; i < p->nClasses; i++ ) + if ( p->pNodes[i] == n ) + Vec_IntPush( vTimes, p->pTimes[i] ); + if ( Vec_IntSize(vTimes) == 0 ) + { + Vec_IntFree(vTimes); + Vec_IntFree(vUsed); + break; + } + Vec_IntSort( vTimes, 0 ); + Count = 1; + Prev = Vec_IntEntry( vTimes, 0 ); + Vec_IntForEachEntryStart( vTimes, Entry, i, 1 ) + if ( Prev == Entry ) + Count++; + else + { + assert( Prev < Entry ); + Vec_IntPushTwo( vUsed, Prev, Count ); + Count = 1; + Prev = Entry; + } + if ( Count > 0 ) + Vec_IntPushTwo( vUsed, Prev, Count ); + printf( "n=%d : ", n); + Vec_IntForEachEntryDouble( vUsed, Prev, Entry, i ) + printf( "%d=%d ", Prev, Entry ); + printf( "\n" ); + Vec_IntFree( vTimes ); + Vec_IntFree( vUsed ); + } +} +void Dtt_PrintMulti( Dtt_Man_t * p ) +{ + int n, Counts[13][11] = {{0}}; + for ( n = 0; n < 13; n++ ) + { + int i, Total = 0, Count = 0; + for ( i = 0; i < p->nClasses; i++ ) + if ( p->pNodes[i] == n ) + { + int Log = Abc_Base2Log(p->pTimes[i]); + assert( Log < 11 ); + if ( p->pTimes[i] < 2 ) + Counts[n][0]++; + else + Counts[n][Log]++; + Total += p->pTimes[i]; + Count++; + } + if ( Count == 0 ) + break; + printf( "n=%2d : ", n ); + printf( "All = %7d ", Count ); + printf( "Ave = %6.2f ", 1.0*Total/Count ); + for ( i = 0; i < 11; i++ ) + if ( Counts[n][i] ) + printf( "%6d", Counts[n][i] ); + else + printf( "%6s", "" ); + printf( "\n" ); + } +} +void Dtt_EnumerateLf( int nVars, int nNodeMax, int fDelay, int fMulti, int fVerbose ) +{ + abctime clk = Abc_Clock(); word nSteps = 0, nMultis = 0; + Dtt_Man_t * p = Dtt_ManAlloc( nVars, fMulti ); int n, i, j; + // constant zero class + Vec_IntPushTwo( p->vFanins, 0, 0 ); + Vec_IntPush( p->vTruths, 0 ); + Vec_IntPush( p->vConfigs, 0 ); + Vec_IntPush( p->vClasses, Vec_IntSize(p->vTruthNpns) ); + Vec_IntPush( p->vTruthNpns, 0 ); + Dtt_ManSetFun( p, 0 ); + // buffer class + Vec_WecPush( p->vFunNodes, 0, Vec_IntSize(p->vFanins)/2 ); + Vec_IntPushTwo( p->vFanins, 0, 0 ); + Vec_IntPush( p->vTruths, (unsigned)s_Truths6[0] ); + Vec_IntPush( p->vConfigs, 0 ); + Vec_IntPush( p->vClasses, Vec_IntSize(p->vTruthNpns) ); + Vec_IntPush( p->vTruthNpns, (unsigned)s_Truths6[0] ); + for ( i = 0; i < nVars; i++ ) + Dtt_ManSetFun( p, (unsigned)s_Truths6[i] ); + p->Counts[0] = 2; + // enumerate + Dtt_PrintStats(0, nVars, p->vFunNodes, nSteps, clk, fDelay, 0); + for ( n = 1; n <= nNodeMax; n++ ) + { + for ( i = 0, j = n - 1; i < n; i++, j = j - 1 + fDelay ) if ( i <= j ) + { + Vec_Int_t * vFaninI = Vec_WecEntry( p->vFunNodes, i ); + Vec_Int_t * vFaninJ = Vec_WecEntry( p->vFunNodes, j ); + int k, i0, j0, EntryI, EntryJ; + Vec_IntForEachEntry( vFaninI, EntryI, i0 ) + { + unsigned TruthI = Vec_IntEntry(p->vTruths, EntryI); + Vec_Int_t * vFuns = Dtt_ManCollect( p, TruthI, p->vTemp ); + int Start = i == j ? i0 : 0; + Vec_IntForEachEntryStart( vFaninJ, EntryJ, j0, Start ) + { + unsigned Truth, TruthJ = Vec_IntEntry(p->vTruths, EntryJ); + Vec_IntForEachEntry( vFuns, Truth, k ) + { + if ( !Dtt_ManGetFun(p, TruthJ & Truth) ) + Dtt_ManAddFunction( p, n, EntryI, EntryJ, 0, TruthJ & Truth ); + if ( !Dtt_ManGetFun(p, TruthJ & ~Truth) ) + Dtt_ManAddFunction( p, n, EntryI, EntryJ, 1, TruthJ & ~Truth ); + if ( !Dtt_ManGetFun(p, ~TruthJ & Truth) ) + Dtt_ManAddFunction( p, n, EntryI, EntryJ, 2, ~TruthJ & Truth ); + if ( !Dtt_ManGetFun(p, TruthJ | Truth) ) + Dtt_ManAddFunction( p, n, EntryI, EntryJ, 3, TruthJ | Truth ); + if ( !Dtt_ManGetFun(p, TruthJ ^ Truth) ) + Dtt_ManAddFunction( p, n, EntryI, EntryJ, 4, TruthJ ^ Truth ); + nSteps += 5; + + if ( p->pTable ) Dtt_ManAddVisited( p, TruthJ & Truth, n ); + if ( p->pTable ) Dtt_ManAddVisited( p, TruthJ & ~Truth, n ); + if ( p->pTable ) Dtt_ManAddVisited( p, ~TruthJ & Truth, n ); + if ( p->pTable ) Dtt_ManAddVisited( p, TruthJ | Truth, n ); + if ( p->pTable ) Dtt_ManAddVisited( p, TruthJ ^ Truth, n ); + } + nMultis++; + if ( p->pTable ) Dtt_ManProcessVisited( p ); + } + } + } + if ( Dtt_PrintStats(n, nVars, p->vFunNodes, nSteps, clk, fDelay, nMultis) == 0 ) + break; + } + if ( fDelay ) + Dtt_PrintDistrib( p ); + if ( p->pTable ) + Dtt_PrintMulti( p ); + Dtt_ManFree( p ); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + +ABC_NAMESPACE_IMPL_END + diff --git a/src/opt/dau/module.make b/src/opt/dau/module.make index 190e30e4..5feb1040 100644 --- a/src/opt/dau/module.make +++ b/src/opt/dau/module.make @@ -1,9 +1,12 @@ SRC += src/opt/dau/dauCanon.c \ src/opt/dau/dauCore.c \ + src/opt/dau/dauCount.c \ src/opt/dau/dauDivs.c \ src/opt/dau/dauDsd.c \ src/opt/dau/dauEnum.c \ src/opt/dau/dauGia.c \ src/opt/dau/dauMerge.c \ src/opt/dau/dauNonDsd.c \ + src/opt/dau/dauNpn.c \ + src/opt/dau/dauNpn2.c \ src/opt/dau/dauTree.c diff --git a/src/opt/lpk/lpkAbcUtil.c b/src/opt/lpk/lpkAbcUtil.c index b96614d2..24a42b5f 100644 --- a/src/opt/lpk/lpkAbcUtil.c +++ b/src/opt/lpk/lpkAbcUtil.c @@ -124,7 +124,7 @@ Lpk_Fun_t * Lpk_FunDup( Lpk_Fun_t * p, unsigned * pTruth ) pNew->uSupp = Kit_TruthSupport( pTruth, p->nVars ); Kit_TruthCopy( Lpk_FunTruth(pNew,0), pTruth, p->nVars ); memcpy( pNew->pFanins, p->pFanins, 16 ); - memcpy( pNew->pDelays, p->pDelays, 16 ); + memcpy( pNew->pDelays, p->pDelays, sizeof(int)*16 ); Vec_PtrPush( p->vNodes, pNew ); return pNew; } @@ -212,7 +212,7 @@ void Lpk_FunComputeCofSupps( Lpk_Fun_t * p ) SeeAlso [] ***********************************************************************/ -int Lpk_SuppDelay( unsigned uSupp, char * pDelays ) +int Lpk_SuppDelay( unsigned uSupp, int * pDelays ) { int Delay, Var; Delay = 0; diff --git a/src/opt/lpk/lpkCore.c b/src/opt/lpk/lpkCore.c index 6595b365..27912a9a 100644 --- a/src/opt/lpk/lpkCore.c +++ b/src/opt/lpk/lpkCore.c @@ -451,6 +451,7 @@ p->timeTruth3 += Abc_Clock() - clk; printf( "%c=%d ", 'a'+k, Abc_ObjLevel(pLeaf) ); printf( "\n" ); Kit_DsdPrintFromTruth( pTruth, pCut->nLeaves ); + printf( "\n" ); // pFileName = Kit_TruthDumpToFile( pTruth, pCut->nLeaves, Count++ ); // printf( "Saved truth table in file \"%s\".\n", pFileName ); } diff --git a/src/opt/lpk/lpkInt.h b/src/opt/lpk/lpkInt.h index 841572c7..02181001 100644 --- a/src/opt/lpk/lpkInt.h +++ b/src/opt/lpk/lpkInt.h @@ -147,13 +147,13 @@ struct Lpk_Fun_t_ unsigned Id : 7; // the ID of this node unsigned nVars : 5; // the number of variables unsigned nLutK : 4; // the number of LUT inputs - unsigned nAreaLim : 5; // the area limit (the largest allowed) - unsigned nDelayLim : 9; // the delay limit (the largest allowed) + unsigned nAreaLim : 14; // the area limit (the largest allowed) unsigned fSupports : 1; // supports of cofactors were precomputed unsigned fMark : 1; // marks the MUX-based dec unsigned uSupp; // the support of this component unsigned puSupps[32]; // the supports of the cofactors - char pDelays[16]; // the delays of the inputs + unsigned nDelayLim; // the delay limit (the largest allowed) + int pDelays[16]; // the delays of the inputs char pFanins[16]; // the fanins of this function unsigned pTruth[0]; // the truth table (contains room for three truth tables) }; @@ -215,7 +215,7 @@ extern Lpk_Fun_t * Lpk_FunCreate( Abc_Ntk_t * pNtk, Vec_Ptr_t * vLeaves, unsi extern Lpk_Fun_t * Lpk_FunDup( Lpk_Fun_t * p, unsigned * pTruth ); extern int Lpk_FunSuppMinimize( Lpk_Fun_t * p ); extern void Lpk_FunComputeCofSupps( Lpk_Fun_t * p ); -extern int Lpk_SuppDelay( unsigned uSupp, char * pDelays ); +extern int Lpk_SuppDelay( unsigned uSupp, int * pDelays ); extern int Lpk_SuppToVars( unsigned uBoundSet, char * pVars ); diff --git a/src/opt/sim/simMan.c b/src/opt/sim/simMan.c index ecee0424..b3f99f89 100644 --- a/src/opt/sim/simMan.c +++ b/src/opt/sim/simMan.c @@ -80,7 +80,7 @@ Sym_Man_t * Sym_ManStart( Abc_Ntk_t * pNtk, int fVerbose ) for ( i = 0; i < p->nOutputs; i++ ) for ( v = 0; v < p->nInputs; v++ ) if ( Sim_SuppFunHasVar( p->vSuppFun, i, v ) ) - Vec_VecPush( p->vSupports, i, (void *)(ABC_PTRUINT_T)v ); + Vec_VecPushInt( p->vSupports, i, v ); return p; } diff --git a/src/proof/acec/acecPo.c b/src/proof/acec/acecPo.c index c975e375..91f6d5aa 100644 --- a/src/proof/acec/acecPo.c +++ b/src/proof/acec/acecPo.c @@ -34,6 +34,168 @@ ABC_NAMESPACE_IMPL_START /**Function************************************************************* + Synopsis [Parses signature given on the command line.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Acec_ParseSignatureMono( char * p, char * pStop, Vec_Int_t * vLevel ) +{ + char * pTemp = p; + int Const = ABC_INFINITY; + int fMinus = pTemp[0] == '-'; + if ( pTemp[0] == '+' || pTemp[0] == '-' || pTemp[0] == '(' ) + pTemp++; + while ( pTemp < pStop ) + { + if ( pTemp[0] == 'i' ) // input + Vec_IntPush( vLevel, -1-atoi(++pTemp) ); + else if ( pTemp[0] == 'o' ) // output + Vec_IntPush( vLevel, atoi(++pTemp) ); + else // coefficient + { + assert( Const == ABC_INFINITY ); + Const = 1 + atoi(pTemp); + } + while ( pTemp[0] >= '0' && pTemp[0] <= '9' ) + pTemp++; + assert( pTemp == pStop || pTemp[0] == '*' ); + pTemp++; + } + assert( Const != ABC_INFINITY ); + Vec_IntPush( vLevel, fMinus ? -Const : Const ); +} +Vec_Wec_t * Acec_ParseSignatureOne( char * p, char * pStop ) +{ + Vec_Wec_t * vMonos = Vec_WecAlloc( 10 ); + char * pTemp = p, * pNext; + assert( p[0] == '(' && pStop[0] == ')' ); + while ( pTemp[0] != ')' ) + { + for ( pNext = pTemp+1; pNext < pStop; pNext++ ) + if ( pNext[0] == '+' || pNext[0] == '-' ) + break; + assert( pNext[0] == '+' || pNext[0] == '-' || pNext[0] == ')' ); + Acec_ParseSignatureMono( pTemp, pNext, Vec_WecPushLevel(vMonos) ); + pTemp = pNext; + } + return vMonos; +} +Vec_Wec_t * Acec_ParseDistribute( Vec_Wec_t * vM1, Vec_Wec_t * vM2, Vec_Wec_t * vAdd ) +{ + Vec_Wec_t * vMonos = Vec_WecAlloc( 10 ); + Vec_Int_t * vLevel1, * vLevel2, * vLevel; + int i, k, n, Entry; + Vec_WecForEachLevel( vM1, vLevel1, i ) + Vec_WecForEachLevel( vM2, vLevel2, k ) + { + vLevel = Vec_WecPushLevel(vMonos); + Vec_IntForEachEntryStop( vLevel1, Entry, n, Vec_IntSize(vLevel1)-1 ) + Vec_IntPush(vLevel, Entry); + Vec_IntForEachEntryStop( vLevel2, Entry, n, Vec_IntSize(vLevel2)-1 ) + Vec_IntPush(vLevel, Entry); + Vec_IntPush(vLevel, Vec_IntEntryLast(vLevel1)+Vec_IntEntryLast(vLevel2)-1); + } + Vec_WecForEachLevel( vAdd, vLevel1, k ) + { + vLevel = Vec_WecPushLevel(vMonos); + Vec_IntForEachEntry( vLevel1, Entry, n ) + Vec_IntPush(vLevel, Entry); + } + return vMonos; +} +Vec_Wec_t * Acec_ParseSignature( char * p ) +{ + Vec_Wec_t * vAdd = NULL, * vTemp1, * vTemp2, * vRes; + if ( p[0] == '(' ) + { + char * pStop = strstr(p, ")"); + if ( pStop == NULL ) + return NULL; + vTemp1 = Acec_ParseSignatureOne( p, pStop ); + if ( pStop[1] == 0 ) + return vTemp1; + if ( pStop[1] == '*' ) + { + char * p2 = pStop + 2; + char * pStop2 = strstr(p2, ")"); + if ( p2[0] != '(' ) + return NULL; + if ( pStop2 == NULL ) + return NULL; + vTemp2 = Acec_ParseSignatureOne( p2, pStop2 ); + if ( pStop2[1] == 0 ) + { + vRes = Acec_ParseDistribute( vTemp1, vTemp2, vAdd ); + Vec_WecFree( vTemp1 ); + Vec_WecFree( vTemp2 ); + return vRes; + } + if ( pStop2[1] == '+' ) + { + char * p3 = pStop2 + 2; + char * pStop3 = strstr(p3, ")"); + if ( p3[0] != '(' ) + return NULL; + if ( pStop3 == NULL ) + return NULL; + vAdd = Acec_ParseSignatureOne( p3, pStop3 ); + vRes = Acec_ParseDistribute( vTemp1, vTemp2, vAdd ); + Vec_WecFree( vTemp1 ); + Vec_WecFree( vTemp2 ); + Vec_WecFree( vAdd ); + return vRes; + } + assert( 0 ); + } + assert( 0 ); + } + else + { + int Len = strlen(p); + char * pCopy = ABC_ALLOC( char, Len+3 ); + pCopy[0] = '('; + strcpy( pCopy+1, p ); + pCopy[Len+1] = ')'; + pCopy[Len+2] = '\0'; + vRes = Acec_ParseSignatureOne( pCopy, pCopy + Len + 1 ); + ABC_FREE( pCopy ); + return vRes; + } + return NULL; +} +void Acec_PrintSignature( Vec_Wec_t * vMonos ) +{ + Vec_Int_t * vLevel; int i, k, Entry; + printf( "Output signature with %d monomials:\n", Vec_WecSize(vMonos) ); + Vec_WecForEachLevel( vMonos, vLevel, i ) + { + printf( " %s2^%d", Vec_IntEntryLast(vLevel) > 0 ? "+":"-", Abc_AbsInt(Vec_IntEntryLast(vLevel))-1 ); + Vec_IntForEachEntryStop( vLevel, Entry, k, Vec_IntSize(vLevel)-1 ) + { + printf( " * " ); + if ( Entry < 0 ) + printf( "i%d", -Entry-1 ); + else + printf( "o%d", Entry ); + } + printf( "\n" ); + } +} +void Acec_ParseSignatureTest() +{ + char * pSign = "(4*o1+2*o2+1*o3)*(4*i4+2*i5+1*i6)+(4*o4+2*o5+1*o6)"; + Vec_Wec_t * vMonos = Acec_ParseSignature( pSign ); + Acec_PrintSignature( vMonos ); + Vec_WecFree( vMonos ); +} + +/**Function************************************************************* + Synopsis [Checks that items are unique and in order.] Description [] @@ -101,7 +263,7 @@ void Gia_PolynPrintMono( Vec_Int_t * vConst, Vec_Int_t * vMono, int Prev ) Vec_IntForEachEntry( vConst, Entry, k ) printf( "%s2^%d", Entry < 0 ? "-" : "+", Abc_AbsInt(Entry)-1 ); Vec_IntForEachEntry( vMono, Entry, k ) - printf( " * %d", Entry-1 ); + printf( " * i%d", Entry-1 ); printf( "\n" ); } void Gia_PolynPrint( Vec_Wec_t * vPolyn ) @@ -121,7 +283,7 @@ void Gia_PolynPrintStats( Vec_Wec_t * vPolyn ) { Vec_Int_t * vConst, * vCountsP, * vCountsN; int i, Entry, Max = 0; - printf( "Polynomial with %d monomials:\n", Vec_WecSize(vPolyn)/2 ); + printf( "Input signature with %d monomials:\n", Vec_WecSize(vPolyn)/2 ); for ( i = 0; i < Vec_WecSize(vPolyn)/2; i++ ) { vConst = Vec_WecEntry( vPolyn, 2*i+0 ); @@ -140,10 +302,10 @@ void Gia_PolynPrintStats( Vec_Wec_t * vPolyn ) } Vec_IntForEachEntry( vCountsN, Entry, i ) if ( Entry ) - printf( "-2^%d appears %d times\n", Abc_AbsInt(i)-1, Entry ); + printf( " -2^%d appears %d times\n", Abc_AbsInt(i)-1, Entry ); Vec_IntForEachEntry( vCountsP, Entry, i ) if ( Entry ) - printf( "+2^%d appears %d times\n", Abc_AbsInt(i)-1, Entry ); + printf( " +2^%d appears %d times\n", Abc_AbsInt(i)-1, Entry ); Vec_IntFree( vCountsP ); Vec_IntFree( vCountsN ); } @@ -474,7 +636,7 @@ static inline void Gia_PolynPrepare4( Vec_Int_t * vTempC[4], Vec_Int_t * vTempM[ Vec_IntPushUniqueOrder( vTempM[3], iFan1 ); } -Vec_Wec_t * Gia_PolynBuildNew( Gia_Man_t * pGia, Vec_Int_t * vRootLits, int nExtra, Vec_Int_t * vLeaves, Vec_Int_t * vNodes, int fSigned, int fVerbose, int fVeryVerbose ) +Vec_Wec_t * Gia_PolynBuildNew( Gia_Man_t * pGia, Vec_Wec_t * vSign, Vec_Int_t * vRootLits, int nExtra, Vec_Int_t * vLeaves, Vec_Int_t * vNodes, int fSigned, int fVerbose, int fVeryVerbose ) { abctime clk = Abc_Clock(); Vec_Wec_t * vPolyn; @@ -498,6 +660,44 @@ Vec_Wec_t * Gia_PolynBuildNew( Gia_Man_t * pGia, Vec_Int_t * vRootLits, int nExt printf( "Assigning %d outputs from %d to %d rank %d.\n", nExtra, Vec_IntSize(vRootLits)-nExtra, Vec_IntSize(vRootLits)-1, Vec_IntSize(vRootLits)-nExtra ); // create output signature + if ( vSign ) + { + Vec_Int_t * vLevel; int Entry, OutLit; + Vec_WecForEachLevel( vSign, vLevel, i ) + { + OutLit = -1; + Vec_IntClear( vTempM[0] ); + Vec_IntFill( vTempC[0], 1, Vec_IntEntryLast(vLevel) ); + Vec_IntForEachEntryStop( vLevel, Entry, k, Vec_IntSize(vLevel)-1 ) + { + if ( Entry < 0 ) // input + Vec_IntPushUniqueOrder( vTempM[0], Vec_IntEntry(vLeaves, -1-Entry) ); + else // output + { + assert( OutLit == -1 ); // only one output literal is expected + OutLit = Vec_IntEntry(vRootLits, Entry); + } + } + if ( OutLit == -1 ) + nMonos += Gia_PolynBuildAdd( pHashC, pHashM, vCoefs, vLit2Mono, vTempC[0], vTempM[0] ); // mono without out + else if ( !Abc_LitIsCompl(OutLit) ) // positive literal + { + Vec_IntPushUniqueOrder( vTempM[0], Abc_Lit2Var(OutLit) ); + nMonos += Gia_PolynBuildAdd( pHashC, pHashM, vCoefs, vLit2Mono, vTempC[0], vTempM[0] ); // mono with pos out + } + else // negative literal + { + // first monomial + nMonos += Gia_PolynBuildAdd( pHashC, pHashM, vCoefs, vLit2Mono, vTempC[0], vTempM[0] ); // mono without out + // second monomial + Vec_IntFill( vTempC[0], 1, -Vec_IntEntryLast(vLevel) ); + Vec_IntPushUniqueOrder( vTempM[0], Abc_Lit2Var(OutLit) ); + nMonos += Gia_PolynBuildAdd( pHashC, pHashM, vCoefs, vLit2Mono, vTempC[0], vTempM[0] ); // mono with neg out + } + nBuilds++; + } + } + else Vec_IntForEachEntry( vRootLits, iLit, i ) { int Value = 1 + Abc_MinInt( i, Vec_IntSize(vRootLits)-nExtra ); @@ -601,15 +801,24 @@ Vec_Wec_t * Gia_PolynBuildNew( Gia_Man_t * pGia, Vec_Int_t * vRootLits, int nExt SeeAlso [] ***********************************************************************/ -void Gia_PolynBuild2Test( Gia_Man_t * pGia, int nExtra, int fSigned, int fVerbose, int fVeryVerbose ) +void Gia_PolynBuild2Test( Gia_Man_t * pGia, char * pSign, int nExtra, int fSigned, int fVerbose, int fVeryVerbose ) { Vec_Wec_t * vPolyn; Vec_Int_t * vRootLits = Vec_IntAlloc( Gia_ManCoNum(pGia) ); Vec_Int_t * vLeaves = Vec_IntAlloc( Gia_ManCiNum(pGia) ); Vec_Int_t * vNodes = Vec_IntAlloc( Gia_ManAndNum(pGia) ); Gia_Obj_t * pObj; + Vec_Wec_t * vMonos = NULL; int i; + if ( pSign != NULL && (vMonos = Acec_ParseSignature(pSign)) == NULL ) + { + printf( "Canont parse the output signatures.\n" ); + return; + } + if ( vMonos && fVerbose ) + Acec_PrintSignature( vMonos ); + // print logic level if ( nExtra == -1 ) { @@ -633,7 +842,7 @@ void Gia_PolynBuild2Test( Gia_Man_t * pGia, int nExtra, int fSigned, int fVerbos else if ( Gia_ObjIsCo(pObj) ) Vec_IntPush( vRootLits, Gia_ObjFaninLit0p(pGia, pObj) ); - vPolyn = Gia_PolynBuildNew( pGia, vRootLits, nExtra, vLeaves, vNodes, fSigned, fVerbose, fVeryVerbose ); + vPolyn = Gia_PolynBuildNew( pGia, vMonos, vRootLits, nExtra, vLeaves, vNodes, fSigned, fVerbose, fVeryVerbose ); //printf( "Polynomial has %d monomials.\n", Vec_WecSize(vPolyn)/2 ); if ( fVerbose || fVeryVerbose ) Gia_PolynPrintStats( vPolyn ); @@ -644,6 +853,7 @@ void Gia_PolynBuild2Test( Gia_Man_t * pGia, int nExtra, int fSigned, int fVerbos Vec_IntFree( vRootLits ); Vec_IntFree( vLeaves ); Vec_IntFree( vNodes ); + Vec_WecFreeP( &vMonos ); } //////////////////////////////////////////////////////////////////////// diff --git a/src/sat/bmc/bmc.h b/src/sat/bmc/bmc.h index 71a33595..cef93bb1 100644 --- a/src/sat/bmc/bmc.h +++ b/src/sat/bmc/bmc.h @@ -58,6 +58,7 @@ struct Bmc_EsPar_t_ int fOrderNodes; int fEnumSols; int fFewerVars; + int RuntimeLim; int fVerbose; char * pTtStr; }; @@ -76,6 +77,7 @@ static inline void Bmc_EsParSetDefault( Bmc_EsPar_t * pPars ) pPars->fOrderNodes = 0; pPars->fEnumSols = 0; pPars->fFewerVars = 0; + pPars->RuntimeLim = 0; pPars->fVerbose = 1; } diff --git a/src/sat/bmc/bmcMaj.c b/src/sat/bmc/bmcMaj.c index 4f2c8db9..08571a3b 100644 --- a/src/sat/bmc/bmcMaj.c +++ b/src/sat/bmc/bmcMaj.c @@ -500,6 +500,8 @@ Exa_Man_t * Exa_ManAlloc( Bmc_EsPar_t * pPars, word * pTruth ) p->vInfo = Exa_ManTruthTables( p ); p->pSat = bmcg_sat_solver_start(); bmcg_sat_solver_set_nvars( p->pSat, p->iVar ); + if ( pPars->RuntimeLim ) + bmcg_sat_solver_set_runtime_limit( p->pSat, Abc_Clock() + pPars->RuntimeLim * CLOCKS_PER_SEC ); return p; } void Exa_ManFree( Exa_Man_t * p ) @@ -572,6 +574,59 @@ static inline int Exa_ManEval( Exa_Man_t * p ) SeeAlso [] ***********************************************************************/ +void Exa_ManDumpBlif( Exa_Man_t * p, int fCompl ) +{ + char Buffer[1000]; + char FileName[1000]; + FILE * pFile; + int i, k, iVar; + if ( fCompl ) + Abc_TtNot( p->pTruth, p->nWords ); + Extra_PrintHexadecimalString( Buffer, (unsigned *)p->pTruth, p->nVars ); + if ( fCompl ) + Abc_TtNot( p->pTruth, p->nWords ); + sprintf( FileName, "%s_%d_%d.blif", Buffer, 2, p->nNodes ); + pFile = fopen( FileName, "wb" ); + fprintf( pFile, "# Realization of the %d-input function %s using %d two-input gates:\n", p->nVars, Buffer, p->nNodes ); + fprintf( pFile, ".model %s_%d_%d\n", Buffer, 2, p->nNodes ); + fprintf( pFile, ".inputs" ); + for ( i = 0; i < p->nVars; i++ ) + fprintf( pFile, " %c", 'a'+i ); + fprintf( pFile, "\n" ); + fprintf( pFile, ".outputs F\n" ); + for ( i = p->nObjs - 1; i >= p->nVars; i-- ) + { + int iVarStart = 1 + 3*(i - p->nVars); + int Val1 = bmcg_sat_solver_read_cex_varvalue(p->pSat, iVarStart); + int Val2 = bmcg_sat_solver_read_cex_varvalue(p->pSat, iVarStart+1); + int Val3 = bmcg_sat_solver_read_cex_varvalue(p->pSat, iVarStart+2); + + fprintf( pFile, ".names" ); + for ( k = 1; k >= 0; k-- ) + { + iVar = Exa_ManFindFanin( p, i, k ); + if ( iVar >= 0 && iVar < p->nVars ) + fprintf( pFile, " %c", 'a'+iVar ); + else + fprintf( pFile, " %02d", iVar ); + } + if ( i == p->nObjs - 1 ) + fprintf( pFile, " F\n" ); + else + fprintf( pFile, " %02d\n", i ); + if ( i == p->nObjs - 1 && fCompl ) + fprintf( pFile, "00 1\n" ); + if ( (i == p->nObjs - 1 && fCompl) ^ Val1 ) + fprintf( pFile, "01 1\n" ); + if ( (i == p->nObjs - 1 && fCompl) ^ Val2 ) + fprintf( pFile, "10 1\n" ); + if ( (i == p->nObjs - 1 && fCompl) ^ Val3 ) + fprintf( pFile, "11 1\n" ); + } + fprintf( pFile, ".end\n\n" ); + fclose( pFile ); + printf( "Solution was dumped into file \"%s\".\n", FileName ); +} void Exa_ManPrintSolution( Exa_Man_t * p, int fCompl ) { int i, k, iVar; @@ -775,10 +830,18 @@ void Exa_ManExactSynthesis( Bmc_EsPar_t * pPars ) printf( "The problem has no solution.\n" ); break; } + if ( status == GLUCOSE_UNDEC ) + { + printf( "The problem timed out after %d sec.\n", pPars->RuntimeLim ); + break; + } iMint = Exa_ManEval( p ); } if ( iMint == -1 ) + { Exa_ManPrintSolution( p, fCompl ); + Exa_ManDumpBlif( p, fCompl ); + } Exa_ManFree( p ); Abc_PrintTime( 1, "Total runtime", Abc_Clock() - clkTotal ); } @@ -915,6 +978,8 @@ static Exa3_Man_t * Exa3_ManAlloc( Bmc_EsPar_t * pPars, word * pTruth ) p->vUsed3 = Vec_BitStart( (1 << p->pPars->nVars) * p->pPars->nNodes * p->nObjs * p->nObjs * p->nObjs ); p->pSat = bmcg_sat_solver_start(); bmcg_sat_solver_set_nvars( p->pSat, p->iVar ); + if ( pPars->RuntimeLim ) + bmcg_sat_solver_set_runtime_limit( p->pSat, Abc_Clock() + pPars->RuntimeLim * CLOCKS_PER_SEC ); return p; } static void Exa3_ManFree( Exa3_Man_t * p ) @@ -1267,15 +1332,17 @@ void Exa3_ManExactSynthesis( Bmc_EsPar_t * pPars ) status = bmcg_sat_solver_solve( p->pSat, NULL, 0 ); if ( pPars->fVerbose && (!pPars->fUseIncr || i % 100 == 0) ) Exa3_ManPrint( p, i, iMint, Abc_Clock() - clkTotal ); - if ( status == GLUCOSE_UNSAT ) + if ( status == GLUCOSE_UNSAT || status == GLUCOSE_UNDEC ) break; iMint = Exa3_ManEval( p ); } - if ( pPars->fVerbose ) + if ( pPars->fVerbose && status != GLUCOSE_UNDEC ) Exa3_ManPrint( p, i, iMint, Abc_Clock() - clkTotal ); if ( iMint == -1 ) Exa3_ManPrintSolution( p, fCompl ); - else + else if ( status == GLUCOSE_UNDEC ) + printf( "The problem timed out after %d sec.\n", pPars->RuntimeLim ); + else printf( "The problem has no solution.\n" ); printf( "Added = %d. Tried = %d. ", p->nUsed[1], p->nUsed[0] ); Exa3_ManFree( p ); |