c794e591fbdf5f0760bf210a30b7061293eba536
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 print("Writing {:x} to reg r{}".format(value
, regnum
))
63 self
.regfile
[regnum
] = value
65 def read_reg(self
, regnum
):
66 val
= self
.regfile
[regnum
]
67 print("Read {:x} from reg r{}".format(val
, regnum
))
70 def assert_gpr(self
, gpr
, val
):
71 reg_val
= self
.read_reg(gpr
)
72 msg
= "reg r{} got {:x}, expecting {:x}".format(
74 assert reg_val
== val
, msg
76 def assert_gprs(self
, gprs
):
77 for k
, v
in list(gprs
.items()):
80 def set_xer(self
, result
, operanda
, operandb
):
88 class InternalOpSimulator
:
90 self
.mem_sim
= MemorySim()
91 self
.regfile
= RegFile()
93 def execute_alu_op(self
, op1
, op2
, internal_op
, carry
=0):
95 if internal_op
== InternalOp
.OP_ADD
.value
:
96 return op1
+ op2
+ carry
97 elif internal_op
== InternalOp
.OP_AND
.value
:
99 elif internal_op
== InternalOp
.OP_OR
.value
:
102 assert False, "Not implemented"
104 def alu_op(self
, pdecode2
):
105 internal_op
= yield pdecode2
.dec
.op
.internal_op
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
115 r1_sel
= yield pdecode2
.e
.read_reg1
.data
116 operand1
= self
.regfile
.read_reg(r1_sel
)
118 r3_sel
= yield pdecode2
.e
.read_reg3
.data
119 operand1
= self
.regfile
.read_reg(r3_sel
)
121 r2_sel
= yield pdecode2
.e
.read_reg2
.data
122 operand2
= self
.regfile
.read_reg(r2_sel
)
124 operand2
= yield pdecode2
.e
.imm_data
.data
126 inv_a
= yield pdecode2
.dec
.op
.inv_a
128 operand1
= (~operand1
) & ((1<<64)-1)
130 cry_in
= yield pdecode2
.dec
.op
.cry_in
131 if cry_in
== CryIn
.ONE
.value
:
134 result
= self
.execute_alu_op(operand1
, operand2
, internal_op
,
136 ro_ok
= yield pdecode2
.e
.write_reg
.ok
138 ro_sel
= yield pdecode2
.e
.write_reg
.data
139 self
.regfile
.write_reg(ro_sel
, result
)
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
)
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
150 imm
= yield pdecode2
.e
.imm_data
.data
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
)
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
)