In reply to verify_mars:
Your original question was how to share variables between components, and the config_db is the best way to do that. Each component that needs it gets a handle to the object containing the variable and can access it when needed. When I said “structural” I was talking about ports and exports which, by definition, are used to communicate transactions.
If the scoreboard’s job is to compare a read_transaction with an expected_read transaction, then you need ports/exports that allow the scoreboard to receive the appropriate transactions (see The UVM Cookbook). This is an example of “point-to-point” communication, which is what TLM was designed for.
You have the option of creating your transactions as you see fit. If your expected_read transaction is an extension of read_transaction, then it probably will have some fields that aren’t filled in, and that’s OK. It will be up to the scoreboard to just worry about those fields that will be filled in and compare appropriately. However, if these two transaction types are coming from different components, it’s OK for the two exports in the scoreboard to be looking at transaction types that aren’t necessarily extended one from another. They could be totally unrelated or they could both be different extensions of a common base type. In any case, the scoreboard will take the appropriate fields from read_transaction and compare them against expected_read.
If one of your config_variables was required by the driver, monitor and/or scoreboard to ensure correct functionality, then you’d want each component to get the value from the config_db and the scoreboard would use that information to determine if the comparision is correct.