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