Commit e52e48c3 by Alan Mishchenko

Version abc50910

parent eb4cdcdc
......@@ -13,7 +13,7 @@ MODULES := src/base/abc src/base/abci src/base/abcs src/base/cmd src/base/io src
src/opt/cut src/opt/dec src/opt/fxu src/opt/rwr src/opt/sim \
src/sat/asat src/sat/csat src/sat/msat src/sat/fraig
#default: $(PROG)
default: $(PROG)
OPTFLAGS := -DNDEBUG -O3
#OPTFLAGS := -g -O
......@@ -59,10 +59,6 @@ tags:
$(PROG): $(OBJ)
$(LD) -o $@ $^ $(LIBS)
lib$(PROG).a: $(OBJ)
ar rv $@ $?
ranlib $@
docs:
doxygen doxygen.conf
This diff is collapsed. Click to expand it.
Microsoft Developer Studio Workspace File, Format Version 6.00
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
###############################################################################
Project: "abc"=.\abc.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Global:
Package=<5>
{{{
}}}
Package=<3>
{{{
}}}
###############################################################################
File added
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
Microsoft Developer Studio Workspace File, Format Version 6.00
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
###############################################################################
Project: "abclib"=.\abclib.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Global:
Package=<5>
{{{
}}}
Package=<3>
{{{
}}}
###############################################################################
File added
This diff is collapsed. Click to expand it.
// Demo program for the static library project of ABC
#include <stdio.h>
#include "src/sat/csat/csat_apis.h"
// procedures to start and stop the ABC framework
extern void Abc_Start();
extern void Abc_Stop();
// simple test prog
int main( int argc, char * argv[] )
{
CSAT_Manager_t * mng;
CSAT_Target_ResultT * pResult;
char * Names[2];
int Values[2];
int i;
// start ABC
// (calling Abc_Start() for each problem is timeconsuming
// because it allocates some internal data structures used by decomposition packages
// so Abc_Start should be called once before creating many solution managers)
Abc_Start();
// start the solution manager
// (the manager can be reused for several targets if the targets
// use the same network and only differ in the asserted values;
// however, only one target can be loaded into the manager at any time)
mng = CSAT_InitManager();
// create a simple circuit
// PIs: A, B, C
// POs: F = ((AB)C) <+> (A(BC))
// Internal nodes:
// X = AB U = XC
// Y = BC W = AY
// G = U <+> W
// F = G
// PIs should be added first
CSAT_AddGate( mng, CSAT_BPI, "A", 0, NULL, 0 );
CSAT_AddGate( mng, CSAT_BPI, "B", 0, NULL, 0 );
CSAT_AddGate( mng, CSAT_BPI, "C", 0, NULL, 0 );
// internal nodes should be added next
Names[0] = "A";
Names[1] = "B";
CSAT_AddGate( mng, CSAT_BAND, "X", 2, Names, 0 );
// CSAT_AddGate( mng, CSAT_BOR, "X", 2, Names, 0 ); // use this line to make the problem SATISFIABLE
Names[0] = "X";
Names[1] = "C";
CSAT_AddGate( mng, CSAT_BAND, "U", 2, Names, 0 );
Names[0] = "B";
Names[1] = "C";
CSAT_AddGate( mng, CSAT_BAND, "Y", 2, Names, 0 );
Names[0] = "A";
Names[1] = "Y";
CSAT_AddGate( mng, CSAT_BAND, "W", 2, Names, 0 );
Names[0] = "U";
Names[1] = "W";
CSAT_AddGate( mng, CSAT_BXOR, "G", 2, Names, 0 );
// POs should be added last
Names[0] = "G";
CSAT_AddGate( mng, CSAT_BPO, "F", 1, Names, 0 );
// check integrity of the manager (and finalize ABC network in the manager!)
if ( CSAT_Check_Integrity( mng ) )
printf( "Integrity is okey.\n" );
else
printf( "Integrity is NOT okey.\n" );
// dump the problem into a BENCH file
// currently BENCH file can only be written for an AIG
// so we will transform the network into AIG before dumping it
CSAT_EnableDump( mng, "simple.bench" );
CSAT_Dump_Bench_File( mng );
// set the solving target (only one target at a time!)
// the target can be expressed sing PI/PO or internal nodes
Names[0] = "F";
Values[0] = 1;
CSAT_AddTarget( mng, 1, Names, Values );
// initialize the sover
CSAT_SolveInit( mng );
// set the solving option (0 = brute-force SAT; 1 = resource-aware FRAIG)
CSAT_SetSolveOption( mng, 1 );
// solves the last added target
CSAT_Solve( mng );
// get the result of solving
pResult = CSAT_Get_Target_Result( mng, 0 );
// print the report
if ( pResult->status == UNDETERMINED )
printf( "The problem is UNDETERMINED.\n" );
else if ( pResult->status == UNSATISFIABLE )
printf( "The problem is UNSATISFIABLE.\n" );
else if ( pResult->status == SATISFIABLE )
{
printf( "The problem is SATISFIABLE.\n" );
printf( "Satisfying assignment is: " );
for ( i = 0; i < pResult->no_sig; i++ )
printf( "%s=%d ", pResult->names[i], pResult->values[i] );
printf( "\n" );
}
// free everything to prevent memory leaks
CSAT_TargetResFree( pResult );
CSAT_QuitManager( mng );
Abc_Stop();
return 0;
}
......@@ -430,11 +430,13 @@ extern void Abc_NodeFreeCuts( void * p, Abc_Obj_t * pObj );
extern Vec_Ptr_t * Abc_NtkDfs( Abc_Ntk_t * pNtk, int fCollectAll );
extern Vec_Ptr_t * Abc_NtkDfsNodes( Abc_Ntk_t * pNtk, Abc_Obj_t ** ppNodes, int nNodes );
extern Vec_Ptr_t * Abc_NtkDfsReverse( Abc_Ntk_t * pNtk );
extern bool Abc_NtkIsDfsOrdered( Abc_Ntk_t * pNtk );
extern Vec_Ptr_t * Abc_NtkNodeSupport( Abc_Ntk_t * pNtk, Abc_Obj_t ** ppNodes, int nNodes );
extern Vec_Ptr_t * Abc_AigDfs( Abc_Ntk_t * pNtk, int fCollectAll, int fCollectCos );
extern Vec_Vec_t * Abc_DfsLevelized( Abc_Obj_t * pNode, bool fTfi );
extern int Abc_NtkGetLevelNum( Abc_Ntk_t * pNtk );
extern bool Abc_NtkIsAcyclic( Abc_Ntk_t * pNtk );
extern Vec_Ptr_t * Abc_AigGetLevelizedOrder( Abc_Ntk_t * pNtk, int fCollectCis );
/*=== abcFanio.c ==========================================================*/
extern void Abc_ObjAddFanin( Abc_Obj_t * pObj, Abc_Obj_t * pFanin );
extern void Abc_ObjDeleteFanin( Abc_Obj_t * pObj, Abc_Obj_t * pFanin );
......
......@@ -101,7 +101,7 @@ bool Abc_NtkDoCheck( Abc_Ntk_t * pNtk )
}
if ( Abc_NtkHasMapping(pNtk) )
{
if ( pNtk->pManFunc != Abc_FrameReadLibGen(Abc_FrameGetGlobalFrame()) )
if ( pNtk->pManFunc != Abc_FrameReadLibGen() )
{
fprintf( stdout, "NetworkCheck: The library of the mapped network is not the global library.\n" );
return 0;
......
......@@ -206,6 +206,37 @@ void Abc_NtkDfsReverse_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes )
Vec_PtrPush( vNodes, pNode );
}
/**Function*************************************************************
Synopsis [Returns 1 if the ordering of nodes is DFS.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
bool Abc_NtkIsDfsOrdered( Abc_Ntk_t * pNtk )
{
Abc_Obj_t * pNode;
int i;
// set the traversal ID
Abc_NtkIncrementTravId( pNtk );
// mark the CIs
Abc_NtkForEachCi( pNtk, pNode, i )
Abc_NodeSetTravIdCurrent( pNode );
// go through the nodes
Abc_NtkForEachNode( pNtk, pNode, i )
{
if ( !Abc_NodeIsTravIdCurrent(Abc_ObjFanin0(pNode)) )
return 0;
if ( !Abc_NodeIsTravIdCurrent(Abc_ObjFanin1(pNode)) )
return 0;
Abc_NodeSetTravIdCurrent( pNode );
}
return 1;
}
/**Function*************************************************************
......@@ -573,6 +604,123 @@ bool Abc_NtkIsAcyclic_rec( Abc_Obj_t * pNode )
return 1;
}
/**Function*************************************************************
Synopsis [Analyses choice nodes.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_NodeSetChoiceLevel_rec( Abc_Obj_t * pNode, int fMaximum )
{
Abc_Obj_t * pTemp;
int Level1, Level2, Level, LevelE;
// skip the visited node
if ( Abc_NodeIsTravIdCurrent( pNode ) )
return (int)pNode->pCopy;
Abc_NodeSetTravIdCurrent( pNode );
// compute levels of the children nodes
Level1 = Abc_NodeSetChoiceLevel_rec( Abc_ObjFanin0(pNode), fMaximum );
Level2 = Abc_NodeSetChoiceLevel_rec( Abc_ObjFanin1(pNode), fMaximum );
Level = 1 + ABC_MAX( Level1, Level2 );
if ( pNode->pData )
{
LevelE = Abc_NodeSetChoiceLevel_rec( pNode->pData, fMaximum );
if ( fMaximum )
Level = ABC_MAX( Level, LevelE );
else
Level = ABC_MIN( Level, LevelE );
// set the level of all equivalent nodes to be the same minimum
for ( pTemp = pNode->pData; pTemp; pTemp = pTemp->pData )
pTemp->pCopy = (void *)Level;
}
pNode->pCopy = (void *)Level;
return Level;
}
/**Function*************************************************************
Synopsis [Resets the levels of the nodes in the choice graph.]
Description [Makes the level of the choice nodes to be equal to the
maximum of the level of the nodes in the equivalence class. This way
sorting by level leads to the reverse topological order, which is
needed for the required time computation.]
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_AigSetChoiceLevels( Abc_Ntk_t * pNtk )
{
Abc_Obj_t * pObj;
int i, LevelMax, LevelCur;
assert( Abc_NtkIsStrash(pNtk) );
// set the new travid counter
Abc_NtkIncrementTravId( pNtk );
// set levels of the CI and constant
Abc_NtkForEachCi( pNtk, pObj, i )
{
Abc_NodeSetTravIdCurrent( pObj );
pObj->pCopy = NULL;
}
pObj = Abc_AigConst1( pNtk->pManFunc );
Abc_NodeSetTravIdCurrent( pObj );
pObj->pCopy = NULL;
// set levels of all other nodes
LevelMax = 0;
Abc_NtkForEachCo( pNtk, pObj, i )
{
LevelCur = Abc_NodeSetChoiceLevel_rec( Abc_ObjFanin0(pObj), 1 );
LevelMax = ABC_MAX( LevelMax, LevelCur );
}
return LevelMax;
}
/**Function*************************************************************
Synopsis [Returns nodes by level from the smallest to the largest.]
Description [Correctly handles the case of choice nodes, by first
spreading them out across several levels and then collecting.]
SideEffects [What happens with dangling nodes???]
SeeAlso []
***********************************************************************/
Vec_Ptr_t * Abc_AigGetLevelizedOrder( Abc_Ntk_t * pNtk, int fCollectCis )
{
Vec_Ptr_t * vNodes, * vLevels;
Abc_Obj_t * pNode, ** ppHead;
int LevelMax, i;
assert( Abc_NtkIsStrash(pNtk) );
// set the correct levels
Abc_NtkCleanCopy( pNtk );
LevelMax = Abc_AigSetChoiceLevels( pNtk );
// relink nodes by level
vLevels = Vec_PtrStart( LevelMax + 1 );
Abc_NtkForEachNode( pNtk, pNode, i )
{
ppHead = ((Abc_Obj_t **)vLevels->pArray) + (int)pNode->pCopy;
pNode->pCopy = *ppHead;
*ppHead = pNode;
}
// recollect nodes
vNodes = Vec_PtrStart( Abc_NtkNodeNum(pNtk) );
Vec_PtrForEachEntryStart( vLevels, pNode, i, !fCollectCis )
for ( ; pNode; pNode = pNode->pCopy )
Vec_PtrPush( vNodes, pNode );
Vec_PtrFree( vLevels );
return vNodes;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
......
......@@ -74,7 +74,7 @@ Abc_Ntk_t * Abc_NtkAlloc( Abc_NtkType_t Type, Abc_NtkFunc_t Func )
else if ( Abc_NtkHasAig(pNtk) )
pNtk->pManFunc = Abc_AigAlloc( pNtk );
else if ( Abc_NtkHasMapping(pNtk) )
pNtk->pManFunc = Abc_FrameReadLibGen(Abc_FrameGetGlobalFrame());
pNtk->pManFunc = Abc_FrameReadLibGen();
else
assert( 0 );
return pNtk;
......
......@@ -518,7 +518,7 @@ Abc_Obj_t * Abc_NodeCreateConst0( Abc_Ntk_t * pNtk )
else if ( Abc_NtkHasBdd(pNtk) )
pNode->pData = Cudd_ReadLogicZero(pNtk->pManFunc), Cudd_Ref( pNode->pData );
else if ( Abc_NtkHasMapping(pNtk) )
pNode->pData = Mio_LibraryReadConst0(Abc_FrameReadLibGen(Abc_FrameGetGlobalFrame()));
pNode->pData = Mio_LibraryReadConst0(Abc_FrameReadLibGen());
else
assert( 0 );
return pNode;
......@@ -546,7 +546,7 @@ Abc_Obj_t * Abc_NodeCreateConst1( Abc_Ntk_t * pNtk )
else if ( Abc_NtkHasBdd(pNtk) )
pNode->pData = Cudd_ReadOne(pNtk->pManFunc), Cudd_Ref( pNode->pData );
else if ( Abc_NtkHasMapping(pNtk) )
pNode->pData = Mio_LibraryReadConst1(Abc_FrameReadLibGen(Abc_FrameGetGlobalFrame()));
pNode->pData = Mio_LibraryReadConst1(Abc_FrameReadLibGen());
else
assert( 0 );
return pNode;
......@@ -574,7 +574,7 @@ Abc_Obj_t * Abc_NodeCreateInv( Abc_Ntk_t * pNtk, Abc_Obj_t * pFanin )
else if ( Abc_NtkHasBdd(pNtk) )
pNode->pData = Cudd_Not(Cudd_bddIthVar(pNtk->pManFunc,0)), Cudd_Ref( pNode->pData );
else if ( Abc_NtkHasMapping(pNtk) )
pNode->pData = Mio_LibraryReadInv(Abc_FrameReadLibGen(Abc_FrameGetGlobalFrame()));
pNode->pData = Mio_LibraryReadInv(Abc_FrameReadLibGen());
else
assert( 0 );
return pNode;
......@@ -602,7 +602,7 @@ Abc_Obj_t * Abc_NodeCreateBuf( Abc_Ntk_t * pNtk, Abc_Obj_t * pFanin )
else if ( Abc_NtkHasBdd(pNtk) )
pNode->pData = Cudd_bddIthVar(pNtk->pManFunc,0), Cudd_Ref( pNode->pData );
else if ( Abc_NtkHasMapping(pNtk) )
pNode->pData = Mio_LibraryReadBuf(Abc_FrameReadLibGen(Abc_FrameGetGlobalFrame()));
pNode->pData = Mio_LibraryReadBuf(Abc_FrameReadLibGen());
else
assert( 0 );
return pNode;
......@@ -781,7 +781,7 @@ bool Abc_NodeIsConst0( Abc_Obj_t * pNode )
if ( Abc_NtkHasAig(pNtk) )
return Abc_ObjNot(pNode) == Abc_AigConst1(pNode->pNtk->pManFunc);
if ( Abc_NtkHasMapping(pNtk) )
return pNode->pData == Mio_LibraryReadConst0(Abc_FrameReadLibSuper(Abc_FrameGetGlobalFrame()));
return pNode->pData == Mio_LibraryReadConst0(Abc_FrameReadLibSuper());
assert( 0 );
return 0;
}
......@@ -809,7 +809,7 @@ bool Abc_NodeIsConst1( Abc_Obj_t * pNode )
if ( Abc_NtkHasAig(pNtk) )
return pNode == Abc_AigConst1(pNode->pNtk->pManFunc);
if ( Abc_NtkHasMapping(pNtk) )
return pNode->pData == Mio_LibraryReadConst1(Abc_FrameReadLibSuper(Abc_FrameGetGlobalFrame()));
return pNode->pData == Mio_LibraryReadConst1(Abc_FrameReadLibSuper());
assert( 0 );
return 0;
}
......@@ -838,7 +838,7 @@ bool Abc_NodeIsBuf( Abc_Obj_t * pNode )
if ( Abc_NtkHasAig(pNtk) )
return 0;
if ( Abc_NtkHasMapping(pNtk) )
return pNode->pData == Mio_LibraryReadBuf(Abc_FrameReadLibSuper(Abc_FrameGetGlobalFrame()));
return pNode->pData == Mio_LibraryReadBuf(Abc_FrameReadLibSuper());
assert( 0 );
return 0;
}
......@@ -867,7 +867,7 @@ bool Abc_NodeIsInv( Abc_Obj_t * pNode )
if ( Abc_NtkHasAig(pNtk) )
return 0;
if ( Abc_NtkHasMapping(pNtk) )
return pNode->pData == Mio_LibraryReadInv(Abc_FrameReadLibSuper(Abc_FrameGetGlobalFrame()));
return pNode->pData == Mio_LibraryReadInv(Abc_FrameReadLibSuper());
assert( 0 );
return 0;
}
......
......@@ -22,6 +22,8 @@
#include "mainInt.h"
#include "fraig.h"
#include "fxu.h"
#include "fpga.h"
#include "pga.h"
#include "cut.h"
////////////////////////////////////////////////////////////////////////
......@@ -80,6 +82,7 @@ static int Abc_CommandAttach ( Abc_Frame_t * pAbc, int argc, char ** argv
static int Abc_CommandSuperChoice ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandFpga ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandPga ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandSeq ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandRetime ( Abc_Frame_t * pAbc, int argc, char ** argv );
......@@ -156,6 +159,7 @@ void Abc_Init( Abc_Frame_t * pAbc )
Cmd_CommandAdd( pAbc, "SC mapping", "sc", Abc_CommandSuperChoice, 1 );
Cmd_CommandAdd( pAbc, "FPGA mapping", "fpga", Abc_CommandFpga, 1 );
Cmd_CommandAdd( pAbc, "FPGA mapping", "pga", Abc_CommandPga, 1 );
Cmd_CommandAdd( pAbc, "Sequential", "seq", Abc_CommandSeq, 1 );
Cmd_CommandAdd( pAbc, "Sequential", "retime", Abc_CommandRetime, 1 );
......@@ -2720,14 +2724,13 @@ int Abc_CommandCut( Abc_Frame_t * pAbc, int argc, char ** argv )
// set defaults
pParams->nVarsMax = 5; // the max cut size ("k" of the k-feasible cuts)
pParams->nKeepMax = 250; // the max number of cuts kept at a node
pParams->fTruth = 1; // compute truth tables
pParams->fHash = 0; // hash cuts to detect unique
pParams->fFilter = 0; // filter dominated cuts
pParams->fTruth = 0; // compute truth tables
pParams->fFilter = 1; // filter dominated cuts
pParams->fSeq = 0; // compute sequential cuts
pParams->fDrop = 0; // drop cuts on the fly
pParams->fVerbose = 0; // the verbosiness flag
util_getopt_reset();
while ( ( c = util_getopt( argc, argv, "KMtrfsdvh" ) ) != EOF )
while ( ( c = util_getopt( argc, argv, "KMtfsdvh" ) ) != EOF )
{
switch ( c )
{
......@@ -2756,9 +2759,6 @@ int Abc_CommandCut( Abc_Frame_t * pAbc, int argc, char ** argv )
case 't':
pParams->fTruth ^= 1;
break;
case 'r':
pParams->fHash ^= 1;
break;
case 'f':
pParams->fFilter ^= 1;
break;
......@@ -2794,16 +2794,15 @@ int Abc_CommandCut( Abc_Frame_t * pAbc, int argc, char ** argv )
return 0;
usage:
fprintf( pErr, "usage: cut [-K num] [-M num] [-trfsdvh]\n" );
fprintf( pErr, "usage: cut [-K num] [-M num] [-tfsdvh]\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-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-r : toggle reduction by hashing [default = %s]\n", pParams->fHash? "yes": "no" );
fprintf( pErr, "\t-f : toggle filtering by dominance [default = %s]\n", pParams->fFilter? "yes": "no" );
fprintf( pErr, "\t-s : toggle sequential cut computation [default = %s]\n", pParams->fSeq? "yes": "no" );
fprintf( pErr, "\t-d : toggle dropping when fanouts are done [default = %s]\n", pParams->fDrop? "yes": "no" );
fprintf( pErr, "\t-v : toggle printing verbose information [default = %s]\n", pParams->fVerbose? "yes": "no" );
fprintf( pErr, "\t-K num : max number of leaves (4 <= num <= 6) [default = %d]\n", 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-s : toggle sequential cut computation [default = %s]\n", pParams->fSeq? "yes": "no" );
fprintf( pErr, "\t-d : toggle dropping when fanouts are done [default = %s]\n", pParams->fDrop? "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;
}
......@@ -3771,6 +3770,123 @@ usage:
return 1;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_CommandPga( Abc_Frame_t * pAbc, int argc, char ** argv )
{
FILE * pOut, * pErr;
Abc_Ntk_t * pNtk, * pNtkRes;
Pga_Params_t Params, * pParams = &Params;
int c;
extern Abc_Ntk_t * Abc_NtkPga( Pga_Params_t * pParams );
pNtk = Abc_FrameReadNet(pAbc);
pOut = Abc_FrameReadOut(pAbc);
pErr = Abc_FrameReadErr(pAbc);
// set defaults
memset( pParams, 0, sizeof(Pga_Params_t) );
pParams->pNtk = pNtk;
pParams->pLutLib = Abc_FrameReadLibLut();
pParams->fAreaFlow = 1;
pParams->fArea = 1;
pParams->fSwitching = 0;
pParams->fDropCuts = 0;
pParams->fVerbose = 0;
util_getopt_reset();
while ( ( c = util_getopt( argc, argv, "fapdvh" ) ) != EOF )
{
switch ( c )
{
case 'f':
pParams->fAreaFlow ^= 1;
break;
case 'a':
pParams->fArea ^= 1;
break;
case 'p':
pParams->fSwitching ^= 1;
break;
case 'd':
pParams->fDropCuts ^= 1;
break;
case 'v':
pParams->fVerbose ^= 1;
break;
case 'h':
default:
goto usage;
}
}
if ( pNtk == NULL )
{
fprintf( pErr, "Empty network.\n" );
return 1;
}
if ( !Abc_NtkIsStrash(pNtk) )
{
// strash and balance the network
pNtk = Abc_NtkStrash( pNtk, 0, 0 );
if ( pNtk == NULL )
{
fprintf( pErr, "Strashing before FPGA mapping has failed.\n" );
return 1;
}
pNtk = Abc_NtkBalance( pNtkRes = pNtk, 0 );
Abc_NtkDelete( pNtkRes );
if ( pNtk == NULL )
{
fprintf( pErr, "Balancing before FPGA mapping has failed.\n" );
return 1;
}
fprintf( pOut, "The network was strashed and balanced before FPGA mapping.\n" );
// get the new network
pNtkRes = Abc_NtkPga( pParams );
if ( pNtkRes == NULL )
{
Abc_NtkDelete( pNtk );
fprintf( pErr, "FPGA mapping has failed.\n" );
return 1;
}
Abc_NtkDelete( pNtk );
}
else
{
// get the new network
pNtkRes = Abc_NtkPga( pParams );
if ( pNtkRes == NULL )
{
fprintf( pErr, "FPGA mapping has failed.\n" );
return 1;
}
}
// replace the current network
Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes );
return 0;
usage:
fprintf( pErr, "usage: pga [-fapdvh]\n" );
fprintf( pErr, "\t performs FPGA mapping of the current network\n" );
fprintf( pErr, "\t-f : toggles area flow recovery [default = %s]\n", pParams->fAreaFlow? "yes": "no" );
fprintf( pErr, "\t-a : toggles area recovery [default = %s]\n", pParams->fArea? "yes": "no" );
fprintf( pErr, "\t-p : optimizes power by minimizing switching activity [default = %s]\n", pParams->fSwitching? "yes": "no" );
fprintf( pErr, "\t-d : toggles dropping cuts to save memory [default = %s]\n", pParams->fDropCuts? "yes": "no" );
fprintf( pErr, "\t-v : toggles verbose output [default = %s]\n", pParams->fVerbose? "yes": "no" );
fprintf( pErr, "\t-h : prints the command usage\n");
return 1;
}
/**Function*************************************************************
......
......@@ -66,7 +66,7 @@ int Abc_NtkAttach( Abc_Ntk_t * pNtk )
assert( Abc_NtkIsSopLogic(pNtk) );
// check that the library is available
pGenlib = Abc_FrameReadLibGen(Abc_FrameGetGlobalFrame());
pGenlib = Abc_FrameReadLibGen();
if ( pGenlib == NULL )
{
printf( "The current library is not available.\n" );
......
......@@ -105,7 +105,6 @@ PRT( "Total", clock() - clk );
if ( Abc_NodeIsTravIdCurrent(pDriver) )
continue;
Abc_NodeSetTravIdCurrent(pDriver);
Cut_NodeSetComputedAsNew( p, pDriver->Id );
}
// compute as long as new cuts appear
......
......@@ -556,7 +556,7 @@ void Abc_NtkFraigStoreCheck( Abc_Ntk_t * pFraig )
int i, k;
// check that the PO functions are correct
nPoFinal = Abc_NtkPoNum(pFraig);
nStored = Abc_FrameReadNtkStoreSize(Abc_FrameGetGlobalFrame());
nStored = Abc_FrameReadNtkStoreSize();
assert( nPoFinal % nStored == 0 );
nPoOrig = nPoFinal / nStored;
for ( i = 0; i < nPoOrig; i++ )
......
......@@ -66,18 +66,18 @@ Abc_Ntk_t * Abc_NtkMap( Abc_Ntk_t * pNtk, double DelayTarget, int fRecovery, int
assert( Abc_NtkIsStrash(pNtk) );
// check that the library is available
if ( Abc_FrameReadLibGen(Abc_FrameGetGlobalFrame()) == NULL )
if ( Abc_FrameReadLibGen() == NULL )
{
printf( "The current library is not available.\n" );
return 0;
}
// derive the supergate library
if ( Abc_FrameReadLibSuper(Abc_FrameGetGlobalFrame()) == NULL && Abc_FrameReadLibGen(Abc_FrameGetGlobalFrame()) )
if ( Abc_FrameReadLibSuper() == NULL && Abc_FrameReadLibGen() )
{
printf( "A simple supergate library is derived from gate library \"%s\".\n",
Mio_LibraryReadName(Abc_FrameReadLibGen(Abc_FrameGetGlobalFrame())) );
Map_SuperLibDeriveFromGenlib( Abc_FrameReadLibGen(Abc_FrameGetGlobalFrame()) );
Mio_LibraryReadName(Abc_FrameReadLibGen()) );
Map_SuperLibDeriveFromGenlib( Abc_FrameReadLibGen() );
}
// print a warning about choice nodes
......@@ -410,7 +410,7 @@ int Abc_NtkUnmap( Abc_Ntk_t * pNtk )
assert( Abc_NtkIsMappedLogic(pNtk) );
// update the functionality manager
assert( pNtk->pManFunc == Abc_FrameReadLibGen(Abc_FrameGetGlobalFrame()) );
assert( pNtk->pManFunc == Abc_FrameReadLibGen() );
pNtk->pManFunc = Extra_MmFlexStart();
pNtk->ntkFunc = ABC_FUNC_SOP;
// update the nodes
......@@ -446,18 +446,18 @@ Abc_Ntk_t * Abc_NtkSuperChoice( Abc_Ntk_t * pNtk )
assert( Abc_NtkIsStrash(pNtk) );
// check that the library is available
if ( Abc_FrameReadLibGen(Abc_FrameGetGlobalFrame()) == NULL )
if ( Abc_FrameReadLibGen() == NULL )
{
printf( "The current library is not available.\n" );
return 0;
}
// derive the supergate library
if ( Abc_FrameReadLibSuper(Abc_FrameGetGlobalFrame()) == NULL && Abc_FrameReadLibGen(Abc_FrameGetGlobalFrame()) )
if ( Abc_FrameReadLibSuper() == NULL && Abc_FrameReadLibGen() )
{
printf( "A simple supergate library is derived from gate library \"%s\".\n",
Mio_LibraryReadName(Abc_FrameReadLibGen(Abc_FrameGetGlobalFrame())) );
Map_SuperLibDeriveFromGenlib( Abc_FrameReadLibGen(Abc_FrameGetGlobalFrame()) );
Mio_LibraryReadName(Abc_FrameReadLibGen()) );
Map_SuperLibDeriveFromGenlib( Abc_FrameReadLibGen() );
}
// print a warning about choice nodes
......
/**CFile****************************************************************
FileName [abcPga.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Network and node package.]
Synopsis [Interface with the FPGA mapping package.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: abcPga.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "abc.h"
#include "fraig.h"
#include "fpga.h"
#include "pga.h"
#include "cut.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
static Abc_Ntk_t * Abc_NtkFromPga( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodeCuts );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Interface with the FPGA mapping package.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Ntk_t * Abc_NtkPga( Pga_Params_t * pParams )
{
Abc_Ntk_t * pNtkNew, * pNtk = pParams->pNtk;
Pga_Man_t * pMan;
Vec_Ptr_t * vNodeCuts;
assert( Abc_NtkIsStrash(pNtk) );
// print a warning about choice nodes
if ( Abc_NtkGetChoiceNum( pNtk ) )
printf( "Performing FPGA mapping with choices.\n" );
// start the mapping manager
pMan = Pga_ManStart( pParams );
if ( pMan == NULL )
return NULL;
// perform mapping
vNodeCuts = Pga_DoMapping( pMan );
// transform the result of mapping into a BDD logic network
pNtkNew = Abc_NtkFromPga( pNtk, vNodeCuts );
if ( pNtkNew == NULL )
return NULL;
Pga_ManStop( pMan );
Vec_PtrFree( vNodeCuts );
// make the network minimum base
Abc_NtkMinimumBase( pNtkNew );
// make sure that everything is okay
if ( !Abc_NtkCheck( pNtkNew ) )
{
printf( "Abc_NtkPga: The network check has failed.\n" );
Abc_NtkDelete( pNtkNew );
return NULL;
}
return pNtkNew;
}
/**Function*************************************************************
Synopsis [Creates the mapped network.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Ntk_t * Abc_NtkFromPga( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodeCuts )
{
ProgressBar * pProgress;
DdManager * dd;
Abc_Ntk_t * pNtkNew;
Abc_Obj_t * pNode, * pFanin, * pNodeNew;
Cut_Cut_t * pCut;
Vec_Ptr_t * vLeaves, * vVisited;
int i, k, nDupGates;
// create the new network
pNtkNew = Abc_NtkStartFrom( pNtk, ABC_TYPE_LOGIC, ABC_FUNC_BDD );
dd = pNtkNew->pManFunc;
// set the constant node
pNode = Abc_AigConst1(pNtk->pManFunc);
if ( Abc_ObjFanoutNum(pNode) > 0 )
pNode->pCopy = Abc_NodeCreateConst1(pNtkNew);
// add new nodes in topologic order
vLeaves = Vec_PtrAlloc( 6 );
vVisited = Vec_PtrAlloc( 100 );
pProgress = Extra_ProgressBarStart( stdout, Vec_PtrSize(vNodeCuts) );
Vec_PtrForEachEntry( vNodeCuts, pCut, i )
{
Extra_ProgressBarUpdate( pProgress, i, NULL );
// create the new node
pNodeNew = Abc_NtkCreateNode( pNtkNew );
Vec_PtrClear( vLeaves );
for ( k = 0; k < (int)pCut->nLeaves; k++ )
{
// add the node representing the old fanin in the new network
pFanin = Abc_NtkObj( pNtk, pCut->pLeaves[k] );
Vec_PtrPush( vLeaves, pFanin );
Abc_ObjAddFanin( pNodeNew, pFanin->pCopy );
}
// set the new node at the old node
pNode = Abc_NtkObj( pNtk, pCut->uSign ); // pCut->uSign contains the ID of the root node
pNode->pCopy = pNodeNew;
// create the function of the new node
pNodeNew->pData = Abc_NodeConeBdd( dd, dd->vars, pNode, vLeaves, vVisited ); Cudd_Ref( pNodeNew->pData );
}
Extra_ProgressBarStop( pProgress );
Vec_PtrFree( vVisited );
Vec_PtrFree( vLeaves );
// finalize the new network
Abc_NtkFinalize( pNtk, pNtkNew );
// decouple the PO driver nodes to reduce the number of levels
nDupGates = Abc_NtkLogicMakeSimpleCos( pNtkNew, 1 );
// if ( nDupGates && Fpga_ManReadVerbose(pMan) )
// printf( "Duplicated %d gates to decouple the CO drivers.\n", nDupGates );
return pNtkNew;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
......@@ -32,7 +32,7 @@
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
static Cut_Man_t * Abc_NtkStartCutManForRewrite( Abc_Ntk_t * pNtk, int fDrop );
static Cut_Man_t * Abc_NtkStartCutManForRewrite( Abc_Ntk_t * pNtk );
static void Abc_NodePrintCuts( Abc_Obj_t * pNode );
////////////////////////////////////////////////////////////////////////
......@@ -52,7 +52,6 @@ static void Abc_NodePrintCuts( Abc_Obj_t * pNode );
***********************************************************************/
int Abc_NtkRewrite( Abc_Ntk_t * pNtk, int fUpdateLevel, int fUseZeros, int fVerbose )
{
int fDrop = 0;
ProgressBar * pProgress;
Cut_Man_t * pManCut;
Rwr_Man_t * pManRwr;
......@@ -72,7 +71,7 @@ int Abc_NtkRewrite( Abc_Ntk_t * pNtk, int fUpdateLevel, int fUseZeros, int fVerb
Abc_NtkStartReverseLevels( pNtk );
// start the cut manager
clk = clock();
pManCut = Abc_NtkStartCutManForRewrite( pNtk, fDrop );
pManCut = Abc_NtkStartCutManForRewrite( pNtk );
Rwr_ManAddTimeCuts( pManRwr, clock() - clk );
pNtk->pManCut = pManCut;
......@@ -142,7 +141,7 @@ Rwr_ManAddTimeTotal( pManRwr, clock() - clkStart );
SeeAlso []
***********************************************************************/
Cut_Man_t * Abc_NtkStartCutManForRewrite( Abc_Ntk_t * pNtk, int fDrop )
Cut_Man_t * Abc_NtkStartCutManForRewrite( Abc_Ntk_t * pNtk )
{
static Cut_Params_t Params, * pParams = &Params;
Cut_Man_t * pManCut;
......@@ -153,10 +152,9 @@ Cut_Man_t * Abc_NtkStartCutManForRewrite( Abc_Ntk_t * pNtk, int fDrop )
pParams->nVarsMax = 4; // the max cut size ("k" of the k-feasible cuts)
pParams->nKeepMax = 250; // the max number of cuts kept at a node
pParams->fTruth = 1; // compute truth tables
pParams->fHash = 1; // hash cuts to detect unique
pParams->fFilter = 0; // filter dominated cuts
pParams->fFilter = 1; // filter dominated cuts
pParams->fSeq = 0; // compute sequential cuts
pParams->fDrop = fDrop; // drop cuts on the fly
pParams->fDrop = 0; // drop cuts on the fly
pParams->fVerbose = 0; // the verbosiness flag
pParams->nIdsMax = Abc_NtkObjNumMax( pNtk );
pManCut = Cut_ManStart( pParams );
......@@ -182,13 +180,15 @@ Cut_Man_t * Abc_NtkStartCutManForRewrite( Abc_Ntk_t * pNtk, int fDrop )
***********************************************************************/
void Abc_NodePrintCuts( Abc_Obj_t * pNode )
{
Vec_Ptr_t * vCuts;
Cut_Cut_t * pCut;
unsigned uTruth;
int k;
printf( "\nNode %s\n", Abc_ObjName(pNode) );
for ( pCut = (Cut_Cut_t *)pNode->pCopy; pCut; pCut = pCut->pNext )
vCuts = (Vec_Ptr_t *)pNode->pCopy;
Vec_PtrForEachEntry( vCuts, pCut, k )
{
uTruth = pCut->uTruth;
Extra_PrintBinary( stdout, &uTruth, 16 );
Extra_PrintBinary( stdout, (unsigned *)&pCut->uSign, 16 );
printf( " " );
Cut_CutPrint( pCut );
printf( "\n" );
......
......@@ -470,9 +470,9 @@ void Abc_NtkSetNodeLevelsArrival( Abc_Ntk_t * pNtkOld )
int i;
if ( pNtkOld->pManTime == NULL )
return;
if ( Mio_LibraryReadNand2(Abc_FrameReadLibGen(Abc_FrameGetGlobalFrame())) == NULL )
if ( Mio_LibraryReadNand2(Abc_FrameReadLibGen()) == NULL )
return;
tAndDelay = Mio_LibraryReadDelayNand2Max(Abc_FrameReadLibGen(Abc_FrameGetGlobalFrame()));
tAndDelay = Mio_LibraryReadDelayNand2Max(Abc_FrameReadLibGen());
Abc_NtkForEachPi( pNtkOld, pNodeOld, i )
{
pNodeNew = pNodeOld->pCopy;
......
......@@ -10,6 +10,7 @@ SRC += src/base/abci/abc.c \
src/base/abci/abcMap.c \
src/base/abci/abcMiter.c \
src/base/abci/abcNtbdd.c \
src/base/abci/abcPga.c \
src/base/abci/abcPrint.c \
src/base/abci/abcReconv.c \
src/base/abci/abcRefactor.c \
......
......@@ -550,7 +550,7 @@ int Io_ReadBlifNetworkGate( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens )
int i, nNames;
// check that the library is available
pGenlib = Abc_FrameReadLibGen(Abc_FrameGetGlobalFrame());
pGenlib = Abc_FrameReadLibGen();
if ( pGenlib == NULL )
{
p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0);
......
......@@ -21,7 +21,7 @@
#include "mainInt.h"
// this line should be included in the library project
#define _LIB
//#define _LIB
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
......
......@@ -77,7 +77,7 @@ void Fpga_Init( Abc_Frame_t * pAbc )
***********************************************************************/
void Fpga_End()
{
Fpga_LutLibFree( Abc_FrameReadLibLut(Abc_FrameGetGlobalFrame()) );
Fpga_LutLibFree( Abc_FrameReadLibLut() );
}
......@@ -221,7 +221,7 @@ int Fpga_CommandPrintLibrary( Abc_Frame_t * pAbc, int argc, char **argv )
}
// set the new network
Fpga_LutLibPrint( Abc_FrameReadLibLut(Abc_FrameGetGlobalFrame()) );
Fpga_LutLibPrint( Abc_FrameReadLibLut() );
return 0;
usage:
......
......@@ -142,6 +142,11 @@ 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 );
extern float * Fpga_LutLibReadLutAreas( Fpga_LutLib_t * p );
extern float * Fpga_LutLibReadLutDelays( Fpga_LutLib_t * p );
extern float Fpga_LutLibReadLutArea( Fpga_LutLib_t * p, int Size );
extern float Fpga_LutLibReadLutDelay( Fpga_LutLib_t * p, int Size );
/*=== fpgaTruth.c =============================================================*/
extern void * Fpga_TruthsCutBdd( void * dd, Fpga_Cut_t * pCut );
/*=== fpgaUtil.c =============================================================*/
......
......@@ -164,7 +164,7 @@ Fpga_Man_t * Fpga_ManCreate( int nInputs, int nOutputs, int fVerbose )
// start the manager
p = ALLOC( Fpga_Man_t, 1 );
memset( p, 0, sizeof(Fpga_Man_t) );
p->pLutLib = Abc_FrameReadLibLut(Abc_FrameGetGlobalFrame());
p->pLutLib = Abc_FrameReadLibLut();
p->nVarsMax = p->pLutLib->LutMax;
p->fVerbose = fVerbose;
p->fAreaRecovery = 1;
......
......@@ -245,7 +245,7 @@ Fpga_Cut_t * Fpga_CutCompute( Fpga_Man_t * p, Fpga_CutTable_t * pTable, Fpga_Nod
// set at the node
pNode->pCuts = pCut;
// remove the dominated cuts
Fpga_CutFilter( p, pNode );
// Fpga_CutFilter( p, pNode );
// set the phase correctly
if ( pNode->pRepr && Fpga_NodeComparePhase(pNode, pNode->pRepr) )
{
......
......@@ -28,6 +28,23 @@
/**Function*************************************************************
Synopsis [APIs to access LUT library.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Fpga_LutLibReadVarMax( Fpga_LutLib_t * p ) { return p->LutMax; }
float * Fpga_LutLibReadLutAreas( Fpga_LutLib_t * p ) { return p->pLutAreas; }
float * Fpga_LutLibReadLutDelays( Fpga_LutLib_t * p ) { return p->pLutDelays; }
float Fpga_LutLibReadLutArea( Fpga_LutLib_t * p, int Size ) { assert( Size <= p->LutMax ); return p->pLutAreas[Size]; }
float Fpga_LutLibReadLutDelay( Fpga_LutLib_t * p, int Size ) { assert( Size <= p->LutMax ); return p->pLutDelays[Size]; }
/**Function*************************************************************
Synopsis [Reads the description of LUTs from the LUT library file.]
Description []
......
......@@ -61,7 +61,7 @@ void Map_Init( Abc_Frame_t * pAbc )
void Map_End()
{
// Map_SuperLibFree( s_pSuperLib );
Map_SuperLibFree( Abc_FrameReadLibSuper(Abc_FrameGetGlobalFrame()) );
Map_SuperLibFree( Abc_FrameReadLibSuper() );
}
......
......@@ -183,7 +183,7 @@ Map_Man_t * Map_ManCreate( int nInputs, int nOutputs, int fVerbose )
int i;
// derive the supergate library
if ( Abc_FrameReadLibSuper(Abc_FrameGetGlobalFrame()) == NULL )
if ( Abc_FrameReadLibSuper() == NULL )
{
printf( "The supergate library is not specified. Use \"read_library\" or \"read_super\".\n" );
return NULL;
......@@ -192,7 +192,7 @@ Map_Man_t * Map_ManCreate( int nInputs, int nOutputs, int fVerbose )
// start the manager
p = ALLOC( Map_Man_t, 1 );
memset( p, 0, sizeof(Map_Man_t) );
p->pSuperLib = Abc_FrameReadLibSuper(Abc_FrameGetGlobalFrame());
p->pSuperLib = Abc_FrameReadLibSuper();
p->nVarsMax = p->pSuperLib->nVarsMax;
p->fVerbose = fVerbose;
p->fEpsilon = (float)0.001;
......
......@@ -208,7 +208,7 @@ Map_Cut_t * Map_CutCompute( Map_Man_t * p, Map_CutTable_t * pTable, Map_Node_t *
// set at the node
pNode->pCuts = pCut;
// remove the dominated cuts
// Map_CutFilter( p, pNode );
Map_CutFilter( p, pNode );
// set the phase correctly
if ( pNode->pRepr && Map_NodeComparePhase(pNode, pNode->pRepr) )
{
......
......@@ -108,7 +108,7 @@ void Mio_Init( Abc_Frame_t * pAbc )
void Mio_End()
{
// Mio_LibraryDelete( s_pLib );
Mio_LibraryDelete( Abc_FrameReadLibGen(Abc_FrameGetGlobalFrame()) );
Mio_LibraryDelete( Abc_FrameReadLibGen() );
}
......@@ -181,7 +181,7 @@ int Mio_CommandReadLibrary( Abc_Frame_t * pAbc, int argc, char **argv )
return 1;
}
// free the current superlib because it depends on the old Mio library
if ( Abc_FrameReadLibSuper(Abc_FrameGetGlobalFrame()) )
if ( Abc_FrameReadLibSuper() )
{
extern void Map_SuperLibFree( Map_SuperLib_t * p );
// Map_SuperLibFree( s_pSuperLib );
......@@ -252,7 +252,7 @@ int Mio_CommandPrintLibrary( Abc_Frame_t * pAbc, int argc, char **argv )
}
// set the new network
Mio_WriteLibrary( stdout, Abc_FrameReadLibGen(Abc_FrameGetGlobalFrame()), 0 );
Mio_WriteLibrary( stdout, Abc_FrameReadLibGen(), 0 );
return 0;
usage:
......
SRC += src/map/pga/pgaCore.c \
src/map/pga/pgaMan.c \
src/map/pga/pgaMatch.c \
src/map/pga/pgaUtil.c
/**CFile****************************************************************
FileName [pga.h]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [FPGA mapper.]
Synopsis [External declarations.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: pga.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#ifndef __PGA_H__
#define __PGA_H__
////////////////////////////////////////////////////////////////////////
/// INCLUDES ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// PARAMETERS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// BASIC TYPES ///
////////////////////////////////////////////////////////////////////////
typedef struct Pga_ManStruct_t_ Pga_Man_t;
typedef struct Pga_ParamsStruct_t_ Pga_Params_t;
struct Pga_ParamsStruct_t_
{
// data for mapping
Abc_Ntk_t * pNtk; // the network to be mapped
Fpga_LutLib_t * pLutLib; // the LUT library
float * pSwitching; // switching activity for each node
// mapping parameters
int fDropCuts; // enables cut dropping
int fAreaFlow; // enables area flow minimization
int fArea; // enables area minimization
int fSwitching; // enables switching activity minimization
int fVerbose; // enables verbose output
};
////////////////////////////////////////////////////////////////////////
/// MACRO DEFITIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
/*=== pgaApi.c ==========================================================*/
extern Vec_Ptr_t * Pga_DoMapping( Pga_Man_t * p );
/*=== pgaMan.c ==========================================================*/
extern Pga_Man_t * Pga_ManStart( Pga_Params_t * pParams );
extern void Pga_ManStop( Pga_Man_t * p );
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
#endif
/**CFile****************************************************************
FileName [pgaCore.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [FPGA mapper.]
Synopsis [External APIs of the FPGA manager.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: pgaCore.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "pgaInt.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
static void Pga_MappingInitCis( Pga_Man_t * p );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Performs technology mapping for the given object graph.]
Description [The object graph is stored in the mapping manager.
First, all the AND-nodes, which fanout into the POs, are collected
in the DFS fashion. Next, three steps are performed: the k-feasible
cuts are computed for each node, the truth tables are computed for
each cut, and the delay-optimal matches are assigned for each node.]
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Ptr_t * Pga_DoMapping( Pga_Man_t * p )
{
int fShowSwitching = 0;
float aAreaTotalCur;
int Iter, clk, clkTotal = clock();
// assign the arrival times of the PIs
Pga_MappingInitCis( p );
// map the AIG for delay
clk = clock();
Pga_MappingMatches( p, 0 );
p->timeDelay = clock() - clk;
// compute area, set references, and collect nodes used in the mapping
Iter = 1;
aAreaTotalCur = Pga_MappingSetRefsAndArea( p );
if ( p->pParams->fVerbose )
{
printf( "Iteration %dD : Area = %8.1f ", Iter++, aAreaTotalCur );
if ( fShowSwitching )
printf( "Switch = %8.1f ", Pga_MappingGetSwitching(p) );
PRT( "Time", p->timeDelay );
}
if ( p->pParams->fAreaFlow )
{
clk = clock();
// compute the required times and the fanouts
Pga_MappingComputeRequired( p );
// remap topologically
Pga_MappingMatches( p, 1 );
p->timeAreaFlow = clock() - clk;
// get the resulting area
aAreaTotalCur = Pga_MappingSetRefsAndArea( p );
// note that here we do not update the reference counter
// for some reason, this works better on benchmarks
if ( p->pParams->fVerbose )
{
printf( "Iteration %dF : Area = %8.1f ", Iter++, aAreaTotalCur );
if ( fShowSwitching )
printf( "Switch = %8.1f ", Pga_MappingGetSwitching(p) );
PRT( "Time", p->timeAreaFlow );
}
}
if ( p->pParams->fArea )
{
clk = clock();
// compute the required times and the fanouts
Pga_MappingComputeRequired( p );
// remap topologically
if ( p->pParams->fSwitching )
Pga_MappingMatches( p, 3 );
else
Pga_MappingMatches( p, 2 );
p->timeArea = clock() - clk;
// get the resulting area
aAreaTotalCur = Pga_MappingSetRefsAndArea( p );
if ( p->pParams->fVerbose )
{
printf( "Iteration %d%s : Area = %8.1f ", Iter++, (p->pParams->fSwitching?"S":"A"), aAreaTotalCur );
if ( fShowSwitching )
printf( "Switch = %8.1f ", Pga_MappingGetSwitching(p) );
PRT( "Time", p->timeArea );
}
}
p->AreaGlobal = aAreaTotalCur;
if ( p->pParams->fVerbose )
Pga_MappingPrintOutputArrivals( p );
// return the mapping
return Pga_MappingResults( p );
}
/**Function*************************************************************
Synopsis [Initializes the CI node arrival times.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Pga_MappingInitCis( Pga_Man_t * p )
{
Pga_Node_t * pNode;
float * pCiArrs;
int i;
// get the CI arrival times
pCiArrs = Abc_NtkGetCiArrivalFloats( p->pParams->pNtk );
// assign the arrival times of the PIs
Pga_ManForEachCi( p, pNode, i )
pNode->Match.Delay = pCiArrs[i];
free( pCiArrs );
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
/**CFile****************************************************************
FileName [pgaInt.h]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [FPGA mapper.]
Synopsis [Internal declarations.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: pgaInt.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#ifndef __PGA_INT_H__
#define __PGA_INT_H__
////////////////////////////////////////////////////////////////////////
/// INCLUDES ///
////////////////////////////////////////////////////////////////////////
#include <stdio.h>
#include "abc.h"
#include "fraig.h"
#include "fpga.h"
#include "cut.h"
#include "pga.h"
////////////////////////////////////////////////////////////////////////
/// PARAMETERS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// BASIC TYPES ///
////////////////////////////////////////////////////////////////////////
typedef struct Pga_NodeStruct_t_ Pga_Node_t;
typedef struct Pga_MatchStruct_t_ Pga_Match_t;
struct Pga_ManStruct_t_
{
// mapping parameters
Pga_Params_t * pParams; // input data
// mapping structures
Pga_Node_t * pMemory; // the memory for all mapping structures
Vec_Ptr_t * vStructs; // mapping structures one-to-one with ABC nodes
Vec_Ptr_t * vOrdering; // mapping nodes ordered by level
// k-feasible cuts
int nVarsMax; // the "k" of k-feasible cuts
Cut_Man_t * pManCut; // the cut manager
// LUT library
float * pLutDelays; // the delay of the LUTs
float * pLutAreas; // the areas of the LUTs
float Epsilon;
// global parameters
float AreaGlobal; // the total area of this mapping
float ArrivalGlobal; // the largest delay of any path
float RequiredGlobal;// the global required time (may be different from largest delay)
float RequiredUser; // the required time given by the user
// runtime stats
int timeToMap; // the time to start the mapper
int timeCuts; // the time to compute the cuts
int timeDelay; // the time to compute delay
int timeAreaFlow; // the time to perform area flow optimization
int timeArea; // the time to perform area flow optimization
int timeToNet; // the time to transform back to network
int timeTotal; // the total time
int time1; // temporary
int time2; // temporary
};
struct Pga_MatchStruct_t_
{
Cut_Cut_t * pCut; // the best cut
float Delay; // the arrival time of this cut
float Area; // the area of this cut
};
struct Pga_NodeStruct_t_
{
int Id; // ID of the node
int nRefs; // the number of references
float EstRefs; // the estimated reference counter
float Required; // the required time
float Switching; // the switching activity
Pga_Match_t Match; // the best match at the node
};
////////////////////////////////////////////////////////////////////////
/// MACRO DEFITIONS ///
////////////////////////////////////////////////////////////////////////
static inline Pga_Node_t * Pga_Node( Pga_Man_t * p, int Id ) { return p->vStructs->pArray[Id]; }
// iterator through the CIs
#define Pga_ManForEachCi( p, pCi, i ) \
for ( i = 0; (i < Abc_NtkCiNum(p->pParams->pNtk)) && (((pCi) = Pga_Node(p, Abc_NtkCi(p->pParams->pNtk,i)->Id)), 1); i++ )
// iterator through the CO derivers
#define Pga_ManForEachCoDriver( p, pCo, i ) \
for ( i = 0; (i < Abc_NtkCoNum(p->pParams->pNtk)) && (((pCo) = Pga_Node(p, Abc_ObjFaninId0(Abc_NtkCo(p->pParams->pNtk,i)))), 1); i++ )
// iterators through the CIs and internal nodes
#define Pga_ManForEachObjDirect( p, pNode, i ) \
Vec_PtrForEachEntry( p->vOrdering, pNode, i )
#define Pga_ManForEachObjReverse( p, pNode, i ) \
Vec_PtrForEachEntryReverse( p->vOrdering, pNode, i )
////////////////////////////////////////////////////////////////////////
/// FUNCTION DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
/*=== pgaMatch.c ==========================================================*/
extern void Pga_MappingMatches( Pga_Man_t * p, int Mode );
/*=== pgaUtil.c ==========================================================*/
extern Vec_Ptr_t * Pga_MappingResults( Pga_Man_t * p );
extern float Pga_TimeComputeArrivalMax( Pga_Man_t * p );
extern void Pga_MappingComputeRequired( Pga_Man_t * p );
extern float Pga_MappingSetRefsAndArea( Pga_Man_t * p );
extern float Pga_MappingGetSwitching( Pga_Man_t * p );
extern void Pga_MappingPrintOutputArrivals( Pga_Man_t * p );
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
#endif
/**CFile****************************************************************
FileName [pgaMan.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [FPGA mapper.]
Synopsis [Mapping manager.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: pgaMan.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "pgaInt.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
static Cut_Man_t * Pga_ManStartCutMan( Pga_Params_t * pParamsPga );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Starts the manager.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Pga_Man_t * Pga_ManStart( Pga_Params_t * pParams )
{
Pga_Man_t * p;
Pga_Node_t * pNode;
Cut_Man_t * pManCut;
Abc_Ntk_t * pNtk;
Abc_Obj_t * pObj;
int i, Counter;
int clk = clock();
// make sure the network is given
pNtk = pParams->pNtk;
if ( pNtk == NULL )
{
printf( "Network is not specified.\n" );
return NULL;
}
if ( !Abc_NtkIsStrash(pNtk) )
{
printf( "Mapping can only be applied to an AIG.\n" );
return NULL;
}
// the cut manager if given should be in sinc
pManCut = pNtk->pManCut;
if ( pManCut && Cut_ManReadVarsMax(pManCut) != Fpga_LutLibReadVarMax(pParams->pLutLib) )
{
printf( "The precomputed cuts have different size.\n" );
return NULL;
}
// make sure the nodes are in the topological order
if ( !Abc_NtkIsDfsOrdered(pNtk) )
{
printf( "The nodes of the network are not DFS ordered.\n" );
// Abc_NtkReassignIds( pNtk );
return NULL;
}
// make sure there are no dangling nodes (unless they are choices)
// start the mapping manager
p = ALLOC( Pga_Man_t, 1 );
memset( p, 0, sizeof(Pga_Man_t) );
p->pParams = pParams;
p->nVarsMax = Fpga_LutLibReadVarMax(pParams->pLutLib);
p->pManCut = pManCut? pManCut : Pga_ManStartCutMan(pParams);
p->vOrdering = Abc_AigGetLevelizedOrder(pNtk, 0); // what happens with dangling nodes???
p->pLutAreas = Fpga_LutLibReadLutAreas(pParams->pLutLib);
p->pLutDelays = Fpga_LutLibReadLutDelays(pParams->pLutLib);
p->Epsilon = (float)0.00001;
// allocate mapping structures
p->pMemory = ALLOC( Pga_Node_t, Abc_NtkObjNum(pNtk) );
memset( p->pMemory, 0, sizeof(Pga_Node_t) * Abc_NtkObjNum(pNtk) );
p->vStructs = Vec_PtrStart( Abc_NtkObjNumMax(pNtk) );
Counter = 0;
Abc_NtkForEachObj( pNtk, pObj, i )
{
pNode = p->pMemory + Counter++;
pNode->Id = pObj->Id;
pNode->nRefs = pObj->vFanouts.nSize;
pNode->Required = ABC_INFINITY;
pNode->Match.Area = ABC_INFINITY;
// skip secondary nodes
if ( Abc_ObjFanoutNum(pObj) == 0 )
continue;
Vec_PtrWriteEntry( p->vStructs, pObj->Id, pNode );
}
assert( Counter == Abc_NtkObjNum(pNtk) );
// update order to depend on mapping nodes
Vec_PtrForEachEntry( p->vOrdering, pObj, i )
Vec_PtrWriteEntry( p->vOrdering, i, Pga_Node(p,pObj->Id) );
p->timeToMap = clock() - clk;
return p;
}
/**Function*************************************************************
Synopsis [Stops the manager.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Pga_ManStop( Pga_Man_t * p )
{
Cut_ManStop( p->pManCut );
Vec_PtrFree( p->vOrdering );
Vec_PtrFree( p->vStructs );
free( p->pMemory );
free( p );
}
/**Function*************************************************************
Synopsis [Starts the cut manager for FPGA mapping.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Cut_Man_t * Pga_ManStartCutMan( Pga_Params_t * pParamsPga )
{
static Cut_Params_t Params, * pParams = &Params;
Abc_Ntk_t * pNtk = pParamsPga->pNtk;
Cut_Man_t * pManCut;
Abc_Obj_t * pObj;
int i;
// start the cut manager
memset( pParams, 0, sizeof(Cut_Params_t) );
pParams->nVarsMax = Fpga_LutLibReadVarMax(pParamsPga->pLutLib); // max cut size
pParams->nKeepMax = 250; // the max number of cuts kept at a node
pParams->fTruth = 0; // compute truth tables
pParams->fFilter = 1; // filter dominated cuts
pParams->fSeq = 0; // compute sequential cuts
pParams->fDrop = pParamsPga->fDropCuts; // drop cuts on the fly
pParams->fVerbose = 0; // the verbosiness flag
pParams->nIdsMax = Abc_NtkObjNumMax( pNtk );
pManCut = Cut_ManStart( pParams );
if ( pParams->fDrop )
Cut_ManSetFanoutCounts( pManCut, Abc_NtkFanoutCounts(pNtk) );
// set cuts for PIs
Abc_NtkForEachCi( pNtk, pObj, i )
if ( Abc_ObjFanoutNum(pObj) > 0 )
Cut_NodeSetTriv( pManCut, pObj->Id );
return pManCut;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
/**CFile****************************************************************
FileName [pgaUtil.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [FPGA mapper.]
Synopsis [Verious utilities.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: pgaUtil.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "pgaInt.h"
#define PGA_CO_LIST_SIZE 5
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Returns the results of mapping.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Ptr_t * Pga_MappingResults( Pga_Man_t * p )
{
Vec_Ptr_t * vResult;
Pga_Node_t * pNode;
int i;
vResult = Vec_PtrAlloc( 1000 );
Pga_ManForEachObjDirect( p, pNode, i )
{
// skip the CIs and nodes not used in the mapping
if ( !pNode->Match.pCut || !pNode->nRefs )
continue;
pNode->Match.pCut->uSign = pNode->Id;
Vec_PtrPush( vResult, pNode->Match.pCut );
}
return vResult;
}
/**Function*************************************************************
Synopsis [Computes the maximum arrival times.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
float Pga_TimeComputeArrivalMax( Pga_Man_t * p )
{
Pga_Node_t * pNode;
float ArrivalMax;
int i;
ArrivalMax = -ABC_INFINITY;
Pga_ManForEachCoDriver( p, pNode, i )
ArrivalMax = ABC_MAX( ArrivalMax, pNode->Match.Delay );
return ArrivalMax;
}
/**Function*************************************************************
Synopsis [Computes required times of all nodes.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Pga_MappingComputeRequired( Pga_Man_t * p )
{
Pga_Node_t * pNode, * pFanin;
Cut_Cut_t * pCutBest;
float RequiredNew;
int i, k;
// clean the required times of all nodes
Pga_ManForEachObjDirect( p, pNode, i )
pNode->Required = ABC_INFINITY;
// get the global required times
p->AreaGlobal = Pga_TimeComputeArrivalMax( p );
p->RequiredGlobal = ABC_MAX( p->AreaGlobal, p->RequiredUser );
// set the global required times of the CO drivers
Pga_ManForEachCoDriver( p, pNode, i )
pNode->Required = p->RequiredGlobal;
// propagate the required times in the reverse topological order
Pga_ManForEachObjReverse( p, pNode, i )
{
// skip the CIs and nodes not used in the mapping
if ( !pNode->Match.pCut || !pNode->nRefs )
continue;
// get the required time for children
pCutBest = pNode->Match.pCut;
RequiredNew = pNode->Required - p->pLutDelays[pCutBest->nLeaves];
// update the required time of the children
for ( k = 0; k < (int)pCutBest->nLeaves; k++ )
{
pFanin = Pga_Node( p, pCutBest->pLeaves[k] );
pFanin->Required = ABC_MIN( pFanin->Required, RequiredNew );
}
}
// check that the required times does not contradict the arrival times
Pga_ManForEachObjDirect( p, pNode, i )
assert( !pNode->Match.pCut || pNode->Match.Delay < pNode->Required + p->Epsilon );
}
/**Function*************************************************************
Synopsis [Sets references and computes area for the current mapping.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
float Pga_MappingSetRefsAndArea( Pga_Man_t * p )
{
Pga_Node_t * pNode, * pFanin;
Cut_Cut_t * pCutBest;
float AreaTotal;
int i, k;
// clean all the references
Pga_ManForEachObjDirect( p, pNode, i )
pNode->nRefs = 0;
// set the references of the CO drivers
Pga_ManForEachCoDriver( p, pNode, i )
pNode->nRefs++;
// go through the nodes in the reverse order
AreaTotal = 0.0;
Pga_ManForEachObjReverse( p, pNode, i )
{
// skip the CIs and nodes not used in the mapping
if ( !pNode->Match.pCut || !pNode->nRefs )
continue;
// increate the reference count of the children
pCutBest = pNode->Match.pCut;
AreaTotal += p->pLutAreas[pCutBest->nLeaves];
// update the required time of the children
for ( k = 0; k < (int)pCutBest->nLeaves; k++ )
{
pFanin = Pga_Node( p, pCutBest->pLeaves[k] );
pFanin->nRefs++;
}
}
return AreaTotal;
}
/**Function*************************************************************
Synopsis [Computes switching activity of the mapping.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
float Pga_MappingGetSwitching( Pga_Man_t * p )
{
float Switching;
Pga_Node_t * pNode;
int i;
Switching = 0;
Pga_ManForEachObjDirect( p, pNode, i )
{
// skip the CIs and nodes not used in the mapping
if ( !pNode->Match.pCut || !pNode->nRefs )
continue;
Switching += pNode->Switching;
}
return Switching;
}
/**Function*************************************************************
Synopsis [Compares the outputs by their arrival times.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Pga_MappingCompareOutputDelay( Pga_Node_t ** ppNode1, Pga_Node_t ** ppNode2 )
{
Pga_Node_t * pNode1 = *ppNode1;
Pga_Node_t * pNode2 = *ppNode2;
float Arrival1 = pNode1->Match.Delay;
float Arrival2 = pNode2->Match.Delay;
if ( Arrival1 < Arrival2 )
return -1;
if ( Arrival1 > Arrival2 )
return 1;
return 0;
}
/**Function*************************************************************
Synopsis [Finds given number of latest arriving COs.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Pga_MappingFindLatest( Pga_Man_t * p, int * pNodes, int nNodesMax )
{
Pga_Node_t * pNodeI, * pNodeK;
Abc_Obj_t * pObjCo;
int nNodes, i, k, v;
assert( Abc_NtkCoNum(p->pParams->pNtk) >= nNodesMax );
pNodes[0] = 0;
nNodes = 1;
// for ( i = 1; i < p->nOutputs; i++ )
Pga_ManForEachCoDriver( p, pNodeI, i )
{
for ( k = nNodes - 1; k >= 0; k-- )
{
pObjCo = Abc_NtkCo( p->pParams->pNtk, pNodes[k] );
pNodeK = Pga_Node( p, Abc_ObjFaninId0(pObjCo) );
if ( Pga_MappingCompareOutputDelay( &pNodeK, &pNodeI ) >= 0 )
break;
}
if ( k == nNodesMax - 1 )
continue;
if ( nNodes < nNodesMax )
nNodes++;
for ( v = nNodes - 1; v > k+1; v-- )
pNodes[v] = pNodes[v-1];
pNodes[k+1] = i;
}
}
/**Function*************************************************************
Synopsis [Prints a bunch of latest arriving outputs.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Pga_MappingPrintOutputArrivals( Pga_Man_t * p )
{
int pSorted[PGA_CO_LIST_SIZE];
Abc_Ntk_t * pNtk = p->pParams->pNtk;
Abc_Obj_t * pObjCo;
Pga_Node_t * pNode;
int Limit, MaxNameSize, i;
// determine the number of nodes to print
Limit = (Abc_NtkCoNum(pNtk) < PGA_CO_LIST_SIZE)? Abc_NtkCoNum(pNtk) : PGA_CO_LIST_SIZE;
// determine the order
Pga_MappingFindLatest( p, pSorted, Limit );
// determine max size of the node's name
MaxNameSize = 0;
for ( i = 0; i < Limit; i++ )
{
pObjCo = Abc_NtkCo( pNtk, pSorted[i] );
if ( MaxNameSize < (int)strlen( Abc_ObjName(pObjCo) ) )
MaxNameSize = strlen( Abc_ObjName(pObjCo) );
}
// print the latest outputs
for ( i = 0; i < Limit; i++ )
{
// get the i-th latest output
pObjCo = Abc_NtkCo( pNtk, pSorted[i] );
pNode = Pga_Node( p, pObjCo->Id );
// print out the best arrival time
printf( "Output %-*s : ", MaxNameSize + 3, Abc_ObjName(pObjCo) );
printf( "Delay = %8.2f ", (double)pNode->Match.Delay );
if ( Abc_ObjFaninC0(pObjCo) )
printf( "NEG" );
else
printf( "POS" );
printf( "\n" );
}
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
......@@ -63,6 +63,15 @@
/* Macro declarations */
/*---------------------------------------------------------------------------*/
typedef unsigned char uint8;
typedef unsigned short uint16;
typedef unsigned int uint32;
#ifdef WIN32
typedef unsigned __int64 uint64;
#else
typedef unsigned long long uint64;
#endif
/* constants of the manager */
#define b0 Cudd_Not((dd)->one)
#define b1 (dd)->one
......
......@@ -53,6 +53,10 @@ struct Vec_Ptr_t_
for ( i = 0; (i < Vec_PtrSize(vVec)) && (((pEntry) = Vec_PtrEntry(vVec, i)), 1); i++ )
#define Vec_PtrForEachEntryStart( vVec, pEntry, i, Start ) \
for ( i = Start; (i < Vec_PtrSize(vVec)) && (((pEntry) = Vec_PtrEntry(vVec, i)), 1); i++ )
#define Vec_PtrForEachEntryStop( vVec, pEntry, i, Stop ) \
for ( i = 0; (i < Stop) && (((pEntry) = Vec_PtrEntry(vVec, i)), 1); i++ )
#define Vec_PtrForEachEntryStartStop( vVec, pEntry, i, Start, Stop ) \
for ( i = Start; (i < Stop) && (((pEntry) = Vec_PtrEntry(vVec, i)), 1); i++ )
#define Vec_PtrForEachEntryReverse( vVec, pEntry, i ) \
for ( i = Vec_PtrSize(vVec) - 1; (i >= 0) && (((pEntry) = Vec_PtrEntry(vVec, i)), 1); i-- )
......
......@@ -43,7 +43,6 @@ struct Cut_ParamsStruct_t_
int nKeepMax; // the max number of cuts kept at a node
int nIdsMax; // the max number of IDs of cut objects
int fTruth; // compute truth tables
int fHash; // hash cuts to detect unique
int fFilter; // filter dominated cuts
int fSeq; // compute sequential cuts
int fDrop; // drop cuts on the fly
......@@ -53,28 +52,25 @@ struct Cut_ParamsStruct_t_
struct Cut_CutStruct_t_
{
unsigned uTruth : 16; // truth table for 4-input cuts
unsigned uPhase : 7; // the phase when mapping into a canonical form
unsigned uPhase : 8; // the phase when mapping into a canonical form
unsigned fSimul : 1; // the value of cut's output at 000.. pattern
unsigned fCompl : 1; // the cut is complemented
unsigned fSeq : 1; // the cut is sequential
unsigned nVarsMax : 3; // the max number of vars [4-6]
unsigned nLeaves : 3; // the number of leaves [4-6]
unsigned uSign; // the signature
Cut_Cut_t * pNext; // the next cut in the list
void * pData; // the user data
int pLeaves[0]; // the array of leaves
};
static inline unsigned * Cut_CutReadTruth( Cut_Cut_t * p ) { if ( p->nVarsMax == 4 ) return (unsigned *)p; return (unsigned *)(p->pLeaves + p->nVarsMax + p->fSeq); }
static inline unsigned * Cut_CutReadTruth( Cut_Cut_t * p ) { if ( p->nVarsMax == 4 ) return (unsigned *)p; return (unsigned *)(p->pLeaves + p->nVarsMax); }
static inline unsigned Cut_CutReadPhase( Cut_Cut_t * p ) { return p->uPhase; }
static inline int Cut_CutReadLeaveNum( Cut_Cut_t * p ) { return p->nLeaves; }
static inline int * Cut_CutReadLeaves( Cut_Cut_t * p ) { return p->pLeaves; }
static inline void * Cut_CutReadData( Cut_Cut_t * p ) { return p->pData; }
static inline void Cut_CutWriteData( Cut_Cut_t * p, void * pData ) { p->pData = pData; }
static inline void Cut_CutWriteTruth( Cut_Cut_t * p, unsigned * puTruth ) {
if ( p->nVarsMax == 4 ) { p->uTruth = *puTruth; return; }
p->pLeaves[p->nVarsMax + p->fSeq] = (int)puTruth[0];
if ( p->nVarsMax == 6 ) p->pLeaves[p->nVarsMax + p->fSeq + 1] = (int)puTruth[1];
p->pLeaves[p->nVarsMax] = (int)puTruth[0];
if ( p->nVarsMax == 6 ) p->pLeaves[p->nVarsMax + 1] = (int)puTruth[1];
}
////////////////////////////////////////////////////////////////////////
......@@ -85,21 +81,23 @@ static inline void Cut_CutWriteTruth( Cut_Cut_t * p, unsigned * puTruth )
/// FUNCTION DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
/*=== cutApi.c ==========================================================*/
extern Cut_Cut_t * Cut_NodeReadCuts( Cut_Man_t * p, int Node );
extern void Cut_NodeWriteCuts( Cut_Man_t * p, int Node, Cut_Cut_t * pList );
extern void Cut_NodeSetTriv( Cut_Man_t * p, int Node );
extern void Cut_NodeTryDroppingCuts( Cut_Man_t * p, int Node );
extern void Cut_NodeFreeCuts( Cut_Man_t * p, int Node );
/*=== cutCut.c ==========================================================*/
extern void Cut_CutPrint( Cut_Cut_t * pCut );
/*=== cutMan.c ==========================================================*/
extern Cut_Man_t * Cut_ManStart( Cut_Params_t * pParams );
extern void Cut_ManStop( Cut_Man_t * p );
extern void Cut_ManPrintStats( Cut_Man_t * p );
extern void Cut_ManSetFanoutCounts( Cut_Man_t * p, Vec_Int_t * vFanCounts );
extern int Cut_ManReadVarsMax( Cut_Man_t * p );
/*=== cutNode.c ==========================================================*/
extern void Cut_NodeSetTriv( Cut_Man_t * p, int Node );
extern Cut_Cut_t * Cut_NodeComputeCuts( Cut_Man_t * p, int Node, int Node0, int Node1, int fCompl0, int fCompl1 );
extern Cut_Cut_t * Cut_NodeUnionCuts( Cut_Man_t * p, Vec_Int_t * vNodes );
extern Cut_Cut_t * Cut_NodeReadCuts( Cut_Man_t * p, int Node );
extern void Cut_NodeWriteCuts( Cut_Man_t * p, int Node, Cut_Cut_t * pList );
extern void Cut_NodeFreeCuts( Cut_Man_t * p, int Node );
extern void Cut_NodeSetComputedAsNew( Cut_Man_t * p, int Node );
extern void Cut_NodeTryDroppingCuts( Cut_Man_t * p, int Node );
extern void Cut_CutPrint( Cut_Cut_t * pCut );
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
......
/**CFile****************************************************************
FileName [cutNode.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [K-feasible cut computation package.]
Synopsis [Procedures to compute cuts for a node.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: cutNode.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "cutInt.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Returns the pointer to the linked list of cuts.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Cut_Cut_t * Cut_NodeReadCuts( Cut_Man_t * p, int Node )
{
if ( Node >= p->vCuts->nSize )
return NULL;
return Vec_PtrEntry( p->vCuts, Node );
}
/**Function*************************************************************
Synopsis [Returns the pointer to the linked list of cuts.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Cut_NodeWriteCuts( Cut_Man_t * p, int Node, Cut_Cut_t * pList )
{
Vec_PtrWriteEntry( p->vCuts, Node, pList );
}
/**Function*************************************************************
Synopsis [Sets the trivial cut for the node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Cut_NodeSetTriv( Cut_Man_t * p, int Node )
{
assert( Cut_NodeReadCuts(p, Node) == NULL );
Cut_NodeWriteCuts( p, Node, Cut_CutCreateTriv(p, Node) );
}
/**Function*************************************************************
Synopsis [Consider dropping cuts if they are useless by now.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Cut_NodeTryDroppingCuts( Cut_Man_t * p, int Node )
{
int nFanouts;
assert( p->vFanCounts );
nFanouts = Vec_IntEntry( p->vFanCounts, Node );
assert( nFanouts > 0 );
if ( --nFanouts == 0 )
Cut_NodeFreeCuts( p, Node );
Vec_IntWriteEntry( p->vFanCounts, Node, nFanouts );
}
/**Function*************************************************************
Synopsis [Deallocates the cuts at the node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Cut_NodeFreeCuts( Cut_Man_t * p, int Node )
{
Cut_Cut_t * pList, * pCut, * pCut2;
pList = Cut_NodeReadCuts( p, Node );
if ( pList == NULL )
return;
Cut_ListForEachCutSafe( pList, pCut, pCut2 )
Cut_CutRecycle( p, pCut );
Cut_NodeWriteCuts( p, Node, NULL );
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
/**CFile****************************************************************
FileName [cutNode.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [K-feasible cut computation package.]
Synopsis [Procedures to compute cuts for a node.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: cutNode.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "cutInt.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Start the cut computation.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Cut_Cut_t * Cut_CutAlloc( Cut_Man_t * p )
{
Cut_Cut_t * pCut;
// cut allocation
pCut = (Cut_Cut_t *)Extra_MmFixedEntryFetch( p->pMmCuts );
memset( pCut, 0, sizeof(Cut_Cut_t) );
pCut->nVarsMax = p->pParams->nVarsMax;
pCut->fSimul = p->fSimul;
// statistics
p->nCutsAlloc++;
p->nCutsCur++;
if ( p->nCutsPeak < p->nCutsAlloc - p->nCutsDealloc )
p->nCutsPeak = p->nCutsAlloc - p->nCutsDealloc;
return pCut;
}
/**Function*************************************************************
Synopsis [Start the cut computation.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Cut_Cut_t * Cut_CutCreateTriv( Cut_Man_t * p, int Node )
{
Cut_Cut_t * pCut;
pCut = Cut_CutAlloc( p );
pCut->nLeaves = 1;
pCut->pLeaves[0] = Node;
pCut->uSign = (1 << (Node % 32));
if ( p->pParams->fTruth )
Cut_CutWriteTruth( pCut, p->uTruthVars[0] );
p->nCutsTriv++;
return pCut;
}
/**Function*************************************************************
Synopsis [Start the cut computation.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Cut_CutRecycle( Cut_Man_t * p, Cut_Cut_t * pCut )
{
p->nCutsDealloc++;
p->nCutsCur--;
if ( pCut->nLeaves == 1 )
p->nCutsTriv--;
Extra_MmFixedEntryRecycle( p->pMmCuts, (char *)pCut );
}
/**Function*************************************************************
Synopsis [Print the cut.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Cut_CutPrint( Cut_Cut_t * pCut )
{
int i;
assert( pCut->nLeaves > 0 );
printf( "%d : {", pCut->nLeaves );
for ( i = 0; i < (int)pCut->nLeaves; i++ )
printf( " %d", pCut->pLeaves[i] );
printf( " }" );
}
/**Function*************************************************************
Synopsis [Consider dropping cuts if they are useless by now.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Cut_CutPrintMerge( Cut_Cut_t * pCut, Cut_Cut_t * pCut0, Cut_Cut_t * pCut1 )
{
printf( "\n" );
printf( "%d : %5d %5d %5d %5d %5d\n",
pCut0->nLeaves,
pCut0->nLeaves > 0 ? pCut0->pLeaves[0] : -1,
pCut0->nLeaves > 1 ? pCut0->pLeaves[1] : -1,
pCut0->nLeaves > 2 ? pCut0->pLeaves[2] : -1,
pCut0->nLeaves > 3 ? pCut0->pLeaves[3] : -1,
pCut0->nLeaves > 4 ? pCut0->pLeaves[4] : -1
);
printf( "%d : %5d %5d %5d %5d %5d\n",
pCut1->nLeaves,
pCut1->nLeaves > 0 ? pCut1->pLeaves[0] : -1,
pCut1->nLeaves > 1 ? pCut1->pLeaves[1] : -1,
pCut1->nLeaves > 2 ? pCut1->pLeaves[2] : -1,
pCut1->nLeaves > 3 ? pCut1->pLeaves[3] : -1,
pCut1->nLeaves > 4 ? pCut1->pLeaves[4] : -1
);
if ( pCut == NULL )
printf( "Cannot merge\n" );
else
printf( "%d : %5d %5d %5d %5d %5d\n",
pCut->nLeaves,
pCut->nLeaves > 0 ? pCut->pLeaves[0] : -1,
pCut->nLeaves > 1 ? pCut->pLeaves[1] : -1,
pCut->nLeaves > 2 ? pCut->pLeaves[2] : -1,
pCut->nLeaves > 3 ? pCut->pLeaves[3] : -1,
pCut->nLeaves > 4 ? pCut->pLeaves[4] : -1
);
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
......@@ -48,7 +48,6 @@ struct Cut_ManStruct_t_
// storage for cuts
Vec_Ptr_t * vCuts; // cuts by ID
Vec_Ptr_t * vCutsNew; // cuts by ID
Cut_HashTable_t * tTable; // cuts by their leaves (and root)
// memory management
Extra_MmFixed_t * pMmCuts;
int EntrySize;
......@@ -58,6 +57,7 @@ struct Cut_ManStruct_t_
int fCompl0;
int fCompl1;
int fSimul;
int nNodeCuts;
// precomputations
unsigned uTruthVars[6][2];
unsigned short ** pPerms43;
......@@ -69,7 +69,8 @@ struct Cut_ManStruct_t_
int nCutsDealloc;
int nCutsPeak;
int nCutsTriv;
int nCutsNode;
int nCutsFilter;
int nCutsLimit;
int nNodes;
// runtime
int timeMerge;
......@@ -79,6 +80,22 @@ struct Cut_ManStruct_t_
int timeHash;
};
// iterator through all the cuts of the list
#define Cut_ListForEachCut( pList, pCut ) \
for ( pCut = pList; \
pCut; \
pCut = pCut->pNext )
#define Cut_ListForEachCutStop( pList, pCut, pStop ) \
for ( pCut = pList; \
pCut != pStop; \
pCut = pCut->pNext )
#define Cut_ListForEachCutSafe( pList, pCut, pCut2 ) \
for ( pCut = pList, \
pCut2 = pCut? pCut->pNext: NULL; \
pCut; \
pCut = pCut2, \
pCut2 = pCut? pCut->pNext: NULL )
////////////////////////////////////////////////////////////////////////
/// MACRO DEFITIONS ///
////////////////////////////////////////////////////////////////////////
......@@ -87,10 +104,14 @@ struct Cut_ManStruct_t_
/// FUNCTION DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
/*=== cutCut.c ==========================================================*/
extern Cut_Cut_t * Cut_CutAlloc( Cut_Man_t * p );
extern Cut_Cut_t * Cut_CutCreateTriv( Cut_Man_t * p, int Node );
extern void Cut_CutRecycle( Cut_Man_t * p, Cut_Cut_t * pCut );
extern void Cut_CutPrint( Cut_Cut_t * pCut );
extern void Cut_CutPrintMerge( Cut_Cut_t * pCut, Cut_Cut_t * pCut0, Cut_Cut_t * pCut1 );
/*=== cutMerge.c ==========================================================*/
extern Cut_Cut_t * Cut_CutMergeTwo( Cut_Man_t * p, Cut_Cut_t * pCut0, Cut_Cut_t * pCut1 );
/*=== cutNode.c ==========================================================*/
extern Cut_Cut_t * Cut_CutAlloc( Cut_Man_t * p );
/*=== cutTable.c ==========================================================*/
extern Cut_HashTable_t * Cut_TableStart( int Size );
extern void Cut_TableStop( Cut_HashTable_t * pTable );
......
......@@ -49,7 +49,7 @@ Cut_Man_t * Cut_ManStart( Cut_Params_t * pParams )
// set and correct parameters
p->pParams = pParams;
if ( p->pParams->fSeq )
p->pParams->fHash = 1;
p->pParams->fFilter = 1;
// space for cuts
p->vCuts = Vec_PtrAlloc( pParams->nIdsMax );
Vec_PtrFill( p->vCuts, pParams->nIdsMax, NULL );
......@@ -58,25 +58,17 @@ Cut_Man_t * Cut_ManStart( Cut_Params_t * pParams )
p->vCutsNew = Vec_PtrAlloc( pParams->nIdsMax );
Vec_PtrFill( p->vCuts, pParams->nIdsMax, NULL );
}
// hash tables
if ( pParams->fHash )
p->tTable = Cut_TableStart( p->pParams->nKeepMax );
// entry size
p->EntrySize = sizeof(Cut_Cut_t) + (pParams->nVarsMax + pParams->fSeq) * sizeof(int);
if ( pParams->nVarsMax == 5 )
p->EntrySize += sizeof(unsigned);
else if ( pParams->nVarsMax == 6 )
p->EntrySize += 2 * sizeof(unsigned);
if ( pParams->fTruth )
{
if ( pParams->nVarsMax == 5 )
p->EntrySize += sizeof(unsigned);
else if ( pParams->nVarsMax == 6 )
p->EntrySize += 2 * sizeof(unsigned);
}
// memory for cuts
p->pMmCuts = Extra_MmFixedStart( p->EntrySize );
// precomputations
// if ( pParams->fTruth && pParams->nVarsMax == 4 )
// p->pPerms43 = Extra_TruthPerm43();
// else if ( pParams->fTruth )
// {
// p->pPerms53 = Extra_TruthPerm53();
// p->pPerms54 = Extra_TruthPerm54();
// }
p->uTruthVars[0][1] = p->uTruthVars[0][0] = 0xAAAAAAAA; // 1010 1010 1010 1010 1010 1010 1010 1010
p->uTruthVars[1][1] = p->uTruthVars[1][0] = 0xCCCCCCCC; // 1010 1010 1010 1010 1010 1010 1010 1010
p->uTruthVars[2][1] = p->uTruthVars[2][0] = 0xF0F0F0F0; // 1111 0000 1111 0000 1111 0000 1111 0000
......@@ -104,13 +96,10 @@ void Cut_ManStop( Cut_Man_t * p )
Cut_Cut_t * pCut;
int i;
Vec_PtrForEachEntry( p->vCuts, pCut, i )
{
if ( pCut != NULL )
{
int k = 0;
}
}
if ( p->vCutsNew ) Vec_PtrFree( p->vCutsNew );
if ( p->vCuts ) Vec_PtrFree( p->vCuts );
if ( p->vFanCounts ) Vec_IntFree( p->vFanCounts );
......@@ -118,7 +107,6 @@ void Cut_ManStop( Cut_Man_t * p )
if ( p->pPerms53 ) free( p->pPerms53 );
if ( p->pPerms54 ) free( p->pPerms54 );
if ( p->vTemp ) Vec_PtrFree( p->vTemp );
if ( p->tTable ) Cut_TableStop( p->tTable );
Extra_MmFixedStop( p->pMmCuts, 0 );
free( p );
}
......@@ -141,12 +129,13 @@ void Cut_ManPrintStats( Cut_Man_t * p )
printf( "Peak cuts = %8d.\n", p->nCutsPeak );
printf( "Total allocated = %8d.\n", p->nCutsAlloc );
printf( "Total deallocated = %8d.\n", p->nCutsDealloc );
printf( "Cuts filtered = %8d.\n", p->nCutsFilter );
printf( "Nodes with limit = %8d.\n", p->nCutsLimit );
printf( "Cuts per node = %8.1f\n", ((float)(p->nCutsCur-p->nCutsTriv))/p->nNodes );
printf( "The cut size = %8d bytes.\n", p->EntrySize );
printf( "Peak memory = %8.2f Mb.\n", (float)p->nCutsPeak * p->EntrySize / (1<<20) );
PRT( "Merge ", p->timeMerge );
PRT( "Union ", p->timeUnion );
PRT( "Hash ", Cut_TableReadTime(p->tTable) );
PRT( "Filter", p->timeFilter );
PRT( "Truth ", p->timeTruth );
}
......@@ -168,6 +157,22 @@ void Cut_ManSetFanoutCounts( Cut_Man_t * p, Vec_Int_t * vFanCounts )
p->vFanCounts = vFanCounts;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Cut_ManReadVarsMax( Cut_Man_t * p )
{
return p->pParams->nVarsMax;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
......
/**CFile****************************************************************
FileName [cutTable.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [K-feasible cut computation package.]
Synopsis [Hashing cuts to prevent duplication.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: cutTable.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "cutInt.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
struct Cut_HashTableStruct_t_
{
int nBins;
Cut_Cut_t ** pBins;
int nEntries;
int * pPlaces;
int nPlaces;
int timeLookup;
};
// iterator through all the cuts of the list
#define Cut_TableListForEachCut( pList, pCut ) \
for ( pCut = pList; \
pCut; \
pCut = pCut->pData )
#define Cut_TableListForEachCutSafe( pList, pCut, pCut2 ) \
for ( pCut = pList, \
pCut2 = pCut? pCut->pData: NULL; \
pCut; \
pCut = pCut2, \
pCut2 = pCut? pCut->pData: NULL )
// primes used to compute the hash key
static int s_HashPrimes[10] = { 109, 499, 557, 619, 631, 709, 797, 881, 907, 991 };
// hashing function
static inline unsigned Cut_HashKey( Cut_Cut_t * pCut )
{
unsigned i, uRes = pCut->nLeaves * s_HashPrimes[9];
for ( i = 0; i < pCut->nLeaves + pCut->fSeq; i++ )
uRes += s_HashPrimes[i] * pCut->pLeaves[i];
return uRes;
}
// hashing function
static inline int Cut_CompareTwo( Cut_Cut_t * pCut1, Cut_Cut_t * pCut2 )
{
unsigned i;
if ( pCut1->nLeaves != pCut2->nLeaves )
return 1;
for ( i = 0; i < pCut1->nLeaves; i++ )
if ( pCut1->pLeaves[i] != pCut2->pLeaves[i] )
return 1;
return 0;
}
static void Cut_TableResize( Cut_HashTable_t * pTable );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Starts the hash table.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Cut_HashTable_t * Cut_TableStart( int Size )
{
Cut_HashTable_t * pTable;
pTable = ALLOC( Cut_HashTable_t, 1 );
memset( pTable, 0, sizeof(Cut_HashTable_t) );
// allocate the table
pTable->nBins = Cudd_PrimeCopy( Size );
pTable->pBins = ALLOC( Cut_Cut_t *, pTable->nBins );
memset( pTable->pBins, 0, sizeof(Cut_Cut_t *) * pTable->nBins );
pTable->pPlaces = ALLOC( int, pTable->nBins );
return pTable;
}
/**Function*************************************************************
Synopsis [Stops the hash table.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Cut_TableStop( Cut_HashTable_t * pTable )
{
FREE( pTable->pPlaces );
free( pTable->pBins );
free( pTable );
}
/**Function*************************************************************
Synopsis [Check the existence of a cut in the lookup table]
Description [Returns 1 if the entry is found.]
SideEffects []
SeeAlso []
***********************************************************************/
int Cut_TableLookup( Cut_HashTable_t * pTable, Cut_Cut_t * pCut, int fStore )
{
Cut_Cut_t * pEnt;
unsigned Key;
int clk = clock();
Key = Cut_HashKey(pCut) % pTable->nBins;
Cut_TableListForEachCut( pTable->pBins[Key], pEnt )
{
if ( !Cut_CompareTwo( pEnt, pCut ) )
{
pTable->timeLookup += clock() - clk;
return 1;
}
}
if ( pTable->nEntries > 2 * pTable->nBins )
{
Cut_TableResize( pTable );
Key = Cut_HashKey(pCut) % pTable->nBins;
}
// remember the place
if ( fStore && pTable->pBins[Key] == NULL )
pTable->pPlaces[ pTable->nPlaces++ ] = Key;
// add the cut to the table
pCut->pData = pTable->pBins[Key];
pTable->pBins[Key] = pCut;
pTable->nEntries++;
pTable->timeLookup += clock() - clk;
return 0;
}
/**Function*************************************************************
Synopsis [Stops the hash table.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Cut_TableClear( Cut_HashTable_t * pTable )
{
int i;
assert( pTable->nPlaces <= pTable->nBins );
for ( i = 0; i < pTable->nPlaces; i++ )
{
assert( pTable->pBins[ pTable->pPlaces[i] ] );
pTable->pBins[ pTable->pPlaces[i] ] = NULL;
}
pTable->nPlaces = 0;
pTable->nEntries = 0;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Cut_TableResize( Cut_HashTable_t * pTable )
{
Cut_Cut_t ** pBinsNew;
Cut_Cut_t * pEnt, * pEnt2;
int nBinsNew, Counter, i, clk;
unsigned Key;
clk = clock();
// get the new table size
nBinsNew = Cudd_PrimeCopy( 3 * pTable->nBins );
// allocate a new array
pBinsNew = ALLOC( Cut_Cut_t *, nBinsNew );
memset( pBinsNew, 0, sizeof(Cut_Cut_t *) * nBinsNew );
// rehash the entries from the old table
Counter = 0;
for ( i = 0; i < pTable->nBins; i++ )
Cut_TableListForEachCutSafe( pTable->pBins[i], pEnt, pEnt2 )
{
Key = Cut_HashKey(pEnt) % nBinsNew;
pEnt->pData = pBinsNew[Key];
pBinsNew[Key] = pEnt;
Counter++;
}
assert( Counter == pTable->nEntries );
// printf( "Increasing the structural table size from %6d to %6d. ", pMan->nBins, nBinsNew );
// PRT( "Time", clock() - clk );
// replace the table and the parameters
free( pTable->pBins );
pTable->pBins = pBinsNew;
pTable->nBins = nBinsNew;
}
/**Function*************************************************************
Synopsis [Stops the hash table.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Cut_TableReadTime( Cut_HashTable_t * pTable )
{
if ( pTable == NULL )
return 0;
return pTable->timeLookup;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
......@@ -315,6 +315,7 @@ void Cut_TruthComputeOld( Cut_Man_t * p, Cut_Cut_t * pCut, Cut_Cut_t * pCut0, Cu
p->timeTruth += clock() - clk;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
......
SRC += src/opt/cut/cutMan.c \
SRC += src/opt/cut/cutApi.c \
src/opt/cut/cutCut.c \
src/opt/cut/cutMan.c \
src/opt/cut/cutMerge.c \
src/opt/cut/cutNode.c \
src/opt/cut/cutSeq.c \
src/opt/cut/cutTable.c \
src/opt/cut/cutTruth.c
......@@ -183,7 +183,7 @@ Dec_Edge_t Dec_Factor_rec( Dec_Graph_t * pFForm, Mvc_Cover_t * pCover )
***********************************************************************/
Dec_Edge_t Dec_FactorLF_rec( Dec_Graph_t * pFForm, Mvc_Cover_t * pCover, Mvc_Cover_t * pSimple )
{
Dec_Man_t * pManDec = Abc_FrameReadManDec(Abc_FrameGetGlobalFrame());
Dec_Man_t * pManDec = Abc_FrameReadManDec();
Vec_Int_t * vEdgeLits = pManDec->vLits;
Mvc_Cover_t * pDiv, * pQuo, * pRem;
Dec_Edge_t eNodeDiv, eNodeQuo, eNodeRem;
......@@ -228,7 +228,7 @@ Dec_Edge_t Dec_FactorLF_rec( Dec_Graph_t * pFForm, Mvc_Cover_t * pCover, Mvc_Cov
***********************************************************************/
Dec_Edge_t Dec_FactorTrivial( Dec_Graph_t * pFForm, Mvc_Cover_t * pCover )
{
Dec_Man_t * pManDec = Abc_FrameReadManDec(Abc_FrameGetGlobalFrame());
Dec_Man_t * pManDec = Abc_FrameReadManDec();
Vec_Int_t * vEdgeCubes = pManDec->vCubes;
Vec_Int_t * vEdgeLits = pManDec->vLits;
Mvc_Manager_t * pMem = pManDec->pMvcMem;
......@@ -323,7 +323,7 @@ Dec_Edge_t Dec_FactorTrivialTree_rec( Dec_Graph_t * pFForm, Dec_Edge_t * peNodes
***********************************************************************/
Mvc_Cover_t * Dec_ConvertSopToMvc( char * pSop )
{
Dec_Man_t * pManDec = Abc_FrameReadManDec(Abc_FrameGetGlobalFrame());
Dec_Man_t * pManDec = Abc_FrameReadManDec();
Mvc_Manager_t * pMem = pManDec->pMvcMem;
Mvc_Cover_t * pMvc;
Mvc_Cube_t * pMvcCube;
......@@ -365,7 +365,7 @@ Mvc_Cover_t * Dec_ConvertSopToMvc( char * pSop )
***********************************************************************/
int Dec_FactorVerify( char * pSop, Dec_Graph_t * pFForm )
{
DdManager * dd = Abc_FrameReadManDd( Abc_FrameGetGlobalFrame() );
DdManager * dd = Abc_FrameReadManDd();
DdNode * bFunc1, * bFunc2;
int RetValue;
bFunc1 = Abc_ConvertSopToBdd( dd, pSop ); Cudd_Ref( bFunc1 );
......
......@@ -50,7 +50,7 @@ clk = clock();
p = ALLOC( Rwr_Man_t, 1 );
memset( p, 0, sizeof(Rwr_Man_t) );
p->nFuncs = (1<<16);
pManDec = Abc_FrameReadManDec(Abc_FrameGetGlobalFrame());
pManDec = Abc_FrameReadManDec();
p->puCanons = pManDec->puCanons;
p->pPhases = pManDec->pPhases;
p->pPerms = pManDec->pPerms;
......
......@@ -43,9 +43,9 @@ typedef int lit;
typedef char lbool;
#ifdef _WIN32
typedef signed __int64 uint64; // compatible with MS VS 6.0
typedef signed __int64 sint64; // compatible with MS VS 6.0
#else
typedef unsigned long long uint64;
typedef long long sint64;
#endif
static const int var_Undef = -1;
......@@ -80,8 +80,8 @@ extern void Asat_SolverWriteDimacs( solver * pSat, char * pFileName );
struct stats_t
{
uint64 starts, decisions, propagations, inspects, conflicts;
uint64 clauses, clauses_literals, learnts, learnts_literals, max_literals, tot_literals;
sint64 starts, decisions, propagations, inspects, conflicts;
sint64 clauses, clauses_literals, learnts, learnts_literals, max_literals, tot_literals;
};
typedef struct stats_t stats;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment