Post processing port resolution of black boxes
From Verific Design Automation FAQ
Revision as of 18:56, 16 February 2024 by Alice (Talk | contribs) (Created page with "C++ example: <nowiki> #include "Map.h" #include "Message.h" #include "veri_file.h" #include "DataBase.h" #include "VeriWrite.h" #include "Run...")
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) ; MapIter mi ; Instance * instance ; FOREACH_INSTANCE_OF_NETLIST(top, mi, instance) { Netlist *view = instance->View() ; if (!view) continue ; if (view->GetAtt(" unknown_design")) { std::cout << "===> Instance '" << instance->Name() << "' is of unknown module '" << instance->View()->Owner()->Name() << "'"<< std::endl ; MapIter mi2 ; PortRef *portref ; FOREACH_PORTREF_OF_INST(instance, mi2, portref) { unsigned dir_known = 0 ; Port *port = portref->GetPort() ; 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 ; view->GetPort(port->Name())->SetDir(DIR_IN) ; dir_known = 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 ; view->GetPort(port->Name())->SetDir(DIR_OUT) ; dir_known = 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 ; view->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 ; } } } if (!dir_known) { // Still clueless std::cout << "===> Not enough data, remains inout" << std::endl ; } } } } 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(9): INFO: compiling module 'known1' (VERI-1018) test.v(12): 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) ===> Instance 'iu1' is 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 'iu2' is 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 -- Writing netlist 'top' to Verilog file 'netlist_after.v' (VDB-1030)
netlist_before.v
module top (i1, i2, i3, o1, o2, o3) ; // 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) 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) 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 iu2 (.p1(t4), .p2(t2), .p3(i3)); // test.v(6) endmodule module known1 (i1, i2, o) ; // test.v(9) input i1; // test.v(9) input i2; // test.v(9) output o; // test.v(9) endmodule module known2 (i1, i2, o) ; // test.v(12) input i1; // test.v(12) input i2; // test.v(12) output o; // test.v(12) 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); // 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) 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) 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 iu2 (.p1(t4), .p2(t2), .p3(i3)); // test.v(6) endmodule module known1 (i1, i2, o) ; // test.v(9) input i1; // test.v(9) input i2; // test.v(9) output o; // test.v(9) endmodule module known2 (i1, i2, o) ; // test.v(12) input i1; // test.v(12) input i2; // test.v(12) output o; // test.v(12) endmodule module unknown1 (p1, p2, p3, p4, p5, p6, p7) ; input p1; input p2; inout p3; output p4; output p5; inout p6; inout p7; endmodule module unknown2 (p1, p2, p3) ; inout p1; inout p2; input p3; endmodule
test.v
module top (input i1, i2, i3, output o1, o2, o3); wire t1, t2, t3, t4, t5; 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 iu2 (.p1(t4), .p2(t2), .p3(i3)); endmodule module known1 (input i1, i2, output o); endmodule module known2 (input i1, i2, output o); endmodule