Hello World на Tang Primer 20K под Linux

—

от автора

После обзора на Tang Primer 20K — стало очевидно, что она вызывает немалый интерес и было решено немедля сделать разбор о том, каким образом можно настроить свой ПК и IDE для того чтобы начать взаимодействовать с отладочной платой, которую я рассмотрел в прошлой статье. Изначально, до момента пока я не познакомился сам лично с ПЛИС от Gowin и не запустил демо-проект — юзабельность, скорость и простота работы с их IDE вызывала сомнение. Но как только попробовал — все опасения были развеяны и я остался доволен.

Опытом настройки я с вами хотел бы поделиться в этой статье. Всех интересующихся — я по традиции приглашаю под кат!

image

❯ Скачиваем, всё что нужно для работы

Работа с Gowin и Tang Primer начинается с того, чтобы скачать архив c IDE с сайта Gowin. Для этого надо перейти на сайт и зарегистрироваться (или пролистать статью чуть ниже и скачать файл):

image

После несложной регистрации нужно перейти обратно по ссылке и скачать версию Education Edition:

image

Вообще — среда разработки доступна в двух версиях: Standard Edition и Education Edition, но для IDE Standard Edition требуется лицензия, которую можно попробовать получить у Gowin. Но если честно — я не пробовал и остановился на Education Edition т. к. она бесплатна в использовании.

Но есть ряд некоторых ограничений, которые могут быть существенными для некоторых разработчиков — Education Edition поддерживает меньшее количество моделей FPGA и включает в себя меньшее количество IP-ядер.

Поддерживаемые модели ПЛИС:

image

К счастью, GW2A-LV18PG256C8/I7 aka GW2A-18C которая установлена на плате Primer 20K поддерживается образовательной версией и мы можем идти дальше.

Итак, скачиваем файл по ссылке — проверял, прямая ссылка вроде работала, но лучше зарегистрироваться, чтобы обновляться и иметь доступ документации. Поле скачивания установка заключается в том, чтобы распаковать архив, присвоить права на исполнение файлу gw_ide и запустить его:

tar xvf Gowin_V1.9.8.11_Education_linux.tar.gz cd Gowin_V1.9.8.11_Education_linux/IDE/bin/ chmod +x ./gw_ide pwd  /home/megalloid/devel/gowin/distr/Gowin_V1.9.8.11_Education_linux/IDE/bin

Можно сделать быстрый alias на запуск IDE:

vim $(echo $HOME)/.bashrc

И добавим в конец файла удобную команду, я выбрал gowin_ide:

alias gowin_ide=’/home/megalloid/devel/gowin/distr/Gowin_V1.9.8.11_Education_linux/IDE/bin/gw_ide’

После этого можно перезапустить терминал и теперь достаточно просто ввести gowin_ide и запустится IDE:

image

Создадим новый проект, для этого жмём в New Project… и выбираем FPGA Design Project. Появится мастер создания нового проекта:

image

Выбираем модель нашего SoC — GW2A и жмём Next:

image

Смотрим саммари и нажимаем Finish:

image

Откроется главное окно IDE, теперь можно создать простой проект, типичных для подобных статей — Hello World, то есть простое мигание светодиодом.

image

Добавим к проекту новый Verilog-файл через File — New:

image

Обзовем файл как helloworld и выберем расширение .sv:

image

❯ Пишем модуль-мигалку на SystemVerilog

В общем давайте сделаем модуль, который заставит отладку моргать светодиодом раз в секунду т. е. менять свое состояние раз в половину секунды. Решение задачи максимально простое: создаем модуль у которого будет внутри организован счётчик. Счётчик будет прибавлять свое значение с каждым тактовым импульсом. На плате Tang Primer 20K расположен кварцевый генератор с частотой 27 МГц, с него мы и возьмем тактовый сигнал:

image

Для того чтобы получить 0.5 секунды при мигании светодиодом — надо просто досчитать до 13500000. При превышении значения 13500000 у счетчика — обнуляем его и инвертируем логическое значение ножки.

Задействуем первый доступный для пользовательских операций светодиод, например L14:

image

Обобщая вышесказанное получается следующая логика модуля (специально для новичков):

image

Начнем с заготовки модуля, назовём его blink и объявим входной и выходной порт для модуля. В теле модуля опишем эту логику на SystemVerilog:

module blink(input sys_clk, output led_l14);          // Задаем регистр для хранения записи о текущем состоянии светодиода     reg r_led;           // Задаем регистр для хранения значения счётчика, использующегося в задержке     reg [31:0] counter;          // Тут мы задаем действия которые должны быть выполнены при старте программы     initial begin         counter <= 32'b0;//  Обнуляем счётчик           r_led <= 1'b0;//  Делаем запись о состоянии светодиода     end          // Тут описываем поведенческий блок, который будет      // реагировать на ниспадающий фронт тактовой частоты     always@(posedge sys_clk)     begin         counter <= counter + 1'b1;// Увеличиваем счетчик                  if(counter > 13500000)// Если счетчик больше некоторого условного значения         begin             r_led <= !r_led;// Инвертируем запись о значении состоянии светодиода             counter <= 32'b0;// Сбрасываем счетчик         end                 end          assign led_l14 = r_led;          // Присваиваем текущее состояние ножке (условно)  endmodule

Записываем это в файл и сохраняем.

❯ Synthesize

Теперь модуль готов к синтезу и базовой проверке синтаксиса. Переходим в меню Process и двойным кликом по Synthesize запускаем синтез:

image

Внизу будет выведен лог синтеза, который говорит о том, что все закончилось успешно:

GowinSynthesis start Running parser ... Analyzing Verilog file '/home/megalloid/hello_world/src/helloworld.sv' Compiling module 'blink'("/home/megalloid/hello_world/src/helloworld.sv":1) NOTE  (EX0101) : Current top module is "blink" [5%] Running netlist conversion ... Running device independent optimization ... [10%] Optimizing Phase 0 completed [15%] Optimizing Phase 1 completed [25%] Optimizing Phase 2 completed Running inference ... [30%] Inferring Phase 0 completed [40%] Inferring Phase 1 completed [50%] Inferring Phase 2 completed [55%] Inferring Phase 3 completed Running technical mapping ... [60%] Tech-Mapping Phase 0 completed [65%] Tech-Mapping Phase 1 completed [75%] Tech-Mapping Phase 2 completed [80%] Tech-Mapping Phase 3 completed [90%] Tech-Mapping Phase 4 completed [95%] Generate netlist file "/home/megalloid/hello_world/impl/gwsynthesis/hello_world.vg" completed [100%] Generate report file "/home/megalloid/hello_world/impl/gwsynthesis/hello_world_syn.rpt.html" completed GowinSynthesis finish

❯ Constraint

Следующим шагом необходимо создать constraint-файл в котором мы опишем для IDE какие пины мы будем использовать на плате для входных и выходных сигналов. Для этого кликаем на FloorPlanner:

image

Нас спросят создать ли cst-файл, соглашаемся:

image

Откроется окно FloorPlanner и необходимо перейти в меню I/O Constraints и в полях подставим значения пинов:

image

После установки нажимаем сохранить и закрываем окно:

image

Теперь в структуре проекта появился файл с constraints-правилами.

❯ Place & Route

Переходим в меню Process и делаем двойной клик по Place & Route.

image

Будет запущен генерации bitstream-файла, который будет представлять собой бинарный файл для прошивки платы. В случае успешной генерации будет выведен соответствующий лог:

Reading netlist file: "/home/megalloid/hello_world/impl/gwsynthesis/hello_world.vg" Parsing netlist file "/home/megalloid/hello_world/impl/gwsynthesis/hello_world.vg" completed Processing netlist completed Reading constraint file: "/home/megalloid/hello_world/src/hello_world.cst" Physical Constraint parsed completed Running placement...... [10%] Placement Phase 0 completed [20%] Placement Phase 1 completed [30%] Placement Phase 2 completed [50%] Placement Phase 3 completed Running routing...... [60%] Routing Phase 0 completed [70%] Routing Phase 1 completed [80%] Routing Phase 2 completed [90%] Routing Phase 3 completed Running timing analysis...... [95%] Timing analysis completed Placement and routing completed Bitstream generation in progress...... Bitstream generation completed Running power analysis...... [100%] Power analysis completed Generate file "/home/megalloid/hello_world/impl/pnr/hello_world.power.html" completed Generate file "/home/megalloid/hello_world/impl/pnr/hello_world.pin.html" completed Generate file "/home/megalloid/hello_world/impl/pnr/hello_world.rpt.html" completed Generate file "/home/megalloid/hello_world/impl/pnr/hello_world.rpt.txt" completed Generate file "/home/megalloid/hello_world/impl/pnr/hello_world.tr.html" completed Fri Jul 14 23:48:34 2023

❯ Прошивка платы в Ubuntu 22.04 через IDE

Теперь, после сборки, казалось бы можно прошивать плату, но не тут то было. Не обошлось в случае Gowin без прыгания на граблях. Не удавалось прошить плату непосредственно из IDE. Нажимаешь Program Device — и не обнаруживается плата. Выводится ошибка:

image

Перехожу в каталог с программатором и пробую сделать то же самое но уже с запрашиваемыми правами. И лучше попробовать для начала из Cli-версии программатора:

cd devel/gowin/distr/Programmer/bin ./programmer_cli --scan

Видим вывод о той же ошибке:

Error: Please run with root privileges while using the FT2CH cable. rmmod: ERROR: ../libkmod/libkmod-module.c:799 kmod_module_remove_module() could not remove 'ftdi_sio': Operation not permitted rmmod: ERROR: could not remove module ftdi_sio: Operation not permitted rmmod: ERROR: Module usbserial is in use by: ftdi_sio  Scanning!  Target Cable: Gowin USB Cable(FT2CH)/0/0/null@2.5MHz  Error: No Gowin devices found!  Cost 0.12 second(s)

Пробуем дать ему этих самых прав, только запустив через sudo. Но теперь пишет, что якобы нет Gowin-устройств:

sudo ./programmer_cli --scan   Scanning!  Target Cable: Gowin USB Cable(FT2CH)/0/0/null@2.5MHz  Error: No Gowin devices found!  Cost 0.01 second(s)

В итоге, не найдя способа решить эту проблему — я обратился к рабочему варианту — программатору openFPGALoader.

❯ Прошивка платы в Ubuntu через openFPGALoader

Для этого необходимо настроить openFPGALoader, именно с его помощью мы будем загружать прошивку на плату. Итак, для начала, если у вас Ubuntu как у меня: установим необходимые зависимости:

sudo apt-get install libftdi1-2 libftdi1-dev libhidapi-hidraw0 libhidapi-dev \ libudev-dev zlib1g-dev cmake pkg-config make g++

Потом склонируем исходники себе и скомпилим их:

git clone https://github.com/trabucayre/openFPGALoader.git cd openFPGALoader mkdir build cd build

Для сборки версии со статической линковкой (когда все необходимые для работы библиотеки интегрируются в исполняемый файл) к cmake-команде добавьте флаг:

cmake -DBUILD_STATIC=ON ../

Или можно просто скомпилить и потом установить без доп.аргументов:

cmake ../ make -j$(nproc) sudo make install

После сборки нужно прописать правила udev, чтобы не было проблем с доступом к железу со стороны собранного софта:

sudo cp 99-openfpgaloader.rules /etc/udev/rules.d/ sudo udevadm control --reload-rules && sudo udevadm trigger

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

megalloid@megalloid-dell:~$ groups megalloid adm dialout cdrom sudo dip plugdev lpadmin lxd sambashare bladerf

При необходимости внести его в эту группу:

sudo usermod -a $USER -G plugdev

Только изменения вносятся не сразу и необходимо сделать Logout из системы и зайти обратно. После этого необходимо обязательно включить первый пин на DIP-переключателе, чтобы режим загрузки платы соответствовал тому, который подходит для перепрошивки:

image

После этого можно попробовать обнаружить отладку на шине USB:

megalloid@megalloid-dell:~$ openFPGALoader --detect No cable or board specified: using direct ft2232 interface Jtag frequency : requested 6.00MHz   -> real 6.00MHz   index 0: idcode 0x81b manufacturer Gowin family GW2A model  GW2A(R)-18(C) irlength 8

Так, плата детектится, теперь для перепрошивки платы нужно ввести команду и в качестве аргумента указать тип прошиваемой платы и путь к bitstream-файлу. Все файлы после синтеза и роутинга хранятся в директории impl/pnr:

megalloid@megalloid-dell:~/devel/gowin/projects/hello_world/impl/pnr$ ll total 6060 drwxrwxr-x 2 megalloid megalloid    4096 июл 14 23:48 ./ drwxrwxr-x 5 megalloid megalloid    4096 июл 14 23:38 ../ -rw-rw-r-- 1 megalloid megalloid     280 июл 14 23:48 cmd.do -rw-rw-r-- 1 megalloid megalloid     550 июл 14 23:48 device.cfg -r-xr-xr-x 1 megalloid megalloid  577178 июл 14 23:48 hello_world.bin* -r-xr-xr-x 1 megalloid megalloid  577672 июл 14 23:48 hello_world.binx* -rw-rw-r-- 1 megalloid megalloid    1712 июл 14 23:48 hello_world.db -r-xr-xr-x 1 megalloid megalloid 4619303 июл 14 23:48 hello_world.fs* -rw-rw-r-- 1 megalloid megalloid    1299 июл 14 23:48 hello_world.log -rw-rw-r-- 1 megalloid megalloid   47622 июл 14 23:48 hello_world.pin.html -rw-rw-r-- 1 megalloid megalloid    6724 июл 14 23:48 hello_world.power.html -rw-rw-r-- 1 megalloid megalloid   52873 июл 14 23:48 hello_world.rpt.html -rw-rw-r-- 1 megalloid megalloid   40074 июл 14 23:48 hello_world.rpt.txt -rw-rw-r-- 1 megalloid megalloid    6985 июл 14 23:48 hello_world.timing_paths -rw-rw-r-- 1 megalloid megalloid    7760 июл 14 23:48 hello_world_tr_cata.html -rw-rw-r-- 1 megalloid megalloid  226333 июл 14 23:48 hello_world_tr_content.html -rw-rw-r-- 1 megalloid megalloid     347 июл 14 23:48 hello_world.tr.html

Нас интересует файл hello_world.fs, его и зальём в SRAM т.е. без перепрошивки:

openFPGALoader -b tangprimer20k hello_world.fs Jtag frequency : requested 6.00MHz   -> real 6.00MHz   Parse file Parse hello_world.fs:  Done DONE Jtag frequency : requested 2.50MHz   -> real 2.00MHz   erase SRAM Done Flash SRAM: [==================================================] 100.00% Done

Если хочется зашить bitstream на Flash — достаточно добавить флаг -f в команду. Сразу предупрежу о том, что плата в большинстве случаем шьётся не с первого раза (почему-то, не было времени на разбирательства), будьте готовы к тому, что придётся перетыкать кабели, повторяя прошивку и танцы с бубнами:

openFPGALoader -b tangprimer20k -f hello_world.fs write to flash Jtag frequency : requested 6.00MHz   -> real 6.00MHz   Parse file Parse hello_world.fs:  Done DONE Jtag frequency : requested 2.50MHz   -> real 2.00MHz   Jtag frequency : requested 10.00MHz  -> real 6.00MHz   erase SRAM Done Detail:  Jedec ID          : 0b memory type       : 40 memory capacity   : 16 EDID + CFD length : 0b EDID              : 1640 CFD               :  Detail:  Jedec ID          : 0b memory type       : 40 memory capacity   : 16 EDID + CFD length : 0b EDID              : 1640 CFD               :  RDSR : 00 WIP  : 0 WEL  : 0 BP   : 0 TB   : 0 SRWD : 0 flash chip unknown: use basic protection detection Erasing: [==================================================] 100.00% Done Writing: [==================================================] 100.00% Done

В этот раз плата прошилась с четвертой попытки. Думаю закажу еще одну отладку и другой программатор, возможно это специфика моего SoM и Onboard-программатора. Пока не понял в чем проблема.

В дополнение к этому. Для расширенного вывода информации о процессе прошивки нужно добавить аргумент —verbose. Это наверняка поможет разобраться с причинами того, что мешает прошивке платы.

Итак, после прошивки — можем обратить внимание, на плату и увидеть мигающий раз в секунду светодиод:

image

После того, как помигали светодиодом — вы можете ознакомиться с различными примерами из репозитория Sipeed. Там их предостаточно, чтобы поиграться с периферией и даже есть демо проекта на PicoRV32-based SoC с выводом в HDMI terminal.

❯ Заключение

В общем тем, кто не знал с чего начать получили ответ на свой запрос. Но меня ужасно опечалил тот факт, что нет нормальной возможности прошивать плату без лишнего гемороя из IDE и тут пользователи Windows могут ликовать. Буду пристально следить за обновлениями как IDE так и программатора — надеюсь что проблему с прошивкой плат рано или поздно решат и с Gowin будет работать гораздо комфортнее. А пока — печаль-беда для LInux-пользователей.

Но не будем расстраиваться, потому что проект который я планирую сделать — написан на SystemVerilog и по своей сути будет универсальным и может быть реализован в итоге как на Gowin, так и Xilinx с Altera.

Пора, думаю, переходить от обзоров к рассмотрению более серьезных технических проблем и способов их решения. Ожидайте новых интересных статей! До встречи! 🙂


Возможно, захочется почитать и это:


ссылка на оригинал статьи https://habr.com/ru/companies/timeweb/articles/748594/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *