OpenCores
URL https://opencores.org/ocsvn/uart2bus_testbench/uart2bus_testbench/trunk

Subversion Repositories uart2bus_testbench

[/] [uart2bus_testbench/] [trunk/] [tb/] [uvm_src/] [seq/] [uvm_sequence_base.svh] - Blame information for rev 16

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 16 HanySalah
//----------------------------------------------------------------------
2
//   Copyright 2007-2011 Mentor Graphics Corporation
3
//   Copyright 2007-2011 Cadence Design Systems, Inc.
4
//   Copyright 2010-2011 Synopsys, Inc.
5
//   All Rights Reserved Worldwide
6
//
7
//   Licensed under the Apache License, Version 2.0 (the
8
//   "License"); you may not use this file except in
9
//   compliance with the License.  You may obtain a copy of
10
//   the License at
11
//
12
//       http://www.apache.org/licenses/LICENSE-2.0
13
//
14
//   Unless required by applicable law or agreed to in
15
//   writing, software distributed under the License is
16
//   distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
17
//   CONDITIONS OF ANY KIND, either express or implied.  See
18
//   the License for the specific language governing
19
//   permissions and limitations under the License.
20
//----------------------------------------------------------------------
21
 
22
 
23
//------------------------------------------------------------------------------
24
//
25
// CLASS: uvm_sequence_base
26
//
27
// The uvm_sequence_base class provides the interfaces needed to create streams
28
// of sequence items and/or other sequences.
29
//
30
// A sequence is executed by calling its  method, either directly
31
// or invocation of any of the `uvm_do_* macros.
32
//
33
// Executing sequences via :
34
//
35
// A sequence's  method has a ~parent_sequence~ argument that controls
36
// whether , , and  are called *in the parent*
37
// sequence. It also has a ~call_pre_post~ argument that controls whether its
38
//  and  methods are called.
39
// In all cases, its  and  methods are always called.
40
//
41
// When  is called directly, you can provide the appropriate arguments
42
// according to your application.
43
//
44
// The sequence execution flow looks like this
45
//
46
// User code
47
//
48
//| sub_seq.randomize(...); // optional
49
//| sub_seq.start(seqr, parent_seq, priority, call_pre_post)
50
//|
51
//
52
// The following methods are called, in order
53
//
54
//|
55
//|   sub_seq.pre_start()        (task)
56
//|   sub_seq.pre_body()         (task)  if call_pre_post==1
57
//|     parent_seq.pre_do(0)     (task)  if parent_sequence!=null
58
//|     parent_seq.mid_do(this)  (func)  if parent_sequence!=null
59
//|   sub_seq.body               (task)  YOUR STIMULUS CODE
60
//|     parent_seq.post_do(this) (func)  if parent_sequence!=null
61
//|   sub_seq.post_body()        (task)  if call_pre_post==1
62
//|   sub_seq.post_start()       (task)
63
//
64
//
65
// Executing sub-sequences via `uvm_do macros:
66
//
67
// A sequence can also be indirectly started as a child in the  of a
68
// parent sequence. The child sequence's  method is called indirectly
69
// by invoking any of the `uvm_do macros.
70
// In these cases,  is called with
71
// ~call_pre_post~ set to 0, preventing the started sequence's  and
72
//  methods from being called. During execution of the
73
// child sequence, the parent's , , and  methods
74
// are called.
75
//
76
// The sub-sequence execution flow looks like
77
//
78
// User code
79
//
80
//|
81
//| `uvm_do_with_prior(seq_seq, { constraints }, priority)
82
//|
83
//
84
// The following methods are called, in order
85
//
86
//|
87
//|   sub_seq.pre_start()         (task)
88
//|   parent_seq.pre_do(0)        (task)
89
//|   parent_req.mid_do(sub_seq)  (func)
90
//|     sub_seq.body()            (task)
91
//|   parent_seq.post_do(sub_seq) (func)
92
//|   sub_seq.post_start()        (task)
93
//|
94
//
95
// Remember, it is the *parent* sequence's pre|mid|post_do that are called, not
96
// the sequence being executed.
97
//
98
//
99
// Executing sequence items via / or `uvm_do macros:
100
//
101
// Items are started in the  of a parent sequence via calls to
102
// / or invocations of any of the `uvm_do
103
// macros. The , , and  methods of the parent
104
// sequence will be called as the item is executed.
105
//
106
// The sequence-item execution flow looks like
107
//
108
// User code
109
//
110
//| parent_seq.start_item(item, priority);
111
//| item.randomize(...) [with {constraints}];
112
//| parent_seq.finish_item(item);
113
//|
114
//| or
115
//|
116
//| `uvm_do_with_prior(item, constraints, priority)
117
//|
118
//
119
// The following methods are called, in order
120
//
121
//|
122
//|   sequencer.wait_for_grant(prior) (task) \ start_item  \
123
//|   parent_seq.pre_do(1)            (task) /              \
124
//|                                                      `uvm_do* macros
125
//|   parent_seq.mid_do(item)         (func) \              /
126
//|   sequencer.send_request(item)    (func)  \finish_item /
127
//|   sequencer.wait_for_item_done()  (task)  /
128
//|   parent_seq.post_do(item)        (func) /
129
//
130
// Attempting to execute a sequence via /
131
// will produce a run-time error.
132
//------------------------------------------------------------------------------
133
 
134
class uvm_sequence_base extends uvm_sequence_item;
135
 
136
  protected uvm_sequence_state m_sequence_state;
137
            int                m_next_transaction_id = 1;
138
  local     int                m_priority = -1;
139
            uvm_recorder       m_tr_recorder;
140
            int                m_wait_for_grant_semaphore;
141
 
142
  // Each sequencer will assign a sequence id.  When a sequence is talking to multiple
143
  // sequencers, each sequence_id is managed separately
144
  protected int m_sqr_seq_ids[int];
145
 
146
  protected bit children_array[uvm_sequence_base];
147
 
148
  protected uvm_sequence_item response_queue[$];
149
  protected int               response_queue_depth = 8;
150
  protected bit               response_queue_error_report_disabled;
151
 
152
  // Variable: do_not_randomize
153
  //
154
  // If set, prevents the sequence from being randomized before being executed
155
  // by the `uvm_do*() and `uvm_rand_send*() macros,
156
  // or as a default sequence.
157
  //
158
  bit do_not_randomize;
159
 
160
  protected process  m_sequence_process;
161
  local bit m_use_response_handler;
162
 
163
  static string type_name = "uvm_sequence_base";
164
 
165
  // bits to detect if is_relevant()/wait_for_relevant() are implemented
166
  local bit is_rel_default;
167
  local bit wait_rel_default;
168
 
169
 
170
  // Function: new
171
  //
172
  // The constructor for uvm_sequence_base.
173
  //
174
  function new (string name = "uvm_sequence");
175
 
176
    super.new(name);
177
    m_sequence_state = UVM_CREATED;
178
    m_wait_for_grant_semaphore = 0;
179
    m_init_phase_daps(1);
180
  endfunction
181
 
182
 
183
  // Function: is_item
184
  //
185
  // Returns 1 on items and 0 on sequences. As this object is a sequence,
186
  // ~is_item~ will always return 0.
187
  //
188
  virtual function bit is_item();
189
    return 0;
190
  endfunction
191
 
192
 
193
  // Function: get_sequence_state
194
  //
195
  // Returns the sequence state as an enumerated value. Can use to wait on
196
  // the sequence reaching or changing from one or more states.
197
  //
198
  //| wait(get_sequence_state() & (UVM_STOPPED|UVM_FINISHED));
199
 
200
  function uvm_sequence_state_enum get_sequence_state();
201
    return m_sequence_state;
202
  endfunction
203
 
204
 
205
  // Task: wait_for_sequence_state
206
  //
207
  // Waits until the sequence reaches one of the given ~state~. If the sequence
208
  // is already in one of the state, this method returns immediately.
209
  //
210
  //| wait_for_sequence_state(UVM_STOPPED|UVM_FINISHED);
211
 
212
  task wait_for_sequence_state(int unsigned state_mask);
213
    wait (m_sequence_state & state_mask);
214
  endtask
215
 
216
 
217
  // Function: get_tr_handle
218
  //
219
  // Returns the integral recording transaction handle for this sequence.
220
  // Can be used to associate sub-sequences and sequence items as
221
  // child transactions when calling .
222
 
223
  function integer get_tr_handle();
224
     if (m_tr_recorder != null)
225
       return m_tr_recorder.get_handle();
226
     else
227
       return 0;
228
  endfunction
229
 
230
 
231
  //--------------------------
232
  // Group: Sequence Execution
233
  //--------------------------
234
 
235
 
236
  // Task: start
237
  //
238
  // Executes this sequence, returning when the sequence has completed.
239
  //
240
  // The ~sequencer~ argument specifies the sequencer on which to run this
241
  // sequence. The sequencer must be compatible with the sequence.
242
  //
243
  // If ~parent_sequence~ is ~null~, then this sequence is a root parent,
244
  // otherwise it is a child of ~parent_sequence~. The ~parent_sequence~'s
245
  // pre_do, mid_do, and post_do methods will be called during the execution
246
  // of this sequence.
247
  //
248
  // By default, the ~priority~ of a sequence
249
  // is the priority of its parent sequence.
250
  // If it is a root sequence, its default priority is 100.
251
  // A different priority may be specified by ~this_priority~.
252
  // Higher numbers indicate higher priority.
253
  //
254
  // If ~call_pre_post~ is set to 1 (default), then the  and
255
  //  tasks will be called before and after the sequence
256
  //  is called.
257
 
258
  virtual task start (uvm_sequencer_base sequencer,
259
                      uvm_sequence_base parent_sequence = null,
260
                      int this_priority = -1,
261
                      bit call_pre_post = 1);
262
    bit                  old_automatic_phase_objection;
263
 
264
    set_item_context(parent_sequence, sequencer);
265
 
266
    if (!(m_sequence_state inside {UVM_CREATED,UVM_STOPPED,UVM_FINISHED})) begin
267
      uvm_report_fatal("SEQ_NOT_DONE",
268
         {"Sequence ", get_full_name(), " already started"},UVM_NONE);
269
    end
270
 
271
    if (m_parent_sequence != null) begin
272
       m_parent_sequence.children_array[this] = 1;
273
    end
274
 
275
    if (this_priority < -1) begin
276
      uvm_report_fatal("SEQPRI", $sformatf("Sequence %s start has illegal priority: %0d",
277
                                           get_full_name(),
278
                                           this_priority), UVM_NONE);
279
    end
280
    if (this_priority < 0) begin
281
       if (parent_sequence == null) this_priority = 100;
282
       else this_priority = parent_sequence.get_priority();
283
    end
284
 
285
    // Check that the response queue is empty from earlier runs
286
    clear_response_queue();
287
 
288
    m_priority           = this_priority;
289
 
290
    if (m_sequencer != null) begin
291
       integer handle;
292
       uvm_tr_stream stream;
293
       if (m_parent_sequence == null) begin
294
          stream = m_sequencer.get_tr_stream(get_name(), "Transactions");
295
          handle = m_sequencer.begin_tr(this, get_name());
296
          m_tr_recorder = uvm_recorder::get_recorder_from_handle(handle);
297
       end else begin
298
          stream = m_sequencer.get_tr_stream(get_root_sequence_name(), "Transactions");
299
          handle = m_sequencer.begin_child_tr(this,
300
                                              (m_parent_sequence.m_tr_recorder == null) ? 0 : m_parent_sequence.m_tr_recorder.get_handle(),
301
                                              get_root_sequence_name());
302
          m_tr_recorder = uvm_recorder::get_recorder_from_handle(handle);
303
       end
304
    end
305
 
306
    // Ensure that the sequence_id is intialized in case this sequence has been stopped previously
307
    set_sequence_id(-1);
308
    // Remove all sqr_seq_ids
309
    m_sqr_seq_ids.delete();
310
 
311
    // Register the sequence with the sequencer if defined.
312
    if (m_sequencer != null) begin
313
      void'(m_sequencer.m_register_sequence(this));
314
    end
315
 
316
    // Change the state to PRE_START, do this before the fork so that
317
    // the "if (!(m_sequence_state inside {...}" works
318
    m_sequence_state = UVM_PRE_START;
319
    fork
320
      begin
321
        m_sequence_process = process::self();
322
 
323
        // absorb delta to ensure PRE_START was seen
324
        #0;
325
 
326
        // Raise the objection if enabled
327
        // (This will lock the uvm_get_to_lock_dap)
328
        if (get_automatic_phase_objection()) begin
329
           m_safe_raise_starting_phase("automatic phase objection");
330
        end
331
 
332
        pre_start();
333
 
334
        if (call_pre_post == 1) begin
335
          m_sequence_state = UVM_PRE_BODY;
336
          #0;
337
          pre_body();
338
        end
339
 
340
        if (parent_sequence != null) begin
341
          parent_sequence.pre_do(0);    // task
342
          parent_sequence.mid_do(this); // function
343
        end
344
 
345
        m_sequence_state = UVM_BODY;
346
        #0;
347
        body();
348
 
349
        m_sequence_state = UVM_ENDED;
350
        #0;
351
 
352
        if (parent_sequence != null) begin
353
          parent_sequence.post_do(this);
354
        end
355
 
356
        if (call_pre_post == 1) begin
357
          m_sequence_state = UVM_POST_BODY;
358
          #0;
359
          post_body();
360
        end
361
 
362
        m_sequence_state = UVM_POST_START;
363
        #0;
364
        post_start();
365
 
366
        // Drop the objection if enabled
367
        if (get_automatic_phase_objection()) begin
368
           m_safe_drop_starting_phase("automatic phase objection");
369
        end
370
 
371
        m_sequence_state = UVM_FINISHED;
372
        #0;
373
 
374
      end
375
    join
376
 
377
    if (m_sequencer != null) begin
378
      m_sequencer.end_tr(this);
379
    end
380
 
381
    // Clean up any sequencer queues after exiting; if we
382
    // were forcibly stoped, this step has already taken place
383
    if (m_sequence_state != UVM_STOPPED) begin
384
      if (m_sequencer != null)
385
        m_sequencer.m_sequence_exiting(this);
386
    end
387
 
388
    #0; // allow stopped and finish waiters to resume
389
 
390
    if ((m_parent_sequence != null) && (m_parent_sequence.children_array.exists(this))) begin
391
       m_parent_sequence.children_array.delete(this);
392
    end
393
 
394
    old_automatic_phase_objection = get_automatic_phase_objection();
395
    m_init_phase_daps(1);
396
    set_automatic_phase_objection(old_automatic_phase_objection);
397
  endtask
398
 
399
 
400
  // Task: pre_start
401
  //
402
  // This task is a user-definable callback that is called before the
403
  // optional execution of .
404
  // This method should not be called directly by the user.
405
 
406
  virtual task pre_start();
407
    return;
408
  endtask
409
 
410
 
411
  // Task: pre_body
412
  //
413
  // This task is a user-definable callback that is called before the
414
  // execution of  ~only~ when the sequence is started with .
415
  // If  is called with ~call_pre_post~ set to 0, ~pre_body~ is not
416
  // called.
417
  // This method should not be called directly by the user.
418
 
419
  virtual task pre_body();
420
    return;
421
  endtask
422
 
423
 
424
  // Task: pre_do
425
  //
426
  // This task is a user-definable callback task that is called ~on the
427
  // parent sequence~, if any
428
  // sequence has issued a wait_for_grant() call and after the sequencer has
429
  // selected this sequence, and before the item is randomized.
430
  //
431
  // Although pre_do is a task, consuming simulation cycles may result in
432
  // unexpected behavior on the driver.
433
  //
434
  // This method should not be called directly by the user.
435
 
436
  virtual task pre_do(bit is_item);
437
    return;
438
  endtask
439
 
440
 
441
  // Function: mid_do
442
  //
443
  // This function is a user-definable callback function that is called after
444
  // the sequence item has been randomized, and just before the item is sent
445
  // to the driver.  This method should not be called directly by the user.
446
 
447
  virtual function void mid_do(uvm_sequence_item this_item);
448
    return;
449
  endfunction
450
 
451
 
452
  // Task: body
453
  //
454
  // This is the user-defined task where the main sequence code resides.
455
  // This method should not be called directly by the user.
456
 
457
  virtual task body();
458
    uvm_report_warning("uvm_sequence_base", "Body definition undefined");
459
    return;
460
  endtask
461
 
462
 
463
  // Function: post_do
464
  //
465
  // This function is a user-definable callback function that is called after
466
  // the driver has indicated that it has completed the item, using either
467
  // this item_done or put methods. This method should not be called directly
468
  // by the user.
469
 
470
  virtual function void post_do(uvm_sequence_item this_item);
471
    return;
472
  endfunction
473
 
474
 
475
  // Task: post_body
476
  //
477
  // This task is a user-definable callback task that is called after the
478
  // execution of  ~only~ when the sequence is started with .
479
  // If  is called with ~call_pre_post~ set to 0, ~post_body~ is not
480
  // called.
481
  // This task is a user-definable callback task that is called after the
482
  // execution of the body, unless the sequence is started with call_pre_post=0.
483
  // This method should not be called directly by the user.
484
 
485
  virtual task post_body();
486
    return;
487
  endtask
488
 
489
 
490
  // Task: post_start
491
  //
492
  // This task is a user-definable callback that is called after the
493
  // optional execution of .
494
  // This method should not be called directly by the user.
495
 
496
  virtual task post_start();
497
    return;
498
  endtask
499
 
500
 
501
  // Group: Run-Time Phasing
502
  //
503
 
504
  // Automatic Phase Objection DAP
505
  local uvm_get_to_lock_dap#(bit) m_automatic_phase_objection_dap;
506
  // Starting Phase DAP
507
  local uvm_get_to_lock_dap#(uvm_phase) m_starting_phase_dap;
508
 
509
  // Function- m_init_phase_daps
510
  // Either creates or renames DAPS
511
  function void m_init_phase_daps(bit create);
512
     string apo_name = $sformatf("%s.automatic_phase_objection", get_full_name());
513
     string sp_name = $sformatf("%s.starting_phase", get_full_name());
514
 
515
     if (create) begin
516
        m_automatic_phase_objection_dap = uvm_get_to_lock_dap#(bit)::type_id::create(apo_name, get_sequencer());
517
        m_starting_phase_dap = uvm_get_to_lock_dap#(uvm_phase)::type_id::create(sp_name, get_sequencer());
518
     end
519
     else begin
520
        m_automatic_phase_objection_dap.set_name(apo_name);
521
        m_starting_phase_dap.set_name(sp_name);
522
     end
523
  endfunction : m_init_phase_daps
524
 
525
`ifndef UVM_NO_DEPRECATED
526
 `define UVM_DEPRECATED_STARTING_PHASE
527
`endif
528
 
529
`ifdef UVM_DEPRECATED_STARTING_PHASE
530
  // DEPRECATED!! Use get/set_starting_phase accessors instead!
531
  uvm_phase starting_phase;
532
  // Value set via set_starting_phase
533
  uvm_phase m_set_starting_phase;
534
  // Ensures we only warn once per sequence
535
  bit m_warn_deprecated_set;
536
`endif
537
 
538
  // Function: get_starting_phase
539
  // Returns the 'starting phase'.
540
  //
541
  // If non-~null~, the starting phase specifies the phase in which this
542
  // sequence was started.  The starting phase is set automatically when
543
  // this sequence is started as the default sequence on a sequencer.
544
  // See  for more information.
545
  //
546
  // Internally, the  uses an  to
547
  // protect the starting phase value from being modified
548
  // after the reference has been read.  Once the sequence has ended
549
  // its execution (either via natural termination, or being killed),
550
  // then the starting phase value can be modified again.
551
  //
552
  function uvm_phase get_starting_phase();
553
`ifdef UVM_DEPRECATED_STARTING_PHASE
554
     begin
555
        bit throw_error;
556
 
557
        if (starting_phase != m_set_starting_phase) begin
558
           if (!m_warn_deprecated_set) begin
559
              `uvm_warning("UVM_DEPRECATED", "'starting_phase' is deprecated and not part of the UVM standard.  See documentation for uvm_sequence_base::set_starting_phase")
560
              m_warn_deprecated_set = 1;
561
           end
562
 
563
           if (m_starting_phase_dap.try_set(starting_phase))
564
             m_set_starting_phase = starting_phase;
565
           else begin
566
              uvm_phase dap_phase = m_starting_phase_dap.get();
567
              `uvm_error("UVM/SEQ/LOCK_DEPR",
568
                         {"The deprecated 'starting_phase' variable has been set to '",
569
                          (starting_phase == null) ? "" : starting_phase.get_full_name(),
570
                          "' after a call to get_starting_phase locked the value to '",
571
                          (dap_phase == null) ? "" : dap_phase.get_full_name(),
572
                          "'.  See documentation for uvm_sequence_base::set_starting_phase."})
573
           end
574
        end
575
 
576
     end
577
`endif
578
     return m_starting_phase_dap.get();
579
  endfunction : get_starting_phase
580
 
581
  // Function: set_starting_phase
582
  // Sets the 'starting phase'.
583
  //
584
  // Internally, the  uses a  to
585
  // protect the starting phase value from being modified
586
  // after the reference has been read.  Once the sequence has ended
587
  // its execution (either via natural termination, or being killed),
588
  // then the starting phase value can be modified again.
589
  //
590
  function void set_starting_phase(uvm_phase phase);
591
`ifdef UVM_DEPRECATED_STARTING_PHASE
592
     begin
593
        if (starting_phase != m_set_starting_phase) begin
594
           if (!m_warn_deprecated_set) begin
595
              `uvm_warning("UVM_DEPRECATED",
596
                           {"The deprecated 'starting_phase' variable has been set to '",
597
                            starting_phase.get_full_name(),
598
                            "' manually.  See documentation for uvm_sequence_base::set_starting_phase."})
599
              m_warn_deprecated_set = 1;
600
           end
601
 
602
           starting_phase = phase;
603
           m_set_starting_phase = phase;
604
        end
605
     end
606
`endif
607
 
608
     m_starting_phase_dap.set(phase);
609
  endfunction : set_starting_phase
610
 
611
  // Function: set_automatic_phase_objection
612
  // Sets the 'automatically object to starting phase' bit.
613
  //
614
  // The most common interaction with the starting phase
615
  // within a sequence is to simply ~raise~ the phase's objection
616
  // prior to executing the sequence, and ~drop~ the objection
617
  // after ending the sequence (either naturally, or
618
  // via a call to ). In order to
619
  // simplify this interaction for the user, the UVM
620
  // provides the ability to perform this functionality
621
  // automatically.
622
  //
623
  // For example:
624
  //| function my_sequence::new(string name="unnamed");
625
  //|   super.new(name);
626
  //|   set_automatic_phase_objection(1);
627
  //| endfunction : new
628
  //
629
  // From a timeline point of view, the automatic phase objection
630
  // looks like:
631
  //| start() is executed
632
  //|   --! Objection is raised !--
633
  //|   pre_start() is executed
634
  //|   pre_body() is optionally executed
635
  //|   body() is executed
636
  //|   post_body() is optionally executed
637
  //|   post_start() is executed
638
  //|   --! Objection is dropped !--
639
  //| start() unblocks
640
  //
641
  // This functionality can also be enabled in sequences
642
  // which were not written with UVM Run-Time Phasing in mind:
643
  //| my_legacy_seq_type seq = new("seq");
644
  //| seq.set_automatic_phase_objection(1);
645
  //| seq.start(my_sequencer);
646
  //
647
  // Internally, the  uses a  to
648
  // protect the ~automatic_phase_objection~ value from being modified
649
  // after the reference has been read.  Once the sequence has ended
650
  // its execution (either via natural termination, or being killed),
651
  // then the ~automatic_phase_objection~ value can be modified again.
652
  //
653
  // NEVER set the automatic phase objection bit to 1 if your sequence
654
  // runs with a forever loop inside of the body, as the objection will
655
  // never get dropped!
656
  function void set_automatic_phase_objection(bit value);
657
     m_automatic_phase_objection_dap.set(value);
658
  endfunction : set_automatic_phase_objection
659
 
660
  // Function: get_automatic_phase_objection
661
  // Returns (and locks) the value of the 'automatically object to
662
  // starting phase' bit.
663
  //
664
  // If 1, then the sequence will automatically raise an objection
665
  // to the starting phase (if the starting phase is not ~null~) immediately
666
  // prior to  being called.  The objection will be dropped
667
  // after  has executed, or  has been called.
668
  //
669
  function bit get_automatic_phase_objection();
670
     return m_automatic_phase_objection_dap.get();
671
  endfunction : get_automatic_phase_objection
672
 
673
  // m_safe_raise_starting_phase
674
  function void m_safe_raise_starting_phase(string description = "",
675
                                            int count = 1);
676
     uvm_phase starting_phase = get_starting_phase();
677
     if (starting_phase != null)
678
       starting_phase.raise_objection(this, description, count);
679
  endfunction : m_safe_raise_starting_phase
680
 
681
  // m_safe_drop_starting_phase
682
  function void m_safe_drop_starting_phase(string description = "",
683
                                           int count = 1);
684
     uvm_phase starting_phase = get_starting_phase();
685
     if (starting_phase != null)
686
       starting_phase.drop_objection(this, description, count);
687
  endfunction : m_safe_drop_starting_phase
688
 
689
  //------------------------
690
  // Group: Sequence Control
691
  //------------------------
692
 
693
  // Function: set_priority
694
  //
695
  // The priority of a sequence may be changed at any point in time.  When the
696
  // priority of a sequence is changed, the new priority will be used by the
697
  // sequencer the next time that it arbitrates between sequences.
698
  //
699
  // The default priority value for a sequence is 100.  Higher values result
700
  // in higher priorities.
701
 
702
  function void set_priority (int value);
703
    m_priority = value;
704
  endfunction
705
 
706
 
707
  // Function: get_priority
708
  //
709
  // This function returns the current priority of the sequence.
710
 
711
  function int get_priority();
712
    return m_priority;
713
  endfunction
714
 
715
 
716
  // Function: is_relevant
717
  //
718
  // The default is_relevant implementation returns 1, indicating that the
719
  // sequence is always relevant.
720
  //
721
  // Users may choose to override with their own virtual function to indicate
722
  // to the sequencer that the sequence is not currently relevant after a
723
  // request has been made.
724
  //
725
  // When the sequencer arbitrates, it will call is_relevant on each requesting,
726
  // unblocked sequence to see if it is relevant. If a 0 is returned, then the
727
  // sequence will not be chosen.
728
  //
729
  // If all requesting sequences are not relevant, then the sequencer will call
730
  // wait_for_relevant on all sequences and re-arbitrate upon its return.
731
  //
732
  // Any sequence that implements is_relevant must also implement
733
  // wait_for_relevant so that the sequencer has a way to wait for a
734
  // sequence to become relevant.
735
 
736
  virtual function bit is_relevant();
737
    is_rel_default = 1;
738
    return 1;
739
  endfunction
740
 
741
 
742
  // Task: wait_for_relevant
743
  //
744
  // This method is called by the sequencer when all available sequences are
745
  // not relevant.  When wait_for_relevant returns the sequencer attempt to
746
  // re-arbitrate.
747
  //
748
  // Returning from this call does not guarantee a sequence is relevant,
749
  // although that would be the ideal. The method provide some delay to
750
  // prevent an infinite loop.
751
  //
752
  // If a sequence defines is_relevant so that it is not always relevant (by
753
  // default, a sequence is always relevant), then the sequence must also supply
754
  // a wait_for_relevant method.
755
 
756
  virtual task wait_for_relevant();
757
    event e;
758
    wait_rel_default = 1;
759
    if (is_rel_default != wait_rel_default)
760
      uvm_report_fatal("RELMSM",
761
        "is_relevant() was implemented without defining wait_for_relevant()", UVM_NONE);
762
    @e;  // this is intended to never return
763
  endtask
764
 
765
 
766
  // Task: lock
767
  //
768
  // Requests a lock on the specified sequencer. If sequencer is ~null~, the lock
769
  // will be requested on the current default sequencer.
770
  //
771
  // A lock request will be arbitrated the same as any other request.  A lock is
772
  // granted after all earlier requests are completed and no other locks or
773
  // grabs are blocking this sequence.
774
  //
775
  // The lock call will return when the lock has been granted.
776
 
777
  task lock(uvm_sequencer_base sequencer = null);
778
    if (sequencer == null)
779
      sequencer = m_sequencer;
780
 
781
    if (sequencer == null)
782
      uvm_report_fatal("LOCKSEQR", "Null m_sequencer reference", UVM_NONE);
783
 
784
    sequencer.lock(this);
785
  endtask
786
 
787
 
788
  // Task: grab
789
  //
790
  // Requests a lock on the specified sequencer.  If no argument is supplied,
791
  // the lock will be requested on the current default sequencer.
792
  //
793
  // A grab request is put in front of the arbitration queue. It will be
794
  // arbitrated before any other requests. A grab is granted when no other grabs
795
  // or locks are blocking this sequence.
796
  //
797
  // The grab call will return when the grab has been granted.
798
 
799
  task grab(uvm_sequencer_base sequencer = null);
800
    if (sequencer == null) begin
801
      if (m_sequencer == null) begin
802
        uvm_report_fatal("GRAB", "Null m_sequencer reference", UVM_NONE);
803
      end
804
      m_sequencer.grab(this);
805
    end
806
    else begin
807
      sequencer.grab(this);
808
    end
809
  endtask
810
 
811
 
812
  // Function: unlock
813
  //
814
  // Removes any locks or grabs obtained by this sequence on the specified
815
  // sequencer. If sequencer is ~null~, then the unlock will be done on the
816
  // current default sequencer.
817
 
818
  function void  unlock(uvm_sequencer_base sequencer = null);
819
    if (sequencer == null) begin
820
      if (m_sequencer == null) begin
821
        uvm_report_fatal("UNLOCK", "Null m_sequencer reference", UVM_NONE);
822
      end
823
      m_sequencer.unlock(this);
824
    end else begin
825
      sequencer.unlock(this);
826
    end
827
  endfunction
828
 
829
 
830
  // Function: ungrab
831
  //
832
  // Removes any locks or grabs obtained by this sequence on the specified
833
  // sequencer. If sequencer is ~null~, then the unlock will be done on the
834
  // current default sequencer.
835
 
836
  function void  ungrab(uvm_sequencer_base sequencer = null);
837
    unlock(sequencer);
838
  endfunction
839
 
840
 
841
  // Function: is_blocked
842
  //
843
  // Returns a bit indicating whether this sequence is currently prevented from
844
  // running due to another lock or grab. A 1 is returned if the sequence is
845
  // currently blocked. A 0 is returned if no lock or grab prevents this
846
  // sequence from executing. Note that even if a sequence is not blocked, it
847
  // is possible for another sequence to issue a lock or grab before this
848
  // sequence can issue a request.
849
 
850
  function bit is_blocked();
851
    return m_sequencer.is_blocked(this);
852
  endfunction
853
 
854
 
855
  // Function: has_lock
856
  //
857
  // Returns 1 if this sequence has a lock, 0 otherwise.
858
  //
859
  // Note that even if this sequence has a lock, a child sequence may also have
860
  // a lock, in which case the sequence is still blocked from issuing
861
  // operations on the sequencer.
862
 
863
  function bit has_lock();
864
    return m_sequencer.has_lock(this);
865
  endfunction
866
 
867
 
868
  // Function: kill
869
  //
870
  // This function will kill the sequence, and cause all current locks and
871
  // requests in the sequence's default sequencer to be removed. The sequence
872
  // state will change to UVM_STOPPED, and the post_body() and post_start() callback
873
  // methods will not be executed.
874
  //
875
  // If a sequence has issued locks, grabs, or requests on sequencers other than
876
  // the default sequencer, then care must be taken to unregister the sequence
877
  // with the other sequencer(s) using the sequencer unregister_sequence()
878
  // method.
879
 
880
  function void kill();
881
    if (m_sequence_process != null) begin
882
      // If we are not connected to a sequencer, then issue
883
      // kill locally.
884
      if (m_sequencer == null) begin
885
        m_kill();
886
        // We need to drop the objection if we raised it...
887
        if (get_automatic_phase_objection()) begin
888
           m_safe_drop_starting_phase("automatic phase objection");
889
        end
890
        return;
891
      end
892
      // If we are attached to a sequencer, then the sequencer
893
      // will clear out queues, and then kill this sequence
894
      m_sequencer.kill_sequence(this);
895
      // We need to drop the objection if we raised it...
896
      if (get_automatic_phase_objection()) begin
897
         m_safe_drop_starting_phase("automatic phase objection");
898
      end
899
      return;
900
    end
901
  endfunction
902
 
903
 
904
  // Function: do_kill
905
  //
906
  // This function is a user hook that is called whenever a sequence is
907
  // terminated by using either sequence.kill() or sequencer.stop_sequences()
908
  // (which effectively calls sequence.kill()).
909
 
910
  virtual function void do_kill();
911
    return;
912
  endfunction
913
 
914
  function void m_kill();
915
    do_kill();
916
    foreach(children_array[i]) begin
917
       i.kill();
918
    end
919
    if (m_sequence_process != null) begin
920
      m_sequence_process.kill;
921
      m_sequence_process = null;
922
    end
923
    m_sequence_state = UVM_STOPPED;
924
    if ((m_parent_sequence != null) && (m_parent_sequence.children_array.exists(this)))
925
      m_parent_sequence.children_array.delete(this);
926
  endfunction
927
 
928
 
929
  //-------------------------------
930
  // Group: Sequence Item Execution
931
  //-------------------------------
932
 
933
  // Function: create_item
934
  //
935
  // Create_item will create and initialize a sequence_item or sequence
936
  // using the factory.  The sequence_item or sequence will be initialized
937
  // to communicate with the specified sequencer.
938
 
939
  protected function uvm_sequence_item create_item(uvm_object_wrapper type_var,
940
                                                   uvm_sequencer_base l_sequencer, string name);
941
 
942
    uvm_coreservice_t cs = uvm_coreservice_t::get();
943
    uvm_factory factory=cs.get_factory();
944
    $cast(create_item,  factory.create_object_by_type( type_var, this.get_full_name(), name ));
945
 
946
    create_item.set_item_context(this, l_sequencer);
947
  endfunction
948
 
949
 
950
  // Function: start_item
951
  //
952
  // ~start_item~ and  together will initiate operation of
953
  // a sequence item.  If the item has not already been
954
  // initialized using create_item, then it will be initialized here to use
955
  // the default sequencer specified by m_sequencer.  Randomization
956
  // may be done between start_item and finish_item to ensure late generation
957
  //
958
 
959
  virtual task start_item (uvm_sequence_item item,
960
                           int set_priority = -1,
961
                           uvm_sequencer_base sequencer=null);
962
    uvm_sequence_base seq;
963
 
964
    if(item == null) begin
965
      uvm_report_fatal("NULLITM",
966
         {"attempting to start a null item from sequence '",
967
          get_full_name(), "'"}, UVM_NONE);
968
      return;
969
    end
970
 
971
    if($cast(seq, item)) begin
972
      uvm_report_fatal("SEQNOTITM",
973
         {"attempting to start a sequence using start_item() from sequence '",
974
          get_full_name(), "'. Use seq.start() instead."}, UVM_NONE);
975
      return;
976
    end
977
 
978
    if (sequencer == null)
979
        sequencer = item.get_sequencer();
980
 
981
    if(sequencer == null)
982
        sequencer = get_sequencer();
983
 
984
    if(sequencer == null) begin
985
        uvm_report_fatal("SEQ",{"neither the item's sequencer nor dedicated sequencer has been supplied to start item in ",get_full_name()},UVM_NONE);
986
       return;
987
    end
988
 
989
    item.set_item_context(this, sequencer);
990
 
991
    if (set_priority < 0)
992
      set_priority = get_priority();
993
 
994
    sequencer.wait_for_grant(this, set_priority);
995
 
996
    if (sequencer.is_auto_item_recording_enabled()) begin
997
      void'(sequencer.begin_child_tr(item,
998
                                     (m_tr_recorder == null) ? 0 : m_tr_recorder.get_handle(),
999
                                     item.get_root_sequence_name(), "Transactions"));
1000
    end
1001
 
1002
    pre_do(1);
1003
 
1004
  endtask
1005
 
1006
 
1007
  // Function: finish_item
1008
  //
1009
  // finish_item, together with start_item together will initiate operation of
1010
  // a sequence_item.  Finish_item must be called
1011
  // after start_item with no delays or delta-cycles.  Randomization, or other
1012
  // functions may be called between the start_item and finish_item calls.
1013
  //
1014
 
1015
  virtual task finish_item (uvm_sequence_item item,
1016
                            int set_priority = -1);
1017
 
1018
    uvm_sequencer_base sequencer;
1019
 
1020
    sequencer = item.get_sequencer();
1021
 
1022
    if (sequencer == null) begin
1023
        uvm_report_fatal("STRITM", "sequence_item has null sequencer", UVM_NONE);
1024
    end
1025
 
1026
    mid_do(item);
1027
    sequencer.send_request(this, item);
1028
    sequencer.wait_for_item_done(this, -1);
1029
 
1030
    if (sequencer.is_auto_item_recording_enabled()) begin
1031
      sequencer.end_tr(item);
1032
    end
1033
 
1034
    post_do(item);
1035
 
1036
  endtask
1037
 
1038
 
1039
  // Task: wait_for_grant
1040
  //
1041
  // This task issues a request to the current sequencer.  If item_priority is
1042
  // not specified, then the current sequence priority will be used by the
1043
  // arbiter. If a lock_request is made, then the sequencer will issue a lock
1044
  // immediately before granting the sequence.  (Note that the lock may be
1045
  // granted without the sequence being granted if is_relevant is not asserted).
1046
  //
1047
  // When this method returns, the sequencer has granted the sequence, and the
1048
  // sequence must call send_request without inserting any simulation delay
1049
  // other than delta cycles.  The driver is currently waiting for the next
1050
  // item to be sent via the send_request call.
1051
 
1052
  virtual task wait_for_grant(int item_priority = -1, bit lock_request = 0);
1053
    if (m_sequencer == null) begin
1054
      uvm_report_fatal("WAITGRANT", "Null m_sequencer reference", UVM_NONE);
1055
    end
1056
    m_sequencer.wait_for_grant(this, item_priority, lock_request);
1057
  endtask
1058
 
1059
 
1060
  // Function: send_request
1061
  //
1062
  // The send_request function may only be called after a wait_for_grant call.
1063
  // This call will send the request item to the sequencer, which will forward
1064
  // it to the driver. If the rerandomize bit is set, the item will be
1065
  // randomized before being sent to the driver.
1066
 
1067
  virtual function void send_request(uvm_sequence_item request, bit rerandomize = 0);
1068
    if (m_sequencer == null) begin
1069
        uvm_report_fatal("SENDREQ", "Null m_sequencer reference", UVM_NONE);
1070
      end
1071
    m_sequencer.send_request(this, request, rerandomize);
1072
  endfunction
1073
 
1074
 
1075
  // Task: wait_for_item_done
1076
  //
1077
  // A sequence may optionally call wait_for_item_done.  This task will block
1078
  // until the driver calls item_done or put.  If no transaction_id parameter
1079
  // is specified, then the call will return the next time that the driver calls
1080
  // item_done or put.  If a specific transaction_id is specified, then the call
1081
  // will return when the driver indicates completion of that specific item.
1082
  //
1083
  // Note that if a specific transaction_id has been specified, and the driver
1084
  // has already issued an item_done or put for that transaction, then the call
1085
  // will hang, having missed the earlier notification.
1086
 
1087
 
1088
  virtual task wait_for_item_done(int transaction_id = -1);
1089
    if (m_sequencer == null) begin
1090
        uvm_report_fatal("WAITITEMDONE", "Null m_sequencer reference", UVM_NONE);
1091
      end
1092
    m_sequencer.wait_for_item_done(this, transaction_id);
1093
  endtask
1094
 
1095
 
1096
 
1097
  // Group: Response API
1098
  //--------------------
1099
 
1100
  // Function: use_response_handler
1101
  //
1102
  // When called with enable set to 1, responses will be sent to the response
1103
  // handler. Otherwise, responses must be retrieved using get_response.
1104
  //
1105
  // By default, responses from the driver are retrieved in the sequence by
1106
  // calling get_response.
1107
  //
1108
  // An alternative method is for the sequencer to call the response_handler
1109
  // function with each response.
1110
 
1111
  function void use_response_handler(bit enable);
1112
    m_use_response_handler = enable;
1113
  endfunction
1114
 
1115
 
1116
  // Function: get_use_response_handler
1117
  //
1118
  // Returns the state of the use_response_handler bit.
1119
 
1120
  function bit get_use_response_handler();
1121
    return m_use_response_handler;
1122
  endfunction
1123
 
1124
 
1125
  // Function: response_handler
1126
  //
1127
  // When the use_response_handler bit is set to 1, this virtual task is called
1128
  // by the sequencer for each response that arrives for this sequence.
1129
 
1130
  virtual function void response_handler(uvm_sequence_item response);
1131
    return;
1132
  endfunction
1133
 
1134
 
1135
  // Function: set_response_queue_error_report_disabled
1136
  //
1137
  // By default, if the response_queue overflows, an error is reported. The
1138
  // response_queue will overflow if more responses are sent to this sequence
1139
  // from the driver than get_response calls are made. Setting value to 0
1140
  // disables these errors, while setting it to 1 enables them.
1141
 
1142
  function void set_response_queue_error_report_disabled(bit value);
1143
    response_queue_error_report_disabled = value;
1144
  endfunction
1145
 
1146
 
1147
  // Function: get_response_queue_error_report_disabled
1148
  //
1149
  // When this bit is 0 (default value), error reports are generated when
1150
  // the response queue overflows. When this bit is 1, no such error
1151
  // reports are generated.
1152
 
1153
  function bit get_response_queue_error_report_disabled();
1154
    return response_queue_error_report_disabled;
1155
  endfunction
1156
 
1157
 
1158
  // Function: set_response_queue_depth
1159
  //
1160
  // The default maximum depth of the response queue is 8. These method is used
1161
  // to examine or change the maximum depth of the response queue.
1162
  //
1163
  // Setting the response_queue_depth to -1 indicates an arbitrarily deep
1164
  // response queue.  No checking is done.
1165
 
1166
  function void set_response_queue_depth(int value);
1167
    response_queue_depth = value;
1168
  endfunction
1169
 
1170
 
1171
  // Function: get_response_queue_depth
1172
  //
1173
  // Returns the current depth setting for the response queue.
1174
 
1175
  function int get_response_queue_depth();
1176
    return response_queue_depth;
1177
  endfunction
1178
 
1179
 
1180
  // Function: clear_response_queue
1181
  //
1182
  // Empties the response queue for this sequence.
1183
 
1184
  virtual function void clear_response_queue();
1185
    response_queue.delete();
1186
  endfunction
1187
 
1188
 
1189
  virtual function void put_base_response(input uvm_sequence_item response);
1190
    if ((response_queue_depth == -1) ||
1191
        (response_queue.size() < response_queue_depth)) begin
1192
      response_queue.push_back(response);
1193
      return;
1194
    end
1195
    if (response_queue_error_report_disabled == 0) begin
1196
      uvm_report_error(get_full_name(), "Response queue overflow, response was dropped", UVM_NONE);
1197
    end
1198
  endfunction
1199
 
1200
 
1201
  // Function- put_response
1202
  //
1203
  // Internal method.
1204
 
1205
  virtual function void put_response (uvm_sequence_item response_item);
1206
    put_base_response(response_item); // no error-checking
1207
  endfunction
1208
 
1209
 
1210
  // Function- get_base_response
1211
 
1212
  virtual task get_base_response(output uvm_sequence_item response, input int transaction_id = -1);
1213
 
1214
    int queue_size, i;
1215
 
1216
    if (response_queue.size() == 0)
1217
      wait (response_queue.size() != 0);
1218
 
1219
    if (transaction_id == -1) begin
1220
      response = response_queue.pop_front();
1221
      return;
1222
    end
1223
 
1224
    forever begin
1225
      queue_size = response_queue.size();
1226
      for (i = 0; i < queue_size; i++) begin
1227
        if (response_queue[i].get_transaction_id() == transaction_id)
1228
          begin
1229
            $cast(response,response_queue[i]);
1230
            response_queue.delete(i);
1231
            return;
1232
          end
1233
      end
1234
      wait (response_queue.size() != queue_size);
1235
    end
1236
  endtask
1237
 
1238
 
1239
 
1240
  //------------------------
1241
  // Group- Sequence Library DEPRECATED
1242
  //------------------------
1243
 
1244
`ifndef UVM_NO_DEPRECATED
1245
 
1246
  // Variable- seq_kind
1247
  //
1248
  // Used as an identifier in constraints for a specific sequence type.
1249
 
1250
  rand int unsigned seq_kind;
1251
 
1252
  // For user random selection. This excludes the exhaustive and
1253
  // random sequences.
1254
  constraint pick_sequence {
1255
       (num_sequences() <= 2) || (seq_kind >= 2);
1256
       (seq_kind <  num_sequences()) || (seq_kind == 0); }
1257
 
1258
 
1259
  // Function- num_sequences
1260
  //
1261
  // Returns the number of sequences in the sequencer's sequence library.
1262
 
1263
  function int num_sequences();
1264
    if (m_sequencer == null)
1265
      return 0;
1266
    return (m_sequencer.num_sequences());
1267
  endfunction
1268
 
1269
 
1270
 
1271
  // Function- get_seq_kind
1272
  //
1273
  // This function returns an int representing the sequence kind that has
1274
  // been registerd with the sequencer.  The return value may be used with
1275
  // the  or  methods.
1276
 
1277
  function int get_seq_kind(string type_name);
1278
    `uvm_warning("UVM_DEPRECATED",$sformatf("%m deprecated."))
1279
    if(m_sequencer != null)
1280
      return m_sequencer.get_seq_kind(type_name);
1281
    else
1282
      uvm_report_warning("NULLSQ", $sformatf("%0s sequencer is null.",
1283
                                           get_type_name()), UVM_NONE);
1284
  endfunction
1285
 
1286
 
1287
  // Function- get_sequence
1288
  //
1289
  // This function returns a reference to a sequence specified by ~req_kind~,
1290
  // which can be obtained using the  method.
1291
 
1292
  function uvm_sequence_base get_sequence(int unsigned req_kind);
1293
    uvm_sequence_base m_seq;
1294
    string m_seq_type;
1295
    uvm_coreservice_t cs = uvm_coreservice_t::get();
1296
    uvm_factory factory=cs.get_factory();
1297
    `uvm_warning("UVM_DEPRECATED",$sformatf("%m deprecated."))
1298
    if (req_kind < 0 || req_kind >= m_sequencer.sequences.size()) begin
1299
      uvm_report_error("SEQRNG",
1300
        $sformatf("Kind arg '%0d' out of range. Need 0-%0d",
1301
        req_kind, m_sequencer.sequences.size()-1), UVM_NONE);
1302
    end
1303
    m_seq_type = m_sequencer.sequences[req_kind];
1304
    if (!$cast(m_seq, factory.create_object_by_name(m_seq_type, get_full_name(), m_seq_type))) begin
1305
      uvm_report_fatal("FCTSEQ",
1306
        $sformatf("Factory cannot produce a sequence of type %0s.",
1307
        m_seq_type), UVM_NONE);
1308
    end
1309
    m_seq.set_use_sequence_info(1);
1310
    return m_seq;
1311
  endfunction
1312
 
1313
 
1314
  // Task- do_sequence_kind
1315
  //
1316
  // This task will start a sequence of kind specified by ~req_kind~,
1317
  // which can be obtained using the  method.
1318
 
1319
  task do_sequence_kind(int unsigned req_kind);
1320
    string m_seq_type;
1321
    uvm_sequence_base m_seq;
1322
    uvm_coreservice_t cs = uvm_coreservice_t::get();
1323
    uvm_factory factory=cs.get_factory();
1324
    `uvm_warning("UVM_DEPRECATED",$sformatf("%m deprecated."))
1325
    m_seq_type = m_sequencer.sequences[req_kind];
1326
    if (!$cast(m_seq, factory.create_object_by_name(m_seq_type, get_full_name(), m_seq_type))) begin
1327
      uvm_report_fatal("FCTSEQ",
1328
        $sformatf("Factory cannot produce a sequence of type %0s.", m_seq_type), UVM_NONE);
1329
    end
1330
 
1331
    m_seq.set_item_context(this, m_sequencer);
1332
 
1333
    if(!m_seq.randomize()) begin
1334
      uvm_report_warning("RNDFLD", "Randomization failed in do_sequence_kind()");
1335
    end
1336
    m_seq.start(m_sequencer,this,get_priority(),0);
1337
  endtask
1338
 
1339
 
1340
  // Function- get_sequence_by_name
1341
  //
1342
  // Internal method.
1343
 
1344
  function uvm_sequence_base get_sequence_by_name(string seq_name);
1345
    uvm_sequence_base m_seq;
1346
    uvm_coreservice_t cs = uvm_coreservice_t::get();
1347
    uvm_factory factory=cs.get_factory();
1348
    `uvm_warning("UVM_DEPRECATED",$sformatf("%m deprecated."))
1349
    if (!$cast(m_seq, factory.create_object_by_name(seq_name, get_full_name(), seq_name))) begin
1350
      uvm_report_fatal("FCTSEQ",
1351
        $sformatf("Factory cannot produce a sequence of type %0s.", seq_name), UVM_NONE);
1352
    end
1353
    m_seq.set_use_sequence_info(1);
1354
    return m_seq;
1355
  endfunction
1356
 
1357
 
1358
  // Task- create_and_start_sequence_by_name
1359
  //
1360
  // Internal method.
1361
 
1362
  task create_and_start_sequence_by_name(string seq_name);
1363
    uvm_sequence_base m_seq;
1364
    `uvm_warning("UVM_DEPRECATED",$sformatf("%m deprecated."))
1365
    m_seq = get_sequence_by_name(seq_name);
1366
    m_seq.start(m_sequencer, this, this.get_priority(), 0);
1367
  endtask
1368
 
1369
 
1370
`endif // UVM_NO_DEPRECATED
1371
 
1372
  //----------------------
1373
  // Misc Internal methods
1374
  //----------------------
1375
 
1376
 
1377
  // m_get_sqr_sequence_id
1378
  // ---------------------
1379
 
1380
  function int m_get_sqr_sequence_id(int sequencer_id, bit update_sequence_id);
1381
    if (m_sqr_seq_ids.exists(sequencer_id)) begin
1382
      if (update_sequence_id == 1) begin
1383
        set_sequence_id(m_sqr_seq_ids[sequencer_id]);
1384
      end
1385
      return m_sqr_seq_ids[sequencer_id];
1386
    end
1387
 
1388
    if (update_sequence_id == 1)
1389
      set_sequence_id(-1);
1390
 
1391
    return -1;
1392
  endfunction
1393
 
1394
 
1395
  // m_set_sqr_sequence_id
1396
  // ---------------------
1397
 
1398
  function void m_set_sqr_sequence_id(int sequencer_id, int sequence_id);
1399
    m_sqr_seq_ids[sequencer_id] = sequence_id;
1400
    set_sequence_id(sequence_id);
1401
  endfunction
1402
 
1403
endclass
1404
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.