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

Subversion Repositories uart2bus_testbench

[/] [uart2bus_testbench/] [trunk/] [tb/] [uvm_src/] [tlm2/] [uvm_tlm2_generic_payload.svh] - Blame information for rev 16

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 16 HanySalah
//----------------------------------------------------------------------
2
//   Copyright 2010 Mentor Graphics Corporation
3
//   Copyright 2010-2011 Synopsys, Inc.
4
//   All Rights Reserved Worldwide
5
//
6
//   Licensed under the Apache License, Version 2.0 (the
7
//   "License"); you may not use this file except in
8
//   compliance with the License.  You may obtain a copy of
9
//   the License at
10
//
11
//       http://www.apache.org/licenses/LICENSE-2.0
12
//
13
//   Unless required by applicable law or agreed to in
14
//   writing, software distributed under the License is
15
//   distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
16
//   CONDITIONS OF ANY KIND, either express or implied.  See
17
//   the License for the specific language governing
18
//   permissions and limitations under the License.
19
//----------------------------------------------------------------------
20
 
21
//----------------------------------------------------------------------
22
// Title: TLM Generic Payload & Extensions
23
//----------------------------------------------------------------------
24
// The Generic Payload transaction represents a generic
25
// bus read/write access. It is used as the default transaction in
26
// TLM2 blocking and nonblocking transport interfaces.
27
//----------------------------------------------------------------------
28
 
29
 
30
//---------------
31
// Group: Globals
32
//---------------
33
//
34
// Defines, Constants, enums.
35
 
36
 
37
// Enum: uvm_tlm_command_e
38
//
39
// Command attribute type definition
40
//
41
// UVM_TLM_READ_COMMAND      - Bus read operation
42
//
43
// UVM_TLM_WRITE_COMMAND     - Bus write operation
44
//
45
// UVM_TLM_IGNORE_COMMAND    - No bus operation.
46
 
47
typedef enum
48
{
49
    UVM_TLM_READ_COMMAND,
50
    UVM_TLM_WRITE_COMMAND,
51
    UVM_TLM_IGNORE_COMMAND
52
} uvm_tlm_command_e;
53
 
54
 
55
// Enum: uvm_tlm_response_status_e
56
//
57
// Response status attribute type definition
58
//
59
// UVM_TLM_OK_RESPONSE                - Bus operation completed successfully
60
//
61
// UVM_TLM_INCOMPLETE_RESPONSE        - Transaction was not delivered to target
62
//
63
// UVM_TLM_GENERIC_ERROR_RESPONSE     - Bus operation had an error
64
//
65
// UVM_TLM_ADDRESS_ERROR_RESPONSE     - Invalid address specified
66
//
67
// UVM_TLM_COMMAND_ERROR_RESPONSE     - Invalid command specified
68
//
69
// UVM_TLM_BURST_ERROR_RESPONSE       - Invalid burst specified
70
//
71
// UVM_TLM_BYTE_ENABLE_ERROR_RESPONSE - Invalid byte enabling specified
72
//
73
 
74
typedef enum
75
{
76
    UVM_TLM_OK_RESPONSE = 1,
77
    UVM_TLM_INCOMPLETE_RESPONSE = 0,
78
    UVM_TLM_GENERIC_ERROR_RESPONSE = -1,
79
    UVM_TLM_ADDRESS_ERROR_RESPONSE = -2,
80
    UVM_TLM_COMMAND_ERROR_RESPONSE = -3,
81
    UVM_TLM_BURST_ERROR_RESPONSE = -4,
82
    UVM_TLM_BYTE_ENABLE_ERROR_RESPONSE = -5
83
} uvm_tlm_response_status_e;
84
 
85
 
86
typedef class uvm_tlm_extension_base;
87
 
88
 
89
//-----------------------
90
// Group: Generic Payload
91
//-----------------------
92
 
93
//----------------------------------------------------------------------
94
// Class: uvm_tlm_generic_payload
95
//
96
// This class provides a transaction definition commonly used in
97
// memory-mapped bus-based systems.  It's intended to be a general
98
// purpose transaction class that lends itself to many applications. The
99
// class is derived from uvm_sequence_item which enables it to be
100
// generated in sequences and transported to drivers through sequencers.
101
//----------------------------------------------------------------------
102
 
103
class uvm_tlm_generic_payload extends uvm_sequence_item;
104
 
105
   // Variable: m_address
106
   //
107
   // Address for the bus operation.
108
   // Should be set or read using the  and 
109
   // methods. The variable should be used only when constraining.
110
   //
111
   // For a read command or a write command, the target shall
112
   // interpret the current value of the address attribute as the start
113
   // address in the system memory map of the contiguous block of data
114
   // being read or written.
115
   // The address associated with any given byte in the data array is
116
   // dependent upon the address attribute, the array index, the
117
   // streaming width attribute, the endianness and the width of the physical bus.
118
   //
119
   // If the target is unable to execute the transaction with
120
   // the given address attribute (because the address is out-of-range,
121
   // for example) it shall generate a standard error response. The
122
   // recommended response status is ~UVM_TLM_ADDRESS_ERROR_RESPONSE~.
123
   //
124
   rand bit [63:0]             m_address;
125
 
126
 
127
   // Variable: m_command
128
   //
129
   // Bus operation type.
130
   // Should be set using the ,  or  methods
131
   // and read using the ,  or  methods.
132
   // The variable should be used only when constraining.
133
   //
134
   // If the target is unable to execute a read or write command, it
135
   // shall generate a standard error response. The
136
   // recommended response status is UVM_TLM_COMMAND_ERROR_RESPONSE.
137
   //
138
   // On receipt of a generic payload transaction with the command
139
   // attribute equal to UVM_TLM_IGNORE_COMMAND, the target shall not execute
140
   // a write command or a read command not modify any data.
141
   // The target may, however, use the value of any attribute in
142
   // the generic payload, including any extensions.
143
   //
144
   // The command attribute shall be set by the initiator, and shall
145
   // not be overwritten by any interconnect
146
   //
147
   rand uvm_tlm_command_e          m_command;
148
 
149
 
150
   // Variable: m_data
151
   //
152
   // Data read or to be written.
153
   // Should be set and read using the  or  methods
154
   // The variable should be used only when constraining.
155
   //
156
   // For a read command or a write command, the target shall copy data
157
   // to or from the data array, respectively, honoring the semantics of
158
   // the remaining attributes of the generic payload.
159
   //
160
   // For a write command or UVM_TLM_IGNORE_COMMAND, the contents of the
161
   // data array shall be set by the initiator, and shall not be
162
   // overwritten by any interconnect component or target. For a read
163
   // command, the contents of the data array shall be overwritten by the
164
   // target (honoring the semantics of the byte enable) but by no other
165
   // component.
166
   //
167
   // Unlike the OSCI TLM-2.0 LRM, there is no requirement on the endiannes
168
   // of multi-byte data in the generic payload to match the host endianness.
169
   // Unlike C++, it is not possible in SystemVerilog to cast an arbitrary
170
   // data type as an array of bytes. Therefore, matching the host
171
   // endianness is not necessary. In contrast, arbitrary data types may be
172
   // converted to and from a byte array using the streaming operator and
173
   //  objects may be further converted using the
174
   //  and  methods.
175
   // All that is required is that a consistent mechanism is used to
176
   // fill the payload data array and later extract data from it.
177
   //
178
   // Should a generic payload be transferred to/from a SystemC model,
179
   // it will be necessary for any multi-byte data in that generic payload
180
   // to use/be interpreted using the host endianness.
181
   // However, this process is currently outside the scope of this standard.
182
   //
183
   rand byte unsigned             m_data[];
184
 
185
 
186
   // Variable: m_length
187
   //
188
   // The number of bytes to be copied to or from the  array,
189
   // inclusive of any bytes disabled by the  attribute.
190
   //
191
   // The data length attribute shall be set by the initiator,
192
   // and shall not be overwritten by any interconnect component or target.
193
   //
194
   // The data length attribute shall not be set to 0.
195
   // In order to transfer zero bytes, the  attribute
196
   // should be set to .
197
   //
198
   rand int unsigned           m_length;
199
 
200
 
201
   // Variable: m_response_status
202
   //
203
   // Status of the bus operation.
204
   // Should be set using the  method
205
   // and read using the , ,
206
   //  or  methods.
207
   // The variable should be used only when constraining.
208
   //
209
   // The response status attribute shall be set to
210
   // UVM_TLM_INCOMPLETE_RESPONSE by the initiator, and may
211
   // be overwritten by the target. The response status attribute
212
   // should not be overwritten by any interconnect
213
   // component, because the default value UVM_TLM_INCOMPLETE_RESPONSE
214
   // indicates that the transaction was not delivered to the target.
215
   //
216
   // The target may set the response status attribute to UVM_TLM_OK_RESPONSE
217
   // to indicate that it was able to execute the command
218
   // successfully, or to one of the five error responses
219
   // to indicate an error. The target should choose the appropriate
220
   // error response depending on the cause of the error.
221
   // If a target detects an error but is unable to select a specific
222
   // error response, it may set the response status to
223
   // UVM_TLM_GENERIC_ERROR_RESPONSE.
224
   //
225
   // The target shall be responsible for setting the response status
226
   // attribute at the appropriate point in the
227
   // lifetime of the transaction. In the case of the blocking
228
   // transport interface, this means before returning
229
   // control from b_transport. In the case of the non-blocking
230
   // transport interface and the base protocol, this
231
   // means before sending the BEGIN_RESP phase or returning a value of UVM_TLM_COMPLETED.
232
   //
233
   // It is recommended that the initiator should always check the
234
   // response status attribute on receiving a
235
   // transition to the BEGIN_RESP phase or after the completion of
236
   // the transaction. An initiator may choose
237
   // to ignore the response status if it is known in advance that the
238
   // value will be UVM_TLM_OK_RESPONSE,
239
   // perhaps because it is known in advance that the initiator is
240
   // only connected to targets that always return
241
   // UVM_TLM_OK_RESPONSE, but in general this will not be the case. In
242
   // other words, the initiator ignores the
243
   // response status at its own risk.
244
   //
245
   rand uvm_tlm_response_status_e  m_response_status;
246
 
247
 
248
   // Variable: m_dmi
249
   //
250
   // DMI mode is not yet supported in the UVM TLM2 subset.
251
   // This variable is provided for completeness and interoperability
252
   // with SystemC.
253
   //
254
   bit m_dmi;
255
 
256
 
257
   // Variable: m_byte_enable
258
   //
259
   // Indicates valid  array elements.
260
   // Should be set and read using the  or  methods
261
   // The variable should be used only when constraining.
262
   //
263
   // The elements in the byte enable array shall be interpreted as
264
   // follows. A value of 8'h00 shall indicate that that
265
   // corresponding byte is disabled, and a value of 8'hFF shall
266
   // indicate that the corresponding byte is enabled.
267
   //
268
   // Byte enables may be used to create burst transfers where the
269
   // address increment between each beat is
270
   // greater than the number of significant bytes transferred on each
271
   // beat, or to place words in selected byte
272
   // lanes of a bus. At a more abstract level, byte enables may be
273
   // used to create "lacy bursts" where the data array of the generic
274
   // payload has an arbitrary pattern of holes punched in it.
275
   //
276
   // The byte enable mask may be defined by a small pattern applied
277
   // repeatedly or by a large pattern covering the whole data array.
278
   // The byte enable array may be empty, in which case byte enables
279
   // shall not be used for the current transaction.
280
   //
281
   // The byte enable array shall be set by the initiator and shall
282
   // not be overwritten by any interconnect component or target.
283
   //
284
   // If the byte enable pointer is not empty, the target shall either
285
   // implement the semantics of the byte enable as defined below or
286
   // shall generate a standard error response. The recommended response
287
   // status is UVM_TLM_BYTE_ENABLE_ERROR_RESPONSE.
288
   //
289
   // In the case of a write command, any interconnect component or
290
   // target should ignore the values of any disabled bytes in the
291
   //  array. In the case of a read command, any interconnect
292
   // component or target should not modify the values of disabled
293
   // bytes in the  array.
294
   //
295
   rand byte unsigned          m_byte_enable[];
296
 
297
 
298
   // Variable: m_byte_enable_length
299
   //
300
   // The number of elements in the  array.
301
   //
302
   // It shall be set by the initiator, and shall not be overwritten
303
   // by any interconnect component or target.
304
   //
305
   rand int unsigned m_byte_enable_length;
306
 
307
 
308
   // Variable: m_streaming_width
309
   //
310
   // Number of bytes transferred on each beat.
311
   // Should be set and read using the  or
312
   //  methods
313
   // The variable should be used only when constraining.
314
   //
315
   // Streaming affects the way a component should interpret the data
316
   // array. A stream consists of a sequence of data transfers occurring
317
   // on successive notional beats, each beat having the same start
318
   // address as given by the generic payload address attribute. The
319
   // streaming width attribute shall determine the width of the stream,
320
   // that is, the number of bytes transferred on each beat. In other
321
   // words, streaming affects the local address associated with each
322
   // byte in the data array. In all other respects, the organization of
323
   // the data array is unaffected by streaming.
324
   //
325
   // The bytes within the data array have a corresponding sequence of
326
   // local addresses within the component accessing the generic payload
327
   // transaction. The lowest address is given by the value of the
328
   // address attribute. The highest address is given by the formula
329
   // address_attribute + streaming_width - 1. The address to or from
330
   // which each byte is being copied in the target shall be set to the
331
   // value of the address attribute at the start of each beat.
332
   //
333
   // With respect to the interpretation of the data array, a single
334
   // transaction with a streaming width shall be functionally equivalent
335
   // to a sequence of transactions each having the same address as the
336
   // original transaction, each having a data length attribute equal to
337
   // the streaming width of the original, and each with a data array
338
   // that is a different subset of the original data array on each
339
   // beat. This subset effectively steps down the original data array
340
   // maintaining the sequence of bytes.
341
   //
342
   // A streaming width of 0 indicates that a streaming transfer
343
   // is not required. it is equivalent to a streaming width
344
   // value greater than or equal to the size of the  array.
345
   //
346
   // Streaming may be used in conjunction with byte enables, in which
347
   // case the streaming width would typically be equal to the byte
348
   // enable length. It would also make sense to have the streaming width
349
   // a multiple of the byte enable length. Having the byte enable length
350
   // a multiple of the streaming width would imply that different bytes
351
   // were enabled on each beat.
352
   //
353
   // If the target is unable to execute the transaction with the
354
   // given streaming width, it shall generate a standard error
355
   // response. The recommended response status is
356
   // TLM_BURST_ERROR_RESPONSE.
357
   //
358
   rand int unsigned m_streaming_width;
359
 
360
   protected uvm_tlm_extension_base m_extensions [uvm_tlm_extension_base];
361
   local rand uvm_tlm_extension_base m_rand_exts[];
362
 
363
 
364
   `uvm_object_utils(uvm_tlm_generic_payload)
365
 
366
 
367
  // Function: new
368
  //
369
  // Create a new instance of the generic payload.  Initialize all the
370
  // members to their default values.
371
 
372
  function new(string name="");
373
    super.new(name);
374
    m_address = 0;
375
    m_command = UVM_TLM_IGNORE_COMMAND;
376
    m_length = 0;
377
    m_response_status = UVM_TLM_INCOMPLETE_RESPONSE;
378
    m_dmi = 0;
379
    m_byte_enable_length = 0;
380
    m_streaming_width = 0;
381
  endfunction
382
 
383
 
384
  // Function- do_print
385
  //
386
  function void do_print(uvm_printer printer);
387
    byte unsigned be;
388
    super.do_print(printer);
389
    printer.print_field_int     ("address", m_address, 64, UVM_HEX);
390
    printer.print_generic ("command", "uvm_tlm_command_e", 32, m_command.name());
391
    printer.print_generic ("response_status", "uvm_tlm_response_status_e",
392
                             32, m_response_status.name());
393
    printer.print_field_int     ("streaming_width", m_streaming_width, 32, UVM_HEX);
394
 
395
    printer.print_array_header("data", m_length, "darray(byte)");
396
    for (int i=0; i < m_length && i < m_data.size(); i++) begin
397
      if (m_byte_enable_length) begin
398
        be = m_byte_enable[i % m_byte_enable_length];
399
        printer.print_generic ($sformatf("[%0d]",i), "byte", 8,
400
            $sformatf("'h%h%s",m_data[i],((be=='hFF) ? "" : " x")));
401
      end
402
      else
403
        printer.print_generic ($sformatf("[%0d]",i), "byte", 8,
404
                               $sformatf("'h%h",m_data[i]));
405
    end
406
    printer.print_array_footer();
407
 
408
    begin
409
    string name;
410
    printer.print_array_header("extensions", m_extensions.num(), "aa(obj,obj)");
411
    foreach (m_extensions[ext_]) begin
412
      uvm_tlm_extension_base ext = m_extensions[ext_];
413
      name = {"[",ext.get_name(),"]"};
414
      printer.print_object(name, ext, "[");
415
    end
416
    printer.print_array_footer();
417
    end
418
  endfunction
419
 
420
 
421
  // Function- do_copy
422
  //
423
  function void do_copy(uvm_object rhs);
424
    uvm_tlm_generic_payload gp;
425
    super.do_copy(rhs);
426
    $cast(gp, rhs);
427
    m_address            = gp.m_address;
428
    m_command            = gp.m_command;
429
    m_data               = gp.m_data;
430
    m_dmi                = gp.m_dmi;
431
    m_length             = gp.m_length;
432
    m_response_status    = gp.m_response_status;
433
    m_byte_enable        = gp.m_byte_enable;
434
    m_streaming_width    = gp.m_streaming_width;
435
    m_byte_enable_length = gp.m_byte_enable_length;
436
 
437
    m_extensions.delete();
438
    foreach (gp.m_extensions[ext])
439
       $cast(m_extensions[ext], gp.m_extensions[ext].clone());
440
 
441
  endfunction
442
 
443
 
444
  // Function- do_compare
445
  //
446
  function bit do_compare(uvm_object rhs, uvm_comparer comparer);
447
    uvm_tlm_generic_payload gp;
448
    do_compare = super.do_compare(rhs, comparer);
449
    $cast(gp, rhs);
450
 
451
    do_compare = (m_address == gp.m_address &&
452
                  m_command == gp.m_command &&
453
                  m_length  == gp.m_length  &&
454
                  m_dmi     == gp.m_dmi &&
455
                  m_byte_enable_length == gp.m_byte_enable_length  &&
456
                  m_response_status    == gp.m_response_status &&
457
                  m_streaming_width    == gp.m_streaming_width );
458
 
459
    if (do_compare && m_length == gp.m_length) begin
460
        byte unsigned lhs_be, rhs_be;
461
        for (int i=0; do_compare && i < m_length && i < m_data.size(); i++) begin
462
          if (m_byte_enable_length) begin
463
            lhs_be = m_byte_enable[i % m_byte_enable_length];
464
            rhs_be = gp.m_byte_enable[i % gp.m_byte_enable_length];
465
            do_compare = ((m_data[i] & lhs_be) == (gp.m_data[i] & rhs_be));
466
          end
467
          else begin
468
            do_compare = (m_data[i] == gp.m_data[i]);
469
          end
470
        end
471
     end
472
 
473
    if (do_compare)
474
      foreach (m_extensions[ext_]) begin
475
         uvm_tlm_extension_base ext = ext_;
476
         uvm_tlm_extension_base rhs_ext = gp.m_extensions.exists(ext) ?
477
                                          gp.m_extensions[ext] : null;
478
         do_compare = comparer.compare_object(ext.get_name(),
479
                                               m_extensions[ext], rhs_ext);
480
         if (!do_compare) break;
481
      end
482
 
483
    if (do_compare)
484
      foreach (gp.m_extensions[ext_]) begin
485
        uvm_tlm_extension_base ext = ext_;
486
        if (!m_extensions.exists(ext)) begin
487
              do_compare = comparer.compare_object(ext.get_name(),
488
                            null, gp.m_extensions[ext]);
489
          if (!do_compare) break;
490
        end
491
      end
492
 
493
    if (!do_compare && comparer.show_max > 0) begin
494
      string msg = $sformatf("GP miscompare between '%s' and '%s':\nlhs = %s\nrhs = %s",
495
            get_full_name(), gp.get_full_name(), this.convert2string(), gp.convert2string());
496
      case (comparer.sev)
497
        UVM_WARNING: `uvm_warning("MISCMP", msg)
498
        UVM_ERROR:   `uvm_error("MISCMP", msg)
499
        default:     `uvm_info("MISCMP", msg, UVM_LOW)
500
      endcase
501
    end
502
 
503
  endfunction
504
 
505
 
506
  // Function- do_pack
507
  //
508
  // We only pack m_length bytes of the m_data array, even if m_data is larger
509
  // than m_length. Same treatment for the byte-enable array. We do not pack
510
  // the extensions, if any, as we will be unable to unpack them.
511
  function void do_pack(uvm_packer packer);
512
    super.do_pack(packer);
513
    if (m_length > m_data.size())
514
       `uvm_fatal("PACK_DATA_ARR",
515
         $sformatf("Data array m_length property (%0d) greater than m_data.size (%0d)",
516
         m_length,m_data.size()))
517
    if (m_byte_enable_length > m_byte_enable.size())
518
       `uvm_fatal("PACK_DATA_ARR",
519
         $sformatf("Data array m_byte_enable_length property (%0d) greater than m_byte_enable.size (%0d)",
520
         m_byte_enable_length,m_byte_enable.size()))
521
    `uvm_pack_intN  (m_address,64)
522
    `uvm_pack_enumN (m_command,32)
523
    `uvm_pack_intN  (m_length,32)
524
    for (int i=0; i
525
      `uvm_pack_intN(m_data[i],8)
526
    `uvm_pack_enumN (m_response_status,32)
527
    `uvm_pack_intN  (m_byte_enable_length,32)
528
    for (int i=0; i
529
      `uvm_pack_intN(m_byte_enable[i],8)
530
    `uvm_pack_intN  (m_streaming_width,32)
531
 
532
  endfunction
533
 
534
 
535
  // Function- do_unpack
536
  //
537
  // We only reallocate m_data/m_byte_enable if the new size
538
  // is greater than their current size. We do not unpack extensions
539
  // because we do not know what object types to allocate before we
540
  // unpack into them. Extensions must be handled by user code.
541
  function void do_unpack(uvm_packer packer);
542
    super.do_unpack(packer);
543
    `uvm_unpack_intN  (m_address,64)
544
    `uvm_unpack_enumN (m_command, 32, uvm_tlm_command_e)
545
    `uvm_unpack_intN  (m_length,32)
546
    if (m_data.size() < m_length)
547
      m_data = new[m_length];
548
    foreach (m_data[i])
549
      `uvm_unpack_intN(m_data[i],8)
550
    `uvm_unpack_enumN (m_response_status, 32, uvm_tlm_response_status_e)
551
    `uvm_unpack_intN  (m_byte_enable_length,32)
552
    if (m_byte_enable.size() < m_byte_enable_length)
553
      m_byte_enable = new[m_byte_enable_length];
554
    for (int i=0; i
555
      `uvm_unpack_intN(m_byte_enable[i],8)
556
    `uvm_unpack_intN  (m_streaming_width,32)
557
 
558
  endfunction
559
 
560
 
561
  // Function- do_record
562
  //
563
  function void do_record(uvm_recorder recorder);
564
    if (!is_recording_enabled())
565
      return;
566
    super.do_record(recorder);
567
    `uvm_record_int("address",m_address,$bits(m_address))
568
    `uvm_record_string("command",m_command.name())
569
    `uvm_record_int("data_length",m_length,$bits(m_length))
570
    `uvm_record_int("byte_enable_length",m_byte_enable_length,$bits(m_byte_enable_length))
571
    `uvm_record_string("response_status",m_response_status.name())
572
    `uvm_record_int("streaming_width",m_streaming_width,$bits(m_streaming_width))
573
 
574
    for (int i=0; i < m_length; i++)
575
      `uvm_record_int($sformatf("\\data[%0d] ", i), m_data[i], $bits(m_data[i]))
576
 
577
    for (int i=0; i < m_byte_enable_length; i++)
578
      `uvm_record_int($sformatf("\\byte_en[%0d] ", i), m_byte_enable[i], $bits(m_byte_enable[i]))
579
 
580
    foreach (m_extensions[ext])
581
      recorder.record_object(ext.get_name(),m_extensions[ext]);
582
  endfunction
583
 
584
 
585
  // Function- convert2string
586
  //
587
  function string convert2string();
588
 
589
    string msg;
590
    string s;
591
 
592
    $sformat(msg, "%s %s [0x%16x] =", super.convert2string(),
593
             m_command.name(), m_address);
594
 
595
    for(int unsigned i = 0; i < m_length; i++) begin
596
      if (!m_byte_enable_length || (m_byte_enable[i % m_byte_enable_length] == 'hFF))
597
        $sformat(s, " %02x", m_data[i]);
598
      else
599
        $sformat(s, " --");
600
      msg = { msg , s };
601
    end
602
 
603
    msg = { msg, " (status=", get_response_string(), ")" };
604
 
605
    return msg;
606
 
607
  endfunction
608
 
609
 
610
  //--------------------------------------------------------------------
611
  // Group: Accessors
612
  //
613
  // The accessor functions let you set and get each of the members of the
614
  // generic payload. All of the accessor methods are virtual. This implies
615
  // a slightly different use model for the generic payload than
616
  // in SystemC. The way the generic payload is defined in SystemC does
617
  // not encourage you to create new transaction types derived from
618
  // uvm_tlm_generic_payload. Instead, you would use the extensions mechanism.
619
  // Thus in SystemC none of the accessors are virtual.
620
  //--------------------------------------------------------------------
621
 
622
   // Function: get_command
623
   //
624
   // Get the value of the  variable
625
 
626
  virtual function uvm_tlm_command_e get_command();
627
    return m_command;
628
  endfunction
629
 
630
   // Function: set_command
631
   //
632
   // Set the value of the  variable
633
 
634
  virtual function void set_command(uvm_tlm_command_e command);
635
    m_command = command;
636
  endfunction
637
 
638
   // Function: is_read
639
   //
640
   // Returns true if the current value of the  variable
641
   // is ~UVM_TLM_READ_COMMAND~.
642
 
643
  virtual function bit is_read();
644
    return (m_command == UVM_TLM_READ_COMMAND);
645
  endfunction
646
 
647
   // Function: set_read
648
   //
649
   // Set the current value of the  variable
650
   // to ~UVM_TLM_READ_COMMAND~.
651
 
652
  virtual function void set_read();
653
    set_command(UVM_TLM_READ_COMMAND);
654
  endfunction
655
 
656
   // Function: is_write
657
   //
658
   // Returns true if the current value of the  variable
659
   // is ~UVM_TLM_WRITE_COMMAND~.
660
 
661
  virtual function bit is_write();
662
    return (m_command == UVM_TLM_WRITE_COMMAND);
663
  endfunction
664
 
665
   // Function: set_write
666
   //
667
   // Set the current value of the  variable
668
   // to ~UVM_TLM_WRITE_COMMAND~.
669
 
670
  virtual function void set_write();
671
    set_command(UVM_TLM_WRITE_COMMAND);
672
  endfunction
673
 
674
   // Function: set_address
675
   //
676
   // Set the value of the  variable
677
  virtual function void set_address(bit [63:0] addr);
678
    m_address = addr;
679
  endfunction
680
 
681
   // Function: get_address
682
   //
683
   // Get the value of the  variable
684
 
685
  virtual function bit [63:0] get_address();
686
    return m_address;
687
  endfunction
688
 
689
   // Function: get_data
690
   //
691
   // Return the value of the  array
692
 
693
  virtual function void get_data (output byte unsigned p []);
694
    p = m_data;
695
  endfunction
696
 
697
   // Function: set_data
698
   //
699
   // Set the value of the  array
700
 
701
  virtual function void set_data(ref byte unsigned p []);
702
    m_data = p;
703
  endfunction
704
 
705
   // Function: get_data_length
706
   //
707
   // Return the current size of the  array
708
 
709
  virtual function int unsigned get_data_length();
710
    return m_length;
711
  endfunction
712
 
713
  // Function: set_data_length
714
  // Set the value of the 
715
 
716
   virtual function void set_data_length(int unsigned length);
717
    m_length = length;
718
  endfunction
719
 
720
   // Function: get_streaming_width
721
   //
722
   // Get the value of the  array
723
 
724
  virtual function int unsigned get_streaming_width();
725
    return m_streaming_width;
726
  endfunction
727
 
728
 
729
   // Function: set_streaming_width
730
   //
731
   // Set the value of the  array
732
 
733
  virtual function void set_streaming_width(int unsigned width);
734
    m_streaming_width = width;
735
  endfunction
736
 
737
   // Function: get_byte_enable
738
   //
739
   // Return the value of the  array
740
  virtual function void get_byte_enable(output byte unsigned p[]);
741
    p = m_byte_enable;
742
  endfunction
743
 
744
   // Function: set_byte_enable
745
   //
746
   // Set the value of the  array
747
 
748
  virtual function void set_byte_enable(ref byte unsigned p[]);
749
    m_byte_enable = p;
750
  endfunction
751
 
752
   // Function: get_byte_enable_length
753
   //
754
   // Return the current size of the  array
755
 
756
  virtual function int unsigned get_byte_enable_length();
757
    return m_byte_enable_length;
758
  endfunction
759
 
760
   // Function: set_byte_enable_length
761
   //
762
   // Set the size  of the  array
763
   // i.e.  .size()
764
 
765
 virtual function void set_byte_enable_length(int unsigned length);
766
    m_byte_enable_length = length;
767
  endfunction
768
 
769
   // Function: set_dmi_allowed
770
   //
771
   // DMI hint. Set the internal flag  to allow dmi access
772
 
773
  virtual function void set_dmi_allowed(bit dmi);
774
    m_dmi = dmi;
775
  endfunction
776
 
777
   // Function: is_dmi_allowed
778
   //
779
   // DMI hint. Query the internal flag  if allowed dmi access
780
 
781
 virtual function bit is_dmi_allowed();
782
    return m_dmi;
783
  endfunction
784
 
785
   // Function: get_response_status
786
   //
787
   // Return the current value of the  variable
788
 
789
  virtual function uvm_tlm_response_status_e get_response_status();
790
    return m_response_status;
791
  endfunction
792
 
793
   // Function: set_response_status
794
   //
795
   // Set the current value of the  variable
796
 
797
  virtual function void set_response_status(uvm_tlm_response_status_e status);
798
    m_response_status = status;
799
  endfunction
800
 
801
   // Function: is_response_ok
802
   //
803
   // Return TRUE if the current value of the  variable
804
   // is ~UVM_TLM_OK_RESPONSE~
805
 
806
  virtual function bit is_response_ok();
807
    return (int'(m_response_status) > 0);
808
  endfunction
809
 
810
   // Function: is_response_error
811
   //
812
   // Return TRUE if the current value of the  variable
813
   // is not ~UVM_TLM_OK_RESPONSE~
814
 
815
  virtual function bit is_response_error();
816
    return !is_response_ok();
817
  endfunction
818
 
819
   // Function: get_response_string
820
   //
821
   // Return the current value of the  variable
822
   // as a string
823
 
824
  virtual function string get_response_string();
825
 
826
    case(m_response_status)
827
      UVM_TLM_OK_RESPONSE                : return "OK";
828
      UVM_TLM_INCOMPLETE_RESPONSE        : return "INCOMPLETE";
829
      UVM_TLM_GENERIC_ERROR_RESPONSE     : return "GENERIC_ERROR";
830
      UVM_TLM_ADDRESS_ERROR_RESPONSE     : return "ADDRESS_ERROR";
831
      UVM_TLM_COMMAND_ERROR_RESPONSE     : return "COMMAND_ERROR";
832
      UVM_TLM_BURST_ERROR_RESPONSE       : return "BURST_ERROR";
833
      UVM_TLM_BYTE_ENABLE_ERROR_RESPONSE : return "BYTE_ENABLE_ERROR";
834
    endcase
835
 
836
    // we should never get here
837
    return "UNKNOWN_RESPONSE";
838
 
839
  endfunction
840
 
841
  //--------------------------------------------------------------------
842
  // Group: Extensions Mechanism
843
  //
844
  //--------------------------------------------------------------------
845
 
846
  // Function: set_extension
847
  //
848
  // Add an instance-specific extension. Only one instance of any given
849
  // extension type is allowed. If there is an existing extension
850
  // instance of the type of ~ext~, ~ext~ replaces it and its handle
851
  // is returned. Otherwise, ~null~ is returned.
852
 
853
  function uvm_tlm_extension_base set_extension(uvm_tlm_extension_base ext);
854
    uvm_tlm_extension_base ext_handle = ext.get_type_handle();
855
    if(!m_extensions.exists(ext_handle))
856
      set_extension = null;
857
    else
858
      set_extension = m_extensions[ext_handle];
859
    m_extensions[ext_handle] = ext;
860
  endfunction
861
 
862
 
863
  // Function: get_num_extensions
864
  //
865
  // Return the current number of instance specific extensions.
866
 
867
  function int get_num_extensions();
868
    return m_extensions.num();
869
  endfunction: get_num_extensions
870
 
871
 
872
  // Function: get_extension
873
  //
874
  // Return the instance specific extension bound under the specified key.
875
  // If no extension is bound under that key, ~null~ is returned.
876
 
877
  function uvm_tlm_extension_base get_extension(uvm_tlm_extension_base ext_handle);
878
    if(!m_extensions.exists(ext_handle))
879
      return null;
880
    return m_extensions[ext_handle];
881
  endfunction
882
 
883
 
884
  // Function: clear_extension
885
  //
886
  // Remove the instance-specific extension bound under the specified key.
887
 
888
  function void clear_extension(uvm_tlm_extension_base ext_handle);
889
    if(m_extensions.exists(ext_handle))
890
      m_extensions.delete(ext_handle);
891
    else
892
      `uvm_info("GP_EXT", $sformatf("Unable to find extension to clear"), UVM_MEDIUM);
893
  endfunction
894
 
895
 
896
  // Function: clear_extensions
897
  //
898
  // Remove all instance-specific extensions
899
 
900
  function void clear_extensions();
901
    m_extensions.delete();
902
  endfunction
903
 
904
 
905
  // Function: pre_randomize()
906
  // Prepare this class instance for randomization
907
  //
908
  function void pre_randomize();
909
    int i;
910
    m_rand_exts = new [m_extensions.num()];
911
    foreach (m_extensions[ext_]) begin
912
      uvm_tlm_extension_base ext = ext_;
913
      m_rand_exts[i++] = m_extensions[ext];
914
    end
915
  endfunction
916
 
917
  // Function: post_randomize()
918
  // Clean-up this class instance after randomization
919
  //
920
  function void post_randomize();
921
     m_rand_exts.delete();
922
  endfunction
923
endclass
924
 
925
//----------------------------------------------------------------------
926
// Class: uvm_tlm_gp
927
//
928
// This typedef provides a short, more convenient name for the
929
//  type.
930
//----------------------------------------------------------------------
931
 
932
typedef uvm_tlm_generic_payload uvm_tlm_gp;
933
 
934
 
935
//----------------------------------------------------------------------
936
// Class: uvm_tlm_extension_base
937
//
938
// The class uvm_tlm_extension_base is the non-parameterized base class for
939
// all generic payload extensions.  It includes the utility do_copy()
940
// and create().  The pure virtual function get_type_handle() allows you
941
// to get a unique handle that represents the derived type.  This is
942
// implemented in derived classes.
943
//
944
// This class is never used directly by users.
945
// The  class is used instead.
946
//
947
virtual class uvm_tlm_extension_base extends uvm_object;
948
 
949
  // Function: new
950
  //
951
  function new(string name = "");
952
    super.new(name);
953
  endfunction
954
 
955
  // Function: get_type_handle
956
  //
957
  // An interface to polymorphically retrieve a handle that uniquely
958
  // identifies the type of the sub-class
959
 
960
  pure virtual function uvm_tlm_extension_base get_type_handle();
961
 
962
  // Function: get_type_handle_name
963
  //
964
  // An interface to polymorphically retrieve the name that uniquely
965
  // identifies the type of the sub-class
966
 
967
  pure virtual function string get_type_handle_name();
968
 
969
  virtual function void do_copy(uvm_object rhs);
970
    super.do_copy(rhs);
971
  endfunction
972
 
973
  // Function: create
974
  //
975
 
976
  virtual function uvm_object create (string name="");
977
    return null;
978
  endfunction
979
 
980
endclass
981
 
982
 
983
//----------------------------------------------------------------------
984
// Class: uvm_tlm_extension
985
//
986
// TLM extension class. The class is parameterized with arbitrary type
987
// which represents the type of the extension. An instance of the
988
// generic payload can contain one extension object of each type; it
989
// cannot contain two instances of the same extension type.
990
//
991
// The extension type can be identified using the 
992
// method.
993
//
994
// To implement a generic payload extension, simply derive a new class
995
// from this class and specify the name of the derived class as the
996
// extension parameter.
997
//
998
//|
999
//| class my_ID extends uvm_tlm_extension#(my_ID);
1000
//|   int ID;
1001
//|
1002
//|   `uvm_object_utils_begin(my_ID)
1003
//|      `uvm_field_int(ID, UVM_ALL_ON)
1004
//|   `uvm_object_utils_end
1005
//|
1006
//|   function new(string name = "my_ID");
1007
//|      super.new(name);
1008
//|   endfunction
1009
//| endclass
1010
//|
1011
 
1012
class uvm_tlm_extension #(type T=int) extends uvm_tlm_extension_base;
1013
 
1014
   typedef uvm_tlm_extension#(T) this_type;
1015
 
1016
   local static this_type m_my_tlm_ext_type = ID();
1017
 
1018
   // Function: new
1019
   //
1020
   // creates a new extension object.
1021
 
1022
   function new(string name="");
1023
     super.new(name);
1024
   endfunction
1025
 
1026
   // Function: ID()
1027
   //
1028
   // Return the unique ID of this TLM extension type.
1029
   // This method is used to identify the type of the extension to retrieve
1030
   // from a  instance,
1031
   // using the  method.
1032
   //
1033
  static function this_type ID();
1034
    if (m_my_tlm_ext_type == null)
1035
      m_my_tlm_ext_type = new();
1036
    return m_my_tlm_ext_type;
1037
  endfunction
1038
 
1039
  virtual function uvm_tlm_extension_base get_type_handle();
1040
     return ID();
1041
  endfunction
1042
 
1043
  virtual function string get_type_handle_name();
1044
    return `uvm_typename(T);
1045
  endfunction
1046
 
1047
  virtual function uvm_object create (string name="");
1048
    return null;
1049
  endfunction
1050
 
1051
endclass
1052
 

powered by: WebSVN 2.1.0

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