Гейтовое моделирование в Verilog: от схем к коду
Большинство цифровых дизайнов выполняется на более высоком уровне абстракции (RTL), но иногда интуитивно проще строить небольшие детерминированные схемы на нижнем уровне с использованием комбинационных элементов and и or. Моделирование на этом уровне называется гейтовым моделированием (gate-level modeling), так как оно использует гейты и имеет один-к-одному соответствие между аппаратной схемой и Verilog-кодом.
Verilog поддерживает базовые логические гейты, называемые примитивами (primitives), так как они могут инстанцироваться как модули — они уже предопределены.
Гейты And/Or/Xor
Эти примитивы реализуют AND и OR гейты, принимающие множество скалярных входов и выдающие один скалярный выход. Первый терминал в списке аргументов — выход, обновляемый при изменении любого входа.
module gates (
input a, b,
output c, d, e
);
and (c, a, b); // c — выход, a,b — входы
or (d, a, b); // d — выход, a,b — входы
xor (e, a, b); // e — выход, a,b — входы
endmodule
module tb;
reg a, b;
wire c, d, e;
integer i;
gates u0 (.a(a), .b(b), .c(c), .d(d), .e(e));
initial begin
{a, b} = 0;
$monitor ("[T=%0t a=%0b b=%0b c(and)=%0b d(or)=%0b e(xor)=%0b", $time, a, b, c, d, e);
for (i = 0; i < 10; i = i+1) begin
#1 a <= $random; b <= $random;
end
end
endmodule
Simulation Log
ncsim> run [T=0 a=0 b=0 c(and)=0 d(or)=0 e(xor)=0 [T=1 a=0 b=1 c(and)=0 d(or)=1 e(xor)=1 [T=2 a=1 b=1 c(and)=1 d(or)=1 e(xor)=0 [T=4 a=1 b=0 c(and)=0 d(or)=1 e(xor)=1 [T=5 a=1 b=1 c(and)=1 d(or)=1 e(xor)=0 [T=6 a=0 b=1 c(and)=0 d(or)=1 e(xor)=1 [T=7 a=1 b=0 c(and)=0 d(or)=1 e(xor)=1 [T=10 a=1 b=1 c(and)=1 d(or)=1 e(xor)=0 ncsim: *W,RNQUIE: Simulation is complete.
Гейты Nand/Nor/Xnor
Инверсные версии доступны как nand, nor, xnor. Тот же дизайн, но примитивы заменены на инверсные.
module gates (
input a, b,
output c, d, e
);
nand (c, a, b);
nor (d, a, b);
xnor (e, a, b);
endmodule
module tb;
reg a, b;
wire c, d, e;
integer i;
gates u0 (.a(a), .b(b), .c(c), .d(d), .e(e));
initial begin
{a, b} = 0;
$monitor ("[T=%0t a=%0b b=%0b c(nand)=%0b d(nor)=%0b e(xnor)=%0b", $time, a, b, c, d, e);
for (i = 0; i < 10; i = i+1) begin
#1 a <= $random; b <= $random;
end
end
endmodule
Simulation Log
ncsim> run [T=0 a=0 b=0 c(nand)=1 d(nor)=1 e(xnor)=1 [T=1 a=0 b=1 c(nand)=1 d(nor)=0 e(xnor)=0 [T=2 a=1 b=1 c(nand)=0 d(nor)=0 e(xnor)=1 [T=4 a=1 b=0 c(nand)=1 d(nor)=0 e(xnor)=0 [T=5 a=1 b=1 c(nand)=0 d(nor)=0 e(xnor)=1 [T=6 a=0 b=1 c(nand)=1 d(nor)=0 e(xnor)=0 [T=7 a=1 b=0 c(nand)=1 d(nor)=0 e(xnor)=0 [T=10 a=1 b=1 c(nand)=0 d(nor)=0 e(xnor)=1 ncsim: *W,RNQUIE: Simulation is complete.
Эти гейты могут иметь более двух входов.
module gates (
input a, b, c, d,
output x, y, z
);
and (x, a, b, c, d);
or (y, a, b, c, d);
nor (z, a, b, c, d);
endmodule
module tb;
reg a, b, c, d;
wire x, y, z;
integer i;
gates u0 (.a(a), .b(b), .c(c), .d(d), .x(x), .y(y), .z(z));
initial begin
{a, b, c, d} = 0;
$monitor ("[T=%0t a=%0b b=%0b c=%0b d=%0b x=%0b y=%0b x=%0b", $time, a, b, c, d, x, y, z);
for (i = 0; i < 10; i = i+1) begin
#1 a <= $random; b <= $random; c <= $random; d <= $random;
end
end
endmodule
Simulation Log
ncsim> run [T=0 a=0 b=0 c=0 d=0 x=0 y=0 x=1 [T=1 a=0 b=1 c=1 d=1 x=0 y=1 x=0 [T=2 a=1 b=1 c=1 d=0 x=0 y=1 x=0 [T=3 a=1 b=1 c=0 d=1 x=0 y=1 x=0 [T=4 a=1 b=0 c=1 d=0 x=0 y=1 x=0 [T=5 a=1 b=0 c=1 d=1 x=0 y=1 x=0 [T=6 a=0 b=1 c=0 d=0 x=0 y=1 x=0 [T=7 a=0 b=1 c=0 d=1 x=0 y=1 x=0 [T=8 a=1 b=1 c=1 d=0 x=0 y=1 x=0 [T=9 a=0 b=0 c=0 d=1 x=0 y=1 x=0 [T=10 a=0 b=1 c=1 d=1 x=0 y=1 x=0 ncsim: *W,RNQUIE: Simulation is complete.
Гейты Buf/Not
Имеют один скалярный вход и один или несколько выходов. buf — буфер, передает значение входа на выход без изменения полярности. not — инвертор, инвертирует полярность: 0→1, 1→0.
module gates (
input a,
output c, d
);
buf (c, a); // c — выход, a — вход
not (d, a); // d — выход, a — вход
endmodule
module tb;
reg a;
wire c, d;
integer i;
gates u0 (.a(a), .c(c), .d(d));
initial begin
a = 0;
$monitor ("[T=%0t a=%0b c(buf)=%0b d(not)=%0b", $time, a, c, d);
for (i = 0; i < 10; i = i+1) begin
#1 a <= $random;
end
end
endmodule
Simulation Log
xcelium> run [T=0 a=0 c(buf)=0 d(not)=1 [T=2 a=1 c(buf)=1 d(not)=0 [T=8 a=0 c(buf)=0 d(not)=1 [T=9 a=1 c(buf)=1 d(not)=0 xmsim: *W,RNQUIE: Simulation is complete.
Последний терминал в списке портов подключается ко входу гейта, остальные — к выходу. Пример многовыходного буфера (редко используется).
module gates (
input a,
output c, d
);
not (c, d, a); // c,d — выходы, a — вход
endmodule
Simulation Log
xcelium> run [T=0 a=0 c=1 d=1 [T=2 a=1 c=0 d=0 [T=8 a=0 c=1 d=1 [T=9 a=1 c=0 d=0 xmsim: *W,RNQUIE: Simulation is complete.
Bufif/Notif
Буферы и инверторы с дополнительным управляющим сигналом для разрешения выхода доступны через примитивы bufif и notif. У этих гейтов валидный выход только если управляющий сигнал активен, иначе выход в высокоомном состоянии (Z). Две версии: нормальная полярность управления (1) — bufif1, notif1; инверсная полярность (0) — bufif0, notif0.
Verilog
- Проектирование и проверка базовой схемы элемента И-НЕ (NAND) на микросхеме 4011
- Полевые транзисторы с p-n переходом (JFET): направление тока затвора и N-канал vs P-канал
- Интегральные схемы: основы цифровых логических элементов
- Область видимости переменных в C#: класс, метод и блок
- Уровни абстракции проектирования: понятное руководство по архитектуре чипов
- Практическое гейтовое дизайнирование в Verilog: AND, OR, NOT гейты и 2x1 мультиплексор
- Понимание задержек гейтов в Verilog: точное тайминг для надежных цифровых схем
- Продвинутое коммутаторное моделирование в Verilog (Switch-Level Modeling)
- Нивелировочная рейка (Level Staff): определение, виды и применение в геодезии
- Точная выверка токарного станка: профессиональное руководство