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

Subversion Repositories uart2bus_testbench

[/] [uart2bus_testbench/] [trunk/] [tb/] [uvm_src/] [base/] [uvm_tr_stream.svh] - Blame information for rev 16

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 16 HanySalah
//
2
//-----------------------------------------------------------------------------
3
//   Copyright 2007-2011 Mentor Graphics Corporation
4
//   Copyright 2007-2011 Cadence Design Systems, Inc.
5
//   Copyright 2010 Synopsys, Inc.
6
//   Copyright 2013 NVIDIA Corporation
7
//   All Rights Reserved Worldwide
8
//
9
//   Licensed under the Apache License, Version 2.0 (the
10
//   "License"); you may not use this file except in
11
//   compliance with the License.  You may obtain a copy of
12
//   the License at
13
//
14
//       http://www.apache.org/licenses/LICENSE-2.0
15
//
16
//   Unless required by applicable law or agreed to in
17
//   writing, software distributed under the License is
18
//   distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
19
//   CONDITIONS OF ANY KIND, either express or implied.  See
20
//   the License for the specific language governing
21
//   permissions and limitations under the License.
22
//-----------------------------------------------------------------------------
23
 
24
//------------------------------------------------------------------------------
25
// File: Transaction Recording Streams
26
//
27
 
28
// class- m_uvm_tr_stream_cfg
29
// Undocumented helper class for storing stream
30
// initialization values.
31
class m_uvm_tr_stream_cfg;
32
   uvm_tr_database db;
33
   string scope;
34
   string stream_type_name;
35
endclass : m_uvm_tr_stream_cfg
36
 
37
typedef class uvm_set_before_get_dap;
38
typedef class uvm_text_recorder;
39
 
40
//------------------------------------------------------------------------------
41
//
42
// CLASS: uvm_tr_stream
43
//
44
// The ~uvm_tr_stream~ base class is a representation of a stream of records
45
// within a .
46
//
47
// The record stream is intended to hide the underlying database implementation
48
// from the end user, as these details are often vendor or tool-specific.
49
//
50
// The ~uvm_tr_stream~ class is pure virtual, and must be extended with an
51
// implementation.  A default text-based implementation is provided via the
52
//  class.
53
//
54
virtual class uvm_tr_stream extends uvm_object;
55
 
56
   // Variable- m_cfg_dap
57
   // Data access protected reference to the DB
58
   local uvm_set_before_get_dap#(m_uvm_tr_stream_cfg) m_cfg_dap;
59
 
60
   // Variable- m_records
61
   // Active records in the stream (active == open or closed)
62
   local bit m_records[uvm_recorder];
63
 
64
   // Variable- m_warn_null_cfg
65
   // Used to limit the number of warnings
66
   local bit m_warn_null_cfg;
67
 
68
   // Variable- m_is_opened
69
   // Used to indicate stream is open
70
   local bit m_is_opened;
71
 
72
   // Variable- m_is_closed
73
   // Used to indicate stream is closed
74
   local bit m_is_closed;
75
 
76
   // !m_is_opened && !m_is_closed == m_is_freed
77
 
78
   // Function: new
79
   // Constructor
80
   //
81
   // Parameters:
82
   // name - Stream instance name
83
   function new(string name="unnamed-uvm_tr_stream");
84
      super.new(name);
85
      m_cfg_dap = new("cfg_dap");
86
   endfunction : new
87
 
88
   // Variable- m_ids_by_stream
89
   // An associative array of integers, indexed by uvm_tr_streams.  This
90
   // provides a unique 'id' or 'handle' for each stream, which can be
91
   // used to identify the stream.
92
   //
93
   // By default, neither ~m_ids_by_stream~ or ~m_streams_by_id~ are
94
   // used.  Streams are only placed in the arrays when the user
95
   // attempts to determine the id for a stream.
96
   local static integer m_ids_by_stream[uvm_tr_stream];
97
 
98
   // Group: Configuration API
99
 
100
   // Function: get_db
101
   // Returns a reference to the database which contains this
102
   // stream.
103
   //
104
   // A warning will be asserted if get_db is called prior to
105
   // the stream being initialized via .
106
   function uvm_tr_database get_db();
107
      m_uvm_tr_stream_cfg m_cfg;
108
      if (!m_cfg_dap.try_get(m_cfg)) begin
109
         if (m_warn_null_cfg == 1)
110
           `uvm_warning("UVM/REC_STR/NO_CFG",
111
                        $sformatf("attempt to retrieve DB from '%s' before it was set!",
112
                                  get_name()))
113
         m_warn_null_cfg = 0;
114
         return null;
115
      end
116
      return m_cfg.db;
117
   endfunction : get_db
118
 
119
   // Function: get_scope
120
   // Returns the ~scope~ supplied when opening this stream.
121
   //
122
   // A warning will be asserted if get_scope is called prior to
123
   // the stream being initialized via .
124
   function string get_scope();
125
      m_uvm_tr_stream_cfg m_cfg;
126
      if (!m_cfg_dap.try_get(m_cfg)) begin
127
         if (m_warn_null_cfg == 1)
128
           `uvm_warning("UVM/REC_STR/NO_CFG",
129
                        $sformatf("attempt to retrieve scope from '%s' before it was set!",
130
                                  get_name()))
131
         m_warn_null_cfg = 0;
132
         return "";
133
      end
134
      return m_cfg.scope;
135
   endfunction : get_scope
136
 
137
   // Function: get_stream_type_name
138
   // Returns a reference to the database which contains this
139
   // stream.
140
   //
141
   // A warning will be asserted if get_stream_type_name is called prior to
142
   // the stream being initialized via .
143
   function string get_stream_type_name();
144
      m_uvm_tr_stream_cfg m_cfg;
145
      if (!m_cfg_dap.try_get(m_cfg)) begin
146
         if (m_warn_null_cfg == 1)
147
           `uvm_warning("UVM/REC_STR/NO_CFG",
148
                        $sformatf("attempt to retrieve STREAM_TYPE_NAME from '%s' before it was set!",
149
                                  get_name()))
150
         m_warn_null_cfg = 0;
151
         return "";
152
      end
153
      return m_cfg.stream_type_name;
154
   endfunction : get_stream_type_name
155
 
156
   // Group: Stream API
157
   //
158
   // Once a stream has been opened via , the user
159
   // can ~close~ the stream.
160
   //
161
   // Due to the fact that many database implementations will require crossing
162
   // a language boundary, an additional step of ~freeing~ the stream is required.
163
   //
164
   // A ~link~ can be established within the database any time between "Open" and
165
   // "Free", however it is illegal to establish a link after "Freeing" the stream.
166
   //
167
 
168
   // Function: close
169
   // Closes this stream.
170
   //
171
   // Closing a stream closes all open recorders in the stream.
172
   //
173
   // This method will trigger a  call, followed by
174
   //  on all open recorders within the
175
   // stream.
176
   function void close();
177
      if (!is_open())
178
        return;
179
 
180
      do_close();
181
 
182
      foreach (m_records[idx])
183
        if (idx.is_open())
184
          idx.close();
185
 
186
      m_is_opened = 0;
187
      m_is_closed = 1;
188
   endfunction : close
189
 
190
   // Function: free
191
   // Frees this stream.
192
   //
193
   // Freeing a stream indicates that the database can free any
194
   // references to the stream (including references to records
195
   // within the stream).
196
   //
197
   // This method will trigger a  call, followed by
198
   //  on all recorders within the stream.
199
   function void free();
200
           process p;
201
           string s;
202
      uvm_tr_database db;
203
      if (!is_open() && !is_closed())
204
        return;
205
 
206
      if (is_open())
207
        close();
208
 
209
      do_free();
210
 
211
      foreach (m_records[idx])
212
        idx.free();
213
 
214
      // Clear out internal state
215
      db = get_db();
216
      m_is_closed = 0;
217
      p = process::self();
218
      if(p != null)
219
        s = p.get_randstate();
220
      m_cfg_dap = new("cfg_dap");
221
      if(p != null)
222
        p.set_randstate(s);
223
      m_warn_null_cfg = 1;
224
      if (m_ids_by_stream.exists(this))
225
        m_free_id(m_ids_by_stream[this]);
226
 
227
      // Clear out DB state
228
      if (db != null)
229
        db.m_free_stream(this);
230
   endfunction : free
231
 
232
   // Function- m_do_open
233
   // Initializes the state of the stream
234
   //
235
   // Parameters-
236
   // db - Database which the stream belongs to
237
   // scope - Optional scope
238
   // stream_type_name - Optional type name for the stream
239
   //
240
   // This method will trigger a  call.
241
   //
242
   // An error will be asserted if-
243
   // - m_do_open is called more than once without the stream
244
   //   being ~freed~ between.
245
   // - m_do_open is passed a ~null~ db
246
   function void m_do_open(uvm_tr_database db,
247
                           string scope="",
248
                           string stream_type_name="");
249
 
250
      m_uvm_tr_stream_cfg m_cfg;
251
      uvm_tr_database m_db;
252
      if (db == null) begin
253
         `uvm_error("UVM/REC_STR/NULL_DB",
254
                    $sformatf("Illegal attempt to set DB for '%s' to ''",
255
                              this.get_full_name()))
256
         return;
257
      end
258
 
259
      if (m_cfg_dap.try_get(m_cfg)) begin
260
         `uvm_error("UVM/REC_STR/RE_CFG",
261
                    $sformatf("Illegal attempt to re-open '%s'",
262
                              this.get_full_name()))
263
      end
264
      else begin
265
         // Never set before
266
         m_cfg = new();
267
         m_cfg.db = db;
268
         m_cfg.scope = scope;
269
         m_cfg.stream_type_name = stream_type_name;
270
         m_cfg_dap.set(m_cfg);
271
         m_is_opened = 1;
272
 
273
         do_open(db, scope, stream_type_name);
274
      end
275
 
276
   endfunction : m_do_open
277
 
278
   // Function: is_open
279
   // Returns true if this ~uvm_tr_stream~ was opened on the database,
280
   // but has not yet been closed.
281
   //
282
   function bit is_open();
283
      return m_is_opened;
284
   endfunction : is_open
285
 
286
   // Function: is_closed
287
   // Returns true if this ~uvm_tr_stream~ was closed on the database,
288
   // but has not yet been freed.
289
   //
290
   function bit is_closed();
291
      return m_is_closed;
292
   endfunction : is_closed
293
 
294
   // Group: Transaction Recorder API
295
   //
296
   // New recorders can be opened prior to the stream being ~closed~.
297
   //
298
   // Once a stream has been closed, requests to open a new recorder
299
   // will be ignored ( will return ~null~).
300
   //
301
 
302
   // Function: open_recorder
303
   // Marks the opening of a new transaction recorder on the stream.
304
   //
305
   // Parameters:
306
   // name - A name for the new transaction
307
   // open_time - Optional time to record as the opening of this transaction
308
   // type_name - Optional type name for the transaction
309
   //
310
   // If ~open_time~ is omitted (or set to 0), then the stream will use
311
   // the current time.
312
   //
313
   // This method will trigger a  call.  If ~do_open_recorder~
314
   // returns a non-~null~ value, then the  method will
315
   // be called in the recorder.
316
   //
317
   // Transaction recorders can only be opened if the stream is
318
   // ~open~ on the database (per ).  Otherwise the
319
   // request will be ignored, and ~null~ will be returned.
320
   function uvm_recorder open_recorder(string name,
321
                                      time   open_time = 0,
322
                                      string type_name="");
323
      time m_time = (open_time == 0) ? $time : open_time;
324
 
325
      // Check to make sure we're open
326
      if (!is_open())
327
        return null;
328
      else begin
329
         process p = process::self();
330
         string s;
331
 
332
         if (p != null)
333
           s = p.get_randstate();
334
 
335
         open_recorder = do_open_recorder(name,
336
                                          m_time,
337
                                          type_name);
338
 
339
 
340
 
341
         if (open_recorder != null) begin
342
            m_records[open_recorder] = 1;
343
            open_recorder.m_do_open(this, m_time, type_name);
344
         end
345
         if (p != null)
346
           p.set_randstate(s);
347
      end
348
   endfunction : open_recorder
349
 
350
   // Function- m_free_recorder
351
   // Removes recorder from the internal array
352
   function void m_free_recorder(uvm_recorder recorder);
353
      if (m_records.exists(recorder))
354
        m_records.delete(recorder);
355
   endfunction : m_free_recorder
356
 
357
   // Function: get_recorders
358
   // Provides a queue of all transactions within the stream.
359
   //
360
   // Parameters:
361
   // q - A reference to the queue of s
362
   //
363
   // The  method returns the size of the queue,
364
   // such that the user can conditionally process the elements.
365
   //
366
   // | uvm_recorder tr_q[$];
367
   // | if (my_stream.get_recorders(tr_q)) begin
368
   // |   // Process the queue...
369
   // | end
370
   //
371
   function unsigned get_recorders(ref uvm_recorder q[$]);
372
      // Clear out the queue first...
373
      q.delete();
374
      // Fill in the values
375
      foreach (m_records[idx])
376
        q.push_back(idx);
377
      // Finally return the size of the queue
378
      return q.size();
379
   endfunction : get_recorders
380
 
381
   // Group: Handles
382
 
383
   // Variable- m_streams_by_id
384
   // A corollary to ~m_ids_by_stream~, this indexes the streams by their
385
   // unique ids.
386
   local static uvm_tr_stream m_streams_by_id[integer];
387
 
388
   // Function: get_handle
389
   // Returns a unique ID for this stream.
390
   //
391
   // A value of ~0~ indicates that the recorder has been ~freed~,
392
   // and no longer has a valid ID.
393
   //
394
   function integer get_handle();
395
      if (!is_open() && !is_closed()) begin
396
        return 0;
397
      end
398
      else begin
399
         integer handle = get_inst_id();
400
 
401
         // Check for the weird case where our handle changed.
402
         if (m_ids_by_stream.exists(this) && m_ids_by_stream[this] != handle)
403
           m_streams_by_id.delete(m_ids_by_stream[this]);
404
 
405
         m_streams_by_id[handle] = this;
406
         m_ids_by_stream[this] = handle;
407
 
408
         return handle;
409
      end
410
   endfunction : get_handle
411
 
412
   // Function- m_get_handle
413
   // Provided to allow implementation-specific handles which are not
414
   // identical to the built-in handles.
415
   //
416
   // This is an implementation detail of the UVM library, which allows
417
   // for vendors to (optionally) put vendor-specific methods into the library.
418
   virtual function integer m_get_handle();
419
      return get_handle();
420
   endfunction : m_get_handle
421
 
422
   // Function: get_stream_from_handle
423
   // Static accessor, returns a stream reference for a given unique id.
424
   //
425
   // If no stream exists with the given ~id~, or if the
426
   // stream with that ~id~ has been freed, then ~null~ is
427
   // returned.
428
   //
429
   static function uvm_tr_stream get_stream_from_handle(integer id);
430
      if (id == 0)
431
        return null;
432
 
433
      if ($isunknown(id) || !m_streams_by_id.exists(id))
434
        return null;
435
 
436
      return m_streams_by_id[id];
437
   endfunction : get_stream_from_handle
438
 
439
   // Function- m_free_id
440
   // Frees the id/stream link (memory cleanup)
441
   //
442
   static function void m_free_id(integer id);
443
      uvm_tr_stream stream;
444
      if (!$isunknown(id) && m_streams_by_id.exists(id))
445
        stream = m_streams_by_id[id];
446
 
447
      if (stream != null) begin
448
         m_streams_by_id.delete(id);
449
         m_ids_by_stream.delete(stream);
450
      end
451
   endfunction : m_free_id
452
 
453
   // Group: Implementation Agnostic API
454
   //
455
 
456
   // Function: do_open
457
   // Callback triggered via .
458
   //
459
   // Parameters:
460
   // db - Database which the stream belongs to
461
   // scope - Optional scope
462
   // stream_type_name - Optional type name for the stream
463
   //
464
   // The ~do_open~ callback can be used to initialize any internal
465
   // state within the stream, as well as providing a location to
466
   // record any initial information about the stream.
467
   protected virtual function void do_open(uvm_tr_database db,
468
                                           string scope,
469
                                           string stream_type_name);
470
   endfunction : do_open
471
 
472
   // Function: do_close
473
   // Callback triggered via .
474
   //
475
   // The ~do_close~ callback can be used to set internal state
476
   // within the stream, as well as providing a location to
477
   // record any closing information.
478
   protected virtual function void do_close();
479
   endfunction : do_close
480
 
481
   // Function: do_free
482
   // Callback triggered via .
483
   //
484
   // The ~do_free~ callback can be used to release the internal
485
   // state within the stream, as well as providing a location
486
   // to record any "freeing" information.
487
   protected virtual function void do_free();
488
   endfunction : do_free
489
 
490
   // Function: do_open_recorder
491
   // Marks the beginning of a new record in the stream.
492
   //
493
   // Backend implementation of 
494
   protected virtual function uvm_recorder do_open_recorder(string name,
495
                                                            time   open_time,
496
                                                            string type_name);
497
      return null;
498
   endfunction : do_open_recorder
499
 
500
endclass : uvm_tr_stream
501
 
502
//------------------------------------------------------------------------------
503
//
504
// CLASS: uvm_text_tr_stream
505
//
506
// The ~uvm_text_tr_stream~ is the default stream implementation for the
507
// .
508
//
509
//
510
 
511
class uvm_text_tr_stream extends uvm_tr_stream;
512
 
513
   // Variable- m_text_db
514
   // Internal reference to the text-based backend
515
   local uvm_text_tr_database m_text_db;
516
 
517
   `uvm_object_utils_begin(uvm_text_tr_stream)
518
   `uvm_object_utils_end
519
 
520
   // Function: new
521
   // Constructor
522
   //
523
   // Parameters:
524
   // name - Instance name
525
   function new(string name="unnamed-uvm_text_tr_stream");
526
      super.new(name);
527
   endfunction : new
528
 
529
   // Group: Implementation Agnostic API
530
 
531
   // Function: do_open
532
   // Callback triggered via .
533
   //
534
   protected virtual function void do_open(uvm_tr_database db,
535
                                           string scope,
536
                                           string stream_type_name);
537
      $cast(m_text_db, db);
538
      if (m_text_db.open_db())
539
        $fdisplay(m_text_db.m_file,
540
                  "  CREATE_STREAM @%0t {NAME:%s T:%s SCOPE:%s STREAM:%0d}",
541
                  $time,
542
                  this.get_name(),
543
                  stream_type_name,
544
                  scope,
545
                  this.get_handle());
546
   endfunction : do_open
547
 
548
   // Function: do_close
549
   // Callback triggered via .
550
   protected virtual function void do_close();
551
      if (m_text_db.open_db())
552
        $fdisplay(m_text_db.m_file,
553
                  "  CLOSE_STREAM @%0t {NAME:%s T:%s SCOPE:%s STREAM:%0d}",
554
                  $time,
555
                  this.get_name(),
556
                  this.get_stream_type_name(),
557
                  this.get_scope(),
558
                  this.get_handle());
559
   endfunction : do_close
560
 
561
   // Function: do_free
562
   // Callback triggered via .
563
   //
564
   protected virtual function void do_free();
565
      if (m_text_db.open_db())
566
        $fdisplay(m_text_db.m_file,
567
                  "  FREE_STREAM @%0t {NAME:%s T:%s SCOPE:%s STREAM:%0d}",
568
                  $time,
569
                  this.get_name(),
570
                  this.get_stream_type_name(),
571
                  this.get_scope(),
572
                  this.get_handle());
573
      m_text_db = null;
574
      return;
575
   endfunction : do_free
576
 
577
   // Function: do_open_recorder
578
   // Marks the beginning of a new record in the stream
579
   //
580
   // Text-backend specific implementation.
581
   protected virtual function uvm_recorder do_open_recorder(string name,
582
                                                           time   open_time,
583
                                                           string type_name);
584
      if (m_text_db.open_db()) begin
585
         return uvm_text_recorder::type_id::create(name);
586
      end
587
 
588
      return null;
589
   endfunction : do_open_recorder
590
 
591
endclass : uvm_text_tr_stream

powered by: WebSVN 2.1.0

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