Virtual sequencer

One of my favorite articles is UVM Rapid Adoption by Sutherland/Fitzpatrick. On the top of page 7: “There is no need to include a virtual sequencer in either the test or the environment. All the virtual sequencer does is add more inter-component connections and complexity to the environment, with no benefit of portability nor flexibility.”

I’m not sure I’m convinced, however. It seems the virtual sequencer offers a nice way to bundle sequencers, especially for scaling purposes. At integration level test, I can avoid an additional layer of digging to acquire a sequencer handle, and it’s clear who the sequencer belongs to (the “bundle”).

Thoughts?

Note that the UVM Cookbook also recommends a virtual sequence without a virtual sequencer. This is not a coincidence. ;-)
In either case, the virtual sequence must contain handles to the sequencers on which the subsequences will run. These handles can either point directly to the agents’ sequencers (the preferred method) or they can point to handles in the virtual sequencer which are in turn connected to the agents’ sequencers.
The sequencers really aren’t being bundled at all. They remain in the agents. All that is needed is to configure the virtual sequence so that each sequencer handle points to the correct agent’s sequencer. If you want to bundle multiple agents, you can also create sequencer handles at the component layer so from outside, you only have to point to bundle.sequencer1 instead of bundle.agent1.sequencer.
In any event, the sequencer belongs to the agent. It’s recommended that you don’t lose sight of that fact.

In reply to tfitz:

By the way, I’m glad you enjoyed the UVM Rapid Adoption article. ;-)

In reply to bmorris:

The only benefit I can see to the virtual sequencer approach is that you can save some code:


    virt_seq.init(.bus_seqr(m_env.m_agent1.m_sequencer),
                  .gpio_seqr(m_env.m_agent2.m_sequencer)); 
    virt_seq.start(null);

    // versus

    virt_seq.start(virtual_sequencer);

If you only start a virtual sequence in the base test, then it’s not a big deal, since you can always do factory overrides after that and get a different virtual sequence instantiated. If you start virtual sequences within virtual sequences, then you’ll always have to pass the bus sequencer handles to each sub-sequence. If you have to pass 4, 5, 6, etc. sequencers, this is going to get really old, really fast.

In reply to Tudor Timi:

I don’t think so. You have to pass the sequencer handles somewhere, so either you do it in an init_vseq() method (see the Cookbook) or you have to make the actual connections between the agent sequencers and the pointers in the virtual sequencer. Granted, using the virtual sequencer could allow you to make these connections in the environment instead of the test, but using init_vseq, you could make the connections in a base test, so there’s not much difference.

In reply to tfitz:

By bundled, I meant the group of sequencer handles offers a test writer a quick glimpse into all the sequencers available for a block. Your wrapper suggestion would provide the same feature, and also remove one level of digging.

For example, this code, pulled from my test, sets up a sequence which drives an ethernet layering agent in my component environment. There are six long path-names right out of the gate.

SeqTraffic.init(
  .chip_select(EXEC_LNP_CS),
  .eth_sqr(env.comp_env1.input_pkt_agent.Eth2LL.sequencer),
  .ip_sqr(env.comp_env1.input_pkt_agent.Ip2Eth.sequencer),
  .icmp_sqr(env.comp_env1.input_pkt_agent.Icmp2Ip.sequencer),
  .igmp_sqr(env.comp_env1.input_pkt_agent.Igmp2Ip.sequencer),
  .udp_sqr(env.comp_env1.input_pkt_agent.Udp2Ip.sequencer),
  .arp_sqr(env.comp_env1.input_pkt_agent.Arp2Eth.sequencer)
  // ...    
);

Now lets say I start adding more of these block level environments, and drive those embedded agents as well…

SeqTraffic.init(
  .chip_select(SYS_LNP_CS),
  .eth_sqr(env.comp_env2.input_pkt_agent.Eth2LL.sequencer),
  .ip_sqr(env.env.comp_env2.input_pkt_agent.Ip2Eth.sequencer),
  .icmp_sqr(env.env.comp_env2.input_pkt_agent.Icmp2Ip.sequencer),
  .igmp_sqr(env.env.comp_env2.input_pkt_agent.Igmp2Ip.sequencer),
  .udp_sqr(env.env.comp_env2.input_pkt_agent.Udp2Ip.sequencer),
  .arp_sqr(env.env.comp_env2.input_pkt_agent.Arp2Eth.sequencer)
  // ...    
);

// etc…

As more and more components are added, it’s verbose. Generally in other parts of the hierarchy, path-names are shunned. Perhaps in the test, it’s not quite as important, as the test is not portable anyway. Anyway, I’m rambling a bit. I think I’ll stick with this approach for the time being.

In reply to tfitz:

In reply to tfitz:
By the way, I’m glad you enjoyed the UVM Rapid Adoption article. ;-)

Ive ready quite a few of both of your papers, this is my current favorite.

I wish I had it when I started SystemVerilog/UVM years ago. It’s what I would hand to a beginner to help them focus on the meat of UVM. I don’t think there is a painless way to learn UVM/SystemVerilog, but it definitely would pave the road a bit. I think the division of labor description is a really key point, especially for someone like myself, who works on a small team that has to wear all the hats. I can at least try to step into the shoes of, say, the “sequence writer” and decide what is appropriate to provide a “test writer”. This is what pushes me to get the complexity out of the test, and into the sequence, since they are the portable workhorses of the environment. Anyway, thanks for taking the time to write. I’d stick it in the “read-this-first” part of your teaching methodology.

In reply to bmorris:

Since all we’re doing is passing sequencer pointers around, you could declare sequencer pointers in your env that point to the agent sequencers. Then, when you init your vseq, you just have to pass in blk_env.agent1_seqr. If that block-level env gets put in a system-level env, you could declare another sequencer pointer and set it to blk_env.agent1_seqr.

Or, if you really want to, you can use a virtual sequencer. ;-)

In reply to tfitz:

Good enough; this clears up my main hang-up with the verbosity issue. Thanks