Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / verif / env / common / vera / classes / baseParamsClass.vr
CommitLineData
86530b38
AT
1// ========== Copyright Header Begin ==========================================
2//
3// OpenSPARC T2 Processor File: baseParamsClass.vr
4// Copyright (C) 1995-2007 Sun Microsystems, Inc. All Rights Reserved
5// 4150 Network Circle, Santa Clara, California 95054, U.S.A.
6//
7// * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
8//
9// This program is free software; you can redistribute it and/or modify
10// it under the terms of the GNU General Public License as published by
11// the Free Software Foundation; version 2 of the License.
12//
13// This program is distributed in the hope that it will be useful,
14// but WITHOUT ANY WARRANTY; without even the implied warranty of
15// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16// GNU General Public License for more details.
17//
18// You should have received a copy of the GNU General Public License
19// along with this program; if not, write to the Free Software
20// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21//
22// For the avoidance of doubt, and except that if any non-GPL license
23// choice is available it will apply instead, Sun elects to use only
24// the General Public License version 2 (GPLv2) at this time for any
25// software where a choice of GPL license versions is made
26// available with the language indicating that GPLv2 or any later version
27// may be used, or where a choice of which version of the GPL is applied is
28// otherwise unspecified.
29//
30// Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
31// CA 95054 USA or visit www.sun.com if you need additional information or
32// have any questions.
33//
34// ========== Copyright Header End ============================================
35#include <vera_defines.vrh>
36
37// defines
38#include "plusArgMacros.vri"
39#include "baseParamDefines.vri"
40
41
42// NOTE, this class is *not* using std_display due to this class being
43// used in many/any bench. It is meant to be a more generic class.
44// #include "std_display_defines.vri"
45// #include "std_display_class.vrh"
46
47
48// usage: In your extended class, do something like this to make use of this
49// base class's methods.
50//
51// // Paramater precedence is:
52// // highest) If paramater is a +arg passed into vcs.
53// // middle) If paramater is in the config/param file.
54// // last) Default value given in getParam call.
55// // There will always be a value.
56// task Params::getCfg(string fileName = null)
57// {
58//
59// // "open" config file for the testcase, even if null
60// openFile(fileName);
61//
62// // getParam(type,name,min,max,default)
63// myParam1 = getParam(DEC,"ZZZ",10,100,20);
64//
65// // hex values
66// myParam2 = getParam(HEX,"myParamTwo",64'h55,64'h1fff,64'hfa);
67//
68// // User can select from 2-5 or RAND (if RANDOK is set), default is RAND
69// // in this case. RAND is -1 and applies to integers only. Your code has
70// // to decide what to do when myParam3 = -1. Generally, it means don't use
71// // one of 2,3,4 or 5 but instead, freely pick an appropriate random value
72// // in your code. Your code decides. See "RAND/RANDOK EXAMPLE" below...
73// myParam3 = getParam(DEC,"abc",2,5,RAND,RANDOK);
74//
75// closeFile(fileName);
76// check4conflict();
77// }
78
79// RAND/RANDOK EXAMPLE
80// if (gParam.por_delay == -1) repeat (urandom_range(1,10)) @ (posedge CLOCK);
81// else repeat (gParam.por_delay) @ (posedge CLOCK);
82
83
84
85class BaseParams {
86
87 protected string configFileName; // configuration file name
88 protected integer cfgFileHndl; // file handle
89 protected reg requireConfig;
90
91 protected function reg [127:0] getParam(integer type,
92 string name,
93 reg [127:0] minval,
94 reg [127:0] maxval,
95 reg [127:0] defval,
96 reg randOK = 0,
97 reg noWarn = 0); // careful!
98
99 protected task getRegArray(integer type,
100 string name,
101 reg [127:0] minval,
102 reg [127:0] maxval,
103 reg [127:0] defval,
104 var reg[511:0] data[],
105 integer itemCnt=0,
106 reg randOK = 0);
107
108 protected task getArray(integer type,
109 string name,
110 integer minval,
111 integer maxval,
112 integer defval,
113 var integer data[],
114 integer itemCnt=0,
115 reg randOK = 0);
116
117
118 protected task openFile(string fileName = null);
119 protected task closeFile(string fileName = null);
120 protected function string getStringParam(string name);
121 task new(reg requireConfig = 0);
122}
123
124task BaseParams::new(reg requireConfig = 0) {
125 // if this is set, bench may fail if config fileName is null. see openFile
126 this.requireConfig = requireConfig;
127}
128
129task BaseParams::openFile(string fileName = null)
130{
131 // check to see if fileName is null or bogus,
132 // if so, we will be using defaults and +args only.
133 // No file will be opened or read or closed but all
134 // methods can be called anyway.
135 //
136 // if requireConfig is set, bench will fail if config fileName is null
137 // and +noConfig is not set.
138 if (fileName == null || fileName.len() < 3) {
139 configFileName = null;
140 cfgFileHndl = 0;
141 if (requireConfig && !mChkPlusarg(noConfig)) {
142 printf("\n\n%9d: baseParamsClass[]: ERROR This bench requires one of 2 things, a non-null config file name or the plus arg -vcs_run_args=+noConfig\n",get_cycle());
143 printf("ERROR: You may have miss-typed when specifying the config file name plus arg?\n\n");
144 exit(0);
145 }
146 } else {
147 configFileName = fileName;
148 cfgFileHndl = fopen(configFileName,"r");
149 if (cfgFileHndl == 0) {
150 printf("\n\n%9d: baseParamsClass[]: ERROR: config file %s open failed!\n", get_cycle(), configFileName);
151 exit(0);
152 }
153 printf("%9d: baseParamsClass[]: reading config from %s\n",get_cycle(),configFileName);
154 }
155}
156
157task BaseParams::closeFile(string fileName = null)
158{
159 if (fileName !== null && cfgFileHndl !== 0) fclose(cfgFileHndl);
160}
161
162// Initialize the parameter requested. We will check to see if a
163// corresponding +arg was provided by the user. If so, it will be used
164// after a min/max check. If not, next we will search the
165// config/paramater file for the paramater name and if found do a min/max
166// check and set the variable, otherwise parmeter is set to the default
167// value.
168//
169// type - DEC convert ascii to 32 bit signed integer,
170// HEX convert ascii to 64 bit hex,
171// FLAG interpret as 1/0 (+arg/no +arg detection)
172// Will flip default value.
173// name - ascii string of the paramater/+arg name
174// minval - minimum valid value
175// maxval - maximum valid value
176// default - default value.
177// randOK - allow a value of -1 (your final code can interpret -1
178// as "wide open" or whatever)
179function reg [127:0] BaseParams::getParam(integer type,
180 string name,
181 reg [127:0] minval,
182 reg [127:0] maxval,
183 reg [127:0] defval,
184 reg randOK = 0,
185 reg noWarn = 0) // careful!
186{
187 string varstring;
188 string varname;
189 string varval;
190 string fullname;
191 string tempstr;
192 integer tmpi = 0, maxvali = 0, minvali = 0;
193 reg [127:0] tmpReg = 0;
194 reg match=0;
195
196 getParam = defval; // use default value if no match below.
197
198 // user over-ride, do not try to find setting in config file
199 // if user has passed in the corresponding plus argument.
200 //sprintf(fullname, "%s", name); // "%s=" to append = but this disallows non value +args
201
202 if (type == FLAG) sprintf(fullname, "%s", name);
203 else sprintf(fullname, "%s=", name);
204
205 if (mChkPlusargSvar(fullname)) {
206 match = 1;
207
208
209// breakpoint;
210
211
212 case (type) {
213 DEC: {
214 mGetPlusargDecSvar(fullname,tmpi);
215 }
216 HEX: {
217 mGetPlusargStrSvar(fullname,tmpReg);
218 tempstr.bittostr(tmpReg);
219 if (tempstr == "all") tmpReg = 64'hffffffffffffffff; // special case
220 else tmpReg = tempstr.atohex();
221 }
222 FLAG: {
223 if (defval > 0) getParam = 0;
224 else getParam = 1; // flip default value
225 }
226 }
227
228 if (!noWarn) {
229 printf("* WARNING: The following setting was given on the command line as +%s *\n",name);
230 //printf("* WARNING: Setting was given as +%s or +%s=%0d or +%s=%0h *\n",name,name,tmpi,name,tmpReg);
231 printf("* WARNING: You need to know this, and do it again, in order to recreate failures! *\n");
232 }
233 } else if (cfgFileHndl !== 0) {
234 // try to find setting in file
235 varstring = freadstr(cfgFileHndl,SILENT);
236 while (varstring != null) {
237 sscanf(varstring,"%s %s",varname,varval);
238 if (name == varname) {
239 match = 1;
240 case (type) {
241 DEC: tmpi = varval.atoi();
242 HEX: tmpReg = varval.atohex();
243 FLAG: {
244 getParam = varval.atoi();
245 if (getParam !== 1 && getParam !== 0)
246 if (defval > 0) getParam = 0;
247 else getParam = 1; // flip default value
248 }
249 }
250 break;
251 }
252 varstring = freadstr(cfgFileHndl,SILENT);
253 } // while
254 }
255
256
257 // Do min/max check if either a match was found in config file
258 // OR the corresponding plus arg was passed in.
259 if (match == 1) {
260 if (type == HEX) {
261 if ((tmpReg >= minval) &&
262 (tmpReg <= maxval)) {
263 getParam = tmpReg;
264 } else {
265 printf("\n%9d: baseParamsClass::getParam[]: ERROR Following hex parameter failed minmax test\n",get_cycle());
266 printf("%9d: baseParamsClass::getParam[]: ERROR actual=0x%0h min=0x%0h max=0x%0h\n",get_cycle(),tmpReg,minval,maxval);
267 exit(0);
268 }
269 } else if (type == DEC) {
270 minvali = minval;
271 maxvali = maxval;
272 if ( (tmpi >= minvali && tmpi <= maxvali) ||
273 (tmpi == -1 && randOK == RANDOK) ) {
274 getParam = 0;
275 getParam[31:0] = tmpi;
276 } else {
277 printf("\n%9d: baseParamsClass::getParam[]: ERROR Following integer parameter failed minmax test\n",get_cycle());
278 printf("%9d: baseParamsClass::getParam[]: ERROR name=%s actual=%0d min=%0d max=%0d\n",get_cycle(),name, tmpi,minvali,maxvali);
279 exit(0);
280 }
281 }
282 } // if match
283
284 // Put final value in log and on screen.
285 if (type == HEX) {
286 if (getParam == defval)
287 printf("%9d: baseParamsClass::getParam[]: setting %s to 0x%0h (== default)\n",get_cycle(),name,getParam);
288 else
289 printf("%9d: baseParamsClass::getParam[]: setting %s to 0x%0h (!= default)\n",get_cycle(),name,getParam);
290 }
291 else if (type == DEC) {
292 tmpi = getParam[31:0]; // casting to signed integer so -1 prints as "-1"
293 if (getParam == defval)
294 printf("%9d: baseParamsClass::getParam[]: setting %s to %0d (== default)\n",get_cycle(),name,tmpi);
295 else
296 printf("%9d: baseParamsClass::getParam[]: setting %s to %0d (!= default)\n",get_cycle(),name,tmpi);
297 } else if (type == FLAG) {
298 if (getParam == defval) printf("%9d: baseParamsClass::getParam[]: setting %s is %0d (== default)\n",get_cycle(),name,getParam);
299 else printf("%9d: baseParamsClass::getParam[]: setting %s is %0d (!= default)\n",get_cycle(),name,getParam);
300 }
301
302 // for next getParam call
303#ifdef NTB
304 closeFile(configFileName);
305 openFile(configFileName);
306#else
307 if (cfgFileHndl !== 0) rewind(cfgFileHndl);
308#endif
309
310}
311
312
313task BaseParams::getArray(integer type,
314 string name,
315 integer minval,
316 integer maxval,
317 integer defval,
318 var integer data[],
319 integer itemCnt=0,
320 reg randOK = 0)
321{
322 reg [511:0] tmpData [];
323 integer i;
324 integer index = -1;
325
326 //Use the prexisting getRegArray task
327 getRegArray(type, name, minval, maxval, defval, tmpData, itemCnt, randOK);
328
329 //Copy the contents of the bit array to the integer array;
330 void = assoc_index(FIRST, tmpData, index);
331
332 for (i=0; i < assoc_index(CHECK, tmpData); i++)
333 {
334 data[index] = tmpData[index];
335 assoc_index(NEXT, tmpData, index);
336 }
337
338}
339
340// For each listed element found after the parameter, the element will be
341// put in the next available index of the array that is passed into this task.
342//
343// type - DEC convert ascii to 32 bit signed integer
344// HEX convert ascii to 64 bit hex
345// STRING store as a string
346// name - ascii string of the paramater array name
347// minval - minimum valid value - only for integers and hex
348// maxval - maximum valid value - only for integers and hex
349//
350// Spaces are ignored. Trailing comma indicates continuation.
351//
352// example list usage in a users file
353// paramater_list 1, 2,
354// 3,
355// 4,5, 6,
356// 7, 8,9,10, 01, 02, 03, 04, 05, 06
357//
358// or ideally
359// paramater_list 1,2,3,4,5
360
361//
362task BaseParams::getRegArray(integer type,
363 string name,
364 reg [127:0] minval,
365 reg [127:0] maxval,
366 reg [127:0] defval,
367 var reg[511:0] array[],
368 integer itemCnt=0,
369 reg randOK = 0)
370{
371 string fullLine = null;
372 string paramName;
373 string paramValue;
374 string fullname;
375 integer tmpi = 0;
376 reg [511:0] tmpReg = 0;
377 integer i, match, foundPlusArg=0;
378 integer index = 0;
379 string element, tempstr;
380 integer done = 0, nextLine = 0;
381 integer arrayIndex = 0;
382 integer minvali, maxvali, value;
383
384 // If an itemCnt is passed into the routine then Initialize all elements
385 // of the array to default value. Still look for elements in the file though.
386 for (i=0; i<itemCnt; i++)
387 {
388 if (type == DEC)
389 {
390 tmpi = defval; // cast to int
391 array[i] = tmpi;
392 printf("%9d: baseParamsClass::getArray[]: setting %s[%0d] to %0d (== default)\n",get_cycle(),name,i,tmpi);
393 } else {
394 array[i] = defval;
395 printf("%9d: baseParamsClass::getArray[]: setting %s[%0d] to 0x%0h (== default)\n",get_cycle(),name,i,defval);
396 }
397 }
398
399
400 // user over-ride, do not try to find setting in config file
401 // if user has passed in the corresponding plus argument.
402 //sprintf(fullname, "%s=", name); // append =
403
404 if (type == FLAG) sprintf(fullname, "%s", name);
405 else sprintf(fullname, "%s=", name);
406
407 if (mChkPlusargSvar(fullname)) {
408 match = 1;
409 mGetPlusargStrSvar(fullname,tmpReg);
410 tempstr.bittostr(tmpReg);
411 printf("* WARNING: The following setting was given on the command line as +arg *\n");
412 printf("* +%s%s\n", fullname, tempstr);
413 printf("* WARNING: You need to know this, and do it again, in order to recreate failures! *\n");
414 // let the file parser parse the +arg
415 fullLine = {name, " ", tempstr};
416 foundPlusArg = 1;
417 }
418
419 // try to find setting in file
420 if (cfgFileHndl !== 0 && !foundPlusArg)
421 fullLine = freadstr(cfgFileHndl,SILENT);
422
423 while (fullLine != null)
424 {
425 //Remove whitespace from the beginning of the line
426 if (fullLine.match("\s*\S"))
427 {
428 fullLine.match("^[ \t]*");
429 fullLine = fullLine.postmatch();
430 }
431
432 sscanf(fullLine,"%s %s",paramName,paramValue);
433
434 if (name == paramName)
435 {
436 index = paramName.len();
437 paramValue = fullLine.substr(index);
438
439 // remove any trailing white space from paramValue
440 index = paramValue.len() - 1;
441 while ( paramValue.substr(index) == " " )
442 {
443 paramValue = paramValue.substr(0,index-1);
444 index--;
445 }
446 // do we have a trailing comma? If so, then line is continued.
447 if (paramValue.substr(index) == "," ) nextLine = 1;
448 else nextLine = 0;
449
450 while (!done)
451 {
452 // Are there no more commas on the line? We could have:
453 // 1) element
454 // 2) element,
455 // 3) element, element
456 index = paramValue.search(",");
457
458 if (index == -1) // no commas
459 {
460 // grab last/only element on line
461 element = paramValue;
462
463 // if this line is NOT continued, then done
464 if (!nextLine)
465 {
466 done = 1;
467 }
468 else // line is continued, get next line
469 {
470 // Read in the next line since previous line was continued
471 if (!foundPlusArg) paramValue = freadstr(cfgFileHndl,SILENT);
472
473 // remove any trailing white space from paramValue
474 index = paramValue.len() - 1;
475 while ( paramValue.substr(index) == " " )
476 {
477 paramValue = paramValue.substr(0,index-1);
478 index--;
479 }
480 // do we have a trailing comma? If so, then line is continued.
481 if (paramValue.substr(index) == "," ) nextLine = 1;
482 else nextLine = 0;
483
484 // remove any leading whitespace
485 while ( paramValue.substr(0,0) == " " )
486 {
487 paramValue = paramValue.substr(1,paramValue.len()-1);
488 }
489
490 // if first char is a comma, remove it
491 if (paramValue.substr(0) == ",")
492 paramValue = paramValue.substr(1,paramValue.len()-1);
493
494 // now get the first element by continuing the loop
495 continue;
496
497 }
498 }
499 else // there is still a comma on the line
500 {
501 // grab the element up to the trailing comma
502 element = paramValue.substr(0, index - 1);
503
504 // remove leading element and comma from paramValue
505 // now that it is captured. (element,)
506 paramValue = paramValue.substr(index + 1, paramValue.len());
507 }
508
509 // remove white space from element
510 sscanf(element,"%s",element);
511
512 case (type)
513 {
514 DEC:
515 {
516 tmpi = element.atoi();
517 minvali = minval;
518 maxvali = maxval;
519
520 if ( (tmpi >= minvali && tmpi <= maxvali) ||
521 (tmpi == -1 && randOK == RANDOK) ) {
522 array[arrayIndex] = tmpi;
523 }
524 else
525 {
526 printf("\n%9d: baseParamsClass::getArray[]: ERROR Failed minmax test\n",get_cycle());
527 printf("%9d: baseParamsClass::getArray[]: ERROR actual=%0d min=%0d max=%0d\n",
528 get_cycle(),tmpi,minvali,maxvali);
529 exit(0);
530 }
531
532 printf("%9d: baseParamsClass::getArray[]: setting %0s[%0d] to %0d (user selected)\n",
533 get_cycle(),name,arrayIndex, tmpi);
534 }
535
536
537 HEX:
538 {
539 tmpReg = element.atohex();
540
541 if ((tmpReg < minval) || (tmpReg > maxval))
542 {
543 printf("\n%9d: baseParamsClass::getArray[]: ERROR Failed minmax test\n",get_cycle());
544 printf("%9d: baseParamsClass::getArray[]: ERROR actual=0x%0h min=0x%0h max=0x%0h\n",
545 get_cycle(),tmpReg,minval,maxval);
546 exit(0);
547 }
548 else
549 array[arrayIndex] = tmpReg;
550
551 printf("%9d: baseParamsClass::getArray[]: setting %0s[%0d] to 0x%0h (user selected)\n",
552 get_cycle(),name,arrayIndex, array[arrayIndex]);
553 }
554
555
556 STRING:
557 {
558 // Remove any white space and force a space before string
559 sscanf(element," %s",element);
560 array[arrayIndex] = element;
561 printf("%9d: baseParamsClass::getArray[]: setting %0s[%0d] to %0s (user selected)\n",
562 get_cycle(),name,arrayIndex, array[arrayIndex]);
563 }
564
565 }
566
567 arrayIndex++;
568
569 } // while !done
570 } // if param
571
572 if (!foundPlusArg) fullLine = freadstr(cfgFileHndl,SILENT);
573 else fullLine = null;
574
575 } // while parsing file
576
577
578 // for next get* call
579#ifdef NTB
580 closeFile(configFileName);
581 openFile(configFileName);
582#else
583 if (cfgFileHndl !== 0 && !foundPlusArg) rewind(cfgFileHndl);
584#endif
585
586}
587
588
589function string BaseParams::getStringParam(string name)
590{
591 string varstring;
592 string varname;
593 string varval;
594 string fullname;
595 reg [127:0] tmpReg = 0;
596
597 getStringParam = null;
598
599 // user over-ride, do not try to find setting in config file
600 // if user has passed in the corresponding plus argument.
601 sprintf(fullname, "%s=", name); // append =
602
603 if (mChkPlusargSvar(fullname)) {
604 mGetPlusargStrSvar(fullname,tmpReg);
605 getStringParam.bittostr(tmpReg);
606 printf("* WARNING: The following (non-default?) setting was given on the command line! *\n");
607 printf("* WARNING: You need to know this, and do it again, in order to recreate failures! *\n");
608 } else if (cfgFileHndl !== 0) {
609 // try to find setting in file
610 varstring = freadstr(cfgFileHndl,SILENT);
611 while (varstring != null) {
612 sscanf(varstring,"%s %s",varname,varval);
613 if (name == varname) {
614 getStringParam = varval;
615 break;
616 }
617 varstring = freadstr(cfgFileHndl,SILENT);
618 } // end while
619 }
620
621 if (getStringParam != null) {
622 printf("%9d: baseParamsClass::getStringParam: setting %s to %s\n",get_cycle(),name,getStringParam);
623 }
624
625 // for next getParam call
626#ifdef NTB
627 closeFile(configFileName);
628 openFile(configFileName);
629#else
630 if (cfgFileHndl !== 0) rewind(cfgFileHndl);
631#endif
632
633} // end function getStringParam