This is done by linking the user-defined system task into the Verilog simulator.. First, the C routine that implements the task must be defined with PLI library routines.. 13.2.1 Linking
Trang 1[ Team LiB ]
13.1 Uses of PLI
PLI provides a powerful capability to extend the Verilog language by allowing users to define their own utilities to access the internal design representation PLI has various applications
• PLI can be used to define additional system tasks and functions Typical examples are monitoring tasks, stimulus tasks, debugging tasks, and complex operations that cannot be implemented with standard Verilog constructs
• Application software like translators and delay calculators can be written with PLI
• 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 Waveform viewers can use this file to generate waveforms, logic connectivity, source level browsers, and hierarchy information
• Routines that provide stimulus to the simulation can be written with PLI The stimulus could be automatically generated or translated from some other form of stimulus
• 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
[ Team LiB ]
[ Team LiB ]
13.2 Linking and Invocation of PLI Tasks
Designers can write their own user-defined system tasks by using PLI library routines However, the Verilog simulator must know about the existence of the user-defined
system task and its corresponding user-defined C function This is done by linking the user-defined system task into the Verilog simulator
To understand the process, let us consider the example of a simple system task
$hello_verilog When invoked, the task simply prints out a message "Hello Verilog World" First, the C routine that implements the task must be defined with PLI library routines The C routine hello_verilog in the file hello_verilog.c is shown below
#include "veriuser.h" /*include the file provided in release dir */
int hello_verilog()
Trang 2{
io_printf("Hello Verilog World\n");
}
The hello_verilog routine is fairly straightforward The io_printf is a PLI library routine that works exactly like printf
The following sections show the steps involved in defining and using the new
$hello_verilog system task
13.2.1 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 Also, though the exact mechanics of the linking process might be different for simulators, the fundamentals of the linking process remain the same For details, refer to the latest reference manuals available with your simulator
At the end of the linking step, a special binary executable containing the new
$hello_verilog system task is created For example, instead of the usual simulator binary executable, a new binary executable hverilog is produced To simulate, run hverilog instead of your usual simulator executable file
13.2.2 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 A Verilog module hello_top, which calls the task $hello_verilog, is defined in file hello.v as shown below
module hello_top;
initial
$hello_verilog; //Invoke the user-defined task $hello_verilog
endmodule
Output of the simulation is as follows:
Hello Verilog World
Trang 313.2.3 General Flow of PLI Task Addition and Invocation
We discussed a simple example to illustrate how a user-defined system task is named, implemented in terms of a user-defined C routine, linked into the simulator, and invoked
in the Verilog code More complex PLI tasks discussed in the following sections will follow the same process Figure 13-2 summarizes the general process of adding and invoking a user-defined system task
Figure 13-2 General Flow of PLI Task Addition and Invocation
[ Team LiB ]
[ Team LiB ]
13.3 Internal Data Representation
Trang 4Before we understand how to use PLI library routines, it is first necessary to describe how a design is viewed internally in the simulator Each module is viewed as a collection
of object types Object types are elements defined in Verilog, such as:
• 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
Each object type has a corresponding set that identifies all objects of that type in the module Sets of all object types are interconnected
A conceptual internal representation of a module is shown in Figure 13-3
Figure 13-3 Conceptual Internal Representation a Module
Each set contains all elements of that object type in the module All sets are
interconnected The connections between the sets are bidirectional The entire internal representation can be traversed by using PLI library routines to obtain information about the module PLI library routines are discussed later in the chapter
To illustrate the internal data representation, consider the example of a simple 2-to-1 multiplexer whose gate level circuit is shown in Figure 13-4
Figure 13-4 2-to-1 Multiplexer
Trang 5The Verilog description of the circuit is shown in Example 13-1
Example 13-1 Verilog Description of 2-to-1 Multiplexer
module mux2_to_1(out, i0, i1, s);
output out; //output port
input i0, i1; //input ports
input s;
wire sbar, y1, y2; //internal nets
//Gate Instantiations
not n1(sbar, s);
and a1(y1, i0, sbar);
and a2(y2, i1, s);
or o1(out, y1, y2);
endmodule
The internal data representation for the 2-to-1 multiplexer is shown in Figure 13-5 Sets are shown for primitive instances, primitive instance terminals, module ports, and nets Other object types are not present in this module
Figure 13-5 Internal Data Representation of 2-to-1 Multiplexer
Trang 6The example shown above does not contain register, integers, module instances, and other object types If they are present in a module definition, they are also represented in terms of sets This description is a conceptual view of the internal structures The exact implementation of data structures is simulator dependent
[ Team LiB ]