简体   繁体   English

在python中实现8位加法器

[英]Implementing 8bit adder in python

I've implemented an 8bit adder in python as follows:我在 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))

The striking thing for me is the "gates" will evaluate lazily, so it won't return a 1/0 unless I call int() , and it seems like there are a tremendous amount of gates in an 8-bit adder.对我来说最引人注目的是“门”会懒惰地评估,所以除非我调用int()否则它不会返回 1/0 ,而且似乎 8 位加法器中有大量的门。 For example:例如:

在此处输入图片说明

Am I making a mistake somewhere (or redundancy) somewhere in the carry/value out evaluation, or does a basic 8bit ripple adder really have this many gates in it??我是在进位/值输出评估中的某处(或冗余)犯了错误,还是基本的 8 位纹波加法器真的有这么多门?

If implemented directly, a full adder does have that many gates in it.如果直接实现,全加器中确实有那么多门。 Have you considered using composite gates, such as 8-bit primitives or using a half adder ?您是否考虑过使用复合门,例如 8 位基元或使用半加器 I don't have direct experience, but I don't think full adders are implemented directly with primitives in practice, instead they probably use these intermediate parts.我没有直接经验,但我不认为全加器在实践中是直接用原语实现的,而是他们可能会使用这些中间部分。

The second chapter of nand2tetris covers the half adder approach, which if you were to apply to your code allows you to make a slight simplification: 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))

can be instead written as:可以改写为:

        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)

This drops the number of gates per iteration from 6 to 5, so it should reduce your output by 1/6th.这会将每次迭代的门数从 6 减少到 5,因此它应该将您的输出减少 1/6。 I'd still recommend putting that in a separate gate though, as a half adder is independently useful.我仍然建议将它放在一个单独的门中,因为半加器是独立有用的。

In a real adder, the gates are connected into a graph, where the output of a gate may be used as the input to several others.在真正的加法器中,门连接成一个图形,其中一个门的输出可以用作其他几个门的输入。

You are writing the output as an expression, where the output of a gate can only be used in one place.您将输出编写为表达式,其中门的输出只能在一个地方使用。

This is accomplished by copying the whole expression for each output into all the places it is used.这是通过将每个输出的整个表达式复制到所有使用它的地方来实现的。 You do this in each iteration -- carry_in is used once to produce the value and 3 times to produce the next carry.您在每次迭代中都这样做carry_in用于生成值一次,使用 3 次来生成下一个进位。

The size of the carry expression is multiplied by 3 in every iteration leading to an exponential explosion in the number of operators you use.进位表达式的大小在每次迭代中都乘以 3,从而导致您使用的运算符数量呈指数级增长。

You should probably be generating your output in a different form that can preserve the gate graph, like static single assignment: https://en.wikipedia.org/wiki/Static_single_assignment_form您可能应该以可以保留门图的不同形式生成输出,例如静态单一分配: https : //en.wikipedia.org/wiki/Static_single_assignment_form

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM