Programming Language Interface Sayed Amirhossein Mirhosseini Uses - - PowerPoint PPT Presentation

programming language interface
SMART_READER_LITE
LIVE PREVIEW

Programming Language Interface Sayed Amirhossein Mirhosseini Uses - - PowerPoint PPT Presentation

Programming Language Interface Sayed Amirhossein Mirhosseini Uses of PLI PLI can be used to define additional system tasks and functions e.g. monitoring tasks , stimulus tasks , PLI can be used to extract design information such


slide-1
SLIDE 1

Sayed Amirhossein Mirhosseini

Programming Language Interface

slide-2
SLIDE 2

Uses of PLI

 PLI can be used to define additional system

tasks and functions

 e.g. monitoring tasks , stimulus tasks , …

 PLI can be used to extract design information

such as hierarchy, connectivity, fanout, and number of logic elements of a certain type.

 PLI can be used to write special-purpose or

customized output display routines.

 General Verilog-based application software can

be written with PLI routines.

 This software will work with all Verilog simulators

because of the uniform access provided by the PLI interface.

slide-3
SLIDE 3

A simple PLI Task

#include "veriuser.h" /*include the file provided in release dir */ int hello_verilog() { io_printf("Hello Verilog World\n"); }

 The io_printf is a PLI library routine that

works exactly like printf.

slide-4
SLIDE 4

Linking PLI Tasks

 Whenever the task $hello_verilog is invoked in

the Verilog code, the C routine hello_verilog must be executed.

 The simulator needs to be aware that a new

system task called $hello_verilog exists and is linked to the C routine hello_verilog

 This process is called linking the PLI routines into the

Verilog simulator.

 Different simulators provide different mechanisms to

link PLI routines.

slide-5
SLIDE 5

Invoking PLI Tasks

 Once the user-defined task has been linked

into the Verilog simulator, it can be invoked like any Verilog system task by the keyword $hello_verilog: module hello_top; initial $hello_verilog; //Invoke the user-defined task hello_verilog endmodule

slide-6
SLIDE 6

General Flow

slide-7
SLIDE 7

Access Routines

 Access routines can read information about

  • bjects in the design.

 Objects can be one of the following types:

 Module instances, module ports, module pin-to-pin paths,

and intermodule paths

 Top-level modules  Primitive instances, primitive terminals  Nets, registers, parameters, specparams  Integer, time, and real variables  Timing checks  Named events

slide-8
SLIDE 8

Mechanics of access routines

 Access routines always start with the prefix

acc_.

 A user-defined C routine that uses access

routines must first initialize the environment by calling the routine acc_initialize().

 When exiting, the user-defined C routine must

call acc_close().

 #include "acc_user.h"  Access routines use the concept of a handle to

access an object.

 Handles are predefined data types that point to

specific objects in the design.

 handle top_handle;

slide-9
SLIDE 9

Types of access routines

 Handle routines:

 They return handles to objects in the design.

 acc_handle_.

 Next routines :

 They return the handle to the next object in the set

  • f a given object type in a design.

 acc_next_

 Value Change Link (VCL) routines :

 They allow the user system task to add and delete

  • bjects from the list of objects that are monitored .

 acc_vcl_

 Fetch routines :

 They can extract a variety of information about

  • bjects (e.g. hierarchical path name, relative name)

 acc_fetch_.

slide-10
SLIDE 10

Example 1: Get Module Port List

#include "acc_user.h" int get_ports() { handle mod, port; int input_ctr = 0; int output_ctr = 0; int inout_ctr = 0; acc_initialize(); mod = acc_handle_tfarg(1); /* get a handle to the module instance first argument in the system task argument list */ port = acc_handle_port(mod, 0); /* get the first port of the module */ while( port != null ) /* loop for all ports */ { if (acc_fetch_direction(port) == accInput) /* Input port */ { io_printf("Input Port %s \n", acc_fetch_fullname(port)); /* full hierarchical name */ input_ctr++; }

slide-11
SLIDE 11

Example 1 (cont.)

else if (acc_fetch_direction(port) == accOutput) /* Output port */ { io_printf("Output Port %s \n", acc_fetch_fullname(port));

  • utput_ctr++;

} else if (acc_fetch_direction(port) == accInout) /* Inout port */ { io_printf("Inout Port %s \n", acc_fetch_fullname(port)); inout_ctr++; } port = acc_next_port(mod, port); /* go to the next port */ } io_printf("Input Ports = %d Output Ports = %d, Inout ports = %d\n\n", input_ctr, output_ctr, inout_ctr); acc_close(); }

slide-12
SLIDE 12

Example 1 (cont.)

module top; wire OUT; reg I0, I1, S; mux2_to_1 my_mux(OUT, I0, I1, S); /*Instantiatethe 2-to-1 mux*/ initial begin $get_ports("top.my_mux"); /*invoke task $get_ports to get port list*/ end endmodule

 Output :

Output Port top.my_mux.out Input Port top.my_mux.i0 Input Port top.my_mux.i1 Input Port top.my_mux.s Input Ports = 3 Output Ports = 1, Inout ports = 0

slide-13
SLIDE 13

Example 2: Monitor Nets

#include "acc_user.h" int my_monitor() { handle net; char *netname ; /*pointer to store names of nets*/ char *malloc(); acc_initialize(); /*initialize environment*/ net = acc_handle_tfarg(1); /*get a handle to the net to be monitored*/ netname = malloc(strlen(acc_fetch_fullname(net))); strcpy(netname, acc_fetch_fullname(net)); /* Call the VCL routine to add a signal to the monitoring list*/ /* Pass four arguments to acc_vcl_add task*/ /* 1st : handle to the monitored object (net) 2nd : Consumer C routine to call when the object value changes (display_net) 3rd : String to be passed to consumer C routine (netname) 4th : Predefined VCL flags: vcl_verilog_logic or vcl_verilog_strength */ acc_vcl_add(net, display_net, netname, vcl_verilog_logic); acc_close(); }

slide-14
SLIDE 14

Example 2 (cont.)

 Whenever the value of the net changes, the

acc_vcl_add calls the consumer routine display_net and passes a pointer to a data structure of the type p_vc_record

typedef struct t_vc_record{ int vc_reason; /*reason for value change*/ int vc_hightime; /*Higher 32 bits of 64-bit simulation time*/ int vc_lowtime; /*Lower 32 bits of 64-bit simulation time*/ char *user_data; /*String passed as the argument of acc_vcl_add*/ union { /*New value of the monitored signal*/ unsigned char logic_value; double real_value; handle vector_handle; s_strengths strengths_s; } out_value; } *p_vc_record;

slide-15
SLIDE 15

Example 2 (cont.)

display_net(p_vc_record vc_record) { io_printf("%d New value of net %s is %c \n", vc_record->vc_lowtime, vc_record->user_data, convert_to_char(vc_record->out_value.logic_value)); }

char convert_to_char(char logic_val) { char temp; switch(logic_val) { case vcl0: temp='0'; break; case vcl1: temp='1'; break; case vclX: temp='X'; break; case vclZ: temp='Z'; break; } return(temp); }

slide-16
SLIDE 16

Example 2 (cont.)

module top; wire OUT; reg I0, I1, S; mux2_to_1 my_mux(OUT, I0, I1, S); //Instantiate the module mux2_to_1 initial //Add nets to the monitoring list begin $my_monitor("top.my_mux.sbar"); $my_monitor("top.my_mux.y1"); end initial //Apply Stimulus begin I0=1'b0; I1=1'b1; S = 1'b0; #5 I0=1'b1; I1=1'b1; S = 1'b1; #5 I0=1'b0; I1=1'b1; S = 1'bx; #5 I0=1'b1; I1=1'b1; S = 1'b1; end endmodule

slide-17
SLIDE 17

Example 2 (cont.)

 Output :

0 New value of net top.my_mux.y1 is 0 0 New value of net top.my_mux.sbar is 1 5 New value of net top.my_mux.y1 is 1 5 New value of net top.my_mux.sbar is 0 5 New value of net top.my_mux.y1 is 0 10 New value of net top.my_mux.sbar is X 15 New value of net top.my_mux.y1 is X 15 New value of net top.my_mux.sbar is 0 15 New value of net top.my_mux.y1 is 0

slide-18
SLIDE 18

Utility Routines

 Utility routines are miscellaneous PLI routines

that pass data in both directions across the Verilog/user C routine boundary.

 Do long arithmetic  Display messages  Halt, terminate, save, and restore simulation  …

 Utility routines are also popularly called "tf"

routines.

 Always start with the prefix tf_.  #include "veriuser.h"

slide-19
SLIDE 19

Example 3: my_stop_finish

 Verilog provides the system tasks $stop and

$finish that suspend and terminate the simulation.

 my_stop_finish does both based on its

arguments :

1st Argument 2nd Argument Action none Stop simulation. Display simulation time and message. 1 none Finish simulation. Display simulation time and message. any value Stop simulation. Display simulation time, module instance from which stop was called, and message. 1 any value Finish simulation. Display simulation time, module instance from which stop was called, and message.

slide-20
SLIDE 20

Example 3 (cont.)

#include "veriuser.h" int my_stop_finish() { if(tf_nump() == 1) /* if 1 argument is passed , display only simulation time */ { if(tf_getp(1) == 0) /* if the argument is 0, then stop the simulation*/ { io_printf("Mymessage: Simulation stopped at time %d\n", tf_gettime()); tf_dostop(); /*stop the simulation*/ } else if(tf_getp(1) == 1) /* if the argument is 0 , terminate the simulation*/ { io_printf("Mymessage: Simulation finished at time %d\n“, tf_gettime()); tf_dofinish(); /*terminate the simulation*/ } else /* Pass warning message */ tf_warning("Bad arguments to \$my_stop_finish at time%d\n“,tf_gettime()); }

slide-21
SLIDE 21

Example 3 (cont.)

else if(tf_nump() == 2) /* if 1 argument is passed, print module instance and time*/ { if(tf_getp(1) == 0) /* if the argument is 0 then stop the simulation*/ { io_printf ("Mymessage: Simulation stopped at time %d in instance %s \n", tf_gettime(), tf_mipname()); tf_dostop(); /*stop the simulation*/ } else if(tf_getp(1) == 1) /* if the argument is 0 then terminate the simulation*/ { io_printf ("Mymessage: Simulation finished at time %d in instance %s \n", tf_gettime(), tf_mipname()); tf_dofinish(); /*terminate the simulation*/ } else /* Pass warning message */ tf_warning("Bad arguments to \$my_stop_finish at time %d\n",tf_gettime()); } }

slide-22
SLIDE 22

Example 3 (cont.)

module top; wire OUT; reg I0, I1, S; mux2_to_1 my_mux(OUT, I0, I1, S); //Instantiate the module mux2_to_1 initial //Apply Stimulus begin I0=1'b0; I1=1'b1; S = 1'b0; $my_stop_finish(0); //Stop simulation. Don't print module instance name #5 I0=1'b1; I1=1'b1; S = 1'b1; $my_stop_finish(0,1); //Stop simulation. Print module instance name #5 I0=1'b0; I1=1'b1; S = 1'bx; $my_stop_finish(2,1); //Pass bad argument 2 to the task #5 I0=1'b1; I1=1'b1; S = 1'b1; $my_stop_finish(1,1); //Terminate simulation. Print module instance //nameend endmodule

slide-23
SLIDE 23

Example 3 (cont.)

 Output :

Mymessage: Simulation stopped at time 0 Type ? for help C1 > . Mymessage: Simulation stopped at time 5 in instance top C1 > . "my_stop_finish.v", 14: warning! Bad arguments to $my_stop_finish at time 10 Mymessage: Simulation finished at time 15 in instance top