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

Subversion Repositories uart2bus_testbench

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 16 HanySalah
//----------------------------------------------------------------------
2
//   Copyright 2010-2011 Synopsys, Inc.
3
//   Copyright 2011 Mentor Graphics Corporation
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
// CLASS: uvm_tlm_time
22
// Canonical time type that can be used in different timescales
23
//
24
// This time type is used to represent time values in a canonical
25
// form that can bridge initiators and targets located in different
26
// timescales and time precisions.
27
//
28
// For a detailed explanation of the purpose for this class,
29
// see .
30
//
31
class uvm_tlm_time;
32
 
33
   static local real m_resolution = 1.0e-12; // ps by default
34
   local real m_res;
35
   local time m_time;  // Number of 'm_res' time units,
36
   local string m_name;
37
 
38
   // Function: set_time_resolution
39
   // Set the default canonical time resolution.
40
   //
41
   // Must be a power of 10.
42
   // When co-simulating with SystemC, it is recommended
43
   // that default canonical time resolution be set to the
44
   // SystemC time resolution.
45
   //
46
   // By default, the default resolution is 1.0e-12 (ps)
47
   //
48
   static function void set_time_resolution(real res);
49
      // Actually, it does not *really* need to be a power of 10.
50
      m_resolution = res;
51
   endfunction
52
 
53
   // Function: new
54
   // Create a new canonical time value.
55
   //
56
   // The new value is initialized to 0.
57
   // If a resolution is not specified,
58
   // the default resolution,
59
   // as specified by ,
60
   // is used.
61
   function new(string name = "uvm_tlm_time", real res = 0);
62
      m_name = name;
63
      m_res = (res == 0) ? m_resolution : res;
64
      reset();
65
   endfunction
66
 
67
 
68
   // Function: get_name
69
   // Return the name of this instance
70
   //
71
   function string get_name();
72
      return m_name;
73
   endfunction
74
 
75
 
76
   // Function: reset
77
   // Reset the value to 0
78
   function void reset();
79
      m_time = 0;
80
   endfunction
81
 
82
 
83
   // Scale a timescaled value to 'm_res' units,
84
   // the specified scale
85
   local function real to_m_res(real t, time scaled, real secs);
86
      // ToDo: Check resolution
87
      return t/real'(scaled) * (secs/m_res);
88
   endfunction
89
 
90
 
91
   // Function: get_realtime
92
   // Return the current canonical time value,
93
   // scaled for the caller's timescale
94
   //
95
   // ~scaled~ must be a time literal value that corresponds
96
   // to the number of seconds specified in ~secs~ (1ns by default).
97
   // It must be a time literal value that is greater or equal
98
   // to the current timescale.
99
   //
100
   //| #(delay.get_realtime(1ns));
101
   //| #(delay.get_realtime(1fs, 1.0e-15));
102
   //
103
   function real get_realtime(time scaled, real secs = 1.0e-9);
104
      return m_time*real'(scaled) * m_res/secs;
105
   endfunction
106
 
107
 
108
   // Function: incr
109
   // Increment the time value by the specified number of scaled time unit
110
   //
111
   // ~t~ is a time value expressed in the scale and precision
112
   // of the caller.
113
   // ~scaled~ must be a time literal value that corresponds
114
   // to the number of seconds specified in ~secs~ (1ns by default).
115
   // It must be a time literal value that is greater or equal
116
   // to the current timescale.
117
   //
118
   //| delay.incr(1.5ns, 1ns);
119
   //| delay.incr(1.5ns, 1ps, 1.0e-12);
120
   //
121
   function void incr(real t, time scaled, real secs = 1.0e-9);
122
      if (t < 0.0) begin
123
         `uvm_error("UVM/TLM/TIMENEG", {"Cannot increment uvm_tlm_time variable ", m_name, " by a negative value"});
124
         return;
125
      end
126
      if (scaled == 0) begin
127
         `uvm_fatal("UVM/TLM/BADSCALE",
128
                    "uvm_tlm_time::incr() called with a scaled time literal that is smaller than the current timescale")
129
      end
130
 
131
      m_time += to_m_res(t, scaled, secs);
132
   endfunction
133
 
134
 
135
   // Function: decr
136
   // Decrement the time value by the specified number of scaled time unit
137
   //
138
   // ~t~ is a time value expressed in the scale and precision
139
   // of the caller.
140
   // ~scaled~ must be a time literal value that corresponds
141
   // to the number of seconds specified in ~secs~ (1ns by default).
142
   // It must be a time literal value that is greater or equal
143
   // to the current timescale.
144
   //
145
   //| delay.decr(200ps, 1ns);
146
   //
147
   function void decr(real t, time scaled, real secs);
148
      if (t < 0.0) begin
149
         `uvm_error("UVM/TLM/TIMENEG", {"Cannot decrement uvm_tlm_time variable ", m_name, " by a negative value"});
150
         return;
151
      end
152
      if (scaled == 0) begin
153
         `uvm_fatal("UVM/TLM/BADSCALE",
154
                    "uvm_tlm_time::decr() called with a scaled time literal that is smaller than the current timescale")
155
      end
156
 
157
      m_time -= to_m_res(t, scaled, secs);
158
 
159
      if (m_time < 0.0) begin
160
         `uvm_error("UVM/TLM/TOODECR", {"Cannot decrement uvm_tlm_time variable ", m_name, " to a negative value"});
161
         reset();
162
      end
163
   endfunction
164
 
165
 
166
   // Function: get_abstime
167
   // Return the current canonical time value,
168
   // in the number of specified time unit, regardless of the
169
   // current timescale of the caller.
170
   //
171
   // ~secs~ is the number of seconds in the desired time unit
172
   // e.g. 1e-9 for nanoseconds.
173
   //
174
   //| $write("%.3f ps\n", delay.get_abstime(1e-12));
175
   //
176
   function real get_abstime(real secs);
177
      return m_time*m_res/secs;
178
   endfunction
179
 
180
 
181
   // Function: set_abstime
182
   // Set the current canonical time value,
183
   // to the number of specified time unit, regardless of the
184
   // current timescale of the caller.
185
   //
186
   // ~secs~ is the number of seconds in the time unit in the value ~t~
187
   // e.g. 1e-9 for nanoseconds.
188
   //
189
   //| delay.set_abstime(1.5, 1e-12));
190
   //
191
   function void set_abstime(real t, real secs);
192
      m_time = t*secs/m_res;
193
   endfunction
194
endclass
195
 
196
 
197
// Group: Why is this necessary
198
//
199
// Integers are not sufficient, on their own,
200
// to represent time without any ambiguity:
201
// you need to know the scale of that integer value.
202
// That scale is information conveyed outside of that integer.
203
// In SystemVerilog, it is based on the timescale
204
// that was active when the code was compiled.
205
// SystemVerilog properly scales time literals, but not integer values.
206
// That's because it does not know the difference between an integer
207
// that carries an integer value and an integer that carries a time value.
208
// The 'time' variables are simply 64-bit integers,
209
// they are not scaled back and forth to the underlying precision.
210
//
211
//| `timescale 1ns/1ps
212
//|
213
//| module m();
214
//|
215
//| time t;
216
//|
217
//| initial
218
//| begin
219
//|    #1.5;
220
//|    $write("T=%f ns (1.5)\n", $realtime());
221
//|    t = 1.5;
222
//|    #t;
223
//|    $write("T=%f ns (3.0)\n", $realtime());
224
//|    #10ps;
225
//|    $write("T=%f ns (3.010)\n", $realtime());
226
//|    t = 10ps;
227
//|    #t;
228
//|    $write("T=%f ns (3.020)\n", $realtime());
229
//| end
230
//| endmodule
231
//
232
// yields
233
//
234
//| T=1.500000 ns (1.5)
235
//| T=3.500000 ns (3.0)
236
//| T=3.510000 ns (3.010)
237
//| T=3.510000 ns (3.020)
238
//
239
// Within SystemVerilog, we have to worry about
240
// - different time scale
241
// - different time precision
242
//
243
// Because each endpoint in a socket
244
// could be coded in different packages
245
// and thus be executing under different timescale directives,
246
// a simple integer cannot be used to exchange time information
247
// across a socket.
248
//
249
// For example
250
//
251
//| `timescale 1ns/1ps
252
//|
253
//| package a_pkg;
254
//|
255
//| class a;
256
//|    function void f(inout time t);
257
//|       t += 10ns;
258
//|    endfunction
259
//| endclass
260
//|
261
//| endpackage
262
//|
263
//|
264
//| `timescale 1ps/1ps
265
//|
266
//| program p;
267
//|
268
//| import a_pkg::*;
269
//|
270
//| time t;
271
//|
272
//| initial
273
//| begin
274
//|    a A = new;
275
//|    A.f(t);
276
//|    #t;
277
//|    $write("T=%0d ps (10,000)\n", $realtime());
278
//| end
279
//| endprogram
280
//
281
// yields
282
//
283
//| T=10 ps (10,000)
284
//
285
// Scaling is needed every time you make a procedural call
286
// to code that may interpret a time value in a different timescale.
287
//
288
// Using the uvm_tlm_time type
289
//
290
//| `timescale 1ns/1ps
291
//|
292
//|    package a_pkg;
293
//|
294
//| import uvm_pkg::*;
295
//|
296
//| class a;
297
//|    function void f(uvm_tlm_time t);
298
//|       t.incr(10ns, 1ns);
299
//|    endfunction
300
//| endclass
301
//|
302
//| endpackage
303
//|
304
//|
305
//| `timescale 1ps/1ps
306
//|
307
//| program p;
308
//|
309
//| import uvm_pkg::*;
310
//| import a_pkg::*;
311
//|
312
//| uvm_tlm_time t = new;
313
//|
314
//| initial
315
//|    begin
316
//|       a A = new;
317
//|       A.f(t);
318
//|       #(t.get_realtime(1ns));
319
//|       $write("T=%0d ps (10,000)\n", $realtime());
320
//| end
321
//| endprogram
322
//
323
// yields
324
//
325
//| T=10000 ps (10,000)
326
//
327
// A similar procedure is required when crossing any simulator
328
// or language boundary,
329
// such as interfacing between SystemVerilog and SystemC.
330
 
331
 
332
 

powered by: WebSVN 2.1.0

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