#$Revision: #26 $$Date: 2003/06/16 $$Author: wsnyder $
######################################################################
#
# This program is Copyright 2001 by Wilson Snyder.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of either the GNU General Public License or the
# Perl Artistic License.
# 
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# If you do not have a copy of the GNU General Public License write to
# the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, 
# MA 02139, USA.
#                                                                           
######################################################################

=pod

=head1 NAME

SystemPerl - SystemPerl Language Extension to SystemC

=head1 DESCRIPTION

SystemPerl is a version of the SystemC language.  It is designed to expand
text so that needless repitition in the language is minimized.  By using
C<sp_preproc>, SystemPerl files can be expanded into C++ files at compile
time, or expanded in place to make them valid stand-alone SystemC files.

The concept of SystemPerl is based upon the AUTOS in the C<verilog-mode>
package for Emacs, by the same author.

=head1 LANGUAGE

=over 4

=item #sp

#sp directives are recognized by SystemPerl to split up files and control
preprocessing.  Use of any #sp's forces use of SystemPerl preprocessing, and
removes full SystemC compatibility.

=item /*AUTOS*/

AUTOmatics provide a way of expanding interconnections, while potentially
retaining fully compatible SystemC code.  The preprocessor can edit the
source code file directly, resulting in the source code having the expanded
automatics.  

Code with expanded AUTOs are fully valid SystemC code, and can be sent to
anyone who does not even have system perl.  Anyone with SystemPerl has the
benefit of being able to automatically regenerate them, and saves coding
time.

=back

=head1 LANGUAGE REQUIREMENTS

SystemPerl requires the following coding conventions.  These tokens are not
changed in any way, but are simply required for SystemPerl to be able to
derrive required information from the source code.

=over 4

=item SP_CELL_DECL (I<refname>, I<instname[s]>)

SP_CELL_DECL declares the cell structures.  It is only needed to declare
those cells that AUTOCELLS will not create itself; currently this is any
cells which are arrayed.

=item SP_CELL (I<instname>, I<refname>)

SP_CELL instantiates the given module named refname as a instantiation
called instname.  The instname is also passed as a parameter to refname as
a string.  Note if you are doing an array, you probably want SP_CELL_FORM.

=item SP_CELL_FORM (I<instname>, I<refname>, I<form>, ...)

SP_CELL_FORM instantiates the given module named refname as a instantiation.
The instantiation is named by using a sprintf of the given format and arguments.
Generally this is used for arrays: i.e.:

=item SC_MODULE (I<modulename>)

Though a standard optional SystemC construct, SystemC requires use of the
SC_MODULE macro when defining a module class. For example "struct mod1 :
public sc_module" must instead be coded as "SC_MODULE(mod1)".

    SP_CELL_FORM(slice[i], smm_pi_slice, "slice[%d]", i);

=item SP_PIN (I<instname>, I<portname>, I<netname>)

SP_PIN declares a connection of a instantation's port to the specified net.

=item SP_TRACED

SP_TRACED is used as an attribute like static or const.  It indicates the
simple variable should be added to any waves files that AUTOTRACE creates.

Note you cannot trace output ports without patching the SystemC library,
see the README file.

=back

=head1 EXPANSIONS

SystemPerl expands the following special tokens.

=over 4

=item __MODULE__

__MODULE__ is predefined to the name of the module, from the basename of
the filename.  This allows files to be more easily replicated, and to avoid
obscure errors when the filename does not match the module name.

For example:

SC_MODULE (__MODULE__) {
  ...

=item /*AUTOENUM_I<CLASS|GLOBAL>(I<enum>)*/

AUTOENUM is used to take an existing enumeration and make it into a class
with functions to return the ASCII name of the enumeration.  This makes
it easy to print the value of the enumeration in text form.

For example:

class MyENumClass {
public:
    enum en {
	IDLE = 0,
	ONE, TWO, THREE, FOUR, FIVE
    };
    /*AUTOENUM_CLASS(MyENumClass.en)*/
};
/*AUTOENUM_GLOBAL(MyENumClass.en)*/

Becomes:

class MyENumClass {
public:
    enum en {
	IDLE = 0,
	ONE, TWO
    };
    /*AUTOENUM_CLASS(MyENumClass.en)*/
    // Beginning of SystemPerl automatic enumeration
    enum en e_en;
    inline MyENumClass () {};
    inline MyENumClass (en _e) : e_en(_e) {};
    explicit inline MyENumClass (int _e) : e_en(static_cast<en>(_e)) {};
    operator const char * (void) const { return ascii(); };
    operator en (void) const { return e_en; };
    const char *ascii (void) const {
       switch (e_en) {
       case IDLE: return "IDLE";
       case ONE: return "ONE";
       case TWO: return "TWO";
       default: return "%E:BadVal:MyENumClass";
       };
    };
    // End of SystemPerl automatic enumeration
};
/*AUTOENUM_GLOBAL(MyENumClass.en)*/
// Beginning of SystemPerl automatic enumeration
inline bool operator== (MyENumClass lhs, MyENumClass rhs) { return (lhs.e_en == rhs.e_en); }
//... other accessors
// End of SystemPerl automatic enumeration

=item /*AUTOINOUT_MODULE(I<mod>)*/

AUTOINOUT_MODULE indicates the input/output list should be copied from the
specified other module.  This is useful for creating null modules which
need identical pinouts to the module which they are nulling out.
AUTOSIGNAL must be used along with this auto, as the ports are inserted
at the point where the AUTOSIGNAL is.

=item /*AUTOIMPLEMENTATION*/

AUTOIMPLEMENTATION includes function definitions required inside the .cpp
file, such as functions implementing ENUM ascii functions.  AUTOIMPLEMENTATION
will be included automatically at the end of a expanded .cpp file if it is
not otherwise found in the file.

=item /*AUTOINST*/

AUTOINST connects any unreferenced ports for the current SP_CELL to signals
named the same as the port name.

For example:

SC_MODULE(submod) {
    sc_in_clk	clk;
    ...

SC_MODULE(mod) {
    SC_CTOR(mod) {
	SP_CELL (sub, submod);
	  /*AUTOINST*/

Becomes:

SC_MODULE(mod) {
    SC_CTOR(mod) {
	SP_CELL (sub, submod);
	  // Beginning of SystemPerl automatic instantiation pins
	  SP_PIN (sub, clk,	clk);
	  // End of SystemPerl automatic instantiation pins

=item /*AUTOMETHODS*/

AUTOMETHODS indicates where interface declarations should be inserted.  It
also declares a SC_CTOR(__MODULE__) method if there is not already one in
the class header.  Additional methods that are inserted are is described
under AUTOTRACE.

=item /*AUTOSUBCELL_CLASS*/

AUTOSUBCELL_CLASS creates forward class declarations for the submodules
instantiated in SP_CELL declarations.

For example:

/*AUTOSUBCELL_CLASS*/
SC_MODULE(mod) {
    SC_CTOR(mod) {
	SP_CELL (sub, submod);

Becomes:

/*AUTOSUBCELL_CLASS*/
// Beginning of SystemPerl automatic subcell includes
class submod;
// End of SystemPerl automatic subcell includes
...

=item /*AUTOSUBCELL_DECL*/

AUTOSUBCELL_DECL declares the submodules instantiated in SP_CELL declarations.

For example:

SC_MODULE(mod) {
    /*AUTOSUBCELL_DECL*/
    SC_CTOR(mod) {
	SP_CELL (sub, submod);
	  SP_PIN (sub, a,	a);

Becomes:

SC_MODULE(mod) {
    /*AUTOSUBCELL_DECL*/
    // Beginning of SystemPerl automatic subcells
    submod            *sub;
    // End of SystemPerl automatic subcells

    SC_CTOR(mod) {
	SP_CELL (sub, submod);
	  SP_PIN (sub, a,	a);

=item /*AUTOSUBCELL_INCLUDE*/

AUTOSUBCELL_INCLUDE creates includes for the submodules instantiated in
SP_CELL declarations.

For example:

/*AUTOSUBCELL_INCLUDE*/
SC_MODULE(mod) {
    SC_CTOR(mod) {
	SP_CELL (sub, submod);

Becomes:

/*AUTOSUBCELL_INCLUDE*/
// Beginning of SystemPerl automatic subcell includes
#include "submod.h"
// End of SystemPerl automatic subcell includes
...

=item /*AUTOSIGNAL*/

AUTOSIGNAL declares any signals used in SP_PIN connections that are not
declared elsewhere.

For example:

SC_MODULE(mod) {
    /*AUTOSIGNAL*/
    SC_CTOR(mod) {
	SP_CELL (sub, submod);
	  SP_PIN (sub, a,	a);

Becomes:

SC_MODULE(mod) {
    /*AUTOSIGNAL*/
    // Beginning of SystemPerl automatic signals
    sc_signal<bool>             a;       // For submod
    // End of SystemPerl automatic signals

    SC_CTOR(mod) {
	SP_CELL (sub, submod);
	  SP_PIN (sub, a,	a);

=item /*AUTOTRACE(I<module>,I<recurse>)*/

AUTOTRACE creates a routine to trace the ports and signals in the current
module, and then call the tracing routine on all submodules.  AUTOMETHODS
is also required in the declaration of the module.  A optional second
argument of "recurse" indicates the trace code should include all
submodules, leading to smaller trace files, but longer compile and link
times.

AUTOTRACE will not trace signals beginning with a underscore.  It also
replaces __DOT__ in signal names to "." to support fake hiearchy, such as
is created with Verilator.

Note because of a SystemC limitation, output ports cannot be traced.  Also
the hiearchy is not properly placed into the trace file; the hiearchy path
will be added to the signal name itself.  Also, arrayed nets/cells aren't
quite right yet.

Example:

SC_MODULE (ExMod) {
    ...
    sc_in<bool>		in;
    SP_CELL_DECL(ExModSub,          suba);

    /*AUTOMETHODS*/
    // Beginning of SystemPerl automatic declarations
    void trace (sc_trace_file *tf, const sc_string& prefix, int levels, int options=0);
    // End of SystemPerl automatic declarations
}
...

/*AUTOTRACE(ExMod)*/
// Beginning of SystemPerl automatic trace file routine
void ExMod::trace (sc_trace_file *tf, const sc_string& prefix, int levels, int options=0) {
    sc_trace(tf, this->in.read(),           prefix+"in", 1);
    if (levels > 0) {
        this->suba->trace (tf, prefix+"suba.", levels-1, options);
    }
}
// End of SystemPerl automatic trace file routine

=item #sp include

Includes the file for the preprocessor, it will be expanded into the output
.h/.cpp files.  Note that regular "#include" files are not read or expanded
to save disk space and time.

=item #sp interface

Interface specifies the following code should be moved into a the header
file.  This allows a common .sp file to contain both .h and .cpp
information.  SystemPerl automatically adds include guards in the header,
to protect against multiple inclusion.

=item #sp implementation

The Interface specifies the following code should be part of the cpp file.
This allows a common .sp file to contain both .h and .cpp information.

=item #sp use

This specifies a file that must be #included at compile time.  In addition
the file is a .sp file, which must be preprocessed by sp_preproc, and added
to the link list.  Thus using #sp use automatically finds the objects
required for linking against the includer.  (Just like perl's package and
use statements.)

In addition to specifing an exact string like with #include, you may also
specify a define symbol or a cell search path.  The value of a definition
will be substituted to find the file to be included.  If a name of the form
.cell.subcell is used, it will include both the header for the module for
"cell", and for "subcell" underneath "cell".

=back

=head1 SEE ALSO

C<sp_includer>
C<sp_preproc>
C<SystemC::Netlist>
C<SystemC::Parser>

=head1 DISTRIBUTION

The latest version is available from CPAN and from C<http://veripool.com/>.

=head1 AUTHORS

Wilson Snyder <wsnyder@wsnyder.org>

=cut
