vak: (Default)
Я наконец осилил back annotation в Верилоге. Это когда синтезируется прошивка для Xilinx FPGA, и на этапе, когда уже известно точное расположение всех элементарных примитивов, образуется файл с описанием всех задержек для каждого провода и логического вентиля. Даже есть такой стандартный формат SDF, или Standard Delay Format. После этого синтезированная схема преобразуется обратно в Верилог (структурный) и симулируется, загружая SDF-файл как набор параметров тайминга. Предполагается, что временная диаграмма такой симуляции будет примерно соответствовать реальному железу.

Вот что я получил для упомянутого сигнала цикла вычисления наибольшего общего делителя. Цикл в 20 итераций должет выполняться за 99500 пикосекунд, или почти ровно 100 нсек.



В реальности на осциллографе имеем 500 нсек.



Как-то точность времянки не особо радует. Плюс-минус порядок получается.
vak: (Default)
До сих пор существует мнение, что язык VHDL является обязательным для военных разработок в США. На самом деле с 1997 года это не так.

"In early 1995, DoD standard MIL-STD-454L was replaced and the use of VHDL was no longer mandated. Instead, the new wording stated that ASIC designs “should be documented” by means of VHDL. By 1997 even this suggestion was removed."

"Who is still using VHDL? In 2015, the US appeared to be 80–90% Verilog/SystemVerilog. There are certain US military and aerospace vendors continuing to use VHDL, despite the lack of a DoD mandate. Europe used to be a huge VHDL supporter, but this is a legacy issue now and there is very little new VHDL being written. There’s little VHDL usage in India/Asia, as these are historically Verilog. When VHDL was mentioned to the Broadcom team in Israel, there were chuckles."

Вот хорошая статья про историю языков и текущее состояние: http://trilobyte.com/pdf/golson_clark_snug16.pdf
vak: (Default)
Появилась статья, суммирующая положительный опыт применения открытого процессорного ядра MIPSfpga в образовательных целях.

https://www.ncsu.edu/wcae/ISCA2017/papers/chaver.pdf
vak: (Default)
В качестве теста возьмём упомянутый наибольший делитель.
module gcd (
input activate,
input [7:0] a,
input [7:0] b,
output [7:0] c
);
reg [7:0] x, y;

always while (activate) begin
fork
x <= a;
y <= b;
join

while select
x > y:
x = x - y;
y > x:
y = y - x;
endselect

c <= x;
end
endmodule
Парсер преобразует исходный текст в следующее синтаксическое дерево:Осталось научиться генерить из этого дерева асинхронную схему.
vak: (Default)
Закончил парсер для языка Verilog. Удалось приспособить Yacc-овскую грамматику от проекта Yosys, переписав её на Go. Лексический сканер позаимствовал от самого компилятора Go.

Узнал много забавного про константы в Верилоге. Обычный десятичный литерал типа 123 имеет знаковый тип. Если добавить к нему десятичный префикс ('d123), он становится беззнаковым. Чтобы снова превратить его в знаковый, надо добавить буковку s: 'sd123. Разницу можно заметить на примерах:
5 - 10 = -5
'd5 - 10 = 4294967291
'sd5 - 10 = -5
vak: (Default)
Обнаружил в языке Verilog неожиданную фичу, не описанную ни в одной книжке. Оказывается, диапазоны можно задавать в виде X+:Y или X-:Y, что эквивалентно X+Y-1:X и X:X-Y+1 соответственно. К примеру, эти три присваивания эквивалентны:
    value[10:8] = 0;
    value[10-:3] = 0;
    value[8+:3] = 0;
vak: (Default)
В продолжение темы 1, 2: слушайте радиопередачу про предстоящий на следующей неделе в Киеве семинар по микроэлектронике для школьников.

Аудиофайл (на украинском языке): https://hromadskeradio.org/sites/default/files/media/zvuk/hr_hh_2017-04-22_hutka.mp3

Частичная расшифровка: "Українські школярі вчитимуться проектувати мікросхеми, які застосовують Аpple та Tesla"
vak: (Default)
В конце апреля в Киеве пройдёт экспериментальный семинар для старших и младших школьников по обучению современной цифровой электронике. Программа семинара и форма для регистрации доступны на сайте: http://electronics-ukraine.com/


vak: (Default)
С какой максимальной скоростью может работать асинхронный процессор на FPGA? Многие считают, что это в принципе невозможно, а я тем временем решил измерить реальную цифру. Возьмём пустой цикл следующего вида:
    forever
        continue;
Еслибы существовал транслятор с SystemVerilog в асинхронные компоненты, он бы породил такую схему:
                 ,---. out ,---.
    activate ---o| # |----o|run|
                 `---'     `---'
                 Loop     Continue
Примитив Continue я уже упоминал недавно. Loop это компонент, реализующий бесконечный цикл. У него два синхропорта: по ведомому порту он получает сигнал активации, после чего начинает генерить последовательность импульсов на ведущем порту. Реализуется он следующим образом:
    module Loop (sync.slave activate, sync.master out);

        wire req = activate.req & !out.ack;

        BUFR b (.O(out.req), .I(req));

        assign activate.ack = '0;
    endmodule
Работает схема так:



С точки зрения формальной логики буфер BUFR здесь не требуется. Однако без него схема не работает. У семейства Xilinx Artix7 есть три типа подходящых буферов на выбор: BUFG, BUGH и BUFR. Я загрузил прошивку в плату Digilent Basys3 и измерил результат для всех трёх вариантов. Самая высокая частота получается с BUFR, а именно 309 МГц. Это будет верхний предел для скорости асинхронного процессора на данном типе FPGA.
vak: (Default)
Продолжаю постигать азы асинхронной логики. Про сигналы и базовый протокол взаимодействия я уже писал. Но то были теоретические рассуждения, а теперь пора заняться реальным кодом. Для описания асинхронных каналов задействуем конструкцию interface языка SystemVerilog. Будет использовать кодирование dual-rail. Адаптировать для quad-rail или 1-of-N будет нетрудно.

Существует три типа асинхронных каналов: push, pull и nonput. В первом случае активная сторона (мастер) выдаёт данные, а пассивная (slave) отвечает подтверждением:
_______           ______
       |  data   |
Master | ======> | Slave
output |         | input
       |  req    |
_______| <------ |______
Второй вариант - канал типа pull. Здесь мастер выдаёт запрос, а в ответ приходят данные:
_______           ______
       |  req    |
Master | ------> | Slave
input  |         | output
       |  data   |
_______| <====== |______
Каналы push и pull с кодированием dual rail ширины N бит можно описать следующим образом:
vak: (Улыбка)
Измерил скорость работы трёх разных Verilog-симуляторов на комплексном тесте системы команд микро-БЭСМ.

Synopsys VCS предсказуемо лидирует с большим отрывом. На втором месте Xilinx Vivado Simulator (бывший Cadence NCSIM). Altera Modelsim (заимствованный у Mentor Graphics) слегка отстаёт.

Сохранилась фотография из газеты "Дубна" от 13 июня 1990 года, где команда разработчиков демонстрирует работу ровно этого же теста отцам-основателям Мельникову и Томилину (автору аналогичного теста системы команд для БЭСМ-6).



На фотографии слева направо: В.М.Кадыков, И.Н.Силин, Т.Ф.Сапожникова, В.А.Мельников, А.П.Сапожников (1 ряд), И.А.Емелин, Ф.В.Левчановский, А.Н.Томилин (2 ряд, что выше).

Упомянутая статья на 4-5 страницах газеты: http://www.besm6.org/wiki/1990-dubna-retro86
 
vak: (Улыбка)
Измерил скорость трёх коммерческих симуляторов Verilog на тесте микро-БЭСМ.

Mentor Modelsim: 2428 микроинструкций в секунду.
Cadence NCsim: 2362 микроинструкций в секунду.
Synopsys VCS: 7759 микроинструкций в секунду.

Первые два - на самом деле бесплатные версии от Altera и Xilinx. Но синопсис по любому в разы быстрее получается.
vak: (Улыбка)
Сделал ассемблер для трансляции микрокода ЭВМ МКБ-8601.
Так выглядит результат: https://github.com/besm6/micro-besm/blob/master/microcode/microcode.v
vak: (Улыбка)
Воспроизвести чип Am2904 на Верилоге нетрудно. Насколько он соотвествует реальности, это другой вопрос. Надо каким-то образом сравнить его с реальныи чипом. Для этого я собрал вот такой стенд на базе Ардуино Мега.



vak: (Улыбка)
Сделал чип Am2904 на СистемВерилоге.
Теперь задача протестировать.
vak: (Улыбка)
Почему-то считается, что асинхронную логику нельзя засунуть в традиционную FPGA. Я решил поисследовать этот вопрос. Чем дольше разбираюсь, тем яснее становится, что это просто предубеждение. Я взял популярную плату Digilent Basys3 на основе чипа Xilinx Virtex-7, и стал смотреть, что тут можно сделать.

Основа асинхронной логики - несколько базовых примитивов: C-элемент, арбитр, S-элемент, T-элемент. Все их удалось реализовать на имеющейся FPGA. Вот, к примеру, как выглядит двухвходовый С-элемент Мюллера:


Дальше про трёхвходовый С-элемент, асинхронный арбитр, S-элемент и Т-элемент... )
vak: (Улыбка)
В поисках неортодоксальных подходов к разработке хардвера, в частности в области асинхронной логики, я неожиданно для себя открыл интересный язык Balsa, и стоящую за ним методику, называемую 'Handshake Circuits'. Взгляните, вот программа вычисления наибольшего общего делителя на Бальсе:
procedure GCD (
    input x: byte;
    input y: byte;
    output z: byte
) is
local 
    variable a, b: byte
begin
    loop
        x -> a || y -> b;
        loop
            while a /= b then
            begin
                if a > b
                then a := (a - b as byte)
                else b := (b - a as byte)
                end
            end
        end;
        z <- b
    end
end
При компиляции она превращается в такую асинхронную схему:

Дальше она преобразуется в Verilog и синтезируется в собственно микросхему. Разве не прелесть? Не одним верилогом жив человек! :)

Бальса разрабатывалась в 1998-2010 годах в университете Манчестера. Её исходные тексты доступны на сайте университета на условиях лицензии GPL. Подход подробно описан в диссертации Andrew Barsley "Balsa: An Asynchronous Circuit Synthesis System".
vak: (Улыбка)
"Compiling from Haste to CDFG: a front end for an asynchronous circuit synthesis system" (PDF).

Вычисление факториала на языке Haste выглядит следующим образом:
int = type [0..2^32-1] &

fact : main proc (in?chan int & out!chan int).
  begin x,y :var int ff
  |
    forever do
      in ? x
    ; y := 1
    ; do x > 1 then
        y := y * x
      ; x := x - 1
      od
    ; out ! y
  od
end

Эта функция превращается в такую асинхронную схему:


Дальнейшее преобразование в Верилог и синтез делаются элементарно.
vak: (Улыбка)
Обычно считается, что FPGA не годятся для асинхронной логики. Родной софт от Xilinx способствует этому предубеждению: при попытке создать latch традиционными средствами языка Verilog, к примеру:
    always @(*)
        if (set)
            z <= 1;
        else if (clr)
            z <= 0;
получаем серию страшных предупреждений типа:
WARNING:Xst:737 - Found 1-bit latch for signal <z>. Latches may
be generated from incomplete case or if statements. We do not
recommend the use of latches in FPGA/CPLD designs, as they may
lead to timing problems.

(*) This 1 clock signal(s) are generated by combinatorial logic,
and XST is not able to identify which are the primary clock signals.
Please use the CLOCK_SIGNAL constraint to specify the clock signal(s)
generated by combinatorial logic.

WARNING:PhysDesignRules:372 - Gated clock. Clock net clr is sourced by a
combinatorial pin. This is not good design practice. Use the CE pin to
control the loading of data into the flip-flop.
Между тем, задача отлично решается посредством компонента FDCPE из библиотеки Xilinx. Немного лёгкого шаманства, и он превращается в асинхронную защёлку:
module th22 (input a, input b, output z);
    assign set = a & b;
    assign clr = !a & !b;

    FDCPE latch (
        .Q   (z),      // Data output
        .D   (0),      // Data input
        .C   (0),      // Clock input
        .CE  (0),      // Clock enable 
        .PRE (set),    // Asynchronous set 
        .CLR (clr)     // Asynchronous clear 
    );
endmodule