Previous Section Next Section

16.2 Integrating C Files

For C routines to interact with e code, the C files have to be integrated with Specman Elite. A special script sn_compile.sh is provided with the Specman Elite installation to compile and link C code and e code in Specman Elite.

16.2.1 Integration Flow

To integrate C code and e code in Specman Elite perform the following steps:

  1. Declare the C routines in e code using the is C routine keywords. These keywords in the e code indicate to the sn_compile.sh script that the particular routine or e method is implemented as a C routine. Therefore the computation of the return value for that routine or method is done in C code.

  2. Often the C code needs access to e types or methods. Export the e types or methods used by C routines by adding C export statements in the e code. The C export statements in e code allow C code to access e types or methods.

  3. Generate the C header files (.h files) from the e files using the sn_compile.sh script with the -h_only option. These C header files contain information declared in e code with is C routine keywords and C export statements. These header files are compiled in the C domain.

  4. Include the generated header files in your C files using the #include C syntax. These header files provide information about accessing e types or methods from C files.

  5. Compile all your C files using the gcc compiler (gcc with -c and -o options) to create object (.o files).

  6. Compile your e files that contain C directives and link them with your simulator and C object files using the sn_compile.sh script with -l option and the -o option to create an executable binary file.

  7. Execute this binary file at the operating system command prompt to run Specman Elite along with the compiled C code instead of running the standard Specman Elite binary.

Figure 16-1 below shows the integration mechanism. The exact commands to execute are shown later in Example 16-4.

Figure 16-1. Integrating e Files and C Files

graphics/16fig01.gif

16.2.2 A Simple Example

A simple example described in this section shows how the integration of e files and C files takes place. This example uses a C routine, wrap_mean_sqrt, declared as a global e routine, mean_sqrt(), to calculate the mean square root of a list of packets.

16.2.2.1 Declaring a Global e Routine as a C Routine

First, a global e routine, mean_sqrt() must be declared. This routine mean_sqrt() is implemented using the C routine wrap_mean_sqrt. Example 16-1 shows the declaration of mean_sqrt() routine.

Example 16-1 Declaring a Global e Routine as a C Routine
File name: wrap_mean_sqrt.e
<'
-- Declare a global e routine named mean_sqrt which takes a list
-- of integers as an argument. The return type is also int.
-- The computation of this routine is performed in C code using
-- the C routine wrap_mean_sqrt

routine mean_sqrt(l:list of int):int is C routine wrap_mean_sqrt;

'>
16.2.2.2 Calling a Global e Routine Declared as a C Routine

The e routine mean_sqrt() declared earlier is invoked in e code simply by calling it like an e method. Example 16-2 calls mean_sqrt() and passes it a list of packet lengths. The mean_sqrt() calls the wrap_mean_sqrt C routine and passes it the list of packet lengths.

Example 16-2 Calling a Global e Routine Declared as a C Routine
File: packets_statistics.e
File calls the mean_sqrt e routine
to compute the mean square root of packet
lengths in a list. The mean_sqrt e routine
calls the C routine wrap_mean_sqrt.
<'
-- Definition of the packet struct
struct packet {
    kind       : [good,bad];
    addr       : uint (bits : 2) ;
    len        : uint (bits : 6) ;
    data [len] : list of byte ;
    !parity    : byte ;
};
-- Definition of port struct
struct port {
     packets        : list of packet; -- List of packets
    !len_mean_sqrt : int; -- Mean square root value
    !packets_lens  : list of uint (bits:6); -- List of lengths

    check() is also {
        -- Create a list of packet lengths
        packets_lens = packets.apply( it.len );
        -- Print the list of packet lengths
        print packets_lens;
        -- Call the mean_sqrt e routine with a list of packet
        -- lengths. This routine calls the C routine
        -- wrap_mean_sqrt to perform the computation.
        len_mean_sqrt = mean_sqrt( packets_lens );
        -- Print the computed value.
        print len_mean_sqrt;
    };
};

-- Instantiate the port struct
extend sys {
    port : port;
};
'>
16.2.2.3 Implementing the C Routine

The wrap_mean_sqrt C routine is implemented by means of another C routine compute_mean_sqrt. Therefore, there are three C files, wrap_mean_sqrt.c, and compute_mean_sqrt.h, compute_mean_sqrt.c. Example 16-3 shows the C code for all three files.

Example 16-3 Implement the C Routine
File name: wrap_mean_sqrt.c
#include "compute_mean_sqrt.h"
#include "wrap_mean_sqrt_.h"

int wrap_mean_sqrt( SN_LIST( int ) e_list_of_int ) {

    int i;
    int result;
    int list_size;
    double * c_list_of_double;

    list_size = SN_LIST_SIZE( e_list_of_int );
    c_list_of_double =
        (double *)calloc( list_size, sizeof(double) );

    for (i=0; i < list_size; i++ ) {
        c_list_of_double[i] =
            (double)SN_LIST_GET( e_list_of_int, i, int);
    };

    result = (int)compute_mean_sqrt( c_list_of_double, list_size );
    free( c_list_of_double );
    return( result );

} // wrap_mean_sqrt
//End of file wrap_mean_sqrt.c
----------------------------------------------------------------------

----------------------------------------------------------------------
File name: compute_mean_sqrt.h
double compute_mean_sqrt( double *nums, int size );
//End of file compute_mean_sqrt.h
----------------------------------------------------------------------

----------------------------------------------------------------------
File name: compute_mean_sqrt.c
#include <math.h>
#include "compute_mean_sqrt.h"

double compute_mean_sqrt( double *nums, int size ) {
    int i;
    double sum = 0;
    for ( i=0; i<size; i++ ) {
        sum += sqrt( nums[ i ] );
    };
    return( sum/size );
};
//End of file compute_mean_sqrt.c
----------------------------------------------------------------------
16.2.2.4 Commands for Compiling and Linking e Code and C Code

Example 16-4 shows the commands required to compile and link e code and C code defined to implement the mean_sqrt() e routine. These commands are executed at the operating system prompt (for example the UNIX command prompt).

Example 16-4 Commands for Compiling and Linking e Code and C Code
[View full width]
This example does not contain e code.
It contains commands executed at the operating system prompt(%)

The file wrap_mean_sqrt.e contains the e routine declaration for mean_sqrt that points to
graphics/ccc.gif C routine wrap_mean_sqrt. The .h file is generated using the sn_compile.sh -h_only option.
graphics/ccc.gif The following command generates the wrap_mean_sqrt_.h file.
    % sn_compile.sh -h_only wrap_mean_sqrt.e -o wrap_mean_sqrt_.h

The file compute_mean_sqrt.c performs the mean square root computation. The file
graphics/ccc.gif wrap_mean_sqrt.c contains an implementation of the wrap_mean_sqrt C routine. This routine
graphics/ccc.gif calls the compute_mean_sqrt routine. The file wrap_mean_sqrt.c also includes the .h file
graphics/ccc.gif wrap_mean_sqrt_.h that was generated in the previous step. Compile the files using the gcc
graphics/ccc.gif -c -o option. These commands create the object files.
    % gcc -c compute_mean_sqrt.c -o mean_sqrt.o
    % gcc -c wrap_mean_sqrt.c -o wrap_mean_sqrt.o

Compile the e files and C object files to create a new Specman Elite binary file. Use the
graphics/ccc.gif command sn_compile.sh -l. The -o option is used to specify the name of the new Specman
graphics/ccc.gif Elite binary called float_mean_sqrt.
    % sn_compile.sh -l "mean_sqrt.o wrap_mean_sqrt.o" \
     wrap_mean_sqrt.e -o float_mean_sqrt

Run the new Specman Elite binary instead of running the standard Specman Elite binary
graphics/ccc.gif(specman).
    % ./float_mean_sqrt

This brings up the Specman prompt. The new binary that is executing contains both standard
graphics/ccc.gif Specman Elite behavior plus the C code. Load the packet_statistics.e file and run the test
graphics/ccc.gif using the test command. In this environment, calls can be made to the mean_sqrt() global e
graphics/ccc.gif routine.
    Specman wrap_mean_sqrt> load packets_statistics.e
    Specman packets_statistics> test
Previous Section Next Section