From d06a561d53cb2e0d5ffd45e6d6c7ee91de9b2db9 Mon Sep 17 00:00:00 2001 From: Andrei Solodovnikov Date: Mon, 18 Mar 2024 12:36:18 +0300 Subject: [PATCH] =?UTF-8?q?=D0=9B=D0=A02,=2012,=2015.=20=D0=98=D0=B7=D0=BC?= =?UTF-8?q?=D0=B5=D0=BD=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=B2=20=D1=83=D0=BF?= =?UTF-8?q?=D0=BE=D0=BC=D0=B8=D0=BD=D0=B0=D0=BD=D0=B8=D1=8F=D1=85=20genera?= =?UTF-8?q?te=20=D0=B1=D0=BB=D0=BE=D0=BA=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Labs/02. Arithmetic-logic unit/README.md | 2 +- Labs/12. Daisy chain/README.md | 24 ++++++++++++++++++++++-- Labs/15. Programming device/README.md | 6 ++++++ 3 files changed, 29 insertions(+), 3 deletions(-) diff --git a/Labs/02. Arithmetic-logic unit/README.md b/Labs/02. Arithmetic-logic unit/README.md index fe1ddfd..e9e4889 100644 --- a/Labs/02. Arithmetic-logic unit/README.md +++ b/Labs/02. Arithmetic-logic unit/README.md @@ -62,7 +62,7 @@ _Рисунок 3. Пример исполнения операции АЛУ._ Допустим, ваше устройство должно включить тостер, если на вход ему придет сигнал `32'haf3c5bd0`. Человек, не знакомый с устройством, при прочтении этого кода будет недоумевать, что это за число и почему используется именно оно. Однако, скрыв его за параметром `TOASTER_EN`, читающий поймет, что это код включения тостера. Кроме того, если некоторая константа должна использоваться в нескольких местах кода, то определив её через в виде параметра, можно будет менять её в одном месте, и она тут же поменяется везде. -Параметры позволяют влиять на структуру модуля. К примеру, описывая сумматор, можно параметризовать его разрядность и использовать этот параметр при описании модуля (например, в блоке `generate for`). В этом случае вы сможете создавать множество сумматоров различных разрядностей, подставляя при создании нужное вам значение параметра. +Параметры позволяют влиять на структуру модуля. К примеру, описывая сумматор, можно параметризовать его разрядность и использовать этот параметр при описании модуля (например, в качестве диапазона массива модулей). В этом случае вы сможете создавать множество сумматоров различных разрядностей, подставляя при создании нужное вам значение параметра. Параметр может быть объявлен в модуле двумя способами: diff --git a/Labs/12. Daisy chain/README.md b/Labs/12. Daisy chain/README.md index eec0e5a..1230d79 100644 --- a/Labs/12. Daisy chain/README.md +++ b/Labs/12. Daisy chain/README.md @@ -17,10 +17,30 @@ _Рисунок 1. Структурная схема daisy chain._ Данная схема состоит из двух массивов элементов И. Первый массив (верхний ряд элементов) формирует многоразрядный сигнал (назовем его для определенности `ready`, на _рис. 1_ он обозначен как "_Приоритет_"), который перемножается с запросами с помощью массива элементов И нижнего ряда, формируя многоразрядный сигнал `y`. Обратите внимание на то, что результат операции И на очередном элементе нижнего массива влияет на результат И следующего за ним элемента верхнего массива и наоборот (`readyₙ₊₁` зависит от `yₙ`, в то время как `yₙ` зависит от `readyₙ`). Как только на одном из разрядов `y` появится значение `1`, оно сразу же распространится в виде `0` по всем оставшимся последующим разрядам `ready`, обнуляя их. А обнулившись, разряды `ready` обнулят соответствующие разряды `y` (нулевые разряды `ready` запрещают генерацию прерывания для соответствующих разрядов `y`). -Для описания верхнего ряда элементов И на языке SystemVerilog будет удобно воспользоваться конструкцией `generate for`, о которой рассказывалось в [ЛР 1 "Сумматор"](../01.%20Adder#Задание) (необходимо сделать непрерывное присваивание `readyₙ & !yₙ` для `n+1`-ого бита `ready`). - Нижний массив элементов И можно описать через непрерывное присваивание побитового И между `ready` и сигналом запросов на прерывание. +Для описания верхнего ряда элементов И вам будет необходимо сделать непрерывное присваивание `readyₙ & !yₙ` для `n+1`-ого бита `ready`. Для будет удобно воспользоваться конструкцией `generate for`, которая позволяет автоматизировать создание множества однотипных структур. + +Рассмотрим принцип работы этой конструкции. Предположим, мы хотим создать побитовое присваивание 5-битного сигнала `a` 5-битному сигналу `b`. + +Индексы, используемые конструкцией, должны быть объявлены с помощью ключевого слова `genvar`. Далее, в области, ограниченной ключевыми словами `generate`/`endgenerate` описывается цикл присваиваний / созданий модулей: + +```SystemVerilog +logic [4:0] a; +logic [4:0] b; + +// ... + +genvar i; +generate + for(i = 0; i < 5; i++) begin + assign a[i] = b[i]; + end +endgenerate +``` + +Разумеется в этом примере можно было бы просто сделать одно непрерывное присваивание `assign a = b;`, однако в случае реализации верхнего ряда элементов И, подобное многобитное непрерывное присваивание не приведет к синтезу требуемой схемы. + ## Практика Рассмотрим реализацию нашего контроллера прерываний: diff --git a/Labs/15. Programming device/README.md b/Labs/15. Programming device/README.md index 6427841..253caed 100644 --- a/Labs/15. Programming device/README.md +++ b/Labs/15. Programming device/README.md @@ -287,6 +287,12 @@ localparam FLASH_MSG_SIZE = 57; localparam ACK_MSG_SIZE = 4; logic [7:0] [7:0] flash_size_ascii, flash_addr_ascii; +// Блок generate позволяет создавать структуры модуля цикличным или условным +// образом. В данном случае, при описании непрерывных присваиваний была +// обнаружена закономерность, позволяющая описать четверки присваиваний в более +// общем виде, который был описан в виде цикла. +// Важно понимать, данный цикл лишь автоматизирует описание присваиваний и во +// время синтеза схемы развернется в четыре четверки непрерывных присваиваний. genvar i; generate for(i=0; i < 4; i=i+1) begin