Difference between revisions of "Post processing port resolution of black boxes"
From Verific Design Automation FAQ
(Created page with "C++ example: <nowiki> #include "Map.h" #include "Message.h" #include "veri_file.h" #include "DataBase.h" #include "VeriWrite.h" #include "Run...") |
(No difference)
|
Revision as of 18:56, 16 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) ;
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