Chiselを使って、非常にシンプルなCPUを作ってみるプロジェクト。テストパタンを動かすためには、CSRレジスタを扱えければならないのと、Ecallなどの例外を扱う命令が実行できなければならない。
Ecallは、例外を発生させ例外コードをmcauseに書き込み、mtvecに格納されているPC位置までジャンプする。 mcauseへの書き込みと、mtvecの読み込みとPC更新ができればよいわけだ。
CSRへの書き込みを実行するのは以下のコードとなる。
when(io.ecall_inst) { reg_mcause := Causes.UserEcall.U } .elsewhen (decoded_addr(CsrAddr.mcause)) { reg_mcause := wdata & ((BigInt(1) << (63)) + 31).U /* only implement 5 LSBs and MSB */ }
Ecall命令を実行すると、mtvecの値に従ってPCを変更し、mcauseに値を設定する。
if_inst_addr := MuxCase (0.U, Array ( (if_inst_en & dec_jalr_en) -> dec_reg_op0.asUInt, (if_inst_en & dec_jal_en) -> (dec_inst_addr + dec_imm_j), (if_inst_en & dec_br_en) -> (dec_inst_addr + dec_imm_b_sext), (if_inst_en & dec_mret_en) -> u_csrfile.io.mepc, (if_inst_en & dec_ecall_en)-> u_csrfile.io.mtvec, (if_inst_en & io.inst_bus.ack) -> (if_inst_addr + 4.U) ))
これで、Ecallでジャンプして、CSRを制御できるようになった。