Adding ACD for 66 LUT structure using a new method

This commit is contained in:
aletempiac 2024-02-08 09:36:58 +01:00
parent 6d1d52deaa
commit 2d9af6c9a4
9 changed files with 1383 additions and 3 deletions

View File

@ -19447,7 +19447,7 @@ int Abc_CommandIf( Abc_Frame_t * pAbc, int argc, char ** argv )
If_ManSetDefaultPars( pPars );
pPars->pLutLib = (If_LibLut_t *)Abc_FrameReadLibLut();
Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "KCFAGRNTXYZDEWSqaflepmrsdbgxyzuojiktncvh" ) ) != EOF )
while ( ( c = Extra_UtilGetopt( argc, argv, "KCFAGRNTXYZDEWSJqaflepmrsdbgxyzuojiktncvh" ) ) != EOF )
{
switch ( c )
{
@ -19621,6 +19621,21 @@ int Abc_CommandIf( Abc_Frame_t * pAbc, int argc, char ** argv )
goto usage;
}
break;
case 'J':
if ( globalUtilOptind >= argc )
{
Abc_Print( -1, "Command line switch \"-J\" should be followed by string.\n" );
goto usage;
}
pPars->pLutStruct = argv[globalUtilOptind];
pPars->fEnableStructN = 1;
globalUtilOptind++;
if ( strlen(pPars->pLutStruct) != 2 )
{
Abc_Print( -1, "Command line switch \"-J\" should be followed by a 2-char string (e.g. \"66\").\n" );
goto usage;
}
break;
case 'q':
pPars->fPreprocess ^= 1;
break;
@ -19801,7 +19816,14 @@ int Abc_CommandIf( Abc_Frame_t * pAbc, int argc, char ** argv )
Abc_Print( -1, "This feature only works for [6;16]-LUTs.\n" );
return 1;
}
pPars->pFuncCell = pPars->fDelayOptLut ? NULL : If_CutPerformCheck16;
if ( pPars->fEnableStructN )
{
pPars->pFuncCell = pPars->fDelayOptLut ? NULL : If_CutPerformCheck66;
}
else
{
pPars->pFuncCell = pPars->fDelayOptLut ? NULL : If_CutPerformCheck16;
}
pPars->fCutMin = 1;
}
@ -20003,6 +20025,7 @@ usage:
Abc_Print( -2, "\t-E float : sets epsilon used for tie-breaking [default = %f]\n", pPars->Epsilon );
Abc_Print( -2, "\t-W float : sets wire delay between adjects LUTs [default = %f]\n", pPars->WireDelay );
Abc_Print( -2, "\t-S str : string representing the LUT structure [default = %s]\n", pPars->pLutStruct ? pPars->pLutStruct : "not used" );
Abc_Print( -2, "\t-J str : string representing the LUT structure (new method) [default = %s]\n", pPars->pLutStruct ? pPars->pLutStruct : "not used" );
Abc_Print( -2, "\t-q : toggles preprocessing using several starting points [default = %s]\n", pPars->fPreprocess? "yes": "no" );
Abc_Print( -2, "\t-a : toggles area-oriented mapping [default = %s]\n", pPars->fArea? "yes": "no" );
Abc_Print( -2, "\t-r : enables expansion/reduction of the best cuts [default = %s]\n", pPars->fExpRed? "yes": "no" );

View File

@ -18,6 +18,7 @@
#include "ac_wrapper.h"
#include "ac_decomposition.hpp"
#include "acd66.hpp"
ABC_NAMESPACE_IMPL_START
@ -69,4 +70,45 @@ int acd_decompose( word * pTruth, unsigned nVars, int lutSize, unsigned *pdelay,
return 0;
}
int acd66_evaluate( word * pTruth, unsigned nVars, int verify )
{
using namespace acd;
acd66_params ps;
ps.verify = static_cast<bool>( verify );
acd66_impl acd( nVars, ps );
if ( acd.run( pTruth ) == 0 )
return 0;
if ( !verify )
return 1;
int val = acd.compute_decomposition();
if ( val != 0 )
{
return 0;
}
return 1;
}
int acd66_decompose( word * pTruth, unsigned nVars, unsigned char *decomposition )
{
using namespace acd;
acd66_params ps;
acd66_impl acd( nVars, ps );
acd.run( pTruth );
int val = acd.compute_decomposition();
if ( val != 0 )
{
return -1;
}
acd.get_decomposition( decomposition );
return 0;
}
ABC_NAMESPACE_IMPL_END

View File

@ -28,6 +28,9 @@ ABC_NAMESPACE_HEADER_START
int acd_evaluate( word * pTruth, unsigned nVars, int lutSize, unsigned *pdelay, unsigned *cost, int try_no_late_arrival );
int acd_decompose( word * pTruth, unsigned nVars, int lutSize, unsigned *pdelay, unsigned char *decomposition );
int acd66_evaluate( word * pTruth, unsigned nVars, int verify );
int acd66_decompose( word * pTruth, unsigned nVars, unsigned char *decomposition );
ABC_NAMESPACE_HEADER_END
#endif

1093
src/map/if/acd/acd66.hpp Normal file

File diff suppressed because it is too large Load Diff

View File

@ -133,6 +133,24 @@ void swap_inplace( TT& tt, uint8_t var_index1, uint8_t var_index2 )
}
}
template<uint32_t NumVars>
inline void swap_inplace( static_truth_table<NumVars, true>& tt, uint8_t var_index1, uint8_t var_index2 )
{
if ( var_index1 == var_index2 )
{
return;
}
if ( var_index1 > var_index2 )
{
std::swap( var_index1, var_index2 );
}
const auto& pmask = detail::ppermutation_masks[var_index1][var_index2];
const auto shift = ( 1 << var_index2 ) - ( 1 << var_index1 );
tt._bits = ( tt._bits & pmask[0] ) | ( ( tt._bits & pmask[1] ) << shift ) | ( ( tt._bits & pmask[2] ) >> shift );
}
/*! \brief Extends smaller truth table to larger one
The most significant variables will not be in the functional support of the

View File

@ -12,8 +12,116 @@ ABC_NAMESPACE_CXX_HEADER_START
namespace kitty
{
template<uint32_t NumVars, bool = ( NumVars <= 6 )>
struct static_truth_table;
/*! Truth table (for up to 6 variables) in which number of variables is known at compile time.
*/
template<uint32_t NumVars>
struct static_truth_table
struct static_truth_table<NumVars, true>
{
/*! \cond PRIVATE */
enum
{
NumBits = uint64_t( 1 ) << NumVars
};
/*! \endcond */
/*! Constructs a new static truth table instance with the same number of variables. */
inline static_truth_table<NumVars> construct() const
{
return static_truth_table<NumVars>();
}
/*! Returns number of variables.
*/
inline auto num_vars() const noexcept { return NumVars; }
/*! Returns number of blocks.
*/
inline auto num_blocks() const noexcept { return 1u; }
/*! Returns number of bits.
*/
inline auto num_bits() const noexcept { return NumBits; }
/*! \brief Begin iterator to bits.
*/
inline auto begin() noexcept { return &_bits; }
/*! \brief End iterator to bits.
*/
inline auto end() noexcept { return ( &_bits ) + 1; }
/*! \brief Begin iterator to bits.
*/
inline auto begin() const noexcept { return &_bits; }
/*! \brief End iterator to bits.
*/
inline auto end() const noexcept { return ( &_bits ) + 1; }
/*! \brief Reverse begin iterator to bits.
*/
inline auto rbegin() noexcept { return &_bits; }
/*! \brief Reverse end iterator to bits.
*/
inline auto rend() noexcept { return ( &_bits ) + 1; }
/*! \brief Constant begin iterator to bits.
*/
inline auto cbegin() const noexcept { return &_bits; }
/*! \brief Constant end iterator to bits.
*/
inline auto cend() const noexcept { return ( &_bits ) + 1; }
/*! \brief Constant reverse begin iterator to bits.
*/
inline auto crbegin() const noexcept { return &_bits; }
/*! \brief Constant everse end iterator to bits.
*/
inline auto crend() const noexcept { return ( &_bits ) + 1; }
/*! \brief Assign other truth table if number of variables match.
This replaces the current truth table with another truth table, if `other`
has the same number of variables. Otherwise, the truth table is not
changed.
\param other Other truth table
*/
template<class TT>
static_truth_table<NumVars>& operator=( const TT& other )
{
if ( other.num_vars() == num_vars() )
{
std::copy( other.begin(), other.end(), begin() );
}
return *this;
}
/*! Masks the number of valid truth table bits.
If the truth table has less than 6 variables, it may not use all
the bits. This operation makes sure to zero out all non-valid
bits.
*/
inline void mask_bits() noexcept { _bits &= detail::masks[NumVars]; }
/*! \cond PRIVATE */
public: /* fields */
uint64_t _bits = 0;
/*! \endcond */
};
/*! Truth table (more than 6 variables) in which number of variables is known at compile time.
*/
template<uint32_t NumVars>
struct static_truth_table<NumVars, false>
{
/*! \cond PRIVATE */
enum

View File

@ -151,6 +151,7 @@ struct If_Par_t_
int fVerbose; // the verbosity flag
int fVerboseTrace; // the verbosity flag
char * pLutStruct; // LUT structure
int fEnableStructN;// LUT structure using a new method
float WireDelay; // wire delay
// internal parameters
int fSkipCutFilter;// skip cut filter
@ -551,6 +552,7 @@ extern int If_CutPerformCheck07( If_Man_t * p, unsigned * pTruth, in
extern int If_CutPerformCheck08( If_Man_t * p, unsigned * pTruth, int nVars, int nLeaves, char * pStr );
extern int If_CutPerformCheck10( If_Man_t * p, unsigned * pTruth, int nVars, int nLeaves, char * pStr );
extern int If_CutPerformCheck16( If_Man_t * p, unsigned * pTruth, int nVars, int nLeaves, char * pStr );
extern int If_CutPerformCheck66( If_Man_t * p, unsigned * pTruth, int nVars, int nLeaves, char * pStr );
extern int If_CutPerformCheck45( If_Man_t * p, unsigned * pTruth, int nVars, int nLeaves, char * pStr );
extern int If_CutPerformCheck54( If_Man_t * p, unsigned * pTruth, int nVars, int nLeaves, char * pStr );
extern int If_CutPerformCheck75( If_Man_t * p, unsigned * pTruth, int nVars, int nLeaves, char * pStr );

90
src/map/if/ifDec66.c Normal file
View File

@ -0,0 +1,90 @@
/**CFile****************************************************************
FileName [ifDec16.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [FPGA mapping based on priority cuts.]
Synopsis [Fast checking procedures.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - November 21, 2006.]
Revision [$Id: ifDec16.c,v 1.00 2006/11/21 00:00:00 alanmi Exp $]
***********************************************************************/
#include "if.h"
#include "bool/kit/kit.h"
#include "misc/vec/vecMem.h"
ABC_NAMESPACE_IMPL_START
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Performs ACD into 66 cascade.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int If_CutPerformCheck66( If_Man_t * p, unsigned * pTruth0, int nVars, int nLeaves, char * pStr )
{
unsigned pTruth[IF_MAX_FUNC_LUTSIZE > 5 ? 1 << (IF_MAX_FUNC_LUTSIZE - 5) : 1];
int i, Length;
// stretch the truth table
assert( nVars >= 6 );
memcpy( pTruth, pTruth0, sizeof(word) * Abc_TtWordNum(nVars) );
Abc_TtStretch6( (word *)pTruth, nLeaves, p->pPars->nLutSize );
// if cutmin is disabled, minimize the function
if ( !p->pPars->fCutMin )
nLeaves = Abc_TtMinBase( (word *)pTruth, NULL, nLeaves, nVars );
// quit if parameters are wrong
Length = strlen(pStr);
if ( Length != 2 )
{
printf( "Wrong LUT struct (%s)\n", pStr );
return 0;
}
for ( i = 0; i < Length; i++ )
{
if ( pStr[i] != '6' )
{
printf( "The LUT size (%d) should belong to {6}.\n", pStr[i] - '0' );
return 0;
}
}
if ( nLeaves > 11 )
{
printf( "The cut size (%d) is too large for the LUT structure %s.\n", nLeaves, pStr );
return 0;
}
// consider easy case
if ( nLeaves <= 6 )
return 1;
// derive the decomposition
return (int)(acd66_evaluate( (word *)pTruth, nVars, 1 ) > 0 );
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
ABC_NAMESPACE_IMPL_END

View File

@ -7,6 +7,7 @@ SRC += src/map/if/ifCom.c \
src/map/if/ifDec08.c \
src/map/if/ifDec10.c \
src/map/if/ifDec16.c \
src/map/if/ifDec66.c \
src/map/if/ifDec75.c \
src/map/if/ifDelay.c \
src/map/if/ifDsd.c \