57 lines
1.3 KiB
Ruby
57 lines
1.3 KiB
Ruby
# returns pair [sum, carry]
|
|
def four_bit_adder(a, b)
|
|
a_bits = binary_string_to_bits(a,4)
|
|
b_bits = binary_string_to_bits(b,4)
|
|
|
|
s0, c0 = full_adder(a_bits[0], b_bits[0], 0)
|
|
s1, c1 = full_adder(a_bits[1], b_bits[1], c0)
|
|
s2, c2 = full_adder(a_bits[2], b_bits[2], c1)
|
|
s3, c3 = full_adder(a_bits[3], b_bits[3], c2)
|
|
|
|
[bits_to_binary_string([s0, s1, s2, s3]), c3.to_s]
|
|
end
|
|
|
|
# returns pair [sum, carry]
|
|
def full_adder(a, b, c0)
|
|
s, c = half_adder(c0, a)
|
|
s, c1 = half_adder(s, b)
|
|
[s, _or(c,c1)]
|
|
end
|
|
|
|
# returns pair [sum, carry]
|
|
def half_adder(a, b)
|
|
[xor(a, b), _and(a,b)]
|
|
end
|
|
|
|
def xor(a, b)
|
|
_or(_and(a, _not(b)), _and(_not(a), b))
|
|
end
|
|
|
|
# "and", "or" and "not" are Ruby keywords
|
|
def _and(a, b) a & b end
|
|
def _or(a, b) a | b end
|
|
def _not(a) ~a & 1 end
|
|
|
|
def int_to_binary_string(n, length)
|
|
"%0#{length}b" % n
|
|
end
|
|
|
|
def binary_string_to_bits(s, length)
|
|
("%#{length}s" % s).reverse.chars.map(&:to_i)
|
|
end
|
|
|
|
def bits_to_binary_string(bits)
|
|
bits.map(&:to_s).reverse.join
|
|
end
|
|
|
|
puts " A B A B C S sum"
|
|
0.upto(15) do |a|
|
|
0.upto(15) do |b|
|
|
bin_a = int_to_binary_string(a, 4)
|
|
bin_b = int_to_binary_string(b, 4)
|
|
sum, carry = four_bit_adder(bin_a, bin_b)
|
|
puts "%2d + %2d = %s + %s = %s %s = %2d" %
|
|
[a, b, bin_a, bin_b, carry, sum, (carry + sum).to_i(2)]
|
|
end
|
|
end
|