fix bug & update xret
This commit is contained in:
@@ -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),
|
||||
|
||||
@@ -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)
|
||||
);
|
||||
|
||||
@@ -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)
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user