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

Subversion Repositories uart2bus_testbench

[/] [uart2bus_testbench/] [trunk/] [tb/] [uvm_src/] [reg/] [uvm_reg_sequence.svh] - Blame information for rev 16

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 16 HanySalah
//
2
// -------------------------------------------------------------
3
//    Copyright 2004-2009 Synopsys, Inc.
4
//    Copyright 2010-2011 Mentor Graphics Corporation
5
//    Copyright 2010-2011 Cadence Design Systems, Inc.
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
// TITLE: Register Sequence Classes
27
//------------------------------------------------------------------------------
28
//
29
// This section defines the base classes used for register stimulus generation.
30
//------------------------------------------------------------------------------
31
 
32
 
33
//------------------------------------------------------------------------------
34
//
35
// CLASS: uvm_reg_sequence
36
//
37
// This class provides base functionality for both user-defined RegModel test
38
// sequences and "register translation sequences".
39
//
40
// - When used as a base for user-defined RegModel test sequences, this class
41
//   provides convenience methods for reading and writing registers and
42
//   memories. Users implement the body() method to interact directly with
43
//   the RegModel model (held in the  property) or indirectly via the
44
//   delegation methods in this class.
45
//
46
// - When used as a translation sequence, objects of this class are
47
//   executed directly on a bus sequencer which are used in support of a layered sequencer
48
//   use model, a pre-defined convert-and-execute algorithm is provided.
49
//
50
// Register operations do not require extending this class if none of the above
51
// services are needed. Register test sequences can be extend from the base
52
//  base class or even from outside a sequence.
53
//
54
// Note- The convenience API not yet implemented.
55
//------------------------------------------------------------------------------
56
 
57
class uvm_reg_sequence #(type BASE=uvm_sequence #(uvm_reg_item)) extends BASE;
58
 
59
  `uvm_object_param_utils(uvm_reg_sequence #(BASE))
60
 
61
  // Parameter: BASE
62
  //
63
  // Specifies the sequence type to extend from.
64
  //
65
  // When used as a translation sequence running on a bus sequencer, ~BASE~ must
66
  // be compatible with the sequence type expected by the bus sequencer.
67
  //
68
  // When used as a test sequence running on a particular sequencer, ~BASE~
69
  // must be compatible with the sequence type expected by that sequencer.
70
  //
71
  // When used as a virtual test sequence without a sequencer, ~BASE~ does
72
  // not need to be specified, i.e. the default specialization is adequate.
73
  //
74
  // To maximize opportunities for reuse, user-defined RegModel sequences should
75
  // "promote" the BASE parameter.
76
  //
77
  // | class my_reg_sequence #(type BASE=uvm_sequence #(uvm_reg_item))
78
  // |                               extends uvm_reg_sequence #(BASE);
79
  //
80
  // This way, the RegModel sequence can be extended from
81
  // user-defined base sequences.
82
 
83
 
84
  // Variable: model
85
  //
86
  // Block abstraction this sequence executes on, defined only when this
87
  // sequence is a user-defined test sequence.
88
  //
89
  uvm_reg_block model;
90
 
91
 
92
  // Variable: adapter
93
  //
94
  // Adapter to use for translating between abstract register transactions
95
  // and physical bus transactions, defined only when this sequence is a
96
  // translation sequence.
97
  //
98
  uvm_reg_adapter adapter;
99
 
100
 
101
  // Variable: reg_seqr
102
  //
103
  // Layered upstream "register" sequencer.
104
  //
105
  // Specifies the upstream sequencer between abstract register transactions
106
  // and physical bus transactions. Defined only when this sequence is a
107
  // translation sequence, and we want to "pull" from an upstream sequencer.
108
  //
109
  uvm_sequencer #(uvm_reg_item) reg_seqr;
110
 
111
 
112
  // Function: new
113
  //
114
  // Create a new instance, giving it the optional ~name~.
115
  //
116
  function new (string name="uvm_reg_sequence_inst");
117
    super.new(name);
118
  endfunction
119
 
120
 
121
  // Task: body
122
  //
123
  // Continually gets a register transaction from the configured upstream
124
  // sequencer, , and executes the corresponding bus transaction
125
  // via .
126
  //
127
  // User-defined RegModel test sequences must override body() and not call
128
  // super.body(), else a warning will be issued and the calling process
129
  // not return.
130
  //
131
  virtual task body();
132
    if (m_sequencer == null) begin
133
      `uvm_fatal("NO_SEQR", {"Sequence executing as translation sequence, ",
134
         "but is not associated with a sequencer (m_sequencer == null)"})
135
    end
136
    if (reg_seqr == null) begin
137
      `uvm_warning("REG_XLATE_NO_SEQR",
138
         {"Executing RegModel translation sequence on sequencer ",
139
       m_sequencer.get_full_name(),"' does not have an upstream sequencer defined. ",
140
       "Execution of register items available only via direct calls to 'do_reg_item'"})
141
      wait(0);
142
    end
143
    `uvm_info("REG_XLATE_SEQ_START",
144
       {"Starting RegModel translation sequence on sequencer ",
145
       m_sequencer.get_full_name(),"'"},UVM_LOW)
146
    forever begin
147
      uvm_reg_item reg_item;
148
      reg_seqr.peek(reg_item);
149
      do_reg_item(reg_item);
150
      reg_seqr.get(reg_item);
151
      #0;
152
    end
153
  endtask
154
 
155
 
156
  typedef enum { LOCAL, UPSTREAM } seq_parent_e;
157
 
158
  seq_parent_e parent_select = LOCAL;
159
 
160
  uvm_sequence_base upstream_parent;
161
 
162
 
163
  // Function: do_reg_item
164
  //
165
  // Executes the given register transaction, ~rw~, via the sequencer on
166
  // which this sequence was started (i.e. m_sequencer). Uses the configured
167
  //  to convert the register transaction into the type expected by
168
  // this sequencer.
169
  //
170
  virtual task do_reg_item(uvm_reg_item rw);
171
     string rws=rw.convert2string();
172
    if (m_sequencer == null)
173
     `uvm_fatal("REG/DO_ITEM/NULL","do_reg_item: m_sequencer is null")
174
    if (adapter == null)
175
     `uvm_fatal("REG/DO_ITEM/NULL","do_reg_item: adapter handle is null")
176
 
177
    `uvm_info("DO_RW_ACCESS",{"Doing transaction: ",rws},UVM_HIGH)
178
 
179
    if (parent_select == LOCAL) begin
180
      upstream_parent = rw.parent;
181
      rw.parent = this;
182
    end
183
 
184
    if (rw.kind == UVM_WRITE)
185
      rw.local_map.do_bus_write(rw, m_sequencer, adapter);
186
    else
187
      rw.local_map.do_bus_read(rw, m_sequencer, adapter);
188
 
189
    if (parent_select == LOCAL)
190
       rw.parent = upstream_parent;
191
  endtask
192
 
193
 
194
   //----------------------------------
195
   // Group: Convenience Write/Read API
196
   //----------------------------------
197
   //
198
   // The following methods delegate to the corresponding method in the
199
   // register or memory element. They allow a sequence ~body()~ to do
200
   // reads and writes without having to explicitly supply itself to
201
   // ~parent~ sequence argument. Thus, a register write
202
   //
203
   //| model.regA.write(status, value, .parent(this));
204
   //
205
   // can be written instead as
206
   //
207
   //| write_reg(model.regA, status, value);
208
   //
209
 
210
 
211
   // Task: write_reg
212
   //
213
   // Writes the given register ~rg~ using , supplying 'this' as
214
   // the ~parent~ argument. Thus,
215
   //
216
   //| write_reg(model.regA, status, value);
217
   //
218
   // is equivalent to
219
   //
220
   //| model.regA.write(status, value, .parent(this));
221
   //
222
   virtual task write_reg(input  uvm_reg           rg,
223
                          output uvm_status_e      status,
224
                          input  uvm_reg_data_t    value,
225
                          input  uvm_path_e        path = UVM_DEFAULT_PATH,
226
                          input  uvm_reg_map       map = null,
227
                          input  int               prior = -1,
228
                          input  uvm_object        extension = null,
229
                          input  string            fname = "",
230
                          input  int               lineno = 0);
231
      if (rg == null)
232
        `uvm_error("NO_REG","Register argument is null")
233
      else
234
        rg.write(status,value,path,map,this,prior,extension,fname,lineno);
235
   endtask
236
 
237
 
238
   // Task: read_reg
239
   //
240
   // Reads the given register ~rg~ using , supplying 'this' as
241
   // the ~parent~ argument. Thus,
242
   //
243
   //| read_reg(model.regA, status, value);
244
   //
245
   // is equivalent to
246
   //
247
   //| model.regA.read(status, value, .parent(this));
248
   //
249
   //
250
   virtual task read_reg(input  uvm_reg           rg,
251
                         output uvm_status_e      status,
252
                         output uvm_reg_data_t    value,
253
                         input  uvm_path_e        path = UVM_DEFAULT_PATH,
254
                         input  uvm_reg_map       map = null,
255
                         input  int               prior = -1,
256
                         input  uvm_object        extension = null,
257
                         input  string            fname = "",
258
                         input  int               lineno = 0);
259
      if (rg == null)
260
        `uvm_error("NO_REG","Register argument is null")
261
      else
262
        rg.read(status,value,path,map,this,prior,extension,fname,lineno);
263
   endtask
264
 
265
 
266
 
267
   // Task: poke_reg
268
   //
269
   // Pokes the given register ~rg~ using , supplying 'this' as
270
   // the ~parent~ argument. Thus,
271
   //
272
   //| poke_reg(model.regA, status, value);
273
   //
274
   // is equivalent to
275
   //
276
   //| model.regA.poke(status, value, .parent(this));
277
   //
278
   //
279
   virtual task poke_reg(input  uvm_reg           rg,
280
                         output uvm_status_e      status,
281
                         input  uvm_reg_data_t    value,
282
                         input  string            kind = "",
283
                         input  uvm_object        extension = null,
284
                         input  string            fname = "",
285
                         input  int               lineno = 0);
286
      if (rg == null)
287
        `uvm_error("NO_REG","Register argument is null")
288
      else
289
        rg.poke(status,value,kind,this,extension,fname,lineno);
290
   endtask
291
 
292
 
293
 
294
   // Task: peek_reg
295
   //
296
   // Peeks the given register ~rg~ using , supplying 'this' as
297
   // the ~parent~ argument. Thus,
298
   //
299
   //| peek_reg(model.regA, status, value);
300
   //
301
   // is equivalent to
302
   //
303
   //| model.regA.peek(status, value, .parent(this));
304
   //
305
   virtual task peek_reg(input  uvm_reg           rg,
306
                         output uvm_status_e      status,
307
                         output uvm_reg_data_t    value,
308
                         input  string            kind = "",
309
                         input  uvm_object        extension = null,
310
                         input  string            fname = "",
311
                         input  int               lineno = 0);
312
      if (rg == null)
313
        `uvm_error("NO_REG","Register argument is null")
314
      else
315
        rg.peek(status,value,kind,this,extension,fname,lineno);
316
   endtask
317
 
318
 
319
 
320
   // Task: update_reg
321
   //
322
   // Updates the given register ~rg~ using , supplying 'this' as
323
   // the ~parent~ argument. Thus,
324
   //
325
   //| update_reg(model.regA, status, value);
326
   //
327
   // is equivalent to
328
   //
329
   //| model.regA.update(status, value, .parent(this));
330
   //
331
   virtual task update_reg(input  uvm_reg           rg,
332
                           output uvm_status_e      status,
333
                           input  uvm_path_e        path = UVM_DEFAULT_PATH,
334
                           input  uvm_reg_map       map = null,
335
                           input  int               prior = -1,
336
                           input  uvm_object        extension = null,
337
                           input  string            fname = "",
338
                           input  int               lineno = 0);
339
      if (rg == null)
340
        `uvm_error("NO_REG","Register argument is null")
341
      else
342
        rg.update(status,path,map,this,prior,extension,fname,lineno);
343
   endtask
344
 
345
 
346
 
347
   // Task: mirror_reg
348
   //
349
   // Mirrors the given register ~rg~ using , supplying 'this' as
350
   // the ~parent~ argument. Thus,
351
   //
352
   //| mirror_reg(model.regA, status, UVM_CHECK);
353
   //
354
   // is equivalent to
355
   //
356
   //| model.regA.mirror(status, UVM_CHECK, .parent(this));
357
   //
358
   virtual task mirror_reg(input  uvm_reg       rg,
359
                           output uvm_status_e  status,
360
                           input  uvm_check_e   check  = UVM_NO_CHECK,
361
                           input  uvm_path_e    path = UVM_DEFAULT_PATH,
362
                           input  uvm_reg_map   map = null,
363
                           input  int           prior = -1,
364
                           input  uvm_object    extension = null,
365
                           input  string        fname = "",
366
                           input  int           lineno = 0);
367
      if (rg == null)
368
        `uvm_error("NO_REG","Register argument is null")
369
      else
370
        rg.mirror(status,check,path,map,this,prior,extension,fname,lineno);
371
   endtask
372
 
373
 
374
 
375
   // Task: write_mem
376
   //
377
   // Writes the given memory ~mem~ using , supplying 'this' as
378
   // the ~parent~ argument. Thus,
379
   //
380
   //| write_mem(model.regA, status, offset, value);
381
   //
382
   // is equivalent to
383
   //
384
   //| model.regA.write(status, offset, value, .parent(this));
385
   //
386
   virtual task write_mem(input  uvm_mem           mem,
387
                          output uvm_status_e      status,
388
                          input  uvm_reg_addr_t    offset,
389
                          input  uvm_reg_data_t    value,
390
                          input  uvm_path_e        path = UVM_DEFAULT_PATH,
391
                          input  uvm_reg_map       map = null,
392
                          input  int               prior = -1,
393
                          input  uvm_object        extension = null,
394
                          input  string            fname = "",
395
                          input  int               lineno = 0);
396
      if (mem == null)
397
        `uvm_error("NO_MEM","Memory argument is null")
398
      else
399
        mem.write(status,offset,value,path,map,this,prior,extension,fname,lineno);
400
   endtask
401
 
402
 
403
   // Task: read_mem
404
   //
405
   // Reads the given memory ~mem~ using , supplying 'this' as
406
   // the ~parent~ argument. Thus,
407
   //
408
   //| read_mem(model.regA, status, offset, value);
409
   //
410
   // is equivalent to
411
   //
412
   //| model.regA.read(status, offset, value, .parent(this));
413
   //
414
   //
415
   virtual task read_mem(input  uvm_mem           mem,
416
                         output uvm_status_e      status,
417
                         input  uvm_reg_addr_t    offset,
418
                         output uvm_reg_data_t    value,
419
                         input  uvm_path_e        path = UVM_DEFAULT_PATH,
420
                         input  uvm_reg_map       map = null,
421
                         input  int               prior = -1,
422
                         input  uvm_object        extension = null,
423
                         input  string            fname = "",
424
                         input  int               lineno = 0);
425
      if (mem == null)
426
        `uvm_error("NO_MEM","Memory argument is null")
427
      else
428
        mem.read(status,offset,value,path,map,this,prior,extension,fname,lineno);
429
   endtask
430
 
431
 
432
 
433
   // Task: poke_mem
434
   //
435
   // Pokes the given memory ~mem~ using , supplying 'this' as
436
   // the ~parent~ argument. Thus,
437
   //
438
   //| poke_mem(model.regA, status, offset, value);
439
   //
440
   // is equivalent to
441
   //
442
   //| model.regA.poke(status, offset, value, .parent(this));
443
   //
444
   //
445
   virtual task poke_mem(input  uvm_mem           mem,
446
                         output uvm_status_e      status,
447
                         input  uvm_reg_addr_t    offset,
448
                         input  uvm_reg_data_t    value,
449
                         input  string            kind = "",
450
                         input  uvm_object        extension = null,
451
                         input  string            fname = "",
452
                         input  int               lineno = 0);
453
      if (mem == null)
454
        `uvm_error("NO_MEM","Memory argument is null")
455
      else
456
        mem.poke(status,offset,value,kind,this,extension,fname,lineno);
457
   endtask
458
 
459
 
460
 
461
   // Task: peek_mem
462
   //
463
   // Peeks the given memory ~mem~ using , supplying 'this' as
464
   // the ~parent~ argument. Thus,
465
   //
466
   //| peek_mem(model.regA, status, offset, value);
467
   //
468
   // is equivalent to
469
   //
470
   //| model.regA.peek(status, offset, value, .parent(this));
471
   //
472
   virtual task peek_mem(input  uvm_mem           mem,
473
                         output uvm_status_e      status,
474
                         input  uvm_reg_addr_t    offset,
475
                         output uvm_reg_data_t    value,
476
                         input  string            kind = "",
477
                         input  uvm_object        extension = null,
478
                         input  string            fname = "",
479
                         input  int               lineno = 0);
480
      if (mem == null)
481
        `uvm_error("NO_MEM","Memory argument is null")
482
      else
483
        mem.peek(status,offset,value,kind,this,extension,fname,lineno);
484
   endtask
485
 
486
 
487
  // Function- put_response
488
  //
489
  // not user visible. Needed to populate this sequence's response
490
  // queue with any bus item type.
491
  //
492
  virtual function void put_response(uvm_sequence_item response_item);
493
    put_base_response(response_item);
494
  endfunction
495
 
496
endclass
497
 
498
 
499
//------------------------------------------------------------------------------
500
// Class: uvm_reg_frontdoor
501
//
502
// Facade class for register and memory frontdoor access.
503
//------------------------------------------------------------------------------
504
//
505
// User-defined frontdoor access sequence
506
//
507
// Base class for user-defined access to register and memory reads and writes
508
// through a physical interface.
509
//
510
// By default, different registers and memories are mapped to different
511
// addresses in the address space and are accessed via those exclusively
512
// through physical addresses.
513
//
514
// The frontdoor allows access using a non-linear and/or non-mapped mechanism.
515
// Users can extend this class to provide the physical access to these registers.
516
//
517
virtual class uvm_reg_frontdoor extends uvm_reg_sequence #(uvm_sequence #(uvm_sequence_item));
518
 
519
   // Variable: rw_info
520
   //
521
   // Holds information about the register being read or written
522
   //
523
   uvm_reg_item rw_info;
524
 
525
   // Variable: sequencer
526
   //
527
   // Sequencer executing the operation
528
   //
529
   uvm_sequencer_base sequencer;
530
 
531
   // Function: new
532
   //
533
   // Constructor, new object given optional ~name~.
534
   //
535
   function new(string name="");
536
      super.new(name);
537
   endfunction
538
 
539
   string fname;
540
   int lineno;
541
 
542
endclass: uvm_reg_frontdoor
543
 
544
 
545
 
546
 
547
 

powered by: WebSVN 2.1.0

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