В предыдущей статье я поделился опытом работы с ПЛИС фирмы Lattice через инструменты с открытым исходным кодом Yosys и NextPNR. Как я отмечал, освоить их меня заставило не столько любопытство, сколько требования Заказчика. В том проекте у меня просто не было выбора. И та статья, скорее, была написана в помощь для быстрого старта тем, кого тоже заставят. А можно ли использовать эту сцепку для дома, для семьи? Для этого она должна быть удобной.  Как мы обсудили в комментариях к прошлой статье, в минусы этой сцепке можно записать отсутствие такого полезного инструмента, как SignalTap (Altera) или ChipScope (Xilinx). Замену этой парочке пока что удалось найти только в виде физического анализатора. Так себе замена, но хоть что-то.  Более серьёзная трудность заключалась в том, что все примеры, которые я находил, были реализованы на чистом Верилоге. А я уже не могу писать автоматы, не используя такой механизм, как enum. Меня каждый раз злит необходимость перенумеровывать состояния, если я правлю автомат по ходу разработки. Но чтобы был enum, надо пользоваться более прогрессивным стандартом языка, который уже называется SystemVerilog. На странице Yosys  YosysHQ/yosys: Yosys Open SYnthesis Suite (github.com) описано, что данный язык ограниченно поддерживается синтезатором, и даже указана опция для его использования. А именно сказано, что команде read_verilog надо добавить ключ –sv. Но попытки найти в сети готовую инструкцию для новичков, как её активировать, я не нашёл, потому что если кто-то и пользуется этой командой, то для одного файла, а не для списка. Наконец, я разобрался, поэтому делаю такую инструкцию, чтобы любой желающий смог быстро найти готовое решение.  В прошлой статье я ссылался на пример makefile, из которого Yosys запускается так: yosys -p "synth_ecp5 -top $(FPGA_TOP) -json $@ -abc2" $(SYN_FILES_REL) То есть, сначала задаётся имя файла (yosys), затем идёт ключ –p и очень длинный аргумент в кавычках. После закрывающих кавычек идёт список обрабатываемых файлов. В свою очередь, аргумент –p говорит, что там будет идти строка скрипта. И все ключи –top, -json и –abc2 относятся уже не к ключам запуска программы, а к ключам команды скрипта, которая называется synth_ecp5. Хитро?  Точно! Но погодите, это только начало! Правда, это надо понять, но запоминать не надо. Но чтобы понять, продолжаем углубляться в теорию. Гугль подсказал мне, что перечень доступных команд скрипта можно найти вот тут: Yosys Open SYnthesis Suite :: Documentation (clairexen.net)  Вот кусочек этого перечня: И тут мы выясняем, что synth_ecp5 – это всего лишь макрокоманда, которая распадается на множество других команд. Теоретически, она даже может быть заменена скриптом из них, только надо брать актуальную расшифровку не из этой документации, а из реальных исходников. Но то в теории. На практике – просто глянем на начало раскрытия этого макроса и задумчиво почешем голову: Что мы сейчас выяснили? Для достижения нашей цели, мы не можем ограничиться одной строкой скрипта. Нам надо как-то сделать скрипт с командами read_verilog, часть из которых будет иметь ключ –sv.  Кстати, если внимательно порыться по документации, можно найти вот такую команду: Я пробовал применить её, чтобы задать опцию –sv по умолчанию. Не помогло. Так что вроде скрипт делать надо! Но как? Решение я нашёл вот в этом проекте ghent360/riscvOnColorlight-5A-75B: RISC-V soft core running on Colorlight 5B-74B. (github.com). Чтобы его собрать, надо установить среду Litex. Коротко я про неё уже рассказывал в прошлой статье. Возможно (если интерес к теме не угаснет) я посвящу этой среде одну-две отдельных статьи. Там есть, что рассказать. В частности, указанный проект под Windows не соберётся. Надо будет поправить совсем чуть-чуть в штатных скриптах… Но чтобы не отвлекаться от темы SystemVerilog, мы просто соберём проект строго в Линуксе. И наконец получим эталонный пакетный файл, содержащий вот такую строку для запуска Yosys: yosys -l colorlight_5a_75b.rpt colorlight_5a_75b.ys В отличие от того, что я показывал выше, здесь нет никакого ключа –p. Ключ –l задаёт файл лога, куда будут сохранены все тексты, выведенные на экран. И дальше идёт аргумент colorlight_5a_75b.ys. А это – имя файла скрипта. Прекрасно! Заглянем в него! verilog_defaults -pushverilog_defaults -add –defer read_verilog VexRiscv_Linux.vread_verilog gateware/colorlight_5a_75b.v verilog_defaults -popattrmap -tocase keep -imap keep="true" keep=1 -imap keep="false" keep=0 -remove  keep=0synth_ecp5   -json colorlight_5a_75b.json -top colorlight_5a_75b Мне кажется, что первые две строки задают очень полезную вещь. Можно ли без них – я точно не знаю. Я просто пользуюсь этой «рыбой». Но возможно, именно они позволяют загрузить не один, а несколько файлов. Поэтому дальше идут две строки с двумя файлами. Целевая платформа и процессор с архитектурой RISC-V. То есть, у нас имеется пример скрипта, содержащего не одну, а целых две команды read_verilog! Это – то, что я так долго искал и до сих пор не мог найти средствами Гугля! Потом идёт строка, комплементарная к первой. Суть предпоследней строки мне пока что неведома. И, наконец, последняя очень похожа на ту, которую вызывал makefile из предыдущего раздела. Ну, собственно, и всё. На радостях, я написал вот такой скрипт (часть несущественных строк выкинута): verilog_defaults -pushverilog_defaults -add -deferread_verilog -sv ../rtl/fpga.vread_verilog ../rtl/fpga_core.vread_verilog ../rtl/rst_gen.vread_verilog ../rtl/lfsr_yosys.vread_verilog -sv ../rtl/sdram.svread_verilog ../lib/eth/rtl/iddr.vread_verilog ../lib/eth/rtl/oddr.vread_verilog ../lib/eth/rtl/ssio_ddr_in.v…read_verilog ../lib/eth/lib/axis/rtl/axis_fifo.vread_verilog ../lib/eth/lib/axis/rtl/sync_reset.vverilog_defaults -popattrmap -tocase keep -imap keep="true" keep=1 -imap keep="false" keep=0 -remove keep=0synth_ecp5 -top fpga -json fpga.json –abc2 Как видим, у двух строк есть ключи –sv. И в тех файлах имеется SystemVerilog код. Файл sdram я просто взял из проекта эмулятора БК, как пример среднестатистического SystemVerilog кода. Он не выдаёт ошибок! В файл fpga я вставлял свой код. К сожалению, там работает не всё, к чему я привык в Квартусе. Вот такая строка приведёт к ошибке enum {red,redyellow,green,yellow,black} state = red; Но если убрать начальное присвоение  – всё заработает.  enum {red,redyellow,green,yellow,black} state; А чтобы начальное присвоение заработало – надо применять typedef. Всяк лучше, чем ничего! И, в конце концов, лучше присваивать начальное значение в обработчике сигнала reset. Когда я показал идею коллегам, мне объяснили, что я не совсем прав. Я вызываю этот скрипт из makefile вот так: yosys ../common/colorlight_5a_75b.ys А список файлов, как я отметил, заранее помещён мною в тело скрипта. Мне объяснили, что ценность makefile в том, что он не вызывает средство сборки, если исходные тексты не изменялись, а для этого список должен формироваться внутри него. Для остальных случаев необходимо и достаточно использовать не makefile, а простой пакетный файл. Но зная текущую теорию, можно найти и пример в тему. Вот так каждый раз формирует скрипт makefile из примера от платы Orange Crab: orangecrab-examples/Makefile at main · orangecrab-fpga/orangecrab-examples · GitHub Все желающие сделать красиво, могут воспользоваться им и сформулировать правила для добавления файлов с расширениями *.v и *.sv. Первые будут добавляться без ключа, вторые – с ним. К целям статьи это уже не относится. Целью статьи было показать реально работающий пример скрипта, понимающего исходные тексты на языке SystemVerilog. Когда идея ясна – дальше каждый уже сможет сделать собственные решения в силу своего понимания красоты. Системное ПО, инструменты для разработчиков