Skip to content

[ bugfix ! ] lutpack caused function issue #515

@light-tian

Description

@light-tian

Version

The latest ABC. Need ABC team helps to merge this bug fix.

How to reproduce ?

#test.bench
INPUT(a)
INPUT(b)
INPUT(c)
OUTPUT(o)
o = LUT 0x5101 (a, n, b, c)
n = LUT 0x1(c)
  • comment following line Abc_NtkSweep( pNtk, 0 ); and build your abc binary to execute your_abc -c "read_bench test.bench; lutpack; cec test.bench;'
int Lpk_Resynthesize( Abc_Ntk_t * pNtk, Lpk_Par_t * pPars )
{
    ProgressBar * pProgress = NULL; // Suppress "might be used uninitialized"
    Lpk_Man_t * p;
    Abc_Obj_t * pObj;
    double Delta;
//    int * pnFanouts, nObjMax;
    int i, Iter, nNodes, nNodesPrev;
    abctime clk = Abc_Clock();
    assert( Abc_NtkIsLogic(pNtk) );
 
    // sweep dangling nodes as a preprocessing step
    // Abc_NtkSweep( pNtk, 0 );
   ...
}
my_terminal@DESKTOP-HJCISF3:~/abc$ ./abc -c "read_bench test.bench; lutpack; cec test.bench"
======== ABC command line "read_bench test.bench; lutpack; cec test.bench"
Networks are NOT EQUIVALENT.  Time =     0.01 sec
INPUT: a = 1'h0, b = 1'h1, c = 1'h0.  OUTPUT: o = 1'h1 (test), o = 1'h0 (test).
Verification failed for at least 1 outputs:  o
Output o: Value in Network1 = 1. Value in Network2 = 0.
Input pattern:  a=0 b=1 c=0

How to fix ?

diff --git a/src/opt/lpk/lpkCut.c b/src/opt/lpk/lpkCut.c
index f19decff0..91eb42905 100644
--- a/src/opt/lpk/lpkCut.c
+++ b/src/opt/lpk/lpkCut.c
@@ -161,6 +161,15 @@ unsigned * Lpk_CutTruth_rec( Hop_Man_t * pMan, Hop_Obj_t * pObj, int nVars, Vec_
     return pTruth;
 }

+unsigned* resolveBufferTrurth(Hop_Obj_t * pObj, int nVars, Vec_Ptr_t * vTtNodes, int * piCount)
+{
+    unsigned* pTruth = (unsigned *)Vec_PtrEntry( vTtNodes, (*piCount)++ );
+    unsigned* ttbuffer = (unsigned *)pObj->pData;
+    for ( int w = Kit_TruthWordNum(nVars)-1; w >= 0; w-- )
+        pTruth[w] = ttbuffer[w];
+    return pTruth;
+}
+
 /**Function*************************************************************

   Synopsis    [Computes the truth able of one cut.]
@@ -201,7 +210,10 @@ unsigned * Lpk_CutTruth( Lpk_Man_t * p, Lpk_Cut_t * pCut, int fInv )
             Hop_ManPi( pManHop, k )->pData = pFanin->pCopy;
         }
         // compute the truth table of internal nodes
-        pTruth = Lpk_CutTruth_rec( pManHop, pObjHop, pCut->nLeaves, p->vTtNodes, &iCount );
+        if (Abc_ObjFaninNum(pObj) == 1) {
+            pTruth = resolveBufferTrurth(pObjHop, pCut->nLeaves, p->vTtNodes, &iCount);
+        } else
+            pTruth = Lpk_CutTruth_rec( pManHop, pObjHop, pCut->nLeaves, p->vTtNodes, &iCount );
         if ( Hop_IsComplement((Hop_Obj_t *)pObj->pData) )
             Kit_TruthNot( pTruth, pTruth, pCut->nLeaves );
         // set the truth table at the node
myterminal@DESKTOP-HJCISF3:~/abc$ ./abc -c "read_bench test.bench; lutpack; cec test.bench"
======== ABC command line "read_bench test.bench; lutpack; cec test.bench"
Networks are equivalent.  Time =     0.01 sec

Why ?

When do truth table computation, the address to save the tt of buffer is the same as the tt of the buffer's driver, if the buffer is an inverter, the tt will be inverted and causes wrong computation when the driver reconverges to cut-root from other path.

Solution is to apply unique memory for buffer, DON'T share the same memory with its driver.

You may say that sweep can optimize the buffer before doing lutpack, yes it will. However, lutpack is an incremental optimization and new buffer may be created.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions