3345c6b7a4a7dee9370ce38d30c16e749cb651bf
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()):
81 class InternalOpSimulator
:
83 self
.mem_sim
= MemorySim()
84 self
.regfile
= RegFile()
86 def execute_alu_op(self
, op1
, op2
, internal_op
):
88 if internal_op
== InternalOp
.OP_ADD
.value
:
90 elif internal_op
== InternalOp
.OP_AND
.value
:
92 elif internal_op
== InternalOp
.OP_OR
.value
:
95 assert False, "Not implemented"
97 def alu_op(self
, pdecode2
):
98 internal_op
= yield pdecode2
.dec
.op
.internal_op
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
107 r1_sel
= yield pdecode2
.e
.read_reg1
.data
108 operand1
= self
.regfile
.read_reg(r1_sel
)
110 r3_sel
= yield pdecode2
.e
.read_reg3
.data
111 operand1
= self
.regfile
.read_reg(r3_sel
)
113 r2_sel
= yield pdecode2
.e
.read_reg2
.data
114 operand2
= self
.regfile
.read_reg(r2_sel
)
116 operand2
= yield pdecode2
.e
.imm_data
.data
118 result
= self
.execute_alu_op(operand1
, operand2
, internal_op
)
119 ro_ok
= yield pdecode2
.e
.write_reg
.ok
121 ro_sel
= yield pdecode2
.e
.write_reg
.data
122 self
.regfile
.write_reg(ro_sel
, result
)
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
)
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
133 imm
= yield pdecode2
.e
.imm_data
.data
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
)
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
)