|  line  | 
 stmt  | 
 bran  | 
 cond  | 
 sub  | 
 pod  | 
 time  | 
 code  | 
| 
1
 | 
  
 
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 package VIC::PIC::Gpsim;  | 
| 
2
 | 
34
 | 
 
 | 
 
 | 
  
34
  
 | 
 
 | 
195
 | 
 use strict;  | 
| 
 
 | 
34
 | 
 
 | 
 
 | 
 
 | 
 
 | 
72
 | 
    | 
| 
 
 | 
34
 | 
 
 | 
 
 | 
 
 | 
 
 | 
798
 | 
    | 
| 
3
 | 
34
 | 
 
 | 
 
 | 
  
34
  
 | 
 
 | 
139
 | 
 use warnings;  | 
| 
 
 | 
34
 | 
 
 | 
 
 | 
 
 | 
 
 | 
49
 | 
    | 
| 
 
 | 
34
 | 
 
 | 
 
 | 
 
 | 
 
 | 
674
 | 
    | 
| 
4
 | 
34
 | 
 
 | 
 
 | 
  
34
  
 | 
 
 | 
559
 | 
 use bigint;  | 
| 
 
 | 
34
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2830
 | 
    | 
| 
 
 | 
34
 | 
 
 | 
 
 | 
 
 | 
 
 | 
198
 | 
    | 
| 
5
 | 
34
 | 
 
 | 
 
 | 
  
34
  
 | 
 
 | 
59930
 | 
 use Carp;  | 
| 
 
 | 
34
 | 
 
 | 
 
 | 
 
 | 
 
 | 
66
 | 
    | 
| 
 
 | 
34
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1361
 | 
    | 
| 
6
 | 
34
 | 
 
 | 
 
 | 
  
34
  
 | 
 
 | 
524
 | 
 use Pegex::Base; # use this instead of Mo  | 
| 
 
 | 
34
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1563
 | 
    | 
| 
 
 | 
34
 | 
 
 | 
 
 | 
 
 | 
 
 | 
157
 | 
    | 
| 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 our $VERSION = '0.32';  | 
| 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 $VERSION = eval $VERSION;  | 
| 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
11
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 has type => 'gpsim';  | 
| 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
13
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 has include => 'coff.inc';  | 
| 
14
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 has pic => undef; # refer to the PIC object  | 
| 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
17
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 has node_count => 0;  | 
| 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
19
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 has scope_channels => 0;  | 
| 
20
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
21
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 has stimulus_count => 0;  | 
| 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
23
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 has should_autorun => 0;  | 
| 
24
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
25
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 has disable => 0;  | 
| 
26
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
27
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub supports_modifier {  | 
| 
28
 | 
12
 | 
 
 | 
 
 | 
  
12
  
 | 
  
0
  
 | 
142
 | 
     my $self = shift;  | 
| 
29
 | 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
22
 | 
     my $mod = shift;  | 
| 
30
 | 
12
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
120
 | 
     return 1 if $mod =~ /^(?:every|wave)$/i;  | 
| 
31
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
6
 | 
     0;  | 
| 
32
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
33
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
34
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub init_code {  | 
| 
35
 | 
19
 | 
 
 | 
 
 | 
  
19
  
 | 
  
0
  
 | 
97
 | 
     my $self = shift;  | 
| 
36
 | 
19
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
86
 | 
     croak "This chip is not supported" unless $self->pic->doesroles(qw(Chip CodeGen GPIO));  | 
| 
37
 | 
19
 | 
 
 | 
 
 | 
 
 | 
 
 | 
40
 | 
     my $pic = '';  | 
| 
38
 | 
19
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
70
 | 
     $pic = $self->pic->type if $self->pic;  | 
| 
39
 | 
19
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
197
 | 
     my $freq = $self->pic->f_osc if $self->pic;  | 
| 
40
 | 
19
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
207
 | 
     if ($freq) {  | 
| 
41
 | 
19
 | 
 
 | 
 
 | 
 
 | 
 
 | 
81
 | 
         $freq = qq{\t.sim "$pic.frequency = $freq"};  | 
| 
42
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     } else {  | 
| 
43
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         $freq = '';  | 
| 
44
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
45
 | 
19
 | 
 
 | 
 
 | 
 
 | 
 
 | 
83
 | 
     return << "...";  | 
| 
46
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 ;;;; generated common code for the Simulator  | 
| 
47
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 \t.sim "module library libgpsim_modules"  | 
| 
48
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 \t.sim "$pic.xpos = 200"  | 
| 
49
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 \t.sim "$pic.ypos = 200"  | 
| 
50
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 $freq  | 
| 
51
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 ...  | 
| 
52
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
53
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
54
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _gen_led {  | 
| 
55
 | 
30
 | 
 
 | 
 
 | 
  
30
  
 | 
 
 | 
48
 | 
     my $self = shift;  | 
| 
56
 | 
30
 | 
 
 | 
 
 | 
 
 | 
 
 | 
56
 | 
     my ($id, $x, $y, $name, $port, $color) = @_;  | 
| 
57
 | 
30
 | 
  
100
  
 | 
  
 66
  
 | 
 
 | 
 
 | 
92
 | 
     if (defined $color and ref $color eq 'HASH') {  | 
| 
58
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
10
 | 
         $color = $color->{string};  | 
| 
59
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
60
 | 
30
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
84
 | 
     $color = 'red' unless defined $color;  | 
| 
61
 | 
30
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
186
 | 
     $color = 'red' unless $color =~ /red|orange|green|yellow|blue/i;  | 
| 
62
 | 
30
 | 
 
 | 
 
 | 
 
 | 
 
 | 
57
 | 
     $color = lc $color;  | 
| 
63
 | 
30
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
80
 | 
     $color = substr ($color, 1) if $color =~ /^@/;  | 
| 
64
 | 
30
 | 
 
 | 
 
 | 
 
 | 
 
 | 
84
 | 
     return << "...";  | 
| 
65
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 \t.sim "module load led L$id"  | 
| 
66
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 \t.sim "L$id.xpos = $x"  | 
| 
67
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 \t.sim "L$id.ypos = $y"  | 
| 
68
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 \t.sim "L$id.color = $color"  | 
| 
69
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 \t.sim "node $name"  | 
| 
70
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 \t.sim "attach $name $port L$id.in"  | 
| 
71
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 ...  | 
| 
72
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
73
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
74
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
75
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _get_gpio_info {  | 
| 
76
 | 
101
 | 
 
 | 
 
 | 
  
101
  
 | 
 
 | 
185
 | 
     my ($self, $port) = @_;  | 
| 
77
 | 
101
 | 
 
 | 
 
 | 
 
 | 
 
 | 
172
 | 
     my $gpio_pin = $self->pic->get_input_pin($port);  | 
| 
78
 | 
101
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
185
 | 
     if ($gpio_pin) {  | 
| 
79
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         # this is a pin  | 
| 
80
 | 
101
 | 
 
 | 
 
 | 
 
 | 
 
 | 
104
 | 
         return @{$self->pic->input_pins->{$gpio_pin}};  | 
| 
 
 | 
101
 | 
 
 | 
 
 | 
 
 | 
 
 | 
176
 | 
    | 
| 
81
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     } else {  | 
| 
82
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         $gpio_pin = $self->pic->get_output_pin($port);  | 
| 
83
 | 
  
0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         if ($gpio_pin) {  | 
| 
84
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             # this is a pin  | 
| 
85
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             return @{$self->pic->output_pins->{$gpio_pin}};  | 
| 
 
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
86
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
87
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
88
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     return;  | 
| 
89
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
90
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
91
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _get_simreg {  | 
| 
92
 | 
32
 | 
 
 | 
 
 | 
  
32
  
 | 
 
 | 
58
 | 
     my ($self, $port) = @_;  | 
| 
93
 | 
32
 | 
 
 | 
 
 | 
 
 | 
 
 | 
76
 | 
     my $simreg = lc $port;  | 
| 
94
 | 
32
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
64
 | 
     if ($self->pic) {  | 
| 
95
 | 
32
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
143
 | 
         if (exists $self->pic->registers->{$port}) {  | 
| 
 
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
96
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             # this is a port  | 
| 
97
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7
 | 
             $simreg = lc $port;  | 
| 
98
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         } elsif (exists $self->pic->pins->{$port}) {  | 
| 
99
 | 
31
 | 
 
 | 
 
 | 
 
 | 
 
 | 
267
 | 
             my ($io1) = $self->_get_gpio_info($port);  | 
| 
100
 | 
31
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
182
 | 
             if (defined $io1) {  | 
| 
101
 | 
31
 | 
 
 | 
 
 | 
 
 | 
 
 | 
63
 | 
                 $simreg = lc $io1;  | 
| 
102
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             } else {  | 
| 
103
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
                 my $pic = $self->pic->type;  | 
| 
104
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
                 carp "Cannot find '$port' in PIC $pic. Using '$simreg'";  | 
| 
105
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             }  | 
| 
106
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         } else {  | 
| 
107
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             my $pic = $self->pic->type;  | 
| 
108
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             carp "Cannot find '$port' in PIC $pic. Using '$simreg'";  | 
| 
109
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
110
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
111
 | 
32
 | 
 
 | 
 
 | 
 
 | 
 
 | 
63
 | 
     return $simreg;  | 
| 
112
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
113
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
114
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _get_simport {  | 
| 
115
 | 
94
 | 
 
 | 
 
 | 
  
94
  
 | 
 
 | 
166
 | 
     my ($self, $port, $pin) = @_;  | 
| 
116
 | 
94
 | 
 
 | 
 
 | 
 
 | 
 
 | 
149
 | 
     my $simport = lc $port;  | 
| 
117
 | 
94
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
189
 | 
     if ($self->pic) {  | 
| 
118
 | 
94
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
385
 | 
         if (exists $self->pic->registers->{$port}) {  | 
| 
 
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
119
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             # this is a port  | 
| 
120
 | 
25
 | 
 
 | 
 
 | 
 
 | 
 
 | 
101
 | 
             $simport = lc $port;  | 
| 
121
 | 
25
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
65
 | 
             $simport .= $pin if defined $pin;  | 
| 
122
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         } elsif (exists $self->pic->pins->{$port}) {  | 
| 
123
 | 
69
 | 
 
 | 
 
 | 
 
 | 
 
 | 
574
 | 
             my ($io1, $io2, $io3) = $self->_get_gpio_info($port);  | 
| 
124
 | 
69
 | 
  
 50
  
 | 
  
 33
  
 | 
 
 | 
 
 | 
462
 | 
             if (defined $io1 and defined $io3) {  | 
| 
125
 | 
69
 | 
 
 | 
 
 | 
 
 | 
 
 | 
182
 | 
                 $simport = lc "$io1$io3";  | 
| 
126
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             } else {  | 
| 
127
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
                 my $pic = $self->pic->type;  | 
| 
128
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
                 carp "Cannot find '$port' in PIC $pic. Using '$simport'";  | 
| 
129
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             }  | 
| 
130
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         } else {  | 
| 
131
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             my $pic = $self->pic->type;  | 
| 
132
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             carp "Cannot find '$port' in PIC $pic. Using '$simport'";  | 
| 
133
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
134
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
135
 | 
94
 | 
 
 | 
 
 | 
 
 | 
 
 | 
170
 | 
     return $simport;  | 
| 
136
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
137
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
138
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _get_portpin {  | 
| 
139
 | 
27
 | 
 
 | 
 
 | 
  
27
  
 | 
 
 | 
44
 | 
     my ($self, $port) = @_;  | 
| 
140
 | 
27
 | 
 
 | 
 
 | 
 
 | 
 
 | 
55
 | 
     my $simport = lc $port;  | 
| 
141
 | 
27
 | 
 
 | 
 
 | 
 
 | 
 
 | 
32
 | 
     my $simpin;  | 
| 
142
 | 
27
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
62
 | 
     if ($self->pic) {  | 
| 
143
 | 
27
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
110
 | 
         if (exists $self->pic->registers->{$port}) {  | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
144
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             # this is a port  | 
| 
145
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             $simport = lc $port;  | 
| 
146
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         } elsif (exists $self->pic->pins->{$port}) {  | 
| 
147
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
30
 | 
             my ($io1, $io2, $io3) = $self->_get_gpio_info($port);  | 
| 
148
 | 
1
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
8
 | 
             if (defined $io1) {  | 
| 
149
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2
 | 
                 $simport = lc $io1;  | 
| 
150
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
9
 | 
                 $simpin = $io3;  | 
| 
151
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             } else {  | 
| 
152
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
                 my $pic = $self->pic->type;  | 
| 
153
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
                 carp "Cannot find '$port' in PIC $pic. Using '$simport'";  | 
| 
154
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             }  | 
| 
155
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         } else {  | 
| 
156
 | 
26
 | 
 
 | 
 
 | 
 
 | 
 
 | 
198
 | 
             return;  | 
| 
157
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
158
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
159
 | 
1
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
6
 | 
     return wantarray ? ($simport, $simpin) : $simport;  | 
| 
160
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
161
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
162
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub attach_led {  | 
| 
163
 | 
17
 | 
 
 | 
 
 | 
  
17
  
 | 
  
0
  
 | 
120
 | 
     my ($self, $port, $count, $color) = @_;  | 
| 
164
 | 
17
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
67
 | 
     $count = 1 unless $count;  | 
| 
165
 | 
17
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
69
 | 
     $count = 1 if int($count) < 1;  | 
| 
166
 | 
17
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1266
 | 
     my $code = '';  | 
| 
167
 | 
17
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
40
 | 
     if ($count == 1) {  | 
| 
168
 | 
14
 | 
 
 | 
 
 | 
 
 | 
 
 | 
353
 | 
         my $c = $self->node_count;  | 
| 
169
 | 
14
 | 
 
 | 
 
 | 
 
 | 
 
 | 
61
 | 
         my $node = lc $port . 'led';  | 
| 
170
 | 
14
 | 
 
 | 
 
 | 
 
 | 
 
 | 
36
 | 
         $self->node_count($c + 1);  | 
| 
171
 | 
14
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
911
 | 
         my $x = ($c >= 4) ? 400 : 100;  | 
| 
172
 | 
14
 | 
 
 | 
 
 | 
 
 | 
 
 | 
380
 | 
         my $y = 50 + 50 * $c;  | 
| 
173
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         # use the default pin 0 here  | 
| 
174
 | 
14
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1594
 | 
         my $simport = $self->_get_simport($port, 0);  | 
| 
175
 | 
14
 | 
 
 | 
 
 | 
 
 | 
 
 | 
53
 | 
         $code = $self->_gen_led($c, $x, $y, $node, $simport, $color);  | 
| 
176
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     } else {  | 
| 
177
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
273
 | 
         $count--;  | 
| 
178
 | 
3
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
20
 | 
         if ($self->pic) {  | 
| 
179
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
36
 | 
             for (0 .. $count) {  | 
| 
180
 | 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1257
 | 
                 my $c = $self->node_count + $_;  | 
| 
181
 | 
16
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
2233
 | 
                 my $x = ($_ >= 4) ? 400 : 100;  | 
| 
182
 | 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1071
 | 
                 my $y = 50 + 50 * $c;  | 
| 
183
 | 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1927
 | 
                 my $node = lc $port . $c . 'led';  | 
| 
184
 | 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
277
 | 
                 my $simport = $self->_get_simport($port, $_);  | 
| 
185
 | 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
39
 | 
                 $code .= $self->_gen_led($c, $x, $y, $node, $simport, $color);  | 
| 
186
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             }  | 
| 
187
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
256
 | 
             $self->node_count($self->node_count + $count + 1);  | 
| 
188
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
189
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
190
 | 
17
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1855
 | 
     return $code;  | 
| 
191
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
192
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
193
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub attach_led7seg {  | 
| 
194
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
  
0
  
 | 
11
 | 
     my ($self, @pins) = @_;  | 
| 
195
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4
 | 
     my $code = '';  | 
| 
196
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2
 | 
     my @simpins = ();  | 
| 
197
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2
 | 
     my $color = 'red';  | 
| 
198
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3
 | 
     foreach my $p (@pins) {  | 
| 
199
 | 
2
 | 
  
 50
  
 | 
  
 33
  
 | 
 
 | 
 
 | 
20
 | 
         if (defined $p and ref $p eq 'HASH') {  | 
| 
200
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             $p = $p->{string};  | 
| 
201
 | 
  
0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             next unless defined $p;  | 
| 
202
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
203
 | 
2
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
7
 | 
         if (exists $self->pic->pins->{$p}) {  | 
| 
 
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
204
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
10
 | 
             push @simpins, $p;  | 
| 
205
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         } elsif (exists $self->pic->registers->{$p}) {  | 
| 
206
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             # find all the output pins for the port  | 
| 
207
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
9
 | 
             foreach (sort(keys %{$self->pic->output_pins})) {  | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4
 | 
    | 
| 
208
 | 
17
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
345
 | 
                 next unless defined $self->pic->output_pins->{$_}->[0];  | 
| 
209
 | 
17
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
339
 | 
                 push @simpins, $_ if $self->pic->output_pins->{$_}->[0] eq $p;  | 
| 
210
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             }  | 
| 
211
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         } elsif ($p =~ /red|orange|green|yellow|blue/i) {  | 
| 
212
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             $color = $p;  | 
| 
213
 | 
  
0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             $color = substr($p, 1) if $p =~ /^@/;  | 
| 
214
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             next;  | 
| 
215
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         } else {  | 
| 
216
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             carp "Ignoring port $p as it doesn't exist\n";  | 
| 
217
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
218
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
219
 | 
1
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
21
 | 
     return unless scalar @simpins;  | 
| 
220
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
5
 | 
     my $id = $self->node_count;  | 
| 
221
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7
 | 
     $self->node_count($id + 1);  | 
| 
222
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
74
 | 
     my $x = 500;  | 
| 
223
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3
 | 
     my $y = 50 + 50 * $id;  | 
| 
224
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
117
 | 
     $code .= << "...";  | 
| 
225
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 \t.sim "module load led_7segments L$id"  | 
| 
226
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 \t.sim "L$id.xpos = $x"  | 
| 
227
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 \t.sim "L$id.ypos = $y"  | 
| 
228
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 ...  | 
| 
229
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
69
 | 
     my @nodes = qw(cc seg0 seg1 seg2 seg3 seg4 seg5 seg6);  | 
| 
230
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3
 | 
     foreach my $n (@nodes) {  | 
| 
231
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
104
 | 
         my $p = shift @simpins;  | 
| 
232
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
14
 | 
         my $sp = $self->_get_simport($p);  | 
| 
233
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
20
 | 
         $code .= << "...";  | 
| 
234
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 \t.sim "node $n"  | 
| 
235
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 \t.sim "attach $n $sp L$id.$n"  | 
| 
236
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 ...  | 
| 
237
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
238
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
18
 | 
     return $code;  | 
| 
239
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
240
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
241
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub stop_after {  | 
| 
242
 | 
16
 | 
 
 | 
 
 | 
  
16
  
 | 
  
0
  
 | 
104
 | 
     my ($self, $usecs) = @_;  | 
| 
243
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # convert $secs to cycles  | 
| 
244
 | 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
54
 | 
     my $cycles = $usecs * 10;  | 
| 
245
 | 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2314
 | 
     my $code = << "...";  | 
| 
246
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 \t.sim "break c $cycles"  | 
| 
247
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 ...  | 
| 
248
 | 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
283
 | 
     return $code;  | 
| 
249
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
250
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
251
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub logfile {  | 
| 
252
 | 
7
 | 
 
 | 
 
 | 
  
7
  
 | 
  
0
  
 | 
36
 | 
     my ($self, $file) = @_;  | 
| 
253
 | 
7
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
26
 | 
     $file = "vicsim.log" unless defined $file;  | 
| 
254
 | 
7
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
30
 | 
     if (ref $file eq 'HASH') {  | 
| 
255
 | 
7
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
22
 | 
         $file = $file->{string} || 'vicsim.log';  | 
| 
256
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
257
 | 
7
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
41
 | 
     $file = substr($file, 1) if $file =~ /^@/;  | 
| 
258
 | 
7
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
44
 | 
     return "\t.sim \"log lxt $file\"\n" if $file =~ /\.lxt/i;  | 
| 
259
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     return "\t.sim \"log on $file\"\n";  | 
| 
260
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
261
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
262
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub log {  | 
| 
263
 | 
20
 | 
 
 | 
 
 | 
  
20
  
 | 
  
0
  
 | 
94
 | 
     my $self = shift;  | 
| 
264
 | 
20
 | 
 
 | 
 
 | 
 
 | 
 
 | 
35
 | 
     my $code = '';  | 
| 
265
 | 
20
 | 
 
 | 
 
 | 
 
 | 
 
 | 
45
 | 
     foreach my $port (@_) {  | 
| 
266
 | 
29
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
74
 | 
         if ($port =~ /US?ART/) {  | 
| 
267
 | 
3
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
17
 | 
             next unless $self->pic->doesrole('USART');  | 
| 
268
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
16
 | 
             my $ipin = $self->pic->usart_pins->{async_in};  | 
| 
269
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
15
 | 
             my $opin = $self->pic->usart_pins->{async_out};  | 
| 
270
 | 
3
 | 
  
 50
  
 | 
  
 33
  
 | 
 
 | 
 
 | 
25
 | 
             if (defined $ipin and defined $opin) {  | 
| 
271
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
16
 | 
                 my $ireg = $self->_get_simreg($ipin);  | 
| 
272
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
12
 | 
                 my $oreg = $self->_get_simreg($opin);  | 
| 
273
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
18
 | 
                 $code .= $self->log($ipin);  | 
| 
274
 | 
3
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
10
 | 
                 $code .= $self->log($opin) if $ireg ne $oreg;  | 
| 
275
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             }  | 
| 
276
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         } else {  | 
| 
277
 | 
26
 | 
 
 | 
 
 | 
 
 | 
 
 | 
63
 | 
             my $reg = $self->_get_simreg($port);  | 
| 
278
 | 
26
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
73
 | 
             next unless $reg;  | 
| 
279
 | 
26
 | 
 
 | 
 
 | 
 
 | 
 
 | 
100
 | 
             $code .= << "...";  | 
| 
280
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 \t.sim "log r $reg"  | 
| 
281
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 \t.sim "log w $reg"  | 
| 
282
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 ...  | 
| 
283
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
284
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
285
 | 
20
 | 
 
 | 
 
 | 
 
 | 
 
 | 
62
 | 
     return $code;  | 
| 
286
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
287
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
288
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _set_scope {  | 
| 
289
 | 
33
 | 
 
 | 
 
 | 
  
33
  
 | 
 
 | 
64
 | 
     my ($self, $port) = @_;  | 
| 
290
 | 
33
 | 
 
 | 
 
 | 
 
 | 
 
 | 
74
 | 
     my $simport = $self->_get_simport($port);  | 
| 
291
 | 
33
 | 
 
 | 
 
 | 
 
 | 
 
 | 
80
 | 
     my $chnl = $self->scope_channels;  | 
| 
292
 | 
33
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
146
 | 
     carp "Maximum of 8 channels can be used in the scope\n" if $chnl > 7;  | 
| 
293
 | 
33
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
966
 | 
     return '' if $chnl > 7;  | 
| 
294
 | 
33
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
795
 | 
     if (lc($simport) eq lc($port)) {  | 
| 
295
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2
 | 
         my @code = ();  | 
| 
296
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3
 | 
         for (0 .. 7) {  | 
| 
297
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
249
 | 
             $simport = $self->_get_simport($port, $_);  | 
| 
298
 | 
8
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
15
 | 
             if ($self->scope_channels < 8) {  | 
| 
299
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
204
 | 
                 $chnl = $self->scope_channels;  | 
| 
300
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
36
 | 
                 push @code, "\t.sim \"scope.ch$chnl = \\\"$simport\\\"\"";  | 
| 
301
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
127
 | 
                 $self->scope_channels($chnl + 1);  | 
| 
302
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             }  | 
| 
303
 | 
8
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
516
 | 
             carp "Maximum of 8 channels can be used in the scope\n" if $chnl > 7;  | 
| 
304
 | 
8
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
199
 | 
             last if $chnl > 7;  | 
| 
305
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
306
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
29
 | 
         return join("\n", @code);  | 
| 
307
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     } else {  | 
| 
308
 | 
32
 | 
 
 | 
 
 | 
 
 | 
 
 | 
74
 | 
         $self->scope_channels($chnl + 1);  | 
| 
309
 | 
32
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2071
 | 
         return << "...";  | 
| 
310
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 \t.sim "scope.ch$chnl = \\"$simport\\""  | 
| 
311
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 ...  | 
| 
312
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
313
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
314
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
315
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub scope {  | 
| 
316
 | 
17
 | 
 
 | 
 
 | 
  
17
  
 | 
  
0
  
 | 
94
 | 
     my $self = shift;  | 
| 
317
 | 
17
 | 
 
 | 
 
 | 
 
 | 
 
 | 
29
 | 
     my $code = '';  | 
| 
318
 | 
17
 | 
 
 | 
 
 | 
 
 | 
 
 | 
59
 | 
     foreach my $port (@_) {  | 
| 
319
 | 
30
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
320
 | 
         if ($port =~ /US?ART/) {  | 
| 
320
 | 
3
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
8
 | 
             next unless $self->pic->doesrole('USART');  | 
| 
321
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8
 | 
             my $ipin = $self->pic->usart_pins->{async_in};  | 
| 
322
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
13
 | 
             my $opin = $self->pic->usart_pins->{async_out};  | 
| 
323
 | 
3
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
18
 | 
             $code .= $self->_set_scope($ipin) if defined $opin;  | 
| 
324
 | 
3
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
69
 | 
             $code .= $self->_set_scope($opin) if defined $opin;  | 
| 
325
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         } else {  | 
| 
326
 | 
27
 | 
 
 | 
 
 | 
 
 | 
 
 | 
80
 | 
             $code .= $self->_set_scope($port);  | 
| 
327
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
328
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
329
 | 
17
 | 
 
 | 
 
 | 
 
 | 
 
 | 
306
 | 
     return $code;  | 
| 
330
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
331
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
332
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 ### have to change the operator back to the form acceptable by gpsim  | 
| 
333
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _get_operator {  | 
| 
334
 | 
27
 | 
 
 | 
 
 | 
  
27
  
 | 
 
 | 
31
 | 
     my $self = shift;  | 
| 
335
 | 
27
 | 
 
 | 
 
 | 
 
 | 
 
 | 
28
 | 
     my $op = shift;  | 
| 
336
 | 
27
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
58
 | 
     return '==' if $op eq 'EQ';  | 
| 
337
 | 
  
0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     return '!=' if $op eq 'NE';  | 
| 
338
 | 
  
0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     return '>' if $op eq 'GT';  | 
| 
339
 | 
  
0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     return '>=' if $op eq 'GE';  | 
| 
340
 | 
  
0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     return '<' if $op eq 'LT';  | 
| 
341
 | 
  
0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     return '<=' if $op eq 'LE';  | 
| 
342
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     return undef;  | 
| 
343
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
344
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
345
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub sim_assert {  | 
| 
346
 | 
29
 | 
 
 | 
 
 | 
  
29
  
 | 
  
0
  
 | 
131
 | 
     my ($self, $condition, $msg) = @_;  | 
| 
347
 | 
29
 | 
 
 | 
 
 | 
 
 | 
 
 | 
29
 | 
     my $assert_msg;  | 
| 
348
 | 
29
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
80
 | 
     if ($condition =~ /@@/) {  | 
| 
349
 | 
27
 | 
 
 | 
 
 | 
 
 | 
 
 | 
60
 | 
         my @args = split /@@/, $condition;  | 
| 
350
 | 
27
 | 
 
 | 
 
 | 
 
 | 
 
 | 
80
 | 
         my $literal = qr/^\d+$/;  | 
| 
351
 | 
27
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
58
 | 
         if (scalar @args == 3) {  | 
| 
352
 | 
27
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2237
 | 
             my $lhs = shift @args;  | 
| 
353
 | 
27
 | 
 
 | 
 
 | 
 
 | 
 
 | 
31
 | 
             my $op = shift @args;  | 
| 
354
 | 
27
 | 
 
 | 
 
 | 
 
 | 
 
 | 
34
 | 
             my $rhs = shift @args;  | 
| 
355
 | 
27
 | 
 
 | 
 
 | 
 
 | 
 
 | 
50
 | 
             my $op2 = $self->_get_operator($op);  | 
| 
356
 | 
27
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
117
 | 
             if ($lhs !~ $literal) {  | 
| 
357
 | 
27
 | 
 
 | 
 
 | 
 
 | 
 
 | 
64
 | 
                 my ($port, $pin) = $self->_get_portpin($lhs);  | 
| 
358
 | 
27
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
49
 | 
                 if (defined $pin) {  | 
| 
 
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
359
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
5
 | 
                     my $pval = sprintf "0x%02X", (1 << $pin);  | 
| 
360
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
217
 | 
                     $lhs = lc "($port & $pval)";  | 
| 
361
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 } elsif (defined $port) {  | 
| 
362
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
                     $lhs = lc $port;  | 
| 
363
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 } else {  | 
| 
364
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     # may be a variable  | 
| 
365
 | 
26
 | 
 
 | 
 
 | 
 
 | 
 
 | 
34
 | 
                     $lhs = uc $lhs;  | 
| 
366
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 }  | 
| 
367
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             } else {  | 
| 
368
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
                 $lhs = sprintf "0x%02X", $lhs;  | 
| 
369
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             }  | 
| 
370
 | 
27
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
121
 | 
             if ($rhs !~ $literal) {  | 
| 
371
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
                 my ($port, $pin) = $self->_get_portpin($lhs);  | 
| 
372
 | 
  
0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
                 if (defined $pin) {  | 
| 
 
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
373
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
                     my $pval = sprintf "0x%02X", (1 << $pin);  | 
| 
374
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
                     $rhs = lc "($port & $pval)";  | 
| 
375
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 } elsif (defined $port) {  | 
| 
376
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
                     $rhs = lc $port;  | 
| 
377
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 } else {  | 
| 
378
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     # may be a variable  | 
| 
379
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
                     $rhs = uc $rhs;  | 
| 
380
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 }  | 
| 
381
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             } else {  | 
| 
382
 | 
27
 | 
 
 | 
 
 | 
 
 | 
 
 | 
94
 | 
                 $rhs = sprintf "0x%02X", $rhs;  | 
| 
383
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             }  | 
| 
384
 | 
27
 | 
 
 | 
 
 | 
 
 | 
 
 | 
55
 | 
             $condition = "$lhs $op2 $rhs";  | 
| 
385
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
386
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         #TODO: handle more complex expressions  | 
| 
387
 | 
27
 | 
  
100
  
 | 
  
 66
  
 | 
 
 | 
 
 | 
109
 | 
         if (defined $msg and ref $msg eq 'HASH') {  | 
| 
388
 | 
26
 | 
 
 | 
 
 | 
 
 | 
 
 | 
43
 | 
             $msg = $msg->{string};  | 
| 
389
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
390
 | 
27
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
47
 | 
         $msg  = "$condition is false" unless $msg;  | 
| 
391
 | 
27
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
45
 | 
         $msg = substr($msg, 1) if $msg =~ /^@/;  | 
| 
392
 | 
27
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
45
 | 
         $condition = substr($condition, 1) if $condition =~ /^@/;  | 
| 
393
 | 
27
 | 
 
 | 
 
 | 
 
 | 
 
 | 
56
 | 
         $assert_msg = qq{$condition, \\\"$msg\\\"};  | 
| 
394
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     } else {  | 
| 
395
 | 
2
 | 
  
 50
  
 | 
  
 33
  
 | 
 
 | 
 
 | 
8
 | 
         if (defined $msg and ref $msg eq 'HASH') {  | 
| 
396
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             $msg = $msg->{string};  | 
| 
397
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
398
 | 
2
 | 
  
 50
  
 | 
  
 33
  
 | 
 
 | 
 
 | 
19
 | 
         if (defined $condition and ref $condition eq 'HASH') {  | 
| 
399
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
5
 | 
             $condition = $condition->{string};  | 
| 
400
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
401
 | 
2
 | 
  
 50
  
 | 
  
 33
  
 | 
 
 | 
 
 | 
14
 | 
         if (defined $condition and defined $msg) {  | 
| 
 
 | 
 
 | 
  
 50
  
 | 
  
 33
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
  0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
402
 | 
  
0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             $msg = substr($msg, 1) if $msg =~ /^@/;  | 
| 
403
 | 
  
0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             $condition = substr($condition, 1) if $condition =~ /^@/;  | 
| 
404
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             $assert_msg = qq{$condition, \\\"$msg\\\"};  | 
| 
405
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         } elsif (defined $condition and not defined $msg) {  | 
| 
406
 | 
2
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
7
 | 
             $condition = substr($condition, 1) if $condition =~ /^@/;  | 
| 
407
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
6
 | 
             $assert_msg = qq{\\\"$condition\\\"};  | 
| 
408
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         } elsif (defined $msg and not defined $condition) {  | 
| 
409
 | 
  
0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             $msg = substr($msg, 1) if $msg =~ /^@/;  | 
| 
410
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             $assert_msg = qq{\\\"$msg\\\"};  | 
| 
411
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         } else {  | 
| 
412
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             $assert_msg = qq{\\\"user requested an assert\\\"};  | 
| 
413
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
414
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
415
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
416
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     return << "..."  | 
| 
417
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 \t;; break if the condition evaluates to false  | 
| 
418
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 \t.assert "$assert_msg"  | 
| 
419
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 \tnop ;; needed for the assert  | 
| 
420
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 ...  | 
| 
421
 | 
29
 | 
 
 | 
 
 | 
 
 | 
 
 | 
84
 | 
 }  | 
| 
422
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
423
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub stimulate {  | 
| 
424
 | 
9
 | 
 
 | 
 
 | 
  
9
  
 | 
  
0
  
 | 
66
 | 
     my $self = shift;  | 
| 
425
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
30
 | 
     my $pin = shift;  | 
| 
426
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
18
 | 
     my %hh = ();  | 
| 
427
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
18
 | 
     foreach my $href (@_) {  | 
| 
428
 | 
11
 | 
 
 | 
 
 | 
 
 | 
 
 | 
63
 | 
         %hh = (%hh, %$href);  | 
| 
429
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
430
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
19
 | 
     my $period = '';  | 
| 
431
 | 
9
 | 
  
100
  
 | 
  
 66
  
 | 
 
 | 
 
 | 
36
 | 
     $period = $hh{EVERY} if (defined $hh{EVERY} and length $hh{EVERY});  | 
| 
432
 | 
9
 | 
  
100
  
 | 
  
 66
  
 | 
 
 | 
 
 | 
89
 | 
     $period = qq{\t.sim "period $period"} if (defined $period and length $period);  | 
| 
433
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
71
 | 
     my $wave = '';  | 
| 
434
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
17
 | 
     my $wave_type = 'digital';  | 
| 
435
 | 
9
 | 
  
 50
  
 | 
  
 33
  
 | 
 
 | 
 
 | 
58
 | 
     if (exists $hh{WAVE} and ref $hh{WAVE} eq 'ARRAY') {  | 
| 
436
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
19
 | 
         my $arr = $hh{WAVE};  | 
| 
437
 | 
9
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
68
 | 
         $wave = "\t.sim \"{ " . join(',', @$arr) . " }\"" if scalar @$arr;  | 
| 
438
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
17
 | 
         my $ad = 0;  | 
| 
439
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
17
 | 
         foreach (@$arr) {  | 
| 
440
 | 
66
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
426
 | 
             $ad |= 1 unless /^\d+$/;  | 
| 
441
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
442
 | 
9
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
69
 | 
         $wave_type = 'analog' if $ad;  | 
| 
443
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
444
 | 
9
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
248
 | 
     my $start = $hh{START} || 0;  | 
| 
445
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
125
 | 
     $start = qq{\t.sim "start_cycle $start"};  | 
| 
446
 | 
9
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
186
 | 
     my $init = $hh{INITIAL} || 0;  | 
| 
447
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
117
 | 
     $init = qq{\t.sim "initial_state $init"};  | 
| 
448
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
143
 | 
     my $num = $self->stimulus_count;  | 
| 
449
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
41
 | 
     $self->stimulus_count($num + 1);  | 
| 
450
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
646
 | 
     my $node = "stim$num$pin";  | 
| 
451
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
150
 | 
     my $simpin = $self->_get_simport($pin);  | 
| 
452
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     return << "..."  | 
| 
453
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 \t.sim \"echo creating stimulus number $num\"  | 
| 
454
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 \t.sim \"stimulus asynchronous_stimulus\"  | 
| 
455
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 $init  | 
| 
456
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 $start  | 
| 
457
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 \t.sim \"$wave_type\"  | 
| 
458
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 $period  | 
| 
459
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 $wave  | 
| 
460
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 \t.sim \"name stim$num\"  | 
| 
461
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 \t.sim \"end\"  | 
| 
462
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 \t.sim \"echo done creating stimulus number $num\"  | 
| 
463
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 \t.sim \"node $node\"  | 
| 
464
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 \t.sim \"attach $node stim$num $simpin\"  | 
| 
465
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 ...  | 
| 
466
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
27
 | 
 }  | 
| 
467
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
468
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub get_autorun_code {  | 
| 
469
 | 
12
 | 
 
 | 
 
 | 
  
12
  
 | 
  
0
  
 | 
94
 | 
     return qq{\t.sim "run"\n};  | 
| 
470
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
471
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
472
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub autorun {  | 
| 
473
 | 
12
 | 
 
 | 
 
 | 
  
12
  
 | 
  
0
  
 | 
58
 | 
     my $self = shift;  | 
| 
474
 | 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
45
 | 
     $self->should_autorun(1);  | 
| 
475
 | 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
39
 | 
     return "\t;;;; will autorun on start\n";  | 
| 
476
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
477
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
478
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub stopwatch {  | 
| 
479
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
  
0
  
 | 
6
 | 
     my ($self, $rollover) = @_;  | 
| 
480
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1
 | 
     my $code = qq{\t.sim "stopwatch.enable = true"\n};  | 
| 
481
 | 
1
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
4
 | 
     $code .= qq{\t.sim "stopwatch.rollover = $rollover"\n} if defined $rollover;  | 
| 
482
 | 
1
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
2
 | 
     $code .= qq{\t.sim "break stopwatch"\n} if defined $rollover;  | 
| 
483
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2
 | 
     return $code;  | 
| 
484
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
485
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
486
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub attach {  | 
| 
487
 | 
3
 | 
 
 | 
 
 | 
  
3
  
 | 
  
0
  
 | 
16
 | 
     my $self = shift;  | 
| 
488
 | 
3
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
7
 | 
     return unless @_;  | 
| 
489
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
5
 | 
     my $pin = shift;  | 
| 
490
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
5
 | 
     my $code = '';  | 
| 
491
 | 
3
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
21
 | 
     if ($pin =~ /US?ART/) {  | 
| 
492
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         # TX - connect to UART  | 
| 
493
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         # RX - connect to UART but also send it data  | 
| 
494
 | 
3
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
12
 | 
         unless ($self->pic->doesrole('USART')) {  | 
| 
495
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             carp "PIC ", $self->pic->type, " does not do USART";  | 
| 
496
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             return;  | 
| 
497
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
498
 | 
3
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
15
 | 
         my $baudrate = shift if @_;  | 
| 
499
 | 
3
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
8
 | 
         my $loopback = shift if @_;  | 
| 
500
 | 
3
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
11
 | 
         my $key = ($pin =~ /^UART/) ? 'uart' : 'usart';  | 
| 
501
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         $baudrate = $self->pic->code_config->{$key}->{baud} unless defined  | 
| 
502
 | 
3
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
6
 | 
         $baudrate;  | 
| 
503
 | 
3
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
15
 | 
         $baudrate = 9600 unless defined $baudrate;  | 
| 
504
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
11
 | 
         my $id = $self->node_count;  | 
| 
505
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
15
 | 
         $self->node_count($id + 1);  | 
| 
506
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
192
 | 
         my $ipin = $self->pic->usart_pins->{async_in};  | 
| 
507
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
20
 | 
         my $rxport = $self->_get_simport($ipin);  | 
| 
508
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
12
 | 
         my $opin = $self->pic->usart_pins->{async_out};  | 
| 
509
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
16
 | 
         my $txport = $self->_get_simport($opin);  | 
| 
510
 | 
3
 | 
  
 50
  
 | 
  
 33
  
 | 
 
 | 
 
 | 
7
 | 
         return unless (exists $self->pic->pins->{$ipin} and exists $self->pic->pins->{$opin});  | 
| 
511
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
40
 | 
         $code .= qq{\t.sim "module load usart U$id"\n};  | 
| 
512
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
58
 | 
         $code .= qq{\t.sim "node TX_U$id"\n};  | 
| 
513
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
59
 | 
         $code .= qq{\t.sim "node RX_U$id"\n};  | 
| 
514
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
42
 | 
         $code .= qq{\t.sim "attach TX_U$id $txport U$id.RXPIN"\n};  | 
| 
515
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
89
 | 
         $code .= qq{\t.sim "attach RX_U$id $rxport U$id.TXPIN"\n};  | 
| 
516
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
71
 | 
         $code .= qq{\t.sim "U$id.txbaud = $baudrate"\n};  | 
| 
517
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
37
 | 
         $code .= qq{\t.sim "U$id.rxbaud = $baudrate"\n};  | 
| 
518
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
36
 | 
         my $x = 500;  | 
| 
519
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7
 | 
         my $y = 50 + 50 * $id;  | 
| 
520
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
353
 | 
         $code .= qq{\t.sim "U$id.xpos = $x"\n};  | 
| 
521
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
76
 | 
         $code .= qq{\t.sim "U$id.ypos = $y"\n};  | 
| 
522
 | 
3
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
78
 | 
         if (defined $loopback) {  | 
| 
523
 | 
2
 | 
  
 50
  
 | 
  
 33
  
 | 
 
 | 
 
 | 
27
 | 
             if (ref $loopback eq 'HASH' and $loopback->{string} =~ /loopback/i) {  | 
| 
524
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
10
 | 
                 $code .= qq{\t.sim "U$id.loop = true"\n};  | 
| 
525
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             }  | 
| 
526
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
527
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
528
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
38
 | 
     return $code;  | 
| 
529
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
530
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
531
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 1;  | 
| 
532
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
533
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =encoding utf8  | 
| 
534
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
535
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 NAME  | 
| 
536
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
537
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 VIC::Receiver  | 
| 
538
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
539
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 SYNOPSIS  | 
| 
540
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
541
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 The Pegex::Receiver class for handling the grammar.  | 
| 
542
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
543
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 DESCRIPTION  | 
| 
544
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
545
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 INTERNAL CLASS.  | 
| 
546
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
547
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 AUTHOR  | 
| 
548
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
549
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Vikas N Kumar   | 
| 
550
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
551
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 COPYRIGHT  | 
| 
552
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
553
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Copyright (c) 2014. Vikas N Kumar  | 
| 
554
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
555
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 This program is free software; you can redistribute it and/or modify it  | 
| 
556
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 under the same terms as Perl itself.  | 
| 
557
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
558
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 See http://www.perl.com/perl/misc/Artistic.html  | 
| 
559
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
560
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =cut  |