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

Subversion Repositories ecpu_alu

[/] [ecpu_alu/] [trunk/] [alu/] [systemc/] [bak/] [verilated.cpp] - Blame information for rev 5

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 5 leonous
// -*- C++ -*-
2
//*************************************************************************
3
//
4
// Copyright 2003-2009 by Wilson Snyder. This program is free software; you can
5
// redistribute it and/or modify it under the terms of either the GNU
6
// Lesser General Public License or the Perl Artistic License.
7
//
8
// Verilator is distributed in the hope that it will be useful,
9
// but WITHOUT ANY WARRANTY; without even the implied warranty of
10
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
// GNU General Public License for more details.
12
//
13
//=========================================================================
14
///
15
/// \file
16
/// \brief Verilator: Linked against all applications using Verilated source.
17
///
18
///     This file must be compiled and linked against all objects
19
///     created from Verilator.
20
///
21
/// Code available from: http://www.veripool.org/verilator
22
///
23
//=========================================================================
24
 
25
#include "verilated.h"
26
#include <cctype>
27
 
28
#define VL_VALUE_STRING_MAX_WIDTH 1024  ///< Max static char array for VL_VALUE_STRING
29
 
30
//===========================================================================
31
// Global variables
32
 
33
int  Verilated::s_randReset = 0;
34
int  Verilated::s_debug = 1;
35
bool Verilated::s_calcUnusedSigs = false;
36
bool Verilated::s_gotFinish = false;
37
bool Verilated::s_assertOn = true;
38
 
39
//===========================================================================
40
// User definable functions
41
 
42
#ifndef VL_USER_FINISH          // Define this to override this function
43
void vl_finish (const char* filename, int linenum, const char* hier) {
44
    if (0 && hier) {}
45
    VL_PRINTF("- %s:%d: Verilog $finish\n", filename, linenum);
46
    if (Verilated::gotFinish()) {
47
        VL_PRINTF("- %s:%d: Second verilog $finish, exiting\n", filename, linenum);
48
        exit(0);
49
    }
50
    Verilated::gotFinish(true);
51
}
52
#endif
53
 
54
#ifndef VL_USER_STOP            // Define this to override this function
55
void vl_stop (const char* filename, int linenum, const char* hier) {
56
    Verilated::gotFinish(true);
57
    vl_fatal (filename,linenum,hier,"Verilog $stop");
58
}
59
#endif
60
 
61
#ifndef VL_USER_FATAL   // Define this to override this function
62
void vl_fatal (const char* filename, int linenum, const char* hier, const char* msg) {
63
    if (0 && hier) {}
64
    Verilated::gotFinish(true);
65
    VL_PRINTF("%%Error: %s:%d: %s\n", filename, linenum, msg);
66
    abort();
67
}
68
#endif
69
 
70
//===========================================================================
71
// Random reset -- Only called at init time, so don't inline.
72
 
73
IData VL_RAND32() {
74
#if defined(_WIN32) && !defined(__CYGWIN__)
75
    // Windows doesn't have lrand48(), although Cygwin does.
76
    return (rand()<<16) ^ rand();
77
#else
78
    return (lrand48()<<16) ^ lrand48();
79
#endif
80
}
81
 
82
IData VL_RANDOM_I(int obits) {
83
    return VL_RAND32() & VL_MASK_I(obits);
84
}
85
 
86
QData VL_RANDOM_Q(int obits) {
87
    QData data = ((QData)VL_RAND32()<<VL_ULL(32)) | (QData)VL_RAND32();
88
    return data & VL_MASK_Q(obits);
89
}
90
 
91
WDataOutP VL_RANDOM_W(int obits, WDataOutP outwp) {
92
    for (int i=0; i<VL_WORDS_I(obits); i++) {
93
        if (i<(VL_WORDS_I(obits)-1)) {
94
            outwp[i] = VL_RAND32();
95
        } else {
96
            outwp[i] = VL_RAND32() & VL_MASK_I(obits);
97
        }
98
    }
99
    return outwp;
100
}
101
 
102
IData VL_RAND_RESET_I(int obits) {
103
    if (Verilated::randReset()==0) return 0;
104
    IData data = ~0;
105
    if (Verilated::randReset()!=1) {    // if 2, randomize
106
        data = VL_RANDOM_I(obits);
107
    }
108
    if (obits<32) data &= VL_MASK_I(obits);
109
    return data;
110
}
111
 
112
QData VL_RAND_RESET_Q(int obits) {
113
    if (Verilated::randReset()==0) return 0;
114
    QData data = VL_ULL(~0);
115
    if (Verilated::randReset()!=1) {    // if 2, randomize
116
        data = VL_RANDOM_Q(obits);
117
    }
118
    if (obits<64) data &= VL_MASK_Q(obits);
119
    return data;
120
}
121
 
122
WDataOutP VL_RAND_RESET_W(int obits, WDataOutP outwp) {
123
    for (int i=0; i<VL_WORDS_I(obits); i++) {
124
        if (i<(VL_WORDS_I(obits)-1)) {
125
            outwp[i] = VL_RAND_RESET_I(32);
126
        } else {
127
            outwp[i] = VL_RAND_RESET_I(32) & VL_MASK_I(obits);
128
        }
129
    }
130
    return outwp;
131
}
132
 
133
WDataOutP VL_ZERO_RESET_W(int obits, WDataOutP outwp) {
134
    for (int i=0; i<VL_WORDS_I(obits); i++) outwp[i] = 0;
135
    return outwp;
136
}
137
 
138
//===========================================================================
139
// Formatting
140
 
141
// Do a va_arg returning a quad, assuming input argument is anything less than wide
142
#define _VL_VA_ARG_Q(ap, bits) (((bits) <= VL_WORDSIZE) ? va_arg(ap,IData) : va_arg(ap,QData))
143
 
144
void _vl_vsformat(string& output, const char* formatp, va_list ap) {
145
    // Format a Verilog $write style format into the output list
146
    // The format must be pre-processed (and lower cased) by Verilator
147
    // Arguments are in "width, arg-value (or WDataIn* if wide)" form
148
    //
149
    // Note uses a single buffer internally; presumes only one usage per printf
150
    // Note also assumes variables < 64 are not wide, this assumption is
151
    // sometimes not true in low-level routines written here in verilated.cpp
152
    static VL_THREAD char tmp[VL_VALUE_STRING_MAX_WIDTH];
153
    bool inPct = false;
154
    bool widthSet = false;
155
    int width = 0;
156
    const char* pos = formatp;
157
    for (; *pos; ++pos) {
158
        if (!inPct && pos[0]=='%') {
159
            inPct = true;
160
            widthSet = false;
161
            width = 0;
162
        } else if (!inPct) {   // Normal text
163
            // Fast-forward to next escape and add to output
164
            const char *ep = pos;
165
            while (ep[0] && ep[0]!='%') ep++;
166
            if (ep != pos) {
167
                output += string(pos, ep-pos);
168
                pos += ep-pos-1;
169
            }
170
        } else { // Format character
171
            inPct = false;
172
            char fmt = pos[0];
173
            switch (fmt) {
174
            case '0': case '1': case '2': case '3': case '4':
175
            case '5': case '6': case '7': case '8': case '9':
176
                inPct = true;  // Get more digits
177
                widthSet = true;
178
                width = width*10 + (fmt - '0');
179
                break;
180
            case '%':
181
                output += '%';
182
                break;
183
            case 'S': { // "C" string
184
                const char* cstrp = va_arg(ap, const char*);
185
                output += cstrp;
186
                break;
187
            }
188
            default: {
189
                // Deal with all read-and-print somethings
190
                const int lbits = va_arg(ap, int);
191
                QData ld = 0;
192
                WDataInP lwp;
193
                if (lbits <= VL_QUADSIZE) {
194
                    WData qlwp[2];
195
                    ld = _VL_VA_ARG_Q(ap, lbits);
196
                    VL_SET_WQ(qlwp,ld);
197
                    lwp = qlwp;
198
                } else {
199
                    lwp = va_arg(ap,WDataInP);
200
                    ld = lwp[0];
201
                    if (fmt == 'u' || fmt == 'd') fmt = 'x';  // Not supported, but show something
202
                }
203
                int lsb=lbits-1;
204
                if (widthSet && width==0) while (lsb && !VL_BITISSET_W(lwp,lsb)) lsb--;
205
                switch (fmt) {
206
                case 'c': {
207
                    IData charval = ld & 0xff;
208
                    output += charval;
209
                    break;
210
                }
211
                case 's':
212
                    for (; lsb>=0; lsb--) {
213
                        lsb = (lsb / 8) * 8; // Next digit
214
                        IData charval = (lwp[VL_BITWORD_I(lsb)]>>VL_BITBIT_I(lsb)) & 0xff;
215
                        output += (charval==0)?' ':charval;
216
                    }
217
                    break;
218
                case 'd': { // Signed decimal
219
                    int digits=sprintf(tmp,"%lld",(vlsint64_t)(VL_EXTENDS_QQ(lbits,lbits,ld)));
220
                    int needmore = width-digits;
221
                    if (needmore>0) output.append(needmore,' '); // Pre-pad spaces
222
                    output += tmp;
223
                    break;
224
                }
225
                case 'u': { // Unsigned decimal
226
                    int digits=sprintf(tmp,"%llu",ld);
227
                    int needmore = width-digits;
228
                    if (needmore>0) output.append(needmore,' '); // Pre-pad spaces
229
                    output += tmp;
230
                    break;
231
                }
232
                case 't': { // Time
233
                    int digits;
234
                    if (VL_TIME_MULTIPLIER==1) {
235
                        digits=sprintf(tmp,"%llu",ld);
236
                    } else if (VL_TIME_MULTIPLIER==1000) {
237
                        digits=sprintf(tmp,"%llu.%03llu",
238
                                       (QData)(ld/VL_TIME_MULTIPLIER),
239
                                       (QData)(ld%VL_TIME_MULTIPLIER));
240
                    } else {
241
                        vl_fatal(__FILE__,__LINE__,"","%%Error: Unsupported VL_TIME_MULTIPLIER");
242
                    }
243
                    int needmore = width-digits;
244
                    if (needmore>0) output.append(needmore,' '); // Pre-pad spaces
245
                    output += tmp;
246
                    break;
247
                }
248
                case 'b':
249
                    for (; lsb>=0; lsb--) {
250
                        output += ((lwp[VL_BITWORD_I(lsb)]>>VL_BITBIT_I(lsb)) & 1) + '0';
251
                    }
252
                    break;
253
                case 'o':
254
                    for (; lsb>=0; lsb--) {
255
                        lsb = (lsb / 3) * 3; // Next digit
256
                        // Octal numbers may span more than one wide word,
257
                        // so we need to grab each bit separately and check for overrun
258
                        // Octal is rare, so we'll do it a slow simple way
259
                        output += ('0'
260
                                   + ((VL_BITISSETLIMIT_W(lwp, lbits, lsb+0)) ? 1 : 0)
261
                                   + ((VL_BITISSETLIMIT_W(lwp, lbits, lsb+1)) ? 2 : 0)
262
                                   + ((VL_BITISSETLIMIT_W(lwp, lbits, lsb+2)) ? 4 : 0));
263
                    }
264
                    break;
265
                case 'x':
266
                    for (; lsb>=0; lsb--) {
267
                        lsb = (lsb / 4) * 4; // Next digit
268
                        IData charval = (lwp[VL_BITWORD_I(lsb)]>>VL_BITBIT_I(lsb)) & 0xf;
269
                        output += "0123456789abcdef"[charval];
270
                    }
271
                    break;
272
                default:
273
                    string msg = string("%%Error: Unknown _vl_vsformat code: ")+pos[0]+"\n";
274
                    vl_fatal(__FILE__,__LINE__,"",msg.c_str());
275
                    break;
276
                } // switch
277
            }
278
            } // switch
279
        }
280
    }
281
}
282
 
283
static inline bool _vl_vsss_eof(FILE* fp, int& floc) {
284
    return fp ? feof(fp) : (floc<0);
285
}
286
static inline void _vl_vsss_advance(FILE* fp, int& floc) {
287
    if (fp) fgetc(fp);
288
    else floc -= 8;
289
}
290
static inline int  _vl_vsss_peek(FILE* fp, int& floc, WDataInP fromp) {
291
    // Get a character without advancing
292
    if (fp) {
293
        int data = fgetc(fp);
294
        if (data == EOF) return EOF;
295
        ungetc(data,fp);
296
        return data;
297
    } else {
298
        if (floc < 0) return EOF;
299
        floc = floc & ~7;       // Align to closest character
300
        int data = (fromp[VL_BITWORD_I(floc)] >> VL_BITBIT_I(floc)) & 0xff;
301
        return data;
302
    }
303
}
304
static inline void _vl_vsss_skipspace(FILE* fp, int& floc, WDataInP fromp) {
305
    while (1) {
306
        int c = _vl_vsss_peek(fp, floc, fromp);
307
        if (c==EOF || !isspace(c)) return;
308
        _vl_vsss_advance(fp, floc);
309
    }
310
}
311
static inline void _vl_vsss_read(FILE* fp, int& floc, WDataInP fromp,
312
                                 char* tmpp, const char* acceptp) {
313
    // Read into tmp, consisting of characters from acceptp list
314
    char* cp = tmpp;
315
    while (1) {
316
        int c = _vl_vsss_peek(fp, floc, fromp);
317
        if (c==EOF || isspace(c)) break;
318
        if (acceptp!=NULL // String - allow anything
319
            && NULL==strchr(acceptp, c)) break;
320
        if (acceptp!=NULL) c = tolower(c); // Non-strings we'll simplify
321
        *cp++ = c;
322
        _vl_vsss_advance(fp, floc);
323
    }
324
    *cp++ = '\0';
325
    //VL_PRINTF("\t_read got='%s'\n", tmpp);
326
}
327
static inline void _vl_vsss_setbit(WDataOutP owp, int obits, int lsb, int nbits, IData ld) {
328
    for (; nbits && lsb<obits; nbits--, lsb++, ld>>=1) {
329
        VL_ASSIGNBIT_WI(0, lsb, owp, ld & 1);
330
    }
331
}
332
 
333
IData _vl_vsscanf(FILE* fp,  // If a fscanf
334
                  int fbits, WDataInP fromp,  // Else if a sscanf
335
                  const char* formatp, va_list ap) {
336
    // Read a Verilog $sscanf/$fscanf style format into the output list
337
    // The format must be pre-processed (and lower cased) by Verilator
338
    // Arguments are in "width, arg-value (or WDataIn* if wide)" form
339
    static VL_THREAD char tmp[VL_VALUE_STRING_MAX_WIDTH];
340
    int floc = fbits - 1;
341
    IData got = 0;
342
    bool inPct = false;
343
    const char* pos = formatp;
344
    for (; *pos && !_vl_vsss_eof(fp,floc); ++pos) {
345
        //VL_PRINTF("_vlscan fmt='%c' floc=%d file='%c'\n", pos[0], floc, _vl_vsss_peek(fp,floc,fromp));
346
        if (!inPct && pos[0]=='%') {
347
            inPct = true;
348
        } else if (!inPct && isspace(pos[0])) {   // Format spaces
349
            while (isspace(pos[1])) pos++;
350
            _vl_vsss_skipspace(fp,floc,fromp);
351
        } else if (!inPct) {   // Expected Format
352
            _vl_vsss_skipspace(fp,floc,fromp);
353
            int c = _vl_vsss_peek(fp,floc,fromp);
354
            if (c != pos[0]) goto done;
355
            else _vl_vsss_advance(fp,floc);
356
        } else { // Format character
357
            // Skip loading spaces
358
            inPct = false;
359
            char fmt = pos[0];
360
            switch (fmt) {
361
            case '%': {
362
                int c = _vl_vsss_peek(fp,floc,fromp);
363
                if (c != '%') goto done;
364
                else _vl_vsss_advance(fp,floc);
365
                break;
366
            }
367
            default: {
368
                // Deal with all read-and-scan somethings
369
                // Note LSBs are preserved if there's an overflow
370
                const int obits = va_arg(ap, int);
371
                int lsb = 0;
372
                WData qowp[2];
373
                WDataOutP owp = qowp;
374
                if (obits > VL_QUADSIZE) {
375
                    owp = va_arg(ap,WDataOutP);
376
                }
377
                for (int i=0; i<VL_WORDS_I(obits); i++) owp[i] = 0;
378
                switch (fmt) {
379
                case 'c': {
380
                    int c = _vl_vsss_peek(fp,floc,fromp);
381
                    if (c==EOF) goto done;
382
                    else _vl_vsss_advance(fp,floc);
383
                    owp[0] = c;
384
                    break;
385
                }
386
                case 's': {
387
                    _vl_vsss_skipspace(fp,floc,fromp);
388
                    _vl_vsss_read(fp,floc,fromp, tmp, NULL);
389
                    if (!tmp[0]) goto done;
390
                    int pos = strlen(tmp)-1;
391
                    for (int i=0; i<obits && pos>=0; pos--) {
392
                        _vl_vsss_setbit(owp,obits,lsb, 8, tmp[pos]); lsb+=8;
393
                    }
394
                    break;
395
                }
396
                case 'd': { // Signed decimal
397
                    _vl_vsss_skipspace(fp,floc,fromp);
398
                    _vl_vsss_read(fp,floc,fromp, tmp, "0123456789+-xz?_");
399
                    if (!tmp[0]) goto done;
400
                    vlsint64_t ld;
401
                    sscanf(tmp,"%lld",&ld);
402
                    VL_SET_WQ(owp,ld);
403
                    break;
404
                }
405
                case 't': // FALLTHRU  // Time
406
                case 'u': { // Unsigned decimal
407
                    _vl_vsss_skipspace(fp,floc,fromp);
408
                    _vl_vsss_read(fp,floc,fromp, tmp, "0123456789+-xz?_");
409
                    if (!tmp[0]) goto done;
410
                    QData ld;
411
                    sscanf(tmp,"%llu",&ld);
412
                    VL_SET_WQ(owp,ld);
413
                    break;
414
                }
415
                case 'b': {
416
                    _vl_vsss_skipspace(fp,floc,fromp);
417
                    _vl_vsss_read(fp,floc,fromp, tmp, "01xz?_");
418
                    if (!tmp[0]) goto done;
419
                    int pos = strlen(tmp)-1;
420
                    for (int i=0; i<obits && pos>=0; pos--) {
421
                        switch(tmp[pos]) {
422
                        case 'x': case 'z': case '?': //FALLTHRU
423
                        case '0': lsb++; break;
424
                        case '1': _vl_vsss_setbit(owp,obits,lsb, 1, 1); lsb++; break;
425
                        case '_': break;
426
                        }
427
                    }
428
                    break;
429
                }
430
                case 'o': {
431
                    _vl_vsss_skipspace(fp,floc,fromp);
432
                    _vl_vsss_read(fp,floc,fromp, tmp, "01234567xz?_");
433
                    if (!tmp[0]) goto done;
434
                    int pos = strlen(tmp)-1;
435
                    for (int i=0; i<obits && pos>=0; pos--) {
436
                        switch(tmp[pos]) {
437
                        case 'x': case 'z': case '?': //FALLTHRU
438
                        case '0': lsb+=3; break;
439
                        case '1': _vl_vsss_setbit(owp,obits,lsb, 3, 1); lsb+=3; break;
440
                        case '2': _vl_vsss_setbit(owp,obits,lsb, 3, 2); lsb+=3; break;
441
                        case '3': _vl_vsss_setbit(owp,obits,lsb, 3, 3); lsb+=3; break;
442
                        case '4': _vl_vsss_setbit(owp,obits,lsb, 3, 4); lsb+=3; break;
443
                        case '5': _vl_vsss_setbit(owp,obits,lsb, 3, 5); lsb+=3; break;
444
                        case '6': _vl_vsss_setbit(owp,obits,lsb, 3, 6); lsb+=3; break;
445
                        case '7': _vl_vsss_setbit(owp,obits,lsb, 3, 7); lsb+=3; break;
446
                        case '_': break;
447
                        }
448
                    }
449
                    break;
450
                }
451
                case 'x': {
452
                    _vl_vsss_skipspace(fp,floc,fromp);
453
                    _vl_vsss_read(fp,floc,fromp, tmp, "0123456789abcdefxz?_");
454
                    if (!tmp[0]) goto done;
455
                    int pos = strlen(tmp)-1;
456
                    for (int i=0; i<obits && pos>=0; pos--) {
457
                        switch(tmp[pos]) {
458
                        case 'x': case 'z': case '?': //FALLTHRU
459
                        case '0': lsb+=4; break;
460
                        case '1': _vl_vsss_setbit(owp,obits,lsb, 4,  1); lsb+=4; break;
461
                        case '2': _vl_vsss_setbit(owp,obits,lsb, 4,  2); lsb+=4; break;
462
                        case '3': _vl_vsss_setbit(owp,obits,lsb, 4,  3); lsb+=4; break;
463
                        case '4': _vl_vsss_setbit(owp,obits,lsb, 4,  4); lsb+=4; break;
464
                        case '5': _vl_vsss_setbit(owp,obits,lsb, 4,  5); lsb+=4; break;
465
                        case '6': _vl_vsss_setbit(owp,obits,lsb, 4,  6); lsb+=4; break;
466
                        case '7': _vl_vsss_setbit(owp,obits,lsb, 4,  7); lsb+=4; break;
467
                        case '8': _vl_vsss_setbit(owp,obits,lsb, 4,  8); lsb+=4; break;
468
                        case '9': _vl_vsss_setbit(owp,obits,lsb, 4,  9); lsb+=4; break;
469
                        case 'a': _vl_vsss_setbit(owp,obits,lsb, 4, 10); lsb+=4; break;
470
                        case 'b': _vl_vsss_setbit(owp,obits,lsb, 4, 11); lsb+=4; break;
471
                        case 'c': _vl_vsss_setbit(owp,obits,lsb, 4, 12); lsb+=4; break;
472
                        case 'd': _vl_vsss_setbit(owp,obits,lsb, 4, 13); lsb+=4; break;
473
                        case 'e': _vl_vsss_setbit(owp,obits,lsb, 4, 14); lsb+=4; break;
474
                        case 'f': _vl_vsss_setbit(owp,obits,lsb, 4, 15); lsb+=4; break;
475
                        case '_': break;
476
                        }
477
                    }
478
                    break;
479
                }
480
                default:
481
                    string msg = string("%%Error: Unknown _vl_vsscanf code: ")+pos[0]+"\n";
482
                    vl_fatal(__FILE__,__LINE__,"",msg.c_str());
483
                    break;
484
                } // switch
485
 
486
                got++;
487
                // Reload data if non-wide (if wide, we put it in the right place directly)
488
                if (obits <= VL_BYTESIZE) {
489
                    CData* p = va_arg(ap,CData*); *p = owp[0];
490
                } else if (obits <= VL_SHORTSIZE) {
491
                    SData* p = va_arg(ap,SData*); *p = owp[0];
492
                } else if (obits <= VL_WORDSIZE) {
493
                    IData* p = va_arg(ap,IData*); *p = owp[0];
494
                } else if (obits <= VL_QUADSIZE) {
495
                    QData* p = va_arg(ap,QData*); *p = VL_SET_QW(owp);
496
                }
497
            }
498
            } // switch
499
        }
500
    }
501
  done:
502
    return got;
503
}
504
 
505
//===========================================================================
506
// File I/O
507
 
508
void _VL_VINT_TO_STRING(int obits, char* destoutp, WDataInP sourcep) {
509
    int lsb=obits-1;
510
    bool start=true;
511
    char* destp = destoutp;
512
    for (; lsb>=0; lsb--) {
513
        lsb = (lsb / 8) * 8; // Next digit
514
        IData charval = (sourcep[VL_BITWORD_I(lsb)]>>VL_BITBIT_I(lsb)) & 0xff;
515
        if (!start || charval) {
516
            *destp++ = (charval==0)?' ':charval;
517
            start = false;      // Drop leading 0s
518
        }
519
    }
520
    *destp++ = '\0'; // Terminate
521
    while (isspace(*(destp-1)) && destp>destoutp) *--destp = '\0';  // Drop trailing spaces
522
}
523
 
524
void _VL_STRING_TO_VINT(int obits, void* destp, int srclen, const char* srcp) {
525
    // Convert C string to Verilog format
526
    int bytes = VL_BYTES_I(obits);
527
    char* op = ((char*)(destp));
528
    if (srclen > bytes) srclen = bytes;  // Don't overflow destination
529
    int i;
530
    for (i=0; i<srclen; i++) { *op++ = srcp[srclen-1-i]; }
531
    for (; i<bytes; i++) { *op++ = 0; }
532
}
533
 
534
IData VL_FGETS_IXQ(int obits, void* destp, QData fpq) {
535
    FILE* fp = VL_CVT_Q_FP(fpq);
536
    if (VL_UNLIKELY(!fp)) return 0;
537
 
538
    // The string needs to be padded with 0's in unused spaces in front of
539
    // any read data.  This means we can't know in what location the first
540
    // character will finally live, so we need to copy.  Yuk.
541
    IData bytes = VL_BYTES_I(obits);
542
    char buffer[VL_TO_STRING_MAX_WORDS*VL_WORDSIZE+1];
543
    // V3Emit has static check that bytes < VL_TO_STRING_MAX_WORDS, but be safe
544
    if (VL_UNLIKELY(bytes > VL_TO_STRING_MAX_WORDS*VL_WORDSIZE)) {
545
        vl_fatal(__FILE__,__LINE__,"","Internal: fgets buffer overrun");
546
    }
547
 
548
    // We don't use fgets, as we must read \0s.
549
    IData got = 0;
550
    char* cp = buffer;
551
    while (got < bytes) {
552
        int c = getc(fp);
553
        if (c==EOF) break;
554
        *cp++ = c;  got++;
555
        if (c=='\n') break;
556
    }
557
 
558
    _VL_STRING_TO_VINT(obits, destp, got, buffer);
559
    return got;
560
}
561
 
562
QData VL_FOPEN_QI(QData filename, IData mode) {
563
    IData fnw[2];  VL_SET_WQ(fnw, filename);
564
    return VL_FOPEN_WI(2, fnw, mode);
565
}
566
QData VL_FOPEN_WI(int fnwords, WDataInP filenamep, IData mode) {
567
    char filenamez[VL_TO_STRING_MAX_WORDS*VL_WORDSIZE+1];
568
    _VL_VINT_TO_STRING(fnwords*VL_WORDSIZE, filenamez, filenamep);
569
    char modez[5];
570
    _VL_VINT_TO_STRING(VL_WORDSIZE, modez, &mode);
571
    return VL_CVT_FP_Q(fopen(filenamez,modez));
572
}
573
 
574
void VL_WRITEF(const char* formatp, ...) {
575
    va_list ap;
576
    va_start(ap,formatp);
577
    string output;
578
    _vl_vsformat(output, formatp, ap);
579
    va_end(ap);
580
 
581
    // Users can redefine VL_PRINTF if they wish.
582
    VL_PRINTF("%s", output.c_str());
583
}
584
 
585
void VL_FWRITEF(QData fpq, const char* formatp, ...) {
586
    FILE* fp = VL_CVT_Q_FP(fpq);
587
    if (VL_UNLIKELY(!fp)) return;
588
 
589
    va_list ap;
590
    va_start(ap,formatp);
591
    string output;
592
    _vl_vsformat(output, formatp, ap);
593
    va_end(ap);
594
 
595
    fputs(output.c_str(), fp);
596
}
597
 
598
IData VL_FSCANF_IX(QData fpq, const char* formatp, ...) {
599
    FILE* fp = VL_CVT_Q_FP(fpq);
600
    if (VL_UNLIKELY(!fp)) return 0;
601
 
602
    va_list ap;
603
    va_start(ap,formatp);
604
    IData got = _vl_vsscanf(fp, 0, NULL, formatp, ap);
605
    va_end(ap);
606
    return got;
607
}
608
 
609
IData VL_SSCANF_IIX(int lbits, IData ld, const char* formatp, ...) {
610
    IData fnw[2];  VL_SET_WI(fnw, ld);
611
 
612
    va_list ap;
613
    va_start(ap,formatp);
614
    IData got = _vl_vsscanf(NULL, lbits, fnw, formatp, ap);
615
    va_end(ap);
616
    return got;
617
}
618
IData VL_SSCANF_IQX(int lbits, QData ld, const char* formatp, ...) {
619
    IData fnw[2];  VL_SET_WQ(fnw, ld);
620
 
621
    va_list ap;
622
    va_start(ap,formatp);
623
    IData got = _vl_vsscanf(NULL, lbits, fnw, formatp, ap);
624
    va_end(ap);
625
    return got;
626
}
627
IData VL_SSCANF_IWX(int lbits, WDataInP lwp, const char* formatp, ...) {
628
    va_list ap;
629
    va_start(ap,formatp);
630
    IData got = _vl_vsscanf(NULL, lbits, lwp, formatp, ap);
631
    va_end(ap);
632
    return got;
633
}
634
 
635
void VL_READMEM_Q(bool hex, int width, int depth, int array_lsb, int,
636
                  QData ofilename, void* memp, IData start, IData end) {
637
    IData fnw[2];  VL_SET_WQ(fnw, ofilename);
638
    return VL_READMEM_W(hex,width,depth,array_lsb,2, fnw,memp,start,end);
639
}
640
 
641
void VL_READMEM_W(bool hex, int width, int depth, int array_lsb, int fnwords,
642
                  WDataInP ofilenamep, void* memp, IData start, IData end) {
643
    char ofilenamez[VL_TO_STRING_MAX_WORDS*VL_WORDSIZE+1];
644
    _VL_VINT_TO_STRING(fnwords*VL_WORDSIZE, ofilenamez, ofilenamep);
645
    FILE* fp = fopen(ofilenamez, "r");
646
    if (!fp) {
647
        // We don't report the Verilog source filename as it slow to have to pass it down
648
        vl_fatal (ofilenamez, 0, "", "$readmem file not found");
649
        return;
650
    }
651
    // Prep for reading
652
    IData addr = start;
653
    int linenum = 1;
654
    bool innum = false;
655
    bool ignore_to_eol = false;
656
    bool ignore_to_cmt = false;
657
    bool needinc = false;
658
    bool reading_addr = false;
659
    int lastc = ' ';
660
    // Read the data
661
    // We process a character at a time, as then we don't need to deal
662
    // with changing buffer sizes dynamically, etc.
663
    while (1) {
664
        int c = fgetc(fp);
665
        if (c==EOF) break;
666
        //printf("%d: Got '%c' Addr%x IN%d IgE%d IgC%d ninc%d\n", linenum, c, addr, innum, ignore_to_eol, ignore_to_cmt, needinc);
667
        if (c=='\n') { linenum++; ignore_to_eol=false; if (innum) reading_addr=false; innum=false; }
668
        else if (c=='\t' || c==' ' || c=='\r' || c=='\f') { if (innum) reading_addr=false; innum=false; }
669
        // Skip // comments and detect /* comments
670
        else if (ignore_to_cmt && lastc=='*' && c=='/') {
671
            ignore_to_cmt = false; if (innum) reading_addr=false; innum=false;
672
        } else if (!ignore_to_eol && !ignore_to_cmt) {
673
            if (lastc=='/' && c=='*') { ignore_to_cmt = true; }
674
            else if (lastc=='/' && c=='/') { ignore_to_eol = true; }
675
            else if (c=='/') {}  // Part of /* or //
676
            else if (c=='_') {}
677
            else if (c=='@') { reading_addr = true; innum=false; needinc=false; }
678
            // Check for hex or binary digits as file format requests
679
            else if (isxdigit(c)) {
680
                c = tolower(c);
681
                int value = (c >= 'a' ? (c-'a'+10) : (c-'0'));
682
                if (!innum) {  // Prep for next number
683
                    if (needinc) { addr++; needinc=false; }
684
                }
685
                if (reading_addr) {
686
                    // Decode @ addresses
687
                    if (!innum) addr=0;
688
                    addr = (addr<<4) + value;
689
                } else {
690
                    needinc = true;
691
                    //printf(" Value width=%d  @%x = %c\n", width, addr, c);
692
                    if (addr >= (IData)(depth+array_lsb) || addr < (IData)(array_lsb)) {
693
                        vl_fatal (ofilenamez, linenum, "", "$readmem file address beyond bounds of array");
694
                    } else {
695
                        int entry = addr - array_lsb;
696
                        QData shift = hex ? VL_ULL(4) : VL_ULL(1);
697
                        // Shift value in
698
                        if (width<=8) {
699
                            CData* datap = &((CData*)(memp))[entry];
700
                            if (!innum) { *datap = 0; }
701
                            *datap = ((*datap << shift) + value) & VL_MASK_I(width);
702
                        } else if (width<=16) {
703
                            SData* datap = &((SData*)(memp))[entry];
704
                            if (!innum) { *datap = 0; }
705
                            *datap = ((*datap << shift) + value) & VL_MASK_I(width);
706
                        } else if (width<=VL_WORDSIZE) {
707
                            IData* datap = &((IData*)(memp))[entry];
708
                            if (!innum) { *datap = 0; }
709
                            *datap = ((*datap << shift) + value) & VL_MASK_I(width);
710
                        } else if (width<=VL_QUADSIZE) {
711
                            QData* datap = &((QData*)(memp))[entry];
712
                            if (!innum) { *datap = 0; }
713
                            *datap = ((*datap << (QData)(shift)) + (QData)(value)) & VL_MASK_Q(width);
714
                        } else {
715
                            WDataOutP datap = &((WDataOutP)(memp))[ entry*VL_WORDS_I(width) ];
716
                            if (!innum) { VL_ZERO_RESET_W(width, datap); }
717
                            _VL_SHIFTL_INPLACE_W(width, datap, shift);
718
                            datap[0] |= value;
719
                        }
720
                        if (value>=(1<<shift)) {
721
                            vl_fatal (ofilenamez, linenum, "", "$readmemb (binary) file contains hex characters");
722
                        }
723
                    }
724
                }
725
                innum = true;
726
            }
727
            else {
728
                vl_fatal (ofilenamez, linenum, "", "$readmem file syntax error");
729
            }
730
        }
731
        lastc = c;
732
    }
733
    if (needinc) { addr++; needinc=false; }
734
 
735
    // Final checks
736
    fclose(fp);
737
    if (end != (IData)(~ VL_ULL(0))  && addr != (end+1)) {
738
        vl_fatal (ofilenamez, linenum, "", "$readmem file ended before specified ending-address");
739
    }
740
}
741
 
742
//===========================================================================
743
// Verilated:: Methods
744
 
745
const char* Verilated::catName(const char* n1, const char* n2) {
746
    // Returns new'ed data
747
    // Used by symbol table creation to make module names
748
    static char* strp = NULL;
749
    static int   len  = -1;
750
    int newlen = strlen(n1)+strlen(n2)+2;
751
    if (newlen > len) {
752
        if (strp) delete [] strp;
753
        strp = new char[newlen];
754
        len = newlen;
755
    }
756
    strcpy(strp,n1);
757
    strcat(strp,n2);
758
    return strp;
759
}
760
 
761
//===========================================================================
762
// VerilatedModule:: Methods
763
 
764
VerilatedModule::VerilatedModule(const char* namep)
765
    : m_namep(strdup(namep)) {
766
}
767
 
768
VerilatedModule::~VerilatedModule() {
769
    if (m_namep) free((void*)m_namep); m_namep=NULL;
770
}
771
 
772
//===========================================================================

powered by: WebSVN 2.1.0

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