# Verilog - Verilog Perl Interface # See copyright, etc in below POD section. ###################################################################### package Verilog::Netlist::Net; use Class::Struct; use Verilog::Netlist; use Verilog::Netlist::Subclass; use vars qw ($VERSION @ISA); use strict; @ISA = qw(Verilog::Netlist::Net::Struct Verilog::Netlist::Subclass); $VERSION = '3.221'; my %_Type_Widths = ( 'bit' => 1, 'byte' => 1, 'genvar' => 32, 'integer' => 32, 'localparam'=> 32, 'logic' => 1, 'longint' => 64, 'parameter' => 32, 'reg' => 1, 'shortint' => 16, 'supply0' => 1, 'supply1' => 1, 'tri' => 1, 'tri0' => 1, 'tri1' => 1, 'triand' => 1, 'trior' => 1, 'trireg' => 1, 'wand' => 1, 'wire' => 1, 'wor' => 1, ); my %_Type_Accessors = ( 'genvar' => 'decl_type', 'localparam'=> 'decl_type', 'parameter' => 'decl_type', 'var' => 'decl_type', # Not in old version, but for completeness #'port' => 'decl_type', # Internals - Look at Port (input/output/inout/ref) #'net' => 'decl_type', # Internals - Look at net_type (wire/tri/...) # 'supply0' => 'net_type', 'supply1' => 'net_type', 'tri' => 'net_type', 'tri0' => 'net_type', 'tri1' => 'net_type', 'triand' => 'net_type', 'trior' => 'net_type', 'trireg' => 'net_type', 'wand' => 'net_type', 'wire' => 'net_type', 'wor' => 'net_type', # 'bit' => 'data_type', 'byte' => 'data_type', 'chandle' => 'data_type', 'event' => 'data_type', 'int' => 'data_type', 'integer' => 'data_type', 'logic' => 'data_type', 'longint' => 'data_type', 'real' => 'data_type', 'realtime' => 'data_type', 'reg' => 'data_type', 'shortint' => 'data_type', 'shortreal' => 'data_type', 'string' => 'data_type', 'time' => 'data_type', ); ###################################################################### structs('_new_base', 'Verilog::Netlist::Net::Struct' =>[name => '$', #' # Name of the net filename => '$', #' # Filename this came from lineno => '$', #' # Linenumber this came from userdata => '%', # User information attributes => '%', #' # Misc attributes for systemperl or other processors # data_type => '$', #' # SystemVerilog Type (logic/integer/reg [3:0] etc) decl_type => '$', #' # Declaration type (parameter/genvar/port/net etc) net_type => '$', #' # Net type (wire/tri/supply0 etc) comment => '$', #' # Comment provided by user array => '$', #' # Vector module => '$', #' # Module, Program or Interface entity belongs to signed => '$', #' # True if signed value => '$', #' # For parameters, the value of the parameter # below only after links() port => '$', #' # Reference to port connected to msb => '$', #' # MSB of signal (if known) lsb => '$', #' # LSB of signal (if known) stored_lsb => '$', #' # Bit number of signal stored in bit 0 (generally lsb) _used_in => '$', #' # Driver count onto signal _used_out => '$', #' # Receiver count on signal _used_inout => '$', #' # Bidirect count on signal # SystemPerl only: below only after autos() simple_type => '$', #' # True if is uint (as opposed to sc_signal) sp_traced => '$', #' # Created by SP_TRACED sp_autocreated => '$', #' # Created by /*AUTOSIGNAL*/ ]); sub new { my $class = shift; my %params = @_; my $self = $class->_new_base (%params); $self->type($params{type}) if $params{type}; # Backward compatibility return $self; } sub delete { my $self = shift; my $h = $self->module->_nets; delete $h->{$self->name}; return undef; } ###################################################################### sub logger { return $_[0]->netlist->logger; } sub netlist { return $_[0]->module->netlist; } sub _used_in_inc { $_[0]->_used_in(1+($_[0]->_used_in()||0)); } sub _used_out_inc { $_[0]->_used_out(1+($_[0]->_used_out()||0)); } sub _used_inout_inc { $_[0]->_used_inout(1+($_[0]->_used_inout()||0)); } sub stored_lsb { defined $_[0]->SUPER::stored_lsb ? $_[0]->SUPER::stored_lsb : $_[0]->lsb; } sub width { my $self = shift; # Return bit width (if known) my $dt = $self->data_type; $dt="" if $dt eq "signed"; if (defined $self->msb && defined $self->lsb) { return (abs($self->msb - $self->lsb) + 1); } elsif (my $width = $_Type_Widths{$dt || $self->net_type || $self->decl_type}) { return $width; } return undef; } sub type { my $self = shift; my $flag = shift; if (defined $flag) { if (my $acc = $_Type_Accessors{$flag}) { if ($acc eq 'decl_type') { $self->decl_type($flag); } elsif ($acc eq 'net_type') { $self->net_type($flag); } else { $self->data_type($flag); } } else { $self->data_type($flag); } } my $dt = $self->data_type; $dt="" if $dt && $dt eq "signed"; return $dt || $self->net_type || $self->decl_type; } ###################################################################### sub _link {} sub lint { my $self = shift; # Sequential logic may gen/use a signal, so we have to be a little sloppy if (0&&$self->_used_inout() && $self->_used_out() && !$self->array()) { # if an array, different outputs might hit different bits $self->warn("Signal is used as both a inout and output: ",$self->name(), "\n"); $self->dump_drivers(8); } elsif ($self->_used_out()) { if ($self->_used_out()>1 && !$self->array()) { # if an array, different outputs might hit different bits $self->warn("Signal has multiple drivers (", $self->_used_out(),"): ",$self->name(), "\n"); $self->dump_drivers(8); } } if (0&&$self->_used_in() && !$self->_used_out()) { $self->warn("Signal has no drivers: ",$self->name(), "\n"); } if (0&&$self->_used_out() && !$self->_used_in() && $self->name() !~ /unused/) { $self->dump(5); $self->port->dump(10) if $self->port; $self->warn("Signal is not used (or needs signal declaration): ",$self->name(), "\n"); flush STDOUT; flush STDERR; } } ###################################################################### ## Outputters sub _decls { my $self = shift; my $out = $self->net_type || $self->decl_type; if ($self->port) { $out = "input" if $self->port->direction eq "in"; $out = "output" if $self->port->direction eq "out"; $out = "inout" if $self->port->direction eq "inout"; } return $out; } sub verilog_text { my $self = shift; my @out; foreach my $decl ($self->_decls) { push @out, $decl; push @out, " ".$self->data_type if $self->data_type; push @out, " ".$self->name; push @out, " ".$self->array if $self->array; push @out, " = ".$self->value if defined $self->value && $self->value ne ''; push @out, ";"; push @out, " ".$self->comment if defined $self->comment && $self->comment ne ''; } return (wantarray ? @out : join('',@out)); } sub dump { my $self = shift; my $indent = shift||0; print " "x$indent,"Net:",$self->name() ," ",($self->_used_in() ? "I":""),($self->_used_out() ? "O":""), ," DeclT:",$self->decl_type||'' ," NetT:",$self->net_type||'' ," DataT:",$self->data_type||'' ," Array:",$self->array()||''; print " ",($self->msb).":".($self->lsb) if defined $self->msb; print " Value:",$self->value if defined $self->value && $self->value ne ''; print "\n"; } sub dump_drivers { my $self = shift; my $indent = shift||0; print " "x$indent,"Net:",$self->name,"\n"; if (my $port = $self->port) { print " "x$indent," Port: ",$port->name," ",$port->direction,"\n"; } foreach my $cell ($self->module->cells_sorted) { foreach my $pin ($cell->pins_sorted) { if ($pin->port && $pin->net && $pin->net == $self) { print " "x$indent," Pin: ",$cell->name,".",$pin->name ," ",$pin->port->direction,"\n"; } elsif ($pin->net && $self->name eq $pin->net->name) { warn "%Warning: Internal net name duplicate: ".$cell->name." ".$self->name."\n" .$self->comment." ".$pin->net->comment."\n" ."$self ".$pin->net->name."\n"; } } } flush STDERR; flush STDOUT; } ###################################################################### #### Package return 1; __END__ =pod =head1 NAME Verilog::Netlist::Net - Net for a Verilog Module =head1 SYNOPSIS use Verilog::Netlist; ... my $net = $module->find_net ('signalname'); print $net->name; =head1 DESCRIPTION A Verilog::Netlist::Net object is created by Verilog::Netlist::Module for every signal and input/output declaration, and parameter in the current module. =head1 ACCESSORS See also Verilog::Netlist::Subclass for additional accessors and methods. =over 4 =item $self->array Any array (vector) declaration for the net. This is for multidimensional signals, for the width of a signal, use msb/lsb/width. =item $self->comment Returns any comments following the definition. keep_comments=>1 must be passed to Verilog::Netlist::new for comments to be retained. =item $self->data_type The data type of the net. This may be a data type keyword ("integer", "logic", etc), user defined type from a type def, a range ("[11:0]", "signed [1:0]" or "" for an implicit wire. =item $self->decl_type How the net was declared. A declaration keyword ("genvar", "localparam", "parameter", "var") or "port" if only as a port - and see the port method, or "net" - and see the net_type method. =item $self->module Reference to the Verilog::Netlist::Module or Verilog::Netlist::Interface the net is under. =item $self->lsb The least significant bit number of the net. =item $self->msb The most significant bit number of the net. =item $self->name The name of the net. =item $self->net_type The net type, if one applies. Always a net type keyword ('supply0', 'supply1', 'tri', 'tri0', 'tri1', 'triand', 'trior', 'trireg', 'wand', 'wire', 'wor'). =item $self->type The type function is provided for backward compatibility to Verilog-Perl versions before 3.200. Applications should change to use data_type() and/or decl_type() instead. The type function returns an agglomeration of data_type, net_type and decl_type that worked ok in Verilog, but does not work with SystemVerilog. Calls to type() will be converted to calls to data_type, decl_type or net_type in a way that attempts to maintain backward compatibility, however compatibility is not always possible. =item $self->value If the net's type is 'parameter', the value from the parameter's declaration. =item $self->width The width of the net in bits. =back =head1 MEMBER FUNCTIONS See also Verilog::Netlist::Subclass for additional accessors and methods. =over 4 =item $self->lint Checks the net for errors. Normally called by Verilog::Netlist::lint. =item $self->dump Prints debugging information for this net. =item $self->dump_drivers Prints debugging information for this net, and all pins driving the net. =back =head1 DISTRIBUTION Verilog-Perl is part of the L free Verilog EDA software tool suite. The latest version is available from CPAN and from L. Copyright 2000-2009 by Wilson Snyder. This package is free software; you can redistribute it and/or modify it under the terms of either the GNU Lesser General Public License Version 3 or the Perl Artistic License Version 2.0. =head1 AUTHORS Wilson Snyder =head1 SEE ALSO L, L L =cut