How Verific elaborator handles blackboxes/unknown boxes

From Verific Design Automation FAQ
Revision as of 18:45, 22 December 2020 by Hoa (Talk | contribs) (Created page with ">> This page is in progress << '''Q: After RTL elaboration on a Verilog design, I see Netlist with names such as 'NamedPorts' or 'OrderedPorts.' Sometimes in the Verilog netl...")

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

>> This page is in progress <<

Q: After RTL elaboration on a Verilog design, I see Netlist with names such as 'NamedPorts' or 'OrderedPorts.' Sometimes in the Verilog netlist output, I see modules with names such as 'foo_NamedPorts' or 'bar_OrderedPorts.' They are not in the original RTL design. Where do they come from?

First, please read the article on Black box, empty box, and unknown box.

When the elaborator see an instance of an unknown box, it creates a dummy Netlist object so that it can create an Instance object to instantiate it in the Netlist that owns the instance.

Verilog module instantiations can be in two styles: ordered port connections and named port connections.

(1) Ordered port connection example: bb_mox b1 (a, b, c) ; (2) Named port connection example: bb_mod b2 (.clk(d), .data(e), .out(f)) ;

For such instances of unknown modules, the elaborator has no info about the size, type and direction of the ports.

For (2) it has names of some ports (there may be some more ports which are unconnected). For (1) it doesn't even have the name of any of the ports.

Also note that port connections for (2) may not be in the order of declaration. For example, bb_mod can very well be declared as: "module bb_mod(out, clk, data)." Therefore, even the module name is the same, the elaborator cannot use the same dummy netlist for both (1) and (2).

Thus it has to create two Netlists with name "OrderedPorts" for (1) and "NamedPorts" for (2). Both are under the Cell with name "bb_mod" and have direction of all ports set to inout.

Also port names for (1) have made-up names p1, p2, etc..

Now when both style of the instances are used in the same design, there are multiple instances of the netlists from same cell but they are actually different (since there is no actual definition).

In writing out the Netlist output file, the writer writes out the first instance with the name of the cell ('foo'), but the instances of other style is written with the name of the netlist appended with the cell name ('foo_OrderedPorts') to avoid conflict and to make the output legal/correct.

To avoid this you can use any of the following:

 a) Read in a stub of the module (with only port dir/size) before you call elaborate.
 b) You can even read in the stub after elaboration which will overwrite the created dummy netlists.
 c) Hook up your own routine which we query to get the port names/size/direction etc using:
       static void veri_file::RegisterIsLibertyCellDefinedCB(unsigned (*cb)(const char *cell_name)) ;
       static void veri_file::RegisterLibertyCellInterfaceNCB(unsigned (*cb)(const char *cell_name, const char *port_name, int &left_bound, int &right_bound, unsigned &port_direction, unsigned ignore_case)) ;
       static void veri_file::RegisterLibertyCellInterfacePCB(const char * (*cb)(const char *cell_name, unsigned port_pos, int &left_bound, int &right_bound, unsigned &port_direction, unsigned ignore_case)) ;
       static void veri_file::RegisterLibertyCellInterfaceNames(Set * (*cb)(const char *cell_name)) ;
       static void veri_file::RegisterLibertySingleBitBusPort(unsigned (*cb)(const char *cell_name, const char *port_name, unsigned ignore_case)) ;

You have to define your own function and hook them up. We pass cell_name, port_name, port_pos and ignore_case when appropriate. You have to set/return left_bound, right_bound and port_direction accordingly.