【问题标题】:Verilog Binary Coded Decimal Adder Not Outputting CorrectlyVerilog 二进制编码的十进制加法器未正确输出
【发布时间】:2021-08-12 16:31:40
【问题描述】:

我是 Verilog 的新手,基本上是在尝试自学一个用于大学的数字逻辑设计模块。我正在尝试使用两个全加器在 Verilog 中编写 BCD 加法器,中间有一些逻辑,以便在需要时转换为 BCD。

这是我的代码:

module      binary_adder (
    output  [3:0]   Sum,
    output          C_out,
    input   [3:0]   A, B,
    input           C_in
);
    assign  {C_out, Sum} = A || B || C_in;
endmodule

module      BCD_Adder (
    output  [3:0]   Sum,
    output          Carry_out,
    input   [3:0]   Addend, Augend,
    input           Carry_in
);

wire [3:0]  Z, correction;
wire adder1C_out, carryInAdder2, adder2C_out;

    binary_adder adder1 (.Sum(Z), .C_out(adder1C_out), .A(Addend), .B(Augend), .C_in(Carry_in));
    
assign Carry_out = (adder1C_out || (Z[3] && Z[1]) || (Z[3] && Z[2]));
assign correction = (Carry_out) ? (4'b0110) : (4'b0000);
assign carryInAdder2 = (1'b0);

    binary_adder adder2 (.Sum(Sum), .C_out(adder2C_out), .A(correction), .B(Z), .C_in(carryInAdder2));

endmodule

出于某种原因,我不断收到以下输出:

已提交:A = 0000,B = 0010,进位 = 0,总和 = 0001,进位 = 0

预期:A = 0000,B = 0010,进位 = 0,总和 = 0010,进位 = 0

已提交:A = 0000,B = 0011,进位 = 0,总和 = 0001,进位 = 0

预期:A = 0000,B = 0011,进位 = 0,总和 = 0011,进位 = 0

已提交:A = 0000,B = 0100,进位 = 0,总和 = 0001,进位 = 0

预期:A = 0000,B = 0100,进位 = 0,总和 = 0100,进位 = 0

对于所有值,它基本上都是这样继续的。我的 A、B、进位和进位值始终匹配,但由于某种原因,输出总和始终为 0001。我不确定我哪里出错了,逻辑对我来说似乎没问题。我对此很陌生,只知道基础知识,因此将不胜感激!

谢谢, 韦斯

【问题讨论】:

    标签: binary verilog add digital-logic bcd


    【解决方案1】:

    binary_adder中的逻辑没有实现加法;按照目前的写法,如果ABC_in 中的任何一个不为零,它只会将Sum 设置为1。

    虽然有许多多位加法架构(请参阅https://en.wikipedia.org/wiki/Adder_(electronics)#Adders_supporting_multiple_bits),但最容易理解的是波纹进位加法器。它实现了几个全加器并将它们链接在一起以实现加法。

    此架构的简单实现如下所示:

    module full_add(input A, B, Cin,
                    output S, Cout);
      // Basic implementation of a Full Adder (see https://en.wikipedia.org/wiki/Adder_(electronics)#Full_adder)
      assign S = A ^ B ^ Cin;
      assign Cout = A & B | ((A ^ B) & Cin); // Note I use bit-wise operators like | and ^ instead of logical ones like ||; its important to know the difference
    endmodule
    
    module add(input [3:0] A, B,
               input Cin,
               output [3:0] S,
               output Cout);
    
      wire [3:0] Carries; // Internal wires for the carries between full adders in Ripple Carry
    
      // This is an array instance which just makes [3:0], ie 4, instances of the full adder.
      // Take note that a single Full Adder modules takes in single bits, but here
      // I can pass bit vectors like A ([3:0]) directly which assign full_add[0].A = A[0], full_add[1].A = A[1], etc
      // Common alternatives to using array instances (which are more rare) include generate statements or just instantiate the module X times
      full_add f[3:0](.A(A), .B(B), .Cin({Carries[2:0], Cin}), .S(S), .Cout(Carries));
    
      assign Cout = Carries[3];
    endmodule
    

    【讨论】:

    • 谢谢你,这对我来说很有意义。我是否正确地说我编写的 binary_adder 模块只是用于单位加法的加法器? (我认为是半加器?)然后因为我试图添加 4 位,我需要使用波纹进位实现的 4 个全加器?
    • 不完全是,因为半加法器要求 SA xor BCoutAB,所以 S = A ^ B; Cout = A && B 可以工作(因为在单个位上,逻辑运算符和布尔运算符是相同的)。 A || B 逻辑不够,您还需要考虑 AB 设置为 S 为 0 和 Cout 为 1 在这种情况下。
    • 抱歉。我自己搞混了。我看到的二进制加法器示例使用了“assign {C_out, S} = A + B + C_in;”这一行。我把这里的“+”误认为是布尔符号,并假设它是逻辑或。我没有意识到 Verilog 支持这样的加法,(我是一个完整的初学者,对不起!)不过,我设法使用您的建议并成功编写了 Ripple Carry Adder,然后我将其转换为二进制编码的十进制。我在意识到自己的错误之前做了这一切,所以这都是很好的练习!谢谢你的帮助,我现在都明白了!
    • 哦,我明白了——是的,常规的数学运算都可用(还有更多!),只要始终了解您正在创建的硬件!很高兴您现在对继续教育有了更好的理解并祝您好运。
    猜你喜欢
    • 2023-04-02
    • 2023-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-03
    • 1970-01-01
    相关资源
    最近更新 更多