Verification Engineers will hook the transactors together to make a verification environment. In SystemVerilog, this hooking together of transactors can be tricky. Callbacks provide a mechanism whereby independently developed objects may be connected together in simple steps.
Some requirements are often unpredictable when the transactor is first written. So a transactor should provide some kind of hooks for executing the code which is defined afterwards. In uvm, these hooks are created using callback methods.
For instance, a driver is developed and an empty method is called before driving the transaction to the DUT. Initially this empty method does nothing. As the implementation goes, user may realize that he needs to print the state of the transaction or to delay the transaction driving to DUT or inject an error into transaction. Callback mechanism allows executing the user defined code in place of the empty callback method without changing the behavior of the transactor(BFM).
Sometimes we are using third party VIP in our verification environment. Third party wants their code to be encrypted and also wants to give facility to their customer to change the behavior of driver(BFM) without allowing to modify driver code. In this case they provide hooks at some particular places like just after getting transaction from sequence (after get_next_item), just before start driving to the interface, etc. These hooks are created using callback.
Other example of callback usage is in monitor. Callbacks can be used in a monitor for collecting coverage information or for hooking up to scoreboard to pass transactions for self checking. With this, user is able to control the behavior of the transactor in verification environment and individual testcases without doing any modifications to the transactor itself.
Let's go through one callback example in which error is injected through callback of driver.