How to Connect e-Language with Python

This post is an addition to the previous post How to connect SystemVerilog with Python. The principles of connecting e-Language with Python are similar to those presented in the aforementioned post.

Table of contents

  • Create the e-Language-to-C Interface
  • Client Layer Code Changes
  • Create the Top Modules
  • How To Run the Example

  • Create the e-Language-to-C Interface

    In order to access the client functions, the e-Language code needs to know where to find those functions.

    I created the client.e file to let the sys unit know that the call_client C function is found in mylibc.so which is a shared object created at compile time. The names of these shared objects along with other headers used for compilation are specified in the sim/sim.options. The client.e code looks like this:

    <'
    //This code tells sys where to find the call_client function written in C
    extend sys {
       call_client(hostname: string, client_port: int, client_msg: string):string is foreign dynamic C routine mylibc:;
    };
    '>
    


    Client Layer Code Changes

    In order to create a DPI between e-Language and C, the C code has to import a special header created when compiling the e-Language code. This header file is similar to the svdpi header used with SystemVerilog and it contains the C function signature previously defined in the client.e file.

    I split the client C code into 2 parts:

    • client.cc: contains the main functionalities of the client layer
    • client_e.cc: adds the special header alongside with client.cc(specific for e-Language-Python integration)


    Create the Top Modules

    The SystemVerilog top module is used to instantiate the DUT and to create the signals required by the DUT and the clock generator. The SystemVerilog top module code looks like this:

    module amiq_top_e;
      reg in0, in1; //the inputs of the mux
      reg sel; //the selection of the mux
      reg out; //the output of the mux
      reg clk; //the clock signal
    
      //Instantiate the DUT
      amiq_mux2_1 dut(clk,sel,in0,in1,out);
    
      //Signals initialization
      initial begin
        in0=0;
        in1=0;
        sel=0;
        clk=0;
      end
    
      //Clock generator
      always#5 clk =~clk;
    endmodule
    

    The e-Language top module is used to define the verification environment of the DUT and to map the e-Language signals with their correspondents from SystemVerilog testbench. In order to have access to the C function, the client.e file must be imported. The code for the e-Language top module looks like this:

    <'
    import client.e;
    
    define HOSTNAME "heket"; //change with your hostname
    define CLIENT_PORT 54000; //must be the same with the server’s port
    define NOF_SAMPLES 10; //number of items to drive
    define DELIM ","; //depends on how data is packed by the server
    
    //Structure used to pack items for the DUT
    struct stimuli_struct{
      !in0 : list of bit;
      !in1 : list of bit;
      !sel : list of bit;
      !delay0 : list of uint;
      !delay1 : list of uint;
      !delay_sel : list of uint;
    };
    
    //Map amiq_top.sv signals with e-Language variables
    unit signal_map{
    	…...
    };
    
    //This unit drives DUT's signals
    unit e_driver{
      packed_stimuli: stimuli_struct; //this structure is used to pack the received stimuli
    	
      !smp_p: signal_map;
      event clock is cycle @smp_p.clk_r; //clock posedge event
    	
      //Drive in0
      drive_in0()@clock is{
      	…...
      };
    	
      //Drive in1
      drive_in1()@clock is{
    	…...
      };
    	
      //Drive sel
      drive_sel()@clock is{
    	…...
      };
    	
      //Drive all signals to DUT in parallel 
      drive_signals()@sys.any is{
        all of{
          {drive_in0()};
          {drive_in1()};
          {drive_sel()};
        };
        stop_run();
      };
    	
      //Ask the python Server to send item data and push it into packed_stimuli
      get_data_from_python() is{
          ……..	
      }
    	
      run() is also{
        get_data_from_python();
        start drive_signals();
      };
    };
    
    extend sys {
      driver: e_driver is instance;
      smp: signal_map is instance;
    	
      //Set the path to the SV top
      keep smp.hdl_path() == "amiq_top_e";
    	
      //Make signals mapping available for the driver
      connect_pointers() is also{
        driver.smp_p=smp;
      };
    };
    '>
    

    As you can see, the above code has the same logic with the SystemVerilog top code presented in How to connect SystemVerilog with Python.

    Be aware that the call_client function can be called only by the sys unit.

    How To Run the Example

    To run the application, you should follow the next steps:

    1. Download the code from GitHub repo
    2. Export the PROJ_HOME variable to the folder containing the code:
       export PROJ_HOME="/path/to/source/folder"
    3. Open the amiq_top.e file and change the HOSTNAME macro to “your hostname”
    4. Open another terminal and start the Server with:
       python3.6 server.py
    5. Run the arun.sh script:
      ./arun.sh



    That’s all for today. Read, comment and subscribe to keep the community alive!



    Later Edit: About a month after we published this article, it looks like Specman 19.05 provides support for built-in integration with Python. You can read more here.


    Comments

    Leave a Comment:

    Your comment will be visible after approval.

    (will not be published)

    This site uses Akismet to reduce spam. Learn how your comment data is processed.