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
, SPRfull
, SPRreduced
, 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 # 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
48 # take copy of D-Form TO field
49 x_fields
= self
.fields
.FormXFX
50 spr
= Signal(len(x_fields
.SPR
))
51 comb
+= spr
.eq(decode_spr_num(x_fields
.SPR
))
53 # TODO: some #defines for the bits n stuff.
54 with m
.Switch(op
.insn_type
):
56 with m
.Case(MicrOp
.OP_MTSPR
):
59 with m
.Case(SPR
.CTR
, SPR
.LR
, SPR
.TAR
, SPR
.SRR0
,
60 SPR
.SRR1
, SPR
.XER
, SPR
.DEC
):
61 comb
+= fast1_o
.data
.eq(a_i
)
62 comb
+= fast1_o
.ok
.eq(1)
64 with m
.If(spr
== SPR
.XER
):
66 comb
+= so_o
.data
.eq(a_i
[63-XER_bits
['SO']])
69 comb
+= ov_o
.data
[0].eq(a_i
[63-XER_bits
['OV']])
70 comb
+= ov_o
.data
[1].eq(a_i
[63-XER_bits
['OV32']])
73 comb
+= ca_o
.data
[0].eq(a_i
[63-XER_bits
['CA']])
74 comb
+= ca_o
.data
[1].eq(a_i
[63-XER_bits
['CA32']])
79 comb
+= spr1_o
.data
.eq(a_i
)
80 comb
+= spr1_o
.ok
.eq(1)
83 with m
.Case(MicrOp
.OP_MFSPR
):
87 with m
.Case(SPR
.CTR
, SPR
.LR
, SPR
.TAR
, SPR
.SRR0
, SPR
.SRR1
,
88 SPR
.XER
, SPR
.DEC
, SPR
.TB
):
89 comb
+= o
.data
.eq(fast1_i
)
90 with m
.If(spr
== SPR
.XER
):
91 # bits 0:31 and 35:43 are treated as reserved
92 # and return 0s when read using mfxer
93 comb
+= o
[32:64].eq(0) # MBS0 bits 0-31
94 comb
+= o
[63-43:64-35].eq(0) # MSB0 bits 35-43
96 comb
+= o
[63-XER_bits
['SO']].eq(so_i
)
98 comb
+= o
[63-XER_bits
['OV']].eq(ov_i
[0])
99 comb
+= o
[63-XER_bits
['OV32']].eq(ov_i
[1])
101 comb
+= o
[63-XER_bits
['CA']].eq(ca_i
[0])
102 comb
+= o
[63-XER_bits
['CA32']].eq(ca_i
[1])
103 with m
.Case(SPR
.TBU
):
104 comb
+= o
.data
[0:32].eq(fast1_i
[32:64])
108 comb
+= o
.data
.eq(spr1_i
)
110 comb
+= self
.o
.ctx
.eq(self
.i
.ctx
)