+class PowerDecodeSubset(Elaboratable):
+ """PowerDecodeSubset: dynamic subset decoder
+
+ """
+
+ def __init__(self, dec, opkls=None, fn_name=None, col_subset=None):
+
+ if dec is None:
+ self.opkls = opkls
+ self.fn_name = fn_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(self, opcode, row):
+ return row['unit'] == self.fn_name
+
+ def ports(self):
+ return self.dec.ports() + self.e.ports()
+
+ def needs_field(self, field, op_field):
+ do = self.e_tmp.do
+ return hasattr(do, field) and self.op_get(op_field)
+
+ def do_copy(self, field, val, final=False):
+ if final:
+ do = self.e.do
+ else:
+ do = self.e_tmp.do
+ if hasattr(do, field) and val is not None:
+ return getattr(do, field).eq(val)
+ return []
+
+ def op_get(self, op_field):
+ return getattr(self.dec.op, op_field, None)
+
+ def elaborate(self, platform):
+ m = Module()
+ comb = m.d.comb
+ state = self.state
+ e_out, op, do_out = self.e, self.dec.op, self.e.do
+ dec_spr, msr, cia, ext_irq = state.dec, state.msr, state.pc, state.eint
+
+ # fill in for a normal instruction (not an exception)
+ # copy over if non-exception, non-privileged etc. is detected
+ 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_ai = dec_ai = DecodeAImm(self.dec)
+ m.submodules.dec_bi = dec_bi = DecodeBImm(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 = 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_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_ai.sel_in.eq(op.in1_sel)
+ comb += dec_bi.sel_in.eq(op.in2_sel)
+ comb += dec_rc.sel_in.eq(op.rc_sel)
+ comb += dec_oe.sel_in.eq(op.rc_sel) # XXX should be OE sel
+ comb += self.dec_cr_in.sel_in.eq(op.cr_in)
+ comb += self.dec_cr_out.sel_in.eq(op.cr_out)
+ comb += self.dec_cr_out.rc_in.eq(dec_rc.rc_out.data)
+
+ # copy "state" over
+ comb += self.do_copy("msr", msr)
+ comb += self.do_copy("cia", cia)
+
+ # set up instruction, pick fn unit
+ # no op: defaults to OP_ILLEGAL
+ comb += self.do_copy("insn_type", self.op_get("internal_op"))
+ comb += self.do_copy("fn_unit", self.op_get("function_unit"))
+
+ # immediates
+ comb += self.do_copy("imm_data", dec_bi.imm_out) # imm in RB
+ comb += self.do_copy("zero_a", dec_ai.immz_out) # RA==0 detected
+
+ # rc and oe out
+ comb += self.do_copy("rc", dec_rc.rc_out)
+ comb += self.do_copy("oe", dec_oe.oe_out)
+
+ comb += self.do_copy("read_cr_whole", self.dec_cr_in.whole_reg)
+ comb += self.do_copy("write_cr_whole", self.dec_cr_out.whole_reg)
+ comb += self.do_copy("write_cr0", self.dec_cr_out.cr_bitfield.ok)
+
+ # decoded/selected instruction flags
+ comb += self.do_copy("data_len", self.op_get("ldst_len"))
+ comb += self.do_copy("invert_in", self.op_get("inv_a"))
+ comb += self.do_copy("invert_out", self.op_get("inv_out"))
+ comb += self.do_copy("input_carry", self.op_get("cry_in"))
+ comb += self.do_copy("output_carry", self.op_get("cry_out"))
+ comb += self.do_copy("is_32bit", self.op_get("is_32b"))
+ comb += self.do_copy("is_signed", self.op_get("sgn"))
+ lk = self.op_get("lk")
+ if lk is not None:
+ with m.If(lk):
+ comb += self.do_copy("lk", self.dec.LK) # XXX TODO: accessor
+
+ comb += self.do_copy("byte_reverse", self.op_get("br"))
+ comb += self.do_copy("sign_extend", self.op_get("sgn_ext"))
+ comb += self.do_copy("ldst_mode", self.op_get("upd")) # LD/ST mode
+
+ # These should be removed eventually
+ comb += self.do_copy("input_cr", self.op_get("cr_in")) # CR in
+ comb += self.do_copy("output_cr", self.op_get("cr_out")) # CR out
+
+ return m
+
+
+class PowerDecode2(PowerDecodeSubset):