Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

How to access module instances inside of generate loop from PLI (VPI) routine

Status
Not open for further replies.

pavel47

Member level 4
Joined
Nov 8, 2005
Messages
68
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,286
Location
Switzerland
Activity points
1,790
Hello,

While accessing simple module instances is quite simple, the same procedure for "module instances inside of generate loop" isn't so simple.
Here is module, where I want to access to module instance array:
Code:
`timescale 1us/1ns
`define reg_len 16

module Shift_REG(input Din, CLK, LOAD, [`reg_len-1:0] DATA_L, output Dout);
  wire [`reg_len-1:0] DATA;
  genvar i;
  
  assign Dout = DATA[`reg_len-1];
	
  initial begin
     #1 $module_explore;
   end
   
  DFF_wload U0(.D(Din), .CLK(CLK), .DL(DATA_L[0]), .LOAD(LOAD), .Q(DATA[0]));
	
  generate
    for (i = 0; i < `reg_len; i = i + 1) begin : Loop_DFF
      if(i == 0)
        DFF_wload U_DFF(.D(Din), .CLK(CLK), .DL(DATA_L[0]), .LOAD(LOAD), .Q(DATA[0]));
      else
        DFF_wload U_DFF(.D(DATA[i-1]), .CLK(CLK), .DL(DATA_L[i]), .LOAD(LOAD), .Q(DATA[i]));
    end
  endgenerate
endmodule

Here is VPI routine, I use:
Code:
//**********************************************************************

#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include "vpi_user.h"

PLI_INT32  PLI_Module_Explore_CallTF(PLI_BYTE8 *user_data);

/**********************************************************************
 * VPI Registration Data
 *********************************************************************/
void PLI_Module_Explore_RGSTR()
{
  s_vpi_systf_data tf_data;   /* allocate register data structure */
  tf_data.type      = vpiSysTask;
	tf_data.sysfunctype = 0;
  tf_data.tfname    = "$module_explore";
  tf_data.calltf    = PLI_Module_Explore_CallTF;
  tf_data.compiletf = NULL;
  tf_data.sizetf    = NULL;
	tf_data.user_data = NULL;
  vpi_register_systf(&tf_data);
}
/*********************************************************************/

PLI_INT32 PLI_Module_Explore_CallTF(PLI_BYTE8 *user_data)
{
	vpiHandle systf_handle, scope_handle;
	vpiHandle module_iterator, module_handle;
	vpiHandle module_arr_iterator, module_arr_handle;
	systf_handle = vpi_handle(vpiSysTfCall, NULL);
	scope_handle = vpi_handle(vpiScope, systf_handle);
	
	vpi_printf("\nScope is: %-10s\n", vpi_get_str(vpiName, scope_handle));
	
	if (vpi_get(vpiType, scope_handle) == vpiModule)
	{
    module_iterator = vpi_iterate(vpiModule, scope_handle);
    if (module_iterator != NULL)
		{
			vpi_printf("List of modules:\n");
			while ((module_handle = vpi_scan(module_iterator)) != NULL )
			{
				vpi_printf("\tModule Name: %-10s\n", vpi_get_str(vpiName, module_handle));
			}
		}
		else
			vpi_printf("\tThis scope doesn't contain modules\n");
			
		module_arr_iterator = vpi_iterate(vpiModuleArray, scope_handle);
    if (module_arr_iterator != NULL)
		{
			vpi_printf("List of modules arrays:\n");
			while ((module_arr_handle = vpi_scan(module_arr_iterator)) != NULL )
			{
				vpi_printf("\tModule Array Name: %-10s\n", vpi_get_str(vpiName, module_arr_handle));
			}
		}
		else
			vpi_printf("\tThis scope doesn't contain module arrays\n");
		
  }

  return(0);
}

And here is simulation output:
Code:
restart
# Loading D:\PROJ_ModelSim\PLI_LIB\mti_pli_apps.dll
# Refreshing D:\PROJ_ModelSim\PLI_Routines_Explore\work.Shift_REG
# Loading work.Shift_REG
run
# 
# Scope is: Shift_REG_TB
# List of modules:
# 	Module Name: U_DUT     
# 	This scope doesn't contain module arrays
# 
# Scope is: U_DUT     
# List of modules:
# 	Module Name: U0        
# 	This scope doesn't contain module arrays

As you can constate the modules inside of generate loop aren't revealed (scope U_DUT) ...

Any ideas ?

Regards.

Pavel.
 

You will also need to iterate over vpiGenScope and vpiGenScopeArray. You will need to make this recursive as each generate scope may also contain modules and module arrays, and each module scope may also contain other modules and generate scopes.
 

Hello Dave,

Thanks for response. Is there some example of using these constants. I've tried with both, but didn't succed to get handle to the generate statement instance.
Here is what I did:

Code:
		gen_scope_iterator = vpi_iterate(vpiGenScopeArray, scope_handle);
		if (gen_scope_iterator != NULL)
		{
			vpi_printf("List of generate statements:\n");
			while ((gen_scope_handle = vpi_scan(gen_scope_iterator)) != NULL )
			{
				vpi_printf("\tExpression: %-10s\n", vpi_get_str(vpiName, gen_scope_handle));
			}
		}
		else
			vpi_printf("\tThis scope doesn't contain generate statements\n");

In this case I've put vpiGenScopeArray in the expression that return handle, but I also tried with vpiGenScope. In both cases the output was the same:
Code:
# Scope is: Shift_REG_TB
# List of modules:
# 	Module Name: U_DUT     
# 	This scope doesn't contain module arrays
# 	This scope doesn't contain expressions
# 	This scope doesn't contain generate statements
# 
# Scope is: U_DUT     
# List of modules:
# 	Module Name: U0        
# 	This scope doesn't contain module arrays
# 	This scope doesn't contain expressions
# 	This scope doesn't contain generate statements

Regards.

Pavel.
 

generate_statement_diagram.JPGHere is extract from object diagram from IEEE 1364-2005 (Verilog Language Standard), related to generate statement.
As you can constate, the handle to the generate scope array can be obtained directly from the module handle (module, that contains this generate scope).
Probably I missed something, but in my case this logic (apparently evident) doesn't work.
Here is my VPI routine:
Code:
//**********************************************************************

#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include "vpi_user.h"

PLI_INT32  PLI_Module_Explore_CallTF(PLI_BYTE8 *user_data);

/**********************************************************************
 * VPI Registration Data
 *********************************************************************/
void PLI_Module_Explore_RGSTR()
{
  s_vpi_systf_data tf_data;   /* allocate register data structure */
  tf_data.type      = vpiSysTask;
	tf_data.sysfunctype = 0;
  tf_data.tfname    = "$module_explore";
  tf_data.calltf    = PLI_Module_Explore_CallTF;
  tf_data.compiletf = NULL;
  tf_data.sizetf    = NULL;
	tf_data.user_data = NULL;
  vpi_register_systf(&tf_data);
}
/*********************************************************************/

PLI_INT32 PLI_Module_Explore_CallTF(PLI_BYTE8 *user_data)
{
	vpiHandle systf_handle, scope_handle;
	vpiHandle module_iterator, module_handle;
	vpiHandle gen_scope_iterator, gen_scope_handle;
	vpiHandle gen_state_handle;
	vpiHandle module_with_generate_handle;
	
	systf_handle = vpi_handle(vpiSysTfCall, NULL);
	scope_handle = vpi_handle(vpiScope, systf_handle);
	
	vpi_printf("\nScope is: %-10s\n", vpi_get_str(vpiName, scope_handle));
	
	if (vpi_get(vpiType, scope_handle) == vpiModule)
	{
		// Get list of modules
    module_iterator = vpi_iterate(vpiModule, scope_handle);
    if (module_iterator != NULL)
		{
			vpi_printf("List of modules:\n");
			while ((module_handle = vpi_scan(module_iterator)) != NULL )
			{
				vpi_printf("\tModule Name: %-10s\n", vpi_get_str(vpiName, module_handle));
			}
		}
		else
			vpi_printf("\tThis scope doesn't contain modules\n");
		
[B]		module_with_generate_handle = vpi_handle_by_name("Shift_REG_TB.U_DUT", NULL);
		// Get list of generate statements
		gen_scope_iterator = vpi_iterate(vpiGenScope, module_with_generate_handle);
		if (gen_scope_iterator != NULL)
		{
			vpi_printf("List of generate statements:\n");
			while ((gen_scope_handle = vpi_scan(gen_scope_iterator)) != NULL )
			{
				vpi_printf("\tExpression: %-10s\n", vpi_get_str(vpiName, gen_scope_handle));
			}
		}
		else
			vpi_printf("\tThis scope doesn't contain generate statements\n");[/B]		
		gen_state_handle = vpi_handle_by_name("Shift_REG_TB.U_DUT.Loop_DFF[0]", NULL);
		if (gen_state_handle != NULL)
			vpi_printf("\nShift_REG_TB.U_DUT.Loop_DFF[0] type: %s", vpi_get_str(vpiType, gen_state_handle));
			
		gen_state_handle = vpi_handle_by_name("Loop_DFF[0]", scope_handle);
		if (gen_state_handle != NULL)
		{
			vpi_printf("\nLoop_DFF[0] type: %s", vpi_get_str(vpiType, gen_state_handle));
		}
  }

  return(0);
}

I've put in bold the peace of code that doesn't work.
Here is output of this routine:

Code:
# Scope is: U_DUT     
# List of modules:
# 	Module Name: U0        
# 	This scope doesn't contain generate statements
# 
# Shift_REG_TB.U_DUT.Loop_DFF[0] type: vpiGenScope
Loop_DFF[0] type: vpiGenScope

The instruction gen_scope_iterator = vpi_iterate(vpiGenScope, module_with_generate_handle); cannot obtain handle to the generate statement despite I explicitely specified the module name in the instruction, that return module handle.

Any ideas ?

Regards.

Pavel.
 

Are you able to solve this issue ? I'm running out into a similar problem where I need to iterate on generate blocks and after that again the vpi modules with gen blocks. If you can let me know how to access vpiGenScope from vpiModule vpiHandle it will be helpfull.

View attachment 84876Here is extract from object diagram from IEEE 1364-2005 (Verilog Language Standard), related to generate statement.
As you can constate, the handle to the generate scope array can be obtained directly from the module handle (module, that contains this generate scope).
Probably I missed something, but in my case this logic (apparently evident) doesn't work.
Here is my VPI routine:
Code:
//**********************************************************************

#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include "vpi_user.h"

PLI_INT32  PLI_Module_Explore_CallTF(PLI_BYTE8 *user_data);

/**********************************************************************
 * VPI Registration Data
 *********************************************************************/
void PLI_Module_Explore_RGSTR()
{
  s_vpi_systf_data tf_data;   /* allocate register data structure */
  tf_data.type      = vpiSysTask;
	tf_data.sysfunctype = 0;
  tf_data.tfname    = "$module_explore";
  tf_data.calltf    = PLI_Module_Explore_CallTF;
  tf_data.compiletf = NULL;
  tf_data.sizetf    = NULL;
	tf_data.user_data = NULL;
  vpi_register_systf(&tf_data);
}
/*********************************************************************/

PLI_INT32 PLI_Module_Explore_CallTF(PLI_BYTE8 *user_data)
{
	vpiHandle systf_handle, scope_handle;
	vpiHandle module_iterator, module_handle;
	vpiHandle gen_scope_iterator, gen_scope_handle;
	vpiHandle gen_state_handle;
	vpiHandle module_with_generate_handle;
	
	systf_handle = vpi_handle(vpiSysTfCall, NULL);
	scope_handle = vpi_handle(vpiScope, systf_handle);
	
	vpi_printf("\nScope is: %-10s\n", vpi_get_str(vpiName, scope_handle));
	
	if (vpi_get(vpiType, scope_handle) == vpiModule)
	{
		// Get list of modules
    module_iterator = vpi_iterate(vpiModule, scope_handle);
    if (module_iterator != NULL)
		{
			vpi_printf("List of modules:\n");
			while ((module_handle = vpi_scan(module_iterator)) != NULL )
			{
				vpi_printf("\tModule Name: %-10s\n", vpi_get_str(vpiName, module_handle));
			}
		}
		else
			vpi_printf("\tThis scope doesn't contain modules\n");
		
[B]		module_with_generate_handle = vpi_handle_by_name("Shift_REG_TB.U_DUT", NULL);
		// Get list of generate statements
		gen_scope_iterator = vpi_iterate(vpiGenScope, module_with_generate_handle);
		if (gen_scope_iterator != NULL)
		{
			vpi_printf("List of generate statements:\n");
			while ((gen_scope_handle = vpi_scan(gen_scope_iterator)) != NULL )
			{
				vpi_printf("\tExpression: %-10s\n", vpi_get_str(vpiName, gen_scope_handle));
			}
		}
		else
			vpi_printf("\tThis scope doesn't contain generate statements\n");[/B]		
		gen_state_handle = vpi_handle_by_name("Shift_REG_TB.U_DUT.Loop_DFF[0]", NULL);
		if (gen_state_handle != NULL)
			vpi_printf("\nShift_REG_TB.U_DUT.Loop_DFF[0] type: %s", vpi_get_str(vpiType, gen_state_handle));
			
		gen_state_handle = vpi_handle_by_name("Loop_DFF[0]", scope_handle);
		if (gen_state_handle != NULL)
		{
			vpi_printf("\nLoop_DFF[0] type: %s", vpi_get_str(vpiType, gen_state_handle));
		}
  }

  return(0);
}

I've put in bold the peace of code that doesn't work.
Here is output of this routine:

Code:
# Scope is: U_DUT     
# List of modules:
# 	Module Name: U0        
# 	This scope doesn't contain generate statements
# 
# Shift_REG_TB.U_DUT.Loop_DFF[0] type: vpiGenScope
Loop_DFF[0] type: vpiGenScope

The instruction gen_scope_iterator = vpi_iterate(vpiGenScope, module_with_generate_handle); cannot obtain handle to the generate statement despite I explicitely specified the module name in the instruction, that return module handle.

Any ideas ?

Regards.

Pavel.
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top