В предыдущей статье я поделился опытом работы с ПЛИС фирмы Lattice через инструменты с открытым исходным кодом Yosys и NextPNR. Как я отмечал, освоить их меня заставило не столько любопытство, сколько требования Заказчика. В том проекте у меня просто не было выбора. И та статья, скорее, была написана в помощь для быстрого старта тем, кого тоже заставят. А можно ли использовать эту сцепку для дома, для семьи? Для этого она должна быть удобной.

Как мы обсудили в комментариях к прошлой статье, в минусы этой сцепке можно записать отсутствие такого полезного инструмента, как SignalTap (Altera) или ChipScope (Xilinx). Замену этой парочке пока что удалось найти только в виде физического анализатора. Так себе замена, но хоть что-то.

Более серьёзная трудность заключалась в том, что все примеры, которые я находил, были реализованы на чистом Верилоге. А я уже не могу писать автоматы, не используя такой механизм, как enum. Меня каждый раз злит необходимость перенумеровывать состояния, если я правлю автомат по ходу разработки. Но чтобы был enum, надо пользоваться более прогрессивным стандартом языка, который уже называется SystemVerilog.

- А у вас есть такой же, но с SystemVerilog-ом?
- А у вас есть такой же, но с 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 -push
verilog_defaults -add –defer

read_verilog VexRiscv_Linux.v
read_verilog gateware/colorlight_5a_75b.v

verilog_defaults -pop
attrmap -tocase keep -imap keep="true" keep=1 -imap keep="false" keep=0 -remove keep=0
synth_ecp5   -json colorlight_5a_75b.json -top colorlight_5a_75b

Мне кажется, что первые две строки задают очень полезную вещь. Можно ли без них – я точно не знаю. Я просто пользуюсь этой «рыбой». Но возможно, именно они позволяют загрузить не один, а несколько файлов. Поэтому дальше идут две строки с двумя файлами. Целевая платформа и процессор с архитектурой RISC-V. То есть, у нас имеется пример скрипта, содержащего не одну, а целых две команды read_verilog! Это – то, что я так долго искал и до сих пор не мог найти средствами Гугля!

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

Собственно решение

Ну, собственно, и всё. На радостях, я написал вот такой скрипт (часть несущественных строк выкинута):

То же самое текстом.

verilog_defaults -push
verilog_defaults -add -defer
read_verilog -sv ../rtl/fpga.v
read_verilog ../rtl/fpga_core.v
read_verilog ../rtl/rst_gen.v
read_verilog ../rtl/lfsr_yosys.v
read_verilog -sv ../rtl/sdram.sv
read_verilog ../lib/eth/rtl/iddr.v
read_verilog ../lib/eth/rtl/oddr.v
read_verilog ../lib/eth/rtl/ssio_ddr_in.v

read_verilog ../lib/eth/lib/axis/rtl/axis_fifo.v
read_verilog ../lib/eth/lib/axis/rtl/sync_reset.v
verilog_defaults -pop
attrmap -tocase keep -imap keep="true" keep=1 -imap keep="false" keep=0 -remove keep=0
synth_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. Когда идея ясна – дальше каждый уже сможет сделать собственные решения в силу своего понимания красоты.

Комментарии (7)


  1. Khort
    07.12.2021 17:16

    Честно говоря, хотелось бы узнать

    1. Какие брали библиотеки, как подключали. Есть ведь, к примеру, в сети различные FreePDK с библиотеками селлов. Хочется видеть конкретные ссылки

    2. Как используется топологическая информация при синтезе - грузится LEF abstract, или используется допотопный wireload? А как быть с макро ячейками?

    3. Что получилось на выходе - просто structural verlog, или к примеру можно sdf выписать, а может быть даже timing_reports?

      Тема очень интересная, а бесплатных синтезаторов как бы и нет больше (поправьте, если не прав). К сожалению, у самого пока руки не дошли этот тул попробовать, отсюда и вопросы. Спасибо!


    1. EasyLy Автор
      07.12.2021 17:52

      Оххх. К сожалению, на большинство вопросов я не могу дать ответ. Я работаю на уровне разработчика несложных вещей.

      Yosys на выходе даёт JSON файл примерно такого вида:

          "DQSBUFM": {
            "attributes": {
              "blackbox": "00000000000000000000000000000001",
              "cells_not_processed": "00000000000000000000000000000001",
              "src": "/cygdrive/d/LATICE/yosys-master/share/ecp5/cells_bb.v:316.1-331.10"
            },
            "parameter_default_values": {
              "DQS_LI_DEL_ADJ": "FACTORYONLY",
              "DQS_LI_DEL_VAL": "00000000000000000000000000000000",
              "DQS_LO_DEL_ADJ": "FACTORYONLY",
              "DQS_LO_DEL_VAL": "00000000000000000000000000000000",
              "GSR": "ENABLED"
            },
            "ports": {
              "DQSI": {
                "direction": "input",
                "bits": [ 2 ]
              },
              "READ1": {
                "direction": "input",
                "bits": [ 3 ]
              },

      Кажется, он умеет выдавать не только JSON, но я особо не разбирался. NextPNR берёт его и выдаёт на выход *.config примерно такого вида

      .tile R11C19:PLC2
      arc: E1_H02E0701 V02S0701
      arc: H00R0100 E1_H02W0701
      arc: S1_V02S0201 E1_H02W0201
      arc: S1_V02S0301 S3_V06N0003
      arc: S1_V02S0501 E1_H01W0100
      arc: V00B0000 V02N0201
      arc: V00T0100 W1_H02E0301
      arc: W1_H02W0601 V02N0601
      arc: C5 V00T0100
      arc: CLK0 G_HPBX0200
      arc: D4 V00B0000
      arc: D5 H00R0100

      И, наконец, утилита ecppack, в моём случае, формирует *.bit и *.svf. А svf я гружу через OpenOCD.

      А так- глубоко не разбирался с файлами. Вот с timing reports - там забавно. Это я месяц сидел. Там в логе показывают всё о самой плохой цепи в каждом из тактовых доменов. Гипнотизируя сведения, можно догадаться, в каком файле и почему происходят задержки. Что приятно - все имена читаемые. Вот пример:

      Info: Critical path report for clock '$glbnet$clk' (posedge -> posedge):
      Info: curr total
      Info:  0.5  0.5  Source ethCore0.eth_mac_inst.eth_mac_1g_rgmii_inst.eth_mac_1g_inst.axis_gmii_tx_inst.gmii_tx_er_reg_TRELLIS_FF_Q_DI_LUT4_Z_B_LUT4_B_Z_LUT4_D_Z_CCU2C_S0_S1_LUT4_D_8_SLICE.Q1
      Info:  1.6  2.1    Net ethCore0.eth_mac_inst.eth_mac_1g_rgmii_inst.eth_mac_1g_inst.axis_gmii_tx_inst.frame_ptr_reg[7] budget 0.972000 ns (4,18) -> (4,19)
      Info:                Sink ethCore0.eth_mac_inst.eth_mac_1g_rgmii_inst.eth_mac_1g_inst.axis_gmii_tx_inst.s_axis_tready_reg_TRELLIS_FF_Q_DI_LUT4_Z_D_LUT4_Z_D_LUT4_B_Z_LUT4_Z_D_LUT4_Z_SLICE.C0
      Info:                Defined in:
      Info:                  ../rtl/fpga.v:202.3-215.2
      Info:                  ../lib/eth/rtl/eth_mac_1g_rgmii_fifo.v:218.1-246.2
      Info:                  ../lib/eth/rtl/eth_mac_1g.v:145.1-165.2
      Info:                  ../lib/eth/rtl/axis_gmii_tx.v:122.12-122.25
      Info:                  ../lib/eth/rtl/eth_mac_1g_rgmii.v:218.1-246.2
      Info:                  ../rtl/fpga_core.v:252.1-284.2
      Info:  0.2  2.3  Source ethCore0.eth_mac_inst.eth_mac_1g_rgmii_inst.eth_mac_1g_inst.axis_gmii_tx_inst.s_axis_tready_reg_TRELLIS_FF_Q_DI_LUT4_Z_D_LUT4_Z_D_LUT4_B_Z_LUT4_Z_D_LUT4_Z_SLICE.F0
      Info:  0.9  3.3    Net ethCore0.eth_mac_inst.eth_mac_1g_rgmii_inst.eth_mac_1g_inst.axis_gmii_tx_inst.s_axis_tready_reg_TRELLIS_FF_Q_DI_LUT4_Z_D_LUT4_Z_D_LUT4_B_Z_LUT4_Z_D[3] budget 0.972000 ns (4,19) -> (5,20)
      Info:                Sink ethCore0.eth_mac_inst.eth_mac_1g_rgmii_inst.rgmii_phy_if_inst.rgmii_tx_clk_fall_LUT4_B_Z_PFUMX_Z_C0_LUT4_Z_1_SLICE.C1
      Info:                Defined in:
      Info:                  /cygdrive/d/LATICE/yosys-master/share/ecp5/cells_map.v:109.23-109.24
      ...
      Info:  0.4  7.6  Setup ethCore0.eth_mac_inst.eth_mac_1g_rgmii_inst.eth_mac_1g_inst.axis_gmii_tx_inst.s_tdata_reg_TRELLIS_FF_Q_3_SLICE.LSR
      Info: 2.3 ns logic, 5.3 ns routing

      Как видим, есть полный путь в иерархии и точное имя цепи. На этом приятное заканчивается. Устранив проблему, получаем новую цепь. Список проблемных цепей, глубже, чем самая плохая, я получить не смог. И вот я месяц устранял проблему за проблемой, пока не довёл FMax с 64 до 125 МГц у Опенсорсного проекта.

      Вот это я могу сказать. А остальное - прошу прощения, не совсем разбираюсь.


      1. Khort
        07.12.2021 18:11

        Спасибо! Timing reports - уже показатель, что тул не просто так оптимизирует булевы функции, но и немножко смотрит на тайминг. Т.е. к примеру известен чисто математический минимизатор булевых функций - Espresso, и его гипотетически можно припрячь делать синтез, просто результат будет .. математический, т.е. от наших задач далекий. А вот чтобы смотреть еще и на тайминг при синтезе - это уже нужен STA-engine, так что Yosys здорово вырос в моих глазах.


        Так, а нетлист (я его выше structural verilog-ом обозвал) точно не выписывается? Это как-бы основной результат синтеза, он должен быть. Расширения могут быть любые, но внутри - верилог.


        1. EasyLy Автор
          07.12.2021 18:17

          Посмотрите, пожалуйста, тут Yosys Open SYnthesis Suite :: Command Reference :: write_verilog (clairexen.net)

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


    1. vsa1256
      07.12.2021 23:17

      Есть библиотека sky130 pdk для производства с открытыми тулами

      https://github.com/google/skywater-pdk

      Еще готовят 90 нм и 180нм .

      Сами открытые тулы включая floorplan, static timing analasys, parasitic extraction , routing разрабатываютя здесь (но все еще в стадии тестирования хотя уже есть успехи в производстве на GLOBAL FOUNDRY 12 nm)

      https://github.com/The-OpenROAD-Project


      1. EasyLy Автор
        07.12.2021 23:26

        Посмотрел. Ничего особенно не понял. Но судя по имени"Гугль", есть шанс, что рано или поздно пойдёт в народ. Потом когда-нибудь кто-нибудь закажет разработку на этой штуке, тогда и разберёмся :-).

        Помню, в комментариях к статье, написанной в начале 2018 года, мне пеняли, что я не принимаю во внимание ПЛИС LATTICE. Причём про них тогда уже многие знали. Должно было пройти три года, чтобы нам свалился реальный заказ на этих ПЛИС. Ещё полгода понадобилось мне, чтобы понять, что об этом вообще имеет смысл писать. Ну, и накопить базу знаний, которые будут интересны другим.

        Так что ждём, когда эта штука выстрелит.


        1. vsa1256
          07.12.2021 23:47

          Ну это про проектирование микросхем т.е ASIC а не fpga. Грубо говоря вы пишете verilog код скармливаете тулу openroad(где в том числе yosys для синтеза) , он разводит транзисторы создает gds файл чипа и вы можете произвести его на кремневой фабрике. До этого подобные тулы от synosys cadence стоили миллионы долларов, а сейчас активно развивается open source EDA в том числе yosys. Google например активно работает над поддержкой system verilog для yosys и симулятора verilator

          https://antmicro.com/blog/2021/07/open-source-systemverilog-tools-in-asic-design/