From ae89f5ea4c2bd994e1e168ca1f42bcc17eafd8cc Mon Sep 17 00:00:00 2001 From: Luke Kenneth Casson Leighton Date: Sun, 8 Mar 2020 15:25:38 +0000 Subject: [PATCH] decode b, c, out, rc and oe --- src/decoder/power_decoder2.py | 166 ++++++++++++++++++++++++++++++++-- 1 file changed, 156 insertions(+), 10 deletions(-) diff --git a/src/decoder/power_decoder2.py b/src/decoder/power_decoder2.py index c8e98705..b703e832 100644 --- a/src/decoder/power_decoder2.py +++ b/src/decoder/power_decoder2.py @@ -5,16 +5,16 @@ based on Anton Blanchard microwatt decode2.vhdl """ from nmigen import Module, Elaboratable, Signal from power_enums import (InternalOp, CryIn, - In1Sel, In2Sel, In3Sel, OutSel, SPR) + In1Sel, In2Sel, In3Sel, OutSel, SPR, RC) class DecodeA(Elaboratable): def __init__(self, dec): self.dec = dec self.sel_in = Signal(In1Sel, reset_less=True) self.insn_in = Signal(32, reset_less=True) - self.ispr1_in = Signal(10, reset_less=True) self.reg_out = Signal(5, reset_less=True) self.regok_out = Signal(reset_less=True) + self.immz_out = Signal(reset_less=True) self.spr_out = Signal(10, reset_less=True) self.sprok_out = Signal(reset_less=True) @@ -23,11 +23,17 @@ class DecodeA(Elaboratable): comb = m.d.comb # select Register A field - comb += self.reg_out.eq(self.dec.RA) with m.If((self.sel_in == In1Sel.RA) | - ((self.sel_in == In1Sel.RA_OR_ZERO) & (ra == Const(0, 5))): + ((self.sel_in == In1Sel.RA_OR_ZERO) & + (self.reg_out != Const(0, 5)))): + comb += self.reg_out.eq(self.dec.RA) comb += self.regok_out.eq(1) + # zero immediate requested + with m.If((self.sel_in == In1Sel.RA_OR_ZERO) & + (self.reg_out == Const(0, 5))): + comb += self.immz_out.eq(1) + # decode SPR1 based on instruction type op = self.dec.op # BC or BCREG: potential implicit register (CTR) @@ -42,15 +48,18 @@ class DecodeA(Elaboratable): self.spr_out.eq(self.dec.SPR) # decode SPR field from XFX insn self.sprok_out.eq(1) + return m + class DecodeB(Elaboratable): def __init__(self, dec): self.dec = dec - self.sel_in = Signal(In1Sel, reset_less=True) + self.sel_in = Signal(In2Sel, reset_less=True) self.insn_in = Signal(32, reset_less=True) - self.ispr1_in = Signal(10, reset_less=True) self.reg_out = Signal(5, reset_less=True) self.regok_out = Signal(reset_less=True) + self.imm_out = Signal(64, reset_less=True) + self.immok_out = Signal(reset_less=True) self.spr_out = Signal(10, reset_less=True) self.sprok_out = Signal(reset_less=True) @@ -59,13 +68,44 @@ class DecodeB(Elaboratable): comb = m.d.comb # select Register B field - comb += self.reg_out.eq(self.dec.RB) - with m.If((self.sel_in == In1Sel.RB) | - ((self.sel_in == In1Sel.RB_OR_ZERO) & (ra == Const(0, 5))): - comb += self.regok_out.eq(1) + with m.Switch(self.sel_in): + with m.Case(In2Sel.RB): + comb += self.reg_out.eq(self.dec.RB) + comb += self.regok_out.eq(1) + with m.Case(In2Sel.CONST_UI): + comb += self.imm_out.eq(self.dec.SI) + comb += self.immok_out.eq(1) + with m.Case(In2Sel.CONST_SI): # TODO: sign-extend here? + comb += self.imm_out.eq(self.dec.SI) + comb += self.immok_out.eq(1) + with m.Case(In2Sel.CONST_UI_HI): + comb += self.imm_out.eq(self.dec.UI<<4) + comb += self.immok_out.eq(1) + with m.Case(In2Sel.CONST_UI_SI): # TODO: sign-extend here? + comb += self.imm_out.eq(self.dec.UI<<4) + comb += self.immok_out.eq(1) + with m.Case(In2Sel.CONST_LI): + comb += self.imm_out.eq(self.dec.LI<<2) + comb += self.immok_out.eq(1) + with m.Case(In2Sel.CONST_BD): + comb += self.imm_out.eq(self.dec.BD<<2) + comb += self.immok_out.eq(1) + with m.Case(In2Sel.CONST_DS): + comb += self.imm_out.eq(self.dec.DS<<2) + comb += self.immok_out.eq(1) + with m.Case(In2Sel.CONST_M1): + comb += self.imm_out.eq(~Const(0, 64)) # all 1s + comb += self.immok_out.eq(1) + with m.Case(In2Sel.CONST_SH): + comb += self.imm_out.eq(self.dec.sh) + comb += self.immok_out.eq(1) + with m.Case(In2Sel.CONST_SH32): + comb += self.imm_out.eq(self.dec.SH32) + comb += self.immok_out.eq(1) # decode SPR2 based on instruction type op = self.dec.op + # BCREG implicitly uses CTR or LR for 2nd reg with m.If(op.internal_op == InternalOP.OP_BCREG): with m.If(self.dec.FormXL.XO[10]): # 3.0B p38 top bit of XO self.spr_out.eq(SPR.CTR) @@ -73,6 +113,112 @@ class DecodeB(Elaboratable): self.spr_out.eq(SPR.LR) self.sprok_out.eq(1) + return m + + +class DecodeC(Elaboratable): + def __init__(self, dec): + self.dec = dec + self.sel_in = Signal(In3Sel, reset_less=True) + self.insn_in = Signal(32, reset_less=True) + self.reg_out = Signal(5, reset_less=True) + self.regok_out = Signal(reset_less=True) + + def elaborate(self, platform): + m = Module() + comb = m.d.comb + + # select Register C field + with m.If(self.sel_in == In3Sel.RC): + comb += self.reg_out.eq(self.dec.RC) + comb += self.regok_out.eq(1) + + return m + + +class DecodeOut(Elaboratable): + def __init__(self, dec): + self.dec = dec + self.sel_in = Signal(In1Sel, reset_less=True) + self.insn_in = Signal(32, reset_less=True) + self.reg_out = Signal(5, reset_less=True) + self.regok_out = Signal(reset_less=True) + self.spr_out = Signal(10, reset_less=True) + self.sprok_out = Signal(reset_less=True) + + def elaborate(self, platform): + m = Module() + comb = m.d.comb + + # select Register out field + with m.Switch(self.sel_in): + with m.Case(In1Sel.RT): + comb += self.reg_out.eq(self.dec.RT) + comb += self.regok_out.eq(1) + with m.Case(In1Sel.RA): + comb += self.reg_out.eq(self.dec.RA) + comb += self.regok_out.eq(1) + with m.Case(In1Sel.SPR): + self.spr_out.eq(self.dec.SPR) # decode SPR field from XFX insn + self.sprok_out.eq(1) + + return m + + +class DecodeRC(Elaboratable): + def __init__(self, dec): + self.dec = dec + self.sel_in = Signal(RC, reset_less=True) + self.insn_in = Signal(32, reset_less=True) + self.rc_out = Signal(1, reset_less=True) + self.rcok_out = Signal(reset_less=True) + + def elaborate(self, platform): + m = Module() + comb = m.d.comb + + # select Record bit out field + with m.Switch(self.sel_in): + with m.Case(RC.RC): + comb += self.rc_out.eq(self.dec.Rc) + comb += self.rcok_out.eq(1) + with m.Case(RC.ONE): + comb += self.rc_out.eq(1) + comb += self.rcok_out.eq(1) + with m.Case(RC.NONE): + comb += self.rc_out.eq(0) + comb += self.rcok_out.eq(1) + + return m + + +class DecodeOE(Elaboratable): + """ + -- For now, use "rc" in the decode table to decide whether oe exists. + -- This is not entirely correct architecturally: For mulhd and + -- mulhdu, the OE field is reserved. It remains to be seen what an + -- actual POWER9 does if we set it on those instructions, for now we + -- test that further down when assigning to the multiplier oe input. + """ + def __init__(self, dec): + self.dec = dec + self.sel_in = Signal(RC, reset_less=True) + self.insn_in = Signal(32, reset_less=True) + self.oe_out = Signal(1, reset_less=True) + self.oeok_out = Signal(reset_less=True) + + def elaborate(self, platform): + m = Module() + comb = m.d.comb + + # select OE bit out field + with m.Switch(self.sel_in): + with m.Case(RC.RC): + comb += self.oe_out.eq(self.dec.OE) + comb += self.oeok_out.eq(1) + + return m + class XerBits: def __init__(self): -- 2.30.2