mirror of https://github.com/YosysHQ/abc.git
443 lines
13 KiB
C
443 lines
13 KiB
C
/**CFile****************************************************************
|
|
|
|
FileName [abcRpo.c]
|
|
|
|
SystemName [ABC: Logic synthesis and verification system.]
|
|
|
|
PackageName [Rpo package.]
|
|
|
|
Synopsis [Procedures for executing RPO.]
|
|
|
|
Author [Mayler G. A. Martins / Vinicius Callegaro]
|
|
|
|
Affiliation [UFRGS]
|
|
|
|
Date [Ver. 1.0. Started - May 08, 2013.]
|
|
|
|
Revision [$Id: abcRpo.c,v 1.00 2013/05/08 00:00:00 mgamartins Exp $]
|
|
|
|
***********************************************************************/
|
|
|
|
#include "misc/extra/extra.h"
|
|
|
|
#include "bool/rpo/rpo.h"
|
|
#include "bool/rpo/literal.h"
|
|
|
|
ABC_NAMESPACE_IMPL_START
|
|
|
|
|
|
// data-structure to store a bunch of truth tables
|
|
typedef struct Rpo_TtStore_t_ Rpo_TtStore_t;
|
|
|
|
struct Rpo_TtStore_t_ {
|
|
int nVars;
|
|
int nWords;
|
|
int nFuncs;
|
|
word ** pFuncs;
|
|
};
|
|
|
|
|
|
// read/write/flip i-th bit of a bit string table:
|
|
|
|
static inline int Abc_TruthGetBit(word * p, int i) {
|
|
return (int) (p[i >> 6] >> (i & 63)) & 1;
|
|
}
|
|
|
|
static inline void Abc_TruthSetBit(word * p, int i) {
|
|
p[i >> 6] |= (((word) 1) << (i & 63));
|
|
}
|
|
|
|
static inline void Abc_TruthXorBit(word * p, int i) {
|
|
p[i >> 6] ^= (((word) 1) << (i & 63));
|
|
}
|
|
|
|
// read/write k-th digit d of a hexadecimal number:
|
|
|
|
static inline int Abc_TruthGetHex(word * p, int k) {
|
|
return (int) (p[k >> 4] >> ((k << 2) & 63)) & 15;
|
|
}
|
|
|
|
static inline void Abc_TruthSetHex(word * p, int k, int d) {
|
|
p[k >> 4] |= (((word) d) << ((k << 2) & 63));
|
|
}
|
|
|
|
static inline void Abc_TruthXorHex(word * p, int k, int d) {
|
|
p[k >> 4] ^= (((word) d) << ((k << 2) & 63));
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
/// FUNCTION DEFINITIONS ///
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
// read one hex character
|
|
|
|
static inline int Abc_TruthReadHexDigit(char HexChar) {
|
|
if (HexChar >= '0' && HexChar <= '9')
|
|
return HexChar - '0';
|
|
if (HexChar >= 'A' && HexChar <= 'F')
|
|
return HexChar - 'A' + 10;
|
|
if (HexChar >= 'a' && HexChar <= 'f')
|
|
return HexChar - 'a' + 10;
|
|
assert(0); // not a hexadecimal symbol
|
|
return -1; // return value which makes no sense
|
|
}
|
|
|
|
// write one hex character
|
|
|
|
static inline void Abc_TruthWriteHexDigit(FILE * pFile, int HexDigit) {
|
|
assert(HexDigit >= 0 && HexDigit < 16);
|
|
if (HexDigit < 10)
|
|
fprintf(pFile, "%d", HexDigit);
|
|
else
|
|
fprintf(pFile, "%c", 'A' + HexDigit - 10);
|
|
}
|
|
|
|
// read one truth table in hexadecimal
|
|
|
|
static void Abc_TruthReadHex(word * pTruth, char * pString, int nVars) {
|
|
int nWords = (nVars < 7) ? 1 : (1 << (nVars - 6));
|
|
int k, Digit, nDigits = (nVars < 7) ? (1 << (nVars-2)) : (nWords << 4);
|
|
char EndSymbol;
|
|
// skip the first 2 symbols if they are "0x"
|
|
if (pString[0] == '0' && pString[1] == 'x')
|
|
pString += 2;
|
|
// get the last symbol
|
|
EndSymbol = pString[nDigits];
|
|
// the end symbol of the TT (the one immediately following hex digits)
|
|
// should be one of the following: space, a new-line, or a zero-terminator
|
|
// (note that on Windows symbols '\r' can be inserted before each '\n')
|
|
assert(EndSymbol == ' ' || EndSymbol == '\n' || EndSymbol == '\r' || EndSymbol == '\0');
|
|
// read hexadecimal digits in the reverse order
|
|
// (the last symbol in the string is the least significant digit)
|
|
for (k = 0; k < nDigits; k++) {
|
|
Digit = Abc_TruthReadHexDigit(pString[nDigits - 1 - k]);
|
|
assert(Digit >= 0 && Digit < 16);
|
|
Abc_TruthSetHex(pTruth, k, Digit);
|
|
}
|
|
}
|
|
|
|
// write one truth table in hexadecimal (do not add end-of-line!)
|
|
|
|
static void Abc_TruthWriteHex(FILE * pFile, word * pTruth, int nVars) {
|
|
int nDigits, Digit, k;
|
|
nDigits = (1 << (nVars - 2));
|
|
for (k = 0; k < nDigits; k++) {
|
|
Digit = Abc_TruthGetHex(pTruth, k);
|
|
assert(Digit >= 0 && Digit < 16);
|
|
Abc_TruthWriteHexDigit(pFile, Digit);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Allocate/Deallocate storage for truth tables..]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
static Rpo_TtStore_t * Abc_TruthStoreAlloc(int nVars, int nFuncs) {
|
|
Rpo_TtStore_t * p;
|
|
int i;
|
|
p = (Rpo_TtStore_t *) malloc(sizeof (Rpo_TtStore_t));
|
|
p->nVars = nVars;
|
|
p->nWords = (nVars < 7) ? 1 : (1 << (nVars - 6));
|
|
p->nFuncs = nFuncs;
|
|
// alloc storage for 'nFuncs' truth tables as one chunk of memory
|
|
p->pFuncs = (word **) malloc((sizeof (word *) + sizeof (word) * p->nWords) * p->nFuncs);
|
|
// assign and clean the truth table storage
|
|
p->pFuncs[0] = (word *) (p->pFuncs + p->nFuncs);
|
|
memset(p->pFuncs[0], 0, sizeof (word) * p->nWords * p->nFuncs);
|
|
// split it up into individual truth tables
|
|
for (i = 1; i < p->nFuncs; i++)
|
|
p->pFuncs[i] = p->pFuncs[i - 1] + p->nWords;
|
|
return p;
|
|
}
|
|
|
|
static Rpo_TtStore_t * Abc_TruthStoreAlloc2(int nVars, int nFuncs, word * pBuffer) {
|
|
Rpo_TtStore_t * p;
|
|
int i;
|
|
p = (Rpo_TtStore_t *) malloc(sizeof (Rpo_TtStore_t));
|
|
p->nVars = nVars;
|
|
p->nWords = (nVars < 7) ? 1 : (1 << (nVars - 6));
|
|
p->nFuncs = nFuncs;
|
|
// alloc storage for 'nFuncs' truth tables as one chunk of memory
|
|
p->pFuncs = (word **) malloc(sizeof (word *) * p->nFuncs);
|
|
// assign and clean the truth table storage
|
|
p->pFuncs[0] = pBuffer;
|
|
// split it up into individual truth tables
|
|
for (i = 1; i < p->nFuncs; i++)
|
|
p->pFuncs[i] = p->pFuncs[i - 1] + p->nWords;
|
|
return p;
|
|
}
|
|
|
|
static void Abc_TtStoreFree(Rpo_TtStore_t * p, int nVarNum) {
|
|
if (nVarNum >= 0)
|
|
ABC_FREE(p->pFuncs[0]);
|
|
ABC_FREE(p->pFuncs);
|
|
ABC_FREE(p);
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Read file contents.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
extern int Abc_FileSize(char * pFileName);
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Read file contents.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
extern char * Abc_FileRead(char * pFileName);
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Determine the number of variables by reading the first line.]
|
|
|
|
Description [Determine the number of functions by counting the lines.]
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
extern void Abc_TruthGetParams(char * pFileName, int * pnVars, int * pnTruths);
|
|
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Read truth tables from file.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
static void Abc_TruthStoreRead(char * pFileName, Rpo_TtStore_t * p) {
|
|
char * pContents;
|
|
int i, nLines;
|
|
pContents = Abc_FileRead(pFileName);
|
|
if (pContents == NULL)
|
|
return;
|
|
// here it is assumed (without checking!) that each line of the file
|
|
// begins with a string of hexadecimal chars followed by space
|
|
|
|
// the file will be read till the first empty line (pContents[i] == '\n')
|
|
// (note that Abc_FileRead() added several empty lines at the end of the file contents)
|
|
for (nLines = i = 0; pContents[i] != '\n';) {
|
|
// read one line
|
|
Abc_TruthReadHex(p->pFuncs[nLines++], &pContents[i], p->nVars);
|
|
// skip till after the end-of-line symbol
|
|
// (note that end-of-line symbol is also skipped)
|
|
while (pContents[i++] != '\n');
|
|
}
|
|
// adjust the number of functions read
|
|
// (we may have allocated more storage because some lines in the file were empty)
|
|
assert(p->nFuncs >= nLines);
|
|
p->nFuncs = nLines;
|
|
ABC_FREE(pContents);
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Write truth tables into file.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
static void Abc_TtStoreWrite(char * pFileName, Rpo_TtStore_t * p, int fBinary) {
|
|
FILE * pFile;
|
|
int i, nBytes = 8 * Abc_Truth6WordNum(p->nVars);
|
|
pFile = fopen(pFileName, "wb");
|
|
if (pFile == NULL) {
|
|
printf("Cannot open file \"%s\" for writing.\n", pFileName);
|
|
return;
|
|
}
|
|
for (i = 0; i < p->nFuncs; i++) {
|
|
if (fBinary)
|
|
fwrite(p->pFuncs[i], nBytes, 1, pFile);
|
|
else
|
|
Abc_TruthWriteHex(pFile, p->pFuncs[i], p->nVars), fprintf(pFile, "\n");
|
|
}
|
|
fclose(pFile);
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Read truth tables from input file and write them into output file.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
static Rpo_TtStore_t * Abc_TtStoreLoad(char * pFileName, int nVarNum) {
|
|
Rpo_TtStore_t * p;
|
|
if (nVarNum < 0) {
|
|
int nVars, nTruths;
|
|
// figure out how many truth table and how many variables
|
|
Abc_TruthGetParams(pFileName, &nVars, &nTruths);
|
|
if (nVars < 2 || nVars > 16 || nTruths == 0)
|
|
return NULL;
|
|
// allocate data-structure
|
|
p = Abc_TruthStoreAlloc(nVars, nTruths);
|
|
// read info from file
|
|
Abc_TruthStoreRead(pFileName, p);
|
|
} else {
|
|
char * pBuffer;
|
|
int nFileSize = Abc_FileSize(pFileName);
|
|
int nBytes = (1 << (nVarNum - 3)); // why mishchencko put -3? ###
|
|
int nTruths = nFileSize / nBytes;
|
|
//Abc_Print(-2,"nFileSize=%d,nTruths=%d\n",nFileSize, nTruths);
|
|
if (nFileSize == -1)
|
|
return NULL;
|
|
assert(nVarNum >= 6);
|
|
if (nFileSize % nBytes != 0)
|
|
Abc_Print(0, "The file size (%d) is divided by the truth table size (%d) with remainder (%d).\n",
|
|
nFileSize, nBytes, nFileSize % nBytes);
|
|
// read file contents
|
|
pBuffer = Abc_FileRead(pFileName);
|
|
// allocate data-structure
|
|
p = Abc_TruthStoreAlloc2(nVarNum, nTruths, (word *) pBuffer);
|
|
}
|
|
return p;
|
|
}
|
|
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Apply decomposition to the truth table.]
|
|
|
|
Description [Returns the number of AIG nodes.]
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
void Abc_TruthRpoPerform(Rpo_TtStore_t * p, int nThreshold, int fVerbose) {
|
|
clock_t clk = clock();
|
|
int i;
|
|
int rpoCount = 0;
|
|
Literal_t* lit;
|
|
float percent;
|
|
for (i = 0; i < p->nFuncs; i++) {
|
|
// if(i>1000) {
|
|
// continue;
|
|
// }
|
|
////
|
|
// if(i!= 2196 ) { //5886
|
|
// continue;
|
|
// }
|
|
if(fVerbose) {
|
|
Abc_Print(-2,"%d: ", i+1);
|
|
}
|
|
|
|
lit = Rpo_Factorize((unsigned *) p->pFuncs[i], p->nVars, nThreshold, fVerbose);
|
|
if (lit != NULL) {
|
|
if(fVerbose) {
|
|
Abc_Print(-2, "Solution : %s\n", lit->expression->pArray);
|
|
Abc_Print(-2, "\n\n");
|
|
}
|
|
Lit_Free(lit);
|
|
rpoCount++;
|
|
} else {
|
|
if(fVerbose) {
|
|
Abc_Print(-2, "null\n");
|
|
Abc_Print(-2, "\n\n");
|
|
}
|
|
}
|
|
}
|
|
percent = (rpoCount * 100.0) / p->nFuncs;
|
|
Abc_Print(-2,"%d of %d (%.2f %%) functions are RPO.\n", rpoCount,p->nFuncs,percent);
|
|
Abc_PrintTime(1, "Time", clock() - clk);
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Apply decomposition to truth tables.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
void Abc_TruthRpoTest(char * pFileName, int nVarNum, int nThreshold, int fVerbose) {
|
|
Rpo_TtStore_t * p;
|
|
|
|
// allocate data-structure
|
|
// if (fVerbose) {
|
|
// Abc_Print(-2, "Number of variables = %d\n", nVarNum);
|
|
// }
|
|
p = Abc_TtStoreLoad(pFileName, nVarNum);
|
|
|
|
if (fVerbose) {
|
|
Abc_Print(-2, "Number of variables = %d\n", p->nVars);
|
|
}
|
|
// consider functions from the file
|
|
Abc_TruthRpoPerform(p, nThreshold, fVerbose);
|
|
|
|
// delete data-structure
|
|
Abc_TtStoreFree(p, nVarNum);
|
|
// printf( "Finished decomposing truth tables from file \"%s\".\n", pFileName );
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Testbench for decomposition algorithms.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
int Abc_RpoTest(char * pFileName, int nVarNum,int nThreshold, int fVerbose) {
|
|
if (fVerbose) {
|
|
printf("Using truth tables from file \"%s\"...\n", pFileName);
|
|
}
|
|
Abc_TruthRpoTest(pFileName, nVarNum, nThreshold, fVerbose);
|
|
fflush(stdout);
|
|
return 0;
|
|
}
|
|
|
|
|
|
/////////////////////ert truth table to ///////////////////////////////////////////////////
|
|
/// END OF FILE ///
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
ABC_NAMESPACE_IMPL_END
|
|
|
|
|