Developing Workers

This section describes the aspects of the worker development process that is common across all types of workers and authoring models. Previous sections above described the files involved in worker development, including:

OCS XML files: component specifications, usually in ../specs

OPS XML files: protocol specifications, usually in ../specs

OWD XML files: worker descriptions

Worker Build Configuration files: XML files for specifying build configurations

Worker Source files: Programming language source code for the worker.

This section describes the development process using these files.

The worker development details for each authoring model are described in the document for each authoring model. Some authoring models (e.g. RCC) support creating a single binary file artifact that implements multiple workers. However, usually a single worker implementation is in its own subdirectory, which when compiled, results in a single binary file for each build configuration (combination target and parameter values).

Creating Workers

A worker is created in a component library using the ocpidev tool.

Creating an OpenCPI Worker

ocpidev create worker

Create an OpenCPI Worker.

Usage:

$ ocpidev create worker [OPTIONS] NAME

Arguments:

  • NAME: [required]

Options:

  • -p, --project Project: Specify the Project that the asset resides in.

  • -l, --library Library: Specify the Library that the asset resides in.

  • -S, --spec Component: Component spec to use.

  • -L, --language TEXT: Specify the source language for the worker being created.

  • --xml-include TEXT: Directory to search for XML include files. May be used more than once.

  • --include-dir TEXT: Directory to search for include files. May be used more than once.

  • --primitive-library TEXT: Primitive library asset depends on. May be used more than once.

  • --component-library TEXT: Component library asset depends on. May be used more than once.

  • --exclude-platform Platform: Do not allow building asset for specified platform. May be used more than once.

  • --only-platform Platform: Only allow building asset for specified platform. May be used more than once.

  • --exclude-target HDL Target: Do not allow building asset for specified HDL target. May be used more than once.

  • --only-target HDL Target: Only allow building asset for specified HDL target. May be used more than once.

  • -O, --other TEXT: Specify a source code file that is not included by default.

  • --static-prereq TEXT: Specify a prerequisite library to statically link.

  • --dynamic-prereq TEXT: Specify a prerequisite library to dynamically link.

  • --slave-worker TEXT: Create the RCC worker as a proxy for the specified slave worker.

  • --core TEXT: Specify an HDL primitive core on which the worker being created depends.

  • --help: Show this message and exit.

The authoring model is inferred from the <name>, using the suffix of the name as the authoring model. The optional <spec> argument specifies the name of the OCS file, normally without any directory indicated (expected to be in the ../specs directory). If <spec> is not specified, it is assumed to be <name>-spec.xml in the library’s specs directory. If the new worker will embed the component spec in its own OWD, then the <spec> argument can be set to none. While rare, some specialized workers will be the only implementation of a spec and there is no need for separate spec file.

The <language> is one of the programming languages allowed for the authoring model (e.g. c, or c++ for RCC, vhdl or verilog for HDL). If not mentioned, the default language for the authoring model will be used.

The ocpidev command is usually executed in the directory where the new worker’s directory will be created. Other options are fully described in The ocpidev Tool for Managing Assets topic.

Deleting an OpenCPI Worker

ocpidev delete worker

Delete an OpenCPI Worker.

Usage:

$ ocpidev delete worker [OPTIONS] [Worker]

Arguments:

  • [Worker]

Options:

  • -p, --project Project: Specify the Project that the asset resides in.

  • -l, --library Library: Specify the Library that the asset resides in.

  • -f, --force

  • --help: Show this message and exit.

When a worker is created, the worker’s XML and source language files are initially generated by ocpidev. Several internal files (not for user editing) are also placed in a gen/ subdirectory of the worker’s directory. When source files are compiled, the resulting binary files are placed in subdirectories named: target-<target>, where <target> is the platform the compilation is targeting. Cleaning a worker directory (via ocpidev clean) simply removes the gen and all target-* subdirectories. In almost all cases, files in the gen subdirectory should be considered read-only and not edited.

Creating a new worker creates initial versions of two files in the worker’s directory:

  1. the OWD XML file

  2. the skeleton source file

These are the files the developer can edit as necessary. Although frequently the OWD XML file does not need any further editing.

The initial source file is termed the skeleton, and is named

<worker-name>.<source-suffix>
  e.g.
xyz.c

It can be compiled, but has empty logic. The skeletal code allows the worker to be test-built even before any editing is done. Each authoring model describes how and where this skeleton source file should be edited and “filled out” with the logic that makes it perform its intended function. A copy of this initial skeleton file is always put in the gen subdirectory, with the name:

gen/<worker-name>-skel.<source-suffix>
  e.g.
gen/xyz-skel.c

This copy can always be examined to see what the skeleton was originally, before any editing. It can also be useful to examine, after the OCS, OPS, or OWD has changed, in case changes are require in the source file. After the initial skeleton (not the copy in gen/) is edited by the developer, it will never be overwritten or removed by ocpidev clean or any other command.

Editing Workers

Often it is useful to break the worker’s logic into supporting code modules in other source files. Those files must be created manually and added to the SourceFiles attribute in the OWD. In some authoring models and languages, the files listed in the SourceFiles attribute must be in dependency order, with lower level modules/files preceding those that depend on them. The primary source file is always considered the top level module for the worker and is put at the end of the list automatically.

Some changes to the OWD, OCS, and OPS files can result in changes that require corresponding changes in the worker’s primary source file, which was initially generated as a skeleton. Since the developer has likely manually edited the primary source file, it is not touched when such changes are required. If it is clear to the developer when these changes are required, they can do it before any building. However, it is likely that the required changes will create build/compilation errors.

Examples would be such things are renaming ports or properties, adding or subtracting access attributes to properties, converting properties to parameters, etc.

When any changes are made, the skeleton is regenerated properly during the next build, and the result places in the file:

gen/<worker>-skel.<source-suffix>

The newly generated skeleton can be used as a guide when changes occur that might require changes in the edited worker source code.

The authoring model documents also list common changes to the OCS, OPS, and OWD files, and the corresponding changes required in the source file. An example is for VHDL workers using the HDL authoring model. The skeleton lists the lower level primitive libraries that the worker depends on. If such a primitive library is added to the worker XML file, the library also needs to be added to the list of libraries in the skeleton.

Advanced Worker Attributes

The OWD format supports advanced attributes for workers that need special build configurations or dynamic code generation. These attributes are optional and typically only used in specialized situations.

configfiles Attribute

The configfiles attribute lets you specify additional XML files that provide build variables during the worker build process. You would use this when a worker needs non-default build configuration that can’t be expressed in the OWD alone. The files listed are paths relative to the worker’s directory.

Each configuration file contains <buildoption> elements that define variable names and their values. Here’s the basic format:

<config>
    <buildoption name="foo"  value="bar"/>
    <buildoption name="foo2" value="bar2" append="true"/>
    ...
</config>

The configuration files are processed in the order they appear in the configfiles list. If the same variable appears multiple times, the last value wins—unless a later occurrence uses the append="true" attribute, in which case the new value is appended to the previous one.

There’s an important distinction in how configuration files are processed based on their location. Files outside the gen/ directory are assumed to be manually written and are processed early in the build—when ocpigen processes the {worker}-build.xml file to produce gen/{worker}.mk. Files inside gen/ are treated as generated content and aren’t processed until after any pre-build scripts have run, resulting in gen/config.mk.

Why the split? Some build variables depend on other variables being set first. For example, you can’t accurately set HdlExactPart without knowing HdlTarget or HdlTargets. By deferring gen/ configuration files until after pre-build scripts run, those dependencies have a chance to be resolved.

NOTE: Setting a build variable via configfiles will typically overwrite the previous value. The exception is SourceFiles when specified in a generated configuration file—the new value is appended instead. This allows using SourceFiles="_" at the top level for all files needed across any target, while a generated configuration file can add target-specific files as needed.

NOTE: Not all variables can be set by generated configuration files. Variables that have already been processed before pre-build scripts run cannot be changed at that stage. The limitations section lists which variables fall into this category.

prebuildscript Attribute

The prebuildscript attribute specifies one or more executable files that run before the worker is built. Each script should be executable with the appropriate shebang line at the start. You’d use pre-build scripts to dynamically generate code, integrate third-party IP, or set build variables based on external conditions.

When you specify a prebuildscript, the build system generates gen/build-variables.xml before running your scripts. This file exposes the current build variable values to your scripts so they can make informed decisions about what to generate. The format matches the configuration file format shown above (but without the append attribute):

<config>
    <buildoption name="foo" value="bar"/>
    <buildoption name="foo2" value="bar2"/>
    ...
</config>

The typical workflow combines prebuildscript with configfiles:

  1. Set configfiles="gen/{name}.xml" in the OWD

  2. Your pre-build script reads gen/build-variables.xml to see current variable values

  3. Your script writes new <buildoption> elements to gen/{name}.xml

  4. The build system processes the newly generated options

This pattern is useful when, for example, a script needs to discover available hardware resources or version information from an external tool and then pass that information into the build.

Limitations

Some build variables are processed before pre-build scripts run, which means a generated configuration file can’t modify them. If you try to set these in a pre-build script output, the change won’t take effect. This list includes:

  • ExcludePlatforms

  • ExcludeTargets

  • OnlyPlatforms

  • OnlyTargets

  • Libraries

  • IncludeDirs

  • Configurations

  • Containers

  • DefaultContainers

  • ParamConfigurations

  • HdlTarget

  • HdlTargets

  • HdlPlatform

  • RccTarget

  • RccPlatform

  • RccPlatforms

This list may not be exhaustive—if a variable controls early-stage build configuration, it’s safest to assume it can’t be changed by a generated configuration file.