Jump to content


  • Content Count

  • Joined

  • Last visited

  1. Thanks for the response! The uvm implementation is very confusing. The body of new() is called when using create(), but not the extra arguments. Actually the extra arguments' default values can be used in the new() body, but not the actual value. Hope this can be improved in future uvm release. BTW, I do agree the capability to override when using create() is very useful.
  2. Is it possible to still use "...type_id::create(..)" when I add arguments to new() constructor? e.g. class myItem extends uvm_sequence_item; function new(string name="", uvm_component initiator=null, int OneMoreArgument=32); ... class mySeq extends uvm_sequence... myItem myitem; ... myitem = new("myitem", this, 1234); <- this line works fine myitem = myItem::type_id::create("myitem", this, 1234); <- bomb! too many arguments Is it possible? Any help is appreciated!
  3. I agree the concept of parameterized driver(or class) facilitates cleaner code. However, currently the extra baggage (e.g "constantly pass parameter through") negates that benefit. Wish there is a way to enhance in the future. Janick, Thanks for the pointers on driver. I agree that's the best approach we can have for now. I do have a follow on concern, regarding the sequence_item that I had put aside so far in the discussion: 3) Do we do the same as declaring the data width in sequence_item.data as MAX_WIDTH, and randomize/capture portion of it? or there's a better approach when it comes to sequence_item? - sequence_item usage has a bigger impact than interface. Many instances of sequence_item are maintained throughout simulation. e.g. a MAX_WIDTH=240 interface seems to post heavy penalty on a smaller interface with data_width=16. Should that be a concern?
  4. Thanks for the pointer, Janick! However, my 2 interfaces (width=64, and width=128) are both used in the same simulation. As a result, MAX_WIDTH macro is not going to work in this case, right? Seems like I'm back to using parameterized interface. Or there's another solution? Thanks!
  5. I would like to reuse my driver code for, say 2, different interfaces that differ in data width only. Anyone can recommend the best way to architect it? I see solution using parameterized interface and sequence_item. However, parameterized classes seem to have more restrictions(on assignment, casting, etc) that negates the benefit of this reusable driver. My first question is: 1) For those who had experience with parameterized classes, would you still recommend building this reusable driver this way? Let's assuming this is the way to go. My second question is: 2) I assume there has to be 2 parameterized interface in this env. How does the driver select which interface to drive? (let me show some ugly code here to illustrate my confusion): class driver extend uvm_driver #(base_item); virtual interface IF_64_WIDTH vif64; virtual interface IF_128_WIDTH vif128; int width=64; ... if (width==64) begin vif64.data <= base_item.data; // for example purpose, ignore potential casting needed for base_item end else if (width==128) begin vif128.data <= base_item.data; end Thanks!
  6. That works. Thanks!! Confusing... pre_body() is mentioned in uvm_user_guide everywhere while there is no mention of pre_start(). I see that for most applications, users should put their code in pre_start(). pre_body() seems to be a more advance topic. Also wish they were named more intuitively, something like pre_body() and optional_pre_body()...
  7. I ran into a problem that my sequence's pre_body() is not executed. Tracing the problem indicates it is not called on purpose (by setting call_pre_post=0) because this is a sub-sequence( this sequence is invoked from a sequence_library). Can anyone suggest a good solution to force this "sub-sequence"'s pre_body() to be executed? I see one possible solution of overriding 'task uvm_sequence_library::execute(...)" to manually start/rand/finish instead of `uvm_rand_send(). I'm hoping for a simpler solution. Thanks!
  8. Thanks mastrick. I ended doing something similar. Environment creates a "my_env" class. Inside there's a flag "start_quiesce" which is controlled by env. Any internal IP out there can grab this class from uvm_resource_db if needed, and implement its all code during quiesce time.
  9. VIP developer defines a task for env developer to call seems reasonable. One note: in this case, task is not used to _start_ the sequence, more for _stop_ the sequence. It would be nice to have a global indication (main_phase/shutdown_phase is perfect for it, if there's no run_phase to complicate the matter): all you components out there, we are entering quiesce time... do whatever you need to do now.
  10. testbench env developer, vip developer...we still want to build a clean and reusable dv env. Let's say I'm VIP developer, is there a clean solution to this real problem?
  11. Thanks Janick for the reply. There are 2 points you raised that caught my interest: 1) main_phase (vs run_phase) 2) "the schedule moves into the drain time" let me explain: 1) if all sequences start on main_phase, I'm happy. My slave model can do the following in shutdown_phase: a) stop applying backpressure, then raise_objection, wait for some drain time, then drop_objection, or c) set_drain_time for this shutdown phase however.. due to the "flexibility" of uvm, run_phase could be used to start sequence instead of main_phase. As testbench env developer, I'll need to create an env flexible enough to handle both cases (seq starts from main_phase or run_phase) . That brings me to the second point: 2) "the schedule moves into the drain time": how can slave model detects such condition, regardless of sequences started on main_phase or run_phase. Also, slave model needs the "ultimate" drain time. i.e. not the case if drain time started, but new sequence reset the drain time. Any suggestions are welcomed. Thanks!
  12. I'm looking for a flag/indication of all sequences are done, and testbench is entertaining drain time for all outstanding transactions/packets to exit DUT. The usage of this flag/indication is release all backpressure from testbench slave model. i.e. the slave model backpressure the DUT's output throughout simulation, but stop backpressuring when testbench reaches drain time. Whats the best way to do so? Thanks!
  13. arh... great info. Thanks! I layered weighted constraints on select_rand in the extended class(no conflict with valid_rand_selection since weighted constraints fall into "inside {[0:sequences.size()-1]". Seems working now. Thanks again, Erling!
  14. Thanks Erling. Could you also tell me where I can find reference/documentation to parameter such as your "valid_rand_selection constraint"? I'm new to UVM and while reading through this forum, I found lots of reference to features/parameters (e.g. is_randomized, valid_rand_selection) that I couldn't find in the 2 docs I use: uvm_users_guild_1.1.pdf and UVM_1.1_Class_Reference_Final_06062011.pdf. Thanks!
  15. Could anyone suggest how to put weight distribution on sequence selection inside the sequence library? I see that UVM_SEQ_LIB_RAND gives control to randomly select one of the sequences in sequence library. However, I'd like finer control as in something like 80% on sequenceA, 10% on sequenceB, 10% on sequenceC. I see UVM_SEQ_LIB_USER in user guide and ref manual but I don't see any examples on using it. Thanks!
  • Create New...