Перевод Verilog-кода на SystemVerilog

This commit is contained in:
Andrei Solodovnikov
2023-11-15 14:47:28 +03:00
parent 1b4f666e25
commit 1da4ed0173
11 changed files with 200 additions and 200 deletions

View File

@@ -7,7 +7,7 @@
При должном отношении, поиск ошибок может превратиться в увлекательное детективное расследование, где у вас есть "место преступления" (обнаруженное несоответствие в поведении, обычно это не сама ошибка, а ее следствие, круги на воде) и какой-то "набор улик" (фрагменты лога, исходный код). И вы по чуть-чуть будете разматывать "нераспутываемую паутину лжи", получая все новые улики, ведущие к истинной ошибке.
Этот документ посвящен практикуму по поискам подобных ошибок в **Verilog**-коде.
Этот документ посвящен практикуму по поискам подобных ошибок в **SystemVerilog**-коде.
- [Руководство по поиску и исправлению ошибок в проекте](#руководство-по-поиску-и-исправлению-ошибок-в-проекте)
- [Цель](#цель)
@@ -75,7 +75,7 @@
Открывается следующий код (с курсором на строчке `wire [31:0] res;`):
```Verilog
```SystemVerilog
module tb();
reg [31:0] a;
@@ -142,7 +142,7 @@ vector_abs dut(
Видим два сигнала в Z-состоянии и один сигнал в X-состоянии. Обычно, сигналы с Z-состоянием проще всего исправить, т.к. зачастую это забытое или некорректное подключение провода. Кроме того, сигнал, зависящий от сигнала с Z-состоянием может оказаться в X-состоянии, так что это может быть решением нашей проблемы, поэтому займемся проводами `min` и `min_half`. Сперва займемся сигналом `min` и перейдем к шагу 2 нашего алгоритма (нажимаем правой кнопкой мыши и выбираем `Go To Source Code`):
```Verilog
```SystemVerilog
module vector_abs(
input [31:0] x,
input [31:0] y,
@@ -217,7 +217,7 @@ vector_abs dut(
Значит надо смотреть как формируется результат в нашем устройстве, посмотрим на выход `abs` в модуле `vector_abs`:
```Verilog
```SystemVerilog
assign abs = max + min_half;
```
@@ -238,7 +238,7 @@ assign abs = max + min_half;
Как и с сигналом `abs`, необходимо определить сигналы, влияющие на значение сигнала `min_half`. Данный сигнал подключен к выходу `quotient` модуля `half_divider`, поэтому мы будем смотреть исходный код данного модуля:
```Verilog
```SystemVerilog
module half_divider(
input [31:0] numerator,
output[31:0] quotient
@@ -264,7 +264,7 @@ endmodule
Именно поэтому, когда мы в первый раз пытались посчитать результат "на бумаге", у нас было расхождение с моделью: когда мы делим 1 на 2, мы получаем 0.5, однако деление путем отбрасывания цифры округляет результат вниз (1/2=0, 15/10=1).
Как "отбросить" цифру средствами цифровой логики? Для этого используется операция сдвига вправо.
Операция сдвига вправо в **Verilog** записывается оператором `>>`. Справа от оператора указывается число "отбрасываемых цифр", в нашем случае одна. Но постойте, в логике присваивания стоит оператор `<<`. Это ошибка, исправим ее!
Операция сдвига вправо в **SystemVerilog** записывается оператором `>>`. Справа от оператора указывается число "отбрасываемых цифр", в нашем случае одна. Но постойте, в логике присваивания стоит оператор `<<`. Это ошибка, исправим ее!
Повторяем моделирование.
@@ -294,7 +294,7 @@ max + min/2 = 4 + 3/2 = 4 + 1 = 5
В глаза сразу же бросается, что сигнал `max` внешне отличается от всех остальных — он ведет себя как однобитный сигнал. Если все остальные сигналы 32-разрядные, то и сигнал `max` должен быть таким же. Перейдем к объявлению этого сигнала, чтобы это исправить (нажав правой кнопкой мыши, и выбрав `Go To Source Code`):
```Verilog
```SystemVerilog
module vector_abs(
input [31:0] x,
input [31:0] y,
@@ -314,7 +314,7 @@ max + min/2 = 4 + 3/2 = 4 + 1 = 5
//...
```
Это странно, курсор был установлен на строку `.max(max)`, хотя раньше в этом случае курсор устанавливался на строку, где объявлялся выбранный сигнал. Но вот в чем дело, если мы просмотрим файл внимательно, то не обнаружим объявления сигнала вовсе. Как так вышло, что мы использовали необъявленный сигнал, а САПР не выдал нам ошибку? Дело в том, что стандарт [IEEE 1364-2005](https://ieeexplore.ieee.org/document/1620780) для языка **Verilog** допускает подобное использование необъявленного сигнала. В этом случае, синтезатор неявно создаст одноименный одноразрядный сигнал, что и произошло.
Это странно, курсор был установлен на строку `.max(max)`, хотя раньше в этом случае курсор устанавливался на строку, где объявлялся выбранный сигнал. Но вот в чем дело, если мы просмотрим файл внимательно, то не обнаружим объявления сигнала вовсе. Как так вышло, что мы использовали необъявленный сигнал, а САПР не выдал нам ошибку? Дело в том, что стандарт [IEEE 1364-2005](https://ieeexplore.ieee.org/document/1620780) для языка **SystemVerilog** допускает подобное использование необъявленного сигнала. В этом случае, синтезатор неявно создаст одноименный одноразрядный сигнал, что и произошло.
Для исправления этой ошибки, объявим сигнал `max` с корректной разрядностью и повторим моделирование.

View File

@@ -25,9 +25,9 @@
10. Удалить папку
11. Повторить все действия самостоятельно
## Создание модуля на Verilog
## Создание модуля на SystemVerilog
1. Создать новый Verilog файл, для этого в окне `Sources` нажать на кнопку `+`
1. Создать новый SystemVerilog файл, для этого в окне `Sources` нажать на кнопку `+`
2. В открывшемся окне выбрать `Add or create design source` → Нажать `Next`
3. Нажать `Create File`В открывшемся окне ввести имя модуля `top` и выбрать тип файла SystemVerilog → Нажать `OK`В оставшемся окне нажать `Finish`
4. В открывшемся окне НЕ вводить названия портов и сразу нажать OK → После чего подтвердить выбор `Yes`