IMPORTANT NOTICE: Please be advised that the Verification Academy Forums will be offline for scheduled maintenance on Sunday, March 23rd at 4:00 US/Pacific.
UVM driver passes an integer variable through configDb. When the monitor tries to get the variable, the value is always 0.
Here is the driver code:
int REQ_NUM_WORDS;
function void build_phase(uvm_phase phase);
super.build_phase(phase);
uvm_config_db#(int)::set(null, "*", "driver_int", REQ_NUM_WORDS);
endfunction: build_phase
And the monitor is:
int REQ_NUM_WORDS;
virtual task run_phase(uvm_phase phase);
super.run_phase(phase);
if(!uvm_config_db#(int)::get(this, "", "driver_int", REQ_NUM_WORDS))
`uvm_fatal("NO_NUM_WORDS",{"uvm event must be set for: ",get_full_name(),".driver_int"});
:
:
:
endtask
I have printed REQ_NUM_WORDS, both in driver and monitor. Though the the value changes to 803, 900 in driver, values printed in monitor is always 0.
I enabled +UVM_CONFIG_DB_TRACE switch and ran the test. I see below [CFGDB/SET].
UVM_INFO verilog_src/uvm-1.2/src/base/uvm_resource_db.svh(121) @ 0: reporter [CFGDB/SET] Configuration ‘*.driver_int’ (type int) set by = (int) 0
I believe the last part should be “set by = (int) {REQ_NUM_WORDS}” to reflect the value of REQ_NUM_WORDS.
I did check configDb set and not able to find the issue.
Thanks Dave!
I understand that, using configuration makes things more reusable friendly.
Can’t we do it without configuration? Like, directly setting an integer in the driver and retrieving it in monitor. I have done that for an uvm_event and things look good.
I set an uvm_event in driver and retrieve it in the monitor.
Though the the value changes to 803, 900 in driver, values printed in monitor is always 0.
How and when are you setting REQ_NUM_WORDS to 803,900 in your driver? You don’t show it.
UVM_INFO verilog_src/uvm-1.2/src/base/uvm_resource_db.svh(121) @ 0: reporter [CFGDB/SET] Configuration ‘*.driver_int’ (type int) set by = (int) 0
According to your log, at the time your driver calls set() REQ_NUM_WORDS is 0. You must be changing the value after that.
But before you try to fix that, you really shouldn’t have a component setting a value in a sibling component, it’s not good encapsulation. In other words, REQ_NUM_WORDS should be a field in your agent, and it should propagate it down to both the driver and monitor. This is fine if you have a single value like this, but if you have more than a couple, a configuration class makes more sense.
In reply to uvmsd:
You did not mention in your original question the intent behind what you wanted to share.
The uvm_config_db can be used to configure many kinds of things. Usually one thinks of a configuration object as a set once, and get one or more times. If you need a uvm_event, you can put the through the uvm_config_db as well. In that case, you are configuring the handle to a shared uvm_event. It is usable friendly that way because the driver needs no knowledge of the components that contains it.
You don’t have to use a configuration object.
How and when are you setting REQ_NUM_WORDS to 803,900 in your driver? You don’t show it.
According to your log, at the time your driver calls set() REQ_NUM_WORDS is 0. You must be changing the value after that.
But before you try to fix that, you really shouldn’t have a component setting a value in a sibling component, it’s not good encapsulation. In other words, REQ_NUM_WORDS should be a field in your agent, and it should propagate it down to both the driver and monitor. This is fine if you have a single value like this, but if you have more than a couple, a configuration class makes more sense.
Sorry, i have not yet completed the coding part. Below is the intent.
REQ_NUM_WORDS represents packet size. I want to send faulty packets(sending the packets with less or more than the standard size). The packet size is set by the sequence and i have added a field in the seq_item. Using this field REQ_NUM_WORDS(packet size), the driver generates cs(chip_select) accordingly.
And i wanted this info to be passed onto monitor too so that the monitor would take appropriate action.
Yes, REQ_NUM_WORDS might change dynamically throughout the test.
In reply to uvmsd:
You did not mention in your original question the intent behind what you wanted to share.
Below is the intent.
REQ_NUM_WORDS represents packet size. I want to send faulty packets(sending the packets with less or more than the standard size). The packet size is set by the sequence and i have added a field in the seq_item. Using this field REQ_NUM_WORDS(packet size), the driver generates cs(chip_select) accordingly.
And i wanted this info to be passed onto monitor too so that the monitor would take appropriate action on those packets.
And REQ_NUM_WORDS might change dynamically(packet boundaries) throughout the test.
If you need a uvm_event, you can put the through the uvm_config_db as well. In that case, you are configuring the handle to a shared uvm_event. It is usable friendly that way because the driver needs no knowledge of the components that contains it.
Sorry, I didn’t get what you said about uvm_event above.
BTW, I have passed uvm_event(not the global pool) through config_db in the driver and retrieved it in the monitor. It did work. It didn’t have to go through agent.
An uvm_event is created and triggered in driver. It triggered based on certain delays. And this uvm_event is set in build_phase of driver.
I did ‘get’ to this uvm_event in build_phase of monitor. Monitor waits for uvm_event to be triggered and then starts writing into TLM fifo(that’s the requirement)
Ok, my understanding is that, once you do a set to uvm_config_db to any variable, and if you have retrieved it in other component, it should reflect all the subsequent changes occurring on that variable, right?
Of course, we have to make sure that, the get doesn’t occur before the set.
You need to distinguish between the handle of the object that you set/get through the uvm_config_db, which never changes, and changing the members of the object. Maybe we are saying the same thing, but you may want to look at my short class on classes.
In reply to uvmsd:
You need to distinguish between the handle of the object that you set/get through the uvm_config_db, which never changes, and changing the members of the object. Maybe we are saying the same thing, but you may want to look at my short class on classes.
Thanks Dave for the link!
My bad, how I forgot that the uvm_event is a class, not a construct.
I was wondering how did it work.
And now I am convinced about having a configuration class. And things are working fine.
REQ_NUM_WORDS represents packet size. I want to send faulty packets(sending the packets with less or more than the standard size). The packet size is set by the sequence and i have added a field in the seq_item. Using this field REQ_NUM_WORDS(packet size), the driver generates cs(chip_select) accordingly.
Why can’t your monitor infer the packet size based on the cs signal? No need to tell the monitor anything.
In reply to uvmsd:
Why can’t your monitor infer the packet size based on the cs signal? No need to tell the monitor anything.
oh! yes.you are correct. That is one way. I did think of it. Since, packets are coming in bit by bit, packet size calculation results in some lines of code(thats how Driver generates cs). Monitor already has so much of logic with fork-join constructs. I just thought to keep it simple uaing configDb. But ended up adding configuration.
Monitor already has so much of logic with fork-join constructs.
Monitors shouldn’t rely on anything from the driver. By making the monitor dependent on the driver, you eliminate the possibility of using this as a passive agent. This sounds like an external interface, so it’s more likely that you can live with that limitation. But consider if you wanted to replace your driver with a model from a vendor, or to create a multi-chip simulation, then you’d still want to be able to put this agent into passive mode.
In reply to uvmsd:
Monitors shouldn’t rely on anything from the driver. By making the monitor dependent on the driver, you eliminate the possibility of using this as a passive agent. This sounds like an external interface, so it’s more likely that you can live with that limitation. But consider if you wanted to replace your driver with a model from a vendor, or to create a multi-chip simulation, then you’d still want to be able to put this agent into passive mode.
Best of luck.
Good point! I didn’t think about it. Definitely will keep that in my mind and will see if i can revisit my monitor. Thanks you!