mirror of https://github.com/YosysHQ/abc.git
New command for LUT cascade decomposition.
This commit is contained in:
parent
1963422c10
commit
43adbc77e8
|
|
@ -1195,6 +1195,10 @@ SOURCE=.\src\bdd\extrab\extraBdd.h
|
|||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\bdd\extrab\extraLutCas.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\bdd\extrab\extraBddAuto.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
|
|
|||
|
|
@ -153,6 +153,7 @@ static int Abc_CommandResubCore ( Abc_Frame_t * pAbc, int argc, cha
|
|||
static int Abc_CommandResubCheck ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Abc_CommandRr ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Abc_CommandCascade ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Abc_CommandLutCas ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Abc_CommandExtract ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Abc_CommandVarMin ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Abc_CommandFaultClasses ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
|
|
@ -947,6 +948,7 @@ void Abc_Init( Abc_Frame_t * pAbc )
|
|||
Cmd_CommandAdd( pAbc, "Synthesis", "resub_check", Abc_CommandResubCheck, 0 );
|
||||
// Cmd_CommandAdd( pAbc, "Synthesis", "rr", Abc_CommandRr, 1 );
|
||||
Cmd_CommandAdd( pAbc, "Synthesis", "cascade", Abc_CommandCascade, 1 );
|
||||
Cmd_CommandAdd( pAbc, "Synthesis", "lutcas", Abc_CommandLutCas, 1 );
|
||||
Cmd_CommandAdd( pAbc, "Synthesis", "extract", Abc_CommandExtract, 1 );
|
||||
Cmd_CommandAdd( pAbc, "Synthesis", "varmin", Abc_CommandVarMin, 0 );
|
||||
Cmd_CommandAdd( pAbc, "Synthesis", "faultclasses", Abc_CommandFaultClasses, 0 );
|
||||
|
|
@ -8820,6 +8822,81 @@ usage:
|
|||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Abc_CommandLutCas( Abc_Frame_t * pAbc, int argc, char ** argv )
|
||||
{
|
||||
extern Abc_Ntk_t * Abc_NtkLutCascade( Abc_Ntk_t * pNtk, int nLutSize, int fVerbose );
|
||||
Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc), * pNtkRes;
|
||||
int c, nLutSize = 6, fVerbose = 0;
|
||||
Extra_UtilGetoptReset();
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "Kvh" ) ) != EOF )
|
||||
{
|
||||
switch ( c )
|
||||
{
|
||||
case 'K':
|
||||
if ( globalUtilOptind >= argc )
|
||||
{
|
||||
Abc_Print( -1, "Command line switch \"-K\" should be followed by an integer.\n" );
|
||||
goto usage;
|
||||
}
|
||||
nLutSize = atoi(argv[globalUtilOptind]);
|
||||
globalUtilOptind++;
|
||||
if ( nLutSize < 0 )
|
||||
goto usage;
|
||||
break;
|
||||
case 'v':
|
||||
fVerbose ^= 1;
|
||||
break;
|
||||
case 'h':
|
||||
goto usage;
|
||||
default:
|
||||
goto usage;
|
||||
}
|
||||
}
|
||||
|
||||
if ( pNtk == NULL )
|
||||
{
|
||||
Abc_Print( -1, "Empty network.\n" );
|
||||
return 1;
|
||||
}
|
||||
if ( Abc_NtkCoNum(pNtk) != 1 )
|
||||
{
|
||||
Abc_Print( -1, "This command is currently applicable only to single-output networks.\n" );
|
||||
return 1;
|
||||
}
|
||||
if ( !Abc_NtkIsStrash(pNtk) )
|
||||
{
|
||||
Abc_Print( -1, "Run command \"strash\" to convert the network into an AIG.\n" );
|
||||
return 1;
|
||||
}
|
||||
pNtkRes = Abc_NtkLutCascade( pNtk, nLutSize, fVerbose );
|
||||
if ( pNtkRes == NULL )
|
||||
{
|
||||
Abc_Print( -1, "LUT cascade mapping failed.\n" );
|
||||
return 1;
|
||||
}
|
||||
Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes );
|
||||
return 0;
|
||||
|
||||
usage:
|
||||
Abc_Print( -2, "usage: lutcas [-K <num>] [-vh]\n" );
|
||||
Abc_Print( -2, "\t derives single-rail LUT cascade for the primary output function\n" );
|
||||
Abc_Print( -2, "\t-K <num> : the number of LUT inputs [default = %d]\n", nLutSize );
|
||||
Abc_Print( -2, "\t-v : toggle verbose printout [default = %s]\n", fVerbose? "yes": "no" );
|
||||
Abc_Print( -2, "\t-h : print the command usage\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
|
|
|||
|
|
@ -19,9 +19,12 @@
|
|||
***********************************************************************/
|
||||
|
||||
#include "base/abc/abc.h"
|
||||
#include "bool/kit/kit.h"
|
||||
#include "aig/miniaig/miniaig.h"
|
||||
|
||||
#ifdef ABC_USE_CUDD
|
||||
#include "bdd/extrab/extraBdd.h"
|
||||
#include "bdd/extrab/extraLutCas.h"
|
||||
#endif
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
|
@ -116,9 +119,153 @@ Abc_Ntk_t * Abc_NtkCascade( Abc_Ntk_t * pNtk, int nLutSize, int fCheck, int fVer
|
|||
#else
|
||||
|
||||
Abc_Ntk_t * Abc_NtkCascade( Abc_Ntk_t * pNtk, int nLutSize, int fCheck, int fVerbose ) { return NULL; }
|
||||
word * Abc_LutCascade( Mini_Aig_t * p, int nLutSize, int fVerbose ) { return NULL; }
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
The decomposed structure of the LUT cascade is represented as an array of 64-bit integers (words).
|
||||
The first word in the record is the number of LUT info blocks in the record, which follow one by one.
|
||||
Each LUT info block contains the following:
|
||||
- the number of words in this block
|
||||
- the number of fanins
|
||||
- the list of fanins
|
||||
- the variable ID of the output (can be one of the fanin variables)
|
||||
- truth tables (one word for 6 vars or less; more words as needed for more than 6 vars)
|
||||
For a 6-input node, the LUT info block takes 10 words (block size, fanin count, 6 fanins, output ID, truth table).
|
||||
For a 4-input node, the LUT info block takes 8 words (block size, fanin count, 4 fanins, output ID, truth table).
|
||||
If the LUT cascade contains a 6-LUT followed by a 4-LUT, the record contains 1+10+8=19 words.
|
||||
*/
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
word * Abc_LutCascadeGenTest()
|
||||
{
|
||||
word * pLuts = ABC_CALLOC( word, 20 ); int i;
|
||||
// node count
|
||||
pLuts[0] = 2;
|
||||
// first node
|
||||
pLuts[1+0] = 10;
|
||||
pLuts[1+1] = 6;
|
||||
for ( i = 0; i < 6; i++ )
|
||||
pLuts[1+2+i] = i;
|
||||
pLuts[1+8] = 0;
|
||||
pLuts[1+9] = ABC_CONST(0x8000000000000000);
|
||||
// second node
|
||||
pLuts[11+0] = 8;
|
||||
pLuts[11+1] = 4;
|
||||
for ( i = 0; i < 4; i++ )
|
||||
pLuts[11+2+i] = i ? i + 5 : 0;
|
||||
pLuts[11+6] = 1;
|
||||
pLuts[11+7] = ABC_CONST(0xFFFEFFFEFFFEFFFE);
|
||||
return pLuts;
|
||||
}
|
||||
void Abc_LutCascadePrint( word * pLuts )
|
||||
{
|
||||
int n, i, k;
|
||||
printf( "Single-rail LUT cascade has %d nodes:\n", (int)pLuts[0] );
|
||||
for ( n = 0, i = 1; n < pLuts[0]; n++, i += pLuts[i] )
|
||||
{
|
||||
word nIns = pLuts[i+1];
|
||||
word * pIns = pLuts+i+2;
|
||||
word * pT = pLuts+i+2+nIns+1;
|
||||
printf( "LUT%d : ", n );
|
||||
printf( "%02d = F( ", (int)pIns[nIns] );
|
||||
for ( k = 0; k < nIns; k++ )
|
||||
printf( "%02d ", (int)pIns[k] );
|
||||
for ( ; k < 8; k++ )
|
||||
printf( " " );
|
||||
printf( ") " );
|
||||
Extra_PrintHex2( stdout, (unsigned *)pT, nIns );
|
||||
printf( "\n" );
|
||||
}
|
||||
}
|
||||
word * Abc_LutCascadeTest( Mini_Aig_t * p, int nLutSize, int fVerbose )
|
||||
{
|
||||
word * pLuts = Abc_LutCascadeGenTest();
|
||||
Abc_LutCascadePrint( pLuts );
|
||||
return pLuts;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Abc_Obj_t * Abc_NtkLutCascadeDeriveSop( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNodeNew, word * pT, int nIns, Vec_Int_t * vCover )
|
||||
{
|
||||
int RetValue = Kit_TruthIsop( (unsigned *)pT, nIns, vCover, 1 );
|
||||
assert( RetValue == 0 || RetValue == 1 );
|
||||
if ( Vec_IntSize(vCover) == 0 || (Vec_IntSize(vCover) == 1 && Vec_IntEntry(vCover,0) == 0) ) {
|
||||
assert( RetValue == 0 );
|
||||
pNodeNew->pData = Abc_SopCreateAnd( (Mem_Flex_t *)pNtkNew->pManFunc, nIns, NULL );
|
||||
return (Vec_IntSize(vCover) == 0) ? Abc_NtkCreateNodeConst0(pNtkNew) : Abc_NtkCreateNodeConst1(pNtkNew);
|
||||
}
|
||||
else {
|
||||
char * pSop = Abc_SopCreateFromIsop( (Mem_Flex_t *)pNtkNew->pManFunc, nIns, vCover );
|
||||
if ( RetValue ) Abc_SopComplement( (char *)pSop );
|
||||
pNodeNew->pData = pSop;
|
||||
return pNodeNew;
|
||||
}
|
||||
}
|
||||
Abc_Ntk_t * Abc_NtkLutCascadeFromLuts( word * pLuts, Abc_Ntk_t * pNtk, int nLutSize, int fVerbose )
|
||||
{
|
||||
Abc_Ntk_t * pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_LOGIC, ABC_FUNC_SOP );
|
||||
Vec_Int_t * vCover = Vec_IntAlloc( 1000 ); word n, i, k, iLastLut = -1;
|
||||
assert( Abc_NtkCoNum(pNtk) == 1 );
|
||||
for ( n = 0, i = 1; n < pLuts[0]; n++, i += pLuts[i] )
|
||||
{
|
||||
word nIns = pLuts[i+1];
|
||||
word * pIns = pLuts+i+2;
|
||||
word * pT = pLuts+i+2+nIns+1;
|
||||
Abc_Obj_t * pNodeNew = Abc_NtkCreateNode( pNtkNew );
|
||||
for ( k = 0; k < nIns; k++ )
|
||||
Abc_ObjAddFanin( pNodeNew, Abc_NtkCi(pNtk, pIns[k])->pCopy );
|
||||
Abc_NtkCi(pNtk, pIns[nIns])->pCopy = Abc_NtkLutCascadeDeriveSop( pNtkNew, pNodeNew, pT, nIns, vCover );
|
||||
iLastLut = pIns[nIns];
|
||||
}
|
||||
Vec_IntFree( vCover );
|
||||
Abc_ObjAddFanin( Abc_NtkCo(pNtk, 0)->pCopy, Abc_NtkCi(pNtk, iLastLut)->pCopy );
|
||||
if ( !Abc_NtkCheck( pNtkNew ) )
|
||||
{
|
||||
printf( "Abc_NtkLutCascadeFromLuts: The network check has failed.\n" );
|
||||
Abc_NtkDelete( pNtkNew );
|
||||
return NULL;
|
||||
}
|
||||
return pNtkNew;
|
||||
}
|
||||
Abc_Ntk_t * Abc_NtkLutCascade( Abc_Ntk_t * pNtk, int nLutSize, int fVerbose )
|
||||
{
|
||||
extern Gia_Man_t * Abc_NtkStrashToGia( Abc_Ntk_t * pNtk );
|
||||
extern Mini_Aig_t * Gia_ManToMiniAig( Gia_Man_t * pGia );
|
||||
extern word * Abc_LutCascade( Mini_Aig_t * p, int nLutSize, int fVerbose );
|
||||
Gia_Man_t * pGia = Abc_NtkStrashToGia( pNtk );
|
||||
Mini_Aig_t * pM = Gia_ManToMiniAig( pGia );
|
||||
word * pLuts = Abc_LutCascade( pM, nLutSize, fVerbose );
|
||||
Abc_Ntk_t * pNew = pLuts ? Abc_NtkLutCascadeFromLuts( pLuts, pNtk, nLutSize, fVerbose ) : NULL;
|
||||
ABC_FREE( pLuts );
|
||||
Mini_AigStop( pM );
|
||||
Gia_ManStop( pGia );
|
||||
return pNew;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -0,0 +1,72 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [extraLutCas.h]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [extra]
|
||||
|
||||
Synopsis [LUT cascade decomposition.]
|
||||
|
||||
Description [LUT cascade decomposition.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - August 6, 2024.]
|
||||
|
||||
Revision [$Id: extraLutCas.h,v 1.00 2024/08/06 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef ABC__misc__extra__extra_lutcas_h
|
||||
#define ABC__misc__extra__extra_lutcas_h
|
||||
|
||||
#ifdef _WIN32
|
||||
#define inline __inline // compatible with MS VS 6.0
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "bdd/cudd/cuddInt.h"
|
||||
|
||||
ABC_NAMESPACE_HEADER_START
|
||||
|
||||
/*
|
||||
The decomposed structure of the LUT cascade is represented as an array of 64-bit integers (words).
|
||||
The first word in the record is the number of LUT info blocks in the record, which follow one by one.
|
||||
Each LUT info block contains the following:
|
||||
- the number of words in this block
|
||||
- the number of fanins
|
||||
- the list of fanins
|
||||
- the variable ID of the output (can be one of the fanin variables)
|
||||
- truth tables (one word for 6 vars or less; more words as needed for more than 6 vars)
|
||||
For a 6-input node, the LUT info block takes 10 words (block size, fanin count, 6 fanins, output ID, truth table).
|
||||
For a 4-input node, the LUT info block takes 8 words (block size, fanin count, 4 fanins, output ID, truth table).
|
||||
If the LUT cascade contains a 6-LUT followed by a 4-LUT, the record contains 1+10+8=19 words.
|
||||
*/
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline word * Abc_LutCascade( Mini_Aig_t * p, int nLutSize, int fVerbose )
|
||||
{
|
||||
word * pLuts = NULL;
|
||||
return pLuts;
|
||||
}
|
||||
|
||||
ABC_NAMESPACE_HEADER_END
|
||||
|
||||
#endif /* __EXTRA_H__ */
|
||||
Loading…
Reference in New Issue