Jump to content


  • Content count

  • Joined

  • Last visited

About gbbrown

  • Rank
    Junior Member

Profile Information

  • Gender
  • Location
    Washington DC
  1. I have a module defined as follows... module dut(); int i; initial begin i = $urandom_range(0, 500); $display("The value of i is %1d", i); end endmodule // dut I'm trying to randomize the value assigned to the variable i. My top level module is module top_tb; dut dut_a(); dut dut_b(); dut dut_c(); endmodule When I simulate this, the output shows the same value for all three instances. # The value of i is 3 # The value of i is 3 # The value of i is 3 This is a simple example. I've tried other approaches, including placing the random variable inside a class, declaring a new object of that class inside the initial block and then randomizing the object. That yields the same result, all the values are the same in the different instances. I've added time before the randomization via a #10 statement. Same result. It seems to be related to the initial block. So how does the SystemVerilog random functions work in regards to an initial block and non-initial blocks? There some part of how those functions work that I'm not understanding. How could I set a different random value inside each dut instance within the initial block? gb
  2. Is there a way to make the randomization of variables via randomize() use one of the different RNGs listed in 20.15 of the IEEE Std 1800 (such as $dist_normal or others)? Or does the use of one of the alternative RNGs require manually doing randomization via direct calls to those utility functions ($dist_normal, etc) in the post_ or pre_randomize() functions? Greg
  3. I've got a situation where the interface connecting my DUT to my UVM environment need to be parameterized. I've started by implementing it via parameterized virtual interfaces. This has become a bit unwieldy as I've had to pass the parameters down the hierarchy from the agent to the drivers/monitors. I'm considering changing the way I'm handling this by converting to using abstract classes for the driver/monitor and then writing the concrete driver/monitor classes inside the interfaces. My question is: are there any disadvantages that anyone has seen in using the abstract class method of interface connection? The only thing I can come up with is that it means any classes that inherit from the concrete driver/monitor classes that reside inside the parameterized interfaces would have to ALSO reside inside the parameterized interface code. This might not be the case, but I can't figure out how to extend a concrete class that is inside an interface when the extending class code is located somewhere else (like in the package, etc). Interested in hearing anyone's experiences in using abstract classes and whether there were any problems you ran into. Greg
  4. What is the effect on a transaction if it is executed on multiple sequencers? If I take a sequence item and without cloning it proceed to .start() it on multiple sequencers, will the item execute correctly on all the sequencers? or will that cause a conflict in the item between the different sequencers? I know there are some configuration settings like "set_sequencer" that I'm guessing would end up battling each other in some race condition if I started the same item on multiple sequencers. Greg
  5. I have 2 sequences, idle_seq and action_seq. I want idle_seq to run over and over on the sequencer with a low priority such that I can start action_seq at various times during the run and it will interrupt idle_seq, taking over the driver and injecting transactions. What's the best mechanism for doing this? OVM used to have a count value in the sequencers, but if I understand correctly that is deprecated. Originally, I thought using a forever begin/end block in the idle_seq body() function would do it. However, I think that will only loop idle_seq forever since the sequence never technically finishes. I haven't tested this yet, but I suspect this would be the case. The best way I can think of doing this is to assign idle_seq a low priority and fork off a forever begin/end loop that constantly calls idle_seq.start() over and over. Then if action_seq.start() is called elsewhere with a higher priority, it will interrupt idle_seq the next time idle_seq finishes. Anyone's insight would be appreciated! Thanks!
  6. set_report_default_file

    Thanks jadec! This is what I was missing. I didn't see that the *_hier() calls in uvm_component. Using those and also making the calls after build fixed my problem.
  7. I'm trying to redirect all `uvm_info/warning/error/fatal messages to a log file. I can't seem to get it to work and I'm sure the way I'm calling the report functions is probably incorrect. From my uvm_test, in the build() function, I'm doing the following... set_report_severity_action(UVM_INFO, UVM_DISPLAY | UVM_LOG); set_report_severity_action(UVM_WARNING, UVM_DISPLAY | UVM_LOG); set_report_severity_action(UVM_ERROR, UVM_DISPLAY | UVM_LOG | UVM_COUNT); set_report_severity_action(UVM_FATAL, UVM_DISPLAY | UVM_LOG | UVM_STOP); default_report_file = "test.log"; // Open report files default_report = $fopen(default_report_file, "w"); // Set report file handling set_report_default_file(default_report); default_report is a UVM_FILE and default_report_file is a string. This doesn't seem to have any effect at all and the report file is empty at the end of the run. I also tried the code above, but called uvm_top.set_report_severity_action(...) and uvm_top.set_report_default_file(default_report) instead. That caused any messages that went to "reporter" (such as the everything with the ID [TEST_DONE]) to be written to the log file, but none of the messages from my user instantiated components were written to the log file. Any help would be greatly appreciated! Greg
  8. Two questions... One... I understand that the set_config_* and get_config_* functions are mapped to use the uvm_config_db. What are the recommendations for using the configuration interface going forward? Should we migrate to using the uvm_config_db#(T)::set(...) calls directly? or is it ok to keep using the set_config_*/get_config_* functions? Two... In the OVM, it was recommended that configuration information for components be packaged in a configuration object and then that object be stored via set_config_object due to excess overhead when storing ints or strings or other types. Is this still the case? Should storing ints or other types directly in the resource database be avoided altogether? or has this improved since the OVM? Apologies if there are already answers to these on the forum. I looked, honest. Thanks!