Python EDAで論理式を簡単化する

CPUの創りかた』に載っているデコーダをPython EDAを使って簡単化してみた。

真理値表

OP3, OP2, OP1, OP0, CFlagが入力。B, A, ~LOAD0, ~LOAD1, ~LOAD2, ~LOAD3が出力。

OP3 OP2 OP1 OP0 CFlag B A ~LOAD0 ~LOAD1 ~LOAD2 ~LOAD3
0 0 0 0 X 0 0 0 1 1 1
0 0 0 1 X 0 1 0 1 1 1
0 0 1 0 X 1 0 0 1 1 1
0 0 1 1 X 1 1 0 1 1 1
0 1 0 0 X 0 0 1 0 1 1
0 1 0 1 X 0 1 1 0 1 1
0 1 1 0 X 1 0 1 0 1 1
0 1 1 1 X 1 1 1 0 1 1
1 0 0 1 X 0 1 1 1 0 1
1 0 1 1 X 1 1 1 1 0 1
1 1 1 0 0 1 1 1 1 1 0
1 1 1 0 1 X X 1 1 1 1
1 1 1 1 X 1 1 1 1 1 0

入力側のdon't careを0, 1になおして、入力の欠けている部分も補ったのが↓。

OP3 OP2 OP1 OP0 CFlag B A ~LOAD0 ~LOAD1 ~LOAD2 ~LOAD3 追加
0 0 0 0 0 0 0 0 1 1 1
0 0 0 0 1 0 0 0 1 1 1
0 0 0 1 0 0 1 0 1 1 1
0 0 0 1 1 0 1 0 1 1 1
0 0 1 0 0 1 0 0 1 1 1
0 0 1 0 1 1 0 0 1 1 1
0 0 1 1 0 1 1 0 1 1 1
0 0 1 1 1 1 1 0 1 1 1
0 1 0 0 0 0 0 1 0 1 1
0 1 0 0 1 0 0 1 0 1 1
0 1 0 1 0 0 1 1 0 1 1
0 1 0 1 1 0 1 1 0 1 1
0 1 1 0 0 1 0 1 0 1 1
0 1 1 0 1 1 0 1 0 1 1
0 1 1 1 0 1 1 1 0 1 1
0 1 1 1 1 1 1 1 0 1 1
1 0 0 0 0 X X X X X X
1 0 0 0 1 X X X X X X
1 0 0 1 0 0 1 1 1 0 1
1 0 0 1 1 0 1 1 1 0 1
1 0 1 0 0 X X X X X X
1 0 1 0 1 X X X X X X
1 0 1 1 0 1 1 1 1 0 1
1 0 1 1 1 1 1 1 1 0 1
1 1 0 0 0 X X X X X X
1 1 0 0 1 X X X X X X
1 1 0 1 0 X X X X X X
1 1 0 1 1 X X X X X X
1 1 1 0 0 1 1 1 1 1 0
1 1 1 0 1 X X 1 1 1 1
1 1 1 1 0 1 1 1 1 1 0
1 1 1 1 1 1 1 1 1 1 0

Python EDA

from pyeda.inter import *

X = ttvars('x', 5)

b     = truthtable(X, '00 00 11 11 00 00 11 11 -- 00 -- 11 -- -- 1- 11'.replace(' ', ''))
a     = truthtable(X, '00 11 00 11 00 11 00 11 -- 11 -- 11 -- -- 1- 11'.replace(' ', ''))

load0 = truthtable(X, '00 00 00 00 11 11 11 11 -- 11 -- 11 -- -- 11 11'.replace(' ', ''))
load1 = truthtable(X, '11 11 11 11 00 00 00 00 -- 11 -- 11 -- -- 11 11'.replace(' ', ''))
load2 = truthtable(X, '11 11 11 11 11 11 11 11 -- 00 -- 00 -- -- 11 11'.replace(' ', ''))
load3 = truthtable(X, '11 11 11 11 11 11 11 11 -- 11 -- 11 -- -- 01 00'.replace(' ', ''))

bm, am, load0m, load1m, load2m, load3m = espresso_tts(b, a, load0, load1, load2, load3)

print('b =', bm)
print('a =', am)
print()

print('load0 =', load0m)
print(expr2truthtable(load0m))

print('load1 =', load1m)
print(expr2truthtable(load1m))

print('load2 =', load2m)
print(expr2truthtable(load2m))

print('load3 =', load3m)
print(expr2truthtable(load3m))

出力が↓。OP3, OP2, OP1, OP0, CFlagがそれぞれ、x[4], x[3], x[2], x[1], x[0]に割り当てられる。

b = x[2]  # OP1
a = Or(x[1], x[4])  # OP0 + OP3

load0 = Or(x[4], And(x[3], ~x[4]))  # OP3 + (OP2・~OP3) = OP2 + OP3
x[4] x[3]
   0    0 : 0
   0    1 : 1
   1    0 : 1
   1    1 : 1

load1 = Or(x[4], And(~x[3], ~x[4]))  # OP3 + (~OP2・~OP3) = ~OP2 + OP3
x[4] x[3]
   0    0 : 1
   0    1 : 0
   1    0 : 1
   1    1 : 1

load2 = Or(x[3], And(~x[3], ~x[4]))  # OP2 + (~OP2・~OP3) = OP2 + ~OP3
x[4] x[3]
   0    0 : 1
   0    1 : 1
   1    0 : 0
   1    1 : 1

load3 = Or(~x[3], And(x[3], ~x[4]), And(x[0], ~x[1]))
        # ~OP2 + (OP2・~OP3) + (CFlag・~OP0)
        # = ~OP2 + ~OP3 + (CFlag・~OP0)
x[4] x[3] x[1] x[0]
   0    0    0    0 : 1
   0    0    0    1 : 1
   0    0    1    0 : 1
   0    0    1    1 : 1
   0    1    0    0 : 1
   0    1    0    1 : 1
   0    1    1    0 : 1
   0    1    1    1 : 1
   1    0    0    0 : 1
   1    0    0    1 : 1
   1    0    1    0 : 1
   1    0    1    1 : 1
   1    1    0    0 : 0
   1    1    0    1 : 1
   1    1    1    0 : 0
   1    1    1    1 : 0
  • B, Aは本に載ってるのと同じものが得られた
  • ~LOAD0, ~LOAD1, ~LOAD2, ~LOAD3は分配律(x + yz) = (x + y)(x + z)を使えば同じ形