加算器
adder
半であるのは繰り上がりを受けられないから
code:halfadder.jl
function halfadder(a, b)
sum = xor(a, b)
carry = a && b
return carry, sum
end
繰り上がりを受けられる加算器
2つの値の和に、キャリーインを加える
半加算器3つで構成できる
キャリー2つを入力する半加算器のキャリーアウトは捨てても問題ない
キャリーどうしの加算で繰り上がりが生じないことを保証できる:
まず、半加算器から(carrry, sum) = (1, 1)と返ってくることはない
(0, 0), (0, 1), (1, 0)の3つの場合のみ
つまり、2つ目の半加算器が受ける入力では((1, 1), 1)が現れることはない
((0, 0), 0), ((0, 0), 0)
((0, 1), 0), ((0, 1), 1)
((1, 0), 0), ((1, 0), 1)
したがって、2つのキャリーが(1, 1)となることはない
図を縦書きで書けば筆算みたいでわかりやすいあんも.icon code:jl
function fulladder(a, b, carryin=false)
carry1, sum = halfadder(a, b)
carry2, sumout = halfadder(carryin, sum)
_, carryout = halfadder(carry1, carry2)
return carryout, sumout
end
3つ目の半加算器はORに置き換え可能
半加算器のキャリーアウトを捨てるのは、XORしか利用していないことと同じ
繰り上がりの起こる(1, 1)を入力されないなら、XORとORは同じ出力をする
XORよりORの方が安い処理なので、できるなら交換したい
code:fulladder.jl
function fulladder(a, b, carryin=false)
carry1, sum = halfadder(a, b)
carry2, sumout = halfadder(carryin, sum)
carryout = carry1 || carry2
return carryout, sumout
end
構成に忠実に書いてみるあんも.icon
コントロールパネルのトグルスイッチで入力する
code:jl
function eightbitadder(a7, a6, a5, a4, a3, a2, a1, a0,
b7, b6, b5, b4, b3, b2, b1, b0,
carryin=false)
c0, s0 = fulladder(a0, b0, carryin)
c1, s1 = fulladder(a1, b1, c0)
c2, s2 = fulladder(a2, b2, c1)
c3, s3 = fulladder(a3, b3, c2)
c4, s4 = fulladder(a4, b4, c3)
c5, s5 = fulladder(a5, b5, c4)
c6, s6 = fulladder(a6, b6, c5)
carryout, s7 = fulladder(a7, b7, c6)
return carryout, s7, s6, s5, s4, s3, s2, s1, s0
end
F, T = false, true
eightbitadder(A..., B...)
減算対応
hi - loのみ
code:jl
function eightbitadder(a7, a6, a5, a4, a3, a2, a1, a0,
b7, b6, b5, b4, b3, b2, b1, b0,
carryin=false;
issub=false)
carryin = xor(carryin, issub) # 減算モードで補数処理の落ち穂になる
c0, s0 = fulladder(a1, b1, carryin) c1, s1 = fulladder(a2, b2, c0) c2, s2 = fulladder(a3, b3, c1) c3, s3 = fulladder(a4, b4, c2) c4, s4 = fulladder(a5, b5, c3) c5, s5 = fulladder(a6, b6, c4) c6, s6 = fulladder(a7, b7, c5) carryout, s7 = fulladder(a8, b8, c6) carryout = xor(carryout, issub) # 減算モードで最上位ビットを削る
return carryout, s7, s6, s5, s4, s3, s2, s1, s0
end
F, T = false, true
eightbitadder(A..., B...)
eightbitadder(A..., B...; issub=true)
(a, b, sum)の最上位ビットを監視してオーバーフローを検知する
加算ならキャリーアウトに読み替えられる?あんも.icon
code:eightbitadder.jl
function eightbitadder(a7, a6, a5, a4, a3, a2, a1, a0,
b7, b6, b5, b4, b3, b2, b1, b0,
carryin=false)
c0, s0 = fulladder(a1, b1, carryin) c1, s1 = fulladder(a2, b2, c0) c2, s2 = fulladder(a3, b3, c1) c3, s3 = fulladder(a4, b4, c2) c4, s4 = fulladder(a5, b5, c3) c5, s5 = fulladder(a6, b6, c4) c6, s6 = fulladder(a7, b7, c5) _, s7 = fulladder(a8, b8, c6) isoverflow = (!s7 && (a7 && b7)) || !(!s7 || a7 || b7)
return isoverflow, s7, s6, s5, s4, s3, s2, s1, s0
end
code:jl
F, T = false, true
eightbitadder(A..., B...)