Verilog Full Adder意外行为

时间:2018-02-13 01:03:38

标签: verilog hardware icarus

我正在尝试做一个非常基本的硬件模块/测试平台,以获得Verilog的支持。我试图实现一个完整的加法器。

如果我没有弄错的话,你有三个输入,即时加数a和b以及从2 ^ n-1位置进位。

输出是求和并执行(可以作为基本加法器中另一个模块的进位或任何不带进位前瞻的方法。)

如果我没弄错,输出逻辑是

sum =(a& b)| (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 个答案:

答案 0 :(得分:1)

您的代码很好,但是由于$display语句,您得到了这个奇怪的结果。如果您使用$strobe而不是$display,您的代码将正常运行。您还可以使用$monitor来显示结果。共鸣是显示语句立即执行,以便您的输出不会使用新值更新,而 strobe 将仅在瞬间结束时执行,因此那时你的产出会得到更新。 监视器用于在值看到更改时自动显示值。

由于你刚开始使用verilog,我建议你通过这个link来了解各种显示语句在verilog中是如何工作的,并且还要通过这个link来理解执行的顺序在特定时刻的陈述,以便您可以更好地规划您的代码