From: Luke Kenneth Casson Leighton Date: Sat, 4 Jul 2020 12:22:09 +0000 (+0100) Subject: add spr main stage X-Git-Tag: div_pipeline~162^2~96 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=4dd9229ee40cf2ce3971bcb46a54d2037d976b9e;p=soc.git add spr main stage --- diff --git a/src/soc/fu/spr/main_stage.py b/src/soc/fu/spr/main_stage.py new file mode 100644 index 00000000..5786eff8 --- /dev/null +++ b/src/soc/fu/spr/main_stage.py @@ -0,0 +1,94 @@ +"""SPR Pipeline + +* https://bugs.libre-soc.org/show_bug.cgi?id=348 +* https://libre-soc.org/openpower/isa/sprset/ +""" + +from nmigen import (Module, Signal, Cat, Mux, Const, signed) +from nmutil.pipemodbase import PipeModBase +from nmutil.extend import exts +from soc.fu.spr.pipe_data import SPRInputData, SPROutputData +from soc.fu.branch.main_stage import br_ext +from soc.decoder.power_enums import InternalOp + +from soc.decoder.power_fields import DecodeFields +from soc.decoder.power_fieldsn import SignalBitRange + +def decode_spr_num(spr): + return Cat(spr[5:10], spr[0:5]) + + +class SPRMainStage(PipeModBase): + def __init__(self, pspec): + super().__init__(pspec, "main") + self.fields = DecodeFields(SignalBitRange, [self.i.ctx.op.insn]) + self.fields.create_specs() + + def ispec(self): + return SPRInputData(self.pspec) + + def ospec(self): + return SPROutputData(self.pspec) + + def elaborate(self, platform): + m = Module() + comb = m.d.comb + op = self.i.ctx.op + + # convenience variables + a_i, spr1_i, fast1_i = self.i.a, self.i.spr1, self.i.fast1 + so_i, ov_i, ca_i = self.i.xer_so, self.i.xer_ov, self.i.xer_ca + so_o, ov_o, ca_o = self.o.xer_so, self.o.xer_ov, self.o.xer_ca + o, spr1_o, fast1_o = self.o.o, self.o.spr1, self.o.fast1 + + # take copy of D-Form TO field + x_fields = self.fields.FormXFX + spr = Signal(x_fields.SPR[0:-1].shape()) + comb += spr.eq(decode_spr_num(i_fields.SPR[0:-1])) + + # TODO: some #defines for the bits n stuff. + with m.Switch(op.insn_type): + #### MTSPR #### + with m.Case(InternalOp.OP_MTSPR): + with m.Switch(spr): + # fast SPRs first + with m.Case(SPR.CTR, SPR.LR, SPR.TAR, SPR.SRR0, SPR.SRR1): + comb += fast1_o.data.eq(a_i) + comb += fast1_o.ok.eq(1) + # XER is constructed + with m.Case(SPR.XER): + # sticky + comb += so_o.data.eq(a_i[63-XER_bits['SO']]) + comb += so_o.ok.eq(1) + # overflow + comb += ov_o.data[0].eq(a_i[63-XER_bits['OV']]) + comb += ov_o.data[1].eq(a_i[63-XER_bits['OV32']]) + comb += ov_o.ok.eq(1) + # carry + comb += ca_o.data[0].eq(a_i[63-XER_bits['CA']]) + comb += ca_o.data[1].eq(a_i[63-XER_bits['CA32']]) + comb += ca_o.ok.eq(1) + # slow SPRs TODO + + # move from SPRs + with m.Case(InternalOp.OP_MFSPR): + comb += o.ok.eq(1) + with m.Switch(spr): + # fast SPRs first + with m.Case(SPR.CTR, SPR.LR, SPR.TAR, SPR.SRR0, SPR.SRR1): + comb += o.data.eq(fast1_i) + # XER is constructed + with m.Case(SPR.XER): + # sticky + comb += o[63-XER_bits['SO']].eq(so_i) + # overflow + comb += o[63-XER_bits['OV']].eq(ov_i[0]) + comb += o[63-XER_bits['OV32']].eq(ov_i[1]) + # carry + comb += o[63-XER_bits['CA']].eq(ca_i[0]) + comb += o[63-XER_bits['CA32']].eq(ca_i[1]) + # slow SPRs TODO + + comb += self.o.ctx.eq(self.i.ctx) + + return m diff --git a/src/soc/fu/spr/pipe_data.py b/src/soc/fu/spr/pipe_data.py index 48439200..1054b147 100644 --- a/src/soc/fu/spr/pipe_data.py +++ b/src/soc/fu/spr/pipe_data.py @@ -16,7 +16,7 @@ from soc.fu.spr.spr_input_record import CompSPROpSubset class SPRInputData(IntegerData): regspec = [('INT', 'ra', '0:63'), # RA ('SPR', 'spr1', '0:63'), # SPR (slow) - ('FAST', 'spr2', '0:63'), # SPR (fast: MSR, LR, CTR etc) + ('FAST', 'fast1', '0:63'), # SPR (fast: MSR, LR, CTR etc) ('XER', 'xer_so', '32'), # XER bit 32: SO ('XER', 'xer_ov', '33,44'), # XER bit 34/45: CA/CA32 ('XER', 'xer_ca', '34,45')] # bit0: ov, bit1: ov32 @@ -29,7 +29,7 @@ class SPRInputData(IntegerData): class SPROutputData(IntegerData): regspec = [('INT', 'o', '0:63'), # RT ('SPR', 'spr1', '0:63'), # SPR (slow) - ('FAST', 'spr2', '0:63'), # SPR (fast: MSR, LR, CTR etc) + ('FAST', 'fast1', '0:63'), # SPR (fast: MSR, LR, CTR etc) ('XER', 'xer_so', '32'), # XER bit 32: SO ('XER', 'xer_ov', '33,44'), # XER bit 34/45: CA/CA32 ('XER', 'xer_ca', '34,45')] # bit0: ov, bit1: ov32