SystemC::Netlist - SystemC Netlist


SystemPerl documentation Contained in the SystemPerl distribution.

Index


Code Index:

NAME

Top

SystemC::Netlist - SystemC Netlist

SYNOPSIS

Top

  use SystemC::Netlist;

  # See Verilog::Netlist for base functions

    $nl->autos();
    $nl->exit_if_error();




DESCRIPTION

Top

SystemC::Netlist contains interconnect information about a whole design database. The classes of SystemC::Netlist parallel those of Verilog::Netlist, which should be seen for all documentation.

The database is composed of files, which contain the text read from each file.

A file may contain modules, which are individual blocks that can be instantiated (designs, in Synopsys terminology.)

Modules have ports, which are the interconnection between nets in that module and the outside world. Modules also have nets, (aka signals), which interconnect the logic inside that module.

Modules can also instantiate other modules. The instantiation of a module is a Cell. Cells have pins that interconnect the referenced module's pin to a net in the module doing the instantiation.

Each of these types, files, modules, ports, nets, cells and pins have a class. For example SystemC::Netlist::Cell has the list of SystemC::Netlist::Pin (s) that interconnect that cell.

FUNCTIONS

Top

See Verilog::Netlist for all common functions.

$netlist->autos

Updates /*AUTO*/ comments in the internal database. Normally called before lint.

$netlist->sc_version

Return the version number of SystemC.

DISTRIBUTION

Top

SystemPerl is part of the http://www.veripool.org/ free SystemC software tool suite. The latest version is available from CPAN and from http://www.veripool.org/systemperl.

Copyright 2001-2010 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.

AUTHORS

Top

Wilson Snyder <wsnyder@wsnyder.org>

SEE ALSO

Top

SystemC::Manual

SystemC::Netlist::Cell, SystemC::Netlist::Class, SystemC::Netlist::CoverGroup, SystemC::Netlist::File, SystemC::Netlist::Module, SystemC::Netlist::Net, SystemC::Netlist::Pin, SystemC::Netlist::Port, Verilog::Netlist::Subclass


SystemPerl documentation Contained in the SystemPerl distribution.

# SystemC - SystemC Perl Interface
# See copyright, etc in below POD section.
######################################################################

package SystemC::Netlist;
use Carp;
use IO::File;

use Verilog::Netlist;
use SystemC::Netlist::Class;
use SystemC::Netlist::Module;
use SystemC::Netlist::File;
use Verilog::Netlist::Subclass;
@ISA = qw(Verilog::Netlist);
use strict;
use vars qw($Debug $Verbose $VERSION);

$VERSION = '1.336';

######################################################################
#### Creation

sub new {
    my $class = shift;
    my $self = $class->SUPER::new
	(sp_allow_output_tracing => undef,	# undef = set it automatically
	 sp_trace_duplicates => 0,
	 sp_netlist => 1,  # General flag for future feature tests
	 sc_version => undef,
	 ncsc => undef,
	 lint_checking => 1,
	 remove_defines_without_tick => 1,
	 _enum_classes => {},
	 _enums => {},
	 _classes => {},
	 @_);
    bless $self, $class;
    $self->_set_features();
    return $self;
}

######################################################################
#### Error Handling

# Netlist file & line numbers don't apply
sub filename { return 'SystemC::Netlist'; }
sub lineno { return ''; }

sub new_logger {
    # Undocumented, as only for backward compatibility before Verilog-Perl 3.041
    if ($::Verilog::Netlist::Logger::{new}) {  # Function exists
	return Verilog::Netlist::Logger->new(@_);
    } else {
	return undef;
    }
}

######################################################################
#### Utilities

sub tracing {
    my $self = shift;
    return !$self->{ncsc};
}

sub sc_version {
    my $self = shift;
    # Return version of SystemC in use
    if (!$self->{sc_version} && $ENV{SYSTEMC}) {
	my $fh;
	foreach my $fn ("$ENV{SYSTEMC}/include/sysc/kernel/sc_ver.h",
			"$ENV{SYSTEMC}/include/systemc/kernel/sc_ver.h",
			"$ENV{SYSTEMC}/include/sc_ver.h") {
	    $fh = IO::File->new("<$fn");
	    last if $fh;
	}
	if ($fh) {
	    while (defined (my $line = $fh->getline)) {
		if ($line =~ /^\s*#\s*define\s+SYSTEMC_VERSION\s+(\S+)/) {
		    $self->{sc_version} = $1;
		    print "SC_VERSION = $1\n" if $Debug;
		    last;
		}
	    }
	}
    }
    return $self->{sc_version};
}

sub sc_numeric_version {
    my $self = shift;
    # Return version of SystemC in use
    if (!exists $self->{sc_numeric_version}) {
	my $scv = $self->sc_version;
	if (!$scv) { # Indeterminate
	    $self->{sc_numeric_version} = undef;
	} elsif ($scv > 20050700) {  # 2.1.v1
	    $self->{sc_numeric_version} = 2.110;
	} elsif ($scv > 20041000) {  # 2.1.oct_12_2004.beta
	    $self->{sc_numeric_version} = 2.100;
	} elsif ($scv > 20011000) {
	    $self->{sc_numeric_version} = 2.010;
	} elsif ($scv > 20010100) {
	    $self->{sc_numeric_version} = 1.211;
	} else {
	    warn "%Warning: SystemC Version isn't recognized: $scv,";
	    $self->{sc_numeric_version} = undef;
	}
	print "SC_NUMERIC_VERSION = $self->{sc_numeric_version}\n" if $Debug;
    }
    return $self->{sc_numeric_version};
}

sub _set_features {
    my $self = shift;
    # Determine what features are in this SystemC version
    my $ver = $self->sc_version;
    my $patched = ($ENV{SYSTEMC} && -r "$ENV{SYSTEMC}/systemperl_patched");
    if (!defined $self->{sp_allow_output_tracing}) {
	if (($self->sc_numeric_version||0) >= 2.000) {
	    $self->{sp_allow_output_tracing} = 1;
	} elsif ($patched) {
	    $self->{sp_allow_output_tracing} = 'hack';
	} else {
	    $self->{sp_allow_output_tracing} = 0;
	}
    }
}

# add this pagename to the list; error if it's already there
sub add_coverpoint_page_name {
    my $self = shift;
    my $pagename = shift;
    my $coverpoint = shift;

    if (defined $self->{pagenames}->{$pagename}) {
	$coverpoint->error("duplicate SP_COVERGROUP page name \"$pagename\"\n");
    }
    $self->{pagenames}->{$pagename} = 1;
}

######################################################################
#### Functions

sub autos {
    my $self = shift;

    # Autos will load new modules, which we must auto in turn, so repeat until everybody's happy
    my %did_autos;
    while (1) {
	my $did_one;
	foreach my $modref ($self->modules) {
	    next if $did_autos{$modref->name};
	    next if $modref->is_libcell();
	    $modref->autos1();
	    $did_autos{$modref->name} = 1;
	    $did_one = 1;
	}
	if ($did_one) {
	    $self->link();  # Pick up pins autos1 created
	} else {
	    last;
	}
    }

    foreach my $modref ($self->modules) {
	next if $modref->is_libcell();
	$modref->autos2();
    }

    $self->link();
}

sub link {
    my $self = shift;
    $self->SUPER::link(@_);
    foreach my $modref ($self->classes) {
	$modref->_link();
    }
}

######################################################################
#### Class access

sub new_class {
    my $self = shift;
    my $modref = new SystemC::Netlist::Class
	(netlist=>$self,
	 @_);
    $self->{_classes}{$modref->name} = $modref;
    return $modref;
}

sub classes {
    return (values %{$_[0]->{_classes}});
}
sub classes_sorted {
    return (sort {$a->name() cmp $b->name()} (values %{$_[0]->{_classes}}));
}

sub find_class {
    my $self = shift;
    my $search = shift;
    # Return file maching name
    my $class = $self->{_classes}{$search};
    return $class if $class;
    return SystemC::Netlist::Class::generate_class($self, $search);
}

######################################################################
#### Module access

sub new_module {
    my $self = shift;
    # @_ params
    # Can't have 'new SystemC::Netlist::Module' do this,
    # as not allowed to override Class::Struct's new()
    my $modref = new SystemC::Netlist::Module
	(netlist=>$self,
	 is_top=>1,
	 @_);
    $self->{_modules}{$modref->name} = $modref;
    return $modref;
}

######################################################################
#### Files access

sub new_file {
    my $self = shift;
    # @_ params
    # Can't have 'new SystemC::Netlist::File' do this,
    # as not allowed to override Class::Struct's new()
    my $fileref = new SystemC::Netlist::File
	(netlist=>$self,
	 @_);
    defined $fileref->name or carp "%Error: No name=> specified, stopped";
    $self->{_files}{$fileref->name} = $fileref;
    $fileref->basename (Verilog::Netlist::Module::modulename_from_filename($fileref->name));
    return $fileref;
}

sub read_file {
    my $self = shift;
    my %params = (netlist=>$self,
		 @_);

    if ($params{filename}) {
	my $filepath = $self->resolve_filename($params{filename});
	if (($filepath||'') =~ /\.v$/) {
	    return $self->read_verilog_file(is_libcell=>1,
					    %params);
	}
    }
    return $self->read_sp_file(%params);
}

sub read_sp_file {
    my $self = shift;
    my $fileref = SystemC::Netlist::File::read
	(netlist=>$self,
	 @_);
}

######################################################################
#### Library files

sub write_cell_library {
    my $self = shift;
    my %params = (filename=>undef,
		  include_libcells=>0,
		  @_);
    $self->dependency_out($params{filename});
    my $fh = IO::File->new(">$params{filename}") or die "%Error: $! writing $params{filename}\n";
    foreach my $modref ($self->modules_sorted) {
	next if !$params{include_libcells} && $modref->is_libcell();
	# Skip libcells that are never used
	next if $params{include_libcells} && $modref->is_libcell() && $modref->userdata('level')==0;
	print $fh "MODULE ",$modref->name,"\n";
	foreach my $cellref ($modref->cells_sorted) {
	    print $fh "  CELL ",$cellref->name," ",$self->remove_defines($cellref->submodname),"\n";
	}
    }
    $fh->close;
}

sub read_cell_library {
    my $self = shift;
    my %params = (filename=>undef,
		  @_);
    $self->dependency_in($params{filename});
    my $fh = IO::File->new("<$params{filename}") or die "%Error: $! $params{filename}\n";
    my $modref;
    while (defined (my $line = $fh->getline)) {
	$line =~ s/#.*$//;
	$line =~ s/^[ \t]+//;
	$line =~ s/[ \t\n\t]+$//;
	if ($line =~ /^PROGRAM\s+(\S+)/) {
	}
	elsif ($line =~ /^MODULE\s+(\S+)/) {
	    $modref = $self->find_module($1);
	    if (!$modref) {
		$modref = $self->new_module(name=>$1, is_libcell=>1,
					    filename=>$params{filename}, lineno=>$.);
	    }
	}
	elsif ($line =~ /^CELL\s+(\S+)\s+(\S+)$/) {
	    my $cellname = $1; my $submodname = $2;
	    my $cellref = $modref->find_cell($cellname);
	    if (!$cellref) {
		$cellref = $modref->new_cell(name=>$cellname, submodname=>$submodname,
					     filename=>$params{filename}, lineno=>$.);
	    }
	}
	else {
	    die "%Error: $params{filename}:$.: Unknown line: $line\n";
	}
    }
    $fh->close;
}

######################################################################
#### Debug

sub dump {
    my $self = shift;
    $self->SUPER::dump();
    foreach my $modref ($self->classes_sorted) {
	$modref->dump();
    }
}

######################################################################
#### Package return
1;
__END__