comb += self.whole_reg.ok.eq(0)
comb += self.sv_override.eq(0)
+ # please note these MUST match (setting of cr_bitfield.ok) exactly
+ # with write_cr0 below in PowerDecoder2. the reason it's separated
+ # is to avoid having duplicate copies of DecodeCROut in multiple
+ # PowerDecoderSubsets. register decoding should be a one-off in
+ # PowerDecoder2. see https://bugs.libre-soc.org/show_bug.cgi?id=606
+
with m.Switch(self.sel_in):
with m.Case(CROutSel.NONE):
pass # No bitfield activated
# set up submodule decoders
m.submodules.dec = self.dec
- m.submodules.dec_rc = dec_rc = DecodeRC(self.dec)
+ m.submodules.dec_rc = self.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)
- rc_out = dec_rc.rc_out.data
# 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]:
+ for i in [do.insn, dec_rc.insn_in, dec_oe.insn_in, ]:
comb += i.eq(self.dec.opcode_in)
# ...and subdecoders' input fields
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(rc_out)
# copy "state" over
comb += self.do_copy("msr", msr)
# set up instruction type
# no op: defaults to OP_ILLEGAL
- if self.fn_name=="MMU":
- # mmu is special case: needs SPR opcode as well
- mmu0 = self.mmu0_spr_dec
- with m.If(((mmu0.dec.op.internal_op == MicrOp.OP_MTSPR) |
- (mmu0.dec.op.internal_op == MicrOp.OP_MFSPR))):
- comb += self.do_copy("insn_type", mmu0.op_get("internal_op"))
- with m.Else():
- comb += self.do_copy("insn_type", self.op_get("internal_op"))
- else:
- comb += self.do_copy("insn_type", self.op_get("internal_op"))
+ # FIX https://bugs.libre-soc.org/show_bug.cgi?id=607
+ comb += self.do_copy("insn_type", self.op_get("internal_op"))
# function unit for decoded instruction: requires minor redirect
# for SPR set/get
spr = Signal(10, reset_less=True)
comb += spr.eq(decode_spr_num(self.dec.SPR)) # from XFX
- # XXX BUG - don't use hardcoded magic constants.
- # also use ".value" otherwise the test fails. bit of a pain
- # https://bugs.libre-soc.org/show_bug.cgi?id=603
-
- SPR_PID = 48 # TODO read docs for POWER9
# Microwatt doesn't implement the partition table
- # instead has PRTBL register (SPR) to point to process table
- SPR_PRTBL = 720 # see common.vhdl in microwatt, not in POWER9
+ # instead has PRTBL(SVSRR0) register (SPR) to point to process table
with m.If(((self.dec.op.internal_op == MicrOp.OP_MTSPR) |
(self.dec.op.internal_op == MicrOp.OP_MFSPR)) &
- ((spr == SPR.DSISR) | (spr == SPR.DAR)
- | (spr==SPR_PRTBL) | (spr==SPR_PID))):
+ ((spr == SPR.DSISR.value) | (spr == SPR.DAR.value) |
+ (spr==SPR.SVSRR0.value) | (spr==SPR.PIDR.value))):
comb += self.do_copy("fn_unit", Function.MMU)
with m.Else():
comb += self.do_copy("fn_unit",fn)
comb += self.do_copy("rc", dec_rc.rc_out)
comb += self.do_copy("oe", dec_oe.oe_out)
- # CR in/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)
+ # CR in/out - note: these MUST match with what happens in
+ # DecodeCROut!
+ rc_out = self.dec_rc.rc_out.data
with m.Switch(op.cr_out):
with m.Case(CROutSel.CR0, CROutSel.CR1):
comb += self.do_copy("write_cr0", rc_out) # only when RC=1
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
+ rc_out = self.dec_rc.rc_out.data
e = self.e_tmp
do = e.do
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_cr_in = self.dec_cr_in = DecodeCRIn(self.dec)
+ m.submodules.dec_cr_out = self.dec_cr_out = DecodeCROut(self.dec)
# and SVP64 Extra decoders
m.submodules.crout_svdec = crout_svdec = SVP64CRExtra()
# copy instruction through...
for i in [do.insn, dec_a.insn_in, dec_b.insn_in,
+ self.dec_cr_in.insn_in, self.dec_cr_out.insn_in,
dec_c.insn_in, dec_o.insn_in, dec_o2.insn_in]:
comb += i.eq(self.dec.opcode_in)
+ # CR setup
+ 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(rc_out)
+
+ # CR register info
+ 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)
+
# 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