Проектирование комбинационной логики в Verilog с помощью assign
Оператор assign в Verilog обычно используется для непрерывного управления сигналом типа wire и синтезируется в комбинационную логику. Вот ещё примеры дизайнов с assign.
Пример #1: Простая комбинационная логика
Код ниже реализует простую цифровую комбинационную логику с выходным проводом z, непрерывно управляемым через assign для реализации цифрового уравнения.
module combo ( input a, b, c, d, e, output z);
assign z = ((a & b) | (c ^ d) & ~e);
endmodule
Модуль combo элаборируется в следующую аппаратную схему с цифровыми гейтами.
Тестбенч
Тестбенч — платформа для симуляции дизайна, чтобы убедиться, что он ведёт себя как ожидается. Все комбинации входов подаются в дизайн-модуль через for цикл с задержкой 10 единиц времени.
module tb;
reg a, b, c, d, e; wire z; integer i;
combo u0 ( .a(a), .b(b), .c(c), .d(d), .e(e), .z(z));
initial begin
a <= 0; b <= 0; c <= 0; d <= 0; e <= 0;
$monitor ("a=%0b b=%0b c=%0b d=%0b e=%0b z=%0b", a, b, c, d, e, z);
for (i = 0; i < 32; i = i + 1) begin {a, b, c, d, e} = i; #10; end
end
endmodule
Simulation Log показывает все 32 комбинации входов и соответствующие выходы.
Пример #2: Половинный сумматор (Half Adder)
Модуль полусумматора принимает два скалярных входа a, b и использует комбинационную логику для выходов sum и переноса cout. Сумма — XOR между a и b, перенос — AND.
module ha ( input a, b, output sum, cout);
assign sum = a ^ b; assign cout = a & b;
endmodule
Тестбенч
module tb; reg a, b; wire sum, cout; integer i;
ha u0 ( .a(a), .b(b), .sum(sum), .cout(cout));
initial begin a <= 0; b <= 0; $monitor("a=%0b b=%0b sum=%0b cout=%0b", a, b, sum, cout);
for (i = 0; i < 4; i = i + 1) begin {a, b} = i; #10; end end endmodule
Simulation Log: 4 комбинации входов.
Пример #3: Полный сумматор (Full Adder)
Полный сумматор можно построить из полусумматора или применить комбинационную логику напрямую с assign для sum и cout.
module fa ( input a, b, cin, output sum, cout);
assign sum = (a ^ b) ^ cin;
assign cout = (a & b) | ((a ^ b) & cin);
endmodule
Тестбенч
module tb; reg a, b, cin; wire sum, cout; integer i;
fa u0 ( .a(a), .b(b), .cin(cin), .sum(sum), .cout(cout));
initial begin a <= 0; b <= 0; $monitor("a=%0b b=%0b cin=%0b sum=%0b cout=%0b", a, b, cin, sum, cout);
for (i = 0; i < 8; i = i + 1) begin {a, b, cin} = i; #10; end end endmodule
Simulation Log: 8 комбинаций.
Пример #4: Мультиплексор 2×1
Простой 2×1 мультиплексор использует тернарный оператор: если sel = 1, выход управляется a, иначе — b.
module mux_2x1 (input a, b, sel, output c);
assign c = sel ? a : b;
endmodule
Тестбенч
module tb; reg a, b, sel; wire c; integer i;
mux_2x1 u0 ( .a(a), .b(b), .sel(sel), .c(c));
initial begin a <= 0; b <= 0; sel <= 0; $monitor("a=%0b b=%0b sel=%0b c=%0b", a, b, sel, c);
for (i = 0; i < 3; i = i + 1) begin {a, b, sel} = i; #10; end end endmodule
Пример #5: Демультиплексор 1×4
Демультиплексор использует комбинацию sel и f для управления разными выходами. Каждый выход управляется отдельным assign (обычно не рекомендуется управлять одним сигналом разными assign).
module demux_1x4 ( input f, input [1:0] sel, output a, b, c, d);
assign a = f & ~sel[1] & ~sel[0];
assign b = f & sel[1] & ~sel[0];
assign c = f & ~sel[1] & sel[0];
assign d = f & sel[1] & sel[0];
endmodule
Тестбенч
module tb; reg f; reg [1:0] sel; wire a, b, c, d; integer i;
demux_1x4 u0 ( .f(f), .sel(sel), .a(a), .b(b), .c(c), .d(d));
initial begin f <= 0; sel <= 0; $monitor("f=%0b sel=%0b a=%0b b=%0b c=%0b d=%0b", f, sel, a, b, c, d);
for (i = 0; i < 8; i = i + 1) begin {f, sel} = i; #10; end end endmodule
Пример #6: Декодер 4×16
module dec_3x8 ( input en, input [3:0] in, output [15:0] out);
assign out = en ? 1 << in: 0;
endmodule
Тестбенч
module tb; reg en; reg [3:0] in; wire [15:0] out; integer i;
dec_3x8 u0 ( .en(en), .in(in), .out(out));
initial begin en <= 0; in <= 0; $monitor("en=%0b in=0x%0h out=0x%0h", en, in, out);
for (i = 0; i < 32; i = i + 1) begin {en, in} = i; #10; end end endmodule
Simulation Log показывает работу декодера: при en=0 выход 0, при en=1 — один бит установлен в соответствии с in.
Verilog
- Мастерство VHDL и Verilog: написание чистой комбинационной и последовательной логики
- Цепь с переключателем: практическое руководство по базовым электрическим цепям
- Интегральные схемы: основы цифровых логических элементов
- Программируемые логические контроллеры (ПЛК): современное цифровое управление для промышленных систем
- Понимание булевой алгебры: от логических основ к цифровым схемам
- Умножение и деление в научной нотации: правила и примеры
- Индустрия 4.0: Интервью с Вереной Майюктке из Bosch.IO об IoT, автоматизации и фабрике будущего
- Точный мониторинг температуры в серверной на Raspberry Pi
- Практическое гейтовое дизайнирование в Verilog: AND, OR, NOT гейты и 2x1 мультиплексор
- Мастерство $timeformat в Verilog: точность и контроль отображения времени