448{
449 FILE * pFile;
451 char * pSopString;
452 int LevelMin, LevelMax, fHasCos, Level, i, k, fHasBdds, fCompl, Prev;
453 int Limit = 300;
454
455 assert( Abc_NtkIsStrash(pNtk) || Abc_NtkIsLogic(pNtk) );
456
457 if ( vNodes->nSize < 1 )
458 {
459 printf( "The set has no nodes. DOT file is not written.\n" );
460 return;
461 }
462
463 if ( vNodes->nSize > Limit )
464 {
465 printf( "The set has more than %d nodes. DOT file is not written.\n", Limit );
466 return;
467 }
468
469
470 if ( (pFile = fopen( pFileName, "w" )) == NULL )
471 {
472 fprintf( stdout, "Cannot open the intermediate file \"%s\".\n", pFileName );
473 return;
474 }
475
476
477 if ( (fHasBdds = Abc_NtkIsBddLogic(pNtk)) )
478 {
480 {
481 printf( "Io_WriteDotNtk(): Converting to SOPs has failed.\n" );
482 return;
483 }
484 }
485
486
489 if ( vNodesShow )
492
493
495 if ( fUseReverse )
496 {
498 assert( LevelMax == LevelMin );
500 if ( Abc_ObjIsNode(pNode) )
502 }
503
504
505 LevelMin = 10000;
506 LevelMax = -1;
507 fHasCos = 0;
509 {
510 if ( Abc_ObjIsCo(pNode) )
511 {
512 fHasCos = 1;
513 continue;
514 }
515 if ( LevelMin > (
int)pNode->
Level )
516 LevelMin = pNode->
Level;
517 if ( LevelMax < (
int)pNode->
Level )
518 LevelMax = pNode->
Level;
519 }
520
521
522 if ( fHasCos )
523 {
524 LevelMax++;
526 {
527 if ( Abc_ObjIsCo(pNode) )
528 pNode->
Level = LevelMax;
529 }
530 }
531
532
533 fprintf( pFile, "# %s\n", "Network structure generated by ABC" );
534 fprintf( pFile, "\n" );
535 fprintf( pFile, "digraph network {\n" );
536 fprintf( pFile, "size = \"7.5,10\";\n" );
537
538
539
540
541
542 fprintf( pFile, "center = true;\n" );
543
544
545
546 fprintf( pFile, "edge [dir = back];\n" );
547 fprintf( pFile, "\n" );
548
549
550 fprintf( pFile, "{\n" );
551 fprintf( pFile, " node [shape = plaintext];\n" );
552 fprintf( pFile, " edge [style = invis];\n" );
553 fprintf( pFile, " LevelTitle1 [label=\"\"];\n" );
554 fprintf( pFile, " LevelTitle2 [label=\"\"];\n" );
555
556 for ( Level = LevelMax; Level >= LevelMin; Level-- )
557 {
558
559 fprintf( pFile, " Level%d", Level );
560 fprintf( pFile, " [label = " );
561
562 fprintf( pFile, "\"" );
563 fprintf( pFile, "\"" );
564 fprintf( pFile, "];\n" );
565 }
566
567
568 fprintf( pFile, " LevelTitle1 -> LevelTitle2 ->" );
569 for ( Level = LevelMax; Level >= LevelMin; Level-- )
570 {
571
572 fprintf( pFile, " Level%d", Level );
573
574 if ( Level != LevelMin )
575 fprintf( pFile, " ->" );
576 else
577 fprintf( pFile, ";" );
578 }
579 fprintf( pFile, "\n" );
580 fprintf( pFile, "}" );
581 fprintf( pFile, "\n" );
582 fprintf( pFile, "\n" );
583
584
585 fprintf( pFile, "{\n" );
586 fprintf( pFile, " rank = same;\n" );
587 fprintf( pFile, " LevelTitle1;\n" );
588 fprintf( pFile, " title1 [shape=plaintext,\n" );
589 fprintf( pFile, " fontsize=20,\n" );
590 fprintf( pFile, " fontname = \"Times-Roman\",\n" );
591 fprintf( pFile, " label=\"" );
592 fprintf( pFile, "%s", "Network structure visualized by ABC" );
593 fprintf( pFile, "\\n" );
594 fprintf( pFile,
"Benchmark \\\"%s\\\". ", pNtk->
pName );
596 fprintf( pFile, "\"\n" );
597 fprintf( pFile, " ];\n" );
598 fprintf( pFile, "}" );
599 fprintf( pFile, "\n" );
600 fprintf( pFile, "\n" );
601
602
603 fprintf( pFile, "{\n" );
604 fprintf( pFile, " rank = same;\n" );
605 fprintf( pFile, " LevelTitle2;\n" );
606 fprintf( pFile, " title2 [shape=plaintext,\n" );
607 fprintf( pFile, " fontsize=18,\n" );
608 fprintf( pFile, " fontname = \"Times-Roman\",\n" );
609 fprintf( pFile, " label=\"" );
610 if ( Abc_NtkObjNum(pNtk) == Vec_PtrSize(vNodes) )
611 fprintf( pFile, "The network contains %d logic nodes and %d latches.", Abc_NtkNodeNum(pNtk), Abc_NtkLatchNum(pNtk) );
612 else
613 fprintf( pFile, "The set contains %d logic nodes and spans %d levels.", Abc_NtkCountLogicNodes(vNodes), LevelMax - LevelMin + 1 );
614 fprintf( pFile, "\\n" );
615 fprintf( pFile, "\"\n" );
616 fprintf( pFile, " ];\n" );
617 fprintf( pFile, "}" );
618 fprintf( pFile, "\n" );
619 fprintf( pFile, "\n" );
620
621
622 if ( fHasCos )
623 {
624 fprintf( pFile, "{\n" );
625 fprintf( pFile, " rank = same;\n" );
626
627 fprintf( pFile, " Level%d;\n", LevelMax );
628
630 {
631 if ( !Abc_ObjIsPo(pNode) )
632 continue;
633 fprintf( pFile,
" Node%d [label = \"%s\"", pNode->
Id,
Abc_ObjName(pNode) );
634 fprintf( pFile, ", shape = %s", "invtriangle" );
636 fprintf( pFile, ", style = filled" );
637 fprintf( pFile, ", color = coral, fillcolor = coral" );
638 fprintf( pFile, "];\n" );
639 }
640 fprintf( pFile, "}" );
641 fprintf( pFile, "\n" );
642 fprintf( pFile, "\n" );
643 }
644
645
646 for ( Level = LevelMax - fHasCos; Level >= LevelMin && Level > 0; Level-- )
647 {
648 fprintf( pFile, "{\n" );
649 fprintf( pFile, " rank = same;\n" );
650
651 fprintf( pFile, " Level%d;\n", Level );
653 {
654 if ( (
int)pNode->
Level != Level )
655 continue;
656
657 if ( Abc_NtkIsStrash(pNtk) )
658 pSopString = "";
659 else if ( Abc_NtkHasMapping(pNtk) && fGateNames )
661 else if ( Abc_NtkHasMapping(pNtk) )
663 else
665 fprintf( pFile,
" Node%d [label = \"%d\\n%s\"", pNode->
Id, pNode->
Id, pSopString );
666
667 fprintf( pFile, ", shape = ellipse" );
669 fprintf( pFile, ", style = filled" );
670 fprintf( pFile, "];\n" );
671 }
672 fprintf( pFile, "}" );
673 fprintf( pFile, "\n" );
674 fprintf( pFile, "\n" );
675 }
676
677
678 if ( LevelMin == 0 )
679 {
680 fprintf( pFile, "{\n" );
681 fprintf( pFile, " rank = same;\n" );
682
683 fprintf( pFile, " Level%d;\n", LevelMin );
684
686 {
687 if ( pNode->
Level > 0 )
688 continue;
689 if ( !Abc_ObjIsPi(pNode) )
690 {
691
692 if ( Abc_ObjFaninNum(pNode) == 0 && Abc_ObjFanoutNum(pNode) > 0 )
693 {
694 fprintf( pFile,
" Node%d [label = \"Const1\"", pNode->
Id );
695 fprintf( pFile, ", shape = ellipse" );
697 fprintf( pFile, ", style = filled" );
698 fprintf( pFile, ", color = coral, fillcolor = coral" );
699 fprintf( pFile, "];\n" );
700 }
701 continue;
702 }
703 fprintf( pFile,
" Node%d [label = \"%s\"", pNode->
Id,
Abc_ObjName(pNode) );
704 fprintf( pFile, ", shape = %s", "triangle" );
706 fprintf( pFile, ", style = filled" );
707 fprintf( pFile, ", color = coral, fillcolor = coral" );
708 fprintf( pFile, "];\n" );
709 }
710 fprintf( pFile, "}" );
711 fprintf( pFile, "\n" );
712 fprintf( pFile, "\n" );
713 }
714
715
717 {
718 if ( !Abc_ObjIsLatch(pNode) )
719 continue;
720 fprintf( pFile,
"Node%d [label = \"%s\"", pNode->
Id,
Abc_ObjName(pNode) );
721 fprintf( pFile, ", shape = box" );
723 fprintf( pFile, ", style = filled" );
724 fprintf( pFile, ", color = coral, fillcolor = coral" );
725 fprintf( pFile, "];\n" );
726 }
727
728
729 fprintf( pFile, "\n" );
730
731
732 fprintf( pFile, "title1 -> title2 [style = invis];\n" );
734 {
735 if ( (
int)pNode->
Level != LevelMax )
736 continue;
737 if ( !Abc_ObjIsPo(pNode) )
738 continue;
739 fprintf( pFile,
"title2 -> Node%d [style = invis];\n", pNode->
Id );
740 }
741
742 Prev = -1;
744 {
745 if ( (
int)pNode->
Level != LevelMax )
746 continue;
747 if ( !Abc_ObjIsPo(pNode) )
748 continue;
749 if ( Prev >= 0 )
750 fprintf( pFile,
"Node%d -> Node%d [style = invis];\n", Prev, pNode->
Id );
752 }
753
754
756 {
757 if ( Abc_ObjIsBi(pNode) || Abc_ObjIsBo(pNode) )
758 continue;
760 {
761 fCompl = 0;
762 if ( Abc_NtkIsStrash(pNtk) )
763 {
764 if ( Abc_ObjIsBi(pFanin) )
765 fCompl = Abc_ObjFaninC(pFanin, k);
766 else
767 fCompl = Abc_ObjFaninC(pNode, k);
768 }
769 if ( Abc_ObjIsBi(pFanin) || Abc_ObjIsBo(pFanin) )
770 pFanin = Abc_ObjFanin0(pFanin);
771 if ( Abc_ObjIsBi(pFanin) || Abc_ObjIsBo(pFanin) )
772 pFanin = Abc_ObjFanin0(pFanin);
774 continue;
775
776
777 fprintf( pFile,
"Node%d", pNode->
Id );
778 fprintf( pFile, " -> " );
779 fprintf( pFile,
"Node%d", pFanin->
Id );
780 fprintf( pFile, " [style = %s", fCompl? "dotted" : "solid" );
781
782 fprintf( pFile, "]" );
783 fprintf( pFile, ";\n" );
784 }
785 }
786
787 fprintf( pFile, "}" );
788 fprintf( pFile, "\n" );
789 fprintf( pFile, "\n" );
790 fclose( pFile );
791
792
795 if ( vNodesShow )
798
799
800 if ( fHasBdds )
802}
#define Abc_NtkForEachNode(pNtk, pNode, i)