mirror of https://github.com/YosysHQ/abc.git
Initial changes to enable new features in the mapper
This commit is contained in:
parent
a37de7cc4d
commit
ebfd70cdf4
|
|
@ -2027,7 +2027,11 @@ SOURCE=.\src\map\if\ifCut.c
|
|||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\map\if\ifDec.c
|
||||
SOURCE=.\src\map\if\ifDec07.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\map\if\ifDec08.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
|
|
|
|||
|
|
@ -179,9 +179,10 @@ struct Abc_Ntk_t_
|
|||
Vec_Ptr_t * vBoxes; // the array of boxes
|
||||
Vec_Ptr_t * vLtlProperties;
|
||||
// the number of living objects
|
||||
int nConstrs; // the number of constraints (model checking only)
|
||||
int nObjs; // the number of live objs
|
||||
int nObjCounts[ABC_OBJ_NUMBER]; // the number of objects by type
|
||||
int nObjs; // the number of live objs
|
||||
int nConstrs; // the number of constraints
|
||||
int nRealPos; // the number of real POs
|
||||
// the backup network and the step number
|
||||
Abc_Ntk_t * pNetBackup; // the pointer to the previous backup network
|
||||
int iStep; // the generation number for the given network
|
||||
|
|
|
|||
|
|
@ -110,6 +110,7 @@ Abc_Ntk_t * Abc_NtkStartFrom( Abc_Ntk_t * pNtk, Abc_NtkType_t Type, Abc_NtkFunc_
|
|||
// start the network
|
||||
pNtkNew = Abc_NtkAlloc( Type, Func, 1 );
|
||||
pNtkNew->nConstrs = pNtk->nConstrs;
|
||||
pNtkNew->nRealPos = pNtk->nRealPos;
|
||||
// duplicate the name and the spec
|
||||
pNtkNew->pName = Extra_UtilStrsav(pNtk->pName);
|
||||
pNtkNew->pSpec = Extra_UtilStrsav(pNtk->pSpec);
|
||||
|
|
@ -163,6 +164,7 @@ Abc_Ntk_t * Abc_NtkStartFromNoLatches( Abc_Ntk_t * pNtk, Abc_NtkType_t Type, Abc
|
|||
// start the network
|
||||
pNtkNew = Abc_NtkAlloc( Type, Func, 1 );
|
||||
pNtkNew->nConstrs = pNtk->nConstrs;
|
||||
pNtkNew->nRealPos = pNtk->nRealPos;
|
||||
// duplicate the name and the spec
|
||||
pNtkNew->pName = Extra_UtilStrsav(pNtk->pName);
|
||||
pNtkNew->pSpec = Extra_UtilStrsav(pNtk->pSpec);
|
||||
|
|
|
|||
|
|
@ -38,6 +38,9 @@ static Vec_Ptr_t * Abc_NtkFindGoodOrder( Abc_Ntk_t * pNtk );
|
|||
|
||||
extern void Abc_NtkBddReorder( Abc_Ntk_t * pNtk, int fVerbose );
|
||||
extern void Abc_NtkBidecResyn( Abc_Ntk_t * pNtk, int fVerbose );
|
||||
|
||||
extern void Abc_NtkCollectPoDrivers( If_Man_t * p, Abc_Ntk_t * pNtk );
|
||||
extern void Abc_NtkFreePoDrivers( If_Man_t * p );
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
|
|
@ -126,17 +129,22 @@ Abc_Ntk_t * Abc_NtkIf( Abc_Ntk_t * pNtk, If_Par_t * pPars )
|
|||
pPars->pTimesArr[c] = -ABC_INFINITY;
|
||||
}
|
||||
|
||||
// perform FPGA mapping
|
||||
// create FPGA mapper
|
||||
pIfMan = Abc_NtkToIf( pNtk, pPars );
|
||||
if ( pIfMan == NULL )
|
||||
return NULL;
|
||||
if ( pPars->fPower )
|
||||
Abc_NtkIfComputeSwitching( pNtk, pIfMan );
|
||||
|
||||
// perform FPGA mapping
|
||||
// Abc_NtkCollectPoDrivers( pIfMan, pNtk );
|
||||
if ( !If_ManPerformMapping( pIfMan ) )
|
||||
{
|
||||
Abc_NtkFreePoDrivers( pIfMan );
|
||||
If_ManStop( pIfMan );
|
||||
return NULL;
|
||||
}
|
||||
Abc_NtkFreePoDrivers( pIfMan );
|
||||
|
||||
// transform the result of mapping into the new network
|
||||
pNtkNew = Abc_NtkFromIf( pIfMan, pNtk );
|
||||
|
|
@ -691,6 +699,87 @@ Vec_Ptr_t * Abc_NtkFindGoodOrder( Abc_Ntk_t * pNtk )
|
|||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Sets PO drivers.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_NtkCollectPoDrivers( If_Man_t * p, Abc_Ntk_t * pNtk )
|
||||
{
|
||||
// 1 a 2 b 3 c 4 a+b+c 5 ab+ac+bc
|
||||
Vec_Int_t * vTemp;
|
||||
Abc_Obj_t * pObj;
|
||||
If_Obj_t * pIfObj;
|
||||
int i, g, nGroups;
|
||||
if ( pNtk->nRealPos == 0 )
|
||||
{
|
||||
printf( "PO drivers are not defined.\n" );
|
||||
return;
|
||||
}
|
||||
if ( (Abc_NtkPoNum(pNtk) - pNtk->nRealPos) % 5 != 0 )
|
||||
{
|
||||
printf( "PO drivers are not divisible by 5.\n" );
|
||||
return;
|
||||
}
|
||||
nGroups = (Abc_NtkPoNum(pNtk) - pNtk->nRealPos) / 5;
|
||||
printf( "Processing %d groups of PO drivers.\n", nGroups );
|
||||
// mark the drivers
|
||||
assert( p->pDriverCuts == NULL );
|
||||
p->pDriverCuts = ABC_CALLOC( Vec_Int_t *, If_ManObjNum(p) );
|
||||
for ( g = 0; g < nGroups; g++ )
|
||||
{
|
||||
// collect inputs
|
||||
vTemp = Vec_IntAlloc( 3 );
|
||||
for ( i = 0; i < 3; i++ )
|
||||
{
|
||||
pObj = Abc_NtkPo( pNtk, pNtk->nRealPos + g * 5 + i );
|
||||
pIfObj = If_Regular( ((If_Obj_t *)pObj->pCopy)->pFanin0 );
|
||||
Vec_IntPush( vTemp, pIfObj->Id );
|
||||
}
|
||||
Vec_IntSort( vTemp, 0 );
|
||||
// find output node
|
||||
pObj = Abc_NtkPo( pNtk, pNtk->nRealPos + g * 5 + 3 );
|
||||
pIfObj = If_Regular( ((If_Obj_t *)pObj->pCopy)->pFanin0 );
|
||||
if ( !If_ObjIsConst1(pIfObj) && p->pDriverCuts[pIfObj->Id] == NULL )
|
||||
p->pDriverCuts[pIfObj->Id] = Vec_IntDup( vTemp );
|
||||
// find output node
|
||||
pObj = Abc_NtkPo( pNtk, pNtk->nRealPos + g * 5 + 4 );
|
||||
pIfObj = If_Regular( ((If_Obj_t *)pObj->pCopy)->pFanin0 );
|
||||
if ( !If_ObjIsConst1(pIfObj) && p->pDriverCuts[pIfObj->Id] == NULL )
|
||||
{
|
||||
p->pDriverCuts[pIfObj->Id] = Vec_IntDup( vTemp );
|
||||
pIfObj->fDriver = 1;
|
||||
}
|
||||
Vec_IntFree( vTemp );
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Frees PO drivers.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_NtkFreePoDrivers( If_Man_t * p )
|
||||
{
|
||||
int i;
|
||||
if ( p->pDriverCuts == NULL )
|
||||
return;
|
||||
for ( i = 0; i < If_ManObjNum(p); i++ )
|
||||
Vec_IntFreeP( &p->pDriverCuts[i] );
|
||||
ABC_FREE( p->pDriverCuts );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
|
|
|
|||
|
|
@ -212,6 +212,8 @@ void Abc_NtkPrintStats( Abc_Ntk_t * pNtk, int fFactored, int fSaveBest, int fDum
|
|||
fprintf( pFile, " i/o =%5d/%5d", Abc_NtkPiNum(pNtk), Abc_NtkPoNum(pNtk) );
|
||||
if ( Abc_NtkConstrNum(pNtk) )
|
||||
fprintf( pFile, "(c=%d)", Abc_NtkConstrNum(pNtk) );
|
||||
if ( pNtk->nRealPos )
|
||||
fprintf( pFile, "(p=%d)", Abc_NtkPoNum(pNtk) - pNtk->nRealPos );
|
||||
fprintf( pFile, " lat =%5d", Abc_NtkLatchNum(pNtk) );
|
||||
if ( Abc_NtkIsNetlist(pNtk) )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -952,6 +952,7 @@ static int Io_MvParseLineOutputs( Io_MvMod_t * p, char * pLine )
|
|||
Vec_Ptr_t * vTokens = p->pMan->vTokens;
|
||||
char * pToken;
|
||||
int i;
|
||||
p->pNtk->nRealPos = Abc_NtkPoNum(p->pNtk);
|
||||
Io_MvSplitIntoTokens( vTokens, pLine, '\0' );
|
||||
pToken = (char *)Vec_PtrEntry(vTokens, 0);
|
||||
assert( !strcmp(pToken, "outputs") );
|
||||
|
|
|
|||
|
|
@ -161,6 +161,7 @@ struct If_Man_t_
|
|||
int fNextRound; // set to 1 after the first round
|
||||
int nChoices; // the number of choice nodes
|
||||
Vec_Int_t * vSwitching; // switching activity of each node
|
||||
Vec_Int_t ** pDriverCuts; // temporary driver cuts
|
||||
// sequential mapping
|
||||
Vec_Ptr_t * vLatchOrder; // topological ordering of latches
|
||||
Vec_Int_t * vLags; // sequentail lags of all nodes
|
||||
|
|
@ -228,7 +229,8 @@ struct If_Obj_t_
|
|||
unsigned fMark : 1; // multipurpose mark
|
||||
unsigned fVisit : 1; // multipurpose mark
|
||||
unsigned fSpec : 1; // multipurpose mark
|
||||
unsigned Level : 21; // logic level of the node
|
||||
unsigned fDriver : 1; // multipurpose mark
|
||||
unsigned Level : 20; // logic level of the node
|
||||
int Id; // integer ID
|
||||
int IdPio; // integer ID of PIs/POs
|
||||
int nRefs; // the number of references
|
||||
|
|
|
|||
|
|
@ -881,7 +881,7 @@ float If_CutAreaFlow( If_Man_t * p, If_Cut_t * pCut )
|
|||
Flow = If_CutLutArea(p, pCut);
|
||||
If_CutForEachLeaf( p, pCut, pLeaf, i )
|
||||
{
|
||||
if ( pLeaf->nRefs == 0 )
|
||||
if ( pLeaf->nRefs == 0 || If_ObjIsConst1(pLeaf) )
|
||||
Flow += If_ObjCutBest(pLeaf)->Area;
|
||||
else if ( p->pPars->fSeqMap ) // seq
|
||||
Flow += If_ObjCutBest(pLeaf)->Area / pLeaf->nRefs;
|
||||
|
|
@ -914,7 +914,7 @@ float If_CutEdgeFlow( If_Man_t * p, If_Cut_t * pCut )
|
|||
Flow = pCut->nLeaves;
|
||||
If_CutForEachLeaf( p, pCut, pLeaf, i )
|
||||
{
|
||||
if ( pLeaf->nRefs == 0 )
|
||||
if ( pLeaf->nRefs == 0 || If_ObjIsConst1(pLeaf) )
|
||||
Flow += If_ObjCutBest(pLeaf)->Edge;
|
||||
else if ( p->pPars->fSeqMap ) // seq
|
||||
Flow += If_ObjCutBest(pLeaf)->Edge / pLeaf->nRefs;
|
||||
|
|
@ -948,7 +948,7 @@ float If_CutPowerFlow( If_Man_t * p, If_Cut_t * pCut, If_Obj_t * pRoot )
|
|||
If_CutForEachLeaf( p, pCut, pLeaf, i )
|
||||
{
|
||||
Power += pSwitching[pLeaf->Id];
|
||||
if ( pLeaf->nRefs == 0 )
|
||||
if ( pLeaf->nRefs == 0 || If_ObjIsConst1(pLeaf) )
|
||||
Power += If_ObjCutBest(pLeaf)->Power;
|
||||
else if ( p->pPars->fSeqMap ) // seq
|
||||
Power += If_ObjCutBest(pLeaf)->Power / pLeaf->nRefs;
|
||||
|
|
|
|||
|
|
@ -51,6 +51,32 @@ static inline int If_WordCountOnes( unsigned uWord )
|
|||
return (uWord & 0x0000FFFF) + (uWord>>16);
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Counts the number of 1s in the signature.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
float If_CutDelaySpecial( If_Man_t * p, If_Cut_t * pCut, int fCarry )
|
||||
{
|
||||
static float Pin2Pin[2][3] = { {1.0, 1.0, 1.0}, {1.0, 1.0, 0.0} };
|
||||
If_Obj_t * pLeaf;
|
||||
float DelayCur, Delay = -IF_FLOAT_LARGE;
|
||||
int i;
|
||||
assert( pCut->nLeaves <= 3 );
|
||||
If_CutForEachLeaf( p, pCut, pLeaf, i )
|
||||
{
|
||||
DelayCur = If_ObjCutBest(pLeaf)->Delay;
|
||||
Delay = IF_MAX( Delay, Pin2Pin[fCarry][i] + DelayCur );
|
||||
}
|
||||
return Delay;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Finds the best cut for the given node.]
|
||||
|
|
@ -79,6 +105,40 @@ void If_ObjPerformMappingAnd( If_Man_t * p, If_Obj_t * pObj, int Mode, int fPrep
|
|||
else if ( Mode == 1 )
|
||||
pObj->EstRefs = (float)((2.0 * pObj->EstRefs + pObj->nRefs) / 3.0);
|
||||
}
|
||||
|
||||
// process special cut
|
||||
if ( p->pDriverCuts && p->pDriverCuts[pObj->Id] )
|
||||
{
|
||||
pCut = If_ObjCutBest(pObj);
|
||||
if ( pCut->nLeaves == 0 )
|
||||
{
|
||||
pCut->nLeaves = Vec_IntSize( p->pDriverCuts[pObj->Id] );
|
||||
Vec_IntForEachEntry( p->pDriverCuts[pObj->Id], k, i )
|
||||
pCut->pLeaves[i] = k;
|
||||
assert( pCut->pLeaves[0] <= pCut->pLeaves[1] );
|
||||
// if ( pObj->nRefs > 0 )
|
||||
// If_CutAreaRef( p, pCut );
|
||||
}
|
||||
pCut->Delay = If_CutDelaySpecial( p, pCut, pObj->fDriver );
|
||||
pCut->Area = (Mode == 2)? 1 : If_CutAreaFlow( p, pCut );
|
||||
if ( p->pPars->fEdge )
|
||||
pCut->Edge = (Mode == 2)? 3 : If_CutEdgeFlow( p, pCut );
|
||||
if ( p->pPars->fPower )
|
||||
pCut->Power = (Mode == 2)? 0 : If_CutPowerFlow( p, pCut, pObj );
|
||||
|
||||
// prepare the cutset
|
||||
pCutSet = If_ManSetupNodeCutSet( p, pObj );
|
||||
// copy best cut
|
||||
If_CutCopy( p, pCutSet->ppCuts[pCutSet->nCuts++], If_ObjCutBest(pObj) );
|
||||
// add the trivial cut to the set
|
||||
If_ManSetupCutTriv( p, pCutSet->ppCuts[pCutSet->nCuts++], pObj->Id );
|
||||
// free the cuts
|
||||
If_ManDerefNodeCutSet( p, pObj );
|
||||
assert( pCutSet->nCuts == 2 );
|
||||
return;
|
||||
}
|
||||
|
||||
// deref the selected cut
|
||||
if ( Mode && pObj->nRefs > 0 )
|
||||
If_CutAreaDeref( p, If_ObjCutBest(pObj) );
|
||||
|
||||
|
|
|
|||
|
|
@ -769,6 +769,7 @@ int If_ManCountSpecialPos( If_Man_t * p )
|
|||
return Counter;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
Loading…
Reference in New Issue