rtl: add mem access misaligned exception

Signed-off-by: liangkangnan <liangkangnan@163.com>
bram
liangkangnan 2020-11-08 22:08:03 +08:00
parent 60a4f7d6df
commit 5c9f1a140e
7 changed files with 56 additions and 43 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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