From a0bf7f174f3f539e51d0ac100a69e73a00c59a82 Mon Sep 17 00:00:00 2001 From: UnbalancedCat Date: Fri, 23 May 2025 20:10:03 +0800 Subject: [PATCH] fix bug & update xret --- rv_cpu.srcs/sources_1/new/cpu_top.v | 8 +- rv_cpu.srcs/sources_1/new/exe_stage.v | 10 +- rv_cpu.srcs/sources_1/new/id_stage.v | 59 ++++++------ rv_cpu.srcs/sources_1/new/mem_stage.v | 2 +- .../sources_1/new/sub_unit/csr/csr_reg_file.v | 91 ++++++++++++------- .../sources_1/new/sub_unit/inst_decoder.v | 8 +- 6 files changed, 107 insertions(+), 71 deletions(-) diff --git a/rv_cpu.srcs/sources_1/new/cpu_top.v b/rv_cpu.srcs/sources_1/new/cpu_top.v index 56f8486..3e335a1 100644 --- a/rv_cpu.srcs/sources_1/new/cpu_top.v +++ b/rv_cpu.srcs/sources_1/new/cpu_top.v @@ -47,7 +47,7 @@ module cpu_top ( // Define local parameters for bus widths based on stage module parameters localparam FS_TO_DS_BUS_WIDTH = 65; - localparam DS_TO_ES_BUS_WIDTH = 315; + localparam DS_TO_ES_BUS_WIDTH = 317; localparam ES_TO_MS_BUS_WIDTH = 164; localparam MS_TO_WS_BUS_WIDTH = 70; localparam WS_TO_DS_BUS_WIDTH = 38; @@ -86,7 +86,7 @@ module cpu_top ( wire [ES_TO_DS_FWD_BUS_WIDTH-1:0] es_to_ds_fwd_bus_data; wire [MS_TO_DS_FWD_BUS_WIDTH-1:0] ms_to_ds_fwd_bus_data; - wire [ 1:0] csr_mpp; + wire [ 1:0] csr_cur_pv; wire es_a_ext_stall; wire ms_a_ext_stall; @@ -150,7 +150,7 @@ module cpu_top ( .clk_i (clk_i), .rstn_i (rstn_i), - .csr_mpp_i (csr_mpp), + .csr_cur_pv_i (csr_cur_pv), .csr_flush_i (csr_flush), .m_ext_stall_i (m_ext_stall), @@ -201,7 +201,7 @@ module cpu_top ( .es_to_ds_fwd_bus_data_o(es_to_ds_fwd_bus_data), - .csr_mpp_o (csr_mpp), + .csr_cur_pv_o (csr_cur_pv), .m_ext_stall_o (m_ext_stall), .a_ext_stall_o (es_a_ext_stall), diff --git a/rv_cpu.srcs/sources_1/new/exe_stage.v b/rv_cpu.srcs/sources_1/new/exe_stage.v index 7cd646d..37f4b40 100644 --- a/rv_cpu.srcs/sources_1/new/exe_stage.v +++ b/rv_cpu.srcs/sources_1/new/exe_stage.v @@ -21,7 +21,7 @@ module exe_stage #( - parameter DS_TO_ES_BUS_WIDTH = 315, + parameter DS_TO_ES_BUS_WIDTH = 317, parameter ES_TO_MS_BUS_WIDTH = 164, parameter ES_TO_DS_FWD_BUS_WIDTH = 39 ) @@ -48,7 +48,7 @@ module exe_stage #( // fowarding bus to ID stage output [ES_TO_DS_FWD_BUS_WIDTH-1:0] es_to_ds_fwd_bus_data_o, - output [ 1:0] csr_mpp_o, + output [ 1:0] csr_cur_pv_o, output m_ext_stall_o, output a_ext_stall_o, @@ -90,6 +90,8 @@ module exe_stage #( wire [ 2:0] es_csr_op; wire [ 7:0] es_m_ext_op; + wire [ 1:0] es_xret_op; + wire es_op_is_alu; wire es_op_is_m_ext; wire es_op_is_jump; @@ -119,6 +121,7 @@ module exe_stage #( assign es_pipeline_stall = m_ext_stall_o; assign { + es_xret_op, // 316:315 (2 bits) es_excp_vec, // 314:283 (32 bits) es_amo_op, // 282:271 (12 bits) es_csr_op, // 270:268 (3 bits) @@ -214,12 +217,13 @@ module exe_stage #( .rstn_i (rstn_i), .csr_pc_i (es_pc), .csr_inst_i (es_inst), + .csr_xret_op_i (es_xret_op), .csr_op_i (es_csr_op), .csr_addr_i (es_csr), .csr_wdata_i (es_calc_src1), .csr_rdata_o (es_csr_result), .csr_excp_vec_i (es_excp_vec), - .csr_mpp_o (csr_mpp_o), + .csr_cur_pv_o (csr_cur_pv_o), .csr_taken_o (es_csr_taken), .csr_target_o (es_csr_target) ); diff --git a/rv_cpu.srcs/sources_1/new/id_stage.v b/rv_cpu.srcs/sources_1/new/id_stage.v index db7231b..04c17b9 100644 --- a/rv_cpu.srcs/sources_1/new/id_stage.v +++ b/rv_cpu.srcs/sources_1/new/id_stage.v @@ -22,7 +22,7 @@ module id_stage #( parameter FS_TO_DS_BUS_WIDTH = 65, - parameter DS_TO_ES_BUS_WIDTH = 315, + parameter DS_TO_ES_BUS_WIDTH = 317, parameter WS_TO_DS_BUS_WIDTH = 38, parameter ES_TO_DS_FWD_BUS_WIDTH = 39, parameter MS_TO_DS_FWD_BUS_WIDTH = 38 @@ -35,7 +35,7 @@ module id_stage #( input a_ext_stall_i, input csr_flush_i, - input [1:0] csr_mpp_i, + input [1:0] csr_cur_pv_i, output fs_to_ds_bus_ready_o, input [FS_TO_DS_BUS_WIDTH-1:0] fs_to_ds_bus_data_i, @@ -88,6 +88,7 @@ module id_stage #( wire [ 7:0] ds_m_ext_op; wire [ 2:0] ds_csr_op; wire [11:0] ds_amo_op; + wire [ 1:0] ds_xret_op; wire ds_excp_illegal_inst; wire ds_excp_breakpoint; wire ds_excp_env_call; @@ -204,6 +205,7 @@ module id_stage #( .amo_op_o (ds_amo_op), .amo_aq_o (), .amo_rl_o (), + .xret_op_o (ds_xret_op), .excp_illegal_inst_o (ds_excp_illegal_inst), .excp_breakpoint_o (ds_excp_breakpoint), .excp_env_call_o (ds_excp_env_call) @@ -226,9 +228,9 @@ module id_stage #( 1'b0, // store page fault 1'b0, // expc code 14 2'b0, // isnt & load page fault - ds_excp_env_call && (csr_mpp_i == 2'b11), + ds_excp_env_call && (csr_cur_pv_i == 2'b11), 1'b0, // excp code 10 - ds_excp_env_call && (csr_mpp_i == 2'b01), + ds_excp_env_call && (csr_cur_pv_i == 2'b01), 1'b0, // env call from u mode 4'b0, // load & store addr misalign & access fault ds_excp_breakpoint, @@ -256,30 +258,31 @@ module id_stage #( assign ds_rs1_lt_rs2 = ($signed(ds_rs1_value) < $signed(ds_rs2_value)); assign ds_rs1_lt_rs2u = (ds_rs1_value < ds_rs2_value); - assign ds_to_es_bus_data_o = { // Total 315 bits - ds_excp_vec, // 314:283 (32 bits) - ds_amo_op, // 282:271 (12 bits) - ds_csr_op, // 270:268 (3 bits) - ds_m_ext_op, // 267:260 (8 bits) - ds_br_taken, // 259:259 (1 bit) - ds_br_target, // 258:227 (32 bits) - ds_store_op, // 226:224 (3 bits) - ds_load_op, // 223:218 (6 bits) - ds_jump_op, // 217:216 (2 bits) - ds_alu_op, // 215:205 (11 bits) - ds_calc_src2_sel, // 204:201 (4 bits) - ds_calc_src1_sel, // 200:197 (4 bits) - ds_rd, // 196:192 (5 bits) - ds_rs2, // 191:187 (5 bits) - ds_rs1, // 186:182 (5 bits) - ds_zimm, // 181:177 (5 bits) - ds_csr, // 176:165 (12 bits) - ds_shamt, // 164:160 (5 bits) - ds_imm, // 159:128 (32 bits) - ds_rs2_value, // 127:96 (32 bits) - ds_rs1_value, // 95:64 (32 bits) - ds_pc, // 63:32 (32 bits) - ds_inst // 31:0 (32 bits) + assign ds_to_es_bus_data_o = { // Total 317 bits + ds_xret_op, // 316:315 (2 bits) + ds_excp_vec, // 314:283 (32 bits) + ds_amo_op, // 282:271 (12 bits) + ds_csr_op, // 270:268 (3 bits) + ds_m_ext_op, // 267:260 (8 bits) + ds_br_taken, // 259:259 (1 bit) + ds_br_target, // 258:227 (32 bits) + ds_store_op, // 226:224 (3 bits) + ds_load_op, // 223:218 (6 bits) + ds_jump_op, // 217:216 (2 bits) + ds_alu_op, // 215:205 (11 bits) + ds_calc_src2_sel, // 204:201 (4 bits) + ds_calc_src1_sel, // 200:197 (4 bits) + ds_rd, // 196:192 (5 bits) + ds_rs2, // 191:187 (5 bits) + ds_rs1, // 186:182 (5 bits) + ds_zimm, // 181:177 (5 bits) + ds_csr, // 176:165 (12 bits) + ds_shamt, // 164:160 (5 bits) + ds_imm, // 159:128 (32 bits) + ds_rs2_value, // 127:96 (32 bits) + ds_rs1_value, // 95:64 (32 bits) + ds_pc, // 63:32 (32 bits) + ds_inst // 31:0 (32 bits) }; diff --git a/rv_cpu.srcs/sources_1/new/mem_stage.v b/rv_cpu.srcs/sources_1/new/mem_stage.v index b58ce16..535d3fd 100644 --- a/rv_cpu.srcs/sources_1/new/mem_stage.v +++ b/rv_cpu.srcs/sources_1/new/mem_stage.v @@ -162,7 +162,7 @@ module mem_stage #( assign ms_mem_lt_rs2 = ($signed(data_sram_rdata_i) < $signed(ms_calc_src2)); assign ms_mem_lt_rs2u = (data_sram_rdata_i < ms_calc_src2); - assign data_sram_en_o = es_to_ms_bus_valid && (|ms_result_sel || |ms_amo_op[9:0]); + assign data_sram_en_o = es_to_ms_bus_valid && |ms_amo_op[9:0]; assign data_sram_wen_o = {4{es_to_ms_bus_valid && |ms_amo_op[9:0]}}; assign data_sram_addr_o = ms_calc_src1; assign data_sram_wdata_o = {32{ms_amo_op[0]}} & (({32{ ms_mem_lt_rs2u}} & ms_calc_src2) | ({32{!ms_mem_lt_rs2u}} & data_sram_rdata_i)) // inst_amomaxu_w diff --git a/rv_cpu.srcs/sources_1/new/sub_unit/csr/csr_reg_file.v b/rv_cpu.srcs/sources_1/new/sub_unit/csr/csr_reg_file.v index 3954f8c..0c49301 100644 --- a/rv_cpu.srcs/sources_1/new/sub_unit/csr/csr_reg_file.v +++ b/rv_cpu.srcs/sources_1/new/sub_unit/csr/csr_reg_file.v @@ -27,6 +27,7 @@ module csr_reg_file( input csr_pc_i, input csr_inst_i, + input [ 1:0] csr_xret_op_i, input [ 2:0] csr_op_i, input [11:0] csr_addr_i, input [31:0] csr_wdata_i, @@ -34,12 +35,14 @@ module csr_reg_file( input [ 4:0] csr_intr_vec_i, input [31:0] csr_excp_vec_i, - output [ 1:0] csr_mpp_o, + output [ 1:0] csr_cur_pv_o, output csr_taken_o, output [31:0] csr_target_o ); + reg [ 1:0] csr_cur_pv; + reg [31:0] csr_mstatus_reg; // 0x300 reg [31:0] csr_misa_reg; // 0x301 reg [31:0] csr_medeleg_reg; // 0x302 not used @@ -54,6 +57,11 @@ module csr_reg_file( reg [31:0] csr_mip_reg; // 0x344 reg [31:0] csr_mscratch_reg; // 0x340 + wire [31:0] csr_mstatus_mask = 32'h005c_19aa; + wire [31:0] csr_misa_mask = 32'h0000_1101; + wire [31:0] csr_mie_mask = 32'h0000_0aaa; + wire [31:0] csr_mip_mask = 32'h0000_0aaa; + reg [31:0] csr_pmpcfg0_reg; // 0x3A0 not used reg [31:0] csr_pmpcfg1_reg; // 0x3A1 not used reg [31:0] csr_pmpcfg2_reg; // 0x3A2 not used @@ -159,6 +167,7 @@ module csr_reg_file( wire [31:0] csr_wdata_internal; wire csr_excp; + wire csr_xret; wire [ 4:0] csr_excp_code; wire csr_mstatus_uie; @@ -226,6 +235,19 @@ module csr_reg_file( | {32{csr_op_i[2]}} & (csr_rdata_internal & ~csr_wdata_i); assign csr_excp = |csr_excp_vec_i; + assign csr_xret = |csr_xret_op_i; + + always @(posedge clk_i or negedge rstn_i) begin + if (!rstn_i) begin + csr_cur_pv <= 2'b11; // cur design the lowest priority is M-mode + end + else if (csr_excp) begin + csr_cur_pv <= 2'b11; + end + else if(csr_xret)begin + csr_cur_pv <= {2{csr_xret_op_i[1]}} & csr_mstatus_mpp; + end + end // csr read logic always @(*) begin @@ -278,8 +300,7 @@ module csr_reg_file( // All other implemented bits are 0. // For RV32, SD bit (bit 31) is 0. FS and XS fields (bits 14:13, 16:15) are 0 (initial/dirty). csr_mstatus_reg <= 32'h0000_1800; - //csr_misa_reg <= 32'h4000_1101; // RV32IMA - csr_misa_reg <= 32'h4040_1101; // test only + csr_misa_reg <= 32'h4000_1101; // RV32IMA csr_mie_reg <= 32'b0; csr_mtvec_reg <= 32'b0; csr_mscratch_reg <= 32'b0; @@ -311,7 +332,7 @@ module csr_reg_file( 1'b0, // reserved csr_mstatus_sie, csr_mstatus_uie - }; + } & csr_mstatus_mask; // WARL csr_mepc_reg <= csr_pc_i; csr_mcause_reg <= {1'b0, 26'b0, csr_excp_code}; // {excp_sign, reserved, excp_code} csr_mtval_reg <= {32{excp_inst_addr_misalign}} & csr_pc_i @@ -319,39 +340,42 @@ module csr_reg_file( | {32{excp_breakpoint }} & 32'b0 | {32{excp_env_call_from_m }} & 32'b0; end + else if(csr_xret) begin + csr_mstatus_reg <= { + csr_mstatus_sd, + 8'b0, // reserved + csr_mstatus_tsr, + csr_mstatus_tw, + csr_mstatus_tvm, + csr_mstatus_mxr, + csr_mstatus_sum, + csr_mstatus_mprv, + csr_mstatus_xs, + csr_mstatus_fs, + 2'b11, // MPP (bits 12:11) set to cur design lowest privilege M-mode + 2'b0, // reserved + csr_mstatus_spp, // Bit 8 (SPP, typically unchanged or reflects S-mode if coming from S) + 1'b1, // MPIE (bit 7) set to 1 (default) + 1'b0, // reserved + csr_mstatus_spie, + csr_mstatus_upie, + csr_mstatus_mpie, // MIE (bit 3) set to MPIE + 1'b0, // reserved + csr_mstatus_sie, + csr_mstatus_uie + } & csr_mstatus_mask; // WARL + end else begin case({32{csr_we}} & csr_addr_i) // 0x300-0x3FF Standard read/write 12'h300: begin // mstatus - csr_mstatus_reg <= { - csr_mstatus_sd, // read-only - 8'b0, // reserved - csr_wdata_internal[22], // TSR - csr_mstatus_tw, // not used - csr_wdata_internal[20], // TVM - csr_wdata_internal[19], // MXR - csr_wdata_internal[18], // SUM - csr_mstatus_mprv, // not used - csr_mstatus_xs, // not used - csr_mstatus_fs, // not used - csr_wdata_internal[12:11], // MPP - 2'b0, // reserved - csr_wdata_internal[8], // SPP - csr_wdata_internal[7], // MPIE - 1'b0, // reserved - csr_wdata_internal[5], // SPIE - csr_mstatus_upie, // not used - csr_wdata_internal[3], // MIE - 1'b0, // reserved - csr_wdata_internal[1], // SIE - csr_mstatus_uie // not used - }; // WARL + csr_mstatus_reg <= csr_wdata_internal & csr_mstatus_mask; // WARL end 12'h301: begin // misa - csr_misa_reg <= {2'b01, 4'b0, 13'b0, csr_wdata_internal[12], 3'b0, csr_wdata_internal[8], 7'b0, csr_wdata_internal[0]}; // WARL + csr_misa_reg <= csr_wdata_internal & csr_misa_mask; // WARL end 12'h304: begin // mie - csr_mie_reg <= csr_wdata_internal; + csr_mie_reg <= csr_wdata_internal & csr_mie_mask; // WARL end 12'h305: begin // mtvec csr_mtvec_reg <= csr_wdata_internal; @@ -369,7 +393,7 @@ module csr_reg_file( csr_mtval_reg <= csr_wdata_internal; end 12'h344: begin // mip - csr_mip_reg <= csr_wdata_internal; + csr_mip_reg <= csr_wdata_internal & csr_mip_mask; // WARL end default: begin // do nothing @@ -378,10 +402,11 @@ module csr_reg_file( end end - assign csr_mpp_o = csr_mstatus_mpp; + assign csr_cur_pv_o = csr_cur_pv; - assign csr_taken_o = csr_excp; - assign csr_target_o = csr_mtvec_reg; + assign csr_taken_o = csr_excp | csr_xret; + assign csr_target_o = {32{csr_excp}} & csr_mtvec_reg + | {32{csr_xret}} & csr_mepc_reg; assign csr_rdata_o = csr_rdata_internal; endmodule diff --git a/rv_cpu.srcs/sources_1/new/sub_unit/inst_decoder.v b/rv_cpu.srcs/sources_1/new/sub_unit/inst_decoder.v index 0006f84..3d225f6 100644 --- a/rv_cpu.srcs/sources_1/new/sub_unit/inst_decoder.v +++ b/rv_cpu.srcs/sources_1/new/sub_unit/inst_decoder.v @@ -50,6 +50,8 @@ module inst_decoder( output amo_aq_o, // reserved output amo_rl_o, // reserved + output [ 1:0] xret_op_o, + output excp_illegal_inst_o, output excp_breakpoint_o, output excp_env_call_o @@ -115,8 +117,8 @@ module inst_decoder( wire inst_fence_i; wire inst_ecall; wire inst_ebreak; - wire inst_mret; // TODO - wire inst_sret; // TODO + wire inst_mret; + wire inst_sret; wire inst_csrrw; wire inst_csrrs; wire inst_csrrc; @@ -330,6 +332,8 @@ module inst_decoder( assign amo_aq_o = inst_i[26]; assign amo_rl_o = inst_i[25]; + assign xret_op_o = {inst_mret, inst_sret}; + assign excp_illegal_inst_o = !(r_type || i_type || s_type || b_type || u_type || j_type); assign excp_breakpoint_o = inst_ebreak; assign excp_env_call_o = inst_ecall;