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   45 use Verilog::Netlist;
  8         11  
  8         202  
8 8     8   2732 use Verilog::Netlist::ContAssign;
  8         19  
  8         296  
9 8     8   2787 use Verilog::Netlist::Defparam;
  8         16  
  8         291  
10 8     8   47 use Verilog::Netlist::Port;
  8         12  
  8         229  
11 8     8   33 use Verilog::Netlist::Net;
  8         13  
  8         193  
12 8     8   49 use Verilog::Netlist::Cell;
  8         13  
  8         175  
13 8     8   32 use Verilog::Netlist::Pin;
  8         12  
  8         184  
14 8     8   61 use Verilog::Netlist::Subclass;
  8         13  
  8         313  
15 8     8   39 use vars qw($VERSION @ISA);
  8         19  
  8         323  
16 8     8   47 use strict;
  8         19  
  8         15828  
17             @ISA = qw(Verilog::Netlist::Module::Struct
18             Verilog::Netlist::Subclass);
19              
20             $VERSION = '3.480';
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 316 my $self = shift;
61 204         477 foreach my $oref ($self->nets) {
62 12406         21183 $oref->delete;
63             }
64 204         20180 foreach my $oref ($self->ports) {
65 603         1277 $oref->delete;
66             }
67 204         1104 foreach my $oref ($self->cells) {
68 400         932 $oref->delete;
69             }
70 204         1342 foreach my $oref ($self->statements) {
71 0         0 $oref->delete;
72             }
73 204         2408 my $h = $self->netlist->{_modules};
74 204         2411 delete $h->{$self->name};
75 204         492 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 406 my $filename = shift;
86 239         1000 (my $module = $filename) =~ s/.*\///;
87 239         906 $module =~ s/\.[a-z]+$//;
88 239         3042 return $module;
89             }
90              
91             sub find_port {
92 26     26 1 41 my $self = shift;
93 26         31 my $search = shift;
94 26   33     280 return $self->_ports->{$search} || $self->_ports->{"\\".$search." "};
95             }
96             sub find_port_by_index {
97 17     17 1 22 my $self = shift;
98 17         20 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         31 my $name = @{$self->_portsordered}[$myindex-1];
  17         185  
103 17 50       34 return undef if !$name;
104 17         271 return $self->_ports->{$name};
105             }
106             sub find_cell {
107 452     452 1 643 my $self = shift;
108 452         513 my $search = shift;
109 452   66     7160 return $self->_cells->{$search} || $self->_cells->{"\\".$search." "};
110             }
111             sub find_net {
112 12720     12720 1 12885 my $self = shift;
113 12720         12805 my $search = shift;
114 12720   100     180902 my $rtn = $self->_nets->{$search}||"";
115             #print "FINDNET ",$self->name, " SS $search $rtn\n";
116 12720   66     134942 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 426 return (values %{$_[0]->_nets});
  337         5397  
124             }
125             sub nets_sorted {
126 97     97 1 206 return (sort {$a->name() cmp $b->name()} (values %{$_[0]->_nets}));
  527         5641  
  97         1274  
127             }
128             sub ports {
129 337     337 1 411 return (values %{$_[0]->_ports});
  337         4320  
130             }
131             sub ports_sorted {
132 80     80 1 107 return (sort {$a->name() cmp $b->name()} (values %{$_[0]->_ports}));
  137         1469  
  80         1049  
133             }
134             sub ports_ordered {
135 1     1 1 3 my $self = shift;
136 1         2 return map {$self->_ports->{$_}} @{$self->_portsordered};
  3         32  
  1         19  
137             }
138             sub cells {
139 346     346 1 417 return (values %{$_[0]->_cells});
  346         4858  
140             }
141             sub cells_sorted {
142 79     79 1 115 return (sort {$a->name() cmp $b->name()} (values %{$_[0]->_cells}));
  51         584  
  79         1006  
143             }
144             sub statements {
145 243     243 1 678 return (values %{$_[0]->_statements});
  243         2914  
146             }
147             sub statements_sorted {
148 69     69 1 70 return (sort {$a->name() cmp $b->name()} (values %{$_[0]->_statements}));
  8         123  
  69         823  
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 17188 my $self = shift;
166 12572         62660 my %params = @_;
167              
168             # Create a new net under this
169 12572         14026 my $netref;
170 12572 100       18724 if (defined($params{msb})) {
171 461         561 my $data_type;
172 461         637 $data_type = "[".($params{msb});
173 461 50       1009 $data_type .= ":".($params{lsb}) if defined $params{lsb};
174 461         512 $data_type .= "]";
175 461         1979 $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         45057 $netref = new Verilog::Netlist::Net(decl_type => 'net',
182             net_type => 'wire',
183             %params,
184             module => $self);
185             }
186 12572         142571 $self->_nets($netref->name(), $netref);
187 12572         38664 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 930 my $self = shift;
198             # @_ params
199             # Create a new port under this module
200 684         2964 my $portref = new Verilog::Netlist::Port(@_, module=>$self,);
201 684         8019 $self->_ports($portref->name(), $portref);
202 684         16745 return $portref;
203             }
204              
205             sub new_cell {
206 451     451 1 648 my $self = shift;
207 451         1807 my %params = @_; # name=>, filename=>, lineno=>, submodname=>, params=>
208             # Create a new cell under this module
209 451 50 33     1915 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       1162 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         6484 my $cellref = new Verilog::Netlist::Cell(%params, module=>$self,);
220             # Add the new cell to the hash of cells in this module
221 451         5518 $self->_cells($params{name}, $cellref);
222 451         1343 return $cellref;
223             }
224              
225             sub new_contassign {
226 6     6 0 12 my $self = shift;
227 6         26 my %params = @_; # name=>, filename=>, lineno=>, keyword=> etc
228             # Create a new statement under this module
229 6 50 33     23 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     94 $self->_stmtnum(($self->_stmtnum||0) + 1);
232 6         65 $params{name} = '__unnamed_statement_' . $self->_stmtnum;
233             }
234             # Create a new object; pass the potentially modified options
235 6         129 my $newref = new Verilog::Netlist::ContAssign(%params, module=>$self,);
236             # Add the new object to the hash of statements in this module
237 6         86 $self->_statements($params{name}, $newref);
238 6         126 return $newref;
239             }
240              
241             sub new_defparam {
242 4     4 0 5 my $self = shift;
243 4         16 my %params = @_; # name=>, filename=>, lineno=>, keyword=> etc
244             # Create a new statement under this module
245 4 50 33     15 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     78 $self->_stmtnum(($self->_stmtnum||0) + 1);
248 4         45 $params{name} = '__unnamed_statement_' . $self->_stmtnum;
249             }
250             # Create a new object; pass the potentially modified options
251 4         91 my $newref = new Verilog::Netlist::Defparam(%params, module=>$self,);
252             # Add the new object to the hash of statements in this module
253 4         61 $self->_statements($params{name}, $newref);
254 4         131 return $newref;
255             }
256              
257             sub level {
258 54     54 1 48 my $self = shift;
259 54         572 my $level = $self->_level;
260 54 100       180 return $level if defined $level;
261 9         93 $self->_level(1); # Set before recurse in case there's circular module refs
262 9         14 foreach my $cell ($self->cells) {
263 12 100       131 if ($cell->submod) {
264 11         112 my $celllevel = $cell->submod->level;
265 11 100       114 $self->_level($celllevel+1) if $celllevel >= $self->_level;
266             }
267             }
268 9         97 return $self->_level;
269             }
270              
271             sub link {
272 94     94 1 107 my $self = shift;
273             # Ports create nets, so link ports before nets
274 94         167 foreach my $portref ($self->ports) {
275 164         313 $portref->_link();
276             }
277 94         189 foreach my $netref ($self->nets) {
278 332         446 $netref->_link();
279             }
280 94         165 foreach my $cellref ($self->cells) {
281 98         225 $cellref->_link();
282             }
283             }
284              
285             sub lint {
286 39     39 1 43 my $self = shift;
287 39 50       401 if ($self->netlist->{use_vars}) {
288 39         76 foreach my $portref ($self->ports) {
289 72         111 $portref->lint();
290             }
291 39         65 foreach my $netref ($self->nets) {
292 137         194 $netref->lint();
293             }
294             }
295 39         63 foreach my $cellref ($self->cells) {
296 39         80 $cellref->lint();
297             }
298 39         70 foreach my $oref ($self->statements) {
299 8         24 $oref->lint();
300             }
301             }
302              
303             sub verilog_text {
304 32     32 1 39 my $self = shift;
305 32   50     396 my @out = ($self->keyword||'module')." ".$self->name." (\n";
306 32         48 my $indent = " ";
307             # Port list
308 32         34 my $comma="";
309 32         40 push @out, $indent;
310 32         54 foreach my $portref ($self->ports_sorted) {
311 68         120 push @out, $comma, $portref->verilog_text;
312 68         95 $comma = ", ";
313             }
314 32         49 push @out, ");\n";
315              
316             # Signal list
317 32         62 foreach my $netref ($self->nets_sorted) {
318 117         209 push @out, $indent, $netref->verilog_text, "\n";
319             }
320             # Cell list
321 32         68 foreach my $cellref ($self->cells_sorted) {
322 28         65 push @out, $indent, $cellref->verilog_text, "\n";
323             }
324 32         63 foreach my $oref ($self->statements_sorted) {
325 8         20 push @out, $indent, $oref->verilog_text, "\n";
326             }
327              
328 32   50     636 push @out, "end".($self->keyword||'module')."\n";
329 32 50       422 return (wantarray ? @out : join('',@out));
330             }
331              
332             sub dump {
333 67     67 1 80 my $self = shift;
334 67   100     148 my $indent = shift||0;
335 67         71 my $norecurse = shift;
336 67   50     801 print " "x$indent,"Module:",$self->name()," Kwd:",($self->keyword||'')," File:",$self->filename(),"\n";
337 67 100       248 if (!$norecurse) {
338 37         114 foreach my $portref ($self->ports_sorted) {
339 70         218 $portref->dump($indent+2);
340             }
341 37         121 foreach my $netref ($self->nets_sorted) {
342 135         416 $netref->dump($indent+2);
343             }
344 37         128 foreach my $cellref ($self->cells_sorted) {
345 36         100 $cellref->dump($indent+2);
346             }
347 37         88 foreach my $cellref ($self->statements_sorted) {
348 8         34 $cellref->dump($indent+2);
349             }
350             }
351             }
352              
353             ######################################################################
354             #### Package return
355             1;
356             __END__