Calling of build phase?

In reply to chris_le:

This is exactly why there is a separate connect_phase() in UVM. During build_phase(), the exact order of building doesn’t matter. The point is that, starting with F in your diagram, its build_phase() method will create B and G. Note that these two uvm_components are effectively independent of each other at this point, so it doesn’t matter in which order they are created. If you are depending on them being created in a particular order, then you’re doing something wrong.
There won’t be any useful information to be had from B or G until their build_phase() methods have been called, which will likely include some call(s) to the uvm_config_db to configure them. This is also why the uvm_config_db is a separate thing rather than trying to pass parameters directly down to a child component when it is created (there are other logistical reasons why this isn’t a good idea). So, even if you wanted to, you couldn’t get any useful information out of B until after its build_phase() method completes. Of course, any such information would already be known to F which would have set it in the config_db to begin with, so F could just as easily use the same information to configure G, so again it doesn’t matter in which order B and G are created.
The same argument applies recursively down the tree. A and D are created by B.build_phase() and it doesn’t matter in which order they are created. Note that I would be created by G.build_phase() at the “same level” as A and D, and all of them are independent.
After the build_phase completes and all components have been configured and created, we call connect_phase() which relies on components having been created so that the ports/exports exist so that they can be created.
Any last-minute tweeking required before main_phase() starts can be handled by end_of_elaboration_phase().