Difference between revisions of "Post processing port resolution of black boxes"

From Verific Design Automation FAQ
Jump to: navigation, search
(Created page with "C++ example: <nowiki> #include "Map.h" #include "Message.h" #include "veri_file.h" #include "DataBase.h" #include "VeriWrite.h" #include "Run...")
 
 
Line 36: Line 36:
 
     vw.WriteFile ("netlist_before.v", top) ;
 
     vw.WriteFile ("netlist_before.v", top) ;
  
     MapIter mi ;
+
     // Lets accumulate all netlist
     Instance * instance ;
+
     Set netlists(POINTER_HASH) ;
     FOREACH_INSTANCE_OF_NETLIST(top, mi, instance) {
+
     top->Hierarchy(netlists, 0 /* bottom to top */) ;
        Netlist *view = instance->View() ;
+
 
         if (!view) continue ;
+
    Netlist *netlist ;
         if (view->GetAtt(" unknown_design")) {
+
    SetIter si ;
             std::cout << "===> Instance '" <<  instance->Name() << "' is of unknown module '"
+
 
                      << instance->View()->Owner()->Name() << "'"<< std::endl ;
+
    unsigned changed = 0 ;
            MapIter mi2 ;
+
    unsigned pass = 1 ;
            PortRef *portref ;
+
    do { // do this until there are no changes in port directions of 'unknown' modules
            FOREACH_PORTREF_OF_INST(instance, mi2, portref) {
+
        std::cout << std::endl << "=> Pass " <<  pass++ << std::endl ;
                unsigned dir_known = 0 ;
+
         changed = 0 ;
                Port *port = portref->GetPort() ;
+
         FOREACH_SET_ITEM(&netlists, si, &netlist) {
                std::cout << "===>    Port: '" << port->Name() << "'"<< std::endl ;
+
            if (!netlist->GetAtt(" unknown_design")) continue ; // Skip if not 'unknown'
                Net *net = portref->GetNet() ;
+
            Instance *instance ;
                if (!net) {
+
            SetIter si2 ;
                    std::cout << "===>    Does not connect to any Net" << std::endl ;
+
            // Iterate over all references (Instances) of this Netlist
                    continue ;
+
             FOREACH_REFERENCE_OF_NETLIST(netlist, si2, instance) {
                }
+
                std::cout << "===> Instance '" <<  instance->Name() << "' of unknown module '"
                // Is this port connected to any Port?
+
                          << netlist->Owner()->Name() << "'"<< std::endl ;
                Port *port2 ;
+
                MapIter mi2 ;
                SetIter si ;
+
                PortRef *portref ;
                FOREACH_PORT_OF_NET(net, si, port2) {
+
                FOREACH_PORTREF_OF_INST(instance, mi2, portref) {
                    if (port2->IsInput()) {
+
                    Port *port = portref->GetPort() ;
                        std::cout << "===>        Connected to input port '" << port2->Name() << "' of owning Netlist" << std::endl ;
+
                    if (!port->IsInout()) continue ; // Only look at inout ports
                        std::cout << "===>            Set port '" << port->Name() << "' to input" << std::endl ;
+
                    unsigned dir_known = 0 ;
                        view->GetPort(port->Name())->SetDir(DIR_IN) ;
+
                    std::cout << "===>    Port: '" << port->Name() << "'"<< std::endl ;
                        dir_known = 1 ;
+
                    Net *net = portref->GetNet() ;
                    } else if (port2->IsOutput()) {
+
                    if (!net) {
                        if (net->NumOfPortRefs() == 1 ) { // does not connected to any other instance
+
                        std::cout << "===>    Does not connect to any Net" << std::endl ;
                            std::cout << "===>        Only connected to output port '" << port2->Name() << "' of owning Netlist" << std::endl ;
+
                        continue ;
                            std::cout << "===>            Set port '" << port->Name() << "' to output" << std::endl ;
+
                            view->GetPort(port->Name())->SetDir(DIR_OUT) ;
+
                            dir_known = 1 ;
+
                        }
+
 
                     }
 
                     }
                }
+
                    // Is this port connected to any Port?
                // If still don't know direction, check other connections
+
                     Port *port2 ;
                if (!dir_known) {
+
                     SetIter si ;
                     PortRef *portref2 ;
+
                     FOREACH_PORT_OF_NET(net, si, port2) {
                     SetIter si2 ;
+
                         if (port2->IsInput()) {
                     FOREACH_PORTREF_OF_NET(net, si2, portref2) {
+
                             std::cout << "===>        Connected to input port '" << port2->Name() << "' of owning Netlist" << std::endl ;
                         if (portref2 == portref) continue ; // not checking self
+
                        if (portref2->IsOutput()) { // connected to an output portref, must be an input port
+
                            Instance *instance2 = portref2->GetInst() ;
+
                            Port *port3 = portref2->GetPort() ;
+
                             std::cout << "===>        Connected to output port '" << port3->Name()
+
                                      << "' of instance ' " << instance2->Name() << "'" << std::endl ;
+
 
                             std::cout << "===>            Set port '" << port->Name() << "' to input" << std::endl ;
 
                             std::cout << "===>            Set port '" << port->Name() << "' to input" << std::endl ;
                             view->GetPort(port->Name())->SetDir(DIR_IN) ;
+
                             netlist->GetPort(port->Name())->SetDir(DIR_IN) ;
                            dir_known = 1 ;
+
                            break ;
+
                        } else if (portref2->IsInout()) { // connected to an inout portref, still don't know direction
+
                            break ;
+
                        } else { // all portrefs are inputs, must be an output port
+
                            std::cout << "===>            All other PortRefs are inputs" << std::endl ;
+
                            std::cout << "===>            Set port '" << port->Name() << "' to output" << std::endl ;
+
                            view->GetPort(port->Name())->SetDir(DIR_OUT) ;
+
 
                             dir_known = 1 ;
 
                             dir_known = 1 ;
 +
                            changed = 1 ;
 +
                        } else if (port2->IsOutput()) {
 +
                            if (net->NumOfPortRefs() == 1 ) { // does not connected to any other instance
 +
                                std::cout << "===>        Only connected to output port '" << port2->Name() << "' of owning Netlist" << std::endl ;
 +
                                std::cout << "===>            Set port '" << port->Name() << "' to output" << std::endl ;
 +
                                netlist->GetPort(port->Name())->SetDir(DIR_OUT) ;
 +
                                dir_known = 1 ;
 +
                                changed = 1 ;
 +
                            }
 
                         }
 
                         }
 
                     }
 
                     }
                }
+
                    // If still don't know direction, check other connections
                if (!dir_known) { // Still clueless
+
                    if (!dir_known) {
                    std::cout << "===>        Not enough data, remains inout" << std::endl ;
+
                        PortRef *portref2 ;
 +
                        SetIter si2 ;
 +
                        FOREACH_PORTREF_OF_NET(net, si2, portref2) {
 +
                            if (portref2 == portref) continue ; // not checking self
 +
                            if (portref2->IsOutput()) { // connected to an output portref, must be an input port
 +
                                Instance *instance2 = portref2->GetInst() ;
 +
                                Port *port3 = portref2->GetPort() ;
 +
                                std::cout << "===>        Connected to output port '" << port3->Name()
 +
                                          << "' of instance ' " << instance2->Name() << "'" << std::endl ;
 +
                                std::cout << "===>            Set port '" << port->Name() << "' to input" << std::endl ;
 +
                                netlist->GetPort(port->Name())->SetDir(DIR_IN) ;
 +
                                dir_known = 1 ;
 +
                                changed = 1 ;
 +
                                break ;
 +
                            } else if (portref2->IsInout()) { // connected to an inout portref, still don't know direction
 +
                                break ;
 +
                            } else { // all portrefs are inputs, must be an output port
 +
                                std::cout << "===>            All other PortRefs are inputs" << std::endl ;
 +
                                std::cout << "===>            Set port '" << port->Name() << "' to output" << std::endl ;
 +
                                netlist->GetPort(port->Name())->SetDir(DIR_OUT) ;
 +
                                dir_known = 1 ;
 +
                                changed = 1 ;
 +
                            }
 +
                        }
 +
                    }
 +
                    if (!dir_known) { // Still clueless
 +
                        std::cout << "===>        Not enough data, remains inout" << std::endl ;
 +
                    }
 
                 }
 
                 }
 
             }
 
             }
 
         }
 
         }
     }
+
     } while (changed) ;
  
 
     vw.WriteFile ("netlist_after.v", top) ;
 
     vw.WriteFile ("netlist_after.v", top) ;
Line 119: Line 137:
 
-- Analyzing Verilog file 'test.v' (VERI-1482)
 
-- Analyzing Verilog file 'test.v' (VERI-1482)
 
test.v(1): INFO: compiling module 'top' (VERI-1018)
 
test.v(1): INFO: compiling module 'top' (VERI-1018)
test.v(9): INFO: compiling module 'known1' (VERI-1018)
+
test.v(11): INFO: compiling module 'known1' (VERI-1018)
test.v(12): INFO: compiling module 'known2' (VERI-1018)
+
test.v(14): INFO: compiling module 'known2' (VERI-1018)
 
test.v(5): WARNING: instantiating unknown module 'unknown1' (VERI-1063)
 
test.v(5): WARNING: instantiating unknown module 'unknown1' (VERI-1063)
 
test.v(6): WARNING: instantiating unknown module 'unknown2' (VERI-1063)
 
test.v(6): WARNING: instantiating unknown module 'unknown2' (VERI-1063)
 
-- Writing netlist 'top' to Verilog file 'netlist_before.v' (VDB-1030)
 
-- Writing netlist 'top' to Verilog file 'netlist_before.v' (VDB-1030)
===> Instance 'iu1' is of unknown module 'unknown1'
+
 
 +
=> Pass 1
 +
===> Instance 'iu1' of unknown module 'unknown1'
 
===>    Port: 'p1'
 
===>    Port: 'p1'
 
===>        Connected to output port 'o' of instance ' ik1'
 
===>        Connected to output port 'o' of instance ' ik1'
Line 143: Line 163:
 
===>    Port: 'p7'
 
===>    Port: 'p7'
 
===>        Not enough data, remains inout
 
===>        Not enough data, remains inout
===> Instance 'iu2' is of unknown module 'unknown2'
+
===> Instance 'iu2a' of unknown module 'unknown2'
 
===>    Port: 'p1'
 
===>    Port: 'p1'
 
===>        Not enough data, remains inout
 
===>        Not enough data, remains inout
Line 151: Line 171:
 
===>        Connected to input port 'i3' of owning Netlist
 
===>        Connected to input port 'i3' of owning Netlist
 
===>            Set port 'p3' to input
 
===>            Set port 'p3' to input
 +
===> Instance 'iu2b' of unknown module 'unknown2'
 +
===>    Port: 'p1'
 +
===>        Connected to input port 'i1' of owning Netlist
 +
===>            Set port 'p1' to input
 +
===>    Port: 'p2'
 +
===>        Not enough data, remains inout
 +
===> Instance 'iu2c' of unknown module 'unknown2'
 +
===>    Port: 'p2'
 +
===>        Only connected to output port 'o4' of owning Netlist
 +
===>            Set port 'p2' to output
 +
 +
=> Pass 2
 +
===> Instance 'iu1' of unknown module 'unknown1'
 +
===>    Port: 'p3'
 +
===>        Connected to output port 'p2' of instance ' iu2a'
 +
===>            Set port 'p3' to input
 +
===>    Port: 'p6'
 +
===>            All other PortRefs are inputs
 +
===>            Set port 'p6' to output
 +
===>    Port: 'p7'
 +
===>        Not enough data, remains inout
 +
===> Instance 'iu2a' of unknown module 'unknown2'
 +
===> Instance 'iu2b' of unknown module 'unknown2'
 +
===> Instance 'iu2c' of unknown module 'unknown2'
 +
 +
=> Pass 3
 +
===> Instance 'iu1' of unknown module 'unknown1'
 +
===>    Port: 'p7'
 +
===>        Not enough data, remains inout
 +
===> Instance 'iu2a' of unknown module 'unknown2'
 +
===> Instance 'iu2b' of unknown module 'unknown2'
 +
===> Instance 'iu2c' of unknown module 'unknown2'
 
-- Writing netlist 'top' to Verilog file 'netlist_after.v' (VDB-1030)
 
-- Writing netlist 'top' to Verilog file 'netlist_after.v' (VDB-1030)
 
  </nowiki>
 
  </nowiki>
Line 159: Line 211:
 
netlist_before.v
 
netlist_before.v
 
  <nowiki>
 
  <nowiki>
module top (i1, i2, i3, o1, o2, o3) ;  // test.v(1)
+
module top (i1, i2, i3, o1, o2, o3, o4) ;  // test.v(1)
 
     input i1;  // test.v(1)
 
     input i1;  // test.v(1)
 
     input i2;  // test.v(1)
 
     input i2;  // test.v(1)
Line 166: Line 218:
 
     output o2;  // test.v(1)
 
     output o2;  // test.v(1)
 
     output o3;  // test.v(1)
 
     output o3;  // test.v(1)
 +
    output o4;  // test.v(1)
 
      
 
      
 
     wire t1;  // test.v(2)
 
     wire t1;  // test.v(2)
Line 172: Line 225:
 
     wire t4;  // test.v(2)
 
     wire t4;  // test.v(2)
 
     wire t5;  // test.v(2)
 
     wire t5;  // test.v(2)
 +
    wire t6;  // test.v(2)
 
      
 
      
 
     known1 ik1 (.i1(i3), .i2(t2), .o(t3));  // test.v(3)
 
     known1 ik1 (.i1(i3), .i2(t2), .o(t3));  // test.v(3)
Line 177: Line 231:
 
     unknown1 iu1 (.p1(t3), .p2(i2), .p3(t2), .p4(t1), .p5(o3), .p6(t4),  
 
     unknown1 iu1 (.p1(t3), .p2(i2), .p3(t2), .p4(t1), .p5(o3), .p6(t4),  
 
             .p7(t5));  // test.v(5)
 
             .p7(t5));  // test.v(5)
     unknown2 iu2 (.p1(t4), .p2(t2), .p3(i3));  // test.v(6)
+
     unknown2 iu2a (.p1(t4), .p2(t2), .p3(i3));  // test.v(6)
 +
    unknown2 iu2b (.p1(i1), .p2(t2), .p3(i3));  // test.v(7)
 +
    unknown2 iu2c (.p1(t6), .p2(o4), .p3(i3));  // test.v(8)
 +
   
 
endmodule
 
endmodule
  
module known1 (i1, i2, o) ;  // test.v(9)
+
module known1 (i1, i2, o) ;  // test.v(11)
     input i1;  // test.v(9)
+
     input i1;  // test.v(11)
     input i2;  // test.v(9)
+
     input i2;  // test.v(11)
     output o;  // test.v(9)
+
     output o;  // test.v(11)  
 
endmodule
 
endmodule
  
module known2 (i1, i2, o) ;  // test.v(12)
+
module known2 (i1, i2, o) ;  // test.v(14)
     input i1;  // test.v(12)
+
     input i1;  // test.v(14)
     input i2;  // test.v(12)
+
     input i2;  // test.v(14)
     output o;  // test.v(12)
+
     output o;  // test.v(14)  
 
endmodule
 
endmodule
  
Line 199: Line 256:
 
     inout p5;
 
     inout p5;
 
     inout p6;
 
     inout p6;
     inout p7;  
+
     inout p7;
 
endmodule
 
endmodule
  
Line 205: Line 262:
 
     inout p1;
 
     inout p1;
 
     inout p2;
 
     inout p2;
     inout p3;  
+
     inout p3;
 
endmodule
 
endmodule
 
 
  </nowiki>
 
  </nowiki>
  
Line 214: Line 270:
 
netlist_after.v
 
netlist_after.v
 
  <nowiki>
 
  <nowiki>
module top (i1, i2, i3, o1, o2, o3);  // test.v(1)
+
module top (i1, i2, i3, o1, o2, o3, o4) ;  // test.v(1)
 
     input i1;  // test.v(1)
 
     input i1;  // test.v(1)
 
     input i2;  // test.v(1)
 
     input i2;  // test.v(1)
Line 221: Line 277:
 
     output o2;  // test.v(1)
 
     output o2;  // test.v(1)
 
     output o3;  // test.v(1)
 
     output o3;  // test.v(1)
 +
    output o4;  // test.v(1)
 
      
 
      
 
     wire t1;  // test.v(2)
 
     wire t1;  // test.v(2)
Line 227: Line 284:
 
     wire t4;  // test.v(2)
 
     wire t4;  // test.v(2)
 
     wire t5;  // test.v(2)
 
     wire t5;  // test.v(2)
 +
    wire t6;  // test.v(2)
 
      
 
      
 
     known1 ik1 (.i1(i3), .i2(t2), .o(t3));  // test.v(3)
 
     known1 ik1 (.i1(i3), .i2(t2), .o(t3));  // test.v(3)
Line 232: Line 290:
 
     unknown1 iu1 (.p1(t3), .p2(i2), .p3(t2), .p4(t1), .p5(o3), .p6(t4),  
 
     unknown1 iu1 (.p1(t3), .p2(i2), .p3(t2), .p4(t1), .p5(o3), .p6(t4),  
 
             .p7(t5));  // test.v(5)
 
             .p7(t5));  // test.v(5)
     unknown2 iu2 (.p1(t4), .p2(t2), .p3(i3));  // test.v(6)
+
     unknown2 iu2a (.p1(t4), .p2(t2), .p3(i3));  // test.v(6)
 +
    unknown2 iu2b (.p1(i1), .p2(t2), .p3(i3));  // test.v(7)
 +
    unknown2 iu2c (.p1(t6), .p2(o4), .p3(i3));  // test.v(8)
 +
   
 
endmodule
 
endmodule
  
module known1 (i1, i2, o) ;  // test.v(9)
+
module known1 (i1, i2, o) ;  // test.v(11)
     input i1;  // test.v(9)
+
     input i1;  // test.v(11)
     input i2;  // test.v(9)
+
     input i2;  // test.v(11)
     output o;  // test.v(9)  
+
     output o;  // test.v(11)
 
endmodule
 
endmodule
  
module known2 (i1, i2, o) ;  // test.v(12)
+
module known2 (i1, i2, o) ;  // test.v(14)
     input i1;  // test.v(12)
+
     input i1;  // test.v(14)
     input i2;  // test.v(12)
+
     input i2;  // test.v(14)
     output o;  // test.v(12)
+
     output o;  // test.v(14)
 
endmodule
 
endmodule
  
Line 250: Line 311:
 
     input p1;
 
     input p1;
 
     input p2;
 
     input p2;
     inout p3;
+
     input p3;
 
     output p4;
 
     output p4;
 
     output p5;
 
     output p5;
     inout p6;
+
     output p6;
 
     inout p7;
 
     inout p7;
 
endmodule
 
endmodule
  
 
module unknown2 (p1, p2, p3) ;
 
module unknown2 (p1, p2, p3) ;
     inout p1;
+
     input p1;
     inout p2;
+
     output p2;
 
     input p3;
 
     input p3;
 
endmodule
 
endmodule
Line 269: Line 330:
 
test.v
 
test.v
 
  <nowiki>
 
  <nowiki>
module top (input i1, i2, i3, output o1, o2, o3);
+
module top (input i1, i2, i3, output o1, o2, o3, o4);
     wire t1, t2, t3, t4, t5;
+
     wire t1, t2, t3, t4, t5, t6;
 
     known1 ik1 (.i1(i3), .i2(t2), .o(t3));
 
     known1 ik1 (.i1(i3), .i2(t2), .o(t3));
 
     known2 ik2 (.i1(i1), .i2(t1), .o(o2));
 
     known2 ik2 (.i1(i1), .i2(t1), .o(o2));
 
     unknown1 iu1 (.p1(t3), .p2(i2), .p3(t2), .p4(t1), .p5(o3), .p6(t4), .p7(t5));
 
     unknown1 iu1 (.p1(t3), .p2(i2), .p3(t2), .p4(t1), .p5(o3), .p6(t4), .p7(t5));
     unknown2 iu2 (.p1(t4), .p2(t2), .p3(i3));
+
     unknown2 iu2a (.p1(t4), .p2(t2), .p3(i3));
 +
    unknown2 iu2b (.p1(i1), .p2(t2), .p3(i3));
 +
    unknown2 iu2c (.p1(t6), .p2(o4), .p3(i3));
 
endmodule
 
endmodule
  

Latest revision as of 16:44, 19 February 2024

C++ example:

#include "Map.h"            
#include "Message.h"        
#include "veri_file.h"      
#include "DataBase.h"       
#include "VeriWrite.h"
#include "RuntimeFlags.h"
#include <iostream>

#ifdef VERIFIC_NAMESPACE
using namespace Verific ;
#endif

int main(int argc, char **argv)
{
    if (argc < 2) {
        Message::PrintLine("Default input file: test.v. Specify command line argument to override") ;
    }

    const char *file_name = 0 ;

    if (argc>1) {
        file_name = argv[1] ; // Set the file name as specified by the user
    } else {
        file_name = "test.v" ;
    }

    if (!veri_file::Analyze(file_name, veri_file::SYSTEM_VERILOG)) return 1 ;
    if (!veri_file::ElaborateAll()) return 1 ;

    Netlist *top = Netlist::PresentDesign() ;

    VeriWrite vw ;
    RuntimeFlags::SetVar("db_verilog_writer_write_blackboxes", 2) ;
    vw.WriteFile ("netlist_before.v", top) ;

    // Lets accumulate all netlist
    Set netlists(POINTER_HASH) ;
    top->Hierarchy(netlists, 0 /* bottom to top */) ;

    Netlist *netlist ;
    SetIter si ;

    unsigned changed = 0 ;
    unsigned pass = 1 ;
    do { // do this until there are no changes in port directions of 'unknown' modules
        std::cout << std::endl << "=> Pass " <<  pass++ << std::endl ;
        changed = 0 ;
        FOREACH_SET_ITEM(&netlists, si, &netlist) {
            if (!netlist->GetAtt(" unknown_design")) continue ; // Skip if not 'unknown'
            Instance *instance ;
            SetIter si2 ;
            // Iterate over all references (Instances) of this Netlist
            FOREACH_REFERENCE_OF_NETLIST(netlist, si2, instance) {
                std::cout << "===> Instance '" <<  instance->Name() << "' of unknown module '"
                          << netlist->Owner()->Name() << "'"<< std::endl ;
                MapIter mi2 ;
                PortRef *portref ;
                FOREACH_PORTREF_OF_INST(instance, mi2, portref) {
                    Port *port = portref->GetPort() ;
                    if (!port->IsInout()) continue ; // Only look at inout ports
                    unsigned dir_known = 0 ;
                    std::cout << "===>     Port: '" << port->Name() << "'"<< std::endl ;
                    Net *net = portref->GetNet() ;
                    if (!net) {
                        std::cout << "===>     Does not connect to any Net" << std::endl ;
                        continue ;
                    }
                    // Is this port connected to any Port?
                    Port *port2 ;
                    SetIter si ;
                    FOREACH_PORT_OF_NET(net, si, port2) {
                        if (port2->IsInput()) {
                            std::cout << "===>         Connected to input port '" << port2->Name() << "' of owning Netlist" << std::endl ;
                            std::cout << "===>             Set port '" << port->Name() << "' to input" << std::endl ;
                            netlist->GetPort(port->Name())->SetDir(DIR_IN) ;
                            dir_known = 1 ;
                            changed = 1 ;
                        } else if (port2->IsOutput()) {
                            if (net->NumOfPortRefs() == 1 ) { // does not connected to any other instance
                                std::cout << "===>         Only connected to output port '" << port2->Name() << "' of owning Netlist" << std::endl ;
                                std::cout << "===>             Set port '" << port->Name() << "' to output" << std::endl ;
                                netlist->GetPort(port->Name())->SetDir(DIR_OUT) ;
                                dir_known = 1 ;
                                changed = 1 ;
                            }
                        }
                    }
                    // If still don't know direction, check other connections
                    if (!dir_known) {
                        PortRef *portref2 ;
                        SetIter si2 ;
                        FOREACH_PORTREF_OF_NET(net, si2, portref2) {
                            if (portref2 == portref) continue ; // not checking self
                            if (portref2->IsOutput()) { // connected to an output portref, must be an input port
                                Instance *instance2 = portref2->GetInst() ;
                                Port *port3 = portref2->GetPort() ;
                                std::cout << "===>         Connected to output port '" << port3->Name()
                                          << "' of instance ' " << instance2->Name() << "'" << std::endl ;
                                std::cout << "===>             Set port '" << port->Name() << "' to input" << std::endl ;
                                netlist->GetPort(port->Name())->SetDir(DIR_IN) ;
                                dir_known = 1 ;
                                changed = 1 ;
                                break ;
                            } else if (portref2->IsInout()) { // connected to an inout portref, still don't know direction
                                break ;
                            } else { // all portrefs are inputs, must be an output port
                                std::cout << "===>             All other PortRefs are inputs" << std::endl ;
                                std::cout << "===>             Set port '" << port->Name() << "' to output" << std::endl ;
                                netlist->GetPort(port->Name())->SetDir(DIR_OUT) ;
                                dir_known = 1 ;
                                changed = 1 ;
                            }
                        }
                    }
                    if (!dir_known) { // Still clueless
                        std::cout << "===>         Not enough data, remains inout" << std::endl ;
                    }
                }
            }
        }
    } while (changed) ;

    vw.WriteFile ("netlist_after.v", top) ;

    return 0 ;
}
 


Run:

-- Default input file: test.v. Specify command line argument to override
-- Analyzing Verilog file 'test.v' (VERI-1482)
test.v(1): INFO: compiling module 'top' (VERI-1018)
test.v(11): INFO: compiling module 'known1' (VERI-1018)
test.v(14): INFO: compiling module 'known2' (VERI-1018)
test.v(5): WARNING: instantiating unknown module 'unknown1' (VERI-1063)
test.v(6): WARNING: instantiating unknown module 'unknown2' (VERI-1063)
-- Writing netlist 'top' to Verilog file 'netlist_before.v' (VDB-1030)

=> Pass 1
===> Instance 'iu1' of unknown module 'unknown1'
===>     Port: 'p1'
===>         Connected to output port 'o' of instance ' ik1'
===>             Set port 'p1' to input
===>     Port: 'p2'
===>         Connected to input port 'i2' of owning Netlist
===>             Set port 'p2' to input
===>     Port: 'p3'
===>         Not enough data, remains inout
===>     Port: 'p4'
===>             All other PortRefs are inputs
===>             Set port 'p4' to output
===>     Port: 'p5'
===>         Only connected to output port 'o3' of owning Netlist
===>             Set port 'p5' to output
===>     Port: 'p6'
===>         Not enough data, remains inout
===>     Port: 'p7'
===>         Not enough data, remains inout
===> Instance 'iu2a' of unknown module 'unknown2'
===>     Port: 'p1'
===>         Not enough data, remains inout
===>     Port: 'p2'
===>         Not enough data, remains inout
===>     Port: 'p3'
===>         Connected to input port 'i3' of owning Netlist
===>             Set port 'p3' to input
===> Instance 'iu2b' of unknown module 'unknown2'
===>     Port: 'p1'
===>         Connected to input port 'i1' of owning Netlist
===>             Set port 'p1' to input
===>     Port: 'p2'
===>         Not enough data, remains inout
===> Instance 'iu2c' of unknown module 'unknown2'
===>     Port: 'p2'
===>         Only connected to output port 'o4' of owning Netlist
===>             Set port 'p2' to output

=> Pass 2
===> Instance 'iu1' of unknown module 'unknown1'
===>     Port: 'p3'
===>         Connected to output port 'p2' of instance ' iu2a'
===>             Set port 'p3' to input
===>     Port: 'p6'
===>             All other PortRefs are inputs
===>             Set port 'p6' to output
===>     Port: 'p7'
===>         Not enough data, remains inout
===> Instance 'iu2a' of unknown module 'unknown2'
===> Instance 'iu2b' of unknown module 'unknown2'
===> Instance 'iu2c' of unknown module 'unknown2'

=> Pass 3
===> Instance 'iu1' of unknown module 'unknown1'
===>     Port: 'p7'
===>         Not enough data, remains inout
===> Instance 'iu2a' of unknown module 'unknown2'
===> Instance 'iu2b' of unknown module 'unknown2'
===> Instance 'iu2c' of unknown module 'unknown2'
-- Writing netlist 'top' to Verilog file 'netlist_after.v' (VDB-1030)
 


netlist_before.v

module top (i1, i2, i3, o1, o2, o3, o4) ;   // test.v(1)
    input i1;   // test.v(1)
    input i2;   // test.v(1)
    input i3;   // test.v(1)
    output o1;   // test.v(1)
    output o2;   // test.v(1)
    output o3;   // test.v(1)
    output o4;   // test.v(1)
    
    wire t1;   // test.v(2)
    wire t2;   // test.v(2)
    wire t3;   // test.v(2)
    wire t4;   // test.v(2)
    wire t5;   // test.v(2)
    wire t6;   // test.v(2)
    
    known1 ik1 (.i1(i3), .i2(t2), .o(t3));   // test.v(3)
    known2 ik2 (.i1(i1), .i2(t1), .o(o2));   // test.v(4)
    unknown1 iu1 (.p1(t3), .p2(i2), .p3(t2), .p4(t1), .p5(o3), .p6(t4), 
            .p7(t5));   // test.v(5)
    unknown2 iu2a (.p1(t4), .p2(t2), .p3(i3));   // test.v(6)
    unknown2 iu2b (.p1(i1), .p2(t2), .p3(i3));   // test.v(7)
    unknown2 iu2c (.p1(t6), .p2(o4), .p3(i3));   // test.v(8)
    
endmodule

module known1 (i1, i2, o) ;   // test.v(11)
    input i1;   // test.v(11)
    input i2;   // test.v(11)
    output o;   // test.v(11)   
endmodule

module known2 (i1, i2, o) ;   // test.v(14)
    input i1;   // test.v(14)
    input i2;   // test.v(14)
    output o;   // test.v(14)    
endmodule

module unknown1 (p1, p2, p3, p4, p5, p6, p7) ;
    inout p1;
    inout p2;
    inout p3;
    inout p4;
    inout p5;
    inout p6;
    inout p7;
endmodule

module unknown2 (p1, p2, p3) ;
    inout p1;
    inout p2;
    inout p3;
endmodule
 


netlist_after.v

module top (i1, i2, i3, o1, o2, o3, o4) ;   // test.v(1)
    input i1;   // test.v(1)
    input i2;   // test.v(1)
    input i3;   // test.v(1)
    output o1;   // test.v(1)
    output o2;   // test.v(1)
    output o3;   // test.v(1)
    output o4;   // test.v(1)
    
    wire t1;   // test.v(2)
    wire t2;   // test.v(2)
    wire t3;   // test.v(2)
    wire t4;   // test.v(2)
    wire t5;   // test.v(2)
    wire t6;   // test.v(2)
    
    known1 ik1 (.i1(i3), .i2(t2), .o(t3));   // test.v(3)
    known2 ik2 (.i1(i1), .i2(t1), .o(o2));   // test.v(4)
    unknown1 iu1 (.p1(t3), .p2(i2), .p3(t2), .p4(t1), .p5(o3), .p6(t4), 
            .p7(t5));   // test.v(5)
    unknown2 iu2a (.p1(t4), .p2(t2), .p3(i3));   // test.v(6)
    unknown2 iu2b (.p1(i1), .p2(t2), .p3(i3));   // test.v(7)
    unknown2 iu2c (.p1(t6), .p2(o4), .p3(i3));   // test.v(8)
    
endmodule

module known1 (i1, i2, o) ;   // test.v(11)
    input i1;   // test.v(11)
    input i2;   // test.v(11)
    output o;   // test.v(11)  
endmodule

module known2 (i1, i2, o) ;   // test.v(14)
    input i1;   // test.v(14)
    input i2;   // test.v(14)
    output o;   // test.v(14)
endmodule

module unknown1 (p1, p2, p3, p4, p5, p6, p7) ;
    input p1;
    input p2;
    input p3;
    output p4;
    output p5;
    output p6;
    inout p7;
endmodule

module unknown2 (p1, p2, p3) ;
    input p1;
    output p2;
    input p3;
endmodule
 


test.v

module top (input i1, i2, i3, output o1, o2, o3, o4);
    wire t1, t2, t3, t4, t5, t6;
    known1 ik1 (.i1(i3), .i2(t2), .o(t3));
    known2 ik2 (.i1(i1), .i2(t1), .o(o2));
    unknown1 iu1 (.p1(t3), .p2(i2), .p3(t2), .p4(t1), .p5(o3), .p6(t4), .p7(t5));
    unknown2 iu2a (.p1(t4), .p2(t2), .p3(i3));
    unknown2 iu2b (.p1(i1), .p2(t2), .p3(i3));
    unknown2 iu2c (.p1(t6), .p2(o4), .p3(i3));
endmodule

module known1 (input i1, i2, output o);
endmodule

module known2 (input i1, i2, output o);
endmodule