在 python 中实现 8 位加法器

Implementing 8bit adder in python

提问人:carl.hiass 提问时间:3/25/2020 更新时间:3/25/2020 访问量:1835

问:

我在 python 中实现了一个 8 位加法器,如下所示:

from gates import AND, OR, XOR
from utils import number_to_binary, binary_to_number

def EightBitAdder(s1='110101', s2='00010', carry_in=0):
    # Limit to 8 bits
    s1 = s1[-8:].zfill(8)
    s2 = s2[-8:].zfill(8)
    s_out = ''
    carry_out = None
    for i in range(8):
        bit_1 = int(s1[8-1-i])
        bit_2 = int(s2[8-1-i])
        carry_in = carry_out if (carry_out is not None) else carry_in
        value_out = XOR(carry_in, XOR(bit_1, bit_2))
        carry_out = OR(AND(bit_1, bit_2), AND(bit_1, carry_in), AND(bit_2, carry_in))
        s_out = str(int(value_out)) + s_out
    print ("  %s (%s) \n+ %s (%s) \n= %s (%s)  -- Carry %s" % (s1, binary_to_number(s1), s2, binary_to_number(s2), s_out, binary_to_number(s_out), int(carry_in)))
    return (s_out, int(carry_out))

对我来说,令人惊讶的是“门”会懒惰地计算,所以除非我调用,否则它不会返回 1/0,而且似乎 8 位加法器中有大量的门。例如:int()

enter image description here

我是在进位/值输出评估的某个地方(或冗余)犯了错误,还是基本的 8 位纹波加法器真的有这么多门?

python 算法 法布尔逻辑 8 位

评论


答:

1赞 kevmo314 3/25/2020 #1

如果直接实现,一个完整的加法器确实有那么多门。您是否考虑过使用复合门,例如 8 位基元或使用半加法器?我没有直接的经验,但我不认为在实践中直接使用原语实现全加法器,而是可能使用这些中间部分。

nand2tetris 的第二章介绍了半加法器方法,如果你要将其应用于你的代码,你可以稍微简化一下:

        carry_in = carry_out if (carry_out is not None) else carry_in
        value_out = XOR(carry_in, XOR(bit_1, bit_2))
        carry_out = OR(AND(bit_1, bit_2), AND(bit_1, carry_in), AND(bit_2, carry_in))

可以改写为:

        carry_in = carry_out if (carry_out is not None) else carry_in
        half_sum = XOR(bit_1, bit_2)
        half_carry = AND(bit_1, bit_2)
        full_sum = XOR(carry_in, half_sum)
        full_carry = AND(half_sum, carry_in)
        value_out = full_sum
        carry_out = OR(half_carry, full_carry)

这会将每次迭代的门数从 6 个减少到 5 个,因此它应该将输出减少 1/6。不过,我仍然建议将其放在一个单独的门中,因为半加法器是独立有用的。

1赞 Matt Timmermans 3/25/2020 #2

在实加法器中,门被连接到一个图中,其中门的输出可以用作其他几个门的输入。

您将输出编写为表达式,其中门的输出只能在一个地方使用。

这是通过将每个输出的整个表达式复制到使用它的所有位置来实现的。在每次迭代中都执行此操作 -- 使用一次生成值,使用 3 次生成下一个进位。carry_in

在每次迭代中,进位表达式的大小都会乘以 3,从而导致您使用的运算符数量呈指数级增长。

您可能应该以可以保留门图的不同形式生成输出,例如静态单赋值:https://en.wikipedia.org/wiki/Static_single_assignment_form