멀티플렉서와 디코더 문서의 검증 코드다. if __name__ == "__main__": 아래가 자체 테스트다.
# 06.멀티플렉서와 디코더: 게이트로 만든 회로를 전수 검사한다(8비트 너비 포함).
# 실행: python3 06_mux-decoder_verify.py (표준 라이브러리만 쓴다)
# 실제 하드웨어가 아니라 파이썬으로 게이트를 흉내 낸 것이다.
from itertools import product
def NOT(a): return 1 - a
def AND(*x): return int(all(x))
def OR(*x): return int(any(x))
def mux2(a, b, s):
"""1비트 2입력 멀티플렉서: y = (NOT s)a + sb. s=0이면 a, s=1이면 b."""
return OR(AND(NOT(s), a), AND(s, b))
def mux4(d0, d1, d2, d3, s1, s0):
"""2입력 멀티플렉서 셋으로 만든 4입력 멀티플렉서."""
return mux2(mux2(d0, d1, s0), mux2(d2, d3, s0), s1)
def decoder(bits):
"""n비트 입력(윗자리부터) -> 2^n개 출력. 입력이 가리키는 번호만 1."""
n = len(bits)
outs = []
for k in range(2 ** n):
want = [(k >> (n - 1 - i)) & 1 for i in range(n)]
outs.append(AND(*[b if w else NOT(b) for b, w in zip(bits, want)]))
return outs
def mux_from_decoder(data, sel_bits):
"""디코더 + AND 줄 + 큰 OR 하나로 만든 멀티플렉서."""
onehot = decoder(sel_bits)
return OR(*[AND(h, d) for h, d in zip(onehot, data)])
def bits_of(x, n):
return [(x >> i) & 1 for i in range(n)] # 아랫자리부터
def mux2_wide(a, b, s, n=8):
"""n비트 너비: 1비트 멀티플렉서 n개가 선택 신호 하나를 함께 쓴다."""
ya = [mux2(x, y, s) for x, y in zip(bits_of(a, n), bits_of(b, n))]
return sum(bit << i for i, bit in enumerate(ya))
if __name__ == "__main__":
# 2입력 멀티플렉서 진리표 8줄
for a, b, s in product((0, 1), repeat=3):
assert mux2(a, b, s) == (b if s else a)
# 4입력: 64가지 모두
for d0, d1, d2, d3, s1, s0 in product((0, 1), repeat=6):
want = (d0, d1, d2, d3)[2 * s1 + s0]
assert mux4(d0, d1, d2, d3, s1, s0) == want
assert mux_from_decoder([d0, d1, d2, d3], [s1, s0]) == want
# 식: e = s1's0'a + s1's0 b + s1 s0' c + s1 s0 d
e = OR(AND(NOT(s1), NOT(s0), d0), AND(NOT(s1), s0, d1), AND(s1, NOT(s0), d2), AND(s1, s0, d3))
assert e == want
# 8비트 너비 2입력 멀티플렉서 전수: 2 x 256 x 256
for a in range(256):
for b in range(256):
assert mux2_wide(a, b, 0) == a
assert mux2_wide(a, b, 1) == b
# 예시의 값
assert mux2_wide(0b00101101, 0b11110000, 0) == 0b00101101
assert mux2_wide(0b00101101, 0b11110000, 1) == 0b11110000
# 디코더: 2->4, 3->8, 5->32 모두 원-핫
for n in (1, 2, 3, 5):
for k in range(2 ** n):
bits = [(k >> (n - 1 - i)) & 1 for i in range(n)]
out = decoder(bits)
assert len(out) == 2 ** n and sum(out) == 1 and out[k] == 1
assert decoder([1, 0, 1]) == [0, 0, 0, 0, 0, 1, 0, 0] # 101(5) -> Out5만 1
assert decoder([1, 0]) == [0, 0, 1, 0]
# 선택 신호 수: 입력 n개면 log2 n개. 32개면 5개
assert (32).bit_length() - 1 == 5 and (4).bit_length() - 1 == 2
# 4입력 멀티플렉서에 드는 2입력 멀티플렉서 = 3개, 32입력이면 31개
assert 2 + 1 == 3 and 16 + 8 + 4 + 2 + 1 == 31
# 표 찾기: 데이터 입력에 진리표를 꽂으면 아무 2입력 함수나 된다 (XOR: 0,1,1,0)
for a, b in product((0, 1), repeat=2):
assert mux4(0, 1, 1, 0, a, b) == a ^ b
# 카드 C2: d = (1,0,1,1), s1 s0 = 1 0 -> d2 = 1
assert mux4(1, 0, 1, 1, 1, 0) == 1
# 카드 C3: 3->8 디코더에 110 -> Out6
assert decoder([1, 1, 0]).index(1) == 6
print("ALL CHECKS PASSED")