Попробовать (online)





Введение

Языки программирования Си и Verilog описывают совершенно разные процессы работы алгоритмов, по этому однозначный перенос между ними сделать нельзя. Но, не смотря на это, обеспечивается поддержка наиболее необходимых и часто встречаемые операции.Vsyn формирует state-машину в точном соответствии с Си кодом. Для максимальной оптимизации алгоритмов, разработчику стоит понимать сущность, необходимость и принципы формирования state-машины.

Генерируемый Verilog код является синтезируемым модулем и может быть легко интегрирован в любой проект.Интерфейс к модулю (input\output) определяется аргументами в функциях, а также особыми директивами. Рекомендуется использовать комбинацию модулей, написанных вручную и генерируемых с помощью Vsyn. Некоторые алгоритмы (как правило, для выполнение которых нужен один clock) удобней представить в виде стандартного конвеера, но для описание алгоритмов с множеством состояний или сложными взаимодействиями - стоит использовать Vsyn (примеры).

Основные отличия от Xilinx Vivado High-Level Synthesis (HLS):

  • Иной подход построения конечного детерминированного автомата FSM (проста и удобна + переходы в картинках!)
  • Удобный интерфейс для работы с памятью
  • Скорость синтеза Си в Verilog (3-5 миллисекунды на х86\64)
  • Бесплатное ознакомление (через web-сайт)

О синтезе

Синтез модулей происходит на основе функций. Параметры в функциях являются входящими сигналами синтезируемого модуля (input), а возвращаемое значение функции выходными сигналами модуля (output). Для создания множества выходных сигналов стоит использовать структуру в возвращаемом типе функции.

Все вызываемые функции синтезируются как inline-функции (для них не будет создан отдельный файл). Также возможно использование внешних модулей (в том числе написанных и на других языках), но для этого необходимо согласовать интерфейс:

  • Произвести описание функции (ее название и входящие параметры)
  • Указать с помощью директив названия служебных сигналов (если они используются): CLOCK, START, DONE, RESET
ВНИМАНИЕ: если внешняя функция использует CLOCK | POSEDGE - это обязательно указать для синтезируемой функции, иначе она не будет рассматриваться как функция, требующая состояний

Конечный детерминированный автомат (FSM)

Когда синтезируемая верилог-логика не может быть представлена в ввиде последовательной логики, Vsyn создает конечный детерминированный автомат. Конечный автомат (Finite State Machine) — абстрактный автомат, число возможных состояний которого конечно. В каждый момент времени автомат имеет одно текущее состояние. Текущее состояние автомата меняется от одного состояния к другому, в зависимости от начальных условий, логики\условий в каждом состоянии. Результат работы автомата определяется по его выходным данным в конечном состоянии.

Вызов функции - происходит по положительному значению START, вызывать функцию можно только тогда, когда она вернула DONE. Начало функции соответствует точке входа в синтезируемый автомат (1-ое состояние), а выход из функции конечному состоянию (0-ое состояние). Переход из одного состояния в другое, характеризует завершение выполнения нужных операций в текущем состоянии и возможность продолжить выполнять дальнейшую логику функции в другом состоянии. Примерами таких ситуаций могут быть:

  • Вызов другой функции, использующей свои состояния
  • Циклы, зависящие от параметров
  • Чтение\запись с использованием указателей
  • Получение данных на следующем клоке (например, ожидание события или прихода данных от периферийного устройства)

В результате, для полного описания работы функции будут синтезироваться дополнительные служебные сигналы:

  • Start – сигнал вызова функции (запуска логики функции)
  • Reset – сигнал принудительного сброса состояния функции (не очищает статические переменные)
  • Done – завершение работы функции (1 функция завершила работу, 0 - нет)
  • Clock – частота, при которой изменяются состояния модуля.

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

Директивы

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

Название директивы
Принимаемые значение
По умолчанию
Описание
CLOCKИмя переменнойclockАнализ и смена состояния в данной функции будет происходить с помощью частоты
POSEDGEtrue | falsetrueРабота на posedge или negadge
STARTИмя переменнойstartСигнал запуска логики функции (запуск по положительному фронту)
RESETИмя переменнойresetСигнал сброса состояния (сброс по положительному фронту)
DONEИмя переменнойdoneСимволизирует завершение работы функции
RETURNИмя переменнойresultНазвание возвращаемого сигнала

При обнаружении множества функций в коде, по умолчанию, будет сентизироваться одна последняя функция. В противном случае, с помощью директивы TOP (без параметров) можно указать название функции, синтез которой будет происходить.

Интерфейс работы с памятью

Указатели на языке Си используются как интерфейс работы с оперативной памятью.

Название сигнала
Направление
Описание
mem_cmdoutputНаличие (=1) команды для работы с памятью, (=0) - отсутствие команды
mem_is_writeoutputЗапись (=1) или чтение (=0) из памяти
mem_addressoutputАдрес (байтовый) для которого происходит действие
mem_sizeoutputРазмер данных, которые пишутся или читаются.
mem_is_readyinputКоманда обработана. Команды на запись или чтение будут будут происходить, когда данный сигнал =1
mem_data_ininputДанные на чтение
mem_data_outoutputДанные на запись

Максимальный размер данных для чтения и записи (mem_data_in и mem_data_out) может быть настроен (по умолчанию 16 байт).При чтении\записи размера данных больших, чем размер сигналов, операция обращения к памяти будет разбита количество итераций (по 16 байт), необходимых для полного чтения\запии данных.

Вопросы оптимизации

Синтезируемый код с языка Си в Verilog однозначно отражает все логические операции написанные на языке Си. В синтезируемом коде всегда используются блокирующие операторы (=), так как они всегда синтезируются в виде "защелок". Дальнейшая оптимизация полностью лежит на синтезаторе из Verilog в RTL, а значит, кажущиеся на первый взгляд не оптимальные конструкции в Verilog коде достаточно эффективно будут реализованны в RTL. В общем случае, рекомендуется оптимизировать Си код, а также стараться минимизировать количество промежуточных состояний в FSM. В данный момент, возможно указать Vsyn-компилятору автоматическое расскрытие всех циклов (не выборочно!), для уменьшения промежуточных состояний. В будущем планируется возможность выборочно указать для каждого цикла количество итераций, которые будут расскрыты.

Частые ошибки

Описание
Примеры частых ошибок
Помним про ограниченияОграничения
Инклуд стандартных библиотек невозможен (тк их нет, но можно написать вручную)include "stdio.h" или include "stdlib.h"
Каждый case (default) в switch должен заканчиваться на breakcase 0: x = 5;
Массивы в аргументах функций не являются указателямиint example(int x[5]) // x - массив, а не указатель
Инициализация массива должна содержать только одно число\константу (без операторов)int x[123+321];
Функции malloc|free и д.р. не доступныchar * x = malloc(10);

Поддерживаемые операции

  • Циклы: for, while, do
  • Условия: if, else if, else, switch
  • Вызовы функций (включая внешние модули) и операторы: return/break/continue
  • Все основные операторы: +, -, /, *, %, ^, &&, &, ||, |, <<, >>, ==, >=, <=, >, <, !=, ?, !, ~, ++, --
  • Любая глубина вложенных скобок
  • Приведение типов
  • Переменные и массивы (многоуровневые)
  • struct и union (любые вложенности, включая массивы)
  • typedef - декларация своих типов
  • enum, bool, void, signed\unsigned: char, short, int, long
  • static и глобальные переменные
  • sizeof
  • Препроцессор: define, undef, ifdef, ifndef, else, endif
  • Доступна функция printf (синтезируется в display)

Ограничения

  • Нет функций для динамической аллокации памяти (возможно написать вручную)*
  • Рекурсия функций
  • Ссылки*
  • Плавающая точка (не целые числа)
  • Variable shadowing*
  • Goto*
  • Переменное кол-во параметров в функциях
  • Отсутствуют операторы: "запятая (,)", "амперсанд (&)", "чтение\запись из памяти по звездочке (*(int*)a = 0)"*
  • Задание строк и символов*
* планируется реализация в следующих версиях