From 0393443405f5b9b286a5ed3b7d8bffbcc8efc526 Mon Sep 17 00:00:00 2001 From: Luke Kenneth Casson Leighton Date: Sun, 31 Jan 2021 15:28:02 +0000 Subject: [PATCH] move SVP64 Extra reg decoding into main PowerDecoder module --- src/soc/decoder/power_decoder2.py | 167 ++++++++++++------------------ 1 file changed, 66 insertions(+), 101 deletions(-) diff --git a/src/soc/decoder/power_decoder2.py b/src/soc/decoder/power_decoder2.py index 7c435ca2..b8b35285 100644 --- a/src/soc/decoder/power_decoder2.py +++ b/src/soc/decoder/power_decoder2.py @@ -221,11 +221,9 @@ class DecodeA(Elaboratable): def __init__(self, dec): self.dec = dec - self.sv_rm = SVP64Rec() # SVP64 RM field self.sel_in = Signal(In1Sel, reset_less=True) self.insn_in = Signal(32, reset_less=True) - self.reg_out = Data(7, name="reg_a") - self.reg_isvec = Signal(1, name="reg_a_isvec") # TODO: in reg_out + self.reg_out = Data(5, name="reg_a") self.spr_out = Data(SPR, "spr_a") self.fast_out = Data(3, "fast_a") @@ -233,11 +231,8 @@ class DecodeA(Elaboratable): m = Module() comb = m.d.comb op = self.dec.op + reg = self.reg_out m.submodules.sprmap = sprmap = SPRMap() - m.submodules.svdec = svdec = SVP64RegExtra() - - # get the 5-bit reg data before svp64-munging it into 7-bit plus isvec - reg = Signal(5, reset_less=True) # select Register A field ra = Signal(5, reset_less=True) @@ -245,30 +240,16 @@ class DecodeA(Elaboratable): with m.If((self.sel_in == In1Sel.RA) | ((self.sel_in == In1Sel.RA_OR_ZERO) & (ra != Const(0, 5)))): - comb += reg.eq(ra) - comb += self.reg_out.ok.eq(1) + comb += reg.data.eq(ra) + comb += reg.ok.eq(1) # some Logic/ALU ops have RS as the 3rd arg, but no "RA". # moved it to 1st position (in1_sel)... because rs = Signal(5, reset_less=True) comb += rs.eq(self.dec.RS) with m.If(self.sel_in == In1Sel.RS): - comb += reg.eq(rs) - comb += self.reg_out.ok.eq(1) - - # now do the SVP64 munging. op.SV_Etype and op.sv_in1 comes from - # PowerDecoder which in turn comes from LDST-RM*.csv and RM-*.csv - # which in turn were auto-generated by sv_analysis.py - - extra = self.sv_rm.extra # SVP64 extra bits 10:18 - comb += svdec.extra.eq(extra) # EXTRA field of SVP64 RM - comb += svdec.etype.eq(op.SV_Etype) # EXTRA2/3 for this insn - comb += svdec.idx.eq(op.sv_in1) # SVP64 reg #1 (matches in1_sel) - comb += svdec.reg_in.eq(reg) # 5-bit (RA, RS) - - # outputs: 7-bit reg number and whether it's vectorised - comb += self.reg_out.data.eq(svdec.reg_out) - comb += self.reg_isvec.eq(svdec.isvec) + comb += reg.data.eq(rs) + comb += reg.ok.eq(1) # decode Fast-SPR based on instruction type with m.Switch(op.internal_op): @@ -334,7 +315,6 @@ class DecodeB(Elaboratable): def __init__(self, dec): self.dec = dec - self.sv_rm = SVP64Rec() # SVP64 RM field self.sel_in = Signal(In2Sel, reset_less=True) self.insn_in = Signal(32, reset_less=True) self.reg_out = Data(7, "reg_b") @@ -345,32 +325,17 @@ class DecodeB(Elaboratable): m = Module() comb = m.d.comb op = self.dec.op - m.submodules.svdec = svdec = SVP64RegExtra() - - # get the 5-bit reg data before svp64-munging it into 7-bit plus isvec - reg = Signal(5, reset_less=True) + reg = self.reg_out # select Register B field with m.Switch(self.sel_in): with m.Case(In2Sel.RB): - comb += reg.eq(self.dec.RB) - comb += self.reg_out.ok.eq(1) + comb += reg.data.eq(self.dec.RB) + comb += reg.ok.eq(1) with m.Case(In2Sel.RS): # for M-Form shiftrot - comb += reg.eq(self.dec.RS) - comb += self.reg_out.ok.eq(1) - - # now do the SVP64 munging. different from DecodeA only by sv_in2 - - extra = self.sv_rm.extra # SVP64 extra bits 10:18 - comb += svdec.extra.eq(extra) # EXTRA field of SVP64 RM - comb += svdec.etype.eq(op.SV_Etype) # EXTRA2/3 for this insn - comb += svdec.idx.eq(op.sv_in2) # SVP64 reg #2 (matches in2_sel) - comb += svdec.reg_in.eq(reg) # 5-bit (RA, RS) - - # outputs: 7-bit reg number and whether it's vectorised - comb += self.reg_out.data.eq(svdec.reg_out) - comb += self.reg_isvec.eq(svdec.isvec) + comb += reg.data.eq(self.dec.RS) + comb += reg.ok.eq(1) # decode SPR2 based on instruction type # BCREG implicitly uses LR or TAR for 2nd reg @@ -459,39 +424,23 @@ class DecodeC(Elaboratable): self.sv_rm = SVP64Rec() # SVP64 RM field self.sel_in = Signal(In3Sel, reset_less=True) self.insn_in = Signal(32, reset_less=True) - self.reg_out = Data(7, "reg_c") - self.reg_isvec = Signal(1, name="reg_c_isvec") # TODO: in reg_out + self.reg_out = Data(5, "reg_c") def elaborate(self, platform): m = Module() comb = m.d.comb op = self.dec.op - m.submodules.svdec = svdec = SVP64RegExtra() - - # get the 5-bit reg data before svp64-munging it into 7-bit plus isvec - reg = Signal(5, reset_less=True) + reg = self.reg_out # select Register C field with m.Switch(self.sel_in): with m.Case(In3Sel.RB): # for M-Form shiftrot - comb += reg.eq(self.dec.RB) - comb += self.reg_out.ok.eq(1) + comb += reg.data.eq(self.dec.RB) + comb += reg.ok.eq(1) with m.Case(In3Sel.RS): - comb += reg.eq(self.dec.RS) - comb += self.reg_out.ok.eq(1) - - # now do the SVP64 munging. different from DecodeA only by sv_in3 - - extra = self.sv_rm.extra # SVP64 extra bits 10:18 - comb += svdec.extra.eq(extra) # EXTRA field of SVP64 RM - comb += svdec.etype.eq(op.SV_Etype) # EXTRA2/3 for this insn - comb += svdec.idx.eq(op.sv_in3) # SVP64 reg #3 (matches in3_sel) - comb += svdec.reg_in.eq(reg) # 5-bit (RA, RS) - - # outputs: 7-bit reg number and whether it's vectorised - comb += self.reg_out.data.eq(svdec.reg_out) - comb += self.reg_isvec.eq(svdec.isvec) + comb += reg.data.eq(self.dec.RS) + comb += reg.ok.eq(1) return m @@ -507,8 +456,7 @@ class DecodeOut(Elaboratable): self.sv_rm = SVP64Rec() # SVP64 RM field self.sel_in = Signal(OutSel, reset_less=True) self.insn_in = Signal(32, reset_less=True) - self.reg_out = Data(7, "reg_o") - self.reg_isvec = Signal(1, name="reg_o_isvec") # TODO: in reg_out + self.reg_out = Data(5, "reg_o") self.spr_out = Data(SPR, "spr_o") self.fast_out = Data(3, "fast_o") @@ -517,19 +465,16 @@ class DecodeOut(Elaboratable): comb = m.d.comb m.submodules.sprmap = sprmap = SPRMap() op = self.dec.op - m.submodules.svdec = svdec = SVP64RegExtra() - - # get the 5-bit reg data before svp64-munging it into 7-bit plus isvec - reg = Signal(5, reset_less=True) + reg = self.reg_out # select Register out field with m.Switch(self.sel_in): with m.Case(OutSel.RT): - comb += reg.eq(self.dec.RT) - comb += self.reg_out.ok.eq(1) + comb += reg.data.eq(self.dec.RT) + comb += reg.ok.eq(1) with m.Case(OutSel.RA): - comb += reg.eq(self.dec.RA) - comb += self.reg_out.ok.eq(1) + comb += reg.data.eq(self.dec.RA) + comb += reg.ok.eq(1) with m.Case(OutSel.SPR): spr = Signal(10, reset_less=True) comb += spr.eq(decode_spr_num(self.dec.SPR)) # from XFX @@ -539,18 +484,6 @@ class DecodeOut(Elaboratable): comb += self.spr_out.eq(sprmap.spr_o) comb += self.fast_out.eq(sprmap.fast_o) - # now do the SVP64 munging. different from DecodeA only by sv_out - - extra = self.sv_rm.extra # SVP64 extra bits 10:18 - comb += svdec.extra.eq(extra) # EXTRA field of SVP64 RM - comb += svdec.etype.eq(op.SV_Etype) # EXTRA2/3 for this insn - comb += svdec.idx.eq(op.sv_out) # SVP64 reg out1 (matches out_sel) - comb += svdec.reg_in.eq(reg) # 5-bit (RA, RS) - - # outputs: 7-bit reg number and whether it's vectorised - comb += self.reg_out.data.eq(svdec.reg_out) - comb += self.reg_isvec.eq(svdec.isvec) - # determine Fast Reg with m.Switch(op.internal_op): @@ -589,8 +522,7 @@ class DecodeOut2(Elaboratable): self.sel_in = Signal(OutSel, reset_less=True) self.lk = Signal(reset_less=True) self.insn_in = Signal(32, reset_less=True) - self.reg_out = Data(7, "reg_o2") - #self.reg_isvec = Signal(1, name="reg_o2_isvec") # TODO: in reg_out + self.reg_out = Data(5, "reg_o2") self.fast_out = Data(3, "fast_o2") def elaborate(self, platform): @@ -1059,6 +991,11 @@ class PowerDecode2(PowerDecodeSubset): self.cr_in_isvec = Signal(1, name="cr_in_isvec") self.cr_in_b_isvec = Signal(1, name="cr_in_b_isvec") self.cr_in_o_isvec = Signal(1, name="cr_in_o_isvec") + self.in1_isvec = Signal(1, name="reg_a_isvec") + self.in2_isvec = Signal(1, name="reg_b_isvec") + self.in3_isvec = Signal(1, name="reg_c_isvec") + self.o_isvec = Signal(1, name="reg_o_isvec") + self.o2_isvec = Signal(1, name="reg_o2_isvec") def get_col_subset(self, opkls): subset = super().get_col_subset(opkls) @@ -1104,6 +1041,14 @@ class PowerDecode2(PowerDecodeSubset): m.submodules.crin_svdec = crin_svdec = SVP64CRExtra() m.submodules.crin_svdec_b = crin_svdec_b = SVP64CRExtra() m.submodules.crin_svdec_o = crin_svdec_o = SVP64CRExtra() + m.submodules.in1_svdec = in1_svdec = SVP64RegExtra() + m.submodules.in2_svdec = in2_svdec = SVP64RegExtra() + m.submodules.in3_svdec = in3_svdec = SVP64RegExtra() + m.submodules.o_svdec = o_svdec = SVP64RegExtra() + m.submodules.o2_svdec = o2_svdec = SVP64RegExtra() + + # get the 5-bit reg data before svp64-munging it into 7-bit plus isvec + reg = Signal(5, reset_less=True) # copy instruction through... for i in [do.insn, dec_a.insn_in, dec_b.insn_in, @@ -1115,7 +1060,9 @@ class PowerDecode2(PowerDecodeSubset): dec_c.insn_in, dec_o.insn_in, dec_o2.insn_in]: comb += i.eq(self.sv_rm) - # now do the SVP64 munging. + # now do the SVP64 munging. op.SV_Etype and op.sv_in1 comes from + # PowerDecoder which in turn comes from LDST-RM*.csv and RM-*.csv + # which in turn were auto-generated by sv_analysis.py extra = self.sv_rm.extra # SVP64 extra bits 10:18 ####### @@ -1128,7 +1075,7 @@ class PowerDecode2(PowerDecodeSubset): cr_a_idx = Signal(SVEXTRA) cr_b_idx = Signal(SVEXTRA) - # these change slighly, when decoding BA/BB. really should have + # these change slightly, when decoding BA/BB. really should have # their own separate CSV column: sv_cr_in1 and sv_cr_in2, but hey comb += cr_a_idx.eq(op.sv_cr_in) comb += cr_b_idx.eq(SVEXTRA.NONE) @@ -1155,15 +1102,33 @@ class PowerDecode2(PowerDecodeSubset): comb += dec_o2.lk.eq(do.lk) # registers a, b, c and out and out2 (LD/ST EA) - for to_reg, fromreg in ( - (e.read_reg1, dec_a.reg_out), - (e.read_reg2, dec_b.reg_out), - (e.read_reg3, dec_c.reg_out), - (e.write_reg, dec_o.reg_out), - (e.write_ea, dec_o2.reg_out)): - comb += to_reg.data.eq(fromreg.data) + for to_reg, fromreg, svdec in ( + (e.read_reg1, dec_a.reg_out, in1_svdec), + (e.read_reg2, dec_b.reg_out, in2_svdec), + (e.read_reg3, dec_c.reg_out, in3_svdec), + (e.write_reg, dec_o.reg_out, o_svdec), + (e.write_ea, dec_o2.reg_out, o2_svdec)): + comb += svdec.extra.eq(extra) # EXTRA field of SVP64 RM + comb += svdec.etype.eq(op.SV_Etype) # EXTRA2/3 for this insn + comb += svdec.reg_in.eq(fromreg.data) # 3-bit (CR0/BC/BFA) + comb += to_reg.data.eq(svdec.reg_out) # 7-bit output comb += to_reg.ok.eq(fromreg.ok) + comb += in1_svdec.idx.eq(op.sv_in1) # SVP64 reg #1 (matches in1_sel) + comb += in2_svdec.idx.eq(op.sv_in2) # SVP64 reg #2 (matches in2_sel) + comb += in3_svdec.idx.eq(op.sv_in3) # SVP64 reg #3 (matches in3_sel) + comb += o_svdec.idx.eq(op.sv_out) # SVP64 output (matches out_sel) + # XXX TODO - work out where this should come from. the problem is + # that LD-with-update is implied (computed from "is instruction in + # "update mode" rather than specified cleanly as its own CSV column + #comb += o2_svdec.idx.eq(op.sv_out) # SVP64 output (implicit) + + comb += self.in1_isvec.eq(in1_svdec.isvec) + comb += self.in2_isvec.eq(in2_svdec.isvec) + comb += self.in3_isvec.eq(in3_svdec.isvec) + comb += self.o_isvec.eq(o_svdec.isvec) + comb += self.o2_isvec.eq(o2_svdec.isvec) + # SPRs out comb += e.read_spr1.eq(dec_a.spr_out) comb += e.write_spr.eq(dec_o.spr_out) -- 2.30.2