| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
# See copyright, etc in below POD section. |
|
2
|
|
|
|
|
|
|
###################################################################### |
|
3
|
|
|
|
|
|
|
|
|
4
|
|
|
|
|
|
|
package SystemC::Vregs::Input::HTML; |
|
5
|
3
|
|
|
3
|
|
14
|
use Carp; |
|
|
3
|
|
|
|
|
5
|
|
|
|
3
|
|
|
|
|
161
|
|
|
6
|
3
|
|
|
3
|
|
13
|
use strict; |
|
|
3
|
|
|
|
|
6
|
|
|
|
3
|
|
|
|
|
78
|
|
|
7
|
|
|
|
|
|
|
|
|
8
|
3
|
|
|
3
|
|
1267
|
use SystemC::Vregs::Input::TableExtract; |
|
|
3
|
|
|
|
|
10
|
|
|
|
3
|
|
|
|
|
32
|
|
|
9
|
3
|
|
|
3
|
|
156
|
use vars qw($VERSION $Debug); |
|
|
3
|
|
|
|
|
4
|
|
|
|
3
|
|
|
|
|
11360
|
|
|
10
|
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
$VERSION = '1.470'; |
|
12
|
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
###################################################################### |
|
14
|
|
|
|
|
|
|
# CONSTRUCTOR |
|
15
|
|
|
|
|
|
|
|
|
16
|
|
|
|
|
|
|
sub new { |
|
17
|
0
|
|
|
0
|
1
|
|
my $class = shift; |
|
18
|
0
|
|
|
|
|
|
my $self = {@_}; |
|
19
|
0
|
|
|
|
|
|
bless $self, $class; |
|
20
|
0
|
|
|
|
|
|
return $self; |
|
21
|
|
|
|
|
|
|
} |
|
22
|
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
###################################################################### |
|
24
|
|
|
|
|
|
|
# Reading |
|
25
|
|
|
|
|
|
|
|
|
26
|
|
|
|
|
|
|
sub read { |
|
27
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
|
28
|
0
|
|
|
|
|
|
my %params = (#filename => |
|
29
|
|
|
|
|
|
|
#pack => |
|
30
|
|
|
|
|
|
|
@_); |
|
31
|
0
|
0
|
|
|
|
|
my $pack = $params{pack} or croak "%Error: No pack=> parameter passed,"; |
|
32
|
0
|
|
|
|
|
|
$self->{pack} = $pack; |
|
33
|
|
|
|
|
|
|
# Dump headers for class name based accessors |
|
34
|
|
|
|
|
|
|
|
|
35
|
0
|
|
|
|
|
|
my $te = new SystemC::Vregs::Input::TableExtract(depth=>0, ); |
|
36
|
0
|
|
|
|
|
|
$te->{_vregs_inp} = $self; |
|
37
|
0
|
|
|
|
|
|
$te->parse_file($params{filename}); |
|
38
|
|
|
|
|
|
|
} |
|
39
|
|
|
|
|
|
|
|
|
40
|
|
|
|
|
|
|
###################################################################### |
|
41
|
|
|
|
|
|
|
# Callbacks from table extract |
|
42
|
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
sub new_item { |
|
44
|
0
|
|
|
0
|
0
|
|
my $self = $_[0]; |
|
45
|
0
|
|
|
|
|
|
my $bittableref = $_[1]; |
|
46
|
0
|
|
|
|
|
|
my $flagref = $_[2]; # Hash of {heading} = value_of_heading |
|
47
|
|
|
|
|
|
|
#Create a new register/class/enum, called from the html parser |
|
48
|
0
|
0
|
|
|
|
|
print "new_item:",::Dumper(\$flagref, $bittableref) if $SystemC::Vregs::Input::TableExtract::Debug; |
|
49
|
|
|
|
|
|
|
|
|
50
|
0
|
0
|
|
|
|
|
if ($flagref->{Register}) { |
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
51
|
0
|
|
|
|
|
|
new_register (@_); |
|
52
|
|
|
|
|
|
|
} elsif ($flagref->{Class}) { |
|
53
|
0
|
|
|
|
|
|
new_register (@_); |
|
54
|
|
|
|
|
|
|
} elsif ($flagref->{Enum}) { |
|
55
|
0
|
|
|
|
|
|
new_enum (@_); |
|
56
|
|
|
|
|
|
|
} elsif (defined $flagref->{Defines}) { # Name not required, so defined. |
|
57
|
0
|
|
|
|
|
|
new_define (@_); |
|
58
|
|
|
|
|
|
|
} elsif ($flagref->{Package}) { |
|
59
|
0
|
|
|
|
|
|
new_package (@_); |
|
60
|
|
|
|
|
|
|
} |
|
61
|
|
|
|
|
|
|
} |
|
62
|
|
|
|
|
|
|
|
|
63
|
|
|
|
|
|
|
sub new_package { |
|
64
|
0
|
|
|
0
|
0
|
|
my $self = shift; |
|
65
|
0
|
|
|
|
|
|
my $bittableref = shift; my @bittable = @{$bittableref}; |
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
66
|
0
|
|
|
|
|
|
my $flagref = shift; # Hash of {heading} = value_of_heading |
|
67
|
|
|
|
|
|
|
# Create a new package |
|
68
|
0
|
|
|
|
|
|
my $pack = $self->{pack}; |
|
69
|
|
|
|
|
|
|
|
|
70
|
0
|
0
|
|
|
|
|
($flagref->{Package}) or die; |
|
71
|
0
|
0
|
|
|
|
|
(!$self->{_got_package_decl}) or return $pack->warn($flagref, "Multiple Package attribute sections, previous at $self->{_got_package_decl}.\n"); |
|
72
|
|
|
|
|
|
|
|
|
73
|
0
|
|
0
|
|
|
|
my $attr = $flagref->{Attributes}||""; |
|
74
|
0
|
0
|
|
|
|
|
print "PACK ATTR $attr\n" if $Debug; |
|
75
|
0
|
|
|
|
|
|
$pack->attributes_parse($attr); |
|
76
|
0
|
|
|
|
|
|
$self->{_got_package_decl} = $flagref->{at}; |
|
77
|
|
|
|
|
|
|
} |
|
78
|
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
sub new_define { |
|
80
|
0
|
|
|
0
|
0
|
|
my $self = shift; |
|
81
|
0
|
|
|
|
|
|
my $bittableref = shift; my @bittable = @{$bittableref}; |
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
82
|
0
|
|
|
|
|
|
my $flagref = shift; # Hash of {heading} = value_of_heading |
|
83
|
|
|
|
|
|
|
# Create a new enumeration |
|
84
|
0
|
0
|
|
|
|
|
return if $#bittable<0; # Empty list of defines |
|
85
|
0
|
|
|
|
|
|
my $pack = $self->{pack}; |
|
86
|
|
|
|
|
|
|
|
|
87
|
|
|
|
|
|
|
#print ::Dumper(\$flagref, $bittableref); |
|
88
|
0
|
0
|
|
|
|
|
(defined $flagref->{Defines}) or die; |
|
89
|
0
|
|
0
|
|
|
|
$flagref->{Defines} ||= ""; |
|
90
|
0
|
|
|
|
|
|
my $defname = _cleanup_column($flagref->{Defines}); |
|
91
|
0
|
0
|
0
|
|
|
|
$defname .= "_" if $defname ne "" && $defname !~ /_$/; |
|
92
|
0
|
0
|
|
|
|
|
$defname = "" if $defname eq "_"; |
|
93
|
|
|
|
|
|
|
|
|
94
|
0
|
|
0
|
|
|
|
my $whole_table_attr = $flagref->{Attributes}||""; |
|
95
|
|
|
|
|
|
|
|
|
96
|
0
|
|
|
|
|
|
my ($const_col, $mnem_col, $def_col) |
|
97
|
|
|
|
|
|
|
= $self->_choose_columns ($flagref, |
|
98
|
|
|
|
|
|
|
[qw(Constant Mnemonic Definition)], |
|
99
|
|
|
|
|
|
|
[qw(Product)], |
|
100
|
|
|
|
|
|
|
$bittable[0]); |
|
101
|
0
|
0
|
|
|
|
|
defined $const_col or return $pack->warn ($flagref, "Define table is missing column headed 'Constant'\n"); |
|
102
|
0
|
0
|
|
|
|
|
defined $mnem_col or return $pack->warn ($flagref, "Define table is missing column headed 'Mnemonic'\n"); |
|
103
|
0
|
0
|
|
|
|
|
defined $def_col or return $pack->warn ($flagref, "Define table is missing column headed 'Definition'\n"); |
|
104
|
|
|
|
|
|
|
|
|
105
|
0
|
|
|
|
|
|
foreach my $row (@bittable) { |
|
106
|
0
|
0
|
|
|
|
|
print " Row:\n" if $Debug; |
|
107
|
0
|
|
|
|
|
|
foreach my $col (@$row) { |
|
108
|
0
|
0
|
|
|
|
|
print " Ent:$col\n" if $Debug; |
|
109
|
0
|
0
|
|
|
|
|
if (!defined $col) { |
|
110
|
0
|
|
|
|
|
|
$pack->warn ($flagref, "Column ".($col+1)." is empty\n"); |
|
111
|
|
|
|
|
|
|
} |
|
112
|
|
|
|
|
|
|
} |
|
113
|
0
|
0
|
|
|
|
|
next if $row eq $bittable[0]; # Ignore header |
|
114
|
|
|
|
|
|
|
|
|
115
|
0
|
|
|
|
|
|
my $val_mnem = $row->[$mnem_col]; |
|
116
|
0
|
|
|
|
|
|
my $desc = $row->[$def_col]; |
|
117
|
|
|
|
|
|
|
|
|
118
|
|
|
|
|
|
|
# Skip blank/reserved values |
|
119
|
0
|
0
|
0
|
|
|
|
next if ($val_mnem eq "" && ($desc eq "" || $desc =~ /^reserved/i)); |
|
|
|
|
0
|
|
|
|
|
|
120
|
|
|
|
|
|
|
|
|
121
|
|
|
|
|
|
|
# Check for empty field |
|
122
|
0
|
|
|
|
|
|
my $defref = new SystemC::Vregs::Define::Value |
|
123
|
|
|
|
|
|
|
(pack => $pack, |
|
124
|
|
|
|
|
|
|
name => $defname . $val_mnem, |
|
125
|
|
|
|
|
|
|
rst => $row->[$const_col], |
|
126
|
|
|
|
|
|
|
desc => $desc, |
|
127
|
|
|
|
|
|
|
at => $flagref->{at}, |
|
128
|
|
|
|
|
|
|
is_manual => 1, |
|
129
|
|
|
|
|
|
|
); |
|
130
|
|
|
|
|
|
|
|
|
131
|
|
|
|
|
|
|
# Take special user defined fields and add to table |
|
132
|
0
|
|
|
|
|
|
for (my $colnum=0; $colnum<=$#{$bittable[0]}; $colnum++) { |
|
|
0
|
|
|
|
|
|
|
|
133
|
0
|
|
|
|
|
|
my $col = $bittable[0][$colnum]; |
|
134
|
0
|
|
|
|
|
|
$col =~ s/\s+//; |
|
135
|
0
|
0
|
|
|
|
|
if ($col =~ /^\s*\(([a-zA-Z_0-9]+)\)\s*$/) { |
|
136
|
0
|
|
|
|
|
|
my $var = $1; |
|
137
|
0
|
|
0
|
|
|
|
my $val = _cleanup_column($row->[$colnum]||""); |
|
138
|
0
|
0
|
|
|
|
|
$defref->{attributes}{$var} = $val if $val =~ /^([][a-zA-Z._:0-9+]+)$/; |
|
139
|
|
|
|
|
|
|
} |
|
140
|
|
|
|
|
|
|
} |
|
141
|
0
|
|
|
|
|
|
$defref->attributes_parse($whole_table_attr); |
|
142
|
|
|
|
|
|
|
} |
|
143
|
|
|
|
|
|
|
} |
|
144
|
|
|
|
|
|
|
|
|
145
|
|
|
|
|
|
|
sub new_enum { |
|
146
|
0
|
|
|
0
|
0
|
|
my $self = shift; |
|
147
|
0
|
|
|
|
|
|
my $bittableref = shift; my @bittable = @{$bittableref}; |
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
148
|
0
|
|
|
|
|
|
my $flagref = shift; # Hash of {heading} = value_of_heading |
|
149
|
|
|
|
|
|
|
# Create a new enumeration |
|
150
|
0
|
|
|
|
|
|
my $pack = $self->{pack}; |
|
151
|
|
|
|
|
|
|
|
|
152
|
0
|
0
|
|
|
|
|
($flagref->{Enum}) or die; |
|
153
|
0
|
|
|
|
|
|
my $classname = _cleanup_column($flagref->{Enum}); |
|
154
|
|
|
|
|
|
|
|
|
155
|
0
|
|
|
|
|
|
my ($const_col, $mnem_col, $def_col) |
|
156
|
|
|
|
|
|
|
= $self->_choose_columns ($flagref, |
|
157
|
|
|
|
|
|
|
[qw(Constant Mnemonic Definition)], |
|
158
|
|
|
|
|
|
|
[qw(Product)], |
|
159
|
|
|
|
|
|
|
$bittable[0]); |
|
160
|
0
|
0
|
|
|
|
|
defined $const_col or return $pack->warn ($flagref, "Enum table is missing column headed 'Constant'\n"); |
|
161
|
0
|
0
|
|
|
|
|
defined $mnem_col or return $pack->warn ($flagref, "Enum table is missing column headed 'Mnemonic'\n"); |
|
162
|
0
|
0
|
|
|
|
|
defined $def_col or return $pack->warn ($flagref, "Enum table is missing column headed 'Definition'\n"); |
|
163
|
|
|
|
|
|
|
|
|
164
|
0
|
|
|
|
|
|
my $classref = new SystemC::Vregs::Enum |
|
165
|
|
|
|
|
|
|
(pack => $pack, |
|
166
|
|
|
|
|
|
|
name => $classname, |
|
167
|
|
|
|
|
|
|
at => $flagref->{at}, |
|
168
|
|
|
|
|
|
|
); |
|
169
|
|
|
|
|
|
|
|
|
170
|
0
|
|
0
|
|
|
|
my $attr = $flagref->{Attributes}||""; |
|
171
|
0
|
|
|
|
|
|
while ($attr =~ s/-(\w+)//) { |
|
172
|
0
|
|
|
|
|
|
$classref->{attributes}{$1} = 1; |
|
173
|
|
|
|
|
|
|
} |
|
174
|
0
|
0
|
|
|
|
|
($attr =~ /^\s*$/) or $pack->warn($flagref, "Strange attributes $attr\n"); |
|
175
|
|
|
|
|
|
|
|
|
176
|
0
|
|
|
|
|
|
foreach my $row (@bittable) { |
|
177
|
0
|
0
|
|
|
|
|
print " Row:\n" if $Debug; |
|
178
|
0
|
|
|
|
|
|
foreach my $col (@$row) { |
|
179
|
0
|
0
|
|
|
|
|
print " Ent:$col\n" if $Debug; |
|
180
|
0
|
0
|
|
|
|
|
if (!defined $col) { |
|
181
|
0
|
|
|
|
|
|
$pack->warn ($flagref, "Column ".($col+1)." is empty\n"); |
|
182
|
|
|
|
|
|
|
} |
|
183
|
|
|
|
|
|
|
} |
|
184
|
0
|
0
|
|
|
|
|
next if $row eq $bittable[0]; # Ignore header |
|
185
|
|
|
|
|
|
|
|
|
186
|
0
|
|
|
|
|
|
my $val_mnem = _cleanup_column($row->[$mnem_col]); |
|
187
|
0
|
|
|
|
|
|
my $desc = _cleanup_column($row->[$def_col]); |
|
188
|
|
|
|
|
|
|
|
|
189
|
|
|
|
|
|
|
# Skip blank/reserved values |
|
190
|
0
|
0
|
0
|
|
|
|
next if ($val_mnem eq "" && ($desc eq "" || $desc =~ /^reserved/i)); |
|
|
|
|
0
|
|
|
|
|
|
191
|
|
|
|
|
|
|
|
|
192
|
|
|
|
|
|
|
# Check for empty field |
|
193
|
0
|
|
|
|
|
|
my $valref = new SystemC::Vregs::Enum::Value |
|
194
|
|
|
|
|
|
|
(pack => $pack, |
|
195
|
|
|
|
|
|
|
name => $val_mnem, |
|
196
|
|
|
|
|
|
|
class => $classref, |
|
197
|
|
|
|
|
|
|
rst => _cleanup_column($row->[$const_col]), |
|
198
|
|
|
|
|
|
|
desc => $desc, |
|
199
|
|
|
|
|
|
|
at => $flagref->{at}, |
|
200
|
|
|
|
|
|
|
); |
|
201
|
|
|
|
|
|
|
|
|
202
|
|
|
|
|
|
|
|
|
203
|
|
|
|
|
|
|
# Take special user defined fields and add to table |
|
204
|
0
|
|
|
|
|
|
for (my $colnum=0; $colnum<=$#{$bittable[0]}; $colnum++) { |
|
|
0
|
|
|
|
|
|
|
|
205
|
0
|
|
|
|
|
|
my $col = $bittable[0][$colnum]; |
|
206
|
0
|
|
|
|
|
|
$col =~ s/\s+//; |
|
207
|
0
|
0
|
|
|
|
|
if ($col =~ /^\s*\(([a-zA-Z_0-9]+)\)\s*$/) { |
|
208
|
0
|
|
|
|
|
|
my $var = $1; |
|
209
|
0
|
|
0
|
|
|
|
my $val = _cleanup_column($row->[$colnum]||""); |
|
210
|
0
|
0
|
|
|
|
|
$valref->{attributes}{$var} = $val if $val =~ /^([][a-zA-Z._:0-9+]+)$/; |
|
211
|
|
|
|
|
|
|
} |
|
212
|
|
|
|
|
|
|
} |
|
213
|
|
|
|
|
|
|
} |
|
214
|
|
|
|
|
|
|
} |
|
215
|
|
|
|
|
|
|
|
|
216
|
|
|
|
|
|
|
sub new_register { |
|
217
|
0
|
|
|
0
|
0
|
|
my $self = shift; |
|
218
|
0
|
|
|
|
|
|
my $bittableref = shift; my @bittable = @{$bittableref}; |
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
219
|
0
|
|
|
|
|
|
my $flagref = shift; # Hash of {heading} = value_of_heading |
|
220
|
|
|
|
|
|
|
# Create a new register |
|
221
|
0
|
|
|
|
|
|
my $pack = $self->{pack}; |
|
222
|
|
|
|
|
|
|
|
|
223
|
0
|
|
0
|
|
|
|
my $classname = _cleanup_column($flagref->{Register} || $flagref->{Class}); |
|
224
|
0
|
0
|
|
|
|
|
(defined $classname) or die; |
|
225
|
|
|
|
|
|
|
|
|
226
|
|
|
|
|
|
|
#print "new_register!\n",::Dumper(\$flagref,\@bittable); |
|
227
|
|
|
|
|
|
|
|
|
228
|
0
|
|
|
|
|
|
my $range = ""; |
|
229
|
0
|
0
|
|
|
|
|
$range = $1 if ($classname =~ s/(\[[^\]]+])//); |
|
230
|
0
|
|
|
|
|
|
$classname =~ s/\s+$//; |
|
231
|
|
|
|
|
|
|
|
|
232
|
0
|
|
0
|
|
|
|
my $is_register = ($flagref->{Register} || $flagref->{Address}); |
|
233
|
|
|
|
|
|
|
|
|
234
|
0
|
|
|
|
|
|
my $inherits = ""; |
|
235
|
0
|
0
|
|
|
|
|
if ($classname =~ s/\s*:\s*(\S+)$//) { |
|
236
|
0
|
|
|
|
|
|
$inherits = $1; |
|
237
|
|
|
|
|
|
|
} |
|
238
|
|
|
|
|
|
|
|
|
239
|
0
|
|
0
|
|
|
|
my $attr = $flagref->{Attributes}||""; |
|
240
|
0
|
0
|
|
|
|
|
return if $attr =~ /noimplementation/; |
|
241
|
|
|
|
|
|
|
|
|
242
|
0
|
|
|
|
|
|
my $typeref = new SystemC::Vregs::Type |
|
243
|
|
|
|
|
|
|
(pack => $pack, |
|
244
|
|
|
|
|
|
|
name => $classname, |
|
245
|
|
|
|
|
|
|
at => $flagref->{at}, |
|
246
|
|
|
|
|
|
|
is_register => $is_register, # Ok, perhaps I should have made a superclass |
|
247
|
|
|
|
|
|
|
); |
|
248
|
0
|
|
|
|
|
|
$typeref->inherits($inherits); |
|
249
|
|
|
|
|
|
|
|
|
250
|
|
|
|
|
|
|
# See also $typeref->{attributes}{lcfirst}, below. |
|
251
|
0
|
|
|
|
|
|
while ($attr =~ s/-([a-zA-Z_0-9]+)\s*=?\s*([a-zA-Z._0-9+]+)?//) { |
|
252
|
0
|
0
|
|
|
|
|
$typeref->{attributes}{$1} = (defined $2 ? $2 : 1); |
|
253
|
|
|
|
|
|
|
} |
|
254
|
0
|
0
|
|
|
|
|
($attr =~ /^\s*$/) or $pack->warn($flagref, "Strange attributes $attr\n"); |
|
255
|
|
|
|
|
|
|
|
|
256
|
0
|
0
|
|
|
|
|
if ($is_register) { |
|
257
|
|
|
|
|
|
|
# Declare a register |
|
258
|
0
|
0
|
|
|
|
|
($classname =~ /^[R]_/) or return $pack->warn($flagref, "Strange mnemonic name, doesn't begin with R_"); |
|
259
|
|
|
|
|
|
|
|
|
260
|
0
|
|
|
|
|
|
my $addr = $flagref->{Address}; # Don't _cleanup_column, as we have (Add 0x) text |
|
261
|
0
|
|
|
|
|
|
my $spacingtext = 0; |
|
262
|
0
|
0
|
|
|
|
|
$spacingtext = $pack->{data_bytes} if $range; |
|
263
|
0
|
0
|
|
|
|
|
if (!$addr) { |
|
264
|
0
|
|
|
|
|
|
$pack->warn ($flagref, "No 'Address' Heading Found\n"); |
|
265
|
0
|
|
|
|
|
|
return; |
|
266
|
|
|
|
|
|
|
} |
|
267
|
0
|
|
|
|
|
|
$addr =~ s/[()]//g; |
|
268
|
0
|
|
|
|
|
|
$addr =~ s/\s*plus\s*base\s*address\s*//; |
|
269
|
0
|
|
|
|
|
|
$addr =~ s/\s*per\s+entry//g; |
|
270
|
0
|
0
|
|
|
|
|
if ($addr =~ s/\s*Add\s*(0x[a-f0-9_]+)\s*//i) { |
|
271
|
0
|
|
|
|
|
|
$spacingtext = $1; |
|
272
|
|
|
|
|
|
|
} |
|
273
|
|
|
|
|
|
|
|
|
274
|
0
|
|
|
|
|
|
my $regref = new SystemC::Vregs::Register |
|
275
|
|
|
|
|
|
|
(pack => $pack, |
|
276
|
|
|
|
|
|
|
typeref => $typeref, |
|
277
|
|
|
|
|
|
|
name => $classname, |
|
278
|
|
|
|
|
|
|
at => $flagref->{at}, |
|
279
|
|
|
|
|
|
|
addrtext => $addr, |
|
280
|
|
|
|
|
|
|
spacingtext => $spacingtext, |
|
281
|
|
|
|
|
|
|
range => $range, |
|
282
|
|
|
|
|
|
|
); |
|
283
|
|
|
|
|
|
|
} |
|
284
|
|
|
|
|
|
|
|
|
285
|
0
|
0
|
0
|
|
|
|
if (defined $bittable[0] || !$inherits) { |
|
286
|
0
|
|
|
|
|
|
my ($bit_col, $mnem_col, $type_col, $def_col, |
|
287
|
|
|
|
|
|
|
$acc_col, $rst_col, |
|
288
|
|
|
|
|
|
|
$const_col, |
|
289
|
|
|
|
|
|
|
$size_col) |
|
290
|
|
|
|
|
|
|
= $self->_choose_columns ($flagref, |
|
291
|
|
|
|
|
|
|
[qw(Bit Mnemonic Type Definition), |
|
292
|
|
|
|
|
|
|
qw(Access Reset), # Register decls |
|
293
|
|
|
|
|
|
|
qw(Constant), # Class declarations |
|
294
|
|
|
|
|
|
|
qw(Size), # Ignored Optionals |
|
295
|
|
|
|
|
|
|
], |
|
296
|
|
|
|
|
|
|
[qw(Product)], |
|
297
|
|
|
|
|
|
|
$bittable[0]); |
|
298
|
0
|
|
0
|
|
|
|
$rst_col ||= $const_col; |
|
299
|
0
|
0
|
|
|
|
|
defined $bit_col or return $pack->warn ($flagref, "Table is missing column headed 'Bit'\n"); |
|
300
|
0
|
0
|
|
|
|
|
defined $mnem_col or return $pack->warn ($flagref, "Table is missing column headed 'Mnemonic'\n"); |
|
301
|
0
|
0
|
|
|
|
|
defined $def_col or return $pack->warn ($flagref, "Table is missing column headed 'Definition'\n"); |
|
302
|
0
|
0
|
|
|
|
|
if ($is_register) { |
|
303
|
0
|
0
|
|
|
|
|
defined $rst_col or return $pack->warn ($flagref, "Table is missing column headed 'Reset'\n"); |
|
304
|
0
|
0
|
|
|
|
|
defined $acc_col or return $pack->warn ($flagref, "Table is missing column headed 'Access'\n"); |
|
305
|
|
|
|
|
|
|
} |
|
306
|
|
|
|
|
|
|
|
|
307
|
|
|
|
|
|
|
# Table by table, allow the field mnemonics to be either 'fooFlag' |
|
308
|
|
|
|
|
|
|
# (per our Coding Conventions) or 'FooFlag' (as in a Vregs ASCII file). |
|
309
|
|
|
|
|
|
|
|
|
310
|
0
|
|
|
|
|
|
my $allMnems_LCFirst = (@bittable > 1); |
|
311
|
0
|
|
|
|
|
|
foreach my $row (@bittable) { |
|
312
|
0
|
0
|
|
|
|
|
next if $row eq $bittable[0]; # Ignore header |
|
313
|
0
|
0
|
|
|
|
|
my $bit_mnem = $row->[$mnem_col] or next; |
|
314
|
0
|
|
|
|
|
|
my $c1 = substr($bit_mnem, 0, 1); |
|
315
|
0
|
0
|
0
|
|
|
|
if ($c1 ge 'A' && $c1 le 'Z') { $allMnems_LCFirst = 0; } |
|
|
0
|
|
|
|
|
|
|
|
316
|
|
|
|
|
|
|
} |
|
317
|
0
|
0
|
|
|
|
|
if ($allMnems_LCFirst) { |
|
318
|
0
|
0
|
|
|
|
|
print " Upcasing first letter of mnemonics.\n" if $Debug; |
|
319
|
0
|
|
|
|
|
|
foreach my $row (@bittable) { |
|
320
|
0
|
0
|
|
|
|
|
next if $row eq $bittable[0]; # Ignore header |
|
321
|
0
|
0
|
|
|
|
|
my $bit_mnem = $row->[$mnem_col] or next; |
|
322
|
0
|
|
|
|
|
|
$row->[$mnem_col] = ucfirst $bit_mnem; |
|
323
|
|
|
|
|
|
|
} |
|
324
|
0
|
|
|
|
|
|
$typeref->{attributes}{lcfirst} = 1; |
|
325
|
|
|
|
|
|
|
} |
|
326
|
|
|
|
|
|
|
|
|
327
|
0
|
|
|
|
|
|
foreach my $row (@bittable) { |
|
328
|
0
|
0
|
|
|
|
|
print " Row:\n" if $Debug; |
|
329
|
0
|
|
|
|
|
|
foreach my $col (@$row) { |
|
330
|
0
|
0
|
|
|
|
|
print " Ent:$col\n" if $Debug; |
|
331
|
0
|
0
|
|
|
|
|
if (!defined $col) { |
|
332
|
0
|
|
|
|
|
|
$pack->warn ($flagref, "Column ".($col+1)." is empty\n"); |
|
333
|
|
|
|
|
|
|
} |
|
334
|
|
|
|
|
|
|
} |
|
335
|
0
|
0
|
|
|
|
|
next if $row eq $bittable[0]; # Ignore header |
|
336
|
|
|
|
|
|
|
|
|
337
|
|
|
|
|
|
|
# Check for empty field |
|
338
|
0
|
|
|
|
|
|
my $bit_mnem = $row->[$mnem_col]; |
|
339
|
0
|
|
|
|
|
|
$bit_mnem =~ s/^_//; |
|
340
|
0
|
|
|
|
|
|
my $desc = $row->[$def_col]; |
|
341
|
|
|
|
|
|
|
|
|
342
|
0
|
|
|
|
|
|
my $overlaps = ""; |
|
343
|
0
|
0
|
|
|
|
|
$overlaps = $1 if ($desc =~ /\boverlaps\s+([a-zA-Z0-9_]+)/i); |
|
344
|
|
|
|
|
|
|
|
|
345
|
|
|
|
|
|
|
# Skip empty fields |
|
346
|
0
|
0
|
0
|
|
|
|
if (($bit_mnem eq "" || $bit_mnem eq '-') |
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
347
|
|
|
|
|
|
|
&& ($desc eq "" || $desc =~ /Reserved/ || $desc=~/Hardwired/ |
|
348
|
|
|
|
|
|
|
|| $desc =~ /^(\/\/|\#)/)) { # Allow //Comment or #Comment |
|
349
|
0
|
|
|
|
|
|
next; |
|
350
|
|
|
|
|
|
|
} |
|
351
|
0
|
0
|
0
|
|
|
|
if ((!defined $bit_col || $row->[$bit_col] eq "") |
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
352
|
|
|
|
|
|
|
&& (!defined $mnem_col || $row->[$mnem_col] eq "") |
|
353
|
|
|
|
|
|
|
&& (!defined $rst_col || $row->[$rst_col] eq "") |
|
354
|
|
|
|
|
|
|
) { |
|
355
|
0
|
|
|
|
|
|
next; # All blank lines (excl comment) are fine. |
|
356
|
|
|
|
|
|
|
} |
|
357
|
|
|
|
|
|
|
|
|
358
|
0
|
0
|
|
|
|
|
my $rst = _cleanup_column(defined $rst_col ? $row->[$rst_col] : ""); |
|
359
|
0
|
0
|
0
|
|
|
|
$rst = 'X' if ($rst eq "" && !$is_register); |
|
360
|
|
|
|
|
|
|
|
|
361
|
0
|
|
0
|
|
|
|
my $type = _cleanup_column(defined $type_col && $row->[$type_col]); |
|
362
|
|
|
|
|
|
|
|
|
363
|
0
|
0
|
|
|
|
|
my $acc = _cleanup_column(defined $acc_col ? $row->[$acc_col] : 'RW'); |
|
364
|
|
|
|
|
|
|
|
|
365
|
0
|
0
|
|
|
|
|
(!$typeref->{fields}{$bit_mnem}) or |
|
366
|
|
|
|
|
|
|
$pack->warn ($typeref->{fields}{$bit_mnem}, "Field defined twice in spec\n"); |
|
367
|
0
|
0
|
0
|
|
|
|
my $bitref = new SystemC::Vregs::Bit |
|
368
|
|
|
|
|
|
|
(pack => $pack, |
|
369
|
|
|
|
|
|
|
name => $bit_mnem, |
|
370
|
|
|
|
|
|
|
typeref => $typeref, |
|
371
|
|
|
|
|
|
|
bits => $row->[$bit_col], |
|
372
|
|
|
|
|
|
|
access => $acc, |
|
373
|
|
|
|
|
|
|
overlaps => $overlaps, |
|
374
|
|
|
|
|
|
|
rst => $rst, |
|
375
|
|
|
|
|
|
|
desc => $row->[$def_col], |
|
376
|
|
|
|
|
|
|
type => $type, |
|
377
|
|
|
|
|
|
|
expand => ($type && $desc =~ /expand class/i)?1:undef, |
|
378
|
|
|
|
|
|
|
at => $flagref->{at}, |
|
379
|
|
|
|
|
|
|
); |
|
380
|
|
|
|
|
|
|
|
|
381
|
|
|
|
|
|
|
# Take special user defined fields and add to table |
|
382
|
0
|
|
|
|
|
|
for (my $colnum=0; $colnum<=$#{$bittable[0]}; $colnum++) { |
|
|
0
|
|
|
|
|
|
|
|
383
|
0
|
|
|
|
|
|
my $col = $bittable[0][$colnum]; |
|
384
|
0
|
|
|
|
|
|
$col =~ s/\s+//; |
|
385
|
0
|
0
|
|
|
|
|
if ($col =~ /^\s*\(([a-zA-Z_0-9]+)\)\s*$/) { |
|
386
|
0
|
|
|
|
|
|
my $var = $1; |
|
387
|
0
|
|
0
|
|
|
|
my $val = _cleanup_column($row->[$colnum]||""); |
|
388
|
0
|
0
|
|
|
|
|
$bitref->{attributes}{$var} = $val if $val =~ /^([][a-zA-Z._:0-9+]+)$/; |
|
389
|
|
|
|
|
|
|
} |
|
390
|
|
|
|
|
|
|
} |
|
391
|
|
|
|
|
|
|
} |
|
392
|
|
|
|
|
|
|
} |
|
393
|
|
|
|
|
|
|
} |
|
394
|
|
|
|
|
|
|
|
|
395
|
|
|
|
|
|
|
###################################################################### |
|
396
|
|
|
|
|
|
|
#### Parsing |
|
397
|
|
|
|
|
|
|
|
|
398
|
|
|
|
|
|
|
sub _choose_columns { |
|
399
|
0
|
|
|
0
|
|
|
my $self = shift; |
|
400
|
0
|
|
|
|
|
|
my $flagref = shift; |
|
401
|
0
|
|
|
|
|
|
my $fieldref = shift; |
|
402
|
0
|
|
|
|
|
|
my $attrfieldref = shift; |
|
403
|
0
|
|
|
|
|
|
my $headref = shift; |
|
404
|
|
|
|
|
|
|
# Look for the columns with the given headings. Require them to exist. |
|
405
|
|
|
|
|
|
|
|
|
406
|
0
|
|
|
|
|
|
my @collist; |
|
407
|
0
|
|
|
|
|
|
my @colused = (); |
|
408
|
0
|
|
|
|
|
|
my @colheads; |
|
409
|
|
|
|
|
|
|
# The list is short, so this is faster than forming a hash. |
|
410
|
|
|
|
|
|
|
# If things get wide, this may change |
|
411
|
0
|
|
|
|
|
|
for (my $h=0; $h<=$#{$headref}; $h++) { |
|
|
0
|
|
|
|
|
|
|
|
412
|
0
|
|
|
|
|
|
$colheads[$h] = $headref->[$h]; |
|
413
|
0
|
|
|
|
|
|
$colheads[$h] =~ s/\s*\(.*\)\s*//; # Ignore comments in the header |
|
414
|
0
|
0
|
|
|
|
|
$colused[$h] = 1 if $colheads[$h] eq ""; |
|
415
|
|
|
|
|
|
|
} |
|
416
|
0
|
|
|
|
|
|
headchk: |
|
417
|
0
|
|
|
|
|
|
foreach my $fld (@{$fieldref}) { |
|
418
|
0
|
|
|
|
|
|
for (my $h=0; $h<=$#{$headref}; $h++) { |
|
|
0
|
|
|
|
|
|
|
|
419
|
0
|
0
|
|
|
|
|
if ($fld eq $colheads[$h]) { |
|
420
|
0
|
|
|
|
|
|
push @collist, $h; |
|
421
|
0
|
|
|
|
|
|
$colused[$h] = 1; |
|
422
|
0
|
|
|
|
|
|
next headchk; |
|
423
|
|
|
|
|
|
|
} |
|
424
|
|
|
|
|
|
|
} |
|
425
|
0
|
|
|
|
|
|
push @collist, undef; |
|
426
|
|
|
|
|
|
|
} |
|
427
|
0
|
|
|
|
|
|
foreach my $fld (@{$attrfieldref}) { |
|
|
0
|
|
|
|
|
|
|
|
428
|
0
|
|
|
|
|
|
for (my $h=0; $h<=$#{$headref}; $h++) { |
|
|
0
|
|
|
|
|
|
|
|
429
|
0
|
0
|
|
|
|
|
if ($fld eq $colheads[$h]) { |
|
430
|
|
|
|
|
|
|
# Convert to a attribute |
|
431
|
0
|
|
|
|
|
|
$headref->[$h] = "(".$headref->[$h].")"; |
|
432
|
0
|
|
|
|
|
|
$colused[$h] = 1; |
|
433
|
|
|
|
|
|
|
} |
|
434
|
|
|
|
|
|
|
} |
|
435
|
|
|
|
|
|
|
} |
|
436
|
|
|
|
|
|
|
|
|
437
|
0
|
|
|
|
|
|
my $ncol = 0; |
|
438
|
0
|
|
|
|
|
|
for (my $h=0; $h<=$#{$headref}; $h++) { |
|
|
0
|
|
|
|
|
|
|
|
439
|
0
|
0
|
|
|
|
|
$ncol = $h+1 if !$colused[$h]; |
|
440
|
|
|
|
|
|
|
} |
|
441
|
|
|
|
|
|
|
|
|
442
|
0
|
0
|
|
|
|
|
if ($ncol) { |
|
443
|
0
|
|
|
|
|
|
SystemC::Vregs::Subclass::warn ($flagref, "Column ".($ncol-1)." found with unknown header.\n"); |
|
444
|
0
|
|
|
|
|
|
print "Desired column headers: '",join("' '",@{$fieldref}),"'\n"; |
|
|
0
|
|
|
|
|
|
|
|
445
|
0
|
|
|
|
|
|
print "Found column headers: '",join("' '",@{$headref}),"'\n"; |
|
|
0
|
|
|
|
|
|
|
|
446
|
0
|
0
|
|
|
|
|
print "Defined:("; foreach (@collist) { print (((defined $_)?$_:'-'),' '); } |
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
447
|
0
|
|
|
|
|
|
print ")\n"; |
|
448
|
0
|
0
|
|
|
|
|
print "Used: ("; foreach (@colused) { print ((($_)?'Y':'-'),' '); } |
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
449
|
0
|
|
|
|
|
|
print ")\n"; |
|
450
|
|
|
|
|
|
|
} |
|
451
|
|
|
|
|
|
|
|
|
452
|
0
|
|
|
|
|
|
return (@collist); |
|
453
|
|
|
|
|
|
|
} |
|
454
|
|
|
|
|
|
|
|
|
455
|
|
|
|
|
|
|
sub _cleanup_column { |
|
456
|
0
|
|
|
0
|
|
|
my $text = shift; |
|
457
|
0
|
0
|
|
|
|
|
return undef if !defined $text; |
|
458
|
0
|
|
|
|
|
|
while ($text =~ s/\s*\([^\(\)]*\)//) {} # Strip (comment) Leave trailing space "foo (bar) x" becomes "foo x" |
|
459
|
0
|
|
|
|
|
|
$text =~ s/\s+$//; |
|
460
|
0
|
|
|
|
|
|
$text =~ s/^\s+//; |
|
461
|
0
|
|
|
|
|
|
return $text; |
|
462
|
|
|
|
|
|
|
} |
|
463
|
|
|
|
|
|
|
|
|
464
|
|
|
|
|
|
|
###################################################################### |
|
465
|
|
|
|
|
|
|
###################################################################### |
|
466
|
|
|
|
|
|
|
#### Package return |
|
467
|
|
|
|
|
|
|
1; |
|
468
|
|
|
|
|
|
|
__END__ |