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   48 use Verilog::Netlist;
  8         10  
  8         197  
8 8     8   30 use Verilog::Netlist::Subclass;
  8         11  
  8         291  
9 8     8   36 use vars qw($VERSION @ISA);
  8         11  
  8         297  
10 8     8   35 use strict;
  8         436  
  8         7856  
11             @ISA = qw(Verilog::Netlist::Cell::Struct
12             Verilog::Netlist::Subclass);
13              
14             $VERSION = '3.480';
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 543 my $self = shift;
40 401         719 foreach my $pinref ($self->pins_sorted) {
41 804         1638 $pinref->delete;
42             }
43 401         5750 my $h = $self->module->_cells;
44 401         4722 delete $h->{$self->name};
45 401         779 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 269 my $self = shift;
57 234         2424 return $self->module->netlist;
58             }
59              
60             sub _link_guts {
61 134     134   135 my $self = shift;
62             # This function is HOT, keep simple
63 134 100       1648 if (!$self->submod) {
64 87 50       961 if (my $name = $self->submodname) {
65 87         155 my $netlist = $self->netlist;
66 87         261 my $sm = $netlist->find_module_or_interface_for_cell($name);
67 87 100       154 if (!$sm) {
68 42         101 my $name2 = $netlist->remove_defines($name);
69 42 50       82 $sm = $netlist->find_module_or_interface_for_cell($name2)
70             if $name ne $name2;
71             }
72 87 100       175 if ($sm) {
73 45         501 $self->submod($sm);
74 45         468 $sm->is_top(0);
75             }
76             }
77             }
78             }
79             sub _link {
80 104     104   120 my $self = shift;
81             # This function is HOT, keep simple
82 104         179 $self->_link_guts();
83 104 100 100     1138 if (!$self->submod && Verilog::Language::is_gateprim($self->submodname)) {
84 2         25 $self->gateprim(1);
85             }
86 104 100 66     1129 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         47 $self->netlist->read_file(filename=>$self->submodname, error_self=>0);
95 25         90 $self->_link_guts();
96             #
97             # Try 2: Libraries
98 25 100       280 if (!$self->submod()) {
99 5         16 $self->netlist->read_libraries();
100 5         11 $self->_link_guts();
101             }
102             # Try 3: Bitch about missing file
103 25 100       270 if (!$self->submod()) {
104             $self->netlist->read_file(filename=>$self->submodname,
105 5 50       14 error_self=>($self->netlist->{link_read_nonfatal} ? 0:$self));
106             }
107             # Still missing
108 25 100       310 if (!$self->submod()) {
109             # Don't link this file again - speeds up if many common gate-ish missing primitives
110 5         16 $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         216 foreach my $pinref ($self->pins) {
116 104         218 $pinref->_link();
117             }
118             }
119              
120             sub lint {
121 39     39 1 42 my $self = shift;
122 39 50 100     411 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       71 if ($self->netlist->{use_vars}) {
126 39         66 foreach my $pinref ($self->pins) {
127 40         80 $pinref->lint();
128             }
129             }
130             }
131              
132             sub verilog_text {
133 29     29 0 36 my $self = shift;
134 29         345 my @out = $self->submodname;
135 29 100       324 if ($self->params) {
136 10         107 push @out, " #(".$self->params.")";
137             }
138 29         313 push @out, " ".$self->name;
139 29 100       347 if ($self->range) {
140 2         21 push @out, " ".$self->range;
141             }
142 29         50 push @out, " (";
143 29         31 my $comma="";
144 29         44 foreach my $pinref ($self->pins_sorted) {
145 37 100       61 push @out, $comma if $comma; $comma=", ";
  37         37  
146 37         65 push @out, $pinref->verilog_text;
147             }
148 29         42 push @out, ");";
149 29 50       125 return (wantarray ? @out : join('',@out));
150             }
151              
152             sub dump {
153 37     37 1 51 my $self = shift;
154 37   50     62 my $indent = shift||0;
155 37         36 my $norecurse = shift;
156 37         478 print " "x$indent,"Cell:",$self->name()," is-a:",$self->submodname();
157 37 100 100     600 print " ".$self->params if (($self->params||"") ne "");
158 37         404 print "\n";
159 37 100       590 if ($self->submod()) {
160 33         341 $self->submod->dump($indent+10, 'norecurse');
161             }
162 37 50       78 if (!$norecurse) {
163 37         81 foreach my $pinref ($self->pins_sorted) {
164 40         115 $pinref->dump($indent+2);
165             }
166             }
167             }
168              
169             ######################################################################
170             #### Pins
171              
172             sub new_pin {
173 851     851 1 997 my $self = shift;
174             # @_ params
175             # Create a new pin under this cell
176 851         1545 push @_, (cell=>$self);
177 851         2783 my $pinref = new Verilog::Netlist::Pin(@_);
178 851         9856 $self->_pins($pinref->name(), $pinref);
179 851         1929 return $pinref;
180             }
181              
182             sub find_pin {
183 2     2 0 4 my $self = shift;
184 2         3 my $name = shift;
185 2   33     23 return $self->_pins($name) || $self->_pins("\\".$name." ");
186             }
187              
188             sub pins {
189 143     143 1 137 return (values %{$_[0]->_pins});
  143         1521  
190             }
191              
192             sub pins_sorted {
193 476     476 1 601 return (sort {$a->name() cmp $b->name()} (values %{$_[0]->_pins}));
  471         5524  
  476         5521  
194             }
195              
196             ######################################################################
197             #### Package return
198             1;
199             __END__