Комбинационная логика всегда
Блок verilog always можно использовать как для последовательной, так и для комбинационной логики. Несколько примеров дизайна были показаны с использованием assign
утверждение в предыдущей статье. Далее будет рассмотрен тот же набор дизайнов с использованием always
. блокировать.
Пример №1. Простая комбинационная логика
Показанный ниже код реализует простую цифровую комбинационную логику, которая имеет выходной сигнал z типа reg
. который обновляется всякий раз, когда один из сигналов в списке чувствительности меняет свое значение. Список чувствительности объявляется в круглых скобках после @
оператор.
module combo ( input a, b, c, d, e,
output reg z);
always @ ( a or b or c or d or e) begin
z = ((a & b) | (c ^ d) & ~e);
end
endmodule
Модуль combo превращается в следующую аппаратную схему с использованием инструментов синтеза, и видно, что комбинационная логика реализована с помощью цифровых вентилей.
Используйте назначения блокировки при моделировании комбинационной логики с постоянным блоком
Тестовый стенд
Тестовый стенд — это платформа для моделирования проекта, чтобы убедиться, что проект ведет себя так, как ожидалось. Все комбинации входных данных передаются в модуль дизайна с помощью for
цикл с оператором задержки 10 единиц времени, чтобы новое значение применялось к входам через некоторое время.
module tb;
// Declare testbench variables
reg a, b, c, d, e;
wire z;
integer i;
// Instantiate the design and connect design inputs/outputs with
// testbench variables
combo u0 ( .a(a), .b(b), .c(c), .d(d), .e(e), .z(z));
initial begin
// At the beginning of time, initialize all inputs of the design
// to a known value, in this case we have chosen it to be 0.
a <= 0;
b <= 0;
c <= 0;
d <= 0;
e <= 0;
// Use a $monitor task to print any change in the signal to
// simulation console
$monitor ("a=%0b b=%0b c=%0b d=%0b e=%0b z=%0b",
a, b, c, d, e, z);
// Because there are 5 inputs, there can be 32 different input combinations
// So use an iterator "i" to increment from 0 to 32 and assign the value
// to testbench variables so that it drives the design inputs
for (i = 0; i < 32; i = i + 1) begin
{a, b, c, d, e} = i;
#10;
end
end
endmodule
Журнал моделирования ncsim> run a=0 b=0 c=0 d=0 e=0 z=0 a=0 b=0 c=0 d=0 e=1 z=0 a=0 b=0 c=0 d=1 e=0 z=1 a=0 b=0 c=0 d=1 e=1 z=0 a=0 b=0 c=1 d=0 e=0 z=1 a=0 b=0 c=1 d=0 e=1 z=0 a=0 b=0 c=1 d=1 e=0 z=0 a=0 b=0 c=1 d=1 e=1 z=0 a=0 b=1 c=0 d=0 e=0 z=0 a=0 b=1 c=0 d=0 e=1 z=0 a=0 b=1 c=0 d=1 e=0 z=1 a=0 b=1 c=0 d=1 e=1 z=0 a=0 b=1 c=1 d=0 e=0 z=1 a=0 b=1 c=1 d=0 e=1 z=0 a=0 b=1 c=1 d=1 e=0 z=0 a=0 b=1 c=1 d=1 e=1 z=0 a=1 b=0 c=0 d=0 e=0 z=0 a=1 b=0 c=0 d=0 e=1 z=0 a=1 b=0 c=0 d=1 e=0 z=1 a=1 b=0 c=0 d=1 e=1 z=0 a=1 b=0 c=1 d=0 e=0 z=1 a=1 b=0 c=1 d=0 e=1 z=0 a=1 b=0 c=1 d=1 e=0 z=0 a=1 b=0 c=1 d=1 e=1 z=0 a=1 b=1 c=0 d=0 e=0 z=1 a=1 b=1 c=0 d=0 e=1 z=1 a=1 b=1 c=0 d=1 e=0 z=1 a=1 b=1 c=0 d=1 e=1 z=1 a=1 b=1 c=1 d=0 e=0 z=1 a=1 b=1 c=1 d=0 e=1 z=1 a=1 b=1 c=1 d=1 e=0 z=1 a=1 b=1 c=1 d=1 e=1 z=1 ncsim: *W,RNQUIE: Simulation is complete.
Обратите внимание, что оба метода, assign
и always
, реализовать в той же аппаратной логике.
Пример №2:Половинный сумматор
Модуль полусумматора принимает два скалярных входа a и b и использует комбинационную логику для назначения суммы выходных сигналов и бита переноса cout. Сумма управляется XOR между a и b, а бит переноса получается с помощью AND между двумя входами.
module ha ( input a, b,
output sum, cout);
always @ (a or b) begin
{cout, sum} = a + b;
end
endmodule
Тестовый стенд
module tb;
// Declare testbench variables
reg a, b;
wire sum, cout;
integer i;
// Instantiate the design and connect design inputs/outputs with
// testbench variables
ha u0 ( .a(a), .b(b), .sum(sum), .cout(cout));
initial begin
// At the beginning of time, initialize all inputs of the design
// to a known value, in this case we have chosen it to be 0.
a <= 0;
b <= 0;
// Use a $monitor task to print any change in the signal to
// simulation console
$monitor("a=%0b b=%0b sum=%0b cout=%0b", a, b, sum, cout);
// Because there are only 2 inputs, there can be 4 different input combinations
// So use an iterator "i" to increment from 0 to 4 and assign the value
// to testbench variables so that it drives the design inputs
for (i = 0; i < 4; i = i + 1) begin
{a, b} = i;
#10;
end
end
endmodule
Журнал моделирования ncsim> run a=0 b=0 sum=0 cout=0 a=0 b=1 sum=1 cout=0 a=1 b=0 sum=1 cout=0 a=1 b=1 sum=0 cout=1 ncsim: *W,RNQUIE: Simulation is complete.
Пример №3:Полный сумматор
Блок always можно использовать для описания поведения полного сумматора для управления суммой выходов и cout.
module fa ( input a, b, cin,
output reg sum, cout);
always @ (a or b or cin) begin
{cout, sum} = a + b + cin;
end
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 cout=%0b sum=%0b", a, b, cin, cout, sum);
for (i = 0; i < 8; i = i + 1) begin
{a, b, cin} = i;
#10;
end
end
endmodule
Журнал моделирования ncsim> run a=0 b=0 cin=0 cout=0 sum=0 a=0 b=0 cin=1 cout=0 sum=1 a=0 b=1 cin=0 cout=0 sum=1 a=0 b=1 cin=1 cout=1 sum=0 a=1 b=0 cin=0 cout=0 sum=1 a=1 b=0 cin=1 cout=1 sum=0 a=1 b=1 cin=0 cout=1 sum=0 a=1 b=1 cin=1 cout=1 sum=1 ncsim: *W,RNQUIE: Simulation is complete.
Пример №4:Мультиплексор 2x1
Простой мультиплексор 2x1 использует тернарный оператор, чтобы решить, какой вход должен быть назначен выходу c. Если sel равно 1, вывод управляется a, а если sel равен 0, вывод управляется b.
module mux_2x1 (input a, b, sel,
output reg c);
always @ ( a or b or sel) begin
c = sel ? a : b;
end
endmodule
Тестовый стенд
module tb;
// Declare testbench variables
reg a, b, sel;
wire c;
integer i;
// Instantiate the design and connect design inputs/outputs with
// testbench variables
mux_2x1 u0 ( .a(a), .b(b), .sel(sel), .c(c));
initial begin
// At the beginning of time, initialize all inputs of the design
// to a known value, in this case we have chosen it to be 0.
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
Журнал моделирования ncsim> run a=0 b=0 sel=0 c=0 a=0 b=0 sel=1 c=0 a=0 b=1 sel=0 c=1 ncsim: *W,RNQUIE: Simulation is complete.
Пример 5. Демультиплексор 1 x 4
Демультиплексор использует комбинацию входов sel и f для управления различными выходными сигналами. Каждый выходной сигнал имеет тип reg
и используется внутри always
блок, который обновляется в зависимости от изменений сигналов, перечисленных в списке чувствительности.
module demux_1x4 ( input f,
input [1:0] sel,
output reg a, b, c, d);
always @ ( f or sel) begin
a = f & ~sel[1] & ~sel[0];
b = f & sel[1] & ~sel[0];
c = f & ~sel[1] & sel[0];
d = f & sel[1] & sel[0];
end
endmodule
Тестовый стенд
module tb;
// Declare testbench variables
reg f;
reg [1:0] sel;
wire a, b, c, d;
integer i;
// Instantiate the design and connect design inputs/outputs with
// testbench variables
demux_1x4 u0 ( .f(f), .sel(sel), .a(a), .b(b), .c(c), .d(d));
// At the beginning of time, initialize all inputs of the design
// to a known value, in this case we have chosen it to be 0.
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);
// Because there are 3 inputs, there can be 8 different input combinations
// So use an iterator "i" to increment from 0 to 8 and assign the value
// to testbench variables so that it drives the design inputs
for (i = 0; i < 8; i = i + 1) begin
{f, sel} = i;
#10;
end
end
endmodule
Журнал моделирования ncsim> run f=0 sel=0 a=0 b=0 c=0 d=0 f=0 sel=1 a=0 b=0 c=0 d=0 f=0 sel=10 a=0 b=0 c=0 d=0 f=0 sel=11 a=0 b=0 c=0 d=0 f=1 sel=0 a=1 b=0 c=0 d=0 f=1 sel=1 a=0 b=0 c=1 d=0 f=1 sel=10 a=0 b=1 c=0 d=0 f=1 sel=11 a=0 b=0 c=0 d=1 ncsim: *W,RNQUIE: Simulation is complete.
Пример №6:Декодер 4x16
module dec_3x8 ( input en,
input [3:0] in,
output reg [15:0] out);
always @ (en or in) begin
out = en ? 1 << in: 0;
end
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
Журнал моделирования ncsim> run en=0 in=0x0 out=0x0 en=0 in=0x1 out=0x0 en=0 in=0x2 out=0x0 en=0 in=0x3 out=0x0 en=0 in=0x4 out=0x0 en=0 in=0x5 out=0x0 en=0 in=0x6 out=0x0 en=0 in=0x7 out=0x0 en=0 in=0x8 out=0x0 en=0 in=0x9 out=0x0 en=0 in=0xa out=0x0 en=0 in=0xb out=0x0 en=0 in=0xc out=0x0 en=0 in=0xd out=0x0 en=0 in=0xe out=0x0 en=0 in=0xf out=0x0 en=1 in=0x0 out=0x1 en=1 in=0x1 out=0x2 en=1 in=0x2 out=0x4 en=1 in=0x3 out=0x8 en=1 in=0x4 out=0x10 en=1 in=0x5 out=0x20 en=1 in=0x6 out=0x40 en=1 in=0x7 out=0x80 en=1 in=0x8 out=0x100 en=1 in=0x9 out=0x200 en=1 in=0xa out=0x400 en=1 in=0xb out=0x800 en=1 in=0xc out=0x1000 en=1 in=0xd out=0x2000 en=1 in=0xe out=0x4000 en=1 in=0xf out=0x8000 ncsim: *W,RNQUIE: Simulation is complete.
Verilog
- Учебное пособие - Написание комбинационного и последовательного кода
- Схема с переключателем
- Интегральные схемы
- Введение в логическую алгебру
- Арифметика с научной записью
- Вопросы и ответы с архитектором решений Индустрии 4.0
- Мониторинг температуры с помощью Raspberry Pi
- Примеры уровней Verilog Gate
- Формат времени Verilog
- Всегда гладкая поверхность с шлифовальными станками Okamoto