1 from soc
.decoder
.power_enums
import (Function
, Form
, InternalOp
,
2 In1Sel
, In2Sel
, In3Sel
, OutSel
,
3 RC
, LdstLen
, CryIn
, get_csv
,
5 get_signal_name
, default_values
)
10 def __init__(self
, bytes_per_word
=8):
12 self
.bytes_per_word
= bytes_per_word
13 self
.word_log2
= math
.ceil(math
.log2(bytes_per_word
))
15 def _get_shifter_mask(self
, width
, remainder
):
16 shifter
= ((self
.bytes_per_word
- width
) - remainder
) * \
18 mask
= (1 << (width
* 8)) - 1
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
]
31 if width
!= self
.bytes_per_word
:
32 shifter
, mask
= self
._get
_shifter
_mask
(width
, remainder
)
33 val
= val
& (mask
<< shifter
)
35 print("Read {:x} from addr {:x}".format(val
, address
))
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
]
48 shifter
, mask
= self
._get
_shifter
_mask
(width
, remainder
)
49 val
&= ~
(mask
<< shifter
)
50 val |
= value
<< shifter
51 self
.mem
[address
] = val
53 self
.mem
[address
] = value
58 self
.regfile
= [0] * 32
61 def write_reg(self
, regnum
, value
):
62 all1s
= (1 << 64)-1 # 64 bits worth of 1s
64 print("Writing {:x} to reg r{}".format(value
, regnum
))
65 self
.regfile
[regnum
] = value
67 def read_reg(self
, regnum
):
68 val
= self
.regfile
[regnum
]
69 print("Read {:x} from reg r{}".format(val
, regnum
))
72 def assert_gpr(self
, gpr
, val
):
73 reg_val
= self
.read_reg(gpr
)
74 msg
= "reg r{} got {:x}, expecting {:x}".format(
76 assert reg_val
== val
, msg
78 def assert_gprs(self
, gprs
):
79 for k
, v
in list(gprs
.items()):
82 def set_xer(self
, result
, operanda
, operandb
):
90 class InternalOpSimulator
:
92 self
.mem_sim
= MemorySim()
93 self
.regfile
= RegFile()
95 def execute_alu_op(self
, op1
, op2
, internal_op
, carry
=0):
97 if internal_op
== InternalOp
.OP_ADD
.value
:
98 return op1
+ op2
+ carry
99 elif internal_op
== InternalOp
.OP_AND
.value
:
101 elif internal_op
== InternalOp
.OP_OR
.value
:
103 elif internal_op
== InternalOp
.OP_MUL_L64
.value
:
106 assert False, "Not implemented"
108 def update_cr0(self
, result
):
115 print("update_cr0", self
.cr0
)
117 def alu_op(self
, pdecode2
):
118 all1s
= (1 << 64)-1 # 64 bits worth of 1s
119 internal_op
= yield pdecode2
.dec
.op
.internal_op
124 r1_ok
= yield pdecode2
.e
.read_reg1
.ok
125 r2_ok
= yield pdecode2
.e
.read_reg2
.ok
126 r3_ok
= yield pdecode2
.e
.read_reg3
.ok
127 imm_ok
= yield pdecode2
.e
.imm_data
.ok
129 r1_sel
= yield pdecode2
.e
.read_reg1
.data
130 operand1
= self
.regfile
.read_reg(r1_sel
)
132 r3_sel
= yield pdecode2
.e
.read_reg3
.data
133 operand1
= self
.regfile
.read_reg(r3_sel
)
135 r2_sel
= yield pdecode2
.e
.read_reg2
.data
136 operand2
= self
.regfile
.read_reg(r2_sel
)
138 operand2
= yield pdecode2
.e
.imm_data
.data
140 inv_a
= yield pdecode2
.dec
.op
.inv_a
142 operand1
= (~operand1
) & all1s
144 cry_in
= yield pdecode2
.dec
.op
.cry_in
145 if cry_in
== CryIn
.ONE
.value
:
147 elif cry_in
== CryIn
.CA
.value
:
148 carry
= self
.carry_out
150 # TODO rc_sel = yield pdecode2.dec.op.rc_sel
151 result
= self
.execute_alu_op(operand1
, operand2
, internal_op
,
154 cry_out
= yield pdecode2
.dec
.op
.cry_out
155 rc
= yield pdecode2
.e
.rc
.data
158 self
.update_cr0(result
)
160 self
.carry_out
= (result
>> 64)
161 print("setting carry_out", self
.carry_out
)
163 ro_ok
= yield pdecode2
.e
.write_reg
.ok
165 ro_sel
= yield pdecode2
.e
.write_reg
.data
166 self
.regfile
.write_reg(ro_sel
, result
)
168 def mem_op(self
, pdecode2
):
169 internal_op
= yield pdecode2
.dec
.op
.internal_op
170 addr_reg
= yield pdecode2
.e
.read_reg1
.data
171 addr
= self
.regfile
.read_reg(addr_reg
)
173 imm_ok
= yield pdecode2
.e
.imm_data
.ok
174 r2_ok
= yield pdecode2
.e
.read_reg2
.ok
175 width
= yield pdecode2
.e
.data_len
177 imm
= yield pdecode2
.e
.imm_data
.data
180 r2_sel
= yield pdecode2
.e
.read_reg2
.data
181 addr
+= self
.regfile
.read_reg(r2_sel
)
182 if internal_op
== InternalOp
.OP_STORE
.value
:
183 val_reg
= yield pdecode2
.e
.read_reg3
.data
184 val
= self
.regfile
.read_reg(val_reg
)
185 self
.mem_sim
.st(addr
, val
, width
)
186 elif internal_op
== InternalOp
.OP_LOAD
.value
:
187 dest_reg
= yield pdecode2
.e
.write_reg
.data
188 val
= self
.mem_sim
.ld(addr
, width
)
189 self
.regfile
.write_reg(dest_reg
, val
)
191 def execute_op(self
, pdecode2
):
192 function
= yield pdecode2
.dec
.op
.function_unit
193 if function
== Function
.ALU
.value
:
194 yield from self
.alu_op(pdecode2
)
195 elif function
== Function
.LDST
.value
:
196 yield from self
.mem_op(pdecode2
)