#include "wlc.h"
ABC_NAMESPACE_IMPL_START
void Wlc_NtkDumpDot( Wlc_Ntk_t * p, char * pFileName, Vec_Int_t * vBold )
{
FILE * pFile;
Wlc_Obj_t * pNode;
int LevelMax, Prev, Level, i;
if ( vBold ? (Vec_IntSize(vBold) > 2000) : (Wlc_NtkObjNum(p) > 2000) )
{
fprintf( stdout, "Cannot visualize WLC with more than %d nodes.\n", 2000 );
return;
}
if ( (pFile = fopen( pFileName, "w" )) == NULL )
{
fprintf( stdout, "Cannot open the intermediate file \"%s\".\n", pFileName );
return;
}
if ( vBold )
Wlc_NtkForEachObjVec( vBold, p, pNode, i )
pNode->Mark = 1;
LevelMax = 1 + Wlc_NtkCreateLevels( p );
if ( vBold )
LevelMax = Wlc_NtkRemapLevels( p, vBold, LevelMax );
fprintf( pFile, "# %s\n", "WLC structure generated by ABC" );
fprintf( pFile, "\n" );
fprintf( pFile, "digraph WLC {\n" );
fprintf( pFile, "size = \"7.5,10\";\n" );
fprintf( pFile, "center = true;\n" );
fprintf( pFile, "edge [dir = back];\n" );
fprintf( pFile, "\n" );
fprintf( pFile, "{\n" );
fprintf( pFile, " node [shape = plaintext];\n" );
fprintf( pFile, " edge [style = invis];\n" );
fprintf( pFile, " LevelTitle1 [label=\"\"];\n" );
fprintf( pFile, " LevelTitle2 [label=\"\"];\n" );
for ( Level = LevelMax; Level >= 0; Level-- )
{
fprintf( pFile, " Level%d", Level );
fprintf( pFile, " [label = " );
fprintf( pFile, "\"" );
fprintf( pFile, "\"" );
fprintf( pFile, "];\n" );
}
fprintf( pFile, " LevelTitle1 -> LevelTitle2 ->" );
for ( Level = LevelMax; Level >= 0; Level-- )
{
fprintf( pFile, " Level%d", Level );
if ( Level != 0 )
fprintf( pFile, " ->" );
else
fprintf( pFile, ";" );
}
fprintf( pFile, "\n" );
fprintf( pFile, "}" );
fprintf( pFile, "\n" );
fprintf( pFile, "\n" );
fprintf( pFile, "{\n" );
fprintf( pFile, " rank = same;\n" );
fprintf( pFile, " LevelTitle1;\n" );
fprintf( pFile, " title1 [shape=plaintext,\n" );
fprintf( pFile, " fontsize=20,\n" );
fprintf( pFile, " fontname = \"Times-Roman\",\n" );
fprintf( pFile, " label=\"" );
fprintf( pFile, "%s", "WLC structure generated by ABC" );
fprintf( pFile, "\\n" );
fprintf( pFile, "Benchmark \\\"%s\\\" from file \\\"%s\\\". ", p->pName, p->pSpec ? Extra_FileNameWithoutPath(p->pSpec) : "unknown" );
fprintf( pFile, "\"\n" );
fprintf( pFile, " ];\n" );
fprintf( pFile, "}" );
fprintf( pFile, "\n" );
fprintf( pFile, "\n" );
fprintf( pFile, "{\n" );
fprintf( pFile, " rank = same;\n" );
fprintf( pFile, " LevelTitle2;\n" );
fprintf( pFile, " title2 [shape=plaintext,\n" );
fprintf( pFile, " fontsize=18,\n" );
fprintf( pFile, " fontname = \"Times-Roman\",\n" );
fprintf( pFile, " label=\"" );
fprintf( pFile, "The word-level network contains %d nodes and spans %d levels.", Wlc_NtkObjNum(p)-Wlc_NtkCiNum(p), LevelMax-1 );
fprintf( pFile, "\\n" );
fprintf( pFile, "\"\n" );
fprintf( pFile, " ];\n" );
fprintf( pFile, "}" );
fprintf( pFile, "\n" );
fprintf( pFile, "\n" );
fprintf( pFile, "{\n" );
fprintf( pFile, " rank = same;\n" );
fprintf( pFile, " Level%d;\n", LevelMax );
Wlc_NtkForEachCo( p, pNode, i )
{
if ( vBold && !pNode->Mark )
continue;
pNode = Wlc_ObjCo2PoFo(p, i);
fprintf( pFile, " NodePo%d [label = \"%s%s %d\"", Wlc_ObjId(p, pNode), Wlc_ObjName(p, Wlc_ObjId(p, pNode)), Wlc_ObjIsPo(pNode)? "":"_in", Wlc_ObjRange(pNode) );
fprintf( pFile, ", shape = %s", i < Wlc_NtkPoNum(p) ? "invtriangle" : "box" );
fprintf( pFile, ", color = coral, fillcolor = coral" );
fprintf( pFile, "];\n" );
}
fprintf( pFile, "}" );
fprintf( pFile, "\n" );
fprintf( pFile, "\n" );
for ( Level = LevelMax - 1; Level > 0; Level-- )
{
fprintf( pFile, "{\n" );
fprintf( pFile, " rank = same;\n" );
fprintf( pFile, " Level%d;\n", Level );
Wlc_NtkForEachObj( p, pNode, i )
{
if ( (int)Wlc_ObjLevel(p, pNode) != Level )
continue;
if ( vBold && !pNode->Mark )
continue;
if ( pNode->Type == WLC_OBJ_CONST )
{
fprintf( pFile, " Node%d [label = \"%d:%d\'h", i, i, Wlc_ObjRange(pNode) );
if ( Wlc_ObjRange(pNode) > 64 )
{
Abc_TtPrintHexArrayRev( pFile, (word *)Wlc_ObjConstValue(pNode), 16 );
fprintf( pFile, "..." );
}
else
Abc_TtPrintHexArrayRev( pFile, (word *)Wlc_ObjConstValue(pNode), (Wlc_ObjRange(pNode) + 3) / 4 );
fprintf( pFile, "\"" );
}
else if ( pNode->Type == WLC_OBJ_BUF || pNode->Type == WLC_OBJ_MUX )
fprintf( pFile, " Node%d [label = \"%d: %d\"", i, i, Wlc_ObjRange(pNode) );
else if ( pNode->Type >= WLC_OBJ_LOGIC_NOT && pNode->Type <= WLC_OBJ_COMP_MOREEQU )
fprintf( pFile, " Node%d [label = \"%d:%s\"", i, i, Wlc_ObjTypeName(pNode) );
else
fprintf( pFile, " Node%d [label = \"%d:%s %d\"", i, i, Wlc_ObjTypeName(pNode), Wlc_ObjRange(pNode) );
if ( pNode->Type == WLC_OBJ_ARI_MULTI )
fprintf( pFile, ", shape = doublecircle" );
else if ( pNode->Type >= WLC_OBJ_COMP_EQU && pNode->Type <= WLC_OBJ_COMP_MOREEQU )
fprintf( pFile, ", shape = diamond" );
else if ( pNode->Type == WLC_OBJ_BIT_SELECT || pNode->Type == WLC_OBJ_BIT_CONCAT || pNode->Type == WLC_OBJ_FF )
fprintf( pFile, ", shape = box" );
else if ( pNode->Type == WLC_OBJ_BUF || pNode->Type == WLC_OBJ_BIT_ZEROPAD || pNode->Type == WLC_OBJ_BIT_SIGNEXT )
fprintf( pFile, ", shape = triangle" );
else if ( pNode->Type == WLC_OBJ_MUX )
fprintf( pFile, ", shape = trapezium" );
else
fprintf( pFile, ", shape = ellipse" );
if ( vBold ? pNode->Mark : ((pNode->Type >= WLC_OBJ_ARI_ADD && pNode->Type <= WLC_OBJ_ARI_SQUARE) || pNode->Type == WLC_OBJ_BIT_NOT) )
fprintf( pFile, ", style = filled" );
fprintf( pFile, "];\n" );
}
fprintf( pFile, "}" );
fprintf( pFile, "\n" );
fprintf( pFile, "\n" );
}
fprintf( pFile, "{\n" );
fprintf( pFile, " rank = same;\n" );
fprintf( pFile, " Level%d;\n", 0 );
Wlc_NtkForEachObj( p, pNode, i )
{
if ( !Wlc_ObjIsCi(pNode) && Wlc_ObjFaninNum(pNode) > 0 )
continue;
if ( vBold && !pNode->Mark )
continue;
if ( pNode->Type == WLC_OBJ_CONST )
{
fprintf( pFile, " Node%d [label = \"%d:%d\'h", i, i, Wlc_ObjRange(pNode) );
if ( Wlc_ObjRange(pNode) > 64 )
{
Abc_TtPrintHexArrayRev( pFile, (word *)Wlc_ObjConstValue(pNode), 16 );
fprintf( pFile, "..." );
}
else
Abc_TtPrintHexArrayRev( pFile, (word *)Wlc_ObjConstValue(pNode), (Wlc_ObjRange(pNode) + 3) / 4 );
fprintf( pFile, "\"" );
}
else
{
fprintf( pFile, " Node%d [label = \"%d:%s %d\"", Wlc_ObjId(p, pNode), Wlc_ObjId(p, pNode), Wlc_ObjName(p, Wlc_ObjId(p, pNode)), Wlc_ObjRange(pNode) );
fprintf( pFile, ", shape = %s", (Vec_IntSize(&p->vFfs2) > 0 || Wlc_ObjCiId(pNode) < Wlc_NtkPiNum(p)) ? "triangle" : "box" );
fprintf( pFile, ", color = coral, fillcolor = coral" );
}
fprintf( pFile, "];\n" );
}
fprintf( pFile, "}" );
fprintf( pFile, "\n" );
fprintf( pFile, "\n" );
fprintf( pFile, "title1 -> title2 [style = invis];\n" );
Wlc_NtkForEachCo( p, pNode, i )
{
if ( vBold && !pNode->Mark )
continue;
pNode = Wlc_ObjCo2PoFo( p, i );
fprintf( pFile, "title2 -> NodePo%d [style = invis];\n", Wlc_ObjId(p, pNode) );
}
Prev = -1;
Wlc_NtkForEachCo( p, pNode, i )
{
pNode = Wlc_ObjCo2PoFo( p, i );
if ( vBold && !pNode->Mark )
continue;
if ( Prev >= 0 )
fprintf( pFile, "NodePo%d -> NodePo%d [style = invis];\n", Prev, Wlc_ObjId(p, pNode) );
Prev = Wlc_ObjId(p, pNode);
}
Prev = -1;
Wlc_NtkForEachCi( p, pNode, i )
{
if ( vBold && !pNode->Mark )
continue;
if ( Prev >= 0 )
fprintf( pFile, "Node%d -> Node%d [style = invis];\n", Prev, Wlc_ObjId(p, pNode) );
Prev = Wlc_ObjId(p, pNode);
}
Wlc_NtkForEachCo( p, pNode, i )
{
if ( vBold && !pNode->Mark )
continue;
fprintf( pFile, "NodePo%d", Wlc_ObjId(p, Wlc_ObjCo2PoFo(p, i)) );
fprintf( pFile, " -> " );
fprintf( pFile, "Node%d", Wlc_ObjId(p, pNode) );
fprintf( pFile, " [" );
fprintf( pFile, "style = %s", pNode->Signed? "dotted" : "solid" );
fprintf( pFile, "]" );
fprintf( pFile, ";\n" );
}
Wlc_NtkForEachObj( p, pNode, i )
{
int k, iFanin;
if ( Wlc_ObjIsCi(pNode) )
continue;
if ( vBold && !pNode->Mark )
continue;
Wlc_ObjForEachFanin( pNode, iFanin, k ) if ( iFanin )
{
fprintf( pFile, "Node%d", i );
fprintf( pFile, " -> " );
fprintf( pFile, "Node%d", iFanin );
fprintf( pFile, " [" );
fprintf( pFile, "style = %s", Wlc_NtkObj(p, iFanin)->Signed? "dotted" : "solid" );
if ( pNode->Type == WLC_OBJ_MUX && k == 0 )
fprintf( pFile, ", style = %s", "bold" );
fprintf( pFile, "]" );
fprintf( pFile, ";\n" );
}
}
fprintf( pFile, "}" );
fprintf( pFile, "\n" );
fprintf( pFile, "\n" );
fclose( pFile );
if ( vBold )
Wlc_NtkCleanMarks( p );
}
void Wlc_NtkShow( Wlc_Ntk_t * p, Vec_Int_t * vBold )
{
extern void Abc_ShowFile( char * FileNameDot, int fKeepDot );
FILE * pFile;
char FileNameDot[200];
char * pName = Extra_FileDesignName(p->pName);
char * pSpec = p->pSpec ? Extra_FileDesignName(p->pSpec) : (char *)"unknown";
sprintf( FileNameDot, "%s_%s.dot", pName, pSpec );
ABC_FREE( pName );
if ( strcmp(pSpec, "unknown") )
ABC_FREE( pSpec );
if ( (pFile = fopen( FileNameDot, "w" )) == NULL )
{
fprintf( stdout, "Cannot open the intermediate file \"%s\".\n", FileNameDot );
return;
}
fclose( pFile );
Wlc_NtkDumpDot( p, FileNameDot, vBold );
Abc_ShowFile( FileNameDot, 0 );
}
ABC_NAMESPACE_IMPL_END