📄 pdpairdecode.c
字号:
break; } Mvc_CubeFree( tempppMvc[i], mask ); } // the cost for the decoder, assume no i-set merge i = Ntk_NodeReadValueNum( p1 ); j = Ntk_NodeReadValueNum( p2 ); if ( iCost == NTK_COST_LIT ) value = value - 2*(i*j-1); else value = value - i*j + 1; return value;} /**Function******************************************************************** Synopsis [create a new node with a and b as inputs or merge a and b.] Description [The fanout nodes of a and b are updated.] SideEffects []******************************************************************************/Ntk_Node_t * Pd_PairNodes_Simp( Ntk_Node_t * a, Ntk_Node_t * b ){ Ntk_Node_t * pDec, * pNodeSdc, * fanout; Ntk_Pin_t * pin; array_t * lFanin, * lResub; array_t * abFanout; Ntk_Network_t * pNet; int i; int timelimit; // timeout, we gave this procedure 200 seconds most timelimit = (int) ( 200*(float)(CLOCKS_PER_SEC) ) + clock(); // create a decoder which is not added in network and has no output pNet = Ntk_NodeReadNetwork( a ); pDec = Ntk_NodeCreateDecoder( pNet, a, b ); Ntk_NodeOrderFanins( pDec ); Ntk_NetworkAddNode( pNet, pDec, 1 ); // find outputs for new node abFanout = array_alloc( Ntk_Node_t *, 0 ); Ntk_NodeForEachFanout( a, pin, fanout ) { if ( fanout == pDec || Ntk_NodeReadFaninIndex( fanout, b ) == -1 ) continue; array_insert_last( Ntk_Node_t *, abFanout, fanout ); } for ( i=0; i<array_n( abFanout ); i++ ) { if ( clock() > timelimit ) break; fanout = array_fetch( Ntk_Node_t *, abFanout, i ); // make the sdc node lFanin = array_alloc( Ntk_Node_t *, Ntk_NodeReadFaninNum( fanout ) ); Ntk_NodeReadFanins( fanout, (Ntk_Node_t **)(lFanin->space) ); lFanin->num = Ntk_NodeReadFaninNum( fanout ); array_insert_last( Ntk_Node_t *, lFanin, pDec ); lResub = array_alloc( Ntk_Node_t *, 0 ); array_insert_last( Ntk_Node_t *, lResub, pDec ); pNodeSdc = Simp_ComputeSdcResub( fanout, (struct SimpArrayStruct *)lFanin, (struct SimpArrayStruct *)lResub ); // for debug // printf("start to simplify node %s\n", Ntk_NodeGetNamePrintable( fanout ) ); // simplify with sdc Simp_NodeSimplifyDc( fanout, pNodeSdc, SIMP_SNOCOMP, SIMP_CUBE, 1, 0, 0, 0 ); Ntk_NodeDelete( pNodeSdc ); array_free( lResub ); array_free( lFanin ); // for debugging // Ntk_NodePrintCvr( stdout, fanout, 0, 0 ); } array_free( abFanout ); // Ntk_NetworkSweepIsets( pDec, 0 ); assert ( Ntk_NetworkCheck( Ntk_NodeReadNetwork(a) ) == 1 ); if ( Ntk_NodeReadFanoutNum( pDec ) ) { _MinimizeValues( pDec ); } else { // node is useless delete it here. Ntk_NetworkDeleteNode( pNet, pDec, 1, 1 ); pDec = NULL; } return pDec;}/* I add all the static functions because the current version of them are based on mdd and give me stupid results */static int _MinimizeValues( Ntk_Node_t * pDec ){ Ntk_Node_t * fanout; Ntk_Pin_t * pin; int i, j, k, *mergeValue, iValues, nVal, oVal, index, *pValues, *pVarValues, nomerge; int position, positionNew, start, nVarsIn, iVal; Vm_VarMap_t *pVm, *pVmNew; Vm_Manager_t *pManVm; Mvc_Cover_t **mvcIsets, **newIsets; Mvc_Cover_t * temp; Mvc_Cube_t * pCube, * pCubeNew; Cvr_Cover_t * pCvr, * pCvrNew; // find out any i-set can be merged since they are used together all the time // mergeValue contain info that the value belongs to which value group // initially we assume all values can be merged nVal = Ntk_NodeReadValueNum( pDec ); mergeValue = ALLOC( int, nVal ); for ( i=0; i<nVal; i++ ) { mergeValue[i] = 0; } // iValues contain how many groups we have iValues = 1; nomerge = 0; assert ( Ntk_NetworkCheck( Ntk_NodeReadNetwork(pDec) ) == 1 ); Ntk_NodeForEachFanout( pDec, pin, fanout ) { pCvr = Ntk_NodeGetFuncCvr( fanout ); pVm = Ntk_NodeGetFuncVm( fanout ); pValues = Vm_VarMapReadValuesArray( pVm ); mvcIsets = Cvr_CoverReadIsets( pCvr ); oVal = Ntk_NodeReadValueNum( fanout ); start = 0; index = Ntk_NodeReadFaninIndex( fanout, pDec ); for ( i=0; i<index; i++ ) { start += pValues[i]; } for ( i=0; i<oVal; i++ ) { if ( mvcIsets[i] == NULL ) continue; Mvc_CoverForEachCube( mvcIsets[i], pCube ) { for ( j=pValues[index]-1; j>0; j-- ) { if ( Mvc_CubeBitValue( pCube, start+j ) != Mvc_CubeBitValue( pCube, start+mergeValue[j] ) ) { for ( k=mergeValue[j]; k<j; k++ ) { if ( mergeValue[k] == mergeValue[j] && Mvc_CubeBitValue( pCube, start+j ) == Mvc_CubeBitValue( pCube, start+k ) ) { mergeValue[j] = k; break; } } // did not find any value can merge with it if ( mergeValue[j] != k ) { mergeValue[j] = j; iValues++; if ( iValues == nVal ) { // no group possible nomerge = 1; break; } } } } if ( nomerge ) break; } if ( nomerge ) break; } if ( nomerge ) break; } // mergeValue[j] contains the least value that j can be merged to if ( !nomerge ) { // justify mergeValue. this seems inefficient, but take it now // old mvsis uses sf_compress j = 1; for ( i=1; i<nVal; i++ ) { if ( mergeValue[i] > 0 ) { // mergeValue[i] must be equal to i for ( k=i+1; k<nVal; k++ ) { if ( mergeValue[k] == i ) mergeValue[k] = -j; } mergeValue[i] = -j; j++; } } // update the output nodes Ntk_NodeForEachFanout( pDec, pin, fanout ) { pCvr = Ntk_NodeGetFuncCvr( fanout ); pVm = Ntk_NodeGetFuncVm( fanout ); mvcIsets = Cvr_CoverReadIsets( pCvr ); pValues = Vm_VarMapReadValuesArray( pVm ); nVarsIn = Vm_VarMapReadVarsInNum( pVm ); oVal = Ntk_NodeReadValueNum( fanout ); index = Ntk_NodeReadFaninIndex( fanout, pDec ); pManVm = Ntk_NetworkReadManVm( Ntk_NodeReadNetwork( fanout ) ); pVarValues = ALLOC( int, nVarsIn+1 ); for ( i=0; i<nVarsIn+1; i++ ) { pVarValues[i] = pValues[i]; } pVarValues[index] = iValues; pVmNew = Vm_VarMapLookup( pManVm, nVarsIn, 1, pVarValues ); newIsets = ALLOC( Mvc_Cover_t *, oVal ); for ( iVal=0; iVal<oVal; iVal++ ) { if ( mvcIsets[iVal] ) { newIsets[iVal] = Mvc_CoverAlloc( mvcIsets[iVal]->pMem, Vm_VarMapReadValuesInNum( pVmNew ) ); // handle each cube Mvc_CoverForEachCube( mvcIsets[iVal], pCube ) { pCubeNew = Mvc_CubeAlloc( newIsets[iVal] ); Mvc_CubeBitClean( pCubeNew ); position = 0; for ( i=0; i<index; i++ ) { for ( j=0; j<pVarValues[i]; j++ ) { if ( Mvc_CubeBitValue( pCube, position+j ) ) Mvc_CubeBitInsert( pCubeNew, position+j ); } position += pVarValues[i]; } for ( j=0; j<pValues[index]; j++ ) { if ( Mvc_CubeBitValue( pCube, position+j ) ) Mvc_CubeBitInsert( pCubeNew, -mergeValue[j] + position ); } positionNew = position + pVarValues[index]; position += pValues[index]; for ( i=index+1; i<nVarsIn; i++ ) { for ( j=0; j<pVarValues[i]; j++ ) { if ( Mvc_CubeBitValue( pCube, position+j ) ) Mvc_CubeBitInsert( pCubeNew, positionNew+j ); } positionNew += pVarValues[i]; position += pVarValues[i]; } Mvc_CoverAddCubeTail( newIsets[iVal], pCubeNew ); } } else { newIsets[iVal] = NULL; } } // set the new cover to fanout pCvrNew = Cvr_CoverCreate( pVmNew, newIsets ); Ntk_NodeSetFuncVm( fanout, pVmNew ); Ntk_NodeSetFuncCvr( fanout, pCvrNew ); FREE( pVarValues ); } // update pDec pCvr = Ntk_NodeReadFuncCvr( pDec ); mvcIsets = Cvr_CoverReadIsets( pCvr ); pVm = Ntk_NodeReadFuncVm( pDec ); pValues = Vm_VarMapReadValuesArray( pVm ); nVarsIn = Vm_VarMapReadVarsInNum( pVm ); pVarValues = ALLOC( int, nVarsIn+1 ); for ( i=0; i<nVarsIn; i++ ) { pVarValues[i] = pValues[i]; } pVarValues[nVarsIn] = iValues; pVmNew = Vm_VarMapLookup( pManVm, nVarsIn, 1, pVarValues ); FREE( pVarValues ); newIsets = ALLOC( Mvc_Cover_t *, iValues ); for ( i=0; i<iValues; i++ ) { newIsets[i] = NULL; } for ( i=0; i<nVal; i++ ) { // no API for this!! if ( mvcIsets[i] == NULL ) continue; if ( newIsets[-mergeValue[i]] == NULL ) { if ( Cvr_CoverReadDefault( pCvr ) != -mergeValue[i] ) newIsets[-mergeValue[i]] = Mvc_CoverDup( mvcIsets[i] ); } else { temp = Mvc_CoverBooleanOr( newIsets[-mergeValue[i]], mvcIsets[i] ); Mvc_CoverFree( newIsets[-mergeValue[i]] ); newIsets[-mergeValue[i]] = temp; } } pCvrNew = Cvr_CoverCreate( pVmNew, newIsets ); Cvr_CoverResetDefault( pCvrNew ); Ntk_NodeSetFuncVm( pDec, pVmNew ); Ntk_NodeSetFuncCvr( pDec, pCvrNew ); Ntk_NodeSetValueNum( pDec, iValues ); } FREE( mergeValue ); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -