Commit 33971604 by Alan Mishchenko

Adding support for adders with carry-in in WLC and NDR.

parent fe56e29d
...@@ -396,10 +396,19 @@ static inline void Ndr_WriteVerilogModule( FILE * pFile, void * pDesign, int Mod ...@@ -396,10 +396,19 @@ static inline void Ndr_WriteVerilogModule( FILE * pFile, void * pDesign, int Mod
fprintf( pFile, "%s", pNames[pArray[0]] ), fprintf( pFile, "%s", pNames[pArray[0]] ),
Ndr_ObjWriteRange( p, Obj, pFile, 0 ), Ndr_ObjWriteRange( p, Obj, pFile, 0 ),
fprintf( pFile, ";\n" ); fprintf( pFile, ";\n" );
else if ( Type == ABC_OPER_CONCAT )
{
fprintf( pFile, "{" );
for ( i = 0; i < nArray; i++ )
fprintf( pFile, "%s%s", pNames[pArray[i]], i==nArray-1 ? "":", " );
fprintf( pFile, "};\n" );
}
else if ( nArray == 1 ) else if ( nArray == 1 )
fprintf( pFile, "%s %s;\n", Abc_OperName(Ndr_ObjReadBody(p, Obj, NDR_OPERTYPE)), pNames[pArray[0]] ); fprintf( pFile, "%s %s;\n", Abc_OperName(Ndr_ObjReadBody(p, Obj, NDR_OPERTYPE)), pNames[pArray[0]] );
else if ( nArray == 2 ) else if ( nArray == 2 )
fprintf( pFile, "%s %s %s;\n", pNames[pArray[0]], Abc_OperName(Ndr_ObjReadBody(p, Obj, NDR_OPERTYPE)), pNames[pArray[1]] ); fprintf( pFile, "%s %s %s;\n", pNames[pArray[0]], Abc_OperName(Ndr_ObjReadBody(p, Obj, NDR_OPERTYPE)), pNames[pArray[1]] );
else if ( nArray == 3 && Type == ABC_OPER_ARI_ADD )
fprintf( pFile, "%s + %s + %s;\n", pNames[pArray[0]], pNames[pArray[1]], pNames[pArray[2]] );
else if ( Type == ABC_OPER_BIT_MUX ) else if ( Type == ABC_OPER_BIT_MUX )
fprintf( pFile, "%s ? %s : %s;\n", pNames[pArray[0]], pNames[pArray[1]], pNames[pArray[2]] ); fprintf( pFile, "%s ? %s : %s;\n", pNames[pArray[0]], pNames[pArray[1]], pNames[pArray[2]] );
else else
...@@ -577,6 +586,95 @@ static inline void Ndr_ModuleTest() ...@@ -577,6 +586,95 @@ static inline void Ndr_ModuleTest()
Ndr_Delete( pDesign ); Ndr_Delete( pDesign );
} }
// This testing procedure creates and writes into a Verilog file
// for the following design composed of one adder divided into two
// module add8 ( input [7:0] a, input [7:0] b, output [7:0] s, output co );
// wire [3:0] a0 = a[3:0];
// wire [3:0] b0 = b[3:0];
// wire [7:4] a1 = a[7:4];
// wire [7:4] b1 = b[7:4];
// wire [4:0] r0 = a0 + b0;
// wire [3:0] s0 = r0[3:0];
// wire rco = r0[4];
// wire [4:0] r1 = a1 + b1 + rco;
// wire [3:0] s1 = r1[3:0];
// assign co = r1[4];
// assign s = {s1, s0};
// endmodule
static inline void Ndr_ModuleTestAdder()
{
// map name IDs into char strings
char * ppNames[20] = { NULL,
"a", "b", "s", "co", // 1, 2, 3, 4
"a0", "a1", "b0", "b1", // 5, 6, 7, 8
"r0", "s0", "rco", // 9, 10, 11
"r1", "s1", "add8" // 12, 13, 14
};
// fanins
int FaninA = 1;
int FaninB = 2;
int FaninS = 3;
int FaninCO = 4;
int FaninA0 = 5;
int FaninA1 = 6;
int FaninB0 = 7;
int FaninB1 = 8;
int FaninR0 = 9;
int FaninS0 = 10;
int FaninRCO = 11;
int FaninR1 = 12;
int FaninS1 = 13;
int Fanins1[2] = { FaninA0, FaninB0 };
int Fanins2[3] = { FaninA1, FaninB1, FaninRCO };
int Fanins3[4] = { FaninS1, FaninS0 };
// create a new module
void * pDesign = Ndr_Create( 14 );
int ModuleID = Ndr_AddModule( pDesign, 14 );
// add objects to the modele
Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CI, 0, 7, 0, 0, 0, NULL, 1, &FaninA, NULL ); // no fanins
Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CI, 0, 7, 0, 0, 0, NULL, 1, &FaninB, NULL ); // no fanins
Ndr_AddObject( pDesign, ModuleID, ABC_OPER_SLICE, 0, 3, 0, 0, 1, &FaninA, 1, &FaninA0, NULL ); // wire [3:0] a0 = a[3:0];
Ndr_AddObject( pDesign, ModuleID, ABC_OPER_SLICE, 0, 3, 0, 0, 1, &FaninB, 1, &FaninB0, NULL ); // wire [3:0] b0 = a[3:0];
Ndr_AddObject( pDesign, ModuleID, ABC_OPER_SLICE, 0, 7, 4, 0, 1, &FaninA, 1, &FaninA1, NULL ); // wire [7:4] a1 = a[7:4];
Ndr_AddObject( pDesign, ModuleID, ABC_OPER_SLICE, 0, 7, 4, 0, 1, &FaninB, 1, &FaninB1, NULL ); // wire [7:4] b1 = b[7:4];
Ndr_AddObject( pDesign, ModuleID, ABC_OPER_ARI_ADD, 0, 4, 0, 0, 2, Fanins1, 1, &FaninR0, NULL ); // wire [4:0] r0 = a0 + b0;
Ndr_AddObject( pDesign, ModuleID, ABC_OPER_SLICE, 0, 3, 0, 0, 1, &FaninR0, 1, &FaninS0, NULL ); // wire [3:0] s0 = r0[3:0];
Ndr_AddObject( pDesign, ModuleID, ABC_OPER_SLICE, 0, 4, 4, 0, 1, &FaninR0, 1, &FaninRCO, NULL ); // wire rco = r0[4];
Ndr_AddObject( pDesign, ModuleID, ABC_OPER_ARI_ADD, 0, 4, 0, 0, 3, Fanins2, 1, &FaninR1, NULL ); // wire [4:0] r1 = a1 + b1 + rco;
Ndr_AddObject( pDesign, ModuleID, ABC_OPER_SLICE, 0, 3, 0, 0, 1, &FaninR1, 1, &FaninS1, NULL ); // wire [3:0] s1 = r1[3:0];
Ndr_AddObject( pDesign, ModuleID, ABC_OPER_SLICE, 0, 4, 4, 0, 1, &FaninR1, 1, &FaninCO, NULL ); // assign co = r1[4];
Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CONCAT, 0, 7, 0, 0, 2, Fanins3, 1, &FaninS, NULL ); // s = {s1, s0};
Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CO, 0, 7, 0, 0, 1, &FaninS, 0, NULL, NULL );
Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CO, 0, 0, 0, 0, 1, &FaninCO, 0, NULL, NULL );
// write Verilog for verification
Ndr_WriteVerilog( NULL, pDesign, ppNames );
Ndr_Write( "add8.ndr", pDesign );
Ndr_Delete( pDesign );
}
// This testing procedure creates and writes into a Verilog file // This testing procedure creates and writes into a Verilog file
// for the following hierarchical design composed of three modules // for the following hierarchical design composed of three modules
......
...@@ -339,9 +339,9 @@ void Wlc_BlastFullAdder( Gia_Man_t * pNew, int a, int b, int c, int * pc, int * ...@@ -339,9 +339,9 @@ void Wlc_BlastFullAdder( Gia_Man_t * pNew, int a, int b, int c, int * pc, int *
if ( fCompl ) if ( fCompl )
*ps = Abc_LitNot(*ps), *pc = Abc_LitNot(*pc); *ps = Abc_LitNot(*ps), *pc = Abc_LitNot(*pc);
} }
void Wlc_BlastAdder( Gia_Man_t * pNew, int * pAdd0, int * pAdd1, int nBits ) // result is in pAdd0 void Wlc_BlastAdder( Gia_Man_t * pNew, int * pAdd0, int * pAdd1, int nBits, int Carry ) // result is in pAdd0
{ {
int b, Carry = 0; int b;
for ( b = 0; b < nBits; b++ ) for ( b = 0; b < nBits; b++ )
Wlc_BlastFullAdder( pNew, pAdd0[b], pAdd1[b], Carry, &Carry, &pAdd0[b] ); Wlc_BlastFullAdder( pNew, pAdd0[b], pAdd1[b], Carry, &Carry, &pAdd0[b] );
} }
...@@ -421,7 +421,7 @@ void Wlc_BlastMultiplier2( Gia_Man_t * pNew, int * pArg0, int * pArg1, int nBits ...@@ -421,7 +421,7 @@ void Wlc_BlastMultiplier2( Gia_Man_t * pNew, int * pArg0, int * pArg1, int nBits
for ( j = 0; Vec_IntSize(vTemp) < nBits; j++ ) for ( j = 0; Vec_IntSize(vTemp) < nBits; j++ )
Vec_IntPush( vTemp, Gia_ManHashAnd(pNew, pArg0[j], pArg1[i]) ); Vec_IntPush( vTemp, Gia_ManHashAnd(pNew, pArg0[j], pArg1[i]) );
assert( Vec_IntSize(vTemp) == nBits ); assert( Vec_IntSize(vTemp) == nBits );
Wlc_BlastAdder( pNew, Vec_IntArray(vRes), Vec_IntArray(vTemp), nBits ); Wlc_BlastAdder( pNew, Vec_IntArray(vRes), Vec_IntArray(vTemp), nBits, 0 );
} }
} }
void Wlc_BlastFullAdderCtrl( Gia_Man_t * pNew, int a, int ac, int b, int c, int * pc, int * ps, int fNeg ) void Wlc_BlastFullAdderCtrl( Gia_Man_t * pNew, int a, int ac, int b, int c, int * pc, int * ps, int fNeg )
...@@ -758,7 +758,7 @@ void Wlc_BlastReduceMatrix( Gia_Man_t * pNew, Vec_Wec_t * vProds, Vec_Wec_t * vL ...@@ -758,7 +758,7 @@ void Wlc_BlastReduceMatrix( Gia_Man_t * pNew, Vec_Wec_t * vProds, Vec_Wec_t * vL
} }
Vec_IntPush( vRes, 0 ); Vec_IntPush( vRes, 0 );
Vec_IntPush( vLevel, 0 ); Vec_IntPush( vLevel, 0 );
Wlc_BlastAdder( pNew, Vec_IntArray(vRes), Vec_IntArray(vLevel), Vec_IntSize(vRes) ); Wlc_BlastAdder( pNew, Vec_IntArray(vRes), Vec_IntArray(vLevel), Vec_IntSize(vRes), 0 );
} }
void Wlc_BlastMultiplier3( Gia_Man_t * pNew, int * pArgA, int * pArgB, int nArgA, int nArgB, Vec_Int_t * vRes ) void Wlc_BlastMultiplier3( Gia_Man_t * pNew, int * pArgA, int * pArgB, int nArgA, int nArgB, Vec_Int_t * vRes )
{ {
...@@ -1314,8 +1314,9 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Vec_Int_t * vBoxIds, int iOutput, in ...@@ -1314,8 +1314,9 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Vec_Int_t * vBoxIds, int iOutput, in
int nRangeMax = Abc_MaxInt( nRange, Abc_MaxInt(nRange0, nRange1) ); int nRangeMax = Abc_MaxInt( nRange, Abc_MaxInt(nRange0, nRange1) );
int * pArg0 = Wlc_VecLoadFanins( vRes, pFans0, nRange0, nRangeMax, Wlc_ObjIsSignedFanin01(p, pObj) ); int * pArg0 = Wlc_VecLoadFanins( vRes, pFans0, nRange0, nRangeMax, Wlc_ObjIsSignedFanin01(p, pObj) );
int * pArg1 = Wlc_VecLoadFanins( vTemp1, pFans1, nRange1, nRangeMax, Wlc_ObjIsSignedFanin01(p, pObj) ); int * pArg1 = Wlc_VecLoadFanins( vTemp1, pFans1, nRange1, nRangeMax, Wlc_ObjIsSignedFanin01(p, pObj) );
int CarryIn = Wlc_ObjFaninNum(pObj) == 3 ? pFans2[0] : 0;
if ( pObj->Type == WLC_OBJ_ARI_ADD ) if ( pObj->Type == WLC_OBJ_ARI_ADD )
Wlc_BlastAdder( pNew, pArg0, pArg1, nRange ); // result is in pFan0 (vRes) Wlc_BlastAdder( pNew, pArg0, pArg1, nRange, CarryIn ); // result is in pFan0 (vRes)
// Wlc_BlastAdderCLA( pNew, pArg0, pArg1, nRange ); // result is in pFan0 (vRes) // Wlc_BlastAdderCLA( pNew, pArg0, pArg1, nRange ); // result is in pFan0 (vRes)
else else
Wlc_BlastSubtract( pNew, pArg0, pArg1, nRange ); // result is in pFan0 (vRes) Wlc_BlastSubtract( pNew, pArg0, pArg1, nRange ); // result is in pFan0 (vRes)
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include "wlc.h" #include "wlc.h"
#include "base/main/mainInt.h" #include "base/main/mainInt.h"
#include "aig/miniaig/ndr.h"
ABC_NAMESPACE_IMPL_START ABC_NAMESPACE_IMPL_START
......
...@@ -801,6 +801,12 @@ static inline int Wlc_PrsFindDefinition( Wlc_Prs_t * p, char * pStr, Vec_Int_t * ...@@ -801,6 +801,12 @@ static inline int Wlc_PrsFindDefinition( Wlc_Prs_t * p, char * pStr, Vec_Int_t *
if ( !(pStr = Wlc_PrsReadName(p, pStr+1, vFanins)) ) if ( !(pStr = Wlc_PrsReadName(p, pStr+1, vFanins)) )
return 0; return 0;
pStr = Wlc_PrsSkipSpaces( pStr ); pStr = Wlc_PrsSkipSpaces( pStr );
if ( Type == WLC_OBJ_ARI_ADD && pStr[0] == '+' )
{
if ( !(pStr = Wlc_PrsReadName(p, pStr+1, vFanins)) )
return 0;
pStr = Wlc_PrsSkipSpaces( pStr );
}
if ( pStr[0] ) if ( pStr[0] )
printf( "Warning: Trailing symbols \"%s\" in line %d.\n", pStr, Wlc_PrsFindLine(p, pStr) ); printf( "Warning: Trailing symbols \"%s\" in line %d.\n", pStr, Wlc_PrsFindLine(p, pStr) );
} }
......
...@@ -355,6 +355,8 @@ void Wlc_WriteVerInt( FILE * pFile, Wlc_Ntk_t * p, int fNoFlops ) ...@@ -355,6 +355,8 @@ void Wlc_WriteVerInt( FILE * pFile, Wlc_Ntk_t * p, int fNoFlops )
else assert( 0 ); else assert( 0 );
//fprintf( pFile, "???" ); //fprintf( pFile, "???" );
fprintf( pFile, " %s", Wlc_ObjName(p, Wlc_ObjFaninId(pObj, 1)) ); fprintf( pFile, " %s", Wlc_ObjName(p, Wlc_ObjFaninId(pObj, 1)) );
if ( Wlc_ObjFaninNum(pObj) == 3 && pObj->Type == WLC_OBJ_ARI_ADD )
fprintf( pFile, " + %s", Wlc_ObjName(p, Wlc_ObjFaninId(pObj, 2)) );
} }
} }
fprintf( pFile, " ;%s\n", (p->fSmtLib && Wlc_ObjIsSigned(pObj)) ? " // signed SMT-LIB operator" : "" ); fprintf( pFile, " ;%s\n", (p->fSmtLib && Wlc_ObjIsSigned(pObj)) ? " // signed SMT-LIB operator" : "" );
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment