Подписка на новости

Опрос

Нужны ли комментарии к статьям? Комментировали бы вы?

Реклама

 

2002 №9

Использование языков программирования С или С++ для HDL описания – будущий стандарт или неудачный эксперимент?

Емец Сергей


Существует ли универсальный язык программирования, пригодный как для описания поведенческих моделей системы, так и для эффективного описания «железа» и программ, работающих на этом «железе»? Возможно ли для всего цикла разработки встраиваемой системы использовать единый язык программирования? В статье рассматривается существующая реализация такого языка - SystemC. Приведены примеры описания генератора ПСП на С, SystemC, Verilog HDL.

Введение

При разработке сложных электронных систем, как, например, SoC — система на кристалле возникает необходимость разработки программной и аппаратной части. При этом, как правило, в начале разрабатывается модель системы, которая описывает поведение системы на верхнем структурном уровне. Эта модель служит для проверки заложенных в систему алгоритмов и совместно с моделями физических уровней (радиолинии, проводной связи, объекта управления и т. п.) используется для моделирования всей системы. В настоящее время из-за своей популярности и универсальности для программного моделирования широко используется язык С++. После завершения моделирования система разбивается на аппаратную и программную составляющие и разработка ведется по двум направлениям. Для описания аппаратной части проекта используются языки описания «железа» (HDL): Verilog или VHDL (также могут использоваться низкоуровневые языки HDL и схематический ввод). В результате такого подхода возникает проблема связи между исходной поведенческой моделью верхнего уровня и более детальным описанием «железной» части проекта, теряется возможность моделировать весь проект целиком, и последующие изменения в аппаратной части либо повторяются в высокоуровневой модели (требуется удвоенное время на внесение изменений как в HDL, так и в C++ модель), либо высокоуровневая модель устаревает и не используется. После разработки аппаратной части требуется полностью переписывать программную часть, так как система должна работать в реальном времени и пользоваться специфическими возможностями RTOS (многозадачность, прерывания, детерминированное время отклика), также возможно, что реальная аппаратная часть сильно отличается от исходной модели. Возникает необходимость в универсальном языке программирования, пригодном как для описания повенденческих моделей системы, так и для описания «железа» и программ, работающих на этом «железе». Таким образом, «программа максимум» заключается в реализации программного средства, объединяющего все этапы разработки — от модели верхнего уровня до готового продукта.

В качестве начального шага («программа минимум») можно рассматривать разработку языка, позволяющего описывать «железо» используя синтаксис, С/С++. Такой шаг позволит упростить разработку аппаратуры за счет того, что разработчику не придется изучать специальный язык HDL. А при наличии поведенческой модели на С++ возможно использование готового кода с минимальными изменениями.

В статье основное внимание направлено на исследование возможности использования С/С++ в качестве языка HDL, но также рассматривается возможность построения единой системы разработки от модели до продукта с использованием единого универсального языка. Для иллюстрации классического подхода к разработке аппаратуры приведен пример синтезируемого описания на Verilog совместно с «тестовым стендом» (testbench).

Обзор средств, существующих в настоящее время

Развитие использования С/С++ для описания архитектуры в настоящее время идет по двум направлениям:

  1. разработка библиотек на С++ — SystemC (www.systemc.org) и Cynlib (www.ForteDS.com), которые должны использоваться совместно со стандартным компилятором С++;
  2. разработка специального языка, основанного на синтаксисе ANSI C и имеющего специальные конструкции для моделирования «железа» — Handel C (www.celoxica.com) и SpecC (www.specc.org).

Концептуально библиотеки гораздо лучше удовлетворяют требованиям, сформулированным во введении. Такой подход дает реальный шанс реализовать «программу максимум» — программное средство для ведения проекта от модели до изделия, также это достаточно удачный первый шаг — альтернатива языкам HDL. К минусам таких библиотек я отношу достаточно сложный синтаксис языка С++.

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

Библиотеки SystemC распространяются свободно и, следовательно, для симуляции потребуется только компилятор С++ (поддерживается свободный GCC, а для Windows — либо GCC+cygwin, либо Microsoft VC++). Крупные фирмы Cadence, Synopsys поддерживают SystemC. Synopsys предлагает в настоящее время средство RTL-синтеза описаний SystemC, поддерживающее синтезируемое подмножество языка, и обещает реализовать поведенческий синтез («behavioral synthesis»). Существуют свободные средства, транслирующие описание на VHDL в описание на SystemC.

Cynlib также является свободной библиотекой, во многом подобной SystemC, но синтаксис описания аппаратуры более сложный. Для упрощения предлагается препроцессор Cyn++, который транслирует конструкции, похожие на Verilog HDL, в Cynlib. На основе GDB предлагается отладчик, работающий с конструкциями Cynlib. Для синтеза предлагается коммерческий продукт Cynthesizer, который транслирует исходник С++ (Cynlib) в описание Verilog/VHDL. Также есть средство, выполняющее преобразование из Verilog/VHDL в С++ c использованием Cynlib. В последние версии Cynlib включена поддержка SystemC.

Разработка новых языков (основанных на ANSI C) менее поддерживается разработчиками коммерческого и свободного программного обеспечения, так как требуется не только средство синтеза, но и симулятор. То есть принципиального выигрыша по сравнению с Verilog/VHDL в данном случае нет. Плюсом данного подхода, по сравнению с использованием библиотек С++, является простота синтаксиса и легкость изучения языка. Целесообразность замены существующих языков описания аппаратуры новыми кажется сомнительной — функциональность языка такая же, как и в Verilog/VHDL, а отличия от С значительны. При моделировании системы, часть которой описана на С, я не вижу выигрыша от использования такого языка и связки Verilog + PLI.

Следует заметить, что применяются и другие подходы для объединения разработки программной и аппаратной части проекта одним универсальным языком. Например, JHDL на основе Java. Но разработка этих проектов находится в зачаточной стадии и использование любого другого объектно-ориентированного языка, кроме С++, не имеет в настоящее время выигрыша перед SystemC или Cynlib.

Таким образом, наиболее заслуживающим внимания направлением является SystemC. Значительным плюсом свободно распространяемой библиотеки можно считать то, что для моделирования системы не нужны коммерческие продукты. То есть дорогостоящие симуляторы, требующиеся для моделирования описаний на Verilog/VHDL, не требуются для симуляции модели SystemC.

Краткое описание возможностей SystemC

Изначально библиотека разрабатывалась для реализации полного цикла разработки, начиная от модели системы и физических объектов и заканчивая моделью RTOS и аппаратной части. Так же, как и для других высокоуровневых языков HDL, для синтеза может быть использован только ограниченный набор конструкций языка. Для того чтобы ознакомиться с этим подмножеством, лучше всего воспользоваться описанием синтеза с SystemC от Synopsys (http://www.synopsys.com/products/cocentric_systemC/cocentric_systemC.html). Особенно полезен документ, описывающий синтезируемое подмножество языка Describing Synthesizable RTL in SystemC.

Независимо от языка, на котором сделано RTL-описание, результатом синтеза является список соединений между триггерами, защелками и логическими элементами. Поэтому синтезируемые подмножества Verilog, VHDL и SystemC совпадают по смыслу и отличаются только синтаксисом описания. Возможно, что разработка поведенческого синтеза расширит возможности SystemC для описания аппаратуры, но в настоящее время следует ориентироваться на привычные и широко используемые RTL-описания.

Для понимания синтаксиса SystemC следует разбираться в С++, так как любая конструкция SystemC является синтаксически верной конструкцией C++, особое внимание следует обратить на классы и шаблоны (template). Из-за популярности С++ существует большое количество книг, описывающих этот язык, из которых можно рекомендовать Б. Страуструп «Язык программирования С++». Но в то же время SystemC можно рассматривать как самостоятельный язык, со своим собственным синтаксисом.

Рассмотрим конструкции SystemC, применяемые для описания иерархической структуры модулей.

В дополнение к стандартным объектам класса С++ добавлены описания портов, сигналов и процессов. Эти объекты воспринимаются средством синтеза и являются основными элементами RTL-описания.

Порты описываются следующим образом:

Типом порта port_data_type может являться любой допустимый для синтеза С++ или SystemC тип данных. Это может быть как встроенный тип языка С++, так и определенный в SystemC. Для битовых переменных может использоваться bool, sc_bit, sc_logic. Для численных или векторных типов могут использоваться signed и unsigned char, int, long или специализированные типы SystemC sc_lv<n>, sc_bv<n>, sc_int<n>, sc_uint<n>, sc_bigint<n>, sc_biguint<n>, где n — число, показывающее разрядность. Для n>64 следует использовать sc_bigint/sc_biguint, а sc_logic и sc_lv применяются в случаях, когда требуется моделирование сигнала с X, Z. Также могут применяться определяемые пользователем структуры struct, содержащие поля из вышеперечисленных типов данных (допустимых для синтеза). Перечисления enum поддерживаются синтезом так же, как и компилятором С++ и используются для задания именованных констант.

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

На типы сигналов действуют те же ограничения, что и на типы портов.

Внутри модуля могут использоваться переменные, не являющиеся сигналами или портами. Описание переменных не отличается от описания в С++. Типы переменных должны принадлежать тому же подмножеству, что и для портов и сигналов. Разница между сигналами и переменными состоит в том, что значения сигналам присваиваются в конце временного шага исполнения модели (дельта-цикла), а присвоения переменным происходят мгновенно.

Аналогом Verilog блока alwais (или process в VHDL) с условием запуска по уровню или фронту сигнала (сигналов), который применяется для описания триггеров, защелок и комбинаторной (параллельной) логики, является процесс. В SystemC существует несколько видов процессов, но для RTL-описаний применяется только SC_METHOD. Процесс должен быть описан как функция-член, а потом зарегистрирован с помощью макроса SC_METHOD.

Список чувствительности может включать в себя события по уровню и по фронту. При этом правила синтезируемости такие же, как и в Verilog/VHDL, поэтому я их приводить не буду.

Предлагается два метода описания списка чувствительности в виде потока или в виде функций. Для описания чувствительности по фронту используются sensitive_pos или sensitive_neg вместо sensitive.

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

В качестве неблокирующего присвоения (Verilog <=) сигналам следует пользоваться функциями read(), write(), но также переопределен оператор присваивания.

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

В общем, этого достаточно для описания аппаратной части. В качестве примера приведу описания некоторых стандартных элементов на SystemC:

Пример 1 описывает триггер с синхронным сбросом, а пример 2 — комбинаторную логику.

В дополнение к RTL-синтезу в будущем предполагается наличие поведенческого синтеза, который не требует от пользователя знаний об элементарных ячейках: триггерах, защелках и логических элементах — и выполняет автоматическое разбиение проекта на соответствующие модули, создание тактовых сигналов и т. п. Возможно, что это направление будет очень полезным.

Для моделирования цифровых схем (или любых других систем) отсутствуют ограничения, накладываемые на описание RTL-кода. То есть возможно использовать всю мощь языка С++ и в дополнение к этому в SystemC существуют классы С++, описывающие электрические сигналы (может принимать значения 0, 1, Z, X) и имеющие правила разрешения конфликтов. Также система моделирования поддерживает запись изменения сигналов в различных форматах, например, vcd. Механизм моделирования привязан ко времени исполнения и использует понятие дельта-цикла так же, как и симулятор Verilog/VHDL.

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

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

Для моделирования RTOS имеются потоки вычислений (THREAD), семафоры, очереди и модель невытесняющей многозадачности.

В кратком обзоре невозможно дать полный обзор возможностей SystemC. Но так как библиотека поставляется в виде исходников и имеет достаточно хорошую документацию, есть возможность разобраться с любой конструкцией «языка» SystemC.

Пример использования SystemC для моделирования устройства генерации GPS L5 кода

Проведем сравнение этапа разработки моделирования аппаратной реализации генератора псевдошумового кода от модели С до RTL-кода с использованием Verilog и SystemC. Исходная модель на С++ описывает процедуру генерации псевдошумового сигнала, который планируется для использования в навигационных GPS-спутниках следующего поколения. Для статьи модель была упрощена: отсутствует модуляция несущей, модель шума, сигналы соседних полос и т. п.

Модель описывает генерацию двух псевдошумовых последовательностей, предназначенных для квадратурного модулятора. Последовательности образуются смешиванием двух М-последовательностей, генерируемых 13-разрядными регистрами с разными порождающими полиномами. Одна из последовательностей (ХА) укорочена на 1 такт, а вторая запускается со сдвигом — для квадратурного (XQ) и синфазного (XI) каналов сдвиги разные. Смешиваются последовательности посредством «исключающего или», а длина повторения — 10230 чипов. Число 10230 определяется кодом в полосе L1 и выбрано так, чтобы время передачи на частоте 10,23 МГц совпало со временем повторения последовательности L1 (код Голда длины 1023 на частоте 1,023 МГц) и составило 1 мс. Иерархия верхнего уровня приведена на рис. 1. Предлагается 37 последовательностей, определяемых различными начальными сдвигами XQ и XI, для спутников и наземного оборудования.

При использовании в качестве языка описания аппаратуры Verilog HDL синтезируемая модель может быть описана следующим образом:

Сразу появляются отличия:

  • принципиальные. Введения тактового сигнала и сигнала сброса, без которых невозможно синтезировать схему;
  • непринципиальные, например, в модели С номер спутника начинается с 0, а в модели Verilog с 1.

Также из-за разных возможностей языков описание одинаковых конструкций выглядят по-разному. Использование двух различных описаний, имеющих расхождения, может вызвать проблемы при взаимодействии разработчиков системного уровня и разработчиков аппаратной части.

Для проверки работы Verilog-модели требуется разработать «испытательный стенд» (testbench). Это специальная программа на Verilog, которая может использовать несинтезируемые конструкции языка и средства ввода-вывода. Для тестирования модели генератора можно воспользоваться таким testbench:

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

Для описания данной модели на SystemC лучше всего пользоваться встроенными типами С++ int и bool, для того чтобы воспользоваться уже готовым кодом с минимальными изменениями. Конечно, описание на SystemC отличается от исходного описания, но если бы описание модели было сделано на SystemC изначально, то объем работы можно было уменьшить вдвое без потери функциональности. Напоминаю, что изменения потребовались, чтобы создать синтезируемую (RTL) модель. Для этого потребовалось ввести тактовый сигнал и немного изменить структуру.

Как принято среди разработчиков С++, разобьем описание на заголовок (h-файл) и файл с определениями (cpp).

Можно видеть, что структуры данных и основные функции перенесены из исходного С-файла. Требования на аппаратную часть (интерфейс) описаны в классе L5codegen.

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

Для того чтобы проверить работоспособность модуля, нужно написать соответствующий испытательный стенд (testbench). Для краткости определения и описания (интерфейс) испытательного стенда помещены в один файл.

В этом файле описан дополнительный модуль test, который формирует управляющие сигналы для тестируемого модуля и печатает результаты. Функция sc_main является аналогом стандартной функции main в С/С++ коде: управление передается на эту функцию после завершения инициализации. sc_clock mclk(«MCLK»,20,0.5); — описание тактового сигнала. Функция sc_start() — функция запуска симулятора, если аргумент — 1, то повторение продолжается до тех пор, пока не будет вызвана функция sc_stop(), иначе аргумент определяет время исполнения.

Для компиляции и исполнения этого примера требуется собрать библиотеку systemc.lib и подключить ее к проекту. В Unix-системах следует воспользоваться configure-make, для пользователей Windows в пакете есть поддиректория msvc60, в которой находятся проекты для сборки библиотеки и примеров.

Выводы

SystemC выглядит удачной альтернативой языкам HDL и может использоваться в качестве системного языка разработки от модели до готового изделия. В библиотеке реализовано много классов для моделирования различных этапов разработки SoC, в особенности для систем связи и обработки сигналов. Минусом системы, на мой взгляд, является сложный синтаксис языка С++, но использование стандартного языка позволяет использовать существующие компиляторы, прежде всего свободно распространяемый gcc www.gcc.org. Если же ограничить использование SystemC описанием RTL, то существенного выигрыша перед HDL-языками у Verilog/VHDL — нет. К плюсам следует отнести то, что для моделирования не требуется симулятор, а к минусам — то, что средства синтеза для SystemC распространены меньше, чем для специализированных HDL-языков. Но производители начинают поддерживать RTL SystemC — в настоящее время продаются компилятор CoCentric от Synopsys или продукция Forte Design Systems.

В примерах SystemC, поставляемых совместно с библиотекой или свободно доступных в сети, можно найти описания процессора, фильтров, схем шифрования, MP3-декодера, различных интерфейсов и т. д. Но большая часть этих примеров не является RTL-кодом и не может быть использована для синтеза.

Совместно со свободными средствами просмотра vcd (value change dump) файлов SystemC может использоваться как полноценное средство моделирования цифровых схем. При этом свободное (бесплатное) использование этих программных продуктов является легальным, и результаты могут использоваться для получения прибыли. Свободный vcd-viewer можно загрузить с http://www.cs.man.ac.uk/amulet/tools/gtkwave/, а версию для Windows — http://daggit.pagecreator.com/ ver/wave/gtkwave9x.html.

Можно предположить, что в ближайшее время SystemC не вытеснит Verilog/VHDL, но займет место среди HDL-языков. Большим плюсом SystemC является возможность интеграции описания аппаратуры, по которому может изготовляться изделие (SoC), и программного обеспечения, пригодного для использования в готовом изделии в одной модели.

Скачать статью в формате PDF  Скачать статью Компоненты и технологии PDF

 


Сообщить об ошибке