Add routed sign detector board.
[trinary.git] / asm / logicCpu.py
blob58bb47ecbe1232c4106be2ffcccbfbbbaa9c0ae5
1 #!env python
2 # Created:20080415
3 # By Antonio Chavez
5 # 3-trit Computer Simulator
6 # usage: logicCpu program.3
7 # This program simulates the hardware of the 3 trit computer we are
8 # developing. Input to the program is a ".3" file which should contain
9 # three encoded instructions to simulate on the first line. Once started,
10 # the user may interactively change the "IN" register at any time.
11 # Execution begins with instruction at program counter 0.
13 import sys, os, threading, time, signal
15 # for safe termination
16 CONTINUE = 0
17 TERMINATE = 1
18 global cont_exec
19 cont_exec = CONTINUE
21 # for concurency
22 global locked
23 locked = False
25 TRACE = False
26 DELAY = 1 # second(s)
27 USER_INPUT_THREAD = True # ask for user input?
28 USER_INPUT_INIT = 8 # initialize input to this
30 trit_integer = {"i": -1, "0":0, "1":1}
32 # Lookup a register's name by address
33 register_name = {
34 -1: "IN",
35 0: "OUT",
36 1: "A"
39 # Register contents
40 registers = {
41 "IN": 0,
42 "OUT": 0,
43 "A": 0,
44 "S": 1
47 # Thread that gets input from user
48 class CPUInput (threading.Thread):
49 def run (self):
50 while True:
51 print "Register Status: %s :" % registers,
53 try:
54 user_input = raw_input('Input value for IN:')
55 except EOFError, e:
56 get_lock()
57 global cont_exec
58 cont_exec = TERMINATE
59 release_lock()
60 sys.exit()
62 get_lock()
63 global cont_exec
64 if cont_exec == TERMINATE:
65 sys.exit()
66 release_lock()
68 try:
69 digit = int(user_input)
70 except ValueError, e:
71 print "invalid input: %s (%s)" % (user_input, e)
72 continue
74 if digit >= -4 and digit <= 4:
75 registers["IN"] = digit
76 else:
77 print """invalid input: %s""" % user_input
79 def get_lock():
80 ''' Busy wait lock to avoid race conditions.
81 This function retrieves the lock.
82 '''
84 global locked
85 while locked:
86 a = 1
87 locked = True
89 def release_lock():
90 ''' This function releases the lock.
91 '''
92 global locked
93 locked = False
96 def main():
97 global cont_exec
99 # check arguments
100 if len(sys.argv) < 2 or len(sys.argv) > 2:
101 print """usage: %s program.3
102 input file: program.3 - machine code
103 """ % (sys.argv[0])
104 raise SystemExit
106 if (sys.argv[1])[len(sys.argv[1])-1:] != "3":
107 print """\'%s\' is an invalid filetype""" % sys.argv[1]
108 raise SystemExit
110 # retrieve file
111 codefile = file(sys.argv[1], "rt")
112 tritstream = codefile.readline()
114 # check for errors in file
115 if codefile == []:
116 print """\'%s\' files is empty""" % (sys.argv[1])
117 raise SystemExit
119 for i in tritstream:
120 if not i in trit_integer:
121 print """invalid char \'%s\' in file \'%s\'""" % (i, sys.argv[1])
122 raise SystemExit
124 if len(tritstream) != 9:
125 print """3 instructions must be provided in \'%s\'""" % (sys.argv[1])
126 raise SystemExit
128 # memory, registers, and program counter
129 memory = {}
131 get_lock()
132 registers["PC"] = 0
133 release_lock()
135 # decode instructions from file
136 for i in range(-1, 2):
137 print "%2d: " % (i),
138 memory[i] = Decoder(tritstream)
139 tritstream = tritstream[3:]
141 # start user input thread
142 if USER_INPUT_THREAD:
143 CPUInput().start()
145 get_lock()
146 registers["IN"] = USER_INPUT_INIT
147 release_lock()
149 # execute instructions
150 while True:
152 get_lock()
153 registers["PC"] = Execute(memory)
154 release_lock()
156 get_lock()
157 if cont_exec == TERMINATE:
158 sys.exit()
159 release_lock()
161 if TRACE:
162 get_lock()
163 print registers
164 release_lock()
166 time.sleep(DELAY)
168 def Decoder(tritstream):
169 """ Decode a single instruction.
170 tristream: stream of trits will only process the first 3 trits.
171 return: dictionary containing the operation
173 inst = {"op":trit_integer[tritstream[0]]}
175 # cmp and be
176 if inst["op"] == -1 or inst["op"] == 1:
178 if inst["op"] == -1:
179 print "cmp ",
180 else:
181 print "be ",
183 inst["src1"] = trit_integer[tritstream[1]]
184 print "%2d," % inst["src1"],
185 inst["src2"] = trit_integer[tritstream[2]]
186 print "%2d" % inst["src2"]
188 # lwi
189 elif inst["op"] == 0:
190 print "lwi ",
191 inst["src1"] = trit_integer[tritstream[1]]
192 inst["src2"] = trit_integer[tritstream[2]]
193 inst["immed"] = 3*inst["src1"] + inst["src2"]
194 print "%2d" % inst["immed"]
196 return inst
198 def Execute(memory):
199 """ Execute one instruction.
200 memory: were decoded instructions are stored
201 registers: contains registers and their values
202 returns: new program counter, to be stored in registers["PC"]
205 op = (memory[registers["PC"]])["op"]
207 # cmp
208 if op == -1:
209 src1 = (memory[registers["PC"]])["src1"]
210 src2 = (memory[registers["PC"]])["src2"]
211 if registers[register_name[src1]] < registers[register_name[src2]]:
212 registers["S"] = -1
213 elif registers[register_name[src1]] > registers[register_name[src2]]:
214 registers["S"] = 1
215 else:
216 registers["S"] = 0
217 new_pc = registers["PC"] + 1
218 # lwi
219 elif op == 0:
220 registers["A"] = (memory[registers["PC"]])["immed"]
221 new_pc = registers["PC"] + 1
222 # be
223 elif op == 1:
224 if registers["S"] == 0:
225 new_pc = (memory[registers["PC"]])["src1"]
226 else:
227 new_pc = (memory[registers["PC"]])["src2"]
229 if new_pc > 1:
230 new_pc = -1
232 return new_pc
234 if __name__ == "__main__":
235 main()