URL
https://opencores.org/ocsvn/uart2bus_testbench/uart2bus_testbench/trunk
Subversion Repositories uart2bus_testbench
[/] [uart2bus_testbench/] [trunk/] [tb/] [uvm_src/] [macros/] [uvm_sequence_defines.svh] - Rev 16
Compare with Previous | Blame | View Log
//------------------------------------------------------------------------------// Copyright 2007-2011 Mentor Graphics Corporation// Copyright 2007-2010 Cadence Design Systems, Inc.// Copyright 2010 Synopsys, Inc.// All Rights Reserved Worldwide//// Licensed under the Apache License, Version 2.0 (the// "License"); you may not use this file except in// compliance with the License. You may obtain a copy of// the License at//// http://www.apache.org/licenses/LICENSE-2.0//// Unless required by applicable law or agreed to in// writing, software distributed under the License is// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR// CONDITIONS OF ANY KIND, either express or implied. See// the License for the specific language governing// permissions and limitations under the License.//------------------------------------------------------------------------------// Title: Sequence-Related Macros//-----------------------------------------------------------------------------//// Group: Sequence Action Macros//// These macros are used to start sequences and sequence items on the default// sequencer, ~m_sequencer~. This is determined a number of ways.// - the sequencer handle provided in the <uvm_sequence_base::start> method// - the sequencer used by the parent sequence// - the sequencer that was set using the <uvm_sequence_item::set_sequencer> method//-----------------------------------------------------------------------------// MACRO: `uvm_create////| `uvm_create(SEQ_OR_ITEM)//// This action creates the item or sequence using the factory. It intentionally// does zero processing. After this action completes, the user can manually set// values, manipulate rand_mode and constraint_mode, etc.`define uvm_create(SEQ_OR_ITEM) \`uvm_create_on(SEQ_OR_ITEM, m_sequencer)// MACRO: `uvm_do////| `uvm_do(SEQ_OR_ITEM)//// This macro takes as an argument a uvm_sequence_item variable or object.// The argument is created using <`uvm_create> if necessary,// then randomized.// In the case of an item, it is randomized after the call to// <uvm_sequence_base::start_item()> returns.// This is called late-randomization.// In the case of a sequence, the sub-sequence is started using// <uvm_sequence_base::start()> with ~call_pre_post~ set to 0.// In the case of an item,// the item is sent to the driver through the associated sequencer.//// For a sequence item, the following are called, in order////|//| `uvm_create(item)//| sequencer.wait_for_grant(prior) (task)//| this.pre_do(1) (task)//| item.randomize()//| this.mid_do(item) (func)//| sequencer.send_request(item) (func)//| sequencer.wait_for_item_done() (task)//| this.post_do(item) (func)//|//// For a sequence, the following are called, in order////|//| `uvm_create(sub_seq)//| sub_seq.randomize()//| sub_seq.pre_start() (task)//| this.pre_do(0) (task)//| this.mid_do(sub_seq) (func)//| sub_seq.body() (task)//| this.post_do(sub_seq) (func)//| sub_seq.post_start() (task)//|`define uvm_do(SEQ_OR_ITEM) \`uvm_do_on_pri_with(SEQ_OR_ITEM, m_sequencer, -1, {})// MACRO: `uvm_do_pri////| `uvm_do_pri(SEQ_OR_ITEM, PRIORITY)//// This is the same as `uvm_do except that the sequence item or sequence is// executed with the priority specified in the argument`define uvm_do_pri(SEQ_OR_ITEM, PRIORITY) \`uvm_do_on_pri_with(SEQ_OR_ITEM, m_sequencer, PRIORITY, {})// MACRO: `uvm_do_with////| `uvm_do_with(SEQ_OR_ITEM, CONSTRAINTS)//// This is the same as `uvm_do except that the constraint block in the 2nd// argument is applied to the item or sequence in a randomize with statement// before execution.`define uvm_do_with(SEQ_OR_ITEM, CONSTRAINTS) \`uvm_do_on_pri_with(SEQ_OR_ITEM, m_sequencer, -1, CONSTRAINTS)// MACRO: `uvm_do_pri_with////| `uvm_do_pri_with(SEQ_OR_ITEM, PRIORITY, CONSTRAINTS)//// This is the same as `uvm_do_pri except that the given constraint block is// applied to the item or sequence in a randomize with statement before// execution.`define uvm_do_pri_with(SEQ_OR_ITEM, PRIORITY, CONSTRAINTS) \`uvm_do_on_pri_with(SEQ_OR_ITEM, m_sequencer, PRIORITY, CONSTRAINTS)//-----------------------------------------------------------------------------//// Group: Sequence on Sequencer Action Macros//// These macros are used to start sequences and sequence items on a specific// sequencer. The sequence or item is created and executed on the given// sequencer.//-----------------------------------------------------------------------------// MACRO: `uvm_create_on////| `uvm_create_on(SEQ_OR_ITEM, SEQR)//// This is the same as <`uvm_create> except that it also sets the parent sequence// to the sequence in which the macro is invoked, and it sets the sequencer to// the specified ~SEQR~ argument.`define uvm_create_on(SEQ_OR_ITEM, SEQR) \begin \uvm_object_wrapper w_; \w_ = SEQ_OR_ITEM.get_type(); \$cast(SEQ_OR_ITEM , create_item(w_, SEQR, `"SEQ_OR_ITEM`"));\end// MACRO: `uvm_do_on////| `uvm_do_on(SEQ_OR_ITEM, SEQR)//// This is the same as <`uvm_do> except that it also sets the parent sequence to// the sequence in which the macro is invoked, and it sets the sequencer to the// specified ~SEQR~ argument.`define uvm_do_on(SEQ_OR_ITEM, SEQR) \`uvm_do_on_pri_with(SEQ_OR_ITEM, SEQR, -1, {})// MACRO: `uvm_do_on_pri////| `uvm_do_on_pri(SEQ_OR_ITEM, SEQR, PRIORITY)//// This is the same as <`uvm_do_pri> except that it also sets the parent sequence// to the sequence in which the macro is invoked, and it sets the sequencer to// the specified ~SEQR~ argument.`define uvm_do_on_pri(SEQ_OR_ITEM, SEQR, PRIORITY) \`uvm_do_on_pri_with(SEQ_OR_ITEM, SEQR, PRIORITY, {})// MACRO: `uvm_do_on_with////| `uvm_do_on_with(SEQ_OR_ITEM, SEQR, CONSTRAINTS)//// This is the same as <`uvm_do_with> except that it also sets the parent// sequence to the sequence in which the macro is invoked, and it sets the// sequencer to the specified ~SEQR~ argument.// The user must supply brackets around the constraints.`define uvm_do_on_with(SEQ_OR_ITEM, SEQR, CONSTRAINTS) \`uvm_do_on_pri_with(SEQ_OR_ITEM, SEQR, -1, CONSTRAINTS)// MACRO: `uvm_do_on_pri_with////| `uvm_do_on_pri_with(SEQ_OR_ITEM, SEQR, PRIORITY, CONSTRAINTS)//// This is the same as `uvm_do_pri_with except that it also sets the parent// sequence to the sequence in which the macro is invoked, and it sets the// sequencer to the specified ~SEQR~ argument.`define uvm_do_on_pri_with(SEQ_OR_ITEM, SEQR, PRIORITY, CONSTRAINTS) \begin \uvm_sequence_base __seq; \`uvm_create_on(SEQ_OR_ITEM, SEQR) \if (!$cast(__seq,SEQ_OR_ITEM)) start_item(SEQ_OR_ITEM, PRIORITY);\if ((__seq == null || !__seq.do_not_randomize) && !SEQ_OR_ITEM.randomize() with CONSTRAINTS ) begin \`uvm_warning("RNDFLD", "Randomization failed in uvm_do_with action") \end\if (!$cast(__seq,SEQ_OR_ITEM)) finish_item(SEQ_OR_ITEM, PRIORITY); \else __seq.start(SEQR, this, PRIORITY, 0); \end//-----------------------------------------------------------------------------//// Group: Sequence Action Macros for Pre-Existing Sequences//// These macros are used to start sequences and sequence items that do not// need to be created.//-----------------------------------------------------------------------------// MACRO: `uvm_send////| `uvm_send(SEQ_OR_ITEM)//// This macro processes the item or sequence that has been created using// `uvm_create. The processing is done without randomization. Essentially, an// `uvm_do without the create or randomization.`define uvm_send(SEQ_OR_ITEM) \`uvm_send_pri(SEQ_OR_ITEM, -1)// MACRO: `uvm_send_pri////| `uvm_send_pri(SEQ_OR_ITEM, PRIORITY)//// This is the same as `uvm_send except that the sequence item or sequence is// executed with the priority specified in the argument.`define uvm_send_pri(SEQ_OR_ITEM, PRIORITY) \begin \uvm_sequence_base __seq; \if (!$cast(__seq,SEQ_OR_ITEM)) begin \start_item(SEQ_OR_ITEM, PRIORITY);\finish_item(SEQ_OR_ITEM, PRIORITY);\end \else __seq.start(__seq.get_sequencer(), this, PRIORITY, 0);\end// MACRO: `uvm_rand_send////| `uvm_rand_send(SEQ_OR_ITEM)//// This macro processes the item or sequence that has been already been// allocated (possibly with `uvm_create). The processing is done with// randomization. Essentially, an `uvm_do without the create.`define uvm_rand_send(SEQ_OR_ITEM) \`uvm_rand_send_pri_with(SEQ_OR_ITEM, -1, {})// MACRO: `uvm_rand_send_pri////| `uvm_rand_send_pri(SEQ_OR_ITEM, PRIORITY)//// This is the same as `uvm_rand_send except that the sequence item or sequence// is executed with the priority specified in the argument.`define uvm_rand_send_pri(SEQ_OR_ITEM, PRIORITY) \`uvm_rand_send_pri_with(SEQ_OR_ITEM, PRIORITY, {})// MACRO: `uvm_rand_send_with////| `uvm_rand_send_with(SEQ_OR_ITEM, CONSTRAINTS)//// This is the same as `uvm_rand_send except that the given constraint block is// applied to the item or sequence in a randomize with statement before// execution.`define uvm_rand_send_with(SEQ_OR_ITEM, CONSTRAINTS) \`uvm_rand_send_pri_with(SEQ_OR_ITEM, -1, CONSTRAINTS)// MACRO: `uvm_rand_send_pri_with////| `uvm_rand_send_pri_with(SEQ_OR_ITEM, PRIORITY, CONSTRAINTS)//// This is the same as `uvm_rand_send_pri except that the given constraint block// is applied to the item or sequence in a randomize with statement before// execution.`define uvm_rand_send_pri_with(SEQ_OR_ITEM, PRIORITY, CONSTRAINTS) \begin \uvm_sequence_base __seq; \if (!$cast(__seq,SEQ_OR_ITEM)) start_item(SEQ_OR_ITEM, PRIORITY);\else __seq.set_item_context(this,SEQ_OR_ITEM.get_sequencer()); \if ((__seq == null || !__seq.do_not_randomize) && !SEQ_OR_ITEM.randomize() with CONSTRAINTS ) begin \`uvm_warning("RNDFLD", "Randomization failed in uvm_rand_send_with action") \end\if (!$cast(__seq,SEQ_OR_ITEM)) finish_item(SEQ_OR_ITEM, PRIORITY);\else __seq.start(__seq.get_sequencer(), this, PRIORITY, 0);\end`define uvm_create_seq(UVM_SEQ, SEQR_CONS_IF) \`uvm_create_on(UVM_SEQ, SEQR_CONS_IF.consumer_seqr) \`define uvm_do_seq(UVM_SEQ, SEQR_CONS_IF) \`uvm_do_on(UVM_SEQ, SEQR_CONS_IF.consumer_seqr) \`define uvm_do_seq_with(UVM_SEQ, SEQR_CONS_IF, CONSTRAINTS) \`uvm_do_on_with(UVM_SEQ, SEQR_CONS_IF.consumer_seqr, CONSTRAINTS) \//-----------------------------------------------------------------------------//// Group- Sequence Library////-----------------------------------------------------------------------------// MACRO: `uvm_add_to_sequence_library//// Adds the given sequence ~TYPE~ to the given sequence library ~LIBTYPE~////| `uvm_add_to_seq_lib(TYPE,LIBTYPE)//// Invoke any number of times within a sequence declaration to statically add// that sequence to one or more sequence library types. The sequence will then// be available for selection and execution in all instances of the given// sequencer types.////| class seqA extends uvm_sequence_base #(simple_item);//|//| function new(string name=`"TYPE`");//| super.new(name);//| endfunction//|//| `uvm_object_utils(seqA)//|//| `uvm_add_to_seq_lib(seqA, simple_seq_lib_RST)//| `uvm_add_to_seq_lib(seqA, simple_seq_lib_CFG)//|//| virtual task body(); \//| `uvm_info("SEQ_START", {"Executing sequence '", get_full_name(),//| "' (",get_type_name(),")"},UVM_HIGH)//| #10;//| endtask//|//| endclass`define uvm_add_to_seq_lib(TYPE,LIBTYPE) \static bit add_``TYPE``_to_seq_lib_``LIBTYPE =\LIBTYPE::m_add_typewide_sequence(TYPE::get_type());// MACRO: `uvm_sequence_library_utils////| `uvm_sequence_library_utils(TYPE)//// Declares the infrastructure needed to define extensions to the// <uvm_sequence_library> class. You define new sequence library subtypes// to statically specify sequence membership from within sequence// definitions. See also <`uvm_add_to_sequence_library> for more information.//////| typedef simple_seq_lib uvm_sequence_library #(simple_item);//|//| class simple_seq_lib_RST extends simple_seq_lib;//|//| `uvm_object_utils(simple_seq_lib_RST)//|//| `uvm_sequence_library_utils(simple_seq_lib_RST)//|//| function new(string name="");//| super.new(name);//| endfunction//|//| endclass//// Each library, itself a sequence, can then be started independently// on different sequencers or in different phases of the same sequencer.// See <uvm_sequencer_base::start_phase_sequence> for information on// starting default sequences.`define uvm_sequence_library_utils(TYPE) \\static protected uvm_object_wrapper m_typewide_sequences[$]; \\function void init_sequence_library(); \foreach (TYPE::m_typewide_sequences[i]) \sequences.push_back(TYPE::m_typewide_sequences[i]); \endfunction \\static function void add_typewide_sequence(uvm_object_wrapper seq_type); \if (m_static_check(seq_type)) \TYPE::m_typewide_sequences.push_back(seq_type); \endfunction \\static function void add_typewide_sequences(uvm_object_wrapper seq_types[$]); \foreach (seq_types[i]) \TYPE::add_typewide_sequence(seq_types[i]); \endfunction \\static function bit m_add_typewide_sequence(uvm_object_wrapper seq_type); \TYPE::add_typewide_sequence(seq_type); \return 1; \endfunction//-----------------------------------------------------------------------------//// Group: Sequencer Subtypes////-----------------------------------------------------------------------------// MACRO: `uvm_declare_p_sequencer//// This macro is used to declare a variable ~p_sequencer~ whose type is// specified by ~SEQUENCER~.////| `uvm_declare_p_sequencer(SEQUENCER)//// The example below shows using the `uvm_declare_p_sequencer macro// along with the uvm_object_utils macros to set up the sequence but// not register the sequence in the sequencer's library.////| class mysequence extends uvm_sequence#(mydata);//| `uvm_object_utils(mysequence)//| `uvm_declare_p_sequencer(some_seqr_type)//| task body;//| //Access some variable in the user's custom sequencer//| if(p_sequencer.some_variable) begin//| ...//| end//| endtask//| endclass//`define uvm_declare_p_sequencer(SEQUENCER) \SEQUENCER p_sequencer;\virtual function void m_set_p_sequencer();\super.m_set_p_sequencer(); \if( !$cast(p_sequencer, m_sequencer)) \`uvm_fatal("DCLPSQ", \$sformatf("%m %s Error casting p_sequencer, please verify that this sequence/sequence item is intended to execute on this type of sequencer", get_full_name())) \endfunction
