rtl: add mem access misaligned exception
Signed-off-by: liangkangnan <liangkangnan@163.com>bram
parent
60a4f7d6df
commit
5c9f1a140e
|
@ -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
|
||||
// 异步中断
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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),
|
||||
|
|
Loading…
Reference in New Issue