返回介绍

30.10 Reading data from multiple databases and/or different read library providers

发布于 2020-09-09 22:56:03 字数 8181 浏览 931 评论 0 收藏 0

The VPI routine vpi_load_extension() is used to load VPI extensions. Such extensions include reader libraries from such tools as waveform viewers. vpi_load_extension() shall return a pointer to a function pointer structure with the following definition.

typedef struct {
    void *user_data; /* Attach user data here if needed */
    /* Below this point user application MUST NOT modify any values */
    size_t struct_size; /* Must be set to sizeof(s_vpi_extension) */
    long struct_version; /* Set to 1 for SystemVerilog 3.1a */
    PLI_BYTE8 *extension_version;
    PLI_BYTE8 *extension_name;
    /* One function pointer for each of the defined VPI routines:
     - Each function pointer has to have the correct prototype */
    ...
    PLI_INT32 (*vpi_chk_error)(error_info_p);
    ...
    PLI_INT32 (*vpi_vprintf)(PLI_BYTE8 *format, ...);
    ...
} s_vpi_extension, *p_vpi_extension;

Subsequent versions of the s_vpi_extension structure shall only extend it by adding members at the end; previously existing entries must not be changed, removed, or re-ordered in order to preserve backward compatability. The struct_size entry allows users to perform basic sanity checks (e.g. before type casting), and the struct_version permits keeping track and checking the version of the s_vpi_extension structure. The structure also has a user_data field to give users a way to attach data to a particular load of an extension if they wish to do so.

The structure shall have an entry for every VPI routine; the order and synopsis of these entries within the structure shall exactly match the order and synopsis of function definitions in Chapter 27 of the Verilog Standard, IEEE Std 1364-2001. After those entries the SystemVerilog VPI routine additions for assertions vpi_get_assertion_info() and then vpi_register_assertion_cb() shall be added in that order. Then all new reader routines defined in Table 30-3 shall be added in exactly the order noted in the table. If a particular extension does not support a specific VPI routine, then it shall still have an entry (with the correct prototype), and a dummy body that shall always have a return (consistent with the VPI prototype) to signify failure (i.e. NULL or FALSE ). The routine call must also raise the appropriate VPI error, which can be checked by vpi_chk_error(), and/or automatically generate an error message in a manner consistent with the specific VPI routine.

If tool providers want to add their own implementation extensions, those extensions must only have the effect of making the s_vpi_extension structure larger and any non-standard content must occur after all the standard fields. This permits applications to use the pointer to the extended structure as if it was a p_vpi_extension pointer, yet still allow the applications to go beyond and access or call tool-specific fields or routines in the extended structure. For example, a tool extended s_vpi_extension could be:

typedef struct {
    /* inline a copy of s_vpi_extension */
    /* begin */
    void *user_data;
    ...
    /* end */
    /* “toolZ” extension with one additional routine */
    int (*toolZfunc)(int);
} s_toolZ_extension, *p_toolZ_extension;

An example of use of the above extended structure is as follows:

p_vpi_extension h;
p_toolZ_extension hZ;
h = vpi_load_extension(“toolZ”, <args>);
if ( h && (h->struct_size >= sizeof(s_toolZ_extension))
&& !(strcmp(h->extension_version, “...”)
&& !strcmp(h->extension_name, “toolZ”) ) {
hZ = (p_toolZ_extension) h;
/* Can now use hZ to access all the VPI routines, including toolZ’s
‘toolZfunc’ */
...
}

The SystemVerilog tool the user application is running under is responsible for loading the appropriate extension, i.e. the reader API library in the case of the read API. The extension name is used for this purpose, following a specific policy, for example, this extension name can be the name of the library to be loaded. Once the reader API library is loaded all VPI function calls that wish to use the implementation in the library shall be performed using the returned p_vpi_extension pointer as an indirection to call the function pointers specified in s_vpi_extension or the extended vendor specific structure as described above. Note that, as stated earlier, in the case the application is using the built-in routine implementation (i.e. the ones provided by the tool (e.g. simulator) it is running under) then the de-reference through the pointer is not necessary.

Multiple databases can be opened for read simultaneously by the application. After a vpi_load_extension() call, a top scope handle can be created for that database to be used later to derive any other handles for objects in that database. An example of multiple database access is shown below. In the example, scope1 and scope2 are the top scope handles used to point into database1 and database2 respectively and perform the processing (comparing data in the two databases for example).

p_vpi_extension reader_pX; /* Pointer to reader libraryfunction struct */
p_vpi_extension reader_pY; /* Pointer to reader libraryfunction struct */
vpiHandle scope1, scope2; /* Some scope being looked at */
vpiHandle var_handle; /* Object handle */
vpiHandle some_net; /* Handle of some net */
vpiHandle some_reg; /* Handle of some reg */
vpiHandle vc_trvs_hdl1; /* Traverse handle */
vpiHandle vc_trvs_hdl2; /* Traverse handle */
vpiHandle itr; /* Iterator */
vpiHandle objCollection1, objCollection2; /* Object collection */
vpiHandle trvsCollection1, trvsCollection2; /* Traverse collection */
p_vpi_time time_p; /* time */
PLI_BYTE8 *data1 = “database1”;
PLI_BYTE8 *data2 = “database2”;
/* Initialize the read interface: Post process mode, read from a database */
/* NOTE: Use library from “toolX” */
reader_pX = vpi_load_extension(“toolX”, data1, vpiAccessPostProcess);
/* Get the scope using its name */
/* NOTE: scope handle comes from database: data1 */
scope1 = reader_pX->vpi_handle_by_name(“top.m1.s1”, NULL);
/* Initialize the read interface: Post process mode, read from a database */
/* NOTE: Use library from “toolY” */
reader_pY = vpi_load_extension(“toolY”, data2, vpiAccessPostProcess);
/* Get the scope using its name */
/* NOTE: scope handle comes from database: data2 */
scope2 = reader_pY->vpi_handle_by_name(“top.m1.s1”, NULL);
/* Create object collections */
objCollection1 = reader_pX->vpi_create(vpiObjCollection, NULL, NULL);
objCollection2 = reader_pY->vpi_create(vpiObjCollection, NULL, NULL);
/* Add data to collection1: All the nets in scope1,
data comes from database1 */
/* ASSUMPTION: (waveform) tool supports this navigation relationship */
itr = reader_pX->vpi_iterate(vpiNet, scope1);
while (var_handle = reader_pX->vpi_scan(itr)) {
objCollection1 = reader_pX->vpi_create(vpiObjCollection, objCollection1,
var_handle);
}
/* Add data to collection2: All the nets in scope2,
data comes from database2 */
/* ASSUMPTION: (waveform) tool supports this navigation relationship */
itr = reader_pY->vpi_iterate(vpiNet, scope2);
while (var_handle = reader_pY->vpi_scan(itr)) {
objCollection2 = reader_pY->vpi_create(vpiObjCollection, objCollection2,
var_handle);
}
/* Initialize the load: focus only on the signals in the object collection:
objCollection */
reader_pX->vpi_load_init(objCollection1, NULL, 0);
reader_pY->vpi_load_init(objCollection2, NULL, 0);
/* Demo: Scan the object collection */
itr = reader_pX->vpi_iterate(vpiMember, objCollection1);
while (var_handle = reader_pX->vpi_scan(itr)) {
...
}
itr = reader_pY->vpi_iterate(vpiMember, objCollection2);
while (var_handle = reader_pY->vpi_scan(itr)) {
...
}
/* Application code here: Access Objects from database1 or database2 */
some_net = ...;
time_p = ...;
some_reg = ...;
....
/* Data querying and processing here */
....
/* free handles*/
reader_pX->vpi_free_object(...);
reader_pY->vpi_free_object(...);
/* close databases */
reader_pX->vpi_close(0, vpiAccessPostProcess, data1);
reader_pY->vpi_close(0, vpiAccessPostProcess, data2);

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文