Типы данных Verilog: биты, провода (wire) и логические значения
Основная цель типов данных в Verilog — представить элементы хранения данных (биты в триггерах) и элементы передачи (провода, соединяющие гейты и последовательные структуры).
Какие значения могут хранить переменные?
Почти все типы данных могут принимать только одно из четырёх значений (кроме real и event):
| 0 | логический ноль, ложь |
| 1 | логическая единица, истина |
| x | неизвестное логическое значение (может быть 0 или 1) |
| z | состояние высокого импеданса |
На тайм-диаграммах и волнах симуляции обычно: красный — X, оранжевый посередине — высокий импеданс Z.
Что подразумевает система значений Verilog?
Verilog описывает аппаратные элементы (триггеры, комбинационную логику NAND, NOR), поэтому моделирует аппаратную систему значений. Логическая единица — напряжение питания Vdd (0.8В – 3В+ в зависимости от технологического узла). Логический ноль — земля, 0В.
X или x означает, что значение просто неизвестно в данный момент (может быть 0 или 1). Это отличается от булевой логики, где X значит «неважно» (don't care).
Как в незамкнутой цепи провод не подключён ни к чему и имеет высокий импеданс на узле, так и в Verilog любой неподключённый провод даёт высокий импеданс Z или z.
Сети (Nets) и переменные (Variables)
Nets и variables — две основные группы типов данных, представляющие разные аппаратные структуры и отличающиеся способом присваивания и удержания значений.
Nets (сети)
Nets соединяют аппаратные сущности (гейты) и сами по себе не хранят значение. На изображении сеть net_11 соединяет выход AND-гейта с первым входом триггера data_0. Два входа AND-гейта соединены с net_45 и net_67.
Существует несколько типов сетей, но самый популярный в цифровом дизайне — wire. wire — тип данных Verilog для соединения элементов и сетей, управляемых одним гейтом или непрерывным присваиванием. Аналогичен электрическому проводу на макетной плате.
Когда нужно несколько сетей, их можно объединить в один wire. На изображении 4-битный wire, передающий 4 отдельных значения. Такие сущности шириной более 1 называются векторами (подробнее в следующей статье).
wire [3:0] n0; // 4-битный wire -> это вектор
Недопустимо повторно объявлять имя, уже объявленное как сеть, параметр или переменная:
module design;
wire abc; wire a; wire b; wire c; wire abc; // Ошибка: "abc" уже объявлен
assign abc = a & b | c;
endmodule
Переменные (Variables)
Переменная — абстракция элемента хранения данных, способная удерживать значения. Триггер — хороший пример элемента хранения.
Тип данных reg в Verilog моделирует аппаратные регистры, так как удерживает значения между присваиваниями. Обратите внимание: reg не всегда представляет триггер, может использоваться и для комбинационной логики.
На изображении слева — триггер на 1 бит, справа — на 4 бита.
Другие типы данных
integer
integer — переменная общего назначения шириной 32 бита для моделирования железа, хранит целые значения.
integer count; // Count — целое значение > 0
time
time — беззнаковая 64-битная переменная для хранения величин времени симуляции (отладка). realtime хранит время как floating-point.
time end_time; // end_time = 50ns
realtime rtime; // rtime = 40.25ps
real
real хранит значения с плавающей точкой, присваивается как integer и reg.
real float; // float = 12.344
Пример
module testbench;
integer int_a;
real real_b;
time time_c;
initial begin
int_a = 32'hcafe_1234;
real_b = 0.1234567;
#20;
time_c = $time;
$display ("int_a = 0x%0h", int_a);
$display ("real_b = %0.5f", real_b);
$display ("time_c = %0t", time_c);
end
endmodule
Simulation Log
ncsim> run int_a = 0xcafe1234 real_b = 0.12346 time_c = 20 ncsim: *W,RNQUIE: Simulation is complete.
Строки в Verilog
Строки хранятся в reg, ширина reg должна быть достаточной. Каждый символ — ASCII, 1 байт. Если переменная меньше строки — Verilog обрезает старшие биты. Если больше — дополняет нулями слева.
// "Hello World" требует 11 байт
reg [8*11:1] str = "Hello World"; // 11 байт, str = "Hello World"
reg [8*5:1] str = "Hello World"; // 5 байт (обрезано), str = "World"
reg [8*20:1] str = "Hello World"; // 20 байт (дополнено нулями), str = " Hello World"
Полный пример симуляции трёх переменных:
module testbench;
reg [8*11:1] str1;
reg [8*5:1] str2;
reg [8*20:1] str3;
initial begin
str1 = "Hello World";
str2 = "Hello World";
str3 = "Hello World";
$display ("str1 = %s", str1);
$display ("str2 = %s", str2);
$display ("str3 = %s", str3);
end
endmodule
str1 имеет правильный размер — печатается вся строка. str2 хранит только 5 байт — старшие 6 байт обрезаны, остаётся "World". str3 больше 11 байт — слева добавляются нули (пробелы), значение становится " Hello World".
Simulation Log
ncsim> run str1 = Hello World str2 = World str3 = Hello World ncsim: *W,RNQUIE: Simulation is complete.
Verilog
- Мастерство C# переменных и примитивных типов данных: полное руководство
- Понимание типов данных C++: основы, модификаторы и лучшие практики
- Типы данных в C: int, float, char и другие — полное руководство
- Освоение типов данных в Python: практическое руководство
- Примитивные типы данных в Java: полное руководство с примерами
- 5 моделей центров обработки данных: дизайн, кейсы и примеры
- Восемь ключевых моделей облачных вычислений 2021 года
- 8 распространённых типов утечек данных — реальные примеры и последствия
- Освоение Verilog: полное руководство по проектированию цифровых схем
- Освоение конкатенации в Verilog: практическое руководство