File Coverage

blib/lib/Verilog/Netlist/Module.pm
Criterion Covered Total %
statement 180 203 88.6
branch 18 28 64.2
condition 18 36 50.0
subroutine 35 39 89.7
pod 24 29 82.7
total 275 335 82.0


line stmt bran cond sub pod time code
1             # Verilog - Verilog Perl Interface
2             # See copyright, etc in below POD section.
3             ######################################################################
4              
5             package Verilog::Netlist::Module;
6              
7 8     8   58 use Verilog::Netlist;
  8         15  
  8         278  
8 8     8   3456 use Verilog::Netlist::ContAssign;
  8         22  
  8         384  
9 8     8   3760 use Verilog::Netlist::Defparam;
  8         21  
  8         373  
10 8     8   55 use Verilog::Netlist::Port;
  8         14  
  8         257  
11 8     8   41 use Verilog::Netlist::Net;
  8         16  
  8         230  
12 8     8   43 use Verilog::Netlist::Cell;
  8         12  
  8         222  
13 8     8   42 use Verilog::Netlist::Pin;
  8         15  
  8         197  
14 8     8   36 use Verilog::Netlist::Subclass;
  8         16  
  8         366  
15 8     8   45 use vars qw($VERSION @ISA);
  8         14  
  8         379  
16 8     8   49 use strict;
  8         14  
  8         19958  
17             @ISA = qw(Verilog::Netlist::Module::Struct
18             Verilog::Netlist::Subclass);
19              
20             $VERSION = '3.478';
21              
22             structs('new',
23             'Verilog::Netlist::Module::Struct'
24             =>[name => '$', #' # Name of the module
25             filename => '$', #' # Filename this came from
26             lineno => '$', #' # Linenumber this came from
27             netlist => '$', #' # Netlist is a member of
28             keyword => '$', #' # Type of module
29             userdata => '%', # User information
30             attributes => '%', #' # Misc attributes for systemperl or other processors
31             #
32             attrs => '@', # list of "category name[ =](.*)" strings
33             comment => '$', #' # Comment provided by user
34             _ports => '%', # hash of Verilog::Netlist::Ports
35             _portsordered=> '@', # list of Verilog::Netlist::Ports as ordered in list of ports
36             _nets => '%', # hash of Verilog::Netlist::Nets
37             _cells => '%', # hash of Verilog::Netlist::Cells
38             _celldecls => '%', # hash of declared cells (for autocell only)
39             _cellarray => '%', # hash of declared cell widths (for autocell only)
40             _cellnum => '$', # Number of next unnamed cell
41             _level => '$', # Depth in hierarchy (if calculated)
42             _statements => '%', # hash of Verilog::Netlist::ContAssigns
43             _stmtnum => '$', # Number of next unnamed statement
44             is_top => '$', #' # Module is at top of hier (not a child)
45             is_libcell => '$', #' # Module is a library cell
46             # SystemPerl:
47             _autocovers => '%', #' # Hash of covers found in code
48             _autosignal => '$', #' # Module has /*AUTOSIGNAL*/ in it
49             _autosubcells=> '$', #' # Module has /*AUTOSUBCELL_DECL*/ in it
50             _autotrace => '%', #' # Module has /*AUTOTRACE*/ in it
51             _autoinoutmod=> '$', #' # Module has /*AUTOINOUT_MODULE*/ in it
52             _pintemplates=> '@', #' # Module SP_TEMPLATEs
53             _ctor => '$', #' # Module has SC_CTOR in it
54             _code_symbols=> '$', #' # Hash ref of symbols found in raw code
55             _covergroups => '%', #' # Hash of covergroups found in code
56             lesswarn => '$', #' # True if some warnings should be disabled
57             ]);
58              
59             sub delete {
60 204     204 0 344 my $self = shift;
61 204         659 foreach my $oref ($self->nets) {
62 12406         27598 $oref->delete;
63             }
64 204         24515 foreach my $oref ($self->ports) {
65 603         1608 $oref->delete;
66             }
67 204         1310 foreach my $oref ($self->cells) {
68 400         1252 $oref->delete;
69             }
70 204         1225 foreach my $oref ($self->statements) {
71 0         0 $oref->delete;
72             }
73 204         2899 my $h = $self->netlist->{_modules};
74 204         2940 delete $h->{$self->name};
75 204         589 return undef;
76             }
77              
78             ######################################################################
79              
80             sub logger {
81 0     0 1 0 return $_[0]->netlist->logger;
82             }
83              
84             sub modulename_from_filename {
85 239     239 1 391 my $filename = shift;
86 239         1211 (my $module = $filename) =~ s/.*\///;
87 239         1038 $module =~ s/\.[a-z]+$//;
88 239         3763 return $module;
89             }
90              
91             sub find_port {
92 26     26 1 52 my $self = shift;
93 26         37 my $search = shift;
94 26   33     350 return $self->_ports->{$search} || $self->_ports->{"\\".$search." "};
95             }
96             sub find_port_by_index {
97 17     17 1 31 my $self = shift;
98 17         27 my $myindex = shift;
99             # @{$self->_portsordered}[$myindex-1] returns the name of
100             # the port in the module at this index. Then, this is
101             # used to find the port reference via the port hash
102 17         38 my $name = @{$self->_portsordered}[$myindex-1];
  17         230  
103 17 50       44 return undef if !$name;
104 17         331 return $self->_ports->{$name};
105             }
106             sub find_cell {
107 452     452 1 742 my $self = shift;
108 452         695 my $search = shift;
109 452   66     8847 return $self->_cells->{$search} || $self->_cells->{"\\".$search." "};
110             }
111             sub find_net {
112 12720     12720 1 16535 my $self = shift;
113 12720         15124 my $search = shift;
114 12720   100     230979 my $rtn = $self->_nets->{$search}||"";
115             #print "FINDNET ",$self->name, " SS $search $rtn\n";
116 12720   66     170055 return $self->_nets->{$search} || $self->_nets->{"\\".$search." "};
117             }
118              
119             sub attrs_sorted {
120 0     0 0 0 return (sort {$a cmp $b} @{$_[0]->attrs});
  0         0  
  0         0  
121             }
122             sub nets {
123 337     337 1 430 return (values %{$_[0]->_nets});
  337         6661  
124             }
125             sub nets_sorted {
126 97     97 1 253 return (sort {$a->name() cmp $b->name()} (values %{$_[0]->_nets}));
  550         6994  
  97         1618  
127             }
128             sub ports {
129 337     337 1 471 return (values %{$_[0]->_ports});
  337         6096  
130             }
131             sub ports_sorted {
132 80     80 1 126 return (sort {$a->name() cmp $b->name()} (values %{$_[0]->_ports}));
  150         2058  
  80         1320  
133             }
134             sub ports_ordered {
135 1     1 1 3 my $self = shift;
136 1         2 return map {$self->_ports->{$_}} @{$self->_portsordered};
  3         42  
  1         24  
137             }
138             sub cells {
139 346     346 1 518 return (values %{$_[0]->_cells});
  346         4751  
140             }
141             sub cells_sorted {
142 79     79 1 129 return (sort {$a->name() cmp $b->name()} (values %{$_[0]->_cells}));
  53         855  
  79         1267  
143             }
144             sub statements {
145 243     243 1 670 return (values %{$_[0]->_statements});
  243         3456  
146             }
147             sub statements_sorted {
148 69     69 1 84 return (sort {$a->name() cmp $b->name()} (values %{$_[0]->_statements}));
  8         159  
  69         1092  
149             }
150              
151             sub nets_and_ports_sorted {
152 0     0 1 0 my $self = shift;
153 0         0 my @list = ($self->nets, $self->ports,);
154 0         0 my @outlist; my $last = "";
  0         0  
155             # Eliminate duplicates
156 0         0 foreach my $e (sort {$a->name() cmp $b->name()} (@list)) {
  0         0  
157 0 0       0 next if $e eq $last;
158 0         0 push @outlist, $e;
159 0         0 $last = $e;
160             }
161 0         0 return (@outlist);
162             }
163              
164             sub new_net {
165 12572     12572 1 19389 my $self = shift;
166 12572         77085 my %params = @_;
167              
168             # Create a new net under this
169 12572         16730 my $netref;
170 12572 100       21901 if (defined($params{msb})) {
171 461         631 my $data_type;
172 461         730 $data_type = "[".($params{msb});
173 461 50       1233 $data_type .= ":".($params{lsb}) if defined $params{lsb};
174 461         583 $data_type .= "]";
175 461         2412 $netref = new Verilog::Netlist::Net(decl_type=>'net',
176             net_type => 'wire',
177             data_type => $data_type,
178             %params,
179             module => $self);
180             } else {
181 12111         55153 $netref = new Verilog::Netlist::Net(decl_type => 'net',
182             net_type => 'wire',
183             %params,
184             module => $self);
185             }
186 12572         179540 $self->_nets($netref->name(), $netref);
187 12572         43348 return $netref;
188             }
189              
190             sub new_attr {
191 0     0 0 0 my $self = shift;
192 0         0 my $clean_text = shift;
193 0         0 push @{$self->attrs}, $clean_text;
  0         0  
194             }
195              
196             sub new_port {
197 684     684 1 1144 my $self = shift;
198             # @_ params
199             # Create a new port under this module
200 684         2739 my $portref = new Verilog::Netlist::Port(@_, module=>$self,);
201 684         9475 $self->_ports($portref->name(), $portref);
202 684         20902 return $portref;
203             }
204              
205             sub new_cell {
206 451     451 1 782 my $self = shift;
207 451         1955 my %params = @_; # name=>, filename=>, lineno=>, submodname=>, params=>
208             # Create a new cell under this module
209 451 50 33     2986 if (!defined $params{name} || $params{name} eq '') {
210             # Blank instance name; invent a new one; use the next instance number in this module t$
211 0   0     0 $self->_cellnum(($self->_cellnum||0) + 1);
212 0         0 $params{name} = '__unnamed_instance_' . $self->_cellnum;
213             }
214 451 50       1557 if (my $preexist = $self->find_cell($params{name})) {
215 0   0     0 $self->_cellnum(($self->_cellnum||0) + 1);
216 0         0 $params{name} .= '__duplicate_' . $self->_cellnum;
217             }
218             # Create a new cell; pass the potentially modified options
219 451         7638 my $cellref = new Verilog::Netlist::Cell(%params, module=>$self,);
220             # Add the new cell to the hash of cells in this module
221 451         6667 $self->_cells($params{name}, $cellref);
222 451         1493 return $cellref;
223             }
224              
225             sub new_contassign {
226 6     6 0 19 my $self = shift;
227 6         36 my %params = @_; # name=>, filename=>, lineno=>, keyword=> etc
228             # Create a new statement under this module
229 6 50 33     30 if (!defined $params{name} || $params{name} eq '') {
230             # Blank instance name; invent a new one; use the next instance number in this module t$
231 6   100     140 $self->_stmtnum(($self->_stmtnum||0) + 1);
232 6         81 $params{name} = '__unnamed_statement_' . $self->_stmtnum;
233             }
234             # Create a new object; pass the potentially modified options
235 6         130 my $newref = new Verilog::Netlist::ContAssign(%params, module=>$self,);
236             # Add the new object to the hash of statements in this module
237 6         100 $self->_statements($params{name}, $newref);
238 6         121 return $newref;
239             }
240              
241             sub new_defparam {
242 4     4 0 10 my $self = shift;
243 4         24 my %params = @_; # name=>, filename=>, lineno=>, keyword=> etc
244             # Create a new statement under this module
245 4 50 33     22 if (!defined $params{name} || $params{name} eq '') {
246             # Blank instance name; invent a new one; use the next instance number in this module t$
247 4   50     98 $self->_stmtnum(($self->_stmtnum||0) + 1);
248 4         57 $params{name} = '__unnamed_statement_' . $self->_stmtnum;
249             }
250             # Create a new object; pass the potentially modified options
251 4         86 my $newref = new Verilog::Netlist::Defparam(%params, module=>$self,);
252             # Add the new object to the hash of statements in this module
253 4         80 $self->_statements($params{name}, $newref);
254 4         164 return $newref;
255             }
256              
257             sub level {
258 44     44 1 54 my $self = shift;
259 44         584 my $level = $self->_level;
260 44 100       232 return $level if defined $level;
261 9         116 $self->_level(1); # Set before recurse in case there's circular module refs
262 9         16 foreach my $cell ($self->cells) {
263 12 100       154 if ($cell->submod) {
264 11         139 my $celllevel = $cell->submod->level;
265 11 100       138 $self->_level($celllevel+1) if $celllevel >= $self->_level;
266             }
267             }
268 9         117 return $self->_level;
269             }
270              
271             sub link {
272 94     94 1 141 my $self = shift;
273             # Ports create nets, so link ports before nets
274 94         199 foreach my $portref ($self->ports) {
275 164         387 $portref->_link();
276             }
277 94         240 foreach my $netref ($self->nets) {
278 332         626 $netref->_link();
279             }
280 94         190 foreach my $cellref ($self->cells) {
281 98         296 $cellref->_link();
282             }
283             }
284              
285             sub lint {
286 39     39 1 56 my $self = shift;
287 39 50       491 if ($self->netlist->{use_vars}) {
288 39         80 foreach my $portref ($self->ports) {
289 72         143 $portref->lint();
290             }
291 39         77 foreach my $netref ($self->nets) {
292 137         352 $netref->lint();
293             }
294             }
295 39         82 foreach my $cellref ($self->cells) {
296 39         106 $cellref->lint();
297             }
298 39         87 foreach my $oref ($self->statements) {
299 8         35 $oref->lint();
300             }
301             }
302              
303             sub verilog_text {
304 32     32 1 46 my $self = shift;
305 32   50     476 my @out = ($self->keyword||'module')." ".$self->name." (\n";
306 32         63 my $indent = " ";
307             # Port list
308 32         51 my $comma="";
309 32         51 push @out, $indent;
310 32         78 foreach my $portref ($self->ports_sorted) {
311 68         160 push @out, $comma, $portref->verilog_text;
312 68         106 $comma = ", ";
313             }
314 32         58 push @out, ");\n";
315              
316             # Signal list
317 32         125 foreach my $netref ($self->nets_sorted) {
318 117         275 push @out, $indent, $netref->verilog_text, "\n";
319             }
320             # Cell list
321 32         94 foreach my $cellref ($self->cells_sorted) {
322 28         78 push @out, $indent, $cellref->verilog_text, "\n";
323             }
324 32         75 foreach my $oref ($self->statements_sorted) {
325 8         29 push @out, $indent, $oref->verilog_text, "\n";
326             }
327              
328 32   50     1035 push @out, "end".($self->keyword||'module')."\n";
329 32 50       516 return (wantarray ? @out : join('',@out));
330             }
331              
332             sub dump {
333 67     67 1 100 my $self = shift;
334 67   100     214 my $indent = shift||0;
335 67         86 my $norecurse = shift;
336 67   50     970 print " "x$indent,"Module:",$self->name()," Kwd:",($self->keyword||'')," File:",$self->filename(),"\n";
337 67 100       318 if (!$norecurse) {
338 37         211 foreach my $portref ($self->ports_sorted) {
339 70         256 $portref->dump($indent+2);
340             }
341 37         124 foreach my $netref ($self->nets_sorted) {
342 135         508 $netref->dump($indent+2);
343             }
344 37         163 foreach my $cellref ($self->cells_sorted) {
345 36         130 $cellref->dump($indent+2);
346             }
347 37         106 foreach my $cellref ($self->statements_sorted) {
348 8         41 $cellref->dump($indent+2);
349             }
350             }
351             }
352              
353             ######################################################################
354             #### Package return
355             1;
356             __END__