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   55 use Verilog::Netlist;
  8         13  
  8         234  
8 8     8   39 use Verilog::Netlist::Subclass;
  8         14  
  8         359  
9 8     8   42 use vars qw($VERSION @ISA);
  8         14  
  8         379  
10 8     8   45 use strict;
  8         518  
  8         9873  
11             @ISA = qw(Verilog::Netlist::Cell::Struct
12             Verilog::Netlist::Subclass);
13              
14             $VERSION = '3.476';
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 613 my $self = shift;
40 401         963 foreach my $pinref ($self->pins_sorted) {
41 804         1845 $pinref->delete;
42             }
43 401         6880 my $h = $self->module->_cells;
44 401         5361 delete $h->{$self->name};
45 401         957 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 306 my $self = shift;
57 234         2889 return $self->module->netlist;
58             }
59              
60             sub _link_guts {
61 134     134   173 my $self = shift;
62             # This function is HOT, keep simple
63 134 100       1952 if (!$self->submod) {
64 87 50       1178 if (my $name = $self->submodname) {
65 87         200 my $netlist = $self->netlist;
66 87         251 my $sm = $netlist->find_module_or_interface_for_cell($name);
67 87 100       180 if (!$sm) {
68 42         117 my $name2 = $netlist->remove_defines($name);
69 42 50       95 $sm = $netlist->find_module_or_interface_for_cell($name2)
70             if $name ne $name2;
71             }
72 87 100       185 if ($sm) {
73 45         587 $self->submod($sm);
74 45         549 $sm->is_top(0);
75             }
76             }
77             }
78             }
79             sub _link {
80 104     104   141 my $self = shift;
81             # This function is HOT, keep simple
82 104         221 $self->_link_guts();
83 104 100 100     1355 if (!$self->submod && Verilog::Language::is_gateprim($self->submodname)) {
84 2         34 $self->gateprim(1);
85             }
86 104 100 66     1297 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       52 print " Link_Read ",$self->submodname,"\n" if $Verilog::Netlist::Debug;
93             # Try 1: Direct filename
94 25         59 $self->netlist->read_file(filename=>$self->submodname, error_self=>0);
95 25         98 $self->_link_guts();
96             #
97             # Try 2: Libraries
98 25 100       323 if (!$self->submod()) {
99 5         17 $self->netlist->read_libraries();
100 5         15 $self->_link_guts();
101             }
102             # Try 3: Bitch about missing file
103 25 100       311 if (!$self->submod()) {
104             $self->netlist->read_file(filename=>$self->submodname,
105 5 50       13 error_self=>($self->netlist->{link_read_nonfatal} ? 0:$self));
106             }
107             # Still missing
108 25 100       411 if (!$self->submod()) {
109             # Don't link this file again - speeds up if many common gate-ish missing primitives
110 5         18 $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         267 foreach my $pinref ($self->pins) {
116 104         267 $pinref->_link();
117             }
118             }
119              
120             sub lint {
121 39     39 1 54 my $self = shift;
122 39 50 100     485 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       73 if ($self->netlist->{use_vars}) {
126 39         137 foreach my $pinref ($self->pins) {
127 40         98 $pinref->lint();
128             }
129             }
130             }
131              
132             sub verilog_text {
133 29     29 0 49 my $self = shift;
134 29         384 my @out = $self->submodname;
135 29 100       374 if ($self->params) {
136 10         126 push @out, " #(".$self->params.")";
137             }
138 29         379 push @out, " ".$self->name;
139 29 100       384 if ($self->range) {
140 2         26 push @out, " ".$self->range;
141             }
142 29         62 push @out, " (";
143 29         36 my $comma="";
144 29         58 foreach my $pinref ($self->pins_sorted) {
145 37 100       75 push @out, $comma if $comma; $comma=", ";
  37         47  
146 37         81 push @out, $pinref->verilog_text;
147             }
148 29         51 push @out, ");";
149 29 50       138 return (wantarray ? @out : join('',@out));
150             }
151              
152             sub dump {
153 37     37 1 58 my $self = shift;
154 37   50     69 my $indent = shift||0;
155 37         51 my $norecurse = shift;
156 37         567 print " "x$indent,"Cell:",$self->name()," is-a:",$self->submodname();
157 37 100 100     699 print " ".$self->params if (($self->params||"") ne "");
158 37         307 print "\n";
159 37 100       682 if ($self->submod()) {
160 33         418 $self->submod->dump($indent+10, 'norecurse');
161             }
162 37 50       89 if (!$norecurse) {
163 37         93 foreach my $pinref ($self->pins_sorted) {
164 40         137 $pinref->dump($indent+2);
165             }
166             }
167             }
168              
169             ######################################################################
170             #### Pins
171              
172             sub new_pin {
173 851     851 1 1227 my $self = shift;
174             # @_ params
175             # Create a new pin under this cell
176 851         1736 push @_, (cell=>$self);
177 851         3014 my $pinref = new Verilog::Netlist::Pin(@_);
178 851         11610 $self->_pins($pinref->name(), $pinref);
179 851         2198 return $pinref;
180             }
181              
182             sub find_pin {
183 2     2 0 5 my $self = shift;
184 2         3 my $name = shift;
185 2   33     27 return $self->_pins($name) || $self->_pins("\\".$name." ");
186             }
187              
188             sub pins {
189 143     143 1 168 return (values %{$_[0]->_pins});
  143         1792  
190             }
191              
192             sub pins_sorted {
193 476     476 1 649 return (sort {$a->name() cmp $b->name()} (values %{$_[0]->_pins}));
  471         6476  
  476         6554  
194             }
195              
196             ######################################################################
197             #### Package return
198             1;
199             __END__