Русский
Русский
English
Статистика
Реклама

Beginners

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

29.05.2021 18:19:27 | Автор: admin

Совсем недавно мне в руки попался один из вариантов отладочной платы с 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 до 17V, 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 Clockset_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       endassign 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 и решения всяких новых задач с использованием этой платы - я смогу порадовать вас ещё.

Подробнее..

5 плохих CSS практик

05.04.2021 02:07:14 | Автор: admin

Бытует мнение, что CSS сложный. Существует много костылей, магии. Легко выстрелить себе в колено. Меня это печалит, потому что я так не считаю. Немного подумав, что можно сделать, я собрал 5 привычек разработчиков, которые мне не нравятся, и показал, как их избежать.


Устанавливать отступы, а потом сбрасывать их


Часто встречаю, что люди устанавливают отступы (margin или padding) для всех элементов, а потом сбрасывают у первого или последнего элемента. Не понимаю зачем писать два правила, когда можно обойтись одним. Проще же сразу установить отступ для нужных элементов.


Используйте один из следующих вариантов: nth-child/nth-of-type селекторы, псевдо-класс :not(), или комбинатор следующего соседнего элемента, более известный как +, и ваш CSS будет более простым и кратким.


Не делайте так


.item {  margin-right: 1rem;}.item:last-child {  margin-right: 0;}

Вы можете использовать


.item:not(:last-child) {  margin-right: 1rem;}/*или*/.item:nth-child(n+2) {  margin-left: 1rem;}/*или*/.item + .item {  margin-left: 1rem;}

Добавлять display: block для элементов с position: absolute или position: fixed


А знаете ли вы, что вам не нужно добавлять display: block для элементов c position: absolute или position: fixed, потому что это происходит по умолчанию?


Кроме того, если вы будете использовать inline-* значения, то они будут изменены следующим образом: inline или inline-block изменятся на block, inline-flex -> flex, inline-grid -> grid, и inline-table -> table.


Поэтому просто пишите position: absolute или position: fixed, и добавляйте display, только тогда, когда вам нужны значения flex или grid.


Не делайте так


.button::before {  content: "";  display: block;  position: absolute;}/*или*/.button::before {  content: "";  display: block;  position: fixed;}

Вы можете использовать


.button::before {  content: "";  position: absolute;}/*или*/.button::before {  content: "";  position: fixed;}

Использовать transform: translate(-50%, -50%) для центрирования


Cуществует популярная задача, которая попила не мало крови. Особенно до 2015 года, когда все ее решения приводили к каким-то проблемам. Я говорю о центрировании элемента с произвольной высотой по двум осям.


В частности одним из решений было использовать комбинацию абсолютного позиционирования и свойства transform. Данный прием приводил к размытию текста в Chromium браузерах.


Но после появления flexbox этот прием, по моему мнению, не актуален. Мало того, что проблема размытия текста еще не решена, так еще нужно использовать 5 свойств. Поэтому я хочу поделиться приемом, который сократит код до 2 свойств.


Мы можем использовать margin: auto внутри flex-контейнера, и браузер расположит элемент по центру. Просто 2 свойства и все.


Не делайте так


.parent {  position: relative;}.child {  position: absolute;  top: 50%;  left: 50%;  transform: translate(-50%, -50%);}

Вы можете использовать


.parent {  display: flex;}.child {  margin: auto;}

Можно использовать justify-content и align-items для этой задачи, но я не люблю этот прием, потому что существуют проблемы, к которым он приводит. О них я расскажу в отдельной статье.


Использовать width: 100% для блочных элементов


Мы часто используем flexbox для создания многоколоночной сетки, которая постепенно преобразовывается в одну колонку.


И чтобы преобразовать сетку в одну колонку разработчики использую width: 100%. Я не понимаю, зачем они это делают. Ведь элементы сетки являются блочными элементами, которые делают это по умолчанию без дополнительных свойств.


Соответственно нам не нужно использовать width: 100%, а следует написать медиа-запрос так, чтобы flexbox использовался только для создания многоколоночной сетки.


Не делайте так


<div class="parent">  <div class="child">1</div>  <div class="child">2</div>  <div class="child">3</div>  <div class="child">4</div></div>

.parent {  display: flex;  flex-wrap: wrap;}.child {  width: 100%;}@media (min-width: 1024px) {  .child {    width: 25%;  }}

Вы можете использовать


<div class="parent">  <div class="child">1</div>  <div class="child">2</div>  <div class="child">3</div>  <div class="child">4</div></div>

@media (min-width: 1024px) {  .parent {    display: flex;    flex-wrap: wrap;  }  .child {    width: 25%;  }}

Если вы знаете, почему нужно добавлять width:100% и мой способ не решает проблему, то напишите об этом в комментариях. Возможно, я что-то не учел. Спасибо


Задавать display: block для flex-элементов


При использовании flexbox важно помнить, что при создании flex-контейнера (добавляем display: flex), все дочерние элементы (flex-элементы) становятся blockified.


Это означает, что у элементов устанавливается свойство display, и у него могут быть только блочные значения. Соответственно, если установить inline или inline-block, то оно изменится на block, inline-flex -> flex, inline-grid -> grid и inline-table -> table.


Поэтому не добавляйте display: block к flex-элементам. Браузер сделает это сам.


Не делайте так


.parent {  display: flex;}.child {  display: block;}

Вы можете использовать


.parent {  display: flex;}

Заключение


Надеюсь мне удалось, показать, как можно избежать простых ошибок, и вы воспользуйтесь моими советами. Если нет, то это будет на вашей совести!


P.S: Если у вас есть вопросы по CSS/HTML, то, не стесняйтесь, пишите мне на мою почту. Она указана в моем профиле на Хабре.

Подробнее..
Категории: Css , Frontend , Tips and tricks , Beginners

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru