for f in [F3.csrrc, F3.csrrci]: c[f] = ~written_value & previous_value
return Case(funct3, c)
+ def handle_trap(self, m, ms, ft, dc, load_store_misaligned):
+ s = [ms.mpie.eq(ms.mie),
+ ms.mie.eq(0),
+ m.mepc.eq(Mux(ft.action == FA.noerror_trap,
+ ft.output_pc + 4,
+ ft.output_pc))]
+
+ # fetch action ack trap
+ i = If(ft.action == FA.ack_trap,
+ m.mcause.eq(cause_instruction_access_fault)
+ )
+
+ # ecall/ebreak
+ i = i.Elif((dc.act & DA.trap_ecall_ebreak) != 0,
+ m.mcause.eq(Mux(decoder_immediate[0],
+ cause_machine_environment_call,
+ cause_breakpoint))
+ )
+
+ # load
+ i = i.Elif((dc.act & DA.load) != 0,
+ If(load_store_misaligned,
+ m.mcause.eq(cause_load_address_misaligned)
+ ).Else(
+ m.mcause.eq(cause_load_access_fault)
+ )
+ )
+
+ # store
+ i = i.Elif((dc.act & DA.store) != 0,
+ If(load_store_misaligned,
+ m.mcause.eq(cause_store_amo_address_misaligned)
+ ).Else(
+ m.mcause.eq(cause_store_amo_access_fault)
+ )
+ )
+
+ # jal/jalr -> misaligned=error, otherwise jump
+ i = i.Elif((dc.act & (DA.jal | DA.jalr | DA.branch)) != 0,
+ m.mcause.eq(cause_instruction_address_misaligned)
+ )
+
+ # defaults to illegal instruction
+ i = i.Else(m.mcause.eq(cause_illegal_instruction))
+
+ s.append(i)
+ return s
+
"""
task handle_trap;
begin