From d35cbb56d2d148d9cd2a3e6aec7f1d1e4193f02d Mon Sep 17 00:00:00 2001 From: Djadik Date: Fri, 10 Apr 2026 23:40:07 +0300 Subject: [PATCH 1/3] =?UTF-8?q?=D0=9B=D0=A006:=20=D0=98=D1=81=D0=BF=D1=80?= =?UTF-8?q?=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D1=8B=20=D0=BF=D1=80=D0=B8=D0=BC?= =?UTF-8?q?=D0=B5=D1=80=D1=8B=20=D0=BA=D0=BE=D0=B4=D0=B0=20=D0=B8=20=D0=BE?= =?UTF-8?q?=D0=BF=D0=B5=D1=87=D0=B0=D1=82=D0=BA=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Исправлена ошибка в названии сигналов. - В модуль simple_valid_ready_slave добавлены: assign ready_o = ready_ff; assign saved_data_o = data_ff; - Исправлен пример формирования grant[3]: было: assign grant[3] = ~req[0] & ~req[1] & req[2] & ~req[3]; стало: assign grant[3] = ~req[0] & ~req[1] & ~req[2] & req[3]; - Исправлены опечатки в тексте. --- Labs/06.AXI-Stream/README.md | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/Labs/06.AXI-Stream/README.md b/Labs/06.AXI-Stream/README.md index 7afb7fc..dd7cd4e 100644 --- a/Labs/06.AXI-Stream/README.md +++ b/Labs/06.AXI-Stream/README.md @@ -78,6 +78,9 @@ module simple_valid_ready_slave end end + assign ready_o = ready_ff; + assign saved_data_o = data_ff; + endmodule ``` @@ -149,7 +152,7 @@ endmodule У вас может возникнуть логичный вопрос: а почему бы просто не поставить регистры на сигнал `ready`, ничего не меняя? Вы можете построить временную диаграмму работы такого решения и убедиться, что оно, к сожалению, окажется неработоспособно. -Тем не менее, существует несколько вариантов решения проблемы с критическим пути по линии `ready`. Самый простой вариант представлен ниже: +Тем не менее, существует несколько вариантов решения проблемы с критическим путем по линии `ready`. Самый простой вариант представлен ниже: ```verilog module valid_ready_pipe_2 @@ -424,7 +427,7 @@ AXI Stream (Advanced eXtensible Interface Stream) — это протокол д 4. `TREADY` (Ready — Готовность приёмника). Указывает, что приёмник готов принять данные. Этот сигнал генерируется Slave. Передача данных происходит только при одновременной активности `TVALID` и `TREADY` (handshake). При этом в спецификации интерфейса AXI Stream существует важные правила, определяющие работу сигналов `TVALID` и `TREADY` -* Slave может удерживать `TREADY` = 1 во то время, когда `TREADY` = 0. +* Slave может удерживать `TREADY` = 1 в то время, когда `TVALID` = 0. * Slave может опускать `TREADY` в 0 в любой момент времени и "слушающий этот сигнал" Master должен это учитывать. * Однажды выставив `TVALID` в 1 Master более **не имеет права** выставлять `TVALID` в 0 до момента, пока не произойдёт рукопожатие и транзакция. То есть, Master не имеет права "передумать", выставляя флаг валидности. @@ -675,7 +678,7 @@ endmodule assign grant[0] = req[0]; assign grant[1] = ~req[0] & req[1]; assign grant[2] = ~req[0] & ~req[1] & req[2]; -assign grant[3] = ~req[0] & ~req[1] & req[2] & ~req[3]; +assign grant[3] = ~req[0] & ~req[1] & ~req[2] & req[3]; ``` Второй способ полезен при описании конфигурируемых дизайнов, где количество портов (а значит и элементов, требующих арбитража) может параметризоваться. Данный пример не является законченным и синтезируемым, но он отлично поясняет идею, которую можно развить с помощью конструкции `for`. @@ -823,7 +826,7 @@ endmodule ![](./pic/rr_arb.png) - Мы добавили указатель `ptr_ff`, который указывает текущий приоритет. При этом, следующее значение указателя всегда выбирается таким, чтобы он указывал на следующий порт относительно того, на котором в данный момент происходит транзакция. Таким образом, приоритет порта с транзакцией на следующий такт понизится до наименьшего. -- В сердце показанного примера до сих пор находится статический арбитр, но мы делаем интересный трюк: сначала мы циклический сдвигаем вектор `req` вправо на количество бит из текущего значения `ptr_ff`, то есть, мы поворачиваем входной вектор `req` так, чтобы `ptr_ff`-й элемент имел максимальный статичный приоритет, в результате получая вектор `req_rotated`. Результат вычисления приоритета `grant_rotated` нельзя просто так использовать для управления портами, его нужно "повернуть обратно", выполнив циклический сдвиг влево на те же `ptr_ff` бит. Таким образом, мы хитрым образом вращаем биты вокруг статического приоритета, чтобы получить динамический арбитраж. Всё гениальное -- просто! +- В сердце показанного примера до сих пор находится статический арбитр, но мы делаем интересный трюк: сначала мы циклически сдвигаем вектор `req` вправо на количество бит из текущего значения `ptr_ff`, то есть, мы поворачиваем входной вектор `req` так, чтобы `ptr_ff`-й элемент имел максимальный статичный приоритет, в результате получая вектор `req_rotated`. Результат вычисления приоритета `grant_rotated` нельзя просто так использовать для управления портами, его нужно "повернуть обратно", выполнив циклический сдвиг влево на те же `ptr_ff` бит. Таким образом, мы хитрым образом вращаем биты вокруг статического приоритета, чтобы получить динамический арбитраж. Всё гениальное -- просто! Стоит обратить внимание на то, что формирование сигналов `req_rotated` и `grant` можно описать более красивым и изящным способом, который, помимо всего прочего, легко ложится на параметризуемый дизайн с переменным числом портов. @@ -843,7 +846,7 @@ assign grant[3:0] = grant_double[7:4]; ### Коммутация потоков данных -Теперь, когда мы знакомы с концепциями fork и join, знаем про арбитраж, мы можем приступить к разработке блока коммутатора, имеющего N входов и M выходов и способного обеспечить связность любого входа с любым выходом. Такую схему, с начиная с зари развития телефонии, принято называть **crossbar switch**. +Теперь, когда мы знакомы с концепциями fork и join, знаем про арбитраж, мы можем приступить к разработке блока коммутатора, имеющего N входов и M выходов и способного обеспечить связность любого входа с любым выходом. Такую схему, начиная с зари развития телефонии, принято называть **crossbar switch**. Суть простейшего коммутатора заключается в наборе блоков fork и join, подключенных с топологией соединений "каждый с каждым". Пример такого коммутатора на 3 входных и 3 выходных показан на рисунке ниже. @@ -981,7 +984,7 @@ module axis_join_param ## Контрольные вопросы 1. Зачем нужен сигнал `ready` в интерфейсе valid-ready? 2. Что такое рукопожатие (handshake)? -3. Что такой обратное давление (backpressure)? +3. Что такое обратное давление (backpressure)? 4. Какая проблема возникает с сигналом `ready` при соединении большого количества модулей в конвейер? 5. Какие способы развязки критического пути по backpressure вы знаете? Опишите их. 6. Что такое кредитный механизм? Для чего он нужен? Как он работает? From faa2ff11e63461fe8e1af895c9f05a43916caf24 Mon Sep 17 00:00:00 2001 From: Djadik Date: Sun, 10 May 2026 13:43:11 +0300 Subject: [PATCH 2/3] =?UTF-8?q?=D0=9B=D0=A01:=20=D0=B4=D0=BE=D0=B1=D0=B0?= =?UTF-8?q?=D0=B2=D0=BB=D0=B5=D0=BD=D0=BE=20=D0=BF=D1=80=D0=B8=D0=BC=D0=B5?= =?UTF-8?q?=D1=87=D0=B0=D0=BD=D0=B8=D0=B5=20=D0=BE=20=D0=BF=D1=83=D1=82?= =?UTF-8?q?=D1=8F=D1=85=20=D0=B2=20Tcl-=D1=81=D0=BA=D1=80=D0=B8=D0=BF?= =?UTF-8?q?=D1=82=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Labs/01. Tcl/README.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/Labs/01. Tcl/README.md b/Labs/01. Tcl/README.md index 65f93b7..7dd656c 100644 --- a/Labs/01. Tcl/README.md +++ b/Labs/01. Tcl/README.md @@ -27,6 +27,23 @@ Если вы не помните как создавать проекты, то обратитесь к [материалам АПС с прошлого семестра](https://github.com/MPSU/APS/tree/master/Vivado%20Basics). +**Примечание** + +Vivado часто сохраняет в Tcl-скрипте абсолютные пути к исходным файлам, например `C:/Users/.../Downloads/...`. Такой скрипт обычно корректно работает только на том компьютере, где он был создан. При переносе проекта в другую папку или на другой компьютер пути могут стать недействительными. + +Для повышения переносимости проекта абсолютные пути можно заменить на относительные. В рамках данной лабораторной работы это не является обязательным требованием, однако в дальнейшем такой подход может быть полезен для улучшения переносимости скрипта. + + Например: +```tcl +# Абсолютный путь +set file "C:/Users/name/Downloads/demo.sv" + +# Относительный путь +set file [file join "." "rtl" "demo.sv"] +``` + +Второй вариант удобнее тем, что при сохранении структуры проекта Tcl-скрипт проще переносить между каталогами и компьютерами. + ## Экспорт скрипта для автоматизированного создания проекта в Vivado Давайте теперь мы создадим свой первый Tcl скрипт. Этот скрипт будет сгенерирован Vivado и будет предназначаться для восстановления проекта. Затем мы будем менять и дополнять этот скрипт. From 24743095a8cd71eeed52947c2d92baa5ab801b8c Mon Sep 17 00:00:00 2001 From: Djadik Date: Sun, 10 May 2026 14:39:17 +0300 Subject: [PATCH 3/3] =?UTF-8?q?=D0=9B=D0=A01:=20=D0=9F=D0=BE=D0=B4=D0=BF?= =?UTF-8?q?=D1=80=D0=B0=D0=B2=D0=B8=D0=BB=20=D0=BE=D1=84=D0=BE=D1=80=D0=BC?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Labs/01. Tcl/README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Labs/01. Tcl/README.md b/Labs/01. Tcl/README.md index 7dd656c..a967d74 100644 --- a/Labs/01. Tcl/README.md +++ b/Labs/01. Tcl/README.md @@ -27,13 +27,14 @@ Если вы не помните как создавать проекты, то обратитесь к [материалам АПС с прошлого семестра](https://github.com/MPSU/APS/tree/master/Vivado%20Basics). -**Примечание** + **Примечание** Vivado часто сохраняет в Tcl-скрипте абсолютные пути к исходным файлам, например `C:/Users/.../Downloads/...`. Такой скрипт обычно корректно работает только на том компьютере, где он был создан. При переносе проекта в другую папку или на другой компьютер пути могут стать недействительными. Для повышения переносимости проекта абсолютные пути можно заменить на относительные. В рамках данной лабораторной работы это не является обязательным требованием, однако в дальнейшем такой подход может быть полезен для улучшения переносимости скрипта. - Например: +Например: + ```tcl # Абсолютный путь set file "C:/Users/name/Downloads/demo.sv" @@ -44,6 +45,7 @@ set file [file join "." "rtl" "demo.sv"] Второй вариант удобнее тем, что при сохранении структуры проекта Tcl-скрипт проще переносить между каталогами и компьютерами. + ## Экспорт скрипта для автоматизированного создания проекта в Vivado Давайте теперь мы создадим свой первый Tcl скрипт. Этот скрипт будет сгенерирован Vivado и будет предназначаться для восстановления проекта. Затем мы будем менять и дополнять этот скрипт.