Main Content

Testbench and Component Function Writing

Writing Functions Using the HDL Instance Object

This section explains how you use the use_instance_obj argument for MATLAB® functions matlabcp and matlabtb. This feature replaces the iport, oport, tnext, tnow, and portinfo arguments of the MATLAB function definition. Instead, an HDL instance object is passed to the function as an argument. With this feature, matlabcp and matlabtb function callbacks get the HDL instance object passed in: to hold state, provide read/write access protection for signals, and allow you to add state as desired.

With this feature, you gain the following advantages:

  • Use of the same MATLAB function to represent behavior for different instances of the same module in HDL without need to create one-off wrapper functions.

  • No need for special portinfoargument on first invocation.

  • No need to use persistent or global variables.

  • Better feedback and protections on reading/writing of signals.

  • Use of object fields to identify the instance path and whether the call comes from a component or testbench function.

  • Use of the field argument to pass user-defined arguments from the matlabcp or matlabtb instantiation on the HDL side to the function callbacks.

The use_instance_obj argument is identical for both matlabcp and matlabtb. You include the -use_instance_obj argument with matlabcp or matlabtb in the following format:

matlabcp modelname -mfunc funcname -use_instance_obj

When you use use_instance_obj, HDL Verifier™ passes an HDL instance object to the function specified with the -mfunc argument. The function called has the following signature:

function MyFunctionName(hdl_instance_obj)

The HDL instance object, hdl_instance_obj, has the fields shown in the following table.

FieldRead/Write AccessDescription
tnextWrite only

Used to schedule a callback during the set time value. This field is the same as tnext in the old portinfo structure. For example:

hdl_instance_obj.tnext = hdl_instance_obj.tnow + 5e-9

This line of code schedules a callback at time = 5 nanoseconds from tnow.

userdataRead/WriteStores state variables of the current matlabcp instance. You can retrieve the variables the next time the callback of this instance is scheduled.
simstatusRead only

Stores the status of the HDL simulator. The HDL Verifier software sets this field to 'Init' during the first callback for this particular instance and to 'Running' thereafter. This field value is a read-only property.

>> hdl_instance_obj.simstatus

ans=
      Init
instanceRead only

Stores the full path of the Verilog®/VHDL® instance associated with the callback. instance is a read-only property. The value of this field equals that of the module instance specified with the function call. For example:

In the HDL simulator:

hdlsim> matlabcp osc_top -mfunc oscfilter use_instance_obj

In MATLAB:

>> hdl_instance_obj.instance

ans=
		osc_top
argumentRead only

Stores the argument set by the -argument option of matlabcp. For example:

matlabtb osc_top -mfunc oscfilter -use_instance_obj -argument foo
The verification software supports the -argument option only when you use it with -use_instance_obj, otherwise the argument is ignored. argument is a read-only property.
>> hdl_instance_obj.argument

ans= 
    	foo

portinfoRead only

Stores information about the VHDL and Verilog ports associated with this instance. This field value is a read-only property, which has a field structure that describes the ports defined for the associated HDL module. For each port, the portinfo structure passes information such as the port’s type, direction, and size. For more information on port data, see Gaining Access to and Applying Port Information.

hdl_instance_obj.portinfo.field1.field2.field3

Note

When you use use_instance_obj, you access tscale through the HDL instance object. If you do not use use_instance_obj, you can still access tscale through portinfo.

tscaleRead only

Stores the resolution limit (tick) in seconds of the HDL simulator. This field value is a read-only property.

>> hdl_instance_obj.tscale

ans=
	1.0000e-009

Note

When you use use_instance_obj, you access tscale through the HDL instance object. If you do not use use_instance_obj, you can still access tscale through portinfo.

tnowRead only

Stores the current time. This field value is a read-only property.

hdl_instance_obj.tnext = hld_instance_obj.tnow + fastestrate;

portvaluesRead/Write

Stores the current values of and sets new values for the output and input ports for a matlabcp instance. For example:

>> hdl_instance_obj.portvalues

ans =
Read Only Input ports:
	clk_enable: []
	clk: []
	reset: []
Read/Write Output ports:
	sine_out: [22x1 char]

linkmodeRead only

Stores the status of the callback. The HDL Verifier software sets this field to 'testbench' if the callback is associated with matlabtb and 'component' if the callback is associated with matlabcp. This field value is a read-only property.

>> hdl_instance_obj.linkmode

ans=
	component

Example: Using matlabcp and the HDL Instance Object

In this example, the HDL simulator makes repeated calls to matlabcp to bind multiple HDL instances to the same MATLAB function. Each call contains -argument as a constructor parameter to differentiate behavior.

> matlabcp u1_filter1x -mfunc osc_filter -use_instance_obj -argument "oversample=1"
> matlabcp u1_filter8x -mfunc osc_filter -use_instance_obj -argument "oversample=8"
> matlabcp u2_filter8x -mfunc osc_filter -use_instance_obj -argument "oversample=8"

The MATLAB function callback, osc_filter.m, sets up user instance-based state using obj.userdata, queries port and simulation context using other obj fields, and uses the passed in obj.argument to differentiate behavior.

function osc_filter(obj)
  if (strcmp(obj.simstatus,'Init'))
    ud = struct('Nbits', 22, 'Norder', 31, 'clockperiod', 80e-9, 'phase', 1));
    eval(obj.argument);
    if (~exist('oversample','var'))
        error('HdlLinkDemo:UseInstanceObj:BadCtorArg', ...
        'Bad constructor arg to osc_filter callback. Expecting 
					''oversample=value''.');
    end
    ud.oversample        = oversample;
    ud.oversampleperiod  = ud.clockperiod/ud.oversample;
    ud.InDelayLine       = zeros(1,ud.Norder+1);

    centerfreq = 70/256;
    passband   = [centerfreq-0.01, centerfreq+0.01];
    b          = fir1((ud.Norder+1)*ud.oversample-1, passband./ud.oversample);
    ud.Hresp             = ud.oversample .* b;

    obj.userdata = ud;
  end

...

Writing Functions Using Port Information

MATLAB Function Syntax and Function Argument Definitions

The syntax of a MATLAB component function is

function [oport, tnext] = MyFunctionName(iport, tnow, portinfo)

The syntax of a MATLAB testbench function is

function [iport, tnext] = MyFunctionName(oport, tnow, portinfo)

The input/output arguments (iport and oport) for a MATLAB component function are the reverse of the port arguments for a MATLAB testbench function. That is, the MATLAB component function returns signal data to the outputs and receives data from the inputs of the associated HDL module.

For more information on using tnext and tnow for simulation scheduling, see Schedule Component Functions Using the tnext Parameter.

The following table describes each of the testbench and component function parameters and the roles they play in each of the functions.

ParameterTestbenchComponent
iportOutput
Structure that forces (by deposit) values onto signals connected to input ports of the associated HDL module.
Input
Structure that receives signal values from the input ports defined for the associated HDL module at the time specified by tnow.
tnextOutput, optional
Specifies the time at which the HDL simulator schedules the next callback to MATLAB. tnext should be initialized to an empty value ([]). If tnext is not later updated, no new entries are added to the simulation schedule.
Output, optional
Same as testbench.
oportInput
Structure that receives signal values from the output ports defined for the associated HDL module at the time specified by tnow.
Output
Structure that forces (by deposit) values onto signals connected to output ports of the associated HDL module.
tnowInput
Receives the simulation time at which the MATLAB function is called. By default, time is represented in seconds. For more information see Schedule Component Functions Using the tnext Parameter.
Same as testbench.
portinfoInput
For the first call to the function only (at the start of the simulation) , portinfo receives a structure whose fields describe the ports defined for the associated HDL module. For each port, the portinfo structure passes information such as the port's type, direction, and size.
Same as testbench.

If you are using matlabcp, initialize the function outputs to empty values at the beginning of the function as in the following example:

tnext = [];
oport = struct();

Note

When you import VHDL signals, signal names in iport, oport, and portinfo are returned in all capitals.

You can use the port information to create a generic MATLAB function that operates differently depending on the port information supplied at startup. For more information on port data, see Gaining Access to and Applying Port Information.

Oscfilter Function Example

The following code gives the definition of the oscfilter MATLAB component function.

function [oport,tnext] = oscfilter(iport, tnow, portinfo)

The function name oscfilter, differs from the entity name u_osc_filter. Therefore, the component function name must be passed in explicitly to the matlabcp command that connects the function to the associated HDL instance using the -mfunc parameter.

The function definition specifies all required input and output parameters, as listed here:

oportForces (by deposit) values onto the signals connected to the entity's output ports, filter1x_out, filter4x_out and filter8x_out.
tnextSpecifies a time value that indicates when the HDL simulator will execute the next callback to the MATLAB function.
iportReceives HDL signal values from the entity's input port, osc_in.
tnowReceives the current simulation time.
portinfoFor the first call to the function, receives a structure that describes the ports defined for the entity.

The following figure shows the relationship between the HDL entity's ports and the MATLAB function's iport and oport parameters (example shown is for use with ModelSim™).

Gaining Access to and Applying Port Information

HDL Verifier software passes information about the entity or module under test in the portinfo structure. The portinfo structure is passed as the third argument to the function. It is passed only in the first call to your ModelSim function. You can use the information passed in the portinfo structure to validate the entity or module under simulation. Three fields supply the information, as indicated in the next sample. The content of these fields depends on the type of ports defined for the VHDL entity or Verilog module.

portinfo.field1.field2.field3

The following table lists possible values for each field and identifies the port types for which the values apply.

HDL Port Information

Field...Can Contain...Which...And Applies to...
field1inIndicates the port is an input portAll port types
outIndicates the port is an output portAll port types
inoutIndicates the port is a bidirectional port All port types
tscaleIndicates the simulator resolution limit in seconds as specified in the HDL simulatorAll types
field2portnameIs the name of the portAll port types
field3type

Identifies the port type

For VHDL: integer, real, time, or enum

For Verilog: 'verilog_logic' identifies port types reg, wire, integer

All port types

right (VHDL only)

The VHDL RIGHT attribute

VHDL integer, natural, or positive port types

left (VHDL only)

The VHDL LEFT attribute

VHDL integer, natural, or positive port types

 size

VHDL: The size of the matrix containing the data

Verilog: The size of the bit vector containing the data

All port types
label

VHDL: A character literal or label

Verilog: the character vector '01ZX'

VHDL: Enumerated types, including predefined types BIT, STD_LOGIC, STD_ULOGIC, BIT_VECTOR, and STD_LOGIC_VECTOR

Verilog: All port types

The first call to the ModelSim function has three arguments including the portinfo structure. Checking the number of arguments is one way you can verify that portinfo was passed. For example:

if(nargin ==3)
 tscale  = portinfo.tscale;
end