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 openpower
.decoder
.power_enums
import MicrOp
, SPRfull
, SPRreduced
, XER_bits
12 from openpower
.decoder
.power_fields
import DecodeFields
13 from openpower
.decoder
.power_fieldsn
import SignalBitRange
14 from openpower
.decoder
.power_decoder2
import decode_spr_num
17 class SPRMainStage(PipeModBase
):
18 def __init__(self
, pspec
):
19 super().__init
__(pspec
, "spr_main")
20 # test if regfiles are reduced
21 self
.regreduce_en
= (hasattr(pspec
, "regreduce") and
22 (pspec
.regreduce
== True))
24 self
.fields
= DecodeFields(SignalBitRange
, [self
.i
.ctx
.op
.insn
])
25 self
.fields
.create_specs()
28 return SPRInputData(self
.pspec
)
31 return SPROutputData(self
.pspec
)
33 def elaborate(self
, platform
):
42 # convenience variables
43 a_i
, spr1_i
, fast1_i
= self
.i
.a
, self
.i
.spr1
, self
.i
.fast1
44 so_i
, ov_i
, ca_i
= self
.i
.xer_so
, self
.i
.xer_ov
, self
.i
.xer_ca
45 so_o
, ov_o
, ca_o
= self
.o
.xer_so
, self
.o
.xer_ov
, self
.o
.xer_ca
46 o
, spr1_o
, fast1_o
= self
.o
.o
, self
.o
.spr1
, self
.o
.fast1
47 state1_i
, state1_o
= self
.i
.state1
, self
.o
.state1
49 # take copy of D-Form TO field
50 x_fields
= self
.fields
.FormXFX
51 spr
= Signal(len(x_fields
.SPR
))
52 comb
+= spr
.eq(decode_spr_num(x_fields
.SPR
))
54 # TODO: some #defines for the bits n stuff.
55 with m
.Switch(op
.insn_type
):
57 with m
.Case(MicrOp
.OP_MTSPR
):
60 with m
.Case(SPR
.DEC
, SPR
.TB
):
61 comb
+= state1_o
.data
.eq(a_i
)
62 comb
+= state1_o
.ok
.eq(1)
64 # Fast SPRs second: anything in FAST regs
65 with m
.Case(SPR
.CTR
, SPR
.LR
, SPR
.TAR
, SPR
.SRR0
,
66 SPR
.SRR1
, SPR
.XER
, SPR
.HSRR0
, SPR
.HSRR1
,
67 SPR
.SPRG0_priv
, SPR
.SPRG1_priv
,
68 SPR
.SPRG2_priv
, SPR
.SPRG3
,
69 SPR
.HSPRG0
, SPR
.HSPRG1
, SPR
.SVSRR0
):
70 comb
+= fast1_o
.data
.eq(a_i
)
71 comb
+= fast1_o
.ok
.eq(1)
73 with m
.If(spr
== SPR
.XER
):
75 comb
+= so_o
.data
.eq(a_i
[63-XER_bits
['SO']])
78 comb
+= ov_o
.data
[0].eq(a_i
[63-XER_bits
['OV']])
79 comb
+= ov_o
.data
[1].eq(a_i
[63-XER_bits
['OV32']])
82 comb
+= ca_o
.data
[0].eq(a_i
[63-XER_bits
['CA']])
83 comb
+= ca_o
.data
[1].eq(a_i
[63-XER_bits
['CA32']])
88 comb
+= spr1_o
.data
.eq(a_i
)
89 comb
+= spr1_o
.ok
.eq(1)
92 with m
.Case(MicrOp
.OP_MFSPR
):
96 with m
.Case(SPR
.DEC
, SPR
.TB
):
97 comb
+= o
.data
.eq(state1_i
)
98 # TBU is upper 32-bits of State Reg
100 comb
+= o
.data
[0:32].eq(state1_i
[32:64])
103 with m
.Case(SPR
.CTR
, SPR
.LR
, SPR
.TAR
, SPR
.SRR0
,
104 SPR
.SRR1
, SPR
.XER
, SPR
.HSRR0
, SPR
.HSRR1
,
105 SPR
.SPRG0_priv
, SPR
.SPRG1_priv
,
106 SPR
.SPRG2_priv
, SPR
.SPRG3
,
107 SPR
.HSPRG0
, SPR
.HSPRG1
, SPR
.SVSRR0
):
108 comb
+= o
.data
.eq(fast1_i
)
109 with m
.If(spr
== SPR
.XER
):
110 # bits 0:31 and 35:43 are treated as reserved
111 # and return 0s when read using mfxer
112 comb
+= o
[32:64].eq(0) # MBS0 bits 0-31
113 comb
+= o
[63-43:64-35].eq(0) # MSB0 bits 35-43
115 comb
+= o
[63-XER_bits
['SO']].eq(so_i
)
117 comb
+= o
[63-XER_bits
['OV']].eq(ov_i
[0])
118 comb
+= o
[63-XER_bits
['OV32']].eq(ov_i
[1])
120 comb
+= o
[63-XER_bits
['CA']].eq(ca_i
[0])
121 comb
+= o
[63-XER_bits
['CA32']].eq(ca_i
[1])
124 comb
+= o
.data
.eq(spr1_i
)
126 comb
+= self
.o
.ctx
.eq(self
.i
.ctx
)