File Coverage

blib/lib/Verilog/Netlist/Cell.pm
Criterion Covered Total %
statement 92 95 96.8
branch 34 42 80.9
condition 18 25 72.0
subroutine 15 16 93.7
pod 8 10 80.0
total 167 188 88.8


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::Cell;
6              
7 8     8   56 use Verilog::Netlist;
  8         17  
  8         237  
8 8     8   43 use Verilog::Netlist::Subclass;
  8         15  
  8         381  
9 8     8   42 use vars qw($VERSION @ISA);
  8         16  
  8         398  
10 8     8   47 use strict;
  8         589  
  8         10396  
11             @ISA = qw(Verilog::Netlist::Cell::Struct
12             Verilog::Netlist::Subclass);
13              
14             $VERSION = '3.478';
15              
16             structs('new',
17             'Verilog::Netlist::Cell::Struct'
18             =>[name => '$', #' # Instantiation name
19             filename => '$', #' # Filename this came from
20             lineno => '$', #' # Linenumber this came from
21             userdata => '%', # User information
22             attributes => '%', #' # Misc attributes for systemperl or other processors
23             #
24             comment => '$', #' # Comment provided by user
25             submodname => '$', #' # Which module it instantiates
26             module => '$', #' # Module reference
27             params => '$', #' # Textual description of parameters
28             range => '$', #' # Range of ranged instance
29             _pins => '%', # List of Verilog::Netlist::Pins
30             byorder => '$', # True if Cell call uses order based pins
31             # after link():
32             submod => '$', #' # Sub Module reference
33             gateprim => '$', #' # Primitive (and/buf/cmos etc), but not UDPs
34             # system perl
35             _autoinst => '$', #' # Marked with AUTOINST tag
36             ]);
37              
38             sub delete {
39 401     401 1 589 my $self = shift;
40 401         872 foreach my $pinref ($self->pins_sorted) {
41 804         1846 $pinref->delete;
42             }
43 401         6995 my $h = $self->module->_cells;
44 401         5528 delete $h->{$self->name};
45 401         985 return undef;
46             }
47              
48             ######################################################################
49             #### Methods
50              
51             sub logger {
52 0     0 1 0 my $self = shift;
53 0         0 return $self->netlist->logger;
54             }
55             sub netlist {
56 234     234 1 294 my $self = shift;
57 234         3052 return $self->module->netlist;
58             }
59              
60             sub _link_guts {
61 134     134   167 my $self = shift;
62             # This function is HOT, keep simple
63 134 100       2134 if (!$self->submod) {
64 87 50       1256 if (my $name = $self->submodname) {
65 87         233 my $netlist = $self->netlist;
66 87         271 my $sm = $netlist->find_module_or_interface_for_cell($name);
67 87 100       181 if (!$sm) {
68 42         116 my $name2 = $netlist->remove_defines($name);
69 42 50       97 $sm = $netlist->find_module_or_interface_for_cell($name2)
70             if $name ne $name2;
71             }
72 87 100       188 if ($sm) {
73 45         605 $self->submod($sm);
74 45         560 $sm->is_top(0);
75             }
76             }
77             }
78             }
79             sub _link {
80 104     104   162 my $self = shift;
81             # This function is HOT, keep simple
82 104         215 $self->_link_guts();
83 104 100 100     1413 if (!$self->submod && Verilog::Language::is_gateprim($self->submodname)) {
84 2         31 $self->gateprim(1);
85             }
86 104 100 66     1407 if (!$self->submod()
      66        
      66        
87             && !$self->gateprim
88             && !$self->module->is_libcell()
89             && $self->netlist->{link_read}
90             && !$self->netlist->{_missing_submod}{$self->submodname}
91             ) {
92 25 50       60 print " Link_Read ",$self->submodname,"\n" if $Verilog::Netlist::Debug;
93             # Try 1: Direct filename
94 25         54 $self->netlist->read_file(filename=>$self->submodname, error_self=>0);
95 25         106 $self->_link_guts();
96             #
97             # Try 2: Libraries
98 25 100       334 if (!$self->submod()) {
99 5         20 $self->netlist->read_libraries();
100 5         15 $self->_link_guts();
101             }
102             # Try 3: Bitch about missing file
103 25 100       326 if (!$self->submod()) {
104             $self->netlist->read_file(filename=>$self->submodname,
105 5 50       15 error_self=>($self->netlist->{link_read_nonfatal} ? 0:$self));
106             }
107             # Still missing
108 25 100       394 if (!$self->submod()) {
109             # Don't link this file again - speeds up if many common gate-ish missing primitives
110 5         19 $self->netlist->{_missing_submod}{$self->submodname} = 1;
111             }
112             # Note if got it the new_module will add it to the _need_link list
113             }
114             # Link pins after module resolved, so don't do it multiple times if not found
115 104         253 foreach my $pinref ($self->pins) {
116 104         275 $pinref->_link();
117             }
118             }
119              
120             sub lint {
121 39     39 1 50 my $self = shift;
122 39 50 100     503 if (!$self->submod() && !$self->gateprim && !$self->netlist->{link_read_nonfatal}) {
      66        
123 0         0 $self->error($self,"Module/Program/Interface reference not found: ",$self->submodname(),,"\n");
124             }
125 39 50       115 if ($self->netlist->{use_vars}) {
126 39         86 foreach my $pinref ($self->pins) {
127 40         104 $pinref->lint();
128             }
129             }
130             }
131              
132             sub verilog_text {
133 29     29 0 43 my $self = shift;
134 29         399 my @out = $self->submodname;
135 29 100       379 if ($self->params) {
136 10         127 push @out, " #(".$self->params.")";
137             }
138 29         403 push @out, " ".$self->name;
139 29 100       439 if ($self->range) {
140 2         28 push @out, " ".$self->range;
141             }
142 29         55 push @out, " (";
143 29         39 my $comma="";
144 29         69 foreach my $pinref ($self->pins_sorted) {
145 37 100       77 push @out, $comma if $comma; $comma=", ";
  37         47  
146 37         93 push @out, $pinref->verilog_text;
147             }
148 29         58 push @out, ");";
149 29 50       153 return (wantarray ? @out : join('',@out));
150             }
151              
152             sub dump {
153 37     37 1 69 my $self = shift;
154 37   50     76 my $indent = shift||0;
155 37         48 my $norecurse = shift;
156 37         544 print " "x$indent,"Cell:",$self->name()," is-a:",$self->submodname();
157 37 100 100     757 print " ".$self->params if (($self->params||"") ne "");
158 37         495 print "\n";
159 37 100       803 if ($self->submod()) {
160 33         427 $self->submod->dump($indent+10, 'norecurse');
161             }
162 37 50       84 if (!$norecurse) {
163 37         110 foreach my $pinref ($self->pins_sorted) {
164 40         141 $pinref->dump($indent+2);
165             }
166             }
167             }
168              
169             ######################################################################
170             #### Pins
171              
172             sub new_pin {
173 851     851 1 1184 my $self = shift;
174             # @_ params
175             # Create a new pin under this cell
176 851         1853 push @_, (cell=>$self);
177 851         3013 my $pinref = new Verilog::Netlist::Pin(@_);
178 851         12186 $self->_pins($pinref->name(), $pinref);
179 851         2465 return $pinref;
180             }
181              
182             sub find_pin {
183 2     2 0 3 my $self = shift;
184 2         4 my $name = shift;
185 2   33     84 return $self->_pins($name) || $self->_pins("\\".$name." ");
186             }
187              
188             sub pins {
189 143     143 1 177 return (values %{$_[0]->_pins});
  143         1831  
190             }
191              
192             sub pins_sorted {
193 476     476 1 676 return (sort {$a->name() cmp $b->name()} (values %{$_[0]->_pins}));
  473         6813  
  476         7016  
194             }
195              
196             ######################################################################
197             #### Package return
198             1;
199             __END__