Variable visibility to various UVM components

I want to make a variable(I want to count the number of read transactions that occur) visible to various components of the test bench. One way I can think of is to define a class called config_variabales and define the variable integer read_number inside the config_variables class, and then put the config_variables object in the configuration and factory area. Is that the only way to do this?

It’s not necessarily the only way, but it’s a good way to do it. Just remember that you don’t want to clone the config_variables object when you put it into the config_db. That way, every component who gets the config_variables object will be looking at the same handle.

In reply to tfitz:

thanks tfitz, can you elaborate and explain why it is a good way of doing it? I am trying to understanding the good programming practices while creating a UVM testbench

In reply to verify_mars:

The only way to

make a variable visible to various components of the test bench

that I can think of besides the config_db would be to use a global variable, and that’s never a good idea.
You definitely wouldn’t want to get into anything structural, like analysis_ports, because that would make your connections too complicated and hamper reuse.

In reply to tfitz:

You definitely wouldn’t want to get into anything structural, like analysis_ports

I want to clarify the above statement.

When ever I use analysis_ports it has always always been only transmitting “transactions”. My read_transaction has all the input variables and all the output variables. When I send an expected_read transaction packet from predictor to the scoreboard, I don’t assign values for each and every variables for the expected_read transaction, instead I only assign predicted values for the output and the remaining variables of the expected_read transaction packet are empty. I send this expected_read transaction - containing some filled and some blank - packet through the analysis port.

I thought can’t I just create another port and send just the required variables?

Questions:

  1. When you mention the statement above, are you telling creating such analysis ports (for variables instead of one complete transaction) it might cause more confusion?

  2. It’s not necessary that all variables of a transactions needs to have a value correct? I don’t why I think they should, but every time I send a partially filled transaction, I feel may be this might not be the right way of doing things.

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.

In reply to tfitz:

This *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

  • Cleared my original question

and this it probably will have some fields that aren’t filled in, and that’s OK; In any case, the scoreboard will take the appropriate fields from read_transaction and compare them against expected_read cleared the partial filled transaction doubt. Thank you