# File: nim.py from Tkinter import * # from random import random master = Tk() # Fonts intFont = "Helvetica 18" binaryFont = "Courier 18" opFont = "Helvetica 18" # Inputs/outputs byte = [False]*7 pc = [False]*5 acc = False # Assembler! def intToByte7(n): return [1==n%(2**(7-i))/(2**(6-i)) for i in range(7)] def intToByte5(n): return [1==n%(2**(5-i))/(2**(4-i)) for i in range(5)] def intToByte4(n): return [1==n%(2**(4-i))/(2**(3-i)) for i in range(4)] def OR(v): return ord(v)-ord("A") def AND(v): return 16+ord(v)-ord("A") def ACC(v): return 32+ord(v)-ord("A") def NOT(v): return 32+16+ord(v)-ord("A") def LOAD(inst): return intToByte7(inst) def STORE(inst): return intToByte7(64+inst) def SET(v): reg[ord(v)-ord("A")]=True # EF 10 # AB 11 # +CD +10 # --- --- # GHI 101 # prog = [ # I = B xor D = (B and not D) or (not B and D) LOAD(NOT('D')), LOAD(AND("B")), STORE(ACC("P")), LOAD(NOT("B")), LOAD(AND("D")), LOAD(OR("P")), STORE(ACC("I")), # F = B and D LOAD(ACC("B")), LOAD(AND("D")), STORE(ACC("F")), # O = A xor C = (A and not C) or (not A and C) LOAD(NOT('C')), LOAD(AND("A")), STORE(ACC("P")), LOAD(NOT("A")), LOAD(AND("C")), LOAD(OR("P")), STORE(ACC("O")), # G = E = (A and C) or (F and O) LOAD(ACC("A")), LOAD(AND("C")), STORE(ACC("P")), LOAD(ACC("F")), LOAD(AND("O")), LOAD(OR("P")), STORE(ACC("E")), STORE(ACC("G")), # H = F xor O = (not F and O) or (F and not O) LOAD(NOT('F')), LOAD(AND("O")), STORE(ACC("P")), LOAD(NOT("O")), LOAD(AND("F")), LOAD(OR("P")), STORE(ACC("H")) ] mem = prog + [byte]*(32-len(prog)) reg = [False]*16 SET("A") SET("B") SET("C") # One logical cycle # [mem,pc,acc] = cycle([mem,pc,acc]) def cycle(input): [mem,pc,acc,reg] = input ir = memlookup32x7(pc,mem) pcnew = addbyte5(pc, intToByte5(1)) v = ir[3:] val = memlookup16x1(v,reg) res = ifthenelse(not ir[1] and not ir[2], acc or val, False) res = ifthenelse(not ir[1] and ir[2], acc and val, res) res = ifthenelse(not ir[0] and ir[1] and not ir[2], val, res) res = ifthenelse(ir[0] and ir[1] and not ir[2], acc, res) res = ifthenelse(not ir[0] and ir[1] and ir[2], not val, res) res = ifthenelse(ir[0] and ir[1] and ir[2], not acc, res) accnew = ifthenelse(ir[0], acc, res) # print "reg", reg # print "ir[0]", ir[0] # print "v", v # print "res", res regnew = memwrite16x1(ir[0],v,reg,res) # print "regnew", regnew return [mem,pcnew,accnew,regnew] # Update the display def update(input): [mem,pc,acc,reg] = input # print "update", pc, acc, "memlen", len(mem) for add in range(32): memint[add].delete(0,END) memint[add].insert(INSERT, byteToInt(mem[add])) membinary[add].configure(text=byteToBinary(mem[add])) memop[add].configure(text=byteToOp(mem[add]),bg="white") pcint.configure(text=byteToInt(pc)) if acc: accval = "True" else: accval = "False" accint.configure(text=accval) memop[byteToInt(pc)].configure(bg="red") # registers for i in range(16): regLab[i].configure(text=reg[i]) def byteToInt(byte): l = len(byte) return sum([2**(l-1-i) * byte[i] for i in range(l)]) def byteToBinary(byte): return ''.join(["0"*(not b)+"1"*b for b in byte]) def byteToOp(byte): store = byte[0] op = byte[1]*2+byte[2] varname = chr(byteToInt(byte[3:])+ord("A")) opname = "error" if (op == 0): opname = "acc or "+ varname if (op == 1): opname = "acc and "+ varname if (store and op == 2): opname = "acc" if (not store and op == 2): opname = varname if (store and op == 3): opname = "not acc" if (not store and op == 3): opname = "not " + varname assert opname != "error" if (store): return varname + " = " + opname if (not store): return "acc = " + opname # Create the display memint = [0]*32 membinary = [0]*32 memop = [0]*32 # functions: byteToInt, byteToBits, byteToOp for colgrp in range(2): for row in range(16): add = colgrp*16+row Label(master, text=add, font=intFont, anchor=E,width=2,bg="gray",fg="white").grid(column=colgrp*4+0,row=row) memint[add] = Entry(master, font=intFont, width=3) memint[add].insert(INSERT, byteToInt(mem[add])) memint[add].grid(column=colgrp*4+1,row=row) def setMem(event, add=add): global mem global pc global acc global res newval = int(memint[add].get()) mem[add] = intToByte7(newval) update([mem,pc,acc,reg]) memint[add].bind('',setMem) membinary[add] = Label(master, text=byteToBinary(mem[add]), font=binaryFont, fg="gray") membinary[add].grid(column=colgrp*4+2,row=row) memop[add] = Label(master, text=byteToOp(mem[add]), font=opFont) memop[add].grid(column=colgrp*4+3,row=row) memop[add].configure(anchor=W, width=13) Label(master, text="PC", font=intFont).grid(row=8,column=2*4+0,columnspan=4) pcint = Label(master, text=byteToInt(pc), font=intFont, width=3) pcint.grid(column=2*4+4,row=8,columnspan=3) Label(master, text="acc", font=intFont).grid(row=9,column=2*4+0,columnspan=4) accint = Label(master, text="False", font=intFont, width=5) accint.grid(column=2*4+4,row=9,columnspan=5) def click(): global mem global pc global acc global reg [mem,pc,acc,reg] = cycle([mem,pc,acc,reg]) update([mem,pc,acc,reg]) Button(master, text="cycle", command=click,font=intFont).grid(row=10,column=2*4+2,columnspan=4,rowspan=2) # Label(master, text="MLMLML", font=intFont, bg = "blue").grid(row=21,column=2*4+2) def clickBit(i): global mem global pc global acc global reg # reg[i] = 1-reg[i] update([mem,pc,acc,reg]) # Register display regLab = [0]*16 for i in range(16): Label(master, text=chr(ord("A")+i)).grid(row=1,column=9+i) regLab[i] = Label(master, text="0", font=binaryFont) regLab[i].grid(row=0,column=9+i) def clickIt(event, i=i): clickBit(i) regLab[i].bind('',clickIt) # Logic Functions def addc(a,b,c): bit = (a and not b and not c) or (not a and b and not c) or (not a and not b and c) or (a and b and c) carry = (a and b and not c) or (a and not b and c) or (not a and b and c) or (a and b and c) return([carry, bit]) def addbyte6(x,y): z = [False]*6 sum5 = addc(x[5],y[5],0) z[5] = sum5[1] sum4 = addc(x[4],y[4],sum5[0]) z[4] = sum4[1] sum3 = addc(x[3],y[3],sum4[0]) z[3] = sum3[1] sum2 = addc(x[2],y[2],sum3[0]) z[2] = sum2[1] sum1 = addc(x[1],y[1],sum2[0]) z[1] = sum1[1] sum0 = addc(x[0],y[0],sum1[0]) z[0] = sum0[1] return z def addbyte5(x,y): z = [False]*5 sum4 = addc(x[4],y[4],0) z[4] = sum4[1] sum3 = addc(x[3],y[3],sum4[0]) z[3] = sum3[1] sum2 = addc(x[2],y[2],sum3[0]) z[2] = sum2[1] sum1 = addc(x[1],y[1],sum2[0]) z[1] = sum1[1] sum0 = addc(x[0],y[0],sum1[0]) z[0] = sum0[1] return z def ifthenelse7(bit, byte1, byte2): return [(byte1[0] and bit) or (byte2[0] and not bit), (byte1[1] and bit) or (byte2[1] and not bit), (byte1[2] and bit) or (byte2[2] and not bit), (byte1[3] and bit) or (byte2[3] and not bit), (byte1[4] and bit) or (byte2[4] and not bit), (byte1[5] and bit) or (byte2[5] and not bit), (byte1[6] and bit) or (byte2[6] and not bit)] def ifthenelse(condition, thenbit, elsebit): return (condition and thenbit) or (not condition and elsebit) # match two bits def equal(bit1, bit2): return ((bit1 and bit2) or (not bit1 and not bit2)) # match two bytes def equal6(byte1, byte2): # print "eq", byte1, byte2 return (equal(byte1[0],byte2[0]) and equal(byte1[1],byte2[1]) and equal(byte1[2],byte2[2]) and equal(byte1[3],byte2[3]) and equal(byte1[4],byte2[4]) and equal(byte1[5],byte2[5])) def equal5(byte1, byte2): # print "eq", byte1, byte2 return (equal(byte1[0],byte2[0]) and equal(byte1[1],byte2[1]) and equal(byte1[2],byte2[2]) and equal(byte1[3],byte2[3]) and equal(byte1[4],byte2[4])) def equal4(byte1, byte2): # print "eq", byte1, byte2 return (equal(byte1[0],byte2[0]) and equal(byte1[1],byte2[1]) and equal(byte1[2],byte2[2]) and equal(byte1[3],byte2[3])) def memlookup32x7(add, mem): mem00 = mem[0] mem01 = ifthenelse7(equal5(intToByte5( 1),add), mem[ 1], mem00) mem02 = ifthenelse7(equal5(intToByte5( 2),add), mem[ 2], mem01) mem03 = ifthenelse7(equal5(intToByte5( 3),add), mem[ 3], mem02) mem04 = ifthenelse7(equal5(intToByte5( 4),add), mem[ 4], mem03) mem05 = ifthenelse7(equal5(intToByte5( 5),add), mem[ 5], mem04) mem06 = ifthenelse7(equal5(intToByte5( 6),add), mem[ 6], mem05) mem07 = ifthenelse7(equal5(intToByte5( 7),add), mem[ 7], mem06) mem08 = ifthenelse7(equal5(intToByte5( 8),add), mem[ 8], mem07) mem09 = ifthenelse7(equal5(intToByte5( 9),add), mem[ 9], mem08) mem10 = ifthenelse7(equal5(intToByte5(10),add), mem[10], mem09) mem11 = ifthenelse7(equal5(intToByte5(11),add), mem[11], mem10) mem12 = ifthenelse7(equal5(intToByte5(12),add), mem[12], mem11) mem13 = ifthenelse7(equal5(intToByte5(13),add), mem[13], mem12) mem14 = ifthenelse7(equal5(intToByte5(14),add), mem[14], mem13) mem15 = ifthenelse7(equal5(intToByte5(15),add), mem[15], mem14) mem16 = ifthenelse7(equal5(intToByte5(16),add), mem[16], mem15) mem17 = ifthenelse7(equal5(intToByte5(17),add), mem[17], mem16) mem18 = ifthenelse7(equal5(intToByte5(18),add), mem[18], mem17) mem19 = ifthenelse7(equal5(intToByte5(19),add), mem[19], mem18) mem20 = ifthenelse7(equal5(intToByte5(20),add), mem[20], mem19) mem21 = ifthenelse7(equal5(intToByte5(21),add), mem[21], mem20) mem22 = ifthenelse7(equal5(intToByte5(22),add), mem[22], mem21) mem23 = ifthenelse7(equal5(intToByte5(23),add), mem[23], mem22) mem24 = ifthenelse7(equal5(intToByte5(24),add), mem[24], mem23) mem25 = ifthenelse7(equal5(intToByte5(25),add), mem[25], mem24) mem26 = ifthenelse7(equal5(intToByte5(26),add), mem[26], mem25) mem27 = ifthenelse7(equal5(intToByte5(27),add), mem[27], mem26) mem28 = ifthenelse7(equal5(intToByte5(28),add), mem[28], mem27) mem29 = ifthenelse7(equal5(intToByte5(29),add), mem[29], mem28) mem30 = ifthenelse7(equal5(intToByte5(30),add), mem[30], mem29) mem31 = ifthenelse7(equal5(intToByte5(31),add), mem[31], mem30) return mem31 def memlookup16x1(add, mem): mem00 = mem[0] mem01 = ifthenelse(equal4(intToByte4( 1),add), mem[ 1], mem00) mem02 = ifthenelse(equal4(intToByte4( 2),add), mem[ 2], mem01) mem03 = ifthenelse(equal4(intToByte4( 3),add), mem[ 3], mem02) mem04 = ifthenelse(equal4(intToByte4( 4),add), mem[ 4], mem03) mem05 = ifthenelse(equal4(intToByte4( 5),add), mem[ 5], mem04) mem06 = ifthenelse(equal4(intToByte4( 6),add), mem[ 6], mem05) mem07 = ifthenelse(equal4(intToByte4( 7),add), mem[ 7], mem06) mem08 = ifthenelse(equal4(intToByte4( 8),add), mem[ 8], mem07) mem09 = ifthenelse(equal4(intToByte4( 9),add), mem[ 9], mem08) mem10 = ifthenelse(equal4(intToByte4(10),add), mem[10], mem09) mem11 = ifthenelse(equal4(intToByte4(11),add), mem[11], mem10) mem12 = ifthenelse(equal4(intToByte4(12),add), mem[12], mem11) mem13 = ifthenelse(equal4(intToByte4(13),add), mem[13], mem12) mem14 = ifthenelse(equal4(intToByte4(14),add), mem[14], mem13) mem15 = ifthenelse(equal4(intToByte4(15),add), mem[15], mem14) return mem15 def memwrite16x1(active, add, mem, val): return [ ifthenelse(active and equal4(intToByte4( 0),add), val, mem[ 0]), ifthenelse(active and equal4(intToByte4( 1),add), val, mem[ 1]), ifthenelse(active and equal4(intToByte4( 2),add), val, mem[ 2]), ifthenelse(active and equal4(intToByte4( 3),add), val, mem[ 3]), ifthenelse(active and equal4(intToByte4( 4),add), val, mem[ 4]), ifthenelse(active and equal4(intToByte4( 5),add), val, mem[ 5]), ifthenelse(active and equal4(intToByte4( 6),add), val, mem[ 6]), ifthenelse(active and equal4(intToByte4( 7),add), val, mem[ 7]), ifthenelse(active and equal4(intToByte4( 8),add), val, mem[ 8]), ifthenelse(active and equal4(intToByte4( 9),add), val, mem[ 9]), ifthenelse(active and equal4(intToByte4(10),add), val, mem[10]), ifthenelse(active and equal4(intToByte4(11),add), val, mem[11]), ifthenelse(active and equal4(intToByte4(12),add), val, mem[12]), ifthenelse(active and equal4(intToByte4(13),add), val, mem[13]), ifthenelse(active and equal4(intToByte4(14),add), val, mem[14]), ifthenelse(active and equal4(intToByte4(15),add), val, mem[15])] # START THE UI update([mem,pc,acc,reg]) master.mainloop()