
Однажды мне не спалось ночью и я залип на сайтах про паяльники. Возникло желание купить и сразу появились вопросы: на сколько ватт? Не больше 30? А почему большинство на 60-80 ватт? 60/40 олово свинец? А почему куча паяльных станций идут в комплекте с lead-free проводами припоя? Канифоль сейчас внутри проводов? А почему есть и провода припоя без канифоли? Бронзовую мочалку для очистки? А почему столько комплектов с и белой и бронзовой?
Вспомнил и повод, чтобы научиться паять. Когда-то Руслан Тихонов, руководитель кружка из Москвы, говорил мне что хочет сделать простые упражнения на платах ПЛИС для школьников. Как часть триады «микросхемы малой степени интеграции — ПЛИС — Ардуино». По этому поводу я купил самую дешевую плату с CPLD Altera MAX II (ныне это Intel FPGA), но обнаружил что у нее не припаян переходник.
Я выставил вопросы по паяльники на фейсбук и после оживленной дискуссии мой приятель Денис Никитин вызвался научить меня паять как полагается. Денис работает проектировщиком печатных плат в компании Zoox, ныне часть компании Amazon. Zoox делает беспилотные автомобили, то есть Денис на передовом рубеже паятельного прогресса. Я заснял мастер-класс от Дениса на видео:
Часть 1. Пайка
Часть 2. Плата ПЛИС, которую мы паяли
Что же из себя представляет плата, которую паяли мы вместе Денисом? Это самая базовая плата ПЛИС, которая бывает, и при этом на ней можно делать полезные упражнения, например познакомить школьников с проектированием цифровых схем на уровне регистровых передач с использованием языка описания аппаратуры SystemVerilog.
Вот сравните как работает макетка с микросхемами малой степени интеграции и плата с ПЛИС. Реализация сдвигового регистра на макетной плате с помощью микросхемы малой степени интеграции CMOD 4015:
Реализация двоичного счетчика на плате ПЛИС:
Внешне выглядит похоже, но первое — технология 1968 года, а второе — технология 2022 года: схема синтезирована из кода на языке описания аппаратуры SystemVerilog с помощью программы Intel Quartus Prime Lite Edition Design Software Version 22.1 (скачать для Linux и для Windows ):
Код для синтеза двоичного счетчика:

Вот как выглядит синтезируемая схема сдвигового регистра в Intel Quartus:

Часть 3. Связь рассыпухи, ПЛИС и Ардуино
Насчет микросхем малой степени интеграции у многих руководителей кружков есть сомнения: «ой, а зачем давать детям технологию 1968 года, это же остатки мамонта?» — спросят некоторые из них и прибавят: «Детям нужно Ардуино и Расберри Пай!»
А затем, что на микросхемах малой степени интеграции максимально наглядно видна работа базовых элементов интегральных схем — И / ИЛИ / НЕ, D-триггеров, мультиплексоров, декодеров итд — всего, из чего состоят в том числе микроконтроллеры на платах Ардуино. Например функцию D-триггера:
Никакое количество программирования Ардуино не заменит это знание, примерно так же как самые хорошие навыки во вождению автомашины не приблизят к навыкам по проектированию ее двигателя.

Другое дело, что за навыки по сборке на макетке микросхем малой степени интеграции вам не будут платить зарплату. И вот тут на помощь и приходит ПЛИС — именно ПЛИС прокладывает мостик между старыми и современными технологиями.
Когда вы синтезируете цифровые схемы и программируете их в ПЛИС, вы используете тот же язык проектирования Verilog, который использует и проектировщик микроконтроллера AVR на Ардуино, сидя в своем офисе в Колорадо Спрингс, и проектировщик микропроцессорного ядра ARM в Расберри Пай, сидя в своем офисе в Кембридже.

Часть 4. Главная технология проектирования микросхем в последние 30 лет
Немного про отличие процесса программирования от процесса проектирования микросхемы с помощью синтеза из языка описания аппаратуры (это стандартная методология проектирования микросхем последние 30 с лишним лет). Программирование — это превращение кода в цепочку инструкций, которые хранятся в памяти и которые оттуда вытаскивает и переваривает процессор:

А синтез схем на языке описания аппаратуры — это другой процесс, при котором получается сама схема из транзисторов и дорожек, в том числе и схема современного микропроцессора, в том числе и в Ардуино. Эта схема в формате геометрических фигур GDSII отправляется на фабрику, где по ней печатают микросхемы:

Все вместе и становится аппаратно-программным комплексом, который и представляет из себя Ардуино:

Часть 5. Природа ПЛИС
«Стоп!» — скажут некоторые читатели. «Но ведь микросхема выпекается на фабрике, а вы говорите что схема в ней потом меняется. Как это может быть?»
Пояснение: схема меняется в ПЛИС, а не обычном микроконтроллере Ардуино, который является вариантом микросхем ASIC (Application-Specific Integrated Circuits). ASIC строится из рядов фиксированных ячеек (так называемых standard cells). Их функция задается «при рождении». Одна ячейка — всегда И, другая — всегда D-триггер.
А вот функцию ячейки в ПЛИС можно менять — в ПЛИС находится «универсальная ячейка», гораздо крупнее, чем ячейка в ASIC. Она соединяется со специальной памятью, и биты в этой памяти определяют, через специальные переключатели / мультиплексоры, является ли ячейка И, ИЛИ, D-триггером или еще чем-то — уже на вашем столе, а не на фабрике.
Это не симулятор процессора в софтвере (в России симуляторы на уровне инструкций называются «эмуляторами», но это мы обсудим в другом посте). Симулятор процессора в софтвере — это программа, цепочка инструкций, а здесь конфигурация матрицы ячеек.
Из ячеек ПЛИС можно построить и аналог микропроцессорного ядра в Ардуино, но он будет дороже, с более низкой тактовой частотой и будет потреблять больше электроэнергии, чем фиксированная микросхема. Такова плата за гибкость.

Часть 6. Отступление о временах и нравах
Да, из ячеек ПЛИС можно строить даже процессор! Это тот самый «процессор в памяти», в существование которого 10 лет назад не верили топ-блоггеры Андрей Нифедов и Алекс Экслер. Они вместе высмеивали кружок электроники в Иркутске, хотя через лабы на платах ПЛИС прошли в свое время все современные проектировщики айфонов и микросхем в Теслах, это стандартная часть курса MIT 6.111.
Учитывая, что Нифедов — бывший оператор станка с ЧПУ, а Экслер — обозреватель гаджетов, это было удивительно и поучительно! Особенно тысячи безумных комментов под их постами от людей, которые наверное думают, что раз они научилились тыкать пальцем в телефон, то что-то понимают как обучать будущих проектировщиков телефонов.

Часть 7. Пакет для обучения школьников с платами ПЛИС
Если какой-нибудь руководитель кружка хочет такое у себя внедрить, я создал проект на сайте GitFlic.ru под названием Пайка, ПЛИС и Линукс или FPGA Soldering Camp. Его описание «Исходники, презентации, задания и примеры для летнего лагеря по пайке, микросхемам ПЛИС и синтезу цифровых схем из кода на верилоге под Линуксом».

То есть идея в том, что школьники совершают своего рода многоборье, которое состоит из:
-
Работе с паяльником — 1 день
-
Работе с макетными платами и микросхемами малой степени интеграции — 2 дня, потом им надоедает
-
Синтезу цифровых схем на ПЛИС с простой платой — от 2-3 дня
-
Работа с более сложной платой ПЛИС и например разработка простого однотактового процессора. Или интерфейс простой платы ПЛИС с Ардуино, если руководитель кружка хочет идти в эту сторону.
-
Все это делается под Линуксом, чтобы привыкали. Все разработчики микросхем для Тесл и Айфонов делают синтез и моделирование под Линуксом просто потому что они используют Synopsys Design Compiler и Cadence Genus и Innovus, у которых нет версий ни под Windows, ни под Макинтошем, только под Linux.
Впрочем, если вам очень не нравится Linux, пакет работает и под Windows (так как у Intel FPGA Quartus есть версия и под Linux, и под Windows).

Часть 8. Предыдущий опыт семинаров для школьников с микросхемами малой степени интеграции и ПЛИС
Вообще я опробовал лагерь такого рода несколько лет назад на Новосибирской Летней Школе Юных Программистов и в других местах (Киев, Москва, Зеленоград). См. мои другие статьи на хабре или на silicon-russia.com .

Вот одно из видео оттуда, с восьмикласником Арсением Чегодаевым:
Часть 9. Как скачать пакет и текущие примеры в нем
Пакет можно или клонировать с помощью Git, или скачать релиз одного из двух видов пакета:
-
Пакет для использования со скриптами, написаными на баше. Со скриптами работать быстрее, но для начинающих GUI может быть удобнее в освоении.
В пакет входят следующие примеры:
01_and_or_not_de_morgan — обычные И, ИЛИ, НЕТ, правила де Моргана на SystemVerilog:
assign out_c1 = ~ (~ in_a & ~ in_b); assign out_c2 = in_a | in_b; // Here is where De Mongan's Laws come in
02_xor_bitwise_concat_and_parity — операции с исключающим ИЛИ на SystemVerilog.
Аналог такого примера на микросхемах малой степени интеграции выглядит так:
03_add_signed_and_unsigned — сумматор со знаком и без знака
С микросхемами малой степени интеграции (CMOS 4008) аналог выглядит так:

04_mux — реализации мультиплексора на SystemVerilog пятью разными способами:
// Five different implementations assign mux = sel ? a : b; assign mux2 = (sel & a) | (~ sel & b); wire [1:0] ab = { a, b }; assign mux3 = ab [sel]; always_comb if (sel) mux4 = a; else mux4 = b; always_comb case (sel) 1'b1: mux5 = a; 1'b0: mux5 = b; endcase
05_binary_counter — уже показал в начале статьи. Вот его аналог с подсоединенной микросхемой-драйвером для семисегментного индикатора. Семисегментный индикатор можно подсоединить и к ПЛИС тоже:
06_shift_register — сдвиговый регистр, уже показал в начале статьи
Четыре способа реализации декодера на SystemVerilog
module top ( input [2:0] in_n, output [7:0] out_n ); wire [2:0] in = ~ in_n; logic [7:0] out; assign out_n = ~ out; // Implementation 1: tedious assign out [0] = ~ in [2] & ~ in [1] & ~ in [0]; assign out [1] = ~ in [2] & ~ in [1] & in [0]; assign out [2] = ~ in [2] & in [1] & ~ in [0]; assign out [3] = ~ in [2] & in [1] & in [0]; assign out [4] = in [2] & ~ in [1] & ~ in [0]; assign out [5] = in [2] & ~ in [1] & in [0]; assign out [6] = in [2] & in [1] & ~ in [0]; assign out [7] = in [2] & in [1] & in [0]; // Implementation 2: case always_comb case (in) 3'b000: out = 8'b00000001; 3'b001: out = 8'b00000010; 3'b010: out = 8'b00000100; 3'b011: out = 8'b00001000; 3'b100: out = 8'b00010000; 3'b101: out = 8'b00100000; 3'b110: out = 8'b01000000; 3'b111: out = 8'b10000000; endcase // Implementation 3: shift assign out = 8'b00000001 << in; // Implementation 4: index always_comb begin out = '0; out [in] = 1'b1; end
Аналогичный декодер на микросхемах малой степени интеграции выглядит так:
Приоритетный энкодер на SystemVerilog четырьмя способами
module top ( input [3:0] in_n, output [7:0] out_n ); wire [3:0] in = ~ in_n; logic [1:0] out0, out1, out2, out3; assign out_n = ~ { out0, out1, out2, out3 }; // Implementation 1. Priority encoder using a chain of "ifs" always_comb if (in [0]) out0 = 2'd0; else if (in [1]) out0 = 2'd1; else if (in [2]) out0 = 2'd2; else if (in [3]) out0 = 2'd3; else out0 = 2'd0; // Implementation 2. Priority encoder using casez always_comb casez (in) 4'b???1: out1 = 2'd0; 4'b??10: out1 = 2'd1; 4'b?100: out1 = 2'd2; 4'b1000: out1 = 2'd3; default: out1 = 2'd0; endcase // Implementation 3: Combination of priority arbiter // and encoder without priority localparam w = 4; wire [w - 1:0] c = { ~ in [w - 2:0] & c [w - 2:0], 1'b1 }; wire [w - 1:0] g = in & c; always_comb unique case (g) 4'b0001: out2 = 2'd0; 4'b0010: out2 = 2'd1; 4'b0100: out2 = 2'd2; 4'b1000: out2 = 2'd3; default: out2 = 2'd0; endcase /* // A variation of Implementation 3: Using unusual case of "case" always_comb unique case (1'b1) g [0]: out2 = 2'd0; g [1]: out2 = 2'd1; g [2]: out2 = 2'd2; g [3]: out2 = 2'd3; default: out2 = 2'd0; endcase */ // A note on obsolete practice: // // Before the SystemVerilog construct "unique case" // got supported by the synthesis tools, // the designers were using pseudo-comment "synopsys parallel_case": // // SystemVerilog : unique case (1'b1) // Verilog 2001 : case (1'b1) // synopsys parallel_case // Implementation 4: Using "for" loop always_comb begin out3 = '0; for (int i = 0; i < w; i ++) begin if (in [i]) begin out3 = 2' (i); break; end end end endmodule
Приоритетный энкодер на микросхемах малой степени интеграции, вместе с микросхемой-драйвером семисегментного индикатора выглядит так:
Числа Фибоначчи, которые выводятся медленно, не на частоте 50 MHz
module top ( input clk, input rst_n, output [7:0] led ); wire rst = ~ rst_n; //------------------------------------------------------------------------ logic [24:0] cnt; always_ff @ (posedge clk) if (rst) cnt <= '0; else cnt <= cnt + 1'd1; wire enable = (cnt == '0); //------------------------------------------------------------------------ logic [7:0] num, num2; assign led = ~ num; // Note you have to press reset button to initialize the design always_ff @ (posedge clk) if (rst) { num, num2 } <= { 8'd1, 8'd1 }; else if (enable) { num, num2 } <= { num2, num + num2 }; endmodule
10_round_robin_arbiter — а вот это уже пример не школьный, а студенческий. Арбитр-мельница, популярный вопрос на интервью в электронные компании для джуниора. Пять реализаций по мотивам статьи Matt Weber. Arbiters: Design Ideas and Coding Styles. SNUG Boston 2001.
Часть 10. Можно ли выучить все это на программном симуляторе?
Две проблемы:
Во-первых, на SystemVerilog можно написать код, который будет работать в симуляторе, но не будет синтезироваться в схему, так называемый несинтезируемый код, который пишется для тестов и моделей.
Во-вторых, даже если код синтезируется, он может глючить на плате, например из-за так называемых гонок (race condition). Чтобы они не происходили, нужно соблюдать правила методологии, в частности не использовать блокирующие присваивания для переменных, которые превращаются в D-триггеры, например «a» внутри:
always @ (posedge clk) a = b; always @ (posedge clk) c = a;
В-третьих, код может симулироваться, но глючить на плате из-за метастабильного состояния, дребезга и нарушения тайминга внутри такта. Конечно, можно обязать ученика пропускать код через статический анализ тайминга одновременно с симуляцией, но без глючащей платы это выглядит как придирчивость преподавателя, а не реальное требование. Реальное железо лучше научит!
Часть 11. Что означают дополнительные файлы (причем на языке Tcl 😎 в пакете?
Кстати, раз уж мы заговорили о нарушении тайминга и других таких параметрах. Преподавателю во время показа этих примеров ученикам, помимо кода на верилоге также нужно показать код на языке Tcl (знать его не обязательно) в двух файлах — top.qsf и top.sdc. Первый привязывает логические порты блока к физическим ножкам микросхемы.
Выглядит файл top.qsf так:
set_global_assignment -name DEVICE EPM240T100I5 set_global_assignment -name NUM_PARALLEL_PROCESSORS 4 set_global_assignment -name PROJECT_OUTPUT_DIRECTORY . set_global_assignment -name TOP_LEVEL_ENTITY top set_global_assignment -name SEARCH_PATH .. set_global_assignment -name SYSTEMVERILOG_FILE top.sv set_location_assignment PIN_72 -to in_n[3] set_location_assignment PIN_73 -to in_n[2] set_location_assignment PIN_70 -to in_n[1] set_location_assignment PIN_71 -to in_n[0] set_location_assignment PIN_56 -to out_n[7] set_location_assignment PIN_57 -to out_n[6] set_location_assignment PIN_54 -to out_n[5] set_location_assignment PIN_55 -to out_n[4] set_location_assignment PIN_52 -to out_n[3] set_location_assignment PIN_53 -to out_n[2] set_location_assignment PIN_50 -to out_n[1] set_location_assignment PIN_51 -to out_n[0]
Второй файл, top.sdc, задает тактовые сигналы и говорит тулу для синтеза, что задержки на сигналах между внешним миром и D-триггерами анализировать не нужно. В какой-то момент обучения, например когда школьник захочет умножать или делить большие числа и обнаружит, что плата глючит, можно будет объяснить значение строчки в этом файле, которая говорит, что комбинационная логика внутри схемы обязана устаканиваться максимум за 20 наносекунд (1 / 50 MHz) иначе логику нужно разносить в несколько тактов:
Файл top.sdc выглядит так:
create_clock -period "50.0 MHz" [get_ports clk] derive_clock_uncertainty set_false_path -from [get_ports rst_n] -to [all_clocks] set_false_path -from [get_ports {key[*]}] -to [all_clocks] set_false_path -from * -to [get_ports {led[*]}]
Главный файл проекта, top.qpf, может оставаться пустым — Quartus хранит в нем всякий мусор типа даты и своей версии. Все реальные установки Quartus берет из .qsf и .sdc.
Разнообразный тьюториалы от Altera и Intel показывают, как связывать порты и ножки в GUI мышкой, но я так никогда не делаю — сначала вы можете просто использовать файлы выше, а когда вам понадобиться их менять, вы можете просто поменять текст, например добавить еще одну ножку. Все ножки перечислены в fpga-soldering-camp/boards/epm240_red/00_template/top.qsf
Часть 12. Установка Quartus под Линукс
Quartus ставится под Linux без особых сюрпризов. Скачать его можно отсюда. После инсталляции, когда вы его запустите и дойдете вот до этого места, нужно нажать «Run»:

Я пробовал Quartus под Lubuntu, ALT Linux Образование, Simply Linux, Astra Linux, Ред ОС, ROSA Linux и Green Linux. Он везде работает, но инсталлятор путается в создании иконки на рабочем столе в русских дистрибутивах.
Вы можете создать иконку руками, заведите вот такой файл в «/home/$USER/Рабочий стол» (вместо «panchul» поставьте своего юзера):
[Desktop Entry] Type=Application Version=0.9.4 Name=Quartus (Quartus Prime 21.1) Lite Edition Comment=Quartus (Quartus Prime 21.1) Icon=/home/panchul/intelFPGA_lite/21.1/quartus/adm/quartusii.png Exec=/home/panchul/intelFPGA_lite/21.1/quartus/bin/quartus --64bit Terminal=false Path=/home/panchul/gitflic/fpga-soldering-camp/boards/epm240_red
Перед тем, как вы попытаетесь сконфигурировать плату, вам нужно записать в директорию /etc/udev/rules.d файл с правилами для программатора USB Blaster. Самый простой способ это сделать — это просто кликнуть в скрипт под названием ВЫПОЛНИ_МЕНЯ_ПРИ_РАБОТЕ_ПОД_ЛИНУКСОМ_ПЕРЕД_ПЕРВЫМ_ЗАПУСКОМ_КВАРТУСА.bash и потом ввести пароль. Этот файл находится сразу внутри директории раззипованного пакета fpga-soldering-camp_20230108_gui_oriented.zip. Правда вы должны быть в списке пользователей, которые имеют право сделать sudo. Проконсультируйтесь со знакомым линуксоидом, если вы не в курсе этого вопроса. Потом вы будете работать внутри GUI Quartus и вопросы администрирования Линукса теоретически вас больше не затронут:


Когда войдете в GUI, кликайте не на «File | Open», а на «File | Open Project» — эту ошибку делают все, даже я, после многих лет работы с квартусом. Потом действуйте по какой-нибудь инструкции в интернете, на худой конец попросите помощи в телеграм-канале DigitalDesignSchool или FPGA-Systems.ru или на вебсайте Марсоход. Общая идея — Compile Design, Program Design, нажмите на checkbox, Start. Если не получается Start, нажмите Hardware Setup и кликните на USB Blaster.
Если программатор зависает, повтыкайте-повытыкайте, повходите-повыходите из квартуса, поперезагружайте. В Интеле эту часть продукта пишут не самые аккуратные программисты (самых аккуратных переманили в Гугл неподалеку), но после некоторого массажирования оно работает.
Если вы скачали версию пакета для использования со скриптами, fpga-soldering-camp_20230108_script_oriented.zip, то вы наверное можете разобраться как она работает без меня. Если кратко — вы просто заходите в директорию каждого примера и запускаете скрипт ./03_synthesize_for_fpga.bash . Скрипт создает временную директорию run для всех файлов, которые генерит Quartus, выполняет синтез, размещение, трассировку и конфигурацию ПЛИС. Вы только читаете текстовые отчеты о тайминге и ресурсах и смотрите на работу платы.
Часть 13. Установка Quartus под Windows
Если вы очень не любите Linux и хотите использовать пакет под Windows, вы можете это сделать. К сожалению, у вас может возникнуть проблема с Windows 11, который не любит старые неподписанные драйверы для USB Blaster. Но на Windows 10 все скорее всего будет работать после того как вы обновите драйвер. Драйвер находится прямо в дистрибутива квартуса:

Вы также можете использовать версию пакета fpga-soldering-camp со скриптами, но тогда вам нужно установить Git для Windows, который включает в себя bash и все необходимые программы. При установке Git под Windows стоит поставить вот такую опцию.

Заключение
В заключение я хочу сказать, что в России есть платы Марсоход, которые полностью подходят для тех же целей, что и красная платка, которую я использовал для этого пакета. Просто красная платка для меня дешевле и мне ее проще заказать.
Информация о том, где купить платы, переходники и т.д. есть в README.md файле в пакете и в репозитории https://gitflic.ru/project/yuri-panchul/fpga-soldering-camp . Если вы хотите помочь в разработке примеров, вы можете завести аккаунт на gitflic.ru , клонировать репозиторию и сообщать мне о вашем прогрессе.
ссылка на оригинал статьи https://habr.com/ru/post/715012/
Добавить комментарий