d3da831f28c1d7afb397bd6b67bdd7e1db1aa875
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)
65 with m
.Case(SPR
.CTR
, SPR
.LR
, SPR
.TAR
, SPR
.SRR0
,
66 SPR
.SRR1
, SPR
.XER
, SPR
.DEC
, SPR
.TB
):
67 comb
+= fast1_o
.data
.eq(a_i
)
68 comb
+= fast1_o
.ok
.eq(1)
70 with m
.If(spr
== SPR
.XER
):
72 comb
+= so_o
.data
.eq(a_i
[63-XER_bits
['SO']])
75 comb
+= ov_o
.data
[0].eq(a_i
[63-XER_bits
['OV']])
76 comb
+= ov_o
.data
[1].eq(a_i
[63-XER_bits
['OV32']])
79 comb
+= ca_o
.data
[0].eq(a_i
[63-XER_bits
['CA']])
80 comb
+= ca_o
.data
[1].eq(a_i
[63-XER_bits
['CA32']])
85 comb
+= spr1_o
.data
.eq(a_i
)
86 comb
+= spr1_o
.ok
.eq(1)
89 with m
.Case(MicrOp
.OP_MFSPR
):
93 with m
.Case(SPR
.DEC
, SPR
.TB
):
94 comb
+= o
.data
.eq(fast1_i
)
97 with m
.Case(SPR
.CTR
, SPR
.LR
, SPR
.TAR
, SPR
.SRR0
, SPR
.SRR1
,
99 comb
+= o
.data
.eq(fast1_i
)
100 with m
.If(spr
== SPR
.XER
):
101 # bits 0:31 and 35:43 are treated as reserved
102 # and return 0s when read using mfxer
103 comb
+= o
[32:64].eq(0) # MBS0 bits 0-31
104 comb
+= o
[63-43:64-35].eq(0) # MSB0 bits 35-43
106 comb
+= o
[63-XER_bits
['SO']].eq(so_i
)
108 comb
+= o
[63-XER_bits
['OV']].eq(ov_i
[0])
109 comb
+= o
[63-XER_bits
['OV32']].eq(ov_i
[1])
111 comb
+= o
[63-XER_bits
['CA']].eq(ca_i
[0])
112 comb
+= o
[63-XER_bits
['CA32']].eq(ca_i
[1])
113 with m
.Case(SPR
.TBU
):
114 comb
+= o
.data
[0:32].eq(fast1_i
[32:64])
118 comb
+= o
.data
.eq(spr1_i
)
120 comb
+= self
.o
.ctx
.eq(self
.i
.ctx
)