Пишем Для Fpga Без Hdl. Сравнение Инструментов Разработки Высокого Уровня

В последнее время производители ПЛИС и сторонние компании активно разрабатывают методы разработки ПЛИС, отличающиеся от традиционных подходов с использованием инструментов разработки высокого уровня.

Как разработчик FPGA, моим основным инструментом является язык описания аппаратного обеспечения ( ЛПВП ) Verilog, но растущая популярность новых методов вызвала у меня большой интерес, поэтому в этой статье я решил сам разобраться, что к чему.

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

Под катом — что из этого получилось.



Зачем нужны инструменты разработки FPGA высокого уровня

  • Ускорить разработку проекта - путем повторного использования кода, уже написанного на языках высокого уровня; — за счет использования всех преимуществ языков высокого уровня при написании кода с нуля; — за счет сокращения времени компиляции и проверки кода.

  • Возможность создания универсального кода, который будет работать на любом семействе ПЛИС.

  • Снизить барьер входа в разработку ПЛИС, например, отойдя от понятий «тактовая частота» и других низкоуровневых сущностей.

    Возможность написания кода FPGA для разработчика, незнакомого с HDL.



Откуда берутся инструменты разработки высокого уровня?

В наше время многих привлекает идея развития высокого уровня.

Занимаются этим как энтузиасты, как, например, Квокка И Генератор кода Python и такие корпорации, как Математические работы и производители FPGA Интел И Ксилинкс Каждый использует свои методы и инструменты для достижения своих целей.

Энтузиасты в борьбе за идеальный и чудесный мир используют свои любимые языки разработки, такие как Python или C#.

Корпорации, пытаясь угодить клиенту, предлагают свои или адаптируют существующие инструменты.

Mathworks предлагает свой инструмент кодирования HDL для генерации HDL-кода из m-скриптов и моделей Simulink, а Intel и Xilinx предлагают компиляторы для распространенных C/C++.

На данный момент большего успеха добились компании, обладающие значительными финансовыми и человеческими ресурсами, а энтузиасты несколько отстают. Эту статью я посвящу обзору продукта HDL-кодера от Mathworks и HLS Compiler от Intel. А что насчет Ксилинкса? В этой статье я не рассматриваю HLS от Xilinx из-за разных архитектур и САПР Intel и Xilinx, что не позволяет провести однозначное сравнение результатов.

Но хочу отметить, что Xilinx HLS, как и Intel HLS, предоставляет компилятор C/C++ и концептуально они схожи.

Начнем сравнивать HDL-кодер от Mathworks и HLS Compiler от Intel с решения нескольких задач с использованием разных подходов.



Сравнение инструментов разработки высокого уровня



Тест один.

«Два умножителя и сумматор»

Решение этой задачи не имеет практической ценности, но вполне подходит в качестве первой проверки.

Функция принимает 4 параметра, умножает первый на второй, третий на четвертый и складывает результаты умножения.

Ничего сложного, но посмотрим, как с этим справятся наши испытуемые.



HDL-кодер от Mathworks

Для решения этой проблемы m-скрипт выглядит так:
  
  
  
   

function [out] = TwoMultAdd(a,b,c,d) out = (a*b)+(c*d); end

Давайте посмотрим, что нам предлагает Mathworks для преобразования кода в HDL. Я не буду подробно рассматривать работу с HDL-кодером, остановлюсь лишь на тех настройках, которые я буду менять в дальнейшем для получения разных результатов в ПЛИС, и об изменениях которых придется думать программисту MATLAB. которому нужно запустить свой код в FPGA. Итак, первое, что вам нужно сделать, это установить тип и диапазон входных значений.

В ПЛИС нет привычных char, int, float, double. Номер может иметь любую разрядность; логично выбирать его исходя из диапазона входных значений, который вы планируете использовать.



Пишем для FPGA без HDL. Сравнение инструментов разработки высокого уровня

Изображение 1 MATLAB проверяет типы переменных, их значения и автоматически подбирает правильную разрядность шин и регистров — это действительно удобно.

Если проблем с разрядностью и набором текста нет, можно переходить к следующим шагам.



Пишем для FPGA без HDL. Сравнение инструментов разработки высокого уровня

фигура 2 HDL Code Generation имеет несколько вкладок, на которых можно выбрать язык, на который будет происходить преобразование (Verilog или VHDL); стиль кода; названия сигналов.

Самая интересная вкладка, на мой взгляд, это «Оптимизация» — с ней я поэкспериментирую, но позже, а пока оставим все значения по умолчанию и посмотрим, какой HDL-кодер выйдет из коробки.

Нажмите кнопку «Выполнить» и получите следующий код:

`timescale 1 ns / 1 ns module TwoMultAdd_fixpt (a, b, c, d, out); input [7:0] a; // ufix8 input [7:0] b; // ufix8 input [7:0] c; // ufix8 input [7:0] d; // ufix8 output [16:0] out; // ufix17 wire [15:0] TwoMultAdd_fixpt_mul_temp; // ufix16 wire [16:0] TwoMultAdd_fixpt_2; // ufix17 wire [15:0] TwoMultAdd_fixpt_mul_temp_1; // ufix16 wire [16:0] TwoMultAdd_fixpt_3; // ufix17 //HDL code generation from MATLAB function: TwoMultAdd_fixpt //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // % // Generated by MATLAB 9.2 and Fixed-Point Designer 5.4 % // % //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% assign TwoMultAdd_fixpt_mul_temp = a * b; assign TwoMultAdd_fixpt_2 = {1'b0, TwoMultAdd_fixpt_mul_temp}; assign TwoMultAdd_fixpt_mul_temp_1 = c * d; assign TwoMultAdd_fixpt_3 = {1'b0, TwoMultAdd_fixpt_mul_temp_1}; assign out = TwoMultAdd_fixpt_2 + TwoMultAdd_fixpt_3; endmodule // TwoMultAdd_fixpt

Код выглядит хорошо.

MATLAB понимает, что писать все выражение в одной строке в Verilog — плохая практика.

Создает отдельные проволока К умножителю и сумматору придраться действительно не к чему.

Настораживает отсутствие описания регистров.

Это произошло потому, что мы не просили об этом HDL-кодер, а оставили все поля в настройках со значениями по умолчанию.

Вот что Quartus синтезирует из такого кода.



Пишем для FPGA без HDL. Сравнение инструментов разработки высокого уровня

Рисунок 3 Никаких проблем, все было по плану.

В ПЛИС мы реализуем синхронные схемы, но нам всё равно хотелось бы видеть регистры.

HDL-кодер предлагает механизм размещения регистров, но где их разместить — решать разработчику.

Мы можем разместить регистры на входе умножителя, на выходе умножителя перед сумматором или на выходе сумматора.

Для синтеза примеров я выбрал семейство FPGA Cyclone V, где для реализации арифметических операций используются специальные блоки DSP со встроенными сумматорами и умножителями.

Блок DSP выглядит так:

Пишем для FPGA без HDL. Сравнение инструментов разработки высокого уровня

Рисунок 4 Блок DSP имеет входные и выходные регистры.

Не нужно пытаться зафиксировать результаты умножения в регистре перед сложением, это только сломает архитектуру (в определенных случаях такой вариант возможен и даже необходим).

Что делать с входным и выходным регистром — решать разработчику, исходя из требований к задержке (латентности) и необходимой максимальной частоте.

Я решил использовать только выходной регистр.

Чтобы этот регистр описывался в коде, сгенерированном HDL-кодером, во вкладке Options в HDL-кодере необходимо поставить галочку в поле Register output и перезапустить преобразование.

В результате получается следующий код:

`timescale 1 ns / 1 ns module TwoMultAdd_fixpt (clk, reset, clke_ena_i, a, b, c, d, clke_ena_o, out); input clk; input reset; input clke_ena_i; input [7:0] a; // ufix8 input [7:0] b; // ufix8 input [7:0] c; // ufix8 input [7:0] d; // ufix8 output clke_ena_o; output [16:0] out; // ufix17 wire enb; wire [16:0] out_1; // ufix17 wire [15:0] TwoMultAdd_fixpt_mul_temp; // ufix16 wire [16:0] TwoMultAdd_fixpt_2; // ufix17 wire [15:0] TwoMultAdd_fixpt_mul_temp_1; // ufix16 wire [16:0] TwoMultAdd_fixpt_3; // ufix17 reg [16:0] out_2; // ufix17 //HDL code generation from MATLAB function: TwoMultAdd_fixpt //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // % // Generated by MATLAB 9.2 and Fixed-Point Designer 5.4 % // % //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% assign TwoMultAdd_fixpt_mul_temp = a * b; assign TwoMultAdd_fixpt_2 = {1'b0, TwoMultAdd_fixpt_mul_temp}; assign TwoMultAdd_fixpt_mul_temp_1 = c * d; assign TwoMultAdd_fixpt_3 = {1'b0, TwoMultAdd_fixpt_mul_temp_1}; assign out_1 = TwoMultAdd_fixpt_2 + TwoMultAdd_fixpt_3; assign enb = clke_ena_i; always @(posedge clk or posedge reset) begin : out_reg_process if (reset == 1'b1) begin out_2 <= 17'b00000000000000000; end else begin if (enb) begin out_2 <= out_1; end end end assign clke_ena_o = clke_ena_i; assign out = out_2; endmodule // TwoMultAdd_fixpt

Как видите, в коде есть принципиальные отличия по сравнению с предыдущей версией.

Появился всегда-блок, представляющий собой описание регистра (именно то, что мы хотели).

Для работы всегда-блока также появились входы модуля clk (тактовая частота) и сброс (сброс).

Видно, что выход сумматора фиксируется в триггере, описанном всегда.

Еще есть пара сигналов включения ena, но они нам не очень интересны.

Давайте посмотрим на схему, которую сейчас синтезирует Quartus.

Пишем для FPGA без HDL. Сравнение инструментов разработки высокого уровня

Рисунок 5 И снова результаты хорошие и ожидаемые.

На рисунке ниже представлена таблица используемых ресурсов — имейте это в виду.



Пишем для FPGA без HDL. Сравнение инструментов разработки высокого уровня

Рисунок 6 Mathworks получает оценку за это первое задание.

Все не сложно, предсказуемо и с желаемым результатом.

Я достаточно подробно описал простой пример, привел схему блока DSP и описал возможности использования настроек использования регистров в HDL-кодере, отличных от настроек «по умолчанию».

Это было сделано не просто так.

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



HLS-компилятор от Intel

Попробуем собрать аналогичный по функционалу код, написанный на C++, и посмотреть, что в итоге синтезируется на ПЛИС с помощью HLS-компилятора.

Итак, код на C++.



component unsigned int TwoMultAdd(unsigned char a, unsigned char b, unsigned char c, unsigned char d) {

Теги: #Электроника для начинающих #Высокая производительность #C++ #hls #matlab #FPGA #verilog #HDL

Вместе с данным постом часто просматривают:

Автор Статьи


Зарегистрирован: 2019-12-10 15:07:06
Баллов опыта: 0
Всего постов на сайте: 0
Всего комментарий на сайте: 0
Dima Manisha

Dima Manisha

Эксперт Wmlog. Профессиональный веб-мастер, SEO-специалист, дизайнер, маркетолог и интернет-предприниматель.