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   55 use Verilog::Netlist;
  8         16  
  8         239  
8 8     8   3200 use Verilog::Netlist::ContAssign;
  8         22  
  8         404  
9 8     8   3572 use Verilog::Netlist::Defparam;
  8         23  
  8         450  
10 8     8   55 use Verilog::Netlist::Port;
  8         14  
  8         239  
11 8     8   41 use Verilog::Netlist::Net;
  8         14  
  8         212  
12 8     8   38 use Verilog::Netlist::Cell;
  8         14  
  8         206  
13 8     8   35 use Verilog::Netlist::Pin;
  8         13  
  8         175  
14 8     8   36 use Verilog::Netlist::Subclass;
  8         11  
  8         353  
15 8     8   44 use vars qw($VERSION @ISA);
  8         14  
  8         369  
16 8     8   54 use strict;
  8         15  
  8         18567  
17             @ISA = qw(Verilog::Netlist::Module::Struct
18             Verilog::Netlist::Subclass);
19              
20             $VERSION = '3.476';
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 308 my $self = shift;
61 204         578 foreach my $oref ($self->nets) {
62 12406         25087 $oref->delete;
63             }
64 204         25066 foreach my $oref ($self->ports) {
65 603         1476 $oref->delete;
66             }
67 204         1290 foreach my $oref ($self->cells) {
68 400         1089 $oref->delete;
69             }
70 204         1244 foreach my $oref ($self->statements) {
71 0         0 $oref->delete;
72             }
73 204         2975 my $h = $self->netlist->{_modules};
74 204         2785 delete $h->{$self->name};
75 204         580 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 420 my $filename = shift;
86 239         1193 (my $module = $filename) =~ s/.*\///;
87 239         1128 $module =~ s/\.[a-z]+$//;
88 239         3761 return $module;
89             }
90              
91             sub find_port {
92 26     26 1 40 my $self = shift;
93 26         38 my $search = shift;
94 26   33     338 return $self->_ports->{$search} || $self->_ports->{"\\".$search." "};
95             }
96             sub find_port_by_index {
97 17     17 1 29 my $self = shift;
98 17         25 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         37 my $name = @{$self->_portsordered}[$myindex-1];
  17         226  
103 17 50       55 return undef if !$name;
104 17         314 return $self->_ports->{$name};
105             }
106             sub find_cell {
107 452     452 1 644 my $self = shift;
108 452         584 my $search = shift;
109 452   66     8271 return $self->_cells->{$search} || $self->_cells->{"\\".$search." "};
110             }
111             sub find_net {
112 12720     12720 1 17172 my $self = shift;
113 12720         15895 my $search = shift;
114 12720   100     228939 my $rtn = $self->_nets->{$search}||"";
115             #print "FINDNET ",$self->name, " SS $search $rtn\n";
116 12720   66     163893 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 459 return (values %{$_[0]->_nets});
  337         6294  
124             }
125             sub nets_sorted {
126 97     97 1 264 return (sort {$a->name() cmp $b->name()} (values %{$_[0]->_nets}));
  508         6423  
  97         1531  
127             }
128             sub ports {
129 337     337 1 508 return (values %{$_[0]->_ports});
  337         6008  
130             }
131             sub ports_sorted {
132 80     80 1 128 return (sort {$a->name() cmp $b->name()} (values %{$_[0]->_ports}));
  151         1934  
  80         1263  
133             }
134             sub ports_ordered {
135 1     1 1 3 my $self = shift;
136 1         3 return map {$self->_ports->{$_}} @{$self->_portsordered};
  3         34  
  1         20  
137             }
138             sub cells {
139 346     346 1 480 return (values %{$_[0]->_cells});
  346         4638  
140             }
141             sub cells_sorted {
142 79     79 1 136 return (sort {$a->name() cmp $b->name()} (values %{$_[0]->_cells}));
  51         670  
  79         1234  
143             }
144             sub statements {
145 243     243 1 363 return (values %{$_[0]->_statements});
  243         3878  
146             }
147             sub statements_sorted {
148 69     69 1 95 return (sort {$a->name() cmp $b->name()} (values %{$_[0]->_statements}));
  8         144  
  69         957  
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 19601 my $self = shift;
166 12572         82588 my %params = @_;
167              
168             # Create a new net under this
169 12572         16993 my $netref;
170 12572 100       22979 if (defined($params{msb})) {
171 461         597 my $data_type;
172 461         689 $data_type = "[".($params{msb});
173 461 50       1148 $data_type .= ":".($params{lsb}) if defined $params{lsb};
174 461         572 $data_type .= "]";
175 461         2236 $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         55115 $netref = new Verilog::Netlist::Net(decl_type => 'net',
182             net_type => 'wire',
183             %params,
184             module => $self);
185             }
186 12572         173482 $self->_nets($netref->name(), $netref);
187 12572         45789 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 1107 my $self = shift;
198             # @_ params
199             # Create a new port under this module
200 684         2773 my $portref = new Verilog::Netlist::Port(@_, module=>$self,);
201 684         9367 $self->_ports($portref->name(), $portref);
202 684         19756 return $portref;
203             }
204              
205             sub new_cell {
206 451     451 1 860 my $self = shift;
207 451         2102 my %params = @_; # name=>, filename=>, lineno=>, submodname=>, params=>
208             # Create a new cell under this module
209 451 50 33     2501 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       1294 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         7522 my $cellref = new Verilog::Netlist::Cell(%params, module=>$self,);
220             # Add the new cell to the hash of cells in this module
221 451         6562 $self->_cells($params{name}, $cellref);
222 451         1542 return $cellref;
223             }
224              
225             sub new_contassign {
226 6     6 0 14 my $self = shift;
227 6         31 my %params = @_; # name=>, filename=>, lineno=>, keyword=> etc
228             # Create a new statement under this module
229 6 50 33     26 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     119 $self->_stmtnum(($self->_stmtnum||0) + 1);
232 6         77 $params{name} = '__unnamed_statement_' . $self->_stmtnum;
233             }
234             # Create a new object; pass the potentially modified options
235 6         121 my $newref = new Verilog::Netlist::ContAssign(%params, module=>$self,);
236             # Add the new object to the hash of statements in this module
237 6         91 $self->_statements($params{name}, $newref);
238 6         112 return $newref;
239             }
240              
241             sub new_defparam {
242 4     4 0 8 my $self = shift;
243 4         21 my %params = @_; # name=>, filename=>, lineno=>, keyword=> etc
244             # Create a new statement under this module
245 4 50 33     19 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     95 $self->_stmtnum(($self->_stmtnum||0) + 1);
248 4         52 $params{name} = '__unnamed_statement_' . $self->_stmtnum;
249             }
250             # Create a new object; pass the potentially modified options
251 4         79 my $newref = new Verilog::Netlist::Defparam(%params, module=>$self,);
252             # Add the new object to the hash of statements in this module
253 4         74 $self->_statements($params{name}, $newref);
254 4         153 return $newref;
255             }
256              
257             sub level {
258 48     48 1 48 my $self = shift;
259 48         521 my $level = $self->_level;
260 48 100       159 return $level if defined $level;
261 9         95 $self->_level(1); # Set before recurse in case there's circular module refs
262 9         17 foreach my $cell ($self->cells) {
263 12 100       128 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         95 return $self->_level;
269             }
270              
271             sub link {
272 94     94 1 124 my $self = shift;
273             # Ports create nets, so link ports before nets
274 94         181 foreach my $portref ($self->ports) {
275 164         366 $portref->_link();
276             }
277 94         216 foreach my $netref ($self->nets) {
278 332         530 $netref->_link();
279             }
280 94         179 foreach my $cellref ($self->cells) {
281 98         268 $cellref->_link();
282             }
283             }
284              
285             sub lint {
286 39     39 1 53 my $self = shift;
287 39 50       498 if ($self->netlist->{use_vars}) {
288 39         75 foreach my $portref ($self->ports) {
289 72         149 $portref->lint();
290             }
291 39         71 foreach my $netref ($self->nets) {
292 137         252 $netref->lint();
293             }
294             }
295 39         85 foreach my $cellref ($self->cells) {
296 39         88 $cellref->lint();
297             }
298 39         88 foreach my $oref ($self->statements) {
299 8         37 $oref->lint();
300             }
301             }
302              
303             sub verilog_text {
304 32     32 1 47 my $self = shift;
305 32   50     459 my @out = ($self->keyword||'module')." ".$self->name." (\n";
306 32         54 my $indent = " ";
307             # Port list
308 32         56 my $comma="";
309 32         54 push @out, $indent;
310 32         70 foreach my $portref ($self->ports_sorted) {
311 68         137 push @out, $comma, $portref->verilog_text;
312 68         109 $comma = ", ";
313             }
314 32         58 push @out, ");\n";
315              
316             # Signal list
317 32         63 foreach my $netref ($self->nets_sorted) {
318 117         247 push @out, $indent, $netref->verilog_text, "\n";
319             }
320             # Cell list
321 32         134 foreach my $cellref ($self->cells_sorted) {
322 28         68 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     430 push @out, "end".($self->keyword||'module')."\n";
329 32 50       881 return (wantarray ? @out : join('',@out));
330             }
331              
332             sub dump {
333 67     67 1 101 my $self = shift;
334 67   100     183 my $indent = shift||0;
335 67         88 my $norecurse = shift;
336 67   50     1016 print " "x$indent,"Module:",$self->name()," Kwd:",($self->keyword||'')," File:",$self->filename(),"\n";
337 67 100       316 if (!$norecurse) {
338 37         204 foreach my $portref ($self->ports_sorted) {
339 70         273 $portref->dump($indent+2);
340             }
341 37         143 foreach my $netref ($self->nets_sorted) {
342 135         448 $netref->dump($indent+2);
343             }
344 37         139 foreach my $cellref ($self->cells_sorted) {
345 36         109 $cellref->dump($indent+2);
346             }
347 37         103 foreach my $cellref ($self->statements_sorted) {
348 8         51 $cellref->dump($indent+2);
349             }
350             }
351             }
352              
353             ######################################################################
354             #### Package return
355             1;
356             __END__