Показаны сообщения с ярлыком hdl. Показать все сообщения
Показаны сообщения с ярлыком hdl. Показать все сообщения

понедельник, 4 сентября 2017 г.

Как начать работать с HDL и ПЛИС (FPGA)

Предисловие

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

Современные тенденции

К сожалению, а может быть и к счастью (в зависимости как на это посмотреть) разработка современной электроники, особенно цифровой, но не только сводится к описанию цифровых функций и автоматов сводится к описанию их на основе одного из HDL (Hardware Description Language) -языков описания аппаратуры. На данный момент, существуют следующие языки описания аппаратуры: AHDL, VHDL, Verilog и System Verilog. Сами ПЛИС (CPLD, FPGA) представляют собой квадратные матрицы ячеек (состоящих из сотен - тысяч, в зависимости  от ресурсов ПЛИС, логических элементов), к этим ячейкам подходят магистрали источников синхросигналов (клоков) и линий питания (+5 или +3,3 В) и земли.  К слову говоря, современные ПЛИС (7 серия от Xilinx, 5 поколение Cyclone и т.п.) - это SoC в которых кроме, самой ПЛИС присутствует процессорное ядро и аппаратная поддержка различных интерфейсов таких, как : USB, Ethernet, CAN, SPI, I2C, RS232 и др.

Три кита разработки цифровых устройств с использованием ПЛИС (FPGA)

 1. Основа всего это алгебра логики (булева алгебра) и способы построения простых цифровых схем и автоматов с использованием алгебры логики.

2. Схемотехника входных и выходных каскадов логических элементов (для понимания, что такое высокоимпедансное Z-состояние, нагрузочные характеристики элементов, схемы с открытым коллектором).

3. И, конечно, 3 этап это способы построения простых цифровых схем с использованием языков описания аппаратуры.

Алгебра логики

Основными в алгебре логики являются следующие вещи:

1) Принцип двойственности
2) Теорема Де-Моргана 
 
 Эти два принципа можно посмотреть, например, здесь: https://studme.org/2002061028280/tovarovedenie/algebra_logiki . Позже сам напишу про алгебру логики.

Так же следует упомянуть про способы представления (алгебраическое, табличное и в виде карт/диаграм Карно и Вена) и минимизации логических функций через карты Карно или другие методы, например, метод Мак-Класки (https://ru.wikipedia.org/wiki/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%9A%D1%83%D0%B0%D0%B9%D0%BD%D0%B0_%E2%80%94_%D0%9C%D0%B0%D0%BA-%D0%9A%D0%BB%D0%B0%D1%81%D0%BA%D0%B8).

Одна неплохая презентация про алгебру логики: https://drive.google.com/file/d/0B9GLCHSwsJn8cURyT3BOUEVxdVE/view?usp=sharing

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

- мультиплексоры
- дешифраторы
- преобразователи кода
- и другие схемы.

Вот, например, https://drive.google.com/open?id=0B9GLCHSwsJn8NmxtTVNUOVZZbWs

 Следующий шаг - изучение последовательностных схем (схемы зависящие от состояния и сигналов на входе схемы).  Такими схемами являются:

-триггеры
-счетчики
-регистры
-генераторы
и др.

Например, https://distant.msu.ru/pluginfile.php/38192/mod_resource/content/1/%D0%9B%D0%B5%D0%BA%D1%86%D0%B8%D1%8F%204.pdf

или

https://drive.google.com/open?id=0B9GLCHSwsJn8YkJZeGtVZzZ4LTQ

а также ознакомиться с описанием цифровых автоматов (которых, 2 основных вида: Мили и Мура (https://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%B2%D1%82%D0%BE%D0%BC%D0%B0%D1%82%D1%8B_%D0%9C%D1%83%D1%80%D0%B0_%D0%B8_%D0%9C%D0%B8%D0%BB%D0%B8)

Схемотехника логических элементов

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

Прежде всего схемотехника зависит от типа логики: ТТЛ (ТТЛШ), КМОП и ЭСЛ: http://www.inp.nsk.su/students/radio/lectures/Pulse/07.pdf

Параметры логических элементов:
 http://myrepititor.ru/electronics/82-Osnovnye_xarakteristiki_i_parametry_logicheskix_eleme.html

http://audioakustika.ru/node/1555

Языки HDL, способы проектирования
У меня довольно большаыя подборка книг по ПЛИС: https://drive.google.com/open?id=0B9GLCHSwsJn8Z0Y3U24ybmxjVjA

Если использовать Verilog, то стоить начать с Verilog и VerilogTutorial, если VHDL - то "Языки Verilog и VHDL", кроме того среди этого архива есть документ с "Золотыми ссылками по HDL".


Что будет в продолжении?

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

воскресенье, 18 июня 2017 г.

Gated clock в HDL

Что такое Gated clock (and/or signal ripple) и его последствия

Недавно занимался одним из своих старых проектов (Quartus 9.1) и, перечитывая, в очередной раз, предупреждения компиляции проекта, обнаружил, что появился такой интересный ворнинг : "Found 1 node(s) in clock paths which may be acting as ripple and or gated clocks -- node(s) analyzed as buffer(s) resulting in clock skew".  Данное предупреждение оказалось связано с моим модулем, управляющим работой двухканальным счетчиком (каждый из счетчиков работает попеременно), сам модуль формирует сигнал адреса и сигналы разрешения и сброса счетчиков.

Прежде всего попытаемся понять, что же означает данное предупреждение. А означает оно то, что на линии тактового сигнала (клока) присутствует логический вентиль (gate). Поскольку мы имеем дело с конкретной микросхемой, а не с математической функцией, то прохождение сигнала через логические элементы всякий раз будет добавлять задержку на время переключения вентиля из 0 в 1 или из 1 в 0. Другая часть предупреждения говорит о том, что наличие вентиля будет приводить к пульсациям. На самом деле, в этом случае могут быть проблемы с переключением на линии клока, например, время переключения вентиля 10 нс, на линии клока пришло переключение из 0 в 1 (posedge), за эти 10 нс, предположим клок переключился из 1 в 0 и, потом, снова из  0 в 1 непрерывно с малыми интервалами, так вот gated clock отфильтрует часть переключений и, как следствие, часть важной информации может быть потеряна.

Как же удалось этого добиться?

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

assign counter0_enable = ~counter_address;
 assign counter1_enable = counter_address;

d_trigger counter0_force_clear_trigger (.clk(counter0_enable), .data(vcc), .reset(counter0_reset), .enable(enable), .out(counter0_force_clear));
- d_trigger counter1_force_clear_trigger (.clk(counter1_enable), .data(vcc), .reset(counter1_reset), .enable(enable), .out(counter1_force_clear));

counter_address генерируется периодически по другому сигналу с помощью Т-триггера. Самое интересное, что к этому эффекту приводит генерация сигналов в counterХ_enable через триггер. И как же быть в такой ситуации? Почитав, что пишут в интернетах и немного подумав, я использовал для клока триггеров исходный сигнал, а операцию выбора работы триггера по адресу перенес в enable (т.е. force_clear сигналы генерируются только в моменты когда enable на триггерах равен 1):

d_trigger counter0_force_clear_trigger (.clk(~channel), .data(vcc), .reset(counter0_reset), .enable(enable & counter1_enable), .out(counter0_force_clear));
+ d_trigger counter1_force_clear_trigger (.clk(channel), .data(vcc), .reset(counter1_reset), .enable(enable & counter0_enable), .out(counter1_force_clear));
На RTL View данная ситуация (gated clock) проявляется следующим образом:










Согласно этому изображению, проблема в шунтировании двух D-триггеров гэйтами.

Заключение
 В HDL бывает много "магии", но при этом всегда нужно внимательно читать все предупреждения, и обязательно смотреть результат синтеза проекта, иначе, даже несмотря на, хороший код, может возникнуть аналогичная ситуация.



суббота, 3 июня 2017 г.

Странности в Verilog-2001


Немного истории или появление ПЛИС и HDL
Ха-ха, здравствуйте-здравствуйте, дорогие читатели. Недавно я писал про странности, связанные с софтом, а именно - Vivado, но дело дошло до самого языка.Вообще для программирования FPGA/PLD/ПЛИС используют языки программирования, позволяющие описать прохождение цифровых электрических сигналов и реакцию цифровых схем на эти сигналы. В данной статье я не буду затрагивать вопросы, связанные с цифровой схемотехникой, булевой алгеброй (алгеброй логики и т.п.). Прообразом ПЛИС стали Программируемые логические матрицы (ПЛМ/PLM), построенные на основе N-в-1 логических элементах (ИЛИ/И), к которым подведены от 1 до N сигналов. Программирование осуществляется с помощью плавления перемычек между входами логических элементов:
Любая логическая функция и любые последовательностные схемы могут быть реализованы на базисных элементах. 

После ПЛМ появились ПЛИС представляющие собой несколько десятков слоев ПЛМ (например, семейство MAX7000). Далее ПЛИС стали сохранять конфигурацию во внутреннюю оперативную память, а конфигурация при старте загружалась с Flash-памяти.

Для описания связей между  логическими элементами (задания какие перемычки нужно включить, а какие убрать) были придуманы языки для описания аппаратуры (HDL): AHDL, VHDL и Verilog.  Наиболее востребованными являются 2 последних, лично я предпочитаю Verilog, т.к. он отдаленно напоминает классику - язык С, а VHDL - Pascal.

Этот странный Verilog

В этом разделе я опишу, пожалуй лишь несколько из странностей Verilog.

1. Доступ к параметрам модуля из функции

Доступ к параметрам  модуля невозможен из функции, например есть модуль:

module my_module #
(
      parameter PARAM_1 = 1
)
(
    // ports defenitions
);

localparam _PARAM_1_LOC = PARAM_1;

function[1:0] some_func();
// local variables defined here ...
      // <!!!!! в этой функции мне недоступен PARAM_1, но доступен PARAM_1_LOC
endfunction;

endmodule

Несмотря на то, что функция some_func принадлежит модулю my_module у нее нет доступа к параметрам модуля, но есть доступ к локальным параметрам.

2. Инверсия порядка бит в байте

Иногда необходимо изменить порядок следования бит в векторе на обратный, очень бы хотелось сделать так:

reg[7:0] byte_vector;

reg[7:0] inversed_byte_vector;
 // где-то внутри always
inversed_byte_vector = byte_vector[0:7]; // ОШИБКА КОМПИЛЯЦИИ

 К сожалению, это не работает, приходится использовать конкатенацию или цикл:

inversed_byte_vector = {byte_vector[0], byte_vector[1], ....byte_vector[7]}


3. Доступ к вектору по индексам

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

reg [31:0] my_vector;
reg [7:0] vector_part;

// где-то внутри always блока
vector_part = my_vector[29:22];

Но доступ по индексам возможен только тогда, когда передаются константы, поэтому приходится городить такие конструкции.

// присвоение внутри функции
reg[7:0] shift;
begin
shift = `MAX_DATA_WIDTH - NUMBER_OF_BYTES * 8;
// потом я не могу вырезать данные так:
result = data[MAX_DATA_WIDTH : shift]; // ошибка

для того, чтобы получить то, что я хочу, я должен сделать так:
result = data[`MAX_DATA_WIDTH - 1 : `MAX_DATA_WIDTH - NUMBER_OF_BYTES * 8];

 4. Чудесный мир литералов

Данная вещь куда как более тривиальна, но менее очевидна, для того, чтобы присвоить двоичное значение какому-нибудь регистру можно его записать как:

my_reg  = 8'b10001111; // Разрядность в битах, одинарная кавычка, латинская "бэ" и бит за битом (старшие биты идут вперед).

Но, что делать если нужно записать значение в 16-ричной системе счисления, т.к. 64 бита писать нереально утомительно, даже если пользоваться конкатом, для этих целей существует представление hex-литералов:

my_reg = 64'hAABBCCDDEEFF0011;
Хоть синтаксис и С подобный, но никаких тебе 0x и т.п.

Это не баги, это фичи
Verilog, конечно же, неплох, для описания HDL, но хочется, чтобы таких неудобств в нем было как можно меньше, учитывая, что последний раз стандарт выходил в 2001 г., а сам язык является наиболее популярным для программирования ПЛИС. Поэтому ждем перемен (с).

Распространение Windows-приложений (Chocolatey)

Менеджеры пакетов для ОС Windows В большинстве дистрибутивов Linux есть свои менеджеры пакетов: в Ubuntu/Mint это apt и deb, в OpenSuse э...