-
Notifications
You must be signed in to change notification settings - Fork 68
/
isa.py
80 lines (66 loc) · 2.29 KB
/
isa.py
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
"""
The assembly format for most instructions (RHM, WHM, MMC, ACT) is
INSTRUCTION SRC, DEST, LENGTH
For RW, it is
RW SRC
for HLT, it is
HLT
=== Binary Encoding ====
| opcode | flags | length | addr | ub addr |
| 1 | 1 | 1 | 8 | 3 |
|13 13|12 12|11 11|10 3|2 0|
All numbers above are expressed in BYTES.
The 'addr' field is used for host memory address (for RHM and WHM),
weight DRAM address (for RW), and accumulator address (for MMC and ACT).
For the later two, the field is larger than necessary, and only the lower bits are used.
'ub addr' is always a Unified Buffer address.
'length' is the number of vectors to read/write/process.
FLAG field is r|r|f|f|f|o|s|c, r stands for reserved bit, s for switch bit,
c for convolve bit, f for function select bits, and o for override bit.
"""
ENDIANNESS = 'big'
#ENDIANNESS = 'little'
INSTRUCTION_WIDTH_BYTES = 14
HOST_ADDR_SIZE = 8 # 64-bit addressing
DRAM_ADDR_SIZE = 5 # 33-bit addressing (TPU has 8 GB on-chip DRAM)
UB_ADDR_SIZE = 3 # 17-bit addressing for Unified Buffer
ACC_ADDR_SIZE = 2 # 12-bit addressing for accumulator
OP_SIZE = 1
FLAGS_SIZE = 1
ADDR_SIZE = 8
UB_ADDR_SIZE = 3
LEN_SIZE = 1
UBADDR_START = 0
UBADDR_END = 3
ADDR_START = 3
ADDR_END = 11
LEN_START = 11
LEN_END = 12
FLAGS_START = 12
FLAGS_END = 13
OP_START = 13
OP_END = 14
# Map text opcode to instruction decomposition info.
# Str -> (opcode_value, src_len, dst_len, 3rd_len)
OPCODE2BIN = {
'NOP': (0x0, 0, 0, 0),
'WHM': (0x1, UB_ADDR_SIZE, HOST_ADDR_SIZE, 1),
'RW': (0x2, DRAM_ADDR_SIZE, 0, 1),
'MMC': (0x3, UB_ADDR_SIZE, ACC_ADDR_SIZE, 1),
'ACT': (0x4, ACC_ADDR_SIZE, UB_ADDR_SIZE, 1),
'SYNC': (0x5, 0, 0, 0),
'RHM': (0x6, HOST_ADDR_SIZE, UB_ADDR_SIZE, 1),
'HLT': (0x7, 0, 0, 0),
}
BIN2OPCODE = {v[0]: k for k, v in OPCODE2BIN.items()}
SWITCH_MASK = 0b00000001
CONV_MASK = 0b00000010
OVERWRITE_MASK = 0b00000100 # whether MMC should overwrite accumulator value or add to it
ACT_FUNC_MASK = 0b00011000 # 0 for nothing; 1 for ReLU; 2 for sigmoid
FUNC_RELU_MASK = 0b00001000
FUNC_SIGMOID_MASK = 0b00010000
SWITCH_BIT = 0
OVERWRITE_BIT = 2
ACT_FUNC_BITS = slice(3,5)
FUNC_RELU_BIT = 3
FUNC_SIGMOID_BIT = 4