Перевод этой страницы:
ru

BreaksVM

BreaksVM (Breaks Verilog Machine) - виртуальная машина для выполнения Verilog-подобных скриптов.

Мы не собдюдаем стандартов, то что не поддерживается можете добавить сами.

Главная особенность и отличие от Verilog - это добавление виртуальных девайсов в скомпилированный netlist. Добавленные девайсы интегрируются в реактивную среду netlist-а и "цепляются" к выбранным IO-контактам модулей.

Устройство

Исходными данными для виртуальной машины являются Verlog-скрипты (*.v)

Встроенный компилятор создает из скриптов netlist, который затем передается статическому рекомпилятору, который преобразует netlist в быстрый платформенный код.

Управлением виртуальной машиной занимается родительское приложение.

BreaksVM API

Весь интерфейс содержится в файле breaksvm.h, а программный код - в breaksvm.c. Из зависимостей - stdio, pthread.

Типы данных используемые в BreaksVM: u8, u16, u32, u64.

  • breaksvm_init () : подготовка виртуальной машины
  • breaksvm_shutdown () : закрыть машину и освободить все используемые ей ресурсы
  • breaksvm_load (filename) : указывается .v файл, который должен быть загружен в VM
  • breaksvm_input_real (input_name, callback) : прикрепить входное устройство типа real
  • breaksvm_input_reg (input_name, callback) : прикрепить входное устройство типа reg
  • breaksvm_output_real (output_name, callback) : прикрепить выходное устройство типа real
  • breaksvm_output_reg (output_name, callback) : прикрепить выходное устройство типа reg
  • breaksvm_run (timeout) : запустить симуляцию состояния. timeout задает количество итераций, для прерывания race condition.
  • breaksvm_status : 1 - VM выполняет симуляцию, 0 - VM idle

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

  • Callbackи входных устройств выполняются ядром ДО симуляции (при вызове run)
  • Соответственно callbacks выходных устройств выполняются после прогона симуляции (в конце run)
  • Callback для девайсов типа reg имеет вид void callback (unsigned char * reg), LSB-first
  • Callback для девайсов типа real имеет вид void callback (float * reg)
  • Можно прикреплять несколько девайсов на один контакт. Выполняться они будут в порядке добавления.

Типичный пример виртуального девайса - это XTAL (генератор опорной частоты) :

void XTAL_output (unsigned char * reg)  // toggle clock
{
    if ( reg[0] == '0' ) reg[0] = '1';
    if ( reg[1] == '1' ) reg[1] = '0';
}

После инициализации VM мы устанавливаем этот callback :

breaksvm_output_reg ( "CLK", XTAL_output );

Теперь после каждого прогона run контакт CLK будет менять своё значение, тем самым тактируя схему.

Все ошибки времени компиляции и симуляции сыпятся в stdout. При серьезных ошибках run прерывается, предупреждения не прерывают симуляцию.

Диалект Verilog

Мы выкинули ненужный хлам, который не понадобился для наших целей. Считайте этот документ описанием стандарта BreaksVM =) Однако главное правило - любой verilog-скрипт для BreaksVM может быть синтезирован в реальный девайс, то есть мы не используем нестандартные дополнения.

Отличия :

  • все временные задержки (delay) игнорируются
  • fork/join блоки не поддерживаются (выдается предупреждение и блок пропускается)
  • переменные типов time и event не поддерживаются (выдается предупреждение, значение переменных всегда неопределено)
  • из всех встроенных функций поддерживается только $display, остальные игнорятся (с предупреждением)
  • нет операторов wait/forever/disable (выдается предупреждение и блок пропускается)
  • директивы препроцессора не поддерживаются (выдается предупреждение)
  • совпадение идентификаторов определенных в модуле и внутри именованного блока выдает предупреждение
  • пространства имён между блоками не поддерживаются (синтаксическая ошибка)
  • Операции редукции и сдвиги пока не поддерживаются
  • Арифметические операции + - * / % также пока не поддерживаются
  • Операцию конкатенации пока не осмыслил до конца )))
  • Пользовательские примитивы не поддерживаются (выдается ошибка)
  • Из встроенных примитивов поддерживаются только: and, nand, nor, or, xor, xnor, buf, not, bufif0, bufif1, notif0, notif1

То есть наш диалект максимально приспособлен для синтезирования логики.

FIXME нужны ли нам real ? чё-то кажется входы и выходы всё равно дискретные..

FIXME нужны ли функции ? и как они будут "синтезироваться" ? Просто как встраиваемый код (inline) ?

Особенности реализации

Все reg и wire хранятся в памяти как байты (unsigned char). Логические значения соответственно могут быть '0', '1', 'x', 'z', 'L', 'H' итп. (char-константы)

real хранятся как float (IEEE734 32-бит). Вещественные входы/выходы используются для аналоговых схем и представляют собой моментальное напряжение.

parameter тоже самое что и integer. integer тоже самое что и reg[31:0].

Все input/output/inout всех модулей связаны реактивно. Симуляция всей системы продолжается до тех пор, пока все входы/выходы останутся неизменными.

Run flow одного запуска симуляции выглядит следующим образом :

  • Вызываются все input_deivce callbacks, устанавливаются входные контакты
  • Производится выборка always блоков, при изменении реактивных сигналов, управляющих ими
  • Выполняется прогон схемы, до тех пор, пока состояние всех входов/выходов не стабилизируется
  • Вызываются все output_device callbacks, используются значения с выходных контактов

Разобранное синтаксическое дерево (netlist) выдается в формате EDIF 2 0 0. http://iroi.seu.edu.cn/books/asics/Book2/CH09/CH09.4.htm Каждый узел этого дерева - стандартная ячейка библиотеки breaksvm.

Netlist преобразуется в двоичную форму, а затем производится его статическая рекомпиляция. После чего VM готова к исполнению (run).

Рекомпиляция заключается в том, что вместо обычного траверса (интерпретации) netlist, блок за блоком производится перевод всего прогона run в исполняемый код платформы.

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

Библиотека стандартных ячеек breaksvm

Библиотека реализует стандартный набор логических элементов эпохи NMOS. Более сложные ячейки могут быть добавлены со временем.

  • x = NAND(a,b)
  • x = NOR(a,b)
  • x = AND(a,b)
  • x = OR(a,b)
  • x = XOR(a,b)
  • x = XNOR(a,b)
  • x = NOT(a)
  • x = BUF(a)
  • x = TRI(a,enable)
  • x = MUX(s,in0,in1)
  • _q = DLATCH(d,t)
sim/breaksvm.txt · Последние изменения: 2013/11/13 14:22 — org
 
За исключением случаев, когда указано иное, содержимое этой вики предоставляется на условиях следующей лицензии: Public Domain
Recent changes RSS feed Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki