1 from soc
.decoder
.power_enums
import (Function
, Form
, InternalOp
,
2 In1Sel
, In2Sel
, In3Sel
, OutSel
, RC
, LdstLen
,
3 CryIn
, get_csv
, single_bit_flags
,
4 get_signal_name
, default_values
)
9 def __init__(self
, bytes_per_word
=8):
11 self
.bytes_per_word
= bytes_per_word
12 self
.word_log2
= math
.ceil(math
.log2(bytes_per_word
))
14 def _get_shifter_mask(self
, width
, remainder
):
15 shifter
= ((self
.bytes_per_word
- width
) - remainder
) * \
17 mask
= (1 << (width
* 8)) - 1
20 # TODO: Implement ld/st of lesser width
21 def ld(self
, address
, width
=8):
22 remainder
= address
& (self
.bytes_per_word
- 1)
23 address
= address
>> self
.word_log2
24 assert remainder
& (width
- 1) == 0, "Unaligned access unsupported!"
25 if address
in self
.mem
:
26 val
= self
.mem
[address
]
30 if width
!= self
.bytes_per_word
:
31 shifter
, mask
= self
._get
_shifter
_mask
(width
, remainder
)
32 val
= val
& (mask
<< shifter
)
34 print("Read {:x} from addr {:x}".format(val
, address
))
37 def st(self
, address
, value
, width
=8):
38 remainder
= address
& (self
.bytes_per_word
- 1)
39 address
= address
>> self
.word_log2
40 assert remainder
& (width
- 1) == 0, "Unaligned access unsupported!"
41 print("Writing {:x} to addr {:x}".format(value
, address
))
42 if width
!= self
.bytes_per_word
:
43 if address
in self
.mem
:
44 val
= self
.mem
[address
]
47 shifter
, mask
= self
._get
_shifter
_mask
(width
, remainder
)
48 val
&= ~
(mask
<< shifter
)
49 val |
= value
<< shifter
50 self
.mem
[address
] = val
52 self
.mem
[address
] = value
57 self
.regfile
= [0] * 32
60 def write_reg(self
, regnum
, value
):
61 print("Writing {:x} to reg r{}".format(value
, regnum
))
62 self
.regfile
[regnum
] = value
64 def read_reg(self
, regnum
):
65 val
= self
.regfile
[regnum
]
66 print("Read {:x} from reg r{}".format(val
, regnum
))
69 def assert_gprs(self
, gprs
):
70 for k
,v
in list(gprs
.items()):
71 reg_val
= self
.read_reg(k
)
72 msg
= "reg r{} got {:x}, expecting {:x}".format(
74 assert reg_val
== v
, msg
77 class InternalOpSimulator
:
79 self
.mem_sim
= MemorySim()
80 self
.regfile
= RegFile()
82 def execute_alu_op(self
, op1
, op2
, internal_op
):
84 if internal_op
== InternalOp
.OP_ADD
.value
:
86 elif internal_op
== InternalOp
.OP_AND
.value
:
88 elif internal_op
== InternalOp
.OP_OR
.value
:
91 assert False, "Not implemented"
93 def alu_op(self
, pdecode2
):
94 internal_op
= yield pdecode2
.dec
.op
.internal_op
98 r1_ok
= yield pdecode2
.e
.read_reg1
.ok
99 r2_ok
= yield pdecode2
.e
.read_reg2
.ok
100 r3_ok
= yield pdecode2
.e
.read_reg3
.ok
101 imm_ok
= yield pdecode2
.e
.imm_data
.ok
103 r1_sel
= yield pdecode2
.e
.read_reg1
.data
104 operand1
= self
.regfile
.read_reg(r1_sel
)
106 r3_sel
= yield pdecode2
.e
.read_reg3
.data
107 operand1
= self
.regfile
.read_reg(r3_sel
)
109 r2_sel
= yield pdecode2
.e
.read_reg2
.data
110 operand2
= self
.regfile
.read_reg(r2_sel
)
112 operand2
= yield pdecode2
.e
.imm_data
.data
114 result
= self
.execute_alu_op(operand1
, operand2
, internal_op
)
115 ro_ok
= yield pdecode2
.e
.write_reg
.ok
117 ro_sel
= yield pdecode2
.e
.write_reg
.data
118 self
.regfile
.write_reg(ro_sel
, result
)
120 def mem_op(self
, pdecode2
):
121 internal_op
= yield pdecode2
.dec
.op
.internal_op
122 addr_reg
= yield pdecode2
.e
.read_reg1
.data
123 addr
= self
.regfile
.read_reg(addr_reg
)
125 imm_ok
= yield pdecode2
.e
.imm_data
.ok
126 r2_ok
= yield pdecode2
.e
.read_reg2
.ok
127 width
= yield pdecode2
.e
.data_len
129 imm
= yield pdecode2
.e
.imm_data
.data
132 r2_sel
= yield pdecode2
.e
.read_reg2
.data
133 addr
+= self
.regfile
.read_reg(r2_sel
)
134 if internal_op
== InternalOp
.OP_STORE
.value
:
135 val_reg
= yield pdecode2
.e
.read_reg3
.data
136 val
= self
.regfile
.read_reg(val_reg
)
137 self
.mem_sim
.st(addr
, val
, width
)
138 elif internal_op
== InternalOp
.OP_LOAD
.value
:
139 dest_reg
= yield pdecode2
.e
.write_reg
.data
140 val
= self
.mem_sim
.ld(addr
, width
)
141 self
.regfile
.write_reg(dest_reg
, val
)
144 def execute_op(self
, pdecode2
):
145 function
= yield pdecode2
.dec
.op
.function_unit
146 if function
== Function
.ALU
.value
:
147 yield from self
.alu_op(pdecode2
)
148 elif function
== Function
.LDST
.value
:
149 yield from self
.mem_op(pdecode2
)