#include <stdio.h>
#include "extra.h"
#include "vec.h"
#include "cut.h"
#include "cutList.h"
Go to the source code of this file.
#define Cut_ListForEachCut | ( | pList, | |||
pCut | ) |
#define Cut_ListForEachCutSafe | ( | pList, | |||
pCut, | |||||
pCut2 | ) |
#define Cut_ListForEachCutStop | ( | pList, | |||
pCut, | |||||
pStop | ) |
typedef struct Cut_HashTableStruct_t_ Cut_HashTable_t |
CFile****************************************************************
FileName [cutInt.h]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [K-feasible cut computation package.]
Synopsis [External declarations.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [
] INCLUDES /// PARAMETERS /// BASIC TYPES ///
FUNCTION DECLARATIONS ///
CFile****************************************************************
FileName [cutNode.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [K-feasible cut computation package.]
Synopsis [Procedures to compute cuts for a node.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [
] DECLARATIONS /// FUNCTION DEFINITIONS ///Function*************************************************************
Synopsis [Allocates the cut.]
Description []
SideEffects []
SeeAlso []
Definition at line 42 of file cutCut.c.
00043 { 00044 Cut_Cut_t * pCut; 00045 // cut allocation 00046 pCut = (Cut_Cut_t *)Extra_MmFixedEntryFetch( p->pMmCuts ); 00047 memset( pCut, 0, sizeof(Cut_Cut_t) ); 00048 pCut->nVarsMax = p->pParams->nVarsMax; 00049 pCut->fSimul = p->fSimul; 00050 // statistics 00051 p->nCutsAlloc++; 00052 p->nCutsCur++; 00053 if ( p->nCutsPeak < p->nCutsAlloc - p->nCutsDealloc ) 00054 p->nCutsPeak = p->nCutsAlloc - p->nCutsDealloc; 00055 return pCut; 00056 }
Function*************************************************************
Synopsis [Compares two cuts.]
Description []
SideEffects []
SeeAlso []
Definition at line 89 of file cutCut.c.
00090 { 00091 int i; 00092 if ( pCut1->nLeaves < pCut2->nLeaves ) 00093 return -1; 00094 if ( pCut1->nLeaves > pCut2->nLeaves ) 00095 return 1; 00096 for ( i = 0; i < (int)pCut1->nLeaves; i++ ) 00097 { 00098 if ( pCut1->pLeaves[i] < pCut2->pLeaves[i] ) 00099 return -1; 00100 if ( pCut1->pLeaves[i] > pCut2->pLeaves[i] ) 00101 return 1; 00102 } 00103 return 0; 00104 }
Function*************************************************************
Synopsis [Creates the trivial cut.]
Description []
SideEffects []
SeeAlso []
Definition at line 235 of file cutCut.c.
00236 { 00237 Cut_Cut_t * pCut; 00238 if ( p->pParams->fSeq ) 00239 Node <<= CUT_SHIFT; 00240 pCut = Cut_CutAlloc( p ); 00241 pCut->nLeaves = 1; 00242 pCut->pLeaves[0] = Node; 00243 pCut->uSign = Cut_NodeSign( Node ); 00244 if ( p->pParams->fTruth ) 00245 { 00246 /* 00247 if ( pCut->nVarsMax == 4 ) 00248 Cut_CutWriteTruth( pCut, p->uTruthVars[0] ); 00249 else 00250 Extra_BitCopy( pCut->nLeaves, p->uTruths[0], (uint8*)Cut_CutReadTruth(pCut) ); 00251 */ 00252 unsigned * pTruth = Cut_CutReadTruth(pCut); 00253 int i; 00254 for ( i = 0; i < p->nTruthWords; i++ ) 00255 pTruth[i] = 0xAAAAAAAA; 00256 } 00257 p->nCutsTriv++; 00258 return pCut; 00259 }
Function*************************************************************
Synopsis [Duplicates the list.]
Description []
SideEffects []
SeeAlso []
Definition at line 117 of file cutCut.c.
00118 { 00119 Cut_Cut_t * pHead = NULL, ** ppTail = &pHead; 00120 Cut_Cut_t * pTemp, * pCopy; 00121 if ( pList == NULL ) 00122 return NULL; 00123 Cut_ListForEachCut( pList, pTemp ) 00124 { 00125 pCopy = (Cut_Cut_t *)Extra_MmFixedEntryFetch( p->pMmCuts ); 00126 memcpy( pCopy, pTemp, p->EntrySize ); 00127 *ppTail = pCopy; 00128 ppTail = &pCopy->pNext; 00129 } 00130 *ppTail = NULL; 00131 return pHead; 00132 }
int Cut_CutListVerify | ( | Cut_Cut_t * | pList | ) |
Function*************************************************************
Synopsis [Verifies that the list contains only non-dominated cuts.]
Description []
SideEffects []
SeeAlso []
Definition at line 967 of file cutNode.c.
00968 { 00969 Cut_Cut_t * pCut, * pDom; 00970 Cut_ListForEachCut( pList, pCut ) 00971 { 00972 Cut_ListForEachCutStop( pList, pDom, pCut ) 00973 { 00974 if ( Cut_CutCheckDominance( pDom, pCut ) ) 00975 { 00976 int x = 0; 00977 printf( "******************* These are contained cuts:\n" ); 00978 Cut_CutPrint( pDom, 1 ); 00979 Cut_CutPrint( pDom, 1 ); 00980 00981 return 0; 00982 } 00983 } 00984 } 00985 return 1; 00986 }
Function*************************************************************
Synopsis [Merges two NULL-terminated linked lists.]
Description []
SideEffects []
SeeAlso []
Definition at line 182 of file cutCut.c.
00183 { 00184 Cut_Cut_t * pList = NULL, ** ppTail = &pList; 00185 Cut_Cut_t * pCut; 00186 while ( pList1 && pList2 ) 00187 { 00188 if ( Cut_CutCompare(pList1, pList2) < 0 ) 00189 { 00190 pCut = pList1; 00191 pList1 = pList1->pNext; 00192 } 00193 else 00194 { 00195 pCut = pList2; 00196 pList2 = pList2->pNext; 00197 } 00198 *ppTail = pCut; 00199 ppTail = &pCut->pNext; 00200 } 00201 *ppTail = pList1? pList1: pList2; 00202 return pList; 00203 }
Function*************************************************************
Synopsis [Merges two cuts.]
Description []
SideEffects []
SeeAlso []
Definition at line 167 of file cutMerge.c.
00168 { 00169 Cut_Cut_t * pRes; 00170 int * pLeaves; 00171 int Limit, nLeaves0, nLeaves1; 00172 int i, k, c; 00173 00174 assert( pCut0->nLeaves >= pCut1->nLeaves ); 00175 00176 // consider two cuts 00177 nLeaves0 = pCut0->nLeaves; 00178 nLeaves1 = pCut1->nLeaves; 00179 00180 // the case of the largest cut sizes 00181 Limit = p->pParams->nVarsMax; 00182 if ( nLeaves0 == Limit && nLeaves1 == Limit ) 00183 { 00184 for ( i = 0; i < nLeaves0; i++ ) 00185 if ( pCut0->pLeaves[i] != pCut1->pLeaves[i] ) 00186 return NULL; 00187 pRes = Cut_CutAlloc( p ); 00188 for ( i = 0; i < nLeaves0; i++ ) 00189 pRes->pLeaves[i] = pCut0->pLeaves[i]; 00190 pRes->nLeaves = pCut0->nLeaves; 00191 return pRes; 00192 } 00193 // the case when one of the cuts is the largest 00194 if ( nLeaves0 == Limit ) 00195 { 00196 for ( i = 0; i < nLeaves1; i++ ) 00197 { 00198 for ( k = nLeaves0 - 1; k >= 0; k-- ) 00199 if ( pCut0->pLeaves[k] == pCut1->pLeaves[i] ) 00200 break; 00201 if ( k == -1 ) // did not find 00202 return NULL; 00203 } 00204 pRes = Cut_CutAlloc( p ); 00205 for ( i = 0; i < nLeaves0; i++ ) 00206 pRes->pLeaves[i] = pCut0->pLeaves[i]; 00207 pRes->nLeaves = pCut0->nLeaves; 00208 return pRes; 00209 } 00210 00211 // prepare the cut 00212 if ( p->pReady == NULL ) 00213 p->pReady = Cut_CutAlloc( p ); 00214 pLeaves = p->pReady->pLeaves; 00215 00216 // compare two cuts with different numbers 00217 i = k = 0; 00218 for ( c = 0; c < Limit; c++ ) 00219 { 00220 if ( k == nLeaves1 ) 00221 { 00222 if ( i == nLeaves0 ) 00223 { 00224 p->pReady->nLeaves = c; 00225 pRes = p->pReady; p->pReady = NULL; 00226 return pRes; 00227 } 00228 pLeaves[c] = pCut0->pLeaves[i++]; 00229 continue; 00230 } 00231 if ( i == nLeaves0 ) 00232 { 00233 if ( k == nLeaves1 ) 00234 { 00235 p->pReady->nLeaves = c; 00236 pRes = p->pReady; p->pReady = NULL; 00237 return pRes; 00238 } 00239 pLeaves[c] = pCut1->pLeaves[k++]; 00240 continue; 00241 } 00242 if ( pCut0->pLeaves[i] < pCut1->pLeaves[k] ) 00243 { 00244 pLeaves[c] = pCut0->pLeaves[i++]; 00245 continue; 00246 } 00247 if ( pCut0->pLeaves[i] > pCut1->pLeaves[k] ) 00248 { 00249 pLeaves[c] = pCut1->pLeaves[k++]; 00250 continue; 00251 } 00252 pLeaves[c] = pCut0->pLeaves[i++]; 00253 k++; 00254 } 00255 if ( i < nLeaves0 || k < nLeaves1 ) 00256 return NULL; 00257 p->pReady->nLeaves = c; 00258 pRes = p->pReady; p->pReady = NULL; 00259 return pRes; 00260 }
void Cut_CutNumberList | ( | Cut_Cut_t * | pList | ) |
Function*************************************************************
Synopsis [Sets the number of the cuts in the list.]
Description []
SideEffects []
SeeAlso []
Definition at line 216 of file cutCut.c.
00217 { 00218 Cut_Cut_t * pCut; 00219 int i = 0; 00220 Cut_ListForEachCut( pList, pCut ) 00221 pCut->Num0 = i++; 00222 }
Function*************************************************************
Synopsis [Consider dropping cuts if they are useless by now.]
Description []
SideEffects []
SeeAlso []
Definition at line 323 of file cutCut.c.
00324 { 00325 printf( "\n" ); 00326 printf( "%d : %5d %5d %5d %5d %5d\n", 00327 pCut0->nLeaves, 00328 pCut0->nLeaves > 0 ? pCut0->pLeaves[0] : -1, 00329 pCut0->nLeaves > 1 ? pCut0->pLeaves[1] : -1, 00330 pCut0->nLeaves > 2 ? pCut0->pLeaves[2] : -1, 00331 pCut0->nLeaves > 3 ? pCut0->pLeaves[3] : -1, 00332 pCut0->nLeaves > 4 ? pCut0->pLeaves[4] : -1 00333 ); 00334 printf( "%d : %5d %5d %5d %5d %5d\n", 00335 pCut1->nLeaves, 00336 pCut1->nLeaves > 0 ? pCut1->pLeaves[0] : -1, 00337 pCut1->nLeaves > 1 ? pCut1->pLeaves[1] : -1, 00338 pCut1->nLeaves > 2 ? pCut1->pLeaves[2] : -1, 00339 pCut1->nLeaves > 3 ? pCut1->pLeaves[3] : -1, 00340 pCut1->nLeaves > 4 ? pCut1->pLeaves[4] : -1 00341 ); 00342 if ( pCut == NULL ) 00343 printf( "Cannot merge\n" ); 00344 else 00345 printf( "%d : %5d %5d %5d %5d %5d\n", 00346 pCut->nLeaves, 00347 pCut->nLeaves > 0 ? pCut->pLeaves[0] : -1, 00348 pCut->nLeaves > 1 ? pCut->pLeaves[1] : -1, 00349 pCut->nLeaves > 2 ? pCut->pLeaves[2] : -1, 00350 pCut->nLeaves > 3 ? pCut->pLeaves[3] : -1, 00351 pCut->nLeaves > 4 ? pCut->pLeaves[4] : -1 00352 ); 00353 }
Function*************************************************************
Synopsis [Recybles the cut.]
Description []
SideEffects []
SeeAlso []
Definition at line 69 of file cutCut.c.
00070 { 00071 p->nCutsDealloc++; 00072 p->nCutsCur--; 00073 if ( pCut->nLeaves == 1 ) 00074 p->nCutsTriv--; 00075 Extra_MmFixedEntryRecycle( p->pMmCuts, (char *)pCut ); 00076 }
Function*************************************************************
Synopsis [Recycles the list.]
Description []
SideEffects []
SeeAlso []
Definition at line 145 of file cutCut.c.
00146 { 00147 Cut_Cut_t * pCut, * pCut2; 00148 Cut_ListForEachCutSafe( pList, pCut, pCut2 ) 00149 Extra_MmFixedEntryRecycle( p->pMmCuts, (char *)pCut ); 00150 }
void Cut_NodeDoComputeCuts | ( | Cut_Man_t * | p, | |
Cut_List_t * | pSuper, | |||
int | Node, | |||
int | fCompl0, | |||
int | fCompl1, | |||
Cut_Cut_t * | pList0, | |||
Cut_Cut_t * | pList1, | |||
int | fTriv, | |||
int | TreeCode | |||
) |
Function*************************************************************
Synopsis [Computes the cuts by merging cuts at two nodes.]
Description []
SideEffects []
SeeAlso []
Definition at line 562 of file cutNode.c.
00563 { 00564 Cut_Cut_t * pStop0, * pStop1, * pTemp0, * pTemp1, * pStore0, * pStore1; 00565 int i, nCutsOld, Limit; 00566 // start with the elementary cut 00567 if ( fTriv ) 00568 { 00569 // printf( "Creating trivial cut %d.\n", Node ); 00570 pTemp0 = Cut_CutCreateTriv( p, Node ); 00571 Cut_ListAdd( pSuper, pTemp0 ); 00572 p->nNodeCuts++; 00573 } 00574 // get the cut lists of children 00575 if ( pList0 == NULL || pList1 == NULL || (p->pParams->fLocal && TreeCode) ) 00576 return; 00577 00578 // remember the old number of cuts 00579 nCutsOld = p->nCutsCur; 00580 Limit = p->pParams->nVarsMax; 00581 // get the simultation bit of the node 00582 p->fSimul = (fCompl0 ^ pList0->fSimul) & (fCompl1 ^ pList1->fSimul); 00583 // set temporary variables 00584 p->fCompl0 = fCompl0; 00585 p->fCompl1 = fCompl1; 00586 // if tree cuts are computed, make sure only the unit cuts propagate over the DAG nodes 00587 if ( TreeCode & 1 ) 00588 { 00589 assert( pList0->nLeaves == 1 ); 00590 pStore0 = pList0->pNext; 00591 pList0->pNext = NULL; 00592 } 00593 if ( TreeCode & 2 ) 00594 { 00595 assert( pList1->nLeaves == 1 ); 00596 pStore1 = pList1->pNext; 00597 pList1->pNext = NULL; 00598 } 00599 // find the point in the list where the max-var cuts begin 00600 Cut_ListForEachCut( pList0, pStop0 ) 00601 if ( pStop0->nLeaves == (unsigned)Limit ) 00602 break; 00603 Cut_ListForEachCut( pList1, pStop1 ) 00604 if ( pStop1->nLeaves == (unsigned)Limit ) 00605 break; 00606 00607 // small by small 00608 Cut_ListForEachCutStop( pList0, pTemp0, pStop0 ) 00609 Cut_ListForEachCutStop( pList1, pTemp1, pStop1 ) 00610 { 00611 if ( Cut_CutProcessTwo( p, pTemp0, pTemp1, pSuper ) ) 00612 goto Quits; 00613 } 00614 // small by large 00615 Cut_ListForEachCutStop( pList0, pTemp0, pStop0 ) 00616 Cut_ListForEachCut( pStop1, pTemp1 ) 00617 { 00618 if ( (pTemp0->uSign & pTemp1->uSign) != pTemp0->uSign ) 00619 continue; 00620 if ( Cut_CutProcessTwo( p, pTemp0, pTemp1, pSuper ) ) 00621 goto Quits; 00622 } 00623 // small by large 00624 Cut_ListForEachCutStop( pList1, pTemp1, pStop1 ) 00625 Cut_ListForEachCut( pStop0, pTemp0 ) 00626 { 00627 if ( (pTemp0->uSign & pTemp1->uSign) != pTemp1->uSign ) 00628 continue; 00629 if ( Cut_CutProcessTwo( p, pTemp0, pTemp1, pSuper ) ) 00630 goto Quits; 00631 } 00632 // large by large 00633 Cut_ListForEachCut( pStop0, pTemp0 ) 00634 Cut_ListForEachCut( pStop1, pTemp1 ) 00635 { 00636 assert( pTemp0->nLeaves == (unsigned)Limit && pTemp1->nLeaves == (unsigned)Limit ); 00637 if ( pTemp0->uSign != pTemp1->uSign ) 00638 continue; 00639 for ( i = 0; i < Limit; i++ ) 00640 if ( pTemp0->pLeaves[i] != pTemp1->pLeaves[i] ) 00641 break; 00642 if ( i < Limit ) 00643 continue; 00644 if ( Cut_CutProcessTwo( p, pTemp0, pTemp1, pSuper ) ) 00645 goto Quits; 00646 } 00647 if ( p->nNodeCuts == 0 ) 00648 p->nNodesNoCuts++; 00649 Quits: 00650 if ( TreeCode & 1 ) 00651 pList0->pNext = pStore0; 00652 if ( TreeCode & 2 ) 00653 pList1->pNext = pStore1; 00654 }
static unsigned Cut_NodeSign | ( | int | Node | ) | [inline, static] |
void Cut_TableClear | ( | Cut_HashTable_t * | pTable | ) |
int Cut_TableLookup | ( | Cut_HashTable_t * | pTable, | |
Cut_Cut_t * | pCut, | |||
int | fStore | |||
) |
int Cut_TableReadTime | ( | Cut_HashTable_t * | pTable | ) |
Cut_HashTable_t* Cut_TableStart | ( | int | Size | ) |
void Cut_TableStop | ( | Cut_HashTable_t * | pTable | ) |
void Cut_TruthCompute | ( | Cut_Man_t * | p, | |
Cut_Cut_t * | pCut, | |||
Cut_Cut_t * | pCut0, | |||
Cut_Cut_t * | pCut1, | |||
int | fCompl0, | |||
int | fCompl1 | |||
) |
Function*************************************************************
Synopsis [Performs truth table computation.]
Description []
SideEffects []
SeeAlso []
Definition at line 173 of file cutTruth.c.
00174 { 00175 // permute the first table 00176 if ( fCompl0 ) 00177 Extra_TruthNot( p->puTemp[0], Cut_CutReadTruth(pCut0), pCut->nVarsMax ); 00178 else 00179 Extra_TruthCopy( p->puTemp[0], Cut_CutReadTruth(pCut0), pCut->nVarsMax ); 00180 Extra_TruthStretch( p->puTemp[2], p->puTemp[0], pCut0->nLeaves, pCut->nVarsMax, Cut_TruthPhase(pCut, pCut0) ); 00181 // permute the second table 00182 if ( fCompl1 ) 00183 Extra_TruthNot( p->puTemp[1], Cut_CutReadTruth(pCut1), pCut->nVarsMax ); 00184 else 00185 Extra_TruthCopy( p->puTemp[1], Cut_CutReadTruth(pCut1), pCut->nVarsMax ); 00186 Extra_TruthStretch( p->puTemp[3], p->puTemp[1], pCut1->nLeaves, pCut->nVarsMax, Cut_TruthPhase(pCut, pCut1) ); 00187 // produce the resulting table 00188 if ( pCut->fCompl ) 00189 Extra_TruthNand( Cut_CutReadTruth(pCut), p->puTemp[2], p->puTemp[3], pCut->nVarsMax ); 00190 else 00191 Extra_TruthAnd( Cut_CutReadTruth(pCut), p->puTemp[2], p->puTemp[3], pCut->nVarsMax ); 00192 00193 // Ivy_TruthTestOne( *Cut_CutReadTruth(pCut) ); 00194 00195 // quit if no fancy computation is needed 00196 if ( !p->pParams->fFancy ) 00197 return; 00198 00199 if ( pCut->nLeaves != 7 ) 00200 return; 00201 00202 // count the total number of truth tables computed 00203 nTotal++; 00204 00205 // MAPPING INTO ALTERA 6-2 LOGIC BLOCKS 00206 // call this procedure to find the minimum number of common variables in the cofactors 00207 // if this number is less or equal than 3, the cut can be implemented using the 6-2 logic block 00208 if ( Extra_TruthMinCofSuppOverlap( Cut_CutReadTruth(pCut), pCut->nVarsMax, NULL ) <= 4 ) 00209 nGood++; 00210 00211 // MAPPING INTO ACTEL 2x2 CELLS 00212 // call this procedure to see if a semi-canonical form can be found in the lookup table 00213 // (if it exists, then a two-level 3-input LUT implementation of the cut exists) 00214 // Before this procedure is called, cell manager should be defined by calling 00215 // Cut_CellLoad (make sure file "cells22_daomap_iwls.txt" is available in the working dir) 00216 // if ( Cut_CellIsRunning() && pCut->nVarsMax <= 9 ) 00217 // nGood += Cut_CellTruthLookup( Cut_CutReadTruth(pCut), pCut->nVarsMax ); 00218 }
void Cut_TruthComputeOld | ( | Cut_Cut_t * | pCut, | |
Cut_Cut_t * | pCut0, | |||
Cut_Cut_t * | pCut1, | |||
int | fCompl0, | |||
int | fCompl1 | |||
) |
Function*************************************************************
Synopsis [Performs truth table computation.]
Description []
SideEffects []
SeeAlso []
Definition at line 122 of file cutTruth.c.
00123 { 00124 static unsigned uTruth0[8], uTruth1[8]; 00125 int nTruthWords = Cut_TruthWords( pCut->nVarsMax ); 00126 unsigned * pTruthRes; 00127 int i, uPhase; 00128 00129 // permute the first table 00130 uPhase = Cut_TruthPhase( pCut, pCut0 ); 00131 Extra_TruthExpand( pCut->nVarsMax, nTruthWords, Cut_CutReadTruth(pCut0), uPhase, uTruth0 ); 00132 if ( fCompl0 ) 00133 { 00134 for ( i = 0; i < nTruthWords; i++ ) 00135 uTruth0[i] = ~uTruth0[i]; 00136 } 00137 00138 // permute the second table 00139 uPhase = Cut_TruthPhase( pCut, pCut1 ); 00140 Extra_TruthExpand( pCut->nVarsMax, nTruthWords, Cut_CutReadTruth(pCut1), uPhase, uTruth1 ); 00141 if ( fCompl1 ) 00142 { 00143 for ( i = 0; i < nTruthWords; i++ ) 00144 uTruth1[i] = ~uTruth1[i]; 00145 } 00146 00147 // write the resulting table 00148 pTruthRes = Cut_CutReadTruth(pCut); 00149 00150 if ( pCut->fCompl ) 00151 { 00152 for ( i = 0; i < nTruthWords; i++ ) 00153 pTruthRes[i] = ~(uTruth0[i] & uTruth1[i]); 00154 } 00155 else 00156 { 00157 for ( i = 0; i < nTruthWords; i++ ) 00158 pTruthRes[i] = uTruth0[i] & uTruth1[i]; 00159 } 00160 }