УДК 004

Разработка и тестирование виртуального прототипа сопроцессора FPU семейства процессоров MIPS32 с использованием SystemC и паттерна IoC

Гаврилова Дарья Александровна – студент-бакалавр Института микроприборов и систем управления имени Л.Н. Преснухина Национального исследовательского университета «Московский институт электронной техники».

Аннотация: Статья посвящена проблемам разработки виртуальных прототипов на SystemC. Рассмотрены уровни абстракции при моделировании и возможности библиотеки SystemC. Описана проблема невысокой реконфигурируемости модулей SystemC. Для ее решения был использован паттерн Инверсия Зависимостей (Inversion of Control). Для реализации этого паттерна на языке программирования C++, была разработана библиотека tiny_ioc. Эти решения позволяют упростить конфигурирование моделей на SystemC, а также их тестирование.

Ключевые слова: инверсия зависимостей, IoC, Service Locator, внедрение зависимостей, SystemC, уровни абстракции, виртуальный прототип.

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

Над созданием программного обеспечения для решения комплексных задач работают большие команды людей. Для настройки и отладки продукта необходима дорогостоящая аппаратура, но для большой группы людей это может стать затратным. Решением сокращения финансовых затрат является создание виртуального прототипа. Его задачей стоит заменить оборудование на заранее определенном уровне абстракции и увеличить возможности для отладки системы. Точность такой модели должна покрывать все потребности необходимые для последующей разработки ПО. Такое решение обеспечит множеству разработчиков доступ к отладке создаваемого кода.

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

Можно выделить следующие уровни абстракции:

  • Transaction-level model (TLM) – связь между модулями моделируется с помощью вызовов функций;
  • Register-transfer level (RTL) – внутренняя структура точно отражает регистры и последовательность логических операций.

Каждый из уровней определяются по таким параметрам как память, время, параллельность, конфигурируемость, связность. Каждый из параметров представляет собой ось, которая в свою очередь определяет степень абстракции своего параметра. Такая оценка обеспечивают полное представление функциональности модели во всех аспектах логического синтеза аппаратуры [1].

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

Языки программирования можно разделить на императивные (imperative) и декларативные (declarative) языки. Императивные языки сосредоточены на описании набора предписанных инструкций, которые должны быть выполнены. В то время как декларативные указывают что должно быть реализовано, но не способ реализации. В свою очередь первые делятся на алгоритмические подходы и архитектурное моделирование подходов.

Наиболее известным и широко используемым языком архитектурного моделирования являются библиотеки классов SystemC. Главное преимущество такого подхода – его можно использовать для разработки модели комплексных систем, реализующих как аппаратную, так и программную части сохраняя высокий уровень абстракции. Для определения уровня моделирования используются такие параметры точности как структура, время, функциональность, организация данных и протокол связи.

SystemC имеет открытый исходный код, что позволяет добавлять расширения, такие как классы, методы и подходы, известным как моделирование на уровне транзакций (TLM), которое было принято OSCI, организацией SystemC, и в конечном итоге будет стандартизировано IEEE [2]. В TLM коммуникация обычно моделируется таким образом, чтобы она была точной с точки зрения функциональности и часто с точки зрения синхронизации, но коммуникация не моделируется таким образом, чтобы она была структурно точной.

Базовый уровень SystemC предоставляет ядро моделирования, управляемое событиями. Это ядро работает с событиями и процессами абстрактным образом. Он знает только, как оперировать событиями и переключаться между процессами, не зная, что на самом деле представляют собой события или что делают процессы. Другие элементы систем включают модули и порты для представления структурной информации, а также интерфейсы и каналы в качестве абстракции для связи. Ядро и эти абстрактные элементы вместе образуют основной язык. Поверх этой языковой основы мы можем затем добавить более конкретные модели вычислений, библиотеки проектирования, руководства по моделированию и методологии проектирования, которые полезны для проектирования систем [3].

SystemC полностью построена на стандарте C++. Это означает, что любая программа, написанная на SystemC, может быть скомпилирована с помощью компилятора C++ для создания исполняемой программы. Наряду с основным языком существует набор типов данных, которые полезны для аппаратного моделирования и для определенных видов программного программирования.

Среди недостатков SystemC стоит отметить слабые возможности по реконфигурированию. Проблема состоит в том, все дочерние модули должны быть созданы в конструкторе родительского, иначе, они не попадут в иерархию. Помимо этого в SystemC нет возможностей для динамического реконфигурирования. Еще одним недостатком является сложность в тестировании. Дело здесь в том, что для проведения тестирования нужно легко заменять компоненты заглушками или макетами. Так в тестировании Float Point Unit (FPU) используется еще не реализованный Memory Management Unit (MMU). Этот модуль отвечает за управление доступом к памяти, преобразовывает виртуальную память в физическую. В тестах необходимо использовать класс MMU, для полной проверки корректной работы системы, он используется с помощью заглушки.

На рынке существует множество вариаций процессоров MIPS c различным набором компонентов, чтобы избавиться от дублирования кода и упростить конфигурацию моделей необходима такая система, которая делала бы это за нас. С этим может помочь принцип инверсии зависимостей (Inversion of Control).

Принцип IoC заключается в разделении компонентов системы. Разорвав зависимости межу модулями верхнего и нижнего уровня, мы увеличим гибкость кода. IoC слишком общий термин, под ним выделяют два метода реализации. Service Locator заключается в том, чтобы знать как получить доступ к другим сервисам, но он не создает объекты. Иначе говоря, фактически содержит созданные экземпляры класса. Его можно разделить на статический, в котором класс имеет метод для каждого необходимого сервиса, и динамический, который позволяет поместить в него любой сервис и менять его во время выполнения. Dependency Injection представляет собой объект, который реализует внедрение зависимостей. Можно выделить 3 вида реализации:

  • container injection – внедрение проходит через конструктор класса, в котором создаваемый аргумент и является зависимостью;
  • setter injection – использует set-метод в классе для установления зависимости;
  • interface injection – подобен setter injection, с отличием в том, что класс куда внедрятся зависимость, наследуется от интерфейса, который обязует класс реализовать данный set-метод [4].

Существует реализация паттерна инверсии зависимостей Hypodermic. Она основанная на методе Dependency Injection и использует Boost (собрании библиотек классов). Но есть потребность избавится от зависимости Boost и уменьшить размеры библиотеки IoC.

Разрабатывается модель процессора на базе архитектуры MIPS32 (рис. 1). В него входит сопроцессор FPU (float point unit). Он необходим для ускорения работы операций с плавающей запятой. Этого можно достичь за счет специализированных регистров для записи и чтения вещественных чисел и математических операции выполняемых одной командой.

1

Рисунок 1. Внутренняя структурная схема процессора.

Чтобы использовать библиотеку tiny_ioc необходимо унаследовать интерфейсы-наследники от класса IoCInterface.

class IFPUExceptionController:

public virtual IoCInterface

{

//реализация интерфейса

};

Фабрика для создания компонента принимает указатели на необходимые интерфейсы и возвращает умный указатель компонента:

std::shared_ptr<IoCInterface> create_FPU(const

std::shared_ptr< IFPUExceptionController>

&exception_controller){

auto fpu = std::shared_ptr<FPU>();

fpu->exception_controller.bind

(exception_controller);

return std::shared_ptr<IoCInterface> object;

}

Далее идёт регистрация фабрик в IoC-контейнере. Фабрики делятся на низкоуровневые и высокоуровневые. Низкоуровневая фабрика принимает в качестве параметра указатель на интерфейс, а возвращает умный указатель на объект. Отличие высокоуровневой в принятии умных указателей на зависимости. После сборки IoC-контейнера можно использовать зарегистрированные компоненты.

IOCContainerBuilder builder;

builder.registerType(createFPU).as<FPU>;

std::shared_ptr<IoCContainer>ioc_container =

builder.build();

ioc_container->provide

<IFPUExceptionController>

(exception_controller);

//использование createFPU

m_container->resolve<FPU>();

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

Список литературы

  1. Bailey B., Martin G. ESL Models and Their Application: Electronic
    System Level Design and Verification in Practice. Springer Science &
    Business Media, 2009. 446 p.
  2. Black D. C., Donovan J., Bunton B., Keist A. SystemC: from the Ground Up Springer Science & Business Media, 2010. 279 p.
  3. Grötker T. et al. System Design with SystemC™. Springer Science &
    Business Media, 2007. 219 p.
  4. Fowler, M. Inversion of Control Containers and the Dependency Injection pattern / M. Fowler. – Текст : электронный // martinfowler.com: [сайт]. – URL: https://martinfowler.com/articles/injection.html (дата обращения: 15.12.2022).

Интересная статья? Поделись ей с другими: