Last active
April 26, 2021 12:56
-
-
Save kelvneo/96e07434063cd9d529ed3a411d9d7b31 to your computer and use it in GitHub Desktop.
Converts State Diagram into State Table and Sum-Of-Products.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from itertools import product | |
from functools import reduce | |
from rich.console import Console | |
from rich.table import Table | |
from sympy.logic import SOPform | |
from sympy import symbols | |
storage = {} | |
states = '' | |
inputs = '' | |
outputs = '' | |
gates = [] | |
def sr_gate(cur, nxt): | |
if cur == 0 and nxt == 0: | |
return (0, 'x') | |
elif cur == 0 and nxt == 1: | |
return (1, 0) | |
elif cur == 1 and nxt == 0: | |
return (0, 1) | |
else: | |
return ('x', 0) | |
def jk_gate(cur, nxt): | |
if cur == 0 and nxt == 0: | |
return (0, 'x') | |
elif cur == 0 and nxt == 1: | |
return (1, 'x') | |
elif cur == 1 and nxt == 0: | |
return ('x', 1) | |
else: | |
return ('x', 0) | |
def t_gate(cur, nxt): | |
if cur == nxt: | |
return 0 | |
else: | |
return 1 | |
def d_gate(cur, nxt): | |
return nxt | |
def main(): | |
states = input('Enter the state names (e.g. ABCD): ') | |
inputs = input('Enter the input names (e.g. xy, press enter for none): ') | |
outputs = input('Enter the output names (e.g. z, press enter for none): ') | |
keys = list(product([0, 1], repeat=(len(states) + len(inputs)))) | |
storage = dict(map(lambda x: (x, ['x' for i in range(len(states) + len(outputs))]), keys)) | |
print('') | |
print('To stop keying in, press enter with no values.') | |
print('') | |
try: | |
while True: | |
in_s = input('Enter input state (in integer): ') | |
if len(in_s) == 0: | |
break | |
in_i = '' | |
if len(inputs) > 0: | |
in_i = input('Enter input (in integer): ') | |
k = tuple(map(lambda x: int(x), bin((int(in_s) << len(inputs)) + int(in_i if len(in_i) > 0 else '0'))[2:].zfill(len(states) + len(inputs)))) | |
out_s = input('Enter output state (in integer): ') | |
if len(out_s) == 0: | |
break | |
out_o = '' | |
if len(outputs) > 0: | |
out_o = input('Enter output (in integer): ') | |
v = list(map(lambda x: int(x), bin((int(out_s) << len(outputs)) + int(out_o if len(out_o) > 0 else '0'))[2:].zfill(len(states) + len(outputs)))) | |
storage[k] = v | |
print('---') | |
except: | |
pass | |
print('') | |
for s in states: | |
gates.append(input('Enter the gate/latch for ' + s + ' (SR/JK/D/T): ')) | |
print('') | |
# Set up the table | |
final_table = Table(show_lines=True) | |
blanked = ['x' for i in range(len(states) + len(outputs))] | |
input_outputs = {} | |
dont_cares = [] | |
# Set up the columns | |
for x in states: | |
final_table.add_column(x) | |
for x in inputs: | |
final_table.add_column(x) | |
for x in states: | |
final_table.add_column(x+'\'') | |
for x in outputs: | |
final_table.add_column(x) | |
input_outputs[x] = ([], []) | |
for i, x in enumerate(gates): | |
if x == 'SR': | |
final_table.add_column('S' + states[i]) | |
input_outputs['S' + states[i]] = ([], []) | |
final_table.add_column('R' + states[i]) | |
input_outputs['R' + states[i]] = ([], []) | |
elif x == 'JK': | |
final_table.add_column('J' + states[i]) | |
input_outputs['J' + states[i]] = ([], []) | |
final_table.add_column('K' + states[i]) | |
input_outputs['K' + states[i]] = ([], []) | |
elif x == 'T': | |
final_table.add_column('T' + states[i]) | |
input_outputs['T' + states[i]] = ([], []) | |
elif x == 'D': | |
final_table.add_column('D' + states[i]) | |
input_outputs['D' + states[i]] = ([], []) | |
# Insert the records into the table | |
for k in keys: | |
# Check if everything is don't care | |
if storage[k] == blanked: | |
for k2 in input_outputs: | |
input_outputs[k2][1].append(k) | |
dont_cares.append(k) | |
continue | |
r = list(k) | |
stor = storage[k] | |
r.extend(stor) | |
if len(outputs) > 0: | |
for i, x in enumerate(stor[len(states):]): | |
if x == 1: | |
input_outputs[outputs[i]][0].append(k) | |
elif x == 'x': | |
input_outputs[outputs[i]][1].append(k) | |
for i, x in enumerate(gates): | |
st = states[i] | |
if x == 'SR': | |
a, b = sr_gate(k[i], stor[i]) | |
if a == 1: | |
input_outputs['S' + st][0].append(k) | |
elif a == 'x': | |
input_outputs['S' + st][1].append(k) | |
if b == 1: | |
input_outputs['R' + st][0].append(k) | |
elif b == 'x': | |
input_outputs['R' + st][1].append(k) | |
r.append(a) | |
r.append(b) | |
elif x == 'JK': | |
a, b = jk_gate(k[i], stor[i]) | |
if a == 1: | |
input_outputs['J' + st][0].append(k) | |
elif a == 'x': | |
input_outputs['J' + st][1].append(k) | |
if b == 1: | |
input_outputs['K' + st][0].append(k) | |
elif b == 'x': | |
input_outputs['K' + st][1].append(k) | |
r.append(a) | |
r.append(b) | |
elif x == 'T': | |
a = t_gate(k[i], stor[i]) | |
if a == 1: | |
input_outputs['T' + st][0].append(k) | |
elif a == 'x': | |
input_outputs['T' + st][1].append(k) | |
r.append(a) | |
elif x == 'D': | |
a = d_gate(k[i], stor[i]) | |
if a == 1: | |
input_outputs['D' + st][0].append(k) | |
elif a == 'x': | |
input_outputs['D' + st][1].append(k) | |
r.append(a) | |
final_table.add_row(*(map(lambda x: str(x), r))) | |
console = Console() | |
console.print(final_table) | |
if len(dont_cares) > 0: | |
print('') | |
print(' - ! - Important - ! - ') | |
print('The following inputs do not have outputs:') | |
for i in dont_cares: | |
print(i, '| Integer Form:', reduce(lambda x, y: (x << 1) + y, i)) | |
syms = symbols(' '.join(i for i in states + inputs)) | |
print('') | |
for keys in input_outputs: | |
print('SOP for ' + keys + ': ', SOPform(syms, input_outputs[keys][0], input_outputs[keys][1])) | |
print('') | |
# print(storage) | |
if __name__ == '__main__': | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment