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

Subversion Repositories uart2bus_testbench

[/] [uart2bus_testbench/] [trunk/] [tb/] [uvm_src/] [seq/] [uvm_sequencer.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 Synopsys, Inc.
5
//   Copyright 2014 NVIDIA Corporation
6
//   All Rights Reserved Worldwide
7
//
8
//   Licensed under the Apache License, Version 2.0 (the
9
//   "License"); you may not use this file except in
10
//   compliance with the License.  You may obtain a copy of
11
//   the License at
12
//
13
//       http://www.apache.org/licenses/LICENSE-2.0
14
//
15
//   Unless required by applicable law or agreed to in
16
//   writing, software distributed under the License is
17
//   distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
18
//   CONDITIONS OF ANY KIND, either express or implied.  See
19
//   the License for the specific language governing
20
//   permissions and limitations under the License.
21
//----------------------------------------------------------------------
22
 
23
 
24
//------------------------------------------------------------------------------
25
//
26
// CLASS: uvm_sequencer #(REQ,RSP)
27
//
28
//------------------------------------------------------------------------------
29
 
30
class uvm_sequencer #(type REQ=uvm_sequence_item, RSP=REQ)
31
                                   extends uvm_sequencer_param_base #(REQ, RSP);
32
 
33
  typedef uvm_sequencer #( REQ , RSP) this_type;
34
 
35
  bit sequence_item_requested;
36
  bit get_next_item_called;
37
 
38
  `uvm_component_param_utils(this_type)
39
 
40
 
41
 
42
  // Function: new
43
  //
44
  // Standard component constructor that creates an instance of this class
45
  // using the given ~name~ and ~parent~, if any.
46
  //
47
  extern function new (string name, uvm_component parent=null);
48
 
49
 
50
  // Function: stop_sequences
51
  //
52
  // Tells the sequencer to kill all sequences and child sequences currently
53
  // operating on the sequencer, and remove all requests, locks and responses
54
  // that are currently queued.  This essentially resets the sequencer to an
55
  // idle state.
56
  //
57
  extern virtual function void stop_sequences();
58
 
59
  extern virtual function string get_type_name();
60
 
61
  // Group: Sequencer Interface
62
  // This is an interface for communicating with sequencers.
63
  //
64
  // The interface is defined as:
65
  //| Requests:
66
  //|  virtual task          get_next_item      (output REQ request);
67
  //|  virtual task          try_next_item      (output REQ request);
68
  //|  virtual task          get                (output REQ request);
69
  //|  virtual task          peek               (output REQ request);
70
  //| Responses:
71
  //|  virtual function void item_done          (input RSP response=null);
72
  //|  virtual task          put                (input RSP response);
73
  //| Sync Control:
74
  //|  virtual task          wait_for_sequences ();
75
  //|  virtual function bit  has_do_available   ();
76
  //
77
  // See  for information about this interface.
78
 
79
  // Variable: seq_item_export
80
  //
81
  // This export provides access to this sequencer's implementation of the
82
  // sequencer interface.
83
  //
84
 
85
  uvm_seq_item_pull_imp #(REQ, RSP, this_type) seq_item_export;
86
 
87
  // Task: get_next_item
88
  // Retrieves the next available item from a sequence.
89
  //
90
  extern virtual task          get_next_item (output REQ t);
91
 
92
  // Task: try_next_item
93
  // Retrieves the next available item from a sequence if one is available.
94
  //
95
  extern virtual task          try_next_item (output REQ t);
96
 
97
  // Function: item_done
98
  // Indicates that the request is completed.
99
  //
100
  extern virtual function void item_done     (RSP item = null);
101
 
102
  // Task: put
103
  // Sends a response back to the sequence that issued the request.
104
  //
105
  extern virtual task          put           (RSP t);
106
 
107
  // Task: get
108
  // Retrieves the next available item from a sequence.
109
  //
110
  extern task                  get           (output REQ t);
111
 
112
  // Task: peek
113
  // Returns the current request item if one is in the FIFO.
114
  //
115
  extern task                  peek          (output REQ t);
116
 
117
  /// Documented here for clarity, implemented in uvm_sequencer_base
118
 
119
  // Task: wait_for_sequences
120
  // Waits for a sequence to have a new item available.
121
  //
122
 
123
  // Function: has_do_available
124
  // Returns 1 if any sequence running on this sequencer is ready to supply
125
  // a transaction, 0 otherwise.
126
  //
127
 
128
  //-----------------
129
  // Internal Methods
130
  //-----------------
131
  // Do not use directly, not part of standard
132
 
133
  extern function void         item_done_trigger(RSP item = null);
134
  function RSP                 item_done_get_trigger_data();
135
    return last_rsp(0);
136
  endfunction
137
  extern protected virtual function int m_find_number_driver_connections();
138
 
139
endclass
140
 
141
 
142
typedef uvm_sequencer #(uvm_sequence_item) uvm_virtual_sequencer;
143
 
144
 
145
 
146
//------------------------------------------------------------------------------
147
// IMPLEMENTATION
148
//------------------------------------------------------------------------------
149
 
150
function uvm_sequencer::new (string name, uvm_component parent=null);
151
  super.new(name, parent);
152
  seq_item_export = new ("seq_item_export", this);
153
endfunction
154
 
155
 
156
// Function- stop_sequences
157
//
158
// Tells the sequencer to kill all sequences and child sequences currently
159
// operating on the sequencer, and remove all requests, locks and responses
160
// that are currently queued.  This essentially resets the sequencer to an
161
// idle state.
162
//
163
function void uvm_sequencer::stop_sequences();
164
  REQ t;
165
  super.stop_sequences();
166
  sequence_item_requested  = 0;
167
  get_next_item_called     = 0;
168
  // Empty the request fifo
169
  if (m_req_fifo.used()) begin
170
    uvm_report_info(get_full_name(), "Sequences stopped.  Removing request from sequencer fifo");
171
    while (m_req_fifo.try_get(t));
172
  end
173
endfunction
174
 
175
 
176
function string uvm_sequencer::get_type_name();
177
  return "uvm_sequencer";
178
endfunction
179
 
180
 
181
//-----------------
182
// Internal Methods
183
//-----------------
184
 
185
// m_find_number_driver_connections
186
// --------------------------------
187
// Counting the number of of connections is done at end of
188
// elaboration and the start of run.  If the user neglects to
189
// call super in one or the other, the sequencer will still
190
// have the correct value
191
 
192
function int uvm_sequencer::m_find_number_driver_connections();
193
  uvm_port_component_base provided_to_port_list[string];
194
  uvm_port_component_base seq_port_base;
195
 
196
  // Check that the seq_item_pull_port is connected
197
  seq_port_base = seq_item_export.get_comp();
198
  seq_port_base.get_provided_to(provided_to_port_list);
199
  return provided_to_port_list.num();
200
endfunction
201
 
202
 
203
// get_next_item
204
// -------------
205
 
206
task uvm_sequencer::get_next_item(output REQ t);
207
  REQ req_item;
208
 
209
  // If a sequence_item has already been requested, then get_next_item()
210
  // should not be called again until item_done() has been called.
211
 
212
  if (get_next_item_called == 1)
213
    uvm_report_error(get_full_name(),
214
      "Get_next_item called twice without item_done or get in between", UVM_NONE);
215
 
216
  if (!sequence_item_requested)
217
    m_select_sequence();
218
 
219
  // Set flag indicating that the item has been requested to ensure that item_done or get
220
  // is called between requests
221
  sequence_item_requested = 1;
222
  get_next_item_called = 1;
223
  m_req_fifo.peek(t);
224
endtask
225
 
226
 
227
// try_next_item
228
// -------------
229
 
230
task uvm_sequencer::try_next_item(output REQ t);
231
  int selected_sequence;
232
  time arb_time;
233
  uvm_sequence_base seq;
234
 
235
  if (get_next_item_called == 1) begin
236
    uvm_report_error(get_full_name(), "get_next_item/try_next_item called twice without item_done or get in between", UVM_NONE);
237
    return;
238
  end
239
 
240
  // allow state from last transaction to settle such that sequences'
241
  // relevancy can be determined with up-to-date information
242
  wait_for_sequences();
243
 
244
  // choose the sequence based on relevancy
245
  selected_sequence = m_choose_next_request();
246
 
247
  // return if none available
248
  if (selected_sequence == -1) begin
249
    t = null;
250
    return;
251
  end
252
 
253
  // now, allow chosen sequence to resume
254
  m_set_arbitration_completed(arb_sequence_q[selected_sequence].request_id);
255
  seq = arb_sequence_q[selected_sequence].sequence_ptr;
256
  arb_sequence_q.delete(selected_sequence);
257
  m_update_lists();
258
  sequence_item_requested = 1;
259
  get_next_item_called = 1;
260
 
261
  // give it one NBA to put a new item in the fifo
262
  wait_for_sequences();
263
 
264
  // attempt to get the item; if it fails, produce an error and return
265
  if (!m_req_fifo.try_peek(t))
266
    uvm_report_error("TRY_NEXT_BLOCKED", {"try_next_item: the selected sequence '",
267
      seq.get_full_name(), "' did not produce an item within an NBA delay. ",
268
      "Sequences should not consume time between calls to start_item and finish_item. ",
269
      "Returning null item."}, UVM_NONE);
270
 
271
endtask
272
 
273
 
274
// item_done
275
// ---------
276
 
277
function void uvm_sequencer::item_done(RSP item = null);
278
  REQ t;
279
 
280
  // Set flag to allow next get_next_item or peek to get a new sequence_item
281
  sequence_item_requested = 0;
282
  get_next_item_called = 0;
283
 
284
  if (m_req_fifo.try_get(t) == 0) begin
285
    uvm_report_fatal(get_full_name(), {"Item_done() called with no outstanding requests.",
286
      " Each call to item_done() must be paired with a previous call to get_next_item()."});
287
  end else begin
288
    m_wait_for_item_sequence_id = t.get_sequence_id();
289
    m_wait_for_item_transaction_id = t.get_transaction_id();
290
  end
291
 
292
  if (item != null) begin
293
    seq_item_export.put_response(item);
294
  end
295
 
296
  // Grant any locks as soon as possible
297
  grant_queued_locks();
298
endfunction
299
 
300
 
301
// put
302
// ---
303
 
304
task uvm_sequencer::put (RSP t);
305
  put_response(t);
306
endtask
307
 
308
 
309
// get
310
// ---
311
 
312
task uvm_sequencer::get(output REQ t);
313
  if (sequence_item_requested == 0) begin
314
    m_select_sequence();
315
  end
316
  sequence_item_requested = 1;
317
  m_req_fifo.peek(t);
318
  item_done();
319
endtask
320
 
321
 
322
// peek
323
// ----
324
 
325
task uvm_sequencer::peek(output REQ t);
326
 
327
  if (sequence_item_requested == 0) begin
328
    m_select_sequence();
329
  end
330
 
331
  // Set flag indicating that the item has been requested to ensure that item_done or get
332
  // is called between requests
333
  sequence_item_requested = 1;
334
  m_req_fifo.peek(t);
335
endtask
336
 
337
 
338
// item_done_trigger
339
// -----------------
340
 
341
function void uvm_sequencer::item_done_trigger(RSP item = null);
342
  item_done(item);
343
endfunction
344
 
345
 
346
 

powered by: WebSVN 2.1.0

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