Sequence access to a virtual interface

I’ve got several sequences which need access to a virtual interface. I chose to pass in the virtual interface handle from the test.

Yes, I avoided using the “penalty” of using the config db, but now I’ve got to populate the handle for each and every sequence that uses it, and there are several layers of sequences, and the handle must be passed down through every single level. Extremely verbose, I regret doing this.

alternate options…

  1. define a base class, and use config DB to automatically assign the handle, in one location.
  2. define a base class, and assign the handle from the test, once, for any of my top level sequences.

In reply to bmorris:

I will argue that a sequence should never need access to a virtual interface. The stimulus generation should be independent of any DUT signal. However, the sequence can change its behavior based on responses received from previous transactions.

In reply to bmorris:

I would use option 1)

i.e,

  1. define a base sequence
  2. extend all the sequences from base sequence
  3. in the base sequence pre_body method, would get the interface
    handle from config db once

In reply to cgales:

I understand your point; let me illustrate my scenario. I’ve got a general purpose bus (“GP_if”) with data, addr, chip select, etc, which connects to several components. One component on this bus has an additional signal, BUSY, which must be checked before performing any bus activity. This BUSY signal is not a part of GP_if; it’s particular to just one component. So, the methods of GP_if, or its BFM, know nothing of the signal.

This leaves my sequence to do the job of checking the signal first.

Thoughts?

In reply to bmorris:

If there is another signal that you need to control how/when your driver puts traffic on an interface, then I would either add the signal to the interface, or add another interface to your driver.

Remember that stimulus generation has no knowledge of time or other testbench state. It is the responsibility of the driver to ensure that it is driving the current transaction when the interface is in the appropriate state.

In reply to cgales:

“Remember that stimulus generation has no knowledge of time or other testbench state.”

This seems very restrictive to a test. What if the test wants to wait until certain DUT events occur, such as it reaching a particular state, or a timer reaching a certain value, or some random signal going low? How would these types of events detected without a virtual interface handle?

In reply to bmorris:

You create agents that handle the various functionality that you need. Interrupt agents to handle interrupt signals, timer agents that allow you to wait for specific number of clocks, reset agents that can coordinate various reset requirements, etc.

Sequence items and responses are then used to provide the co-ordination between all the agents.

In reply to cgales:

Let’s say I’m sitting in my sequence, and I want to wait until reset deasserts before providing any stimulus. Currently, I just call system_vif.wait_rst_done().

Instead of calling that vif method, how would I use a “reset agent” to achieve the same purpose?
This agent has a sequencer, driver, and monitor I’m assuming, and it’s own transaction type.

Do you have some examples? I’m a bit confused.

In reply to bmorris:

One thing to remember is that stimulus can be created before the simulation starts. It is very common that the first transactions are created at time 0 and the drivers will wait until the interface is ready before it drives the transaction. This is possible because most interfaces contain a reset signal as part of the interface specification signal.

If you really insist on waiting until reset is de-asserted before generating stimulus, then you can create an agent using the standard agent architecture. You would create a sequence item which when processed by the driver would wait for the reset signal to be de-asserted. The driver would then call item_done(), allowing for the reset sequence to finish.

Since sequences are blocking, once the reset sequence is complete you can then continue with your stimulus generation.

In reply to cgales:

One thing to remember is that stimulus can be created before the simulation starts. It is very common that the first transactions are created at time 0 and the drivers will wait until the interface is ready before it drives the transaction. This is possible because most interfaces contain a reset signal as part of the interface specification signal.

yes; my transactors/bfms currently do this. I should have picked a different example. But in any case, if I were doing it manually…

Along with the reset agent, I presume I need to create this:

typedef enum {WAIT_RST_LOW, WAIT_RST_HIGH, DO_THIS, DO_THAT} reset_cmd_t;

class reset_txn extends uvm_sequence_item;
  `uvm_object_utils(reset_txn);

  reset_cmd_t cmd;

  function new(string name="");
    super.new(name);
  endfunction

endclass

// Using reset agent from my virtual sequence

virtual task body();

  // wait for reset to de-assert
  reset_txn txn;
  txn = reset_txn::type_id::create("txn");
  txn.cmd=WAIT_RESET_LOW;
  start_item(txn,,rst_agent);
  finish_item(txn);
  //...

Is this the idea?

In reply to bmorris:

Yes. That is what you want to do.

You will commonly see all the ancillary functions such as clocks, resets, interrupts and other signals into one easy to use agent.

In reply to cgales:

Thanks for the info. I haven’t seen this approach in literature.

Do you include a monitor in this “system agent”, which broadcasts when interrupt signals, resets, etc change value? Perhaps for feeding a checker/model?

In reply to bmorris:

Yes. It would be used for both a scoreboard/checker and coverage.

In reply to cgales:

this leads a bit full circle to my original question then; now I’ve got an additional sequencer handle that must be passed around everywhere I want to do some system activity. I’ve got a few tiers of sequences.

How do you recommend getting the sequencer passed around succinctly?

*I’ve tried just passing the handle around everywhere it’s needed, and Ive found it verbose and prone to error (forgetting to assign it).

In reply to bmorris:

I take the following approach regarding sequencer handles:

  • Each environment will have a base test class and a base test sequence class. Every test for that environment extends from the base test class and every test sequence extends from the base test sequence class.
  • The base test class contains a function to assign the environment’s agent sequencers to the base test sequence. If you add a new agent to the base test sequence, then you can simply assign the additional agent’s sequencer handle from the base test.

By using a function in the base test sequence class, you only have to add the new agent’s sequencer assignment one time and not in each sequence.

In reply to cgales:

ah the approach from the cookbook. yes, that just leaves not forgetting to call the function! Thanks for your advice as always.

In reply to cgales:

In reply to bmorris:
Yes. That is what you want to do.
You will commonly see all the ancillary functions such as clocks, resets, interrupts and other signals into one easy to use agent.

Do you know where I could look at source code for one of these? driver, agent, monitor, transaction?

In reply to cgales:

In reply to bmorris:
If there is another signal that you need to control how/when your driver puts traffic on an interface, then I would either add the signal to the interface, or add another interface to your driver.
Remember that stimulus generation has no knowledge of time or other testbench state. It is the responsibility of the driver to ensure that it is driving the current transaction when the interface is in the appropriate state.

I diddled with the agent for awhile, and based off another forum where you made a post, you described including optional signals into the interface. This helped me justify adding them in. I included the extra signals for devices that had them, and made it optional (via txn switch). It greatly simplified the sequences by pushing all the handshaking to the BFM.

I’m not sold on using an agent for sideband signals and simply waiting X clocks etc, seems very verbose. I’ll stew on that for the future…