Документация Engee

Возможности генератора кода

Внутренние функции в сгенерированном коде

Генератор кода Engee поддерживает виртуальные и атомарные подсистемы для генерации кода. Виртуальные подсистемы служат только для визуальной иерархии в модели, в то время как атомарные подсистемы представляют собой единый блок выполнения (или функцию в сгенерированном коде). Настройка в свойствах подсистемы Treat as atomic unit позволяет сделать подсистему виртуальной или атомарной.

Все вычисления внутри виртуальных подсистем встраиваются (инлайнятся) непосредственно в код объемлющей подсистемы или модели. Это может улучшить производительность сгенерированного кода, но ухудшить читаемость и трассируемость к модели.

Все вычисления внутри атомарных подсистем генерируются в отдельную функцию с именем подсистемы. Вызов этой функции затем осуществляется автоматически в коде объемлющей подсистемы или модели. Это может улучшить читаемость и трассируемость сгенерированного кода к модели, но ухудшить производительность.

Для примера, превратите RollMode из модели autopilot_roll.engee (см. Пример генерации кода) в атомарную подсистему:

RollMode атомарная подсистема

Сохраните модель и снова сгенерируйте код. В сгенерированном коде теперь появилась функция с именем RollMode (соответствующая имени подсистемы в модели). Эта функция вызывается внутри функции autopilot_roll_step, которая представляет код объемлющей модели. Функция RollMode объявлена как static и, таким образом, является внутренней функцией этой модели.

Генератор кода игнорирует отключенные блоки, и связанный с ними код не создается.

comment out 1

Параметры в сгенерированном коде

Параметры в блоках модели

В блоках модели параметры могут быть заданы:

  • В виде чисел (например, 0.2);

  • В виде выражений (например, 0.2 + 0.7);

  • В виде имен переменных из рабочего пространства Engee (например, Kp).

В сгенерированном коде параметры встраиваются (инлайнятся) с теми значениями, которые заданы в модели:

  • Простые численные значения добавляются в код «как есть», и дополнительных действий не требуется;

  • Выражения могут быть упрощены, и в коде окажется только конечное вычисленное значение;

Настраиваемые параметры

Некоторые параметры блоков могут быть сделаны настраиваемыми (tunable), чтобы их можно было изменять после генерации кода. Такие параметры сохраняются в структуре modelname_P, которая выглядит так:

  • Если параметр задан через имя переменной (например, Kp), то ее имя сохраняется в структуре:

    struct P_modelname_T_ {
        double Kp;
    };
  • Если параметр задан в виде выражения (например, Kp + 1), то используется название параметра (например, Amplitude):

    struct P_modelname_T_ {
        double Amplitude;
    };

Во всех случаях параметры в структуре modelname_P заполняются вычисленными значениями, доступными из модели, например:

P_modelname_T modelname_P = {
    0.5 // Значение параметра
};

С помощью опции Поведение параметров по умолчанию в окне настроек debug article icon 1 можно управлять тем, какие параметры останутся настраиваемыми в сгенерированном коде:

behavior setting 1

  • Встроенные (inlined) — числовые значения напрямую вставляются в сгенерированный код и не добавляются в структуру.

  • Настраиваемые (tunable) — параметры добавляются в структуру даже при числовых значениях.

Интерфейсы сгенерированного кода и интеграция во внешнюю среду разработки

Интерфейсы сгенерированного кода

Внешние интерфейсы сгенерированного кода можно увидеть в сгенерированном файле modelname.h. Внешние интерфейсы включают в себя функции и структуры для работы со сгенерированным кодом:

  • modelname_init — является функцией инициализации модели — должна вызываться однократно;

  • modelname_step — является точкой входа в модель и содержит алгоритм модели — должна вызываться периодически в соответствии с шагом расчета модели;

  • modelname_U — структура содержит внешние входные порты модели;

  • modelname_Y — структура содержит внешние выходные порты модели;

  • modelname_S — структура содержит внутренние состояния модели;

  • modelname_P — структура содержит настраиваемые параметры модели.

Интеграция во внешнюю среду разработки

Чтобы использовать функции и структуры сгенерированного файла modelname.h во внешнем коде (написанном вручную), нужно выполнить следующие действия:

  1. Подключить сгенерированный заголовочный файл:

    #include "modelname.h"
  2. Организовать однократный вызов сгенерированной функции init в своем main:

    modelname_init();
  3. Организовать периодический вызов сгенерированной функции step в своем main с нужным шагом:

    modelname_step();
  4. Организовать передачу входных и выходных данных в и из функции step:

    /* Устанавливаем значения входов */
    modelname_U.input1 = 42;
    /* Вызываем функцию step */
    modelname_step();
    /* Можно использовать modelname_Y.output1 */

Генерируемые файлы

После построения модели в Engee и генерации ее кода (с помощью команды engee.generate_code() или кнопки Сгенерировать код codegen icon 1) автоматически создаются генерируемые файлы, которые содержат реализацию модели на языке Си. Ниже приведено описание этих файлов и их назначения.

codegen all generated files

  • modelname.h — заголовочный файл, в котором описаны внешние интерфейсы модели. В его состав входят функции и структуры, необходимые для работы с моделью из внешнего кода (подробнее см. выше). Процесс подключения этих функций и структур к внешнему приложению также описан в разделе выше.

  • modelname.c — файл с реализацией логики модели. Содержит определения всех переменных и реализацию ключевых функций модели:

    • init() — функция инициализации, устанавливающая начальные значения переменных и состояний модели;

    • step() — основная вычислительная функция. Выполняет расчет одного шага симуляции и обновляет выходные значения;

    • term() — функция завершения работы модели.

  • model_data.c — файл с начальной инициализацией параметров модели. В нем задаются значения всех настраиваемых параметров, которые используются при выполнении модели. Например:

    • Амплитуда и частота сигнала;

    • Фаза, смещение;

    • Количество выборок и другие параметры.

      Эти глобальные параметры являются настраиваемыми и их можно менять во время работы исполняемого кода. Это позволяет гибко управлять поведением модели без необходимости пересборки логики или редактирования основных функций.

  • main.c — файл с примером использования модели. Это основной исполняемый файл, где показано, как инициализировать и вызывать модель из программы на языке Си. Содержит:

    • init() — функцию инициализации модели, вызывается один раз перед началом работы;

    • step() — основную вычислительную функцию, выполняющую один шаг расчета модели. Обычно вызывается периодически, в соответствии с заданным шагом интегрирования;

    • term() — функцию завершения работы модели.

      Файл main.c не содержит алгоритм работы модели, а лишь демонстрирует, как корректно запускать и управлять ее выполнением в приложении с поддержкой Си кода. main.c следует использовать как шаблон для интеграции модели в пользовательские проекты.

Поддерживаемые типы данных

Типы данных в сгенерированном коде соответствуют типам данных в модели Engee.

Если пользователь не задал тип данных в модели, то используется тип данных с плавающей точкой двойной точности, соответствующий типу double в Си. Для логических операций или вычислений, формирующих булевые результаты (true (1) или false (0)), используется тип данных boolean, соответствующий восьмибитному беззнаковому типу данных в Си.

Для отображения типов данных в модели, в окне настроек debug article icon 1 во вкладке «Отладка параметр» включите опцию Типы данных.

Векторизация

Генератор кода поддерживает векторные типы данных в моделях, включая вектора и матрицы. Для векторных операций в коде генерируются стандартные циклы for без вызовов специфических BLAS или LAPACK функций.

Комплексные числа

Генератор кода поддерживает комплексные типы данных в моделях. Для комплексных типов используются типы из стандартного заголовочного файла <complex.h>.

Многочастотные модели

Модели Engee могут быть многочастотными, то есть содержать несколько отличающихся частот дискретизации. Применяя блоки Переход между частотами дискретизации, а также задавая параметр Sample Time блоков и подсистем, пользователь может управлять тем, с каким шагом расчета работают блоки или группы блоков.

Генератор кода Engee поддерживает генерацию кода для многочастотных моделей. Для этого блоки группируются по частотам, и пользователь может управлять тем, в каком виде эти разные частоты представлены в сгенерированном коде.

Настройка Генерация многочастотного кода позволяет управлять режимом работы сгенерированного кода для многочастотной модели. «Однозадачный» код позволяет сгенерировать одну функцию step для модели. «Многозадачный» код позволяет сгенерировать несколько функций step для модели, каждая из которых соответствует определенной частоте дискретизации в модели.

Настройка генерации многочастотного кода

Однозадачный код содержит условия (в виде if) внутри сгенерированной функции step, которые оборачивают вызовы более медленных частот в модели. Функция step содержит блоки, работающие на базовой частоте модели (самой быстрой частоте). Из пользовательской обвязки достаточно обеспечить вызов функции step, при этом планирование вызовов более медленных частот и обмен информацией между частотами осуществляется автоматически в самом сгенерированном коде.

Многозадачный код содержит несколько функций step_N в сгенерированном коде, каждая из которых соответствует своей частоте в модели. Функция step_0 соответствует самой быстрой частоте в модели (базовой частоте), функция step_1 второй более медленной частоте и так далее. Из пользовательской обвязки требуется обеспечить вызов функций step_N с нужными шагами расчета. Взаимодействия по данным между различными частотами обеспечиваются автоматически в самом сгенерированном коде.

Комментарии в сгенерированном коде

По умолчанию в сгенерированном коде содержатся комментарии, позволяющие проследить код до блоков в модели.

Настройка Включить комментарии в панели Генерация кода позволяют управлять комментариями в сгенерированном коде и при необходимости отключить их полностью.

Верификация кода

Под верификацией понимается генерация проверочной модели с блоком Си функция, чьи результаты симуляции должны совпадать с результатами симуляции исходной модели при одинаковых входных данных.

Блок Си функция можно создать автоматически для верификации сгенерированного кода. Для этого поставьте галочку Генерировать блок C Function в окне настроек lk 5:

c function codegen

При следующей генерации кода (через интерфейс, контекстное меню или команду generate_code) в директории ouput_dir появится файл modelname_verification.jl (если директории не существует — она будет создана автоматически). Этот файл будет содержать скрипт, который можно выполнить в редакторе скриптов (двойным нажатием) interactive scripts icon или командной строке command line icon:

include("path/to/verification.jl")

Скрипт создаст модель Engee с именем modelname_verification.engee и блоком Си функция, который использует сгенерированный код:

model generated cfunction

В Engee также доступна генерация кода на языке Verilog, подробнее см. в статье Генерация Verilog (HDL) кода.

Генерация кода на основе пользовательских шаблонов

Engee поддерживает генерацию кода на основе пользовательских шаблонов (подробнее см. в статье Генерация кода на основе пользовательских шаблонов).

Управление именами сигналов

Генератор кода использует названия сигналов, заданные пользователем в модели, чтобы сделать сгенерированный код более понятным и легким для сопоставления с моделью. Например:

image14

Если сигнал (выход блока) имеет имя, то в сгенерированном коде для этого сигнала будет использоваться то же имя переменной. Это возможно, только если сигнал не был оптимизирован и не содержит символов, которые не поддерживаются в Си-коде.

Поддерживаемые блоки

Генератором кода Engee поддерживаются следующие библиотечные блоки: