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

Subversion Repositories uart2bus_testbench

[/] [uart2bus_testbench/] [trunk/] [tb/] [uvm_src/] [dpi/] [uvm_hdl_questa.c] - Blame information for rev 16

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 16 HanySalah
//----------------------------------------------------------------------
2
//   Copyright 2007-2011 Cadence Design Systems, Inc.
3
//   Copyright 2009-2010 Mentor Graphics Corporation
4
//   Copyright 2010-2011 Synopsys, Inc.
5
//   All Rights Reserved Worldwide
6
//
7
//   Licensed under the Apache License, Version 2.0 (the
8
//   "License"); you may not use this file except in
9
//   compliance with the License.  You may obtain a copy of
10
//   the License at
11
//
12
//       http://www.apache.org/licenses/LICENSE-2.0
13
//
14
//   Unless required by applicable law or agreed to in
15
//   writing, software distributed under the License is
16
//   distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
17
//   CONDITIONS OF ANY KIND, either express or implied.  See
18
//   the License for the specific language governing
19
//   permissions and limitations under the License.
20
//----------------------------------------------------------------------
21
 
22
#include "uvm_dpi.h"
23
 
24
 
25
/*
26
 * UVM HDL access C code.
27
 *
28
 */
29
 
30
/*
31
 * This C code checks to see if there is PLI handle
32
 * with a value set to define the maximum bit width.
33
 *
34
 * If no such variable is found, then the default
35
 * width of 1024 is used.
36
 *
37
 * This function should only get called once or twice,
38
 * its return value is cached in the caller.
39
 *
40
 */
41
static int uvm_hdl_max_width()
42
{
43
  vpiHandle ms;
44
  s_vpi_value value_s = { vpiIntVal, { 0 } };
45
  ms = vpi_handle_by_name((PLI_BYTE8*) "uvm_pkg::UVM_HDL_MAX_WIDTH", 0);
46
  if(ms == 0)
47
    return 1024;  /* If nothing else is defined,
48
                     this is the DEFAULT */
49
  vpi_get_value(ms, &value_s);
50
  return value_s.value.integer;
51
}
52
 
53
 
54
#ifdef QUESTA
55
static int uvm_hdl_set_vlog(char *path, p_vpi_vecval value, PLI_INT32 flag);
56
static int uvm_hdl_get_vlog(char *path, p_vpi_vecval value, PLI_INT32 flag);
57
static int partsel = 0;
58
 
59
/*
60
 * Given a path with part-select, break into individual bit accesses
61
 * path = pointer to user string
62
 * value = pointer to logic vector
63
 * flag = deposit vs force/release options, etc
64
 */
65
static int uvm_hdl_set_vlog_partsel(char *path, p_vpi_vecval value, PLI_INT32 flag)
66
{
67
  char *path_ptr = path;
68
  int path_len, idx;
69
  svLogicVecVal bit_value;
70
 
71
  path_len = strlen(path);
72
  path_ptr = (char*)(path+path_len-1);
73
 
74
  if (*path_ptr != ']')
75
    return 0;
76
 
77
  while(path_ptr != path && *path_ptr != ':' && *path_ptr != '[')
78
    path_ptr--;
79
 
80
  if (path_ptr == path || *path_ptr != ':')
81
    return 0;
82
 
83
  while(path_ptr != path && *path_ptr != '[')
84
    path_ptr--;
85
 
86
  if (path_ptr == path || *path_ptr != '[')
87
    return 0;
88
 
89
  int lhs, rhs, width, incr;
90
 
91
  // extract range from path
92
  if (sscanf(path_ptr,"[%u:%u]",&lhs, &rhs)) {
93
    char index_str[20];
94
    int i;
95
    path_ptr++;
96
    path_len = (path_len - (path_ptr - path));
97
    incr = (lhs>rhs) ? 1 : -1;
98
    width = (lhs>rhs) ? lhs-rhs+1 : rhs-lhs+1;
99
 
100
    // perform set for each individual bit
101
    for (i=0; i < width; i++) {
102
      sprintf(index_str,"%u]",rhs);
103
      strncpy(path_ptr,index_str,path_len);
104
      svGetPartselLogic(&bit_value,value,i,1);
105
      rhs += incr;
106
      if (!uvm_hdl_set_vlog(path,&bit_value,flag))
107
        return 0;
108
    }
109
    return 1;
110
  }
111
}
112
 
113
 
114
/*
115
 * Given a path with part-select, break into individual bit accesses
116
 * path = pointer to user string
117
 * value = pointer to logic vector
118
 * flag = deposit vs force/release options, etc
119
 */
120
static int uvm_hdl_get_vlog_partsel(char *path, p_vpi_vecval value, PLI_INT32 flag)
121
{
122
  char *path_ptr = path;
123
  int path_len, idx;
124
  svLogicVecVal bit_value;
125
 
126
  path_len = strlen(path);
127
  path_ptr = (char*)(path+path_len-1);
128
 
129
  if (*path_ptr != ']')
130
    return 0;
131
 
132
  while(path_ptr != path && *path_ptr != ':' && *path_ptr != '[')
133
    path_ptr--;
134
 
135
  if (path_ptr == path || *path_ptr != ':')
136
    return 0;
137
 
138
  while(path_ptr != path && *path_ptr != '[')
139
    path_ptr--;
140
 
141
  if (path_ptr == path || *path_ptr != '[')
142
    return 0;
143
 
144
  int lhs, rhs, width, incr;
145
 
146
  // extract range from path
147
  if (sscanf(path_ptr,"[%u:%u]",&lhs, &rhs)) {
148
    char index_str[20];
149
    int i;
150
    path_ptr++;
151
    path_len = (path_len - (path_ptr - path));
152
    incr = (lhs>rhs) ? 1 : -1;
153
    width = (lhs>rhs) ? lhs-rhs+1 : rhs-lhs+1;
154
    bit_value.aval = 0;
155
    bit_value.bval = 0;
156
    partsel = 1;
157
    for (i=0; i < width; i++) {
158
      int result;
159
      svLogic logic_bit;
160
      sprintf(index_str,"%u]",rhs);
161
      strncpy(path_ptr,index_str,path_len);
162
      result = uvm_hdl_get_vlog(path,&bit_value,flag);
163
      logic_bit = svGetBitselLogic(&bit_value,0);
164
      svPutPartselLogic(value,bit_value,i,1);
165
      rhs += incr;
166
      if (!result)
167
        return 0;
168
    }
169
    partsel = 0;
170
    return 1;
171
  }
172
}
173
#endif
174
 
175
 
176
/*
177
 * Given a path, look the path name up using the PLI,
178
 * and set it to 'value'.
179
 */
180
static int uvm_hdl_set_vlog(char *path, p_vpi_vecval value, PLI_INT32 flag)
181
{
182
  static int maxsize = -1;
183
  vpiHandle r;
184
  s_vpi_value value_s = { vpiIntVal, { 0 } };
185
  s_vpi_time  time_s = { vpiSimTime, 0, 0, 0.0 };
186
 
187
  //vpi_printf("uvm_hdl_set_vlog(%s,%0x)\n",path,value[0].aval);
188
 
189
  #ifdef QUESTA
190
  int result = 0;
191
  result = uvm_hdl_set_vlog_partsel(path,value,flag);
192
  if (result < 0)
193
    return 0;
194
  if (result == 1)
195
    return 1;
196
 
197
  if (!strncmp(path,"$root.",6))
198
    r = vpi_handle_by_name(path+6, 0);
199
  else
200
  #endif
201
  r = vpi_handle_by_name(path, 0);
202
 
203
  if(r == 0)
204
  {
205
      const char * err_str = "set: unable to locate hdl path (%s)\n Either the name is incorrect, or you may not have PLI/ACC visibility to that name";
206
      char buffer[strlen(err_str) + strlen(path)];
207
      sprintf(buffer, err_str, path);
208
      m_uvm_report_dpi(M_UVM_ERROR,
209
                       (char*) "UVM/DPI/HDL_SET",
210
                       &buffer[0],
211
                       M_UVM_NONE,
212
                       (char*)__FILE__,
213
                       __LINE__);
214
    return 0;
215
  }
216
  else
217
  {
218
    if(maxsize == -1)
219
        maxsize = uvm_hdl_max_width();
220
 
221
    if (flag == vpiReleaseFlag) {
222
      //size = vpi_get(vpiSize, r);
223
      //value_p = (p_vpi_vecval)(malloc(((size-1)/32+1)*8*sizeof(s_vpi_vecval)));
224
      //value = &value_p;
225
    }
226
    value_s.format = vpiVectorVal;
227
    value_s.value.vector = value;
228
    vpi_put_value(r, &value_s, &time_s, flag);
229
    //if (value_p != NULL)
230
    //  free(value_p);
231
    if (value == NULL) {
232
      value = value_s.value.vector;
233
    }
234
  }
235
#ifndef VCS
236
  vpi_release_handle(r);
237
#endif
238
  return 1;
239
}
240
 
241
 
242
/*
243
 * Given a path, look the path name up using the PLI
244
 * and return its 'value'.
245
 */
246
static int uvm_hdl_get_vlog(char *path, p_vpi_vecval value, PLI_INT32 flag)
247
{
248
  static int maxsize = -1;
249
  int i, size, chunks;
250
  vpiHandle r;
251
  s_vpi_value value_s;
252
 
253
  #ifdef QUESTA
254
  if (!partsel) {
255
    maxsize = uvm_hdl_max_width();
256
    chunks = (maxsize-1)/32 + 1;
257
    for(i=0;i<chunks-1; ++i) {
258
      value[i].aval = 0;
259
      value[i].bval = 0;
260
    }
261
  }
262
  int result = 0;
263
  result = uvm_hdl_get_vlog_partsel(path,value,flag);
264
  if (result < 0)
265
    return 0;
266
  if (result == 1)
267
    return 1;
268
 
269
  if (!strncmp(path,"$root.",6))
270
    r = vpi_handle_by_name(path+6, 0);
271
  else
272
  #endif
273
  r = vpi_handle_by_name(path, 0);
274
 
275
  if(r == 0)
276
  {
277
      const char * err_str = "get: unable to locate hdl path (%s)\n Either the name is incorrect, or you may not have PLI/ACC visibility to that name";
278
      char buffer[strlen(err_str) + strlen(path)];
279
      sprintf(buffer, err_str, path);
280
      m_uvm_report_dpi(M_UVM_ERROR,
281
                  (char*)"UVM/DPI/HDL_GET",
282
                       &buffer[0],
283
                       M_UVM_NONE,
284
                       (char*)__FILE__,
285
                       __LINE__);
286
    // Exiting is too harsh. Just return instead.
287
    // tf_dofinish();
288
    return 0;
289
  }
290
  else
291
  {
292
    if(maxsize == -1)
293
        maxsize = uvm_hdl_max_width();
294
 
295
    size = vpi_get(vpiSize, r);
296
    if(size > maxsize)
297
    {
298
      const char * err_str = "uvm_reg : hdl path '%s' is %0d bits, but the maximum size is %0d.  You can increase the maximum via a compile-time flag: +define+UVM_HDL_MAX_WIDTH=<value>";
299
      char buffer[strlen(err_str) + strlen(path) + (2*int_str_max(10))];
300
      sprintf(buffer, err_str, path, size, maxsize);
301
      m_uvm_report_dpi(M_UVM_ERROR,
302
                  (char*)"UVM/DPI/HDL_SET",
303
                       &buffer[0],
304
                       M_UVM_NONE,
305
                       (char*)__FILE__,
306
                       __LINE__);
307
      //tf_dofinish();
308
#ifndef VCS
309
      vpi_release_handle(r);
310
#endif
311
      return 0;
312
    }
313
    chunks = (size-1)/32 + 1;
314
 
315
    value_s.format = vpiVectorVal;
316
    vpi_get_value(r, &value_s);
317
    /*dpi and vpi are reversed*/
318
    for(i=0;i<chunks; ++i)
319
    {
320
      value[i].aval = value_s.value.vector[i].aval;
321
      value[i].bval = value_s.value.vector[i].bval;
322
    }
323
  }
324
  //vpi_printf("uvm_hdl_get_vlog(%s,%0x)\n",path,value[0].aval);
325
#ifndef VCS
326
  vpi_release_handle(r);
327
#endif
328
  return 1;
329
}
330
 
331
 
332
/*
333
 * Given a path, look the path name up using the PLI,
334
 * but don't set or get. Just check.
335
 *
336
 * Return 0 if NOT found.
337
 * Return 1 if found.
338
 */
339
int uvm_hdl_check_path(char *path)
340
{
341
  vpiHandle r;
342
 
343
  #ifdef QUESTA
344
  if (!strncmp(path,"$root.",6)) {
345
    r = vpi_handle_by_name(path+6, 0);
346
  }
347
  else
348
  #endif
349
  r = vpi_handle_by_name(path, 0);
350
 
351
  if(r == 0)
352
      return 0;
353
  else
354
    return 1;
355
}
356
 
357
 
358
/*
359
 * Given a path, look the path name up using the PLI
360
 * or the FLI, and return its 'value'.
361
 */
362
int uvm_hdl_read(char *path, p_vpi_vecval value)
363
{
364
    return uvm_hdl_get_vlog(path, value, vpiNoDelay);
365
}
366
 
367
/*
368
 * Given a path, look the path name up using the PLI
369
 * or the FLI, and set it to 'value'.
370
 */
371
int uvm_hdl_deposit(char *path, p_vpi_vecval value)
372
{
373
    return uvm_hdl_set_vlog(path, value, vpiNoDelay);
374
}
375
 
376
 
377
/*
378
 * Given a path, look the path name up using the PLI
379
 * or the FLI, and set it to 'value'.
380
 */
381
int uvm_hdl_force(char *path, p_vpi_vecval value)
382
{
383
    return uvm_hdl_set_vlog(path, value, vpiForceFlag);
384
}
385
 
386
 
387
/*
388
 * Given a path, look the path name up using the PLI
389
 * or the FLI, and release it.
390
 */
391
int uvm_hdl_release_and_read(char *path, p_vpi_vecval value)
392
{
393
    return uvm_hdl_set_vlog(path, value, vpiReleaseFlag);
394
}
395
 
396
/*
397
 * Given a path, look the path name up using the PLI
398
 * or the FLI, and release it.
399
 */
400
int uvm_hdl_release(char *path)
401
{
402
  s_vpi_vecval value;
403
  p_vpi_vecval valuep = &value;
404
  return uvm_hdl_set_vlog(path, valuep, vpiReleaseFlag);
405
}
406
 

powered by: WebSVN 2.1.0

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