fix bug & update xret

This commit is contained in:
2025-05-23 20:10:03 +08:00
parent 9135170576
commit a0bf7f174f
6 changed files with 107 additions and 71 deletions

View File

@@ -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),

View File

@@ -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)
);

View File

@@ -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)
};

View File

@@ -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

View File

@@ -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

View File

@@ -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;