c794e591fbdf5f0760bf210a30b7061293eba536
[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 def set_xer(self, result, operanda, operandb):
81 xer = 0
82 if result & 1 << 64:
83 xer |= XER.CA
84
85 self.xer = xer
86
87
88 class InternalOpSimulator:
89 def __init__(self):
90 self.mem_sim = MemorySim()
91 self.regfile = RegFile()
92
93 def execute_alu_op(self, op1, op2, internal_op, carry=0):
94 print(internal_op)
95 if internal_op == InternalOp.OP_ADD.value:
96 return op1 + op2 + carry
97 elif internal_op == InternalOp.OP_AND.value:
98 return op1 & op2
99 elif internal_op == InternalOp.OP_OR.value:
100 return op1 | op2
101 else:
102 assert False, "Not implemented"
103
104 def alu_op(self, pdecode2):
105 internal_op = yield pdecode2.dec.op.internal_op
106 operand1 = 0
107 operand2 = 0
108 result = 0
109 carry = 0
110 r1_ok = yield pdecode2.e.read_reg1.ok
111 r2_ok = yield pdecode2.e.read_reg2.ok
112 r3_ok = yield pdecode2.e.read_reg3.ok
113 imm_ok = yield pdecode2.e.imm_data.ok
114 if r1_ok:
115 r1_sel = yield pdecode2.e.read_reg1.data
116 operand1 = self.regfile.read_reg(r1_sel)
117 elif r3_ok:
118 r3_sel = yield pdecode2.e.read_reg3.data
119 operand1 = self.regfile.read_reg(r3_sel)
120 if r2_ok:
121 r2_sel = yield pdecode2.e.read_reg2.data
122 operand2 = self.regfile.read_reg(r2_sel)
123 if imm_ok:
124 operand2 = yield pdecode2.e.imm_data.data
125
126 inv_a = yield pdecode2.dec.op.inv_a
127 if inv_a:
128 operand1 = (~operand1) & ((1<<64)-1)
129
130 cry_in = yield pdecode2.dec.op.cry_in
131 if cry_in == CryIn.ONE.value:
132 carry = 1
133
134 result = self.execute_alu_op(operand1, operand2, internal_op,
135 carry=carry)
136 ro_ok = yield pdecode2.e.write_reg.ok
137 if ro_ok:
138 ro_sel = yield pdecode2.e.write_reg.data
139 self.regfile.write_reg(ro_sel, result)
140
141 def mem_op(self, pdecode2):
142 internal_op = yield pdecode2.dec.op.internal_op
143 addr_reg = yield pdecode2.e.read_reg1.data
144 addr = self.regfile.read_reg(addr_reg)
145
146 imm_ok = yield pdecode2.e.imm_data.ok
147 r2_ok = yield pdecode2.e.read_reg2.ok
148 width = yield pdecode2.e.data_len
149 if imm_ok:
150 imm = yield pdecode2.e.imm_data.data
151 addr += imm
152 elif r2_ok:
153 r2_sel = yield pdecode2.e.read_reg2.data
154 addr += self.regfile.read_reg(r2_sel)
155 if internal_op == InternalOp.OP_STORE.value:
156 val_reg = yield pdecode2.e.read_reg3.data
157 val = self.regfile.read_reg(val_reg)
158 self.mem_sim.st(addr, val, width)
159 elif internal_op == InternalOp.OP_LOAD.value:
160 dest_reg = yield pdecode2.e.write_reg.data
161 val = self.mem_sim.ld(addr, width)
162 self.regfile.write_reg(dest_reg, val)
163
164 def execute_op(self, pdecode2):
165 function = yield pdecode2.dec.op.function_unit
166 if function == Function.ALU.value:
167 yield from self.alu_op(pdecode2)
168 elif function == Function.LDST.value:
169 yield from self.mem_op(pdecode2)