Jump to content


  • Content Count

  • Joined

  • Last visited

  • Days Won


Erling last won the day on July 18 2015

Erling had the most liked content!

About Erling

  • Rank
    Senior Member

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

  1. Is this a bug or does the LRM state that an initializer for a static member is not in the scope of the member's class? Erling
  2. Is this really correct? The expression c=a+1 refers to a, and the rule is then that a must have been declared already. The initializer for a is part of the declaration of a, thus the value is known already to be 3 at point of declaration of c, and the initializer for c should therefore be 4. What do you mean the value could be 1? One should think that one reason for merging initialization with the declaration was to avoid this confusion. In C++ for example, where the two steps are separated, the initializers can be listed in an order that isn't the actual initialization order (which is the declaration order). It would seem that if the SV improvement in this regard comes with undefined initialization order, then this isn't an improvement after all, but a defect. Erling
  3. The slave monitor having a uvm_blocking_peek_imp means it is implementing a peek member task for someone else to call through a uvm_blocking_peek_port, which in this case sits in the sequencer. A sequence can then call peek() on the sequencer port, i.e p_sequencer.addr_ph_port.peek(). The peek call will be forwarded to the peek task of the monitor since the slave agent has connected the peek port of the sequencer to the monitor peek imp. At that point, peek() of the monitor will pend on the address_phase_grabbed event and return trans_collected to the sequence in the trans output parameter when the event triggers. Erling
  4. >But suppose i need the status of a particluar signal to cal a sequence inside a virtual sequencer, is there a way other than peek/poke the interface signals. Yes, the interface signals can be abstracted away. The status needed can be given a name, and providing that named status can be put as a requirement on the top level environment, i.e. simply assert that a testbench for my_dut shall provide status this and status that. When the test, in turn, is implemented by means of the testbench, it can just ask the testbench for status between sequences as needed, without direct reference to interface signals. Virtual sequences too can be implemented by means of the testbench, and can get hold of status in the same way a test would do. In this way, the testbench can use whatever method it likes to obtain the status, e.g. receive it through a port or event, or forward the status request to a component in the interface. The test or virtual sequence wouldn't notice the difference. Erling
  5. >If it does, then how create an instance of the semaphore via new()? Could you give the example codes? Just declare the semaphore with an initializer in the interface, for example: interface fifo_if ... semaphore lock = new(1); endinterface >The situation is like this, a_item is used to config the duv, b_item and c_item >are different types of packet, such as b_item is a "nap" packet, c_item is a >"dma" packet. but a_item, b_item and c_item all need to transfer to duv via the >same interface, which is fifo interface or pcie packet interface. Is it >difficult for uvm to solve such problem? There is no perfect solution to this problem. It is sometimes feasible to transfer different things through one representation, and sometimes not. If you choose different types extended from the agent transaction type, uvm may be of help at the sender side, as you can use the factory to override what's actually sent. Things will be serialized at the receiver side, since there is only one driver, but there will be downcast to the actual transaction type. To get started, it is probably easier to represent all packets types by one transaction type, i.e have the packet type a rand field of the transaction, and then choose packet type by randomizing the packet with the actual packet type. The receiver will have to use the packet type field to figure out how to interpret the rest of the request, again a cast, sort of, in the driver. You may want to try to get this up and running first, and then consider alternatives as needed. Erling
  6. >Maybe I can do like this: Individual semaphores on the items isn't going to help. If you want to serialize access to the interface, have a single semaphore in the interface for this purpose. >But I have one question about this, will the uvm report compile error or >runtime error while assigning data to the same interface's data in the write() >task in different drivers in uvm??? The last written data will be driven. >...how will the driver be blocked when it cann't get the semaphore while another driver is doing write task? Unless the drivers have idle work to do, they could simply block on the semaphore, ie use get() and not try_get. By the way, what makes you conclude that the transactions need to be of different types, ie what is special about a_item and b_item, so they can't be represented by my_item? Erling
  7. If the driver is parameterized on my_item, it can also accept any transaction extended from my_item. A sequence producing my_item's could be configured to produce some other item extended from my_item (by means of instance overrides for example). The driver would then have to downcast to determine the actual item type. Erling
  8. You could have a_item, b_item, etc extend from my_item, and transfer them as my_item through the agent, with the driver downcasting my_item to reveal the actual request. If the transactions aren't related in any way, it would seem better, as you point out, to have separate agents for them. Not sure what you mean by "how does it arbitrates the drivers". If the drivers are going to work with the same interface, but can't do that concurrently for some reason, a semaphore in the interface could be used to enforce serialization. Erling
  9. Yes, I'd hoped there were more than a lonely num I have many settings too, but they need not be visible in all sequences. If all knobs need to be visible everywhere, I'd suspect there is something unfortunate going on that isn't related to knobs. Also, if sequences indeed need access to many external settings, then it is always possible to aggregate and get hold of them in one operation. If you're concerned about performance, I'd recommend to fix the problem at one place, instead of distributing caches with direct access. Erling
  10. Not necessarily. Starting sequences could be delegated, without reference to sequencers. What often has to be dealt with, though, is the little things in between sequences, necessary to orchestrate operations, but it is not obvious to me that the sequencer should be involved in this (either). Another option could be to implement virtual sequences by means of the environment, and leave the sequencers an implementation detail. For example, if a piece of information is needed, and all the sequence has to talk to is the sequencer, then it is necessary for the environment to cache the information on the sequencer, and for the sequence to get hold of it via a dynamic downcast, i.e the p_sequencer solution. But if the sequence is implemented by means of the environment, on the other hand, it can go directly to the source, without casting or caching anything, and this would also work nicely in cases where the information isn't cacheable. What do you think, are there obvious problems with this solution? Other ideas? Erling
  11. It seems to me this would be reinventing global variables. I believe it is better to encapsulate related properties in components and sequences and strive to make them standalone and decoupled. If you need additional behavior later on, it may be better to extend instead of if-else-ing the original class on global knobs. Yes, but there are other solutions to this problem. For example, the good little monitor could handle interrupts as events, and transfer any additional info, if necessary, through the event. A sequence could fetch the event of interest from a pool setup by the environment. Things would be decoupled with no sequencer in between. Erling
  12. If num in your sample code is meant to be configurable, why not get hold of it explicitly at point of usage? This can be reduced to a one-liner with support from a common base class for sequences. The sub-sequence could go like this for example: class MySubSeq ...; rand int num; function void pre_randomize(); if (IsConfigInt("N", num)) num.rand_mode(0); endfunction endclass The inherited IsConfigInt() could first check the command line for +N=value, and if not found, try read an int resource named "N" in scope of the sequence. If a value was found in this way, randomization of num is turned off, otherwise num is randomized locally as usual. The top level virtual sequence could be responsible for coming up with a value for num, for example: class MyTopSeq ...; rand int num; function void pre_randomize(); if (IsUserInt("N", num)) num.rand_mode(0); endfunction function void post_randomize(); SetConfigInt("N", num); endfunction endclass The inherited IsUserInt() checks if there a command line value for num, and SetConfigInt() writes the actual num to a resource named "N" in scope of the sequence. The root component in the environment where the sequences shall run, could be responsible for creating the num resource with default value and scope to be matched by the sequences. This could happen in build or end_of_elaboration, so there will be a self-documenting list of system-wide settings at one place in the environment. I know this isn't rocket science exactly, but it is simple, explicit, and debuggable, and you can still choose to randomize sequences with inline constraints when this makes sense. Erling
  13. Why is it you want to have the config settings on the sequencer? What problem does this solve? Erling
  14. I recommand putting your own uvm survival kit in a package and document it. In this case you could have a common base for all sequences, and that base can override get_full_name() to return whatever dot-separted list of strings that makes sense for you. Erling
  • Create New...