-
-"""
-
- 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;
- end
- end
- endtask
-
- wire [11:0] csr_number = decoder_immediate;
- wire [31:0] csr_input_value = decoder_funct3[2] ? decoder_rs1 : register_rs1;
- wire csr_reads = decoder_funct3[1] | (decoder_rd != 0);
- wire csr_writes = ~decoder_funct3[1] | (decoder_rs1 != 0);
-
- function get_csr_op_is_valid(input [11:0] csr_number, input csr_reads, input csr_writes);
- begin
- case(csr_number)
- `csr_ustatus,
- `csr_fflags,
- `csr_frm,
- `csr_fcsr,
- `csr_uie,
- `csr_utvec,
- `csr_uscratch,
- `csr_uepc,
- `csr_ucause,
- `csr_utval,
- `csr_uip,
- `csr_sstatus,
- `csr_sedeleg,
- `csr_sideleg,
- `csr_sie,
- `csr_stvec,
- `csr_scounteren,
- `csr_sscratch,
- `csr_sepc,
- `csr_scause,
- `csr_stval,
- `csr_sip,
- `csr_satp,
- `csr_medeleg,
- `csr_mideleg,
- `csr_dcsr,
- `csr_dpc,
- `csr_dscratch:
- get_csr_op_is_valid = 0;
- `csr_cycle,
- `csr_time,
- `csr_instret,
- `csr_cycleh,
- `csr_timeh,
- `csr_instreth,
- `csr_mvendorid,
- `csr_marchid,
- `csr_mimpid,
- `csr_mhartid:
- get_csr_op_is_valid = ~csr_writes;
- `csr_misa,
- `csr_mstatus,
- `csr_mie,
- `csr_mtvec,
- `csr_mscratch,
- `csr_mepc,
- `csr_mcause,
- `csr_mip:
- get_csr_op_is_valid = 1;
- `csr_mcounteren,
- `csr_mtval,
- `csr_mcycle,
- `csr_minstret,
- `csr_mcycleh,
- `csr_minstreth:
- // TODO: CSRs not implemented yet
- get_csr_op_is_valid = 0;
- endcase
- end
- endfunction
-
- assign csr_op_is_valid = get_csr_op_is_valid(csr_number, csr_reads, csr_writes);
-
- wire [63:0] cycle_counter = 0; // TODO: implement cycle_counter
- wire [63:0] time_counter = 0; // TODO: implement time_counter
- wire [63:0] instret_counter = 0; // TODO: implement instret_counter
-
- always @(posedge clk) begin:main_block
- if(reset) begin
- reset_to_initial();
- disable main_block;
- end
- case(fetch_output_state)
- `fetch_output_state_empty: begin
- end
- `fetch_output_state_trap: begin
- handle_trap();
- end
- `fetch_output_state_valid: begin:valid
- if((fetch_action == `fetch_action_error_trap) | (fetch_action == `fetch_action_noerror_trap)) begin
- handle_trap();
- end
- else if((decode_action & `decode_action_load) != 0) begin
- if(~memory_interface_rw_wait)
- write_register(decoder_rd, loaded_value);
- end
- else if((decode_action & `decode_action_op_op_imm) != 0) begin
- write_register(decoder_rd, alu_result);
- end
- else if((decode_action & `decode_action_lui_auipc) != 0) begin
- write_register(decoder_rd, lui_auipc_result);
- end
- else if((decode_action & (`decode_action_jal | `decode_action_jalr)) != 0) begin
- write_register(decoder_rd, fetch_output_pc + 4);
- end
- else if((decode_action & `decode_action_csr) != 0) begin:csr
- 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
- else if((decode_action & (`decode_action_fence | `decode_action_fence_i | `decode_action_store | `decode_action_branch)) != 0) begin
- // do nothing
- end
- end
- endcase
- end
-
-endmodule
-"""
-