Merge pull request #55 from MPSU/svg-transition

Перенос drawio-изображений в svg-формат
This commit is contained in:
Andrei Solodovnikov
2024-01-31 17:54:53 +03:00
committed by GitHub
159 changed files with 395 additions and 126 deletions

View File

@@ -6,7 +6,7 @@
Предположим, у нас есть следующий набор сигналов:
![../.pic/Basic%20Verilog%20structures/concatenation/fig_01.drawio.png](../.pic/Basic%20Verilog%20structures/concatenation/fig_01.drawio.png)
![../.pic/Basic%20Verilog%20structures/concatenation/fig_01.drawio.svg](../.pic/Basic%20Verilog%20structures/concatenation/fig_01.drawio.svg)
```SystemVerilog
@@ -25,7 +25,7 @@ logic [5:0] e;
- на его следующие 2 бита подавались биты `[4:3]` сигнала `c`
- на младшие 2 бита подавался сигнал `d`
![../.pic/Basic%20Verilog%20structures/concatenation/fig_02.drawio.png](../.pic/Basic%20Verilog%20structures/concatenation/fig_02.drawio.png)
![../.pic/Basic%20Verilog%20structures/concatenation/fig_02.drawio.svg](../.pic/Basic%20Verilog%20structures/concatenation/fig_02.drawio.svg)
Это можно сделать путем 4 непрерывных присваиваний:
@@ -58,7 +58,7 @@ assign e = {a, b, c[4:3], d};
Кроме того, возможна и обратная ситуация. Предположим, мы хотим подать отдельные биты сигнала `e` на различные провода:
![../.pic/Basic%20Verilog%20structures/concatenation/fig_02.drawio.png](../.pic/Basic%20Verilog%20structures/concatenation/fig_02.drawio.png)
![../.pic/Basic%20Verilog%20structures/concatenation/fig_02.drawio.svg](../.pic/Basic%20Verilog%20structures/concatenation/fig_02.drawio.svg)
```SystemVerilog
logic a;
@@ -105,4 +105,3 @@ logic [7:0] e;
assign e = { {3{c[4:3]}}, a, b};
```

View File

@@ -86,19 +86,19 @@ endmodule
Для начала, добавим на структурную схему входы и выходы модуля:
![../.pic/Basic%20Verilog%20structures/controllers/fig_01.drawio.png](../.pic/Basic%20Verilog%20structures/controllers/fig_01.drawio.png)
![../.pic/Basic%20Verilog%20structures/controllers/fig_01.drawio.svg](../.pic/Basic%20Verilog%20structures/controllers/fig_01.drawio.svg)
В первую очередь, спецификация вводит понятия **запрос на чтение** и **запрос на запись**. Создадим вспомогательные провода, которые будут сигнализировать о том, что произошел **запрос на чтение** или **запрос на запись**:
![../.pic/Basic%20Verilog%20structures/controllers/fig_02.drawio.png](../.pic/Basic%20Verilog%20structures/controllers/fig_02.drawio.png)
![../.pic/Basic%20Verilog%20structures/controllers/fig_02.drawio.svg](../.pic/Basic%20Verilog%20structures/controllers/fig_02.drawio.svg)
Далее, спецификация накладывает ограничение на допустимые адреса и значения. Поэтому создадим вспомогательные сигналы, сигнализирующие о том, что текущий адрес соответствует одному из регистров контроллера, а данные для записи соответствуют диапазону допустимых значений этих регистров:
![../.pic/Basic%20Verilog%20structures/controllers/fig_03.drawio.png](../.pic/Basic%20Verilog%20structures/controllers/fig_03.drawio.png)
![../.pic/Basic%20Verilog%20structures/controllers/fig_03.drawio.svg](../.pic/Basic%20Verilog%20structures/controllers/fig_03.drawio.svg)
Теперь, когда подготовительные работы выполнены, начнем с реализации сброса этого контроллера. Сброс может произойти в двух случаях: когда `rst_i == 1` либо же в случае **запроса на запись** единицы по адресу `0x24`. Создадим вспомогательный провод `rst`, который будет равен единице в случае, если произойдет любое из этих событий. Этот сигнал будет сбрасывать все созданные в данном модуле регистры.
![../.pic/Basic%20Verilog%20structures/controllers/fig_04.drawio.png](../.pic/Basic%20Verilog%20structures/controllers/fig_04.drawio.png)
![../.pic/Basic%20Verilog%20structures/controllers/fig_04.drawio.svg](../.pic/Basic%20Verilog%20structures/controllers/fig_04.drawio.svg)
Продолжим описание контроллера, создав первый из **архитектурных регистров**`led_val`. Запись в этот регистр возможна только в случае выполнения трех условий:
@@ -108,7 +108,7 @@ endmodule
Создадим вспомогательный сигнал `val_en`, который будет равен единице только в случае выполнения этих трех условий:
![../.pic/Basic%20Verilog%20structures/controllers/fig_05.drawio.png](../.pic/Basic%20Verilog%20structures/controllers/fig_05.drawio.png)
![../.pic/Basic%20Verilog%20structures/controllers/fig_05.drawio.svg](../.pic/Basic%20Verilog%20structures/controllers/fig_05.drawio.svg)
Теперь реализация регистра `lev_val` становится совершенно тривиальной задачей, ведь у нас есть:
@@ -116,11 +116,11 @@ endmodule
* сигнал разрешения записи в регистр `val_en`;
* сигнал данных для записи в регистр `write_data_i`(из которого мы будем брать только младшие 16 бит данных).
![../.pic/Basic%20Verilog%20structures/controllers/fig_06.drawio.png](../.pic/Basic%20Verilog%20structures/controllers/fig_06.drawio.png)
![../.pic/Basic%20Verilog%20structures/controllers/fig_06.drawio.svg](../.pic/Basic%20Verilog%20structures/controllers/fig_06.drawio.svg)
Аналогичным образом реализуем еще один **архитектурный регистр** `led_mode`:
![../.pic/Basic%20Verilog%20structures/controllers/fig_07.drawio.png](../.pic/Basic%20Verilog%20structures/controllers/fig_07.drawio.png)
![../.pic/Basic%20Verilog%20structures/controllers/fig_07.drawio.svg](../.pic/Basic%20Verilog%20structures/controllers/fig_07.drawio.svg)
Два этих регистра должны управлять поведением выходного сигнала `led_o` следующим образом:
@@ -140,7 +140,7 @@ endmodule
* счетчик досчитал до 20 миллионов (`cntr >= 32'd20_000_000`);
* в остальных ситуациях, счетчик инкрементирует свое значение.
![../.pic/Basic%20Verilog%20structures/controllers/fig_08.drawio.png](../.pic/Basic%20Verilog%20structures/controllers/fig_08.drawio.png)
![../.pic/Basic%20Verilog%20structures/controllers/fig_08.drawio.svg](../.pic/Basic%20Verilog%20structures/controllers/fig_08.drawio.svg)
Последним этапом описания контроллера будет добавление логики управления выходным сигналом `read_data_o`.
@@ -154,4 +154,4 @@ endmodule
Таким образом, итоговая схема примет вид:
![../.pic/Basic%20Verilog%20structures/controllers/fig_09.drawio.png](../.pic/Basic%20Verilog%20structures/controllers/fig_09.drawio.png)
![../.pic/Basic%20Verilog%20structures/controllers/fig_09.drawio.svg](../.pic/Basic%20Verilog%20structures/controllers/fig_09.drawio.svg)

View File

@@ -10,7 +10,7 @@
Определим наш модуль:
![../.pic/Basic%20Verilog%20structures/modules/fig_01.drawio.png](../.pic/Basic%20Verilog%20structures/modules/fig_01.drawio.png)
![../.pic/Basic%20Verilog%20structures/modules/fig_01.drawio.svg](../.pic/Basic%20Verilog%20structures/modules/fig_01.drawio.svg)
```SystemVerilog
module
@@ -21,7 +21,7 @@ endmodule
У всякого модуля должно быть название. Назовём его `box`. В круглых скобках пишутся имена портов, их направление и типы. Если модуль не имеет ни входов, ни выходов, внутри скобок ничего не пишется. После них всегда ставится точка с запятой.
![../.pic/Basic%20Verilog%20structures/modules/fig_02.drawio.png](../.pic/Basic%20Verilog%20structures/modules/fig_02.drawio.png)
![../.pic/Basic%20Verilog%20structures/modules/fig_02.drawio.svg](../.pic/Basic%20Verilog%20structures/modules/fig_02.drawio.svg)
```SystemVerilog
module box();
@@ -32,7 +32,7 @@ endmodule
Модуль без входов и выходов (портов) — это просто коробка, которая никак не взаимодействует с внешним миром. Подключим к нему два входных сигнала `a, b` и один выходной `q`. Для объявления портов, необходимо указать направление порта (вход это или выход), и тип используемого сигнала. В рамках данного курса лабораторных работ в качестве типа и входов и выходов будет использоваться тип `logic`, о котором будет рассказано чуть позже.
![../.pic/Basic%20Verilog%20structures/modules/fig_03.drawio.png](../.pic/Basic%20Verilog%20structures/modules/fig_03.drawio.png)
![../.pic/Basic%20Verilog%20structures/modules/fig_03.drawio.svg](../.pic/Basic%20Verilog%20structures/modules/fig_03.drawio.svg)
```SystemVerilog
module box(
@@ -47,7 +47,7 @@ endmodule
Внутри модуля могут быть объявления сигналов, параметров, констант и т.п., о которых другой модуль не узнает. Объявим внутри модуля `box` провод `c`.
![../.pic/Basic%20Verilog%20structures/modules/fig_04.drawio.png](../.pic/Basic%20Verilog%20structures/modules/fig_04.drawio.png)
![../.pic/Basic%20Verilog%20structures/modules/fig_04.drawio.svg](../.pic/Basic%20Verilog%20structures/modules/fig_04.drawio.svg)
```SystemVerilog
module box(
@@ -66,7 +66,7 @@ endmodule
Подключим провод `c` ко входу `a`. Для этого используется конструкция `assign c = a;`. Такая конструкция называется **непрерывным присваиванием**. Если очень сильно упростить, то непрерывное присваивание схоже со спайкой двух проводов. После подобного присваивания, провод `c` всегда будет иметь то же значение, что и `a` — как только входной сигнал `a` изменит свое значение, внутренний провод `c` также изменит свое значение (проводу `c` будет **непрерывно присваиваться** значение входа `a`).
![../.pic/Basic%20Verilog%20structures/modules/fig_05.drawio.png](../.pic/Basic%20Verilog%20structures/modules/fig_05.drawio.png)
![../.pic/Basic%20Verilog%20structures/modules/fig_05.drawio.svg](../.pic/Basic%20Verilog%20structures/modules/fig_05.drawio.svg)
```SystemVerilog
module box(
@@ -91,7 +91,7 @@ endmodule
К примеру, мы можем присвоить проводу `с` значение выхода логического вентиля. Пусть нам нужно, чтобы к сигналу `c` был подключен результат операции `a ИЛИ b`.
![../.pic/Basic%20Verilog%20structures/modules/fig_06.drawio.png](../.pic/Basic%20Verilog%20structures/modules/fig_06.drawio.png)
![../.pic/Basic%20Verilog%20structures/modules/fig_06.drawio.svg](../.pic/Basic%20Verilog%20structures/modules/fig_06.drawio.svg)
Такую схему можно реализовать следующим описанием:
@@ -112,7 +112,7 @@ endmodule
Пусть в схеме имеется ещё один логический вентиль - Исключающее ИЛИ. На него подаётся результат операции `a ИЛИ b`, то есть `c`, а также входной сигнал `b`. Результат операции `c ИСКЛЮЧАЮЩЕЕ ИЛИ b` подаётся на выход `q` нашего модуля.
![../.pic/Basic%20Verilog%20structures/modules/fig_07.drawio.png](../.pic/Basic%20Verilog%20structures/modules/fig_07.drawio.png)
![../.pic/Basic%20Verilog%20structures/modules/fig_07.drawio.svg](../.pic/Basic%20Verilog%20structures/modules/fig_07.drawio.svg)
```SystemVerilog
module box(
@@ -182,7 +182,7 @@ endmodule
Допустим, у нас есть модуль `inv`, который подает на выход инверсию входа, и мы хотим реализовать модуль `top`, который хочет использовать функционал модуля `inv` следующим образом:
![../.pic/Basic%20Verilog%20structures/modules/fig_08.drawio.png](../.pic/Basic%20Verilog%20structures/modules/fig_08.drawio.png)
![../.pic/Basic%20Verilog%20structures/modules/fig_08.drawio.svg](../.pic/Basic%20Verilog%20structures/modules/fig_08.drawio.svg)
Опишем `inv`:
@@ -223,7 +223,7 @@ endmodule
Мы можем подключить сколько угодно экземпляров одного модуля, поэтому у каждого из экземпляра должно быть свое уникальное имя. Пусть `c` подаётся на логический вентиль И вместе со входом `b`. Результат операции И тоже пойдет на инвертор, а затем на выход `q` модуля top.
![../.pic/Basic%20Verilog%20structures/modules/fig_09.drawio.png](../.pic/Basic%20Verilog%20structures/modules/fig_09.drawio.png)
![../.pic/Basic%20Verilog%20structures/modules/fig_09.drawio.svg](../.pic/Basic%20Verilog%20structures/modules/fig_09.drawio.svg)
Тогда в нашем описании добавится подключение второго модуля `inv` и провод `c`.
@@ -293,4 +293,4 @@ ___
Обратите внимание, что вход `a` модуля `top` является двухразрядным: нулевой его бит идет на вход `a` модуля `or`, первый бит идет на вход `b` модуля `or`.
![../.pic/Basic%20Verilog%20structures/modules/fig_10.drawio.png](../.pic/Basic%20Verilog%20structures/modules/fig_10.drawio.png)
![../.pic/Basic%20Verilog%20structures/modules/fig_10.drawio.svg](../.pic/Basic%20Verilog%20structures/modules/fig_10.drawio.svg)

View File

@@ -4,11 +4,11 @@
Иными словами, мультиплексор — это переключатель (коммутатор), соединяющий выход с одним из множества входов.
![../.pic/Basic%20Verilog%20structures/multiplexor/fig_01.drawio.png](../.pic/Basic%20Verilog%20structures/multiplexors/fig_01.drawio.png)
![../.pic/Basic%20Verilog%20structures/multiplexor/fig_01.drawio.svg](../.pic/Basic%20Verilog%20structures/multiplexors/fig_01.drawio.svg)
Для начала создадим простой двухвходовой мультиплексор. Предположим, на `Y` нам необходимо передать один из сигналов — `D0` или `D1` в зависимости от значения управляющего сигнала `S`: когда `S==0`, на `Y` подается сигнал `D0`, в противном случае — `D1`.
![../.pic/Basic%20Verilog%20structures/multiplexors/fig_02.drawio.png](../.pic/Basic%20Verilog%20structures/multiplexors/fig_02.drawio.png)
![../.pic/Basic%20Verilog%20structures/multiplexors/fig_02.drawio.svg](../.pic/Basic%20Verilog%20structures/multiplexors/fig_02.drawio.svg)
На языке SystemVerilog это можно описать несколькими способами. Первый — с помощью **[тернарного условного оператора](https://ru.wikipedia.org/wiki/Тернарная_условная_операция)**:
@@ -49,7 +49,7 @@ assign Y = S==1 ? D1 : D0;
Данное выражение говорит нам, что если `S==1`, то `Y` присваивается значение `D1`, в противном случае — значение `D0`.
![../.pic/Basic%20Verilog%20structures/multiplexors/fig_03.drawio.png](../.pic/Basic%20Verilog%20structures/multiplexors/fig_03.drawio.png)
![../.pic/Basic%20Verilog%20structures/multiplexors/fig_03.drawio.svg](../.pic/Basic%20Verilog%20structures/multiplexors/fig_03.drawio.svg)
Также мультиплексор можно описать через конструкцию `if-else` в блоке `always`.
@@ -137,7 +137,7 @@ end // (так же как каждый begin должен ок
Рассмотрим вариант посложнее и опишем следующую схему:
![../.pic/Basic%20Verilog%20structures/multiplexors/fig_04.drawio.png](../.pic/Basic%20Verilog%20structures/multiplexors/fig_04.drawio.png)
![../.pic/Basic%20Verilog%20structures/multiplexors/fig_04.drawio.svg](../.pic/Basic%20Verilog%20structures/multiplexors/fig_04.drawio.svg)
Здесь уже используется мультиплексор 4в1. Управляющий сигнал `S` в данном случае двухбитный. В блоке `case` мы перечисляем всевозможные варианты значений `S` и описываем выход мультиплексора.
@@ -269,4 +269,4 @@ endmodule
Как, по-вашему, описать на языке SystemVerilog схему, приведённую ниже?
![../.pic/Basic%20Verilog%20structures/multiplexors/fig_04.drawio.png](../.pic/Basic%20Verilog%20structures/multiplexors/fig_04.drawio.png)
![../.pic/Basic%20Verilog%20structures/multiplexors/fig_04.drawio.svg](../.pic/Basic%20Verilog%20structures/multiplexors/fig_04.drawio.svg)

View File

@@ -6,7 +6,7 @@
logic reg_name;
```
![../.pic/Basic%20Verilog%20structures/registers/fig_01.drawio.png](../.pic/Basic%20Verilog%20structures/registers/fig_01.drawio.png)
![../.pic/Basic%20Verilog%20structures/registers/fig_01.drawio.svg](../.pic/Basic%20Verilog%20structures/registers/fig_01.drawio.svg)
У регистра может быть несколько входов и один выход. Основных входов, без которых не может существовать регистр два: вход данных и вход тактирующего синхроимпульса. На рисунке они обозначены как `D` и `clk`. Опциональный вход сигнала сброса (`rst`) позволяет обнулять содержимое регистра вне зависимости от входных данных и может работать как с тактовым синхроимпульсом (синхронный сброс), так и без него (асинхронный сброс).
@@ -18,11 +18,11 @@ logic reg_name;
Поскольку все сигналы в цифровой схеме передаются по цепям, удобно представлять, что к выходу регистра всегда неявно подключен провод, с именем, совпадающим с именем регистра, поэтому вы можете использовать имя регистра в дальнейшей цифровой логике:
![../.pic/Basic%20Verilog%20structures/registers/fig_02.drawio.png](../.pic/Basic%20Verilog%20structures/registers/fig_02.drawio.png)
![../.pic/Basic%20Verilog%20structures/registers/fig_02.drawio.svg](../.pic/Basic%20Verilog%20structures/registers/fig_02.drawio.svg)
Итак, мы добавили регистр на холст схемы, но как соединить его с какой-то логикой? Предположим, у нас есть сигнал тактового синхроимпульса и данные, которые мы хотим записать:
![../.pic/Basic%20Verilog%20structures/registers/fig_03.drawio.png](../.pic/Basic%20Verilog%20structures/registers/fig_03.drawio.png)
![../.pic/Basic%20Verilog%20structures/registers/fig_03.drawio.svg](../.pic/Basic%20Verilog%20structures/registers/fig_03.drawio.svg)
Данной схеме соответствует код:
@@ -40,7 +40,7 @@ modulе rеg_ехаmрlе(
Очевидно, мы хотим подключить сигнал `clk` ко входу тактирующего сигнала регистра, вход `data` ко входу данных, а выход регистра к выходу `reg_data`:
![../.pic/Basic%20Verilog%20structures/registers/fig_04.drawio.png](../.pic/Basic%20Verilog%20structures/registers/fig_04.drawio.png)
![../.pic/Basic%20Verilog%20structures/registers/fig_04.drawio.svg](../.pic/Basic%20Verilog%20structures/registers/fig_04.drawio.svg)
Запись в регистр возможна только по фронту тактирующего синхроимпульса. **Фронт** — это переход сигнала из нуля в единицу (**положительный фронт**), либо из единицы в ноль (**отрицательный фронт**).
@@ -116,7 +116,7 @@ modulе rеg_ехаmрlе(
Итоговая схема регистра со сбросом и сигналом разрешения записи:
![../.pic/Basic%20Verilog%20structures/registers/fig_05.drawio.png](../.pic/Basic%20Verilog%20structures/registers/fig_05.drawio.png)
![../.pic/Basic%20Verilog%20structures/registers/fig_05.drawio.svg](../.pic/Basic%20Verilog%20structures/registers/fig_05.drawio.svg)
Помимо прочего есть еще одно важное правило, которое необходимо знать при описании регистра:
@@ -126,7 +126,7 @@ modulе rеg_ехаmрlе(
В блоке присваивания регистру можно описывать и комбинационную логику, стоящую перед ним, например схему:
![../.pic/Basic%20Verilog%20structures/registers/fig_06.drawio.png](../.pic/Basic%20Verilog%20structures/registers/fig_06.drawio.png)
![../.pic/Basic%20Verilog%20structures/registers/fig_06.drawio.svg](../.pic/Basic%20Verilog%20structures/registers/fig_06.drawio.svg)
можно описать как
@@ -214,4 +214,4 @@ modulе rеg_ехаmрlе(
Как, по-вашему, описать на языке SystemVerilog схему, приведённую ниже?
![../.pic/Basic%20Verilog%20structures/registers/fig_07.drawio.png](../.pic/Basic%20Verilog%20structures/registers/fig_07.drawio.png)
![../.pic/Basic%20Verilog%20structures/registers/fig_07.drawio.svg](../.pic/Basic%20Verilog%20structures/registers/fig_07.drawio.svg)