summaryrefslogtreecommitdiffstats
path: root/src/base
diff options
context:
space:
mode:
authorAlan Mishchenko <alanmi@berkeley.edu>2005-10-02 08:01:00 -0700
committerAlan Mishchenko <alanmi@berkeley.edu>2005-10-02 08:01:00 -0700
commit91ca630b0fd316f0843dee8b9e6d236d849eb445 (patch)
treee43afba1c8b2180e981bf75aa02551fa7b2f7793 /src/base
parent78fbd336aa584c4d285123ad18617aa9277016b4 (diff)
downloadabc-91ca630b0fd316f0843dee8b9e6d236d849eb445.tar.gz
abc-91ca630b0fd316f0843dee8b9e6d236d849eb445.tar.bz2
abc-91ca630b0fd316f0843dee8b9e6d236d849eb445.zip
Version abc51002
Diffstat (limited to 'src/base')
-rw-r--r--src/base/abci/abc.c191
-rw-r--r--src/base/abci/abcCut.c70
-rw-r--r--src/base/abcs/abcFpgaDelay.c327
-rw-r--r--src/base/abcs/abcFpgaSeq.c201
-rw-r--r--src/base/abcs/abcRetDelay.c6
-rw-r--r--src/base/abcs/abcs.h26
6 files changed, 801 insertions, 20 deletions
diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c
index 4e2e14a2..ca9f1dfa 100644
--- a/src/base/abci/abc.c
+++ b/src/base/abci/abc.c
@@ -91,6 +91,8 @@ static int Abc_CommandPipe ( Abc_Frame_t * pAbc, int argc, char ** argv
static int Abc_CommandSeq ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandUnseq ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandRetime ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandSeqFpga ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandSeqMap ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandCec ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandSec ( Abc_Frame_t * pAbc, int argc, char ** argv );
@@ -172,6 +174,8 @@ void Abc_Init( Abc_Frame_t * pAbc )
Cmd_CommandAdd( pAbc, "Sequential", "seq", Abc_CommandSeq, 1 );
Cmd_CommandAdd( pAbc, "Sequential", "unseq", Abc_CommandUnseq, 1 );
Cmd_CommandAdd( pAbc, "Sequential", "retime", Abc_CommandRetime, 1 );
+ Cmd_CommandAdd( pAbc, "Sequential", "sfpga", Abc_CommandSeqFpga, 1 );
+ Cmd_CommandAdd( pAbc, "Sequential", "smap", Abc_CommandSeqMap, 1 );
Cmd_CommandAdd( pAbc, "Verification", "cec", Abc_CommandCec, 0 );
Cmd_CommandAdd( pAbc, "Verification", "sec", Abc_CommandSec, 0 );
@@ -2735,16 +2739,20 @@ int Abc_CommandCut( Abc_Frame_t * pAbc, int argc, char ** argv )
{
Cut_Params_t Params, * pParams = &Params;
Cut_Man_t * pCutMan;
+ Cut_Oracle_t * pCutOracle;
FILE * pOut, * pErr;
Abc_Ntk_t * pNtk;
int c;
+ int fOracle;
extern Cut_Man_t * Abc_NtkCuts( Abc_Ntk_t * pNtk, Cut_Params_t * pParams );
+ extern void Abc_NtkCutsOracle( Abc_Ntk_t * pNtk, Cut_Oracle_t * pCutOracle );
pNtk = Abc_FrameReadNet(pAbc);
pOut = Abc_FrameReadOut(pAbc);
pErr = Abc_FrameReadErr(pAbc);
// set defaults
+ fOracle = 0;
memset( pParams, 0, sizeof(Cut_Params_t) );
pParams->nVarsMax = 5; // the max cut size ("k" of the k-feasible cuts)
pParams->nKeepMax = 1000; // the max number of cuts kept at a node
@@ -2754,7 +2762,7 @@ int Abc_CommandCut( Abc_Frame_t * pAbc, int argc, char ** argv )
pParams->fMulti = 0; // use multi-input AND-gates
pParams->fVerbose = 0; // the verbosiness flag
util_getopt_reset();
- while ( ( c = util_getopt( argc, argv, "KMtfdmvh" ) ) != EOF )
+ while ( ( c = util_getopt( argc, argv, "KMtfdmvoh" ) ) != EOF )
{
switch ( c )
{
@@ -2795,6 +2803,9 @@ int Abc_CommandCut( Abc_Frame_t * pAbc, int argc, char ** argv )
case 'v':
pParams->fVerbose ^= 1;
break;
+ case 'o':
+ fOracle ^= 1;
+ break;
case 'h':
goto usage;
default:
@@ -2812,20 +2823,35 @@ int Abc_CommandCut( Abc_Frame_t * pAbc, int argc, char ** argv )
fprintf( pErr, "Cut computation is available only for AIGs (run \"strash\").\n" );
return 1;
}
+ if ( pParams->nVarsMax < CUT_SIZE_MIN || pParams->nVarsMax > CUT_SIZE_MAX )
+ {
+ fprintf( pErr, "Can only compute the cuts for %d <= K <= %d.\n", CUT_SIZE_MIN, CUT_SIZE_MAX );
+ return 1;
+ }
+
+ if ( fOracle )
+ pParams->fRecord = 1;
pCutMan = Abc_NtkCuts( pNtk, pParams );
Cut_ManPrintStats( pCutMan );
+ if ( fOracle )
+ pCutOracle = Cut_OracleStart( pCutMan );
Cut_ManStop( pCutMan );
+ if ( fOracle )
+ {
+ Abc_NtkCutsOracle( pNtk, pCutOracle );
+ Cut_OracleStop( pCutOracle );
+ }
return 0;
usage:
fprintf( pErr, "usage: cut [-K num] [-M num] [-tfdmvh]\n" );
fprintf( pErr, "\t computes k-feasible cuts for the AIG\n" );
- fprintf( pErr, "\t-K num : max number of leaves (4 <= num <= 6) [default = %d]\n", pParams->nVarsMax );
+ fprintf( pErr, "\t-K num : max number of leaves (%d <= num <= %d) [default = %d]\n", CUT_SIZE_MIN, CUT_SIZE_MAX, pParams->nVarsMax );
fprintf( pErr, "\t-M num : max number of cuts stored at a node [default = %d]\n", pParams->nKeepMax );
- fprintf( pErr, "\t-t : toggle truth table computation [default = %s]\n", pParams->fTruth? "yes": "no" );
- fprintf( pErr, "\t-f : toggle filtering of duplicated/dominated [default = %s]\n", pParams->fFilter? "yes": "no" );
- fprintf( pErr, "\t-d : toggle dropping when fanouts are done [default = %s]\n", pParams->fDrop? "yes": "no" );
- fprintf( pErr, "\t-m : toggle using multi-input AND-gates [default = %s]\n", pParams->fMulti? "yes": "no" );
+ fprintf( pErr, "\t-t : toggle truth table computation [default = %s]\n", pParams->fTruth? "yes": "no" );
+ fprintf( pErr, "\t-f : toggle filtering of duplicated/dominated [default = %s]\n", pParams->fFilter? "yes": "no" );
+ fprintf( pErr, "\t-d : toggle dropping when fanouts are done [default = %s]\n", pParams->fDrop? "yes": "no" );
+ fprintf( pErr, "\t-m : toggle using multi-input AND-gates [default = %s]\n", pParams->fMulti? "yes": "no" );
fprintf( pErr, "\t-v : toggle printing verbose information [default = %s]\n", pParams->fVerbose? "yes": "no" );
fprintf( pErr, "\t-h : print the command usage\n");
return 1;
@@ -2913,6 +2939,12 @@ int Abc_CommandScut( Abc_Frame_t * pAbc, int argc, char ** argv )
fprintf( pErr, "Sequential cuts can be computed for sequential AIGs (run \"seq\").\n" );
return 1;
}
+ if ( pParams->nVarsMax < CUT_SIZE_MIN || pParams->nVarsMax > CUT_SIZE_MAX )
+ {
+ fprintf( pErr, "Can only compute the cuts for %d <= K <= %d.\n", CUT_SIZE_MIN, CUT_SIZE_MAX );
+ return 1;
+ }
+
pCutMan = Abc_NtkSeqCuts( pNtk, pParams );
Cut_ManPrintStats( pCutMan );
Cut_ManStop( pCutMan );
@@ -2921,9 +2953,9 @@ int Abc_CommandScut( Abc_Frame_t * pAbc, int argc, char ** argv )
usage:
fprintf( pErr, "usage: scut [-K num] [-M num] [-tvh]\n" );
fprintf( pErr, "\t computes k-feasible cuts for the sequential AIG\n" );
- fprintf( pErr, "\t-K num : max number of leaves (4 <= num <= 6) [default = %d]\n", pParams->nVarsMax );
+ fprintf( pErr, "\t-K num : max number of leaves (%d <= num <= %d) [default = %d]\n", CUT_SIZE_MIN, CUT_SIZE_MAX, pParams->nVarsMax );
fprintf( pErr, "\t-M num : max number of cuts stored at a node [default = %d]\n", pParams->nKeepMax );
- fprintf( pErr, "\t-t : toggle truth table computation [default = %s]\n", pParams->fTruth? "yes": "no" );
+ fprintf( pErr, "\t-t : toggle truth table computation [default = %s]\n", pParams->fTruth? "yes": "no" );
fprintf( pErr, "\t-v : toggle printing verbose information [default = %s]\n", pParams->fVerbose? "yes": "no" );
fprintf( pErr, "\t-h : print the command usage\n");
return 1;
@@ -4434,6 +4466,149 @@ usage:
return 1;
}
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_CommandSeqFpga( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ FILE * pOut, * pErr;
+ 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);
+ pErr = Abc_FrameReadErr(pAbc);
+
+ // set defaults
+ fVerbose = 1;
+ util_getopt_reset();
+ while ( ( c = util_getopt( argc, argv, "vh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'v':
+ fVerbose ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+
+ if ( pNtk == NULL )
+ {
+ fprintf( pErr, "Empty network.\n" );
+ return 1;
+ }
+
+ if ( !Abc_NtkIsSeq(pNtk) )
+ {
+ fprintf( pErr, "Works only for sequential AIG (run \"seq\").\n" );
+ return 1;
+ }
+
+ // get the new network
+ pNtkRes = Abc_NtkFpgaSeq( pNtk, fVerbose );
+ if ( pNtkRes == NULL )
+ {
+ fprintf( pErr, "Sequential FPGA mapping has failed.\n" );
+ return 1;
+ }
+ // replace the current network
+ Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes );
+ return 0;
+
+usage:
+ fprintf( pErr, "usage: sfpga [-vh]\n" );
+ fprintf( pErr, "\t performs integrated sequential FPGA mapping\n" );
+ fprintf( pErr, "\t-v : toggle verbose output [default = %s]\n", fVerbose? "yes": "no" );
+ fprintf( pErr, "\t-h : print the command usage\n");
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_CommandSeqMap( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ FILE * pOut, * pErr;
+ Abc_Ntk_t * pNtk, * pNtkRes;
+ int c;
+ int fVerbose;
+ extern Abc_Ntk_t * Abc_NtkMapSeq( Abc_Ntk_t * pNtk, int fVerbose );
+
+ pNtk = Abc_FrameReadNet(pAbc);
+ pOut = Abc_FrameReadOut(pAbc);
+ pErr = Abc_FrameReadErr(pAbc);
+
+ // set defaults
+ fVerbose = 1;
+ util_getopt_reset();
+ while ( ( c = util_getopt( argc, argv, "vh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'v':
+ fVerbose ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+
+ if ( pNtk == NULL )
+ {
+ fprintf( pErr, "Empty network.\n" );
+ return 1;
+ }
+
+ if ( !Abc_NtkIsSeq(pNtk) )
+ {
+ fprintf( pErr, "Works only for sequential AIG (run \"seq\").\n" );
+ return 1;
+ }
+
+ // get the new network
+ pNtkRes = Abc_NtkMapSeq( pNtk, fVerbose );
+ if ( pNtkRes == NULL )
+ {
+ fprintf( pErr, "Sequential FPGA mapping has failed.\n" );
+ return 1;
+ }
+ // replace the current network
+ Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes );
+ return 0;
+
+usage:
+ fprintf( pErr, "usage: smap [-vh]\n" );
+ fprintf( pErr, "\t performs integrated sequential standard-cell mapping" );
+ fprintf( pErr, "\t-v : toggle verbose output [default = %s]\n", fVerbose? "yes": "no" );
+ fprintf( pErr, "\t-h : print the command usage\n");
+ return 1;
+}
+
+
/**Function*************************************************************
diff --git a/src/base/abci/abcCut.c b/src/base/abci/abcCut.c
index 7cc3d65b..8081c769 100644
--- a/src/base/abci/abcCut.c
+++ b/src/base/abci/abcCut.c
@@ -69,7 +69,7 @@ Cut_Man_t * Abc_NtkCuts( Abc_Ntk_t * pNtk, Cut_Params_t * pParams )
if ( Abc_ObjFanoutNum(pObj) > 0 )
Cut_NodeSetTriv( p, pObj->Id );
// compute cuts for internal nodes
- vNodes = Abc_AigDfs( pNtk, 0, 1 );
+ vNodes = Abc_AigDfs( pNtk, 0, 1 ); // collects POs
vChoices = Vec_IntAlloc( 100 );
Vec_PtrForEachEntry( vNodes, pObj, i )
{
@@ -105,13 +105,72 @@ Cut_Man_t * Abc_NtkCuts( Abc_Ntk_t * pNtk, Cut_Params_t * pParams )
if ( pParams->fMulti )
Abc_NtkBalanceDetach(pNtk);
PRT( "Total", clock() - clk );
-Abc_NtkPrintCuts_( p, pNtk, 0 );
+//Abc_NtkPrintCuts_( p, pNtk, 0 );
// Cut_ManPrintStatsToFile( p, pNtk->pSpec, clock() - clk );
return p;
}
/**Function*************************************************************
+ Synopsis [Cut computation using the oracle.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkCutsOracle( Abc_Ntk_t * pNtk, Cut_Oracle_t * p )
+{
+ Abc_Obj_t * pObj;
+ Vec_Ptr_t * vNodes;
+ int i, clk = clock();
+ int fDrop = Cut_OracleReadDrop(p);
+
+ assert( Abc_NtkIsStrash(pNtk) );
+
+ // prepare cut droppping
+ if ( fDrop )
+ Cut_OracleSetFanoutCounts( p, Abc_NtkFanoutCounts(pNtk) );
+
+ // set cuts for PIs
+ Abc_NtkForEachCi( pNtk, pObj, i )
+ if ( Abc_ObjFanoutNum(pObj) > 0 )
+ Cut_OracleNodeSetTriv( p, pObj->Id );
+
+ // compute cuts for internal nodes
+ vNodes = Abc_AigDfs( pNtk, 0, 1 ); // collects POs
+ Vec_PtrForEachEntry( vNodes, pObj, i )
+ {
+ // when we reached a CO, it is time to deallocate the cuts
+ if ( Abc_ObjIsCo(pObj) )
+ {
+ if ( fDrop )
+ Cut_OracleTryDroppingCuts( p, Abc_ObjFaninId0(pObj) );
+ continue;
+ }
+ // skip constant node, it has no cuts
+ if ( Abc_NodeIsConst(pObj) )
+ continue;
+ // compute the cuts to the internal node
+ Cut_OracleComputeCuts( p, pObj->Id, Abc_ObjFaninId0(pObj), Abc_ObjFaninId1(pObj),
+ Abc_ObjFaninC0(pObj), Abc_ObjFaninC1(pObj) );
+ // consider dropping the fanins cuts
+ if ( fDrop )
+ {
+ Cut_OracleTryDroppingCuts( p, Abc_ObjFaninId0(pObj) );
+ Cut_OracleTryDroppingCuts( p, Abc_ObjFaninId1(pObj) );
+ }
+ }
+ Vec_PtrFree( vNodes );
+//PRT( "Total", clock() - clk );
+//Abc_NtkPrintCuts_( p, pNtk, 0 );
+}
+
+
+/**Function*************************************************************
+
Synopsis [Computes the cuts for the network.]
Description []
@@ -156,7 +215,6 @@ Cut_Man_t * Abc_NtkSeqCuts( Abc_Ntk_t * pNtk, Cut_Params_t * pParams )
// compute the cuts for the internal nodes
Abc_AigForEachAnd( pNtk, pObj, i )
Abc_NodeGetCutsSeq( p, pObj, nIters==0 );
-Abc_NtkPrintCuts( p, pNtk, 1 );
// merge the new cuts with the old cuts
Abc_NtkForEachPi( pNtk, pObj, i )
Cut_NodeNewMergeWithOld( p, pObj->Id );
@@ -183,7 +241,7 @@ Abc_NtkPrintCuts( p, pNtk, 1 );
pObj->fMarkC = 0;
PRT( "Total", clock() - clk );
printf( "Converged after %d iterations.\n", nIters );
-Abc_NtkPrintCuts( p, pNtk, 1 );
+//Abc_NtkPrintCuts( p, pNtk, 1 );
return p;
}
@@ -225,7 +283,7 @@ void * Abc_NodeGetCuts( void * p, Abc_Obj_t * pObj, int fMulti )
assert( Abc_NtkIsStrash(pObj->pNtk) );
assert( Abc_ObjFaninNum(pObj) == 2 );
return Cut_NodeComputeCuts( p, pObj->Id, Abc_ObjFaninId0(pObj), Abc_ObjFaninId1(pObj),
- Abc_ObjFaninC0(pObj), Abc_ObjFaninC1(pObj), 1, 1, fTriv );
+ Abc_ObjFaninC0(pObj), Abc_ObjFaninC1(pObj), fTriv );
}
/**Function*************************************************************
@@ -244,7 +302,7 @@ void Abc_NodeGetCutsSeq( void * p, Abc_Obj_t * pObj, int fTriv )
int CutSetNum;
assert( Abc_NtkIsSeq(pObj->pNtk) );
assert( Abc_ObjFaninNum(pObj) == 2 );
-// fTriv = pObj->fMarkC ? 0 : fTriv;
+ fTriv = pObj->fMarkC ? 0 : fTriv;
CutSetNum = pObj->fMarkC ? (int)pObj->pCopy : -1;
Cut_NodeComputeCutsSeq( p, pObj->Id, Abc_ObjFaninId0(pObj), Abc_ObjFaninId1(pObj),
Abc_ObjFaninC0(pObj), Abc_ObjFaninC1(pObj), Abc_ObjFaninL0(pObj), Abc_ObjFaninL1(pObj), fTriv, CutSetNum );
diff --git a/src/base/abcs/abcFpgaDelay.c b/src/base/abcs/abcFpgaDelay.c
new file mode 100644
index 00000000..1b957093
--- /dev/null
+++ b/src/base/abcs/abcFpgaDelay.c
@@ -0,0 +1,327 @@
+/**CFile****************************************************************
+
+ FileName [abcFpgaDelay.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Network and node package.]
+
+ Synopsis [Utilities working sequential AIGs.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: abcFpgaDelay.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "abcs.h"
+#include "cut.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+// the internal procedures
+static int Abc_NtkFpgaRetimeSearch_rec( Seq_FpgaMan_t * p, Abc_Ntk_t * pNtk, int FiMin, int FiMax, int fVerbose );
+static int Abc_NtkFpgaRetimeForPeriod( Seq_FpgaMan_t * p, Abc_Ntk_t * pNtk, int Fi, int fVerbose );
+static int Abc_NodeFpgaUpdateLValue( Seq_FpgaMan_t * p, Abc_Obj_t * pObj, int Fi );
+static void Abc_NtkFpgaCollect( Seq_FpgaMan_t * p );
+
+// node status after updating its arrival time
+enum { ABC_FPGA_UPDATE_FAIL, ABC_FPGA_UPDATE_NO, ABC_FPGA_UPDATE_YES };
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Retimes AIG for optimal delay.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkFpgaSeqRetimeDelayLags( Seq_FpgaMan_t * p )
+{
+ Abc_Ntk_t * pNtk = p->pNtk;
+ int fVerbose = p->fVerbose;
+ Abc_Obj_t * pNode;
+ int i, FiMax, FiBest, RetValue;
+
+ // start storage for sequential arrival times
+ assert( pNtk->pData == NULL );
+ pNtk->pData = p->vArrivals;
+
+ // get the upper bound on the clock period
+// FiMax = Abc_NtkNodeNum(pNtk);
+ FiMax = 0;
+ Abc_AigForEachAnd( pNtk, pNode, i )
+ if ( FiMax < (int)pNode->Level )
+ FiMax = pNode->Level;
+ FiMax += 2;
+
+ // make sure this clock period is feasible
+ assert( Abc_NtkFpgaRetimeForPeriod( p, pNtk, FiMax, fVerbose ) );
+
+ // search for the optimal clock period between 0 and nLevelMax
+ FiBest = Abc_NtkFpgaRetimeSearch_rec( p, pNtk, 0, FiMax, fVerbose );
+
+ // recompute the best LValues
+ RetValue = Abc_NtkFpgaRetimeForPeriod( p, pNtk, FiBest, fVerbose );
+ assert( RetValue );
+
+ // print the result
+ if ( fVerbose )
+ printf( "The best clock period is %3d.\n", FiBest );
+
+ // convert to lags
+ Abc_AigForEachAnd( pNtk, pNode, i )
+ Vec_StrWriteEntry( p->vLagsMap, i, (char)Abc_NodeGetLag(Abc_NodeReadLValue(pNode), FiBest) );
+/*
+ printf( "LValues : " );
+ Abc_AigForEachAnd( pNtk, pNode, i )
+ printf( "%d=%d ", i, Abc_NodeReadLValue(pNode) );
+ printf( "\n" );
+ printf( "Lags : " );
+ Abc_AigForEachAnd( pNtk, pNode, i )
+ if ( Vec_StrEntry(vLags,i) != 0 )
+ printf( "%d=%d(%d)(%d) ", i, Vec_StrEntry(vLags,i), Abc_NodeReadLValue(pNode), Abc_NodeReadLValue(pNode) - FiBest * Vec_StrEntry(vLags,i) );
+ printf( "\n" );
+*/
+ Abc_NtkFpgaCollect( p );
+
+ pNtk->pData = NULL;
+
+ Cut_ManStop( p->pMan );
+ p->pMan = NULL;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs binary search for the optimal clock period.]
+
+ Description [Assumes that FiMin is infeasible while FiMax is feasible.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_NtkFpgaRetimeSearch_rec( Seq_FpgaMan_t * p, Abc_Ntk_t * pNtk, int FiMin, int FiMax, int fVerbose )
+{
+ int Median;
+ assert( FiMin < FiMax );
+ if ( FiMin + 1 == FiMax )
+ return FiMax;
+ Median = FiMin + (FiMax - FiMin)/2;
+ if ( Abc_NtkFpgaRetimeForPeriod( p, pNtk, Median, fVerbose ) )
+ return Abc_NtkFpgaRetimeSearch_rec( p, pNtk, FiMin, Median, fVerbose ); // Median is feasible
+ else
+ return Abc_NtkFpgaRetimeSearch_rec( p, pNtk, Median, FiMax, fVerbose ); // Median is infeasible
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns 1 if retiming with this clock period is feasible.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_NtkFpgaRetimeForPeriod( Seq_FpgaMan_t * p, Abc_Ntk_t * pNtk, int Fi, int fVerbose )
+{
+ Abc_Obj_t * pObj;
+ int i, c, RetValue, fChange, Counter;
+ char * pReason = "";
+
+ // set l-values of all nodes to be minus infinity
+ Vec_IntFill( p->vArrivals, Abc_NtkObjNumMax(pNtk), -ABC_INFINITY );
+ Vec_PtrFill( p->vBestCuts, Abc_NtkObjNumMax(pNtk), NULL );
+
+ // set l-values for the constant and PIs
+ pObj = Abc_NtkObj( pNtk, 0 );
+ Abc_NodeSetLValue( pObj, 0 );
+ Abc_NtkForEachPi( pNtk, pObj, i )
+ Abc_NodeSetLValue( pObj, 0 );
+
+ // update all values iteratively
+ Counter = 0;
+ for ( c = 0; c < 20; c++ )
+ {
+ fChange = 0;
+ Abc_NtkForEachObj( pNtk, pObj, i )
+ {
+ if ( Abc_ObjIsPi(pObj) )
+ continue;
+ if ( Abc_ObjFaninNum(pObj) == 0 )
+ continue;
+ RetValue = Abc_NodeFpgaUpdateLValue( p, pObj, Fi );
+ Counter++;
+ if ( RetValue == ABC_FPGA_UPDATE_FAIL )
+ break;
+ if ( RetValue == ABC_FPGA_UPDATE_NO )
+ continue;
+ fChange = 1;
+ }
+ if ( RetValue == ABC_FPGA_UPDATE_FAIL )
+ break;
+ if ( fChange == 0 )
+ break;
+ }
+ if ( c == 20 )
+ {
+ RetValue = ABC_FPGA_UPDATE_FAIL;
+ pReason = "(timeout)";
+ }
+
+ // report the results
+ if ( fVerbose )
+ {
+ if ( RetValue == ABC_FPGA_UPDATE_FAIL )
+ printf( "Period = %3d. Iterations = %3d. Updates = %6d. Infeasible %s\n", Fi, c, Counter, pReason );
+ else
+ printf( "Period = %3d. Iterations = %3d. Updates = %6d. Feasible\n", Fi, c, Counter );
+ }
+ return RetValue != ABC_FPGA_UPDATE_FAIL;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Computes the l-value of the node.]
+
+ Description [The node can be internal or a PO.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_NodeFpgaUpdateLValue( Seq_FpgaMan_t * p, Abc_Obj_t * pObj, int Fi )
+{
+ Abc_Obj_t * pFanin;
+ Cut_Cut_t * pList, * pCut, * pCutBest;
+ int lValueNew, lValueOld, lValueCur, lValueFan;
+ int i;
+
+ assert( !Abc_ObjIsPi(pObj) );
+ assert( Abc_ObjFaninNum(pObj) > 0 );
+
+ if ( Abc_ObjIsPo(pObj) )
+ {
+ lValueOld = Abc_NodeReadLValue(Abc_ObjFanin0(pObj));
+ lValueNew = lValueOld - Fi * Abc_ObjFaninL0(pObj);
+ return (lValueNew > Fi)? ABC_FPGA_UPDATE_FAIL : ABC_FPGA_UPDATE_NO;
+ }
+
+ pCutBest = NULL;
+ lValueNew = ABC_INFINITY;
+ pList = Abc_NodeReadCuts( p->pMan, pObj );
+ for ( pCut = pList; pCut; pCut = pCut->pNext )
+ {
+ if ( pCut->nLeaves < 2 )
+ continue;
+ lValueCur = -ABC_INFINITY;
+ for ( i = 0; i < (int)pCut->nLeaves; i++ )
+ {
+ pFanin = Abc_NtkObj( pObj->pNtk, (pCut->pLeaves[i] >> CUT_SHIFT) );
+ lValueFan = Abc_NodeReadLValue(pFanin) - Fi * (pCut->pLeaves[i] & CUT_MASK);
+ lValueCur = ABC_MAX( lValueCur, lValueFan );
+ }
+ lValueCur += 1;
+ lValueNew = ABC_MIN( lValueNew, lValueCur );
+ if ( lValueNew == lValueCur )
+ pCutBest = pCut;
+ }
+
+ lValueOld = Abc_NodeReadLValue(pObj);
+// if ( lValueNew == lValueOld )
+ if ( lValueNew <= lValueOld )
+ return ABC_FPGA_UPDATE_NO;
+
+ Abc_NodeSetLValue( pObj, lValueNew );
+ Vec_PtrWriteEntry( p->vBestCuts, pObj->Id, pCutBest );
+ return ABC_FPGA_UPDATE_YES;
+}
+
+
+
+/**Function*************************************************************
+
+ Synopsis [Select nodes visible in the mapping.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NodeFpgaCollect_rec( Seq_FpgaMan_t * p, Abc_Obj_t * pNode )
+{
+ Cut_Cut_t * pCutBest;
+ Abc_Obj_t * pFanin;
+ Vec_Int_t * vLeaves;
+ int i;
+ // skip the CI
+ if ( Abc_ObjIsCi(pNode) )
+ return;
+ // if this node is already visited, skip
+ if ( Abc_NodeIsTravIdCurrent( pNode ) )
+ return;
+ // mark the node as visited
+ Abc_NodeSetTravIdCurrent( pNode );
+ // get the best cut of the node
+ pCutBest = Vec_PtrEntry( p->vBestCuts, pNode->Id );
+ for ( i = 0; i < (int)pCutBest->nLeaves; i++ )
+ {
+ pFanin = Abc_NtkObj( pNode->pNtk, (pCutBest->pLeaves[i] >> CUT_SHIFT) );
+ Abc_NodeFpgaCollect_rec( p, pFanin );
+ }
+ // collect the node and its cut
+ vLeaves = Vec_IntAlloc( pCutBest->nLeaves );
+ for ( i = 0; i < (int)pCutBest->nLeaves; i++ )
+ Vec_IntPush( vLeaves, pCutBest->pLeaves[i] );
+ Vec_PtrPush( p->vMapCuts, vLeaves );
+ Vec_PtrPush( p->vMapping, pNode );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Select nodes visible in the mapping.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkFpgaCollect( Seq_FpgaMan_t * p )
+{
+ Abc_Ntk_t * pNtk = p->pNtk;
+ Abc_Obj_t * pObj;
+ int i;
+ Vec_PtrClear( p->vMapping );
+ Vec_PtrClear( p->vMapCuts );
+ Abc_NtkIncrementTravId( pNtk );
+ Abc_NtkForEachPo( pNtk, pObj, i )
+ Abc_NodeFpgaCollect_rec( p, Abc_ObjFanin0(pObj) );
+}
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/base/abcs/abcFpgaSeq.c b/src/base/abcs/abcFpgaSeq.c
new file mode 100644
index 00000000..d68c2082
--- /dev/null
+++ b/src/base/abcs/abcFpgaSeq.c
@@ -0,0 +1,201 @@
+/**CFile****************************************************************
+
+ FileName [abcFpgaSeq.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Network and node package.]
+
+ Synopsis [Mapping for FPGAs using sequential cuts.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: abcFpgaSeq.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "abcs.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+Abc_Ntk_t * Abc_NtkMapSeq( Abc_Ntk_t * pNtk, int fVerbose ) { return 0; }
+
+extern Cut_Man_t * Abc_NtkSeqCuts( Abc_Ntk_t * pNtk, Cut_Params_t * pParams );
+extern void Abc_NtkFpgaSeqRetimeDelayLags( Seq_FpgaMan_t * p );
+
+static Seq_FpgaMan_t * Abc_NtkFpgaSeqStart( Abc_Ntk_t * pNtk, int fVerbose );
+static void Abc_NtkFpgaSeqStop( Seq_FpgaMan_t * p );
+
+static Abc_Ntk_t * Abc_NtkFpgaSeqConstruct( Seq_FpgaMan_t * p );
+static void Abc_NtkFpgaSeqRetime( Seq_FpgaMan_t * p, Abc_Ntk_t * pNtkNew );
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Retimes AIG for optimal delay.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Ntk_t * Abc_NtkFpgaSeq( Abc_Ntk_t * pNtk, int fVerbose )
+{
+ Abc_Ntk_t * pNtkNew;
+ Seq_FpgaMan_t * p;
+ Cut_Params_t Params, * pParams = &Params;
+ int clk;
+
+ assert( Abc_NtkIsSeq( pNtk ) );
+
+ // get the sequential FPGA manager
+ p = Abc_NtkFpgaSeqStart( pNtk, fVerbose );
+
+ // create the cuts
+ memset( pParams, 0, sizeof(Cut_Params_t) );
+ pParams->nVarsMax = 5; // 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
+
+clk = clock();
+ p->pMan = Abc_NtkSeqCuts( pNtk, pParams );
+p->timeCuts += clock() - clk;
+
+ // find best arrival times (p->vArrivals) and free the cuts
+ // select mapping (p->vMapping) and remember best cuts (p->vMapCuts)
+clk = clock();
+ Abc_NtkFpgaSeqRetimeDelayLags( p );
+p->timeDelay += clock() - clk;
+
+return NULL;
+
+ // construct the network
+clk = clock();
+ pNtkNew = Abc_NtkFpgaSeqConstruct( p );
+p->timeNtk += clock() - clk;
+
+ // retime the network
+clk = clock();
+ Abc_NtkFpgaSeqRetime( p, pNtkNew );
+p->timeRet += clock() - clk;
+
+ // remove temporaries
+ Abc_NtkFpgaSeqStop( p );
+
+ // check the resulting network
+ if ( !Abc_NtkCheck( pNtkNew ) )
+ fprintf( stdout, "Abc_NtkFpgaSeq(): Network check has failed.\n" );
+ return pNtkNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Starts sequential FPGA mapper.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Seq_FpgaMan_t * Abc_NtkFpgaSeqStart( Abc_Ntk_t * pNtk, int fVerbose )
+{
+ Seq_FpgaMan_t * p;
+ // create the FPGA mapping manager
+ p = ALLOC( Seq_FpgaMan_t, 1 );
+ memset( p, 0, sizeof(Seq_FpgaMan_t) );
+ p->pNtk = pNtk;
+ p->pMan = NULL;
+ p->vArrivals = Vec_IntAlloc( 0 );
+ p->vBestCuts = Vec_PtrAlloc( 0 );
+ p->vMapping = Vec_PtrAlloc( 0 );
+ p->vMapCuts = Vec_PtrAlloc( 0 );
+ p->vLagsMap = Vec_StrStart( Abc_NtkObjNumMax(pNtk) );
+ p->fVerbose = fVerbose;
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Stops sequential FPGA mapper.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkFpgaSeqStop( Seq_FpgaMan_t * p )
+{
+ if ( p->fVerbose )
+ {
+ printf( "Sequential FPGA mapping stats:\n" );
+// printf( "Total allocated = %8d.\n", p->nCutsAlloc );
+// printf( "Cuts per node = %8.1f\n", ((float)(p->nCutsCur-p->nCutsTriv))/p->nNodes );
+ PRT( "Cuts ", p->timeCuts );
+ PRT( "Arrival", p->timeDelay );
+ PRT( "Network", p->timeNtk );
+ PRT( "Retime ", p->timeRet );
+ }
+ Vec_IntFree( p->vArrivals );
+ Vec_PtrFree( p->vBestCuts );
+ Vec_PtrFree( p->vMapping );
+ Vec_VecFree( (Vec_Vec_t *)p->vMapCuts );
+ Vec_StrFree( p->vLagsMap );
+ free( p );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Construct the final network after mapping.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Ntk_t * Abc_NtkFpgaSeqConstruct( Seq_FpgaMan_t * p )
+{
+ Abc_Ntk_t * pNtk = NULL;
+ return pNtk;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Retimes the final network after mapping.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkFpgaSeqRetime( Seq_FpgaMan_t * p, Abc_Ntk_t * pNtkNew )
+{
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/base/abcs/abcRetDelay.c b/src/base/abcs/abcRetDelay.c
index 0697c699..0eda33c9 100644
--- a/src/base/abcs/abcRetDelay.c
+++ b/src/base/abcs/abcRetDelay.c
@@ -24,12 +24,6 @@
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
-// storing arrival times in the nodes
-static inline int Abc_NodeReadLValue( Abc_Obj_t * pNode ) { return Vec_IntEntry( (pNode)->pNtk->pData, (pNode)->Id ); }
-static inline void Abc_NodeSetLValue( Abc_Obj_t * pNode, int Value ) { Vec_IntWriteEntry( (pNode)->pNtk->pData, (pNode)->Id, (Value) ); }
-//static inline int Abc_NodeGetLag( int LValue, int Fi ) { return LValue/Fi - (int)(LValue % Fi == 0); }
-static inline int Abc_NodeGetLag( int LValue, int Fi ) { return (LValue + 256*Fi)/Fi - 256 - (int)(LValue % Fi == 0); }
-
// the internal procedures
static int Abc_NtkRetimeSearch_rec( Abc_Ntk_t * pNtk, int FiMin, int FiMax, int fVerbose );
static int Abc_NtkRetimeForPeriod( Abc_Ntk_t * pNtk, int Fi, int fVerbose );
diff --git a/src/base/abcs/abcs.h b/src/base/abcs/abcs.h
index fb45efba..e250d929 100644
--- a/src/base/abcs/abcs.h
+++ b/src/base/abcs/abcs.h
@@ -26,6 +26,7 @@
////////////////////////////////////////////////////////////////////////
#include "abc.h"
+#include "cut.h"
////////////////////////////////////////////////////////////////////////
/// PARAMETERS ///
@@ -38,6 +39,25 @@
/// BASIC TYPES ///
////////////////////////////////////////////////////////////////////////
+typedef struct Seq_FpgaMan_t_ Seq_FpgaMan_t;
+struct Seq_FpgaMan_t_
+{
+ Abc_Ntk_t * pNtk; // the network to be mapped
+ Cut_Man_t * pMan; // the cut manager
+ Vec_Int_t * vArrivals; // the arrival times (L-Values of nodes)
+ Vec_Ptr_t * vBestCuts; // the best cuts for nodes
+ Vec_Ptr_t * vMapping; // the nodes used in the mapping
+ Vec_Ptr_t * vMapCuts; // the info about the cut of each mapped node
+ Vec_Str_t * vLagsMap; // the lags of the mapped nodes
+ int fVerbose; // the verbose flag
+ // runtime stats
+ int timeCuts; // runtime to compute the cuts
+ int timeDelay; // runtime to compute the L-values
+ int timeRet; // runtime to retime the resulting network
+ int timeNtk; // runtime to create the final network
+};
+
+
// representation of latch on the edge
typedef struct Abc_RetEdge_t_ Abc_RetEdge_t;
struct Abc_RetEdge_t_ // 1 word
@@ -61,6 +81,12 @@ static inline Abc_RetEdge_t Abc_Int2RetEdge( int Num ) { return *((A
static inline int Abc_RetStep2Int( Abc_RetStep_t Str ) { return *((int *)&Str); }
static inline Abc_RetStep_t Abc_Int2RetStep( int Num ) { return *((Abc_RetStep_t *)&Num); }
+// storing arrival times in the nodes
+static inline int Abc_NodeReadLValue( Abc_Obj_t * pNode ) { return Vec_IntEntry( (pNode)->pNtk->pData, (pNode)->Id ); }
+static inline void Abc_NodeSetLValue( Abc_Obj_t * pNode, int Value ) { Vec_IntWriteEntry( (pNode)->pNtk->pData, (pNode)->Id, (Value) ); }
+//static inline int Abc_NodeGetLag( int LValue, int Fi ) { return LValue/Fi - (int)(LValue % Fi == 0); }
+static inline int Abc_NodeGetLag( int LValue, int Fi ) { return (LValue + 256*Fi)/Fi - 256 - (int)(LValue % Fi == 0); }
+
////////////////////////////////////////////////////////////////////////
/// MACRO DEFITIONS ///
////////////////////////////////////////////////////////////////////////