mirror of https://github.com/YosysHQ/abc.git
Experiments with multipliers.
This commit is contained in:
parent
53edce3382
commit
9b0786fe89
|
|
@ -1419,6 +1419,8 @@ typedef struct Gia_ChMan_t_ Gia_ChMan_t;
|
|||
extern Gia_ChMan_t * Gia_ManDupChoicesStart( Gia_Man_t * pGia );
|
||||
extern void Gia_ManDupChoicesAdd( Gia_ChMan_t * pMan, Gia_Man_t * pGia );
|
||||
extern Gia_Man_t * Gia_ManDupChoicesFinish( Gia_ChMan_t * pMan );
|
||||
extern Vec_Int_t * Gia_ManComputeMffc( Gia_Man_t * p, Vec_Int_t * vLits, Vec_Int_t * vOuts );
|
||||
extern Gia_Man_t * Gia_ManDupExtractMffc( Gia_Man_t * p, Vec_Int_t * vLits, Vec_Int_t * vAnds, Vec_Int_t * vCos );
|
||||
/*=== giaEdge.c ==========================================================*/
|
||||
extern void Gia_ManEdgeFromArray( Gia_Man_t * p, Vec_Int_t * vArray );
|
||||
extern Vec_Int_t * Gia_ManEdgeToArray( Gia_Man_t * p );
|
||||
|
|
|
|||
|
|
@ -292,8 +292,8 @@ static inline int Gia_CutCompare2( Gia_Cut_t * pCut0, Gia_Cut_t * pCut1 )
|
|||
}
|
||||
static inline int Gia_CutCompare( Gia_Cut_t * pCut0, Gia_Cut_t * pCut1 )
|
||||
{
|
||||
if ( pCut0->CostF > pCut1->CostF ) return -1;
|
||||
if ( pCut0->CostF < pCut1->CostF ) return 1;
|
||||
if ( pCut0->CostF > pCut1->CostF ) return -1;
|
||||
if ( pCut0->CostF < pCut1->CostF ) return 1;
|
||||
if ( pCut0->nLeaves < pCut1->nLeaves ) return -1;
|
||||
if ( pCut0->nLeaves > pCut1->nLeaves ) return 1;
|
||||
return 0;
|
||||
|
|
@ -1230,7 +1230,7 @@ void Gia_ManComputeCutsCore( Gia_Man_t * pGia, int nCutSize, int nCutNum, int fT
|
|||
|
||||
Vec_Wec_t * Gia_ManCompute54Cuts( Gia_Man_t * pGia, int fVerbose )
|
||||
{
|
||||
Gia_Sto_t * pSto = Gia_ManMatchCutsInt( pGia, 5, 16, 0, fVerbose );
|
||||
Gia_Sto_t * pSto = Gia_ManMatchCutsInt( pGia, 5, 8, 0, fVerbose );
|
||||
Vec_Wec_t * vRes = Vec_WecAlloc( 1000 );
|
||||
Vec_Int_t * vLevel; int i, k, c, * pCut;
|
||||
Vec_WecForEachLevel( pSto->vCuts, vLevel, i ) if ( Vec_IntSize(vLevel) ) {
|
||||
|
|
|
|||
|
|
@ -6609,6 +6609,64 @@ Gia_Man_t * Gia_ManDupChoicesFinish( Gia_ChMan_t * p )
|
|||
return pTemp;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Extracting MFFC of the nodes supported by a set of literals.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
// collecting internal nodes and outputs in the MFF of a given set of literals
|
||||
Vec_Int_t * Gia_ManComputeMffc( Gia_Man_t * p, Vec_Int_t * vLits, Vec_Int_t * vOuts )
|
||||
{
|
||||
Vec_Int_t * vTfo = Vec_IntAlloc( 100 );
|
||||
Gia_Obj_t * pObj; int i, Lit;
|
||||
Vec_IntClear( vOuts );
|
||||
Gia_ManIncrementTravId( p );
|
||||
Vec_IntForEachEntry( vLits, Lit, i )
|
||||
Gia_ObjSetTravIdCurrentId( p, Abc_Lit2Var(Lit) );
|
||||
Gia_ManForEachAnd( p, pObj, i ) {
|
||||
if ( Gia_ObjIsTravIdCurrentId(p, i) )
|
||||
continue;
|
||||
if ( Gia_ObjIsTravIdCurrentId(p, Gia_ObjFaninId0(pObj, i)) && Gia_ObjIsTravIdCurrentId(p, Gia_ObjFaninId1(pObj, i)) )
|
||||
Gia_ObjSetTravIdCurrentId( p, i ), Vec_IntPush( vTfo, i );
|
||||
else if ( Gia_ObjIsTravIdCurrentId(p, Gia_ObjFaninId0(pObj, i)) )
|
||||
Vec_IntPushUniqueOrder( vOuts, Gia_ObjFaninId0(pObj, i) );
|
||||
else if ( Gia_ObjIsTravIdCurrentId(p, Gia_ObjFaninId1(pObj, i)) )
|
||||
Vec_IntPushUniqueOrder( vOuts, Gia_ObjFaninId1(pObj, i) );
|
||||
}
|
||||
Gia_ManForEachCo( p, pObj, i )
|
||||
if ( Gia_ObjIsTravIdCurrentId(p, Gia_ObjFaninId0p(p, pObj)) )
|
||||
Vec_IntPushUniqueOrder( vOuts, Gia_ObjFaninId0p(p, pObj) );
|
||||
Vec_IntTwoFilter( vOuts, vTfo );
|
||||
return vTfo;
|
||||
}
|
||||
|
||||
// extracting the AIG of the MFFC defined by a given set of literals
|
||||
Gia_Man_t * Gia_ManDupExtractMffc( Gia_Man_t * p, Vec_Int_t * vLits, Vec_Int_t * vAnds, Vec_Int_t * vCos )
|
||||
{
|
||||
Gia_Man_t * pNew;
|
||||
Gia_Obj_t * pObj;
|
||||
int i, Lit;
|
||||
pNew = Gia_ManStart( 5000 );
|
||||
pNew->pName = Abc_UtilStrsav( p->pName );
|
||||
pNew->pSpec = Abc_UtilStrsav( p->pSpec );
|
||||
pNew->fGiaSimple = 1;
|
||||
Gia_ManConst0(p)->Value = 0;
|
||||
Vec_IntForEachEntry( vLits, Lit, i )
|
||||
Gia_ManObj(p, Abc_Lit2Var(Lit))->Value = Abc_LitNotCond( Gia_ManAppendCi(pNew), Abc_LitIsCompl(Lit) );
|
||||
Gia_ManForEachObjVec( vAnds, p, pObj, i )
|
||||
pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
|
||||
Gia_ManForEachObjVec( vCos, p, pObj, i )
|
||||
pObj->Value = Gia_ManAppendCo( pNew, pObj->Value );
|
||||
return pNew;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -726,8 +726,16 @@ Vec_Wrd_t * Gia_ManMulFindSim( Vec_Wrd_t * vSim0, Vec_Wrd_t * vSim1, int fSigned
|
|||
}
|
||||
return vRes;
|
||||
}
|
||||
void Gia_ManMulFindOutputs( Gia_Man_t * p, Vec_Wec_t * vTerms, int fLits, int fVerbose )
|
||||
Vec_Wrd_t * Gia_ManMulFindSim2( Vec_Wrd_t * vSim0, Vec_Wrd_t * vSim1, int fSigned )
|
||||
{
|
||||
extern word * product_many(word *pInfo1, int nBits1, word *pInfo2, int nBits2, int fSigned );
|
||||
word * pRes = product_many( Vec_WrdArray(vSim0), Vec_WrdSize(vSim0), Vec_WrdArray(vSim1), Vec_WrdSize(vSim1), fSigned );
|
||||
return Vec_WrdAllocArray( pRes, Vec_WrdSize(vSim0) + Vec_WrdSize(vSim1) );
|
||||
}
|
||||
int Gia_ManMulFindOutputs( Gia_Man_t * p, Vec_Wec_t * vTerms, int fLits, int fVerbose )
|
||||
{
|
||||
//abctime clkTotal = Abc_Clock();
|
||||
int nDetected = 0;
|
||||
Abc_Random(1);
|
||||
for ( int m = 0; m < Vec_WecSize(vTerms)/3; m++ ) {
|
||||
Vec_Int_t * vIn0 = Vec_WecEntry(vTerms, 3*m+0);
|
||||
|
|
@ -735,8 +743,8 @@ void Gia_ManMulFindOutputs( Gia_Man_t * p, Vec_Wec_t * vTerms, int fLits, int fV
|
|||
Vec_Int_t * vOut = Vec_WecEntry(vTerms, 3*m+2);
|
||||
Vec_Wrd_t * vSim0 = Vec_WrdStartRandom( Vec_IntSize(vIn0) );
|
||||
Vec_Wrd_t * vSim1 = Vec_WrdStartRandom( Vec_IntSize(vIn1) );
|
||||
Vec_Wrd_t * vSimU = Gia_ManMulFindSim( vSim0, vSim1, 0 );
|
||||
Vec_Wrd_t * vSimS = Gia_ManMulFindSim( vSim0, vSim1, 1 );
|
||||
Vec_Wrd_t * vSimU = Gia_ManMulFindSim2( vSim0, vSim1, 0 );
|
||||
Vec_Wrd_t * vSimS = Gia_ManMulFindSim2( vSim0, vSim1, 1 );
|
||||
Vec_Int_t * vTfo = Gia_ManMulFindTfo( p, vIn0, vIn1, fLits );
|
||||
Vec_Wrd_t * vSims = Gia_ManMulFindSimCone( p, vIn0, vIn1, vSim0, vSim1, vTfo, fLits );
|
||||
Vec_Int_t * vOutU = Vec_IntAlloc( 100 );
|
||||
|
|
@ -762,10 +770,14 @@ void Gia_ManMulFindOutputs( Gia_Man_t * p, Vec_Wec_t * vTerms, int fLits, int fV
|
|||
if ( Vec_IntCountEntry(vOutU, -1) < Vec_IntSize(vOutU) ||
|
||||
Vec_IntCountEntry(vOutS, -1) < Vec_IntSize(vOutS) )
|
||||
{
|
||||
if ( Vec_IntCountEntry(vOutU, -1) < Vec_IntCountEntry(vOutS, -1) )
|
||||
if ( Vec_IntCountEntry(vOutU, -1) < Vec_IntCountEntry(vOutS, -1) ) {
|
||||
Vec_IntAppend( vOut, vOutU ), Vec_IntPush(vOut, 0);
|
||||
else
|
||||
nDetected = Vec_IntSize(vOutU) - Vec_IntCountEntry(vOutU, -1);
|
||||
}
|
||||
else {
|
||||
Vec_IntAppend( vOut, vOutS ), Vec_IntPush(vOut, 1);
|
||||
nDetected = Vec_IntSize(vOutS) - Vec_IntCountEntry(vOutS, -1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -782,6 +794,8 @@ void Gia_ManMulFindOutputs( Gia_Man_t * p, Vec_Wec_t * vTerms, int fLits, int fV
|
|||
Vec_IntFree( vOutS );
|
||||
}
|
||||
Vec_WecRemoveEmpty( vTerms );
|
||||
//Abc_PrintTime( 1, "Output detection time", Abc_Clock() - clkTotal );
|
||||
return nDetected;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
|
@ -831,11 +845,28 @@ void Gia_ManMulFindPrintSet( Vec_Int_t * vSet, int fLit, int fSkipLast )
|
|||
{
|
||||
int i, Temp, Limit = Vec_IntSize(vSet) - fSkipLast;
|
||||
printf( "{" );
|
||||
Vec_IntForEachEntryStop( vSet, Temp, i, Limit ) {
|
||||
if ( Temp == -1 )
|
||||
printf( "n/a%s", i < Limit-1 ? " ":"" );
|
||||
else
|
||||
printf( "%s%d%s", (fLit & Abc_LitIsCompl(Temp)) ? "~":"", fLit ? Abc_Lit2Var(Temp) : Temp, i < Limit-1 ? " ":"" );
|
||||
if ( Vec_IntSize(vSet) > 16 ) {
|
||||
Vec_IntForEachEntryStop( vSet, Temp, i, 4 ) {
|
||||
if ( Temp == -1 )
|
||||
printf( "n/a%s", i < Limit-1 ? " ":"" );
|
||||
else
|
||||
printf( "%s%d%s", (fLit & Abc_LitIsCompl(Temp)) ? "~":"", fLit ? Abc_Lit2Var(Temp) : Temp, i < Limit-1 ? " ":"" );
|
||||
}
|
||||
printf( "... " );
|
||||
Vec_IntForEachEntryStartStop( vSet, Temp, i, Limit-4, Limit ) {
|
||||
if ( Temp == -1 )
|
||||
printf( "n/a%s", i < Limit-1 ? " ":"" );
|
||||
else
|
||||
printf( "%s%d%s", (fLit & Abc_LitIsCompl(Temp)) ? "~":"", fLit ? Abc_Lit2Var(Temp) : Temp, i < Limit-1 ? " ":"" );
|
||||
}
|
||||
}
|
||||
else {
|
||||
Vec_IntForEachEntryStop( vSet, Temp, i, Limit ) {
|
||||
if ( Temp == -1 )
|
||||
printf( "n/a%s", i < Limit-1 ? " ":"" );
|
||||
else
|
||||
printf( "%s%d%s", (fLit & Abc_LitIsCompl(Temp)) ? "~":"", fLit ? Abc_Lit2Var(Temp) : Temp, i < Limit-1 ? " ":"" );
|
||||
}
|
||||
}
|
||||
printf( "}" );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ SRC += src/misc/util/utilBridge.c \
|
|||
src/misc/util/utilIsop.c \
|
||||
src/misc/util/utilLinear.c \
|
||||
src/misc/util/utilMiniver.c \
|
||||
src/misc/util/utilMulSim.c \
|
||||
src/misc/util/utilNam.c \
|
||||
src/misc/util/utilPrefix.cpp \
|
||||
src/misc/util/utilPth.c \
|
||||
|
|
|
|||
|
|
@ -0,0 +1,230 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [utilMulSim.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Generating multiplier simulation info.]
|
||||
|
||||
Synopsis [Generating multiplier simulation info.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - Feburary 13, 2011.]
|
||||
|
||||
Revision [$Id: utilMulSim.c,v 1.00 2011/02/11 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include "misc/util/abc_global.h"
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define SIG_WIDTH 64 // 64 simulation patterns in each signature word
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Core 32-bit-limb big integer unsigned multiply
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
uint32_t * product(const uint32_t *pArg1, int nInts1,
|
||||
const uint32_t *pArg2, int nInts2)
|
||||
{
|
||||
assert( pArg1 && pArg2 && nInts1 > 0 && nInts2 > 0 );
|
||||
int nRes = nInts1 + nInts2;
|
||||
uint32_t *pRes = (uint32_t *)calloc((size_t)nRes, sizeof(uint32_t));
|
||||
if (!pRes) return NULL;
|
||||
// Schoolbook multiplication in base 2^32
|
||||
for (int i = 0; i < nInts1; ++i) {
|
||||
uint64_t a = pArg1[i];
|
||||
if (a == 0) continue;
|
||||
uint64_t carry = 0;
|
||||
for (int j = 0; j < nInts2; ++j) {
|
||||
uint64_t t = (uint64_t)pRes[i + j] + a * (uint64_t)pArg2[j] + carry;
|
||||
pRes[i + j] = (uint32_t)t;
|
||||
carry = t >> 32;
|
||||
}
|
||||
pRes[i + nInts2] = (uint32_t)carry;
|
||||
}
|
||||
return pRes;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Bit-matrix helpers: signatures <-> per-pattern 32-bit-limb big ints
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
static void transpose_signatures_to_pattern(const uint64_t *sigs,
|
||||
int nBits,
|
||||
uint32_t *dst,
|
||||
int nInts,
|
||||
int patternIdx)
|
||||
{
|
||||
memset(dst, 0, (size_t)nInts * sizeof(uint32_t));
|
||||
for (int bit = 0; bit < nBits; ++bit) {
|
||||
uint64_t sigWord = sigs[bit];
|
||||
uint64_t bitVal = (sigWord >> patternIdx) & 1ULL;
|
||||
if (!bitVal) continue;
|
||||
int word = bit / 32;
|
||||
int offset = bit & 31;
|
||||
dst[word] |= (uint32_t)(1u << offset);
|
||||
}
|
||||
}
|
||||
|
||||
static void transpose_pattern_to_signatures(const uint32_t *src,
|
||||
int nIntsRes,
|
||||
int nBitsRes,
|
||||
uint64_t *outSigs,
|
||||
int patternIdx)
|
||||
{
|
||||
for (int bit = 0; bit < nBitsRes; ++bit) {
|
||||
int word = bit / 32;
|
||||
int offset = bit & 31;
|
||||
if (word >= nIntsRes)
|
||||
break;
|
||||
uint32_t bitVal = (src[word] >> offset) & 1u;
|
||||
if (bitVal)
|
||||
outSigs[bit] |= (uint64_t)1ULL << patternIdx;
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Signed helpers for 32-bit-limb big ints (two's complement on nBits)
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
static int is_negative(const uint32_t *x, int nBits)
|
||||
{
|
||||
int bitPos = nBits - 1;
|
||||
int word = bitPos / 32;
|
||||
int offset = bitPos & 31;
|
||||
return (x[word] >> offset) & 1u;
|
||||
}
|
||||
|
||||
static void mask_to_nBits(uint32_t *x, int nInts, int nBits)
|
||||
{
|
||||
if (nBits <= 0) {
|
||||
for (int i = 0; i < nInts; ++i)
|
||||
x[i] = 0;
|
||||
return;
|
||||
}
|
||||
int lastWord = (nBits - 1) / 32; // index of last used word
|
||||
int usedBitsInLast = nBits - lastWord * 32; // 1..32
|
||||
// Zero any words above the last used word
|
||||
for (int i = lastWord + 1; i < nInts; ++i)
|
||||
x[i] = 0;
|
||||
// If nBits is not a multiple of 32, mask off the high bits of last word
|
||||
if (usedBitsInLast < 32) {
|
||||
uint32_t mask = ((uint32_t)1u << usedBitsInLast) - 1u;
|
||||
x[lastWord] &= mask;
|
||||
}
|
||||
}
|
||||
|
||||
static void twos_complement_inplace(uint32_t *x, int nInts, int nBits)
|
||||
{
|
||||
// Invert
|
||||
for (int i = 0; i < nInts; ++i)
|
||||
x[i] = ~x[i];
|
||||
mask_to_nBits(x, nInts, nBits);
|
||||
// Add 1
|
||||
uint64_t carry = 1;
|
||||
for (int i = 0; i < nInts; ++i) {
|
||||
uint64_t sum = (uint64_t)x[i] + carry;
|
||||
x[i] = (uint32_t)sum;
|
||||
carry = sum >> 32;
|
||||
if (!carry)
|
||||
break;
|
||||
}
|
||||
mask_to_nBits(x, nInts, nBits);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// product_many: unsigned and signed (two's-complement) versions
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
uint64_t * product_many_unsigned(uint64_t *pInfo1, int nBits1,
|
||||
uint64_t *pInfo2, int nBits2)
|
||||
{
|
||||
assert( pInfo1 && pInfo2 && nBits1 > 0 && nBits2 > 0 );
|
||||
int nInts1 = (nBits1 + 31) / 32;
|
||||
int nInts2 = (nBits2 + 31) / 32;
|
||||
int nBitsRes = nBits1 + nBits2;
|
||||
int nIntsRes = nInts1 + nInts2;
|
||||
uint64_t *outSigs = (uint64_t *)calloc((size_t)nBitsRes, sizeof(uint64_t));
|
||||
if (!outSigs) return NULL;
|
||||
uint32_t *tmp1 = (uint32_t *)calloc((size_t)nInts1, sizeof(uint32_t));
|
||||
uint32_t *tmp2 = (uint32_t *)calloc((size_t)nInts2, sizeof(uint32_t));
|
||||
assert( tmp1 && tmp2 );
|
||||
for (int pattern = 0; pattern < SIG_WIDTH; ++pattern) {
|
||||
transpose_signatures_to_pattern(pInfo1, nBits1, tmp1, nInts1, pattern);
|
||||
transpose_signatures_to_pattern(pInfo2, nBits2, tmp2, nInts2, pattern);
|
||||
uint32_t *tmpRes = product(tmp1, nInts1, tmp2, nInts2); assert( tmpRes );
|
||||
transpose_pattern_to_signatures(tmpRes, nIntsRes, nBitsRes, outSigs, pattern);
|
||||
free(tmpRes);
|
||||
}
|
||||
free(tmp1);
|
||||
free(tmp2);
|
||||
return outSigs;
|
||||
}
|
||||
|
||||
uint64_t * product_many_signed(uint64_t *pInfo1, int nBits1,
|
||||
uint64_t *pInfo2, int nBits2)
|
||||
{
|
||||
assert( pInfo1 && pInfo2 && nBits1 > 0 && nBits2 > 0 );
|
||||
int nInts1 = (nBits1 + 31) / 32;
|
||||
int nInts2 = (nBits2 + 31) / 32;
|
||||
int nBitsRes = nBits1 + nBits2;
|
||||
int nIntsRes = nInts1 + nInts2;
|
||||
uint64_t *outSigs = (uint64_t *)calloc((size_t)nBitsRes, sizeof(uint64_t));
|
||||
if (!outSigs) return NULL;
|
||||
uint32_t *op1 = (uint32_t *)calloc((size_t)nInts1, sizeof(uint32_t));
|
||||
uint32_t *op2 = (uint32_t *)calloc((size_t)nInts2, sizeof(uint32_t));
|
||||
assert( op1 && op2 );
|
||||
for (int pattern = 0; pattern < SIG_WIDTH; ++pattern) {
|
||||
transpose_signatures_to_pattern(pInfo1, nBits1, op1, nInts1, pattern);
|
||||
transpose_signatures_to_pattern(pInfo2, nBits2, op2, nInts2, pattern);
|
||||
int neg1 = is_negative(op1, nBits1);
|
||||
int neg2 = is_negative(op2, nBits2);
|
||||
int negRes = neg1 ^ neg2;
|
||||
if (neg1) twos_complement_inplace(op1, nInts1, nBits1);
|
||||
if (neg2) twos_complement_inplace(op2, nInts2, nBits2);
|
||||
uint32_t *tmpRes = product(op1, nInts1, op2, nInts2); assert( tmpRes );
|
||||
if (negRes)
|
||||
twos_complement_inplace(tmpRes, nIntsRes, nBitsRes);
|
||||
else
|
||||
mask_to_nBits(tmpRes, nIntsRes, nBitsRes);
|
||||
transpose_pattern_to_signatures(tmpRes, nIntsRes, nBitsRes, outSigs, pattern);
|
||||
free(tmpRes);
|
||||
}
|
||||
free(op1);
|
||||
free(op2);
|
||||
return outSigs;
|
||||
}
|
||||
|
||||
word * product_many(word *pInfo1, int nBits1, word *pInfo2, int nBits2, int fSigned )
|
||||
{
|
||||
if ( fSigned )
|
||||
return (word *)product_many_signed((uint64_t *)pInfo1, nBits1, (uint64_t *)pInfo2, nBits2);
|
||||
else
|
||||
return (word *)product_many_unsigned((uint64_t *)pInfo1, nBits1, (uint64_t *)pInfo2, nBits2);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
||||
|
|
@ -1947,16 +1947,16 @@ static inline int Vec_IntTwoRemove( Vec_Int_t * vArr1, Vec_Int_t * vArr2 )
|
|||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns the result of merging the two vectors.]
|
||||
Synopsis [Keeps only those entries in vArr1, which are in vArr2.]
|
||||
|
||||
Description [Keeps only those entries of vArr1, which are in vArr2.]
|
||||
Description [Assumes that the vectors are sorted in the increasing order.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_IntTwoMerge1( Vec_Int_t * vArr1, Vec_Int_t * vArr2 )
|
||||
static inline void Vec_IntTwoFilter( Vec_Int_t * vArr1, Vec_Int_t * vArr2 )
|
||||
{
|
||||
int * pBeg = vArr1->pArray;
|
||||
int * pBeg1 = vArr1->pArray;
|
||||
|
|
|
|||
Loading…
Reference in New Issue