diff --git a/rtl/core/clint.v b/rtl/core/clint.v index c17d83e..6537ae8 100644 --- a/rtl/core/clint.v +++ b/rtl/core/clint.v @@ -32,6 +32,7 @@ module clint( input wire inst_mret_i, // mret指令 input wire[31:0] inst_addr_i, // 指令地址 input wire jump_flag_i, + input wire mem_access_misaligned_i, // from csr_reg input wire[31:0] csr_mtvec_i, // mtvec寄存器 @@ -93,7 +94,7 @@ module clint( // 中断仲裁逻辑 always @ (*) begin // 同步中断 - if (inst_ecall_i | inst_ebreak_i) begin + if (inst_ecall_i | inst_ebreak_i | mem_access_misaligned_i) begin int_state = S_INT_SYNC_ASSERT; // 异步中断 end else if ((int_flag_i != `INT_NONE) & global_int_en & inst_addr_valid) begin @@ -124,6 +125,7 @@ module clint( inst_addr <= inst_addr_i; cause <= inst_ebreak_i? 32'd3: inst_ecall_i? 32'd11: + mem_access_misaligned_i? 32'd4: 32'd10; end // 异步中断 diff --git a/rtl/core/exu.v b/rtl/core/exu.v index f63b656..f65797a 100644 --- a/rtl/core/exu.v +++ b/rtl/core/exu.v @@ -41,12 +41,9 @@ module exu( output wire[3:0] mem_sel_o, // 瀛楄妭浣 output wire mem_req_valid_o, output wire mem_rsp_ready_o, + output wire mem_access_misaligned_o, // gpr_reg - input wire[31:0] reg1_rdata_i, // 閫氱敤瀵勫瓨鍣1杈撳叆鏁版嵁 - input wire[31:0] reg2_rdata_i, // 閫氱敤瀵勫瓨鍣2杈撳叆鏁版嵁 - output wire[4:0] reg1_raddr_o, // 璇婚氱敤瀵勫瓨鍣1鍦板潃 - output wire[4:0] reg2_raddr_o, // 璇婚氱敤瀵勫瓨鍣2鍦板潃 output wire[31:0] reg_wdata_o, // 鍐欏瘎瀛樺櫒鏁版嵁 output wire reg_we_o, // 鏄惁瑕佸啓閫氱敤瀵勫瓨鍣 output wire[4:0] reg_waddr_o, // 鍐欓氱敤瀵勫瓨鍣ㄥ湴鍧 @@ -68,9 +65,9 @@ module exu( input wire[31:0] dec_imm_i, input wire[31:0] dec_pc_i, input wire[31:0] next_pc_i, - input wire[4:0] rs1_raddr_i, - input wire[4:0] rs2_raddr_i, input wire[4:0] rd_waddr_i, + input wire[31:0] reg1_rdata_i, // 閫氱敤瀵勫瓨鍣1杈撳叆鏁版嵁 + input wire[31:0] reg2_rdata_i, // 閫氱敤瀵勫瓨鍣2杈撳叆鏁版嵁 input wire rd_we_i ); @@ -300,6 +297,7 @@ module exu( .mem_op_sb_i(mem_op_sb_o), .mem_op_sh_i(mem_op_sh_o), .mem_op_sw_i(mem_op_sw_o), + .mem_access_misaligned_o(mem_access_misaligned_o), .mem_stall_o(mem_stall_o), .mem_addr_o(mem_addr_o), .mem_wdata_o(mem_wdata), @@ -363,9 +361,6 @@ module exu( assign reg_we_o = commit_reg_we_o; - assign reg1_raddr_o = rs1_raddr_i; - assign reg2_raddr_o = rs2_raddr_i; - assign jump_flag_o = bjp_cmp_res_o | bjp_op_jump_o | sys_op_fence_o | int_assert_i; assign jump_addr_o = int_assert_i? int_addr_i: sys_op_fence_o? next_pc_i: diff --git a/rtl/core/exu_mem.v b/rtl/core/exu_mem.v index 5591ccc..2c69a04 100644 --- a/rtl/core/exu_mem.v +++ b/rtl/core/exu_mem.v @@ -37,6 +37,7 @@ module exu_mem( input wire mem_op_sh_i, input wire mem_op_sw_i, + output wire mem_access_misaligned_o, output wire mem_stall_o, output wire[31:0] mem_addr_o, output wire[31:0] mem_wdata_o, @@ -119,4 +120,8 @@ module exu_mem( // 鍐欏唴瀛樹娇鑳 assign mem_mem_we_o = (mem_op_sb_i | mem_op_sh_i | mem_op_sw_i) & mem_rsp_hsked_r; + assign mem_access_misaligned_o = (mem_op_sw_i | mem_op_lw_i)? (mem_addr_i[0] | mem_addr_i[1]): + (mem_op_sh_i | mem_op_lh_i | mem_op_lhu_i)? mem_addr_i[0]: + 0; + endmodule diff --git a/rtl/core/gpr_reg.v b/rtl/core/gpr_reg.v index c6e5bdc..8d0941f 100644 --- a/rtl/core/gpr_reg.v +++ b/rtl/core/gpr_reg.v @@ -40,20 +40,20 @@ module gpr_reg( genvar i; generate - for (i = 0; i < 32; i = i + 1) begin + for (i = 0; i < 32; i = i + 1) begin: gpr_rw // x0 cannot be wrote since it is constant-zeros - if (i == 0) begin + if (i == 0) begin: is_x0 assign we[i] = 1'b0; assign regs[i] = 32'h0; - end else begin + end else begin: not_x0 assign we[i] = we_i & (waddr_i == i); gen_en_dffnr #(32) rf_dff(clk, we[i], wdata_i, regs[i]); end end endgenerate - assign rdata1_o = regs[raddr1_i]; - assign rdata2_o = regs[raddr2_i]; + assign rdata1_o = (|raddr1_i)? ((we_i & (waddr_i == raddr1_i))? wdata_i: regs[raddr1_i]): 32'h0; + assign rdata2_o = (|raddr2_i)? ((we_i & (waddr_i == raddr2_i))? wdata_i: regs[raddr2_i]): 32'h0; // for debug wire[31:0] ra = regs[1]; diff --git a/rtl/core/idu.v b/rtl/core/idu.v index c54014a..9cf9def 100644 --- a/rtl/core/idu.v +++ b/rtl/core/idu.v @@ -27,6 +27,10 @@ module idu( input wire[31:0] inst_i, // 鎸囦护鍐呭 input wire[31:0] inst_addr_i, // 鎸囦护鍦板潃 + // from gpr_reg + input wire[31:0] rs1_rdata_i, // 閫氱敤瀵勫瓨鍣1杈撳叆鏁版嵁 + input wire[31:0] rs2_rdata_i, // 閫氱敤瀵勫瓨鍣2杈撳叆鏁版嵁 + output wire stall_o, // to id_ex @@ -36,12 +40,16 @@ module idu( output wire[31:0] dec_pc_o, output wire[4:0] rs1_raddr_o, output wire[4:0] rs2_raddr_o, + output wire[31:0] rs1_rdata_o, + output wire[31:0] rs2_rdata_o, output wire[4:0] rd_waddr_o, output wire rd_we_o ); assign inst_o = inst_i; + assign rs1_rdata_o = rs1_rdata_i; + assign rs2_rdata_o = rs2_rdata_i; // 鍙栧嚭鎸囦护涓殑姣忎竴涓煙 wire[6:0] opcode = inst_i[6:0]; diff --git a/rtl/core/idu_exu.v b/rtl/core/idu_exu.v index 5ef93bb..79f38ae 100644 --- a/rtl/core/idu_exu.v +++ b/rtl/core/idu_exu.v @@ -29,8 +29,8 @@ module idu_exu( input wire[`DECINFO_WIDTH-1:0] dec_info_bus_i, input wire[31:0] dec_imm_i, input wire[31:0] dec_pc_i, - input wire[4:0] rs1_raddr_i, - input wire[4:0] rs2_raddr_i, + input wire[31:0] rs1_rdata_i, + input wire[31:0] rs2_rdata_i, input wire[4:0] rd_waddr_i, input wire rd_we_i, @@ -38,8 +38,8 @@ module idu_exu( output wire[`DECINFO_WIDTH-1:0] dec_info_bus_o, output wire[31:0] dec_imm_o, output wire[31:0] dec_pc_o, - output wire[4:0] rs1_raddr_o, - output wire[4:0] rs2_raddr_o, + output wire[31:0] rs1_rdata_o, + output wire[31:0] rs2_rdata_o, output wire[4:0] rd_waddr_o, output wire rd_we_o @@ -62,15 +62,15 @@ module idu_exu( gen_en_dff #(32) pc_ff(clk, rst_n, en, i_dec_pc, dec_pc); assign dec_pc_o = dec_pc; - wire[4:0] i_rs1_raddr = flush_i? 5'h0: rs1_raddr_i; - wire[4:0] rs1_raddr; - gen_en_dff #(5) rs1_raddr_ff(clk, rst_n, en, i_rs1_raddr, rs1_raddr); - assign rs1_raddr_o = rs1_raddr; + wire[31:0] i_rs1_rdata = flush_i? 32'h0: rs1_rdata_i; + wire[31:0] rs1_rdata; + gen_en_dff #(32) rs1_rdata_ff(clk, rst_n, en, i_rs1_rdata, rs1_rdata); + assign rs1_rdata_o = rs1_rdata; - wire[4:0] i_rs2_raddr = flush_i? 5'h0: rs2_raddr_i; - wire[4:0] rs2_raddr; - gen_en_dff #(5) rs2_raddr_ff(clk, rst_n, en, i_rs2_raddr, rs2_raddr); - assign rs2_raddr_o = rs2_raddr; + wire[31:0] i_rs2_rdata = flush_i? 32'h0: rs2_rdata_i; + wire[31:0] rs2_rdata; + gen_en_dff #(32) rs2_rdata_ff(clk, rst_n, en, i_rs2_rdata, rs2_rdata); + assign rs2_rdata_o = rs2_rdata; wire[4:0] i_rd_waddr = flush_i? 5'h0: rd_waddr_i; wire[4:0] rd_waddr; diff --git a/rtl/core/tinyriscv_core.v b/rtl/core/tinyriscv_core.v index 22cc848..98bbde3 100644 --- a/rtl/core/tinyriscv_core.v +++ b/rtl/core/tinyriscv_core.v @@ -68,6 +68,8 @@ module tinyriscv_core( wire[4:0] id_rd_waddr_o; wire id_rd_we_o; wire id_stall_o; + wire[31:0] id_rs1_rdata_o; + wire[31:0] id_rs2_rdata_o; // idu_exu妯″潡杈撳嚭淇″彿 wire[31:0] ie_inst_o; @@ -75,8 +77,8 @@ module tinyriscv_core( wire[`DECINFO_WIDTH-1:0] ie_dec_info_bus_o; wire[31:0] ie_dec_imm_o; wire[31:0] ie_dec_pc_o; - wire[4:0] ie_rs1_raddr_o; - wire[4:0] ie_rs2_raddr_o; + wire[31:0] ie_rs1_rdata_o; + wire[31:0] ie_rs2_rdata_o; wire[4:0] ie_rd_waddr_o; wire ie_rd_we_o; @@ -87,11 +89,10 @@ module tinyriscv_core( wire[3:0] ex_mem_sel_o; wire ex_mem_req_valid_o; wire ex_mem_rsp_ready_o; + wire ex_mem_access_misaligned_o; wire[31:0] ex_reg_wdata_o; wire ex_reg_we_o; wire[4:0] ex_reg_waddr_o; - wire[4:0] ex_reg1_raddr_o; - wire[4:0] ex_reg2_raddr_o; wire ex_hold_flag_o; wire ex_jump_flag_o; wire[31:0] ex_jump_addr_o; @@ -176,9 +177,9 @@ module tinyriscv_core( .we_i(ex_reg_we_o), .waddr_i(ex_reg_waddr_o), .wdata_i(ex_reg_wdata_o), - .raddr1_i(ex_reg1_raddr_o), + .raddr1_i(id_rs1_raddr_o), .rdata1_o(regs_rdata1_o), - .raddr2_i(ex_reg2_raddr_o), + .raddr2_i(id_rs2_raddr_o), .rdata2_o(regs_rdata2_o) ); @@ -214,8 +215,12 @@ module tinyriscv_core( .clk(clk), .rst_n(rst_n), .inst_i(if_inst_o), + .rs1_rdata_i(regs_rdata1_o), + .rs2_rdata_i(regs_rdata2_o), .inst_o(id_inst_o), .inst_addr_i(if_inst_addr_o), + .rs1_rdata_o(id_rs1_rdata_o), + .rs2_rdata_o(id_rs2_rdata_o), .stall_o(id_stall_o), .dec_info_bus_o(id_dec_info_bus_o), .dec_imm_o(id_dec_imm_o), @@ -235,16 +240,16 @@ module tinyriscv_core( .dec_info_bus_i(id_dec_info_bus_o), .dec_imm_i(id_dec_imm_o), .dec_pc_i(id_dec_pc_o), - .rs1_raddr_i(id_rs1_raddr_o), - .rs2_raddr_i(id_rs2_raddr_o), + .rs1_rdata_i(id_rs1_rdata_o), + .rs2_rdata_i(id_rs2_rdata_o), .rd_waddr_i(id_rd_waddr_o), .rd_we_i(id_rd_we_o), .inst_o(ie_inst_o), .dec_info_bus_o(ie_dec_info_bus_o), .dec_imm_o(ie_dec_imm_o), .dec_pc_o(ie_dec_pc_o), - .rs1_raddr_o(ie_rs1_raddr_o), - .rs2_raddr_o(ie_rs2_raddr_o), + .rs1_rdata_o(ie_rs1_rdata_o), + .rs2_rdata_o(ie_rs2_rdata_o), .rd_waddr_o(ie_rd_waddr_o), .rd_we_o(ie_rd_we_o) ); @@ -252,10 +257,8 @@ module tinyriscv_core( exu u_exu( .clk(clk), .rst_n(rst_n), - .reg1_raddr_o(ex_reg1_raddr_o), - .reg2_raddr_o(ex_reg2_raddr_o), - .reg1_rdata_i(regs_rdata1_o), - .reg2_rdata_i(regs_rdata2_o), + .reg1_rdata_i(ie_rs1_rdata_o), + .reg2_rdata_i(ie_rs2_rdata_o), .mem_rdata_i(dbus_data_i), .mem_req_ready_i(dbus_req_ready_i), .mem_rsp_valid_i(dbus_rsp_valid_i), @@ -265,6 +268,7 @@ module tinyriscv_core( .mem_sel_o(ex_mem_sel_o), .mem_req_valid_o(ex_mem_req_valid_o), .mem_rsp_ready_o(ex_mem_rsp_ready_o), + .mem_access_misaligned_o(ex_mem_access_misaligned_o), .reg_wdata_o(ex_reg_wdata_o), .reg_we_o(ex_reg_we_o), .reg_waddr_o(ex_reg_waddr_o), @@ -286,8 +290,6 @@ module tinyriscv_core( .dec_imm_i(ie_dec_imm_o), .dec_pc_i(ie_dec_pc_o), .next_pc_i(if_inst_addr_o), - .rs1_raddr_i(ie_rs1_raddr_o), - .rs2_raddr_i(ie_rs2_raddr_o), .rd_waddr_i(ie_rd_waddr_o), .rd_we_i(ie_rd_we_o) ); @@ -301,6 +303,7 @@ module tinyriscv_core( .inst_mret_i(ex_inst_mret_o), .inst_addr_i(ie_dec_pc_o), .jump_flag_i(ex_jump_flag_o), + .mem_access_misaligned_i(ex_mem_access_misaligned_o), .csr_mtvec_i(csr_mtvec_o), .csr_mepc_i(csr_mepc_o), .csr_mstatus_i(csr_mstatus_o),