Skip to content

Instantly share code, notes, and snippets.

@JoshCheek
Created April 23, 2016 03:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JoshCheek/2b56e302fa7f14fffc1e71977f985c8f to your computer and use it in GitHub Desktop.
Save JoshCheek/2b56e302fa7f14fffc1e71977f985c8f to your computer and use it in GitHub Desktop.
Playing with bits
def eq!(a, b)
return true if a == b
message = "#{a.inspect} != #{b.inspect} @ #{caller[0].split(":")[1]}"
raise message
end
# ===== Basic =====
# List of truth tables and gate symbols @ http://www.allaboutcircuits.com/worksheets/basic-logic-gates/
def nand!(a, b) # Given
a_and_b = a&b
negated = ~a_and_b
as_bit = negated[0]
as_bit
end
eq! 1, nand!(0, 0)
eq! 1, nand!(0, 1)
eq! 1, nand!(1, 0)
eq! 0, nand!(1, 1)
def not!(a)
nand!(a, a)
end
eq! 1, not!(0)
eq! 0, not!(1)
def and!(a, b)
not!(nand!(a, b))
end
eq! 0, and!(0, 0)
eq! 0, and!(0, 1)
eq! 0, and!(1, 0)
eq! 1, and!(1, 1)
def or!(a, b)
nand!(not!(a), not!(b))
end
eq! 0, or!(0, 0)
eq! 1, or!(0, 1)
eq! 1, or!(1, 0)
eq! 1, or!(1, 1)
def xor!(a, b)
and! nand!(a, b), or!(a, b)
end
eq! 0, xor!(0, 0)
eq! 1, xor!(0, 1)
eq! 1, xor!(1, 0)
eq! 0, xor!(1, 1)
def nor!(a, b)
not!(or!(a, b))
end
eq! 1, nor!(0, 0)
eq! 0, nor!(0, 1)
eq! 0, nor!(1, 0)
eq! 0, nor!(1, 1)
def xnor!(a, b)
nand! nand!(a, b),
nand!(not!(a), not!(b))
end
eq! 1, xnor!(0, 0)
eq! 0, xnor!(0, 1)
eq! 0, xnor!(1, 0)
eq! 1, xnor!(1, 1)
def neg_and!(a, b)
and! not!(a), not!(b)
end
eq! 1, neg_and!(0, 0)
eq! 0, neg_and!(0, 1)
eq! 0, neg_and!(1, 0)
eq! 0, neg_and!(1, 1)
def neg_or!(a, b)
or! not!(a), not!(b)
end
eq! 1, neg_or!(0, 0)
eq! 1, neg_or!(0, 1)
eq! 1, neg_or!(1, 0)
eq! 0, neg_or!(1, 1)
# ===== Adders =====
def add_bits!(a, b, overflow)
[ nand!(
and!(
nand!(a, b),
nand!(b, overflow)
),
nand!(a, overflow)
),
xor!(xor!(a, b), overflow)
]
end
eq! [0, 0], add_bits!(0, 0, 0)
eq! [0, 1], add_bits!(0, 1, 0)
eq! [0, 1], add_bits!(1, 0, 0)
eq! [1, 0], add_bits!(1, 1, 0)
eq! [0, 1], add_bits!(0, 0, 1)
eq! [1, 0], add_bits!(0, 1, 1)
eq! [1, 0], add_bits!(1, 0, 1)
eq! [1, 1], add_bits!(1, 1, 1)
def half_add!(a4, a3, a2, a1, b4, b3, b2, b1)
ovf, out1 = add_bits!(a1, b1, 0)
ovf, out2 = add_bits!(a2, b2, ovf)
ovf, out3 = add_bits!(a3, b3, ovf)
ovf, out4 = add_bits!(a4, b4, ovf)
[ovf, out4, out3, out2, out1]
end
(2**4).times do |a|
(2**4).times do |b|
expected = (a+b).tap { |added| break [added[4], added[3], added[2], added[1], added[0]] }
actual = half_add! a[3], a[2], a[1], a[0],
b[3], b[2], b[1], b[0]
eq! expected, actual
end
end
def add!(a8, a7, a6, a5, a4, a3, a2, a1,
b8, b7, b6, b5, b4, b3, b2, b1)
ovf, out1 = add_bits!(a1, b1, 0)
ovf, out2 = add_bits!(a2, b2, ovf)
ovf, out3 = add_bits!(a3, b3, ovf)
ovf, out4 = add_bits!(a4, b4, ovf)
ovf, out5 = add_bits!(a5, b5, ovf)
ovf, out6 = add_bits!(a6, b6, ovf)
ovf, out7 = add_bits!(a7, b7, ovf)
ovf, out8 = add_bits!(a8, b8, ovf)
[ovf, out8, out7, out6, out5, out4, out3, out2, out1]
end
(2**8).times do |a|
(2**8).times do |b|
expected = (a+b).tap { |added|
break [added[8], added[7], added[6], added[5], added[4], added[3], added[2], added[1], added[0]]
}
actual = add! a[7], a[6], a[5], a[4], a[3], a[2], a[1], a[0],
b[7], b[6], b[5], b[4], b[3], b[2], b[1], b[0]
eq! expected, actual
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment