cliffc Posted September 19, 2014 Report Share Posted September 19, 2014 Hi, All - I have seen examples of sequences started on a null sequencer of the form: seq.start(null). How is a sequencer specified for these sequences? Thanks. Regards - Cliff Quote Link to comment Share on other sites More sharing options...
uwes Posted September 19, 2014 Report Share Posted September 19, 2014 hi, running a sequence on a "null" sequencer is only valid for virtual sequences. /uwe Quote Link to comment Share on other sites More sharing options...
tudor.timi Posted September 19, 2014 Report Share Posted September 19, 2014 @Uwe But what does this mean exactly? If it's a virtual sequence running on a 'null' sequencer, it can only start other sequences if it gets pointers to the respective sequencers from some other source (config DB, etc.) and not from its parent sequencer, right? Also, we probably can't do any funky grabbing or prioritization, either. In what scenario would this be useful? Quote Link to comment Share on other sites More sharing options...
apfitch Posted September 19, 2014 Report Share Posted September 19, 2014 I've used it just because for a simple virtual sequence there's no need to create a virtual sequencer whose only purpose is to hold references to the sub-sequencers. You can put those references in the virtual sequence instead. So I suppose it just saves a bit of typing! regards Alan P.S. I wish UVM had used different words that "sequence" and "sequencer"... it's a recipe for confusion. Quote Link to comment Share on other sites More sharing options...
cliffc Posted September 21, 2014 Author Report Share Posted September 21, 2014 @Alan - I have always used the almost-empty virtual sequencer with references to the sub-sequencers and used the env to copy the subsequencer handles to the handles declared in the virtual sequencer, then my vseq_base class would $cast the m_sequencer handle to the vseqr handle and use that handle to set the sub-sequencer handles declared in the vseq_base class. Then I could extend the vseq_base to create virtual sequences that started on the two sub-sequencer handles. Relevant code from the vseq_base and vseq classes below. Could you give an equivalent example of how you copy the handles into the virtual sequence and then execute the virtual sequence on null? Perhaps @uwes could explain how it tis done. Thanks - Cliff class vseq_base extends uvm_sequence; `uvm_object_utils(vseq_base) function new(string name="vseq_base"); super.new(name); endfunction vsequencer v_sqr; tb_ahb_sequencer ahb_sqr; tb_eth_sequencer eth_sqr; virtual task pre_body(); if(!$cast( v_sqr, get_sequencer() )) `uvm_fatal("vseq_base","BAD v_sqr type");; ahb_sqr = v_sqr.ahb_sqr; eth_sqr = v_sqr.eth_sqr; endtask endclass class v_seq1 extends vseq_base; `uvm_object_utils(v_seq1) function new(string name="v_seq1"); super.new(name); endfunction task body(); ahb_pkt ahb_pkt; eth_pkt eth_pkt; //--------------------------------------------------- `uvm_info("v_seq1", "Executing virtual sequence on DUT.", UVM_HIGH) `uvm_do_on(ahb_pkt, ahb_sqr) `uvm_do_on(eth_pkt, eth_sqr) `uvm_do_on(eth_pkt, eth_sqr) `uvm_do_on(ahb_pkt, ahb_sqr) `uvm_info("v_seq1", "Sequence complete.", UVM_MEDIUM) endtask endclass Quote Link to comment Share on other sites More sharing options...
uwes Posted September 22, 2014 Report Share Posted September 22, 2014 @Uwe But what does this mean exactly? If it's a virtual sequence running on a 'null' sequencer, it can only start other sequences if it gets pointers to the respective sequencers from some other source (config DB, etc.) and not from its parent sequencer, right? Also, we probably can't do any funky grabbing or prioritization, either. In what scenario would this be useful? thats correct. a virtual sequence running on a null sequencer can start other virtual sequences(on this or other sequencers) or other BFM sequences/items (when a real sequencer handle is supplied). The 'funky' stuff like grab/lock does probably require a sequencer instance. priorities should only be in the picture for items. /uwe Quote Link to comment Share on other sites More sharing options...
uwes Posted September 22, 2014 Report Share Posted September 22, 2014 hi, some pseudo code (lacking checks,ctor and other things) class vseq1 extends uvm_sequence...; seqr1 s1; seqr2 s2; task body(); ... endtask endclass // with this simply instantiate the sequence assign the sequencers and start it vseq1 = new(); vseq1.s1 = path.to.my.sqr1; vseq1.s2 = path.to.other.sqr1; vseq.start(null); you may also do it via the config-db class vseq1 extends uvm_sequence...; task body(); seqr1 s1; seqr2 s2; uvm_config_db#(seq1type)::get(ctxt,"sqr1",s1); uvm_config_db#(seq1type)::get(ctxt,"sqr2",s2); `uvm_do_on(....) endtask endclass the challenge here is to invent a 'context'. 'null' or get_sequencer() isnt a good context alone here since it would map to uvm_root::get() and doesnt scale. but you could use ctxt=null and {get_full_name(),".sqr1"} as the full path for your virtual sequence plus the "sqr1" postfix /uwe. Quote Link to comment Share on other sites More sharing options...
ejo Posted September 24, 2014 Report Share Posted September 24, 2014 the challenge here is to invent a 'context'. 'null' or get_sequencer() isnt a good context alone here since it would map to uvm_root::get() and doesnt scale. but you could use ctxt=null and {get_full_name(),".sqr1"} as the full path for your virtual sequence plus the "sqr1" postfix /uwe. An alternative approach is to add a sequence to sequencer mapper to the top level environment, and use it to run sequences without reference to sequencers by calling (common) services in base classes for tests and sequences. Cliff's vsequence would go like this: task body(); `uvm_info("v_seq1", "Executing virtual sequence on DUT.", UVM_HIGH) RunSequence(ahb_pkt::Create()); RunSequence(eth_pkt::Create()); RunSequence(eth_pkt::Create()); RunSequence(ahb_pkt::Create()); `uvm_info("v_seq1", "Sequence complete.", UVM_MEDIUM) endtask In other words, just create the sequence and run, and it will be randomized in context of, and start on, the right sequencer automatically, provided the calling context is a test, sequence, or vsequence. Advantages: - no dot-pointing into the env - no need to single step through macros to debug - no need to distribute sequencers - easier for non-experts to modify/add tests - randomization, error checking etc in one place - inline constraints are discouraged BTW, null-sequencers aren't a wonderful idea in my opinion. An actual sequencer provides a context for sequences from the very beginning, which makes it easier to deal with resources etc, where the caller context is significant. Erling Quote Link to comment Share on other sites More sharing options...
joniale Posted January 16, 2018 Report Share Posted January 16, 2018 Hi experts, I have the following question about vertical reusability and null sequencers. I have a sequence that stimulates a sub block inside a TOP block. I have verified first the separated sub block. Therefore, i had a testbench for the sub block that has of course VC interfaces and registers. I would like to have a clear way of coding to allow vertical reusability of the sequence that test the sub block. In other words, i would like how to code the sub sequence so that i can start that sequence from a TOP module afterwards. I see the following problems 1)The TOP test bench will not have the interfaces (VCs) for the sub block. 2)The registers will be accessed through the TOP interface but not the sub interface. I can solve the 2 point by creating a new register model and connecting the predictor/adapter of the top. At the same time, i can overwrite the register model used in the sub block sequence so that it uses the new register TOP block handler correctly.---:OK However for the point one, it is more difficult. Theoretically, the sequence should ignore all the VCs of the sub block that are not used anymore. Now the sub block is driven by the TOP DUT and not by a test bench VC. How should a write the sequence so that these VC accesses are ignored in case a TOP sequence calling the old subsequence?. I though that any uvm_do macro that is performed to a VC that is not declared would be ignored but that is not the case... The only idea it comes to me is to code the sub-sequence with an if asking if the VC exists (not null). If it exists, then go ahead, but if it doesn´t assume that this access will be done by a TOP DUT and ignore it! Is this the right way to do this? How can you reuse your old sub sequence from the top sequence? Is there any methodology? Any link? Thanks in advance Jonathan Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.