Commit 5e0f86a2 by Alan Mishchenko

Version abc51128

parent 3a1ca9fa
No preview for this file type
......@@ -71,9 +71,6 @@ alias resynl "b; rw -l; rwz -l; b; rwz -l; b"
alias resyn2 "b; rw; rf; b; rw; rwz; b; rfz; rwz; b"
alias resyn2l "b; rw -l; rf -l; b; rw -l; rwz -l; b; rfz -l; rwz -l; b"
alias thin "rwz; rfz; b; ps"
alias reti "st; seq; ret; unseq; st"
alias retis "st; seq; ret; unseq -s; st"
alias choice "fraig_store; resyn; fraig_store; resyn2; fraig_store; fraig_restore"
alias stest "st; ps; seq; ps; unseq; st; ps; sec"
alias t "r pan2.blif; st; seq; sfpga; sec"
alias choice "fsto; resynl; fsto; resyn2l; fsto; fres"
alias t "r iscas2/s3330_edf.blif; st; seq; smap"
......@@ -235,8 +235,8 @@ Abc_Ntk_t * Abc_NtkStartRead( char * pName )
// allocate the empty network
pNtkNew = Abc_NtkAlloc( ABC_NTK_NETLIST, ABC_FUNC_SOP );
// set the specs
pNtkNew->pName = util_strsav( pName );
pNtkNew->pSpec = util_strsav( pName );
pNtkNew->pName = util_strsav( Extra_FileNameGeneric(pName) );
pNtkNew->pSpec = util_strsav( Extra_FileNameGeneric(pName) );
return pNtkNew;
}
......@@ -313,7 +313,11 @@ Abc_Ntk_t * Abc_NtkDup( Abc_Ntk_t * pNtk )
// copy the nodes
Abc_NtkForEachObj( pNtk, pObj, i )
if ( pObj->pCopy == NULL )
{
Abc_NtkDupObj(pNtkNew, pObj);
pObj->pCopy->Level = pObj->Level;
pObj->pCopy->fPhase = pObj->fPhase;
}
// connect the nodes
Abc_NtkForEachObj( pNtk, pObj, i )
{
......
......@@ -5100,17 +5100,16 @@ int Abc_CommandRetime( Abc_Frame_t * pAbc, int argc, char ** argv )
if ( Abc_NtkHasAig(pNtk) )
{
// quit if there are choice nodes
if ( Abc_NtkGetChoiceNum(pNtk) )
{
fprintf( pErr, "Currently cannot retime networks with choice nodes.\n" );
return 0;
}
if ( Abc_NtkIsStrash(pNtk) )
pNtkRes = Abc_NtkAigToSeq(pNtk);
else
{
if ( Abc_NtkGetChoiceNum(pNtk) )
{
fprintf( pErr, "Currently cannot retime networks with choice nodes.\n" );
return 0;
}
pNtkRes = Abc_NtkDup(pNtk);
}
// retime the network
if ( fForward )
Seq_NtkSeqRetimeForward( pNtkRes, fInitial, fVerbose );
......@@ -5118,11 +5117,13 @@ int Abc_CommandRetime( Abc_Frame_t * pAbc, int argc, char ** argv )
Seq_NtkSeqRetimeBackward( pNtkRes, fInitial, fVerbose );
else
Seq_NtkSeqRetimeDelay( pNtkRes, nMaxIters, fInitial, fVerbose );
// convert from the sequential AIG
// if the network is an AIG, convert the result into an AIG
if ( Abc_NtkIsStrash(pNtk) )
{
pNtkRes = Abc_NtkSeqToLogicSop( pNtkTemp = pNtkRes );
Abc_NtkDelete( pNtkTemp );
pNtkRes = Abc_NtkStrash( pNtkTemp = pNtkRes, 0, 0 );
Abc_NtkDelete( pNtkTemp );
}
}
else
......@@ -5162,7 +5163,7 @@ usage:
int Abc_CommandSeqFpga( Abc_Frame_t * pAbc, int argc, char ** argv )
{
FILE * pOut, * pErr;
Abc_Ntk_t * pNtk, * pNtkRes;
Abc_Ntk_t * pNtk, * pNtkNew, * pNtkRes;
int c, nMaxIters;
int fVerbose;
......@@ -5205,26 +5206,65 @@ int Abc_CommandSeqFpga( Abc_Frame_t * pAbc, int argc, char ** argv )
return 1;
}
if ( !Abc_NtkIsSeq(pNtk) )
if ( Abc_NtkHasAig(pNtk) )
{
fprintf( pErr, "Sequential FPGA mapping works only for sequential AIG (run \"seq\").\n" );
return 0;
// quit if there are choice nodes
if ( Abc_NtkGetChoiceNum(pNtk) )
{
fprintf( pErr, "Currently cannot map/retime networks with choice nodes.\n" );
return 0;
}
if ( Abc_NtkIsStrash(pNtk) )
pNtkNew = Abc_NtkAigToSeq(pNtk);
else
pNtkNew = Abc_NtkDup(pNtk);
}
else
{
// strash and balance the network
pNtkNew = Abc_NtkStrash( pNtk, 0, 0 );
if ( pNtkNew == NULL )
{
fprintf( pErr, "Strashing before FPGA mapping/retiming has failed.\n" );
return 1;
}
pNtkNew = Abc_NtkBalance( pNtkRes = pNtkNew, 0 );
Abc_NtkDelete( pNtkRes );
if ( pNtkNew == NULL )
{
fprintf( pErr, "Balancing before FPGA mapping has failed.\n" );
return 1;
}
// convert into a sequential AIG
pNtkNew = Abc_NtkAigToSeq( pNtkRes = pNtkNew );
Abc_NtkDelete( pNtkRes );
if ( pNtkNew == NULL )
{
fprintf( pErr, "Converting into a seq AIG before FPGA mapping/retiming has failed.\n" );
return 1;
}
fprintf( pOut, "The network was strashed and balanced before FPGA mapping/retiming.\n" );
}
// get the new network
pNtkRes = Seq_NtkFpgaMapRetime( pNtk, nMaxIters, fVerbose );
pNtkRes = Seq_NtkFpgaMapRetime( pNtkNew, nMaxIters, fVerbose );
if ( pNtkRes == NULL )
{
fprintf( pErr, "Sequential FPGA mapping has failed.\n" );
Abc_NtkDelete( pNtkNew );
return 0;
}
Abc_NtkDelete( pNtkNew );
// replace the current network
Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes );
return 0;
usage:
fprintf( pErr, "usage: sfpga [-I num] [-vh]\n" );
fprintf( pErr, "\t performs integrated sequential FPGA mapping\n" );
fprintf( pErr, "\t performs integrated sequential FPGA mapping/retiming\n" );
fprintf( pErr, "\t-I num : max number of iterations of l-value computation [default = %d]\n", nMaxIters );
fprintf( pErr, "\t-v : toggle verbose output [default = %s]\n", fVerbose? "yes": "no" );
fprintf( pErr, "\t-h : print the command usage\n");
......@@ -5245,7 +5285,7 @@ usage:
int Abc_CommandSeqMap( Abc_Frame_t * pAbc, int argc, char ** argv )
{
FILE * pOut, * pErr;
Abc_Ntk_t * pNtk, * pNtkRes;
Abc_Ntk_t * pNtk, * pNtkNew, * pNtkRes;
int c, nMaxIters;
int fVerbose;
......@@ -5255,7 +5295,7 @@ int Abc_CommandSeqMap( Abc_Frame_t * pAbc, int argc, char ** argv )
// set defaults
nMaxIters = 15;
fVerbose = 1;
fVerbose = 0;
util_getopt_reset();
while ( ( c = util_getopt( argc, argv, "Ivh" ) ) != EOF )
{
......@@ -5288,28 +5328,66 @@ int Abc_CommandSeqMap( Abc_Frame_t * pAbc, int argc, char ** argv )
return 1;
}
if ( !Abc_NtkIsSeq(pNtk) )
if ( Abc_NtkHasAig(pNtk) )
{
fprintf( pErr, "Sequential standard cell mapping works only for sequential AIG (run \"seq\").\n" );
return 1;
// quit if there are choice nodes
if ( Abc_NtkGetChoiceNum(pNtk) )
{
fprintf( pErr, "Currently cannot map/retime networks with choice nodes.\n" );
return 0;
}
if ( Abc_NtkIsStrash(pNtk) )
pNtkNew = Abc_NtkAigToSeq(pNtk);
else
pNtkNew = Abc_NtkDup(pNtk);
}
else
{
// strash and balance the network
pNtkNew = Abc_NtkStrash( pNtk, 0, 0 );
if ( pNtkNew == NULL )
{
fprintf( pErr, "Strashing before SC mapping/retiming has failed.\n" );
return 1;
}
pNtkNew = Abc_NtkBalance( pNtkRes = pNtkNew, 0 );
Abc_NtkDelete( pNtkRes );
if ( pNtkNew == NULL )
{
fprintf( pErr, "Balancing before SC mapping/retiming has failed.\n" );
return 1;
}
// convert into a sequential AIG
pNtkNew = Abc_NtkAigToSeq( pNtkRes = pNtkNew );
Abc_NtkDelete( pNtkRes );
if ( pNtkNew == NULL )
{
fprintf( pErr, "Converting into a seq AIG before SC mapping/retiming has failed.\n" );
return 1;
}
fprintf( pOut, "The network was strashed and balanced before SC mapping/retiming.\n" );
}
// printf( "This command is not yet implemented.\n" );
// return 0;
// get the new network
pNtkRes = Seq_MapRetime( pNtk, nMaxIters, fVerbose );
pNtkRes = Seq_MapRetime( pNtkNew, nMaxIters, fVerbose );
if ( pNtkRes == NULL )
{
fprintf( pErr, "Sequential standard-cell mapping has failed.\n" );
fprintf( pErr, "Sequential FPGA mapping has failed.\n" );
Abc_NtkDelete( pNtkNew );
return 1;
}
Abc_NtkDelete( pNtkNew );
// replace the current network
Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes );
return 0;
usage:
fprintf( pErr, "usage: smap [-I num] [-vh]\n" );
fprintf( pErr, "\t performs integrated sequential standard-cell mapping" );
fprintf( pErr, "\t performs integrated sequential standard-cell mapping/retiming\n" );
fprintf( pErr, "\t-I num : max number of iterations of l-value computation [default = %d]\n", nMaxIters );
fprintf( pErr, "\t-v : toggle verbose output [default = %s]\n", fVerbose? "yes": "no" );
fprintf( pErr, "\t-h : print the command usage\n");
......
......@@ -26,6 +26,7 @@
////////////////////////////////////////////////////////////////////////
static char * Abc_NtkPrintSop( char * pSop );
static int Abc_NtkCountLogicNodes( Vec_Ptr_t * vNodes );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
......@@ -181,7 +182,7 @@ void Io_WriteDotAig( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, Vec_Ptr_t * vNodesSho
fprintf( pFile, " fontsize=18,\n" );
fprintf( pFile, " fontname = \"Times-Roman\",\n" );
fprintf( pFile, " label=\"" );
fprintf( pFile, "The set contains %d nodes and spans %d levels.", vNodes->nSize, LevelMax - LevelMin + 1 );
fprintf( pFile, "The set contains %d logic nodes and spans %d levels.", Abc_NtkCountLogicNodes(vNodes), LevelMax - LevelMin + 1 );
fprintf( pFile, "\\n" );
fprintf( pFile, "\"\n" );
fprintf( pFile, " ];\n" );
......@@ -526,7 +527,7 @@ void Io_WriteDotNtk( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, Vec_Ptr_t * vNodesSho
fprintf( pFile, " fontsize=18,\n" );
fprintf( pFile, " fontname = \"Times-Roman\",\n" );
fprintf( pFile, " label=\"" );
fprintf( pFile, "The set contains %d nodes and spans %d levels.", vNodes->nSize, LevelMax - LevelMin + 1 );
fprintf( pFile, "The set contains %d logic nodes and spans %d levels.", Abc_NtkCountLogicNodes(vNodes), LevelMax - LevelMin + 1 );
fprintf( pFile, "\\n" );
fprintf( pFile, "\"\n" );
fprintf( pFile, " ];\n" );
......@@ -701,6 +702,32 @@ char * Abc_NtkPrintSop( char * pSop )
return Buffer;
}
/**Function*************************************************************
Synopsis [Computes the printable SOP form.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_NtkCountLogicNodes( Vec_Ptr_t * vNodes )
{
Abc_Obj_t * pObj;
int i, Counter = 0;
Vec_PtrForEachEntry( vNodes, pObj, i )
{
if ( !Abc_ObjIsNode(pObj) )
continue;
if ( Abc_ObjFaninNum(pObj) == 0 && Abc_ObjFanoutNum(pObj) == 0 )
continue;
Counter ++;
}
return Counter;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
......
......@@ -67,7 +67,7 @@ extern bool Abc_NtkSeqCheck( Abc_Ntk_t * pNtk );
/*=== seqShare.c =============================================================*/
extern void Seq_NtkShareFanouts( Abc_Ntk_t * pNtk );
extern void Seq_NtkShareLatches( Abc_Ntk_t * pNtkNew, Abc_Ntk_t * pNtk );
extern void Seq_NtkShareLatchesFpga( Abc_Ntk_t * pNtkNew, Abc_Ntk_t * pNtk, Vec_Ptr_t * vMapAnds );
extern void Seq_NtkShareLatchesMapping( Abc_Ntk_t * pNtkNew, Abc_Ntk_t * pNtk, Vec_Ptr_t * vMapAnds, int fFpga );
extern void Seq_NtkShareLatchesClean( Abc_Ntk_t * pNtk );
/*=== seqUtil.c ==============================================================*/
extern char * Seq_ObjFaninGetInitPrintable( Abc_Obj_t * pObj, int Edge );
......@@ -78,6 +78,7 @@ extern int Seq_NtkLatchNumShared( Abc_Ntk_t * pNtk );
extern void Seq_NtkLatchGetInitNums( Abc_Ntk_t * pNtk, int * pInits );
extern int Seq_NtkLatchGetEqualFaninNum( Abc_Ntk_t * pNtk );
extern int Seq_NtkCountNodesAboveLimit( Abc_Ntk_t * pNtk, int Limit );
extern int Seq_MapComputeAreaFlows( Abc_Ntk_t * pNtk, int fVerbose );
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
......
......@@ -815,14 +815,14 @@ Vec_Ptr_t * Abc_NtkUtilRetimingGetMoves( Abc_Ntk_t * pNtk, Vec_Int_t * vSteps, b
if ( !fChange )
{
printf( "Warning: %d strange steps (a minor bug to be fixed later).\n", Vec_IntSize(vSteps) );
/*
/*
Vec_IntForEachEntry( vSteps, Number, i )
{
RetStep = Seq_Int2RetStep( Number );
printf( "%d(%d) ", RetStep.iNode, RetStep.nLatches );
}
printf( "\n" );
*/
*/
break;
}
}
......
......@@ -82,6 +82,7 @@ Abc_Ntk_t * Seq_NtkFpgaMapRetime( Abc_Ntk_t * pNtk, int nMaxIters, int fVerbose
// check the compatibility of initial states computed
if ( RetValue = Seq_NtkFpgaInitCompatible( pNtkNew, fVerbose ) )
printf( "The number of LUTs with incompatible edges = %d.\n", RetValue );
// create the final mapped network
pNtkMap = Seq_NtkSeqFpgaMapped( pNtkNew );
Abc_NtkDelete( pNtkNew );
......@@ -142,8 +143,6 @@ Abc_Ntk_t * Seq_NtkFpgaDup( Abc_Ntk_t * pNtk )
// transfer the mapping info to the new manager
Vec_PtrForEachEntry( p->vMapAnds, pObj, i )
{
// convert the root node
Vec_PtrWriteEntry( p->vMapAnds, i, pObj->pCopy );
// get the leaves of the cut
vLeaves = Vec_VecEntry( p->vMapCuts, i );
// convert the leaf nodes
......@@ -151,13 +150,14 @@ Abc_Ntk_t * Seq_NtkFpgaDup( Abc_Ntk_t * pNtk )
{
SeqEdge = (unsigned)pLeaf;
pLeaf = Abc_NtkObj( pNtk, SeqEdge >> 8 );
// Lag = (SeqEdge & 255);// + Seq_NodeGetLag(pObj) - Seq_NodeGetLag(pLeaf);
Lag = (SeqEdge & 255) + Seq_NodeGetLag(pObj) - Seq_NodeGetLag(pLeaf);
assert( Lag >= 0 );
// translate the old leaf into the leaf in the new network
Vec_PtrWriteEntry( vLeaves, k, (void *)((pLeaf->pCopy->Id << 8) | Lag) );
// printf( "%d -> %d\n", pLeaf->Id, pLeaf->pCopy->Id );
}
// convert the root node
Vec_PtrWriteEntry( p->vMapAnds, i, pObj->pCopy );
}
pNew = pNtkNew->pManFunc;
pNew->nVarsMax = p->nVarsMax;
......@@ -290,8 +290,9 @@ Abc_Ntk_t * Seq_NtkSeqFpgaMapped( Abc_Ntk_t * pNtk )
// duplicate the nodes used in the mapping
Vec_PtrForEachEntry( p->vMapAnds, pObj, i )
pObj->pCopy = Abc_NtkCreateNode( pNtkMap );
// create and share the latches
Seq_NtkShareLatchesFpga( pNtkMap, pNtk, p->vMapAnds );
Seq_NtkShareLatchesMapping( pNtkMap, pNtk, p->vMapAnds, 1 );
// connect the nodes
Vec_PtrForEachEntry( p->vMapAnds, pObj, i )
......
......@@ -73,6 +73,9 @@ p->timeCuts = clock() - clk;
if ( fVerbose )
Cut_ManPrintStats( p->pCutMan );
// compute area flows
// Seq_MapComputeAreaFlows( pNtk, fVerbose );
// compute the delays
clk = clock();
Seq_AigRetimeDelayLags( pNtk, fVerbose );
......@@ -170,6 +173,7 @@ Cut_Cut_t * Seq_FpgaMappingSelectCut( Abc_Obj_t * pAnd )
if ( Abc_NodeIsTravIdCurrent(pFanin) )
continue;
CostCur += (float)(1.0 / Abc_ObjFanoutNum(pFanin));
// CostCur += Seq_NodeGetFlow( pFanin );
}
if ( CostMin > CostCur )
{
......
......@@ -64,6 +64,7 @@ struct Abc_Seq_t_
Cut_Man_t * pCutMan; // cut manager
Map_SuperLib_t * pSuperLib; // the current supergate library
// sequential arrival time computation
Vec_Int_t * vAFlows; // the area flow of each cut
Vec_Int_t * vLValues; // the arrival times (L-Values of nodes)
Vec_Int_t * vLValuesN; // the arrival times (L-Values of nodes)
Vec_Str_t * vLags; // the lags of the mapped nodes
......@@ -73,6 +74,7 @@ struct Abc_Seq_t_
Vec_Ptr_t * vMapAnds; // nodes visible in the mapping
Vec_Vec_t * vMapCuts; // best cuts for each node
Vec_Vec_t * vMapDelays; // the delay of each fanin
Vec_Vec_t * vMapFanins; // the delay of each fanin
// runtime stats
int timeCuts; // runtime to compute the cuts
int timeDelay; // runtime to compute the L-values
......@@ -117,7 +119,8 @@ struct Seq_Match_t_ // 3 words
unsigned fCompl : 1; // the polarity of the AND gate
unsigned fCutInv : 1; // the polarity of the cut
unsigned PolUse : 2; // the polarity use of this node
unsigned uPhase : 28; // the phase assignment at the boundary
unsigned uPhase : 14; // the phase assignment at the boundary
unsigned uPhaseR : 14; // the real phase assignment at the boundary
};
////////////////////////////////////////////////////////////////////////
......@@ -157,8 +160,11 @@ static inline float Seq_NodeGetLValueP( Abc_Obj_t * pNode )
static inline float Seq_NodeGetLValueN( Abc_Obj_t * pNode ) { return Abc_Int2Float( Vec_IntEntry( Seq_NodeLValuesN(pNode), (pNode)->Id ) ); }
static inline void Seq_NodeSetLValueP( Abc_Obj_t * pNode, float Value ) { Vec_IntWriteEntry( Seq_NodeLValues(pNode), (pNode)->Id, Abc_Float2Int(Value) ); }
static inline void Seq_NodeSetLValueN( Abc_Obj_t * pNode, float Value ) { Vec_IntWriteEntry( Seq_NodeLValuesN(pNode), (pNode)->Id, Abc_Float2Int(Value) ); }
static inline int Seq_NodeComputeLag( int LValue, int Fi ) { return (LValue + 1024*Fi)/Fi - 1024 - (int)(LValue % Fi == 0); }
static inline int Seq_NodeComputeLagFloat( float LValue, float Fi ) { return ((int)ceil(LValue/Fi)) - 1; }
// reading area flows
static inline Vec_Int_t * Seq_NodeFlow( Abc_Obj_t * pNode ) { return ((Abc_Seq_t *)(pNode)->pNtk->pManFunc)->vAFlows; }
static inline float Seq_NodeGetFlow( Abc_Obj_t * pNode ) { return Abc_Int2Float( Vec_IntEntry( Seq_NodeFlow(pNode), (pNode)->Id ) ); }
static inline void Seq_NodeSetFlow( Abc_Obj_t * pNode, float Value ) { Vec_IntWriteEntry( Seq_NodeFlow(pNode), (pNode)->Id, Abc_Float2Int(Value) ); }
// reading the contents of the lat
static inline Abc_InitType_t Seq_LatInit( Seq_Lat_t * pLat ) { return ((unsigned)pLat->pPrev) & 3; }
......@@ -178,6 +184,8 @@ static inline char Seq_NodeGetLag( Abc_Obj_t * pNode )
static inline char Seq_NodeGetLagN( Abc_Obj_t * pNode ) { return Vec_StrEntry( Seq_NodeLagsN(pNode), (pNode)->Id ); }
static inline void Seq_NodeSetLag( Abc_Obj_t * pNode, char Value ) { Vec_StrWriteEntry( Seq_NodeLags(pNode), (pNode)->Id, (Value) ); }
static inline void Seq_NodeSetLagN( Abc_Obj_t * pNode, char Value ) { Vec_StrWriteEntry( Seq_NodeLagsN(pNode), (pNode)->Id, (Value) ); }
static inline int Seq_NodeComputeLag( int LValue, int Fi ) { return (LValue + 1024*Fi)/Fi - 1024 - (int)(LValue % Fi == 0); }
static inline int Seq_NodeComputeLagFloat( float LValue, float Fi ) { return ((int)ceil(LValue/Fi)) - 1; }
// phase usage
static inline Vec_Str_t * Seq_NodeUses( Abc_Obj_t * pNode ) { return ((Abc_Seq_t *)(pNode)->pNtk->pManFunc)->vUses; }
......
......@@ -58,6 +58,7 @@ Abc_Seq_t * Seq_Create( Abc_Ntk_t * pNtk )
p->vLValues = Vec_IntStart( p->nSize );
p->vLags = Vec_StrStart( p->nSize );
p->vLValuesN = Vec_IntStart( p->nSize );
p->vAFlows = Vec_IntStart( p->nSize );
p->vLagsN = Vec_StrStart( p->nSize );
p->vUses = Vec_StrStart( p->nSize );
return p;
......@@ -84,6 +85,7 @@ void Seq_Resize( Abc_Seq_t * p, int nMaxId )
Vec_IntFill( p->vLValues, p->nSize, 0 );
Vec_StrFill( p->vLags, p->nSize, 0 );
Vec_IntFill( p->vLValuesN, p->nSize, 0 );
Vec_IntFill( p->vAFlows, p->nSize, 0 );
Vec_StrFill( p->vLagsN, p->nSize, 0 );
Vec_StrFill( p->vUses, p->nSize, 0 );
}
......@@ -102,21 +104,24 @@ void Seq_Resize( Abc_Seq_t * p, int nMaxId )
***********************************************************************/
void Seq_Delete( Abc_Seq_t * p )
{
if ( p->fStandCells )
if ( p->fStandCells && p->vMapAnds )
{
void * pVoid; int i;
Vec_PtrForEachEntry( p->vMapAnds, pVoid, i )
free( pVoid );
}
if ( p->vMapAnds ) Vec_PtrFree( p->vMapAnds ); // the nodes used in the mapping
if ( p->vMapCuts ) Vec_VecFree( p->vMapCuts ); // the cuts used in the mapping
if ( p->vLValues ) Vec_IntFree( p->vLValues ); // the arrival times (L-Values of nodes)
if ( p->vLags ) Vec_StrFree( p->vLags ); // the lags of the mapped nodes
if ( p->vLValuesN ) Vec_IntFree( p->vLValuesN ); // the arrival times (L-Values of nodes)
if ( p->vLagsN ) Vec_StrFree( p->vLagsN ); // the lags of the mapped nodes
if ( p->vUses ) Vec_StrFree( p->vUses ); // the uses of phases
if ( p->vInits ) Vec_PtrFree( p->vInits ); // the initial values of the latches
if ( p->vNums ) Vec_IntFree( p->vNums ); // the numbers of latches
if ( p->vMapDelays ) Vec_VecFree( p->vMapDelays ); // the nodes used in the mapping
if ( p->vMapFanins ) Vec_VecFree( p->vMapFanins ); // the cuts used in the mapping
if ( p->vMapAnds ) Vec_PtrFree( p->vMapAnds ); // the nodes used in the mapping
if ( p->vMapCuts ) Vec_VecFree( p->vMapCuts ); // the cuts used in the mapping
if ( p->vLValues ) Vec_IntFree( p->vLValues ); // the arrival times (L-Values of nodes)
if ( p->vLags ) Vec_StrFree( p->vLags ); // the lags of the mapped nodes
if ( p->vLValuesN ) Vec_IntFree( p->vLValuesN ); // the arrival times (L-Values of nodes)
if ( p->vAFlows ) Vec_IntFree( p->vAFlows ); // the arrival times (L-Values of nodes)
if ( p->vLagsN ) Vec_StrFree( p->vLagsN ); // the lags of the mapped nodes
if ( p->vUses ) Vec_StrFree( p->vUses ); // the uses of phases
if ( p->vInits ) Vec_PtrFree( p->vInits ); // the initial values of the latches
if ( p->vNums ) Vec_IntFree( p->vNums ); // the numbers of latches
Extra_MmFixedStop( p->pMmInits, 0 );
free( p );
}
......
......@@ -75,11 +75,18 @@ p->timeCuts = clock() - clk;
// compute canonical forms of the truth tables of the cuts
Seq_MapCanonicizeTruthTables( pNtk );
// compute area flows
// Seq_MapComputeAreaFlows( pNtk, fVerbose );
// compute the delays
clk = clock();
FiBest = Seq_MapRetimeDelayLagsInternal( pNtk, fVerbose );
p->timeDelay = clock() - clk;
// clean the marks
Abc_NtkForEachObj( pNtk, pObj, i )
assert( !pObj->fMarkA && !pObj->fMarkB );
// collect the nodes and cuts used in the mapping
p->vMapAnds = Vec_PtrAlloc( 1000 );
p->vMapCuts = Vec_VecAlloc( 1000 );
......@@ -133,7 +140,7 @@ float Seq_MapRetimeDelayLagsInternal( Abc_Ntk_t * pNtk, int fVerbose )
}
// get the upper bound on the clock period
FiMax = Delta * (2 + Seq_NtkLevelMax(pNtk));
FiMax = Delta * (5 + Seq_NtkLevelMax(pNtk));
Delta /= 2;
// make sure this clock period is feasible
......@@ -155,11 +162,17 @@ float Seq_MapRetimeDelayLagsInternal( Abc_Ntk_t * pNtk, int fVerbose )
Seq_NodeSetLag( pNode, NodeLag );
NodeLag = Seq_NodeComputeLagFloat( Seq_NodeGetLValueN(pNode), FiBest );
Seq_NodeSetLagN( pNode, NodeLag );
//printf( "%6d=(%d,%d) ", pNode->Id, Seq_NodeGetLag(pNode), Seq_NodeGetLagN(pNode) );
// if ( Seq_NodeGetLag(pNode) != Seq_NodeGetLagN(pNode) )
// {
//printf( "%6d=(%d,%d) ", pNode->Id, Seq_NodeGetLag(pNode), Seq_NodeGetLagN(pNode) );
// }
}
//printf( "\n\n" );
// print the result
if ( fVerbose )
printf( "The best clock period is %6.2f.\n", FiBest );
// if ( fVerbose )
printf( "The best clock period after mapping/retiming is %6.2f.\n", FiBest );
return FiBest;
}
......@@ -209,7 +222,7 @@ int Seq_MapRetimeForPeriod( Abc_Ntk_t * pNtk, float Fi, int fVerbose )
// set l-values of all nodes to be minus infinity
Vec_IntFill( p->vLValues, p->nSize, Abc_Float2Int( (float)-ABC_INFINITY ) );
Vec_IntFill( p->vLValuesN, p->nSize, Abc_Float2Int( (float)-ABC_INFINITY ) );
Vec_StrFill( p->vUses, p->nSize, 0 );
Vec_StrFill( p->vUses, p->nSize, 0 );
// set l-values of constants and PIs
pObj = Abc_NtkObj( pNtk, 0 );
......@@ -243,6 +256,7 @@ int Seq_MapRetimeForPeriod( Abc_Ntk_t * pNtk, float Fi, int fVerbose )
break;
if ( fChange == 0 )
break;
//printf( "\n\n" );
}
if ( c == p->nMaxIters )
{
......@@ -265,7 +279,6 @@ int Seq_MapRetimeForPeriod( Abc_Ntk_t * pNtk, float Fi, int fVerbose )
/**Function*************************************************************
Synopsis [Computes the l-value of the cut.]
......@@ -325,6 +338,15 @@ float Seq_MapNodeComputeCut( Abc_Obj_t * pObj, Cut_Cut_t * pCut, int fCompl, fl
assert( pCut->nLeaves < 6 );
// get the canonical truth table of this cut
uCanon[0] = uCanon[1] = (fCompl? pCut->uCanon0 : pCut->uCanon1);
if ( uCanon[0] == 0 || ~uCanon[0] == 0 )
{
if ( pMatchBest )
{
memset( pMatchBest, 0, sizeof(Seq_Match_t) );
pMatchBest->pCut = pCut;
}
return (float)0.0;
}
// match the given phase of the cut
pSuperList = Map_SuperTableLookupC( p->pSuperLib, uCanon );
// compute the arrival times of each supergate
......@@ -340,7 +362,7 @@ float Seq_MapNodeComputeCut( Abc_Obj_t * pObj, Cut_Cut_t * pCut, int fCompl, fl
pMatchCur->uPhase = (fCompl? pCut->Num0 : pCut->Num1) ^ pSuper->uPhases[i];
// find the arrival time of this match
lValueCur = Seq_MapSuperGetArrival( pObj, Fi, pMatchCur, lValueBest );
if ( lValueBest > lValueCur )
if ( lValueBest > lValueCur )//&& lValueCur > -ABC_INFINITY/2 )
{
lValueBest = lValueCur;
if ( pMatchBest )
......@@ -348,6 +370,7 @@ float Seq_MapNodeComputeCut( Abc_Obj_t * pObj, Cut_Cut_t * pCut, int fCompl, fl
}
}
}
// assert( lValueBest < ABC_INFINITY/2 );
return lValueBest;
}
......@@ -366,22 +389,23 @@ float Seq_MapNodeComputePhase( Abc_Obj_t * pObj, int fCompl, float Fi, Seq_Match
{
Seq_Match_t Match, * pMatchCur = &Match;
Cut_Cut_t * pList, * pCut;
float lValueNew, lValueCut;
float lValueBest, lValueCut;
// get the list of cuts
pList = Abc_NodeReadCuts( Seq_NodeCutMan(pObj), pObj );
// get the arrival time of the best non-trivial cut
lValueNew = ABC_INFINITY;
lValueBest = ABC_INFINITY;
for ( pCut = pList->pNext; pCut; pCut = pCut->pNext )
{
lValueCut = Seq_MapNodeComputeCut( pObj, pCut, fCompl, Fi, pMatchBest? pMatchCur : NULL );
if ( lValueNew > lValueCut )
if ( lValueBest > lValueCut )
{
lValueNew = lValueCut;
lValueBest = lValueCut;
if ( pMatchBest )
*pMatchBest = *pMatchCur;
}
}
return lValueNew;
// assert( lValueBest < ABC_INFINITY/2 );
return lValueBest;
}
/**Function*************************************************************
......@@ -434,11 +458,14 @@ int Seq_MapNodeUpdateLValue( Abc_Obj_t * pObj, float Fi, float DelayInv )
// compare
if ( lValue0 <= lValueOld0 + p->fEpsilon && lValue1 <= lValueOld1 + p->fEpsilon )
return SEQ_UPDATE_NO;
assert( lValue0 < ABC_INFINITY/2 );
assert( lValue1 < ABC_INFINITY/2 );
// update the values
if ( lValue0 > lValueOld0 + p->fEpsilon )
Seq_NodeSetLValueN( pObj, lValue0 );
if ( lValue1 > lValueOld1 + p->fEpsilon )
Seq_NodeSetLValueP( pObj, lValue1 );
//printf( "%6d=(%4.2f,%4.2f) ", pObj->Id, Seq_NodeGetLValueP(pObj), Seq_NodeGetLValueN(pObj) );
return SEQ_UPDATE_YES;
}
......@@ -460,6 +487,7 @@ float Seq_MapCollectNode_rec( Abc_Obj_t * pAnd, float FiBest, Vec_Ptr_t * vMappi
Seq_Match_t * pMatch;
Abc_Obj_t * pFanin;
int k, fCompl, Use;
float AreaInv = Mio_LibraryReadAreaInv(Abc_FrameReadLibGen());
float Area;
// get the polarity of the node
......@@ -467,42 +495,44 @@ float Seq_MapCollectNode_rec( Abc_Obj_t * pAnd, float FiBest, Vec_Ptr_t * vMappi
pAnd = Abc_ObjRegular(pAnd);
// skip visited nodes
if ( fCompl )
{
if ( pAnd->fMarkB )
if ( !fCompl )
{ // need the positive polarity
if ( pAnd->fMarkA )
return 0.0;
pAnd->fMarkB = 1;
pAnd->fMarkA = 1;
}
else
{
if ( pAnd->fMarkA )
{ // need the negative polarity
if ( pAnd->fMarkB )
return 0.0;
pAnd->fMarkA = 1;
pAnd->fMarkB = 1;
}
// skip if this is a non-PI node
// skip if this is a PI or a constant
if ( !Abc_NodeIsAigAnd(pAnd) )
{
if ( Abc_ObjIsPi(pAnd) && fCompl )
return Mio_LibraryReadAreaInv(Abc_FrameReadLibGen());
return AreaInv;
return 0.0;
}
// check the uses of this node
Use = Seq_NodeGetUses( pAnd );
if ( fCompl && Use == 2 ) // the neg phase is required; the pos phase is used
if ( !fCompl && Use == 1 ) // the pos phase is required; only the neg phase is used
{
Area = Seq_MapCollectNode_rec( pAnd, FiBest, vMapping, vMapCuts );
return Area + Mio_LibraryReadAreaInv(Abc_FrameReadLibGen());
Area = Seq_MapCollectNode_rec( Abc_ObjNot(pAnd), FiBest, vMapping, vMapCuts );
return Area + AreaInv;
}
if ( !fCompl && Use == 1 ) // the pos phase is required; the neg phase is used
if ( fCompl && Use == 2 ) // the neg phase is required; only the pos phase is used
{
Area = Seq_MapCollectNode_rec( Abc_ObjNot(pAnd), FiBest, vMapping, vMapCuts );
return Area + Mio_LibraryReadAreaInv(Abc_FrameReadLibGen());
Area = Seq_MapCollectNode_rec( pAnd, FiBest, vMapping, vMapCuts );
return Area + AreaInv;
}
// both phases are used; the needed one can be selected
// get the best match
pMatch = ALLOC( Seq_Match_t, 1 );
memset( pMatch, 1, sizeof(Seq_Match_t) );
Seq_MapNodeComputePhase( pAnd, fCompl, FiBest, pMatch );
pMatch->pAnd = pAnd;
pMatch->fCompl = fCompl;
......@@ -510,7 +540,7 @@ float Seq_MapCollectNode_rec( Abc_Obj_t * pAnd, float FiBest, Vec_Ptr_t * vMappi
pMatch->PolUse = Use;
// call for the fanin cuts
Area = pMatch->pSuper->Area;
Area = pMatch->pSuper? pMatch->pSuper->Area : (float)0.0;
for ( k = 0; k < (int)pMatch->pCut->nLeaves; k++ )
{
pFanin = Abc_NtkObj( pAnd->pNtk, pMatch->pCut->pLeaves[k] >> 8 );
......@@ -524,6 +554,9 @@ float Seq_MapCollectNode_rec( Abc_Obj_t * pAnd, float FiBest, Vec_Ptr_t * vMappi
for ( k = 0; k < (int)pMatch->pCut->nLeaves; k++ )
Vec_VecPush( vMapCuts, Vec_PtrSize(vMapping)-1, (void *)pMatch->pCut->pLeaves[k] );
// the cut will become unavailable when the cuts are deallocated
pMatch->pCut = NULL;
return Area;
}
......@@ -551,6 +584,7 @@ void Seq_MapCanonicizeTruthTables( Abc_Ntk_t * pNtk )
}
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
......@@ -31,6 +31,9 @@ static int Seq_NtkMappingForPeriod( Abc_Ntk_t * pNtk, float Fi, int fVerbose )
static int Seq_NtkNodeUpdateLValue( Abc_Obj_t * pObj, float Fi, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vDelays );
static void Seq_NodeRetimeSetLag_rec( Abc_Obj_t * pNode, char Lag );
static void Seq_NodePrintInfo( Abc_Obj_t * pNode );
static void Seq_NodePrintInfoPlus( Abc_Obj_t * pNode );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
......@@ -60,6 +63,7 @@ void Seq_NtkRetimeDelayLags( Abc_Ntk_t * pNtkOld, Abc_Ntk_t * pNtk, int fVerbose
assert( p->vMapAnds );
assert( p->vMapCuts );
assert( p->vMapDelays );
assert( p->vMapFanins );
// guess the upper bound on the clock period
if ( Abc_NtkHasMapping(pNtkOld) )
......@@ -107,6 +111,11 @@ void Seq_NtkRetimeDelayLags( Abc_Ntk_t * pNtkOld, Abc_Ntk_t * pNtk, int fVerbose
Vec_StrFill( p->vLags, p->nSize, 0 );
Vec_PtrForEachEntry( p->vMapAnds, pNode, i )
{
if ( Vec_PtrSize( Vec_VecEntry(p->vMapCuts, i) ) == 0 )
{
Seq_NodeSetLag( pNode, 0 );
continue;
}
NodeLag = Seq_NodeComputeLagFloat( Seq_NodeGetLValueP(pNode), FiBest );
Seq_NodeRetimeSetLag_rec( pNode, NodeLag );
}
......@@ -117,6 +126,8 @@ void Seq_NtkRetimeDelayLags( Abc_Ntk_t * pNtkOld, Abc_Ntk_t * pNtk, int fVerbose
// print the result
if ( fVerbose )
printf( "The best clock period is %6.2f.\n", FiBest );
// Seq_NodePrintInfo( Abc_NtkObj(pNtk, 847) );
}
/**Function*************************************************************
......@@ -181,6 +192,11 @@ int Seq_NtkMappingForPeriod( Abc_Ntk_t * pNtk, float Fi, int fVerbose )
Counter++;
vLeaves = Vec_VecEntry( p->vMapCuts, i );
vDelays = Vec_VecEntry( p->vMapDelays, i );
if ( Vec_PtrSize(vLeaves) == 0 )
{
Seq_NodeSetLValueP( pObj, 0.0 );
continue;
}
RetValue = Seq_NtkNodeUpdateLValue( pObj, Fi, vLeaves, vDelays );
if ( RetValue == SEQ_UPDATE_YES )
fChange = 1;
......@@ -293,6 +309,72 @@ void Seq_NodeRetimeSetLag_rec( Abc_Obj_t * pNode, char Lag )
}
/**Function*************************************************************
Synopsis [Add sequential edges.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Seq_NodePrintInfo( Abc_Obj_t * pNode )
{
Abc_Seq_t * p = pNode->pNtk->pManFunc;
Abc_Obj_t * pFanin, * pObj, * pLeaf;
Vec_Ptr_t * vLeaves;
unsigned SeqEdge;
int i, Number;
// print the node
printf( " Node = %6d. LValue = %7.2f. Lag = %2d.\n",
pNode->Id, Seq_NodeGetLValueP(pNode), Seq_NodeGetLag(pNode) );
// find the number
Vec_PtrForEachEntry( p->vMapAnds, pObj, Number )
if ( pObj == pNode )
break;
// get the leaves
vLeaves = Vec_VecEntry( p->vMapCuts, Number );
// print the leaves
Vec_PtrForEachEntry( vLeaves, pLeaf, i )
{
SeqEdge = (unsigned)pLeaf;
pFanin = Abc_NtkObj( pNode->pNtk, SeqEdge >> 8 );
// print the leaf
printf( " Fanin%d(%d) = %6d. LValue = %7.2f. Lag = %2d.\n", i, SeqEdge & 255,
pFanin->Id, Seq_NodeGetLValueP(pFanin), Seq_NodeGetLag(pFanin) );
}
}
/**Function*************************************************************
Synopsis [Add sequential edges.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Seq_NodePrintInfoPlus( Abc_Obj_t * pNode )
{
Abc_Obj_t * pFanout;
int i;
printf( "CENTRAL NODE:\n" );
Seq_NodePrintInfo( pNode );
Abc_ObjForEachFanout( pNode, pFanout, i )
{
printf( "FANOUT%d:\n", i );
Seq_NodePrintInfo( pFanout );
}
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
......
......@@ -275,15 +275,17 @@ Abc_Obj_t * Seq_NtkShareLatches_rec( Abc_Ntk_t * pNtk, Abc_Obj_t * pObj, Seq_Lat
***********************************************************************/
void Seq_NtkShareLatches( Abc_Ntk_t * pNtkNew, Abc_Ntk_t * pNtk )
{
Abc_Obj_t * pObj;
Abc_Obj_t * pObj, * pFanin;
stmm_table * tLatchMap;
int i;
assert( Abc_NtkIsSeq( pNtk ) );
tLatchMap = stmm_init_table( stmm_ptrcmp, stmm_ptrhash );
Abc_AigForEachAnd( pNtk, pObj, i )
{
Seq_NtkShareLatches_rec( pNtkNew, Abc_ObjFanin0(pObj)->pCopy, Seq_NodeGetRing(pObj,0), Seq_NodeCountLats(pObj,0), tLatchMap );
Seq_NtkShareLatches_rec( pNtkNew, Abc_ObjFanin1(pObj)->pCopy, Seq_NodeGetRing(pObj,1), Seq_NodeCountLats(pObj,1), tLatchMap );
pFanin = Abc_ObjFanin0(pObj);
Seq_NtkShareLatches_rec( pNtkNew, pFanin->pCopy, Seq_NodeGetRing(pObj,0), Seq_NodeCountLats(pObj,0), tLatchMap );
pFanin = Abc_ObjFanin1(pObj);
Seq_NtkShareLatches_rec( pNtkNew, pFanin->pCopy, Seq_NodeGetRing(pObj,1), Seq_NodeCountLats(pObj,1), tLatchMap );
}
Abc_NtkForEachPo( pNtk, pObj, i )
Seq_NtkShareLatches_rec( pNtkNew, Abc_ObjFanin0(pObj)->pCopy, Seq_NodeGetRing(pObj,0), Seq_NodeCountLats(pObj,0), tLatchMap );
......@@ -303,22 +305,36 @@ void Seq_NtkShareLatches( Abc_Ntk_t * pNtkNew, Abc_Ntk_t * pNtk )
SeeAlso []
***********************************************************************/
void Seq_NtkShareLatchesFpga( Abc_Ntk_t * pNtkNew, Abc_Ntk_t * pNtk, Vec_Ptr_t * vMapAnds )
void Seq_NtkShareLatchesMapping( Abc_Ntk_t * pNtkNew, Abc_Ntk_t * pNtk, Vec_Ptr_t * vMapAnds, int fFpga )
{
Seq_Match_t * pMatch;
Abc_Obj_t * pObj, * pFanout;
stmm_table * tLatchMap;
int i, k, nOldNodes;
Vec_Ptr_t * vNodes;
int i, k;
assert( Abc_NtkIsSeq( pNtk ) );
// start the table
tLatchMap = stmm_init_table( stmm_ptrcmp, stmm_ptrhash );
// remember the old nodes
nOldNodes = Vec_PtrSize( vMapAnds );
// add constant and PIs
Vec_PtrPush( vMapAnds, Abc_NtkConst1(pNtk) );
// create the array of all nodes with sharable fanouts
vNodes = Vec_PtrAlloc( 100 );
Vec_PtrPush( vNodes, Abc_NtkConst1(pNtk) );
Abc_NtkForEachPi( pNtk, pObj, i )
Vec_PtrPush( vMapAnds, pObj );
Vec_PtrPush( vNodes, pObj );
if ( fFpga )
{
Vec_PtrForEachEntry( vMapAnds, pObj, i )
Vec_PtrPush( vNodes, pObj );
}
else
{
Vec_PtrForEachEntry( vMapAnds, pMatch, i )
Vec_PtrPush( vNodes, pMatch->pAnd );
}
// process nodes used in the mapping
Vec_PtrForEachEntry( vMapAnds, pObj, i )
Vec_PtrForEachEntry( vNodes, pObj, i )
{
// make sure the label is clean
Abc_ObjForEachFanout( pObj, pFanout, k )
......@@ -339,7 +355,7 @@ void Seq_NtkShareLatchesFpga( Abc_Ntk_t * pNtkNew, Abc_Ntk_t * pNtk, Vec_Ptr_t *
}
stmm_free_table( tLatchMap );
// return to the old array
Vec_PtrShrink( vMapAnds, nOldNodes );
Vec_PtrFree( vNodes );
}
/**Function*************************************************************
......
......@@ -417,6 +417,50 @@ int Seq_NtkCountNodesAboveLimit( Abc_Ntk_t * pNtk, int Limit )
return Counter;
}
/**Function*************************************************************
Synopsis [Computes area flows.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Seq_MapComputeAreaFlows( Abc_Ntk_t * pNtk, int fVerbose )
{
Abc_Seq_t * p = pNtk->pManFunc;
Abc_Obj_t * pObj;
float AFlow;
int i, c;
assert( Abc_NtkIsSeq(pNtk) );
Vec_IntFill( p->vAFlows, p->nSize, Abc_Float2Int( (float)0.0 ) );
// update all values iteratively
for ( c = 0; c < 7; c++ )
{
Abc_AigForEachAnd( pNtk, pObj, i )
{
AFlow = (float)1.0 + Seq_NodeGetFlow( Abc_ObjFanin0(pObj) ) + Seq_NodeGetFlow( Abc_ObjFanin1(pObj) );
AFlow /= Abc_ObjFanoutNum(pObj);
pObj->pNext = (void *)Abc_Float2Int( AFlow );
}
Abc_AigForEachAnd( pNtk, pObj, i )
{
AFlow = Abc_Int2Float( (int)pObj->pNext );
pObj->pNext = NULL;
Seq_NodeSetFlow( pObj, AFlow );
// printf( "%5d : %6.1f\n", pObj->Id, Seq_NodeGetFlow(pObj) );
}
// printf( "\n" );
}
return 1;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment