1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
|
import sys
memory_block_start = """
mov UP, LEFT
mov UP, ACC
mov UP, LEFT
jnz is_write
mov LEFT, DOWN
mov 0, DOWN
mov UP, DOWN
mov LEFT, NIL
jmp wrap
is_write:
mov LEFT, DOWN
mov 1, DOWN
mov UP, ACC
xor LEFT
mov ACC, DOWN
swp
wrap:
mov DOWN, ACC
xor LEFT
mov LEFT, RIGHT
mov ${{addr}}, RIGHT
mov ${OP_ACK}, RIGHT
mov ACC, RIGHT
mov ${OP_NIL}, RIGHT
"""
memory_block_start_left = """
mov RIGHT, ACC
swp
mov RIGHT, ACC
mov ACC, RIGHT
mov ACC, RIGHT
mov ACC, RIGHT
swp
mov ACC, RIGHT
"""
memory_block_start_right = """
mov LEFT, UP
"""
code_memory_split = """
mov UP, ACC
mov ACC, LEFT
mov ACC, RIGHT
mov UP, ACC
mov ACC, LEFT
mov ACC, RIGHT
mov UP, ACC
mov ACC, LEFT
mov ACC, RIGHT
mov ANY, ACC
add ANY
mov ACC, UP
"""
code_memory_split_rev = """
mov UP, ACC
mov ACC, RIGHT
mov ACC, LEFT
mov UP, ACC
mov ACC, RIGHT
mov ACC, LEFT
mov UP, ACC
mov ACC, RIGHT
mov ACC, LEFT
mov ANY, ACC
add ANY
mov ACC, UP
"""
code_memory_cell = """
mov 0x{val:02x}, ACC
sav
start:
mov UP, ACC
xor {idx}
jnz skip
mov UP, ACC
jnz WRITE
mov UP, NIL
swp
mov ACC, UP
sav
jmp start
write:
mov UP, ACC
swp
mov ACC, UP
jmp start
skip:
mov UP, NIL
mov UP, NIL
mov 0, UP
jmp start
"""
code_memory_right = """
mov LEFT, RIGHT
mov LEFT, RIGHT
mov LEFT, RIGHT
mov RIGHT, LEFT
"""
code_memory_right_corner = """
mov LEFT, DOWN
mov LEFT, DOWN
mov LEFT, DOWN
mov DOWN, LEFT
"""
code_memory_left = """
mov RIGHT, LEFT
mov RIGHT, LEFT
mov RIGHT, LEFT
mov LEFT, RIGHT
"""
code_memory_left_corner = """
mov RIGHT, DOWN
mov RIGHT, DOWN
mov RIGHT, DOWN
mov DOWN, RIGHT
"""
class BlockMap(dict):
def __setattr__(self, key, value):
if key in self.__dict__:
raise ValueError("Already exists")
super().__setattr__(key, value)
def gen_memory(blocks, start, idx_offset, idx, depth, contents):
if depth <= 0:
addr = idx_offset + idx
blocks[start] = code_memory_cell.format(idx=addr,val=addr^contents[idx])
return
sx, sy = start
blocks[start] = code_memory_split_rev if depth % 2 else code_memory_split
sidelen = int(2**(depth-1))
for i in range(1, sidelen):
blocks[(sx + i, sy)] = code_memory_right
blocks[(sx - i, sy)] = code_memory_left
blocks[(sx + sidelen, sy)] = code_memory_right_corner
blocks[(sx - sidelen, sy)] = code_memory_left_corner
gen_memory(blocks, (start[0] + sidelen, start[1] + 1),
idx_offset, idx + 2**(depth-1), depth - 1, contents)
gen_memory(blocks, (start[0] - sidelen, start[1] + 1),
idx_offset, idx, depth - 1, contents)
def write_blocks(blocks, filepath, addr_tmpl):
with open(filepath, "w+") as f:
for i,(x,y) in enumerate(blocks):
f.write(f"tpu X{x} Y{y}\n")
if i == 0:
f.write("\t## ${" + addr_tmpl + "}\n")
for l in blocks[(x,y)].strip("\n").split("\n"):
f.write(f"{l}\n")
f.write(f"end\n")
f.write("\n")
if __name__ == "__main__":
blocks = {}
blocks[(0, 0)] = memory_block_start.replace("{addr}", sys.argv[5])
blocks[(-1, 0)] = memory_block_start_left
blocks[(1, 0)] = memory_block_start_right
gen_memory(blocks, (0, 1), int(sys.argv[2]), 0, int(sys.argv[3]),
open(sys.argv[4], "rb").read().ljust(256, b"\x00"))
write_blocks(blocks, sys.argv[1], sys.argv[5])
|