Model Composer API for Programmatic Generation - 2023.2 English

Vitis Model Composer User Guide (UG1483)

Document ID
UG1483
Release Date
2023-11-15
Version
2023.2 English

Introduction

A script of Model Composer for programmatic generation (PG API script) is a MATLAB M-function file that builds a Model Composer Subsystem by instantiating and interconnecting xBlock, xSignal, xInport, and xOutport objects. It is a programmatic way of constructing Model Composer diagrams (for example, Subsystems). As is demonstrated below with examples, the top-level function of a Model Composer programmatic script is its entry point and must be invoked through an xBlock contructor. Upon constructor exit, MATLAB adds the corresponding Model Composer Subsystem to the corresponding model. If no model is opened, a new untitled model is created and the Model Composer Subsystem is inserted into it.

The xBlock constructor creates an xBlock object. The object can be created from a library block or it can be a Subsystem. An xSignal object corresponds to a wire that connects a source block to a target. An xInport object instantiates a Simulink Inport and an xOutport object instantiates a Simulink Outport.

The API also has one helper function, xlsub2script which converts a Simulink diagram to a programmatic generation script.

The API works in three modes: learning mode, production mode, and debugging mode. The learning mode allows you to type in the commands without having a physical script file. It is very useful when you learn the API. In this mode, all blocks, ports and Subsystems are added into a Simulink model named untiled. Please remember to run xBlock without any argument or to close the untitled model before starting a new learning session. The production mode has an M-function file and is invoked through the xBlock constructor. You will have a Subsystem generated. The Subsystem can be either in the existing model or can be inserted in a new model. The debugging mode works the same as the production mode except that every time a new object is created or a new connection is established, the Simulink diagram is rerouted. It is very useful when you debug the script that you set some break points in the script or single step the script.

xBlock

The xBlock constructor creates an xBlock object. The object can be created from a library block or it can be a Subsystem. The xBlock constructor can be used in three ways:

  • to add a leaf block to the current Subsystem,
  • to add a Subsystem to the current Subsystem,
  • to attach a top-level Subsystem to a model.

The xBlock takes four arguments and is invoked as follows.

block = xBlock(source, params, inports, outports);

If the source argument is a string, it is expected to be a library block name. If the source block is in the xbsIndex_r4 library or in the Simulink built-in library, you can use the block name without the library name. For example, calling xBlock('AddSub', ...) is equivalent to xBlock('xbsIndex_r4/AddSub',...). For a source block that is not in the xbsIndex_r4 library or built-in library, you need to use the full path, for example, xBlock('xbsTest_r4/Assert Relation', ...). If the source argument is a function handle, it is interpreted as a PG API function. If it is a MATLAB struct, it is treated as a configuration struct to specify how to attach the top-level to a model.

The params argument sets up the parameters. It can be a cell array for position-based binding or a MATLAB struct for name-based binding. If the source parameter is a block in a library, this argument must be a cell array. If the source parameter is a function pointer, this argument must be a cell array.

The inports and outports arguments specify how Subsystem input and output ports are bound. The binding can be a cell array for position-based binding or a MATLAB struct for name-based binding. When specifying an inport/outport binding, an element of a cell array can be an xSignal, an xInport, or an xOutport object. If the port binding argument is a MATLAB struct, a field of the struct is a port name of the block, a value of the struct is the object that the port is bound to.

The two port binding arguments are optional. If the arguments are missing when constructing the xBlock object, the port binding can be specified through the bindPort method of an xBlock object. The bindPort method is invoked as follows:

block.bindPort(inports, outports)

where inports and outports arguments specify the input and output port binding. In this case, the object block is create by xBlock with only two arguments, the source and the parameter binding.

Other xBlock methods include the following.

  • names = block.getOutportNames returns a cell array of outport names.
  • names = block.getInportNames returns a cell array of inport names.
  • nin = block.getNumInports returns the number of inports.
  • nout = block.getNumoutports returns the number of outports.
  • insigs = block.getInSignals returns a cell array of in coming signals.
  • outsigs = block.getOutSignals returns a cell array of out going signals.

xInport

An xInport object represents a Subsystem input port.

The constructor

port = xInport(port_name)

creates an xInport object with name port_name,

[port1, port2, port3, ...] = xInport(name1, name2, name2, ...)

creates a list of input port with names, and

port = xInport

creates an input port with an automatically generated name.

An xInport object can be passed for port binding.

METHODS

outsigs = port.getOutSignals

returns a cell array of out going signals.

xOutport

An xOutport object represents a Subsystem output port.

The constructor

port = xOutport(port_name)

creates an xOutport object with name port_name,

[port1, port2, port3, ...] = xOutport(name1, name2, name2, ...)

creates a list of output port with names, and

port = xOutport

creates an output port with an automatically generated name.

An xOutport object can be passed for port binding.

METHODS

port.bind(obj)

connects the object to port, where port is an xOutport object and obj is an xSignal or xInport object.

insigs = port.getInSignals

returns a cell array of incoming signals.

xSignal

An xSignal represents a signal object that connects a source to targets.

The constructor

sig = xSignal(sig_name)

creates an xSignal object with name sig_name,

[sig1, sig2, sig3, ...] = xSignal(name1, name2, name2, ...)

creates a list of signals with names, and

sig = xSignal

creates an xSignal for which a name is automatically generated.

An xSignal object can be passed for port binding.

METHODS

sig.bind(obj)

connects the obj to sig, where sig is an xSignal object and obj is an xSignal or an xInport object.

src = sig.getSrc

returns a cell array of the source objects that are driving the xSignal object. The cell array can have at most one element. If the source is an input port, the source object is an xInport object. If the source is an output port of a block, the source object is a struct, having two fields block and port. The block field is an xBlock object and the port field is the port index.

dst = sig.getDst

returns a cell array of the destination objects that the xSignal object is driving. Each element can be either a struct or an xOutport object. It is defined same as the return value of the getSrc method.

xlsub2script

xlsub2script is a helper function that converts a Subsystem into the top level of a Sysgen script.

xlsub2script(Subsystem) converts the Subsystem into the top-level script. The argument can also be a model.

By default, the generated M-function file is named after the name of the Subsystem with white spaces replaced with underscores. Once the xlsub2script finishes, a help message will guide you how to use the generated script. The main purpose of this xlsub2script function is to make learning Sysgen Script easier. This is also a nice utility that allows you to construct a Subsystem using graphic means and then convert the Subsystem to a PG API M-function.

xlsub2script(block), where block is a leaf block, prints out the xBlock call that creates the block.

The following are the limitations of xlsub2script.

  • If the Subsystem has mask initialization code that contains function calls such as gcb, set_param, get_param, add_block, and so on, the function will error out and you must modify the mask initialization code to remove those Simulink calls.
  • If there is an access to global variables inside the Subsystem, you need add corresponding mask parameters to the top Subsystem that you run the xlsub2script.
  • If a block’s link is broken, that block is skipped.

xlsub2script can also be invoked as the following:

xlsub2script(subsyste, options)

where options is a MATLAB struct. The options struct can have two fields: forcewrite, and basevars.

If xlsub2script is invoked for the same Subsystem the second time, xlsub2script will try to overwrite the existing M-function file. By default, xlsub2script will pop up a question dialog asking whether to overwrite the file or not. If the forcewrite field of the options argument is set to be true or 1, xlsub2script will overwrite the M-function file without asking.

Sometimes a Subsystem is depended on some variables in the MATLAB base workspace. In that case, when you run xlsub2script, you want xlsub2script to pick these base workspace variables and generate the proper code to handle base workspace variables. The basevars field of the options argument is for that purpose. If you want xlsub2script to pick up every variable in the base workspace, you need to set the basevars field to be 'all'. If you want xlsub2script to selectively pick up some variables, you can set the basevars field to be a cell array of strings, where each string is a variable name.

The following are examples of calling xlsub2script with the options argument:

xlsub2script(Subsystem, struct('forcewrite', true));
xlsub2script(Subsystem, struct('forcewrite', true, 'basevars', 

 'all'));
options.basevars = {'var1', 'var2', 'var3');
xlsub2script(Subsystem, options);
xlsub2script(Subsystem, struct('basevars', {{'var1', 'var2', 

 'var3'}}));

In MATLAB, if the field of a struct is a cell array, when you call the struct() function call, you need the extra {}.

xBlockHelp

xBlockHelp(<block_name>) prints out the parameter names and the acceptable values for the corresponding parameters. When you execute xBlockHelp without a parameter, the available blocks in the xbsIndex_r4 library are listed.

For example, when you execute the following in the MATLAB command line:

xBlockHelp('AddSub')

You'll get the following table in the transcript:

'xbsIndex_r4/AddSub' Parameter Table

Parameter              Acceptable value        Type
============           ==================      ========
mode                   'Addition'              String
                       'Subtraction'           
                       'Addition or Subtraction' 
------------           ------------------      --------
use_carryin            'off'                   String
                       'on'                    
------------           ------------------      --------
use_carryout           'off'                   String
                       'on'                    
------------           ------------------      --------
en                     'off'                   String
                       'on'                    
------------           ------------------      --------
latency                An Int value            Int
------------           ------------------      --------
precision              'Full'                  String
                       'User Defined'          
------------           ------------------      --------
arith_type             'Signed  (2's comp)'    String
                       'Unsigned'              
------------           ------------------      --------
n_bits                 An Int value            Int
------------           ------------------      --------
bin_pt                 An Int value            Int
------------           ------------------      --------
quantization           'Truncate'              String
                       'Round  (unbiased: +/- Inf)' 
------------           ------------------      --------
overflow               'Wrap'                  String
                       'Saturate'              
                       'Flag as error'         
------------           ------------------      --------
use_behavioral_HDL     'off'                   String
                       'on'                    
------------           ------------------      --------
pipelined              'off'                   String
                       'on'                    
------------           ------------------      --------
use_rpm                'off'                   String
                       'on'                    
------------           ------------------      --------