Skip to content

POETSII/pml

Repository files navigation

POETS XML Generator (PML)

Content

Overview

This repository contains a tool (pml) for generating POETS XML files from higher-level descriptions.

Usage

Usage:
  pml.py [-p <name:value>...] <app.json> <file.graphml>

Options:
  -p, --param <name:value>  Specify a code generation parameter.

where app.json is an application configuration file and file.graphml is a graph in GraphML format.

Application Definition

The application configuration file (called app.json by convention) is a concise description of the application, specifying things such as message/state fields and documentation strings. An example is shown below:

{
    "type": "ro",
    "model": "simple",
    "doc": "Ring Oscillator",
    "messages": {
        "toggle": {
            "doc": "Toggle next node"
        }
    },
    "device": {
        "name": "node",
        "state": {
            "counter": {},
            "state": {}
        }
    }
}

This format is similar to the POETS XML schema but has three important differences:

  • It does not contain device instance or connectivity information (the problem graph). Graph instances are not considered part of pml application logic -- they are treated as a seperate input to the code generation process. This decoupling allows the same application to be combined with graphs of different sizes and topologies.

  • It does not contain handler code snippets. These are stored in separate .c files, so that they are more convenient to edit, and are included automatically during code generation.

  • In general, the format follows convention over configuration. For example, undeclared types are assumed uint32_t and handler code files must be placed in the same directory as the configuration file.

Features

Choice of Programming Model

In the above application file, the "model": "simple" entry defines this application as an instance of the simple model. pml supports different code generation models that provide slightly different programming interfaces. For example, simple applications contain a single device type that can send and receive all message types. The simple model makes it easier to develop these applications without having to worry about device types, pins or edges, all irrelevant details in this case.

pml does not only abstract away capabilities. Some models emulate behavior that is not directly supported by hardware (or the POETS XML schema) but is useful or convenient in some applications. For example, simple allows receive handlers to queue messages for delivery (using software buffers).

Templating and Introspection

pml model templates are in fact Jinja2 template XML files, inheriting all the capabilities of Jinja. Application handler files are imported as Jinja templates too, and are passed graph and application information through Jinja's context giving them poweful templating and introspective features.

To illustrate why this may be useful, consider the following snippet:

// File: print_msg.c

handler_log(2, "Content of %d message:", {{ msg_type }})

{%- set fields = messages[msg_type].get('fields', {}).keys() %}
{%- for field in fields %}
handler_log(2, "Field {{ field }} = %d", msg->{{ field }});
{% endfor %}

The above template can be re-used to dump the content of any message type, for example as in:

// File: receive_req.c

{{ include('print_msg.c', msg_type='req') }}

This is possible because the context of print_msg.c has access to the application's configuration (the messages dictionary in this case) so it can enumerate message fields during code generation. Graph information can be accessed in a similar way too, offering a convenient alternative to maintaining XML properties.

Installation

Requirements: Python 2 and pip.

To install using pip, run:

git clone https://github.com/POETSII/pml.git
pip install -r requirements.txt

or with pip and virtualenv:

git clone https://github.com/POETSII/pml.git
virtualenv env
source env/bin/activate
pip install -r requirements.txt

Documentation