mirror of
https://github.com/YosysHQ/abc.git
synced 2026-09-07 02:00:13 +02:00
Version abc70930
This commit is contained in:
@@ -1,176 +0,0 @@
|
||||
/**CFile****************************************************************
|
||||
|
||||
FileName [mapper.c]
|
||||
|
||||
PackageName [MVSIS 1.3: Multi-valued logic synthesis system.]
|
||||
|
||||
Synopsis [Command file for the mapper package.]
|
||||
|
||||
Author [MVSIS Group]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 2.0. Started - June 1, 2004.]
|
||||
|
||||
Revision [$Id: mapper.c,v 1.7 2005/01/23 06:59:42 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "abc.h"
|
||||
#include "mainInt.h"
|
||||
#include "mio.h"
|
||||
#include "mapperInt.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static int Map_CommandReadLibrary ( Abc_Frame_t * pAbc, int argc, char **argv );
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Map_Init( Abc_Frame_t * pAbc )
|
||||
{
|
||||
Cmd_CommandAdd( pAbc, "SC mapping", "read_super", Map_CommandReadLibrary, 0 );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Map_End()
|
||||
{
|
||||
// Map_SuperLibFree( s_pSuperLib );
|
||||
Map_SuperLibFree( Abc_FrameReadLibSuper() );
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Map_CommandReadLibrary( Abc_Frame_t * pAbc, int argc, char **argv )
|
||||
{
|
||||
FILE * pFile;
|
||||
FILE * pOut, * pErr;
|
||||
Map_SuperLib_t * pLib;
|
||||
Abc_Ntk_t * pNet;
|
||||
char * FileName, * ExcludeFile;
|
||||
int fVerbose;
|
||||
int fAlgorithm;
|
||||
int c;
|
||||
|
||||
pNet = Abc_FrameReadNtk(pAbc);
|
||||
pOut = Abc_FrameReadOut(pAbc);
|
||||
pErr = Abc_FrameReadErr(pAbc);
|
||||
|
||||
// set the defaults
|
||||
fVerbose = 1;
|
||||
fAlgorithm = 1;
|
||||
ExcludeFile = 0;
|
||||
Extra_UtilGetoptReset();
|
||||
while ( (c = Extra_UtilGetopt(argc, argv, "eovh")) != EOF )
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case 'e':
|
||||
ExcludeFile = argv[globalUtilOptind];
|
||||
if ( ExcludeFile == 0 )
|
||||
goto usage;
|
||||
globalUtilOptind++;
|
||||
break;
|
||||
case 'o':
|
||||
fAlgorithm ^= 1;
|
||||
break;
|
||||
case 'v':
|
||||
fVerbose ^= 1;
|
||||
break;
|
||||
case 'h':
|
||||
goto usage;
|
||||
break;
|
||||
default:
|
||||
goto usage;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if ( argc != globalUtilOptind + 1 )
|
||||
{
|
||||
goto usage;
|
||||
}
|
||||
|
||||
// get the input file name
|
||||
FileName = argv[globalUtilOptind];
|
||||
if ( (pFile = Io_FileOpen( FileName, "open_path", "r", 0 )) == NULL )
|
||||
// if ( (pFile = fopen( FileName, "r" )) == NULL )
|
||||
{
|
||||
fprintf( pErr, "Cannot open input file \"%s\". ", FileName );
|
||||
if ( FileName = Extra_FileGetSimilarName( FileName, ".genlib", ".lib", ".gen", ".g", NULL ) )
|
||||
fprintf( pErr, "Did you mean \"%s\"?", FileName );
|
||||
fprintf( pErr, "\n" );
|
||||
return 1;
|
||||
}
|
||||
fclose( pFile );
|
||||
|
||||
// set the new network
|
||||
pLib = Map_SuperLibCreate( FileName, ExcludeFile, fAlgorithm, fVerbose );
|
||||
if ( pLib == NULL )
|
||||
{
|
||||
fprintf( pErr, "Reading supergate library has failed.\n" );
|
||||
goto usage;
|
||||
}
|
||||
// replace the current library
|
||||
// Map_SuperLibFree( s_pSuperLib );
|
||||
// s_pSuperLib = pLib;
|
||||
Map_SuperLibFree( Abc_FrameReadLibSuper() );
|
||||
Abc_FrameSetLibSuper( pLib );
|
||||
// replace the current genlib library
|
||||
// if ( s_pLib ) Mio_LibraryDelete( s_pLib );
|
||||
// s_pLib = s_pSuperLib->pGenlib;
|
||||
Mio_LibraryDelete( Abc_FrameReadLibGen() );
|
||||
Abc_FrameSetLibGen( pLib->pGenlib );
|
||||
return 0;
|
||||
|
||||
usage:
|
||||
fprintf( pErr, "\nusage: read_super [-ovh]\n");
|
||||
fprintf( pErr, "\t read the supergate library from the file\n" );
|
||||
fprintf( pErr, "\t-e file : file contains list of genlib gates to exclude\n" );
|
||||
fprintf( pErr, "\t-o : toggles the use of old file format [default = %s]\n", (fAlgorithm? "new" : "old") );
|
||||
fprintf( pErr, "\t-v : toggles enabling of verbose output [default = %s]\n", (fVerbose? "yes" : "no") );
|
||||
fprintf( pErr, "\t-h : print the command usage\n");
|
||||
return 1; /* error exit */
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
@@ -1,195 +0,0 @@
|
||||
/**CFile****************************************************************
|
||||
|
||||
FileName [mapper.h]
|
||||
|
||||
PackageName [MVSIS 2.0: Multi-valued logic synthesis system.]
|
||||
|
||||
Synopsis [Generic technology mapping engine.]
|
||||
|
||||
Author [MVSIS Group]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 2.0. Started - June 1, 2004.]
|
||||
|
||||
Revision [$Id: mapper.h,v 1.11 2005/02/28 05:34:26 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef __MAPPER_H__
|
||||
#define __MAPPER_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// INCLUDES ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// PARAMETERS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// STRUCTURE DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef struct Map_ManStruct_t_ Map_Man_t;
|
||||
typedef struct Map_NodeStruct_t_ Map_Node_t;
|
||||
typedef struct Map_NodeVecStruct_t_ Map_NodeVec_t;
|
||||
typedef struct Map_CutStruct_t_ Map_Cut_t;
|
||||
typedef struct Map_MatchStruct_t_ Map_Match_t;
|
||||
typedef struct Map_SuperStruct_t_ Map_Super_t;
|
||||
typedef struct Map_SuperLibStruct_t_ Map_SuperLib_t;
|
||||
typedef struct Map_HashTableStruct_t_ Map_HashTable_t;
|
||||
typedef struct Map_HashEntryStruct_t_ Map_HashEntry_t;
|
||||
typedef struct Map_TimeStruct_t_ Map_Time_t;
|
||||
|
||||
// the pair of rise/fall time parameters
|
||||
struct Map_TimeStruct_t_
|
||||
{
|
||||
float Rise;
|
||||
float Fall;
|
||||
float Worst;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// GLOBAL VARIABLES ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// MACRO DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define Map_IsComplement(p) (((int)((unsigned long) (p) & 01)))
|
||||
#define Map_Regular(p) ((Map_Node_t *)((unsigned long)(p) & ~01))
|
||||
#define Map_Not(p) ((Map_Node_t *)((unsigned long)(p) ^ 01))
|
||||
#define Map_NotCond(p,c) ((Map_Node_t *)((unsigned long)(p) ^ (c)))
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/*=== mapperCreate.c =============================================================*/
|
||||
extern Map_Man_t * Map_ManCreate( int nInputs, int nOutputs, int fVerbose );
|
||||
extern Map_Node_t * Map_NodeCreate( Map_Man_t * p, Map_Node_t * p1, Map_Node_t * p2 );
|
||||
extern void Map_ManFree( Map_Man_t * pMan );
|
||||
extern void Map_ManPrintTimeStats( Map_Man_t * p );
|
||||
extern void Map_ManPrintStatsToFile( char * pName, float Area, float Delay, int Time );
|
||||
extern int Map_ManReadInputNum( Map_Man_t * p );
|
||||
extern int Map_ManReadOutputNum( Map_Man_t * p );
|
||||
extern Map_Node_t ** Map_ManReadInputs ( Map_Man_t * p );
|
||||
extern Map_Node_t ** Map_ManReadOutputs( Map_Man_t * p );
|
||||
extern Map_Node_t * Map_ManReadConst1 ( Map_Man_t * p );
|
||||
extern Map_Time_t * Map_ManReadInputArrivals( Map_Man_t * p );
|
||||
extern Mio_Library_t * Map_ManReadGenLib ( Map_Man_t * p );
|
||||
extern bool Map_ManReadVerbose( Map_Man_t * p );
|
||||
extern float Map_ManReadAreaFinal( Map_Man_t * p );
|
||||
extern float Map_ManReadRequiredGlo( Map_Man_t * p );
|
||||
extern void Map_ManSetTimeToMap( Map_Man_t * p, int Time );
|
||||
extern void Map_ManSetTimeToNet( Map_Man_t * p, int Time );
|
||||
extern void Map_ManSetTimeSweep( Map_Man_t * p, int Time );
|
||||
extern void Map_ManSetTimeTotal( Map_Man_t * p, int Time );
|
||||
extern void Map_ManSetOutputNames( Map_Man_t * p, char ** ppNames );
|
||||
extern void Map_ManSetAreaRecovery( Map_Man_t * p, int fAreaRecovery );
|
||||
extern void Map_ManSetDelayTarget( Map_Man_t * p, float DelayTarget );
|
||||
extern void Map_ManSetInputArrivals( Map_Man_t * p, Map_Time_t * pArrivals );
|
||||
extern void Map_ManSetObeyFanoutLimits( Map_Man_t * p, bool fObeyFanoutLimits );
|
||||
extern void Map_ManSetNumIterations( Map_Man_t * p, int nNumIterations );
|
||||
extern int Map_ManReadPass( Map_Man_t * p );
|
||||
extern void Map_ManSetPass( Map_Man_t * p, int nPass );
|
||||
extern int Map_ManReadFanoutViolations( Map_Man_t * p );
|
||||
extern void Map_ManSetFanoutViolations( Map_Man_t * p, int nVio );
|
||||
extern void Map_ManSetChoiceNodeNum( Map_Man_t * p, int nChoiceNodes );
|
||||
extern void Map_ManSetChoiceNum( Map_Man_t * p, int nChoices );
|
||||
extern void Map_ManSetVerbose( Map_Man_t * p, int fVerbose );
|
||||
extern void Map_ManSetSwitching( Map_Man_t * p, int fSwitching );
|
||||
|
||||
extern Map_Man_t * Map_NodeReadMan( Map_Node_t * p );
|
||||
extern char * Map_NodeReadData( Map_Node_t * p, int fPhase );
|
||||
extern int Map_NodeReadNum( Map_Node_t * p );
|
||||
extern int Map_NodeReadLevel( Map_Node_t * p );
|
||||
extern Map_Cut_t * Map_NodeReadCuts( Map_Node_t * p );
|
||||
extern Map_Cut_t * Map_NodeReadCutBest( Map_Node_t * p, int fPhase );
|
||||
extern Map_Node_t * Map_NodeReadOne( Map_Node_t * p );
|
||||
extern Map_Node_t * Map_NodeReadTwo( Map_Node_t * p );
|
||||
extern void Map_NodeSetData( Map_Node_t * p, int fPhase, char * pData );
|
||||
extern void Map_NodeSetNextE( Map_Node_t * p, Map_Node_t * pNextE );
|
||||
extern void Map_NodeSetRepr( Map_Node_t * p, Map_Node_t * pRepr );
|
||||
extern void Map_NodeSetSwitching( Map_Node_t * p, float Switching );
|
||||
|
||||
extern int Map_NodeIsConst( Map_Node_t * p );
|
||||
extern int Map_NodeIsVar( Map_Node_t * p );
|
||||
extern int Map_NodeIsAnd( Map_Node_t * p );
|
||||
extern int Map_NodeComparePhase( Map_Node_t * p1, Map_Node_t * p2 );
|
||||
|
||||
extern Map_Super_t * Map_CutReadSuperBest( Map_Cut_t * p, int fPhase );
|
||||
extern Map_Super_t * Map_CutReadSuper0( Map_Cut_t * p );
|
||||
extern Map_Super_t * Map_CutReadSuper1( Map_Cut_t * p );
|
||||
extern int Map_CutReadLeavesNum( Map_Cut_t * p );
|
||||
extern Map_Node_t ** Map_CutReadLeaves( Map_Cut_t * p );
|
||||
extern unsigned Map_CutReadPhaseBest( Map_Cut_t * p, int fPhase );
|
||||
extern unsigned Map_CutReadPhase0( Map_Cut_t * p );
|
||||
extern unsigned Map_CutReadPhase1( Map_Cut_t * p );
|
||||
extern Map_Cut_t * Map_CutReadNext( Map_Cut_t * p );
|
||||
|
||||
extern char * Map_SuperReadFormula( Map_Super_t * p );
|
||||
extern Mio_Gate_t * Map_SuperReadRoot( Map_Super_t * p );
|
||||
extern int Map_SuperReadNum( Map_Super_t * p );
|
||||
extern Map_Super_t ** Map_SuperReadFanins( Map_Super_t * p );
|
||||
extern int Map_SuperReadFaninNum( Map_Super_t * p );
|
||||
extern Map_Super_t * Map_SuperReadNext( Map_Super_t * p );
|
||||
extern int Map_SuperReadNumPhases( Map_Super_t * p );
|
||||
extern unsigned char * Map_SuperReadPhases( Map_Super_t * p );
|
||||
extern int Map_SuperReadFanoutLimit( Map_Super_t * p );
|
||||
|
||||
extern Mio_Library_t * Map_SuperLibReadGenLib( Map_SuperLib_t * p );
|
||||
extern float Map_SuperLibReadAreaInv( Map_SuperLib_t * p );
|
||||
extern Map_Time_t Map_SuperLibReadDelayInv( Map_SuperLib_t * p );
|
||||
extern int Map_SuperLibReadVarsMax( Map_SuperLib_t * p );
|
||||
|
||||
extern Map_Node_t * Map_NodeAnd( Map_Man_t * p, Map_Node_t * p1, Map_Node_t * p2 );
|
||||
extern Map_Node_t * Map_NodeOr( Map_Man_t * p, Map_Node_t * p1, Map_Node_t * p2 );
|
||||
extern Map_Node_t * Map_NodeExor( Map_Man_t * p, Map_Node_t * p1, Map_Node_t * p2 );
|
||||
extern Map_Node_t * Map_NodeMux( Map_Man_t * p, Map_Node_t * pNode, Map_Node_t * pNodeT, Map_Node_t * pNodeE );
|
||||
extern void Map_NodeSetChoice( Map_Man_t * pMan, Map_Node_t * pNodeOld, Map_Node_t * pNodeNew );
|
||||
|
||||
/*=== resmCanon.c =============================================================*/
|
||||
extern int Map_CanonComputeSlow( unsigned uTruths[][2], int nVarsMax, int nVarsReal, unsigned uTruth[], unsigned char * puPhases, unsigned uTruthRes[] );
|
||||
extern int Map_CanonComputeFast( Map_Man_t * p, int nVarsMax, int nVarsReal, unsigned uTruth[], unsigned char * puPhases, unsigned uTruthRes[] );
|
||||
/*=== mapperCut.c =============================================================*/
|
||||
extern Map_Cut_t * Map_CutAlloc( Map_Man_t * p );
|
||||
/*=== mapperCutUtils.c =============================================================*/
|
||||
extern void Map_CutCreateFromNode( Map_Man_t * p, Map_Super_t * pSuper, int iRoot, unsigned uPhaseRoot,
|
||||
int * pLeaves, int nLeaves, unsigned uPhaseLeaves );
|
||||
/*=== mapperCore.c =============================================================*/
|
||||
extern int Map_Mapping( Map_Man_t * p );
|
||||
/*=== mapperLib.c =============================================================*/
|
||||
extern int Map_SuperLibDeriveFromGenlib( Mio_Library_t * pLib );
|
||||
/*=== mapperMntk.c =============================================================*/
|
||||
//extern Mntk_Man_t * Map_ConvertMappingToMntk( Map_Man_t * pMan );
|
||||
/*=== mapperSuper.c =============================================================*/
|
||||
extern char * Map_LibraryReadFormulaStep( char * pFormula, char * pStrings[], int * pnStrings );
|
||||
/*=== mapperSweep.c =============================================================*/
|
||||
extern void Map_NetworkSweep( Abc_Ntk_t * pNet );
|
||||
/*=== mapperTable.c =============================================================*/
|
||||
extern Map_Super_t * Map_SuperTableLookupC( Map_SuperLib_t * pLib, unsigned uTruth[] );
|
||||
/*=== mapperTime.c =============================================================*/
|
||||
/*=== mapperUtil.c =============================================================*/
|
||||
extern int Map_ManCheckConsistency( Map_Man_t * p );
|
||||
extern st_table * Map_CreateTableGate2Super( Map_Man_t * p );
|
||||
extern void Map_ManCleanData( Map_Man_t * p );
|
||||
extern void Map_MappingSetupTruthTables( unsigned uTruths[][2] );
|
||||
extern void Map_MappingSetupTruthTablesLarge( unsigned uTruths[][32] );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
@@ -1,271 +0,0 @@
|
||||
/**CFile****************************************************************
|
||||
|
||||
FileName [mapperCanon.c]
|
||||
|
||||
PackageName [MVSIS 1.3: Multi-valued logic synthesis system.]
|
||||
|
||||
Synopsis [Generic technology mapping engine.]
|
||||
|
||||
Author [MVSIS Group]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 2.0. Started - June 1, 2004.]
|
||||
|
||||
Revision [$Id: mapperCanon.c,v 1.2 2005/01/23 06:59:42 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "mapperInt.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static unsigned Map_CanonComputePhase( unsigned uTruths[][2], int nVars, unsigned uTruth, unsigned uPhase );
|
||||
static void Map_CanonComputePhase6( unsigned uTruths[][2], int nVars, unsigned uTruth[], unsigned uPhase, unsigned uTruthRes[] );
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes the N-canonical form of the Boolean function.]
|
||||
|
||||
Description [The N-canonical form is defined as the truth table with
|
||||
the minimum integer value. This function exhaustively enumerates
|
||||
through the complete set of 2^N phase assignments.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Map_CanonComputeSlow( unsigned uTruths[][2], int nVarsMax, int nVarsReal, unsigned uTruth[], unsigned char * puPhases, unsigned uTruthRes[] )
|
||||
{
|
||||
unsigned uTruthPerm[2];
|
||||
int nMints, nPhases, m;
|
||||
|
||||
nPhases = 0;
|
||||
nMints = (1 << nVarsReal);
|
||||
if ( nVarsMax < 6 )
|
||||
{
|
||||
uTruthRes[0] = MAP_MASK(32);
|
||||
for ( m = 0; m < nMints; m++ )
|
||||
{
|
||||
uTruthPerm[0] = Map_CanonComputePhase( uTruths, nVarsMax, uTruth[0], m );
|
||||
if ( uTruthRes[0] > uTruthPerm[0] )
|
||||
{
|
||||
uTruthRes[0] = uTruthPerm[0];
|
||||
nPhases = 0;
|
||||
puPhases[nPhases++] = (unsigned char)m;
|
||||
}
|
||||
else if ( uTruthRes[0] == uTruthPerm[0] )
|
||||
{
|
||||
if ( nPhases < 4 ) // the max number of phases in Map_Super_t
|
||||
puPhases[nPhases++] = (unsigned char)m;
|
||||
}
|
||||
}
|
||||
uTruthRes[1] = uTruthRes[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
uTruthRes[0] = MAP_MASK(32);
|
||||
uTruthRes[1] = MAP_MASK(32);
|
||||
for ( m = 0; m < nMints; m++ )
|
||||
{
|
||||
Map_CanonComputePhase6( uTruths, nVarsMax, uTruth, m, uTruthPerm );
|
||||
if ( uTruthRes[1] > uTruthPerm[1] || uTruthRes[1] == uTruthPerm[1] && uTruthRes[0] > uTruthPerm[0] )
|
||||
{
|
||||
uTruthRes[0] = uTruthPerm[0];
|
||||
uTruthRes[1] = uTruthPerm[1];
|
||||
nPhases = 0;
|
||||
puPhases[nPhases++] = (unsigned char)m;
|
||||
}
|
||||
else if ( uTruthRes[1] == uTruthPerm[1] && uTruthRes[0] == uTruthPerm[0] )
|
||||
{
|
||||
if ( nPhases < 4 ) // the max number of phases in Map_Super_t
|
||||
puPhases[nPhases++] = (unsigned char)m;
|
||||
}
|
||||
}
|
||||
}
|
||||
assert( nPhases > 0 );
|
||||
// printf( "%d ", nPhases );
|
||||
return nPhases;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Performs phase transformation for one function of less than 6 variables.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
unsigned Map_CanonComputePhase( unsigned uTruths[][2], int nVars, unsigned uTruth, unsigned uPhase )
|
||||
{
|
||||
int v, Shift;
|
||||
for ( v = 0, Shift = 1; v < nVars; v++, Shift <<= 1 )
|
||||
if ( uPhase & Shift )
|
||||
uTruth = (((uTruth & ~uTruths[v][0]) << Shift) | ((uTruth & uTruths[v][0]) >> Shift));
|
||||
return uTruth;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Performs phase transformation for one function of 6 variables.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Map_CanonComputePhase6( unsigned uTruths[][2], int nVars, unsigned uTruth[], unsigned uPhase, unsigned uTruthRes[] )
|
||||
{
|
||||
unsigned uTemp;
|
||||
int v, Shift;
|
||||
|
||||
// initialize the result
|
||||
uTruthRes[0] = uTruth[0];
|
||||
uTruthRes[1] = uTruth[1];
|
||||
if ( uPhase == 0 )
|
||||
return;
|
||||
// compute the phase
|
||||
for ( v = 0, Shift = 1; v < nVars; v++, Shift <<= 1 )
|
||||
if ( uPhase & Shift )
|
||||
{
|
||||
if ( Shift < 32 )
|
||||
{
|
||||
uTruthRes[0] = (((uTruthRes[0] & ~uTruths[v][0]) << Shift) | ((uTruthRes[0] & uTruths[v][0]) >> Shift));
|
||||
uTruthRes[1] = (((uTruthRes[1] & ~uTruths[v][1]) << Shift) | ((uTruthRes[1] & uTruths[v][1]) >> Shift));
|
||||
}
|
||||
else
|
||||
{
|
||||
uTemp = uTruthRes[0];
|
||||
uTruthRes[0] = uTruthRes[1];
|
||||
uTruthRes[1] = uTemp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes the N-canonical form of the Boolean function.]
|
||||
|
||||
Description [The N-canonical form is defined as the truth table with
|
||||
the minimum integer value. This function exhaustively enumerates
|
||||
through the complete set of 2^N phase assignments.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Map_CanonComputeFast( Map_Man_t * p, int nVarsMax, int nVarsReal, unsigned uTruth[], unsigned char * puPhases, unsigned uTruthRes[] )
|
||||
{
|
||||
unsigned uTruth0, uTruth1;
|
||||
unsigned uCanon0, uCanon1, uCanonBest, uPhaseBest;
|
||||
int i, Limit;
|
||||
|
||||
if ( nVarsMax == 6 )
|
||||
return Map_CanonComputeSlow( p->uTruths, nVarsMax, nVarsReal, uTruth, puPhases, uTruthRes );
|
||||
|
||||
if ( nVarsReal < 5 )
|
||||
{
|
||||
// return Map_CanonComputeSlow( p->uTruths, nVarsMax, nVarsReal, uTruth, puPhases, uTruthRes );
|
||||
|
||||
uTruth0 = uTruth[0] & 0xFFFF;
|
||||
assert( p->pCounters[uTruth0] > 0 );
|
||||
uTruthRes[0] = (p->uCanons[uTruth0] << 16) | p->uCanons[uTruth0];
|
||||
uTruthRes[1] = uTruthRes[0];
|
||||
puPhases[0] = p->uPhases[uTruth0][0];
|
||||
return 1;
|
||||
}
|
||||
|
||||
assert( nVarsMax == 5 );
|
||||
assert( nVarsReal == 5 );
|
||||
uTruth0 = uTruth[0] & 0xFFFF;
|
||||
uTruth1 = (uTruth[0] >> 16);
|
||||
if ( uTruth1 == 0 )
|
||||
{
|
||||
uTruthRes[0] = p->uCanons[uTruth0];
|
||||
uTruthRes[1] = uTruthRes[0];
|
||||
Limit = (p->pCounters[uTruth0] > 4)? 4 : p->pCounters[uTruth0];
|
||||
for ( i = 0; i < Limit; i++ )
|
||||
puPhases[i] = p->uPhases[uTruth0][i];
|
||||
return Limit;
|
||||
}
|
||||
else if ( uTruth0 == 0 )
|
||||
{
|
||||
uTruthRes[0] = p->uCanons[uTruth1];
|
||||
uTruthRes[1] = uTruthRes[0];
|
||||
Limit = (p->pCounters[uTruth1] > 4)? 4 : p->pCounters[uTruth1];
|
||||
for ( i = 0; i < Limit; i++ )
|
||||
{
|
||||
puPhases[i] = p->uPhases[uTruth1][i];
|
||||
puPhases[i] |= (1 << 4);
|
||||
}
|
||||
return Limit;
|
||||
}
|
||||
uCanon0 = p->uCanons[uTruth0];
|
||||
uCanon1 = p->uCanons[uTruth1];
|
||||
if ( uCanon0 >= uCanon1 ) // using nCanon1 as the main one
|
||||
{
|
||||
assert( p->pCounters[uTruth1] > 0 );
|
||||
uCanonBest = 0xFFFFFFFF;
|
||||
for ( i = 0; i < p->pCounters[uTruth1]; i++ )
|
||||
{
|
||||
uCanon0 = Extra_TruthPolarize( uTruth0, p->uPhases[uTruth1][i], 4 );
|
||||
if ( uCanonBest > uCanon0 )
|
||||
{
|
||||
uCanonBest = uCanon0;
|
||||
uPhaseBest = p->uPhases[uTruth1][i];
|
||||
assert( uPhaseBest < 16 );
|
||||
}
|
||||
}
|
||||
uTruthRes[0] = (uCanon1 << 16) | uCanonBest;
|
||||
uTruthRes[1] = uTruthRes[0];
|
||||
puPhases[0] = uPhaseBest;
|
||||
return 1;
|
||||
}
|
||||
else if ( uCanon0 < uCanon1 )
|
||||
{
|
||||
assert( p->pCounters[uTruth0] > 0 );
|
||||
uCanonBest = 0xFFFFFFFF;
|
||||
for ( i = 0; i < p->pCounters[uTruth0]; i++ )
|
||||
{
|
||||
uCanon1 = Extra_TruthPolarize( uTruth1, p->uPhases[uTruth0][i], 4 );
|
||||
if ( uCanonBest > uCanon1 )
|
||||
{
|
||||
uCanonBest = uCanon1;
|
||||
uPhaseBest = p->uPhases[uTruth0][i];
|
||||
assert( uPhaseBest < 16 );
|
||||
}
|
||||
}
|
||||
uTruthRes[0] = (uCanon0 << 16) | uCanonBest;
|
||||
uTruthRes[1] = uTruthRes[0];
|
||||
puPhases[0] = uPhaseBest | (1 << 4);
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
assert( 0 );
|
||||
return Map_CanonComputeSlow( p->uTruths, nVarsMax, nVarsReal, uTruth, puPhases, uTruthRes );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
@@ -1,228 +0,0 @@
|
||||
/**CFile****************************************************************
|
||||
|
||||
FileName [mapperCore.c]
|
||||
|
||||
PackageName [MVSIS 1.3: Multi-valued logic synthesis system.]
|
||||
|
||||
Synopsis [Generic technology mapping engine.]
|
||||
|
||||
Author [MVSIS Group]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 2.0. Started - June 1, 2004.]
|
||||
|
||||
Revision [$Id: mapperCore.c,v 1.7 2004/10/01 23:41:04 satrajit Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "mapperInt.h"
|
||||
//#include "resm.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Performs technology mapping for the given object graph.]
|
||||
|
||||
Description [The object graph is stored in the mapping manager.
|
||||
First, the AND nodes that fanout into POs are collected in the DFS order.
|
||||
Two preprocessing steps are performed: the k-feasible cuts are computed
|
||||
for each node and the truth tables are computed for each cut. Next, the
|
||||
delay-optimal matches are assigned for each node, followed by several
|
||||
iterations of area recoveryd: using area flow (global optimization)
|
||||
and using exact area at a node (local optimization).]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Map_Mapping( Map_Man_t * p )
|
||||
{
|
||||
int fShowSwitching = 1;
|
||||
int fUseAreaFlow = 1;
|
||||
int fUseExactArea = !p->fSwitching;
|
||||
int fUseExactAreaWithPhase = !p->fSwitching;
|
||||
int clk;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// perform pre-mapping computations
|
||||
// collect the nodes reachable from POs in the DFS order (including the choices)
|
||||
p->vAnds = Map_MappingDfs( p, 1 );
|
||||
if ( p->fVerbose )
|
||||
Map_MappingReportChoices( p );
|
||||
Map_MappingSetChoiceLevels( p ); // should always be called before mapping!
|
||||
// return 1;
|
||||
|
||||
// compute the cuts of nodes in the DFS order
|
||||
clk = clock();
|
||||
Map_MappingCuts( p );
|
||||
p->timeCuts = clock() - clk;
|
||||
// derive the truth tables
|
||||
clk = clock();
|
||||
Map_MappingTruths( p );
|
||||
p->timeTruth = clock() - clk;
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
//PRT( "Truths", clock() - clk );
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// compute the minimum-delay mapping
|
||||
clk = clock();
|
||||
p->fMappingMode = 0;
|
||||
if ( !Map_MappingMatches( p ) )
|
||||
return 0;
|
||||
p->timeMatch = clock() - clk;
|
||||
// compute the references and collect the nodes used in the mapping
|
||||
Map_MappingSetRefs( p );
|
||||
p->AreaBase = Map_MappingGetArea( p, p->vMapping );
|
||||
if ( p->fVerbose )
|
||||
{
|
||||
printf( "Delay : %s = %8.2f Flow = %11.1f Area = %11.1f %4.1f %% ",
|
||||
fShowSwitching? "Switch" : "Delay",
|
||||
fShowSwitching? Map_MappingGetSwitching(p,p->vMapping) : p->fRequiredGlo,
|
||||
Map_MappingGetAreaFlow(p), p->AreaBase, 0.0 );
|
||||
PRT( "Time", p->timeMatch );
|
||||
}
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
if ( !p->fAreaRecovery )
|
||||
{
|
||||
if ( p->fVerbose )
|
||||
Map_MappingPrintOutputArrivals( p );
|
||||
return 1;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// perform area recovery using area flow
|
||||
clk = clock();
|
||||
if ( fUseAreaFlow )
|
||||
{
|
||||
// compute the required times
|
||||
Map_TimeComputeRequiredGlobal( p );
|
||||
// recover area flow
|
||||
p->fMappingMode = 1;
|
||||
Map_MappingMatches( p );
|
||||
// compute the references and collect the nodes used in the mapping
|
||||
Map_MappingSetRefs( p );
|
||||
p->AreaFinal = Map_MappingGetArea( p, p->vMapping );
|
||||
if ( p->fVerbose )
|
||||
{
|
||||
printf( "AreaFlow : %s = %8.2f Flow = %11.1f Area = %11.1f %4.1f %% ",
|
||||
fShowSwitching? "Switch" : "Delay",
|
||||
fShowSwitching? Map_MappingGetSwitching(p,p->vMapping) : p->fRequiredGlo,
|
||||
Map_MappingGetAreaFlow(p), p->AreaFinal,
|
||||
100.0*(p->AreaBase-p->AreaFinal)/p->AreaBase );
|
||||
PRT( "Time", clock() - clk );
|
||||
}
|
||||
}
|
||||
p->timeArea += clock() - clk;
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// perform area recovery using exact area
|
||||
clk = clock();
|
||||
if ( fUseExactArea )
|
||||
{
|
||||
// compute the required times
|
||||
Map_TimeComputeRequiredGlobal( p );
|
||||
// recover area
|
||||
p->fMappingMode = 2;
|
||||
Map_MappingMatches( p );
|
||||
// compute the references and collect the nodes used in the mapping
|
||||
Map_MappingSetRefs( p );
|
||||
p->AreaFinal = Map_MappingGetArea( p, p->vMapping );
|
||||
if ( p->fVerbose )
|
||||
{
|
||||
printf( "Area : %s = %8.2f Flow = %11.1f Area = %11.1f %4.1f %% ",
|
||||
fShowSwitching? "Switch" : "Delay",
|
||||
fShowSwitching? Map_MappingGetSwitching(p,p->vMapping) : p->fRequiredGlo,
|
||||
0.0, p->AreaFinal,
|
||||
100.0*(p->AreaBase-p->AreaFinal)/p->AreaBase );
|
||||
PRT( "Time", clock() - clk );
|
||||
}
|
||||
}
|
||||
p->timeArea += clock() - clk;
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// perform area recovery using exact area
|
||||
clk = clock();
|
||||
if ( fUseExactAreaWithPhase )
|
||||
{
|
||||
// compute the required times
|
||||
Map_TimeComputeRequiredGlobal( p );
|
||||
// recover area
|
||||
p->fMappingMode = 3;
|
||||
Map_MappingMatches( p );
|
||||
// compute the references and collect the nodes used in the mapping
|
||||
Map_MappingSetRefs( p );
|
||||
p->AreaFinal = Map_MappingGetArea( p, p->vMapping );
|
||||
if ( p->fVerbose )
|
||||
{
|
||||
printf( "Area : %s = %8.2f Flow = %11.1f Area = %11.1f %4.1f %% ",
|
||||
fShowSwitching? "Switch" : "Delay",
|
||||
fShowSwitching? Map_MappingGetSwitching(p,p->vMapping) : p->fRequiredGlo,
|
||||
0.0, p->AreaFinal,
|
||||
100.0*(p->AreaBase-p->AreaFinal)/p->AreaBase );
|
||||
PRT( "Time", clock() - clk );
|
||||
}
|
||||
}
|
||||
p->timeArea += clock() - clk;
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// perform area recovery using exact area
|
||||
clk = clock();
|
||||
if ( p->fSwitching )
|
||||
{
|
||||
// compute the required times
|
||||
Map_TimeComputeRequiredGlobal( p );
|
||||
// recover switching activity
|
||||
p->fMappingMode = 4;
|
||||
Map_MappingMatches( p );
|
||||
// compute the references and collect the nodes used in the mapping
|
||||
Map_MappingSetRefs( p );
|
||||
p->AreaFinal = Map_MappingGetArea( p, p->vMapping );
|
||||
if ( p->fVerbose )
|
||||
{
|
||||
printf( "Switching: %s = %8.2f Flow = %11.1f Area = %11.1f %4.1f %% ",
|
||||
fShowSwitching? "Switch" : "Delay",
|
||||
fShowSwitching? Map_MappingGetSwitching(p,p->vMapping) : p->fRequiredGlo,
|
||||
0.0, p->AreaFinal,
|
||||
100.0*(p->AreaBase-p->AreaFinal)/p->AreaBase );
|
||||
PRT( "Time", clock() - clk );
|
||||
}
|
||||
|
||||
// compute the required times
|
||||
Map_TimeComputeRequiredGlobal( p );
|
||||
// recover switching activity
|
||||
p->fMappingMode = 4;
|
||||
Map_MappingMatches( p );
|
||||
// compute the references and collect the nodes used in the mapping
|
||||
Map_MappingSetRefs( p );
|
||||
p->AreaFinal = Map_MappingGetArea( p, p->vMapping );
|
||||
if ( p->fVerbose )
|
||||
{
|
||||
printf( "Switching: %s = %8.2f Flow = %11.1f Area = %11.1f %4.1f %% ",
|
||||
fShowSwitching? "Switch" : "Delay",
|
||||
fShowSwitching? Map_MappingGetSwitching(p,p->vMapping) : p->fRequiredGlo,
|
||||
0.0, p->AreaFinal,
|
||||
100.0*(p->AreaBase-p->AreaFinal)/p->AreaBase );
|
||||
PRT( "Time", clock() - clk );
|
||||
}
|
||||
}
|
||||
p->timeArea += clock() - clk;
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
// print the arrival times of the latest outputs
|
||||
if ( p->fVerbose )
|
||||
Map_MappingPrintOutputArrivals( p );
|
||||
return 1;
|
||||
}
|
||||
@@ -1,600 +0,0 @@
|
||||
/**CFile****************************************************************
|
||||
|
||||
FileName [mapperCreate.c]
|
||||
|
||||
PackageName [MVSIS 1.3: Multi-valued logic synthesis system.]
|
||||
|
||||
Synopsis [Generic technology mapping engine.]
|
||||
|
||||
Author [MVSIS Group]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 2.0. Started - June 1, 2004.]
|
||||
|
||||
Revision [$Id: mapperCreate.c,v 1.15 2005/02/28 05:34:26 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "mapperInt.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static void Map_TableCreate( Map_Man_t * p );
|
||||
static void Map_TableResize( Map_Man_t * p );
|
||||
static Map_Node_t * Map_TableLookup( Map_Man_t * p, Map_Node_t * p1, Map_Node_t * p2 );
|
||||
|
||||
// hash key for the structural hash table
|
||||
static inline unsigned Map_HashKey2( Map_Node_t * p0, Map_Node_t * p1, int TableSize ) { return ((unsigned)(p0) + (unsigned)(p1) * 12582917) % TableSize; }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Reads parameters from the mapping manager.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Map_ManReadInputNum( Map_Man_t * p ) { return p->nInputs; }
|
||||
int Map_ManReadOutputNum( Map_Man_t * p ) { return p->nOutputs; }
|
||||
Map_Node_t ** Map_ManReadInputs ( Map_Man_t * p ) { return p->pInputs; }
|
||||
Map_Node_t ** Map_ManReadOutputs( Map_Man_t * p ) { return p->pOutputs; }
|
||||
Map_Node_t * Map_ManReadConst1 ( Map_Man_t * p ) { return p->pConst1; }
|
||||
Map_Time_t * Map_ManReadInputArrivals( Map_Man_t * p ) { return p->pInputArrivals;}
|
||||
Mio_Library_t * Map_ManReadGenLib ( Map_Man_t * p ) { return p->pSuperLib->pGenlib; }
|
||||
bool Map_ManReadVerbose( Map_Man_t * p ) { return p->fVerbose; }
|
||||
float Map_ManReadAreaFinal( Map_Man_t * p ) { return p->AreaFinal; }
|
||||
float Map_ManReadRequiredGlo( Map_Man_t * p ) { return p->fRequiredGlo; }
|
||||
void Map_ManSetTimeToMap( Map_Man_t * p, int Time ) { p->timeToMap = Time; }
|
||||
void Map_ManSetTimeToNet( Map_Man_t * p, int Time ) { p->timeToNet = Time; }
|
||||
void Map_ManSetTimeSweep( Map_Man_t * p, int Time ) { p->timeSweep = Time; }
|
||||
void Map_ManSetTimeTotal( Map_Man_t * p, int Time ) { p->timeTotal = Time; }
|
||||
void Map_ManSetOutputNames( Map_Man_t * p, char ** ppNames ) { p->ppOutputNames = ppNames; }
|
||||
void Map_ManSetAreaRecovery( Map_Man_t * p, int fAreaRecovery ) { p->fAreaRecovery = fAreaRecovery;}
|
||||
void Map_ManSetDelayTarget( Map_Man_t * p, float DelayTarget ) { p->DelayTarget = DelayTarget;}
|
||||
void Map_ManSetInputArrivals( Map_Man_t * p, Map_Time_t * pArrivals ) { p->pInputArrivals = pArrivals;}
|
||||
void Map_ManSetObeyFanoutLimits( Map_Man_t * p, bool fObeyFanoutLimits ) { p->fObeyFanoutLimits = fObeyFanoutLimits; }
|
||||
void Map_ManSetNumIterations( Map_Man_t * p, int nIterations ) { p->nIterations = nIterations; }
|
||||
int Map_ManReadFanoutViolations( Map_Man_t * p ) { return p->nFanoutViolations; }
|
||||
void Map_ManSetFanoutViolations( Map_Man_t * p, int nVio ) { p->nFanoutViolations = nVio; }
|
||||
void Map_ManSetChoiceNodeNum( Map_Man_t * p, int nChoiceNodes ) { p->nChoiceNodes = nChoiceNodes; }
|
||||
void Map_ManSetChoiceNum( Map_Man_t * p, int nChoices ) { p->nChoices = nChoices; }
|
||||
void Map_ManSetVerbose( Map_Man_t * p, int fVerbose ) { p->fVerbose = fVerbose; }
|
||||
void Map_ManSetSwitching( Map_Man_t * p, int fSwitching ) { p->fSwitching = fSwitching; }
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Reads parameters from the mapping node.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Map_Man_t * Map_NodeReadMan( Map_Node_t * p ) { return p->p; }
|
||||
char * Map_NodeReadData( Map_Node_t * p, int fPhase ) { return fPhase? p->pData1 : p->pData0; }
|
||||
int Map_NodeReadNum( Map_Node_t * p ) { return p->Num; }
|
||||
int Map_NodeReadLevel( Map_Node_t * p ) { return Map_Regular(p)->Level; }
|
||||
Map_Cut_t * Map_NodeReadCuts( Map_Node_t * p ) { return p->pCuts; }
|
||||
Map_Cut_t * Map_NodeReadCutBest( Map_Node_t * p, int fPhase ) { return p->pCutBest[fPhase]; }
|
||||
Map_Node_t * Map_NodeReadOne( Map_Node_t * p ) { return p->p1; }
|
||||
Map_Node_t * Map_NodeReadTwo( Map_Node_t * p ) { return p->p2; }
|
||||
void Map_NodeSetData( Map_Node_t * p, int fPhase, char * pData ) { if (fPhase) p->pData1 = pData; else p->pData0 = pData; }
|
||||
void Map_NodeSetNextE( Map_Node_t * p, Map_Node_t * pNextE ) { p->pNextE = pNextE; }
|
||||
void Map_NodeSetRepr( Map_Node_t * p, Map_Node_t * pRepr ) { p->pRepr = pRepr; }
|
||||
void Map_NodeSetSwitching( Map_Node_t * p, float Switching ) { p->Switching = Switching; }
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Checks the type of the node.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Map_NodeIsConst( Map_Node_t * p ) { return (Map_Regular(p))->Num == -1; }
|
||||
int Map_NodeIsVar( Map_Node_t * p ) { return (Map_Regular(p))->p1 == NULL && (Map_Regular(p))->Num >= 0; }
|
||||
int Map_NodeIsAnd( Map_Node_t * p ) { return (Map_Regular(p))->p1 != NULL; }
|
||||
int Map_NodeComparePhase( Map_Node_t * p1, Map_Node_t * p2 ) { assert( !Map_IsComplement(p1) ); assert( !Map_IsComplement(p2) ); return p1->fInv ^ p2->fInv; }
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Reads parameters from the cut.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Map_Super_t * Map_CutReadSuperBest( Map_Cut_t * p, int fPhase ) { return p->M[fPhase].pSuperBest;}
|
||||
Map_Super_t * Map_CutReadSuper0( Map_Cut_t * p ) { return p->M[0].pSuperBest;}
|
||||
Map_Super_t * Map_CutReadSuper1( Map_Cut_t * p ) { return p->M[1].pSuperBest;}
|
||||
int Map_CutReadLeavesNum( Map_Cut_t * p ) { return p->nLeaves; }
|
||||
Map_Node_t ** Map_CutReadLeaves( Map_Cut_t * p ) { return p->ppLeaves; }
|
||||
unsigned Map_CutReadPhaseBest( Map_Cut_t * p, int fPhase ) { return p->M[fPhase].uPhaseBest;}
|
||||
unsigned Map_CutReadPhase0( Map_Cut_t * p ) { return p->M[0].uPhaseBest;}
|
||||
unsigned Map_CutReadPhase1( Map_Cut_t * p ) { return p->M[1].uPhaseBest;}
|
||||
Map_Cut_t * Map_CutReadNext( Map_Cut_t * p ) { return p->pNext; }
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Reads parameters from the supergate.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
char * Map_SuperReadFormula( Map_Super_t * p ) { return p->pFormula; }
|
||||
Mio_Gate_t * Map_SuperReadRoot( Map_Super_t * p ) { return p->pRoot; }
|
||||
int Map_SuperReadNum( Map_Super_t * p ) { return p->Num; }
|
||||
Map_Super_t ** Map_SuperReadFanins( Map_Super_t * p ) { return p->pFanins; }
|
||||
int Map_SuperReadFaninNum( Map_Super_t * p ) { return p->nFanins; }
|
||||
Map_Super_t * Map_SuperReadNext( Map_Super_t * p ) { return p->pNext; }
|
||||
int Map_SuperReadNumPhases( Map_Super_t * p ) { return p->nPhases; }
|
||||
unsigned char * Map_SuperReadPhases( Map_Super_t * p ) { return p->uPhases; }
|
||||
int Map_SuperReadFanoutLimit( Map_Super_t * p ) { return p->nFanLimit;}
|
||||
|
||||
Mio_Library_t * Map_SuperLibReadGenLib( Map_SuperLib_t * p ) { return p->pGenlib; }
|
||||
float Map_SuperLibReadAreaInv( Map_SuperLib_t * p ) { return p->AreaInv; }
|
||||
Map_Time_t Map_SuperLibReadDelayInv( Map_SuperLib_t * p ) { return p->tDelayInv;}
|
||||
int Map_SuperLibReadVarsMax( Map_SuperLib_t * p ) { return p->nVarsMax; }
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Create the mapping manager.]
|
||||
|
||||
Description [The number of inputs and outputs is assumed to be
|
||||
known is advance. It is much simpler to have them fixed upfront.
|
||||
When it comes to representing the object graph in the form of
|
||||
AIG, the resulting manager is similar to the regular AIG manager,
|
||||
except that it does not use reference counting (and therefore
|
||||
does not have garbage collections). It does have table resizing.
|
||||
The data structure is more flexible to represent additional
|
||||
information needed for mapping.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Map_Man_t * Map_ManCreate( int nInputs, int nOutputs, int fVerbose )
|
||||
{
|
||||
Map_Man_t * p;
|
||||
int i;
|
||||
|
||||
// derive the supergate library
|
||||
if ( Abc_FrameReadLibSuper() == NULL )
|
||||
{
|
||||
printf( "The supergate library is not specified. Use \"read_library\" or \"read_super\".\n" );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// start the manager
|
||||
p = ALLOC( Map_Man_t, 1 );
|
||||
memset( p, 0, sizeof(Map_Man_t) );
|
||||
p->pSuperLib = Abc_FrameReadLibSuper();
|
||||
p->nVarsMax = p->pSuperLib->nVarsMax;
|
||||
p->fVerbose = fVerbose;
|
||||
p->fEpsilon = (float)0.001;
|
||||
assert( p->nVarsMax > 0 );
|
||||
|
||||
if ( p->nVarsMax == 5 )
|
||||
Extra_Truth4VarN( &p->uCanons, &p->uPhases, &p->pCounters, 8 );
|
||||
|
||||
// start various data structures
|
||||
Map_TableCreate( p );
|
||||
Map_MappingSetupTruthTables( p->uTruths );
|
||||
Map_MappingSetupTruthTablesLarge( p->uTruthsLarge );
|
||||
// printf( "Node = %d bytes. Cut = %d bytes. Super = %d bytes.\n", sizeof(Map_Node_t), sizeof(Map_Cut_t), sizeof(Map_Super_t) );
|
||||
p->mmNodes = Extra_MmFixedStart( sizeof(Map_Node_t) );
|
||||
p->mmCuts = Extra_MmFixedStart( sizeof(Map_Cut_t) );
|
||||
|
||||
// make sure the constant node will get index -1
|
||||
p->nNodes = -1;
|
||||
// create the constant node
|
||||
p->pConst1 = Map_NodeCreate( p, NULL, NULL );
|
||||
p->vNodesAll = Map_NodeVecAlloc( 100 );
|
||||
p->vNodesTemp = Map_NodeVecAlloc( 100 );
|
||||
p->vMapping = Map_NodeVecAlloc( 100 );
|
||||
p->vVisited = Map_NodeVecAlloc( 100 );
|
||||
|
||||
// create the PI nodes
|
||||
p->nInputs = nInputs;
|
||||
p->pInputs = ALLOC( Map_Node_t *, nInputs );
|
||||
for ( i = 0; i < nInputs; i++ )
|
||||
p->pInputs[i] = Map_NodeCreate( p, NULL, NULL );
|
||||
|
||||
// create the place for the output nodes
|
||||
p->nOutputs = nOutputs;
|
||||
p->pOutputs = ALLOC( Map_Node_t *, nOutputs );
|
||||
memset( p->pOutputs, 0, sizeof(Map_Node_t *) * nOutputs );
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Deallocates the mapping manager.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Map_ManFree( Map_Man_t * p )
|
||||
{
|
||||
// int i;
|
||||
// for ( i = 0; i < p->vNodesAll->nSize; i++ )
|
||||
// Map_NodeVecFree( p->vNodesAll->pArray[i]->vFanouts );
|
||||
// Map_NodeVecFree( p->pConst1->vFanouts );
|
||||
if ( p->vAnds )
|
||||
Map_NodeVecFree( p->vAnds );
|
||||
if ( p->vNodesAll )
|
||||
Map_NodeVecFree( p->vNodesAll );
|
||||
if ( p->vNodesTemp )
|
||||
Map_NodeVecFree( p->vNodesTemp );
|
||||
if ( p->vMapping )
|
||||
Map_NodeVecFree( p->vMapping );
|
||||
if ( p->vVisited )
|
||||
Map_NodeVecFree( p->vVisited );
|
||||
if ( p->uCanons ) free( p->uCanons );
|
||||
if ( p->uPhases ) free( p->uPhases );
|
||||
if ( p->pCounters ) free( p->pCounters );
|
||||
Extra_MmFixedStop( p->mmNodes );
|
||||
Extra_MmFixedStop( p->mmCuts );
|
||||
FREE( p->pInputArrivals );
|
||||
FREE( p->pInputs );
|
||||
FREE( p->pOutputs );
|
||||
FREE( p->pBins );
|
||||
FREE( p->ppOutputNames );
|
||||
FREE( p );
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Deallocates the mapping manager.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Map_ManPrintTimeStats( Map_Man_t * p )
|
||||
{
|
||||
printf( "N-canonical = %d. Matchings = %d. Phases = %d. ", p->nCanons, p->nMatches, p->nPhases );
|
||||
printf( "Choice nodes = %d. Choices = %d.\n", p->nChoiceNodes, p->nChoices );
|
||||
PRT( "ToMap", p->timeToMap );
|
||||
PRT( "Cuts ", p->timeCuts );
|
||||
PRT( "Truth", p->timeTruth );
|
||||
PRT( "Match", p->timeMatch );
|
||||
PRT( "Area ", p->timeArea );
|
||||
PRT( "Sweep", p->timeSweep );
|
||||
PRT( "ToNet", p->timeToNet );
|
||||
PRT( "TOTAL", p->timeTotal );
|
||||
if ( p->time1 ) { PRT( "time1", p->time1 ); }
|
||||
if ( p->time2 ) { PRT( "time2", p->time2 ); }
|
||||
if ( p->time3 ) { PRT( "time3", p->time3 ); }
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Prints the mapping stats.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Map_ManPrintStatsToFile( char * pName, float Area, float Delay, int Time )
|
||||
{
|
||||
FILE * pTable;
|
||||
pTable = fopen( "map_stats.txt", "a+" );
|
||||
fprintf( pTable, "%s ", pName );
|
||||
fprintf( pTable, "%4.2f ", Area );
|
||||
fprintf( pTable, "%4.2f ", Delay );
|
||||
fprintf( pTable, "%4.2f\n", (float)(Time)/(float)(CLOCKS_PER_SEC) );
|
||||
fclose( pTable );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Creates a new node.]
|
||||
|
||||
Description [This procedure should be called to create the constant
|
||||
node and the PI nodes first.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Map_Node_t * Map_NodeCreate( Map_Man_t * p, Map_Node_t * p1, Map_Node_t * p2 )
|
||||
{
|
||||
Map_Node_t * pNode;
|
||||
// create the node
|
||||
pNode = (Map_Node_t *)Extra_MmFixedEntryFetch( p->mmNodes );
|
||||
memset( pNode, 0, sizeof(Map_Node_t) );
|
||||
pNode->tRequired[0].Rise = pNode->tRequired[0].Fall = pNode->tRequired[0].Worst = MAP_FLOAT_LARGE;
|
||||
pNode->tRequired[1].Rise = pNode->tRequired[1].Fall = pNode->tRequired[1].Worst = MAP_FLOAT_LARGE;
|
||||
pNode->p1 = p1;
|
||||
pNode->p2 = p2;
|
||||
pNode->p = p;
|
||||
// set the number of this node
|
||||
pNode->Num = p->nNodes++;
|
||||
// place to store the fanouts
|
||||
// pNode->vFanouts = Map_NodeVecAlloc( 5 );
|
||||
// store this node in the internal array
|
||||
if ( pNode->Num >= 0 )
|
||||
Map_NodeVecPush( p->vNodesAll, pNode );
|
||||
else
|
||||
pNode->fInv = 1;
|
||||
// set the level of this node
|
||||
if ( p1 )
|
||||
{
|
||||
#ifdef MAP_ALLOCATE_FANOUT
|
||||
// create the fanout info
|
||||
Map_NodeAddFaninFanout( Map_Regular(p1), pNode );
|
||||
Map_NodeAddFaninFanout( Map_Regular(p2), pNode );
|
||||
#endif
|
||||
pNode->Level = 1 + MAP_MAX(Map_Regular(pNode->p1)->Level, Map_Regular(pNode->p2)->Level);
|
||||
pNode->fInv = Map_NodeIsSimComplement(p1) & Map_NodeIsSimComplement(p2);
|
||||
}
|
||||
// reference the inputs (will be used to compute the number of fanouts)
|
||||
if ( p1 ) Map_NodeRef(p1);
|
||||
if ( p2 ) Map_NodeRef(p2);
|
||||
|
||||
pNode->nRefEst[0] = pNode->nRefEst[1] = -1;
|
||||
return pNode;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Create the unique table of AND gates.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Map_TableCreate( Map_Man_t * pMan )
|
||||
{
|
||||
assert( pMan->pBins == NULL );
|
||||
pMan->nBins = Cudd_Prime(5000);
|
||||
pMan->pBins = ALLOC( Map_Node_t *, pMan->nBins );
|
||||
memset( pMan->pBins, 0, sizeof(Map_Node_t *) * pMan->nBins );
|
||||
pMan->nNodes = 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Looks up the AND2 node in the unique table.]
|
||||
|
||||
Description [This procedure implements one-level hashing. All the nodes
|
||||
are hashed by their children. If the node with the same children was already
|
||||
created, it is returned by the call to this procedure. If it does not exist,
|
||||
this procedure creates a new node with these children. ]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Map_Node_t * Map_TableLookup( Map_Man_t * pMan, Map_Node_t * p1, Map_Node_t * p2 )
|
||||
{
|
||||
Map_Node_t * pEnt;
|
||||
unsigned Key;
|
||||
|
||||
if ( p1 == p2 )
|
||||
return p1;
|
||||
if ( p1 == Map_Not(p2) )
|
||||
return Map_Not(pMan->pConst1);
|
||||
if ( Map_NodeIsConst(p1) )
|
||||
{
|
||||
if ( p1 == pMan->pConst1 )
|
||||
return p2;
|
||||
return Map_Not(pMan->pConst1);
|
||||
}
|
||||
if ( Map_NodeIsConst(p2) )
|
||||
{
|
||||
if ( p2 == pMan->pConst1 )
|
||||
return p1;
|
||||
return Map_Not(pMan->pConst1);
|
||||
}
|
||||
|
||||
if ( Map_Regular(p1)->Num > Map_Regular(p2)->Num )
|
||||
pEnt = p1, p1 = p2, p2 = pEnt;
|
||||
|
||||
Key = Map_HashKey2( p1, p2, pMan->nBins );
|
||||
for ( pEnt = pMan->pBins[Key]; pEnt; pEnt = pEnt->pNext )
|
||||
if ( pEnt->p1 == p1 && pEnt->p2 == p2 )
|
||||
return pEnt;
|
||||
// resize the table
|
||||
if ( pMan->nNodes >= 2 * pMan->nBins )
|
||||
{
|
||||
Map_TableResize( pMan );
|
||||
Key = Map_HashKey2( p1, p2, pMan->nBins );
|
||||
}
|
||||
// create the new node
|
||||
pEnt = Map_NodeCreate( pMan, p1, p2 );
|
||||
// add the node to the corresponding linked list in the table
|
||||
pEnt->pNext = pMan->pBins[Key];
|
||||
pMan->pBins[Key] = pEnt;
|
||||
return pEnt;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Resizes the table.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Map_TableResize( Map_Man_t * pMan )
|
||||
{
|
||||
Map_Node_t ** pBinsNew;
|
||||
Map_Node_t * pEnt, * pEnt2;
|
||||
int nBinsNew, Counter, i, clk;
|
||||
unsigned Key;
|
||||
|
||||
clk = clock();
|
||||
// get the new table size
|
||||
nBinsNew = Cudd_Prime(2 * pMan->nBins);
|
||||
// allocate a new array
|
||||
pBinsNew = ALLOC( Map_Node_t *, nBinsNew );
|
||||
memset( pBinsNew, 0, sizeof(Map_Node_t *) * nBinsNew );
|
||||
// rehash the entries from the old table
|
||||
Counter = 0;
|
||||
for ( i = 0; i < pMan->nBins; i++ )
|
||||
for ( pEnt = pMan->pBins[i], pEnt2 = pEnt? pEnt->pNext: NULL; pEnt;
|
||||
pEnt = pEnt2, pEnt2 = pEnt? pEnt->pNext: NULL )
|
||||
{
|
||||
Key = Map_HashKey2( pEnt->p1, pEnt->p2, nBinsNew );
|
||||
pEnt->pNext = pBinsNew[Key];
|
||||
pBinsNew[Key] = pEnt;
|
||||
Counter++;
|
||||
}
|
||||
assert( Counter == pMan->nNodes - pMan->nInputs );
|
||||
if ( pMan->fVerbose )
|
||||
{
|
||||
// printf( "Increasing the unique table size from %6d to %6d. ", pMan->nBins, nBinsNew );
|
||||
// PRT( "Time", clock() - clk );
|
||||
}
|
||||
// replace the table and the parameters
|
||||
free( pMan->pBins );
|
||||
pMan->pBins = pBinsNew;
|
||||
pMan->nBins = nBinsNew;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Map_Node_t * Map_NodeAnd( Map_Man_t * p, Map_Node_t * p1, Map_Node_t * p2 )
|
||||
{
|
||||
Map_Node_t * pNode;
|
||||
pNode = Map_TableLookup( p, p1, p2 );
|
||||
return pNode;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Map_Node_t * Map_NodeOr( Map_Man_t * p, Map_Node_t * p1, Map_Node_t * p2 )
|
||||
{
|
||||
Map_Node_t * pNode;
|
||||
pNode = Map_Not( Map_TableLookup( p, Map_Not(p1), Map_Not(p2) ) );
|
||||
return pNode;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Map_Node_t * Map_NodeExor( Map_Man_t * p, Map_Node_t * p1, Map_Node_t * p2 )
|
||||
{
|
||||
return Map_NodeMux( p, p1, Map_Not(p2), p2 );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Map_Node_t * Map_NodeMux( Map_Man_t * p, Map_Node_t * pC, Map_Node_t * pT, Map_Node_t * pE )
|
||||
{
|
||||
Map_Node_t * pAnd1, * pAnd2, * pRes;
|
||||
pAnd1 = Map_TableLookup( p, pC, pT );
|
||||
pAnd2 = Map_TableLookup( p, Map_Not(pC), pE );
|
||||
pRes = Map_NodeOr( p, pAnd1, pAnd2 );
|
||||
return pRes;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Sets the node to be equivalent to the given one.]
|
||||
|
||||
Description [This procedure is a work-around for the equivalence check.
|
||||
Does not verify the equivalence. Use at the user's risk.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Map_NodeSetChoice( Map_Man_t * pMan, Map_Node_t * pNodeOld, Map_Node_t * pNodeNew )
|
||||
{
|
||||
pNodeNew->pNextE = pNodeOld->pNextE;
|
||||
pNodeOld->pNextE = pNodeNew;
|
||||
pNodeNew->pRepr = pNodeOld;
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,273 +0,0 @@
|
||||
/**CFile****************************************************************
|
||||
|
||||
FileName [mapperCutUtils.c]
|
||||
|
||||
PackageName [MVSIS 1.3: Multi-valued logic synthesis system.]
|
||||
|
||||
Synopsis [Generic technology mapping engine.]
|
||||
|
||||
Author [MVSIS Group]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 2.0. Started - June 1, 2004.]
|
||||
|
||||
Revision [$Id: mapperCutUtils.h,v 1.0 2003/09/08 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "mapperInt.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Allocates the cut.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Map_Cut_t * Map_CutAlloc( Map_Man_t * p )
|
||||
{
|
||||
Map_Cut_t * pCut;
|
||||
Map_Match_t * pMatch;
|
||||
pCut = (Map_Cut_t *)Extra_MmFixedEntryFetch( p->mmCuts );
|
||||
memset( pCut, 0, sizeof(Map_Cut_t) );
|
||||
|
||||
pMatch = pCut->M;
|
||||
pMatch->AreaFlow = MAP_FLOAT_LARGE; // unassigned
|
||||
pMatch->tArrive.Rise = MAP_FLOAT_LARGE; // unassigned
|
||||
pMatch->tArrive.Fall = MAP_FLOAT_LARGE; // unassigned
|
||||
pMatch->tArrive.Worst = MAP_FLOAT_LARGE; // unassigned
|
||||
|
||||
pMatch = pCut->M + 1;
|
||||
pMatch->AreaFlow = MAP_FLOAT_LARGE; // unassigned
|
||||
pMatch->tArrive.Rise = MAP_FLOAT_LARGE; // unassigned
|
||||
pMatch->tArrive.Fall = MAP_FLOAT_LARGE; // unassigned
|
||||
pMatch->tArrive.Worst = MAP_FLOAT_LARGE; // unassigned
|
||||
return pCut;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Deallocates the cut.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Map_CutFree( Map_Man_t * p, Map_Cut_t * pCut )
|
||||
{
|
||||
if ( pCut )
|
||||
Extra_MmFixedEntryRecycle( p->mmCuts, (char *)pCut );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Map_CutPrint( Map_Man_t * p, Map_Node_t * pRoot, Map_Cut_t * pCut, int fPhase )
|
||||
{
|
||||
int i;
|
||||
printf( "CUT: Delay = (%4.2f, %4.2f). Area = %4.2f. Nodes = %d -> {",
|
||||
pCut->M[fPhase].tArrive.Rise, pCut->M[fPhase].tArrive.Fall, pCut->M[fPhase].AreaFlow, pRoot->Num );
|
||||
for ( i = 0; i < pCut->nLeaves; i++ )
|
||||
printf( " %d", pCut->ppLeaves[i]->Num );
|
||||
printf( " } \n" );
|
||||
}
|
||||
|
||||
|
||||
/**function*************************************************************
|
||||
|
||||
synopsis [Computes the exact area associated with the cut.]
|
||||
|
||||
description []
|
||||
|
||||
sideeffects []
|
||||
|
||||
seealso []
|
||||
|
||||
***********************************************************************/
|
||||
float Map_CutGetRootArea( Map_Cut_t * pCut, int fPhase )
|
||||
{
|
||||
assert( pCut->M[fPhase].pSuperBest );
|
||||
return pCut->M[fPhase].pSuperBest->Area;
|
||||
}
|
||||
|
||||
/**function*************************************************************
|
||||
|
||||
synopsis [Computes the exact area associated with the cut.]
|
||||
|
||||
description []
|
||||
|
||||
sideeffects []
|
||||
|
||||
seealso []
|
||||
|
||||
***********************************************************************/
|
||||
int Map_CutGetLeafPhase( Map_Cut_t * pCut, int fPhase, int iLeaf )
|
||||
{
|
||||
assert( pCut->M[fPhase].pSuperBest );
|
||||
return (( pCut->M[fPhase].uPhaseBest & (1<<iLeaf) ) == 0);
|
||||
}
|
||||
|
||||
/**function*************************************************************
|
||||
|
||||
synopsis [Computes the exact area associated with the cut.]
|
||||
|
||||
description []
|
||||
|
||||
sideeffects []
|
||||
|
||||
seealso []
|
||||
|
||||
***********************************************************************/
|
||||
int Map_NodeGetLeafPhase( Map_Node_t * pNode, int fPhase, int iLeaf )
|
||||
{
|
||||
assert( pNode->pCutBest[fPhase]->M[fPhase].pSuperBest );
|
||||
return (( pNode->pCutBest[fPhase]->M[fPhase].uPhaseBest & (1<<iLeaf) ) == 0);
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Map_Cut_t * Map_CutListAppend( Map_Cut_t * pSetAll, Map_Cut_t * pSets )
|
||||
{
|
||||
Map_Cut_t * pPrev, * pTemp;
|
||||
if ( pSetAll == NULL )
|
||||
return pSets;
|
||||
if ( pSets == NULL )
|
||||
return pSetAll;
|
||||
// find the last one
|
||||
for ( pTemp = pSets; pTemp; pTemp = pTemp->pNext )
|
||||
pPrev = pTemp;
|
||||
// append all the end of the current set
|
||||
assert( pPrev->pNext == NULL );
|
||||
pPrev->pNext = pSetAll;
|
||||
return pSets;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Map_CutListRecycle( Map_Man_t * p, Map_Cut_t * pSetList, Map_Cut_t * pSave )
|
||||
{
|
||||
Map_Cut_t * pNext, * pTemp;
|
||||
for ( pTemp = pSetList, pNext = pTemp? pTemp->pNext : NULL;
|
||||
pTemp;
|
||||
pTemp = pNext, pNext = pNext? pNext->pNext : NULL )
|
||||
if ( pTemp != pSave )
|
||||
Extra_MmFixedEntryRecycle( p->mmCuts, (char *)pTemp );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Map_CutListCount( Map_Cut_t * pSets )
|
||||
{
|
||||
Map_Cut_t * pTemp;
|
||||
int i;
|
||||
for ( i = 0, pTemp = pSets; pTemp; pTemp = pTemp->pNext, i++ );
|
||||
return i;
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
/**function*************************************************************
|
||||
|
||||
synopsis [Removes the fanouts of the cut.]
|
||||
|
||||
description []
|
||||
|
||||
sideeffects []
|
||||
|
||||
seealso []
|
||||
|
||||
***********************************************************************/
|
||||
void Map_CutRemoveFanouts( Map_Node_t * pNode, Map_Cut_t * pCut, int fPhase )
|
||||
{
|
||||
Map_NodeVec_t * vFanouts;
|
||||
int i, k;
|
||||
for ( i = 0; i < pCut->nLeaves; i++ )
|
||||
{
|
||||
vFanouts = pCut->ppLeaves[i]->vFanouts;
|
||||
for ( k = 0; k < vFanouts->nSize; k++ )
|
||||
if ( vFanouts->pArray[k] == pNode )
|
||||
break;
|
||||
assert( k != vFanouts->nSize );
|
||||
for ( k++; k < vFanouts->nSize; k++ )
|
||||
vFanouts->pArray[k-1] = vFanouts->pArray[k];
|
||||
vFanouts->nSize--;
|
||||
}
|
||||
}
|
||||
|
||||
/**function*************************************************************
|
||||
|
||||
synopsis [Removes the fanouts of the cut.]
|
||||
|
||||
description []
|
||||
|
||||
sideeffects []
|
||||
|
||||
seealso []
|
||||
|
||||
***********************************************************************/
|
||||
void Map_CutInsertFanouts( Map_Node_t * pNode, Map_Cut_t * pCut, int fPhase )
|
||||
{
|
||||
int i;
|
||||
for ( i = 0; i < pCut->nLeaves; i++ )
|
||||
Map_NodeVecPush( pCut->ppLeaves[i]->vFanouts, pNode );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
@@ -1,141 +0,0 @@
|
||||
/**CFile****************************************************************
|
||||
|
||||
FileName [mapperFanout.c]
|
||||
|
||||
PackageName [FRAIG: Functionally reduced AND-INV graphs.]
|
||||
|
||||
Synopsis [Procedures to manipulate fanouts of the FRAIG nodes.]
|
||||
|
||||
Author [Alan Mishchenko <[email protected]>]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 2.0. Started - June 1, 2004.]
|
||||
|
||||
Revision [$Id: mapperFanout.c,v 1.5 2005/01/23 06:59:43 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "mapperInt.h"
|
||||
|
||||
#ifdef MAP_ALLOCATE_FANOUT
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Add the fanout to the node.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Map_NodeAddFaninFanout( Map_Node_t * pFanin, Map_Node_t * pFanout )
|
||||
{
|
||||
Map_Node_t * pPivot;
|
||||
|
||||
// pFanins is a fanin of pFanout
|
||||
assert( !Map_IsComplement(pFanin) );
|
||||
assert( !Map_IsComplement(pFanout) );
|
||||
assert( Map_Regular(pFanout->p1) == pFanin || Map_Regular(pFanout->p2) == pFanin );
|
||||
|
||||
pPivot = pFanin->pFanPivot;
|
||||
if ( pPivot == NULL )
|
||||
{
|
||||
pFanin->pFanPivot = pFanout;
|
||||
return;
|
||||
}
|
||||
|
||||
if ( Map_Regular(pPivot->p1) == pFanin )
|
||||
{
|
||||
if ( Map_Regular(pFanout->p1) == pFanin )
|
||||
{
|
||||
pFanout->pFanFanin1 = pPivot->pFanFanin1;
|
||||
pPivot->pFanFanin1 = pFanout;
|
||||
}
|
||||
else // if ( Map_Regular(pFanout->p2) == pFanin )
|
||||
{
|
||||
pFanout->pFanFanin2 = pPivot->pFanFanin1;
|
||||
pPivot->pFanFanin1 = pFanout;
|
||||
}
|
||||
}
|
||||
else // if ( Map_Regular(pPivot->p2) == pFanin )
|
||||
{
|
||||
assert( Map_Regular(pPivot->p2) == pFanin );
|
||||
if ( Map_Regular(pFanout->p1) == pFanin )
|
||||
{
|
||||
pFanout->pFanFanin1 = pPivot->pFanFanin2;
|
||||
pPivot->pFanFanin2 = pFanout;
|
||||
}
|
||||
else // if ( Map_Regular(pFanout->p2) == pFanin )
|
||||
{
|
||||
pFanout->pFanFanin2 = pPivot->pFanFanin2;
|
||||
pPivot->pFanFanin2 = pFanout;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Add the fanout to the node.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Map_NodeRemoveFaninFanout( Map_Node_t * pFanin, Map_Node_t * pFanoutToRemove )
|
||||
{
|
||||
Map_Node_t * pFanout, * pFanout2, ** ppFanList;
|
||||
// start the linked list of fanouts
|
||||
ppFanList = &pFanin->pFanPivot;
|
||||
// go through the fanouts
|
||||
Map_NodeForEachFanoutSafe( pFanin, pFanout, pFanout2 )
|
||||
{
|
||||
// skip the fanout-to-remove
|
||||
if ( pFanout == pFanoutToRemove )
|
||||
continue;
|
||||
// add useful fanouts to the list
|
||||
*ppFanList = pFanout;
|
||||
ppFanList = Map_NodeReadNextFanoutPlace( pFanin, pFanout );
|
||||
}
|
||||
*ppFanList = NULL;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns the number of fanouts of a node.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Map_NodeGetFanoutNum( Map_Node_t * pNode )
|
||||
{
|
||||
Map_Node_t * pFanout;
|
||||
int Counter = 0;
|
||||
Map_NodeForEachFanout( pNode, pFanout )
|
||||
Counter++;
|
||||
return Counter;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
/**CFile****************************************************************
|
||||
|
||||
FileName [mapper__.c]
|
||||
|
||||
PackageName [MVSIS 1.3: Multi-valued logic synthesis system.]
|
||||
|
||||
Synopsis [Generic technology mapping engine.]
|
||||
|
||||
Author [MVSIS Group]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - September 8, 2003.]
|
||||
|
||||
Revision [$Id: mapper__.h,v 1.0 2003/09/08 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "mapperInt.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
@@ -1,477 +0,0 @@
|
||||
/**CFile****************************************************************
|
||||
|
||||
FileName [mapperInt.h]
|
||||
|
||||
PackageName [MVSIS 2.0: Multi-valued logic synthesis system.]
|
||||
|
||||
Synopsis [Generic technology mapping engine.]
|
||||
|
||||
Author [MVSIS Group]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 2.0. Started - June 1, 2004.]
|
||||
|
||||
Revision [$Id: mapperInt.h,v 1.8 2004/09/30 21:18:10 satrajit Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef __MAPPER_INT_H__
|
||||
#define __MAPPER_INT_H__
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// INCLUDES ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//#include "leaks.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <float.h>
|
||||
#include "cuddInt.h"
|
||||
#include "main.h"
|
||||
#include "mio.h"
|
||||
#include "mapper.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// PARAMETERS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// uncomment to have fanouts represented in the mapping graph
|
||||
//#define MAP_ALLOCATE_FANOUT 1
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// MACRO DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// the bit masks
|
||||
#define MAP_MASK(n) ((~((unsigned)0)) >> (32-(n)))
|
||||
#define MAP_FULL (~((unsigned)0))
|
||||
#define MAP_NO_VAR (-9999.0)
|
||||
|
||||
// maximum/minimum operators
|
||||
#define MAP_MIN(a,b) (((a) < (b))? (a) : (b))
|
||||
#define MAP_MAX(a,b) (((a) > (b))? (a) : (b))
|
||||
|
||||
// the small and large numbers (min/max float are 1.17e-38/3.40e+38)
|
||||
#define MAP_FLOAT_LARGE ((float)(FLT_MAX/10))
|
||||
#define MAP_FLOAT_SMALL ((float)1.0e-03)
|
||||
|
||||
// generating random unsigned (#define RAND_MAX 0x7fff)
|
||||
#define MAP_RANDOM_UNSIGNED ((((unsigned)rand()) << 24) ^ (((unsigned)rand()) << 12) ^ ((unsigned)rand()))
|
||||
|
||||
// internal macros to work with cuts
|
||||
#define Map_CutIsComplement(p) (((int)((unsigned long) (p) & 01)))
|
||||
#define Map_CutRegular(p) ((Map_Cut_t *)((unsigned long)(p) & ~01))
|
||||
#define Map_CutNot(p) ((Map_Cut_t *)((unsigned long)(p) ^ 01))
|
||||
#define Map_CutNotCond(p,c) ((Map_Cut_t *)((unsigned long)(p) ^ (c)))
|
||||
|
||||
// internal macros for referencing of nodes
|
||||
#define Map_NodeReadRef(p) ((Map_Regular(p))->nRefs)
|
||||
#define Map_NodeRef(p) ((Map_Regular(p))->nRefs++)
|
||||
|
||||
// macros to get hold of the bits in the support info
|
||||
#define Map_InfoSetVar(p,i) (p[(i)>>5] |= (1<<((i) & 31)))
|
||||
#define Map_InfoRemVar(p,i) (p[(i)>>5] &= ~(1<<((i) & 31)))
|
||||
#define Map_InfoFlipVar(p,i) (p[(i)>>5] ^= (1<<((i) & 31)))
|
||||
#define Map_InfoReadVar(p,i) ((p[(i)>>5] & (1<<((i) & 31))) > 0)
|
||||
|
||||
// returns the complemented attribute of the node
|
||||
#define Map_NodeIsSimComplement(p) (Map_IsComplement(p)? !(Map_Regular(p)->fInv) : (p)->fInv)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// STRUCTURE DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// the mapping manager
|
||||
struct Map_ManStruct_t_
|
||||
{
|
||||
// the mapping graph
|
||||
Map_Node_t ** pBins; // the table of nodes hashed by their children
|
||||
int nBins; // the size of the table
|
||||
Map_Node_t ** pInputs; // the array of inputs
|
||||
int nInputs; // the number of inputs
|
||||
Map_Node_t ** pOutputs; // the array of outputs
|
||||
int nOutputs; // the number of outputs
|
||||
int nNodes; // the total number of nodes
|
||||
Map_Node_t * pConst1; // the constant 1 node
|
||||
Map_NodeVec_t * vAnds; // the array of nodes in the DFS order
|
||||
Map_NodeVec_t * vNodesAll; // the array of all nodes
|
||||
Map_NodeVec_t * vNodesTemp; // the array of all nodes
|
||||
Map_NodeVec_t * vMapping; // the array of internal nodes used in the mapping
|
||||
|
||||
// info about the original circuit
|
||||
char ** ppOutputNames; // the primary output names
|
||||
Map_Time_t * pInputArrivals;// the PI arrival times
|
||||
|
||||
// mapping parameters
|
||||
int nVarsMax; // the max number of variables
|
||||
int fAreaRecovery; // the flag to enable area recovery
|
||||
int fVerbose; // the verbosiness flag
|
||||
int fMappingMode; // set to 1 when doing area
|
||||
float fRequiredGlo; // the global required times
|
||||
float fEpsilon; // the epsilon used to compare floats
|
||||
float AreaBase; // the area after delay-oriented mapping
|
||||
float AreaFinal; // the area after delay-oriented mapping
|
||||
int nIterations; // How many matching passes to do
|
||||
bool fObeyFanoutLimits;// Should mapper try to obey fanout limits or not
|
||||
float DelayTarget; // the required times set by the user
|
||||
int nTravIds; // the traversal counter
|
||||
bool fSwitching; // Should mapper try to obey fanout limits or not
|
||||
|
||||
// the supergate library
|
||||
Map_SuperLib_t * pSuperLib; // the current supergate library
|
||||
unsigned uTruths[6][2]; // the elementary truth tables
|
||||
unsigned uTruthsLarge[10][32]; // the elementary truth tables
|
||||
int nCounts[32]; // the counter of minterms
|
||||
int nCountsBest[32];// the counter of minterms
|
||||
Map_NodeVec_t * vVisited; // the visited cuts during cut computation
|
||||
|
||||
// the memory managers
|
||||
Extra_MmFixed_t * mmNodes; // the memory manager for nodes
|
||||
Extra_MmFixed_t * mmCuts; // the memory manager for cuts
|
||||
|
||||
// precomputed N-canonical forms
|
||||
unsigned short * uCanons; // N-canonical forms
|
||||
char ** uPhases; // N-canonical phases
|
||||
char * pCounters; // counters of phases
|
||||
|
||||
// various statistical variables
|
||||
int nChoiceNodes; // the number of choice nodes
|
||||
int nChoices; // the number of all choices
|
||||
int nCanons; // the number of times N-canonical form was computed
|
||||
int nMatches; // the number of times supergate matching was performed
|
||||
int nPhases; // the number of phases considered during matching
|
||||
int nFanoutViolations; // the number of nodes in mapped circuit violating fanout
|
||||
|
||||
// runtime statistics
|
||||
int timeToMap; // time to transfer to the mapping structure
|
||||
int timeCuts; // time to compute k-feasible cuts
|
||||
int timeTruth; // time to compute the truth table for each cut
|
||||
int timeMatch; // time to perform matching for each node
|
||||
int timeArea; // time to recover area after delay oriented mapping
|
||||
int timeSweep; // time to perform technology dependent sweep
|
||||
int timeToNet; // time to transfer back to the network
|
||||
int timeTotal; // the total mapping time
|
||||
int time1; // time to transfer to the mapping structure
|
||||
int time2; // time to transfer to the mapping structure
|
||||
int time3; // time to transfer to the mapping structure
|
||||
};
|
||||
|
||||
// the supergate library
|
||||
struct Map_SuperLibStruct_t_
|
||||
{
|
||||
// general info
|
||||
char * pName; // the name of the supergate library
|
||||
Mio_Library_t * pGenlib; // the generic library
|
||||
|
||||
// other info
|
||||
int nVarsMax; // the max number of variables
|
||||
int nSupersAll; // the total number of supergates
|
||||
int nSupersReal; // the total number of supergates
|
||||
int nLines; // the total number of lines in the supergate file
|
||||
bool fVerbose; // the verbosity flag
|
||||
|
||||
// hash tables
|
||||
Map_Super_t ** ppSupers; // the array of supergates
|
||||
Map_HashTable_t * tTableC; // the table mapping N-canonical forms into supergates
|
||||
Map_HashTable_t * tTable; // the table mapping truth tables into supergates
|
||||
|
||||
// data structures for N-canonical form computation
|
||||
unsigned uTruths[6][2]; // the elementary truth tables
|
||||
unsigned uMask[2]; // the mask for the truth table
|
||||
|
||||
// the invertor
|
||||
Mio_Gate_t * pGateInv; // the pointer to the intertor gate
|
||||
Map_Time_t tDelayInv; // the delay of the inverter
|
||||
float AreaInv; // the area of the inverter
|
||||
float AreaBuf; // the area of the buffer
|
||||
Map_Super_t * pSuperInv; // the supergate representing the inverter
|
||||
|
||||
// the memory manager for the internal table
|
||||
Extra_MmFixed_t * mmSupers; // the mamory manager for supergates
|
||||
Extra_MmFixed_t * mmEntries; // the memory manager for the entries
|
||||
Extra_MmFlex_t * mmForms; // the memory manager for formulas
|
||||
};
|
||||
|
||||
// the mapping node
|
||||
struct Map_NodeStruct_t_
|
||||
{
|
||||
// general information about the node
|
||||
Map_Man_t * p; // the mapping manager
|
||||
Map_Node_t * pNext; // the next node in the hash table
|
||||
int Num; // the unique number of this node
|
||||
int TravId; // the traversal ID (use to avoid cleaning marks)
|
||||
int nRefs; // the number of references (fanouts) of the given node
|
||||
unsigned fMark0 : 1; // the mark used for traversals
|
||||
unsigned fMark1 : 1; // the mark used for traversals
|
||||
unsigned fUsed : 1; // the mark to mark the node or its fanins
|
||||
unsigned fInv : 1; // the complemented attribute for the equivalent nodes
|
||||
unsigned fInvert: 1; // the flag to denote the use of interter
|
||||
unsigned Level :16; // the level of the given node
|
||||
unsigned NumTemp:10; // the level of the given node
|
||||
int nRefAct[3]; // estimated fanout for current covering phase, neg and pos and sum
|
||||
float nRefEst[3]; // actual fanout for previous covering phase, neg and pos and sum
|
||||
float Switching; // the probability of switching
|
||||
|
||||
// connectivity
|
||||
Map_Node_t * p1; // the first child
|
||||
Map_Node_t * p2; // the second child
|
||||
Map_Node_t * pNextE; // the next functionally equivalent node
|
||||
Map_Node_t * pRepr; // the representative of the functionally equivalent class
|
||||
|
||||
#ifdef MAP_ALLOCATE_FANOUT
|
||||
// representation of node's fanouts
|
||||
Map_Node_t * pFanPivot; // the first fanout of this node
|
||||
Map_Node_t * pFanFanin1; // the next fanout of p1
|
||||
Map_Node_t * pFanFanin2; // the next fanout of p2
|
||||
// Map_NodeVec_t * vFanouts; // the array of fanouts of the gate
|
||||
#endif
|
||||
|
||||
// the delay information
|
||||
Map_Time_t tArrival[2]; // the best arrival time of the neg (0) and pos (1) phases
|
||||
Map_Time_t tRequired[2]; // the required time of the neg (0) and pos (1) phases
|
||||
|
||||
// misc information
|
||||
Map_Cut_t * pCutBest[2]; // the best mapping for neg and pos phase
|
||||
Map_Cut_t * pCuts; // mapping choices for the node (elementary comes first)
|
||||
char * pData0; // temporary storage for the corresponding network node
|
||||
char * pData1; // temporary storage for the corresponding network node
|
||||
};
|
||||
|
||||
// the match of the cut
|
||||
struct Map_MatchStruct_t_
|
||||
{
|
||||
// information used for matching
|
||||
Map_Super_t * pSupers;
|
||||
unsigned uPhase;
|
||||
// information about the best selected match
|
||||
unsigned uPhaseBest; // the best phase (the EXOR of match's phase and gate's phase)
|
||||
Map_Super_t * pSuperBest; // the best supergate matched
|
||||
// the parameters of the match
|
||||
Map_Time_t tArrive; // the arrival time of this match
|
||||
float AreaFlow; // the area flow or area of this match
|
||||
};
|
||||
|
||||
// the cuts used for matching
|
||||
struct Map_CutStruct_t_
|
||||
{
|
||||
Map_Cut_t * pNext; // the pointer to the next cut in the list
|
||||
Map_Cut_t * pOne; // the father of this cut
|
||||
Map_Cut_t * pTwo; // the mother of this cut
|
||||
Map_Node_t * ppLeaves[6]; // the leaves of this cut
|
||||
unsigned uTruth; // truth table for five-input cuts
|
||||
char nLeaves; // the number of leaves
|
||||
char nVolume; // the volume of this cut
|
||||
char fMark; // the mark to denote visited cut
|
||||
char Phase; // the mark to denote complemented cut
|
||||
Map_Match_t M[2]; // the matches for positive/negative phase
|
||||
};
|
||||
|
||||
// the supergate internally represented
|
||||
struct Map_SuperStruct_t_
|
||||
{
|
||||
int Num; // the ID of the supergate
|
||||
unsigned fSuper : 1; // the flag to distinquish a real super from a fake one
|
||||
unsigned fExclude: 1; // the flag if set causes gate to be excluded from being used for mapping
|
||||
unsigned nFanins : 3; // the number of inputs
|
||||
unsigned nGates : 3; // the number of gates inside this supergate
|
||||
unsigned nFanLimit: 4; // the max number of fanout count
|
||||
unsigned nSupers : 16; // the number of supergates in the list
|
||||
unsigned nPhases : 4; // the number of phases for matching with canonical form
|
||||
unsigned char uPhases[4]; // the maximum of 4 phases for matching with canonical form
|
||||
int nUsed; // the number of times the supergate is used
|
||||
Map_Super_t * pFanins[6]; // the fanins of the gate
|
||||
Mio_Gate_t * pRoot; // the root gate
|
||||
unsigned uTruth[2]; // the truth table
|
||||
Map_Time_t tDelaysR[6]; // the pin-to-pin delay constraints for the rise of the output
|
||||
Map_Time_t tDelaysF[6]; // the pin-to-pin delay constraints for the rise of the output
|
||||
Map_Time_t tDelayMax; // the maximum delay
|
||||
float Area; // the area
|
||||
char * pFormula; // the symbolic formula
|
||||
Map_Super_t * pNext; // the pointer to the next super in the list
|
||||
};
|
||||
|
||||
// the vector of nodes
|
||||
struct Map_NodeVecStruct_t_
|
||||
{
|
||||
Map_Node_t ** pArray; // the array of nodes
|
||||
int nSize; // the number of entries in the array
|
||||
int nCap; // the number of allocated entries
|
||||
};
|
||||
|
||||
// the hash table
|
||||
struct Map_HashTableStruct_t_
|
||||
{
|
||||
Map_HashEntry_t ** pBins; // the table bins
|
||||
int nBins; // the size of the table
|
||||
int nEntries; // the total number of entries in the table
|
||||
Extra_MmFixed_t * mmMan; // the memory manager for entries
|
||||
};
|
||||
|
||||
// the entry in the hash table
|
||||
struct Map_HashEntryStruct_t_
|
||||
{
|
||||
unsigned uTruth[2]; // the truth table for 6-var function
|
||||
unsigned uPhase; // the phase to tranform it into the canonical form
|
||||
Map_Super_t * pGates; // the linked list of matching supergates
|
||||
Map_HashEntry_t * pNext; // the next entry in the hash table
|
||||
};
|
||||
|
||||
// getting hold of the next fanout of the node
|
||||
#define Map_NodeReadNextFanout( pNode, pFanout ) \
|
||||
( ( pFanout == NULL )? NULL : \
|
||||
((Map_Regular((pFanout)->p1) == (pNode))? \
|
||||
(pFanout)->pFanFanin1 : (pFanout)->pFanFanin2) )
|
||||
|
||||
// getting hold of the place where the next fanout will be attached
|
||||
#define Map_NodeReadNextFanoutPlace( pNode, pFanout ) \
|
||||
( (Map_Regular((pFanout)->p1) == (pNode))? \
|
||||
&(pFanout)->pFanFanin1 : &(pFanout)->pFanFanin2 )
|
||||
|
||||
// iterator through the fanouts of the node
|
||||
#define Map_NodeForEachFanout( pNode, pFanout ) \
|
||||
for ( pFanout = (pNode)->pFanPivot; pFanout; \
|
||||
pFanout = Map_NodeReadNextFanout(pNode, pFanout) )
|
||||
|
||||
// safe iterator through the fanouts of the node
|
||||
#define Map_NodeForEachFanoutSafe( pNode, pFanout, pFanout2 ) \
|
||||
for ( pFanout = (pNode)->pFanPivot, \
|
||||
pFanout2 = Map_NodeReadNextFanout(pNode, pFanout); \
|
||||
pFanout; \
|
||||
pFanout = pFanout2, \
|
||||
pFanout2 = Map_NodeReadNextFanout(pNode, pFanout) )
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// GLOBAL VARIABLES ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/*=== mapperCanon.c =============================================================*/
|
||||
/*=== mapperCut.c ===============================================================*/
|
||||
extern void Map_MappingCuts( Map_Man_t * p );
|
||||
extern int Map_MappingCountAllCuts( Map_Man_t * p );
|
||||
/*=== mapperCutDcs.c ===============================================================*/
|
||||
extern void Map_ComputeDcs( Map_Man_t * p );
|
||||
extern unsigned Map_ComputeIsop_rec( Map_Man_t * p, unsigned uF, unsigned uFD, int iVar, int nVars, int fDir );
|
||||
/*=== mapperCutUtils.c ===============================================================*/
|
||||
extern Map_Cut_t * Map_CutAlloc( Map_Man_t * p );
|
||||
extern void Map_CutFree( Map_Man_t * p, Map_Cut_t * pCut );
|
||||
extern void Map_CutPrint( Map_Man_t * p, Map_Node_t * pRoot, Map_Cut_t * pCut, int fPhase );
|
||||
extern float Map_CutGetRootArea( Map_Cut_t * pCut, int fPhase );
|
||||
extern int Map_CutGetLeafPhase( Map_Cut_t * pCut, int fPhase, int iLeaf );
|
||||
extern int Map_NodeGetLeafPhase( Map_Node_t * pNode, int fPhase, int iLeaf );
|
||||
extern Map_Cut_t * Map_CutListAppend( Map_Cut_t * pSetAll, Map_Cut_t * pSets );
|
||||
extern void Map_CutListRecycle( Map_Man_t * p, Map_Cut_t * pSetList, Map_Cut_t * pSave );
|
||||
extern int Map_CutListCount( Map_Cut_t * pSets );
|
||||
extern void Map_CutRemoveFanouts( Map_Node_t * pNode, Map_Cut_t * pCut, int fPhase );
|
||||
extern void Map_CutInsertFanouts( Map_Node_t * pNode, Map_Cut_t * pCut, int fPhase );
|
||||
/*=== mapperFanout.c =============================================================*/
|
||||
extern void Map_NodeAddFaninFanout( Map_Node_t * pFanin, Map_Node_t * pFanout );
|
||||
extern void Map_NodeRemoveFaninFanout( Map_Node_t * pFanin, Map_Node_t * pFanoutToRemove );
|
||||
extern int Map_NodeGetFanoutNum( Map_Node_t * pNode );
|
||||
/*=== mapperLib.c ============================================================*/
|
||||
extern Map_SuperLib_t * Map_SuperLibCreate( char * pFileName, char * pExcludeFile, bool fAlgorithm, bool fVerbose );
|
||||
extern void Map_SuperLibFree( Map_SuperLib_t * p );
|
||||
/*=== mapperMatch.c ===============================================================*/
|
||||
extern int Map_MappingMatches( Map_Man_t * p );
|
||||
extern float Map_MappingCombinePhases( Map_Man_t * p );
|
||||
extern void Map_MatchClean( Map_Match_t * pMatch );
|
||||
extern int Map_MatchCompare( Map_Man_t * pMan, Map_Match_t * pM1, Map_Match_t * pM2, int fDoingArea );
|
||||
/*=== mapperPower.c =============================================================*/
|
||||
extern float Map_SwitchCutGetDerefed( Map_Node_t * pNode, Map_Cut_t * pCut, int fPhase );
|
||||
extern float Map_SwitchCutRef( Map_Node_t * pNode, Map_Cut_t * pCut, int fPhase );
|
||||
extern float Map_SwitchCutDeref( Map_Node_t * pNode, Map_Cut_t * pCut, int fPhase );
|
||||
extern float Map_MappingGetSwitching( Map_Man_t * pMan, Map_NodeVec_t * vMapping );
|
||||
/*=== mapperRefs.c =============================================================*/
|
||||
extern int Map_NodeReadRefPhaseAct( Map_Node_t * pNode, int fPhase );
|
||||
extern float Map_NodeReadRefPhaseEst( Map_Node_t * pNode, int fPhase );
|
||||
extern void Map_MappingEstimateRefsInit( Map_Man_t * p );
|
||||
extern void Map_MappingEstimateRefs( Map_Man_t * p );
|
||||
extern float Map_CutGetAreaFlow( Map_Cut_t * pCut, int fPhase );
|
||||
extern float Map_CutGetAreaRefed( Map_Cut_t * pCut, int fPhase );
|
||||
extern float Map_CutGetAreaDerefed( Map_Cut_t * pCut, int fPhase );
|
||||
extern float Map_CutRef( Map_Cut_t * pCut, int fPhase );
|
||||
extern float Map_CutDeref( Map_Cut_t * pCut, int fPhase );
|
||||
extern void Map_MappingSetRefs( Map_Man_t * pMan );
|
||||
extern float Map_MappingGetArea( Map_Man_t * pMan, Map_NodeVec_t * vMapping );
|
||||
/*=== mapperShow.c =============================================================*/
|
||||
extern void Map_MappingShow( Map_Man_t * pMan, char * pFileName );
|
||||
/*=== mapperTree.c ===============================================================*/
|
||||
extern int Map_LibraryReadTree( Map_SuperLib_t * pLib, char * pFileName, char * pExcludeFile );
|
||||
extern void Map_LibraryPrintTree( Map_SuperLib_t * pLib );
|
||||
/*=== mapperSuper.c ===============================================================*/
|
||||
extern int Map_LibraryRead( Map_SuperLib_t * p, char * pFileName );
|
||||
extern void Map_LibraryPrintSupergate( Map_Super_t * pGate );
|
||||
/*=== mapperTable.c ============================================================*/
|
||||
extern Map_HashTable_t * Map_SuperTableCreate( Map_SuperLib_t * pLib );
|
||||
extern void Map_SuperTableFree( Map_HashTable_t * p );
|
||||
extern int Map_SuperTableInsertC( Map_HashTable_t * pLib, unsigned uTruthC[], Map_Super_t * pGate );
|
||||
extern int Map_SuperTableInsert( Map_HashTable_t * pLib, unsigned uTruth[], Map_Super_t * pGate, unsigned uPhase );
|
||||
extern Map_Super_t * Map_SuperTableLookup( Map_HashTable_t * p, unsigned uTruth[], unsigned * puPhase );
|
||||
extern void Map_SuperTableSortSupergates( Map_HashTable_t * p, int nSupersMax );
|
||||
extern void Map_SuperTableSortSupergatesByDelay( Map_HashTable_t * p, int nSupersMax );
|
||||
/*=== mapperTime.c =============================================================*/
|
||||
extern float Map_TimeCutComputeArrival( Map_Node_t * pNode, Map_Cut_t * pCut, int fPhase, float tWorstCaseLimit );
|
||||
extern void Map_TimeCutComputeArrival_rec( Map_Cut_t * pCut, int fPhase );
|
||||
extern float Map_TimeComputeArrivalMax( Map_Man_t * p );
|
||||
extern void Map_TimeComputeRequiredGlobal( Map_Man_t * p );
|
||||
extern void Map_TimeComputeRequired( Map_Man_t * p, float fRequired );
|
||||
extern float Map_TimeNodeFanoutDelay( Map_Node_t * pNode, int fPhase );
|
||||
extern float Map_TimeCutFanoutDelay( Map_Node_t * pNode, Map_Cut_t * pCut, int fPhase );
|
||||
extern float Map_TimeMatchWithInverter( Map_Man_t * p, Map_Match_t * pMatch );
|
||||
/*=== mapperTruth.c ===============================================================*/
|
||||
extern void Map_MappingTruths( Map_Man_t * pMan );
|
||||
extern int Map_TruthsCutDontCare( Map_Man_t * pMan, Map_Cut_t * pCut, unsigned * uTruthDc );
|
||||
extern int Map_TruthCountOnes( unsigned * uTruth, int nLeaves );
|
||||
extern int Map_TruthDetectTwoFirst( unsigned * uTruth, int nLeaves );
|
||||
/*=== mapperUtils.c ===============================================================*/
|
||||
extern Map_NodeVec_t * Map_MappingDfs( Map_Man_t * pMan, int fCollectEquiv );
|
||||
extern Map_NodeVec_t * Map_MappingDfsNodes( Map_Man_t * pMan, Map_Node_t ** ppNodes, int nNodes, int fEquiv );
|
||||
|
||||
extern void Map_MappingDfsMarked1_rec( Map_Node_t * pNode, Map_NodeVec_t * vNodes, int fFirst );
|
||||
extern void Map_MappingDfsMarked2_rec( Map_Node_t * pNode, Map_NodeVec_t * vNodes, Map_NodeVec_t * vBoundary, int fFirst );
|
||||
|
||||
extern int Map_MappingCountLevels( Map_Man_t * pMan );
|
||||
extern void Map_MappingUnmark( Map_Man_t * pMan );
|
||||
extern void Map_MappingMark_rec( Map_Node_t * pNode );
|
||||
extern void Map_MappingUnmark_rec( Map_Node_t * pNode );
|
||||
extern void Map_MappingPrintOutputArrivals( Map_Man_t * p );
|
||||
extern void Map_MappingSetupMask( unsigned uMask[], int nVarsMax );
|
||||
extern int Map_MappingNodeIsViolator( Map_Node_t * pNode, Map_Cut_t * pCut, int fPosPol );
|
||||
extern float Map_MappingGetAreaFlow( Map_Man_t * p );
|
||||
extern void Map_MappingSortByLevel( Map_Man_t * pMan, Map_NodeVec_t * vNodes );
|
||||
extern int Map_MappingCountDoubles( Map_Man_t * pMan, Map_NodeVec_t * vNodes );
|
||||
extern void Map_MappingExpandTruth( unsigned uTruth[2], int nVars );
|
||||
extern float Map_MappingPrintSwitching( Map_Man_t * pMan );
|
||||
extern void Map_MappingSetPlacementInfo( Map_Man_t * p );
|
||||
extern float Map_MappingPrintWirelength( Map_Man_t * p );
|
||||
extern void Map_MappingWireReport( Map_Man_t * p );
|
||||
extern float Map_MappingComputeDelayWithFanouts( Map_Man_t * p );
|
||||
extern int Map_MappingGetMaxLevel( Map_Man_t * pMan );
|
||||
extern void Map_MappingSetChoiceLevels( Map_Man_t * pMan );
|
||||
extern void Map_MappingReportChoices( Map_Man_t * pMan );
|
||||
/*=== mapperVec.c =============================================================*/
|
||||
extern Map_NodeVec_t * Map_NodeVecAlloc( int nCap );
|
||||
extern void Map_NodeVecFree( Map_NodeVec_t * p );
|
||||
extern Map_Node_t ** Map_NodeVecReadArray( Map_NodeVec_t * p );
|
||||
extern int Map_NodeVecReadSize( Map_NodeVec_t * p );
|
||||
extern void Map_NodeVecGrow( Map_NodeVec_t * p, int nCapMin );
|
||||
extern void Map_NodeVecShrink( Map_NodeVec_t * p, int nSizeNew );
|
||||
extern void Map_NodeVecClear( Map_NodeVec_t * p );
|
||||
extern void Map_NodeVecPush( Map_NodeVec_t * p, Map_Node_t * Entry );
|
||||
extern int Map_NodeVecPushUnique( Map_NodeVec_t * p, Map_Node_t * Entry );
|
||||
extern Map_Node_t * Map_NodeVecPop( Map_NodeVec_t * p );
|
||||
extern void Map_NodeVecRemove( Map_NodeVec_t * p, Map_Node_t * Entry );
|
||||
extern void Map_NodeVecWriteEntry( Map_NodeVec_t * p, int i, Map_Node_t * Entry );
|
||||
extern Map_Node_t * Map_NodeVecReadEntry( Map_NodeVec_t * p, int i );
|
||||
extern void Map_NodeVecSortByLevel( Map_NodeVec_t * p );
|
||||
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
@@ -1,231 +0,0 @@
|
||||
/**CFile****************************************************************
|
||||
|
||||
FileName [mapperLib.c]
|
||||
|
||||
PackageName [MVSIS 1.3: Multi-valued logic synthesis system.]
|
||||
|
||||
Synopsis [Generic technology mapping engine.]
|
||||
|
||||
Author [MVSIS Group]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 2.0. Started - June 1, 2004.]
|
||||
|
||||
Revision [$Id: mapperLib.c,v 1.6 2005/01/23 06:59:44 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "mapperInt.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Reads in the supergate library and prepares it for use.]
|
||||
|
||||
Description [The supergates library comes in a .super file. This file
|
||||
contains descriptions of supergates along with some relevant information.
|
||||
This procedure reads the supergate file, canonicizes the supergates,
|
||||
and constructs an additional lookup table, which can be used to map
|
||||
truth tables of the cuts into the pair (phase, supergate). The phase
|
||||
indicates how the current truth table should be phase assigned to
|
||||
match the canonical form of the supergate. The resulting phase is the
|
||||
bitwise EXOR of the phase needed to canonicize the supergate and the
|
||||
phase needed to transform the truth table into its canonical form.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Map_SuperLib_t * Map_SuperLibCreate( char * pFileName, char * pExcludeFile, bool fAlgorithm, bool fVerbose )
|
||||
{
|
||||
Map_SuperLib_t * p;
|
||||
int clk;
|
||||
|
||||
// start the supergate library
|
||||
p = ALLOC( Map_SuperLib_t, 1 );
|
||||
memset( p, 0, sizeof(Map_SuperLib_t) );
|
||||
p->pName = pFileName;
|
||||
p->fVerbose = fVerbose;
|
||||
p->mmSupers = Extra_MmFixedStart( sizeof(Map_Super_t) );
|
||||
p->mmEntries = Extra_MmFixedStart( sizeof(Map_HashEntry_t) );
|
||||
p->mmForms = Extra_MmFlexStart();
|
||||
Map_MappingSetupTruthTables( p->uTruths );
|
||||
|
||||
// start the hash table
|
||||
p->tTableC = Map_SuperTableCreate( p );
|
||||
p->tTable = Map_SuperTableCreate( p );
|
||||
|
||||
// read the supergate library from file
|
||||
clk = clock();
|
||||
if ( fAlgorithm )
|
||||
{
|
||||
if ( !Map_LibraryReadTree( p, pFileName, pExcludeFile ) )
|
||||
{
|
||||
Map_SuperLibFree( p );
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( pExcludeFile != 0 )
|
||||
{
|
||||
printf ("Error: Exclude file support not present for old format. Stop.\n");
|
||||
return NULL;
|
||||
}
|
||||
if ( !Map_LibraryRead( p, pFileName ) )
|
||||
{
|
||||
Map_SuperLibFree( p );
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
assert( p->nVarsMax > 0 );
|
||||
|
||||
// report the stats
|
||||
if ( fVerbose ) {
|
||||
printf( "Loaded %d unique %d-input supergates from \"%s\". ",
|
||||
p->nSupersReal, p->nVarsMax, pFileName );
|
||||
PRT( "Time", clock() - clk );
|
||||
}
|
||||
|
||||
// assign the interver parameters
|
||||
p->pGateInv = Mio_LibraryReadInv( p->pGenlib );
|
||||
p->tDelayInv.Rise = Mio_LibraryReadDelayInvRise( p->pGenlib );
|
||||
p->tDelayInv.Fall = Mio_LibraryReadDelayInvFall( p->pGenlib );
|
||||
p->tDelayInv.Worst = MAP_MAX( p->tDelayInv.Rise, p->tDelayInv.Fall );
|
||||
p->AreaInv = Mio_LibraryReadAreaInv( p->pGenlib );
|
||||
p->AreaBuf = Mio_LibraryReadAreaBuf( p->pGenlib );
|
||||
|
||||
// assign the interver supergate
|
||||
p->pSuperInv = (Map_Super_t *)Extra_MmFixedEntryFetch( p->mmSupers );
|
||||
memset( p->pSuperInv, 0, sizeof(Map_Super_t) );
|
||||
p->pSuperInv->Num = -1;
|
||||
p->pSuperInv->nGates = 1;
|
||||
p->pSuperInv->nFanins = 1;
|
||||
p->pSuperInv->nFanLimit = 10;
|
||||
p->pSuperInv->pFanins[0] = p->ppSupers[0];
|
||||
p->pSuperInv->pRoot = p->pGateInv;
|
||||
p->pSuperInv->Area = p->AreaInv;
|
||||
p->pSuperInv->tDelayMax = p->tDelayInv;
|
||||
p->pSuperInv->tDelaysR[0].Rise = MAP_NO_VAR;
|
||||
p->pSuperInv->tDelaysR[0].Fall = p->tDelayInv.Rise;
|
||||
p->pSuperInv->tDelaysF[0].Rise = p->tDelayInv.Fall;
|
||||
p->pSuperInv->tDelaysF[0].Fall = MAP_NO_VAR;
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Deallocates the supergate library.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Map_SuperLibFree( Map_SuperLib_t * p )
|
||||
{
|
||||
if ( p == NULL ) return;
|
||||
if ( p->pGenlib )
|
||||
{
|
||||
assert( p->pGenlib == Abc_FrameReadLibGen() );
|
||||
Mio_LibraryDelete( p->pGenlib );
|
||||
Abc_FrameSetLibGen( NULL );
|
||||
}
|
||||
if ( p->tTableC )
|
||||
Map_SuperTableFree( p->tTableC );
|
||||
if ( p->tTable )
|
||||
Map_SuperTableFree( p->tTable );
|
||||
Extra_MmFixedStop( p->mmSupers );
|
||||
Extra_MmFixedStop( p->mmEntries );
|
||||
Extra_MmFlexStop( p->mmForms );
|
||||
FREE( p->ppSupers );
|
||||
FREE( p );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Derives the library from the genlib library.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Map_SuperLibDeriveFromGenlib( Mio_Library_t * pLib )
|
||||
{
|
||||
Abc_Frame_t * pAbc = Abc_FrameGetGlobalFrame();
|
||||
char * pNameGeneric;
|
||||
char FileNameGenlib[100];
|
||||
char FileNameSuper[100];
|
||||
char CommandSuper[500];
|
||||
char CommandRead[500];
|
||||
FILE * pFile;
|
||||
|
||||
if ( pLib == NULL )
|
||||
return 0;
|
||||
|
||||
// write the current library into the file
|
||||
sprintf( FileNameGenlib, "%s_temp", Mio_LibraryReadName(pLib) );
|
||||
pFile = fopen( FileNameGenlib, "w" );
|
||||
Mio_WriteLibrary( pFile, pLib, 0 );
|
||||
fclose( pFile );
|
||||
|
||||
// get the file name with the library
|
||||
pNameGeneric = Extra_FileNameGeneric( Mio_LibraryReadName(pLib) );
|
||||
sprintf( FileNameSuper, "%s.super", pNameGeneric );
|
||||
free( pNameGeneric );
|
||||
|
||||
sprintf( CommandSuper, "super -l 1 -i 5 -d 10000000 -a 10000000 -t 100 %s", FileNameGenlib );
|
||||
if ( Cmd_CommandExecute( pAbc, CommandSuper ) )
|
||||
{
|
||||
fprintf( stdout, "Cannot execute command \"%s\".\n", CommandSuper );
|
||||
return 0;
|
||||
}
|
||||
//#ifdef WIN32
|
||||
// _unlink( FileNameGenlib );
|
||||
//#else
|
||||
// unlink( FileNameGenlib );
|
||||
//#endif
|
||||
|
||||
sprintf( CommandRead, "read_super %s", FileNameSuper );
|
||||
if ( Cmd_CommandExecute( pAbc, CommandRead ) )
|
||||
{
|
||||
#ifdef WIN32
|
||||
_unlink( FileNameSuper );
|
||||
#else
|
||||
unlink( FileNameSuper );
|
||||
#endif
|
||||
fprintf( stdout, "Cannot execute command \"%s\".\n", CommandRead );
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* // don't remove the intermediate file
|
||||
#ifdef WIN32
|
||||
_unlink( FileNameSuper );
|
||||
#else
|
||||
unlink( FileNameSuper );
|
||||
#endif
|
||||
*/
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
@@ -1,596 +0,0 @@
|
||||
/**CFile****************************************************************
|
||||
|
||||
FileName [mapperMatch.c]
|
||||
|
||||
PackageName [MVSIS 1.3: Multi-valued logic synthesis system.]
|
||||
|
||||
Synopsis [Generic technology mapping engine.]
|
||||
|
||||
Author [MVSIS Group]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 2.0. Started - June 1, 2004.]
|
||||
|
||||
Revision [$Id: mapperMatch.c,v 1.7 2004/09/30 21:18:10 satrajit Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "mapperInt.h"
|
||||
|
||||
/*
|
||||
A potential improvement:
|
||||
When an internal node is not used in the mapping, its required times
|
||||
are set to be +infinity. So when we recover area, we try to find the
|
||||
best match for area and completely disregard the delay for the nodes
|
||||
that are not currently used in the mapping because any match whose
|
||||
arrival times are less than the required times (+infinity) can be used.
|
||||
It may be possible to develop a better approach to recover area for
|
||||
the nodes that are not currently used in the mapping...
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static int Map_MatchNodePhase( Map_Man_t * p, Map_Node_t * pNode, int fPhase );
|
||||
static int Map_MatchNodeCut( Map_Man_t * p, Map_Node_t * pNode, Map_Cut_t * pCut, int fPhase, float fWorstLimit );
|
||||
|
||||
static void Map_MappingSetPiArrivalTimes( Map_Man_t * p );
|
||||
static void Map_NodeTryDroppingOnePhase( Map_Man_t * p, Map_Node_t * pNode );
|
||||
static void Map_NodeTransferArrivalTimes( Map_Man_t * p, Map_Node_t * pNode );
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes the best matches of the nodes.]
|
||||
|
||||
Description [Uses parameter p->fMappingMode to decide how to assign
|
||||
the matches for both polarities of the node. While the matches are
|
||||
being assigned, one of them may turn out to be better than the other
|
||||
(in terms of delay, for example). In this case, the worse match can
|
||||
be permanently dropped, and the corresponding pointer set to NULL.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Map_MappingMatches( Map_Man_t * p )
|
||||
{
|
||||
ProgressBar * pProgress;
|
||||
Map_Node_t * pNode;
|
||||
int i;
|
||||
|
||||
assert( p->fMappingMode >= 0 && p->fMappingMode <= 4 );
|
||||
|
||||
// use the externally given PI arrival times
|
||||
if ( p->fMappingMode == 0 )
|
||||
Map_MappingSetPiArrivalTimes( p );
|
||||
|
||||
// estimate the fanouts
|
||||
if ( p->fMappingMode == 0 )
|
||||
Map_MappingEstimateRefsInit( p );
|
||||
else if ( p->fMappingMode == 1 )
|
||||
Map_MappingEstimateRefs( p );
|
||||
|
||||
// the PI cuts are matched in the cut computation package
|
||||
// in the loop below we match the internal nodes
|
||||
pProgress = Extra_ProgressBarStart( stdout, p->vAnds->nSize );
|
||||
for ( i = 0; i < p->vAnds->nSize; i++ )
|
||||
{
|
||||
// skip primary inputs and secondary nodes if mapping with choices
|
||||
pNode = p->vAnds->pArray[i];
|
||||
if ( !Map_NodeIsAnd( pNode ) || pNode->pRepr )
|
||||
continue;
|
||||
|
||||
// make sure that at least one non-trival cut is present
|
||||
if ( pNode->pCuts->pNext == NULL )
|
||||
{
|
||||
printf( "\nError: A node in the mapping graph does not have feasible cuts.\n" );
|
||||
return 0;
|
||||
}
|
||||
|
||||
// match negative phase
|
||||
if ( !Map_MatchNodePhase( p, pNode, 0 ) )
|
||||
return 0;
|
||||
// match positive phase
|
||||
if ( !Map_MatchNodePhase( p, pNode, 1 ) )
|
||||
return 0;
|
||||
|
||||
// make sure that at least one phase is mapped
|
||||
if ( pNode->pCutBest[0] == NULL && pNode->pCutBest[1] == NULL )
|
||||
{
|
||||
printf( "\nError: Could not match both phases of AIG node %d.\n", pNode->Num );
|
||||
printf( "Please make sure that the supergate library has equivalents of AND2 or NAND2.\n" );
|
||||
printf( "If such supergates exist in the library, report a bug.\n" );
|
||||
return 0;
|
||||
}
|
||||
|
||||
// if both phases are assigned, check if one of them can be dropped
|
||||
Map_NodeTryDroppingOnePhase( p, pNode );
|
||||
// set the arrival times of the node using the best cuts
|
||||
Map_NodeTransferArrivalTimes( p, pNode );
|
||||
|
||||
// update the progress bar
|
||||
Extra_ProgressBarUpdate( pProgress, i, "Matches ..." );
|
||||
}
|
||||
Extra_ProgressBarStop( pProgress );
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Find the matching of one polarity of the node.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Map_MatchNodePhase( Map_Man_t * p, Map_Node_t * pNode, int fPhase )
|
||||
{
|
||||
Map_Match_t MatchBest, * pMatch;
|
||||
Map_Cut_t * pCut, * pCutBest;
|
||||
float Area1, Area2, fWorstLimit;
|
||||
|
||||
// skip the cuts that have been unassigned during area recovery
|
||||
pCutBest = pNode->pCutBest[fPhase];
|
||||
if ( p->fMappingMode != 0 && pCutBest == NULL )
|
||||
return 1;
|
||||
|
||||
// recompute the arrival times of the current best match
|
||||
// because the arrival times of the fanins may have changed
|
||||
// as a result of remapping fanins in the topological order
|
||||
if ( p->fMappingMode != 0 )
|
||||
{
|
||||
Map_TimeCutComputeArrival( pNode, pCutBest, fPhase, MAP_FLOAT_LARGE );
|
||||
// make sure that the required times are met
|
||||
assert( pCutBest->M[fPhase].tArrive.Rise < pNode->tRequired[fPhase].Rise + p->fEpsilon );
|
||||
assert( pCutBest->M[fPhase].tArrive.Fall < pNode->tRequired[fPhase].Fall + p->fEpsilon );
|
||||
}
|
||||
|
||||
// recompute the exact area of the current best match
|
||||
// because the exact area of the fanins may have changed
|
||||
// as a result of remapping fanins in the topological order
|
||||
if ( p->fMappingMode == 2 || p->fMappingMode == 3 )
|
||||
{
|
||||
pMatch = pCutBest->M + fPhase;
|
||||
if ( pNode->nRefAct[fPhase] > 0 ||
|
||||
(pNode->pCutBest[!fPhase] == NULL && pNode->nRefAct[!fPhase] > 0) )
|
||||
pMatch->AreaFlow = Area1 = Map_CutDeref( pCutBest, fPhase );
|
||||
else
|
||||
pMatch->AreaFlow = Area1 = Map_CutGetAreaDerefed( pCutBest, fPhase );
|
||||
}
|
||||
else if ( p->fMappingMode == 4 )
|
||||
{
|
||||
pMatch = pCutBest->M + fPhase;
|
||||
if ( pNode->nRefAct[fPhase] > 0 ||
|
||||
(pNode->pCutBest[!fPhase] == NULL && pNode->nRefAct[!fPhase] > 0) )
|
||||
pMatch->AreaFlow = Area1 = Map_SwitchCutDeref( pNode, pCutBest, fPhase );
|
||||
else
|
||||
pMatch->AreaFlow = Area1 = Map_SwitchCutGetDerefed( pNode, pCutBest, fPhase );
|
||||
}
|
||||
|
||||
// save the old mapping
|
||||
if ( pCutBest )
|
||||
MatchBest = pCutBest->M[fPhase];
|
||||
else
|
||||
Map_MatchClean( &MatchBest );
|
||||
|
||||
// select the new best cut
|
||||
fWorstLimit = pNode->tRequired[fPhase].Worst;
|
||||
for ( pCut = pNode->pCuts->pNext; pCut; pCut = pCut->pNext )
|
||||
{
|
||||
pMatch = pCut->M + fPhase;
|
||||
if ( pMatch->pSupers == NULL )
|
||||
continue;
|
||||
|
||||
// find the matches for the cut
|
||||
Map_MatchNodeCut( p, pNode, pCut, fPhase, fWorstLimit );
|
||||
if ( pMatch->pSuperBest == NULL || pMatch->tArrive.Worst > fWorstLimit + p->fEpsilon )
|
||||
continue;
|
||||
|
||||
// if the cut can be matched compare the matchings
|
||||
if ( Map_MatchCompare( p, &MatchBest, pMatch, p->fMappingMode ) )
|
||||
{
|
||||
pCutBest = pCut;
|
||||
MatchBest = *pMatch;
|
||||
// if we are mapping for delay, the worst-case limit should be tightened
|
||||
if ( p->fMappingMode == 0 )
|
||||
fWorstLimit = MatchBest.tArrive.Worst;
|
||||
}
|
||||
}
|
||||
|
||||
if ( pCutBest == NULL )
|
||||
return 1;
|
||||
|
||||
// set the new mapping
|
||||
pNode->pCutBest[fPhase] = pCutBest;
|
||||
pCutBest->M[fPhase] = MatchBest;
|
||||
|
||||
// reference the new cut if it used
|
||||
if ( p->fMappingMode >= 2 &&
|
||||
(pNode->nRefAct[fPhase] > 0 ||
|
||||
(pNode->pCutBest[!fPhase] == NULL && pNode->nRefAct[!fPhase] > 0)) )
|
||||
{
|
||||
if ( p->fMappingMode == 2 || p->fMappingMode == 3 )
|
||||
Area2 = Map_CutRef( pNode->pCutBest[fPhase], fPhase );
|
||||
else if ( p->fMappingMode == 4 )
|
||||
Area2 = Map_SwitchCutRef( pNode, pNode->pCutBest[fPhase], fPhase );
|
||||
else
|
||||
assert( 0 );
|
||||
assert( Area2 < Area1 + p->fEpsilon );
|
||||
}
|
||||
|
||||
// make sure that the requited times are met
|
||||
assert( MatchBest.tArrive.Rise < pNode->tRequired[fPhase].Rise + p->fEpsilon );
|
||||
assert( MatchBest.tArrive.Fall < pNode->tRequired[fPhase].Fall + p->fEpsilon );
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Find the best matching of the cut.]
|
||||
|
||||
Description [The parameters: the node (pNode), the cut (pCut), the phase to be matched
|
||||
(fPhase), and the upper bound on the arrival times of the cut (fWorstLimit). This
|
||||
procedure goes through the matching supergates up to the phase assignment, and selects the
|
||||
best supergate, which will be used to map the cut. As a result of calling this procedure
|
||||
the matching information is written into pMatch.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Map_MatchNodeCut( Map_Man_t * p, Map_Node_t * pNode, Map_Cut_t * pCut, int fPhase, float fWorstLimit )
|
||||
{
|
||||
Map_Match_t MatchBest, * pMatch = pCut->M + fPhase;
|
||||
Map_Super_t * pSuper;
|
||||
int i, Counter;
|
||||
|
||||
// save the current match of the cut
|
||||
MatchBest = *pMatch;
|
||||
// go through the supergates
|
||||
for ( pSuper = pMatch->pSupers, Counter = 0; pSuper; pSuper = pSuper->pNext, Counter++ )
|
||||
{
|
||||
p->nMatches++;
|
||||
// this is an attempt to reduce the runtime of matching and area
|
||||
// at the cost of rare and very minor increase in delay
|
||||
// (the supergates are sorted by increasing area)
|
||||
if ( Counter == 30 )
|
||||
break;
|
||||
|
||||
// go through different phases of the given match and supergate
|
||||
pMatch->pSuperBest = pSuper;
|
||||
for ( i = 0; i < (int)pSuper->nPhases; i++ )
|
||||
{
|
||||
p->nPhases++;
|
||||
// find the overall phase of this match
|
||||
pMatch->uPhaseBest = pMatch->uPhase ^ pSuper->uPhases[i];
|
||||
if ( p->fMappingMode == 0 )
|
||||
{
|
||||
// get the arrival time
|
||||
Map_TimeCutComputeArrival( pNode, pCut, fPhase, fWorstLimit );
|
||||
// skip the cut if the arrival times exceed the required times
|
||||
if ( pMatch->tArrive.Worst > fWorstLimit + p->fEpsilon )
|
||||
continue;
|
||||
// get the area (area flow)
|
||||
pMatch->AreaFlow = Map_CutGetAreaFlow( pCut, fPhase );
|
||||
}
|
||||
else
|
||||
{
|
||||
// get the area (area flow)
|
||||
if ( p->fMappingMode == 2 || p->fMappingMode == 3 )
|
||||
pMatch->AreaFlow = Map_CutGetAreaDerefed( pCut, fPhase );
|
||||
else if ( p->fMappingMode == 4 )
|
||||
pMatch->AreaFlow = Map_SwitchCutGetDerefed( pNode, pCut, fPhase );
|
||||
else
|
||||
pMatch->AreaFlow = Map_CutGetAreaFlow( pCut, fPhase );
|
||||
// skip if the cut is too large
|
||||
if ( pMatch->AreaFlow > MatchBest.AreaFlow + p->fEpsilon )
|
||||
continue;
|
||||
// get the arrival time
|
||||
Map_TimeCutComputeArrival( pNode, pCut, fPhase, fWorstLimit );
|
||||
// skip the cut if the arrival times exceed the required times
|
||||
if ( pMatch->tArrive.Worst > fWorstLimit + p->fEpsilon )
|
||||
continue;
|
||||
}
|
||||
|
||||
// if the cut is non-trivial, compare it
|
||||
if ( Map_MatchCompare( p, &MatchBest, pMatch, p->fMappingMode ) )
|
||||
{
|
||||
MatchBest = *pMatch;
|
||||
// if we are mapping for delay, the worst-case limit should be reduced
|
||||
if ( p->fMappingMode == 0 )
|
||||
fWorstLimit = MatchBest.tArrive.Worst;
|
||||
}
|
||||
}
|
||||
}
|
||||
// set the best match
|
||||
*pMatch = MatchBest;
|
||||
|
||||
// recompute the arrival time and area (area flow) of this cut
|
||||
if ( pMatch->pSuperBest )
|
||||
{
|
||||
Map_TimeCutComputeArrival( pNode, pCut, fPhase, MAP_FLOAT_LARGE );
|
||||
if ( p->fMappingMode == 2 || p->fMappingMode == 3 )
|
||||
pMatch->AreaFlow = Map_CutGetAreaDerefed( pCut, fPhase );
|
||||
else if ( p->fMappingMode == 4 )
|
||||
pMatch->AreaFlow = Map_SwitchCutGetDerefed( pNode, pCut, fPhase );
|
||||
else
|
||||
pMatch->AreaFlow = Map_CutGetAreaFlow( pCut, fPhase );
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Cleans the match.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Map_MatchClean( Map_Match_t * pMatch )
|
||||
{
|
||||
memset( pMatch, 0, sizeof(Map_Match_t) );
|
||||
pMatch->AreaFlow = MAP_FLOAT_LARGE; // unassigned
|
||||
pMatch->tArrive.Rise = MAP_FLOAT_LARGE; // unassigned
|
||||
pMatch->tArrive.Fall = MAP_FLOAT_LARGE; // unassigned
|
||||
pMatch->tArrive.Worst = MAP_FLOAT_LARGE; // unassigned
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Compares two matches.]
|
||||
|
||||
Description [Returns 1 if the second match is better. Otherwise returns 0.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Map_MatchCompare( Map_Man_t * pMan, Map_Match_t * pM1, Map_Match_t * pM2, int fDoingArea )
|
||||
{
|
||||
if ( !fDoingArea )
|
||||
{
|
||||
// compare the arrival times
|
||||
if ( pM1->tArrive.Worst < pM2->tArrive.Worst - pMan->fEpsilon )
|
||||
return 0;
|
||||
if ( pM1->tArrive.Worst > pM2->tArrive.Worst + pMan->fEpsilon )
|
||||
return 1;
|
||||
// compare the areas or area flows
|
||||
if ( pM1->AreaFlow < pM2->AreaFlow - pMan->fEpsilon )
|
||||
return 0;
|
||||
if ( pM1->AreaFlow > pM2->AreaFlow + pMan->fEpsilon )
|
||||
return 1;
|
||||
// compare the fanout limits
|
||||
if ( pM1->pSuperBest->nFanLimit > pM2->pSuperBest->nFanLimit )
|
||||
return 0;
|
||||
if ( pM1->pSuperBest->nFanLimit < pM2->pSuperBest->nFanLimit )
|
||||
return 1;
|
||||
// compare the number of leaves
|
||||
if ( pM1->pSuperBest->nFanins < pM2->pSuperBest->nFanins )
|
||||
return 0;
|
||||
if ( pM1->pSuperBest->nFanins > pM2->pSuperBest->nFanins )
|
||||
return 1;
|
||||
// otherwise prefer the old cut
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// compare the areas or area flows
|
||||
if ( pM1->AreaFlow < pM2->AreaFlow - pMan->fEpsilon )
|
||||
return 0;
|
||||
if ( pM1->AreaFlow > pM2->AreaFlow + pMan->fEpsilon )
|
||||
return 1;
|
||||
// compare the arrival times
|
||||
if ( pM1->tArrive.Worst < pM2->tArrive.Worst - pMan->fEpsilon )
|
||||
return 0;
|
||||
if ( pM1->tArrive.Worst > pM2->tArrive.Worst + pMan->fEpsilon )
|
||||
return 1;
|
||||
// compare the fanout limits
|
||||
if ( pM1->pSuperBest->nFanLimit > pM2->pSuperBest->nFanLimit )
|
||||
return 0;
|
||||
if ( pM1->pSuperBest->nFanLimit < pM2->pSuperBest->nFanLimit )
|
||||
return 1;
|
||||
// compare the number of leaves
|
||||
if ( pM1->pSuperBest->nFanins < pM2->pSuperBest->nFanins )
|
||||
return 0;
|
||||
if ( pM1->pSuperBest->nFanins > pM2->pSuperBest->nFanins )
|
||||
return 1;
|
||||
// otherwise prefer the old cut
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Sets the PI arrival times.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Map_MappingSetPiArrivalTimes( Map_Man_t * p )
|
||||
{
|
||||
Map_Node_t * pNode;
|
||||
int i;
|
||||
for ( i = 0; i < p->nInputs; i++ )
|
||||
{
|
||||
pNode = p->pInputs[i];
|
||||
// set the arrival time of the positive phase
|
||||
pNode->tArrival[1] = p->pInputArrivals[i];
|
||||
// set the arrival time of the negative phase
|
||||
pNode->tArrival[0].Rise = pNode->tArrival[1].Fall + p->pSuperLib->tDelayInv.Rise;
|
||||
pNode->tArrival[0].Fall = pNode->tArrival[1].Rise + p->pSuperLib->tDelayInv.Fall;
|
||||
pNode->tArrival[0].Worst = MAP_MAX(pNode->tArrival[0].Rise, pNode->tArrival[0].Fall);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Attempts dropping one phase of the node.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Map_NodeTryDroppingOnePhase( Map_Man_t * p, Map_Node_t * pNode )
|
||||
{
|
||||
Map_Match_t * pMatchBest0, * pMatchBest1;
|
||||
float tWorst0Using1, tWorst1Using0;
|
||||
int fUsePhase1, fUsePhase0;
|
||||
|
||||
// nothing to do if one of the phases is already dropped
|
||||
if ( pNode->pCutBest[0] == NULL || pNode->pCutBest[1] == NULL )
|
||||
return;
|
||||
|
||||
// do not drop while recovering area flow
|
||||
if ( p->fMappingMode == 1 )//|| p->fMappingMode == 2 )
|
||||
return;
|
||||
|
||||
// get the pointers to the matches of the best cuts
|
||||
pMatchBest0 = pNode->pCutBest[0]->M + 0;
|
||||
pMatchBest1 = pNode->pCutBest[1]->M + 1;
|
||||
|
||||
// get the worst arrival times of each phase
|
||||
// implemented using the other phase with inverter added
|
||||
tWorst0Using1 = Map_TimeMatchWithInverter( p, pMatchBest1 );
|
||||
tWorst1Using0 = Map_TimeMatchWithInverter( p, pMatchBest0 );
|
||||
|
||||
// consider the case of mapping for delay
|
||||
if ( p->fMappingMode == 0 )
|
||||
{
|
||||
// if the arrival time of a phase is larger than the arrival time
|
||||
// of the opposite phase plus the inverter, drop this phase
|
||||
if ( pMatchBest0->tArrive.Worst > tWorst0Using1 + p->fEpsilon )
|
||||
pNode->pCutBest[0] = NULL;
|
||||
else if ( pMatchBest1->tArrive.Worst > tWorst1Using0 + p->fEpsilon )
|
||||
pNode->pCutBest[1] = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
// do not perform replacement if one of the phases is unused
|
||||
if ( pNode->nRefAct[0] == 0 || pNode->nRefAct[1] == 0 )
|
||||
return;
|
||||
|
||||
// check if replacement of each phase is possible using required times
|
||||
fUsePhase0 = fUsePhase1 = 0;
|
||||
if ( p->fMappingMode == 2 )
|
||||
{
|
||||
fUsePhase0 = (pNode->tRequired[1].Worst > tWorst1Using0 + 3*p->pSuperLib->tDelayInv.Worst + p->fEpsilon);
|
||||
fUsePhase1 = (pNode->tRequired[0].Worst > tWorst0Using1 + 3*p->pSuperLib->tDelayInv.Worst + p->fEpsilon);
|
||||
}
|
||||
else if ( p->fMappingMode == 3 || p->fMappingMode == 4 )
|
||||
{
|
||||
fUsePhase0 = (pNode->tRequired[1].Worst > tWorst1Using0 + p->fEpsilon);
|
||||
fUsePhase1 = (pNode->tRequired[0].Worst > tWorst0Using1 + p->fEpsilon);
|
||||
}
|
||||
if ( !fUsePhase0 && !fUsePhase1 )
|
||||
return;
|
||||
|
||||
// if replacement is possible both ways, use the one that works better
|
||||
if ( fUsePhase0 && fUsePhase1 )
|
||||
{
|
||||
if ( pMatchBest0->AreaFlow < pMatchBest1->AreaFlow )
|
||||
fUsePhase1 = 0;
|
||||
else
|
||||
fUsePhase0 = 0;
|
||||
}
|
||||
// only one phase should be used
|
||||
assert( fUsePhase0 ^ fUsePhase1 );
|
||||
|
||||
// set the corresponding cut to NULL
|
||||
if ( fUsePhase0 )
|
||||
{
|
||||
// deref phase 1 cut if necessary
|
||||
if ( p->fMappingMode >= 2 && pNode->nRefAct[1] > 0 )
|
||||
Map_CutDeref( pNode->pCutBest[1], 1 );
|
||||
// get rid of the cut
|
||||
pNode->pCutBest[1] = NULL;
|
||||
// ref phase 0 cut if necessary
|
||||
if ( p->fMappingMode >= 2 && pNode->nRefAct[0] == 0 )
|
||||
Map_CutRef( pNode->pCutBest[0], 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
// deref phase 0 cut if necessary
|
||||
if ( p->fMappingMode >= 2 && pNode->nRefAct[0] > 0 )
|
||||
Map_CutDeref( pNode->pCutBest[0], 0 );
|
||||
// get rid of the cut
|
||||
pNode->pCutBest[0] = NULL;
|
||||
// ref phase 1 cut if necessary
|
||||
if ( p->fMappingMode >= 2 && pNode->nRefAct[1] == 0 )
|
||||
Map_CutRef( pNode->pCutBest[1], 1 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Transfers the arrival times from the best cuts to the node.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Map_NodeTransferArrivalTimes( Map_Man_t * p, Map_Node_t * pNode )
|
||||
{
|
||||
// if both phases are available, set their arrival times
|
||||
if ( pNode->pCutBest[0] && pNode->pCutBest[1] )
|
||||
{
|
||||
pNode->tArrival[0] = pNode->pCutBest[0]->M[0].tArrive;
|
||||
pNode->tArrival[1] = pNode->pCutBest[1]->M[1].tArrive;
|
||||
}
|
||||
// if only one phase is available, compute the arrival time of other phase
|
||||
else if ( pNode->pCutBest[0] )
|
||||
{
|
||||
pNode->tArrival[0] = pNode->pCutBest[0]->M[0].tArrive;
|
||||
pNode->tArrival[1].Rise = pNode->tArrival[0].Fall + p->pSuperLib->tDelayInv.Rise;
|
||||
pNode->tArrival[1].Fall = pNode->tArrival[0].Rise + p->pSuperLib->tDelayInv.Fall;
|
||||
pNode->tArrival[1].Worst = MAP_MAX(pNode->tArrival[1].Rise, pNode->tArrival[1].Fall);
|
||||
}
|
||||
else if ( pNode->pCutBest[1] )
|
||||
{
|
||||
pNode->tArrival[1] = pNode->pCutBest[1]->M[1].tArrive;
|
||||
pNode->tArrival[0].Rise = pNode->tArrival[1].Fall + p->pSuperLib->tDelayInv.Rise;
|
||||
pNode->tArrival[0].Fall = pNode->tArrival[1].Rise + p->pSuperLib->tDelayInv.Fall;
|
||||
pNode->tArrival[0].Worst = MAP_MAX(pNode->tArrival[0].Rise, pNode->tArrival[0].Fall);
|
||||
}
|
||||
else
|
||||
{
|
||||
assert( 0 );
|
||||
}
|
||||
|
||||
assert( pNode->tArrival[0].Rise < pNode->tRequired[0].Rise + p->fEpsilon );
|
||||
assert( pNode->tArrival[0].Fall < pNode->tRequired[0].Fall + p->fEpsilon );
|
||||
|
||||
assert( pNode->tArrival[1].Rise < pNode->tRequired[1].Rise + p->fEpsilon );
|
||||
assert( pNode->tArrival[1].Fall < pNode->tRequired[1].Fall + p->fEpsilon );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
@@ -1,557 +0,0 @@
|
||||
/**CFile****************************************************************
|
||||
|
||||
FileName [mapperRefs.c]
|
||||
|
||||
PackageName [MVSIS 1.3: Multi-valued logic synthesis system.]
|
||||
|
||||
Synopsis [Generic technology mapping engine.]
|
||||
|
||||
Author [MVSIS Group]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 2.0. Started - June 1, 2004.]
|
||||
|
||||
Revision [$Id: mapperRefs.h,v 1.0 2003/09/08 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "mapperInt.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static int Map_NodeIncRefPhaseAct( Map_Node_t * pNode, int fPhase );
|
||||
static int Map_NodeDecRefPhaseAct( Map_Node_t * pNode, int fPhase );
|
||||
static float Map_CutRefDeref( Map_Cut_t * pCut, int fPhase, int fReference );
|
||||
static void Map_MappingSetRefs_rec( Map_Man_t * pMan, Map_Node_t * pNode, Map_Node_t ** ppStore );
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Reads the actual reference counter of a phase.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Map_NodeReadRefPhaseAct( Map_Node_t * pNode, int fPhase )
|
||||
{
|
||||
assert( !Map_IsComplement(pNode) );
|
||||
if ( pNode->pCutBest[0] && pNode->pCutBest[1] ) // both assigned
|
||||
return pNode->nRefAct[fPhase];
|
||||
assert( pNode->pCutBest[0] || pNode->pCutBest[1] ); // at least one assigned
|
||||
return pNode->nRefAct[2];
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Reads the estimated reference counter of a phase.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
float Map_NodeReadRefPhaseEst( Map_Node_t * pNode, int fPhase )
|
||||
{
|
||||
assert( !Map_IsComplement(pNode) );
|
||||
if ( pNode->pCutBest[0] && pNode->pCutBest[1] ) // both assigned
|
||||
return pNode->nRefEst[fPhase];
|
||||
assert( pNode->pCutBest[0] || pNode->pCutBest[1] ); // at least one assigned
|
||||
// return pNode->nRefEst[0] + pNode->nRefEst[1];
|
||||
return pNode->nRefEst[2];
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Increments the actual reference counter of a phase.]
|
||||
|
||||
Description [Returns the old reference counter.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Map_NodeIncRefPhaseAct( Map_Node_t * pNode, int fPhase )
|
||||
{
|
||||
assert( !Map_IsComplement(pNode) );
|
||||
if ( pNode->pCutBest[0] && pNode->pCutBest[1] ) // both assigned
|
||||
return pNode->nRefAct[fPhase]++;
|
||||
assert( pNode->pCutBest[0] || pNode->pCutBest[1] ); // at least one assigned
|
||||
return pNode->nRefAct[2]++;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Decrements the actual reference counter of a phase.]
|
||||
|
||||
Description [Returns the new reference counter.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Map_NodeDecRefPhaseAct( Map_Node_t * pNode, int fPhase )
|
||||
{
|
||||
assert( !Map_IsComplement(pNode) );
|
||||
if ( pNode->pCutBest[0] && pNode->pCutBest[1] ) // both assigned
|
||||
return --pNode->nRefAct[fPhase];
|
||||
assert( pNode->pCutBest[0] || pNode->pCutBest[1] ); // at least one assigned
|
||||
return --pNode->nRefAct[2];
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Sets the estimated reference counter for the PIs.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Map_MappingEstimateRefsInit( Map_Man_t * p )
|
||||
{
|
||||
Map_Node_t * pNode;
|
||||
int i;
|
||||
for ( i = 0; i < p->vAnds->nSize; i++ )
|
||||
{
|
||||
pNode = p->vAnds->pArray[i];
|
||||
// pNode->nRefEst[0] = pNode->nRefEst[1] = ((float)pNode->nRefs)*(float)2.0;
|
||||
pNode->nRefEst[0] = pNode->nRefEst[1] = pNode->nRefEst[2] = ((float)pNode->nRefs);
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Sets the estimated reference counter.]
|
||||
|
||||
Description [When this procedure is called for the first time,
|
||||
the reference counter is estimated from the AIG. Otherwise, it is
|
||||
a linear combination of reference counters in the last two iterations.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Map_MappingEstimateRefs( Map_Man_t * p )
|
||||
{
|
||||
Map_Node_t * pNode;
|
||||
int i;
|
||||
for ( i = 0; i < p->vAnds->nSize; i++ )
|
||||
{
|
||||
pNode = p->vAnds->pArray[i];
|
||||
// pNode->nRefEst[0] = (float)((2.0 * pNode->nRefEst[0] + 1.0 * pNode->nRefAct[0]) / 3.0);
|
||||
// pNode->nRefEst[1] = (float)((2.0 * pNode->nRefEst[1] + 1.0 * pNode->nRefAct[1]) / 3.0);
|
||||
// pNode->nRefEst[2] = (float)((2.0 * pNode->nRefEst[2] + 1.0 * pNode->nRefAct[2]) / 3.0);
|
||||
pNode->nRefEst[0] = (float)((3.0 * pNode->nRefEst[0] + 1.0 * pNode->nRefAct[0]) / 4.0);
|
||||
pNode->nRefEst[1] = (float)((3.0 * pNode->nRefEst[1] + 1.0 * pNode->nRefAct[1]) / 4.0);
|
||||
pNode->nRefEst[2] = (float)((3.0 * pNode->nRefEst[2] + 1.0 * pNode->nRefAct[2]) / 4.0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**function*************************************************************
|
||||
|
||||
synopsis [Computes the area flow of the cut.]
|
||||
|
||||
description [Computes the area flow of the cut if it is implemented using
|
||||
the best supergate with the best phase.]
|
||||
|
||||
sideeffects []
|
||||
|
||||
seealso []
|
||||
|
||||
***********************************************************************/
|
||||
float Map_CutGetAreaFlow( Map_Cut_t * pCut, int fPhase )
|
||||
{
|
||||
Map_Match_t * pM = pCut->M + fPhase;
|
||||
Map_Super_t * pSuper = pM->pSuperBest;
|
||||
unsigned uPhaseTot = pM->uPhaseBest;
|
||||
Map_Cut_t * pCutFanin;
|
||||
float aFlowRes, aFlowFanin, nRefs;
|
||||
int i, fPinPhasePos;
|
||||
|
||||
// start the resulting area flow
|
||||
aFlowRes = pSuper->Area;
|
||||
// iterate through the leaves
|
||||
for ( i = 0; i < pCut->nLeaves; i++ )
|
||||
{
|
||||
// get the phase of this fanin
|
||||
fPinPhasePos = ((uPhaseTot & (1 << i)) == 0);
|
||||
// get the cut implementing this phase of the fanin
|
||||
pCutFanin = pCut->ppLeaves[i]->pCutBest[fPinPhasePos];
|
||||
// if the cut is not available, we have to use the opposite phase
|
||||
if ( pCutFanin == NULL )
|
||||
{
|
||||
fPinPhasePos = !fPinPhasePos;
|
||||
pCutFanin = pCut->ppLeaves[i]->pCutBest[fPinPhasePos];
|
||||
}
|
||||
aFlowFanin = pCutFanin->M[fPinPhasePos].AreaFlow; // ignores the area of the interter
|
||||
// get the fanout count of the cut in the given phase
|
||||
nRefs = Map_NodeReadRefPhaseEst( pCut->ppLeaves[i], fPinPhasePos );
|
||||
// if the node does no fanout, assume fanout count equal to 1
|
||||
if ( nRefs == (float)0.0 )
|
||||
nRefs = (float)1.0;
|
||||
// add the area flow due to the fanin
|
||||
aFlowRes += aFlowFanin / nRefs;
|
||||
}
|
||||
pM->AreaFlow = aFlowRes;
|
||||
return aFlowRes;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**function*************************************************************
|
||||
|
||||
synopsis [Computes the exact area associated with the cut.]
|
||||
|
||||
description [Assumes that the cut is referenced.]
|
||||
|
||||
sideeffects []
|
||||
|
||||
seealso []
|
||||
|
||||
***********************************************************************/
|
||||
float Map_CutGetAreaRefed( Map_Cut_t * pCut, int fPhase )
|
||||
{
|
||||
float aResult, aResult2;
|
||||
aResult2 = Map_CutRefDeref( pCut, fPhase, 0 ); // dereference
|
||||
aResult = Map_CutRefDeref( pCut, fPhase, 1 ); // reference
|
||||
// assert( aResult == aResult2 );
|
||||
return aResult;
|
||||
}
|
||||
|
||||
/**function*************************************************************
|
||||
|
||||
synopsis [Computes the exact area associated with the cut.]
|
||||
|
||||
description []
|
||||
|
||||
sideeffects []
|
||||
|
||||
seealso []
|
||||
|
||||
***********************************************************************/
|
||||
float Map_CutGetAreaDerefed( Map_Cut_t * pCut, int fPhase )
|
||||
{
|
||||
float aResult, aResult2;
|
||||
aResult2 = Map_CutRefDeref( pCut, fPhase, 1 ); // reference
|
||||
aResult = Map_CutRefDeref( pCut, fPhase, 0 ); // dereference
|
||||
// assert( aResult == aResult2 );
|
||||
return aResult;
|
||||
}
|
||||
|
||||
/**function*************************************************************
|
||||
|
||||
synopsis [References the cut.]
|
||||
|
||||
description []
|
||||
|
||||
sideeffects []
|
||||
|
||||
seealso []
|
||||
|
||||
***********************************************************************/
|
||||
float Map_CutRef( Map_Cut_t * pCut, int fPhase )
|
||||
{
|
||||
return Map_CutRefDeref( pCut, fPhase, 1 ); // reference
|
||||
}
|
||||
|
||||
/**function*************************************************************
|
||||
|
||||
synopsis [Dereferences the cut.]
|
||||
|
||||
description []
|
||||
|
||||
sideeffects []
|
||||
|
||||
seealso []
|
||||
|
||||
***********************************************************************/
|
||||
float Map_CutDeref( Map_Cut_t * pCut, int fPhase )
|
||||
{
|
||||
return Map_CutRefDeref( pCut, fPhase, 0 ); // dereference
|
||||
}
|
||||
|
||||
/**function*************************************************************
|
||||
|
||||
synopsis [References or dereferences the cut.]
|
||||
|
||||
description [This reference part is similar to Cudd_NodeReclaim().
|
||||
The dereference part is similar to Cudd_RecursiveDeref().]
|
||||
|
||||
sideeffects []
|
||||
|
||||
seealso []
|
||||
|
||||
***********************************************************************/
|
||||
float Map_CutRefDeref( Map_Cut_t * pCut, int fPhase, int fReference )
|
||||
{
|
||||
Map_Node_t * pNodeChild;
|
||||
Map_Cut_t * pCutChild;
|
||||
float aArea;
|
||||
int i, fPhaseChild;
|
||||
// int nRefs;
|
||||
|
||||
// consider the elementary variable
|
||||
if ( pCut->nLeaves == 1 )
|
||||
return 0;
|
||||
// start the area of this cut
|
||||
aArea = Map_CutGetRootArea( pCut, fPhase );
|
||||
// go through the children
|
||||
for ( i = 0; i < pCut->nLeaves; i++ )
|
||||
{
|
||||
pNodeChild = pCut->ppLeaves[i];
|
||||
fPhaseChild = Map_CutGetLeafPhase( pCut, fPhase, i );
|
||||
// get the reference counter of the child
|
||||
/*
|
||||
// this code does not take inverters into account
|
||||
// the quality of area recovery seems to always be a little worse
|
||||
if ( fReference )
|
||||
nRefs = Map_NodeIncRefPhaseAct( pNodeChild, fPhaseChild );
|
||||
else
|
||||
nRefs = Map_NodeDecRefPhaseAct( pNodeChild, fPhaseChild );
|
||||
assert( nRefs >= 0 );
|
||||
// skip if the child was already reference before
|
||||
if ( nRefs > 0 )
|
||||
continue;
|
||||
*/
|
||||
|
||||
if ( fReference )
|
||||
{
|
||||
if ( pNodeChild->pCutBest[0] && pNodeChild->pCutBest[1] ) // both phases are present
|
||||
{
|
||||
// if this phase of the node is referenced, there is no recursive call
|
||||
pNodeChild->nRefAct[2]++;
|
||||
if ( pNodeChild->nRefAct[fPhaseChild]++ > 0 )
|
||||
continue;
|
||||
}
|
||||
else // only one phase is present
|
||||
{
|
||||
// inverter should be added if the phase
|
||||
// (a) has no reference and (b) is implemented using other phase
|
||||
if ( pNodeChild->nRefAct[fPhaseChild]++ == 0 && pNodeChild->pCutBest[fPhaseChild] == NULL )
|
||||
aArea += pNodeChild->p->pSuperLib->AreaInv;
|
||||
// if the node is referenced, there is no recursive call
|
||||
if ( pNodeChild->nRefAct[2]++ > 0 )
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( pNodeChild->pCutBest[0] && pNodeChild->pCutBest[1] ) // both phases are present
|
||||
{
|
||||
// if this phase of the node is referenced, there is no recursive call
|
||||
--pNodeChild->nRefAct[2];
|
||||
if ( --pNodeChild->nRefAct[fPhaseChild] > 0 )
|
||||
continue;
|
||||
}
|
||||
else // only one phase is present
|
||||
{
|
||||
// inverter should be added if the phase
|
||||
// (a) has no reference and (b) is implemented using other phase
|
||||
if ( --pNodeChild->nRefAct[fPhaseChild] == 0 && pNodeChild->pCutBest[fPhaseChild] == NULL )
|
||||
aArea += pNodeChild->p->pSuperLib->AreaInv;
|
||||
// if the node is referenced, there is no recursive call
|
||||
if ( --pNodeChild->nRefAct[2] > 0 )
|
||||
continue;
|
||||
}
|
||||
assert( pNodeChild->nRefAct[fPhaseChild] >= 0 );
|
||||
}
|
||||
|
||||
// get the child cut
|
||||
pCutChild = pNodeChild->pCutBest[fPhaseChild];
|
||||
// if the child does not have this phase mapped, take the opposite phase
|
||||
if ( pCutChild == NULL )
|
||||
{
|
||||
fPhaseChild = !fPhaseChild;
|
||||
pCutChild = pNodeChild->pCutBest[fPhaseChild];
|
||||
}
|
||||
// reference and compute area recursively
|
||||
aArea += Map_CutRefDeref( pCutChild, fPhaseChild, fReference );
|
||||
}
|
||||
return aArea;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes actual reference counters.]
|
||||
|
||||
Description [Collects the nodes used in the mapping in array pMan->vMapping.
|
||||
Nodes are collected in reverse topological order to facilitate the
|
||||
computation of required times.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Map_MappingSetRefs( Map_Man_t * pMan )
|
||||
{
|
||||
Map_Node_t * pNode, ** ppStore;
|
||||
int i, fPhase, LevelMax;
|
||||
|
||||
// clean all references
|
||||
for ( i = 0; i < pMan->vNodesAll->nSize; i++ )
|
||||
{
|
||||
pNode = pMan->vNodesAll->pArray[i];
|
||||
pNode->nRefAct[0] = 0;
|
||||
pNode->nRefAct[1] = 0;
|
||||
pNode->nRefAct[2] = 0;
|
||||
}
|
||||
|
||||
// find the largest level of a node
|
||||
LevelMax = 0;
|
||||
for ( i = 0; i < pMan->nOutputs; i++ )
|
||||
if ( LevelMax < (int)Map_Regular(pMan->pOutputs[i])->Level )
|
||||
LevelMax = Map_Regular(pMan->pOutputs[i])->Level;
|
||||
|
||||
// allocate place to store the nodes
|
||||
ppStore = ALLOC( Map_Node_t *, LevelMax + 1 );
|
||||
memset( ppStore, 0, sizeof(Map_Node_t *) * (LevelMax + 1) );
|
||||
|
||||
// visit nodes reachable from POs in the DFS order through the best cuts
|
||||
for ( i = 0; i < pMan->nOutputs; i++ )
|
||||
{
|
||||
pNode = pMan->pOutputs[i];
|
||||
fPhase = !Map_IsComplement(pNode);
|
||||
if ( !Map_NodeIsConst(pNode) )
|
||||
Map_MappingSetRefs_rec( pMan, pNode, ppStore );
|
||||
}
|
||||
|
||||
// reconnect the nodes in reverse topological order
|
||||
pMan->vMapping->nSize = 0;
|
||||
for ( i = LevelMax; i >= 0; i-- )
|
||||
for ( pNode = ppStore[i]; pNode; pNode = (Map_Node_t *)pNode->pData0 )
|
||||
Map_NodeVecPush( pMan->vMapping, pNode );
|
||||
free( ppStore );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Recursively computes the DFS ordering of the nodes.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Map_MappingSetRefs_rec( Map_Man_t * pMan, Map_Node_t * pNode, Map_Node_t ** ppStore )
|
||||
{
|
||||
Map_Cut_t * pCut;
|
||||
Map_Node_t * pNodeR;
|
||||
unsigned uPhase;
|
||||
int i, fPhase, fInvPin;
|
||||
|
||||
// get the regular node and its phase
|
||||
pNodeR = Map_Regular(pNode);
|
||||
fPhase = !Map_IsComplement(pNode);
|
||||
|
||||
// add the node to the list of all visited nodes
|
||||
if ( pNodeR->nRefAct[2]++ == 0 )
|
||||
// Map_NodeVecPush( pMan->vMapping, pNodeR );
|
||||
pNodeR->pData0 = (char *)ppStore[pNodeR->Level], ppStore[pNodeR->Level] = pNodeR;
|
||||
|
||||
// quit if the node was already visited in this phase
|
||||
if ( pNodeR->nRefAct[fPhase]++ )
|
||||
return;
|
||||
|
||||
// quit if this is a PI node
|
||||
if ( Map_NodeIsVar(pNodeR) )
|
||||
return;
|
||||
|
||||
// get the cut implementing this or opposite polarity
|
||||
pCut = pNodeR->pCutBest[fPhase];
|
||||
if ( pCut == NULL )
|
||||
{
|
||||
fPhase = !fPhase;
|
||||
pCut = pNodeR->pCutBest[fPhase];
|
||||
}
|
||||
|
||||
// visit the transitive fanin
|
||||
uPhase = pCut->M[fPhase].uPhaseBest;
|
||||
for ( i = 0; i < pCut->nLeaves; i++ )
|
||||
{
|
||||
fInvPin = ((uPhase & (1 << i)) > 0);
|
||||
Map_MappingSetRefs_rec( pMan, Map_NotCond(pCut->ppLeaves[i], fInvPin), ppStore );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes the array of mapping.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
float Map_MappingGetArea( Map_Man_t * pMan, Map_NodeVec_t * vMapping )
|
||||
{
|
||||
Map_Node_t * pNode;
|
||||
float Area;
|
||||
int i;
|
||||
Area = 0.0;
|
||||
for ( i = 0; i < vMapping->nSize; i++ )
|
||||
{
|
||||
pNode = vMapping->pArray[i];
|
||||
// at least one phase has the best cut assigned
|
||||
assert( pNode->pCutBest[0] != NULL || pNode->pCutBest[1] != NULL );
|
||||
// at least one phase is used in the mapping
|
||||
assert( pNode->nRefAct[0] > 0 || pNode->nRefAct[1] > 0 );
|
||||
// compute the array due to the supergate
|
||||
if ( Map_NodeIsAnd(pNode) )
|
||||
{
|
||||
// count area of the negative phase
|
||||
if ( pNode->pCutBest[0] && (pNode->nRefAct[0] > 0 || pNode->pCutBest[1] == NULL) )
|
||||
Area += pNode->pCutBest[0]->M[0].pSuperBest->Area;
|
||||
// count area of the positive phase
|
||||
if ( pNode->pCutBest[1] && (pNode->nRefAct[1] > 0 || pNode->pCutBest[0] == NULL) )
|
||||
Area += pNode->pCutBest[1]->M[1].pSuperBest->Area;
|
||||
}
|
||||
// count area of the interver if we need to implement one phase with another phase
|
||||
if ( (pNode->pCutBest[0] == NULL && pNode->nRefAct[0] > 0) ||
|
||||
(pNode->pCutBest[1] == NULL && pNode->nRefAct[1] > 0) )
|
||||
Area += pMan->pSuperLib->AreaInv;
|
||||
}
|
||||
// add buffers for each CO driven by a CI
|
||||
for ( i = 0; i < pMan->nOutputs; i++ )
|
||||
if ( Map_NodeIsVar(pMan->pOutputs[i]) && !Map_IsComplement(pMan->pOutputs[i]) )
|
||||
Area += pMan->pSuperLib->AreaBuf;
|
||||
return Area;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
@@ -1,449 +0,0 @@
|
||||
/**CFile****************************************************************
|
||||
|
||||
FileName [mapperSuper.c]
|
||||
|
||||
PackageName [MVSIS 1.3: Multi-valued logic synthesis system.]
|
||||
|
||||
Synopsis [Generic technology mapping engine.]
|
||||
|
||||
Author [MVSIS Group]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 2.0. Started - June 1, 2004.]
|
||||
|
||||
Revision [$Id: mapperSuper.c,v 1.6 2005/01/23 06:59:44 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "mapperInt.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static int Map_LibraryReadFile( Map_SuperLib_t * pLib, FILE * pFile );
|
||||
static Map_Super_t * Map_LibraryReadGate( Map_SuperLib_t * pLib, char * pBuffer, int nVars );
|
||||
static int Map_LibraryTruthVerify( Map_SuperLib_t * pLib, Map_Super_t * pGate );
|
||||
static void Map_LibraryComputeTruth( Map_SuperLib_t * pLib, char * pFormula, unsigned uTruthRes[] );
|
||||
static void Map_LibraryComputeTruth_rec( Map_SuperLib_t * pLib, char * pFormula, unsigned uTruthsIn[][2], unsigned uTruthRes[] );
|
||||
static void Map_LibraryPrintClasses( Map_SuperLib_t * p );
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Reads the supergate library from file.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Map_LibraryRead( Map_SuperLib_t * pLib, char * pFileName )
|
||||
{
|
||||
FILE * pFile;
|
||||
int Status;
|
||||
// read the beginning of the file
|
||||
assert( pLib->pGenlib == NULL );
|
||||
pFile = fopen( pFileName, "r" );
|
||||
if ( pFile == NULL )
|
||||
{
|
||||
printf( "Cannot open input file \"%s\".\n", pFileName );
|
||||
return 0;
|
||||
}
|
||||
Status = Map_LibraryReadFile( pLib, pFile );
|
||||
fclose( pFile );
|
||||
// Map_LibraryPrintClasses( pLib );
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Reads the library file.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Map_LibraryReadFile( Map_SuperLib_t * pLib, FILE * pFile )
|
||||
{
|
||||
ProgressBar * pProgress;
|
||||
char pBuffer[2000];
|
||||
FILE * pFileGen;
|
||||
Map_Super_t * pGate;
|
||||
char * pTemp, * pLibName;
|
||||
int nCounter, nGatesTotal;
|
||||
unsigned uCanon[2];
|
||||
|
||||
// skip empty and comment lines
|
||||
while ( fgets( pBuffer, 5000, pFile ) != NULL )
|
||||
{
|
||||
// skip leading spaces
|
||||
for ( pTemp = pBuffer; *pTemp == ' ' || *pTemp == '\r' || *pTemp == '\n'; pTemp++ );
|
||||
// skip comment lines and empty lines
|
||||
if ( *pTemp != 0 && *pTemp != '#' )
|
||||
break;
|
||||
}
|
||||
|
||||
// get the genlib file name
|
||||
pLibName = strtok( pTemp, " \t\r\n" );
|
||||
if ( strcmp( pLibName, "GATE" ) == 0 )
|
||||
{
|
||||
printf( "The input file \"%s\" looks like a GENLIB file and not a supergate library file.\n", pLib->pName );
|
||||
return 0;
|
||||
}
|
||||
pFileGen = fopen( pLibName, "r" );
|
||||
if ( pFileGen == NULL )
|
||||
{
|
||||
printf( "Cannot open the GENLIB file \"%s\".\n", pLibName );
|
||||
return 0;
|
||||
}
|
||||
fclose( pFileGen );
|
||||
|
||||
// read the genlib library
|
||||
pLib->pGenlib = Mio_LibraryRead( Abc_FrameGetGlobalFrame(), pLibName, 0, 0 );
|
||||
if ( pLib->pGenlib == NULL )
|
||||
{
|
||||
printf( "Cannot read GENLIB file \"%s\".\n", pLibName );
|
||||
return 0;
|
||||
}
|
||||
|
||||
// read the number of variables
|
||||
fscanf( pFile, "%d\n", &pLib->nVarsMax );
|
||||
if ( pLib->nVarsMax < 2 || pLib->nVarsMax > 10 )
|
||||
{
|
||||
printf( "Suspicious number of variables (%d).\n", pLib->nVarsMax );
|
||||
return 0;
|
||||
}
|
||||
|
||||
// read the number of gates
|
||||
fscanf( pFile, "%d\n", &nGatesTotal );
|
||||
if ( nGatesTotal < 1 || nGatesTotal > 10000000 )
|
||||
{
|
||||
printf( "Suspicious number of gates (%d).\n", nGatesTotal );
|
||||
return 0;
|
||||
}
|
||||
|
||||
// read the lines
|
||||
nCounter = 0;
|
||||
pProgress = Extra_ProgressBarStart( stdout, nGatesTotal );
|
||||
while ( fgets( pBuffer, 5000, pFile ) != NULL )
|
||||
{
|
||||
for ( pTemp = pBuffer; *pTemp == ' ' || *pTemp == '\r' || *pTemp == '\n'; pTemp++ );
|
||||
if ( pTemp[0] == '\0' )
|
||||
continue;
|
||||
// get the gate
|
||||
pGate = Map_LibraryReadGate( pLib, pTemp, pLib->nVarsMax );
|
||||
assert( pGate->Num == nCounter + 1 );
|
||||
// count the number of parantheses in the formula - this is the number of gates
|
||||
for ( pTemp = pGate->pFormula; *pTemp; pTemp++ )
|
||||
pGate->nGates += (*pTemp == '(');
|
||||
// verify the truth table
|
||||
assert( Map_LibraryTruthVerify(pLib, pGate) );
|
||||
|
||||
// find the N-canonical form of this supergate
|
||||
pGate->nPhases = Map_CanonComputeSlow( pLib->uTruths, pLib->nVarsMax, pLib->nVarsMax, pGate->uTruth, pGate->uPhases, uCanon );
|
||||
// add the supergate into the table by its N-canonical table
|
||||
Map_SuperTableInsertC( pLib->tTableC, uCanon, pGate );
|
||||
// update the progress bar
|
||||
Extra_ProgressBarUpdate( pProgress, ++nCounter, NULL );
|
||||
}
|
||||
Extra_ProgressBarStop( pProgress );
|
||||
pLib->nSupersAll = nCounter;
|
||||
if ( nCounter != nGatesTotal )
|
||||
printf( "The number of gates read (%d) is different what the file says (%d).\n", nGatesTotal, nCounter );
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Map_Super_t * Map_LibraryReadGate( Map_SuperLib_t * pLib, char * pBuffer, int nVars )
|
||||
{
|
||||
Map_Super_t * pGate;
|
||||
char * pTemp;
|
||||
int i;
|
||||
|
||||
// start and clean the gate
|
||||
pGate = (Map_Super_t *)Extra_MmFixedEntryFetch( pLib->mmSupers );
|
||||
memset( pGate, 0, sizeof(Map_Super_t) );
|
||||
|
||||
// read the number
|
||||
pTemp = strtok( pBuffer, " " );
|
||||
pGate->Num = atoi(pTemp);
|
||||
|
||||
// read the signature
|
||||
pTemp = strtok( NULL, " " );
|
||||
if ( pLib->nVarsMax < 6 )
|
||||
{
|
||||
pGate->uTruth[0] = Extra_ReadBinary(pTemp);
|
||||
pGate->uTruth[1] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
pGate->uTruth[0] = Extra_ReadBinary(pTemp+32);
|
||||
pTemp[32] = 0;
|
||||
pGate->uTruth[1] = Extra_ReadBinary(pTemp);
|
||||
}
|
||||
|
||||
// read the max delay
|
||||
pTemp = strtok( NULL, " " );
|
||||
pGate->tDelayMax.Rise = (float)atof(pTemp);
|
||||
pGate->tDelayMax.Fall = pGate->tDelayMax.Rise;
|
||||
|
||||
// read the pin-to-pin delay
|
||||
for ( i = 0; i < nVars; i++ )
|
||||
{
|
||||
pTemp = strtok( NULL, " " );
|
||||
pGate->tDelaysR[i].Rise = (float)atof(pTemp);
|
||||
pGate->tDelaysF[i].Fall = pGate->tDelaysR[i].Rise;
|
||||
}
|
||||
|
||||
// read the area
|
||||
pTemp = strtok( NULL, " " );
|
||||
pGate->Area = (float)atof(pTemp);
|
||||
|
||||
// the rest is the gate name
|
||||
pTemp = strtok( NULL, " \r\n" );
|
||||
if ( strlen(pTemp) == 0 )
|
||||
printf( "A gate name is empty.\n" );
|
||||
|
||||
// save the gate name
|
||||
pGate->pFormula = Extra_MmFlexEntryFetch( pLib->mmForms, strlen(pTemp) + 1 );
|
||||
strcpy( pGate->pFormula, pTemp );
|
||||
|
||||
// the rest is the gate name
|
||||
pTemp = strtok( NULL, " \n\0" );
|
||||
if ( pTemp != NULL )
|
||||
printf( "The following trailing symbols found \"%s\".\n", pTemp );
|
||||
return pGate;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Performs one step of parsing the formula into parts.]
|
||||
|
||||
Description [This function will eventually be replaced when the
|
||||
tree-supergate library representation will become standard.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
char * Map_LibraryReadFormulaStep( char * pFormula, char * pStrings[], int * pnStrings )
|
||||
{
|
||||
char * pName, * pPar1, * pPar2, * pCur;
|
||||
int nStrings, CountPars;
|
||||
|
||||
// skip leading spaces
|
||||
for ( pName = pFormula; *pName && *pName == ' '; pName++ );
|
||||
assert( *pName );
|
||||
// find the first opening paranthesis
|
||||
for ( pPar1 = pName; *pPar1 && *pPar1 != '('; pPar1++ );
|
||||
if ( *pPar1 == 0 )
|
||||
{
|
||||
*pnStrings = 0;
|
||||
return pName;
|
||||
}
|
||||
// overwrite it with space
|
||||
assert( *pPar1 == '(' );
|
||||
*pPar1 = 0;
|
||||
// find the corresponding closing paranthesis
|
||||
for ( CountPars = 1, pPar2 = pPar1 + 1; *pPar2 && CountPars; pPar2++ )
|
||||
if ( *pPar2 == '(' )
|
||||
CountPars++;
|
||||
else if ( *pPar2 == ')' )
|
||||
CountPars--;
|
||||
pPar2--;
|
||||
assert( CountPars == 0 );
|
||||
// overwrite it with space
|
||||
assert( *pPar2 == ')' );
|
||||
*pPar2 = 0;
|
||||
// save the intervals between the commas
|
||||
nStrings = 0;
|
||||
pCur = pPar1 + 1;
|
||||
while ( 1 )
|
||||
{
|
||||
// save the current string
|
||||
pStrings[ nStrings++ ] = pCur;
|
||||
// find the beginning of the next string
|
||||
for ( CountPars = 0; *pCur && (CountPars || *pCur != ','); pCur++ )
|
||||
if ( *pCur == '(' )
|
||||
CountPars++;
|
||||
else if ( *pCur == ')' )
|
||||
CountPars--;
|
||||
if ( *pCur == 0 )
|
||||
break;
|
||||
assert( *pCur == ',' );
|
||||
*pCur = 0;
|
||||
pCur++;
|
||||
}
|
||||
// save the results and return
|
||||
*pnStrings = nStrings;
|
||||
return pName;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Verifies the truth table of the supergate.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Map_LibraryTruthVerify( Map_SuperLib_t * pLib, Map_Super_t * pGate )
|
||||
{
|
||||
unsigned uTruthRes[2];
|
||||
Map_LibraryComputeTruth( pLib, pGate->pFormula, uTruthRes );
|
||||
if ( uTruthRes[0] != pGate->uTruth[0] || uTruthRes[1] != pGate->uTruth[1] )
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Derives the functionality of the supergate.]
|
||||
|
||||
Description [This procedure is useful for verification the supergate
|
||||
library. The truth table derived by this procedure should be the same
|
||||
as the one contained in the original supergate file.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Map_LibraryComputeTruth( Map_SuperLib_t * pLib, char * pFormula, unsigned uTruthRes[] )
|
||||
{
|
||||
char Buffer[1000];
|
||||
strcpy( Buffer, pFormula );
|
||||
Map_LibraryComputeTruth_rec( pLib, Buffer, pLib->uTruths, uTruthRes );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Derives the functionality of the supergate.]
|
||||
|
||||
Description [This procedure is useful for verification the supergate
|
||||
library. The truth table derived by this procedure should be the same
|
||||
as the one contained in the original supergate file.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Map_LibraryComputeTruth_rec( Map_SuperLib_t * pLib, char * pFormula, unsigned uTruthsIn[][2], unsigned uTruthRes[] )
|
||||
{
|
||||
Mio_Gate_t * pMioGate;
|
||||
char * pGateName, * pStrings[6];
|
||||
unsigned uTruthsFanins[6][2];
|
||||
int nStrings, i;
|
||||
|
||||
// perform one step parsing of the formula
|
||||
// detect the root gate name, the next-step strings, and their number
|
||||
pGateName = Map_LibraryReadFormulaStep( pFormula, pStrings, &nStrings );
|
||||
if ( nStrings == 0 ) // elementary variable
|
||||
{
|
||||
assert( pGateName[0] - 'a' < pLib->nVarsMax );
|
||||
uTruthRes[0] = uTruthsIn[pGateName[0] - 'a'][0];
|
||||
uTruthRes[1] = uTruthsIn[pGateName[0] - 'a'][1];
|
||||
return;
|
||||
}
|
||||
// derive the functionality of the fanins
|
||||
for ( i = 0; i < nStrings; i++ )
|
||||
Map_LibraryComputeTruth_rec( pLib, pStrings[i], uTruthsIn, uTruthsFanins[i] );
|
||||
// get the root supergate
|
||||
pMioGate = Mio_LibraryReadGateByName( pLib->pGenlib, pGateName );
|
||||
if ( pMioGate == NULL )
|
||||
printf( "A supergate contains gate \"%s\" that is not in \"%s\".\n", pGateName, Mio_LibraryReadName(pLib->pGenlib) );
|
||||
// derive the functionality of the output of the supergate
|
||||
Mio_DeriveTruthTable( pMioGate, uTruthsFanins, nStrings, pLib->nVarsMax, uTruthRes );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Map_LibraryPrintSupergate( Map_Super_t * pGate )
|
||||
{
|
||||
printf( "%5d : ", pGate->nUsed );
|
||||
printf( "%5d ", pGate->Num );
|
||||
printf( "A = %5.2f ", pGate->Area );
|
||||
printf( "D = %5.2f ", pGate->tDelayMax );
|
||||
printf( "%s", pGate->pFormula );
|
||||
printf( "\n" );
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Prints N-classes of supergates.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Map_LibraryPrintClasses( Map_SuperLib_t * p )
|
||||
{
|
||||
/*
|
||||
st_generator * gen;
|
||||
Map_Super_t * pSuper, * pSuper2;
|
||||
unsigned Key, uTruth;
|
||||
int Counter = 0;
|
||||
// copy all the supergates into one array
|
||||
st_foreach_item( p->tSuplib, gen, (char **)&Key, (char **)&pSuper )
|
||||
{
|
||||
for ( pSuper2 = pSuper; pSuper2; pSuper2 = pSuper2->pNext )
|
||||
{
|
||||
uTruth = pSuper2->Phase;
|
||||
Extra_PrintBinary( stdout, &uTruth, 5 );
|
||||
printf( " %5d ", pSuper2->Num );
|
||||
printf( "%s", pSuper2->pFormula );
|
||||
printf( "\n" );
|
||||
}
|
||||
printf( "\n" );
|
||||
if ( ++ Counter == 100 )
|
||||
break;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
@@ -1,223 +0,0 @@
|
||||
/**CFile****************************************************************
|
||||
|
||||
FileName [mapperSwitch.c]
|
||||
|
||||
PackageName [MVSIS 1.3: Multi-valued logic synthesis system.]
|
||||
|
||||
Synopsis [Generic technology mapping engine.]
|
||||
|
||||
Author [MVSIS Group]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - September 8, 2003.]
|
||||
|
||||
Revision [$Id: mapperSwitch.h,v 1.0 2003/09/08 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "mapperInt.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static float Map_SwitchCutRefDeref( Map_Node_t * pNode, Map_Cut_t * pCut, int fPhase, int fReference );
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**function*************************************************************
|
||||
|
||||
synopsis [Computes the exact area associated with the cut.]
|
||||
|
||||
description []
|
||||
|
||||
sideeffects []
|
||||
|
||||
seealso []
|
||||
|
||||
***********************************************************************/
|
||||
float Map_SwitchCutGetDerefed( Map_Node_t * pNode, Map_Cut_t * pCut, int fPhase )
|
||||
{
|
||||
float aResult, aResult2;
|
||||
// assert( pNode->Switching > 0 );
|
||||
aResult2 = Map_SwitchCutRefDeref( pNode, pCut, fPhase, 1 ); // reference
|
||||
aResult = Map_SwitchCutRefDeref( pNode, pCut, fPhase, 0 ); // dereference
|
||||
// assert( aResult == aResult2 );
|
||||
return aResult;
|
||||
}
|
||||
|
||||
/**function*************************************************************
|
||||
|
||||
synopsis [References the cut.]
|
||||
|
||||
description []
|
||||
|
||||
sideeffects []
|
||||
|
||||
seealso []
|
||||
|
||||
***********************************************************************/
|
||||
float Map_SwitchCutRef( Map_Node_t * pNode, Map_Cut_t * pCut, int fPhase )
|
||||
{
|
||||
return Map_SwitchCutRefDeref( pNode, pCut, fPhase, 1 ); // reference
|
||||
}
|
||||
|
||||
/**function*************************************************************
|
||||
|
||||
synopsis [References the cut.]
|
||||
|
||||
description []
|
||||
|
||||
sideeffects []
|
||||
|
||||
seealso []
|
||||
|
||||
***********************************************************************/
|
||||
float Map_SwitchCutDeref( Map_Node_t * pNode, Map_Cut_t * pCut, int fPhase )
|
||||
{
|
||||
return Map_SwitchCutRefDeref( pNode, pCut, fPhase, 0 ); // dereference
|
||||
}
|
||||
|
||||
/**function*************************************************************
|
||||
|
||||
synopsis [References or dereferences the cut.]
|
||||
|
||||
description [This reference part is similar to Cudd_NodeReclaim().
|
||||
The dereference part is similar to Cudd_RecursiveDeref().]
|
||||
|
||||
sideeffects []
|
||||
|
||||
seealso []
|
||||
|
||||
***********************************************************************/
|
||||
float Map_SwitchCutRefDeref( Map_Node_t * pNode, Map_Cut_t * pCut, int fPhase, int fReference )
|
||||
{
|
||||
Map_Node_t * pNodeChild;
|
||||
Map_Cut_t * pCutChild;
|
||||
float aSwitchActivity;
|
||||
int i, fPhaseChild;
|
||||
|
||||
// start switching activity for the node
|
||||
aSwitchActivity = pNode->Switching;
|
||||
// consider the elementary variable
|
||||
if ( pCut->nLeaves == 1 )
|
||||
return aSwitchActivity;
|
||||
|
||||
// go through the children
|
||||
assert( pCut->M[fPhase].pSuperBest );
|
||||
for ( i = 0; i < pCut->nLeaves; i++ )
|
||||
{
|
||||
pNodeChild = pCut->ppLeaves[i];
|
||||
fPhaseChild = Map_CutGetLeafPhase( pCut, fPhase, i );
|
||||
// get the reference counter of the child
|
||||
|
||||
if ( fReference )
|
||||
{
|
||||
if ( pNodeChild->pCutBest[0] && pNodeChild->pCutBest[1] ) // both phases are present
|
||||
{
|
||||
// if this phase of the node is referenced, there is no recursive call
|
||||
pNodeChild->nRefAct[2]++;
|
||||
if ( pNodeChild->nRefAct[fPhaseChild]++ > 0 )
|
||||
continue;
|
||||
}
|
||||
else // only one phase is present
|
||||
{
|
||||
// inverter should be added if the phase
|
||||
// (a) has no reference and (b) is implemented using other phase
|
||||
if ( pNodeChild->nRefAct[fPhaseChild]++ == 0 && pNodeChild->pCutBest[fPhaseChild] == NULL )
|
||||
aSwitchActivity += pNodeChild->Switching; // inverter switches the same as the node
|
||||
// if the node is referenced, there is no recursive call
|
||||
if ( pNodeChild->nRefAct[2]++ > 0 )
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( pNodeChild->pCutBest[0] && pNodeChild->pCutBest[1] ) // both phases are present
|
||||
{
|
||||
// if this phase of the node is referenced, there is no recursive call
|
||||
--pNodeChild->nRefAct[2];
|
||||
if ( --pNodeChild->nRefAct[fPhaseChild] > 0 )
|
||||
continue;
|
||||
}
|
||||
else // only one phase is present
|
||||
{
|
||||
// inverter should be added if the phase
|
||||
// (a) has no reference and (b) is implemented using other phase
|
||||
if ( --pNodeChild->nRefAct[fPhaseChild] == 0 && pNodeChild->pCutBest[fPhaseChild] == NULL )
|
||||
aSwitchActivity += pNodeChild->Switching; // inverter switches the same as the node
|
||||
// if the node is referenced, there is no recursive call
|
||||
if ( --pNodeChild->nRefAct[2] > 0 )
|
||||
continue;
|
||||
}
|
||||
assert( pNodeChild->nRefAct[fPhaseChild] >= 0 );
|
||||
}
|
||||
|
||||
// get the child cut
|
||||
pCutChild = pNodeChild->pCutBest[fPhaseChild];
|
||||
// if the child does not have this phase mapped, take the opposite phase
|
||||
if ( pCutChild == NULL )
|
||||
{
|
||||
fPhaseChild = !fPhaseChild;
|
||||
pCutChild = pNodeChild->pCutBest[fPhaseChild];
|
||||
}
|
||||
// reference and compute area recursively
|
||||
aSwitchActivity += Map_SwitchCutRefDeref( pNodeChild, pCutChild, fPhaseChild, fReference );
|
||||
}
|
||||
return aSwitchActivity;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes the array of mapping.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
float Map_MappingGetSwitching( Map_Man_t * pMan, Map_NodeVec_t * vMapping )
|
||||
{
|
||||
Map_Node_t * pNode;
|
||||
float Switch;
|
||||
int i;
|
||||
Switch = 0.0;
|
||||
for ( i = 0; i < vMapping->nSize; i++ )
|
||||
{
|
||||
pNode = vMapping->pArray[i];
|
||||
// at least one phase has the best cut assigned
|
||||
assert( pNode->pCutBest[0] != NULL || pNode->pCutBest[1] != NULL );
|
||||
// at least one phase is used in the mapping
|
||||
assert( pNode->nRefAct[0] > 0 || pNode->nRefAct[1] > 0 );
|
||||
// compute the array due to the supergate
|
||||
if ( Map_NodeIsAnd(pNode) )
|
||||
{
|
||||
// count switching of the negative phase
|
||||
if ( pNode->pCutBest[0] && (pNode->nRefAct[0] > 0 || pNode->pCutBest[1] == NULL) )
|
||||
Switch += pNode->Switching;
|
||||
// count switching of the positive phase
|
||||
if ( pNode->pCutBest[1] && (pNode->nRefAct[1] > 0 || pNode->pCutBest[0] == NULL) )
|
||||
Switch += pNode->Switching;
|
||||
}
|
||||
// count switching of the interver if we need to implement one phase with another phase
|
||||
if ( (pNode->pCutBest[0] == NULL && pNode->nRefAct[0] > 0) ||
|
||||
(pNode->pCutBest[1] == NULL && pNode->nRefAct[1] > 0) )
|
||||
Switch += pNode->Switching; // inverter switches the same as the node
|
||||
}
|
||||
// add buffers for each CO driven by a CI
|
||||
for ( i = 0; i < pMan->nOutputs; i++ )
|
||||
if ( Map_NodeIsVar(pMan->pOutputs[i]) && !Map_IsComplement(pMan->pOutputs[i]) )
|
||||
Switch += pMan->pOutputs[i]->Switching;
|
||||
return Switch;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
@@ -1,402 +0,0 @@
|
||||
/**CFile****************************************************************
|
||||
|
||||
FileName [mapperTable.c]
|
||||
|
||||
PackageName [MVSIS 1.3: Multi-valued logic synthesis system.]
|
||||
|
||||
Synopsis [Generic technology mapping engine.]
|
||||
|
||||
Author [MVSIS Group]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 2.0. Started - June 1, 2004.]
|
||||
|
||||
Revision [$Id: mapperTable.c,v 1.6 2005/01/23 06:59:44 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "mapperInt.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// the table function for the tables
|
||||
#define MAP_TABLE_HASH(u1,u2,nSize) (((u1) + 2003 * (u2)) % nSize)
|
||||
|
||||
static void Map_SuperTableResize( Map_HashTable_t * pLib );
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Creates the hash table for supergates.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Map_HashTable_t * Map_SuperTableCreate( Map_SuperLib_t * pLib )
|
||||
{
|
||||
Map_HashTable_t * p;
|
||||
// allocate the table
|
||||
p = ALLOC( Map_HashTable_t, 1 );
|
||||
memset( p, 0, sizeof(Map_HashTable_t) );
|
||||
p->mmMan = pLib->mmEntries;
|
||||
// allocate and clean the bins
|
||||
p->nBins = Cudd_Prime(20000);
|
||||
p->pBins = ALLOC( Map_HashEntry_t *, p->nBins );
|
||||
memset( p->pBins, 0, sizeof(Map_HashEntry_t *) * p->nBins );
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Deallocates the supergate hash table.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Map_SuperTableFree( Map_HashTable_t * p )
|
||||
{
|
||||
FREE( p->pBins );
|
||||
FREE( p );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Inserts a new entry into the hash table.]
|
||||
|
||||
Description [This function inserts the new gate (pGate), which will be
|
||||
accessible through its canonical form (uTruthC).]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Map_SuperTableInsertC( Map_HashTable_t * p, unsigned uTruthC[], Map_Super_t * pGate )
|
||||
{
|
||||
Map_HashEntry_t * pEnt;
|
||||
unsigned Key;
|
||||
// resize the table
|
||||
if ( p->nEntries >= 2 * p->nBins )
|
||||
Map_SuperTableResize( p );
|
||||
// check if another supergate with the same canonical form exists
|
||||
Key = MAP_TABLE_HASH( uTruthC[0], uTruthC[1], p->nBins );
|
||||
for ( pEnt = p->pBins[Key]; pEnt; pEnt = pEnt->pNext )
|
||||
if ( pEnt->uTruth[0] == uTruthC[0] && pEnt->uTruth[1] == uTruthC[1] )
|
||||
break;
|
||||
// create a new entry if it does not exist
|
||||
if ( pEnt == NULL )
|
||||
{
|
||||
// add the new entry to the table
|
||||
pEnt = (Map_HashEntry_t *)Extra_MmFixedEntryFetch( p->mmMan );
|
||||
memset( pEnt, 0, sizeof(Map_HashEntry_t) );
|
||||
pEnt->uTruth[0] = uTruthC[0];
|
||||
pEnt->uTruth[1] = uTruthC[1];
|
||||
// add the hash table entry to the corresponding linked list in the table
|
||||
pEnt->pNext = p->pBins[Key];
|
||||
p->pBins[Key] = pEnt;
|
||||
p->nEntries++;
|
||||
}
|
||||
// add the supergate to the entry
|
||||
pGate->pNext = pEnt->pGates;
|
||||
pEnt->pGates = pGate;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Inserts a new entry into the library.]
|
||||
|
||||
Description [This function inserts the new gate (pGate), which will be
|
||||
accessible through its unfolded function (uTruth).]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Map_SuperTableInsert( Map_HashTable_t * p, unsigned uTruth[], Map_Super_t * pGate, unsigned uPhase )
|
||||
{
|
||||
Map_HashEntry_t * pEnt;
|
||||
unsigned Key;
|
||||
// resize the table
|
||||
if ( p->nEntries >= 2 * p->nBins )
|
||||
Map_SuperTableResize( p );
|
||||
// check if this entry already exists
|
||||
Key = MAP_TABLE_HASH( uTruth[0], uTruth[1], p->nBins );
|
||||
for ( pEnt = p->pBins[Key]; pEnt; pEnt = pEnt->pNext )
|
||||
if ( pEnt->uTruth[0] == uTruth[0] && pEnt->uTruth[1] == uTruth[1] )
|
||||
return 1;
|
||||
// add the new hash table entry to the table
|
||||
pEnt = (Map_HashEntry_t *)Extra_MmFixedEntryFetch( p->mmMan );
|
||||
memset( pEnt, 0, sizeof(Map_HashEntry_t) );
|
||||
pEnt->uTruth[0] = uTruth[0];
|
||||
pEnt->uTruth[1] = uTruth[1];
|
||||
pEnt->pGates = pGate;
|
||||
pEnt->uPhase = uPhase;
|
||||
// add the hash table to the corresponding linked list in the table
|
||||
pEnt->pNext = p->pBins[Key];
|
||||
p->pBins[Key] = pEnt;
|
||||
p->nEntries++;
|
||||
/*
|
||||
printf( "Adding gate: %10u ", Key );
|
||||
Map_LibraryPrintSupergate( pGate );
|
||||
Extra_PrintBinary( stdout, uTruth, 32 );
|
||||
printf( "\n" );
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Looks up an entry in the library.]
|
||||
|
||||
Description [This function looks up the function, given by its truth table,
|
||||
and return two things: (1) the linked list of supergates, which can implement
|
||||
the functions of this N-class; (2) the phase, which should be applied to the
|
||||
given function, in order to derive the canonical form of this N-class.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Map_Super_t * Map_SuperTableLookupC( Map_SuperLib_t * p, unsigned uTruth[] )
|
||||
{
|
||||
Map_HashEntry_t * pEnt;
|
||||
unsigned Key;
|
||||
Key = MAP_TABLE_HASH( uTruth[0], uTruth[1], p->tTableC->nBins );
|
||||
for ( pEnt = p->tTableC->pBins[Key]; pEnt; pEnt = pEnt->pNext )
|
||||
if ( pEnt->uTruth[0] == uTruth[0] && pEnt->uTruth[1] == uTruth[1] )
|
||||
return pEnt->pGates;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Looks up an entry in the library.]
|
||||
|
||||
Description [This function looks up the function, given by its truth table,
|
||||
and return two things: (1) the linked list of supergates, which can implement
|
||||
the functions of this N-class; (2) the phase, which should be applied to the
|
||||
given function, in order to derive the canonical form of this N-class.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Map_Super_t * Map_SuperTableLookup( Map_HashTable_t * p, unsigned uTruth[], unsigned * puPhase )
|
||||
{
|
||||
Map_HashEntry_t * pEnt;
|
||||
unsigned Key;
|
||||
Key = MAP_TABLE_HASH( uTruth[0], uTruth[1], p->nBins );
|
||||
for ( pEnt = p->pBins[Key]; pEnt; pEnt = pEnt->pNext )
|
||||
if ( pEnt->uTruth[0] == uTruth[0] && pEnt->uTruth[1] == uTruth[1] )
|
||||
{
|
||||
*puPhase = pEnt->uPhase;
|
||||
return pEnt->pGates;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Resizes the table.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Map_SuperTableResize( Map_HashTable_t * p )
|
||||
{
|
||||
Map_HashEntry_t ** pBinsNew;
|
||||
Map_HashEntry_t * pEnt, * pEnt2;
|
||||
int nBinsNew, Counter, i, clk = clock();
|
||||
unsigned Key;
|
||||
// get the new table size
|
||||
nBinsNew = Cudd_Prime(2 * p->nBins);
|
||||
// allocate a new array
|
||||
pBinsNew = ALLOC( Map_HashEntry_t *, nBinsNew );
|
||||
memset( pBinsNew, 0, sizeof(Map_HashEntry_t *) * nBinsNew );
|
||||
// rehash the entries from the old table
|
||||
Counter = 0;
|
||||
for ( i = 0; i < p->nBins; i++ )
|
||||
for ( pEnt = p->pBins[i], pEnt2 = pEnt? pEnt->pNext: NULL; pEnt;
|
||||
pEnt = pEnt2, pEnt2 = pEnt? pEnt->pNext: NULL )
|
||||
{
|
||||
Key = MAP_TABLE_HASH( pEnt->uTruth[0], pEnt->uTruth[1], nBinsNew );
|
||||
pEnt->pNext = pBinsNew[Key];
|
||||
pBinsNew[Key] = pEnt;
|
||||
Counter++;
|
||||
}
|
||||
assert( Counter == p->nEntries );
|
||||
// replace the table and the parameters
|
||||
free( p->pBins );
|
||||
p->pBins = pBinsNew;
|
||||
p->nBins = nBinsNew;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Compares the supergates by the number of times they are used.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Map_SuperTableCompareSupergates( Map_Super_t ** ppS1, Map_Super_t ** ppS2 )
|
||||
{
|
||||
if ( (*ppS1)->nUsed > (*ppS2)->nUsed )
|
||||
return -1;
|
||||
if ( (*ppS1)->nUsed < (*ppS2)->nUsed )
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Compares the supergates by the number of times they are used.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Map_SuperTableCompareGatesInList( Map_Super_t ** ppS1, Map_Super_t ** ppS2 )
|
||||
{
|
||||
// if ( (*ppS1)->tDelayMax.Rise > (*ppS2)->tDelayMax.Rise )
|
||||
if ( (*ppS1)->Area > (*ppS2)->Area )
|
||||
return -1;
|
||||
// if ( (*ppS1)->tDelayMax.Rise < (*ppS2)->tDelayMax.Rise )
|
||||
if ( (*ppS1)->Area < (*ppS2)->Area )
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Sorts supergates by usefulness and prints out most useful.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Map_SuperTableSortSupergates( Map_HashTable_t * p, int nSupersMax )
|
||||
{
|
||||
Map_HashEntry_t * pEnt;
|
||||
Map_Super_t ** ppSupers;
|
||||
Map_Super_t * pSuper;
|
||||
int nSupers, i;
|
||||
|
||||
// copy all the supergates into one array
|
||||
ppSupers = ALLOC( Map_Super_t *, nSupersMax );
|
||||
nSupers = 0;
|
||||
for ( i = 0; i < p->nBins; i++ )
|
||||
for ( pEnt = p->pBins[i]; pEnt; pEnt = pEnt->pNext )
|
||||
for ( pSuper = pEnt->pGates; pSuper; pSuper = pSuper->pNext )
|
||||
ppSupers[nSupers++] = pSuper;
|
||||
|
||||
// sort by usage
|
||||
qsort( (void *)ppSupers, nSupers, sizeof(Map_Super_t *),
|
||||
(int (*)(const void *, const void *)) Map_SuperTableCompareSupergates );
|
||||
assert( Map_SuperTableCompareSupergates( ppSupers, ppSupers + nSupers - 1 ) <= 0 );
|
||||
|
||||
// print out the "top ten"
|
||||
// for ( i = 0; i < nSupers; i++ )
|
||||
for ( i = 0; i < 10; i++ )
|
||||
{
|
||||
if ( ppSupers[i]->nUsed == 0 )
|
||||
break;
|
||||
printf( "%5d : ", ppSupers[i]->nUsed );
|
||||
printf( "%5d ", ppSupers[i]->Num );
|
||||
printf( "A = %5.2f ", ppSupers[i]->Area );
|
||||
printf( "D = %5.2f ", ppSupers[i]->tDelayMax.Rise );
|
||||
printf( "%s", ppSupers[i]->pFormula );
|
||||
printf( "\n" );
|
||||
}
|
||||
free( ppSupers );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Sorts supergates by max delay for each truth table.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Map_SuperTableSortSupergatesByDelay( Map_HashTable_t * p, int nSupersMax )
|
||||
{
|
||||
Map_HashEntry_t * pEnt;
|
||||
Map_Super_t ** ppSupers;
|
||||
Map_Super_t * pSuper;
|
||||
int nSupers, i, k;
|
||||
|
||||
ppSupers = ALLOC( Map_Super_t *, nSupersMax );
|
||||
for ( i = 0; i < p->nBins; i++ )
|
||||
for ( pEnt = p->pBins[i]; pEnt; pEnt = pEnt->pNext )
|
||||
{
|
||||
// collect the gates in this entry
|
||||
nSupers = 0;
|
||||
for ( pSuper = pEnt->pGates; pSuper; pSuper = pSuper->pNext )
|
||||
{
|
||||
// skip supergates, whose root is the AND gate
|
||||
// if ( strcmp( Mio_GateReadName(pSuper->pRoot), "and" ) == 0 )
|
||||
// continue;
|
||||
ppSupers[nSupers++] = pSuper;
|
||||
}
|
||||
pEnt->pGates = NULL;
|
||||
if ( nSupers == 0 )
|
||||
continue;
|
||||
// sort the gates by delay
|
||||
qsort( (void *)ppSupers, nSupers, sizeof(Map_Super_t *),
|
||||
(int (*)(const void *, const void *)) Map_SuperTableCompareGatesInList );
|
||||
assert( Map_SuperTableCompareGatesInList( ppSupers, ppSupers + nSupers - 1 ) <= 0 );
|
||||
// link them in the reverse order
|
||||
for ( k = 0; k < nSupers; k++ )
|
||||
{
|
||||
ppSupers[k]->pNext = pEnt->pGates;
|
||||
pEnt->pGates = ppSupers[k];
|
||||
}
|
||||
// save the number of supergates in the list
|
||||
pEnt->pGates->nSupers = nSupers;
|
||||
}
|
||||
FREE( ppSupers );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
@@ -1,510 +0,0 @@
|
||||
/**CFile****************************************************************
|
||||
|
||||
FileName [mapperTime.c]
|
||||
|
||||
PackageName [MVSIS 1.3: Multi-valued logic synthesis system.]
|
||||
|
||||
Synopsis [Generic technology mapping engine.]
|
||||
|
||||
Author [MVSIS Group]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 2.0. Started - June 1, 2004.]
|
||||
|
||||
Revision [$Id: mapperTime.c,v 1.3 2005/03/02 02:35:54 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "mapperInt.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static void Map_TimePropagateRequired( Map_Man_t * p, Map_NodeVec_t * vNodes );
|
||||
static void Map_TimePropagateRequiredPhase( Map_Man_t * p, Map_Node_t * pNode, int fPhase );
|
||||
static float Map_MatchComputeReqTimes( Map_Cut_t * pCut, int fPhase, Map_Time_t * ptArrRes );
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**function*************************************************************
|
||||
|
||||
synopsis [Computes the exact area associated with the cut.]
|
||||
|
||||
description []
|
||||
|
||||
sideeffects []
|
||||
|
||||
seealso []
|
||||
|
||||
***********************************************************************/
|
||||
float Map_TimeMatchWithInverter( Map_Man_t * p, Map_Match_t * pMatch )
|
||||
{
|
||||
Map_Time_t tArrInv;
|
||||
tArrInv.Fall = pMatch->tArrive.Rise + p->pSuperLib->tDelayInv.Fall;
|
||||
tArrInv.Rise = pMatch->tArrive.Fall + p->pSuperLib->tDelayInv.Rise;
|
||||
tArrInv.Worst = MAP_MAX( tArrInv.Rise, tArrInv.Fall );
|
||||
return tArrInv.Worst;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes the arrival times of the cut recursively.]
|
||||
|
||||
Description [When computing the arrival time for the previously unused
|
||||
cuts, their arrival time may be incorrect because their fanins have
|
||||
incorrect arrival time. This procedure is called to fix this problem.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Map_TimeCutComputeArrival_rec( Map_Cut_t * pCut, int fPhase )
|
||||
{
|
||||
int i, fPhaseLeaf;
|
||||
for ( i = 0; i < pCut->nLeaves; i++ )
|
||||
{
|
||||
fPhaseLeaf = Map_CutGetLeafPhase( pCut, fPhase, i );
|
||||
if ( pCut->ppLeaves[i]->nRefAct[fPhaseLeaf] > 0 )
|
||||
continue;
|
||||
Map_TimeCutComputeArrival_rec( pCut->ppLeaves[i]->pCutBest[fPhaseLeaf], fPhaseLeaf );
|
||||
}
|
||||
Map_TimeCutComputeArrival( NULL, pCut, fPhase, MAP_FLOAT_LARGE );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes the arrival times of the cut.]
|
||||
|
||||
Description [Computes the arrival times of the cut if it is implemented using
|
||||
the given supergate with the given phase. Uses the constraint-type specification
|
||||
of rise/fall arrival times.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
float Map_TimeCutComputeArrival( Map_Node_t * pNode, Map_Cut_t * pCut, int fPhase, float tWorstLimit )
|
||||
{
|
||||
Map_Match_t * pM = pCut->M + fPhase;
|
||||
Map_Super_t * pSuper = pM->pSuperBest;
|
||||
unsigned uPhaseTot = pM->uPhaseBest;
|
||||
Map_Time_t * ptArrRes = &pM->tArrive;
|
||||
Map_Time_t * ptArrIn;
|
||||
bool fPinPhase;
|
||||
float tDelay;
|
||||
int i;
|
||||
|
||||
ptArrRes->Rise = ptArrRes->Fall = 0.0;
|
||||
ptArrRes->Worst = MAP_FLOAT_LARGE;
|
||||
for ( i = pCut->nLeaves - 1; i >= 0; i-- )
|
||||
{
|
||||
// get the phase of the given pin
|
||||
fPinPhase = ((uPhaseTot & (1 << i)) == 0);
|
||||
ptArrIn = pCut->ppLeaves[i]->tArrival + fPinPhase;
|
||||
|
||||
// get the rise of the output due to rise of the inputs
|
||||
if ( pSuper->tDelaysR[i].Rise > 0 )
|
||||
{
|
||||
tDelay = ptArrIn->Rise + pSuper->tDelaysR[i].Rise;
|
||||
if ( tDelay > tWorstLimit )
|
||||
return MAP_FLOAT_LARGE;
|
||||
if ( ptArrRes->Rise < tDelay )
|
||||
ptArrRes->Rise = tDelay;
|
||||
}
|
||||
|
||||
// get the rise of the output due to fall of the inputs
|
||||
if ( pSuper->tDelaysR[i].Fall > 0 )
|
||||
{
|
||||
tDelay = ptArrIn->Fall + pSuper->tDelaysR[i].Fall;
|
||||
if ( tDelay > tWorstLimit )
|
||||
return MAP_FLOAT_LARGE;
|
||||
if ( ptArrRes->Rise < tDelay )
|
||||
ptArrRes->Rise = tDelay;
|
||||
}
|
||||
|
||||
// get the fall of the output due to rise of the inputs
|
||||
if ( pSuper->tDelaysF[i].Rise > 0 )
|
||||
{
|
||||
tDelay = ptArrIn->Rise + pSuper->tDelaysF[i].Rise;
|
||||
if ( tDelay > tWorstLimit )
|
||||
return MAP_FLOAT_LARGE;
|
||||
if ( ptArrRes->Fall < tDelay )
|
||||
ptArrRes->Fall = tDelay;
|
||||
}
|
||||
|
||||
// get the fall of the output due to fall of the inputs
|
||||
if ( pSuper->tDelaysF[i].Fall > 0 )
|
||||
{
|
||||
tDelay = ptArrIn->Fall + pSuper->tDelaysF[i].Fall;
|
||||
if ( tDelay > tWorstLimit )
|
||||
return MAP_FLOAT_LARGE;
|
||||
if ( ptArrRes->Fall < tDelay )
|
||||
ptArrRes->Fall = tDelay;
|
||||
}
|
||||
}
|
||||
// return the worst-case of rise/fall arrival times
|
||||
ptArrRes->Worst = MAP_MAX(ptArrRes->Rise, ptArrRes->Fall);
|
||||
return ptArrRes->Worst;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes the maximum arrival times.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
float Map_TimeComputeArrivalMax( Map_Man_t * p )
|
||||
{
|
||||
float tReqMax, tReq;
|
||||
int i, fPhase;
|
||||
// get the critical PO arrival time
|
||||
tReqMax = -MAP_FLOAT_LARGE;
|
||||
for ( i = 0; i < p->nOutputs; i++ )
|
||||
{
|
||||
if ( Map_NodeIsConst(p->pOutputs[i]) )
|
||||
continue;
|
||||
fPhase = !Map_IsComplement(p->pOutputs[i]);
|
||||
tReq = Map_Regular(p->pOutputs[i])->tArrival[fPhase].Worst;
|
||||
tReqMax = MAP_MAX( tReqMax, tReq );
|
||||
}
|
||||
return tReqMax;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes the required times of all nodes.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Map_TimeComputeRequiredGlobal( Map_Man_t * p )
|
||||
{
|
||||
p->fRequiredGlo = Map_TimeComputeArrivalMax( p );
|
||||
// update the required times according to the target
|
||||
if ( p->DelayTarget != -1 )
|
||||
{
|
||||
if ( p->fRequiredGlo > p->DelayTarget + p->fEpsilon )
|
||||
{
|
||||
if ( p->fMappingMode == 1 )
|
||||
printf( "Cannot meet the target required times (%4.2f). Continue anyway.\n", p->DelayTarget );
|
||||
}
|
||||
else if ( p->fRequiredGlo < p->DelayTarget - p->fEpsilon )
|
||||
{
|
||||
if ( p->fMappingMode == 1 )
|
||||
printf( "Relaxing the required times from (%4.2f) to the target (%4.2f).\n", p->fRequiredGlo, p->DelayTarget );
|
||||
p->fRequiredGlo = p->DelayTarget;
|
||||
}
|
||||
}
|
||||
Map_TimeComputeRequired( p, p->fRequiredGlo );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes the required times of all nodes.]
|
||||
|
||||
Description [This procedure assumes that the nodes used in the mapping
|
||||
are collected in p->vMapping.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Map_TimeComputeRequired( Map_Man_t * p, float fRequired )
|
||||
{
|
||||
Map_Time_t * ptTime;
|
||||
int fPhase, i;
|
||||
|
||||
// clean the required times
|
||||
for ( i = 0; i < p->vAnds->nSize; i++ )
|
||||
{
|
||||
p->vAnds->pArray[i]->tRequired[0].Rise = MAP_FLOAT_LARGE;
|
||||
p->vAnds->pArray[i]->tRequired[0].Fall = MAP_FLOAT_LARGE;
|
||||
p->vAnds->pArray[i]->tRequired[0].Worst = MAP_FLOAT_LARGE;
|
||||
p->vAnds->pArray[i]->tRequired[1].Rise = MAP_FLOAT_LARGE;
|
||||
p->vAnds->pArray[i]->tRequired[1].Fall = MAP_FLOAT_LARGE;
|
||||
p->vAnds->pArray[i]->tRequired[1].Worst = MAP_FLOAT_LARGE;
|
||||
}
|
||||
|
||||
// set the required times for the POs
|
||||
for ( i = 0; i < p->nOutputs; i++ )
|
||||
{
|
||||
fPhase = !Map_IsComplement(p->pOutputs[i]);
|
||||
ptTime = Map_Regular(p->pOutputs[i])->tRequired + fPhase;
|
||||
ptTime->Rise = ptTime->Fall = ptTime->Worst = fRequired;
|
||||
}
|
||||
|
||||
// sorts the nodes in the decreasing order of levels
|
||||
// this puts the nodes in reverse topological order
|
||||
// Map_MappingSortByLevel( p, p->vMapping );
|
||||
// the array is already sorted by construction in Map_MappingSetRefs()
|
||||
|
||||
Map_TimePropagateRequired( p, p->vMapping );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes the required times of the given nodes.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Map_TimePropagateRequired( Map_Man_t * p, Map_NodeVec_t * vNodes )
|
||||
{
|
||||
Map_Node_t * pNode;
|
||||
Map_Time_t tReqOutTest, * ptReqOutTest = &tReqOutTest;
|
||||
Map_Time_t * ptReqIn, * ptReqOut;
|
||||
int fPhase, k;
|
||||
|
||||
// go through the nodes in the reverse topological order
|
||||
for ( k = 0; k < vNodes->nSize; k++ )
|
||||
{
|
||||
pNode = vNodes->pArray[k];
|
||||
|
||||
// this computation works for regular nodes only
|
||||
assert( !Map_IsComplement(pNode) );
|
||||
// at least one phase should be mapped
|
||||
assert( pNode->pCutBest[0] != NULL || pNode->pCutBest[1] != NULL );
|
||||
// the node should be used in the currently assigned mapping
|
||||
assert( pNode->nRefAct[0] > 0 || pNode->nRefAct[1] > 0 );
|
||||
|
||||
// if one of the cuts is not given, project the required times from the other cut
|
||||
if ( pNode->pCutBest[0] == NULL || pNode->pCutBest[1] == NULL )
|
||||
{
|
||||
// assert( 0 );
|
||||
// get the missing phase
|
||||
fPhase = (pNode->pCutBest[1] == NULL);
|
||||
// check if the missing phase is needed in the mapping
|
||||
if ( pNode->nRefAct[fPhase] > 0 )
|
||||
{
|
||||
// get the pointers to the required times of the missing phase
|
||||
ptReqOut = pNode->tRequired + fPhase;
|
||||
// assert( ptReqOut->Fall < MAP_FLOAT_LARGE );
|
||||
// get the pointers to the required times of the present phase
|
||||
ptReqIn = pNode->tRequired + !fPhase;
|
||||
// propagate the required times from the missing phase to the present phase
|
||||
// tArrInv.Fall = pMatch->tArrive.Rise + p->pSuperLib->tDelayInv.Fall;
|
||||
// tArrInv.Rise = pMatch->tArrive.Fall + p->pSuperLib->tDelayInv.Rise;
|
||||
ptReqIn->Fall = MAP_MIN( ptReqIn->Fall, ptReqOut->Rise - p->pSuperLib->tDelayInv.Rise );
|
||||
ptReqIn->Rise = MAP_MIN( ptReqIn->Rise, ptReqOut->Fall - p->pSuperLib->tDelayInv.Fall );
|
||||
}
|
||||
}
|
||||
|
||||
// finalize the worst case computation
|
||||
pNode->tRequired[0].Worst = MAP_MIN( pNode->tRequired[0].Fall, pNode->tRequired[0].Rise );
|
||||
pNode->tRequired[1].Worst = MAP_MIN( pNode->tRequired[1].Fall, pNode->tRequired[1].Rise );
|
||||
|
||||
// skip the PIs
|
||||
if ( !Map_NodeIsAnd(pNode) )
|
||||
continue;
|
||||
|
||||
// propagate required times of different phases of the node
|
||||
// the ordering of phases does not matter since they are mapped independently
|
||||
if ( pNode->pCutBest[0] && pNode->tRequired[0].Worst < MAP_FLOAT_LARGE )
|
||||
Map_TimePropagateRequiredPhase( p, pNode, 0 );
|
||||
if ( pNode->pCutBest[1] && pNode->tRequired[1].Worst < MAP_FLOAT_LARGE )
|
||||
Map_TimePropagateRequiredPhase( p, pNode, 1 );
|
||||
}
|
||||
|
||||
// in the end, we verify the required times
|
||||
// for this, we compute the arrival times of the outputs of each phase
|
||||
// of the supergates using the fanins' required times as the fanins' arrival times
|
||||
// the resulting arrival time of the supergate should be less than the actual required time
|
||||
for ( k = 0; k < vNodes->nSize; k++ )
|
||||
{
|
||||
pNode = vNodes->pArray[k];
|
||||
if ( !Map_NodeIsAnd(pNode) )
|
||||
continue;
|
||||
// verify that the required times are propagated correctly
|
||||
// if ( pNode->pCutBest[0] && (pNode->nRefAct[0] > 0 || pNode->pCutBest[1] == NULL) )
|
||||
if ( pNode->pCutBest[0] && pNode->tRequired[0].Worst < MAP_FLOAT_LARGE )
|
||||
{
|
||||
Map_MatchComputeReqTimes( pNode->pCutBest[0], 0, ptReqOutTest );
|
||||
assert( ptReqOutTest->Rise < pNode->tRequired[0].Rise + p->fEpsilon );
|
||||
assert( ptReqOutTest->Fall < pNode->tRequired[0].Fall + p->fEpsilon );
|
||||
}
|
||||
// if ( pNode->pCutBest[1] && (pNode->nRefAct[1] > 0 || pNode->pCutBest[0] == NULL) )
|
||||
if ( pNode->pCutBest[1] && pNode->tRequired[1].Worst < MAP_FLOAT_LARGE )
|
||||
{
|
||||
Map_MatchComputeReqTimes( pNode->pCutBest[1], 1, ptReqOutTest );
|
||||
assert( ptReqOutTest->Rise < pNode->tRequired[1].Rise + p->fEpsilon );
|
||||
assert( ptReqOutTest->Fall < pNode->tRequired[1].Fall + p->fEpsilon );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes the required times of the given nodes.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Map_TimePropagateRequiredPhase( Map_Man_t * p, Map_Node_t * pNode, int fPhase )
|
||||
{
|
||||
Map_Time_t * ptReqIn, * ptReqOut;
|
||||
Map_Cut_t * pCut;
|
||||
Map_Super_t * pSuper;
|
||||
float tNewReqTime;
|
||||
unsigned uPhase;
|
||||
int fPinPhase, i;
|
||||
|
||||
// get the cut to be propagated
|
||||
pCut = pNode->pCutBest[fPhase];
|
||||
assert( pCut != NULL );
|
||||
// get the supergate and its polarity
|
||||
pSuper = pCut->M[fPhase].pSuperBest;
|
||||
uPhase = pCut->M[fPhase].uPhaseBest;
|
||||
// get the required time of the output of the supergate
|
||||
ptReqOut = pNode->tRequired + fPhase;
|
||||
// set the required time of the children
|
||||
for ( i = 0; i < pCut->nLeaves; i++ )
|
||||
{
|
||||
// get the phase of the given pin of the supergate
|
||||
fPinPhase = ((uPhase & (1 << i)) == 0);
|
||||
ptReqIn = pCut->ppLeaves[i]->tRequired + fPinPhase;
|
||||
assert( pCut->ppLeaves[i]->nRefAct[2] > 0 );
|
||||
|
||||
// get the rise of the output due to rise of the inputs
|
||||
// if ( ptArrOut->Rise < ptArrIn->Rise + pSuper->tDelaysR[i].Rise )
|
||||
// ptArrOut->Rise = ptArrIn->Rise + pSuper->tDelaysR[i].Rise;
|
||||
if ( pSuper->tDelaysR[i].Rise > 0 )
|
||||
{
|
||||
tNewReqTime = ptReqOut->Rise - pSuper->tDelaysR[i].Rise;
|
||||
ptReqIn->Rise = MAP_MIN( ptReqIn->Rise, tNewReqTime );
|
||||
}
|
||||
|
||||
// get the rise of the output due to fall of the inputs
|
||||
// if ( ptArrOut->Rise < ptArrIn->Fall + pSuper->tDelaysR[i].Fall )
|
||||
// ptArrOut->Rise = ptArrIn->Fall + pSuper->tDelaysR[i].Fall;
|
||||
if ( pSuper->tDelaysR[i].Fall > 0 )
|
||||
{
|
||||
tNewReqTime = ptReqOut->Rise - pSuper->tDelaysR[i].Fall;
|
||||
ptReqIn->Fall = MAP_MIN( ptReqIn->Fall, tNewReqTime );
|
||||
}
|
||||
|
||||
// get the fall of the output due to rise of the inputs
|
||||
// if ( ptArrOut->Fall < ptArrIn->Rise + pSuper->tDelaysF[i].Rise )
|
||||
// ptArrOut->Fall = ptArrIn->Rise + pSuper->tDelaysF[i].Rise;
|
||||
if ( pSuper->tDelaysF[i].Rise > 0 )
|
||||
{
|
||||
tNewReqTime = ptReqOut->Fall - pSuper->tDelaysF[i].Rise;
|
||||
ptReqIn->Rise = MAP_MIN( ptReqIn->Rise, tNewReqTime );
|
||||
}
|
||||
|
||||
// get the fall of the output due to fall of the inputs
|
||||
// if ( ptArrOut->Fall < ptArrIn->Fall + pSuper->tDelaysF[i].Fall )
|
||||
// ptArrOut->Fall = ptArrIn->Fall + pSuper->tDelaysF[i].Fall;
|
||||
if ( pSuper->tDelaysF[i].Fall > 0 )
|
||||
{
|
||||
tNewReqTime = ptReqOut->Fall - pSuper->tDelaysF[i].Fall;
|
||||
ptReqIn->Fall = MAP_MIN( ptReqIn->Fall, tNewReqTime );
|
||||
}
|
||||
}
|
||||
|
||||
// compare the required times with the arrival times
|
||||
assert( pNode->tArrival[fPhase].Rise < ptReqOut->Rise + p->fEpsilon );
|
||||
assert( pNode->tArrival[fPhase].Fall < ptReqOut->Fall + p->fEpsilon );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes the arrival times of the cut.]
|
||||
|
||||
Description [Computes the arrival times of the cut if it is implemented using
|
||||
the given supergate with the given phase. Uses the constraint-type specification
|
||||
of rise/fall arrival times.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
float Map_MatchComputeReqTimes( Map_Cut_t * pCut, int fPhase, Map_Time_t * ptArrRes )
|
||||
{
|
||||
Map_Time_t * ptArrIn;
|
||||
Map_Super_t * pSuper;
|
||||
unsigned uPhaseTot;
|
||||
int fPinPhase, i;
|
||||
float tDelay;
|
||||
|
||||
// get the supergate and the phase
|
||||
pSuper = pCut->M[fPhase].pSuperBest;
|
||||
uPhaseTot = pCut->M[fPhase].uPhaseBest;
|
||||
|
||||
// propagate the arrival times
|
||||
ptArrRes->Rise = ptArrRes->Fall = -MAP_FLOAT_LARGE;
|
||||
for ( i = 0; i < pCut->nLeaves; i++ )
|
||||
{
|
||||
// get the phase of the given pin
|
||||
fPinPhase = ((uPhaseTot & (1 << i)) == 0);
|
||||
ptArrIn = pCut->ppLeaves[i]->tRequired + fPinPhase;
|
||||
// assert( ptArrIn->Worst < MAP_FLOAT_LARGE );
|
||||
|
||||
// get the rise of the output due to rise of the inputs
|
||||
if ( pSuper->tDelaysR[i].Rise > 0 )
|
||||
{
|
||||
tDelay = ptArrIn->Rise + pSuper->tDelaysR[i].Rise;
|
||||
if ( ptArrRes->Rise < tDelay )
|
||||
ptArrRes->Rise = tDelay;
|
||||
}
|
||||
|
||||
// get the rise of the output due to fall of the inputs
|
||||
if ( pSuper->tDelaysR[i].Fall > 0 )
|
||||
{
|
||||
tDelay = ptArrIn->Fall + pSuper->tDelaysR[i].Fall;
|
||||
if ( ptArrRes->Rise < tDelay )
|
||||
ptArrRes->Rise = tDelay;
|
||||
}
|
||||
|
||||
// get the fall of the output due to rise of the inputs
|
||||
if ( pSuper->tDelaysF[i].Rise > 0 )
|
||||
{
|
||||
tDelay = ptArrIn->Rise + pSuper->tDelaysF[i].Rise;
|
||||
if ( ptArrRes->Fall < tDelay )
|
||||
ptArrRes->Fall = tDelay;
|
||||
}
|
||||
|
||||
// get the fall of the output due to fall of the inputs
|
||||
if ( pSuper->tDelaysF[i].Fall > 0 )
|
||||
{
|
||||
tDelay = ptArrIn->Fall + pSuper->tDelaysF[i].Fall;
|
||||
if ( ptArrRes->Fall < tDelay )
|
||||
ptArrRes->Fall = tDelay;
|
||||
}
|
||||
}
|
||||
// return the worst-case of rise/fall arrival times
|
||||
return MAP_MAX(ptArrRes->Rise, ptArrRes->Fall);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
@@ -1,818 +0,0 @@
|
||||
/**CFile****************************************************************
|
||||
|
||||
FileName [mapperTree.c]
|
||||
|
||||
PackageName [MVSIS 1.3: Multi-valued logic synthesis system.]
|
||||
|
||||
Synopsis [Generic technology mapping engine.]
|
||||
|
||||
Author [MVSIS Group]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 2.0. Started - June 1, 2004.]
|
||||
|
||||
Revision [$Id: mapperTree.c,v 1.9 2005/01/23 06:59:45 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#ifdef __linux__
|
||||
#include <libgen.h>
|
||||
#endif
|
||||
|
||||
#include "mapperInt.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static int Map_LibraryReadFileTree( Map_SuperLib_t * pLib, FILE * pFile, char *pFileName );
|
||||
static Map_Super_t * Map_LibraryReadGateTree( Map_SuperLib_t * pLib, char * pBuffer, int Number, int nVars );
|
||||
static int Map_LibraryDeriveGateInfo( Map_SuperLib_t * pLib, st_table * tExcludeGate );
|
||||
static void Map_LibraryAddFaninDelays( Map_SuperLib_t * pLib, Map_Super_t * pGate, Map_Super_t * pFanin, Mio_Pin_t * pPin );
|
||||
static int Map_LibraryGetMaxSuperPi_rec( Map_Super_t * pGate );
|
||||
static unsigned Map_LibraryGetGateSupp_rec( Map_Super_t * pGate );
|
||||
|
||||
// fanout limits
|
||||
extern const int s_MapFanoutLimits[10] = { 1/*0*/, 10/*1*/, 5/*2*/, 2/*3*/, 1/*4*/, 1/*5*/, 1/*6*/ };
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Reads the supergate library from file.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Map_LibraryReadTree( Map_SuperLib_t * pLib, char * pFileName, char * pExcludeFile )
|
||||
{
|
||||
FILE * pFile;
|
||||
int Status, num;
|
||||
Abc_Frame_t * pAbc;
|
||||
st_table * tExcludeGate = 0;
|
||||
|
||||
// read the beginning of the file
|
||||
assert( pLib->pGenlib == NULL );
|
||||
pFile = Io_FileOpen( pFileName, "open_path", "r", 1 );
|
||||
// pFile = fopen( pFileName, "r" );
|
||||
if ( pFile == NULL )
|
||||
{
|
||||
printf( "Cannot open input file \"%s\".\n", pFileName );
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ( pExcludeFile )
|
||||
{
|
||||
pAbc = Abc_FrameGetGlobalFrame();
|
||||
|
||||
tExcludeGate = st_init_table(strcmp, st_strhash);
|
||||
if ( (num = Mio_LibraryReadExclude( pAbc, pExcludeFile, tExcludeGate )) == -1 )
|
||||
{
|
||||
st_free_table( tExcludeGate );
|
||||
tExcludeGate = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
fprintf ( Abc_FrameReadOut( pAbc ), "Read %d gates from exclude file\n", num );
|
||||
}
|
||||
|
||||
Status = Map_LibraryReadFileTree( pLib, pFile, pFileName );
|
||||
fclose( pFile );
|
||||
if ( Status == 0 )
|
||||
return 0;
|
||||
// prepare the info about the library
|
||||
return Map_LibraryDeriveGateInfo( pLib, tExcludeGate );
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Reads the library file.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Map_LibraryReadFileTree( Map_SuperLib_t * pLib, FILE * pFile, char *pFileName )
|
||||
{
|
||||
ProgressBar * pProgress;
|
||||
char pBuffer[5000], pLibFile[5000];
|
||||
FILE * pFileGen;
|
||||
Map_Super_t * pGate;
|
||||
char * pTemp = 0, * pLibName;
|
||||
int nCounter, k, i;
|
||||
|
||||
// skip empty and comment lines
|
||||
while ( fgets( pBuffer, 5000, pFile ) != NULL )
|
||||
{
|
||||
// skip leading spaces
|
||||
for ( pTemp = pBuffer; *pTemp == ' ' || *pTemp == '\r' || *pTemp == '\n'; pTemp++ );
|
||||
// skip comment lines and empty lines
|
||||
if ( *pTemp != 0 && *pTemp != '#' )
|
||||
break;
|
||||
}
|
||||
|
||||
// get the genlib file name (base)
|
||||
pLibName = strtok( pTemp, " \t\r\n" );
|
||||
|
||||
if ( strcmp( pLibName, "GATE" ) == 0 )
|
||||
{
|
||||
printf( "The input file \"%s\" looks like a GENLIB file and not a supergate library file.\n", pLib->pName );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// now figure out the directory if any in the pFileName
|
||||
#ifdef __linux__
|
||||
snprintf( pLibFile, 5000, "%s/%s", dirname(strdup(pFileName)), pLibName );
|
||||
#else
|
||||
{
|
||||
char * pStr;
|
||||
strcpy( pLibFile, pFileName );
|
||||
pStr = pLibFile + strlen(pBuffer) - 1;
|
||||
while ( pStr > pLibFile && *pStr != '\\' && *pStr != '/' )
|
||||
pStr--;
|
||||
if ( pStr == pLibFile )
|
||||
strcpy( pLibFile, pLibName );
|
||||
else
|
||||
sprintf( pStr, "/%s", pLibName );
|
||||
}
|
||||
#endif
|
||||
|
||||
pFileGen = Io_FileOpen( pLibFile, "open_path", "r", 1 );
|
||||
// pFileGen = fopen( pLibFile, "r" );
|
||||
if ( pFileGen == NULL )
|
||||
{
|
||||
printf( "Cannot open the GENLIB file \"%s\".\n", pLibFile );
|
||||
return 0;
|
||||
}
|
||||
fclose( pFileGen );
|
||||
|
||||
// read the genlib library
|
||||
pLib->pGenlib = Mio_LibraryRead( Abc_FrameGetGlobalFrame(), pLibFile, 0, 0 );
|
||||
if ( pLib->pGenlib == NULL )
|
||||
{
|
||||
printf( "Cannot read GENLIB file \"%s\".\n", pLibFile );
|
||||
return 0;
|
||||
}
|
||||
|
||||
// read the number of variables
|
||||
fscanf( pFile, "%d\n", &pLib->nVarsMax );
|
||||
if ( pLib->nVarsMax < 2 || pLib->nVarsMax > 10 )
|
||||
{
|
||||
printf( "Suspicious number of variables (%d).\n", pLib->nVarsMax );
|
||||
return 0;
|
||||
}
|
||||
|
||||
// read the number of gates
|
||||
fscanf( pFile, "%d\n", &pLib->nSupersReal );
|
||||
if ( pLib->nSupersReal < 1 || pLib->nSupersReal > 10000000 )
|
||||
{
|
||||
printf( "Suspicious number of gates (%d).\n", pLib->nSupersReal );
|
||||
return 0;
|
||||
}
|
||||
|
||||
// read the number of lines
|
||||
fscanf( pFile, "%d\n", &pLib->nLines );
|
||||
if ( pLib->nLines < 1 || pLib->nLines > 10000000 )
|
||||
{
|
||||
printf( "Suspicious number of lines (%d).\n", pLib->nLines );
|
||||
return 0;
|
||||
}
|
||||
|
||||
// allocate room for supergate pointers
|
||||
pLib->ppSupers = ALLOC( Map_Super_t *, pLib->nLines + 10000 );
|
||||
|
||||
// create the elementary supergates
|
||||
for ( i = 0; i < pLib->nVarsMax; i++ )
|
||||
{
|
||||
// get a new gate
|
||||
pGate = (Map_Super_t *)Extra_MmFixedEntryFetch( pLib->mmSupers );
|
||||
memset( pGate, 0, sizeof(Map_Super_t) );
|
||||
// assign the elementary variable, the truth table, and the delays
|
||||
pGate->Num = i;
|
||||
// set the truth table
|
||||
pGate->uTruth[0] = pLib->uTruths[i][0];
|
||||
pGate->uTruth[1] = pLib->uTruths[i][1];
|
||||
// set the arrival times of all input to non-existent delay
|
||||
for ( k = 0; k < pLib->nVarsMax; k++ )
|
||||
{
|
||||
pGate->tDelaysR[k].Rise = pGate->tDelaysR[k].Fall = MAP_NO_VAR;
|
||||
pGate->tDelaysF[k].Rise = pGate->tDelaysF[k].Fall = MAP_NO_VAR;
|
||||
}
|
||||
// set an existent arrival time for rise and fall
|
||||
pGate->tDelaysR[i].Rise = 0.0;
|
||||
pGate->tDelaysF[i].Fall = 0.0;
|
||||
// set the gate
|
||||
pLib->ppSupers[i] = pGate;
|
||||
}
|
||||
|
||||
// read the lines
|
||||
nCounter = pLib->nVarsMax;
|
||||
pProgress = Extra_ProgressBarStart( stdout, pLib->nLines );
|
||||
while ( fgets( pBuffer, 5000, pFile ) != NULL )
|
||||
{
|
||||
for ( pTemp = pBuffer; *pTemp == ' ' || *pTemp == '\r' || *pTemp == '\n'; pTemp++ );
|
||||
if ( pTemp[0] == '\0' )
|
||||
continue;
|
||||
// if ( pTemp[0] == 'a' || pTemp[2] == 'a' )
|
||||
// {
|
||||
// pLib->nLines--;
|
||||
// continue;
|
||||
// }
|
||||
|
||||
// get the gate
|
||||
pGate = Map_LibraryReadGateTree( pLib, pTemp, nCounter, pLib->nVarsMax );
|
||||
if ( pGate == NULL )
|
||||
{
|
||||
Extra_ProgressBarStop( pProgress );
|
||||
return 0;
|
||||
}
|
||||
pLib->ppSupers[nCounter++] = pGate;
|
||||
// later we will derive: truth table, delays, area, number of component gates, etc
|
||||
|
||||
// update the progress bar
|
||||
Extra_ProgressBarUpdate( pProgress, nCounter, NULL );
|
||||
}
|
||||
Extra_ProgressBarStop( pProgress );
|
||||
if ( nCounter != pLib->nLines )
|
||||
printf( "The number of lines read (%d) is different what the file says (%d).\n", nCounter, pLib->nLines );
|
||||
pLib->nSupersAll = nCounter;
|
||||
// count the number of real supergates
|
||||
nCounter = 0;
|
||||
for ( k = 0; k < pLib->nLines; k++ )
|
||||
nCounter += pLib->ppSupers[k]->fSuper;
|
||||
if ( nCounter != pLib->nSupersReal )
|
||||
printf( "The number of gates read (%d) is different what the file says (%d).\n", nCounter, pLib->nSupersReal );
|
||||
pLib->nSupersReal = nCounter;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Reads one gate.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Map_Super_t * Map_LibraryReadGateTree( Map_SuperLib_t * pLib, char * pBuffer, int Number, int nVarsMax )
|
||||
{
|
||||
Map_Super_t * pGate;
|
||||
char * pTemp;
|
||||
int i, Num;
|
||||
|
||||
// start and clean the gate
|
||||
pGate = (Map_Super_t *)Extra_MmFixedEntryFetch( pLib->mmSupers );
|
||||
memset( pGate, 0, sizeof(Map_Super_t) );
|
||||
|
||||
// set the gate number
|
||||
pGate->Num = Number;
|
||||
|
||||
// read the mark
|
||||
pTemp = strtok( pBuffer, " " );
|
||||
if ( pTemp[0] == '*' )
|
||||
{
|
||||
pGate->fSuper = 1;
|
||||
pTemp = strtok( NULL, " " );
|
||||
}
|
||||
|
||||
// read the root gate
|
||||
pGate->pRoot = Mio_LibraryReadGateByName( pLib->pGenlib, pTemp );
|
||||
if ( pGate->pRoot == NULL )
|
||||
{
|
||||
printf( "Cannot read the root gate names %s.\n", pTemp );
|
||||
return NULL;
|
||||
}
|
||||
// set the max number of fanouts
|
||||
pGate->nFanLimit = s_MapFanoutLimits[ Mio_GateReadInputs(pGate->pRoot) ];
|
||||
|
||||
// read the pin-to-pin delay
|
||||
for ( i = 0; ( pTemp = strtok( NULL, " \n\0" ) ); i++ )
|
||||
{
|
||||
if ( pTemp[0] == '#' )
|
||||
break;
|
||||
if ( i == nVarsMax )
|
||||
{
|
||||
printf( "There are too many entries on the line.\n" );
|
||||
return NULL;
|
||||
}
|
||||
Num = atoi(pTemp);
|
||||
if ( Num < 0 )
|
||||
{
|
||||
printf( "The number of a child supergate is negative.\n" );
|
||||
return NULL;
|
||||
}
|
||||
if ( Num > pLib->nLines )
|
||||
{
|
||||
printf( "The number of a child supergate (%d) exceeded the number of lines (%d).\n",
|
||||
Num, pLib->nLines );
|
||||
return NULL;
|
||||
}
|
||||
pGate->pFanins[i] = pLib->ppSupers[Num];
|
||||
}
|
||||
pGate->nFanins = i;
|
||||
if ( pGate->nFanins != (unsigned)Mio_GateReadInputs(pGate->pRoot) )
|
||||
{
|
||||
printf( "The number of fanins of a root gate is wrong.\n" );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// save the gate name, just in case
|
||||
if ( pTemp && pTemp[0] == '#' )
|
||||
{
|
||||
if ( pTemp[1] == 0 )
|
||||
pTemp = strtok( NULL, " \n\0" );
|
||||
else // skip spaces
|
||||
for ( pTemp++; *pTemp == ' '; pTemp++ );
|
||||
// save the formula
|
||||
pGate->pFormula = Extra_MmFlexEntryFetch( pLib->mmForms, strlen(pTemp)+1 );
|
||||
strcpy( pGate->pFormula, pTemp );
|
||||
}
|
||||
// check the rest of the string
|
||||
pTemp = strtok( NULL, " \n\0" );
|
||||
if ( pTemp != NULL )
|
||||
printf( "The following trailing symbols found \"%s\".\n", pTemp );
|
||||
return pGate;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Derives information about the library.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Map_LibraryDeriveGateInfo( Map_SuperLib_t * pLib, st_table * tExcludeGate )
|
||||
{
|
||||
Map_Super_t * pGate, * pFanin;
|
||||
Mio_Pin_t * pPin;
|
||||
unsigned uCanon[2];
|
||||
unsigned uTruths[6][2];
|
||||
int i, k, nRealVars;
|
||||
|
||||
// set all the derivable info related to the supergates
|
||||
for ( i = pLib->nVarsMax; i < (int)pLib->nLines; i++ )
|
||||
{
|
||||
pGate = pLib->ppSupers[i];
|
||||
|
||||
if ( tExcludeGate )
|
||||
{
|
||||
if ( st_is_member( tExcludeGate, Mio_GateReadName( pGate->pRoot ) ) )
|
||||
pGate->fExclude = 1;
|
||||
for ( k = 0; k < (int)pGate->nFanins; k++ )
|
||||
{
|
||||
pFanin = pGate->pFanins[k];
|
||||
if ( pFanin->fExclude )
|
||||
{
|
||||
pGate->fExclude = 1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// collect the truth tables of the fanins
|
||||
for ( k = 0; k < (int)pGate->nFanins; k++ )
|
||||
{
|
||||
pFanin = pGate->pFanins[k];
|
||||
uTruths[k][0] = pFanin->uTruth[0];
|
||||
uTruths[k][1] = pFanin->uTruth[1];
|
||||
}
|
||||
// derive the new truth table
|
||||
Mio_DeriveTruthTable( pGate->pRoot, uTruths, pGate->nFanins, 6, pGate->uTruth );
|
||||
|
||||
// set the initial delays of the supergate
|
||||
for ( k = 0; k < pLib->nVarsMax; k++ )
|
||||
{
|
||||
pGate->tDelaysR[k].Rise = pGate->tDelaysR[k].Fall = MAP_NO_VAR;
|
||||
pGate->tDelaysF[k].Rise = pGate->tDelaysF[k].Fall = MAP_NO_VAR;
|
||||
}
|
||||
// get the linked list of pins for the given root gate
|
||||
pPin = Mio_GateReadPins( pGate->pRoot );
|
||||
// update the initial delay of the supergate using info from the corresponding pin
|
||||
for ( k = 0; k < (int)pGate->nFanins; k++, pPin = Mio_PinReadNext(pPin) )
|
||||
{
|
||||
// if there is no corresponding pin, this is a bug, return fail
|
||||
if ( pPin == NULL )
|
||||
{
|
||||
printf( "There are less pins than gate inputs.\n" );
|
||||
return 0;
|
||||
}
|
||||
// update the delay information of k-th fanins info from the corresponding pin
|
||||
Map_LibraryAddFaninDelays( pLib, pGate, pGate->pFanins[k], pPin );
|
||||
}
|
||||
// if there are some pins left, this is a bug, return fail
|
||||
if ( pPin != NULL )
|
||||
{
|
||||
printf( "There are more pins than gate inputs.\n" );
|
||||
return 0;
|
||||
}
|
||||
// find the max delay
|
||||
pGate->tDelayMax.Rise = pGate->tDelayMax.Fall = MAP_NO_VAR;
|
||||
for ( k = 0; k < pLib->nVarsMax; k++ )
|
||||
{
|
||||
// the rise of the output depends on the rise and fall of the output
|
||||
if ( pGate->tDelayMax.Rise < pGate->tDelaysR[k].Rise )
|
||||
pGate->tDelayMax.Rise = pGate->tDelaysR[k].Rise;
|
||||
if ( pGate->tDelayMax.Rise < pGate->tDelaysR[k].Fall )
|
||||
pGate->tDelayMax.Rise = pGate->tDelaysR[k].Fall;
|
||||
// the fall of the output depends on the rise and fall of the output
|
||||
if ( pGate->tDelayMax.Fall < pGate->tDelaysF[k].Rise )
|
||||
pGate->tDelayMax.Fall = pGate->tDelaysF[k].Rise;
|
||||
if ( pGate->tDelayMax.Fall < pGate->tDelaysF[k].Fall )
|
||||
pGate->tDelayMax.Fall = pGate->tDelaysF[k].Fall;
|
||||
|
||||
pGate->tDelaysF[k].Worst = MAP_MAX( pGate->tDelaysF[k].Fall, pGate->tDelaysF[k].Rise );
|
||||
pGate->tDelaysR[k].Worst = MAP_MAX( pGate->tDelaysR[k].Fall, pGate->tDelaysR[k].Rise );
|
||||
}
|
||||
|
||||
// count gates and area of the supergate
|
||||
pGate->nGates = 1;
|
||||
pGate->Area = (float)Mio_GateReadArea(pGate->pRoot);
|
||||
for ( k = 0; k < (int)pGate->nFanins; k++ )
|
||||
{
|
||||
pGate->nGates += pGate->pFanins[k]->nGates;
|
||||
pGate->Area += pGate->pFanins[k]->Area;
|
||||
}
|
||||
// do not add the gate to the table, if this gate is an internal gate
|
||||
// of some supegate and does not correspond to a supergate output
|
||||
if ( ( !pGate->fSuper ) || pGate->fExclude )
|
||||
continue;
|
||||
|
||||
// find the maximum index of a variable in the support of the supergates
|
||||
// this is important for two reasons:
|
||||
// (1) to limit the number of permutations considered for canonicization
|
||||
// (2) to get rid of equivalence phases to speed-up matching
|
||||
nRealVars = Map_LibraryGetMaxSuperPi_rec( pGate ) + 1;
|
||||
assert( nRealVars > 0 && nRealVars <= pLib->nVarsMax );
|
||||
// if there are some problems with this code, try this instead
|
||||
// nRealVars = pLib->nVarsMax;
|
||||
|
||||
// find the N-canonical form of this supergate
|
||||
pGate->nPhases = Map_CanonComputeSlow( pLib->uTruths, pLib->nVarsMax, nRealVars, pGate->uTruth, pGate->uPhases, uCanon );
|
||||
// add the supergate into the table by its N-canonical table
|
||||
Map_SuperTableInsertC( pLib->tTableC, uCanon, pGate );
|
||||
/*
|
||||
{
|
||||
int uCanon1, uCanon2;
|
||||
uCanon1 = uCanon[0];
|
||||
pGate->uTruth[0] = ~pGate->uTruth[0];
|
||||
pGate->uTruth[1] = ~pGate->uTruth[1];
|
||||
Map_CanonComputeSlow( pLib->uTruths, pLib->nVarsMax, nRealVars, pGate->uTruth, pGate->uPhases, uCanon );
|
||||
uCanon2 = uCanon[0];
|
||||
Rwt_Man5ExploreCount( uCanon1 < uCanon2 ? uCanon1 : uCanon2 );
|
||||
}
|
||||
*/
|
||||
}
|
||||
// sort the gates in each line
|
||||
Map_SuperTableSortSupergatesByDelay( pLib->tTableC, pLib->nSupersAll );
|
||||
|
||||
// let the glory be manifest
|
||||
// Map_LibraryPrintTree( pLib );
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Finds the largest PI number in the support of the supergate.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Map_LibraryGetMaxSuperPi_rec( Map_Super_t * pGate )
|
||||
{
|
||||
int i, VarCur, VarMax = 0;
|
||||
if ( pGate->pRoot == NULL )
|
||||
return pGate->Num;
|
||||
for ( i = 0; i < (int)pGate->nFanins; i++ )
|
||||
{
|
||||
VarCur = Map_LibraryGetMaxSuperPi_rec( pGate->pFanins[i] );
|
||||
if ( VarMax < VarCur )
|
||||
VarMax = VarCur;
|
||||
}
|
||||
return VarMax;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Finds the largest PI number in the support of the supergate.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
unsigned Map_LibraryGetGateSupp_rec( Map_Super_t * pGate )
|
||||
{
|
||||
unsigned uSupport;
|
||||
int i;
|
||||
if ( pGate->pRoot == NULL )
|
||||
return (unsigned)(1 << (pGate->Num));
|
||||
uSupport = 0;
|
||||
for ( i = 0; i < (int)pGate->nFanins; i++ )
|
||||
uSupport |= Map_LibraryGetGateSupp_rec( pGate->pFanins[i] );
|
||||
return uSupport;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Derives the pin-to-pin delay constraints for the supergate.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Map_LibraryAddFaninDelays( Map_SuperLib_t * pLib, Map_Super_t * pGate, Map_Super_t * pFanin, Mio_Pin_t * pPin )
|
||||
{
|
||||
Mio_PinPhase_t PinPhase;
|
||||
float tDelayBlockRise, tDelayBlockFall, tDelayPin;
|
||||
bool fMaxDelay = 0;
|
||||
int i;
|
||||
|
||||
// use this node to enable max-delay model
|
||||
if ( fMaxDelay )
|
||||
{
|
||||
float tDelayBlockMax;
|
||||
// get the maximum delay
|
||||
tDelayBlockMax = (float)Mio_PinReadDelayBlockMax(pPin);
|
||||
// go through the supergate inputs
|
||||
for ( i = 0; i < pLib->nVarsMax; i++ )
|
||||
{
|
||||
if ( pFanin->tDelaysR[i].Rise < 0 )
|
||||
continue;
|
||||
tDelayPin = pFanin->tDelaysR[i].Rise + tDelayBlockMax;
|
||||
if ( pGate->tDelaysR[i].Rise < tDelayPin )
|
||||
pGate->tDelaysR[i].Rise = tDelayPin;
|
||||
}
|
||||
// go through the supergate inputs
|
||||
for ( i = 0; i < pLib->nVarsMax; i++ )
|
||||
{
|
||||
if ( pFanin->tDelaysF[i].Fall < 0 )
|
||||
continue;
|
||||
tDelayPin = pFanin->tDelaysF[i].Fall + tDelayBlockMax;
|
||||
if ( pGate->tDelaysF[i].Fall < tDelayPin )
|
||||
pGate->tDelaysF[i].Fall = tDelayPin;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// get the interesting parameters of this pin
|
||||
PinPhase = Mio_PinReadPhase(pPin);
|
||||
tDelayBlockRise = (float)Mio_PinReadDelayBlockRise( pPin );
|
||||
tDelayBlockFall = (float)Mio_PinReadDelayBlockFall( pPin );
|
||||
|
||||
// update the rise and fall of the output depending on the phase of the pin
|
||||
if ( PinPhase != MIO_PHASE_INV ) // NONINV phase is present
|
||||
{
|
||||
// the rise of the gate is determined by the rise of the fanin
|
||||
// the fall of the gate is determined by the fall of the fanin
|
||||
for ( i = 0; i < pLib->nVarsMax; i++ )
|
||||
{
|
||||
////////////////////////////////////////////////////////
|
||||
// consider the rise of the gate
|
||||
////////////////////////////////////////////////////////
|
||||
// check two types of constraints on the rise of the fanin:
|
||||
// (1) the constraints related to the rise of the PIs
|
||||
// (2) the constraints related to the fall of the PIs
|
||||
if ( pFanin->tDelaysR[i].Rise >= 0 ) // case (1)
|
||||
{ // fanin's rise depends on the rise of i-th PI
|
||||
// update the rise of the gate's output
|
||||
if ( pGate->tDelaysR[i].Rise < pFanin->tDelaysR[i].Rise + tDelayBlockRise )
|
||||
pGate->tDelaysR[i].Rise = pFanin->tDelaysR[i].Rise + tDelayBlockRise;
|
||||
}
|
||||
if ( pFanin->tDelaysR[i].Fall >= 0 ) // case (2)
|
||||
{ // fanin's rise depends on the fall of i-th PI
|
||||
// update the rise of the gate's output
|
||||
if ( pGate->tDelaysR[i].Fall < pFanin->tDelaysR[i].Fall + tDelayBlockRise )
|
||||
pGate->tDelaysR[i].Fall = pFanin->tDelaysR[i].Fall + tDelayBlockRise;
|
||||
}
|
||||
////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
// consider the fall of the gate (similar)
|
||||
////////////////////////////////////////////////////////
|
||||
// check two types of constraints on the fall of the fanin:
|
||||
// (1) the constraints related to the rise of the PIs
|
||||
// (2) the constraints related to the fall of the PIs
|
||||
if ( pFanin->tDelaysF[i].Rise >= 0 ) // case (1)
|
||||
{
|
||||
if ( pGate->tDelaysF[i].Rise < pFanin->tDelaysF[i].Rise + tDelayBlockFall )
|
||||
pGate->tDelaysF[i].Rise = pFanin->tDelaysF[i].Rise + tDelayBlockFall;
|
||||
}
|
||||
if ( pFanin->tDelaysF[i].Fall >= 0 ) // case (2)
|
||||
{
|
||||
if ( pGate->tDelaysF[i].Fall < pFanin->tDelaysF[i].Fall + tDelayBlockFall )
|
||||
pGate->tDelaysF[i].Fall = pFanin->tDelaysF[i].Fall + tDelayBlockFall;
|
||||
}
|
||||
////////////////////////////////////////////////////////
|
||||
}
|
||||
}
|
||||
if ( PinPhase != MIO_PHASE_NONINV ) // INV phase is present
|
||||
{
|
||||
// the rise of the gate is determined by the fall of the fanin
|
||||
// the fall of the gate is determined by the rise of the fanin
|
||||
for ( i = 0; i < pLib->nVarsMax; i++ )
|
||||
{
|
||||
////////////////////////////////////////////////////////
|
||||
// consider the rise of the gate's output
|
||||
////////////////////////////////////////////////////////
|
||||
// check two types of constraints on the fall of the fanin:
|
||||
// (1) the constraints related to the rise of the PIs
|
||||
// (2) the constraints related to the fall of the PIs
|
||||
if ( pFanin->tDelaysF[i].Rise >= 0 ) // case (1)
|
||||
{ // fanin's rise depends on the rise of i-th PI
|
||||
// update the rise of the gate
|
||||
if ( pGate->tDelaysR[i].Rise < pFanin->tDelaysF[i].Rise + tDelayBlockRise )
|
||||
pGate->tDelaysR[i].Rise = pFanin->tDelaysF[i].Rise + tDelayBlockRise;
|
||||
}
|
||||
if ( pFanin->tDelaysF[i].Fall >= 0 ) // case (2)
|
||||
{ // fanin's rise depends on the fall of i-th PI
|
||||
// update the rise of the gate
|
||||
if ( pGate->tDelaysR[i].Fall < pFanin->tDelaysF[i].Fall + tDelayBlockRise )
|
||||
pGate->tDelaysR[i].Fall = pFanin->tDelaysF[i].Fall + tDelayBlockRise;
|
||||
}
|
||||
////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
// consider the fall of the gate (similar)
|
||||
////////////////////////////////////////////////////////
|
||||
// check two types of constraints on the rise of the fanin:
|
||||
// (1) the constraints related to the rise of the PIs
|
||||
// (2) the constraints related to the fall of the PIs
|
||||
if ( pFanin->tDelaysR[i].Rise >= 0 ) // case (1)
|
||||
{
|
||||
if ( pGate->tDelaysF[i].Rise < pFanin->tDelaysR[i].Rise + tDelayBlockFall )
|
||||
pGate->tDelaysF[i].Rise = pFanin->tDelaysR[i].Rise + tDelayBlockFall;
|
||||
}
|
||||
if ( pFanin->tDelaysR[i].Fall >= 0 ) // case (2)
|
||||
{
|
||||
if ( pGate->tDelaysF[i].Fall < pFanin->tDelaysR[i].Fall + tDelayBlockFall )
|
||||
pGate->tDelaysF[i].Fall = pFanin->tDelaysR[i].Fall + tDelayBlockFall;
|
||||
}
|
||||
////////////////////////////////////////////////////////
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Performs phase transformation for one function.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
unsigned Map_CalculatePhase( unsigned uTruths[][2], int nVars, unsigned uTruth, unsigned uPhase )
|
||||
{
|
||||
int v, Shift;
|
||||
for ( v = 0, Shift = 1; v < nVars; v++, Shift <<= 1 )
|
||||
if ( uPhase & Shift )
|
||||
uTruth = (((uTruth & ~uTruths[v][0]) << Shift) | ((uTruth & uTruths[v][0]) >> Shift));
|
||||
return uTruth;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Performs phase transformation for one function.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Map_CalculatePhase6( unsigned uTruths[][2], int nVars, unsigned uTruth[], unsigned uPhase, unsigned uTruthRes[] )
|
||||
{
|
||||
unsigned uTemp;
|
||||
int v, Shift;
|
||||
|
||||
// initialize the result
|
||||
uTruthRes[0] = uTruth[0];
|
||||
uTruthRes[1] = uTruth[1];
|
||||
if ( uPhase == 0 )
|
||||
return;
|
||||
// compute the phase
|
||||
for ( v = 0, Shift = 1; v < nVars; v++, Shift <<= 1 )
|
||||
if ( uPhase & Shift )
|
||||
{
|
||||
if ( Shift < 32 )
|
||||
{
|
||||
uTruthRes[0] = (((uTruthRes[0] & ~uTruths[v][0]) << Shift) | ((uTruthRes[0] & uTruths[v][0]) >> Shift));
|
||||
uTruthRes[1] = (((uTruthRes[1] & ~uTruths[v][1]) << Shift) | ((uTruthRes[1] & uTruths[v][1]) >> Shift));
|
||||
}
|
||||
else
|
||||
{
|
||||
uTemp = uTruthRes[0];
|
||||
uTruthRes[0] = uTruthRes[1];
|
||||
uTruthRes[1] = uTemp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Prints the supergate library after deriving parameters.]
|
||||
|
||||
Description [This procedure is very useful to see the library after
|
||||
it has been read into the mapper by "read_super" and all the information
|
||||
about the supergates derived.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Map_LibraryPrintTree( Map_SuperLib_t * pLib )
|
||||
{
|
||||
Map_Super_t * pGate;
|
||||
int i, k;
|
||||
|
||||
// print all the info related to the supergates
|
||||
// for ( i = pLib->nVarsMax; i < (int)pLib->nLines; i++ )
|
||||
for ( i = pLib->nVarsMax; i < 20; i++ )
|
||||
{
|
||||
pGate = pLib->ppSupers[i];
|
||||
|
||||
// write the gate's fanin info and formula
|
||||
printf( "%6d ", pGate->Num );
|
||||
printf( "%c ", pGate->fSuper? '*' : ' ' );
|
||||
printf( "%6s", Mio_GateReadName(pGate->pRoot) );
|
||||
for ( k = 0; k < (int)pGate->nFanins; k++ )
|
||||
printf( " %6d", pGate->pFanins[k]->Num );
|
||||
printf( " %s", pGate->pFormula );
|
||||
printf( "\n" );
|
||||
|
||||
// write the gate's derived info
|
||||
Extra_PrintBinary( stdout, pGate->uTruth, 64 );
|
||||
printf( " %3d", pGate->nGates );
|
||||
printf( " %6.2f", pGate->Area );
|
||||
printf( " (%4.2f, %4.2f)", pGate->tDelayMax.Rise, pGate->tDelayMax.Fall );
|
||||
printf( "\n" );
|
||||
for ( k = 0; k < pLib->nVarsMax; k++ )
|
||||
{
|
||||
// print the constraint on the rise of the gate in the form (D1, D2),
|
||||
// where D1 is the constraint related to the rise of the k-th PI
|
||||
// where D2 is the constraint related to the fall of the k-th PI
|
||||
if ( pGate->tDelaysR[k].Rise < 0 && pGate->tDelaysR[k].Fall < 0 )
|
||||
printf( " (----, ----)" );
|
||||
else if ( pGate->tDelaysR[k].Fall < 0 )
|
||||
printf( " (%4.2f, ----)", pGate->tDelaysR[k].Rise );
|
||||
else if ( pGate->tDelaysR[k].Rise < 0 )
|
||||
printf( " (----, %4.2f)", pGate->tDelaysR[k].Fall );
|
||||
else
|
||||
printf( " (%4.2f, %4.2f)", pGate->tDelaysR[k].Rise, pGate->tDelaysR[k].Fall );
|
||||
|
||||
// print the constraint on the fall of the gate in the form (D1, D2),
|
||||
// where D1 is the constraint related to the rise of the k-th PI
|
||||
// where D2 is the constraint related to the fall of the k-th PI
|
||||
if ( pGate->tDelaysF[k].Rise < 0 && pGate->tDelaysF[k].Fall < 0 )
|
||||
printf( " (----, ----)" );
|
||||
else if ( pGate->tDelaysF[k].Fall < 0 )
|
||||
printf( " (%4.2f, ----)", pGate->tDelaysF[k].Rise );
|
||||
else if ( pGate->tDelaysF[k].Rise < 0 )
|
||||
printf( " (----, %4.2f)", pGate->tDelaysF[k].Fall );
|
||||
else
|
||||
printf( " (%4.2f, %4.2f)", pGate->tDelaysF[k].Rise, pGate->tDelaysF[k].Fall );
|
||||
printf( "\n" );
|
||||
}
|
||||
printf( "\n" );
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
@@ -1,310 +0,0 @@
|
||||
/**CFile****************************************************************
|
||||
|
||||
FileName [mapperTruth.c]
|
||||
|
||||
PackageName [MVSIS 1.3: Multi-valued logic synthesis system.]
|
||||
|
||||
Synopsis [Generic technology mapping engine.]
|
||||
|
||||
Author [MVSIS Group]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 2.0. Started - June 1, 2004.]
|
||||
|
||||
Revision [$Id: mapperTruth.c,v 1.8 2005/01/23 06:59:45 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "mapperInt.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static void Map_TruthsCut( Map_Man_t * pMan, Map_Cut_t * pCut );
|
||||
extern void Map_TruthsCutOne( Map_Man_t * p, Map_Cut_t * pCut, unsigned uTruth[] );
|
||||
static void Map_CutsCollect_rec( Map_Cut_t * pCut, Map_NodeVec_t * vVisited );
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Derives truth tables for each cut.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Map_MappingTruths( Map_Man_t * pMan )
|
||||
{
|
||||
ProgressBar * pProgress;
|
||||
Map_Node_t * pNode;
|
||||
Map_Cut_t * pCut;
|
||||
int nNodes, i;
|
||||
// compute the cuts for the POs
|
||||
nNodes = pMan->vAnds->nSize;
|
||||
pProgress = Extra_ProgressBarStart( stdout, nNodes );
|
||||
for ( i = 0; i < nNodes; i++ )
|
||||
{
|
||||
pNode = pMan->vAnds->pArray[i];
|
||||
if ( !Map_NodeIsAnd( pNode ) )
|
||||
continue;
|
||||
assert( pNode->pCuts );
|
||||
assert( pNode->pCuts->nLeaves == 1 );
|
||||
|
||||
// match the simple cut
|
||||
pNode->pCuts->M[0].uPhase = 0;
|
||||
pNode->pCuts->M[0].pSupers = pMan->pSuperLib->pSuperInv;
|
||||
pNode->pCuts->M[0].uPhaseBest = 0;
|
||||
pNode->pCuts->M[0].pSuperBest = pMan->pSuperLib->pSuperInv;
|
||||
|
||||
pNode->pCuts->M[1].uPhase = 0;
|
||||
pNode->pCuts->M[1].pSupers = pMan->pSuperLib->pSuperInv;
|
||||
pNode->pCuts->M[1].uPhaseBest = 1;
|
||||
pNode->pCuts->M[1].pSuperBest = pMan->pSuperLib->pSuperInv;
|
||||
|
||||
// match the rest of the cuts
|
||||
for ( pCut = pNode->pCuts->pNext; pCut; pCut = pCut->pNext )
|
||||
Map_TruthsCut( pMan, pCut );
|
||||
Extra_ProgressBarUpdate( pProgress, i, "Tables ..." );
|
||||
}
|
||||
Extra_ProgressBarStop( pProgress );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Derives the truth table for one cut.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Map_TruthsCut( Map_Man_t * p, Map_Cut_t * pCut )
|
||||
{
|
||||
// unsigned uCanon1, uCanon2;
|
||||
unsigned uTruth[2], uCanon[2];
|
||||
unsigned char uPhases[16];
|
||||
unsigned * uCanon2;
|
||||
char * pPhases2;
|
||||
int fUseFast = 1;
|
||||
int fUseSlow = 0;
|
||||
int fUseRec = 0; // this does not work for Solaris
|
||||
|
||||
extern int Map_CanonCompute( int nVarsMax, int nVarsReal, unsigned * pt, unsigned ** pptRes, char ** ppfRes );
|
||||
|
||||
// generally speaking, 1-input cut can be matched into a wire!
|
||||
if ( pCut->nLeaves == 1 )
|
||||
return;
|
||||
/*
|
||||
if ( p->nVarsMax == 5 )
|
||||
{
|
||||
uTruth[0] = pCut->uTruth;
|
||||
uTruth[1] = pCut->uTruth;
|
||||
}
|
||||
else
|
||||
*/
|
||||
Map_TruthsCutOne( p, pCut, uTruth );
|
||||
|
||||
|
||||
// compute the canonical form for the positive phase
|
||||
if ( fUseFast )
|
||||
Map_CanonComputeFast( p, p->nVarsMax, pCut->nLeaves, uTruth, uPhases, uCanon );
|
||||
else if ( fUseSlow )
|
||||
Map_CanonComputeSlow( p->uTruths, p->nVarsMax, pCut->nLeaves, uTruth, uPhases, uCanon );
|
||||
else if ( fUseRec )
|
||||
{
|
||||
// Map_CanonComputeSlow( p->uTruths, p->nVarsMax, pCut->nLeaves, uTruth, uPhases, uCanon );
|
||||
Extra_TruthCanonFastN( p->nVarsMax, pCut->nLeaves, uTruth, &uCanon2, &pPhases2 );
|
||||
/*
|
||||
if ( uCanon[0] != uCanon2[0] || uPhases[0] != pPhases2[0] )
|
||||
{
|
||||
int k = 0;
|
||||
Map_CanonCompute( p->nVarsMax, pCut->nLeaves, uTruth, &uCanon2, &pPhases2 );
|
||||
}
|
||||
*/
|
||||
uCanon[0] = uCanon2[0];
|
||||
uCanon[1] = (p->nVarsMax == 6)? uCanon2[1] : uCanon2[0];
|
||||
uPhases[0] = pPhases2[0];
|
||||
}
|
||||
else
|
||||
Map_CanonComputeSlow( p->uTruths, p->nVarsMax, pCut->nLeaves, uTruth, uPhases, uCanon );
|
||||
pCut->M[1].pSupers = Map_SuperTableLookupC( p->pSuperLib, uCanon );
|
||||
pCut->M[1].uPhase = uPhases[0];
|
||||
p->nCanons++;
|
||||
|
||||
//uCanon1 = uCanon[0] & 0xFFFF;
|
||||
|
||||
// compute the canonical form for the negative phase
|
||||
uTruth[0] = ~uTruth[0];
|
||||
uTruth[1] = ~uTruth[1];
|
||||
if ( fUseFast )
|
||||
Map_CanonComputeFast( p, p->nVarsMax, pCut->nLeaves, uTruth, uPhases, uCanon );
|
||||
else if ( fUseSlow )
|
||||
Map_CanonComputeSlow( p->uTruths, p->nVarsMax, pCut->nLeaves, uTruth, uPhases, uCanon );
|
||||
else if ( fUseRec )
|
||||
{
|
||||
// Map_CanonComputeSlow( p->uTruths, p->nVarsMax, pCut->nLeaves, uTruth, uPhases, uCanon );
|
||||
Extra_TruthCanonFastN( p->nVarsMax, pCut->nLeaves, uTruth, &uCanon2, &pPhases2 );
|
||||
/*
|
||||
if ( uCanon[0] != uCanon2[0] || uPhases[0] != pPhases2[0] )
|
||||
{
|
||||
int k = 0;
|
||||
Map_CanonCompute( p->nVarsMax, pCut->nLeaves, uTruth, &uCanon2, &pPhases2 );
|
||||
}
|
||||
*/
|
||||
uCanon[0] = uCanon2[0];
|
||||
uCanon[1] = (p->nVarsMax == 6)? uCanon2[1] : uCanon2[0];
|
||||
uPhases[0] = pPhases2[0];
|
||||
}
|
||||
else
|
||||
Map_CanonComputeSlow( p->uTruths, p->nVarsMax, pCut->nLeaves, uTruth, uPhases, uCanon );
|
||||
pCut->M[0].pSupers = Map_SuperTableLookupC( p->pSuperLib, uCanon );
|
||||
pCut->M[0].uPhase = uPhases[0];
|
||||
p->nCanons++;
|
||||
|
||||
//uCanon2 = uCanon[0] & 0xFFFF;
|
||||
//assert( p->nVarsMax == 4 );
|
||||
//Rwt_Man4ExploreCount( uCanon1 < uCanon2 ? uCanon1 : uCanon2 );
|
||||
|
||||
// restore the truth table
|
||||
uTruth[0] = ~uTruth[0];
|
||||
uTruth[1] = ~uTruth[1];
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes the truth table of one cut.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Map_TruthsCutOne( Map_Man_t * p, Map_Cut_t * pCut, unsigned uTruth[] )
|
||||
{
|
||||
unsigned uTruth1[2], uTruth2[2];
|
||||
Map_Cut_t * pTemp;
|
||||
int i;
|
||||
// mark the cut leaves
|
||||
for ( i = 0; i < pCut->nLeaves; i++ )
|
||||
{
|
||||
pTemp = pCut->ppLeaves[i]->pCuts;
|
||||
pTemp->fMark = 1;
|
||||
pTemp->M[0].uPhaseBest = p->uTruths[i][0];
|
||||
pTemp->M[1].uPhaseBest = p->uTruths[i][1];
|
||||
}
|
||||
assert( pCut->fMark == 0 );
|
||||
|
||||
// collect the cuts in the cut cone
|
||||
p->vVisited->nSize = 0;
|
||||
Map_CutsCollect_rec( pCut, p->vVisited );
|
||||
assert( p->vVisited->nSize > 0 );
|
||||
pCut->nVolume = p->vVisited->nSize;
|
||||
|
||||
// compute the tables and unmark
|
||||
for ( i = 0; i < pCut->nLeaves; i++ )
|
||||
{
|
||||
pTemp = pCut->ppLeaves[i]->pCuts;
|
||||
pTemp->fMark = 0;
|
||||
}
|
||||
for ( i = 0; i < p->vVisited->nSize; i++ )
|
||||
{
|
||||
// get the cut
|
||||
pTemp = (Map_Cut_t *)p->vVisited->pArray[i];
|
||||
pTemp->fMark = 0;
|
||||
// get truth table of the first branch
|
||||
if ( Map_CutIsComplement(pTemp->pOne) )
|
||||
{
|
||||
uTruth1[0] = ~Map_CutRegular(pTemp->pOne)->M[0].uPhaseBest;
|
||||
uTruth1[1] = ~Map_CutRegular(pTemp->pOne)->M[1].uPhaseBest;
|
||||
}
|
||||
else
|
||||
{
|
||||
uTruth1[0] = Map_CutRegular(pTemp->pOne)->M[0].uPhaseBest;
|
||||
uTruth1[1] = Map_CutRegular(pTemp->pOne)->M[1].uPhaseBest;
|
||||
}
|
||||
// get truth table of the second branch
|
||||
if ( Map_CutIsComplement(pTemp->pTwo) )
|
||||
{
|
||||
uTruth2[0] = ~Map_CutRegular(pTemp->pTwo)->M[0].uPhaseBest;
|
||||
uTruth2[1] = ~Map_CutRegular(pTemp->pTwo)->M[1].uPhaseBest;
|
||||
}
|
||||
else
|
||||
{
|
||||
uTruth2[0] = Map_CutRegular(pTemp->pTwo)->M[0].uPhaseBest;
|
||||
uTruth2[1] = Map_CutRegular(pTemp->pTwo)->M[1].uPhaseBest;
|
||||
}
|
||||
// get the truth table of the output
|
||||
if ( !pTemp->Phase )
|
||||
{
|
||||
pTemp->M[0].uPhaseBest = uTruth1[0] & uTruth2[0];
|
||||
pTemp->M[1].uPhaseBest = uTruth1[1] & uTruth2[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
pTemp->M[0].uPhaseBest = ~(uTruth1[0] & uTruth2[0]);
|
||||
pTemp->M[1].uPhaseBest = ~(uTruth1[1] & uTruth2[1]);
|
||||
}
|
||||
}
|
||||
uTruth[0] = pTemp->M[0].uPhaseBest;
|
||||
uTruth[1] = pTemp->M[1].uPhaseBest;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Recursively collect the cuts.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Map_CutsCollect_rec( Map_Cut_t * pCut, Map_NodeVec_t * vVisited )
|
||||
{
|
||||
if ( pCut->fMark )
|
||||
return;
|
||||
Map_CutsCollect_rec( Map_CutRegular(pCut->pOne), vVisited );
|
||||
Map_CutsCollect_rec( Map_CutRegular(pCut->pTwo), vVisited );
|
||||
assert( pCut->fMark == 0 );
|
||||
pCut->fMark = 1;
|
||||
Map_NodeVecPush( vVisited, (Map_Node_t *)pCut );
|
||||
}
|
||||
|
||||
/*
|
||||
{
|
||||
unsigned * uCanon2;
|
||||
char * pPhases2;
|
||||
|
||||
Map_CanonComputeSlow( p->uTruths, p->nVarsMax, pCut->nLeaves, uTruth, uPhases, uCanon );
|
||||
Map_CanonCompute( p->nVarsMax, pCut->nLeaves, uTruth, &uCanon2, &pPhases2 );
|
||||
if ( uCanon2[0] != uCanon[0] )
|
||||
{
|
||||
int v = 0;
|
||||
Map_CanonCompute( p->nVarsMax, pCut->nLeaves, uTruth, &uCanon2, &pPhases2 );
|
||||
Map_CanonComputeFast( p, p->nVarsMax, pCut->nLeaves, uTruth, uPhases, uCanon );
|
||||
}
|
||||
// else
|
||||
// {
|
||||
// printf( "Correct.\n" );
|
||||
// }
|
||||
}
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,318 +0,0 @@
|
||||
/**CFile****************************************************************
|
||||
|
||||
FileName [mapperVec.c]
|
||||
|
||||
PackageName [MVSIS 1.3: Multi-valued logic synthesis system.]
|
||||
|
||||
Synopsis [Generic technology mapping engine.]
|
||||
|
||||
Author [MVSIS Group]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 2.0. Started - June 1, 2004.]
|
||||
|
||||
Revision [$Id: mapperVec.c,v 1.3 2005/01/23 06:59:45 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "mapperInt.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static int Map_NodeVecCompareLevels( Map_Node_t ** pp1, Map_Node_t ** pp2 );
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Allocates a vector with the given capacity.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Map_NodeVec_t * Map_NodeVecAlloc( int nCap )
|
||||
{
|
||||
Map_NodeVec_t * p;
|
||||
p = ALLOC( Map_NodeVec_t, 1 );
|
||||
if ( nCap > 0 && nCap < 16 )
|
||||
nCap = 16;
|
||||
p->nSize = 0;
|
||||
p->nCap = nCap;
|
||||
p->pArray = p->nCap? ALLOC( Map_Node_t *, p->nCap ) : NULL;
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Map_NodeVecFree( Map_NodeVec_t * p )
|
||||
{
|
||||
FREE( p->pArray );
|
||||
FREE( p );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Map_Node_t ** Map_NodeVecReadArray( Map_NodeVec_t * p )
|
||||
{
|
||||
return p->pArray;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Map_NodeVecReadSize( Map_NodeVec_t * p )
|
||||
{
|
||||
return p->nSize;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Resizes the vector to the given capacity.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Map_NodeVecGrow( Map_NodeVec_t * p, int nCapMin )
|
||||
{
|
||||
if ( p->nCap >= nCapMin )
|
||||
return;
|
||||
p->pArray = REALLOC( Map_Node_t *, p->pArray, nCapMin );
|
||||
p->nCap = nCapMin;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Map_NodeVecShrink( Map_NodeVec_t * p, int nSizeNew )
|
||||
{
|
||||
assert( p->nSize >= nSizeNew );
|
||||
p->nSize = nSizeNew;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Map_NodeVecClear( Map_NodeVec_t * p )
|
||||
{
|
||||
p->nSize = 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Map_NodeVecPush( Map_NodeVec_t * p, Map_Node_t * Entry )
|
||||
{
|
||||
if ( p->nSize == p->nCap )
|
||||
{
|
||||
if ( p->nCap < 16 )
|
||||
Map_NodeVecGrow( p, 16 );
|
||||
else
|
||||
Map_NodeVecGrow( p, 2 * p->nCap );
|
||||
}
|
||||
p->pArray[p->nSize++] = Entry;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Add the element while ensuring uniqueness.]
|
||||
|
||||
Description [Returns 1 if the element was found, and 0 if it was new. ]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Map_NodeVecPushUnique( Map_NodeVec_t * p, Map_Node_t * Entry )
|
||||
{
|
||||
int i;
|
||||
for ( i = 0; i < p->nSize; i++ )
|
||||
if ( p->pArray[i] == Entry )
|
||||
return 1;
|
||||
Map_NodeVecPush( p, Entry );
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Map_Node_t * Map_NodeVecPop( Map_NodeVec_t * p )
|
||||
{
|
||||
return p->pArray[--p->nSize];
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Map_NodeVecRemove( Map_NodeVec_t * p, Map_Node_t * Entry )
|
||||
{
|
||||
int i;
|
||||
for ( i = 0; i < p->nSize; i++ )
|
||||
if ( p->pArray[i] == Entry )
|
||||
break;
|
||||
assert( i < p->nSize );
|
||||
for ( i++; i < p->nSize; i++ )
|
||||
p->pArray[i-1] = p->pArray[i];
|
||||
p->nSize--;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Map_NodeVecWriteEntry( Map_NodeVec_t * p, int i, Map_Node_t * Entry )
|
||||
{
|
||||
assert( i >= 0 && i < p->nSize );
|
||||
p->pArray[i] = Entry;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Map_Node_t * Map_NodeVecReadEntry( Map_NodeVec_t * p, int i )
|
||||
{
|
||||
assert( i >= 0 && i < p->nSize );
|
||||
return p->pArray[i];
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Sorting the entries by their integer value.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Map_NodeVecSortByLevel( Map_NodeVec_t * p )
|
||||
{
|
||||
qsort( (void *)p->pArray, p->nSize, sizeof(Map_Node_t *),
|
||||
(int (*)(const void *, const void *)) Map_NodeVecCompareLevels );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Comparison procedure for two clauses.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Map_NodeVecCompareLevels( Map_Node_t ** pp1, Map_Node_t ** pp2 )
|
||||
{
|
||||
int Level1 = Map_Regular(*pp1)->Level;
|
||||
int Level2 = Map_Regular(*pp2)->Level;
|
||||
if ( Level1 < Level2 )
|
||||
return -1;
|
||||
if ( Level1 > Level2 )
|
||||
return 1;
|
||||
if ( Map_Regular(*pp1)->Num < Map_Regular(*pp2)->Num )
|
||||
return -1;
|
||||
if ( Map_Regular(*pp1)->Num > Map_Regular(*pp2)->Num )
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
SRC += src/map/mapper/mapper.c \
|
||||
src/map/mapper/mapperCanon.c \
|
||||
src/map/mapper/mapperCore.c \
|
||||
src/map/mapper/mapperCreate.c \
|
||||
src/map/mapper/mapperCut.c \
|
||||
src/map/mapper/mapperCutUtils.c \
|
||||
src/map/mapper/mapperFanout.c \
|
||||
src/map/mapper/mapperLib.c \
|
||||
src/map/mapper/mapperMatch.c \
|
||||
src/map/mapper/mapperRefs.c \
|
||||
src/map/mapper/mapperSuper.c \
|
||||
src/map/mapper/mapperSwitch.c \
|
||||
src/map/mapper/mapperTable.c \
|
||||
src/map/mapper/mapperTime.c \
|
||||
src/map/mapper/mapperTree.c \
|
||||
src/map/mapper/mapperTruth.c \
|
||||
src/map/mapper/mapperUtils.c \
|
||||
src/map/mapper/mapperVec.c
|
||||
Reference in New Issue
Block a user