mirror of
https://github.com/YosysHQ/abc.git
synced 2026-09-01 10:18:06 +02:00
316 lines
9.9 KiB
C
316 lines
9.9 KiB
C
/**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"
|
|
|
|
ABC_NAMESPACE_IMPL_START
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
/// 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 = NULL; // Suppress "might be used uninitialized"
|
|
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 ///
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
ABC_NAMESPACE_IMPL_END
|
|
|