mirror of https://github.com/YosysHQ/abc.git
Merge remote-tracking branch 'upstream/master' into yosys-experimental
This commit is contained in:
commit
7e961f4f3e
46
Makefile
46
Makefile
|
|
@ -8,10 +8,19 @@ MSG_PREFIX ?=
|
|||
ABCSRC ?= .
|
||||
VPATH = $(ABCSRC)
|
||||
|
||||
$(info $(MSG_PREFIX)Using CC=$(CC))
|
||||
$(info $(MSG_PREFIX)Using CXX=$(CXX))
|
||||
$(info $(MSG_PREFIX)Using AR=$(AR))
|
||||
$(info $(MSG_PREFIX)Using LD=$(LD))
|
||||
# whether to print build options, tools, and echo commands while building
|
||||
ifdef ABC_MAKE_VERBOSE
|
||||
VERBOSE=
|
||||
abc_info = $(info $(1))
|
||||
else
|
||||
VERBOSE=@
|
||||
abc_info =
|
||||
endif
|
||||
|
||||
$(call abc_info,$(MSG_PREFIX)Using CC=$(CC))
|
||||
$(call abc_info,$(MSG_PREFIX)Using CXX=$(CXX))
|
||||
$(call abc_info,$(MSG_PREFIX)Using AR=$(AR))
|
||||
$(call abc_info,$(MSG_PREFIX)Using LD=$(LD))
|
||||
|
||||
PROG := abc
|
||||
OS := $(shell uname -s)
|
||||
|
|
@ -66,14 +75,14 @@ endif
|
|||
ifdef ABC_USE_NAMESPACE
|
||||
CFLAGS += -DABC_NAMESPACE=$(ABC_USE_NAMESPACE) -fpermissive -x c++
|
||||
CC := $(CXX)
|
||||
$(info $(MSG_PREFIX)Compiling in namespace $(ABC_USE_NAMESPACE))
|
||||
$(call abc_info,$(MSG_PREFIX)Compiling in namespace $(ABC_USE_NAMESPACE))
|
||||
endif
|
||||
|
||||
# compile CUDD with ABC
|
||||
ifndef ABC_USE_NO_CUDD
|
||||
CFLAGS += -DABC_USE_CUDD=1
|
||||
MODULES += src/bdd/cudd src/bdd/extrab src/bdd/dsd src/bdd/epd src/bdd/mtr src/bdd/reo src/bdd/cas src/bdd/bbr src/bdd/llb
|
||||
$(info $(MSG_PREFIX)Compiling with CUDD)
|
||||
$(call abc_info,$(MSG_PREFIX)Compiling with CUDD)
|
||||
endif
|
||||
|
||||
ABC_READLINE_INCLUDES ?=
|
||||
|
|
@ -87,28 +96,21 @@ ifndef ABC_USE_NO_READLINE
|
|||
CFLAGS += -I/usr/local/include
|
||||
LDFLAGS += -L/usr/local/lib
|
||||
endif
|
||||
$(info $(MSG_PREFIX)Using libreadline)
|
||||
$(call abc_info,$(MSG_PREFIX)Using libreadline)
|
||||
endif
|
||||
|
||||
# whether to compile with thread support
|
||||
ifndef ABC_USE_NO_PTHREADS
|
||||
CFLAGS += -DABC_USE_PTHREADS
|
||||
LIBS += -lpthread
|
||||
$(info $(MSG_PREFIX)Using pthreads)
|
||||
$(call abc_info,$(MSG_PREFIX)Using pthreads)
|
||||
endif
|
||||
|
||||
# whether to compile into position independent code
|
||||
ifdef ABC_USE_PIC
|
||||
CFLAGS += -fPIC
|
||||
LIBS += -fPIC
|
||||
$(info $(MSG_PREFIX)Compiling position independent code)
|
||||
endif
|
||||
|
||||
# whether to echo commands while building
|
||||
ifdef ABC_MAKE_VERBOSE
|
||||
VERBOSE=
|
||||
else
|
||||
VERBOSE=@
|
||||
$(call abc_info,$(MSG_PREFIX)Compiling position independent code)
|
||||
endif
|
||||
|
||||
# Set -Wno-unused-bug-set-variable for GCC 4.6.0 and greater only
|
||||
|
|
@ -120,16 +122,16 @@ GCC_VERSION=$(shell $(CC) -dumpversion)
|
|||
GCC_MAJOR=$(word 1,$(subst .,$(space),$(GCC_VERSION)))
|
||||
GCC_MINOR=$(word 2,$(subst .,$(space),$(GCC_VERSION)))
|
||||
|
||||
$(info $(MSG_PREFIX)Found GCC_VERSION $(GCC_VERSION))
|
||||
$(call abc_info,$(MSG_PREFIX)Found GCC_VERSION $(GCC_VERSION))
|
||||
ifeq ($(findstring $(GCC_MAJOR),0 1 2 3),)
|
||||
ifeq ($(GCC_MAJOR),4)
|
||||
$(info $(MSG_PREFIX)Found GCC_MAJOR==4)
|
||||
$(call abc_info,$(MSG_PREFIX)Found GCC_MAJOR==4)
|
||||
ifeq ($(findstring $(GCC_MINOR),0 1 2 3 4 5),)
|
||||
$(info $(MSG_PREFIX)Found GCC_MINOR>=6)
|
||||
$(call abc_info,$(MSG_PREFIX)Found GCC_MINOR>=6)
|
||||
CFLAGS += -Wno-unused-but-set-variable
|
||||
endif
|
||||
else
|
||||
$(info $(MSG_PREFIX)Found GCC_MAJOR>=5)
|
||||
$(call abc_info,$(MSG_PREFIX)Found GCC_MAJOR>=5)
|
||||
CFLAGS += -Wno-unused-but-set-variable
|
||||
endif
|
||||
endif
|
||||
|
|
@ -148,10 +150,10 @@ endif
|
|||
|
||||
ifdef ABC_USE_LIBSTDCXX
|
||||
LIBS += -lstdc++
|
||||
$(info $(MSG_PREFIX)Using explicit -lstdc++)
|
||||
$(call abc_info,$(MSG_PREFIX)Using explicit -lstdc++)
|
||||
endif
|
||||
|
||||
$(info $(MSG_PREFIX)Using CFLAGS=$(CFLAGS))
|
||||
$(call abc_info,$(MSG_PREFIX)Using CFLAGS=$(CFLAGS))
|
||||
CXXFLAGS += $(CFLAGS) -std=c++17 -fno-exceptions
|
||||
|
||||
SRC :=
|
||||
|
|
|
|||
|
|
@ -140,6 +140,7 @@ struct Gia_Man_t_
|
|||
void * pSatlutWinman; // windowing for SAT-based mapping
|
||||
Vec_Int_t * vPacking; // packing information
|
||||
Vec_Int_t * vConfigs; // cell configurations
|
||||
Vec_Str_t * vConfigs2; // cell configurations
|
||||
char * pCellStr; // cell description
|
||||
Vec_Int_t * vLutConfigs; // LUT configurations
|
||||
Vec_Int_t * vEdgeDelay; // special edge information
|
||||
|
|
@ -1827,6 +1828,10 @@ extern void Tas_ManSatPrintStats( Tas_Man_t * p );
|
|||
extern int Tas_ManSolve( Tas_Man_t * p, Gia_Obj_t * pObj, Gia_Obj_t * pObj2 );
|
||||
extern int Tas_ManSolveArray( Tas_Man_t * p, Vec_Ptr_t * vObjs );
|
||||
|
||||
/*=== giaDecGraph.c ===========================================================*/
|
||||
extern Gia_Man_t* Gia_ManDecGraph( Gia_Man_t* p );
|
||||
extern Gia_Man_t* Gia_ManDecGraphFromFile( char* pFileName );
|
||||
|
||||
/*=== giaBound.c ===========================================================*/
|
||||
typedef struct Bnd_Man_t_ Bnd_Man_t;
|
||||
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
#include "gia.h"
|
||||
#include "misc/tim/tim.h"
|
||||
#include "base/main/main.h"
|
||||
#include "map/if/if.h"
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
|
|
@ -651,6 +652,9 @@ Gia_Man_t * Gia_AigerReadFromMemory( char * pContents, int nFileSize, int fGiaSi
|
|||
pNew->vInArrs = Vec_FltStart( nInputs );
|
||||
memcpy( Vec_FltArray(pNew->vInArrs), pCur, (size_t)4*nInputs ); pCur += 4*nInputs;
|
||||
if ( fVerbose ) printf( "Finished reading extension \"i\".\n" );
|
||||
if ( Vec_FltSize(pNew->vInArrs) == Gia_ManPiNum(pNew) )
|
||||
Vec_FltFillExtra(pNew->vInArrs, Gia_ManCiNum(pNew), 0);
|
||||
assert( Vec_FltSize(pNew->vInArrs) == Gia_ManCiNum(pNew) );
|
||||
}
|
||||
else if ( *pCur == 'o' )
|
||||
{
|
||||
|
|
@ -659,6 +663,9 @@ Gia_Man_t * Gia_AigerReadFromMemory( char * pContents, int nFileSize, int fGiaSi
|
|||
pNew->vOutReqs = Vec_FltStart( nOutputs );
|
||||
memcpy( Vec_FltArray(pNew->vOutReqs), pCur, (size_t)4*nOutputs ); pCur += 4*nOutputs;
|
||||
if ( fVerbose ) printf( "Finished reading extension \"o\".\n" );
|
||||
if ( Vec_FltSize(pNew->vOutReqs) == Gia_ManPoNum(pNew) )
|
||||
Vec_FltFillExtra(pNew->vOutReqs, Gia_ManCoNum(pNew), 0);
|
||||
assert( Vec_FltSize(pNew->vOutReqs) == Gia_ManCoNum(pNew) );
|
||||
}
|
||||
// read equivalence classes
|
||||
else if ( *pCur == 'e' )
|
||||
|
|
@ -800,6 +807,36 @@ Gia_Man_t * Gia_AigerReadFromMemory( char * pContents, int nFileSize, int fGiaSi
|
|||
assert( pCur == pCurTemp );
|
||||
if ( fVerbose ) printf( "Finished reading extension \"b\".\n" );
|
||||
}
|
||||
// read configuration data for extension "j"
|
||||
else if ( *pCur == 'j' )
|
||||
{
|
||||
int nSize, Reserved, NumCellTypes, CellId, BytesPerInstance, TotalInstances;
|
||||
pCur++;
|
||||
nSize = Gia_AigerReadInt(pCur);
|
||||
pCurTemp = pCur + nSize + 4; pCur += 4;
|
||||
// Read reserved value (should be 0)
|
||||
Reserved = Gia_AigerReadInt(pCur); pCur += 4;
|
||||
assert( Reserved == 0 );
|
||||
// Read number of cell types
|
||||
NumCellTypes = Gia_AigerReadInt(pCur); pCur += 4;
|
||||
// Skip cell type definitions (we know them already)
|
||||
for ( i = 0; i < NumCellTypes; i++ )
|
||||
{
|
||||
CellId = Gia_AigerReadInt(pCur); pCur += 4;
|
||||
// Skip function description string (null-terminated)
|
||||
while ( *pCur++ != '\0' );
|
||||
BytesPerInstance = Gia_AigerReadInt(pCur); pCur += 4;
|
||||
}
|
||||
// Read total number of instances
|
||||
TotalInstances = Gia_AigerReadInt(pCur); pCur += 4;
|
||||
// Create byte vector for instance data
|
||||
pNew->vConfigs2 = Vec_StrAlloc( (int)(pCurTemp - pCur) );
|
||||
// Read instance data as bytes
|
||||
while ( pCur < pCurTemp )
|
||||
Vec_StrPush( pNew->vConfigs2, *pCur++ );
|
||||
assert( pCur == pCurTemp );
|
||||
if ( fVerbose ) printf( "Finished reading extension \"j\".\n" );
|
||||
}
|
||||
// read choices
|
||||
else if ( *pCur == 'q' )
|
||||
{
|
||||
|
|
@ -1514,6 +1551,88 @@ void Gia_AigerWriteS( Gia_Man_t * pInit, char * pFileName, int fWriteSymbols, in
|
|||
for ( i = 0; i < Vec_IntSize(p->vConfigs); i++ )
|
||||
Gia_FileWriteBufferSize( pFile, Vec_IntEntry(p->vConfigs, i) );
|
||||
}
|
||||
// write configuration data for extension "j"
|
||||
if ( p->vConfigs2 )
|
||||
{
|
||||
int nTotalSize, nInstances = 0;
|
||||
If_LibCell_t * pLibCell = (If_LibCell_t *)Abc_FrameReadLibCell();
|
||||
char *pCell0, *pCell1, *pCell2;
|
||||
|
||||
// Get formulas from cell library or use defaults
|
||||
if ( pLibCell && pLibCell->nCellNum == 3 &&
|
||||
pLibCell->pCellNames[0] && pLibCell->pCellNames[1] && pLibCell->pCellNames[2] )
|
||||
{
|
||||
pCell0 = pLibCell->pCellNames[0];
|
||||
pCell1 = pLibCell->pCellNames[1];
|
||||
pCell2 = pLibCell->pCellNames[2];
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( !pLibCell )
|
||||
Abc_Print( 0, "Warning: Cell library is not loaded. Using generic formulas.\n" );
|
||||
else if ( pLibCell->nCellNum != 3 )
|
||||
Abc_Print( 0, "Warning: Cell library has %d cells (expected exactly 3). Using generic formulas.\n", pLibCell->nCellNum );
|
||||
else
|
||||
Abc_Print( 0, "Warning: Cell library does not contain all required cells. Using generic formulas.\n" );
|
||||
pCell0 = "Formula1";
|
||||
pCell1 = "Formula2";
|
||||
pCell2 = "Formula3";
|
||||
}
|
||||
// Count instances by scanning the byte data
|
||||
for ( i = 0; i < Vec_StrSize(p->vConfigs2); )
|
||||
{
|
||||
unsigned char CellId = (unsigned char)Vec_StrEntry(p->vConfigs2, i);
|
||||
if ( CellId == 0 )
|
||||
i += 4; // 1 byte CellId + 2 bytes truth table + 1 padding
|
||||
else if ( CellId == 1 )
|
||||
i += 12; // 1 byte CellId + 4 bytes mapping + 4 bytes truth tables + 3 padding
|
||||
else if ( CellId == 2 )
|
||||
i += 12; // 1 byte CellId + 5 bytes mapping + 4 bytes truth tables + 2 padding
|
||||
else
|
||||
assert( 0 ); // Unknown cell type
|
||||
nInstances++;
|
||||
}
|
||||
fprintf( pFile, "j" );
|
||||
// Calculate total size
|
||||
nTotalSize = 4; // Reserved value
|
||||
nTotalSize += 4; // Number of cell types
|
||||
// Cell type 0
|
||||
nTotalSize += 4; // CellId
|
||||
nTotalSize += strlen(pCell0) + 1; // Function description
|
||||
nTotalSize += 4; // Bytes per instance
|
||||
// Cell type 1
|
||||
nTotalSize += 4; // CellId
|
||||
nTotalSize += strlen(pCell1) + 1; // Function description
|
||||
nTotalSize += 4; // Bytes per instance
|
||||
// Cell type 2
|
||||
nTotalSize += 4; // CellId
|
||||
nTotalSize += strlen(pCell2) + 1; // Function description
|
||||
nTotalSize += 4; // Bytes per instance
|
||||
// Instance data
|
||||
nTotalSize += 4; // Total instances count
|
||||
nTotalSize += Vec_StrSize(p->vConfigs2); // Actual instance data
|
||||
Gia_FileWriteBufferSize( pFile, nTotalSize );
|
||||
// Write reserved value
|
||||
Gia_FileWriteBufferSize( pFile, 0 );
|
||||
// Write number of cell types
|
||||
Gia_FileWriteBufferSize( pFile, 3 );
|
||||
// Write cell type 0 (LUT4)
|
||||
Gia_FileWriteBufferSize( pFile, 0 ); // CellId
|
||||
fwrite( pCell0, 1, strlen(pCell0) + 1, pFile );
|
||||
Gia_FileWriteBufferSize( pFile, 4 ); // 1 byte CellId + 2 bytes truth table, rounded to 4
|
||||
// Write cell type 1 (S44)
|
||||
Gia_FileWriteBufferSize( pFile, 1 ); // CellId
|
||||
fwrite( pCell1, 1, strlen(pCell1) + 1, pFile );
|
||||
Gia_FileWriteBufferSize( pFile, 12 ); // 1 byte CellId + 4 bytes mapping + 4 bytes truth tables, rounded to 12
|
||||
// Write cell type 2 (9-input)
|
||||
Gia_FileWriteBufferSize( pFile, 2 ); // CellId
|
||||
fwrite( pCell2, 1, strlen(pCell2) + 1, pFile );
|
||||
Gia_FileWriteBufferSize( pFile, 12 ); // 1 byte CellId + 5 bytes mapping + 4 bytes truth tables (LUT4s only), rounded to 12
|
||||
// Write total instances
|
||||
Gia_FileWriteBufferSize( pFile, nInstances );
|
||||
// Write instance data as raw bytes
|
||||
fwrite( Vec_StrArray(p->vConfigs2), 1, Vec_StrSize(p->vConfigs2), pFile );
|
||||
}
|
||||
// write choices
|
||||
if ( Gia_ManHasChoices(p) )
|
||||
{
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -790,6 +790,8 @@ Gia_Man_t * Gia_ManDupWithAttributes( Gia_Man_t * p )
|
|||
pNew->vRegInits = Vec_IntDup( p->vRegInits );
|
||||
if ( p->vConfigs )
|
||||
pNew->vConfigs = Vec_IntDup( p->vConfigs );
|
||||
if ( p->vConfigs2 )
|
||||
pNew->vConfigs2 = Vec_StrDup( p->vConfigs2 );
|
||||
if ( p->pCellStr )
|
||||
pNew->pCellStr = Abc_UtilStrsav( p->pCellStr );
|
||||
// copy names if present
|
||||
|
|
|
|||
|
|
@ -1175,6 +1175,111 @@ int Gia_ManFromIfLogicCreateLutSpecial( Gia_Man_t * pNew, word * pRes, Vec_Int_t
|
|||
return iObjLit2;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Write mapping for LUT with given fanins.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Gia_ManFromIfLogicCreateLutSpecialJ( Gia_Man_t * pNew, word * pRes, Vec_Int_t * vLeaves, Vec_Int_t * vLeavesTemp, Vec_Int_t * vCover, Vec_Int_t * vMapping, Vec_Int_t * vMapping2, Vec_Int_t * vPacking )
|
||||
{
|
||||
word Truth;
|
||||
int i, iObjLit1, iObjLit2, iObjLit3;
|
||||
word z = If_CutPerformDeriveJ( NULL, (unsigned *)pRes, Vec_IntSize(vLeaves), Vec_IntSize(vLeaves), NULL, 1 );
|
||||
assert( z != 0 );
|
||||
if ( ((z >> 63) & 1) == 0 )
|
||||
{
|
||||
// create first LUT
|
||||
Vec_IntClear( vLeavesTemp );
|
||||
for ( i = 0; i < 4; i++ )
|
||||
{
|
||||
int v = (int)((z >> (16+(i<<2))) & 7);
|
||||
if ( v == 6 && Vec_IntSize(vLeaves) == 5 )
|
||||
continue;
|
||||
Vec_IntPush( vLeavesTemp, Vec_IntEntry(vLeaves, v) );
|
||||
}
|
||||
Truth = (z & 0xffff);
|
||||
Truth |= (Truth << 16);
|
||||
Truth |= (Truth << 32);
|
||||
iObjLit1 = Gia_ManFromIfLogicCreateLut( pNew, &Truth, vLeavesTemp, vCover, vMapping, vMapping2 );
|
||||
// create second LUT
|
||||
Vec_IntClear( vLeavesTemp );
|
||||
for ( i = 0; i < 4; i++ )
|
||||
{
|
||||
int v = (int)((z >> (48+(i<<2))) & 7);
|
||||
if ( v == 6 && Vec_IntSize(vLeaves) == 5 )
|
||||
continue;
|
||||
if ( v == 7 )
|
||||
Vec_IntPush( vLeavesTemp, iObjLit1 );
|
||||
else
|
||||
Vec_IntPush( vLeavesTemp, Vec_IntEntry(vLeaves, v) );
|
||||
}
|
||||
Truth = ((z >> 32) & 0xffff);
|
||||
Truth |= (Truth << 16);
|
||||
Truth |= (Truth << 32);
|
||||
iObjLit2 = Gia_ManFromIfLogicCreateLut( pNew, &Truth, vLeavesTemp, vCover, vMapping, vMapping2 );
|
||||
// write packing
|
||||
Vec_IntPush( vPacking, 2 );
|
||||
Vec_IntPush( vPacking, Abc_Lit2Var(iObjLit1) );
|
||||
Vec_IntPush( vPacking, Abc_Lit2Var(iObjLit2) );
|
||||
Vec_IntAddToEntry( vPacking, 0, 1 );
|
||||
return iObjLit2;
|
||||
}
|
||||
else
|
||||
{
|
||||
int Pla2Var[9];
|
||||
extern void If_PermUnpack( unsigned Value, int Pla2Var[9] );
|
||||
If_PermUnpack( (unsigned)(z >> 32), Pla2Var );
|
||||
|
||||
// create first data LUT
|
||||
Vec_IntClear( vLeavesTemp );
|
||||
for ( i = 0; i < 4; i++ )
|
||||
{
|
||||
if ( Pla2Var[i] != 9 )
|
||||
Vec_IntPush( vLeavesTemp, Vec_IntEntry(vLeaves, Pla2Var[i]) );
|
||||
}
|
||||
Truth = (z & 0xffff);
|
||||
Truth |= (Truth << 16);
|
||||
Truth |= (Truth << 32);
|
||||
iObjLit1 = Gia_ManFromIfLogicCreateLut( pNew, &Truth, vLeavesTemp, vCover, vMapping, vMapping2 );
|
||||
|
||||
// create second data LUT
|
||||
Vec_IntClear( vLeavesTemp );
|
||||
for ( i = 4; i < 8; i++ )
|
||||
{
|
||||
if ( Pla2Var[i] != 9 )
|
||||
Vec_IntPush( vLeavesTemp, Vec_IntEntry(vLeaves, Pla2Var[i]) );
|
||||
}
|
||||
Truth = ((z >> 16) & 0xffff);
|
||||
Truth |= (Truth << 16);
|
||||
Truth |= (Truth << 32);
|
||||
iObjLit2 = Gia_ManFromIfLogicCreateLut( pNew, &Truth, vLeavesTemp, vCover, vMapping, vMapping2 );
|
||||
|
||||
// create MUX LUT (2-input MUX: select ? iObjLit2 : iObjLit1)
|
||||
Vec_IntClear( vLeavesTemp );
|
||||
Vec_IntPush( vLeavesTemp, iObjLit1 ); // data 0
|
||||
Vec_IntPush( vLeavesTemp, iObjLit2 ); // data 1
|
||||
if ( Pla2Var[8] != 9 )
|
||||
Vec_IntPush( vLeavesTemp, Vec_IntEntry(vLeaves, Pla2Var[8]) ); // select
|
||||
// MUX truth table: f = s ? d1 : d0 = ~s&d0 | s&d1 = 0xCACACACA for (d0,d1,s)
|
||||
Truth = ABC_CONST(0xCACACACACACACACA);
|
||||
iObjLit3 = Gia_ManFromIfLogicCreateLut( pNew, &Truth, vLeavesTemp, vCover, vMapping, vMapping2 );
|
||||
|
||||
// write packing - 3 LUTs packed together
|
||||
Vec_IntPush( vPacking, 3 );
|
||||
Vec_IntPush( vPacking, Abc_Lit2Var(iObjLit1) );
|
||||
Vec_IntPush( vPacking, Abc_Lit2Var(iObjLit2) );
|
||||
Vec_IntPush( vPacking, Abc_Lit2Var(iObjLit3) );
|
||||
Vec_IntAddToEntry( vPacking, 0, 1 );
|
||||
return iObjLit3;
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Write the node into a file.]
|
||||
|
|
@ -1187,31 +1292,13 @@ int Gia_ManFromIfLogicCreateLutSpecial( Gia_Man_t * pNew, word * pRes, Vec_Int_t
|
|||
|
||||
***********************************************************************/
|
||||
int Gia_ManFromIfLogicNode( void * pIfMan, Gia_Man_t * pNew, int iObj, Vec_Int_t * vLeaves, Vec_Int_t * vLeavesTemp,
|
||||
word * pRes, char * pStr, Vec_Int_t * vCover, Vec_Int_t * vMapping, Vec_Int_t * vMapping2, Vec_Int_t * vPacking, int fCheck75, int fCheck44e )
|
||||
word * pRes, char * pStr, Vec_Int_t * vCover, Vec_Int_t * vMapping, Vec_Int_t * vMapping2, Vec_Int_t * vPacking, int fCheck75 )
|
||||
{
|
||||
int nLeaves = Vec_IntSize(vLeaves);
|
||||
int i, Length, nLutLeaf, nLutLeaf2, nLutRoot, iObjLit1, iObjLit2, iObjLit3;
|
||||
// workaround for the special case
|
||||
if ( fCheck75 )
|
||||
pStr = "54";
|
||||
// perform special case matching for 44
|
||||
if ( fCheck44e )
|
||||
{
|
||||
if ( Vec_IntSize(vLeaves) <= 4 )
|
||||
{
|
||||
// create mapping
|
||||
iObjLit1 = Gia_ManFromIfLogicCreateLut( pNew, pRes, vLeaves, vCover, vMapping, vMapping2 );
|
||||
// write packing
|
||||
if ( !Gia_ObjIsCi(Gia_ManObj(pNew, Abc_Lit2Var(iObjLit1))) && iObjLit1 > 1 )
|
||||
{
|
||||
Vec_IntPush( vPacking, 1 );
|
||||
Vec_IntPush( vPacking, Abc_Lit2Var(iObjLit1) );
|
||||
Vec_IntAddToEntry( vPacking, 0, 1 );
|
||||
}
|
||||
return iObjLit1;
|
||||
}
|
||||
return Gia_ManFromIfLogicCreateLutSpecial( pNew, pRes, vLeaves, vLeavesTemp, vCover, vMapping, vMapping2, vPacking );
|
||||
}
|
||||
if ( ((If_Man_t *)pIfMan)->pPars->fLut6Filter && Vec_IntSize(vLeaves) == 6 )
|
||||
{
|
||||
extern word If_Dec6Perform( word t, int fDerive );
|
||||
|
|
@ -1811,6 +1898,234 @@ void Gia_ManFromIfGetConfig( Vec_Int_t * vConfigs, If_Man_t * pIfMan, If_Cut_t *
|
|||
Vec_StrPush( vConfigsStr, '\n' );
|
||||
}
|
||||
}
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Print configuration during encoding.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Gia_ManConfigPrint( word Truth4, word z, int nLeaves )
|
||||
{
|
||||
static int Count = 0;
|
||||
int i;
|
||||
printf( "[%4d] Encoding (nLeaves=%d): ", Count++, nLeaves );
|
||||
// Simple LUT4 case (Truth4 != 0, z == 0)
|
||||
if ( z == 0 )
|
||||
{
|
||||
printf( "%04lX{", (unsigned long)(Truth4 & 0xFFFF) );
|
||||
for ( i = 0; i < nLeaves && i < 4; i++ )
|
||||
printf( "%c", 'a' + i );
|
||||
printf( "} [Cell 0, LUT4]\n" );
|
||||
return;
|
||||
}
|
||||
if ( ((z >> 63) & 1) == 0 )
|
||||
{
|
||||
// Extract truth tables
|
||||
word Truth1 = z & 0xFFFF;
|
||||
word Truth2 = (z >> 32) & 0xFFFF;
|
||||
printf( "h=%04lX{", (unsigned long)Truth1 );
|
||||
// First LUT4 inputs from bits 16-31
|
||||
for ( i = 0; i < 4; i++ )
|
||||
{
|
||||
int v = (int)((z >> (16 + (i << 2))) & 7);
|
||||
if ( v == 6 && nLeaves == 5 )
|
||||
printf( "0" ); // Constant 0 for 5-input cuts
|
||||
else if ( v == 7 )
|
||||
printf( "?" ); // Internal connection (shouldn't appear in first LUT)
|
||||
else if ( v <= 6 )
|
||||
printf( "%c", 'a' + v );
|
||||
else
|
||||
printf( "?" );
|
||||
}
|
||||
printf( "} ");
|
||||
printf( "i=%04lX{", (unsigned long)Truth2 );
|
||||
// Second LUT4 inputs from bits 48-63
|
||||
for ( i = 0; i < 4; i++ )
|
||||
{
|
||||
int v = (int)((z >> (48 + (i << 2))) & 7);
|
||||
if ( v == 6 && nLeaves == 5 )
|
||||
printf( "0" ); // Constant 0 for 5-input cuts
|
||||
else if ( v == 7 )
|
||||
printf( "h" ); // Output of first LUT
|
||||
else if ( v <= 6 )
|
||||
printf( "%c", 'a' + v );
|
||||
else
|
||||
printf( "?" );
|
||||
}
|
||||
printf( "} [Cell 1, S44]\n" );
|
||||
}
|
||||
else
|
||||
{
|
||||
int Pla2Var[9];
|
||||
extern void If_PermUnpack( unsigned Value, int Pla2Var[9] );
|
||||
If_PermUnpack( (unsigned)(z >> 32), Pla2Var );
|
||||
// Extract truth tables
|
||||
word Truth1 = z & 0xFFFF;
|
||||
word Truth2 = (z >> 16) & 0xFFFF;
|
||||
printf( "j=%04lX{", (unsigned long)Truth1 );
|
||||
// First LUT4 inputs
|
||||
for ( i = 0; i < 4; i++ )
|
||||
{
|
||||
if ( Pla2Var[i] == 9 )
|
||||
printf( "0" ); // Will be encoded as constant 0
|
||||
else if ( Pla2Var[i] < 9 )
|
||||
printf( "%c", 'a' + Pla2Var[i] );
|
||||
else
|
||||
printf( "?" );
|
||||
}
|
||||
printf( "} ");
|
||||
printf( "k=%04lX{", (unsigned long)Truth2 );
|
||||
// Second LUT4 inputs
|
||||
for ( i = 4; i < 8; i++ )
|
||||
{
|
||||
if ( Pla2Var[i] == 9 )
|
||||
printf( "0" ); // Will be encoded as constant 0
|
||||
else if ( Pla2Var[i] < 9 )
|
||||
printf( "%c", 'a' + Pla2Var[i] );
|
||||
else
|
||||
printf( "?" );
|
||||
}
|
||||
printf( "} ");
|
||||
// final
|
||||
printf( "l=<" );
|
||||
if ( Pla2Var[8] == 9 )
|
||||
printf( "0" ); // Will be encoded as constant 0
|
||||
else if ( Pla2Var[8] < 9 )
|
||||
printf( "%c", 'a' + Pla2Var[8] );
|
||||
else
|
||||
printf( "?" );
|
||||
printf( "jk> [Cell 2, 9-input MUX]\n" );
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Derive configurations.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Gia_ManFromIfGetConfig2( Vec_Str_t * vConfigs2, If_Man_t * pIfMan, word * pTruth, int nLeaves )
|
||||
{
|
||||
int i, CellId, nBytes;
|
||||
int startPos = Vec_StrSize(vConfigs2);
|
||||
|
||||
// Determine cell type based on the number of leaves and configuration
|
||||
if ( nLeaves <= 4 )
|
||||
{
|
||||
// Cell type 0: Simple LUT4
|
||||
CellId = 0;
|
||||
nBytes = 3; // 1 byte CellId + 2 bytes truth table (16 bits)
|
||||
// Write CellId
|
||||
Vec_StrPush( vConfigs2, (char)CellId );
|
||||
// Write truth table (16 bits for LUT4)
|
||||
word Truth = pTruth[0];
|
||||
Vec_StrPush( vConfigs2, (char)(Truth & 0xFF) );
|
||||
Vec_StrPush( vConfigs2, (char)((Truth >> 8) & 0xFF) );
|
||||
// Pad to 4-byte boundary
|
||||
while ( (Vec_StrSize(vConfigs2) - startPos) % 4 != 0 )
|
||||
Vec_StrPush( vConfigs2, 0 );
|
||||
//Gia_ManConfigPrint( Truth, 0, pCutBest->nLeaves );
|
||||
}
|
||||
else
|
||||
{
|
||||
word z = If_CutPerformDeriveJ( pIfMan, (unsigned *)pTruth, nLeaves, nLeaves, NULL, 1 );
|
||||
//Gia_ManConfigPrint( 0, z, pCutBest->nLeaves );
|
||||
if ( ((z >> 63) & 1) == 0 )
|
||||
{
|
||||
CellId = 1;
|
||||
unsigned char mappingBytes[4] = {0};
|
||||
// Write CellId
|
||||
Vec_StrPush( vConfigs2, (char)CellId );
|
||||
// Write input mappings for first LUT4 (4 inputs)
|
||||
for ( i = 0; i < 4; i++ )
|
||||
{
|
||||
int v = (int)((z >> (16 + (i << 2))) & 7);
|
||||
if ( v == 6 && nLeaves == 5 )
|
||||
mappingBytes[i / 2] |= (0 << ((i % 2) * 4)); // constant 0
|
||||
else
|
||||
mappingBytes[i / 2] |= ((v+2) << ((i % 2) * 4)); // leaf v (direct mapping)
|
||||
}
|
||||
Vec_StrPush( vConfigs2, (char)mappingBytes[0] );
|
||||
Vec_StrPush( vConfigs2, (char)mappingBytes[1] );
|
||||
// Write input mappings for second LUT4 (4 inputs)
|
||||
mappingBytes[0] = mappingBytes[1] = 0;
|
||||
for ( i = 0; i < 4; i++ )
|
||||
{
|
||||
int v = (int)((z >> (48 + (i << 2))) & 7);
|
||||
if ( v == 6 && nLeaves == 5 )
|
||||
mappingBytes[i / 2] |= (0 << ((i % 2) * 4)); // constant 0
|
||||
else if ( v == 7 )
|
||||
mappingBytes[i / 2] |= ((7+2) << ((i % 2) * 4)); // output of first LUT at index N+2 where N=7
|
||||
else
|
||||
mappingBytes[i / 2] |= ((v+2) << ((i % 2) * 4)); // leaf v (direct mapping)
|
||||
}
|
||||
Vec_StrPush( vConfigs2, (char)mappingBytes[0] );
|
||||
Vec_StrPush( vConfigs2, (char)mappingBytes[1] );
|
||||
// Write truth tables
|
||||
word Truth1 = z & 0xFFFF;
|
||||
word Truth2 = (z >> 32) & 0xFFFF;
|
||||
Vec_StrPush( vConfigs2, (char)(Truth1 & 0xFF) );
|
||||
Vec_StrPush( vConfigs2, (char)((Truth1 >> 8) & 0xFF) );
|
||||
Vec_StrPush( vConfigs2, (char)(Truth2 & 0xFF) );
|
||||
Vec_StrPush( vConfigs2, (char)((Truth2 >> 8) & 0xFF) );
|
||||
// Pad to 4-byte boundary
|
||||
while ( (Vec_StrSize(vConfigs2) - startPos) % 4 != 0 )
|
||||
Vec_StrPush( vConfigs2, 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
CellId = 2;
|
||||
int Pla2Var[9];
|
||||
extern void If_PermUnpack( unsigned Value, int Pla2Var[9] );
|
||||
If_PermUnpack( (unsigned)(z >> 32), Pla2Var );
|
||||
// Write CellId
|
||||
Vec_StrPush( vConfigs2, (char)CellId );
|
||||
// Write input mappings (9 inputs, 4 bits each, packed)
|
||||
unsigned char mappingByte = 0;
|
||||
int bitPos = 0;
|
||||
for ( i = 0; i < 9; i++ )
|
||||
{
|
||||
int v;
|
||||
if ( Pla2Var[i] == 9 ) // constant 0
|
||||
v = 0;
|
||||
else // leaf index
|
||||
v = Pla2Var[i] + 2;
|
||||
if ( bitPos == 0 ) {
|
||||
mappingByte = v & 0xF;
|
||||
bitPos = 4;
|
||||
}
|
||||
else {
|
||||
mappingByte |= (v & 0xF) << 4;
|
||||
Vec_StrPush( vConfigs2, (char)mappingByte );
|
||||
bitPos = 0;
|
||||
}
|
||||
}
|
||||
// Push last byte if needed
|
||||
if ( bitPos != 0 )
|
||||
Vec_StrPush( vConfigs2, (char)mappingByte );
|
||||
// Write truth tables for the two LUT4s only (MUX is structural, not a LUT)
|
||||
word Truth1 = z & 0xFFFF;
|
||||
word Truth2 = (z >> 16) & 0xFFFF;
|
||||
Vec_StrPush( vConfigs2, (char)(Truth1 & 0xFF) );
|
||||
Vec_StrPush( vConfigs2, (char)((Truth1 >> 8) & 0xFF) );
|
||||
Vec_StrPush( vConfigs2, (char)(Truth2 & 0xFF) );
|
||||
Vec_StrPush( vConfigs2, (char)((Truth2 >> 8) & 0xFF) );
|
||||
// Pad to 4-byte boundary
|
||||
while ( (Vec_StrSize(vConfigs2) - startPos) % 4 != 0 )
|
||||
Vec_StrPush( vConfigs2, 0 );
|
||||
}
|
||||
}
|
||||
}
|
||||
int Gia_ManFromIfLogicFindCell( If_Man_t * pIfMan, Gia_Man_t * pNew, Gia_Man_t * pTemp, If_Cut_t * pCutBest, Ifn_Ntk_t * pNtkCell, int nLutMax, Vec_Int_t * vLeaves, Vec_Int_t * vLits, Vec_Int_t * vCover, Vec_Int_t * vMapping, Vec_Int_t * vMapping2, Vec_Int_t * vConfigs )
|
||||
{
|
||||
int iLit;
|
||||
|
|
@ -2004,18 +2319,19 @@ Gia_Man_t * Gia_ManFromIfLogic( If_Man_t * pIfMan )
|
|||
If_Cut_t * pCutBest;
|
||||
If_Obj_t * pIfObj, * pIfLeaf;
|
||||
Vec_Int_t * vMapping, * vMapping2, * vPacking = NULL, * vConfigs = NULL;
|
||||
Vec_Str_t * vConfigs2 = NULL;
|
||||
Vec_Int_t * vLeaves, * vLeaves2, * vCover, * vLits;
|
||||
Vec_Str_t * vConfigsStr = NULL;
|
||||
Ifn_Ntk_t * pNtkCell = NULL;
|
||||
sat_solver * pSat = NULL;
|
||||
int i, k, Entry;
|
||||
assert( !pIfMan->pPars->fDeriveLuts || pIfMan->pPars->fTruth );
|
||||
// if ( pIfMan->pPars->fEnableCheck07 )
|
||||
// pIfMan->pPars->fDeriveLuts = 0;
|
||||
//if ( pIfMan->pPars->fEnableCheck07 )
|
||||
// pIfMan->pPars->fDeriveLuts = 0;
|
||||
// start mapping and packing
|
||||
vMapping = Vec_IntStart( If_ManObjNum(pIfMan) );
|
||||
vMapping2 = Vec_IntStart( 1 );
|
||||
if ( pIfMan->pPars->fDeriveLuts && (pIfMan->pPars->pLutStruct || pIfMan->pPars->fEnableCheck75 || pIfMan->pPars->fEnableCheck75u || pIfMan->pPars->fEnableCheck07) )
|
||||
if ( pIfMan->pPars->fDeriveLuts && (pIfMan->pPars->pLutStruct || pIfMan->pPars->fEnableCheck75 || pIfMan->pPars->fEnableCheck75u) )
|
||||
{
|
||||
vPacking = Vec_IntAlloc( 1000 );
|
||||
Vec_IntPush( vPacking, 0 );
|
||||
|
|
@ -2031,6 +2347,8 @@ Gia_Man_t * Gia_ManFromIfLogic( If_Man_t * pIfMan )
|
|||
if ( fWriteConfigs )
|
||||
vConfigsStr = Vec_StrAlloc( 1000 );
|
||||
}
|
||||
if ( pIfMan->pPars->fEnableCheck07 )
|
||||
vConfigs2 = Vec_StrAlloc( 1000 );
|
||||
// create new manager
|
||||
pNew = Gia_ManStart( If_ManObjNum(pIfMan) );
|
||||
// iterate through nodes used in the mapping
|
||||
|
|
@ -2114,10 +2432,21 @@ Gia_Man_t * Gia_ManFromIfLogic( If_Man_t * pIfMan )
|
|||
if ( If_CutLeafBit(pCutBest, k) )
|
||||
Abc_TtFlip( pTruth, Abc_TtWordNum(pCutBest->nLeaves), k );
|
||||
// perform decomposition of the cut
|
||||
pIfObj->iCopy = Gia_ManFromIfLogicNode( pIfMan, pNew, i, vLeaves, vLeaves2, pTruth, pIfMan->pPars->pLutStruct, vCover, vMapping, vMapping2, vPacking, (pIfMan->pPars->fEnableCheck75 || pIfMan->pPars->fEnableCheck75u), pIfMan->pPars->fEnableCheck07 );
|
||||
if ( pIfMan->pPars->fEnableCheck07 )
|
||||
pIfObj->iCopy = Gia_ManFromIfLogicCreateLut( pNew, pTruth, vLeaves, vCover, vMapping, vMapping2 );
|
||||
else
|
||||
pIfObj->iCopy = Gia_ManFromIfLogicNode( pIfMan, pNew, i, vLeaves, vLeaves2, pTruth, pIfMan->pPars->pLutStruct, vCover, vMapping, vMapping2, vPacking, (pIfMan->pPars->fEnableCheck75 || pIfMan->pPars->fEnableCheck75u) );
|
||||
pIfObj->iCopy = Abc_LitNotCond( pIfObj->iCopy, pCutBest->fCompl );
|
||||
if ( vConfigs && Vec_IntSize(vLeaves) > 1 && !Gia_ObjIsCi(Gia_ManObj(pNew, Abc_Lit2Var(pIfObj->iCopy))) && pIfObj->iCopy > 1 )
|
||||
Gia_ManFromIfGetConfig( vConfigs, pIfMan, pCutBest, pIfObj->iCopy, vConfigsStr );
|
||||
else if ( vConfigs2 && Vec_IntSize(vLeaves) > 1 && !Gia_ObjIsCi(Gia_ManObj(pNew, Abc_Lit2Var(pIfObj->iCopy))) && pIfObj->iCopy > 1 ) {
|
||||
If_CutForEachLeaf( pIfMan, pCutBest, pIfLeaf, k )
|
||||
if ( Abc_LitIsCompl(pIfLeaf->iCopy) )
|
||||
Abc_TtFlip( pTruth, Abc_TtWordNum(pCutBest->nLeaves), k );
|
||||
if ( Abc_LitIsCompl(pIfObj->iCopy) ^ pCutBest->fCompl )
|
||||
Abc_TtNot( pTruth, Abc_TtWordNum(pCutBest->nLeaves) );
|
||||
Gia_ManFromIfGetConfig2( vConfigs2, pIfMan, pTruth, pCutBest->nLeaves );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -2174,11 +2503,14 @@ Gia_Man_t * Gia_ManFromIfLogic( If_Man_t * pIfMan )
|
|||
assert( pNew->vPacking == NULL );
|
||||
assert( pNew->vConfigs == NULL );
|
||||
assert( pNew->pCellStr == NULL );
|
||||
assert( pNew->vConfigs2== NULL );
|
||||
pNew->vMapping = vMapping;
|
||||
pNew->vPacking = vPacking;
|
||||
pNew->vConfigs = vConfigs;
|
||||
pNew->pCellStr = vConfigs ? Abc_UtilStrsav( If_DsdManGetCellStr(pIfMan->pIfDsdMan) ) : NULL;
|
||||
assert( !vConfigs || Vec_IntSize(vConfigs) == 2 + Vec_IntEntry(vConfigs, 0) * Vec_IntEntry(vConfigs, 1) );
|
||||
pNew->vConfigs2= vConfigs2;
|
||||
assert( !vConfigs || Vec_IntSize(vConfigs) == 2 + Vec_IntEntry(vConfigs, 0) * Vec_IntEntry(vConfigs, 1) );
|
||||
// vConfigs2 is now a byte vector, no fixed size relationship
|
||||
// verify that COs have mapping
|
||||
{
|
||||
Gia_Obj_t * pObj;
|
||||
|
|
@ -2398,6 +2730,10 @@ void Gia_ManTransferTiming( Gia_Man_t * p, Gia_Man_t * pGia )
|
|||
p->vConfigs = pGia->vConfigs; pGia->vConfigs = NULL;
|
||||
p->pCellStr = pGia->pCellStr; pGia->pCellStr = NULL;
|
||||
}
|
||||
if ( pGia->vConfigs2 )
|
||||
{
|
||||
p->vConfigs2 = pGia->vConfigs2; pGia->vConfigs2 = NULL;
|
||||
}
|
||||
if ( pGia->pManTime == NULL )
|
||||
return;
|
||||
p->pManTime = pGia->pManTime; pGia->pManTime = NULL;
|
||||
|
|
@ -2523,6 +2859,7 @@ Gia_Man_t * Gia_ManPerformMappingInt( Gia_Man_t * p, If_Par_t * pPars )
|
|||
*/
|
||||
ABC_FREE( p->pCellStr );
|
||||
Vec_IntFreeP( &p->vConfigs );
|
||||
Vec_StrFreeP( &p->vConfigs2 );
|
||||
// disable cut minimization when GIA strucure is needed
|
||||
if ( !pPars->fDelayOpt && !pPars->fDelayOptLut && !pPars->fDsdBalance && !pPars->fUserRecLib && !pPars->fUserSesLib && !pPars->fDeriveLuts && !pPars->fUseDsd && !pPars->fUseTtPerm && !pPars->pFuncCell2 )
|
||||
pPars->fCutMin = 0;
|
||||
|
|
|
|||
|
|
@ -142,6 +142,7 @@ void Gia_ManStop( Gia_Man_t * p )
|
|||
Vec_IntFreeP( &p->vCellMapping );
|
||||
Vec_IntFreeP( &p->vPacking );
|
||||
Vec_IntFreeP( &p->vConfigs );
|
||||
Vec_StrFreeP( &p->vConfigs2 );
|
||||
ABC_FREE( p->pCellStr );
|
||||
Vec_FltFreeP( &p->vInArrs );
|
||||
Vec_FltFreeP( &p->vOutReqs );
|
||||
|
|
|
|||
|
|
@ -113,4 +113,5 @@ SRC += src/aig/gia/giaAig.c \
|
|||
src/aig/gia/giaTtopt.cpp \
|
||||
src/aig/gia/giaUnate.c \
|
||||
src/aig/gia/giaUtil.c \
|
||||
src/aig/gia/giaBound.c
|
||||
src/aig/gia/giaBound.c \
|
||||
src/aig/gia/giaDecGraph.cpp
|
||||
|
|
|
|||
|
|
@ -532,6 +532,7 @@ static int Abc_CommandAbc9Transduction ( Abc_Frame_t * pAbc, int argc, cha
|
|||
static int Abc_CommandAbc9TranStoch ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Abc_CommandAbc9Rrr ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Abc_CommandAbc9Rewire ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Abc_CommandAbc9DecGraph ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
//#endif
|
||||
static int Abc_CommandAbc9LNetMap ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Abc_CommandAbc9Unmap ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
|
|
@ -1352,6 +1353,7 @@ void Abc_Init( Abc_Frame_t * pAbc )
|
|||
Cmd_CommandAdd( pAbc, "ABC9", "&transtoch" , Abc_CommandAbc9TranStoch, 0 );
|
||||
Cmd_CommandAdd( pAbc, "ABC9", "&rrr", Abc_CommandAbc9Rrr, 0 );
|
||||
Cmd_CommandAdd( pAbc, "ABC9", "&rewire" , Abc_CommandAbc9Rewire, 0 );
|
||||
Cmd_CommandAdd( pAbc, "ABC9", "&dg" , Abc_CommandAbc9DecGraph, 0 );
|
||||
//#endif
|
||||
Cmd_CommandAdd( pAbc, "ABC9", "&lnetmap", Abc_CommandAbc9LNetMap, 0 );
|
||||
Cmd_CommandAdd( pAbc, "ABC9", "&unmap", Abc_CommandAbc9Unmap, 0 );
|
||||
|
|
@ -10835,7 +10837,7 @@ int Abc_CommandLutExact( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
Abc_Print( -1, "Function with %d variales cannot be implemented with %d %d-input LUTs.\n", pPars->nVars, pPars->nNodes, pPars->nLutSize );
|
||||
return 1;
|
||||
}
|
||||
if ( pPars->nVars > 10 )
|
||||
if ( pPars->nVars > 12 )
|
||||
{
|
||||
Abc_Print( -1, "Function should not have more than 10 inputs.\n" );
|
||||
return 1;
|
||||
|
|
@ -21838,12 +21840,12 @@ int Abc_CommandIf( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
}
|
||||
if ( pPars->fEnableCheck07 )
|
||||
{
|
||||
if ( pPars->nLutSize < 6 || pPars->nLutSize > 7 )
|
||||
if ( pPars->nLutSize > 9 )
|
||||
{
|
||||
Abc_Print( -1, "This feature only works for {6,7}-LUTs.\n" );
|
||||
Abc_Print( -1, "This feature only works for up to 9-input LUTs.\n" );
|
||||
return 1;
|
||||
}
|
||||
pPars->pFuncCell = If_CutPerformCheck07;
|
||||
pPars->pFuncCell = If_CutPerformCheckJ;
|
||||
pPars->fCutMin = 1;
|
||||
}
|
||||
if ( pPars->fUseCofVars )
|
||||
|
|
@ -35656,6 +35658,8 @@ int Abc_CommandAbc9Strash( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
Gia_ManTransferPacking( pTemp, pAbc->pGia );
|
||||
Gia_ManTransferTiming( pTemp, pAbc->pGia );
|
||||
}
|
||||
else if ( Gia_ManHasMapping(pAbc->pGia) && pAbc->pGia->vConfigs2 )
|
||||
pTemp = (Gia_Man_t *)If_ManDeriveGiaFromCells2( pAbc->pGia );
|
||||
else if ( Gia_ManHasMapping(pAbc->pGia) && pAbc->pGia->vConfigs )
|
||||
pTemp = (Gia_Man_t *)If_ManDeriveGiaFromCells( pAbc->pGia );
|
||||
else if ( Gia_ManHasMapping(pAbc->pGia) )
|
||||
|
|
@ -35704,6 +35708,7 @@ int Abc_CommandAbc9Strash( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
Gia_ManTransferTiming( pTemp, pAbc->pGia );
|
||||
pAbc->pGia->vConfigs = pTemp->vConfigs; pTemp->vConfigs = NULL;
|
||||
pAbc->pGia->pCellStr = pTemp->pCellStr; pTemp->pCellStr = NULL;
|
||||
pAbc->pGia->vConfigs2= pTemp->vConfigs2; pTemp->vConfigs2= NULL;
|
||||
}
|
||||
Abc_FrameUpdateGia( pAbc, pTemp );
|
||||
return 0;
|
||||
|
|
@ -42953,12 +42958,12 @@ int Abc_CommandAbc9If( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
int c;
|
||||
// set defaults
|
||||
Gia_ManSetIfParsDefault( pPars );
|
||||
if ( pAbc->pLibLut == NULL )
|
||||
if ( Abc_FrameReadLibLut() == NULL )
|
||||
{
|
||||
Abc_Print( -1, "LUT library is not given. Using default LUT library.\n" );
|
||||
pAbc->pLibLut = If_LibLutSetSimple( 6 );
|
||||
Abc_FrameSetLibLut( If_LibLutSetSimple( 6 ) );
|
||||
}
|
||||
pPars->pLutLib = (If_LibLut_t *)pAbc->pLibLut;
|
||||
pPars->pLutLib = (If_LibLut_t *)Abc_FrameReadLibLut();
|
||||
Extra_UtilGetoptReset();
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "KCFAGRDEWSJTXYZqalepmrsdbgxyofuijkztncvwh" ) ) != EOF )
|
||||
{
|
||||
|
|
@ -43192,12 +43197,12 @@ int Abc_CommandAbc9If( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
//pPars->fUseCofVars ^= 1;
|
||||
pPars->fUseCheck2 ^= 1;
|
||||
break;
|
||||
// case 'j':
|
||||
// pPars->fEnableCheck07 ^= 1;
|
||||
// break;
|
||||
case 'j':
|
||||
pPars->fUseAndVars ^= 1;
|
||||
pPars->fEnableCheck07 ^= 1;
|
||||
break;
|
||||
//case 'j':
|
||||
// pPars->fUseAndVars ^= 1;
|
||||
// break;
|
||||
case 'k':
|
||||
pPars->fUseDsdTune ^= 1;
|
||||
break;
|
||||
|
|
@ -43295,12 +43300,12 @@ int Abc_CommandAbc9If( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
}
|
||||
if ( pPars->fEnableCheck07 )
|
||||
{
|
||||
if ( pPars->nLutSize < 6 || pPars->nLutSize > 7 )
|
||||
if ( pPars->nLutSize > 9 )
|
||||
{
|
||||
Abc_Print( -1, "This feature only works for {6,7}-LUTs.\n" );
|
||||
Abc_Print( -1, "This feature only works for up to 9-input LUTs.\n" );
|
||||
return 1;
|
||||
}
|
||||
pPars->pFuncCell = If_CutPerformCheck07;
|
||||
pPars->pFuncCell = If_CutPerformCheckJ;
|
||||
pPars->fCutMin = 1;
|
||||
}
|
||||
if ( pPars->fUseCheck1 || pPars->fUseCheck2 )
|
||||
|
|
@ -43581,7 +43586,7 @@ usage:
|
|||
Abc_Print( -2, "\t-f : toggles enabling additional check [default = %s]\n", pPars->fEnableCheck75? "yes": "no" );
|
||||
Abc_Print( -2, "\t-u : toggles enabling additional check [default = %s]\n", pPars->fEnableCheck75u? "yes": "no" );
|
||||
Abc_Print( -2, "\t-i : toggles using cofactoring variables [default = %s]\n", pPars->fUseCofVars? "yes": "no" );
|
||||
// Abc_Print( -2, "\t-j : toggles enabling additional check [default = %s]\n", pPars->fEnableCheck07? "yes": "no" );
|
||||
Abc_Print( -2, "\t-j : toggles enabling additional check [default = %s]\n", pPars->fEnableCheck07? "yes": "no" );
|
||||
Abc_Print( -2, "\t-j : toggles using AND bi-decomposition [default = %s]\n", pPars->fUseAndVars? "yes": "no" );
|
||||
Abc_Print( -2, "\t-k : toggles matching based on precomputed DSD manager [default = %s]\n", pPars->fUseDsdTune? "yes": "no" );
|
||||
Abc_Print( -2, "\t-z : toggles deriving LUTs when mapping into LUT structures [default = %s]\n", pPars->fDeriveLuts? "yes": "no" );
|
||||
|
|
@ -43633,12 +43638,12 @@ int Abc_CommandAbc9Iff( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
Abc_Print( -1, "Abc_CommandAbc9Iff(): Mapping of the AIG is not defined.\n" );
|
||||
return 1;
|
||||
}
|
||||
if ( pAbc->pLibLut == NULL )
|
||||
if ( Abc_FrameReadLibLut() == NULL )
|
||||
{
|
||||
Abc_Print( -1, "Abc_CommandAbc9Iff(): LUT library is not defined.\n" );
|
||||
return 1;
|
||||
}
|
||||
Gia_ManIffTest( pAbc->pGia, (If_LibLut_t *)pAbc->pLibLut, fVerbose );
|
||||
Gia_ManIffTest( pAbc->pGia, (If_LibLut_t *)Abc_FrameReadLibLut(), fVerbose );
|
||||
return 0;
|
||||
|
||||
usage:
|
||||
|
|
@ -46986,6 +46991,80 @@ usage:
|
|||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Abc_CommandAbc9DecGraph( Abc_Frame_t * pAbc, int argc, char ** argv )
|
||||
{
|
||||
Gia_Man_t * pTemp;
|
||||
char * pFileName = NULL;
|
||||
int c, fFile = 0;
|
||||
|
||||
Extra_UtilGetoptReset();
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "fh" ) ) != EOF )
|
||||
{
|
||||
switch ( c )
|
||||
{
|
||||
case 'f':
|
||||
fFile ^= 1;
|
||||
break;
|
||||
case 'h':
|
||||
default:
|
||||
goto usage;
|
||||
}
|
||||
}
|
||||
if ( argc > globalUtilOptind + 1 )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if ( !fFile && argc == globalUtilOptind + 1 )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if ( !fFile && pAbc->pGia == NULL )
|
||||
{
|
||||
Abc_Print( -1, "Empty GIA network.\n" );
|
||||
return 1;
|
||||
}
|
||||
if ( fFile && argc == globalUtilOptind + 1 )
|
||||
{
|
||||
FILE * pFile = fopen( argv[globalUtilOptind], "rb" );
|
||||
if ( pFile == NULL )
|
||||
{
|
||||
Abc_Print( -1, "Abc_CommandAbc9BCore(): Cannot open file \"%s\" for reading the simulation information.\n", argv[globalUtilOptind] );
|
||||
return 0;
|
||||
}
|
||||
fclose( pFile );
|
||||
pFileName = argv[globalUtilOptind];
|
||||
}
|
||||
if ( pFileName ) {
|
||||
pTemp = Gia_ManDecGraphFromFile( pFileName );
|
||||
} else {
|
||||
pTemp = Gia_ManDecGraph( pAbc->pGia );
|
||||
}
|
||||
Abc_FrameUpdateGia( pAbc, pTemp );
|
||||
return 0;
|
||||
|
||||
usage:
|
||||
Abc_Print( -2, "usage: &dg [-vhf] <file>\n" );
|
||||
Abc_Print( -2, "\t convert AIG into decision graph structure\n" );
|
||||
Abc_Print( -2, "\t-f : read from file (in IWLS format) [default = %s]\n" , fFile ? "yes" : "no");
|
||||
Abc_Print( -2, "\t-h : prints the command usage\n\n");
|
||||
Abc_Print( -2, "\t This command was contributed by Jiun-Hao Chen from National Taiwan University.\n" );
|
||||
Abc_Print( -2, "\t For more info, please refer to the paper: Jiun-Hao Chen and Jie-Hong R. Jiang,\n");
|
||||
Abc_Print( -2, "\t \"Circuit learning for multi-output Boolean functions\", Proc. IWLS 2025.\n");
|
||||
Abc_Print( -2, "\t https://people.eecs.berkeley.edu/~alanmi/publications/other/iwls25_dg.pdf\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
|
@ -47234,7 +47313,7 @@ int Abc_CommandAbc9Trace( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
Abc_Print( -1, "Abc_CommandAbc9Speedup(): Mapping of the AIG is not defined.\n" );
|
||||
return 1;
|
||||
}
|
||||
pAbc->pGia->pLutLib = fUseLutLib ? pAbc->pLibLut : NULL;
|
||||
pAbc->pGia->pLutLib = fUseLutLib ? Abc_FrameReadLibLut() : NULL;
|
||||
Gia_ManDelayTraceLutPrint( pAbc->pGia, fVerbose );
|
||||
return 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -62,6 +62,9 @@ ABC_NAMESPACE_HEADER_START
|
|||
/// MACRO DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// the maximum number of LUT libraries
|
||||
#define ABC_LUT_LIBS 4
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -96,6 +99,8 @@ extern ABC_DLL Abc_Frame_t * Abc_FrameReadGlobalFrame();
|
|||
extern ABC_DLL Vec_Ptr_t * Abc_FrameReadStore();
|
||||
extern ABC_DLL int Abc_FrameReadStoreSize();
|
||||
extern ABC_DLL void * Abc_FrameReadLibLut();
|
||||
extern ABC_DLL void * Abc_FrameReadLibLutI( int i );
|
||||
extern ABC_DLL void * Abc_FrameReadLibCell();
|
||||
extern ABC_DLL void * Abc_FrameReadLibBox();
|
||||
extern ABC_DLL void * Abc_FrameReadLibGen();
|
||||
extern ABC_DLL void * Abc_FrameReadLibGen2();
|
||||
|
|
@ -134,6 +139,8 @@ extern ABC_DLL int Abc_FrameReadCexFrame( Abc_Frame_t * p );
|
|||
extern ABC_DLL void Abc_FrameSetNtkStore( Abc_Ntk_t * pNtk );
|
||||
extern ABC_DLL void Abc_FrameSetNtkStoreSize( int nStored );
|
||||
extern ABC_DLL void Abc_FrameSetLibLut( void * pLib );
|
||||
extern ABC_DLL void Abc_FrameSetLibLutI( void * pLib, int i );
|
||||
extern ABC_DLL void Abc_FrameSetLibCell( void * pLib );
|
||||
extern ABC_DLL void Abc_FrameSetLibBox( void * pLib );
|
||||
extern ABC_DLL void Abc_FrameSetLibGen( void * pLib );
|
||||
extern ABC_DLL void Abc_FrameSetLibGen2( void * pLib );
|
||||
|
|
|
|||
|
|
@ -54,7 +54,9 @@ static Abc_Frame_t * s_GlobalFrame = NULL;
|
|||
***********************************************************************/
|
||||
Vec_Ptr_t * Abc_FrameReadStore() { return s_GlobalFrame->vStore; }
|
||||
int Abc_FrameReadStoreSize() { return Vec_PtrSize(s_GlobalFrame->vStore); }
|
||||
void * Abc_FrameReadLibLut() { return s_GlobalFrame->pLibLut; }
|
||||
void * Abc_FrameReadLibLut() { return s_GlobalFrame->pLibLut[0]; }
|
||||
void * Abc_FrameReadLibLutI( int i ) { return s_GlobalFrame->pLibLut[i]; }
|
||||
void * Abc_FrameReadLibCell() { return s_GlobalFrame->pLibCell; }
|
||||
void * Abc_FrameReadLibBox() { return s_GlobalFrame->pLibBox; }
|
||||
void * Abc_FrameReadLibGen() { return s_GlobalFrame->pLibGen; }
|
||||
void * Abc_FrameReadLibGen2() { return s_GlobalFrame->pLibGen2; }
|
||||
|
|
@ -90,7 +92,9 @@ void Abc_FrameInputNdr( Abc_Frame_t * pAbc, void * pData ) { Ndr_Delete(s
|
|||
void * Abc_FrameOutputNdr( Abc_Frame_t * pAbc ) { void * pData = s_GlobalFrame->pNdr; s_GlobalFrame->pNdr = NULL; return pData; }
|
||||
int * Abc_FrameOutputNdrArray( Abc_Frame_t * pAbc ) { int * pArray = s_GlobalFrame->pNdrArray; s_GlobalFrame->pNdrArray = NULL; return pArray; }
|
||||
|
||||
void Abc_FrameSetLibLut( void * pLib ) { s_GlobalFrame->pLibLut = pLib; }
|
||||
void Abc_FrameSetLibLut( void * pLib ) { s_GlobalFrame->pLibLut[0]= pLib; }
|
||||
void Abc_FrameSetLibLutI( void * pLib, int i ) { s_GlobalFrame->pLibLut[i]= pLib; }
|
||||
void Abc_FrameSetLibCell( void * pLib ) { s_GlobalFrame->pLibCell = pLib; }
|
||||
void Abc_FrameSetLibBox( void * pLib ) { s_GlobalFrame->pLibBox = pLib; }
|
||||
void Abc_FrameSetLibGen( void * pLib ) { s_GlobalFrame->pLibGen = pLib; }
|
||||
void Abc_FrameSetLibGen2( void * pLib ) { s_GlobalFrame->pLibGen2 = pLib; }
|
||||
|
|
|
|||
|
|
@ -98,7 +98,8 @@ struct Abc_Frame_t_
|
|||
void * pManDsd; // decomposition manager
|
||||
void * pManDsd2; // decomposition manager
|
||||
// libraries for mapping
|
||||
void * pLibLut; // the current LUT library
|
||||
void * pLibLut[ABC_LUT_LIBS]; // the current LUT library
|
||||
void * pLibCell; // the current cell library
|
||||
void * pLibBox; // the current box library
|
||||
void * pLibGen; // the current genlib
|
||||
void * pLibGen2; // the current genlib
|
||||
|
|
|
|||
|
|
@ -512,17 +512,16 @@ private:
|
|||
} while ( combinations_offset_next( free_set_size, offset, pComb, pInvPerm, tt ) );
|
||||
|
||||
std::array<uint32_t, max_num_vars> res_perm;
|
||||
for ( uint32_t i = 0; i < num_vars; ++i )
|
||||
{
|
||||
res_perm[i] = permutations[bestPerm[i]];
|
||||
}
|
||||
|
||||
if ( best_cost > ( 1 << ( ps.lut_size - free_set_size ) ) )
|
||||
{
|
||||
return std::make_tuple( local_best_tt, res_perm, UINT32_MAX );
|
||||
}
|
||||
|
||||
for ( uint32_t i = 0; i < num_vars; ++i )
|
||||
{
|
||||
res_perm[i] = permutations[bestPerm[i]];
|
||||
}
|
||||
|
||||
return std::make_tuple( local_best_tt, res_perm, best_cost );
|
||||
}
|
||||
|
||||
|
|
@ -544,7 +543,11 @@ private:
|
|||
}
|
||||
|
||||
/* enumerate combinations */
|
||||
std::array<uint32_t, max_num_vars> res_perm;
|
||||
std::array<uint32_t, max_num_vars> res_perm;
|
||||
for ( uint32_t i = 0; i < num_vars; ++i )
|
||||
{
|
||||
res_perm[i] = permutations[pComb[i]];
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
|
|
|
|||
|
|
@ -80,6 +80,7 @@ typedef struct If_Obj_t_ If_Obj_t;
|
|||
typedef struct If_Cut_t_ If_Cut_t;
|
||||
typedef struct If_Set_t_ If_Set_t;
|
||||
typedef struct If_LibLut_t_ If_LibLut_t;
|
||||
typedef struct If_LibCell_t_ If_LibCell_t;
|
||||
typedef struct If_LibBox_t_ If_LibBox_t;
|
||||
typedef struct If_DsdMan_t_ If_DsdMan_t;
|
||||
typedef struct Ifn_Ntk_t_ Ifn_Ntk_t;
|
||||
|
|
@ -194,6 +195,17 @@ struct If_LibLut_t_
|
|||
float pLutDelays[IF_MAX_LUTSIZE+1][IF_MAX_LUTSIZE+1];// the delays of LUTs
|
||||
};
|
||||
|
||||
// the cell library
|
||||
struct If_LibCell_t_
|
||||
{
|
||||
char * pName; // the name of the LUT library
|
||||
int nCellNum; // the number of cells in the library
|
||||
int nCellInputs[IF_MAX_LUTSIZE];
|
||||
char * pCellNames[IF_MAX_LUTSIZE];
|
||||
float pCellAreas[IF_MAX_LUTSIZE];
|
||||
int pCellPinDelays[IF_MAX_LUTSIZE][IF_MAX_LUTSIZE];
|
||||
};
|
||||
|
||||
// manager
|
||||
struct If_Man_t_
|
||||
{
|
||||
|
|
@ -552,6 +564,7 @@ extern float If_CutPowerDerefed( If_Man_t * p, If_Cut_t * pCut, If_Obj
|
|||
extern float If_CutPowerRefed( If_Man_t * p, If_Cut_t * pCut, If_Obj_t * pRoot );
|
||||
/*=== ifDec.c =============================================================*/
|
||||
extern word If_CutPerformDerive07( If_Man_t * p, unsigned * pTruth, int nVars, int nLeaves, char * pStr );
|
||||
extern word If_CutPerformDeriveJ( If_Man_t * p, unsigned * pTruth, int nVars, int nLeaves, char * pStr, int fDerive );
|
||||
extern int If_CutPerformCheck07( If_Man_t * p, unsigned * pTruth, int nVars, int nLeaves, char * pStr );
|
||||
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 );
|
||||
|
|
@ -560,6 +573,7 @@ extern int If_CutPerformCheckXX( If_Man_t * p, unsigned * pTruth, in
|
|||
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 );
|
||||
extern int If_CutPerformCheckJ( If_Man_t * p, unsigned * pTruth, int nVars, int nLeaves, char * pStr );
|
||||
extern float If_CutDelayLutStruct( If_Man_t * p, If_Cut_t * pCut, char * pStr, float WireDelay );
|
||||
// extern int If_CutPerformAcd( If_Man_t * p, unsigned nVars, int lutSize, unsigned * pdelay, int use_late_arrival, unsigned * cost );
|
||||
extern int If_CluCheckExt( void * p, word * pTruth, int nVars, int nLutLeaf, int nLutRoot,
|
||||
|
|
@ -624,6 +638,10 @@ extern int If_LibLutDelaysAreDifferent( If_LibLut_t * pLutLib );
|
|||
extern If_LibLut_t * If_LibLutSetSimple( int nLutSize );
|
||||
extern float If_LibLutFastestPinDelay( If_LibLut_t * p );
|
||||
extern float If_LibLutSlowestPinDelay( If_LibLut_t * p );
|
||||
extern If_LibCell_t * If_LibCellRead( char * FileName );
|
||||
extern If_LibCell_t * If_LibCellDup( If_LibCell_t * p );
|
||||
extern void If_LibCellFree( If_LibCell_t * pCellLib );
|
||||
extern void If_LibCellPrint( If_LibCell_t * pCellLib );
|
||||
/*=== ifLibBox.c =============================================================*/
|
||||
extern If_LibBox_t * If_LibBoxStart();
|
||||
extern void If_LibBoxFree( If_LibBox_t * p );
|
||||
|
|
@ -690,6 +708,7 @@ extern void * If_ManSatBuildFromCell( char * pStr, Vec_Int_t ** pvPiVar
|
|||
extern int If_ManSatFindCofigBits( void * pSat, Vec_Int_t * vPiVars, Vec_Int_t * vPoVars, word * pTruth, int nVars, word Perm, int nInps, Vec_Int_t * vValues );
|
||||
extern int If_ManSatDeriveGiaFromBits( void * pNew, Ifn_Ntk_t * p, word * pTtData, Vec_Int_t * vLeaves, Vec_Int_t * vValues );
|
||||
extern void * If_ManDeriveGiaFromCells( void * p );
|
||||
extern void * If_ManDeriveGiaFromCells2( void * p );
|
||||
/*=== ifUtil.c ============================================================*/
|
||||
extern void If_ManCleanNodeCopy( If_Man_t * p );
|
||||
extern void If_ManCleanCutData( If_Man_t * p );
|
||||
|
|
|
|||
|
|
@ -30,6 +30,8 @@ ABC_NAMESPACE_IMPL_START
|
|||
|
||||
static int If_CommandReadLut ( Abc_Frame_t * pAbc, int argc, char **argv );
|
||||
static int If_CommandPrintLut( Abc_Frame_t * pAbc, int argc, char **argv );
|
||||
static int If_CommandReadCell( Abc_Frame_t * pAbc, int argc, char **argv );
|
||||
static int If_CommandPrintCell( Abc_Frame_t * pAbc, int argc, char **argv );
|
||||
static int If_CommandReadBox ( Abc_Frame_t * pAbc, int argc, char **argv );
|
||||
static int If_CommandPrintBox( Abc_Frame_t * pAbc, int argc, char **argv );
|
||||
static int If_CommandWriteBox( Abc_Frame_t * pAbc, int argc, char **argv );
|
||||
|
|
@ -59,6 +61,9 @@ void If_Init( Abc_Frame_t * pAbc )
|
|||
Cmd_CommandAdd( pAbc, "FPGA mapping", "read_lut", If_CommandReadLut, 0 );
|
||||
Cmd_CommandAdd( pAbc, "FPGA mapping", "print_lut", If_CommandPrintLut, 0 );
|
||||
|
||||
Cmd_CommandAdd( pAbc, "FPGA mapping", "read_cell", If_CommandReadCell, 0 );
|
||||
Cmd_CommandAdd( pAbc, "FPGA mapping", "print_cell", If_CommandPrintCell, 0 );
|
||||
|
||||
Cmd_CommandAdd( pAbc, "FPGA mapping", "read_box", If_CommandReadBox, 0 );
|
||||
Cmd_CommandAdd( pAbc, "FPGA mapping", "print_box", If_CommandPrintBox, 0 );
|
||||
Cmd_CommandAdd( pAbc, "FPGA mapping", "write_box", If_CommandWriteBox, 0 );
|
||||
|
|
@ -78,7 +83,10 @@ void If_Init( Abc_Frame_t * pAbc )
|
|||
***********************************************************************/
|
||||
void If_End( Abc_Frame_t * pAbc )
|
||||
{
|
||||
If_LibLutFree( (If_LibLut_t *) Abc_FrameReadLibLut() );
|
||||
int i;
|
||||
for ( i = 0; i < ABC_LUT_LIBS; i++ )
|
||||
if ( Abc_FrameReadLibLutI(i) )
|
||||
If_LibLutFree( (If_LibLut_t *)Abc_FrameReadLibLutI(i) );
|
||||
If_LibBoxFree( (If_LibBox_t *)Abc_FrameReadLibBox() );
|
||||
}
|
||||
|
||||
|
|
@ -125,36 +133,51 @@ int If_CommandReadLut( Abc_Frame_t * pAbc, int argc, char **argv )
|
|||
}
|
||||
}
|
||||
|
||||
if ( argc != globalUtilOptind + 1 )
|
||||
goto usage;
|
||||
|
||||
// get the input file name
|
||||
FileName = argv[globalUtilOptind];
|
||||
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 = If_LibLutRead( FileName );
|
||||
if ( pLib == NULL )
|
||||
{
|
||||
fprintf( pErr, "Reading LUT library has failed.\n" );
|
||||
if ( argc == globalUtilOptind ) {
|
||||
fprintf( pErr, "The library file should be specified in the command line.\n" );
|
||||
goto usage;
|
||||
}
|
||||
// replace the current library
|
||||
If_LibLutFree( (If_LibLut_t *)Abc_FrameReadLibLut() );
|
||||
Abc_FrameSetLibLut( pLib );
|
||||
if ( argc > globalUtilOptind + ABC_LUT_LIBS ) {
|
||||
fprintf( pErr, "Can read at most %d libraries. Quitting...\n", ABC_LUT_LIBS );
|
||||
goto usage;
|
||||
}
|
||||
|
||||
// remove current libraries
|
||||
int i;
|
||||
for ( i = 0; i < ABC_LUT_LIBS; i++ )
|
||||
if ( Abc_FrameReadLibLutI(i) ) {
|
||||
If_LibLutFree( (If_LibLut_t *)Abc_FrameReadLibLutI(i) );
|
||||
Abc_FrameSetLibLutI( NULL, i );
|
||||
}
|
||||
|
||||
// input new libraries
|
||||
for ( i = globalUtilOptind; i < argc; i++ ) {
|
||||
// get the input file name
|
||||
FileName = argv[i];
|
||||
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 = If_LibLutRead( FileName );
|
||||
if ( pLib == NULL )
|
||||
{
|
||||
fprintf( pErr, "Reading LUT library has failed.\n" );
|
||||
goto usage;
|
||||
}
|
||||
// replace the current library
|
||||
Abc_FrameSetLibLutI( pLib, i-globalUtilOptind );
|
||||
}
|
||||
return 0;
|
||||
|
||||
usage:
|
||||
fprintf( pErr, "\nusage: read_lut [-vh]\n");
|
||||
fprintf( pErr, "\t read the LUT library from the file\n" );
|
||||
fprintf( pErr, "\nusage: read_lut [-vh] <file1> <file2> ... <fileN>\n");
|
||||
fprintf( pErr, "\t read the LUT library from the file(s)\n" );
|
||||
fprintf( pErr, "\t-v : toggles enabling of verbose output [default = %s]\n", (fVerbose? "yes" : "no") );
|
||||
fprintf( pErr, "\t-h : print the command usage\n");
|
||||
fprintf( pErr, "\t \n");
|
||||
|
|
@ -216,7 +239,10 @@ int If_CommandPrintLut( Abc_Frame_t * pAbc, int argc, char **argv )
|
|||
goto usage;
|
||||
|
||||
// set the new network
|
||||
If_LibLutPrint( (If_LibLut_t *)Abc_FrameReadLibLut() );
|
||||
int i;
|
||||
for ( i = 0; i < ABC_LUT_LIBS; i++ )
|
||||
if ( Abc_FrameReadLibLutI(i) )
|
||||
If_LibLutPrint( (If_LibLut_t *)Abc_FrameReadLibLutI(i) );
|
||||
return 0;
|
||||
|
||||
usage:
|
||||
|
|
@ -227,6 +253,143 @@ usage:
|
|||
return 1; /* error exit */
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Command procedure to read LUT libraries.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int If_CommandReadCell( Abc_Frame_t * pAbc, int argc, char **argv )
|
||||
{
|
||||
FILE * pFile;
|
||||
FILE * pOut, * pErr;
|
||||
If_LibCell_t * pLib;
|
||||
Abc_Ntk_t * pNet;
|
||||
char * FileName;
|
||||
int fVerbose;
|
||||
int c;
|
||||
|
||||
pNet = Abc_FrameReadNtk(pAbc);
|
||||
pOut = Abc_FrameReadOut(pAbc);
|
||||
pErr = Abc_FrameReadErr(pAbc);
|
||||
|
||||
// set the defaults
|
||||
fVerbose = 1;
|
||||
Extra_UtilGetoptReset();
|
||||
while ( (c = Extra_UtilGetopt(argc, argv, "vh")) != EOF )
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case 'v':
|
||||
fVerbose ^= 1;
|
||||
break;
|
||||
case 'h':
|
||||
goto usage;
|
||||
break;
|
||||
default:
|
||||
goto usage;
|
||||
}
|
||||
}
|
||||
|
||||
if ( argc == globalUtilOptind ) {
|
||||
fprintf( pErr, "The library file should be specified in the command line.\n" );
|
||||
goto usage;
|
||||
}
|
||||
|
||||
// remove current libraries
|
||||
If_LibCellFree( (If_LibCell_t *)Abc_FrameReadLibCell() );
|
||||
Abc_FrameSetLibCell( NULL );
|
||||
|
||||
// get the input file name
|
||||
FileName = argv[globalUtilOptind];
|
||||
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 = If_LibCellRead( FileName );
|
||||
if ( pLib == NULL )
|
||||
{
|
||||
fprintf( pErr, "Reading LUT library has failed.\n" );
|
||||
goto usage;
|
||||
}
|
||||
// replace the current library
|
||||
Abc_FrameSetLibCell( pLib );
|
||||
return 0;
|
||||
|
||||
usage:
|
||||
fprintf( pErr, "\nusage: read_cell [-vh] <file>\n");
|
||||
fprintf( pErr, "\t read the cell library from the file\n" );
|
||||
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 */
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Command procedure to read cell libraries.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int If_CommandPrintCell( Abc_Frame_t * pAbc, int argc, char **argv )
|
||||
{
|
||||
FILE * pOut, * pErr;
|
||||
Abc_Ntk_t * pNet;
|
||||
int fVerbose;
|
||||
int c;
|
||||
|
||||
pNet = Abc_FrameReadNtk(pAbc);
|
||||
pOut = Abc_FrameReadOut(pAbc);
|
||||
pErr = Abc_FrameReadErr(pAbc);
|
||||
|
||||
// set the defaults
|
||||
fVerbose = 1;
|
||||
Extra_UtilGetoptReset();
|
||||
while ( (c = Extra_UtilGetopt(argc, argv, "vh")) != EOF )
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case 'v':
|
||||
fVerbose ^= 1;
|
||||
break;
|
||||
case 'h':
|
||||
goto usage;
|
||||
break;
|
||||
default:
|
||||
goto usage;
|
||||
}
|
||||
}
|
||||
|
||||
if ( argc != globalUtilOptind )
|
||||
goto usage;
|
||||
|
||||
// set the new network
|
||||
If_LibCellPrint( (If_LibCell_t *)Abc_FrameReadLibCell() );
|
||||
return 0;
|
||||
|
||||
usage:
|
||||
fprintf( pErr, "\nusage: print_cell [-vh]\n");
|
||||
fprintf( pErr, "\t print the current cell library\n" );
|
||||
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 */
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
|
|
|||
|
|
@ -0,0 +1,51 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [ifDec07.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [FPGA mapping based on priority cuts.]
|
||||
|
||||
Synopsis [Performs additional check.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - November 21, 2006.]
|
||||
|
||||
Revision [$Id: ifDec07.c,v 1.00 2006/11/21 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "if.h"
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int If_CutPerformCheckJ( If_Man_t * p, unsigned * pTruth, int nVars, int nLeaves, char * pStr )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
word If_CutPerformDeriveJ( If_Man_t * p, unsigned * pTruth, int nVars, int nLeaves, char * pStr, int fDerive )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
void If_PermUnpack( unsigned Value, int Pla2Var[9] )
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
||||
|
|
@ -369,6 +369,240 @@ void If_LibLutPrint( If_LibLut_t * pLutLib )
|
|||
Abc_Print( 1, "%d %7.2f %7.2f\n", i, pLutLib->pLutAreas[i], pLutLib->pLutDelays[i][0] );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Allocates the cell library structure.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
If_LibCell_t * If_LibCellAlloc( void )
|
||||
{
|
||||
If_LibCell_t * p;
|
||||
p = ABC_ALLOC( If_LibCell_t, 1 );
|
||||
memset( p, 0, sizeof(If_LibCell_t) );
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Reads the description of cells from the cell library file.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
If_LibCell_t * If_LibCellRead( char * FileName )
|
||||
{
|
||||
char pBuffer[1000], * pToken;
|
||||
If_LibCell_t * p;
|
||||
FILE * pFile;
|
||||
int i, k;
|
||||
int CellId;
|
||||
char * FuncDesc;
|
||||
|
||||
pFile = fopen( FileName, "r" );
|
||||
if ( pFile == NULL )
|
||||
{
|
||||
Abc_Print( -1, "Cannot open cell library file \"%s\".\n", FileName );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
p = If_LibCellAlloc();
|
||||
p->pName = Abc_UtilStrsav( FileName );
|
||||
p->nCellNum = 0;
|
||||
|
||||
// Read each line of the file
|
||||
while ( fgets( pBuffer, 1000, pFile ) != NULL )
|
||||
{
|
||||
pToken = strtok( pBuffer, " \t\n" );
|
||||
if ( pToken == NULL )
|
||||
continue;
|
||||
if ( pToken[0] == '#' )
|
||||
continue;
|
||||
|
||||
// Read CellId
|
||||
CellId = atoi(pToken);
|
||||
if ( CellId < 0 || CellId >= IF_MAX_LUTSIZE )
|
||||
{
|
||||
Abc_Print( -1, "Cell ID %d is out of bounds (0-%d).\n", CellId, IF_MAX_LUTSIZE-1 );
|
||||
If_LibCellFree( p );
|
||||
fclose( pFile );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Read FuncDesc
|
||||
pToken = strtok( NULL, " \t\n" );
|
||||
if ( pToken == NULL )
|
||||
{
|
||||
Abc_Print( -1, "Missing function description for cell %d.\n", CellId );
|
||||
If_LibCellFree( p );
|
||||
fclose( pFile );
|
||||
return NULL;
|
||||
}
|
||||
FuncDesc = Abc_UtilStrsav( pToken );
|
||||
p->pCellNames[CellId] = FuncDesc;
|
||||
|
||||
// Determine number of inputs from function description
|
||||
int nInputs = 0;
|
||||
if ( FuncDesc[0] >= 'a' && FuncDesc[0] <= 'z' )
|
||||
{
|
||||
// If it begins with a letter, that letter indicates the output
|
||||
// and the number of inputs is that letter - 'a'
|
||||
nInputs = FuncDesc[0] - 'a';
|
||||
}
|
||||
else
|
||||
{
|
||||
// Otherwise, find the largest letter in the formula
|
||||
char maxChar = 'a' - 1;
|
||||
for ( i = 0; FuncDesc[i]; i++ )
|
||||
{
|
||||
if ( FuncDesc[i] >= 'a' && FuncDesc[i] <= 'z' && FuncDesc[i] > maxChar )
|
||||
maxChar = FuncDesc[i];
|
||||
}
|
||||
if ( maxChar >= 'a' )
|
||||
nInputs = maxChar - 'a' + 1;
|
||||
}
|
||||
p->nCellInputs[CellId] = nInputs;
|
||||
|
||||
// Read Area
|
||||
pToken = strtok( NULL, " \t\n" );
|
||||
if ( pToken == NULL )
|
||||
{
|
||||
Abc_Print( -1, "Missing area for cell %d.\n", CellId );
|
||||
If_LibCellFree( p );
|
||||
fclose( pFile );
|
||||
return NULL;
|
||||
}
|
||||
p->pCellAreas[CellId] = (float)atof(pToken);
|
||||
|
||||
// Read all available delays
|
||||
k = 0;
|
||||
while ( (pToken = strtok( NULL, " \t\n" )) != NULL && k < IF_MAX_LUTSIZE )
|
||||
{
|
||||
p->pCellPinDelays[CellId][k] = atoi(pToken);
|
||||
k++;
|
||||
}
|
||||
|
||||
// Check if number of delays matches number of inputs
|
||||
if ( k != nInputs )
|
||||
{
|
||||
Abc_Print( 0, "Warning: Cell %d has %d inputs but %d delays specified.\n", CellId, nInputs, k );
|
||||
}
|
||||
|
||||
p->nCellNum++;
|
||||
}
|
||||
|
||||
fclose( pFile );
|
||||
|
||||
// Validate the library
|
||||
for ( i = 0; i < IF_MAX_LUTSIZE; i++ )
|
||||
{
|
||||
if ( p->pCellNames[i] == NULL )
|
||||
continue;
|
||||
for ( k = 0; k < IF_MAX_LUTSIZE && p->pCellPinDelays[i][k] > 0; k++ )
|
||||
{
|
||||
if ( p->pCellPinDelays[i][k] < 0 )
|
||||
{
|
||||
Abc_Print( 0, "Pin %d of cell %d has delay %d. Pin delays should be non-negative. Technology mapping may not work correctly.\n",
|
||||
k, i, p->pCellPinDelays[i][k] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Duplicates the cell library.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
If_LibCell_t * If_LibCellDup( If_LibCell_t * p )
|
||||
{
|
||||
If_LibCell_t * pNew;
|
||||
int i;
|
||||
pNew = ABC_ALLOC( If_LibCell_t, 1 );
|
||||
*pNew = *p;
|
||||
pNew->pName = Abc_UtilStrsav( p->pName );
|
||||
for ( i = 0; i < IF_MAX_LUTSIZE; i++ )
|
||||
if ( p->pCellNames[i] )
|
||||
pNew->pCellNames[i] = Abc_UtilStrsav( p->pCellNames[i] );
|
||||
return pNew;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Frees the cell library.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void If_LibCellFree( If_LibCell_t * pCellLib )
|
||||
{
|
||||
int i;
|
||||
if ( pCellLib == NULL )
|
||||
return;
|
||||
ABC_FREE( pCellLib->pName );
|
||||
for ( i = 0; i < IF_MAX_LUTSIZE; i++ )
|
||||
ABC_FREE( pCellLib->pCellNames[i] );
|
||||
ABC_FREE( pCellLib );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Prints the cell library.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void If_LibCellPrint( If_LibCell_t * pCellLib )
|
||||
{
|
||||
int i, k;
|
||||
if ( pCellLib == NULL )
|
||||
{
|
||||
Abc_Print( 1, "Cell library is not available.\n" );
|
||||
return;
|
||||
}
|
||||
Abc_Print( 1, "# Cell library: %s\n", pCellLib->pName ? pCellLib->pName : "Unknown" );
|
||||
Abc_Print( 1, "# Number of cells: %d\n", pCellLib->nCellNum );
|
||||
Abc_Print( 1, "# CellId Inputs Cell Description Area Delays\n" );
|
||||
|
||||
for ( i = 0; i < IF_MAX_LUTSIZE; i++ )
|
||||
{
|
||||
if ( pCellLib->pCellNames[i] == NULL )
|
||||
continue;
|
||||
|
||||
Abc_Print( 1, "%3d %6d %-32s %6.2f ", i, pCellLib->nCellInputs[i], pCellLib->pCellNames[i], pCellLib->pCellAreas[i] );
|
||||
|
||||
// Print all non-zero delays
|
||||
for ( k = 0; k < IF_MAX_LUTSIZE && pCellLib->pCellPinDelays[i][k] > 0; k++ )
|
||||
Abc_Print( 1, " %4d", pCellLib->pCellPinDelays[i][k] );
|
||||
Abc_Print( 1, "\n" );
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns 1 if the delays are discrete.]
|
||||
|
|
|
|||
|
|
@ -229,19 +229,24 @@ void If_ManDumpCut( If_Cut_t * pCut, int nLutSize, Vec_Int_t * vCuts )
|
|||
for ( i = 0; i < pCut->nLeaves; i++ )
|
||||
Vec_IntPush( vCuts, pCut->pLeaves[i] );
|
||||
for ( ; i < nLutSize; i++ )
|
||||
Vec_IntPush( vCuts, 0 );
|
||||
Vec_IntPush( vCuts, -1 );
|
||||
}
|
||||
void If_ManDumpCutsAndCost( If_Man_t * p, If_Obj_t * pObj, Vec_Int_t * vCuts, Vec_Int_t * vCutCosts )
|
||||
{
|
||||
If_Cut_t * pCut; int k, nCuts = 0;
|
||||
while ( nCuts < p->pPars->nCutsMax ) {
|
||||
If_ObjForEachCut( pObj, pCut, k ) {
|
||||
If_ManDumpCut( pCut, p->pPars->nLutSize, vCuts );
|
||||
Vec_IntPush( vCutCosts, (int)pCut->Area );
|
||||
if ( ++nCuts == p->pPars->nCutsMax )
|
||||
break;
|
||||
}
|
||||
If_ObjForEachCut( pObj, pCut, k ) {
|
||||
If_ManDumpCut( pCut, p->pPars->nLutSize, vCuts );
|
||||
Vec_IntPush( vCutCosts, 1 );
|
||||
if ( ++nCuts == p->pPars->nCutsMax )
|
||||
break;
|
||||
}
|
||||
while ( nCuts < p->pPars->nCutsMax ) {
|
||||
for ( k = 0; k < p->pPars->nLutSize; k++ )
|
||||
Vec_IntPush( vCuts, -1 );
|
||||
Vec_IntPush( vCutCosts, 1 );
|
||||
nCuts++;
|
||||
}
|
||||
assert( nCuts == p->pPars->nCutsMax );
|
||||
}
|
||||
void If_ManDumpCutsAndCostAdd( int Obj, int nCutsMax, int nLutSize, Vec_Int_t * vCopy, Vec_Int_t * vCuts, Vec_Int_t * vCutCosts, Vec_Int_t * vCutsOut, Vec_Int_t * vCutCostsOut )
|
||||
{
|
||||
|
|
@ -255,7 +260,7 @@ void If_ManDumpCutsAndCostAdd( int Obj, int nCutsMax, int nLutSize, Vec_Int_t *
|
|||
for ( i = 0; i < nCutsMax; i++ )
|
||||
Vec_IntPush( vCutCostsOut, Vec_IntEntry( vCutCosts, Obj * nCutsMax + i ) );
|
||||
}
|
||||
int If_ManDumpData( If_Man_t * p, FILE * pFile )
|
||||
int If_ManDumpData2( If_Man_t * p, FILE * pFile )
|
||||
{
|
||||
Vec_Int_t * vCopy = Vec_IntStartFull( If_ManObjNum(p) );
|
||||
Vec_Int_t * vCopy2 = Vec_IntAlloc( If_ManObjNum(p) );
|
||||
|
|
@ -313,6 +318,22 @@ int If_ManDumpData( If_Man_t * p, FILE * pFile )
|
|||
Vec_IntFree( vCutCosts );
|
||||
return nBytes;
|
||||
}
|
||||
int If_ManDumpData( If_Man_t * p, FILE * pFile )
|
||||
{
|
||||
int nSpace = p->pPars->nCutsMax * p->pPars->nLutSize;
|
||||
If_Obj_t * pObj; int i, nBytes;
|
||||
Vec_Int_t * vCuts = Vec_IntAlloc( 1 << 20 );
|
||||
Vec_IntFill( vCuts, (1 + If_ManCiNum(p))*nSpace, -1 );
|
||||
Vec_IntAppend( vCuts, p->vCuts );
|
||||
If_ManForEachCo( p, pObj, i ) {
|
||||
Vec_IntPush( vCuts, If_ObjFanin0(pObj)->Id );
|
||||
Vec_IntFillExtra( vCuts, Vec_IntSize(vCuts)+nSpace-1, -1 );
|
||||
}
|
||||
nBytes = fwrite( Vec_IntArray(vCuts), 1, sizeof(int)*Vec_IntSize(vCuts), pFile );
|
||||
assert( nBytes == If_ManObjNum(p)*nSpace*sizeof(int) );
|
||||
Vec_IntFree( vCuts );
|
||||
return nBytes;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
|
|
@ -332,16 +353,16 @@ void If_ManStop( If_Man_t * p )
|
|||
char pFileName[1000] = {0};
|
||||
// "I15_O20_L32_N256_C16_K6__name.bin"
|
||||
char * pName = Extra_FileNameGeneric(Extra_FileNameWithoutPath(p->pName));
|
||||
sprintf( pFileName, "%s__I%d_O%d_L%d_N%d_C%d_K%d.bin", pName, If_ManCiNum(p), If_ManCoNum(p), p->nLevelMax, If_ManAndNum(p), p->pPars->nCutsMax, p->pPars->nLutSize );
|
||||
sprintf( pFileName, "%s__n%d_c%d_k%d.bin", pName, If_ManObjNum(p), p->pPars->nCutsMax, p->pPars->nLutSize );
|
||||
ABC_FREE( pName );
|
||||
FILE * pFile = fopen( pFileName, "wb" );
|
||||
if ( pFile == NULL )
|
||||
printf( "Cannot open file \"%s\" for writing.\n", pFileName );
|
||||
else {
|
||||
int nBytes = If_ManDumpData( p, pFile );
|
||||
int nBytes2 = sizeof(int) * (If_ManAndNum(p) * p->pPars->nCutsMax * p->pPars->nLutSize + If_ManCoNum(p) + p->nLevelMax + 1);
|
||||
nBytes2 += sizeof(int) * (If_ManAndNum(p) * p->pPars->nCutsMax);
|
||||
assert( nBytes == nBytes2 );
|
||||
//int nBytes2 = sizeof(int) * (If_ManAndNum(p) * p->pPars->nCutsMax * p->pPars->nLutSize + If_ManCoNum(p) + p->nLevelMax + 1);
|
||||
//nBytes2 += sizeof(int) * (If_ManAndNum(p) * p->pPars->nCutsMax);
|
||||
//assert( nBytes == nBytes2 );
|
||||
fclose( pFile );
|
||||
printf( "Finished writing cut information into file \"%s\" (%.3f MB).\n", pFileName, 1.0 * nBytes / (1<<20) );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -892,6 +892,342 @@ void * If_ManDeriveGiaFromCells( void * pGia )
|
|||
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Print cell configuration data.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void If_ManConfigPrint( unsigned char * pConfigData, int nLeaves )
|
||||
{
|
||||
unsigned char CellId = pConfigData[0];
|
||||
int i;
|
||||
static int Count = 0;
|
||||
printf( "[%4d] ", Count++ ); // Print instance number
|
||||
if ( CellId == 0 )
|
||||
{
|
||||
// Extract 16-bit truth table
|
||||
word Truth = ((word)pConfigData[2] << 8) | pConfigData[1];
|
||||
printf( "%04lX{", (unsigned long)Truth );
|
||||
// Print as simple {abcd} since it's just a direct LUT4
|
||||
for ( i = 0; i < nLeaves && i < 4; i++ )
|
||||
printf( "%c", 'a' + i );
|
||||
printf( "}" );
|
||||
// Pad with spaces if less than 4 inputs
|
||||
for ( i = nLeaves; i < 4; i++ )
|
||||
printf( " " );
|
||||
printf( " [Cell %d, %d leaves]\n", CellId, nLeaves );
|
||||
}
|
||||
else if ( CellId == 1 )
|
||||
{
|
||||
// First LUT4
|
||||
word Truth1 = ((word)pConfigData[6] << 8) | pConfigData[5];
|
||||
printf( "h=%04lX{", (unsigned long)Truth1 );
|
||||
for ( i = 0; i < 4; i++ )
|
||||
{
|
||||
int v = (pConfigData[1 + i/2] >> ((i%2) * 4)) & 0xF;
|
||||
if ( v == 0 )
|
||||
printf( "0");
|
||||
else if ( v == 1 )
|
||||
printf( "1");
|
||||
else if ( v >= 2 && v < 2 + nLeaves )
|
||||
printf( "%c", 'a' + (v-2));
|
||||
else
|
||||
printf( "?");
|
||||
}
|
||||
printf( "} ");
|
||||
// Second LUT4
|
||||
word Truth2 = ((word)pConfigData[8] << 8) | pConfigData[7];
|
||||
printf( "i=%04lX{", (unsigned long)Truth2 );
|
||||
for ( i = 0; i < 4; i++ )
|
||||
{
|
||||
int v = (pConfigData[3 + i/2] >> ((i%2) * 4)) & 0xF;
|
||||
if ( v == 0 )
|
||||
printf( "0");
|
||||
else if ( v == 1 )
|
||||
printf( "1");
|
||||
else if ( v >= 2 && v < 2 + nLeaves )
|
||||
printf( "%c", 'a' + (v-2));
|
||||
else if ( v == 9 )
|
||||
printf( "h"); // Output of first LUT
|
||||
else
|
||||
printf( "?");
|
||||
}
|
||||
printf( "} [Cell %d, %d leaves]\n", CellId, nLeaves );
|
||||
}
|
||||
else if ( CellId == 2 )
|
||||
{
|
||||
// Extract 9 input mappings
|
||||
int inputs[9];
|
||||
int bitPos = 0;
|
||||
for ( i = 0; i < 9; i++ )
|
||||
{
|
||||
if ( bitPos == 0 )
|
||||
{
|
||||
inputs[i] = pConfigData[1 + i/2] & 0xF;
|
||||
bitPos = 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
inputs[i] = (pConfigData[1 + i/2] >> 4) & 0xF;
|
||||
bitPos = 0;
|
||||
}
|
||||
}
|
||||
// First LUT4
|
||||
word Truth1 = ((word)pConfigData[7] << 8) | pConfigData[6];
|
||||
printf( "j=%04lX{", (unsigned long)Truth1 );
|
||||
for ( i = 0; i < 4; i++ )
|
||||
{
|
||||
int v = inputs[i];
|
||||
if ( v == 0 )
|
||||
printf( "0");
|
||||
else if ( v == 1 )
|
||||
printf( "1");
|
||||
else if ( v >= 2 && v < 2 + nLeaves )
|
||||
printf( "%c", 'a' + (v-2));
|
||||
else
|
||||
printf( "?");
|
||||
}
|
||||
printf( "} ");
|
||||
// Second LUT4
|
||||
word Truth2 = ((word)pConfigData[9] << 8) | pConfigData[8];
|
||||
printf( "k=%04lX{", (unsigned long)Truth2 );
|
||||
for ( i = 4; i < 8; i++ )
|
||||
{
|
||||
int v = inputs[i];
|
||||
if ( v == 0 )
|
||||
printf( "0");
|
||||
else if ( v == 1 )
|
||||
printf( "1");
|
||||
else if ( v >= 2 && v < 2 + nLeaves )
|
||||
printf( "%c", 'a' + (v-2));
|
||||
else
|
||||
printf( "?");
|
||||
}
|
||||
printf( "} ");
|
||||
// final node
|
||||
printf( "l=<");
|
||||
int v = inputs[8];
|
||||
if ( v == 0 )
|
||||
printf( "0");
|
||||
else if ( v == 1 )
|
||||
printf( "1");
|
||||
else if ( v >= 2 && v < 2 + nLeaves )
|
||||
printf( "%c", 'a' + (v-2));
|
||||
else
|
||||
printf( "?");
|
||||
printf( "jk> [Cell %d, %d leaves]\n", CellId, nLeaves );
|
||||
}
|
||||
else
|
||||
{
|
||||
printf( "Unknown cell type %d!\n", CellId );
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Derive GIA using programmable bits.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void * If_ManDeriveGiaFromCells2( void * pGia )
|
||||
{
|
||||
Gia_Man_t * p = (Gia_Man_t *)pGia;
|
||||
Gia_Man_t * pNew, * pTemp;
|
||||
Vec_Int_t * vCover, * vLeaves;
|
||||
Gia_Obj_t * pObj;
|
||||
unsigned char * pConfigData;
|
||||
int k, i, iLut, iVar;
|
||||
int Count = 0;
|
||||
assert( p->vConfigs2 != NULL );
|
||||
assert( Gia_ManHasMapping(p) );
|
||||
// create new manager
|
||||
pNew = Gia_ManStart( 6*Gia_ManObjNum(p)/5 + 100 );
|
||||
pNew->pName = Abc_UtilStrsav( p->pName );
|
||||
pNew->pSpec = Abc_UtilStrsav( p->pSpec );
|
||||
// map primary inputs
|
||||
Gia_ManFillValue(p);
|
||||
Gia_ManConst0(p)->Value = 0;
|
||||
Gia_ManForEachCi( p, pObj, i )
|
||||
pObj->Value = Gia_ManAppendCi(pNew);
|
||||
// iterate through nodes used in the mapping
|
||||
vLeaves = Vec_IntAlloc( 16 );
|
||||
vCover = Vec_IntAlloc( 1 << 16 );
|
||||
Gia_ManHashStart( pNew );
|
||||
// Process each mapped node
|
||||
int bytePos = 0;
|
||||
Gia_ManForEachAnd( p, pObj, iLut )
|
||||
{
|
||||
if ( Gia_ObjIsBuf(pObj) )
|
||||
{
|
||||
pObj->Value = Gia_ManAppendBuf( pNew, Gia_ObjFanin0Copy(pObj) );
|
||||
continue;
|
||||
}
|
||||
if ( !Gia_ObjIsLut(p, iLut) )
|
||||
continue;
|
||||
|
||||
// collect incoming literals
|
||||
Vec_IntClear( vLeaves );
|
||||
Gia_LutForEachFanin( p, iLut, iVar, k )
|
||||
Vec_IntPush( vLeaves, Gia_ManObj(p, iVar)->Value );
|
||||
// Get configuration data for this instance
|
||||
pConfigData = (unsigned char *)Vec_StrEntryP( p->vConfigs2, bytePos );
|
||||
//If_ManConfigPrint( pConfigData, Vec_IntSize(vLeaves) );
|
||||
unsigned char CellId = pConfigData[0];
|
||||
if ( CellId == 0 )
|
||||
{
|
||||
// Extract 16-bit truth table
|
||||
word Truth = ((word)pConfigData[2] << 8) | pConfigData[1];
|
||||
Truth = Abc_Tt6Stretch( Truth, 4 );
|
||||
extern int Kit_TruthToGia( Gia_Man_t * pMan, unsigned * pTruth, int nVars, Vec_Int_t * vMemory, Vec_Int_t * vLeaves, int fHash );
|
||||
Gia_ManObj(p, iLut)->Value = Kit_TruthToGia( pNew, (unsigned *)&Truth, Vec_IntSize(vLeaves), vCover, vLeaves, 1 );
|
||||
bytePos += 4; // 1 byte CellId + 2 bytes truth table + 1 padding
|
||||
}
|
||||
else if ( CellId == 1 )
|
||||
{
|
||||
Vec_Int_t * vLeavesTemp = Vec_IntAlloc( 4 );
|
||||
int iObjLit1, iObjLit2;
|
||||
// First LUT4 - extract inputs and truth table
|
||||
Vec_IntClear( vLeavesTemp );
|
||||
for ( i = 0; i < 4; i++ )
|
||||
{
|
||||
int v = (pConfigData[1 + i/2] >> ((i%2) * 4)) & 0xF;
|
||||
if ( v == 0 )
|
||||
Vec_IntPush( vLeavesTemp, 0 ); // constant 0
|
||||
else if ( v == 1 )
|
||||
Vec_IntPush( vLeavesTemp, 1 ); // constant 1
|
||||
else if ( v >= 2 && v < 2 + Vec_IntSize(vLeaves) )
|
||||
Vec_IntPush( vLeavesTemp, Vec_IntEntry(vLeaves, v - 2) ); // leaf (v-2)
|
||||
else
|
||||
assert( 0 ); // Invalid value
|
||||
}
|
||||
word Truth1 = ((word)pConfigData[6] << 8) | pConfigData[5];
|
||||
Truth1 = Abc_Tt6Stretch( Truth1, 4 );
|
||||
extern int Kit_TruthToGia( Gia_Man_t * pMan, unsigned * pTruth, int nVars, Vec_Int_t * vMemory, Vec_Int_t * vLeaves, int fHash );
|
||||
iObjLit1 = Kit_TruthToGia( pNew, (unsigned *)&Truth1, Vec_IntSize(vLeavesTemp), vCover, vLeavesTemp, 1 );
|
||||
// Second LUT4 - extract inputs and truth table
|
||||
Vec_IntClear( vLeavesTemp );
|
||||
for ( i = 0; i < 4; i++ )
|
||||
{
|
||||
int v = (pConfigData[3 + i/2] >> ((i%2) * 4)) & 0xF;
|
||||
if ( v == 0 )
|
||||
Vec_IntPush( vLeavesTemp, 0 ); // constant 0
|
||||
else if ( v == 1 )
|
||||
Vec_IntPush( vLeavesTemp, 1 ); // constant 1
|
||||
else if ( v >= 2 && v < 2 + Vec_IntSize(vLeaves) )
|
||||
Vec_IntPush( vLeavesTemp, Vec_IntEntry(vLeaves, v - 2) ); // leaf (v-2)
|
||||
else if ( v == 9 ) // N+2 where N=7 (number of S44 inputs)
|
||||
Vec_IntPush( vLeavesTemp, iObjLit1 ); // output of first LUT (internal connection)
|
||||
else
|
||||
assert( 0 ); // Invalid value
|
||||
}
|
||||
word Truth2 = ((word)pConfigData[8] << 8) | pConfigData[7];
|
||||
Truth2 = Abc_Tt6Stretch( Truth2, 4 );
|
||||
iObjLit2 = Kit_TruthToGia( pNew, (unsigned *)&Truth2, Vec_IntSize(vLeavesTemp), vCover, vLeavesTemp, 1 );
|
||||
Gia_ManObj(p, iLut)->Value = iObjLit2;
|
||||
Vec_IntFree( vLeavesTemp );
|
||||
bytePos += 12; // 1 byte CellId + 4 bytes mapping + 4 bytes truth tables + 3 padding
|
||||
}
|
||||
else if ( CellId == 2 )
|
||||
{
|
||||
Vec_Int_t * vLeavesTemp = Vec_IntAlloc( 4 );
|
||||
int iObjLit1, iObjLit2, iObjLit3;
|
||||
// Extract 9 input mappings (4 bits each, packed)
|
||||
int inputs[9];
|
||||
int bitPos = 0;
|
||||
for ( i = 0; i < 9; i++ )
|
||||
{
|
||||
if ( bitPos == 0 )
|
||||
{
|
||||
inputs[i] = pConfigData[1 + i/2] & 0xF;
|
||||
bitPos = 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
inputs[i] = (pConfigData[1 + i/2] >> 4) & 0xF;
|
||||
bitPos = 0;
|
||||
}
|
||||
}
|
||||
// First LUT4 (inputs 0-3)
|
||||
Vec_IntClear( vLeavesTemp );
|
||||
for ( i = 0; i < 4; i++ )
|
||||
{
|
||||
int v = inputs[i];
|
||||
if ( v == 0 )
|
||||
Vec_IntPush( vLeavesTemp, 0 ); // constant 0
|
||||
else if ( v == 1 )
|
||||
Vec_IntPush( vLeavesTemp, 1 ); // constant 1
|
||||
else if ( v >= 2 && v < 2 + Vec_IntSize(vLeaves) )
|
||||
Vec_IntPush( vLeavesTemp, Vec_IntEntry(vLeaves, v - 2) ); // leaf (v-2)
|
||||
else
|
||||
assert( 0 ); // Invalid value
|
||||
}
|
||||
word Truth1 = ((word)pConfigData[7] << 8) | pConfigData[6];
|
||||
Truth1 = Abc_Tt6Stretch( Truth1, 4 );
|
||||
extern int Kit_TruthToGia( Gia_Man_t * pMan, unsigned * pTruth, int nVars, Vec_Int_t * vMemory, Vec_Int_t * vLeaves, int fHash );
|
||||
iObjLit1 = Kit_TruthToGia( pNew, (unsigned *)&Truth1, Vec_IntSize(vLeavesTemp), vCover, vLeavesTemp, 1 );
|
||||
// Second LUT4 (inputs 4-7)
|
||||
Vec_IntClear( vLeavesTemp );
|
||||
for ( i = 4; i < 8; i++ )
|
||||
{
|
||||
int v = inputs[i];
|
||||
if ( v == 0 )
|
||||
Vec_IntPush( vLeavesTemp, 0 ); // constant 0
|
||||
else if ( v == 1 )
|
||||
Vec_IntPush( vLeavesTemp, 1 ); // constant 1
|
||||
else if ( v >= 2 && v < 2 + Vec_IntSize(vLeaves) )
|
||||
Vec_IntPush( vLeavesTemp, Vec_IntEntry(vLeaves, v - 2) ); // leaf (v-2)
|
||||
else
|
||||
assert( 0 ); // Invalid value
|
||||
}
|
||||
word Truth2 = ((word)pConfigData[9] << 8) | pConfigData[8];
|
||||
Truth2 = Abc_Tt6Stretch( Truth2, 4 );
|
||||
iObjLit2 = Kit_TruthToGia( pNew, (unsigned *)&Truth2, Vec_IntSize(vLeavesTemp), vCover, vLeavesTemp, 1 );
|
||||
// MUX (select is input 8) - structural implementation
|
||||
int iSelectLit;
|
||||
int v = inputs[8];
|
||||
if ( v == 0 )
|
||||
iSelectLit = 0; // constant 0 select
|
||||
else if ( v == 1 )
|
||||
iSelectLit = 1; // constant 1 select (unlikely for select)
|
||||
else if ( v >= 2 && v < 2 + Vec_IntSize(vLeaves) )
|
||||
iSelectLit = Vec_IntEntry(vLeaves, v - 2); // select from leaf (v-2)
|
||||
else
|
||||
assert( 0 ); // Invalid value
|
||||
iObjLit3 = Gia_ManHashMux( pNew, iSelectLit, iObjLit2, iObjLit1 );
|
||||
Gia_ManObj(p, iLut)->Value = iObjLit3;
|
||||
Vec_IntFree( vLeavesTemp );
|
||||
bytePos += 12; // 1 byte CellId + 5 bytes mapping + 4 bytes truth tables + 2 padding
|
||||
}
|
||||
else
|
||||
{
|
||||
assert( 0 ); // Unknown cell type
|
||||
}
|
||||
Count++;
|
||||
}
|
||||
|
||||
Gia_ManForEachCo( p, pObj, i )
|
||||
pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
|
||||
Gia_ManHashStop( pNew );
|
||||
Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) );
|
||||
Vec_IntFree( vLeaves );
|
||||
Vec_IntFree( vCover );
|
||||
// perform cleanup
|
||||
pNew = Gia_ManCleanup( pTemp = pNew );
|
||||
Gia_ManStop( pTemp );
|
||||
return pNew;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Derive truth table given the configulation values.]
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ SRC += src/map/if/ifCom.c \
|
|||
src/map/if/ifDec16.c \
|
||||
src/map/if/ifDec66.c \
|
||||
src/map/if/ifDec75.c \
|
||||
src/map/if/ifDecJ.c \
|
||||
src/map/if/ifDelay.c \
|
||||
src/map/if/ifDsd.c \
|
||||
src/map/if/ifLibBox.c \
|
||||
|
|
|
|||
|
|
@ -249,14 +249,14 @@ void * Mpm_ManFromIfLogic( Mpm_Man_t * pMan )
|
|||
if ( pMan->pPars->fDeriveLuts && (pMan->pPars->fUseTruth || pMan->pPars->fUseDsd) )
|
||||
{
|
||||
extern int Gia_ManFromIfLogicNode( void * p, Gia_Man_t * pNew, int iObj, Vec_Int_t * vLeaves, Vec_Int_t * vLeavesTemp,
|
||||
word * pRes, char * pStr, Vec_Int_t * vCover, Vec_Int_t * vMapping, Vec_Int_t * vMapping2, Vec_Int_t * vPacking, int fCheck75, int fCheck44e );
|
||||
word * pRes, char * pStr, Vec_Int_t * vCover, Vec_Int_t * vMapping, Vec_Int_t * vMapping2, Vec_Int_t * vPacking, int fCheck75 );
|
||||
if ( pMan->pPars->fUseTruth )
|
||||
pTruth = Mpm_CutTruth(pMan, Abc_Lit2Var(pCutBest->iFunc));
|
||||
else
|
||||
uTruth = Mpm_CutTruthFromDsd( pMan, pCutBest, Abc_Lit2Var(pCutBest->iFunc) );
|
||||
// Kit_DsdPrintFromTruth( pTruth, Vec_IntSize(vLeaves) ); printf( "\n" );
|
||||
// perform decomposition of the cut
|
||||
iLitNew = Gia_ManFromIfLogicNode( NULL, pNew, Mig_ObjId(pObj), vLeaves, vLeaves2, pTruth, NULL, vCover, vMapping, vMapping2, vPacking, 0, 0 );
|
||||
iLitNew = Gia_ManFromIfLogicNode( NULL, pNew, Mig_ObjId(pObj), vLeaves, vLeaves2, pTruth, NULL, vCover, vMapping, vMapping2, vPacking, 0 );
|
||||
iLitNew = Abc_LitNotCond( iLitNew, pCutBest->fCompl ^ Abc_LitIsCompl(pCutBest->iFunc) );
|
||||
}
|
||||
else
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
***********************************************************************/
|
||||
|
||||
#include "mpmInt.h"
|
||||
#include "base/main/main.h"
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
|
|
@ -55,8 +56,8 @@ Mpm_Man_t * Mpm_ManStart( Mig_Man_t * pMig, Mpm_Par_t * pPars )
|
|||
p = ABC_CALLOC( Mpm_Man_t, 1 );
|
||||
p->pMig = pMig;
|
||||
p->pPars = pPars;
|
||||
p->pLibLut = pPars->pLib;
|
||||
p->nLutSize = pPars->pLib->LutMax;
|
||||
p->pLibLut = (Mpm_LibLut_t *)Abc_FrameReadLibLut();
|
||||
p->nLutSize = p->pLibLut->LutMax;
|
||||
p->nTruWords = pPars->fUseTruth ? Abc_Truth6WordNum(p->nLutSize) : 0;
|
||||
p->nNumCuts = pPars->nNumCuts;
|
||||
// cuts
|
||||
|
|
|
|||
|
|
@ -451,19 +451,31 @@ void Tim_ManCreate( Tim_Man_t * p, void * pLib, Vec_Flt_t * vInArrs, Vec_Flt_t *
|
|||
// create arrival times
|
||||
if ( vInArrs )
|
||||
{
|
||||
assert( Vec_FltSize(vInArrs) == Tim_ManPiNum(p) );
|
||||
Tim_ManForEachPi( p, pObj, i )
|
||||
pObj->timeArr = Vec_FltEntry(vInArrs, i);
|
||||
|
||||
if ( Vec_FltSize(vInArrs) == Tim_ManPiNum(p) ) {
|
||||
Tim_ManForEachPi( p, pObj, i )
|
||||
pObj->timeArr = Vec_FltEntry(vInArrs, i);
|
||||
}
|
||||
else if ( Vec_FltSize(vInArrs) == Tim_ManCiNum(p) ) {
|
||||
Tim_ManForEachCi( p, pObj, i )
|
||||
pObj->timeArr = Vec_FltEntry(vInArrs, i);
|
||||
}
|
||||
else assert( 0 );
|
||||
}
|
||||
// create required times
|
||||
if ( vOutReqs )
|
||||
{
|
||||
k = 0;
|
||||
assert( Vec_FltSize(vOutReqs) == Tim_ManPoNum(p) );
|
||||
Tim_ManForEachPo( p, pObj, i )
|
||||
pObj->timeReq = Vec_FltEntry(vOutReqs, k++);
|
||||
assert( k == Tim_ManPoNum(p) );
|
||||
if ( Vec_FltSize(vOutReqs) == Tim_ManPoNum(p) ) {
|
||||
Tim_ManForEachPo( p, pObj, i )
|
||||
pObj->timeReq = Vec_FltEntry(vOutReqs, k++);
|
||||
assert( k == Tim_ManPoNum(p) );
|
||||
}
|
||||
else if ( Vec_FltSize(vOutReqs) == Tim_ManCoNum(p) ) {
|
||||
Tim_ManForEachCo( p, pObj, i )
|
||||
pObj->timeReq = Vec_FltEntry(vOutReqs, k++);
|
||||
assert( k == Tim_ManCoNum(p) );
|
||||
}
|
||||
else assert( 0 );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ SRC += src/misc/util/utilBridge.c \
|
|||
src/misc/util/utilColor.c \
|
||||
src/misc/util/utilFile.c \
|
||||
src/misc/util/utilIsop.c \
|
||||
src/misc/util/utilLinear.c \
|
||||
src/misc/util/utilNam.c \
|
||||
src/misc/util/utilPrefix.cpp \
|
||||
src/misc/util/utilPth.c \
|
||||
|
|
|
|||
|
|
@ -0,0 +1,821 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [utilLinear.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Handling counter-examples.]
|
||||
|
||||
Synopsis [Handling counter-examples.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: utilColor.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
//#define _POSIX_C_SOURCE 200809L
|
||||
|
||||
#include <errno.h>
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "misc/util/abc_global.h"
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define EPSILON 1e-12
|
||||
#define VERIFY_TOLERANCE 1e-9
|
||||
#define INTEGER_TOLERANCE 1e-9
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Reads a full line from the file, allocating memory dynamically.
|
||||
static char *read_line(FILE *fp) {
|
||||
size_t capacity = 128;
|
||||
size_t length = 0;
|
||||
char *buffer = (char *)malloc(capacity);
|
||||
if (!buffer) {
|
||||
errno = ENOMEM;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int ch;
|
||||
while ((ch = fgetc(fp)) != EOF) {
|
||||
if (ch == '\r') {
|
||||
continue;
|
||||
}
|
||||
if (ch == '\n') {
|
||||
break;
|
||||
}
|
||||
if (length + 1 >= capacity) {
|
||||
size_t new_capacity = capacity * 2;
|
||||
char *tmp = (char *)realloc(buffer, new_capacity);
|
||||
if (!tmp) {
|
||||
free(buffer);
|
||||
errno = ENOMEM;
|
||||
return NULL;
|
||||
}
|
||||
buffer = tmp;
|
||||
capacity = new_capacity;
|
||||
}
|
||||
buffer[length++] = (char)ch;
|
||||
}
|
||||
|
||||
if (length == 0 && ch == EOF) {
|
||||
free(buffer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
buffer[length] = '\0';
|
||||
return buffer;
|
||||
}
|
||||
|
||||
// Loads the augmented matrix from a text file.
|
||||
static int load_augmented_matrix(const char *path, double **outMatrix, int *outEqus, int *outVars) {
|
||||
FILE *fp = fopen(path, "r");
|
||||
if (!fp) {
|
||||
perror("fopen");
|
||||
return 0;
|
||||
}
|
||||
|
||||
double *data = NULL;
|
||||
size_t capacity = 0;
|
||||
size_t count = 0;
|
||||
int row_width = -1;
|
||||
int rows = 0;
|
||||
|
||||
while (1) {
|
||||
char *line = read_line(fp);
|
||||
if (!line) {
|
||||
if (feof(fp)) {
|
||||
break;
|
||||
}
|
||||
fprintf(stderr, "Failed to read line from input file.\n");
|
||||
free(data);
|
||||
fclose(fp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
char *ptr = line;
|
||||
int columns = 0;
|
||||
while (*ptr != '\0') {
|
||||
char *end_ptr;
|
||||
double value = strtod(ptr, &end_ptr);
|
||||
if (end_ptr == ptr) {
|
||||
if (*ptr == '\0') {
|
||||
break;
|
||||
}
|
||||
++ptr;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (count == capacity) {
|
||||
size_t new_capacity = capacity == 0 ? 64 : capacity * 2;
|
||||
double *tmp = (double *)realloc(data, new_capacity * sizeof(double));
|
||||
if (!tmp) {
|
||||
fprintf(stderr, "Out of memory while loading matrix.\n");
|
||||
free(data);
|
||||
free(line);
|
||||
fclose(fp);
|
||||
return 0;
|
||||
}
|
||||
data = tmp;
|
||||
capacity = new_capacity;
|
||||
}
|
||||
|
||||
data[count++] = value;
|
||||
++columns;
|
||||
ptr = end_ptr;
|
||||
}
|
||||
|
||||
free(line);
|
||||
|
||||
if (columns == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (row_width == -1) {
|
||||
row_width = columns;
|
||||
} else if (columns != row_width) {
|
||||
fprintf(stderr, "Row %d has %d entries, expected %d.\n", rows + 1, columns, row_width);
|
||||
free(data);
|
||||
fclose(fp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
++rows;
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
|
||||
if (rows == 0) {
|
||||
fprintf(stderr, "Input file is empty or contains no data rows.\n");
|
||||
free(data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (row_width <= 1) {
|
||||
fprintf(stderr, "Each row must contain at least two numbers.\n");
|
||||
free(data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((size_t)rows * (size_t)row_width != count) {
|
||||
fprintf(stderr, "Internal error: unexpected data size.\n");
|
||||
free(data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
*outMatrix = data;
|
||||
*outEqus = rows;
|
||||
*outVars = row_width - 1;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Swaps two rows in-place.
|
||||
static void swap_rows(double *matrix, int cols, int row_a, int row_b) {
|
||||
if (row_a == row_b) {
|
||||
return;
|
||||
}
|
||||
for (int c = 0; c < cols; ++c) {
|
||||
double tmp = matrix[row_a * cols + c];
|
||||
matrix[row_a * cols + c] = matrix[row_b * cols + c];
|
||||
matrix[row_b * cols + c] = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
// Clears values that are numerically close to zero.
|
||||
static void prune_small_values(double *row, int count) {
|
||||
for (int i = 0; i < count; ++i) {
|
||||
if (fabs(row[i]) < EPSILON) {
|
||||
row[i] = 0.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Computes a solution vector given assignments for the free variables.
|
||||
static void compute_solution_from_free(
|
||||
const double *rref,
|
||||
int nVars,
|
||||
const int *pivot_cols,
|
||||
int rank,
|
||||
const int *free_cols,
|
||||
int free_count,
|
||||
const double *free_values,
|
||||
double *solution_out) {
|
||||
int row_len = nVars + 1;
|
||||
|
||||
for (int i = 0; i < nVars; ++i) {
|
||||
solution_out[i] = 0.0;
|
||||
}
|
||||
|
||||
for (int i = 0; i < free_count; ++i) {
|
||||
int col = free_cols[i];
|
||||
double value = free_values ? free_values[i] : 0.0;
|
||||
solution_out[col] = value;
|
||||
}
|
||||
|
||||
for (int r = 0; r < rank; ++r) {
|
||||
int pivot_col = pivot_cols[r];
|
||||
double value = rref[r * row_len + nVars];
|
||||
for (int j = 0; j < free_count; ++j) {
|
||||
int free_col = free_cols[j];
|
||||
value -= rref[r * row_len + free_col] * solution_out[free_col];
|
||||
}
|
||||
solution_out[pivot_col] = value;
|
||||
}
|
||||
}
|
||||
|
||||
// Verifies that the solution satisfies the original system.
|
||||
static int verify_solution(
|
||||
const double *matrix,
|
||||
int nEqus,
|
||||
int nVars,
|
||||
const double *solution,
|
||||
double tolerance,
|
||||
double *out_max_residual) {
|
||||
int row_len = nVars + 1;
|
||||
double max_residual = 0.0;
|
||||
int ok = 1;
|
||||
|
||||
for (int r = 0; r < nEqus; ++r) {
|
||||
double lhs = 0.0;
|
||||
for (int c = 0; c < nVars; ++c) {
|
||||
lhs += (double)matrix[r * row_len + c] * (double)solution[c];
|
||||
}
|
||||
double rhs = matrix[r * row_len + nVars];
|
||||
double residual = fabs(lhs - rhs);
|
||||
if ((double)residual > max_residual) {
|
||||
max_residual = (double)residual;
|
||||
}
|
||||
if ((double)residual > tolerance) {
|
||||
ok = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (out_max_residual) {
|
||||
*out_max_residual = max_residual;
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
// Checks whether a particular free-variable assignment yields an integer solution.
|
||||
// Optionally enforces that the first two variables differ once rounded to integers.
|
||||
static int assign_and_check_integer(
|
||||
const double *rref,
|
||||
int nVars,
|
||||
const int *pivot_cols,
|
||||
int rank,
|
||||
const int *free_cols,
|
||||
int free_count,
|
||||
const double *free_values,
|
||||
const double *original_matrix,
|
||||
int nEqus,
|
||||
double verify_tolerance,
|
||||
double *workspace,
|
||||
double *rounded,
|
||||
double *out_solution,
|
||||
int require_nonzero,
|
||||
int require_distinct_first_two) {
|
||||
compute_solution_from_free(
|
||||
rref,
|
||||
nVars,
|
||||
pivot_cols,
|
||||
rank,
|
||||
free_cols,
|
||||
free_count,
|
||||
free_values,
|
||||
workspace);
|
||||
|
||||
for (int i = 0; i < nVars; ++i) {
|
||||
double candidate = workspace[i];
|
||||
double nearest = round(candidate);
|
||||
if (fabs(candidate - nearest) > INTEGER_TOLERANCE) {
|
||||
return 0;
|
||||
}
|
||||
rounded[i] = nearest;
|
||||
}
|
||||
|
||||
int all_zero = 1;
|
||||
int has_zero_component = 0;
|
||||
int has_positive_component = 0;
|
||||
int has_negative_component = 0;
|
||||
for (int i = 0; i < nVars; ++i) {
|
||||
if (rounded[i] != 0.0) {
|
||||
all_zero = 0;
|
||||
} else {
|
||||
has_zero_component = 1;
|
||||
}
|
||||
if (rounded[i] > 0.0) {
|
||||
has_positive_component = 1;
|
||||
} else if (rounded[i] < 0.0) {
|
||||
has_negative_component = 1;
|
||||
}
|
||||
}
|
||||
if (require_nonzero) {
|
||||
if (all_zero || has_negative_component || !has_positive_component || !has_zero_component) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (require_distinct_first_two && nVars >= 2) {
|
||||
if (fabs(rounded[0] - rounded[1]) < INTEGER_TOLERANCE) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (verify_solution(original_matrix, nEqus, nVars, rounded, verify_tolerance, NULL)) {
|
||||
memcpy(out_solution, rounded, (size_t)nVars * sizeof(double));
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Recursively explores integer assignments for free variables while propagating optional constraints.
|
||||
static int search_integer_solutions(
|
||||
int depth,
|
||||
int free_count,
|
||||
double *free_values,
|
||||
const int *candidates,
|
||||
int candidate_count,
|
||||
const double *rref,
|
||||
int nEqus,
|
||||
int nVars,
|
||||
const int *pivot_cols,
|
||||
int rank,
|
||||
const int *free_cols,
|
||||
const double *original_matrix,
|
||||
double verify_tolerance,
|
||||
double *workspace,
|
||||
double *rounded,
|
||||
double *out_solution,
|
||||
int require_nonzero,
|
||||
int require_distinct_first_two,
|
||||
int *explored,
|
||||
int exploration_limit) {
|
||||
if (*explored >= exploration_limit) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (depth == free_count) {
|
||||
(*explored)++;
|
||||
return assign_and_check_integer(
|
||||
rref,
|
||||
nVars,
|
||||
pivot_cols,
|
||||
rank,
|
||||
free_cols,
|
||||
free_count,
|
||||
free_values,
|
||||
original_matrix,
|
||||
nEqus,
|
||||
verify_tolerance,
|
||||
workspace,
|
||||
rounded,
|
||||
out_solution,
|
||||
require_nonzero,
|
||||
require_distinct_first_two);
|
||||
}
|
||||
|
||||
for (int i = 0; i < candidate_count; ++i) {
|
||||
free_values[depth] = (double)candidates[i];
|
||||
if (search_integer_solutions(
|
||||
depth + 1,
|
||||
free_count,
|
||||
free_values,
|
||||
candidates,
|
||||
candidate_count,
|
||||
rref,
|
||||
nEqus,
|
||||
nVars,
|
||||
pivot_cols,
|
||||
rank,
|
||||
free_cols,
|
||||
original_matrix,
|
||||
verify_tolerance,
|
||||
workspace,
|
||||
rounded,
|
||||
out_solution,
|
||||
require_nonzero,
|
||||
require_distinct_first_two,
|
||||
explored,
|
||||
exploration_limit)) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Attempts to locate an integer solution when free variables are present.
|
||||
// Searches a small integer lattice and enforces optional constraints such as distinct first variables.
|
||||
static int try_integer_solution(
|
||||
const double *rref,
|
||||
int nEqus,
|
||||
int nVars,
|
||||
const int *pivot_cols,
|
||||
int rank,
|
||||
const int *free_cols,
|
||||
int free_count,
|
||||
const double *original_matrix,
|
||||
double verify_tolerance,
|
||||
double *workspace,
|
||||
double *rounded,
|
||||
double *out_solution,
|
||||
int require_nonzero,
|
||||
int require_distinct_first_two) {
|
||||
if (free_count == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Expand search radius to allow moderately sized integer assignments (up to |20|).
|
||||
const int candidates[] = {
|
||||
0,
|
||||
1, -1,
|
||||
2, -2,
|
||||
3, -3,
|
||||
4, -4,
|
||||
5, -5,
|
||||
6, -6,
|
||||
7, -7,
|
||||
8, -8,
|
||||
9, -9,
|
||||
10, -10,
|
||||
11, -11,
|
||||
12, -12,
|
||||
13, -13,
|
||||
14, -14,
|
||||
15, -15,
|
||||
16, -16,
|
||||
17, -17,
|
||||
18, -18,
|
||||
19, -19,
|
||||
20, -20
|
||||
};
|
||||
const int candidate_count = (int)(sizeof(candidates) / sizeof(candidates[0]));
|
||||
int exploration_limit = 200000;
|
||||
int explored = 0;
|
||||
|
||||
double *free_values = (double *)malloc((size_t)free_count * sizeof(double));
|
||||
if (!free_values) {
|
||||
return 0;
|
||||
}
|
||||
for (int i = 0; i < free_count; ++i) {
|
||||
free_values[i] = 0.0;
|
||||
}
|
||||
|
||||
if (assign_and_check_integer(
|
||||
rref,
|
||||
nVars,
|
||||
pivot_cols,
|
||||
rank,
|
||||
free_cols,
|
||||
free_count,
|
||||
free_values,
|
||||
original_matrix,
|
||||
nEqus,
|
||||
verify_tolerance,
|
||||
workspace,
|
||||
rounded,
|
||||
out_solution,
|
||||
require_nonzero,
|
||||
require_distinct_first_two)) {
|
||||
free(free_values);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int found = search_integer_solutions(
|
||||
0,
|
||||
free_count,
|
||||
free_values,
|
||||
candidates,
|
||||
candidate_count,
|
||||
rref,
|
||||
nEqus,
|
||||
nVars,
|
||||
pivot_cols,
|
||||
rank,
|
||||
free_cols,
|
||||
original_matrix,
|
||||
verify_tolerance,
|
||||
workspace,
|
||||
rounded,
|
||||
out_solution,
|
||||
require_nonzero,
|
||||
require_distinct_first_two,
|
||||
&explored,
|
||||
exploration_limit);
|
||||
|
||||
free(free_values);
|
||||
return found;
|
||||
}
|
||||
|
||||
// Gaussian-elimination-based solver that optionally searches for integer solutions.
|
||||
double *linear_equation_solver(double *pMatrix, int nEqus, int nVars) {
|
||||
if (!pMatrix || nEqus <= 0 || nVars <= 0) {
|
||||
fprintf(stderr, "Invalid matrix dimensions provided to solver.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int row_len = nVars + 1;
|
||||
size_t matrix_bytes = (size_t)nEqus * (size_t)row_len * sizeof(double);
|
||||
|
||||
double *matrix_copy = NULL;
|
||||
double *solution = NULL;
|
||||
double *workspace = NULL;
|
||||
double *rounded = NULL;
|
||||
double *result = NULL;
|
||||
int *pivot_cols = NULL;
|
||||
int *pivot_column_used = NULL;
|
||||
int *free_cols = NULL;
|
||||
int free_count = 0;
|
||||
int homogeneous_rhs = 0;
|
||||
int require_nonzero_integer = 0;
|
||||
int require_distinct_first_two = 0;
|
||||
int pivot_row_index = 0;
|
||||
int rank = 0;
|
||||
double max_residual = 0.0;
|
||||
|
||||
matrix_copy = (double *)malloc(matrix_bytes);
|
||||
if (!matrix_copy) {
|
||||
fprintf(stderr, "Unable to allocate memory for solver workspace.\n");
|
||||
goto cleanup;
|
||||
}
|
||||
memcpy(matrix_copy, pMatrix, matrix_bytes);
|
||||
|
||||
pivot_cols = (int *)malloc((size_t)nEqus * sizeof(int));
|
||||
if (!pivot_cols) {
|
||||
fprintf(stderr, "Unable to allocate memory for pivot tracking.\n");
|
||||
goto cleanup;
|
||||
}
|
||||
for (int i = 0; i < nEqus; ++i) {
|
||||
pivot_cols[i] = -1;
|
||||
}
|
||||
|
||||
pivot_row_index = 0;
|
||||
for (int col = 0; col < nVars && pivot_row_index < nEqus; ++col) {
|
||||
int best_row = pivot_row_index;
|
||||
double max_value = fabs(matrix_copy[best_row * row_len + col]);
|
||||
for (int r = pivot_row_index + 1; r < nEqus; ++r) {
|
||||
double value = fabs(matrix_copy[r * row_len + col]);
|
||||
if (value > max_value) {
|
||||
max_value = value;
|
||||
best_row = r;
|
||||
}
|
||||
}
|
||||
|
||||
if (max_value < EPSILON) {
|
||||
continue;
|
||||
}
|
||||
|
||||
swap_rows(matrix_copy, row_len, pivot_row_index, best_row);
|
||||
|
||||
double pivot_value = matrix_copy[pivot_row_index * row_len + col];
|
||||
for (int c = 0; c < row_len; ++c) {
|
||||
matrix_copy[pivot_row_index * row_len + c] /= pivot_value;
|
||||
}
|
||||
matrix_copy[pivot_row_index * row_len + col] = 1.0;
|
||||
prune_small_values(&matrix_copy[pivot_row_index * row_len], row_len);
|
||||
|
||||
for (int r = 0; r < nEqus; ++r) {
|
||||
if (r == pivot_row_index) {
|
||||
continue;
|
||||
}
|
||||
double factor = matrix_copy[r * row_len + col];
|
||||
if (fabs(factor) < EPSILON) {
|
||||
continue;
|
||||
}
|
||||
for (int c = 0; c < row_len; ++c) {
|
||||
matrix_copy[r * row_len + c] -= factor * matrix_copy[pivot_row_index * row_len + c];
|
||||
}
|
||||
matrix_copy[r * row_len + col] = 0.0;
|
||||
prune_small_values(&matrix_copy[r * row_len], row_len);
|
||||
}
|
||||
|
||||
pivot_cols[pivot_row_index] = col;
|
||||
++pivot_row_index;
|
||||
}
|
||||
|
||||
rank = pivot_row_index;
|
||||
//printf("Rank: %d\n", rank);
|
||||
|
||||
for (int r = 0; r < nEqus; ++r) {
|
||||
int zero_row = 1;
|
||||
for (int c = 0; c < nVars; ++c) {
|
||||
if (fabs(matrix_copy[r * row_len + c]) > EPSILON) {
|
||||
zero_row = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (zero_row && fabs(matrix_copy[r * row_len + nVars]) > EPSILON) {
|
||||
printf("Verification: inconsistent system detected.\n");
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
pivot_column_used = (int *)calloc((size_t)nVars, sizeof(int));
|
||||
if (!pivot_column_used) {
|
||||
fprintf(stderr, "Unable to allocate memory for pivot metadata.\n");
|
||||
goto cleanup;
|
||||
}
|
||||
for (int r = 0; r < rank; ++r) {
|
||||
int col = pivot_cols[r];
|
||||
if (col >= 0 && col < nVars) {
|
||||
pivot_column_used[col] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
free_count = 0;
|
||||
for (int c = 0; c < nVars; ++c) {
|
||||
if (!pivot_column_used[c]) {
|
||||
++free_count;
|
||||
}
|
||||
}
|
||||
|
||||
if (free_count > 0) {
|
||||
free_cols = (int *)malloc((size_t)free_count * sizeof(int));
|
||||
if (!free_cols) {
|
||||
fprintf(stderr, "Unable to allocate memory for free column list.\n");
|
||||
goto cleanup;
|
||||
}
|
||||
int idx = 0;
|
||||
for (int c = 0; c < nVars; ++c) {
|
||||
if (!pivot_column_used[c]) {
|
||||
free_cols[idx++] = c;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
homogeneous_rhs = 1;
|
||||
for (int r = 0; r < nEqus; ++r) {
|
||||
if (fabs(pMatrix[r * row_len + nVars]) > EPSILON) {
|
||||
homogeneous_rhs = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Only demand integer solutions when the system is homogeneous with free variables.
|
||||
require_nonzero_integer = homogeneous_rhs && free_count > 0;
|
||||
// Enforce distinct first two variables whenever multiple variables remain free.
|
||||
require_distinct_first_two = (free_count > 0 && nVars >= 2);
|
||||
|
||||
solution = (double *)malloc((size_t)nVars * sizeof(double));
|
||||
workspace = (double *)malloc((size_t)nVars * sizeof(double));
|
||||
rounded = (double *)malloc((size_t)nVars * sizeof(double));
|
||||
if (!solution || !workspace || !rounded) {
|
||||
fprintf(stderr, "Unable to allocate solver buffers.\n");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (free_count == 0) {
|
||||
compute_solution_from_free(
|
||||
matrix_copy,
|
||||
nVars,
|
||||
pivot_cols,
|
||||
rank,
|
||||
free_cols,
|
||||
free_count,
|
||||
NULL,
|
||||
solution);
|
||||
} else {
|
||||
if (free_count >= 6) {
|
||||
printf("Warning: large nullspace (%d free variables); integer search radius +/-20 may be expensive.\n", free_count);
|
||||
}
|
||||
if (!try_integer_solution(
|
||||
matrix_copy,
|
||||
nEqus,
|
||||
nVars,
|
||||
pivot_cols,
|
||||
rank,
|
||||
free_cols,
|
||||
free_count,
|
||||
pMatrix,
|
||||
VERIFY_TOLERANCE,
|
||||
workspace,
|
||||
rounded,
|
||||
solution,
|
||||
require_nonzero_integer,
|
||||
require_distinct_first_two)) {
|
||||
for (int i = 0; i < free_count; ++i) {
|
||||
workspace[i] = 0.0;
|
||||
}
|
||||
compute_solution_from_free(
|
||||
matrix_copy,
|
||||
nVars,
|
||||
pivot_cols,
|
||||
rank,
|
||||
free_cols,
|
||||
free_count,
|
||||
workspace,
|
||||
solution);
|
||||
if (require_nonzero_integer && require_distinct_first_two) {
|
||||
printf("Note: integer solution meeting non-negative and distinct-first-two constraints not found; returning floating-point solution.\n");
|
||||
} else if (require_nonzero_integer) {
|
||||
printf("Note: non-negative integer solution with mixed zero/positive entries not found; returning floating-point solution.\n");
|
||||
} else if (require_distinct_first_two) {
|
||||
printf("Note: integer solution with distinct first two variables not found; returning floating-point solution.\n");
|
||||
} else {
|
||||
printf("Note: integer solution not found; returning floating-point solution.\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
max_residual = 0.0;
|
||||
if (!verify_solution(pMatrix, nEqus, nVars, solution, VERIFY_TOLERANCE, &max_residual)) {
|
||||
printf("Verification: failure (max residual = %.6f)\n", max_residual);
|
||||
goto cleanup;
|
||||
}
|
||||
//printf("Verification: success (max residual = %.6f)\n", max_residual);
|
||||
|
||||
result = solution;
|
||||
solution = NULL;
|
||||
|
||||
cleanup:
|
||||
free(matrix_copy);
|
||||
free(pivot_cols);
|
||||
free(pivot_column_used);
|
||||
free(free_cols);
|
||||
free(workspace);
|
||||
free(rounded);
|
||||
free(solution);
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
if (argc != 2) {
|
||||
fprintf(stderr, "Usage: %s <matrix_file>\n", argv[0]);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
double *matrix = NULL;
|
||||
int nEqus = 0;
|
||||
int nVars = 0;
|
||||
|
||||
if (!load_augmented_matrix(argv[1], &matrix, &nEqus, &nVars)) {
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
printf("Equations: %d, Variables: %d\n", nEqus, nVars);
|
||||
|
||||
struct timespec start_time;
|
||||
struct timespec end_time;
|
||||
if (clock_gettime(CLOCK_MONOTONIC, &start_time) != 0) {
|
||||
perror("clock_gettime");
|
||||
free(matrix);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
double *solution = linear_equation_solver(matrix, nEqus, nVars);
|
||||
|
||||
if (clock_gettime(CLOCK_MONOTONIC, &end_time) != 0) {
|
||||
perror("clock_gettime");
|
||||
free(matrix);
|
||||
free(solution);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (!solution) {
|
||||
free(matrix);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
double elapsed = (double)(end_time.tv_sec - start_time.tv_sec);
|
||||
elapsed += (double)(end_time.tv_nsec - start_time.tv_nsec) / 1e9;
|
||||
printf("Solve time: %.6f seconds\n", elapsed);
|
||||
|
||||
for (int i = 0; i < nVars; ++i) {
|
||||
printf("x%d = %.6f\n", i, solution[i]);
|
||||
}
|
||||
|
||||
free(matrix);
|
||||
free(solution);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
||||
|
|
@ -605,19 +605,23 @@ static inline int Exa_ManEval( Exa_Man_t * p )
|
|||
***********************************************************************/
|
||||
void Exa_ManDumpBlif( Exa_Man_t * p, int fCompl )
|
||||
{
|
||||
char Buffer[1000];
|
||||
char * pStr = ABC_ALLOC( char, (1 << (p->nVars-2)) + 10 );
|
||||
char FileName[1100];
|
||||
FILE * pFile;
|
||||
int i, k, iVar;
|
||||
if ( fCompl )
|
||||
Abc_TtNot( p->pTruth, p->nWords );
|
||||
Extra_PrintHexadecimalString( Buffer, (unsigned *)p->pTruth, p->nVars );
|
||||
Extra_PrintHexadecimalString( pStr, (unsigned *)p->pTruth, p->nVars );
|
||||
if ( strlen(pStr) > 16 ) {
|
||||
pStr[16] = '_';
|
||||
pStr[17] = '\0';
|
||||
}
|
||||
if ( fCompl )
|
||||
Abc_TtNot( p->pTruth, p->nWords );
|
||||
sprintf( FileName, "%s_%d_%d.blif", Buffer, 2, p->nNodes );
|
||||
sprintf( FileName, "%s_%d_%d.blif", pStr, 2, p->nNodes );
|
||||
pFile = fopen( FileName, "wb" );
|
||||
fprintf( pFile, "# Realization of the %d-input function %s using %d two-input gates:\n", p->nVars, Buffer, p->nNodes );
|
||||
fprintf( pFile, ".model %s_%d_%d\n", Buffer, 2, p->nNodes );
|
||||
fprintf( pFile, "# Realization of the %d-input function %s using %d two-input gates:\n", p->nVars, pStr, p->nNodes );
|
||||
fprintf( pFile, ".model %s_%d_%d\n", pStr, 2, p->nNodes );
|
||||
fprintf( pFile, ".inputs" );
|
||||
for ( i = 0; i < p->nVars; i++ )
|
||||
fprintf( pFile, " %c", 'a'+i );
|
||||
|
|
@ -655,6 +659,7 @@ void Exa_ManDumpBlif( Exa_Man_t * p, int fCompl )
|
|||
fprintf( pFile, ".end\n\n" );
|
||||
fclose( pFile );
|
||||
printf( "Solution was dumped into file \"%s\".\n", FileName );
|
||||
ABC_FREE( pStr );
|
||||
}
|
||||
void Exa_ManPrintSolution( Exa_Man_t * p, int fCompl )
|
||||
{
|
||||
|
|
@ -942,8 +947,8 @@ void Exa_ManExactSynthesis( Bmc_EsPar_t * pPars )
|
|||
int i, status, iMint = 1;
|
||||
abctime clkTotal = Abc_Clock();
|
||||
Exa_Man_t * p; int fCompl = 0;
|
||||
word pTruth[16]; Abc_TtReadHex( pTruth, pPars->pTtStr );
|
||||
assert( pPars->nVars <= 10 );
|
||||
word pTruth[64]; Abc_TtReadHex( pTruth, pPars->pTtStr );
|
||||
assert( pPars->nVars <= 12 );
|
||||
p = Exa_ManAlloc( pPars, pTruth );
|
||||
if ( pTruth[0] & 1 ) { fCompl = 1; Abc_TtNot( pTruth, p->nWords ); }
|
||||
status = Exa_ManAddCnfStart( p, pPars->fOnlyAnd );
|
||||
|
|
@ -1327,11 +1332,16 @@ static void Exa3_ManDumpBlif( Exa3_Man_t * p, int fCompl )
|
|||
{
|
||||
int i, k, b, iVar;
|
||||
char pFileName[1000];
|
||||
sprintf( pFileName, "%s.blif", p->pPars->pTtStr );
|
||||
char * pStr = Abc_UtilStrsav(p->pPars->pTtStr);
|
||||
if ( strlen(pStr) > 16 ) {
|
||||
pStr[16] = '_';
|
||||
pStr[17] = '\0';
|
||||
}
|
||||
sprintf( pFileName, "%s.blif", pStr );
|
||||
FILE * pFile = fopen( pFileName, "wb" );
|
||||
if ( pFile == NULL ) return;
|
||||
fprintf( pFile, "# Realization of given %d-input function using %d %d-input LUTs synthesized by ABC on %s\n", p->nVars, p->nNodes, p->nLutSize, Extra_TimeStamp() );
|
||||
fprintf( pFile, ".model %s\n", p->pPars->pTtStr );
|
||||
fprintf( pFile, ".model %s\n", pStr );
|
||||
fprintf( pFile, ".inputs" );
|
||||
for ( k = 0; k < p->nVars; k++ )
|
||||
fprintf( pFile, " %c", 'a'+k );
|
||||
|
|
@ -1365,6 +1375,7 @@ static void Exa3_ManDumpBlif( Exa3_Man_t * p, int fCompl )
|
|||
fprintf( pFile, ".end\n\n" );
|
||||
fclose( pFile );
|
||||
printf( "Finished dumping the resulting LUT network into file \"%s\".\n", pFileName );
|
||||
ABC_FREE( pStr );
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1600,7 +1611,7 @@ int Exa3_ManExactSynthesis( Bmc_EsPar_t * pPars )
|
|||
int i, status, Res = 0, iMint = 1;
|
||||
abctime clkTotal = Abc_Clock();
|
||||
Exa3_Man_t * p; int fCompl = 0;
|
||||
word pTruth[16];
|
||||
word pTruth[64];
|
||||
if ( pPars->pSymStr ) {
|
||||
word * pFun = Abc_TtSymFunGenerate( pPars->pSymStr, pPars->nVars );
|
||||
pPars->pTtStr = ABC_CALLOC( char, pPars->nVars > 2 ? (1 << (pPars->nVars-2)) + 1 : 2 );
|
||||
|
|
@ -1611,7 +1622,7 @@ int Exa3_ManExactSynthesis( Bmc_EsPar_t * pPars )
|
|||
if ( pPars->pTtStr )
|
||||
Abc_TtReadHex( pTruth, pPars->pTtStr );
|
||||
else assert( 0 );
|
||||
assert( pPars->nVars <= 10 );
|
||||
assert( pPars->nVars <= 12 );
|
||||
assert( pPars->nLutSize <= 6 );
|
||||
p = Exa3_ManAlloc( pPars, pTruth );
|
||||
if ( pTruth[0] & 1 ) { fCompl = 1; Abc_TtNot( pTruth, p->nWords ); }
|
||||
|
|
@ -2491,9 +2502,9 @@ void Exa_ManExactSynthesis4( Bmc_EsPar_t * pPars )
|
|||
int i, m, nMints = 1 << pPars->nVars, fCompl = 0;
|
||||
Vec_Wrd_t * vSimsIn = Vec_WrdStart( nMints );
|
||||
Vec_Wrd_t * vSimsOut = Vec_WrdStart( nMints );
|
||||
word pTruth[16]; Abc_TtReadHex( pTruth, pPars->pTtStr );
|
||||
word pTruth[64]; Abc_TtReadHex( pTruth, pPars->pTtStr );
|
||||
if ( pTruth[0] & 1 ) { fCompl = 1; Abc_TtNot( pTruth, Abc_TtWordNum(pPars->nVars) ); }
|
||||
assert( pPars->nVars <= 10 );
|
||||
assert( pPars->nVars <= 12 );
|
||||
for ( m = 0; m < nMints; m++ )
|
||||
{
|
||||
Abc_TtSetBit( Vec_WrdEntryP(vSimsOut, m), Abc_TtGetBit(pTruth, m) );
|
||||
|
|
@ -2995,9 +3006,9 @@ void Exa_ManExactSynthesis5( Bmc_EsPar_t * pPars )
|
|||
int i, m, nMints = 1 << pPars->nVars, fCompl = 0;
|
||||
Vec_Wrd_t * vSimsIn = Vec_WrdStart( nMints );
|
||||
Vec_Wrd_t * vSimsOut = Vec_WrdStart( nMints );
|
||||
word pTruth[16]; Abc_TtReadHex( pTruth, pPars->pTtStr );
|
||||
word pTruth[64]; Abc_TtReadHex( pTruth, pPars->pTtStr );
|
||||
if ( pTruth[0] & 1 ) { fCompl = 1; Abc_TtNot( pTruth, Abc_TtWordNum(pPars->nVars) ); }
|
||||
assert( pPars->nVars <= 10 );
|
||||
assert( pPars->nVars <= 12 );
|
||||
for ( m = 0; m < nMints; m++ )
|
||||
{
|
||||
Abc_TtSetBit( Vec_WrdEntryP(vSimsOut, m), Abc_TtGetBit(pTruth, m) );
|
||||
|
|
@ -3102,7 +3113,7 @@ word Exa_ManExactSynthesis4VarsOne( int Index, int Truth, int nNodes )
|
|||
int i, m, nMints = 16, fCompl = 0;
|
||||
Vec_Wrd_t * vSimsIn = Vec_WrdStart( nMints );
|
||||
Vec_Wrd_t * vSimsOut = Vec_WrdStart( nMints );
|
||||
word pTruth[16] = { Abc_Tt6Stretch((word)Truth, 4) };
|
||||
word pTruth[64] = { Abc_Tt6Stretch((word)Truth, 4) };
|
||||
if ( pTruth[0] & 1 ) { fCompl = 1; Abc_TtNot( pTruth, 1 ); }
|
||||
for ( m = 0; m < nMints; m++ )
|
||||
{
|
||||
|
|
@ -4189,7 +4200,7 @@ void Exa_ManExactSynthesis7( Bmc_EsPar_t * pPars, int GateSize )
|
|||
abctime clkTotal = Abc_Clock();
|
||||
int v, n, nMints = 1 << pPars->nVars;
|
||||
int nV = pPars->nVars + pPars->nNodes;
|
||||
word pTruth[16]; Abc_TtReadHex( pTruth, pPars->pTtStr );
|
||||
word pTruth[64]; Abc_TtReadHex( pTruth, pPars->pTtStr );
|
||||
Vec_Int_t * vValues = NULL;
|
||||
int Rand = ((((unsigned)rand()) << 12) ^ ((unsigned)rand())) & 0xFFFFF;
|
||||
char pFileNameIn[32]; sprintf( pFileNameIn, "_%05x_.cnf", Rand );
|
||||
|
|
|
|||
|
|
@ -854,8 +854,8 @@ void Exa_ManExactSynthesis2( Bmc_EsPar_t * pPars )
|
|||
int i, status, iMint = 1;
|
||||
abctime clkTotal = Abc_Clock();
|
||||
Exa_Man_t * p; int fCompl = 0;
|
||||
word pTruth[16]; Abc_TtReadHex( pTruth, pPars->pTtStr );
|
||||
assert( pPars->nVars <= 10 );
|
||||
word pTruth[64]; Abc_TtReadHex( pTruth, pPars->pTtStr );
|
||||
assert( pPars->nVars <= 12 );
|
||||
p = Exa_ManAlloc( pPars, pTruth );
|
||||
if ( pTruth[0] & 1 ) { fCompl = 1; Abc_TtNot( pTruth, p->nWords ); }
|
||||
status = Exa_ManAddCnfStart( p, pPars->fOnlyAnd );
|
||||
|
|
@ -1191,11 +1191,16 @@ static void Exa3_ManDumpBlif( Exa3_Man_t * p, int fCompl )
|
|||
{
|
||||
int i, k, b, iVar;
|
||||
char pFileName[1000];
|
||||
sprintf( pFileName, "%s.blif", p->pPars->pTtStr );
|
||||
char * pStr = Abc_UtilStrsav(p->pPars->pTtStr);
|
||||
if ( strlen(pStr) > 16 ) {
|
||||
pStr[16] = '_';
|
||||
pStr[17] = '\0';
|
||||
}
|
||||
sprintf( pFileName, "%s.blif", pStr );
|
||||
FILE * pFile = fopen( pFileName, "wb" );
|
||||
if ( pFile == NULL ) return;
|
||||
fprintf( pFile, "# Realization of given %d-input function using %d %d-input LUTs synthesized by ABC on %s\n", p->nVars, p->nNodes, p->nLutSize, Extra_TimeStamp() );
|
||||
fprintf( pFile, ".model %s\n", p->pPars->pTtStr );
|
||||
fprintf( pFile, ".model %s\n", pStr );
|
||||
fprintf( pFile, ".inputs" );
|
||||
for ( k = 0; k < p->nVars; k++ )
|
||||
fprintf( pFile, " %c", 'a'+k );
|
||||
|
|
@ -1229,6 +1234,7 @@ static void Exa3_ManDumpBlif( Exa3_Man_t * p, int fCompl )
|
|||
fprintf( pFile, ".end\n\n" );
|
||||
fclose( pFile );
|
||||
printf( "Finished dumping the resulting LUT network into file \"%s\".\n", pFileName );
|
||||
ABC_FREE( pStr );
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1387,7 +1393,7 @@ void Exa3_ManExactSynthesis2( Bmc_EsPar_t * pPars )
|
|||
int i, status, iMint = 1;
|
||||
abctime clkTotal = Abc_Clock();
|
||||
Exa3_Man_t * p; int fCompl = 0;
|
||||
word pTruth[16];
|
||||
word pTruth[64];
|
||||
if ( pPars->pSymStr ) {
|
||||
word * pFun = Abc_TtSymFunGenerate( pPars->pSymStr, pPars->nVars );
|
||||
pPars->pTtStr = ABC_CALLOC( char, pPars->nVars > 2 ? (1 << (pPars->nVars-2)) + 1 : 2 );
|
||||
|
|
@ -1398,13 +1404,15 @@ void Exa3_ManExactSynthesis2( Bmc_EsPar_t * pPars )
|
|||
if ( pPars->pTtStr )
|
||||
Abc_TtReadHex( pTruth, pPars->pTtStr );
|
||||
else assert( 0 );
|
||||
assert( pPars->nVars <= 10 );
|
||||
assert( pPars->nVars <= 12 );
|
||||
assert( pPars->nLutSize <= 6 );
|
||||
p = Exa3_ManAlloc( pPars, pTruth );
|
||||
if ( pTruth[0] & 1 ) { fCompl = 1; Abc_TtNot( pTruth, p->nWords ); }
|
||||
status = Exa3_ManAddCnfStart( p, pPars->fOnlyAnd );
|
||||
assert( status );
|
||||
printf( "Running exact synthesis for %d-input function with %d %d-input LUTs...\n", p->nVars, p->nNodes, p->nLutSize );
|
||||
abctime nTimeToStop = pPars->RuntimeLim ? pPars->RuntimeLim * CLOCKS_PER_SEC + Abc_Clock(): 0;
|
||||
sat_solver_set_runtime_limit( p->pSat, nTimeToStop );
|
||||
for ( i = 0; iMint != -1; i++ )
|
||||
{
|
||||
abctime clk = Abc_Clock();
|
||||
|
|
@ -1420,6 +1428,12 @@ void Exa3_ManExactSynthesis2( Bmc_EsPar_t * pPars )
|
|||
printf( "Conf =%9d ", sat_solver_nconflicts(p->pSat) );
|
||||
Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
|
||||
}
|
||||
if ( nTimeToStop && Abc_Clock() > nTimeToStop )
|
||||
{
|
||||
printf( "Runtime limit (%d sec) is reached. ", pPars->RuntimeLim );
|
||||
status = l_Undef;
|
||||
break;
|
||||
}
|
||||
if ( status == l_False )
|
||||
{
|
||||
printf( "The problem has no solution.\n" );
|
||||
|
|
|
|||
|
|
@ -1263,13 +1263,13 @@ void Zyx_ManExactSynthesis( Bmc_EsPar_t * pPars )
|
|||
{
|
||||
int status, Iter, iMint = 0, fCompl = 0, nLazyAll = 0, nSols = 0;
|
||||
abctime clkTotal = Abc_Clock(), clk = Abc_Clock(); Zyx_Man_t * p;
|
||||
word pTruth[16];
|
||||
word pTruth[64];
|
||||
if ( !pPars->fMajority )
|
||||
{
|
||||
Abc_TtReadHex( pTruth, pPars->pTtStr );
|
||||
if ( pTruth[0] & 1 ) { fCompl = 1; Abc_TtNot( pTruth, Abc_TtWordNum(pPars->nVars) ); }
|
||||
}
|
||||
assert( pPars->nVars <= 10 );
|
||||
assert( pPars->nVars <= 12 );
|
||||
assert( pPars->nLutSize <= 6 );
|
||||
p = Zyx_ManAlloc( pPars, pPars->fMajority ? NULL : pTruth );
|
||||
printf( "Running exact synthesis for %d-input function with %d %d-input %s...\n",
|
||||
|
|
|
|||
Loading…
Reference in New Issue