Jump to content

walkeranderson

Members
  • Posts

    23
  • Joined

  • Last visited

  • Days Won

    3

Everything posted by walkeranderson

  1. What is the recommended way to control the timescale of the UVM timeout as set with set_timeout()? Controlling the timescale in the calling code doesn't seem to work. For example, `timescale 1ns/1ps ... uvm_top.set_timeout(2000000ns, 1); results in the timeout set to 2000ns. UVM seems to be using a timescale of 1ps.
  2. What happens when a driver calls seq_item_port.put_response() with a response associated a request sequence item where the sequence that sent the request sequence item has terminated (and taken its response queue with it)? I'm not talking about a programming error condition where the sequence shouldn't have terminated. I'm talking about a real use case where the sequence did not want to wait for the response. And there would be other sequences working with this driver that did want to wait for and get their responses. It seems to be "handled" by the UVM code. Presumably the code under the hood for put_response sees that the response queue (or sequence) is no longer running and just does nothing. I'm wondering if this is intentional in the UVM implementation, and an expected usage model, or I'm just getting lucky and the current implementation happens to work for me. Thanks. Walker
  3. Figured this out myself. In case anyone is interested, here's what I did. My goal was to add a run-time phase that I could use for configuring default sequences on sequencers. /////////////////////////////////////////////////////// Here's the definition of the new phase class uvm_foo_phase extends uvm_task_phase; virtual task exec_task(uvm_component comp, uvm_phase phase); my_uvm_sequencer seqr; if ($cast(seqr, comp)) seqr.foo_phase(phase); endtask local static uvm_foo_phase m_inst; static const string type_name = "uvm_foo_phase"; // Function: get // Returns the singleton phase handle static function uvm_foo_phase get(); if(m_inst == null) m_inst = new; return m_inst; endfunction protected function new(string name="foo"); super.new(name); endfunction virtual function string get_type_name(); return type_name; endfunction endclass /////////////////////////////////////////////////////// Here's what I added to the build phase of my test component to add it to the run time schedule. uvm_phase sched = uvm_domain::get_uvm_schedule(); sched.add(uvm_foo_phase::get(), .after_phase(sched.find_by_name("pre_configure")), .before_phase(sched.find_by_name("configure"))); /////////////////////////////////////////////////////// Here's what I added to my my_uvm_sequencer class virtual function void foo_phase(uvm_phase phase); start_phase_sequence(phase); endfunction
  4. I'm sure it's simple (if you know what you're doing) but could someone please point me to, or include in a response, a simple and complete example of defining a user-defined phase to be inserted into the schedule between the pre_configure and configure phases? Thanks.
  5. In the run_phase() of a component, I'd like to raise an objection to the main phase so I added the following: uvm_main_phase::get().raise_objection(this); and I get this error when it runs: UVM_ERROR @ 0 ns: reporter [uVM/PH/NULL_OBJECTION] 'uvm_test_top.foo' attempted to raise an objection on 'main', however 'main' is not a task-based phase node! (This is a UVM_PHASE_IMP, you have to query the schedule to find the UVM_PHASE_NODE) Why? What do I not understand or how should this be done? It looks to me like uvm_main_phase is derived from uvm_task_phase so wouldn't that make it a "task-based phase node"? Thanks. Walker
  6. Actually that bug report is for uvm_mem. The bug I described is with uvm_mem_mam. FWIW, changing all of the "int unsigned" size or n_bytes arguments to "longint unsigned" works just fine it seems.
  7. Is there some good reason that the n_bytes argument to uvm_mem_mam request_region() and reserve_region() are unsigned ints and not unsigned longints? It seems inconsistent with the address "offset" arguments/attributes which *are* longints (or bit [63:0]) and obviously it prevents allocation of regions larger than 2**32-1. Perhaps this could/should be fixed in a future release? Or is there some subtlety I'm missing. Thanks. Walker
  8. No time to do a full-fledged test case but I think it could be described simply enough. 1) Sequence A locks a sequencer 2) Sequence B tries to lock the sequencer but the call to lock() doesn't return (presumably because sequence A has the sequencer locked) 3) Sequence C tries to lock the sequencer but the call to lock() doesn't return (presumably because sequence A has the sequencer locked) 4) Sequence A unlocks the sequencer 5) The call to lock() from sequences B and C both return 6) Sequences B and C both call start_item() 7) Sequences B and C hang because start_item() never completes for them As I instrumented the UVM code to debug, there is code to clearly have a notion of a lock list suggesting that the idea of more than one sequence getting the lock is somehow supported but I don't understand that usage model. It seems like a sequence can get the lock but still be "blocked". I ended up working around it by having the grabbing sequences do the following. Not sure if this is what one is expected to do or if this is a robust solution so comments would be welcome. lock(); while (is_blocked()) begin unlock(); lock(); end start_item(foo); finish_item(foo); unlock();
  9. Right. I have no problem with the check/warning. But the code that's causing it is in the UVM library and all that I did to expose it was create a nested register block. What's the recommended workaround? I downgraded the warning but perhaps there is something more elegant. Thanks.
  10. I'm working on upgrading to UVM 1.2 (from 1.1d). I am seeing a case where multiple sequences have called a sequencer's grab(), they are both blocked waiting on a grab() done by an earlier sequence, and when that earlier sequence calls ungrab(), both of the waiting sequences unblock and their grab() calls complete. I thought this shouldn't happen. My understanding was that the grab ensured that only one grabbing sequence would win that arbitration until it ungrabbed. Instrumenting the UVM code, I can see the grant_queued_locks() function calling m_set_arbitration_completed() for two sequences in a foreach loop. Am I misunderstanding grab/ungrab or doing something wrong? Thanks.
  11. Creating a UVM register block that is a sub-block of another UVM register block, when I call the configure function of the sub-block, I get this warning. UVM_WARNING @ 0 ns: reporter [uVM/RSRC/NOREGEX] a resource with meta characters in the field name has been created "regs.foo_regs" because of this implementation of configure from the UVM 1.2 source code function void uvm_reg_block::configure(uvm_reg_block parent=null, string hdl_path=""); this.parent = parent; if (parent != null) this.parent.add_block(this); add_hdl_path(hdl_path); uvm_resource_db#(uvm_reg_block)::set("uvm_reg::*", get_full_name(), this); endfunction Because the full name for the sub-block includes the name of the parent block with a "." between it. Am I missing something or doing something wrong? Seems like this will always happen with nested register blocks.
  12. FWIW, Later yesterday I found this bug logged which seems to be the same thing. http://www.eda.org/svdb/view.php?id=4820
  13. I just hit this same problem and tracked it down to the same underlying problem in the UVM code. This change, to both the do_bus_read() and do_bus_write() tasks in uvm_reg_map.svh, seemed to fix it for me. Changed: rw.parent.get_base_response(bus_rsp); to: rw.parent.get_base_response(bus_rsp, bus_req.get_transaction_id()); Any comments on whether this is a bug or not. It is not changed/fixed in the UVM 1.2 release.
  14. Does anyone have an answer to this question about use of the backdoor. I encountered a related problem to this map override issue described in this post. http://forums.accellera.org/topic/2104-question-about-backdoor-map/ I can't see any way around it and any way to not get the warning from the register model that I described for any back door write. Thanks. Walker
  15. Agree with post #7. Also, if you look carefully at the example I posted, the count seemed to be incrementing quite nicely but it didn't seem to be getting used to initializing the ID of each object.
  16. Funny, the response I got from the simulator vendor is basically that the ID is not guaranteed to be unique over the whole simulation for the very reasons cited by post #4. I guess I'd argue that I would have thought that the UVM intention was that these IDs would be unique across UVM objects over the life of the simulation. Is that the UVM intention? The use of a static counter variable in the reference implementation suggest that it is the intention. Also, as post #5 says, since the uvm_object new() is using a static count variable to assign the ID, this shouldn't ever be decremented/destroyed by garbage collection so I agree that I still think it's a simulator bug.
  17. I'm seeing the uvm_object get_inst_id() function not returning unique, new IDs for new objects that I create. More specifically, it's returning a repeating cycle of a few different IDs. Looking under the hood at uvm_object.svh it's a pretty trivial mechanism so I can't see why it isn't working. Also, in a derived class I created I mimicked the same mechanism and my mechanism works fine. Test case and example output is below. Note that the static instance count value seems to increment nicely as expected but the instance ID values seem to bear no relation to that count and repeat every 6 objects. Am I missing something really obvious here or is this a possible bug. I see this using UVM 1.1d downloaded from Accellera. ////////////////////////////////////////////////////////////////////////////////////////////////////////////// class my_object_t extends uvm_object; static int next_id; int my_id; function new (string name="my_object"); super.new(name); my_id = next_id++; endfunction : new `uvm_object_utils(my_object_t) endclass begin my_object_t my_object; for (int i = 0; i < 100; i++) begin my_object = new(); `uvm_info("", $sformatf("my object inst id is %d (0x%0x) or %0d, inst count is %d (0x%0x) or %0d", my_object.get_inst_id(), my_object.get_inst_id(), my_object.my_id, my_object.get_inst_count(), my_object.get_inst_count(), my_object.next_id), UVM_LOW) end end UVM_INFO @ 0 ns: uvm_test_top.tb.c [] my object inst id is 72135 (0x119c7) or 0, inst count is 9585 (0x2571) or 1 UVM_INFO @ 0 ns: uvm_test_top.tb.c [] my object inst id is 72122 (0x119ba) or 1, inst count is 9586 (0x2572) or 2 UVM_INFO @ 0 ns: uvm_test_top.tb.c [] my object inst id is 581 (0x245) or 2, inst count is 9587 (0x2573) or 3 UVM_INFO @ 0 ns: uvm_test_top.tb.c [] my object inst id is 72126 (0x119be) or 3, inst count is 9588 (0x2574) or 4 UVM_INFO @ 0 ns: uvm_test_top.tb.c [] my object inst id is 72120 (0x119b8) or 4, inst count is 9589 (0x2575) or 5 UVM_INFO @ 0 ns: uvm_test_top.tb.c [] my object inst id is 69783 (0x11097) or 5, inst count is 9590 (0x2576) or 6 UVM_INFO @ 0 ns: uvm_test_top.tb.c [] my object inst id is 72135 (0x119c7) or 6, inst count is 9591 (0x2577) or 7 UVM_INFO @ 0 ns: uvm_test_top.tb.c [] my object inst id is 72122 (0x119ba) or 7, inst count is 9592 (0x2578) or 8 UVM_INFO @ 0 ns: uvm_test_top.tb.c [] my object inst id is 581 (0x245) or 8, inst count is 9593 (0x2579) or 9 UVM_INFO @ 0 ns: uvm_test_top.tb.c [] my object inst id is 72126 (0x119be) or 9, inst count is 9594 (0x257a) or 10 UVM_INFO @ 0 ns: uvm_test_top.tb.c [] my object inst id is 72120 (0x119b8) or 10, inst count is 9595 (0x257b) or 11 UVM_INFO @ 0 ns: uvm_test_top.tb.c [] my object inst id is 69783 (0x11097) or 11, inst count is 9596 (0x257c) or 12 UVM_INFO @ 0 ns: uvm_test_top.tb.c [] my object inst id is 72135 (0x119c7) or 12, inst count is 9597 (0x257d) or 13 UVM_INFO @ 0 ns: uvm_test_top.tb.c [] my object inst id is 72122 (0x119ba) or 13, inst count is 9598 (0x257e) or 14 UVM_INFO @ 0 ns: uvm_test_top.tb.c [] my object inst id is 581 (0x245) or 14, inst count is 9599 (0x257f) or 15 UVM_INFO @ 0 ns: uvm_test_top.tb.c [] my object inst id is 72126 (0x119be) or 15, inst count is 9600 (0x2580) or 16 UVM_INFO @ 0 ns: uvm_test_top.tb.c [] my object inst id is 72120 (0x119b8) or 16, inst count is 9601 (0x2581) or 17 UVM_INFO @ 0 ns: uvm_test_top.tb.c [] my object inst id is 69783 (0x11097) or 17, inst count is 9602 (0x2582) or 18 UVM_INFO @ 0 ns: uvm_test_top.tb.c [] my object inst id is 72135 (0x119c7) or 18, inst count is 9603 (0x2583) or 19 UVM_INFO @ 0 ns: uvm_test_top.tb.c [] my object inst id is 72122 (0x119ba) or 19, inst count is 9604 (0x2584) or 20 UVM_INFO @ 0 ns: uvm_test_top.tb.c [] my object inst id is 581 (0x245) or 20, inst count is 9605 (0x2585) or 21 UVM_INFO @ 0 ns: uvm_test_top.tb.c [] my object inst id is 72126 (0x119be) or 21, inst count is 9606 (0x2586) or 22 UVM_INFO @ 0 ns: uvm_test_top.tb.c [] my object inst id is 72120 (0x119b8) or 22, inst count is 9607 (0x2587) or 23 UVM_INFO @ 0 ns: uvm_test_top.tb.c [] my object inst id is 69783 (0x11097) or 23, inst count is 9608 (0x2588) or 24 UVM_INFO @ 0 ns: uvm_test_top.tb.c [] my object inst id is 72135 (0x119c7) or 24, inst count is 9609 (0x2589) or 25 UVM_INFO @ 0 ns: uvm_test_top.tb.c [] my object inst id is 72122 (0x119ba) or 25, inst count is 9610 (0x258a) or 26 UVM_INFO @ 0 ns: uvm_test_top.tb.c [] my object inst id is 581 (0x245) or 26, inst count is 9611 (0x258b) or 27 UVM_INFO @ 0 ns: uvm_test_top.tb.c [] my object inst id is 72126 (0x119be) or 27, inst count is 9612 (0x258c) or 28 UVM_INFO @ 0 ns: uvm_test_top.tb.c [] my object inst id is 72120 (0x119b8) or 28, inst count is 9613 (0x258d) or 29 UVM_INFO @ 0 ns: uvm_test_top.tb.c [] my object inst id is 69783 (0x11097) or 29, inst count is 9614 (0x258e) or 30 UVM_INFO @ 0 ns: uvm_test_top.tb.c [] my object inst id is 72135 (0x119c7) or 30, inst count is 9615 (0x258f) or 31 UVM_INFO @ 0 ns: uvm_test_top.tb.c [] my object inst id is 72122 (0x119ba) or 31, inst count is 9616 (0x2590) or 32 UVM_INFO @ 0 ns: uvm_test_top.tb.c [] my object inst id is 581 (0x245) or 32, inst count is 9617 (0x2591) or 33 UVM_INFO @ 0 ns: uvm_test_top.tb.c [] my object inst id is 72126 (0x119be) or 33, inst count is 9618 (0x2592) or 34 UVM_INFO @ 0 ns: uvm_test_top.tb.c [] my object inst id is 72120 (0x119b8) or 34, inst count is 9619 (0x2593) or 35 UVM_INFO @ 0 ns: uvm_test_top.tb.c [] my object inst id is 69783 (0x11097) or 35, inst count is 9620 (0x2594) or 36 UVM_INFO @ 0 ns: uvm_test_top.tb.c [] my object inst id is 72135 (0x119c7) or 36, inst count is 9621 (0x2595) or 37 UVM_INFO @ 0 ns: uvm_test_top.tb.c [] my object inst id is 72122 (0x119ba) or 37, inst count is 9622 (0x2596) or 38 UVM_INFO @ 0 ns: uvm_test_top.tb.c [] my object inst id is 581 (0x245) or 38, inst count is 9623 (0x2597) or 39
  18. I'm trying to set up user-defined backdoor access to a memory. I created a derived uvm_reg_backdoor object and configured the memory with it. When I do a backdoor write to this memory, I get this warning: UVM_WARNING @ 0 ns: reporter [RegModel] Memory 'mem.Memory' is not contained within map 'Backdoor' (called from get_access()) Digging into the UVM source code, I can see some code using the map returned by the static uvm_reg_map::backdoor() which returns its local m_backdoor (after creating a map first if it happens to be null). I tried using uvm_reg_map::backdoor() to get a reference to this map and then using it to add my memory to the map but this error: UVM_ERROR @ 0 ns: reporter [RegModel] Memory 'mem.Memory' may not be added to address map 'Backdoor' : they are not in the same block I didn't see anything in any documentation about creating or setting up this backdoor map and I don't really see any way for users to even do that if they wanted to. My user-defined write() function still seems to be called despite the warning. Can someone please enlighten me about the proper way to set up this backdoor map or point me in the direction of an example or some documentation? I'm missing something. Thanks.
  19. Thanks. That worked. I couldn't find and example or discussion of exactly how to do this in either the reference manual, user's guide, or any of the examples. It's essentially what is discussed as a configuration object in the user's guide but the details are not covered. It seems like a good example of this somewhere is warranted. Also, it's not clear to me why it is essential to use the uvm_object type; i.e. why using my object type (which is derived from uvm_object) won't work. I tried it. It doesn't. Even if the field is defined using UVM_REFERENCE. Anyway, thanks again. Walker
  20. I'm having trouble using the config_db mechanism to set a property in a uvm component that is an object. Using the same flow/mechanisms for an integer property seems to work fine but the setting of a property defined using uvm_field_object doesn't work. The essence of the code is extracted below. Any ideas? Thanks. Walker // my_foo_struct_t is class that extends foo_struct_t class my_foo_struct_t foo_struct; virtual function void build_phase(uvm_phase phase); super.build_phase(phase); chip = chip_t::type_id::create("c", this); foo_struct = new(); // Set the foo_struct property in any sub-component to this component's foo_struct // foo_struct is a uvm_field_object in one component type // This doesn't work uvm_config_db#(foo_struct_t)::set(this, "*", "foo_struct", foo_struct); // Set the foo property in any sub-component // foo is a uvm_field_int in several component types // This does work uvm_config_db#(int)::set(this, "*", "foo", 33); endfunction : build_phase
×
×
  • Create New...