In cases when there are multiple UVCs of the same type, they will all use the same write function to pass their collected data items to the scoreboard or reference model. The usual way to connect the agents to the reference model is through analysis imps using the `uvm_analysis_imp_decl macro. In many cases, the reference model should be aware of which of the UVCs did the data item come from. However, this won’t work because the definition of `uvm_analysis_imp_decl doesn’t have enough info which could be used to distinguish between UVCs:

One way to provide this info is to define a new macro based on `uvm_analysis_imp_decl which declares a new uvm_numbered_analysis_imp class of analysis imps that now also includes an imp_id variable for assigning a different ID number to each UVC:

The new macro’s write function also has a checker that issues a fatal error in case id is not assigned. This macro can then be used to declare analysis imps the same way as with `uvm_analysis_imp_decl, but this time we can create an array of imps – one for each UVC and then assign the imp index as the id value in the reference model’s build phase:

The write function is now modified to also take the UVC id as input when sending an item. The id can be used by the reference model for any relevant calculation or prediction. Finally, all agents are instantiated (also in an array) in an env class, along with the reference model and the virtual sequencer. In the env’s connect phase, each UVC’s analysis port is connected to the corresponding analysis imp in the scoreboard, and the agents’ sequencer handles are assigned to the virtual sequencer’s handles:
