Начинаем работу с Zynq 7000. Пособие для начинающих

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

Совсем недавно мне в руки попался один из вариантов отладочной платы с SoC Zynq XC7Z020. Поискав в Интернете материалы, а-ля how-to, и попробовав накидать свой минимальный проект обнаружил, что есть целый ряд подводных камней. Именно об этом я и хотел бы рассказать в статье. Кому интересно - добро пожаловать под кат.

Важно! Перед началом повествования, хотелось бы заранее оговориться, что основная цель которую я преследую при написании этой статьи - показать любителям, с чего можно начать, при изучении отладочных плат на базе Zynq. Я не являюсь профессиональным разработчиком под ПЛИС и SoC Zynq и могу допускать какие-либо ошибки в использовании терминологии, использовать не самые оптимальные пути решения задач, etc. Но любая конструктивная и аргументированная критика только приветствуется. Что ж, поехали…

Что за отладка такая? Покажи-расскажи...

Мне очень давно хотелось поиграться с SoC Zynq, но никак не доходили руки. Но в очередной раз погуглив - увидел, что за вполне вменяемый ценник продаётся отладка с Zynq на борту, от компании QMTech, называется она Bajie Board. Выпускается отладка в нескольких вариантах с разными вариантами SoC Zynq. Я выбрал для себя вариант на XC7Z020 и тут же ее заказал, через пару недель она у меня уже была в руках.

После распаковки я был приятно удивлен, комплект поставки порадовал. Это была сама отладочная плата, блок питания на 5В/2А, mini-USB кабель и microSD Flash-карта SanDisk на 16Гб с уже залитым на нее Linux. То есть, сразу после получения вы можете подключить к плате питание, воткнуть USB-шнурок, открыть Putty и получить в свое распоряжение полноценный mini-компьютер с Embedded Linux. О Linux для Zynq, я думаю, расскажу в другой статье, поэтому едем дальше...

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

  • SoC: XC7Z020-1CLG400C 

  • (datasheet:https://www.xilinx.com/support/documentation/data_sheets/ds190-Zynq-7000-Overview.pdf);

  • Осциллятор на 33,333 МГц;

  • Оперативная память DDR3 на 512 Мб от компании Micron, MT41K256M16TW-107:P;

  • Встроенный слот micro SD;

  • Источник питания для FPGA TPS563201 с широким диапазоном входных напряжений (от 4.5V до 17​V, 3A);

  • Один 50-пиновый и две Digilent PMOD совместимых, гребёнки с пинами, с шагом в 2,54 мм. для пользовательских кейсов (как заверяет производитель, все проводники до пинов выровнены по длине);

  • Кнопка для логического сброса процессорной системы (PS);

  • Гигабитный RGMII Ethernet-контроллер Realtek RTL8211E-VL, подключенный к PS;

  • Два пользовательских светодиода, один подключен к программируемой логике (PL) и другой подключен к процессорной системе (PS);

  • Встроенный HDMI-совместимый интерфейс дисплея TI TPD12S016;

  • Гребёнка для подключения JTAG-отладчика;

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

Единственное, что меня опечалило и про что я напрочь забыл, когда покупал плату - это то что для работы с платой необходим JTAG-программатор. Но я его быстро нашел в Москве и мне его привезли курьером буквально в этот же день.

Установка необходимого набора ПО для разработки

Итак, прежде чем начать работу с платой мне было необходимо установить ПО Xilinx Vivado и Xilinx SDK. Насколько я понимаю, грубо говоря, Vivado используется для конфигурации аппаратной части используемой платы и для работы с программируемой логикой. А Xilinx SDK (ныне именуется Vitis) используется для создания кода непосредственно для процессорной системы.

Поскольку бОльшая часть примеров из документации и репозитория производителя и разнообразных примеров из роликов на YouTube делались в версии Vivado 2019.1 (видимо из-за того, что это последняя версия поддерживающая работу с Xilinx SDK) - я установил именно её, а не последнюю доступную 2020.2.

Все программные продукты необходимые для работы с Xilinx Zynq - можно взять на официальном сайте Xilinx, тут. Сразу же спешу обратить внимание, что те из вас, кто захочет установить самую новую версию Vivado - нужно скачивать версию 2020.2, а не 2020.3 т.к. последняя поддерживает только Versal SoC, и не поддерживает Zynq.

В моём случае, т.к. я работаю в операционной системе Linux - я перешел в меню Vivado Archive - 2019.1 и нажал на кнопку скачивания по ссылке  Vivado HLx 2019.1: WebPACK and Editions - Linux Self Extracting Web Installer в списке Vivado Design Suite - HLx Editions - 2019.1. Для пользователей Windows - выбирайте Windows Self Extracting Web Installer.

После скачивания открываем инсталлятор, установив права на исполнение:

chmod +x ~/Downloads/Xilinx_Vivado_SDK_Web_2019.1_0524_1430_Lin64.bin
~/Downloads/Xilinx_Vivado_SDK_Web_2019.1_0524_1430_Lin64.bin 

Вся установка состоит из набора стандартных шагов. 

  1. Вводим авторизационные данные, которые мы указывали при регистрации;

  2. Принимаем условия лицензионных соглашений;

  3. Выбираем Vivado HL WebPACK;

  4. Удостоверяемся в том, что выбран SoC Zynq в списке предложенного оборудования.

  5. Далее программа скачает порядка 16Гб всякого-разного, установит это и на Рабочем столе появятся иконки нужных нам приложений.

После установки Vivado необходимо установить драйвер для JTAG-программатора. В Linux это делается так:

cd Xilinx2019.1/Vivado/2019.1/data/xicom/cable_drivers/lin64/install_script/install_drivers/
sudo ./install_drivers 

Подключаем все 6 пинов от JTAG-программатора в соответствии с шелкографией на плате. И проверяем установлены ли драйвера и определяется ли наша отладочная плата:

cd ~/Xilinx2019.1/Vivado/2019.1/bin
./xsdb 
xsdb% connect -host localhost   
xsdb% jtag targets                                                                                                                                                           
  1  Platform Cable USB 13724327082b01
     2  arm_dap (idcode 4ba00477 irlen 4)
     3  xc7z020 (idcode 23727093 irlen 6 fpga)

На этом подготовительных этап можно считать завершенным.

Hello, world или “Баяны подъехали”

Не будем отходить от традиции и попробуем поморгать LED-иком который подключен к программируемой логике. 

Запускаем Vivado и создаем новый проект. Нажимаем File - Project - New

Откроется мастер создания нового проекта, нажимаем Next > и пишем название нашего проекта PL-Blink.

Выбираем RTL Project и ставим галочку у пункта Do not specify sources at this time.

Далее в списке ищем наш процессор xc7z020clg400-1.

Жмём на кнопку Finish.

Перед нами открывается главное окно программы Vivado и мы можем приступать к реализации намеченной нами цели!

Первым делом, мы добавим необходимые указания программе, на то, какие физические ножки мы задействуем в нашей моргающей вакханалии =)

Находим меню Sources и нажимаем кнопку Add Sources.

Откроется мастер импорта и нам нужно выбрать Add or create constraints. 

В следующем меню нажимаем Create file и пишем название нашему файлу physical_constr. Именно в этом файле мы опишем какие ножки и в каком режиме должны работать.

Нажимаем кнопку Finish и в дереве Sourсes ищем только что созданный нами файл и открываем его:

Обратимся к схеме, которую любезно предоставил нам производитель и найдем какая ножка отвечает за тактирование, а какая за наш светодиод. Бегло поискав, я отметил для себя, что из Ethernet-контроллера RTL8211E-VL выведен опорный тактовый сигнал с его внутреннего PLL, частотой в 125МГц и заведен в ножку H16 (IO_L13P_T2_MRCC_35). Так почему бы нам его и не задействовать в нашем примере? =)

Его мы и заюзаем для нашего счетчика, который будет генерировать задержку между включенным и выключенным состоянием светодиода.

Тут же, рядом, на ножке H17 (IO_L13N_T2_MRCC_35) расположен светодиод, которым мы будем моргать.

Итак. Открыв наш constraints-файл запишем в него следующие строки:

# User LED and Clock
set_property IOSTANDARD LVCMOS33 [get_ports led_h17_d4]
set_property IOSTANDARD LVCMOS33 [get_ports sys_clk]

set_property PACKAGE_PIN H17 [get_ports led_h17_d4]
set_property PACKAGE_PIN H16 [get_ports sys_clk]

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

В квадратных скобках, после get_ports необходимо указать логическое имя ножки (на ваше усмотрение). Имена стоит придумать осмысленно, потому что мы его будем использовать в Verilog-коде. 

Кстати, подробнее о Physical Constraints можно почитать тут в главе 8.

Добавим в наш проект таким же образом Design Source. Находим меню Sources и нажимаем кнопку Add Sources.

Откроется мастер импорта и нам нужно выбрать Add or create design sources. Далее нажимаем Create File, смотрим, что выбран язык Verilog. Нажимаем ОК и Finish.

В следующем меню всё оставляем без изменений и нажимаем ОК и Yes.

Открываем созданный файл и видим небольшую заготовку:

Здесь вместо предложенного кода пишем наш Verilog-код и прокомментируем что значит каждая из строк:

// Директива компилятора, которая определяет единицу времени и точность для моделирования Verilog.
// В целом, не очень интересный пункт для нас.

`timescale 1ns / 1ps 	
		
// Определяем стандартный блок-модуль (как класс в С++)
module pl_blink(input sys_clk, output led_h17_d4);
    
// Задаем регистр для хранения записи о текущем состоянии светодиода
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 > 12000000)		// Если счетчик больше некоторого условного значения
    begin
        r_led <= !r_led;		// Инвертируем запись о значении состоянии светодиода
        counter <= 32'b0;		// Сбрасываем счетчик
    end   
    
end

assign led_h17_d4 = r_led;          // Присваиваем текущее состояние ножке (условно)
           
endmodule

Нажимаем сочетание клавиш Ctrl + S чтобы сохранить код. Смотрим, не подсвечены ли где возможные ошибки. Если нет - то можем приступить к синтезированию, имплементации и генерации бинарного файла который мы потом зальем в нашу плату Zynq и будем наблюдать за морганием светодиода.

Нажимаем кнопку Run Synthesis и дожидаемся завершения синтеза. После окончания программа нам скажет, что синтез успешно завершен и мы можем переходить к следующему шагу:

Выбираем Run implementation и дожидаемся окончания. После выбираем пункт Generate Bitstream для запуска финального этапа:

Тут так же дожидаемся сигнала о том, что всё прошло успешно, выбираем Open Hardware Manager и можем приступать к заливке результата компиляции в нашу плату:

В открывшемся меню Hardware Manager нажимаем кнопку Auto connect, дожидаемся когда произойдет успешное соединение и откроется меню со списком устройств:

В меню слева или через нажатие правой кнопкой по xc7z020_1 в меню Hardware нажимаем пункт Program Device.

В следующем окне убеждаемся, что правильно указан путь к bitstream-файлу и нажимаем кнопку Program.

Программа заливается на нашу плату…

И через мгновение на плате загорается светодиод D2, который сообщает нам, что “FPGA DONE” и в другом конце платы мы видим весело моргающий светодиод. =)

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

Источник: https://habr.com/ru/post/559946/


Интересные статьи

Интересные статьи

Разные организации и крупные компании постоянно проводят чемпионаты, соревнования и олимпиады по программированию. Со стороны они выглядят как развлечения для студенто...
Давно у меня стояла задача по автоматизации работы системы отопления в доме. Дано — классические термостаты теплого пола ballu с крутилкой — покупались в leroymerlin в далеком 2017 го...
При работе с UITableView хотелось избежать написания шаблонного кода, который еще больше усложняется, если нужно обновлять состояние таблицы анимировано. Apple представила свое реше...
Если месяц назад вопрос перевода сотрудников на дистанционную работу был делом вкуса работодателя, то в текущей ситуации он может стать насущной потребностью. На неделе к нам обратилось множество...
Всем привет. Когда я искал информацию о журналировании (аудите событий) в Bitrix, на Хабре не было ни чего, в остальном рунете кое что было, но кто же там найдёт? Для пополнения базы знаний...