Project

General

Profile

[logo] 
 
Home
About/Contact
Major Tools
  Dinotrace
  Verilator
  Verilog-mode
  Verilog-Perl
Other Tools
  IPC::Locker
  Parallel::Forker
  Voneline
General Info
  Papers

allow-strings-in-option-file.patch

Version 4 of the proposal - Yves Mathieu, 10/24/2019 09:34 AM

Download (10.9 KB)

View differences:

src/V3Options.cpp
1236 1236
    fl = new FileLine(filename);
1237 1237

  
1238 1238
    // Split into argument list and process
1239
    // Note we don't respect quotes.  It seems most simulators dont.
1240
    // Woez those that expect it; we'll at least complain.
1241
    if (whole_file.find('\"') != string::npos) {
1242
        fl->v3error("Double quotes in -f files cause unspecified behavior.");
1243
    }
1239
    // Note we try to respect escaped char, double/simple quoted strings
1240
    // Other simulators dont respect a common syntax...
1244 1241

  
1245 1242
    // Strip off arguments and parse into words
1246 1243
    std::vector<string> args;
1247
    string::size_type startpos = 0;
1248
    while (startpos < whole_file.length()) {
1249
        while (isspace(whole_file[startpos])) ++startpos;
1250
        string::size_type endpos = startpos;
1251
        while (endpos < whole_file.length() && !isspace(whole_file[endpos])) ++endpos;
1252
        if (startpos != endpos) {
1253
            string arg (whole_file, startpos, endpos-startpos);
1254
            args.reserve(args.size()+1);
1255
            args.push_back(arg);
1256
        }
1257
        startpos = endpos;
1244
    string::size_type pos = 0;
1245

  
1246
    // parse file using a state machine, taking into account quoted strings and escaped chars
1247
    enum state { ST_IN_OPTION,
1248
                 ST_ESCAPED_CHAR,
1249
                 ST_IN_QUOTED_STR,
1250
                 ST_IN_DOUBLE_QUOTED_STR};
1251

  
1252
    state st = ST_IN_OPTION;
1253
    state last_st;
1254
    string arg("");
1255
    while (pos < whole_file.length()) {
1256
       char curr_char = whole_file[pos];
1257
       switch (st) {
1258
           case ST_IN_OPTION:  // Get all chars up to a white space or a "="
1259
               if (isspace(curr_char)) {  // end of option
1260
                  if (!arg.empty()) {  // end of word
1261
                       //args.reserve(args.size()+1);
1262
                       args.push_back(arg);
1263
                   }
1264
                   arg = "";
1265
                   break;
1266
               }
1267
               if (curr_char == '\\') {  // Escape char, we wait for next char
1268
                   last_st = st;  // memorize current state
1269
                   st = ST_ESCAPED_CHAR;
1270
                   break;
1271
               }
1272
               if (curr_char == '\'') {  // find begin of quoted string
1273
                    // Examine next char in order to decide between
1274
                    // a string or a base specifier for integer literal
1275
                    ++pos;
1276
                    if(pos <  whole_file.length()) curr_char = whole_file[pos];
1277
                    if(curr_char == '"') {  // string
1278
                       st = ST_IN_QUOTED_STR;
1279
                    } else {  // base specifier
1280
                       arg += '\'';
1281
                    }
1282
                    arg +=  curr_char;
1283
                    break;
1284
               }
1285
               if (curr_char == '"') {  // find begin of double quoted string
1286
                    // doesn't insert char
1287
                    st = ST_IN_DOUBLE_QUOTED_STR;
1288
                    break;
1289
               }
1290
               arg += curr_char;
1291
               break;
1292

  
1293
           case ST_IN_QUOTED_STR:  // just store all chars inside string
1294
               if (curr_char != '\'') {
1295
                  arg += curr_char;
1296
               } else {  // End of quoted string
1297
                  st = ST_IN_OPTION;
1298
               }
1299
               break;
1300

  
1301
           case ST_IN_DOUBLE_QUOTED_STR:  // takes into account escaped chars
1302
               if (curr_char != '"') {
1303
                  if (curr_char == '\\') {
1304
                     last_st = st;  // memorize current state
1305
                     st = ST_ESCAPED_CHAR;
1306
                  } else {
1307
                    arg += curr_char;
1308
                  }
1309
               } else {  // End of double quoted string
1310
                  st = ST_IN_OPTION;
1311
               }
1312
               break;
1313

  
1314
           case ST_ESCAPED_CHAR:  // Just add the escaped char
1315
               arg += curr_char;
1316
               st = last_st;  // and return to last state
1317
               break;
1318

  
1319
       }
1320
       ++pos;
1321
    }
1322
    if (!arg.empty()) {  // add last word
1323
        args.reserve(args.size()+1);
1324
        args.push_back(arg);
1258 1325
    }
1259 1326

  
1260 1327
    // Path
test_regress/t/t_flag_define.v
2 2
//
3 3
// This file ONLY is placed into the Public Domain, for any use,
4 4
// without warranty, 2014 by Wilson Snyder
5
//
6
// Special cases of "string parameters" :
7
// This table compares obtain results from big-3 simulators to Verilator
8
// expected behavior. Base specified integer literals are also included as
9
// string detection may impact results for such cases.
10
//
11
// | In the options file       | simulator 1 | simulator 2 | simulator 3 | verilator   |
12
// |----------------------- ---|-------------|-------------|-------------|-------------|
13
// | +define+C0='"AB CD"'      | AB CD       | UNSUPPORTED | AB CD       | AB CD       |
14
// | +define+C1=\"AB\ CD\"     | AB CD       | UNSUPPORTED | AB CD       | AB CD       |
15
// | +define+C2="\"AB CD\""    | AB CD       | AB CD       | UNSUPPORTED | AB CD       |
16
// | +define+C3="\"AB\ CD\""   | AB CD       | AB CD       | UNSUPPORTED | AB CD       |
17
// | +define+C4=32'h600D600D   | UNSUPPORTED | 32'h600D600D| 32'h600D600D| 32'h600D600D|
18
// | +define+C5=32\'h600D600D  | 32'h600D600D| UNSUPPORTED | UNSUPPORTED | 32'h600D600D|
19
// | +define+C6="32'h600D600D" | 32'h600D600D| 32'h600D600D| 32'h600D600D| 32'h600D600D|
20
// | +define+C7='AB CD'        | AB CD       | UNSUPPORTED | UNSUPPORTED | UNSUPPORTED |
5 21

  
6 22
`define STRINGIFY(x) `"x`"
7 23

  
......
55 71
      $write("%%Error: Missing define\n"); $stop;
56 72
`endif
57 73

  
74
`ifdef STRING1
75
      if (`STRING1 !== "New String") $stop;
76
`else
77
      $write("%%Error: Missing define\n"); $stop;
78
`endif
79

  
80
`ifdef STRING2
81
      if (`STRING2 !== "New String") $stop;
82
`else
83
      $write("%%Error: Missing define\n"); $stop;
84
`endif
85

  
86
`ifdef STRING3
87
      if (`STRING3 !== "New String") $stop;
88
`else
89
      $write("%%Error: Missing define\n"); $stop;
90
`endif
91

  
92
`ifdef LIT1
93
      if (`STRINGIFY(`LIT1) !== "32'h600D600D") $stop;
94
`else
95
      $write("%%Error: Missing define\n"); $stop;
96
`endif
97

  
98
`ifdef LIT2
99
      if (`STRINGIFY(`LIT2) !== "32'h600D600D") $stop;
100
`else
101
      $write("%%Error: Missing define\n"); $stop;
102
`endif
103

  
104
`ifdef LIT3
105
      if (`STRINGIFY(`LIT3) !== "32'h600D600D") $stop;
106
`else
107
      $write("%%Error: Missing define\n"); $stop;
108
`endif
109

  
58 110
      $write("*-* All Finished *-*\n");
59 111
      $finish;
60 112
   end
test_regress/t/t_flag_define.vc
5 5
+define+D5A=VALA+D5B=VALB
6 6
// Quotes do NOT escape the plus
7 7
//+define+D5A="VALA+D5B"+D5C
8
+define+STRING1="\"New String\""
9
+define+STRING2='"New String"'
10
+define+STRING3=\"New\ String\"
11
+define+LIT1=32'h600D600D
12
+define+LIT2=32\'h600D600D
13
+define+LIT3="32'h600D600D"
test_regress/t/t_flag_parameter.pl
11 11

  
12 12
compile(
13 13
    # It is not possible to put them into the options file
14
    v_flags2 => ['-Gstring1="\"New String\"" -pvalue+string2="\"New String\"" -f t/t_flag_parameter.vc'],
14
    v_flags2 => ['-f t/t_flag_parameter.vc'],
15 15
    );
16 16

  
17 17
execute(
test_regress/t/t_flag_parameter.v
2 2
//
3 3
// This file ONLY is placed into the Public Domain, for any use,
4 4
// without warranty, 2016 by Wilson Snyder
5
//
6
// Special cases of "string parameters" :
7
// This table compares obtain results from big-3 simulators to Verilator
8
// expected behavior. Base specified integer literals are also included as
9
// string detection may impact results for such cases.
10
//
11
// | Option/Param file   | simulator 1 | simulator 2 | simulator 3 | verilator   |
12
// |---------------------|-------------|-------------|-------------|-------------|
13
// | -gC0='"AB CD"'      | AB CD       | UNSUPPORTED | AB CD       | AB CD       |
14
// | -gC1=\"AB\ CD\"     | AB CD       | UNSUPPORTED | UNSUPPORTED | AB CD       |
15
// | -gC2="\"AB CD\""    | AB CD       | AB CD       | AB CD       | AB CD       |
16
// | -gC3="\"AB\ CD\""   | AB CD       | AB\\ CD     | AB CD       | AB CD       |
17
// | -gC4=32'h600D600D   | UNSUPPORTED | 32'h600D600D| 32'h600D600D| 32'h600D600D|
18
// | -gC5=32\'h600D600D  | 32'h600D600D| UNSUPPORTED | UNSUPPORTED | 32'h600D600D|
19
// | -gC6="32'h600D600D" | 32'h600D600D| 32'h600D600D| UNSUPPORTED | 32'h600D600D|
20
// | -gC7='AB CD'        | AB CD       | UNSUPPORTED | UNSUPPORTED | UNSUPPORTED |
5 21

  
6 22
`define check(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: Wrong parameter value", `__FILE__,`__LINE__); $stop; end while(0);
7 23

  
8 24
module t;
9 25
   parameter string1 = "Original String";
10 26
   parameter string2 = "Original String";
27
   parameter string11 = "Original String";
28
   parameter string12 = "Original String";
29
   parameter string21 = "Original String";
30
   parameter string22 = "Original String";
11 31

  
12 32
   parameter real11 = 0.1;
13 33
   parameter real12 = 0.1;
......
24 44
   parameter int32 = 1;
25 45
   parameter int41 = 1;
26 46
   parameter int42 = 1;
47
   parameter int51 = 1;
48
   parameter int52 = 1;
49
   parameter int61 = 1;
50
   parameter int62 = 1;
27 51

  
28 52
   initial begin
29 53
      `check(string1,"New String");
30 54
      `check(string2,"New String");
55
      `check(string11,"New String");
56
      `check(string12,"New String");
57
      `check(string21,"New String");
58
      `check(string22,"New String");
31 59
      `check(real11,0.2);
32 60
      `check(real12,0.2);
33 61
      `check(real21,400);
......
42 70
      `check(int32,123);
43 71
      `check(int41,32'hdeadbeef);
44 72
      `check(int42,32'hdeadbeef);
73
      `check(int51,32'hdeadbeef);
74
      `check(int52,32'hdeadbeef);
75
      `check(int61,32'hdeadbeef);
76
      `check(int62,32'hdeadbeef);
45 77

  
46 78
      $write("*-* All Finished *-*\n");
47 79
      $finish;
test_regress/t/t_flag_parameter.vc
1
-Gstring1="\"New String\""
2
-pvalue+string2="\"New String\""
3
-Gstring11='"New String"'
4
-pvalue+string12='"New String"'
5
-Gstring21=\"New\ String\"
6
-pvalue+string22=\"New\ String\"
1 7
-Greal11=0.2
2 8
-pvalue+real12=0.2
3 9
-Greal21=4e2
......
12 18
-pvalue+int32=123
13 19
-Gint41=32'hdead_beef
14 20
-pvalue+int42=32'hdead_beef
21
-Gint51=32\'hdead_beef
22
-pvalue+int52=32\'hdead_beef
23
-Gint61="32'hdead_beef"
24
-pvalue+int62="32'hdead_beef"