FIJI.pm 52.5 KB
Newer Older
1
2
3
#-----------------------------------------------------------------------
# Fault InJection Instrumenter (FIJI)
# https://embsys.technikum-wien.at/projects/vecs/fiji
Christian Fibich's avatar
Christian Fibich committed
4
#
5
6
7
8
# The creation of this file has been supported by the publicly funded
# R&D project Josef Ressel Center for Verification of Embedded Computing
# Systems (VECS) managed by the Christian Doppler Gesellschaft (CDG).
#
9
10
11
# Authors:
# Christian Fibich <fibich@technikum-wien.at>
# Stefan Tauner <tauner@technikum-wien.at>
Christian Fibich's avatar
Christian Fibich committed
12
#
13
14
# This module is free software; you can redistribute it and/or modify
# it under the same terms as Perl itself.
Christian Fibich's avatar
Christian Fibich committed
15
#
16
17
18
19
20
21
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
#
# See the LICENSE file for more details.
#-----------------------------------------------------------------------
Christian Fibich's avatar
Christian Fibich committed
22

23
## @file FIJI.pm
Christian Fibich's avatar
Christian Fibich committed
24
# @brief Contains class \ref FIJI
25

26
## @class FIJI
Christian Fibich's avatar
Christian Fibich committed
27
# @brief Various constants used in the FIJI packages.
28

29
30
package FIJI;

31
32
33
use strict;
use warnings;

34
use Cwd;
35
36
37
use Cwd 'realpath';
use File::Spec;
use Log::Log4perl qw(:easy);
Stefan Tauner's avatar
Stefan Tauner committed
38

39
use constant FIJI_DIR => realpath(File::Spec->rel2abs("..", $FindBin::Bin));
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59

my $documentation_path;
BEGIN {
    my $pdf = 
        File::Spec->rel2abs(
            File::Spec->catfile(
                "..",
                "docs",
                "user_guide",
                "fiji_user_guide.pdf"
            ),
            $FindBin::Bin
        );
    
    eval { $pdf = realpath($pdf) };
    if ($@) {
        $pdf = undef;
    }
};
use constant FIJI_DOCUMENTATION_PATH => $documentation_path;
60

Stefan Tauner's avatar
Stefan Tauner committed
61
62
63
64
65
66
67
68
69
70
use constant FIJI_MEDIA_PATH => realpath(
    File::Spec->rel2abs(
        File::Spec->catfile(
            "..",
            "media",
        ),
        $FindBin::Bin
    )
);

71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87

my $version;
BEGIN {
    local $/ = undef;
    my $version_file = File::Spec->rel2abs(
        File::Spec->catfile(
            "..",
            "VERSION",
        ),
        $FindBin::Bin
    );
    open FILE, $version_file or die "Couldn't open VERSION file: $!";
    $version = <FILE>;
    close FILE;
};
use constant FIJI_VERSION => $version;

88
my @optimization_settings = qw(ALLOW OPT_OFF FIX_PLACEMENT);
89
use constant OPTIMIZATION_SETTINGS => \@optimization_settings;
90

91
92
93
94
95
96
#
# Maximal period polynomials for LFSRs of given lengths
# Thank you http://www.eej.ulst.ac.uk/~ian/modules/EEE515/files/old_files/lfsr/lfsr_table.pdf
# Our LFSR uses bit numbers are mirrored compared to the document above.
#
use constant LFSR_POLY_CHOICES => {
Christian Fibich's avatar
Christian Fibich committed
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
    2  => ['0x3'],
    3  => ['0x3'],
    4  => ['0x3'],
    5  => ['0x5', '0xF'],
    6  => ['0x3', '0x1B'],
    7  => ['0x3', '0xF'],
    8  => ['0x1D'],
    9  => ['0x11', '0x1B'],
    10 => ['0x9', '0x1B'],
    11 => ['0x5', '0x17'],
    12 => ['0x53'],
    13 => ['0x1B'],
    14 => ['0x2B'],
    15 => ['0x3', '0x17'],
    16 => ['0x2D'],
    17 => ['0x9', '0xF'],
    18 => ['0x81', '0x27'],
    19 => ['0x27'],
    20 => ['0x9', '0x53'],
    21 => ['0x5', '0x27'],
    22 => ['0x3', '0x39'],
    23 => ['0x21', '0x2B'],
    24 => ['0x1B'],
    25 => ['0x9', '0xF'],
    26 => ['0x47'],
    27 => ['0x27'],
    28 => ['0x9', '0x53'],
    29 => ['0x5', '0x17'],
    30 => ['0x53'],
    31 => ['0x9', '0xF'],
    32 => ['0xC5'],
    33 => ['0x2001', '0x53'],
    34 => ['0x119'],
    35 => ['0x5', '0x183'],
    36 => ['0x801', '0x183'],
    37 => ['0x53'],
    38 => ['0x63'],
    39 => ['0x11', '0x93'],
    40 => ['0x39'],
    41 => ['0x9', '0xF'],
    42 => ['0xA5'],
    43 => ['0x63'],
    44 => ['0x65'],
    45 => ['0x1B'],
    46 => ['0x1C1'],
    47 => ['0x21', '0x33'],
    48 => ['0x291'],
    49 => ['0x201', '0x71'],
    50 => ['0x1D'],
    51 => ['0x4B'],
    52 => ['0x9', '0x4B'],
    53 => ['0x47'],
    54 => ['0x149'],
    55 => ['0x1000001', '0x47'],
    56 => ['0x95'],
    57 => ['0x81', '0x2D'],
    58 => ['0x80001', '0x63'],
    59 => ['0x95'],
    60 => ['0x3', '0x35'],
    61 => ['0x27'],
    62 => ['0x69'],
    63 => ['0x3', '0x33'],
    64 => ['0x1B'],
160
161
};

162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
use constant FIJI_LOGO => <<logo_end;
FIJIFIJIFIJIFIJIFIJIFIJIFIJIFIJIFIJIFIJI
FIJIFIJIFIJIFIJIF   FIJIFIJIFIJIFIJIFIJI
FIJIFIJIFIJIFIJ    IFIJIFIJIFIJIFIJIFIJI
FIJIF       FI           IJIFIJIFIJIFIJI
FIJIFIJIFI            JIFIJIFIJIFIJIFIJI
FIJIFIJI            FIJIFIJIFIJIFIJIFIJI
FIJIFI     I   IFI   IJIFIJIFIJIFIJIFIJI
FIJIF         JIFIJ   JIFIJIFIJIFIJIFIJI
FIJIFIJIFI   IJIFIJI   IFIJIFIJIFIJIFIJI
FIJIFIJIF    IJIFIJIFIJIFIJIFIJIFIJIFIJI
FIJIFIJI    FIJIFIJIFIJIFIJIFIJIFIJIFIJI
FIJIFIJ     FIJIF           FIJIFIJIFIJI
FIJIFI     IFI      Fault      IFIJIFIJI
FIJIF             InJection     FIJIFIJI
FIJ              Instrumenter    IJIFIJI
F                                    IJI
FIJIFIJIFIJIFIJIFIJIFIJIFIJIFIJIFIJIFIJI
logo_end

182
183
184
185
#** @var public %designmap Hash containing all FIJI::Settings
#
# Architecture from http://www.perlmonks.org/?node_id=1072731
#
186
# Fields:
187
188
#    - ini_name     key name in FIJI Settings file
#    - unit         (optional) physical unit
189
#    - type         enables type-specific conversions and tests:
190
191
192
193
#                   - natural: values must be oct, hex, binary strings looking like a real number.
#                   - hexadecimal: values must be hexadecimal numbers.
#                   - boolean: will be convert to a truth value by Perl semantics
#                   - net: name of a net from the input netlist
194
#                   FIXME: complete docs (e.g., dut_port, external_port)
195
196
#    - values       (optional) used to restrict valid values. Can be...
#                   - an array reference listing all valid values (emulates an enum)
197
198
#                   - a code reference to a function that gets the new plus old values
#                     (as well as the value of the dependency if there is one) and
199
200
201
#                     returns true if the new value is allowed, or false otherwise.
#    - phases_opt   (optional) list of phases (subset of "setup", "instrument", "download")
#                   where no value must be present in input (e.g. ID is only necessary while downloading).
202
203
#    - phases_moot  (optional) list of phases (subset of "setup", "instrument", "download")
#                   where values present in the input are not validated at all.
204
#    - depends_on   (optional) specifies the key of another constant.
205
#                   The respective constant is only relevant (and thus required as input)
206
207
#                   if the value of the referenced constant is of type boolean and its value true.
#                   Additionally, the values function will get the value of the depends_on setting passed.
208
209
210
211
212
213
#    - group        (optional) specifies how to group this value in output. Value will not be displayed if undef
#    - order        (optional) specifies how to sort this value in output group
#    - noedit       (optional) display value, but don't allow to alter
#    - default      (optional) default value if not given in file and not determinable otherwise
#    - help         (optional) short help text, e.g. to be displayed via Tk:Balloon
#    - forbidden_by (optional) specifies the key of another constant
214
215
#                     The respective constant may not be enabled if the value
#                     of the referenced constant is true
216
my %designmap;
217

218
BEGIN {
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
    %designmap = (
        FIU_NUM => {
            description => "Number of FIUs",
            ini_name    => "FIU_NUM",
            type        => 'natural',
            phases_opt  => [qw(setup instrument download)],    # auto-generated if need be
        },
        FIU_CFG_BITS => {
            description => "Bits per FIU pattern",
            ini_name    => "FIU_CFG_BITS",
            default     => 3,
            type        => 'natural',
            phases_opt  => [qw(setup instrument download)],    # currently not user-configurable at all
        },
        CFGS_PER_MSG => {
234
            description => "Patterns sent per FIU configuration",
235
236
237
238
239
240
241
242
243
244
            ini_name    => "CFGS_PER_MSG",
            default     => 2,
            type        => 'natural',
            phases_opt  => [qw(setup instrument download)],    # currently not user-configurable at all
        },
        CLOCK_NET => {
            type        => 'net',
            description => "Clock net",
            help        => "Select a net in the DUT which shall be used to clock the FIJI logic",
            ini_name    => "CLOCK_NET",
245
            default     => "",
246
247
            phases_opt  => [qw(setup)],
            phases_moot => [qw(download)],
248
            group       => 'clock',
249
            order       => 10
250
251
252
253
254
255
256
257
258
259
260
        },
        FREQUENCY => {
            description => "Clock frequency",
            help        => "Enter the clock frequency in Hz.\n This information is needed e.g. to calculate the Baud rate prescaler",
            ini_name    => "FREQUENCY",
            default     => 50e6,
            type        => 'natural',
            phases_opt  => [qw(setup download)],
            unit        => 'Hz',
            group       => 'clock',
            order       => 20,
261
            values      => sub { return $_[0] > 0; },
262
263
264
        },
        OUTPUT_DIR => {
            description => "Output directory",
265
            help        => "Output directory for FIJI Instrument (relative to location of FIJI settings file)",
266
            ini_name    => "OUTPUT_DIR",
267
            default     => ".",
268
269
270
271
272
            type        => 'dir',
            group       => 'general_control',
            phases_opt  => [qw(setup)],
            order       => 5,
        },
273
        INST_LOG => {
274
            description => "Instrumentation log file",
275
            help        => "Log file for FIJI Instrumentation tool (relative to location of FIJI settings file)",
276
            ini_name    => "INST_LOG",
277
278
279
280
281
282
            default     => "fiji_instrument.log",
            type        => 'file',
            group       => 'general_control',
            phases_opt  => [qw(setup)],
            order       => 6,
        },
283
284
285
286
287
288
289
290
291
        BAUDRATE => {
            description => "Baud rate",
            help        => "Enter the Baud rate for communication between Host and FIJI logic.",
            ini_name    => "BAUDRATE",
            default     => 115200,
            type        => 'natural',
            unit        => 'bps',
            group       => 'general_control',
            order       => 10,
292
293
294
            depends_on  => "FREQUENCY",
            values      => sub {
                my ($baud, $old, $fclk) = @_;
295
                return 0 if $baud <= 0;
296
297
298
299
300
                if (defined $fclk) {
                    return $baud < $fclk;
                } else {
                    return 1;
                }
Christian Fibich's avatar
Christian Fibich committed
301
              }
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
        },
        ID => {
            description => "Design ID",
            help        => "The design ID is automatically calculated upon instrumentation.",
            ini_name    => "ID",
            type        => 'hexadecimal',
            phases_opt  => [qw(setup instrument)],                                              # generated in instrumentation
            noedit      => 1,
        },
        TIMER_WIDTH => {
            description => "Timer width",
            help        => "Enter the timer width in bytes.\n This influences the maximum fault duration.",
            ini_name    => "TIMER_WIDTH",
            default     => 4,
            type        => 'natural',
            unit        => 'bytes',
            values      => sub {
                my $val = shift;
Christian Fibich's avatar
Christian Fibich committed
320
                return ($val > 0 && $val <= 16);
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
            },
            group => 'general_control',
            order => 20,
        },
        LFSR_WIDTH => {
            description => "LFSR width",
            help        => "Enter the width of the LFSR in bits.\n The LFSR is used to emulate \"floating\" nets in the stuck-open model.",
            ini_name    => "LFSR_WIDTH",
            default     => 16,
            type        => 'natural',
            unit        => 'bits',
            values      => sub {
                my $val = shift;
                return $val > 0 && $val <= 64;
            },
            group => 'lfsr',
            order => 10,
        },
        LFSR_POLY => {
            description => "LFSR polynomial",
            help        => "Enter the polynomial for the LFSR.\n The LFSR is used to emulate \"floating\" nets in the stuck-open model.",
            ini_name    => "LFSR_POLY",
            default     => 0x2D,
344
            type        => 'lfsrpoly',
345
            unit        => 'hex',
346
            depends_on  => 'LFSR_WIDTH',
347
            values      => sub {
348
349
350
                my ($val, $old, $top) = @_;
                $top = 64 if !defined $top;
                return $val > 0 && $val <= (2**($top) - 1);
351
352
353
354
355
356
357
358
359
360
            },
            group => 'lfsr',
            order => 20,
        },
        LFSR_SEED => {
            description => "LFSR seed value",
            help        => "Enter the starting value for the LFSR.\n The LFSR is used to emulate \"floating\" nets in the stuck-open model.",
            ini_name    => "LFSR_SEED",
            default     => 0xCAFE,
            type        => 'hexadecimal',
361
            unit        => 'hex',
362
            depends_on  => 'LFSR_WIDTH',
363
            values      => sub {
364
365
366
                my ($val, $old, $top) = @_;
                $top = 64 if !defined $top;
                return $val > 0 && $val <= (2**($top) - 1);
367
368
369
370
371
372
            },
            group => 'lfsr',
            order => 30,
        },

        # External reset
373
        RST_EXT_EN => {
374
375
            description => "Use external reset",
            help        => "If enabled, the FIJI logic can be reset using an FPGA pin.",
376
            ini_name    => "RST_EXT_EN",
377
            type        => 'boolean',
378
379
            default     => 0,
            phases_opt  => ['setup'],
380
381
382
            group       => 'reset_external',
            order       => 10,
        },
383
        RST_EXT_ACT => {
384
385
            description => "External Reset: Active level",
            help        => "If enabled, the FIJI logic can be reset using an FPGA pin.",
386
            ini_name    => "RST_EXT_ACT",
387
388
389
            type        => 'bit',
            values      => [qw(0 1)],
            default     => '1',
390
            phases_opt  => ['setup', 'download'],
391
            depends_on  => 'RST_EXT_EN',
392
393
394
            group       => 'reset_external',
            order       => 20,
        },
395
        RST_EXT_IN_NAME => {
396
397
            description => "External Reset: Port name",
            help        => "Specify the name of the external reset port in the wrapper.\nThis port name must not exist in the toplevel.",
398
            ini_name    => "RST_EXT_IN_NAME",
Christian Fibich's avatar
Christian Fibich committed
399
            default     => "s_fiji_reset_i",
400
401
            phases_opt  => [qw(setup)],
            phases_moot => [qw(download)],
Christian Fibich's avatar
Christian Fibich committed
402
            type        => "external_port",
403
            group       => 'reset_external',
404
            depends_on  => 'RST_EXT_EN',
405
406
407
408
            order       => 30,
        },

        # Reset from DUT
409
        RST_DUT_OUT_EN => {
410
411
            description  => "Enable DUT-to-FIJI reset",
            help         => "If enabled, a net in the DUT is used as a reset source for the FIJI logic.",
412
            ini_name     => "RST_DUT_OUT_EN",
413
            type         => 'boolean',
414
415
            default      => 0,
            phases_opt  => ['setup'],
416
            group        => 'reset_from_dut',
417
            forbidden_by => 'RST_DUT_IN_EN',
418
419
            order        => 10,
        },
420
        RST_DUT_OUT_NAME => {
421
            description => "Source for DUT-to-FIJI reset",
422
            help        => "If enabled, a net in the DUT is used as a reset source for the FIJI logic.",
423
424
            ini_name    => "RST_DUT_OUT_NAME",
            depends_on  => 'RST_DUT_OUT_EN',
425
            type        => 'net',
426
            default     => "",
427
428
            phases_opt  => [qw(setup)],
            phases_moot => [qw(download)],
429
430
431
            group       => 'reset_from_dut',
            order       => 30,
        },
432
        RST_DUT_OUT_ACT => {
433
            description => "Active level of DUT-to-FIJI reset",
434
            help        => "If enabled, a net in the DUT is used as a reset source for the FIJI logic.",
435
            ini_name    => "RST_DUT_OUT_ACT",
436
437
438
            type        => 'bit',
            values      => [qw(0 1)],
            default     => '1',
439
            phases_opt  => ['setup'],
440
            depends_on  => 'RST_DUT_OUT_EN',
441
442
443
444
445
            group       => 'reset_from_dut',
            order       => 20,
        },

        # Reset to DUT
446
        RST_DUT_IN_EN => {
447
448
            description  => "Enable FIJI-to-DUT reset",
            help         => "If enabled, the DUT will be reset from the FIJI logic.",
449
            ini_name     => "RST_DUT_IN_EN",
450
            type         => 'boolean',
451
452
            default      => 0,
            phases_opt  => ['setup'],
453
            group        => 'reset_to_dut',
454
            forbidden_by => 'RST_DUT_OUT_EN',
455
456
            order        => 10,
        },
457
        RST_DUT_IN_NAME => {
458
459
            description => "Port for FIJI-to-DUT reset",
            help        => "The specified DUT reset input will be connected\n to the FIJI logic's reset output.",
460
            ini_name    => "RST_DUT_IN_NAME",
461
            default     => "",
462
            phases_opt  => [qw(setup download)],
463
            depends_on  => 'RST_DUT_IN_EN',
464
            type        => 'dut_port',
465
466
467
            group       => 'reset_to_dut',
            order       => 40,
        },
468
        RST_DUT_IN_DUR => {
469
470
            description => "Duration for FIJI-to-DUT reset",
            help        => "Enter the duration of each FIJI-to-DUT reset operation in clock cycles.",
471
            ini_name    => "RST_DUT_IN_DUR",
472
473
            type        => 'natural',
            default     => 1,
474
            phases_opt  => ['setup'],
475
476
477
478
479
            unit        => 'cycles',
            values      => sub {
                my $val = shift;
                return $val > 0 && $val <= 2**32 - 1;
            },
480
            depends_on => 'RST_DUT_IN_EN',
481
482
483
            group      => 'reset_to_dut',
            order      => 30,
        },
484
        RST_DUT_IN_ACT => {
485
            description => "Active level of FIJI-to-DUT reset",
486
            help        => "Enter the level the FIJI-to-DUT reset signal shall be brought to during reset.",
487
            ini_name    => "RST_DUT_IN_ACT",
488
489
490
            type        => 'bit',
            values      => [qw(0 1)],
            default     => '1',
491
            phases_opt  => ['setup'],
492
            depends_on  => 'RST_DUT_IN_EN',
493
494
495
496
497
            group       => 'reset_to_dut',
            order       => 20,
        },

        # Trigger from DUT
498
        TRIG_DUT_EN => {
499
500
            description => "Enable DUT-to-FIJI trigger",
            help        => "If enabled, a signal in the DUT can be selected to trigger fault injection operations.\n" . "Once a pattern is downloaded with the INTERNAL trigger enabled, the FIJI logic waits for\n" . "an inactive-to-active transition on this signal before starting to count down duration t1.",
501
            ini_name    => "TRIG_DUT_EN",
502
            type        => 'boolean',
503
504
            default     => 0,
            phases_opt  => ['setup'],
505
506
507
            group       => 'trigger',
            order       => 10,
        },
508

509
        TRIG_DUT_ACT => {
510
            description => "Active level of DUT-to-FIJI trigger",
511
            help        => "Select the signal level to trigger fault injection.",
512
            ini_name    => "TRIG_DUT_ACT",
513
514
515
            type        => 'bit',
            values      => [qw(0 1)],
            default     => '1',
516
            phases_opt  => ['setup'],
517
            depends_on  => 'TRIG_DUT_EN',
518
            group       => 'trigger',
519
520
521
            order       => 20,
        },

522
        TRIG_DUT_NAME => {
523
524
            description => "Source net for DUT-to-FIJI trigger",
            help        => "Select the net in the DUT which shall be used to trigger fault injection operations.",
525
            ini_name    => "TRIG_DUT_NAME",
526
            default     => "",
527
528
            phases_opt  => [qw(setup)],
            phases_moot => [qw(download)],
529
            depends_on  => 'TRIG_DUT_EN',
530
531
            type        => 'net',
            group       => 'trigger',
532
533
534
535
            order       => 30,
        },

        # External trigger
536
        TRIG_EXT_EN => {
537
538
            description => "Enable external trigger",
            help        => "If enabled, an I/O port can be selected to trigger fault injection operations.\n" . "Once a pattern is downloaded with the EXTERNAL trigger enabled, the FIJI logic waits for \n" . "an inactive-to-active transition on this port before starting to count down duration t1. \n" . "The port is synchronized to the FIJI logic's clock, thus introducing a few clock cycles delay.",
539
            ini_name    => "TRIG_EXT_EN",
540
            type        => 'boolean',
541
542
            default     => 0,
            phases_opt  => ['setup'],
543
544
545
            group       => 'trigger',
            order       => 40,
        },
546
        TRIG_EXT_ACT => {
547
            description => "Active level of external trigger",
548
            help        => "Select the port level to trigger fault injection.",
549
            ini_name    => "TRIG_EXT_ACT",
550
551
552
            type        => 'bit',
            values      => [qw(0 1)],
            default     => '1',
553
            phases_opt  => ['setup'],
554
            depends_on  => 'TRIG_EXT_EN',
555
556
557
            group       => 'trigger',
            order       => 50,
        },
558
        TRIG_EXT_IN_NAME => {
559
            description => "External trigger port name",
560
            help        => "Specify the name of the external trigger port in the wrapper.\nThis port name must not exist in the toplevel.",
561
            ini_name    => "TRIG_EXT_IN_NAME",
Christian Fibich's avatar
Christian Fibich committed
562
            type        => "external_port",
563
            default     => "s_fiji_trig_ext_i",
564
565
            phases_opt  => [qw(setup)],
            phases_moot => [qw(download)],
566
            depends_on  => 'TRIG_EXT_EN',
567
568
569
            group       => "trigger",
            order       => 60,
        },
570
        FD_1_EN => {
571
572
            description => "Enable fault-detect bit 1",
            help        => "If enabled, a signal in the DUT can be selected as a return channel.\n" . "This could e.g. be the output of a fault detection unit. \n" . "The FIJI logic registers inactive-to-active transition on this signal and returns the status \n" . "in the serial communication messages to the host.",
573
            ini_name    => "FD_1_EN",
574
575
            type        => 'boolean',
            default     => 0,
576
            phases_opt  => ['setup'],
577
578
579
            group       => 'fault_detect',
            order       => 10,
        },
580
        FD_1_NAME => {
581
582
            description => "Source net for fault-detect bit 1",
            help        => "Select the net in the DUT which shall be used for the fault detection feature.",
583
            ini_name    => "FD_1_NAME",
584
            type        => 'net',
585
            default     => "",
586
587
            phases_opt  => [qw(setup)],
            phases_moot => [qw(download)],
588
            depends_on  => 'FD_1_EN',
589
590
591
            group       => 'fault_detect',
            order       => 20,
        },
592
        FD_1_INVERT => {
593
594
            description => "Invert fault detect bit 1",
            help        => "Specifies if the selected net shall be inverted prior to edge detection.\n" . "Leave unchecked if the net uses positive logic.",
595
            ini_name    => "FD_1_INVERT",
596
597
598
            type        => 'boolean',
            values      => [qw(0 1)],
            default     => '0',
599
            phases_opt  => ['setup'],
600
            depends_on  => 'FD_1_EN',
601
602
603
            group       => 'fault_detect',
            order       => 30,
        },
604
        FD_2_EN => {
605
606
            description => "Enable fault-detect bit 2",
            help        => "If enabled, a signal in the DUT can be selected as a return channel.\n" . "This could e.g. be the output of a fault detection unit. \n" . "The FIJI logic registers inactive-to-active transition on this signal and returns the status \n" . "in the serial communication messages to the host.",
607
            ini_name    => "FD_2_EN",
608
609
            type        => 'boolean',
            default     => 0,
610
            phases_opt  => ['setup'],
611
612
613
            group       => 'fault_detect',
            order       => 40,
        },
614
        FD_2_NAME => {
615
616
            description => "Source net for fault-detect bit 2",
            help        => "Select the net in the DUT which shall be used for the fault detection feature.",
617
            ini_name    => "FD_2_NAME",
618
            type        => 'net',
619
            default     => "",
620
621
            phases_opt  => [qw(setup)],
            phases_moot => [qw(download)],
622
            depends_on  => 'FD_2_EN',
623
624
625
            group       => 'fault_detect',
            order       => 50,
        },
626
        FD_2_INVERT => {
627
628
            description => "Invert fault detect bit 2",
            help        => "Specify if the selected net shall be inverted prior to edge detection.\n" . "Leave unchecked if the net uses positive logic.",
629
            ini_name    => "FD_2_INVERT",
630
631
632
            type        => 'boolean',
            values      => [qw(0 1)],
            default     => '0',
633
            phases_opt  => ['setup'],
634
            depends_on  => 'FD_2_EN',
635
636
637
638
639
            group       => 'fault_detect',
            order       => 60,
        },
        RX_IN_NAME => {
            description => "RX port name",
640
            help        => "Specify the name of the Host-to-FIJI serial RX port in the wrapper.\nThis port name must not exist in the toplevel.",
641
            ini_name    => "RX_IN_NAME",
Christian Fibich's avatar
Christian Fibich committed
642
            type        => "external_port",
643
            default     => "s_fiji_rx_i",
644
645
            phases_opt  => [qw(setup)],
            phases_moot => [qw(download)],
646
            group       => "general_control",
Stefan Tauner's avatar
Stefan Tauner committed
647
            order       => 11,
648
649
650
        },
        TX_OUT_NAME => {
            description => "TX port name",
651
            help        => "Specify the name of the FIJI-to-Host serial TX port in the wrapper.\nThis port name must not exist in the toplevel.",
652
            ini_name    => "TX_OUT_NAME",
Christian Fibich's avatar
Christian Fibich committed
653
            type        => "external_port",
654
            default     => "s_fiji_tx_o",
655
656
            phases_opt  => [qw(setup)],
            phases_moot => [qw(download)],
657
            group       => "general_control",
Stefan Tauner's avatar
Stefan Tauner committed
658
            order       => 12,
659
        },
660
        OPTIMIZATIONS => {
661
            description => "Optimization Settings",
662
            help        => "Specifies which set of constraints to use in synthesis/P&R to\n- prevent optimizations and/or\n- fix physical placement.",
663
            ini_name    => "OPTIMIZATIONS",
664
            type        => "dropdown",
665
            values      => \@optimization_settings,
666
            default     => "ALLOW",
667
            phases_opt  => [qw(setup)],
668
669
670
            group       => "general_control",
            order       => 50,
        },
671
672
673
674
675
676
677
678
679
680
681
        SYNTHESIS_TOOL => {
            description => "Synthesis Tool",
            help        => "The FPGA synthesis tool that will be used. Needed for generating appropriate constraints.",
            ini_name    => "SYNTHESIS_TOOL",
            type        => "dropdown",
            values      => ["SYNPLIFY_PRO"],
            default     => "SYNPLIFY_PRO",
            phases_opt  => [qw(setup)],
            group       => "general_control",
            order       => 60,
        },
682
        IMPL_TOOL => {
683
684
            description => "Implementation Tool",
            help        => "The FPGA implementation tool that will be used. Needed for generating appropriate constraints.",
685
            ini_name    => "IMPL_TOOL",
686
            type        => "dropdown",
Christian Fibich's avatar
Christian Fibich committed
687
            values      => ["ALTERA_QUARTUS", "XILINX_VIVADO"],
688
689
690
691
692
            default     => "ALTERA_QUARTUS",
            phases_opt  => [qw(setup)],
            group       => "general_control",
            order       => 70,
        },
693
    );
694
695
}

696
697
698
use constant \%designmap;
use constant DESIGNMAP => \%designmap;

Christian Fibich's avatar
Christian Fibich committed
699
700
701
702
703
704
705
#** @var public %displaygroups Hash containing groups for displaying \ref designmap
##
# Fields:
#    -title         Just a short title
#    -subtitle      ...
#    -description   Longer description
#    -order         The sorting order to display this group
706
my %displaygroups;
707

708
709
710
711
712
BEGIN {
    %displaygroups = (
        fault_detect => {
            title       => "Fault Detection Settings",
            subtitle    => "",
Christian Fibich's avatar
Christian Fibich committed
713
714
            description => "Settings concerning internal fault detection propagation",
            order       => 80,
715
716
717
718
        },
        trigger => {
            title       => "Trigger Settings",
            subtitle    => "",
Christian Fibich's avatar
Christian Fibich committed
719
720
            description => "Settings concerning internal and external fault injection triggers",
            order       => 70,
721
722
        },
        reset_to_dut => {
723
            title       => "Reset from FIJI to DUT",
724
            subtitle    => "",
Christian Fibich's avatar
Christian Fibich committed
725
726
            description => "Settings concerning FIJI's ability to reset the DUT",
            order       => 60,
727
728
        },
        reset_from_dut => {
729
            title       => "Reset from DUT to FIJI",
730
            subtitle    => "",
Christian Fibich's avatar
Christian Fibich committed
731
732
            description => "Settings concerning FIJI's internal (from DUT) reset feature",
            order       => 50,
733
734
        },
        reset_external => {
735
736
            title       => "External Reset",
            subtitle    => "",
Christian Fibich's avatar
Christian Fibich committed
737
738
            description => "Settings concerning FIJI's external (via pin) reset feature",
            order       => 40,
739
740
741
742
        },
        lfsr => {
            title       => "LFSR Settings",
            subtitle    => "",
Christian Fibich's avatar
Christian Fibich committed
743
744
            description => "Settings concerning the LFSR for Stuck-open emulation",
            order       => 30,
745
746
        },
        general_control => {
747
            title       => "General settings",
748
            subtitle    => "",
749
            description => "Settings concerning miscellaneous features of FIJI",
Christian Fibich's avatar
Christian Fibich committed
750
            order       => 10,
751
752
753
754
        },
        clock => {
            title       => "Clock settings",
            subtitle    => "",
Christian Fibich's avatar
Christian Fibich committed
755
756
            description => "Settings concerning the clocking of the FIJI logic",
            order       => 20,
757
758
759
760
761
762
        },
        fius => {
            title       => "FIUs",
            subtitle    => "",
            description => "Settings concerning Fault Injection Units",
            order       => 100
763
        }
764
    );
765
}
766

767
768
use constant \%displaygroups;
use constant DISPLAYGROUPS => \%displaygroups;
769
use constant DISPLAYGROUPS_FIU_KEY => 'fius';
770

Christian Fibich's avatar
Christian Fibich committed
771
772
773
774
775
776
777
778
779
## @var public %fiumap Hash containing all FIJI::Settings for FIUs
#
# Fields:
#    - ini_name     key name in FIJI Settings file
#    - unit         (optional) physical unit
#    - type         (optional) enables type-specific conversions and tests:
#                   - natural: values must be oct, hex, binary strings looking like a real number.
#                   - hexadecimal: values must be hexadecimal numbers.
#                   - boolean: will be convert to a truth value by Perl semantics
780
#                   - net: hierarchical path of a net from the input netlist
781
#                   - driver: driver-specific hierarchical path of a net from the input netlist
Christian Fibich's avatar
Christian Fibich committed
782
783
784
785
786
787
788
#    - values       (optional) used to restrict valid values. Can be...
#                   - an array reference listing all valid values (emulates an enum)
#                   - a code reference to a function that gets the new and old values and
#                     returns true if the new value is allowed, or false otherwise.
#    - phases_opt   (optional) list of phases (subset of "setup", "instrument", "download")
#                   where no value must be present in input (e.g. ID is only necessary while downloading).
#    - group        (optional) specifies how to group this value in output. Value will not be displayed if undef
789
790
791
#    - default      (optional) default value if not given in file and not determinable otherwise.
#                   Can either be a scalar or a function pointer expecting following parameters:
#                   related FIJI settings hash, the tool phase, FIJI design settings, FIU number.
792
my %fiumap;
793

794
BEGIN {
795
    %fiumap = (
796
797
798
799
800
801
        FIU_NAME => {
            ini_name => "NAME",
            default  => "",
            help     => "Display name for this FIU",
            phases_opt => [qw(setup instrument download)]
        },
802
803
804
        FIU_NET_NAME => {
            ini_name   => "NET_NAME",
            default    => "",
805
806
            type       => 'net',
            help       => "String representation of the instrumented net.",
807
808
            phases_opt  => [qw(setup)], # Either FIU or net name is strongly recommended during download
            phases_moot => [qw(download)],
809
810
811
812
        },
        FIU_DRIVER_TYPE => {
            ini_name   => "DRIVER_TYPE",
            values     => [qw(PIN PORT ASSIGN)],
813
            default    => "PIN",
814
815
816
817
818
            phases_opt => [qw(setup)],
        },
        FIU_DRIVER_PATH => {
            ini_name   => "DRIVER_PATH",
            default    => "",
819
            type       => 'driver',
820
            help       => "String representation of a driver.",
821
822
            phases_opt  => [qw(setup)], # Either FIU or net name is strongly recommended during download
            phases_moot => [qw(download)],
823
824
825
826
827
        },
        FIU_MODEL => {
            ini_name   => "FAULT_MODEL",
            default    => "RUNTIME",
            values     => [qw(RUNTIME PASS_THRU STUCK_AT_0 STUCK_AT_1 STUCK_OPEN DELAY SEU)],
828
            help       => "Possible fault models: no fault (PASS_THRU), a single mode that can be switched on and off, or selection and activation of the type at RUNTIME.",
829
830
831
832
            phases_opt => [qw(setup)],
        },
        FIU_LFSR_MASK => {
            ini_name   => "LFSR_MASK",
833
834
835
836
837
838
            default    => sub {
                my ($consts_ref, $phase, $design_ref, $i) = @_;
                $i = 0 if !defined($i);
                my $mask_width = defined($design_ref) && defined($design_ref->{'LFSR_WIDTH'}) ? $design_ref->{'LFSR_WIDTH'} : 1;
                return 1 << ($i % $mask_width);
            },
839
840
841
842
843
844
845
846
847
848
849
            values     => sub {
                my ($val, $old, $map_ref, $consts_ref, $lfsr_width) = @_;
                return 0 if $val <= 0;
                # If the width is bogus, we cannot do much but ignore them here
                # FIXME: we should not ever get hex numbers in lfsr_width, however we do
                # because they don't get stored as numbers in the settings
                return 1 if (!defined($lfsr_width) || $lfsr_width !~ /^[1-9][0-9]*$/);
                my $mask_width = log($val+1)/log(2);
                return $lfsr_width >= $mask_width;
            },
            depends_on => 'LFSR_WIDTH',
850
            type       => 'hexadecimal',
851
            help       => "Selects the bits of the LFSR that are ANDed together to determine the value of a floating net.",
852
853
854
            phases_opt => [qw(setup)],
        },
    );
855
856
857
858
}

use constant \%fiumap;
use constant FIUMAP => \%fiumap;
859

Christian Fibich's avatar
Christian Fibich committed
860
861
862
863
864
865
866
867
868
869
870
871
#** @var public %testconstmap Hash containing all global values of FIJI::Tests
#
# Fields:
#    - ini_name     key name in FIJI Tests file
#    - unit         (optional) physical unit
#    - type         (optional) enables type-specific conversions and tests:
#                   - natural: values must be oct, hex, binary strings looking like a real number.
#                   - hexadecimal: values must be hexadecimal numbers.
#                   - boolean: will be convert to a truth value by Perl semantics
#                   - net: name of a net from the input netlist
#    - values       (optional) used to restrict valid values. Can be...
#                   - an array reference listing all valid values (emulates an enum)
872
873
#                   - a code reference to a function that gets the old value and current settings and
#                     returns the allowed value(s).
Christian Fibich's avatar
Christian Fibich committed
874
875
876
877
#    - phases_opt   (optional) list of phases (subset of "setup", "instrument", "download")
#                   where no value must be present in input (e.g. ID is only necessary while downloading).
#    - gui_modes    (optional) specifies in which mode of {manual,auto,random} this key will be displayed in the GUI
#    - depends_on   (optional) specifies the key of another constant.
878
879
880
#                   The respective constant is only relevant (and thus required as input)
#                   if the value of the referenced constant is of type boolean and its value true.
#                   Additionally, the values function will get the value of the depends_on setting passed.
Christian Fibich's avatar
Christian Fibich committed
881
#    - order        (optional) specifies how to sort this value in output group
882
#    - default      (optional) default value if not given in file and not determinable otherwise.
883
#                   Can either be a scalar or a function pointer expecting a FIJI settings reference.
Christian Fibich's avatar
Christian Fibich committed
884
885
886
#    - help         (optional) short help text, e.g. to be displayed via Tk:Balloon
#                     The respective constant may not be enabled if the value
#                     of the referenced constant is true
887
my %testconstmap;
888

889
BEGIN {
890
891
892
893
894
895
896
897
898
    %testconstmap = (
        FIJI_CFG => {
            description => "FIJI Settings File",
            ini_name    => "FIJI_CFG",
            default     => "fiji.cfg",

            #gui_modes   => [qw (manual auto random)],
        },
        UART => {
899
            description => "Control UART",
900
            ini_name    => "UART",
901
902
903
904
            default     => sub {
                my $devs = FIJI::Utils::get_uart_devs();
                return (scalar(@$devs) > 0) ? @{$devs}[0] : "";
            },
Christian Fibich's avatar
Christian Fibich committed
905
            help        => "The host's serial port connected to FIJI.\nLinux/Unix: /dev/ttyUSBx, /dev/ttyACMx, /dev/ttySx\nWindows: COMx",
906
            type        => "autocomplete",
907
908
        },
        HALT_ON_FAULT_DETECT => {
Christian Fibich's avatar
Christian Fibich committed
909
910
911
912
913
914
915
            description           => "Halt on detected fault?",
            ini_name              => "HALT_ON_FAULT_DETECT",
            default               => 1,
            type                  => 'boolean',
            phases_opt            => [qw(manual)],
            gui_modes             => [qw (auto random)],
            order                 => 10,
916
            activated_by_settings => sub {
Christian Fibich's avatar
Christian Fibich committed
917
                my $settings = shift;
918
                return ($settings->{'design'}->{'FD_1_EN'} == 1 || $settings->{'design'}->{'FD_2_EN'} == 1);
919
            },
Christian Fibich's avatar
Christian Fibich committed
920
            help                  => "Specify if the injection campaign shall be aborted when a fault has been detected"
921
922
923
924
925
926
927
928
929
930
931
932
933
        },
        NUM_TESTS => {
            ini_name   => "NUM_TESTS",
            type       => 'natural',
            phases_opt => [qw(manual)],
        },
        REPEAT => {
            description => "Repeat Injection?",
            ini_name    => "REPEAT",
            default     => 0,
            type        => 'boolean',
            phases_opt  => [qw(manual)],
            gui_modes   => [qw (auto)],
934
            order       => 12,
Christian Fibich's avatar
Christian Fibich committed
935
            help        => "Specify if the injection campaign shall start again after the last test",
936
937
938
939
940
941
942
943
        },
        REPEAT_OFFSET => {
            description => "Repetition start pattern",
            ini_name    => "REPEAT_OFFSET",
            default     => 0,
            type        => 'natural',
            phases_opt  => [qw(manual)],
            gui_modes   => [qw (auto)],
944
            order       => 13,
945
            depends_on  => "REPEAT",
Christian Fibich's avatar
Christian Fibich committed
946
            help        => "Specify an offset for all repetitions except the first"
947
        },
948
949
950
951
952
953
954
955
956
957
958
959
        REPEAT_NUM => {
            description => "Number of repetitions",
            ini_name    => "REPEAT_NUM",
            default     => 0,
            type        => 'natural',
            phases_opt  => [qw(manual)],
            gui_modes   => [qw (auto)],
            order       => 14,
            depends_on  => "REPEAT",
            help        => "Specify a number of repetitions"
        },

960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
        HALT_ON_UART_ERROR => {
            ini_name   => "HALT_ON_UART_ERROR",
            default    => 1,
            type       => 'boolean',
            phases_opt => [qw(manual)],
        },
        HALT_ON_CRC_ERROR => {
            ini_name   => "HALT_ON_CRC_ERROR",
            default    => 1,
            type       => 'boolean',
            phases_opt => [qw(manual)],
        },
        HALT_ON_ID_ERROR => {
            ini_name   => "HALT_ON_ID_ERROR",
            default    => 1,
            type       => 'boolean',
            phases_opt => [qw(manual)],
        },
        HALT_ON_UNDERRUN => {
979
980
981
982
983
984
985
            description => "Halt on buffer underrun?",
            ini_name    => "HALT_ON_UNDERRUN",
            default     => 0,
            type        => 'boolean',
            phases_opt  => [qw(manual)],
            gui_modes   => [qw (auto random)],
            order       => 11,
Christian Fibich's avatar
Christian Fibich committed
986
            help        => "Specify if the injection campaign shall be halted when the FIC reported that a pattern did not arrive in time."
987
988
989
990
991
992
993
994
995
        },
        MULTIFAULT => {
            description => "Generate multiple faults per pattern?",
            ini_name    => "MULTIFAULT",
            default     => 1,
            type        => 'boolean',
            phases_opt  => [qw(manual auto)],
            gui_modes   => [qw (random)],
            order       => 60,
Christian Fibich's avatar
Christian Fibich committed
996
            help        => "Allow multiple FIUs to generate errors within one pattern"
997
        },
998
        MIN_DUR_T1 => {
999
            description => "Minimum Duration T1",
1000
            ini_name    => "MIN_DUR_T1",
1001
            default     => sub {shift->default_timer_value()},
1002
1003
1004
            phases_opt  => [qw(manual auto)],
            gui_modes   => [qw (random)],
            type        => "min_duration",
1005
            matching    => "MAX_DUR_T1",
1006
            unit        => "cycles",
1007
            order       => 20,
Christian Fibich's avatar
Christian Fibich committed
1008
            help        => "Minimum duration before the first fault is applied."
1009
        },
1010
        MIN_DUR_T2 => {
1011
            description => "Minimum Duration T2",
1012
            ini_name    => "MIN_DUR_T2",
1013
            default     => sub {shift->default_timer_value()},
1014
1015
1016
            phases_opt  => [qw(manual auto)],
            gui_modes   => [qw (random)],
            type        => "min_duration",
1017
            matching    => "MAX_DUR_T2",
1018
            unit        => "cycles",
1019
            order       => 40,
Christian Fibich's avatar
Christian Fibich committed
1020
            help        => "Minimum duration to keep the first fault is enabled."
1021
        },
1022
        MAX_DUR_T1 => {
1023
            description => "Maximum Duration T1",