Jump to content


  • Content Count

  • Joined

  • Last visited

  • Days Won


Everything posted by mastrick

  1. It is certainly possible. That is one of the main reasons for domains. You may want to look into domain.sync() if you want the domains to go through all the phase transitions together (except the jump). Also, there are improvements in this area in UVM1.1c.
  2. We use default_sequence and it works fine. The config_db can be particular, however. If your sequence is not starting at all (which sounds like the case), you can use the config_db tracing to see what is going on.
  3. We want to pack a field of type bit[95:0] with big_endian. If we use `uvm_pack_intN(field,96), we lose 32 bits because the macro uses a temporary variable of type longint. Is there some other way to do this? If not, should uvm_pack_intN use uvm_bitstream_t like the unpack version does? Thanks, Mark
  4. Another possibility is that your sequence path is fine but your reset phase is finishing in 0 time. If this sequence is supposed to complete before reset phase is done, then make sure the sequence raises and drops an objection to the phase. The sequence can get a handle to the current phase via its handle to its parent sequencer.
  5. Hi jalilm, I'd be very interested to hear the scenario that is addressed by objecting to the shutdown phase in this sequence. In general, if you are OK with finding the phase in the domain that the sequencer belongs to, you could use get_sequencer().get_domain().find_by_name("shutdown") to return the phase handle. Be aware raising and dropping objections is pretty expensive if you do it very frequently.
  6. FYI: If you use +UVM_PHASE_TRACE in 1.1c, it will show who is objecting upon a timeout.
  7. Manju, Perhaps there is more to your code, but could you just call return where you have the disable? I believe seq.kill() will mean that post_body() will not execute and you may want that to drop objections, etc. Mark
  8. Thanks again, Dave. That makes perfect sense to me. Perhaps we could get some of your text in the next update to the LRM?
  9. Thanks for the detailed response, Dave. Can you clarify one point? Your example shows that wait(getB2()) is evaluated when B2 changes, but your text says "when any operand in the expression changes. That includes arguments to any function calls as well as any objects referenced directly in the expression". B2 is not an argument to the function nor referenced directly in the expression. Is there another category of operands that covers B2?
  10. The LRM says that an "event control expression" can include a non-virtual function as long as it has a singular return value. Do those restrictions apply to the expression within wait()? If any function is allowed within wait, should I expect that the wait will unblock within the same time that the function return value changes (to whatever would make the expression true)?
  11. I suspect the code in line 308 never executes; there is no guarantee there will be more than one call to ready_to_end. Unless somebody raises an objection when ready_to_end is called, phase_ended will happen immediately. If you remove all the "count" stuff, you should avoid the error you are getting. You could implement the phase_ready_to_end in the sequencer itself and avoid the "agtA.sequencer". I'm pretty sure you could then move it to phase_ended() and the stop_sequences() would be guaranteed to be called before the sequence is killed.
  12. There is no defined ordering of the execution of main_phase between components. They could be called in any order, and they will be terminated when there are no outstanding objections to the phase. You may be able to make your existing code work by having the driver affect when the sequence completes. If the driver does not call item_done() until it has finished send_frame(), then the sequence could not finish (and the objection could not drop) until send_frame() ends. In fact, it would be more standard to start your driver in the run_phase(), conditioned by reset, so that it is just waiting for the sequence to come alive in the main phase. If you do your driver this way, it will not be terminated by the end of main_phase at all, but you will still need to extend a phase after main so that the end of simulation does not occur in 0 time.
  13. The new() that is done by create allocates new memory to store your transaction (including payload). If you don't do that, the information about your previous transaction is completely lost, so the scoreboard cannot match it. An alternative to create would be to send a clone of the transaction to the scoreboard, but I doubt that will save simulation time.
  14. The uvm_phase::jump() clears the phase done objection, so you don't really need the explicit clear afterwards. You could find all the sequencer handles and call stop_sequences() just before the jump. If you have multiple domains, make sure you check the domain of the sequencer matches what you are jumping. The stop_sequences() resolves problems in the sequencer-sequence interaction. You may also have to consider problems in the sequencer-driver interaction -- if your driver calls get_next_item() and then due to reset the sequence is killed, a subsequent item_done() from the driver will cause an error. An alternative we are using is to replace using jump with setting a notification flag in the config_db and then clearing the phase_done manually. That will cause all components in the domain to get a phase_ready_to_end() callback, which we use in the sequencer to kill sequences (when the notification flag is present).
  15. If I have a component that uses pack()/compare()/etc on a base data type and I expect that each user will extend that base type with some customized implementation of pack/compare, I can either make my component have a parameterized data type and have the users use their type as the parameter or I can have my component use the base data type and have users factory replace that type with their own. Any opinions on which way to go?
  16. That does look wrong. Do you need someone else to file a Mantis? Another workaround would be to set a verbosity of UVM_NONE on the MISCMP id when you do not want to see it; that does require special attention to this message.
  17. We have created some classes that extend uvm classes and add functionality to some of the uvm virtual functions. Our end users are supposed to extend those new classes and if they need to extend those same functions, they must call super.function(). If they forget to call the super version for some of the extended functions, they can get very strange broken behavior. Does anyone have a good idea on how to prevent such a problem? My best idea so far is to have our centralized extensions update flags and check the flag status of functions that should have been called previously, so that if a super version is not called, that flag will not be set and the next inherited function called will report an error based on that missing flag.
  18. We take a middle ground for our internal IP. Some of the associated sequences have an "ending_phase" config value (so the value can be controlled from the environment) and upon an event emitted by the associated sequencer when phase_ready_to_end, a sequence will terminate itself gracefully. The environment is fully in charge of determining when the quiesce time begins, but the IP does its own cleanup.
  19. I would recommend a reset monitor for each instance that informs its clients about reset state some other way than jumping to reset_phase, e.g. an analysis port. The usage recommendation from Accellera is still evolving, but it is generally agreed that testbench objects that are not involved in providing stimulus should not use phasing. The prime reason is that phasing implies a progression of phase states leading to a final state when the run ends, but an IP component could go into reset and stay there for the rest of the sim. Along with your reset monitor, you may want a reset driver. The behavior of this reset driver, being stimulus, could be specified as part of the phasing. For example, you might have a reset_phase sequence that causes the driver to assert reset.
  20. One clean solution is for the VIP developer to provide sequences/tasks but not to start any of them. The env developer then starts the desired sequences/tasks in the desired phases.
  21. We have a number of base classes that inherit from uvm base classes. Our base classes are intended to be inherited from by end user classes; we do not instance these base classes. So far, we have been using `uvm_object_utils, etc. to register our base classes. But we have seen there is quite a compile time overhead to doing that. What do we give up if we do not use `uvm_object_utils for our base classes but do use it for our end user classes? Is it just that we could not include base class fields in the pre-defined methods and if we ever did instance a base class, we could not ever replace it? Or is there another pitfall we may encounter? Thanks, Mark
  22. phase_ready_to_end() is called whenever the total objection count for the current phase decrements to 0. If the objection is raised and dropped in phase_ready_to_end(), it will be called again. To avoid endless loops, there is a maximum count of phase_ready_to_end() that defaults to 20.
  • Create New...