3 * https://bugs.libre-soc.org/show_bug.cgi?id=348
4 * https://libre-soc.org/openpower/isa/sprset/
7 from nmigen
import (Module
, Signal
, Cat
)
8 from nmutil
.pipemodbase
import PipeModBase
9 from soc
.fu
.spr
.pipe_data
import SPRInputData
, SPROutputData
10 from soc
.decoder
.power_enums
import MicrOp
, SPR
, XER_bits
12 from soc
.decoder
.power_fields
import DecodeFields
13 from soc
.decoder
.power_fieldsn
import SignalBitRange
14 from soc
.decoder
.power_decoder2
import decode_spr_num
17 class SPRMainStage(PipeModBase
):
18 def __init__(self
, pspec
):
19 super().__init
__(pspec
, "spr_main")
20 self
.fields
= DecodeFields(SignalBitRange
, [self
.i
.ctx
.op
.insn
])
21 self
.fields
.create_specs()
24 return SPRInputData(self
.pspec
)
27 return SPROutputData(self
.pspec
)
29 def elaborate(self
, platform
):
34 # convenience variables
35 a_i
, spr1_i
, fast1_i
= self
.i
.a
, self
.i
.spr1
, self
.i
.fast1
36 so_i
, ov_i
, ca_i
= self
.i
.xer_so
, self
.i
.xer_ov
, self
.i
.xer_ca
37 so_o
, ov_o
, ca_o
= self
.o
.xer_so
, self
.o
.xer_ov
, self
.o
.xer_ca
38 o
, spr1_o
, fast1_o
= self
.o
.o
, self
.o
.spr1
, self
.o
.fast1
39 state_i
, state_o
= self
.i
.state
, self
.o
.state
41 # take copy of D-Form TO field
42 x_fields
= self
.fields
.FormXFX
43 spr
= Signal(len(x_fields
.SPR
))
44 comb
+= spr
.eq(decode_spr_num(x_fields
.SPR
))
46 # TODO: some #defines for the bits n stuff.
47 with m
.Switch(op
.insn_type
):
49 with m
.Case(MicrOp
.OP_MTSPR
):
52 with m
.Case(SPR
.CTR
, SPR
.LR
, SPR
.TAR
, SPR
.SRR0
,
54 comb
+= fast1_o
.data
.eq(a_i
)
55 comb
+= fast1_o
.ok
.eq(1)
57 with m
.If(spr
== SPR
.XER
):
59 comb
+= so_o
.data
.eq(a_i
[63-XER_bits
['SO']])
62 comb
+= ov_o
.data
[0].eq(a_i
[63-XER_bits
['OV']])
63 comb
+= ov_o
.data
[1].eq(a_i
[63-XER_bits
['OV32']])
66 comb
+= ca_o
.data
[0].eq(a_i
[63-XER_bits
['CA']])
67 comb
+= ca_o
.data
[1].eq(a_i
[63-XER_bits
['CA32']])
69 # STATE SPRs (dec, tb)
71 comb
+= state_o
.data
.eq(a_i
)
72 comb
+= state_o
.ok
.eq(1)
77 with m
.Case(MicrOp
.OP_MFSPR
):
81 with m
.Case(SPR
.CTR
, SPR
.LR
, SPR
.TAR
, SPR
.SRR0
, SPR
.SRR1
,
83 comb
+= o
.data
.eq(fast1_i
)
84 with m
.If(spr
== SPR
.XER
):
85 # bits 0:31 and 35:43 are treated as reserved
86 # and return 0s when read using mfxer
87 comb
+= o
[32:64].eq(0) # MBS0 bits 0-31
88 comb
+= o
[63-43:64-35].eq(0) # MSB0 bits 35-43
90 comb
+= o
[63-XER_bits
['SO']].eq(so_i
)
92 comb
+= o
[63-XER_bits
['OV']].eq(ov_i
[0])
93 comb
+= o
[63-XER_bits
['OV32']].eq(ov_i
[1])
95 comb
+= o
[63-XER_bits
['CA']].eq(ca_i
[0])
96 comb
+= o
[63-XER_bits
['CA32']].eq(ca_i
[1])
97 # STATE SPRs (dec, tb)
98 with m
.Case(SPR
.DEC
, SPR
.TB
):
99 comb
+= o
.data
.eq(state_i
)
100 with m
.Case(SPR
.TBU
):
101 comb
+= o
.data
[0:32].eq(state_i
[32:64])
105 comb
+= self
.o
.ctx
.eq(self
.i
.ctx
)