mirror of
https://github.com/YosysHQ/abc.git
synced 2026-08-29 01:13:24 +02:00
Version abc51120
This commit is contained in:
@@ -171,7 +171,11 @@ Abc_Ntk_t * Abc_NtkLogicSopToNetlist( Abc_Ntk_t * pNtk )
|
||||
//printf( "\n" );
|
||||
// duplicate all nodes
|
||||
Abc_NtkForEachNode( pNtk, pObj, i )
|
||||
{
|
||||
if ( Abc_ObjFaninNum(pObj) == 0 && Abc_ObjFanoutNum(pObj) == 0 )
|
||||
continue;
|
||||
Abc_NtkDupObj(pNtkNew, pObj);
|
||||
}
|
||||
// first add the nets to the CO drivers
|
||||
Abc_NtkForEachCo( pNtk, pObj, i )
|
||||
{
|
||||
@@ -199,6 +203,8 @@ Abc_Ntk_t * Abc_NtkLogicSopToNetlist( Abc_Ntk_t * pNtk )
|
||||
// create the missing nets
|
||||
Abc_NtkForEachNode( pNtk, pObj, i )
|
||||
{
|
||||
if ( Abc_ObjFaninNum(pObj) == 0 && Abc_ObjFanoutNum(pObj) == 0 )
|
||||
continue;
|
||||
if ( pObj->pCopy->pCopy ) // the net of the new object is already created
|
||||
continue;
|
||||
// create the new net
|
||||
|
||||
+6
-5
@@ -4474,6 +4474,8 @@ int Abc_CommandPga( Abc_Frame_t * pAbc, int argc, char ** argv )
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf( "This command is not yet implemented.\n" );
|
||||
return 0;
|
||||
|
||||
if ( !Abc_NtkIsStrash(pNtk) )
|
||||
{
|
||||
@@ -4848,7 +4850,7 @@ int Abc_CommandUnseq( Abc_Frame_t * pAbc, int argc, char ** argv )
|
||||
|
||||
// share the latches on the fanout edges
|
||||
if ( fShare )
|
||||
Seq_NtkSeqShareFanouts(pNtk);
|
||||
Seq_NtkShareFanouts(pNtk);
|
||||
|
||||
// get the new network
|
||||
pNtkRes = Abc_NtkSeqToLogicSop( pNtk );
|
||||
@@ -4971,7 +4973,6 @@ int Abc_CommandSeqFpga( Abc_Frame_t * pAbc, int argc, char ** argv )
|
||||
Abc_Ntk_t * pNtk, * pNtkRes;
|
||||
int c;
|
||||
int fVerbose;
|
||||
extern Abc_Ntk_t * Abc_NtkFpgaSeq( Abc_Ntk_t * pNtk, int fVerbose );
|
||||
|
||||
pNtk = Abc_FrameReadNet(pAbc);
|
||||
pOut = Abc_FrameReadOut(pAbc);
|
||||
@@ -5006,12 +5007,12 @@ int Abc_CommandSeqFpga( Abc_Frame_t * pAbc, int argc, char ** argv )
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf( "This command is not yet implemented.\n" );
|
||||
return 0;
|
||||
// printf( "This command is not yet implemented.\n" );
|
||||
// return 0;
|
||||
|
||||
|
||||
// get the new network
|
||||
pNtkRes = Abc_NtkFpgaSeq( pNtk, fVerbose );
|
||||
pNtkRes = Seq_NtkFpgaMapRetime( pNtk, fVerbose );
|
||||
if ( pNtkRes == NULL )
|
||||
{
|
||||
fprintf( pErr, "Sequential FPGA mapping has failed.\n" );
|
||||
|
||||
@@ -193,7 +193,7 @@ Cut_Man_t * Abc_NtkSeqCuts( Abc_Ntk_t * pNtk, Cut_Params_t * pParams )
|
||||
|
||||
// start the manager
|
||||
pParams->nIdsMax = Abc_NtkObjNumMax( pNtk );
|
||||
pParams->nCutSet = pNtk->vLats->nSize;
|
||||
pParams->nCutSet = Abc_NtkCutSetNodeNum( pNtk );
|
||||
p = Cut_ManStart( pParams );
|
||||
|
||||
// set cuts for PIs
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
|
||||
The body:
|
||||
(1) First part of the body contains binary information about the internal AIG nodes.
|
||||
Each internal AIG node is represented using two 4-byte integers.
|
||||
Each internal AIG node is represented using two edges (each edge is a 4-byte integer).
|
||||
Each integer is the fanin ID followed by 1-bit representation of the complemented attribute.
|
||||
(For example, complemented edge to node 10 will be represented as 2*10 + 1 = 21.)
|
||||
The IDs of the nodes are created as follows: Constant 1 node has ID=0.
|
||||
@@ -58,8 +58,8 @@
|
||||
Each node in the array of the internal AIG nodes has the ID assigned in that order.
|
||||
The constant 1 node is not written into the file.
|
||||
(2) Second part of the body contains binary information about the edges connecting
|
||||
the COs (POs and latch inputs) with the internal AIG nodes.
|
||||
Each edge is represented by one 4-byte integer the same way as a node fanin.
|
||||
the COs (POs and latch inputs) to the internal AIG nodes.
|
||||
Each edge is a 4-byte integer the same way as a node fanin.
|
||||
The latch initial value (2 bits) is stored in this integer.
|
||||
*/
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
#include "mainInt.h"
|
||||
|
||||
// this line should be included in the library project
|
||||
#define _LIB
|
||||
//#define _LIB
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
|
||||
+4
-1
@@ -43,8 +43,11 @@ typedef struct Abc_Seq_t_ Abc_Seq_t;
|
||||
/// FUNCTION DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/*=== seqFpgaCore.c ===============================================================*/
|
||||
extern Abc_Ntk_t * Seq_NtkFpgaMapRetime( Abc_Ntk_t * pNtk, int fVerbose );
|
||||
/*=== seqLatch.c ===============================================================*/
|
||||
extern void Seq_NodeDupLats( Abc_Obj_t * pObjNew, Abc_Obj_t * pObj, int Edge );
|
||||
extern int Seq_NodeCompareLats( Abc_Obj_t * pObj1, int Edge1, Abc_Obj_t * pObj2, int Edge2 );
|
||||
/*=== seqMan.c ===============================================================*/
|
||||
extern Abc_Seq_t * Seq_Create( Abc_Ntk_t * pNtk );
|
||||
extern void Seq_Resize( Abc_Seq_t * p, int nMaxId );
|
||||
@@ -53,7 +56,7 @@ extern void Seq_Delete( Abc_Seq_t * p );
|
||||
extern Abc_Ntk_t * Abc_NtkAigToSeq( Abc_Ntk_t * pNtk );
|
||||
extern Abc_Ntk_t * Abc_NtkSeqToLogicSop( Abc_Ntk_t * pNtk );
|
||||
/*=== seqShare.c =============================================================*/
|
||||
extern void Seq_NtkSeqShareFanouts( Abc_Ntk_t * pNtk );
|
||||
extern void Seq_NtkShareFanouts( Abc_Ntk_t * pNtk );
|
||||
/*=== seqRetCore.c ===========================================================*/
|
||||
extern void Seq_NtkSeqRetimeDelay( Abc_Ntk_t * pNtk, int fInitial, int fVerbose );
|
||||
extern void Seq_NtkSeqRetimeForward( Abc_Ntk_t * pNtk, int fInitial, int fVerbose );
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
PackageName [Construction and manipulation of sequential AIGs.]
|
||||
|
||||
Synopsis []
|
||||
Synopsis [Transformations to and from the sequential AIG.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
@@ -100,9 +100,9 @@ Abc_Ntk_t * Abc_NtkAigToSeq( Abc_Ntk_t * pNtk )
|
||||
if ( i == 0 || Abc_ObjIsLatch(pObj) )
|
||||
continue;
|
||||
pObj->pCopy = Abc_ObjAlloc( pNtkNew, pObj->Type );
|
||||
pObj->pCopy->Id = pObj->Id;
|
||||
pObj->pCopy->fPhase = pObj->fPhase;
|
||||
pObj->pCopy->Level = pObj->Level;
|
||||
pObj->pCopy->Id = pObj->Id; // the ID is the same for both
|
||||
pObj->pCopy->fPhase = pObj->fPhase; // used to work with choices
|
||||
pObj->pCopy->Level = pObj->Level; // used for upper bound on clock cycle
|
||||
Vec_PtrWriteEntry( pNtkNew->vObjs, pObj->pCopy->Id, pObj->pCopy );
|
||||
pNtkNew->nObjs++;
|
||||
}
|
||||
|
||||
+459
-62
@@ -6,7 +6,7 @@
|
||||
|
||||
PackageName [Construction and manipulation of sequential AIGs.]
|
||||
|
||||
Synopsis []
|
||||
Synopsis [The core of FPGA mapping/retiming package.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
@@ -24,8 +24,14 @@
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static Abc_Ntk_t * Seq_NtkSeqFpgaDup( Abc_Ntk_t * pNtk );
|
||||
static Abc_Ntk_t * Seq_NtkSeqFpgaMapped( Abc_Ntk_t * pNtkNew, Abc_Ntk_t * pNtk );
|
||||
static Abc_Ntk_t * Seq_NtkFpgaDup( Abc_Ntk_t * pNtk );
|
||||
static int Seq_NtkFpgaInitCompatible( Abc_Ntk_t * pNtk );
|
||||
static Abc_Ntk_t * Seq_NtkSeqFpgaMapped( Abc_Ntk_t * pNtkNew );
|
||||
static int Seq_FpgaMappingCount( Abc_Ntk_t * pNtk );
|
||||
static int Seq_FpgaMappingCount_rec( Abc_Ntk_t * pNtk, unsigned SeqEdge, Vec_Ptr_t * vLeaves );
|
||||
static DdNode * Seq_FpgaMappingBdd_rec( DdManager * dd, Abc_Ntk_t * pNtk, unsigned SeqEdge, Vec_Ptr_t * vLeaves );
|
||||
static void Seq_FpgaMappingEdges_rec( Abc_Ntk_t * pNtk, unsigned SeqEdge, Abc_Obj_t * pPrev, Vec_Ptr_t * vLeaves, Vec_Vec_t * vMapEdges );
|
||||
static Abc_Obj_t * Seq_FpgaMappingBuild_rec( Abc_Ntk_t * pNtkNew, Abc_Ntk_t * pNtk, unsigned SeqEdge, int fTop, Vec_Ptr_t * vLeaves );
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
@@ -42,23 +48,28 @@ static Abc_Ntk_t * Seq_NtkSeqFpgaMapped( Abc_Ntk_t * pNtkNew, Abc_Ntk_t * pNtk )
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Abc_Ntk_t * Seq_NtkSeqFpgaRetime( Abc_Ntk_t * pNtk, int fVerbose )
|
||||
Abc_Ntk_t * Seq_NtkFpgaMapRetime( Abc_Ntk_t * pNtk, int fVerbose )
|
||||
{
|
||||
Abc_Seq_t * p;
|
||||
Abc_Ntk_t * pNtkNew;
|
||||
Abc_Ntk_t * pNtkMap;
|
||||
int RetValue;
|
||||
// find the best mapping and retiming (p->vMapping, p->vLags)
|
||||
Seq_NtkSeqFpgaMapping( pNtk, fVerbose );
|
||||
// find the best mapping and retiming for all nodes (p->vLValues, p->vBestCuts, p->vLags)
|
||||
Seq_FpgaMappingDelays( pNtk, fVerbose );
|
||||
// duplicate the nodes contained in multiple cuts
|
||||
pNtkNew = Seq_NtkSeqFpgaDup( pNtk );
|
||||
// implement this retiming
|
||||
p = pNtkNew->pManFunc;
|
||||
RetValue = Seq_NtkImplementRetiming( pNtkNew, p->vLags, fVerbose );
|
||||
pNtkNew = Seq_NtkFpgaDup( pNtk );
|
||||
// implement the retiming
|
||||
RetValue = Seq_NtkImplementRetiming( pNtkNew, ((Abc_Seq_t *)pNtkNew->pManFunc)->vLags, fVerbose );
|
||||
if ( RetValue == 0 )
|
||||
printf( "Retiming completed but initial state computation has failed.\n" );
|
||||
// check the compatibility of initial states computed
|
||||
if ( RetValue = Seq_NtkFpgaInitCompatible( pNtkNew ) )
|
||||
{
|
||||
printf( "The number of LUTs with incompatible edges = %d.\n", RetValue );
|
||||
Abc_NtkDelete( pNtkNew );
|
||||
return NULL;
|
||||
}
|
||||
// create the final mapped network
|
||||
pNtkMap = Seq_NtkSeqFpgaMapped( pNtkNew, pNtk );
|
||||
pNtkMap = Seq_NtkSeqFpgaMapped( pNtkNew );
|
||||
Abc_NtkDelete( pNtkNew );
|
||||
return pNtkMap;
|
||||
}
|
||||
@@ -67,82 +78,169 @@ Abc_Ntk_t * Seq_NtkSeqFpgaRetime( Abc_Ntk_t * pNtk, int fVerbose )
|
||||
|
||||
Synopsis [Derives the network by duplicating some of the nodes.]
|
||||
|
||||
Description [Information about mapping is given as
|
||||
(1) array of mapping nodes (p->vMapAnds),
|
||||
(2) array of best cuts for each node (p->vMapCuts),
|
||||
(3) array of nodes subsumed by each cut (p->vMapBags),
|
||||
(4) array of lags of each node in the cut (p->vMapLags).]
|
||||
Description [Information about mapping is given as mapping nodes (p->vMapAnds)
|
||||
and best cuts for each node (p->vMapCuts).]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Abc_Ntk_t * Seq_NtkSeqFpgaDup( Abc_Ntk_t * pNtk )
|
||||
Abc_Ntk_t * Seq_NtkFpgaDup( Abc_Ntk_t * pNtk )
|
||||
{
|
||||
Abc_Seq_t * p = pNtk->pManFunc;
|
||||
Abc_Seq_t * pNew, * p = pNtk->pManFunc;
|
||||
Abc_Ntk_t * pNtkNew;
|
||||
Abc_Obj_t * pObj, * pLeaf, * pNode, * pDriver, * pDriverNew;
|
||||
Vec_Ptr_t * vLeaves, * vInside, * vLags;
|
||||
int i, k, TotalLag;
|
||||
Abc_Obj_t * pObj, * pLeaf;
|
||||
Vec_Ptr_t * vLeaves;
|
||||
unsigned SeqEdge;
|
||||
int i, k, nObjsNew;
|
||||
|
||||
assert( Abc_NtkIsSeq(pNtk) );
|
||||
|
||||
// start the network
|
||||
// start the expanded network
|
||||
pNtkNew = Abc_NtkStartFrom( pNtk, pNtk->ntkType, pNtk->ntkFunc );
|
||||
|
||||
// set the next pointers
|
||||
Abc_NtkForEachPi( pNtk, pObj, i )
|
||||
pObj->pNext = pObj->pCopy;
|
||||
Abc_NtkForEachNode( pNtk, pObj, i )
|
||||
pObj->pNext = NULL;
|
||||
|
||||
// start the new sequential AIG manager
|
||||
Seq_Resize( pNtkNew->pManFunc, 10 + Abc_NtkPiNum(pNtk) + Abc_NtkPoNum(pNtk) + Vec_VecSizeSize(p->vMapBags) );
|
||||
nObjsNew = 1 + Abc_NtkPiNum(pNtk) + Abc_NtkPoNum(pNtk) + Seq_FpgaMappingCount(pNtk);
|
||||
Seq_Resize( pNtkNew->pManFunc, nObjsNew );
|
||||
|
||||
// create the nodes
|
||||
// duplicate the nodes in the mapping
|
||||
Vec_PtrForEachEntry( p->vMapAnds, pObj, i )
|
||||
Abc_NtkDupObj( pNtkNew, pObj );
|
||||
|
||||
// recursively construct the internals of each node
|
||||
Vec_PtrForEachEntry( p->vMapAnds, pObj, i )
|
||||
{
|
||||
// make sure the leaves are assigned
|
||||
vLeaves = Vec_VecEntry( p->vMapCuts, i );
|
||||
Vec_PtrForEachEntry( vLeaves, pLeaf, k )
|
||||
{
|
||||
assert( pLeaf->pNext );
|
||||
pLeaf->pCopy = pLeaf->pNext;
|
||||
}
|
||||
// recursively construct the internals
|
||||
vInside = Vec_VecEntry( p->vMapBags, i );
|
||||
vLags = Vec_VecEntry( p->vMapLags, i );
|
||||
Vec_PtrForEachEntry( vInside, pNode, k )
|
||||
{
|
||||
Abc_NtkDupObj( pNtkNew, pNode );
|
||||
Abc_ObjAddFanin( pNode->pCopy, Abc_ObjChild0Copy(pNode) );
|
||||
Abc_ObjAddFanin( pNode->pCopy, Abc_ObjChild1Copy(pNode) );
|
||||
Abc_ObjSetFaninL( pNode->pCopy, 0, Abc_ObjFaninL(pNode, 0) );
|
||||
Abc_ObjSetFaninL( pNode->pCopy, 1, Abc_ObjFaninL(pNode, 1) );
|
||||
Seq_NodeDupLats( pNode->pCopy, pNode, 0 );
|
||||
Seq_NodeDupLats( pNode->pCopy, pNode, 1 );
|
||||
// set the lag of the new node
|
||||
TotalLag = Seq_NodeGetLag(pObj) + (char)Vec_PtrEntry(vLags, k);
|
||||
Seq_NodeSetLag( pNode->pCopy, (char)TotalLag );
|
||||
}
|
||||
// set the copy of the last node
|
||||
pObj->pNext = pObj->pCopy;
|
||||
Seq_FpgaMappingBuild_rec( pNtkNew, pNtk, pObj->Id << 8, 1, vLeaves );
|
||||
}
|
||||
assert( nObjsNew == pNtkNew->nObjs );
|
||||
|
||||
// set the POs
|
||||
Abc_NtkForEachPo( pNtk, pObj, i )
|
||||
Abc_NtkFinalize( pNtk, pNtkNew );
|
||||
|
||||
//Abc_NtkShowAig( pNtkNew );
|
||||
|
||||
// transfer the mapping info to the new manager
|
||||
Vec_PtrForEachEntry( p->vMapAnds, pObj, i )
|
||||
{
|
||||
pDriver = Abc_ObjFanin0(pObj);
|
||||
pDriverNew = Abc_ObjNotCond(pDriver->pNext, Abc_ObjFaninC0(pObj));
|
||||
Abc_ObjAddFanin( pObj->pCopy, pDriverNew );
|
||||
// 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
|
||||
Vec_PtrForEachEntry( vLeaves, pLeaf, k )
|
||||
{
|
||||
SeqEdge = (unsigned)pLeaf;
|
||||
pLeaf = Abc_NtkObj( pNtk, SeqEdge >> 8 );
|
||||
// translate the old leaf into the leaf in the new network
|
||||
Vec_PtrWriteEntry( vLeaves, k, (void *)((pLeaf->pCopy->Id << 8) | (SeqEdge & 255)) );
|
||||
// printf( "%d -> %d\n", pLeaf->Id, pLeaf->pCopy->Id );
|
||||
}
|
||||
}
|
||||
pNew = pNtkNew->pManFunc;
|
||||
pNew->nVarsMax = p->nVarsMax;
|
||||
pNew->vMapAnds = p->vMapAnds; p->vMapAnds = NULL;
|
||||
pNew->vMapCuts = p->vMapCuts; p->vMapCuts = NULL;
|
||||
|
||||
if ( !Abc_NtkCheck( pNtkNew ) )
|
||||
fprintf( stdout, "Seq_NtkSeqFpgaDup(): Network check has failed.\n" );
|
||||
fprintf( stdout, "Seq_NtkFpgaDup(): Network check has failed.\n" );
|
||||
return pNtkNew;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Checks if the initial states are compatible.]
|
||||
|
||||
Description [Checks of all the initial states on the fanins edges
|
||||
of the cut have compatible number of latches and initial states.
|
||||
If this is not true, then the mapped network with the does not have initial
|
||||
state. Returns the number of LUTs with incompatible edges.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Seq_NtkFpgaInitCompatible( Abc_Ntk_t * pNtk )
|
||||
{
|
||||
Abc_Seq_t * p = pNtk->pManFunc;
|
||||
Abc_Obj_t * pAnd, * pLeaf, * pFanout0, * pFanout1;
|
||||
Vec_Vec_t * vTotalEdges;
|
||||
Vec_Ptr_t * vLeaves, * vEdges;
|
||||
int i, k, m, Edge0, Edge1, nLatchBefore, nLatchAfter, nLatches1, nLatches2;
|
||||
unsigned SeqEdge;
|
||||
int CountBad = 0;
|
||||
|
||||
vTotalEdges = Vec_VecStart( p->nVarsMax );
|
||||
// go through all the nodes (cuts) used in the mapping
|
||||
Vec_PtrForEachEntry( p->vMapAnds, pAnd, i )
|
||||
{
|
||||
// printf( "*** Node %d.\n", pAnd->Id );
|
||||
|
||||
// get the cut of this gate
|
||||
vLeaves = Vec_VecEntry( p->vMapCuts, i );
|
||||
|
||||
// get the edges pointing to the leaves
|
||||
Vec_VecClear( vTotalEdges );
|
||||
Seq_FpgaMappingEdges_rec( pNtk, pAnd->Id << 8, NULL, vLeaves, vTotalEdges );
|
||||
|
||||
// for each leaf, consider its edges
|
||||
Vec_PtrForEachEntry( vLeaves, pLeaf, k )
|
||||
{
|
||||
SeqEdge = (unsigned)pLeaf;
|
||||
pLeaf = Abc_NtkObj( pNtk, SeqEdge >> 8 );
|
||||
nLatchBefore = SeqEdge & 255;
|
||||
|
||||
// get the resulting lag of this node
|
||||
nLatchAfter = nLatchBefore + Seq_NodeGetLag(pAnd) - Seq_NodeGetLag(pLeaf);
|
||||
assert( nLatchAfter >= 0 );
|
||||
if ( nLatchAfter == 0 )
|
||||
continue;
|
||||
|
||||
// go through the edges
|
||||
vEdges = Vec_VecEntry( vTotalEdges, k );
|
||||
pFanout0 = NULL;
|
||||
Vec_PtrForEachEntry( vEdges, pFanout1, m )
|
||||
{
|
||||
Edge1 = Abc_ObjIsComplement(pFanout1);
|
||||
pFanout1 = Abc_ObjRegular(pFanout1);
|
||||
//printf( "Fanin = %d. Fanout = %d.\n", pLeaf->Id, pFanout1->Id );
|
||||
|
||||
// make sure this is the same fanin
|
||||
if ( Edge1 )
|
||||
assert( pLeaf == Abc_ObjFanin1(pFanout1) );
|
||||
else
|
||||
assert( pLeaf == Abc_ObjFanin0(pFanout1) );
|
||||
|
||||
// save the first one
|
||||
if ( pFanout0 == NULL )
|
||||
{
|
||||
pFanout0 = pFanout1;
|
||||
Edge0 = Edge1;
|
||||
continue;
|
||||
}
|
||||
// compare the rings
|
||||
// if they have different number of latches, this is the bug
|
||||
nLatches1 = Seq_NodeCountLats(pFanout0, Edge0);
|
||||
nLatches2 = Seq_NodeCountLats(pFanout1, Edge1);
|
||||
assert( nLatches1 == nLatches2 );
|
||||
assert( nLatches1 > 0 );
|
||||
|
||||
// if they have different initial states, this is the problem
|
||||
if ( !Seq_NodeCompareLats(pFanout0, Edge0, pFanout1, Edge1) )
|
||||
{
|
||||
CountBad++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Vec_VecFree( vTotalEdges );
|
||||
return CountBad;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Derives the final mapped network.]
|
||||
@@ -154,15 +252,314 @@ Abc_Ntk_t * Seq_NtkSeqFpgaDup( Abc_Ntk_t * pNtk )
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Abc_Ntk_t * Seq_NtkSeqFpgaMapped( Abc_Ntk_t * pNtkNew, Abc_Ntk_t * pNtk )
|
||||
Abc_Ntk_t * Seq_NtkSeqFpgaMapped( Abc_Ntk_t * pNtk )
|
||||
{
|
||||
Abc_Seq_t * p = pNtk->pManFunc;
|
||||
Seq_Lat_t * pLat, * pRing;
|
||||
Abc_Ntk_t * pNtkMap;
|
||||
pNtkMap = NULL;
|
||||
Vec_Vec_t * vTotalEdges;
|
||||
Vec_Ptr_t * vLeaves, * vMapEdges;
|
||||
Abc_Obj_t * pObj, * pAnd, * pLeaf, * pFanout, * pFanin, * pLatch;
|
||||
int i, k, m, Edge, nLatches, nLatchBefore, nLatchAfter;
|
||||
unsigned SeqEdge;
|
||||
|
||||
assert( Abc_NtkIsSeq(pNtk) );
|
||||
|
||||
// start the network
|
||||
pNtkMap = Abc_NtkStartFrom( pNtk, ABC_NTK_LOGIC, ABC_FUNC_BDD );
|
||||
|
||||
// duplicate the nodes used in the mapping
|
||||
Vec_PtrForEachEntry( p->vMapAnds, pAnd, i )
|
||||
{
|
||||
pAnd->pCopy = Abc_NtkCreateNode( pNtkMap );
|
||||
// get the leaves of this gate
|
||||
vLeaves = Vec_VecEntry( p->vMapCuts, i );
|
||||
// get the BDD of the node
|
||||
pAnd->pCopy->pData = Seq_FpgaMappingBdd_rec( pNtkMap->pManFunc, pNtk, pAnd->Id << 8, vLeaves );
|
||||
Cudd_Ref( pAnd->pCopy->pData );
|
||||
}
|
||||
|
||||
// construct nodes in the mapped network
|
||||
vTotalEdges = Vec_VecStart( p->nVarsMax );
|
||||
Vec_PtrForEachEntry( p->vMapAnds, pAnd, i )
|
||||
{
|
||||
// get the leaves of this gate
|
||||
vLeaves = Vec_VecEntry( p->vMapCuts, i );
|
||||
// get the edges pointing to the leaves
|
||||
Vec_VecClear( vTotalEdges );
|
||||
Seq_FpgaMappingEdges_rec( pNtk, pAnd->Id << 8, NULL, vLeaves, vTotalEdges );
|
||||
// for each leaf, consider its edges
|
||||
Vec_PtrForEachEntry( vLeaves, pLeaf, k )
|
||||
{
|
||||
SeqEdge = (unsigned)pLeaf;
|
||||
pLeaf = Abc_NtkObj( pNtk, SeqEdge >> 8 );
|
||||
nLatchBefore = SeqEdge & 255;
|
||||
|
||||
// get the resulting lag of this node
|
||||
nLatchAfter = nLatchBefore + Seq_NodeGetLag(pAnd) - Seq_NodeGetLag(pLeaf);
|
||||
assert( nLatchAfter >= 0 );
|
||||
if ( nLatchAfter == 0 )
|
||||
{
|
||||
// add the fanin
|
||||
Abc_ObjAddFanin( pAnd->pCopy, pLeaf->pCopy );
|
||||
continue;
|
||||
}
|
||||
|
||||
// get the first edge
|
||||
vMapEdges = Vec_VecEntry( vTotalEdges, k );
|
||||
pFanout = Vec_PtrEntry( vMapEdges, 0 );
|
||||
Edge = Abc_ObjIsComplement(pFanout);
|
||||
pFanout = Abc_ObjRegular(pFanout);
|
||||
// make sure this is the same fanin
|
||||
if ( Edge )
|
||||
assert( pLeaf == Abc_ObjFanin1(pFanout) );
|
||||
else
|
||||
assert( pLeaf == Abc_ObjFanin0(pFanout) );
|
||||
nLatches = Seq_NodeCountLats(pFanout, Edge);
|
||||
assert( nLatches > 0 );
|
||||
|
||||
// for each implicit latch add the real latch
|
||||
pFanin = pLeaf->pCopy;
|
||||
pRing = Seq_NodeGetRing(pFanout, Edge);
|
||||
for ( m = 0, pLat = Seq_LatPrev(pRing); m < nLatches; m++, pLat = Seq_LatPrev(pLat) )
|
||||
{
|
||||
pLatch = Abc_NtkCreateLatch( pNtkMap );
|
||||
pLatch->pData = (void *)Seq_LatInit(pLat);
|
||||
Abc_ObjAddFanin( pLatch, pFanin );
|
||||
pFanin = pLatch;
|
||||
}
|
||||
// finally connect to the latch
|
||||
Abc_ObjAddFanin( pAnd->pCopy, pFanin );
|
||||
}
|
||||
}
|
||||
Vec_VecFree( vTotalEdges );
|
||||
|
||||
// set the POs
|
||||
Abc_NtkForEachPo( pNtk, pObj, i )
|
||||
{
|
||||
pFanin = Abc_ObjFanin0(pObj)->pCopy;
|
||||
if ( Abc_ObjFaninL0(pObj) > 0 )
|
||||
{
|
||||
pRing = Seq_NodeGetRing(pObj, 0);
|
||||
for ( m = 0, pLat = Seq_LatPrev(pRing); m < nLatches; m++, pLat = Seq_LatPrev(pLat) )
|
||||
{
|
||||
pLatch = Abc_NtkCreateLatch( pNtkMap );
|
||||
pLatch->pData = (void *)Seq_LatInit(pLat);
|
||||
Abc_ObjAddFanin( pLatch, pFanin );
|
||||
pFanin = pLatch;
|
||||
}
|
||||
}
|
||||
pFanin = Abc_ObjNotCond(pFanin, Abc_ObjFaninC0(pObj));
|
||||
Abc_ObjAddFanin( pObj->pCopy, pFanin );
|
||||
}
|
||||
|
||||
// add the latches and their names
|
||||
Abc_NtkAddDummyLatchNames( pNtkMap );
|
||||
Abc_NtkForEachLatch( pNtkMap, pLatch, i )
|
||||
{
|
||||
Vec_PtrPush( pNtkMap->vCis, pLatch );
|
||||
Vec_PtrPush( pNtkMap->vCos, pLatch );
|
||||
}
|
||||
|
||||
// fix the problem with complemented and duplicated CO edges
|
||||
Abc_NtkLogicMakeSimpleCos( pNtkMap, 1 );
|
||||
|
||||
if ( !Abc_NtkCheck( pNtkMap ) )
|
||||
fprintf( stdout, "Seq_NtkSeqFpgaMapped(): Network check has failed.\n" );
|
||||
return pNtkMap;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Counts the number of nodes in the bag.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Seq_FpgaMappingCount( Abc_Ntk_t * pNtk )
|
||||
{
|
||||
Abc_Seq_t * p = pNtk->pManFunc;
|
||||
Vec_Ptr_t * vLeaves;
|
||||
Abc_Obj_t * pAnd;
|
||||
int i, Counter = 0;
|
||||
Vec_PtrForEachEntry( p->vMapAnds, pAnd, i )
|
||||
{
|
||||
vLeaves = Vec_VecEntry( p->vMapCuts, i );
|
||||
Counter += Seq_FpgaMappingCount_rec( pNtk, pAnd->Id << 8, vLeaves );
|
||||
}
|
||||
return Counter;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Counts the number of nodes in the bag.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Seq_FpgaMappingCount_rec( Abc_Ntk_t * pNtk, unsigned SeqEdge, Vec_Ptr_t * vLeaves )
|
||||
{
|
||||
Abc_Obj_t * pObj, * pLeaf;
|
||||
unsigned SeqEdge0, SeqEdge1;
|
||||
int Lag, i;
|
||||
// get the object and the lag
|
||||
pObj = Abc_NtkObj( pNtk, SeqEdge >> 8 );
|
||||
Lag = SeqEdge & 255;
|
||||
// if the node is the fanin of the cut, return
|
||||
Vec_PtrForEachEntry( vLeaves, pLeaf, i )
|
||||
if ( SeqEdge == (unsigned)pLeaf )
|
||||
return 0;
|
||||
// continue unfolding
|
||||
assert( Abc_NodeIsAigAnd(pObj) );
|
||||
// get new sequential edges
|
||||
assert( Lag + Abc_ObjFaninL0(pObj) < 255 );
|
||||
assert( Lag + Abc_ObjFaninL1(pObj) < 255 );
|
||||
SeqEdge0 = (Abc_ObjFanin0(pObj)->Id << 8) + Lag + Abc_ObjFaninL0(pObj);
|
||||
SeqEdge1 = (Abc_ObjFanin1(pObj)->Id << 8) + Lag + Abc_ObjFaninL1(pObj);
|
||||
// call for the children
|
||||
return 1 + Seq_FpgaMappingCount_rec( pNtk, SeqEdge0, vLeaves ) +
|
||||
Seq_FpgaMappingCount_rec( pNtk, SeqEdge1, vLeaves );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Derives the BDD of the selected cut.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
DdNode * Seq_FpgaMappingBdd_rec( DdManager * dd, Abc_Ntk_t * pNtk, unsigned SeqEdge, Vec_Ptr_t * vLeaves )
|
||||
{
|
||||
Abc_Obj_t * pObj, * pLeaf;
|
||||
DdNode * bFunc0, * bFunc1, * bFunc;
|
||||
unsigned SeqEdge0, SeqEdge1;
|
||||
int Lag, i;
|
||||
// get the object and the lag
|
||||
pObj = Abc_NtkObj( pNtk, SeqEdge >> 8 );
|
||||
Lag = SeqEdge & 255;
|
||||
// if the node is the fanin of the cut, return
|
||||
Vec_PtrForEachEntry( vLeaves, pLeaf, i )
|
||||
if ( SeqEdge == (unsigned)pLeaf )
|
||||
return Cudd_bddIthVar( dd, i );
|
||||
// continue unfolding
|
||||
assert( Abc_NodeIsAigAnd(pObj) );
|
||||
// get new sequential edges
|
||||
assert( Lag + Abc_ObjFaninL0(pObj) < 255 );
|
||||
assert( Lag + Abc_ObjFaninL1(pObj) < 255 );
|
||||
SeqEdge0 = (Abc_ObjFanin0(pObj)->Id << 8) + Lag + Abc_ObjFaninL0(pObj);
|
||||
SeqEdge1 = (Abc_ObjFanin1(pObj)->Id << 8) + Lag + Abc_ObjFaninL1(pObj);
|
||||
// call for the children
|
||||
bFunc0 = Seq_FpgaMappingBdd_rec( dd, pNtk, SeqEdge0, vLeaves ); Cudd_Ref( bFunc0 );
|
||||
bFunc1 = Seq_FpgaMappingBdd_rec( dd, pNtk, SeqEdge1, vLeaves ); Cudd_Ref( bFunc1 );
|
||||
// get the BDD of the node
|
||||
bFunc = Cudd_bddAnd( dd, Cudd_NotCond(bFunc0, Abc_ObjFaninC0(pObj)), Cudd_NotCond(bFunc1, Abc_ObjFaninC1(pObj)) ); Cudd_Ref( bFunc );
|
||||
Cudd_RecursiveDeref( dd, bFunc0 );
|
||||
Cudd_RecursiveDeref( dd, bFunc1 );
|
||||
// return the BDD
|
||||
Cudd_Deref( bFunc );
|
||||
return bFunc;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Collects the edges pointing to the leaves of the cut.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Seq_FpgaMappingEdges_rec( Abc_Ntk_t * pNtk, unsigned SeqEdge, Abc_Obj_t * pPrev, Vec_Ptr_t * vLeaves, Vec_Vec_t * vMapEdges )
|
||||
{
|
||||
Abc_Obj_t * pObj, * pLeaf;
|
||||
unsigned SeqEdge0, SeqEdge1;
|
||||
int Lag, i;
|
||||
// get the object and the lag
|
||||
pObj = Abc_NtkObj( pNtk, SeqEdge >> 8 );
|
||||
Lag = SeqEdge & 255;
|
||||
// if the node is the fanin of the cut, return
|
||||
Vec_PtrForEachEntry( vLeaves, pLeaf, i )
|
||||
{
|
||||
if ( SeqEdge == (unsigned)pLeaf )
|
||||
{
|
||||
assert( pPrev != NULL );
|
||||
Vec_VecPush( vMapEdges, i, pPrev );
|
||||
return;
|
||||
}
|
||||
}
|
||||
// continue unfolding
|
||||
assert( Abc_NodeIsAigAnd(pObj) );
|
||||
// get new sequential edges
|
||||
assert( Lag + Abc_ObjFaninL0(pObj) < 255 );
|
||||
assert( Lag + Abc_ObjFaninL1(pObj) < 255 );
|
||||
SeqEdge0 = (Abc_ObjFanin0(pObj)->Id << 8) + Lag + Abc_ObjFaninL0(pObj);
|
||||
SeqEdge1 = (Abc_ObjFanin1(pObj)->Id << 8) + Lag + Abc_ObjFaninL1(pObj);
|
||||
// call for the children
|
||||
Seq_FpgaMappingEdges_rec( pNtk, SeqEdge0, pObj , vLeaves, vMapEdges );
|
||||
Seq_FpgaMappingEdges_rec( pNtk, SeqEdge1, Abc_ObjNot(pObj), vLeaves, vMapEdges );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Collects the edges pointing to the leaves of the cut.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Abc_Obj_t * Seq_FpgaMappingBuild_rec( Abc_Ntk_t * pNtkNew, Abc_Ntk_t * pNtk, unsigned SeqEdge, int fTop, Vec_Ptr_t * vLeaves )
|
||||
{
|
||||
Abc_Obj_t * pObj, * pObjNew, * pLeaf, * pFaninNew0, * pFaninNew1;
|
||||
unsigned SeqEdge0, SeqEdge1;
|
||||
int TotalLag, Lag, i;
|
||||
// get the object and the lag
|
||||
pObj = Abc_NtkObj( pNtk, SeqEdge >> 8 );
|
||||
Lag = SeqEdge & 255;
|
||||
// if the node is the fanin of the cut, return
|
||||
Vec_PtrForEachEntry( vLeaves, pLeaf, i )
|
||||
if ( SeqEdge == (unsigned)pLeaf )
|
||||
return pObj->pCopy;
|
||||
// continue unfolding
|
||||
assert( Abc_NodeIsAigAnd(pObj) );
|
||||
// get new sequential edges
|
||||
assert( Lag + Abc_ObjFaninL0(pObj) < 255 );
|
||||
assert( Lag + Abc_ObjFaninL1(pObj) < 255 );
|
||||
SeqEdge0 = (Abc_ObjFanin0(pObj)->Id << 8) + Lag + Abc_ObjFaninL0(pObj);
|
||||
SeqEdge1 = (Abc_ObjFanin1(pObj)->Id << 8) + Lag + Abc_ObjFaninL1(pObj);
|
||||
// call for the children
|
||||
pObjNew = fTop? pObj->pCopy : Abc_NtkCreateNode( pNtkNew );
|
||||
// solve subproblems
|
||||
pFaninNew0 = Seq_FpgaMappingBuild_rec( pNtkNew, pNtk, SeqEdge0, 0, vLeaves );
|
||||
pFaninNew1 = Seq_FpgaMappingBuild_rec( pNtkNew, pNtk, SeqEdge1, 0, vLeaves );
|
||||
// add the fanins to the node
|
||||
Abc_ObjAddFanin( pObjNew, Abc_ObjNotCond( pFaninNew0, Abc_ObjFaninC0(pObj) ) );
|
||||
Abc_ObjAddFanin( pObjNew, Abc_ObjNotCond( pFaninNew1, Abc_ObjFaninC1(pObj) ) );
|
||||
Seq_NodeDupLats( pObjNew, pObj, 0 );
|
||||
Seq_NodeDupLats( pObjNew, pObj, 1 );
|
||||
// set the lag of the new node equal to the internal lag plus mapping/retiming lag
|
||||
TotalLag = Lag + Seq_NodeGetLag(pObj);
|
||||
Seq_NodeSetLag( pObjNew, (char)TotalLag );
|
||||
return pObjNew;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
+214
-3
@@ -6,7 +6,7 @@
|
||||
|
||||
PackageName [Construction and manipulation of sequential AIGs.]
|
||||
|
||||
Synopsis []
|
||||
Synopsis [Iterative delay computation in FPGA mapping/retiming package.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
@@ -19,18 +19,25 @@
|
||||
***********************************************************************/
|
||||
|
||||
#include "seqInt.h"
|
||||
#include "main.h"
|
||||
#include "fpga.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static void Seq_FpgaMappingCollectNode_rec( Abc_Obj_t * pAnd, Vec_Ptr_t * vMapping, Vec_Vec_t * vMapCuts );
|
||||
static Cut_Cut_t * Seq_FpgaMappingSelectCut( Abc_Obj_t * pAnd );
|
||||
|
||||
extern Cut_Man_t * Abc_NtkSeqCuts( Abc_Ntk_t * pNtk, Cut_Params_t * pParams );
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
Synopsis [Computes the retiming lags for FPGA mapping.]
|
||||
|
||||
Description []
|
||||
|
||||
@@ -39,10 +46,214 @@
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Seq_NtkSeqFpgaMapping( Abc_Ntk_t * pNtk, int fVerbose )
|
||||
void Seq_FpgaMappingDelays( Abc_Ntk_t * pNtk, int fVerbose )
|
||||
{
|
||||
Abc_Seq_t * p = pNtk->pManFunc;
|
||||
Cut_Params_t Params, * pParams = &Params;
|
||||
Abc_Obj_t * pObj;
|
||||
int i, clk;
|
||||
|
||||
// get the LUT library
|
||||
p->nVarsMax = Fpga_LutLibReadVarMax( Abc_FrameReadLibLut() );
|
||||
|
||||
// set defaults for cut computation
|
||||
memset( pParams, 0, sizeof(Cut_Params_t) );
|
||||
pParams->nVarsMax = p->nVarsMax; // the max cut size ("k" of the k-feasible cuts)
|
||||
pParams->nKeepMax = 1000; // the max number of cuts kept at a node
|
||||
pParams->fTruth = 0; // compute truth tables
|
||||
pParams->fFilter = 1; // filter dominated cuts
|
||||
pParams->fSeq = 1; // compute sequential cuts
|
||||
pParams->fVerbose = 0; // the verbosiness flag
|
||||
|
||||
// compute the cuts
|
||||
clk = clock();
|
||||
p->pCutMan = Abc_NtkSeqCuts( pNtk, pParams );
|
||||
p->timeCuts = clock() - clk;
|
||||
if ( fVerbose )
|
||||
Cut_ManPrintStats( p->pCutMan );
|
||||
|
||||
// compute the delays
|
||||
clk = clock();
|
||||
Seq_NtkRetimeDelayLags( pNtk, fVerbose );
|
||||
p->timeDelay = clock() - clk;
|
||||
|
||||
// collect the nodes and cuts used in the mapping
|
||||
p->vMapAnds = Vec_PtrAlloc( 1000 );
|
||||
p->vMapCuts = Vec_VecAlloc( 1000 );
|
||||
Abc_NtkIncrementTravId( pNtk );
|
||||
Abc_NtkForEachPo( pNtk, pObj, i )
|
||||
Seq_FpgaMappingCollectNode_rec( Abc_ObjFanin0(pObj), p->vMapAnds, p->vMapCuts );
|
||||
|
||||
printf( "The number of LUTs = %d.\n", Vec_PtrSize(p->vMapAnds) );
|
||||
|
||||
// remove the cuts
|
||||
Cut_ManStop( p->pCutMan );
|
||||
p->pCutMan = NULL;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Derives the parameters of the best mapping/retiming for one node.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Seq_FpgaMappingCollectNode_rec( Abc_Obj_t * pAnd, Vec_Ptr_t * vMapping, Vec_Vec_t * vMapCuts )
|
||||
{
|
||||
Abc_Obj_t * pFanin;
|
||||
Cut_Cut_t * pCutBest;
|
||||
int k;
|
||||
|
||||
// skip if this is a non-PI node
|
||||
if ( !Abc_NodeIsAigAnd(pAnd) )
|
||||
return;
|
||||
// skip a visited node
|
||||
if ( Abc_NodeIsTravIdCurrent(pAnd) )
|
||||
return;
|
||||
Abc_NodeSetTravIdCurrent(pAnd);
|
||||
|
||||
// visit the fanins of the node
|
||||
pCutBest = Seq_FpgaMappingSelectCut( pAnd );
|
||||
for ( k = 0; k < (int)pCutBest->nLeaves; k++ )
|
||||
{
|
||||
pFanin = Abc_NtkObj( pAnd->pNtk, pCutBest->pLeaves[k] >> 8 );
|
||||
Seq_FpgaMappingCollectNode_rec( pFanin, vMapping, vMapCuts );
|
||||
}
|
||||
|
||||
// add this node
|
||||
Vec_PtrPush( vMapping, pAnd );
|
||||
for ( k = 0; k < (int)pCutBest->nLeaves; k++ )
|
||||
Vec_VecPush( vMapCuts, Vec_PtrSize(vMapping)-1, (void *)pCutBest->pLeaves[k] );
|
||||
|
||||
//printf( "Adding %d.\n", pAnd->Id );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Selects the best cut to represent the node in the mapping.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Cut_Cut_t * Seq_FpgaMappingSelectCut( Abc_Obj_t * pAnd )
|
||||
{
|
||||
Abc_Obj_t * pFanin;
|
||||
Cut_Cut_t * pCut, * pCutBest, * pList;
|
||||
float CostCur, CostMin = ABC_INFINITY;
|
||||
int ArrivalCut, ArrivalMin, i;
|
||||
// get the arrival time of the best non-trivial cut
|
||||
ArrivalMin = Seq_NodeGetLValue( pAnd );
|
||||
// iterate through the cuts and with the one with the minimum cost
|
||||
pList = Abc_NodeReadCuts( Seq_NodeCutMan(pAnd), pAnd );
|
||||
CostMin = ABC_INFINITY;
|
||||
pCutBest = NULL;
|
||||
for ( pCut = pList->pNext; pCut; pCut = pCut->pNext )
|
||||
{
|
||||
ArrivalCut = *((int *)&pCut->uSign);
|
||||
assert( ArrivalCut >= ArrivalMin );
|
||||
if ( ArrivalCut > ArrivalMin )
|
||||
continue;
|
||||
CostCur = 0.0;
|
||||
for ( i = 0; i < (int)pCut->nLeaves; i++ )
|
||||
{
|
||||
pFanin = Abc_NtkObj( pAnd->pNtk, pCut->pLeaves[i] >> 8 );
|
||||
if ( Abc_ObjIsPi(pFanin) )
|
||||
continue;
|
||||
if ( Abc_NodeIsTravIdCurrent(pFanin) )
|
||||
continue;
|
||||
CostCur += (float)(1.0 / Abc_ObjFanoutNum(pFanin));
|
||||
}
|
||||
if ( CostMin > CostCur )
|
||||
{
|
||||
CostMin = CostCur;
|
||||
pCutBest = pCut;
|
||||
}
|
||||
}
|
||||
assert( pCutBest != NULL );
|
||||
return pCutBest;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes the l-value of the cut.]
|
||||
|
||||
Description [The node should be internal.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Seq_FpgaCutUpdateLValue( Cut_Cut_t * pCut, Abc_Obj_t * pObj, int Fi )
|
||||
{
|
||||
Abc_Obj_t * pFanin;
|
||||
int i, lValueMax, lValueCur;
|
||||
assert( Abc_NodeIsAigAnd(pObj) );
|
||||
lValueMax = -ABC_INFINITY;
|
||||
for ( i = 0; i < (int)pCut->nLeaves; i++ )
|
||||
{
|
||||
// lValue0 = Seq_NodeGetLValue(Abc_ObjFanin0(pObj)) - Fi * Abc_ObjFaninL0(pObj);
|
||||
pFanin = Abc_NtkObj(pObj->pNtk, pCut->pLeaves[i] >> 8);
|
||||
lValueCur = Seq_NodeGetLValue(pFanin) - Fi * (pCut->pLeaves[i] & 255);
|
||||
if ( lValueMax < lValueCur )
|
||||
lValueMax = lValueCur;
|
||||
}
|
||||
lValueMax += 1;
|
||||
*((int *)&pCut->uSign) = lValueMax;
|
||||
return lValueMax;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes the l-value of the node.]
|
||||
|
||||
Description [The node can be internal or a PO.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Seq_FpgaNodeUpdateLValue( Abc_Obj_t * pObj, int Fi )
|
||||
{
|
||||
Cut_Cut_t * pCut, * pList;
|
||||
int lValueNew, lValueOld, lValueCut;
|
||||
assert( !Abc_ObjIsPi(pObj) );
|
||||
assert( Abc_ObjFaninNum(pObj) > 0 );
|
||||
if ( Abc_ObjIsPo(pObj) )
|
||||
{
|
||||
lValueNew = Seq_NodeGetLValue(Abc_ObjFanin0(pObj)) - Fi * Abc_ObjFaninL0(pObj);
|
||||
return (lValueNew > Fi)? SEQ_UPDATE_FAIL : SEQ_UPDATE_NO;
|
||||
}
|
||||
// get the arrival time of the best non-trivial cut
|
||||
pList = Abc_NodeReadCuts( Seq_NodeCutMan(pObj), pObj );
|
||||
lValueNew = ABC_INFINITY;
|
||||
for ( pCut = pList->pNext; pCut; pCut = pCut->pNext )
|
||||
{
|
||||
lValueCut = Seq_FpgaCutUpdateLValue( pCut, pObj, Fi );
|
||||
if ( lValueNew > lValueCut )
|
||||
lValueNew = lValueCut;
|
||||
}
|
||||
// compare the arrival time with the previous arrival time
|
||||
lValueOld = Seq_NodeGetLValue(pObj);
|
||||
// if ( lValueNew == lValueOld )
|
||||
if ( lValueNew <= lValueOld )
|
||||
return SEQ_UPDATE_NO;
|
||||
//printf( "%d ", lValueNew );
|
||||
Seq_NodeSetLValue( pObj, lValueNew );
|
||||
return SEQ_UPDATE_YES;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
+24
-12
@@ -6,7 +6,7 @@
|
||||
|
||||
PackageName [Construction and manipulation of sequential AIGs.]
|
||||
|
||||
Synopsis [External declarations.]
|
||||
Synopsis [Internal declarations.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "abc.h"
|
||||
#include "cut.h"
|
||||
#include "seq.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
@@ -34,6 +35,9 @@
|
||||
|
||||
#define SEQ_FULL_MASK 0xFFFFFFFF
|
||||
|
||||
// node status after updating its arrival time
|
||||
enum { SEQ_UPDATE_FAIL, SEQ_UPDATE_NO, SEQ_UPDATE_YES };
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// BASIC TYPES ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
@@ -41,20 +45,21 @@
|
||||
// manager of sequential AIG
|
||||
struct Abc_Seq_t_
|
||||
{
|
||||
// sequential information
|
||||
Abc_Ntk_t * pNtk; // the network
|
||||
int nSize; // the number of entries in all internal arrays
|
||||
Vec_Ptr_t * vInits; // the initial states for each edge in the AIG
|
||||
Extra_MmFixed_t * pMmInits; // memory manager for latch structures used to remember init states
|
||||
int fVerbose; // the verbose flag
|
||||
// the arrival times
|
||||
// K-feasible cuts
|
||||
int nVarsMax; // the max cut size
|
||||
Cut_Man_t * pCutMan; // cut manager
|
||||
// sequential arrival time computation
|
||||
Vec_Int_t * vLValues; // the arrival times (L-Values of nodes)
|
||||
Vec_Ptr_t * vBestCuts; // the best cuts for nodes
|
||||
Vec_Str_t * vLags; // the lags of the mapped nodes
|
||||
// representation of the mapping
|
||||
Vec_Ptr_t * vMapAnds; // nodes visible in the mapping
|
||||
Vec_Vec_t * vMapCuts; // best cuts for each node
|
||||
Vec_Vec_t * vMapBags; // nodes subsumed by each cut
|
||||
Vec_Vec_t * vMapLags; // the internal lags of each node in the bag
|
||||
// runtime stats
|
||||
int timeCuts; // runtime to compute the cuts
|
||||
int timeDelay; // runtime to compute the L-values
|
||||
@@ -99,11 +104,17 @@ static inline Seq_RetEdge_t Seq_Int2RetEdge( int Num ) { return *((S
|
||||
static inline int Seq_RetStep2Int( Seq_RetStep_t Val ) { return *((int *)&Val); }
|
||||
static inline Seq_RetStep_t Seq_Int2RetStep( int Num ) { return *((Seq_RetStep_t *)&Num); }
|
||||
|
||||
// storing arrival times in the nodes
|
||||
static inline Vec_Int_t * Seq_NodeLValues( Abc_Obj_t * pNode ) { return ((Abc_Seq_t *)(pNode)->pNtk->pManFunc)->vLValues; }
|
||||
static inline int Seq_NodeGetLValue( Abc_Obj_t * pNode ) { return Vec_IntEntry( Seq_NodeLValues(pNode), (pNode)->Id ); }
|
||||
static inline void Seq_NodeSetLValue( Abc_Obj_t * pNode, int Value ) { Vec_IntWriteEntry( Seq_NodeLValues(pNode), (pNode)->Id, (Value) ); }
|
||||
static inline int Seq_NodeComputeLag( int LValue, int Fi ) { return (LValue + 1024*Fi)/Fi - 1024 - (int)(LValue % Fi == 0); }
|
||||
// reading l-values and lags
|
||||
static inline Vec_Int_t * Seq_NodeLValues( Abc_Obj_t * pNode ) { return ((Abc_Seq_t *)(pNode)->pNtk->pManFunc)->vLValues; }
|
||||
static inline int Seq_NodeGetLValue( Abc_Obj_t * pNode ) { return Vec_IntEntry( Seq_NodeLValues(pNode), (pNode)->Id ); }
|
||||
static inline void Seq_NodeSetLValue( Abc_Obj_t * pNode, int Value ) { Vec_IntWriteEntry( Seq_NodeLValues(pNode), (pNode)->Id, Value ); }
|
||||
static inline int Seq_NodeComputeLag( int LValue, int Fi ) { return (LValue + 1024*Fi)/Fi - 1024 - (int)(LValue % Fi == 0); }
|
||||
|
||||
// reading best cuts at each node
|
||||
static inline Cut_Man_t * Seq_NodeCutMan( Abc_Obj_t * pNode ) { return ((Abc_Seq_t *)(pNode)->pNtk->pManFunc)->pCutMan; }
|
||||
//static inline Vec_Ptr_t * Seq_NodeCutBests( Abc_Obj_t * pNode ) { return ((Abc_Seq_t *)(pNode)->pNtk->pManFunc)->vBestCuts; }
|
||||
//static inline Cut_Cut_t * Seq_NodeGetCutBest( Abc_Obj_t * pNode ) { return Vec_PtrEntry( Seq_NodeCutBests(pNode), (pNode)->Id ); }
|
||||
//static inline void Seq_NodeSetCutBest( Abc_Obj_t * pNode, Cut_Cut_t * pCut ) { Vec_PtrWriteEntry( Seq_NodeCutBests(pNode), (pNode)->Id, pCut ); }
|
||||
|
||||
// reading the contents of the lat
|
||||
static inline Abc_InitType_t Seq_LatInit( Seq_Lat_t * pLat ) { return ((unsigned)pLat->pPrev) & 3; }
|
||||
@@ -149,9 +160,10 @@ extern void Seq_NodeInsertLast( Abc_Obj_t * pObj, int Edge, Abc
|
||||
extern Abc_InitType_t Seq_NodeDeleteFirst( Abc_Obj_t * pObj, int Edge );
|
||||
extern Abc_InitType_t Seq_NodeDeleteLast( Abc_Obj_t * pObj, int Edge );
|
||||
/*=== seqFpgaIter.c ============================================================*/
|
||||
extern void Seq_NtkSeqFpgaMapping( Abc_Ntk_t * pNtk, int fVerbose );
|
||||
extern void Seq_FpgaMappingDelays( Abc_Ntk_t * pNtk, int fVerbose );
|
||||
extern int Seq_FpgaNodeUpdateLValue( Abc_Obj_t * pObj, int Fi );
|
||||
/*=== seqRetIter.c =============================================================*/
|
||||
extern void Seq_NtkSeqRetimeDelayLags( Abc_Ntk_t * pNtk, int fVerbose );
|
||||
extern void Seq_NtkRetimeDelayLags( Abc_Ntk_t * pNtk, int fVerbose );
|
||||
extern int Seq_NtkImplementRetiming( Abc_Ntk_t * pNtk, Vec_Str_t * vLags, int fVerbose );
|
||||
/*=== seqUtil.c ================================================================*/
|
||||
extern int Seq_ObjFanoutLMax( Abc_Obj_t * pObj );
|
||||
|
||||
@@ -185,6 +185,36 @@ void Seq_NodeDupLats( Abc_Obj_t * pObjNew, Abc_Obj_t * pObj, int Edge )
|
||||
Seq_NodeInsertLast( pObjNew, Edge, Seq_LatInit(pLat) );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Insert the last Lat on the edge.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Seq_NodeCompareLats( Abc_Obj_t * pObj1, int Edge1, Abc_Obj_t * pObj2, int Edge2 )
|
||||
{
|
||||
Seq_Lat_t * pRing1, * pRing2, * pLat1, * pLat2;
|
||||
int i, nLatches1, nLatches2;
|
||||
|
||||
nLatches1 = Seq_NodeCountLats( pObj1, Edge1 );
|
||||
nLatches2 = Seq_NodeCountLats( pObj2, Edge2 );
|
||||
if ( nLatches1 != nLatches2 )
|
||||
return 0;
|
||||
|
||||
pRing1 = Seq_NodeGetRing( pObj1, Edge1 );
|
||||
pRing2 = Seq_NodeGetRing( pObj2, Edge2 );
|
||||
for ( i = 0, pLat1 = pRing1, pLat2 = pRing2; i < nLatches1; i++, pLat1 = pLat1->pNext, pLat2 = pLat2->pNext )
|
||||
if ( Seq_LatInit(pLat1) != Seq_LatInit(pLat2) )
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
+9
-11
@@ -6,7 +6,7 @@
|
||||
|
||||
PackageName [Construction and manipulation of sequential AIGs.]
|
||||
|
||||
Synopsis []
|
||||
Synopsis [Manager of sequential AIG containing.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
@@ -32,7 +32,9 @@
|
||||
|
||||
Synopsis [Allocates sequential AIG manager.]
|
||||
|
||||
Description []
|
||||
Description [The manager contains all the data structures needed to
|
||||
represent sequential AIG and compute stand-alone retiming as well as
|
||||
the integrated mapping/retiming of the sequential AIG.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
@@ -47,9 +49,9 @@ Abc_Seq_t * Seq_Create( Abc_Ntk_t * pNtk )
|
||||
memset( p, 0, sizeof(Abc_Seq_t) );
|
||||
p->pNtk = pNtk;
|
||||
p->nSize = 1000;
|
||||
p->pMmInits = Extra_MmFixedStart( sizeof(Seq_Lat_t) );
|
||||
// create internal data structures
|
||||
p->vInits = Vec_PtrStart( 2 * p->nSize );
|
||||
p->pMmInits = Extra_MmFixedStart( sizeof(Seq_Lat_t) );
|
||||
p->vLValues = Vec_IntStart( p->nSize );
|
||||
p->vLags = Vec_StrStart( p->nSize );
|
||||
return p;
|
||||
@@ -71,9 +73,9 @@ void Seq_Resize( Abc_Seq_t * p, int nMaxId )
|
||||
if ( p->nSize > nMaxId )
|
||||
return;
|
||||
p->nSize = nMaxId + 1;
|
||||
Vec_PtrFill( p->vInits, 2 * p->nSize, NULL );
|
||||
Vec_IntFill( p->vLValues, p->nSize, 0 );
|
||||
Vec_StrFill( p->vLags, p->nSize, 0 );
|
||||
Vec_PtrFill( p->vInits, 2 * p->nSize, NULL );
|
||||
Vec_IntFill( p->vLValues, p->nSize, 0 );
|
||||
Vec_StrFill( p->vLags, p->nSize, 0 );
|
||||
}
|
||||
|
||||
|
||||
@@ -92,13 +94,9 @@ void Seq_Delete( Abc_Seq_t * p )
|
||||
{
|
||||
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->vMapBags ) Vec_VecFree( p->vMapBags ); // the nodes included in the cuts used in the mapping
|
||||
if ( p->vMapLags ) Vec_VecFree( p->vMapLags ); // the lags of the mapped nodes
|
||||
|
||||
if ( p->vBestCuts ) Vec_PtrFree( p->vBestCuts ); // the best cuts for nodes
|
||||
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
|
||||
Vec_PtrFree( p->vInits );
|
||||
if ( p->vInits ) Vec_PtrFree( p->vInits ); // the initial values of the latches
|
||||
Extra_MmFixedStop( p->pMmInits, 0 );
|
||||
free( p );
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
PackageName [Construction and manipulation of sequential AIGs.]
|
||||
|
||||
Synopsis []
|
||||
Synopsis [The core of SC mapping/retiming package.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
PackageName [Construction and manipulation of sequential AIGs.]
|
||||
|
||||
Synopsis []
|
||||
Synopsis [Iterative delay computation in SC mapping/retiming package.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
PackageName [Construction and manipulation of sequential AIGs.]
|
||||
|
||||
Synopsis []
|
||||
Synopsis [The core of retiming procedures.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
@@ -72,7 +72,7 @@ void Seq_NtkSeqRetimeDelay( Abc_Ntk_t * pNtk, int fInitial, int fVerbose )
|
||||
if ( !fInitial )
|
||||
Seq_NtkLatchSetValues( pNtk, ABC_INIT_DC );
|
||||
// get the retiming lags
|
||||
Seq_NtkSeqRetimeDelayLags( pNtk, fVerbose );
|
||||
Seq_NtkRetimeDelayLags( pNtk, fVerbose );
|
||||
// implement this retiming
|
||||
RetValue = Seq_NtkImplementRetiming( pNtk, p->vLags, fVerbose );
|
||||
if ( RetValue == 0 )
|
||||
|
||||
+36
-17
@@ -6,7 +6,7 @@
|
||||
|
||||
PackageName [Construction and manipulation of sequential AIGs.]
|
||||
|
||||
Synopsis []
|
||||
Synopsis [The iterative L-Value computation for retiming procedures.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
@@ -27,10 +27,7 @@
|
||||
// the internal procedures
|
||||
static int Seq_RetimeSearch_rec( Abc_Ntk_t * pNtk, int FiMin, int FiMax, int fVerbose );
|
||||
static int Seq_RetimeForPeriod( Abc_Ntk_t * pNtk, int Fi, int fVerbose );
|
||||
static int Seq_NodeUpdateLValue( Abc_Obj_t * pObj, int Fi );
|
||||
|
||||
// node status after updating its arrival time
|
||||
enum { SEQ_UPDATE_FAIL, SEQ_UPDATE_NO, SEQ_UPDATE_YES };
|
||||
static int Seq_RetimeNodeUpdateLValue( Abc_Obj_t * pObj, int Fi );
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
@@ -47,11 +44,12 @@ enum { SEQ_UPDATE_FAIL, SEQ_UPDATE_NO, SEQ_UPDATE_YES };
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Seq_NtkSeqRetimeDelayLags( Abc_Ntk_t * pNtk, int fVerbose )
|
||||
void Seq_NtkRetimeDelayLags( Abc_Ntk_t * pNtk, int fVerbose )
|
||||
{
|
||||
Abc_Seq_t * p = pNtk->pManFunc;
|
||||
Abc_Obj_t * pNode;
|
||||
int i, FiMax, FiBest, RetValue;
|
||||
char NodeLag;
|
||||
|
||||
assert( Abc_NtkIsSeq( pNtk ) );
|
||||
|
||||
@@ -69,14 +67,17 @@ void Seq_NtkSeqRetimeDelayLags( Abc_Ntk_t * pNtk, int fVerbose )
|
||||
// search for the optimal clock period between 0 and nLevelMax
|
||||
FiBest = Seq_RetimeSearch_rec( pNtk, 0, FiMax, fVerbose );
|
||||
|
||||
// recompute the best LValues
|
||||
// recompute the best l-values
|
||||
RetValue = Seq_RetimeForPeriod( pNtk, FiBest, fVerbose );
|
||||
assert( RetValue );
|
||||
|
||||
// write the retiming lags
|
||||
Vec_StrFill( p->vLags, p->nSize, 0 );
|
||||
Abc_AigForEachAnd( pNtk, pNode, i )
|
||||
Seq_NodeSetLag( pNode, (char)Seq_NodeComputeLag(Seq_NodeGetLValue(pNode), FiBest) );
|
||||
{
|
||||
NodeLag = Seq_NodeComputeLag( Seq_NodeGetLValue(pNode), FiBest );
|
||||
Seq_NodeSetLag( pNode, NodeLag );
|
||||
}
|
||||
|
||||
// print the result
|
||||
if ( fVerbose )
|
||||
@@ -140,7 +141,7 @@ int Seq_RetimeForPeriod( Abc_Ntk_t * pNtk, int Fi, int fVerbose )
|
||||
// set l-values of all nodes to be minus infinity
|
||||
Vec_IntFill( p->vLValues, p->nSize, -ABC_INFINITY );
|
||||
|
||||
// set l-values for the constant and PIs
|
||||
// set l-values of constants and PIs
|
||||
pObj = Abc_NtkObj( pNtk, 0 );
|
||||
Seq_NodeSetLValue( pObj, 0 );
|
||||
Abc_NtkForEachPi( pNtk, pObj, i )
|
||||
@@ -151,13 +152,27 @@ int Seq_RetimeForPeriod( Abc_Ntk_t * pNtk, int Fi, int fVerbose )
|
||||
for ( c = 0; c < 20; c++ )
|
||||
{
|
||||
fChange = 0;
|
||||
Abc_NtkForEachObj( pNtk, pObj, i )
|
||||
Abc_AigForEachAnd( pNtk, pObj, i )
|
||||
{
|
||||
if ( Abc_ObjIsPi(pObj) )
|
||||
if ( Seq_NodeCutMan(pObj) )
|
||||
RetValue = Seq_FpgaNodeUpdateLValue( pObj, Fi );
|
||||
else
|
||||
RetValue = Seq_RetimeNodeUpdateLValue( pObj, Fi );
|
||||
//printf( "Node = %d. Value = %d. \n", pObj->Id, RetValue );
|
||||
Counter++;
|
||||
if ( RetValue == SEQ_UPDATE_FAIL )
|
||||
break;
|
||||
if ( RetValue == SEQ_UPDATE_NO )
|
||||
continue;
|
||||
if ( Abc_ObjFaninNum(pObj) == 0 )
|
||||
continue;
|
||||
RetValue = Seq_NodeUpdateLValue( pObj, Fi );
|
||||
fChange = 1;
|
||||
}
|
||||
Abc_NtkForEachPo( pNtk, pObj, i )
|
||||
{
|
||||
if ( Seq_NodeCutMan(pObj) )
|
||||
RetValue = Seq_FpgaNodeUpdateLValue( pObj, Fi );
|
||||
else
|
||||
RetValue = Seq_RetimeNodeUpdateLValue( pObj, Fi );
|
||||
//printf( "Node = %d. Value = %d. \n", pObj->Id, RetValue );
|
||||
Counter++;
|
||||
if ( RetValue == SEQ_UPDATE_FAIL )
|
||||
break;
|
||||
@@ -176,13 +191,17 @@ int Seq_RetimeForPeriod( Abc_Ntk_t * pNtk, int Fi, int fVerbose )
|
||||
pReason = "(timeout)";
|
||||
}
|
||||
|
||||
//Abc_NtkForEachObj( pNtk, pObj, i )
|
||||
//printf( "%d ", Seq_NodeGetLValue(pObj) );
|
||||
//printf( "\n" );
|
||||
|
||||
// report the results
|
||||
if ( fVerbose )
|
||||
{
|
||||
if ( RetValue == SEQ_UPDATE_FAIL )
|
||||
printf( "Period = %3d. Iterations = %3d. Updates = %10d. Infeasible %s\n", Fi, c, Counter, pReason );
|
||||
printf( "Period = %3d. Iterations = %3d. Updates = %10d. Infeasible %s\n", Fi, c, Counter, pReason );
|
||||
else
|
||||
printf( "Period = %3d. Iterations = %3d. Updates = %10d. Feasible\n", Fi, c, Counter );
|
||||
printf( "Period = %3d. Iterations = %3d. Updates = %10d. Feasible\n", Fi, c, Counter );
|
||||
}
|
||||
return RetValue != SEQ_UPDATE_FAIL;
|
||||
}
|
||||
@@ -198,7 +217,7 @@ int Seq_RetimeForPeriod( Abc_Ntk_t * pNtk, int Fi, int fVerbose )
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Seq_NodeUpdateLValue( Abc_Obj_t * pObj, int Fi )
|
||||
int Seq_RetimeNodeUpdateLValue( Abc_Obj_t * pObj, int Fi )
|
||||
{
|
||||
int lValueNew, lValueOld, lValue0, lValue1;
|
||||
assert( !Abc_ObjIsPi(pObj) );
|
||||
|
||||
+14
-14
@@ -6,7 +6,7 @@
|
||||
|
||||
PackageName [Construction and manipulation of sequential AIGs.]
|
||||
|
||||
Synopsis []
|
||||
Synopsis [Latch sharing at the fanout stems.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
@@ -24,8 +24,8 @@
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static void Abc_NodeSeqShareFanouts( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes );
|
||||
static void Abc_NodeSeqShareOne( Abc_Obj_t * pNode, Abc_InitType_t Init, Vec_Ptr_t * vNodes );
|
||||
static void Seq_NodeShareFanouts( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes );
|
||||
static void Seq_NodeShareOne( Abc_Obj_t * pNode, Abc_InitType_t Init, Vec_Ptr_t * vNodes );
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
@@ -42,7 +42,7 @@ static void Abc_NodeSeqShareOne( Abc_Obj_t * pNode, Abc_InitType_t Init, Vec_Ptr
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Seq_NtkSeqShareFanouts( Abc_Ntk_t * pNtk )
|
||||
void Seq_NtkShareFanouts( Abc_Ntk_t * pNtk )
|
||||
{
|
||||
Vec_Ptr_t * vNodes;
|
||||
Abc_Obj_t * pObj;
|
||||
@@ -50,10 +50,10 @@ void Seq_NtkSeqShareFanouts( Abc_Ntk_t * pNtk )
|
||||
vNodes = Vec_PtrAlloc( 10 );
|
||||
// share the PI latches
|
||||
Abc_NtkForEachPi( pNtk, pObj, i )
|
||||
Abc_NodeSeqShareFanouts( pObj, vNodes );
|
||||
Seq_NodeShareFanouts( pObj, vNodes );
|
||||
// share the node latches
|
||||
Abc_NtkForEachNode( pNtk, pObj, i )
|
||||
Abc_NodeSeqShareFanouts( pObj, vNodes );
|
||||
Seq_NodeShareFanouts( pObj, vNodes );
|
||||
Vec_PtrFree( vNodes );
|
||||
}
|
||||
|
||||
@@ -68,7 +68,7 @@ void Seq_NtkSeqShareFanouts( Abc_Ntk_t * pNtk )
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_NodeSeqShareFanouts( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes )
|
||||
void Seq_NodeShareFanouts( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes )
|
||||
{
|
||||
Abc_Obj_t * pFanout;
|
||||
Abc_InitType_t Type;
|
||||
@@ -90,19 +90,19 @@ void Abc_NodeSeqShareFanouts( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes )
|
||||
// decide what to do
|
||||
if ( nLatches[ABC_INIT_ZERO] > 1 && nLatches[ABC_INIT_ONE] > 1 ) // 0-group and 1-group
|
||||
{
|
||||
Abc_NodeSeqShareOne( pNode, ABC_INIT_ZERO, vNodes ); // shares 0 and DC
|
||||
Abc_NodeSeqShareOne( pNode, ABC_INIT_ONE, vNodes ); // shares 1 and DC
|
||||
Seq_NodeShareOne( pNode, ABC_INIT_ZERO, vNodes ); // shares 0 and DC
|
||||
Seq_NodeShareOne( pNode, ABC_INIT_ONE, vNodes ); // shares 1 and DC
|
||||
}
|
||||
else if ( nLatches[ABC_INIT_ZERO] > 1 ) // 0-group
|
||||
Abc_NodeSeqShareOne( pNode, ABC_INIT_ZERO, vNodes ); // shares 0 and DC
|
||||
Seq_NodeShareOne( pNode, ABC_INIT_ZERO, vNodes ); // shares 0 and DC
|
||||
else if ( nLatches[ABC_INIT_ONE] > 1 ) // 1-group
|
||||
Abc_NodeSeqShareOne( pNode, ABC_INIT_ONE, vNodes ); // shares 1 and DC
|
||||
Seq_NodeShareOne( pNode, ABC_INIT_ONE, vNodes ); // shares 1 and DC
|
||||
else if ( nLatches[ABC_INIT_DC] > 1 ) // DC-group
|
||||
{
|
||||
if ( nLatches[ABC_INIT_ZERO] > 0 )
|
||||
Abc_NodeSeqShareOne( pNode, ABC_INIT_ZERO, vNodes ); // shares 0 and DC
|
||||
Seq_NodeShareOne( pNode, ABC_INIT_ZERO, vNodes ); // shares 0 and DC
|
||||
else
|
||||
Abc_NodeSeqShareOne( pNode, ABC_INIT_ONE, vNodes ); // shares 1 and DC
|
||||
Seq_NodeShareOne( pNode, ABC_INIT_ONE, vNodes ); // shares 1 and DC
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,7 +117,7 @@ void Abc_NodeSeqShareFanouts( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes )
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_NodeSeqShareOne( Abc_Obj_t * pNode, Abc_InitType_t Init, Vec_Ptr_t * vNodes )
|
||||
void Seq_NodeShareOne( Abc_Obj_t * pNode, Abc_InitType_t Init, Vec_Ptr_t * vNodes )
|
||||
{
|
||||
Vec_Ptr_t * vInits = Seq_NodeLats( pNode );
|
||||
Abc_Obj_t * pFanout, * pBuffer;
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
PackageName [Construction and manipulation of sequential AIGs.]
|
||||
|
||||
Synopsis []
|
||||
Synopsis [Various utilities working with sequential AIGs.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
|
||||
+4
-1
@@ -57,7 +57,10 @@ void Fpga_Init( Abc_Frame_t * pAbc )
|
||||
{
|
||||
// set the default library
|
||||
//Fpga_LutLib_t s_LutLib = { "lutlib", 6, {0,1,2,4,8,16,32}, {0,1,2,3,4,5,6} };
|
||||
Fpga_LutLib_t s_LutLib = { "lutlib", 5, {0,1,1,1,1,1}, {0,1,1,1,1,1} };
|
||||
//Fpga_LutLib_t s_LutLib = { "lutlib", 5, {0,1,1,1,1,1}, {0,1,1,1,1,1} };
|
||||
Fpga_LutLib_t s_LutLib = { "lutlib", 4, {0,1,1,1,1}, {0,1,1,1,1} };
|
||||
//Fpga_LutLib_t s_LutLib = { "lutlib", 3, {0,1,1,1}, {0,1,1,1} };
|
||||
|
||||
Abc_FrameSetLibLut( Fpga_LutLibDup(&s_LutLib) );
|
||||
|
||||
Cmd_CommandAdd( pAbc, "FPGA mapping", "read_lut", Fpga_CommandReadLibrary, 0 );
|
||||
|
||||
@@ -137,9 +137,6 @@ extern void Fpga_CutsCleanSign( Fpga_Man_t * pMan );
|
||||
/*=== fpgaCutUtils.c =============================================================*/
|
||||
extern void Fpga_CutCreateFromNode( Fpga_Man_t * p, int iRoot, int * pLeaves, int nLeaves );
|
||||
extern void Fpga_MappingSetUsedCuts( Fpga_Man_t * p );
|
||||
/*=== fpgaFraig.c =============================================================*/
|
||||
extern Fpga_Man_t * Fpga_ManDupFraig( Fraig_Man_t * pManFraig );
|
||||
extern Fpga_Man_t * Fpga_ManBalanceFraig( Fraig_Man_t * pManFraig, int * pInputArrivals );
|
||||
/*=== fpgaLib.c =============================================================*/
|
||||
extern Fpga_LutLib_t * Fpga_LutLibDup( Fpga_LutLib_t * p );
|
||||
extern int Fpga_LutLibReadVarMax( Fpga_LutLib_t * p );
|
||||
|
||||
@@ -49,6 +49,7 @@ struct Cut_ParamsStruct_t_
|
||||
int nVarsMax; // the max cut size ("k" of the k-feasible cuts)
|
||||
int nKeepMax; // the max number of cuts kept at a node
|
||||
int nIdsMax; // the max number of IDs of cut objects
|
||||
int nBitShift; // the number of bits used for the latch counter of an edge
|
||||
int nCutSet; // the number of nodes in the cut set
|
||||
int fTruth; // compute truth tables
|
||||
int fFilter; // filter dominated cuts
|
||||
|
||||
Reference in New Issue
Block a user