Verilog Full Adder Неожиданное поведение
Я пытаюсь сделать очень простой аппаратный модуль / тестовый стенд, чтобы освоить Verilog. Я попытался реализовать полный сумматор.
Если я не ошибаюсь, у вас есть три входных, немедленных добавления a и b и перенос с места 2^n-1.
Выходные данные суммируются и выполняются (которые могут служить переносом в другой модуль в базовом сумматоре или как называется "не переносить").
Если я не ошибаюсь, логика вывода
сумма = (а & б) | (a & cin) | (b & cin) // или все три, которые охватываются любым из этих
cout = a ^ b ^ cin
Вот полный модуль сумматора
module FullAdder(
a,
b,
cin,
sum,
co
);
input a;
input b;
input cin;
output sum;
output co;
//wire a;
//wire b;
//wire ci;
wire sum;
wire co;
//At least two
assign co = (a & b) | (a & cin) | (b & cin);
//one or three
assign sum = a ^ b ^ cin; //(a & ~b & ~cin) | (~a & b & ~cin) | (~a & ~b & cin) | (a & b & cin);
endmodule
А вот и стенд
module HalfAdderTB();
reg a_in;
reg b_in;
reg cin_in;
wire s_out;
wire cout_out;
FullAdder DUT(
a_in,
b_in,
cin_in,
s_out,
cout_out
);
initial begin
a_in = 1'b0;
b_in = 1'b0;
cin_in = 1'b0;
#20
a_in = 1'b0;
b_in = 1'b0;
cin_in = 1'b0;
$display("a: %d, b: %d, cin: %d", a_in, b_in, cin_in);
$display("s: %b, cout: %b", s_out, cout_out);
#20
a_in = 1'b0;
b_in = 1'b0;
cin_in = 1'b1;
$display("a: %d, b: %d, cin: %d", a_in, b_in, cin_in);
$display("s: %b, cout: %b", s_out, cout_out);
#20
a_in = 1'b0;
b_in = 1'b1;
cin_in = 1'b0;
$display("a: %d, b: %d, cin: %d", a_in, b_in, cin_in);
$display("s: %b, cout: %b", s_out, cout_out);
#20
a_in = 1'b0;
b_in = 1'b1;
cin_in = 1'b1;
$display("a: %d, b: %d, cin: %d", a_in, b_in, cin_in);
$display("s: %b, cout: %b", s_out, cout_out);
#20
a_in = 1'b1;
b_in = 1'b0;
cin_in = 1'b0;
$display("a: %d, b: %d, cin: %d", a_in, b_in, cin_in);
$display("s: %b, cout: %b", s_out, cout_out);
#20
a_in = 1'b1;
b_in = 1'b0;
cin_in = 1'b1;
$display("a: %d, b: %d, cin: %d", a_in, b_in, cin_in);
2,1 4%
a_in = 1'b1;
b_in = 1'b1;
cin_in = 1'b0;
$display("a: %d, b: %d, cin: %d", a_in, b_in, cin_in);
$display("s: %b, cout: %b", s_out, cout_out);
#20
assign a_in = 1'b1;
assign b_in = 1'b1;
assign cin_in = 1'b1;
$display("a: %d, b: %d, cin: %d", a_in, b_in, cin_in);
$display("s: %b, cout: %b", s_out, cout_out);
#20
$finish;
end
endmodule
Мой вывод выглядит так
a: 0, b: 0, cin: 0
s: 0, cout: 0
a: 0, b: 0, cin: 1
s: 0, cout: 0
a: 0, b: 1, cin: 0
s: 1, cout: 0
a: 0, b: 1, cin: 1
s: 1, cout: 0
a: 1, b: 0, cin: 0
s: 0, cout: 1
a: 1, b: 0, cin: 1
s: 1, cout: 0
a: 1, b: 1, cin: 0
s: 0, cout: 1
a: 1, b: 1, cin: 1
s: 0, cout: 1
Я считаю, что логические утверждения в моем коде соответствуют булевым уравнениям, которые я написал в начале. Я уверен в своей логике. Я не могу понять, что не так с Verilog. Я что-то упустил из-за времени и ввода тестового стенда в Full Adder?
1 ответ
Ваш код в порядке, но вы получаете этот странный результат из-за $display
заявление. Ваш код будет работать нормально, если вы используете $strobe
вместо $display
, Вы также можете использовать $monitor
для отображения результатов. Резонанс заключается в том, что оператор display выполняется немедленно, так что ваши выходные данные еще не будут обновлены новыми значениями, тогда как стробоскоп будет выполняться только в конце момента времени, так что ваши выходные данные будут обновлены к тому времени. Монитор используется для автоматического отображения значений, когда значения видят изменения.
Поскольку вы только начинаете работать с Verilog, я бы посоветовал вам перейти по этой ссылке, чтобы понять, как различные операторы отображения работают в Verilog, а также пройти по этой ссылке, чтобы понять порядок выполнения операторов в конкретный момент времени, чтобы вы могли может лучше спланировать свой код