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 |
|
|
|