【问题标题】:Full Adder Sum Off by One Clock Cycle一个时钟周期的全加器总和
【发布时间】:2016-04-11 18:40:17
【问题描述】:

我正在测试一个 8 位 Ripple Carry Adder 的功能,该测试台会尝试每一种组合。由于某种原因,A 和 B 的当前值之和在下一个时钟周期中计算。我不确定为什么会这样。最初,我认为这是因为延迟,但是当我更改延迟时仍然会出现错误。这是我的代码:

//one_adder.v

module One_adder(a,b,cin,sum,carry);
    output carry,sum;
    input a,b,cin;
    wire w0,w1,w2;

        xor(sum,a,b,cin);
        and(w0,a,b);
        and(w1,a,cin);
        and(w2,cin,b);
        or(carry,w0,w1,w2);

endmodule;


//Eight_adder.v

module Eight_adder(A,B,S,Carry);
    output [7:0]S, Carry;
    input [7:0]A, B;
    //wire [7:0]w;
    wire overflow;

    One_adder add0(.carry(Carry[0]), .sum(S[0]), .a(A[0]), .b(B[0]), .cin(Carry[0]));
    One_adder add1(.carry(Carry[1]), .sum(S[1]), .a(A[1]), .b(B[1]), .cin(Carry[1]));
    One_adder add2(.carry(Carry[2]), .sum(S[2]), .a(A[2]), .b(B[2]), .cin(Carry[2]));
    One_adder add3(.carry(Carry[3]), .sum(S[3]), .a(A[3]), .b(B[3]), .cin(Carry[3]));
    One_adder add4(.carry(Carry[4]), .sum(S[4]), .a(A[4]), .b(B[4]), .cin(Carry[4]));
    One_adder add5(.carry(Carry[5]), .sum(S[5]), .a(A[5]), .b(B[5]), .cin(Carry[5]));
    One_adder add6(.carry(Carry[6]), .sum(S[6]), .a(A[6]), .b(B[6]), .cin(Carry[6]));
    One_adder add7(.carry(Carry[7]), .sum(S[7]), .a(A[7]), .b(B[7]), .cin(Carry[7]));
    assign overflow= (A[7]&B[7]&~Carry[7]) | (~A[7]&~B[7]&Carry[7]);

endmodule


//tBench.v
//`timescale 1 ns/ 1 ns

module tBench;
    wire [7:0]sum;
    wire cin, co;
    reg[7:0] A, B;      // the different combinations
//module Eight_adder(A,B,Cin,S,Cout);
Eight_adder FA(A,B,sum,co);

initial begin
    for(A =0; A<255; A=A+1)
    begin
        #10 // the period in ModelSim: 10ns
        for(B=0; B<255; B=B+1)
        begin
          $display("A=%b,, B=%b,, Sum=%b,,", A,B,{co,sum});
         #10
            if({co,sum} != (A+B))
                $display("Error: A=%b b=%b sum=%b cout=%b\n", A, B, sum, co);
        end
    end
    $finish;
end
endmodule

这是一个示例输出:

【问题讨论】:

  • 你为什么要通过你的 FA 的全部执行?为什么您对 cin 和 cout 使用相同的进位值?你为什么要同时使用and(w1,b,cin);and(w2,cin,b);
  • @wilcroft 1Q),不知道我为什么要这样做。 2Q)因为当我串联制作一个 8 位加法器时,进位成为所有一位加法器的进位。 3Q) 那应该是and(w1,a,cin); 和 `and(w2,b,cin);'我编辑了代码
  • 请参阅 Greg 对我在 #2 中提出的问题的回答。

标签: verilog modelsim intel-fpga quartus


【解决方案1】:

您正在以正确的周期计算总和,但您在不同的时间显示它。将$display 移动到$monitor,如下所示:

initial begin
    $monitor("A=%b,, B=%b,, Sum=%b,,", A,B,{co,sum});
    for(A =0; A<255; A=A+1)
    begin
        #10 // the period in ModelSim: 10ns
        for(B=0; B<255; B=B+1)
        begin
         #10
            if({co,sum} != (A+B))
                $display("Error: A=%b b=%b sum=%b cout=%b\n", A, B, sum, co);
        end
    end
    $finish;
end

【讨论】:

    【解决方案2】:

    我很惊讶您的总和输出没有只得到 X。您将进位位反馈回同一加法器的进位。应该有一个偏移量,因此一个加法器的进位是另一个加法器的进位。

    One_adder add0(.carry(Carry[0]), .sum(S[0]), .a(A[0]), .b(B[0]), .cin(1'b0));
    ...
    One_adder add7(.carry(carryout), .sum(S[7]), .a(A[7]), .b(B[7]), .cin(Carry[7]));
    

    至于您的显示消息,您的{co,sum}AB 使用相同的时间戳进行更新。在有机会计算任何东西之前,verilog 调度程序正在评估$display。您可以在$display 之前添加延迟(就像您在错误检查中所做的那样),将$display 替换为$strobe,或者在循环之前使用$monitor。 (您可能想阅读display vs strobe vs monitor in verilog?

    【讨论】:

      猜你喜欢
      • 2017-03-12
      • 1970-01-01
      • 1970-01-01
      • 2014-11-02
      • 1970-01-01
      • 1970-01-01
      • 2017-09-24
      • 2012-05-10
      • 1970-01-01
      相关资源
      最近更新 更多