From ec3d17992123c7311892fe79b604ac030628d4ca Mon Sep 17 00:00:00 2001 From: Luke Kenneth Casson Leighton Date: Mon, 7 Sep 2020 16:14:11 +0100 Subject: [PATCH] split out PowerDecode2 into PowerDecodeSubset --- src/soc/decoder/decode2execute1.py | 5 +- src/soc/decoder/power_decoder2.py | 193 +++++++++++++++++------------ src/soc/decoder/power_enums.py | 2 + 3 files changed, 123 insertions(+), 77 deletions(-) diff --git a/src/soc/decoder/decode2execute1.py b/src/soc/decoder/decode2execute1.py index 73296930..82815ade 100644 --- a/src/soc/decoder/decode2execute1.py +++ b/src/soc/decoder/decode2execute1.py @@ -64,7 +64,10 @@ class Decode2ToOperand(RecordObject): class Decode2ToExecute1Type(RecordObject): - def __init__(self, name=None, asmcode=True, opkls=Decode2ToOperand): + def __init__(self, name=None, asmcode=True, opkls=None): + + if opkls is None: + opkls = Decode2ToOperand RecordObject.__init__(self, name=name) diff --git a/src/soc/decoder/power_decoder2.py b/src/soc/decoder/power_decoder2.py index bfe4abb7..2862804b 100644 --- a/src/soc/decoder/power_decoder2.py +++ b/src/soc/decoder/power_decoder2.py @@ -593,34 +593,30 @@ class DecodeCROut(Elaboratable): return m -class PowerDecode2(Elaboratable): - """PowerDecode2: the main instruction decoder. - - whilst PowerDecode is responsible for decoding the actual opcode, this - module encapsulates further specialist, sparse information and - expansion of fields that is inconvenient to have in the CSV files. - for example: the encoding of the immediates, which are detected - and expanded out to their full value from an annotated (enum) - representation. - - implicit register usage is also set up, here. for example: OP_BC - requires implicitly reading CTR, OP_RFID requires implicitly writing - to SRR1 and so on. +class PowerDecodeSubset(Elaboratable): + """PowerDecodeSubset: dynamic subset decoder - in addition, PowerDecoder2 is responsible for detecting whether - instructions are illegal (or privileged) or not, and instead of - just leaving at that, *replacing* the instruction to execute with - a suitable alternative (trap). """ - def __init__(self, dec): + def __init__(self, dec, fn_unit=None): - self.dec = dec - self.e = Decode2ToExecute1Type() + if dec is None: + self.opkls = fn_unit.opsubsetkls + self.fn_name = fn_unit.fnunit.name + self.dec = create_pdecode(name=fn_name, col_subset=col_subset, + row_subset=self.rowsubsetfn) + else: + self.dec = dec + self.opkls = None + self.fn_name = None + self.e = Decode2ToExecute1Type(name=self.fn_name, opkls=self.opkls) # state information needed by the Decoder (TODO: this as a Record) self.state = CoreState("dec2") + def rowsubsetfn(opcode, row): + return row['unit'] == self.fn_name + def ports(self): return self.dec.ports() + self.e.ports() @@ -649,76 +645,33 @@ class PowerDecode2(Elaboratable): # fill in for a normal instruction (not an exception) # copy over if non-exception, non-privileged etc. is detected - self.e_tmp = e = Decode2ToExecute1Type() + self.e_tmp = e = Decode2ToExecute1Type(name=self.fn_name, + opkls=self.opkls) do = e.do # set up submodule decoders m.submodules.dec = self.dec - m.submodules.dec_a = dec_a = DecodeA(self.dec) m.submodules.dec_ai = dec_ai = DecodeAImm(self.dec) - m.submodules.dec_b = dec_b = DecodeB(self.dec) m.submodules.dec_bi = dec_bi = DecodeBImm(self.dec) - m.submodules.dec_c = dec_c = DecodeC(self.dec) - m.submodules.dec_o = dec_o = DecodeOut(self.dec) - m.submodules.dec_o2 = dec_o2 = DecodeOut2(self.dec) m.submodules.dec_rc = dec_rc = DecodeRC(self.dec) m.submodules.dec_oe = dec_oe = DecodeOE(self.dec) - m.submodules.dec_cr_in = dec_cr_in = DecodeCRIn(self.dec) - m.submodules.dec_cr_out = dec_cr_out = DecodeCROut(self.dec) + m.submodules.dec_cr_in = self.dec_cr_in = DecodeCRIn(self.dec) + m.submodules.dec_cr_out = self.dec_cr_out = DecodeCROut(self.dec) # copy instruction through... - for i in [do.insn, dec_a.insn_in, dec_b.insn_in, - dec_c.insn_in, dec_o.insn_in, dec_o2.insn_in, dec_rc.insn_in, - dec_oe.insn_in, dec_cr_in.insn_in, dec_cr_out.insn_in]: + for i in [do.insn, + dec_rc.insn_in, dec_oe.insn_in, + self.dec_cr_in.insn_in, self.dec_cr_out.insn_in]: comb += i.eq(self.dec.opcode_in) # ...and subdecoders' input fields - comb += dec_a.sel_in.eq(op.in1_sel) comb += dec_ai.sel_in.eq(op.in1_sel) - comb += dec_b.sel_in.eq(op.in2_sel) comb += dec_bi.sel_in.eq(op.in2_sel) - comb += dec_c.sel_in.eq(op.in3_sel) - comb += dec_o.sel_in.eq(op.out_sel) - comb += dec_o2.sel_in.eq(op.out_sel) - comb += dec_o2.lk.eq(do.lk) comb += dec_rc.sel_in.eq(op.rc_sel) comb += dec_oe.sel_in.eq(op.rc_sel) # XXX should be OE sel - comb += dec_cr_in.sel_in.eq(op.cr_in) - comb += dec_cr_out.sel_in.eq(op.cr_out) - comb += dec_cr_out.rc_in.eq(dec_rc.rc_out.data) - - # registers a, b, c and out and out2 (LD/ST EA) - comb += e.read_reg1.eq(dec_a.reg_out) - comb += e.read_reg2.eq(dec_b.reg_out) - comb += e.read_reg3.eq(dec_c.reg_out) - comb += e.write_reg.eq(dec_o.reg_out) - comb += e.write_ea.eq(dec_o2.reg_out) - - # SPRs out - comb += e.read_spr1.eq(dec_a.spr_out) - comb += e.write_spr.eq(dec_o.spr_out) - - # Fast regs out - comb += e.read_fast1.eq(dec_a.fast_out) - comb += e.read_fast2.eq(dec_b.fast_out) - comb += e.write_fast1.eq(dec_o.fast_out) - comb += e.write_fast2.eq(dec_o2.fast_out) - - # condition registers (CR) - comb += e.read_cr1.eq(dec_cr_in.cr_bitfield) - comb += e.read_cr2.eq(dec_cr_in.cr_bitfield_b) - comb += e.read_cr3.eq(dec_cr_in.cr_bitfield_o) - comb += e.write_cr.eq(dec_cr_out.cr_bitfield) - - # sigh this is exactly the sort of thing for which the - # decoder is designed to not need. MTSPR, MFSPR and others need - # access to the XER bits. however setting e.oe is not appropriate - with m.If(op.internal_op == MicrOp.OP_MFSPR): - comb += e.xer_in.eq(0b111) # SO, CA, OV - with m.If(op.internal_op == MicrOp.OP_CMP): - comb += e.xer_in.eq(1<