Commit 867600b7 by Alan Mishchenko

Supporting the decoder primitive in NDR and bit-blasting.

parent 5b588e09
......@@ -1542,7 +1542,7 @@ int Lf_ManSetMapRefs( Lf_Man_t * p )
}
if ( p->pGia->pManTime != NULL )
{
assert( Gia_ManBufNum(p->pGia) );
assert( !Gia_ManBufNum(p->pGia) );
Tim_ManIncrementTravId( (Tim_Man_t*)p->pGia->pManTime );
if ( p->pPars->fDoAverage )
for ( i = 0; i < Gia_ManCoNum(p->pGia); i++ )
......
......@@ -1005,6 +1005,38 @@ static inline void Ndr_ModuleTestSelSel()
Ndr_Delete( pDesign );
}
// This testing procedure creates and writes into a Verilog file
// the following design composed of one decoder
// module dec ( input [1:0] in, output [3:0] out );
// wire out0 = ~in[1] & ~in[0] ;
// wire out1 = ~in[1] & in[0] ;
// wire out2 = in[1] & ~in[0] ;
// wire out3 = in[1] & in[0] ;
// assign out = { out3, out2, out1, out0 } ;
// endmodule
static inline void Ndr_ModuleTestDec()
{
// map name IDs into char strings
char * ppNames[12] = { NULL, "dec", "in", "out" };
// name IDs
int NameIdIn = 2;
int NameIdOut = 3;
// create a new module
void * pDesign = Ndr_Create( 1 );
int ModuleID = Ndr_AddModule( pDesign, 1 );
// add objects to the modele
Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CI, 0, 1, 0, 0, 0, NULL, 1, &NameIdIn, NULL );
Ndr_AddObject( pDesign, ModuleID, ABC_OPER_SEL_DEC, 0, 3, 0, 0, 1, &NameIdIn, 1, &NameIdOut, NULL );
Ndr_AddObject( pDesign, ModuleID, ABC_OPER_CO, 0, 3, 0, 0, 1, &NameIdOut, 0, NULL, NULL );
Ndr_Write( "dec.ndr", pDesign );
Ndr_Delete( pDesign );
}
ABC_NAMESPACE_HEADER_END
......
......@@ -100,7 +100,8 @@ typedef enum {
WLC_OBJ_WRITE, // 55: write port
WLC_OBJ_ARI_ADDSUB, // 56: adder-subtractor
WLC_OBJ_SEL, // 57: positionally encoded selector
WLC_OBJ_NUMBER // 57: unused
WLC_OBJ_DEC, // 58: decoder
WLC_OBJ_NUMBER // 59: unused
} Wlc_ObjType_t;
// when adding new types, remember to update table Wlc_Names in "wlcNtk.c"
......
......@@ -836,6 +836,18 @@ void Wlc_BlastSquare( Gia_Man_t * pNew, int * pNum, int nNum, Vec_Int_t * vTmp,
Vec_WecFree( vProds );
Vec_WecFree( vLevels );
}
void Wlc_BlastDecoder( Gia_Man_t * pNew, int * pNum, int nNum, Vec_Int_t * vTmp, Vec_Int_t * vRes )
{
int i, k, nMints = 1 << nNum;
Vec_IntClear( vRes );
for ( i = 0; i < nMints; i++ )
{
int iMint = 1;
for ( k = 0; k < nNum; k++ )
iMint = Gia_ManHashAnd( pNew, iMint, Abc_LitNotCond(pNum[k], !((i >> k) & 1)) );
Vec_IntPush( vRes, iMint );
}
}
void Wlc_BlastBooth( Gia_Man_t * pNew, int * pArgA, int * pArgB, int nArgA, int nArgB, Vec_Int_t * vRes, int fSigned, int fCla )
{
Vec_Wec_t * vProds = Vec_WecStart( nArgA + nArgB + 3 );
......@@ -1514,6 +1526,15 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Wlc_BstPar_t * pParIn )
else
Vec_IntShrink( vRes, nRange );
}
else if ( pObj->Type == WLC_OBJ_DEC )
{
int * pArg0 = Wlc_VecLoadFanins( vTemp0, pFans0, nRange0, nRange0, 0 );
Wlc_BlastDecoder( pNew, pArg0, nRange0, vTemp2, vRes );
if ( nRange > Vec_IntSize(vRes) )
Vec_IntFillExtra( vRes, nRange, 0 );
else
Vec_IntShrink( vRes, nRange );
}
else if ( pObj->Type == WLC_OBJ_TABLE )
Wlc_BlastTable( pNew, Wlc_ObjTable(p, pObj), pFans0, nRange0, nRange, vRes );
else assert( 0 );
......
......@@ -1676,7 +1676,7 @@ int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv )
//Wlc_NtkSimulateTest( (Wlc_Ntk_t *)pAbc->pAbcWlc );
//pNtk = Wlc_NtkDupSingleNodes( pNtk );
//Wlc_AbcUpdateNtk( pAbc, pNtk );
Ndr_ModuleTestSelSel();
Ndr_ModuleTestDec();
//pNtk = Wlc_NtkMemAbstractTest( pNtk );
//Wlc_AbcUpdateNtk( pAbc, pNtk );
return 0;
......
......@@ -71,6 +71,7 @@ int Ndr_TypeNdr2Wlc( int Type )
if ( Type == ABC_OPER_LOGIC_XOR ) return WLC_OBJ_LOGIC_XOR; // 30: logic XOR
if ( Type == ABC_OPER_SEL_NMUX ) return WLC_OBJ_MUX; // 08: multiplexer
if ( Type == ABC_OPER_SEL_SEL ) return WLC_OBJ_SEL; // 57: selector
if ( Type == ABC_OPER_SEL_DEC ) return WLC_OBJ_DEC; // 58: decoder
if ( Type == ABC_OPER_COMP_EQU ) return WLC_OBJ_COMP_EQU; // 31: compare equal
if ( Type == ABC_OPER_COMP_NOTEQU ) return WLC_OBJ_COMP_NOTEQU; // 32: compare not equal
if ( Type == ABC_OPER_COMP_LESS ) return WLC_OBJ_COMP_LESS; // 33: compare less
......@@ -129,6 +130,7 @@ int Ndr_TypeWlc2Ndr( int Type )
if ( Type == WLC_OBJ_LOGIC_OR ) return ABC_OPER_LOGIC_OR; // 29: logic OR
if ( Type == WLC_OBJ_LOGIC_XOR ) return ABC_OPER_LOGIC_XOR; // 30: logic XOR
if ( Type == WLC_OBJ_SEL ) return ABC_OPER_SEL_SEL; // 57: selector
if ( Type == WLC_OBJ_DEC ) return ABC_OPER_SEL_DEC; // 58: decoder
if ( Type == WLC_OBJ_COMP_EQU ) return ABC_OPER_COMP_EQU; // 31: compare equal
if ( Type == WLC_OBJ_COMP_NOTEQU ) return ABC_OPER_COMP_NOTEQU; // 32: compare not equal
if ( Type == WLC_OBJ_COMP_LESS ) return ABC_OPER_COMP_LESS; // 33: compare less
......
......@@ -87,7 +87,10 @@ static char * Wlc_Names[WLC_OBJ_NUMBER+1] = {
"table", // 53: bit table
"READ", // 54: mem read port
"WRITE", // 55: mem write port
NULL // 56: unused
"addsub", // 56: adder/subtractor
"sel", // 57: selector
"dec", // 58: decoder
NULL // 58: unused
};
char * Wlc_ObjTypeName( Wlc_Obj_t * p ) { return Wlc_Names[p->Type]; }
......
......@@ -192,7 +192,7 @@ void Wlc_WriteVerInt( FILE * pFile, Wlc_Ntk_t * p, int fNoFlops )
continue;
fprintf( pFile, " assign " );
}
else if ( (pObj->Type == WLC_OBJ_MUX && Wlc_ObjFaninNum(pObj) > 3) || pObj->Type == WLC_OBJ_FF )
else if ( (pObj->Type == WLC_OBJ_MUX && Wlc_ObjFaninNum(pObj) > 3) || pObj->Type == WLC_OBJ_FF || pObj->Type == WLC_OBJ_SEL )
fprintf( pFile, "reg %s ", Range );
else
fprintf( pFile, "wire %s ", Range );
......@@ -275,12 +275,49 @@ void Wlc_WriteVerInt( FILE * pFile, Wlc_Ntk_t * p, int fNoFlops )
fprintf( pFile, " : %s = ", Wlc_ObjName(p, i) );
fprintf( pFile, "%s ;\n", Wlc_ObjName(p, Wlc_ObjFaninId(pObj, k)) );
}
fprintf( pFile, " " );
fprintf( pFile, "default" );
fprintf( pFile, " : %s = ", Wlc_ObjName(p, i) );
fprintf( pFile, "%d\'b", Wlc_ObjRange(pObj) );
for ( j = Wlc_ObjRange(pObj)-1; j >= 0; j-- )
fprintf( pFile, "%d", 0 );
fprintf( pFile, " ;\n" );
fprintf( pFile, " " );
fprintf( pFile, "endcase\n" );
fprintf( pFile, " " );
fprintf( pFile, "end\n" );
continue;
}
else if ( pObj->Type == WLC_OBJ_DEC )
{
int nRange = Wlc_ObjRange(Wlc_ObjFanin0(p, pObj));
assert( (1 << nRange) == Wlc_ObjRange(pObj) );
fprintf( pFile, "%s ;\n", Wlc_ObjName(p, i) );
for ( k = 0; k < Wlc_ObjRange(pObj); k++ )
{
fprintf( pFile, " " );
fprintf( pFile, "wire " );
fprintf( pFile, "%s_", Wlc_ObjName(p, i) );
for ( j = 0; j < nRange; j++ )
fprintf( pFile, "%d", (k >> (nRange-1-j)) & 1 );
fprintf( pFile, " = " );
for ( j = 0; j < nRange; j++ )
fprintf( pFile, "%s%s%s[%d]",
j ? " & ":"", ((k >> (nRange-1-j)) & 1) ? " ":"~",
Wlc_ObjName(p, Wlc_ObjFaninId(pObj, 0)), nRange-1-j );
fprintf( pFile, " ;\n" );
}
fprintf( pFile, " " );
fprintf( pFile, "assign %s = { ", Wlc_ObjName(p, i) );
for ( k = Wlc_ObjRange(pObj)-1; k >= 0; k-- )
{
fprintf( pFile, "%s%s_", k < Wlc_ObjRange(pObj)-1 ? ", ":"", Wlc_ObjName(p, i) );
for ( j = 0; j < nRange; j++ )
fprintf( pFile, "%d", (k >> (nRange-1-j)) & 1 );
}
fprintf( pFile, " } ;\n" );
continue;
}
else if ( pObj->Type == WLC_OBJ_READ || pObj->Type == WLC_OBJ_WRITE )
{
if ( p->fMemPorts )
......
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