svp64_en=self.svp64_en,
regreduce_en=self.regreduce_en)
self.des[funame] = self.decoders[funame].do
+ print ("create decoder subset", funame, opkls, self.des[funame])
# create per-Function Unit write-after-write hazard signals
# yes, really, this should have been added in ReservationStations
# is a waw hazard. decoder has to still
# be asserted in order to detect that, tho
comb += fu.oper_i.eq_from(do)
+ if funame == 'mmu0':
+ # URRR this is truly dreadful.
+ # OP_FETCH_FAILED is a "fake" op.
+ # no instruction creates it. OP_TRAP
+ # uses the *main* decoder: this is
+ # a *Satellite* decoder that reacts
+ # on *insn_in*... not fake ops. gaah.
+ main_op = self.ireg.e.do
+ with m.If(main_op.insn_type ==
+ MicrOp.OP_FETCH_FAILED):
+ comb += fu.oper_i.insn_type.eq(
+ MicrOp.OP_FETCH_FAILED)
+ comb += fu.oper_i.fn_unit.eq(
+ Function.MMU)
# issue when valid (and no write-hazard)
comb += fu.issue_i.eq(~self.waw_hazard)
# instruction ok, indicate ready
m = super().elaborate(platform)
dbg = self.dbg
- core = self.core,
+ core = self.core
pc = self.i.pc
svstate = self.svstate
nia = self.nia
msr_read = Signal(reset=1)
+ # also note instruction fetch failed
+ if hasattr(core, "icache"):
+ fetch_failed = core.icache.i_out.fetch_failed
+ else:
+ fetch_failed = Const(0, 1)
+
# don't read msr every cycle
staterf = self.core.regs.rf['state']
state_r_msr = staterf.r_ports['msr'] # MSR rd
# waiting (zzz)
with m.State("IDLE"):
- with m.If(~dbg.stopping_o):
+ with m.If(~dbg.stopping_o & ~fetch_failed):
comb += fetch_pc_o_ready.eq(1)
- with m.If(fetch_pc_i_valid):
+ with m.If(fetch_pc_i_valid & ~fetch_failed):
# instruction allowed to go: start by reading the PC
# capture the PC and also drop it into Insn Memory
# we have joined a pair of combinatorial memory
with m.If(~msr_read):
sync += msr_read.eq(1) # yeah don't read it again
sync += cur_state.msr.eq(state_r_msr.o_data)
- with m.If(self.imem.f_busy_o): # zzz...
- # busy: stay in wait-read
+ with m.If(self.imem.f_busy_o & ~fetch_failed): # zzz...
+ # busy but not fetch failed: stay in wait-read
comb += self.imem.a_i_valid.eq(1)
comb += self.imem.f_i_valid.eq(1)
with m.Else():
- # not busy: instruction fetched
- insn = get_insn(self.imem.f_instr_o, cur_state.pc)
+ # not busy (or fetch failed!): instruction fetched
+ # when fetch failed, the instruction gets ignored
+ # by the decoder
+ insn = ~get_insn(self.imem.f_instr_o, cur_state.pc)
if self.svp64_en:
svp64 = self.svp64
# decode the SVP64 prefix, if any