3345c6b7a4a7dee9370ce38d30c16e749cb651bf
[soc.git] / src / soc / simulator / internalop_sim.py
1 from soc.decoder.power_enums import (Function, Form, InternalOp,
2 In1Sel, In2Sel, In3Sel, OutSel,
3 RC, LdstLen, CryIn, get_csv,
4 single_bit_flags,
5 get_signal_name, default_values)
6 import math
7
8
9 class MemorySim:
10 def __init__(self, bytes_per_word=8):
11 self.mem = {}
12 self.bytes_per_word = bytes_per_word
13 self.word_log2 = math.ceil(math.log2(bytes_per_word))
14
15 def _get_shifter_mask(self, width, remainder):
16 shifter = ((self.bytes_per_word - width) - remainder) * \
17 8 # bits per byte
18 mask = (1 << (width * 8)) - 1
19 return shifter, mask
20
21 # TODO: Implement ld/st of lesser width
22 def ld(self, address, width=8):
23 remainder = address & (self.bytes_per_word - 1)
24 address = address >> self.word_log2
25 assert remainder & (width - 1) == 0, "Unaligned access unsupported!"
26 if address in self.mem:
27 val = self.mem[address]
28 else:
29 val = 0
30
31 if width != self.bytes_per_word:
32 shifter, mask = self._get_shifter_mask(width, remainder)
33 val = val & (mask << shifter)
34 val >>= shifter
35 print("Read {:x} from addr {:x}".format(val, address))
36 return val
37
38 def st(self, address, value, width=8):
39 remainder = address & (self.bytes_per_word - 1)
40 address = address >> self.word_log2
41 assert remainder & (width - 1) == 0, "Unaligned access unsupported!"
42 print("Writing {:x} to addr {:x}".format(value, address))
43 if width != self.bytes_per_word:
44 if address in self.mem:
45 val = self.mem[address]
46 else:
47 val = 0
48 shifter, mask = self._get_shifter_mask(width, remainder)
49 val &= ~(mask << shifter)
50 val |= value << shifter
51 self.mem[address] = val
52 else:
53 self.mem[address] = value
54
55
56 class RegFile:
57 def __init__(self):
58 self.regfile = [0] * 32
59 self.sprs = {}
60
61 def write_reg(self, regnum, value):
62 print("Writing {:x} to reg r{}".format(value, regnum))
63 self.regfile[regnum] = value
64
65 def read_reg(self, regnum):
66 val = self.regfile[regnum]
67 print("Read {:x} from reg r{}".format(val, regnum))
68 return val
69
70 def assert_gpr(self, gpr, val):
71 reg_val = self.read_reg(gpr)
72 msg = "reg r{} got {:x}, expecting {:x}".format(
73 gpr, reg_val, val)
74 assert reg_val == val, msg
75
76 def assert_gprs(self, gprs):
77 for k, v in list(gprs.items()):
78 self.assert_gpr(k, v)
79
80
81 class InternalOpSimulator:
82 def __init__(self):
83 self.mem_sim = MemorySim()
84 self.regfile = RegFile()
85
86 def execute_alu_op(self, op1, op2, internal_op):
87 print(internal_op)
88 if internal_op == InternalOp.OP_ADD.value:
89 return op1 + op2
90 elif internal_op == InternalOp.OP_AND.value:
91 return op1 & op2
92 elif internal_op == InternalOp.OP_OR.value:
93 return op1 | op2
94 else:
95 assert False, "Not implemented"
96
97 def alu_op(self, pdecode2):
98 internal_op = yield pdecode2.dec.op.internal_op
99 operand1 = 0
100 operand2 = 0
101 result = 0
102 r1_ok = yield pdecode2.e.read_reg1.ok
103 r2_ok = yield pdecode2.e.read_reg2.ok
104 r3_ok = yield pdecode2.e.read_reg3.ok
105 imm_ok = yield pdecode2.e.imm_data.ok
106 if r1_ok:
107 r1_sel = yield pdecode2.e.read_reg1.data
108 operand1 = self.regfile.read_reg(r1_sel)
109 elif r3_ok:
110 r3_sel = yield pdecode2.e.read_reg3.data
111 operand1 = self.regfile.read_reg(r3_sel)
112 if r2_ok:
113 r2_sel = yield pdecode2.e.read_reg2.data
114 operand2 = self.regfile.read_reg(r2_sel)
115 if imm_ok:
116 operand2 = yield pdecode2.e.imm_data.data
117
118 result = self.execute_alu_op(operand1, operand2, internal_op)
119 ro_ok = yield pdecode2.e.write_reg.ok
120 if ro_ok:
121 ro_sel = yield pdecode2.e.write_reg.data
122 self.regfile.write_reg(ro_sel, result)
123
124 def mem_op(self, pdecode2):
125 internal_op = yield pdecode2.dec.op.internal_op
126 addr_reg = yield pdecode2.e.read_reg1.data
127 addr = self.regfile.read_reg(addr_reg)
128
129 imm_ok = yield pdecode2.e.imm_data.ok
130 r2_ok = yield pdecode2.e.read_reg2.ok
131 width = yield pdecode2.e.data_len
132 if imm_ok:
133 imm = yield pdecode2.e.imm_data.data
134 addr += imm
135 elif r2_ok:
136 r2_sel = yield pdecode2.e.read_reg2.data
137 addr += self.regfile.read_reg(r2_sel)
138 if internal_op == InternalOp.OP_STORE.value:
139 val_reg = yield pdecode2.e.read_reg3.data
140 val = self.regfile.read_reg(val_reg)
141 self.mem_sim.st(addr, val, width)
142 elif internal_op == InternalOp.OP_LOAD.value:
143 dest_reg = yield pdecode2.e.write_reg.data
144 val = self.mem_sim.ld(addr, width)
145 self.regfile.write_reg(dest_reg, val)
146
147 def execute_op(self, pdecode2):
148 function = yield pdecode2.dec.op.function_unit
149 if function == Function.ALU.value:
150 yield from self.alu_op(pdecode2)
151 elif function == Function.LDST.value:
152 yield from self.mem_op(pdecode2)