- """
- task handle_trap;
- begin
- mstatus_mpie = mstatus_mie;
- mstatus_mie = 0;
- mepc = (fetch_action == `fetch_action_noerror_trap) ? fetch_output_pc + 4 : fetch_output_pc;
- if(fetch_action == `fetch_action_ack_trap) begin
- mcause = `cause_instruction_access_fault;
- end
- else if((decode_action & `decode_action_trap_illegal_instruction) != 0) begin
- mcause = `cause_illegal_instruction;
- end
- else if((decode_action & `decode_action_trap_ecall_ebreak) != 0) begin
- mcause = decoder_immediate[0] ? `cause_machine_environment_call : `cause_breakpoint;
- end
- else if((decode_action & `decode_action_load) != 0) begin
- if(load_store_misaligned)
- mcause = `cause_load_address_misaligned;
- else
- mcause = `cause_load_access_fault;
- end
- else if((decode_action & `decode_action_store) != 0) begin
- if(load_store_misaligned)
- mcause = `cause_store_amo_address_misaligned;
- else
- mcause = `cause_store_amo_access_fault;
- end
- else if((decode_action & (`decode_action_branch | `decode_action_jal | `decode_action_jalr)) != 0) begin
- mcause = `cause_instruction_address_misaligned;
- end
- else begin
- mcause = `cause_illegal_instruction;
+ def main_block(self, minfo, csr, mi, m, mstatus, ft, dc,
+ load_store_misaligned,
+ loaded_value, alu_result,
+ lui_auipc_result):
+ c = {}
+ c[FOS.empty] = []
+ c[FOS.trap] = self.handle_trap(m, mstatus, ft, dc,
+ load_store_misaligned)
+ c[FOS.valid] = self.handle_valid(minfo, csr, mi, m, mstatus, ft, dc,
+ load_store_misaligned,
+ loaded_value,
+ alu_result,
+ lui_auipc_result)
+ return Case(ft.output_state, c)
+
+ def handle_valid(self, minfo, csr, mi, m, mstatus, ft, dc,
+ load_store_misaligned,
+ loaded_value, alu_result,
+ lui_auipc_result):
+ # fetch action ack trap
+ i = If((ft.action == FA.ack_trap) | (ft.action == FA.noerror_trap),
+ self.handle_trap(m, mstatus, ft, dc,
+ load_store_misaligned)
+ )
+
+ # load
+ i = i.Elif((dc.act & DA.load) != 0,
+ If(~mi.rw_wait,
+ self.write_register(dc.rd, loaded_value)
+ )
+ )
+
+ # op or op_immediate
+ i = i.Elif((dc.act & DA.op_op_imm) != 0,
+ self.write_register(dc.rd, alu_result)
+ )
+
+ # lui or auipc
+ i = i.Elif((dc.act & DA.lui_auipc) != 0,
+ self.write_register(dc.rd, lui_auipc_result)
+ )
+
+ # jal/jalr
+ i = i.Elif((dc.act & (DA.jal | DA.jalr)) != 0,
+ self.write_register(dc.rd, ft.output_pc + 4)
+ )
+
+ i = i.Elif((dc.act & DA.csr) != 0,
+ self.handle_csr(minfo, mstatus, dc, csr)
+ )
+
+ # fence, store, branch
+ i = i.Elif((dc.act & (DA.fence | DA.fence_i |
+ DA.store | DA.branch)) != 0,
+ # do nothing
+ )
+
+ return i
+
+ def handle_csr(self, minfo, mstatus, dc, csr):
+ csr_output_value = Signal()
+ csr_written_value = Signal()
+ c = {}
+
+ return Case(csr.number, c)
+
+ """
+ reg [31:0] csr_output_value;
+ reg [31:0] csr_written_value;
+ csr_output_value = 32'hXXXXXXXX;
+ csr_written_value = 32'hXXXXXXXX;
+ case(csr_number)
+ `csr_cycle: begin
+ csr_output_value = cycle_counter[31:0];
+ end
+ `csr_time: begin
+ csr_output_value = time_counter[31:0];
+ end
+ `csr_instret: begin
+ csr_output_value = instret_counter[31:0];
+ end
+ `csr_cycleh: begin
+ csr_output_value = cycle_counter[63:32];
+ end
+ `csr_timeh: begin
+ csr_output_value = time_counter[63:32];
+ end
+ `csr_instreth: begin
+ csr_output_value = instret_counter[63:32];
+ end
+ `csr_mvendorid: begin
+ csr_output_value = mvendorid;
+ end
+ `csr_marchid: begin
+ csr_output_value = marchid;
+ end
+ `csr_mimpid: begin
+ csr_output_value = mimpid;
+ end
+ `csr_mhartid: begin
+ csr_output_value = mhartid;
+ end
+ `csr_misa: begin
+ csr_output_value = misa;
+ end
+ `csr_mstatus: begin
+ csr_output_value = make_mstatus(mstatus_tsr,
+ mstatus_tw,
+ mstatus_tvm,
+ mstatus_mxr,
+ mstatus_sum,
+ mstatus_mprv,
+ mstatus_xs,
+ mstatus_fs,
+ mstatus_mpp,
+ mstatus_spp,
+ mstatus_mpie,
+ mstatus_spie,
+ mstatus_upie,
+ mstatus_mie,
+ mstatus_sie,
+ mstatus_uie);
+ csr_written_value = evaluate_csr_funct3_operation(decoder_funct3, csr_output_value, csr_input_value);
+ if(csr_writes) begin
+ mstatus_mpie = csr_written_value[7];
+ mstatus_mie = csr_written_value[3];
+ end
+ end
+ `csr_mie: begin
+ csr_output_value = 0;
+ csr_output_value[11] = mie_meie;
+ csr_output_value[9] = mie_seie;
+ csr_output_value[8] = mie_ueie;
+ csr_output_value[7] = mie_mtie;
+ csr_output_value[5] = mie_stie;
+ csr_output_value[4] = mie_utie;
+ csr_output_value[3] = mie_msie;
+ csr_output_value[1] = mie_ssie;
+ csr_output_value[0] = mie_usie;
+ csr_written_value = evaluate_csr_funct3_operation(decoder_funct3, csr_output_value, csr_input_value);
+ if(csr_writes) begin
+ mie_meie = csr_written_value[11];
+ mie_mtie = csr_written_value[7];
+ mie_msie = csr_written_value[3];
+ end
+ end
+ `csr_mtvec: begin
+ csr_output_value = mtvec;
+ end
+ `csr_mscratch: begin
+ csr_output_value = mscratch;
+ csr_written_value = evaluate_csr_funct3_operation(decoder_funct3, csr_output_value, csr_input_value);
+ if(csr_writes)
+ mscratch = csr_written_value;
+ end
+ `csr_mepc: begin
+ csr_output_value = mepc;
+ csr_written_value = evaluate_csr_funct3_operation(decoder_funct3, csr_output_value, csr_input_value);
+ if(csr_writes)
+ mepc = csr_written_value;
+ end
+ `csr_mcause: begin
+ csr_output_value = mcause;
+ csr_written_value = evaluate_csr_funct3_operation(decoder_funct3, csr_output_value, csr_input_value);
+ if(csr_writes)
+ mcause = csr_written_value;
+ end
+ `csr_mip: begin
+ csr_output_value = 0;
+ csr_output_value[11] = mip_meip;
+ csr_output_value[9] = mip_seip;
+ csr_output_value[8] = mip_ueip;
+ csr_output_value[7] = mip_mtip;
+ csr_output_value[5] = mip_stip;
+ csr_output_value[4] = mip_utip;
+ csr_output_value[3] = mip_msip;
+ csr_output_value[1] = mip_ssip;
+ csr_output_value[0] = mip_usip;
+ end
+ endcase
+ if(csr_reads)
+ write_register(decoder_rd, csr_output_value);
+ end