Commit 87d2fe12 authored by Tristan Gingold's avatar Tristan Gingold Committed by Dimitris Lampridis

Simplify exceptions; re-enable div & mul tests.

parent a2c624b3
......@@ -90,14 +90,17 @@
`define CSR_OP_CSRRCI 3'b111
`define URV_RESET_VECTOR 32'h00000000
`define URV_TRAP_VECTOR 32'h00000040
`define EXCEPT_ILLEGAL_INSN 2
`define EXCEPT_BREAKPOINT 3
`define EXCEPT_UNALIGNED_LOAD 4
`define EXCEPT_UNALIGNED_STORE 6
`define EXCEPT_TIMER 9
`define EXCEPT_IRQ 10
`define URV_TRAP_VECTOR 32'h00000008
// Bits in mie/mip for user mode
`define EXCEPT_TIMER 4
`define EXCEPT_IRQ 8
// Cause
`define CAUSE_ILLEGAL_INSN 2
`define CAUSE_BREAKPOINT 3
`define CAUSE_UNALIGNED_LOAD 4
`define CAUSE_UNALIGNED_STORE 6
`define OP_SEL_BYPASS_X 0
`define OP_SEL_BYPASS_W 1
......
......@@ -25,33 +25,33 @@
module urv_exceptions
(
input clk_i,
input rst_i,
input clk_i,
input rst_i,
input x_stall_i,
input x_kill_i,
input x_stall_i,
input x_kill_i,
input d_is_csr_i,
input d_is_mret_i,
input d_is_csr_i,
input d_is_mret_i,
input [2:0] d_fun_i,
input [4:0] d_csr_imm_i,
input [2:0] d_fun_i,
input [4:0] d_csr_imm_i,
input [11:0] d_csr_sel_i,
input exp_irq_i,
input exp_tick_i,
input exp_breakpoint_i,
input exp_unaligned_load_i,
input exp_unaligned_store_i,
input exp_invalid_insn_i,
input exp_irq_i,
input exp_tick_i,
input exp_breakpoint_i,
input exp_unaligned_load_i,
input exp_unaligned_store_i,
input exp_invalid_insn_i,
input [31:0] x_csr_write_value_i,
output reg x_exception_o,
input x_exception_i,
input [3:0] x_exception_cause_i,
input [31:0] x_exception_pc_i,
output [31:0] x_exception_pc_o,
output [31:0] x_exception_vector_o,
input x_exception_taken_i,
output [31:0] csr_mstatus_o,
output [31:0] csr_mip_o,
......@@ -61,18 +61,15 @@ module urv_exceptions
);
reg [31:0] csr_mepc;
reg [31:0] csr_mie;
reg [31:0] csr_mie;
reg csr_ie;
reg [3:0] csr_mcause;
reg exception;
reg [3:0] cause;
reg [5:0] except_vec_masked;
reg exception_pending;
assign csr_mcause_o = {28'h0, csr_mcause};
assign csr_mepc_o = csr_mepc;
......@@ -80,21 +77,7 @@ module urv_exceptions
assign csr_mstatus_o[0] = csr_ie;
assign csr_mstatus_o[31:1] = 0;
reg [31:0] csr_mip;
always@*
begin
csr_mip <= 0;
csr_mip[`EXCEPT_ILLEGAL_INSN] <= except_vec_masked[0];
csr_mip[`EXCEPT_BREAKPOINT] <= except_vec_masked[1];
csr_mip[`EXCEPT_UNALIGNED_LOAD]<= except_vec_masked[2];
csr_mip[`EXCEPT_UNALIGNED_STORE] <= except_vec_masked[3];
csr_mip[`EXCEPT_TIMER] <= except_vec_masked[4];
csr_mip[`EXCEPT_IRQ] <= except_vec_masked[5];
end
assign csr_mip_o = csr_mip;
assign csr_mip_o = 0;
always@(posedge clk_i)
if (rst_i)
......@@ -102,26 +85,10 @@ module urv_exceptions
else begin
if(!x_stall_i && !x_kill_i && d_is_csr_i && d_csr_sel_i == `CSR_ID_MIP)
begin
except_vec_masked[0] <= x_csr_write_value_i [`EXCEPT_ILLEGAL_INSN];
except_vec_masked[1] <= x_csr_write_value_i [`EXCEPT_BREAKPOINT];
except_vec_masked[2] <= x_csr_write_value_i [`EXCEPT_UNALIGNED_LOAD];
except_vec_masked[3] <= x_csr_write_value_i [`EXCEPT_UNALIGNED_STORE];
except_vec_masked[4] <= x_csr_write_value_i [`EXCEPT_TIMER];
except_vec_masked[5] <= x_csr_write_value_i [`EXCEPT_IRQ];
end
else begin
if ( exp_invalid_insn_i )
except_vec_masked[0] <= 1'b1;
if ( exp_breakpoint_i )
except_vec_masked[1] <= 1'b1;
if ( exp_unaligned_load_i )
except_vec_masked[2] <= 1'b1;
if ( exp_unaligned_store_i )
except_vec_masked[3] <= 1'b1;
if ( exp_tick_i )
except_vec_masked[4] <= csr_mie[`EXCEPT_TIMER] & csr_ie;
......@@ -134,71 +101,37 @@ module urv_exceptions
exception <= |except_vec_masked | exp_invalid_insn_i;
assign x_exception_vector_o = 'h8;
always@*
if(exp_invalid_insn_i || except_vec_masked[0])
cause <= `EXCEPT_ILLEGAL_INSN;
else if (except_vec_masked[1])
cause <= `EXCEPT_BREAKPOINT;
else if (except_vec_masked[2])
cause <= `EXCEPT_UNALIGNED_LOAD;
else if (except_vec_masked[3])
cause <= `EXCEPT_UNALIGNED_STORE;
else if (except_vec_masked[4])
cause <= `EXCEPT_TIMER;
else
cause <= `EXCEPT_IRQ;
always@(posedge clk_i)
if(rst_i)
begin
csr_mcause <= 0;
csr_mepc <= 0;
csr_mie <= 0;
csr_ie <= 0;
exception_pending <= 0;
end
else if (!x_stall_i && !x_kill_i)
else
begin
if (d_is_mret_i)
exception_pending <= 0;
else if (x_exception_taken_i)
if (x_exception_i)
begin
csr_mepc <= x_exception_pc_i;
csr_mcause <= cause;
exception_pending <= 1;
csr_mcause <= x_exception_cause_i;
end
if (d_is_csr_i)
begin
case (d_csr_sel_i)
`CSR_ID_MSTATUS:
csr_ie <= x_csr_write_value_i[0];
`CSR_ID_MEPC:
csr_mepc <= x_csr_write_value_i;
`CSR_ID_MIE:
begin
csr_mie[`EXCEPT_ILLEGAL_INSN] <= 1;
csr_mie[`EXCEPT_BREAKPOINT] <= 1;
csr_mie[`EXCEPT_UNALIGNED_LOAD] <= 1;
csr_mie[`EXCEPT_UNALIGNED_STORE] <= 1;
csr_mie[`EXCEPT_TIMER] <= x_csr_write_value_i [`EXCEPT_TIMER];
csr_mie[`EXCEPT_IRQ] <= x_csr_write_value_i [`EXCEPT_IRQ];
end
endcase // case (d_csr_sel_i)
end // if (d_is_csr_i)
end // if (!x_stall_i && !x_kill_i)
if (!x_stall_i && !x_kill_i && d_is_csr_i)
case (d_csr_sel_i)
`CSR_ID_MSTATUS:
csr_ie <= x_csr_write_value_i[0];
`CSR_ID_MEPC:
csr_mepc <= x_csr_write_value_i;
`CSR_ID_MIE:
begin
csr_mie[`EXCEPT_TIMER] <= x_csr_write_value_i[`EXCEPT_TIMER];
csr_mie[`EXCEPT_IRQ] <= x_csr_write_value_i[`EXCEPT_IRQ];
end
endcase // case (d_csr_sel_i)
end // if (d_is_csr_i)
assign x_exception_pc_o = csr_mepc;
always@(posedge clk_i)
if (rst_i)
x_exception_o <= 0;
else if (x_exception_taken_i)
x_exception_o <= 0;
else if (exception && !exception_pending)
x_exception_o <= 1;
endmodule // urv_exceptions
......@@ -114,8 +114,8 @@ module urv_exec
reg [31:0] alu_op1, alu_op2, alu_result;
reg [31:0] rd_value;
wire exception_taken;
reg x_exception;
reg [3:0] x_exception_cause;
reg branch_take;
reg branch_condition_met;
......@@ -135,7 +135,6 @@ module urv_exec
wire [31:0] rd_csr;
wire [31:0] rd_div;
wire exception;
wire [31:0] csr_mie, csr_mip, csr_mepc, csr_mstatus,csr_mcause;
wire [31:0] csr_write_value;
wire [31:0] exception_address, exception_vector;
......@@ -193,11 +192,10 @@ module urv_exec
.exp_unaligned_store_i(1'b0),
.exp_invalid_insn_i(d_is_undef_i && !x_stall_i && !x_kill_i && d_valid_i),
.x_exception_o(exception),
.x_exception_i(x_exception),
.x_exception_cause_i(x_exception_cause),
.x_exception_pc_i(exception_pc),
.x_exception_pc_o(exception_address),
.x_exception_vector_o(exception_vector),
.x_exception_taken_i(exception_taken),
.csr_mstatus_o(csr_mstatus),
.csr_mip_o(csr_mip),
......@@ -227,8 +225,8 @@ module urv_exec
always@*
if (d_is_mret_i)
branch_target <= exception_address;
else if (exception)
branch_target <= exception_vector;
else if (x_exception)
branch_target <= `URV_TRAP_VECTOR;
else
branch_target <= dm_addr;
......@@ -356,6 +354,38 @@ module urv_exec
endcase // case (d_fun_i)
// x_exception: exception due to execution
always@*
if (x_stall_i || x_kill_i || !d_valid_i)
begin
// If the current instruction is not valid, there is no exception.
x_exception <= 0;
x_exception_cause <= 4'hx;
end
else if (d_is_undef_i)
begin
x_exception <= 1;
x_exception_cause <= `CAUSE_ILLEGAL_INSN;
end
else
case (d_opcode_i)
`OPC_LOAD:
begin
x_exception <= unaligned_addr;
x_exception_cause <= `CAUSE_UNALIGNED_LOAD;
end
`OPC_STORE:
begin
x_exception <= unaligned_addr;
x_exception_cause <= `CAUSE_UNALIGNED_STORE;
end
default:
begin
x_exception <= 0;
x_exception_cause <= 4'hx;
end
endcase
// generate store value/select
always@*
case (d_fun_i)
......@@ -392,7 +422,7 @@ module urv_exec
//branch decision
always@*
if( exception || d_is_mret_i)
if (x_exception)
branch_take <= 1;
else
case (d_opcode_i)
......@@ -400,6 +430,8 @@ module urv_exec
branch_take <= 1;
`OPC_BRANCH:
branch_take <= branch_condition_met;
`OPC_SYSTEM:
branch_take <= d_is_mret_i;
default:
branch_take <= 0;
endcase // case (d_opcode_i)
......@@ -411,8 +443,8 @@ module urv_exec
assign dm_data_s_o = dm_data_s;
assign dm_data_select_o = dm_select_s;
assign dm_load_o = d_is_load_i & d_valid_i & !x_kill_i & !x_stall_i & !exception;
assign dm_store_o = d_is_store_i & d_valid_i & !x_kill_i & !x_stall_i & !exception;
assign dm_load_o = d_is_load_i & d_valid_i & !x_kill_i & !x_stall_i & !x_exception;
assign dm_store_o = d_is_store_i & d_valid_i & !x_kill_i & !x_stall_i & !x_exception;
// X/W pipeline registers
......@@ -428,25 +460,24 @@ module urv_exec
else if (!x_stall_i)
begin
f_branch_target_o <= branch_target;
f_branch_take <= branch_take && !x_kill_i && (d_valid_i || exception);
f_branch_take <= branch_take && !x_kill_i && d_valid_i;
w_rd_o <= d_rd_i;
w_rd_value_o <= rd_value;
w_rd_write_o <= d_rd_write_i && !x_kill_i && d_valid_i && !exception;
w_load_o <= d_is_load_i && !x_kill_i && d_valid_i && !exception;
w_store_o <= d_is_store_i && !x_kill_i && d_valid_i && !exception;
w_rd_write_o <= d_rd_write_i && !x_kill_i && d_valid_i && !x_exception;
w_load_o <= d_is_load_i && !x_kill_i && d_valid_i && !x_exception;
w_store_o <= d_is_store_i && !x_kill_i && d_valid_i && !x_exception;
w_rd_source_o <= d_rd_source_i;
w_fun_o <= d_fun_i;
w_dm_addr_o <= dm_addr;
w_valid_o <= !exception;
w_valid_o <= !x_exception;
end
always@*
exception_pc <= d_pc_i;
assign f_branch_take_o = f_branch_take;
assign exception_taken = exception && (branch_take && !x_kill_i && (d_valid_i || exception));
// pipeline control: generate stall request signal
always@*
......
......@@ -10,8 +10,8 @@ rv32ui-p-bgeu.ram
rv32ui-p-blt.ram
rv32ui-p-bltu.ram
rv32ui-p-bne.ram
#rv32ui-p-div.ram
#rv32ui-p-divu.ram
rv32ui-p-div.ram
rv32ui-p-divu.ram
rv32ui-p-jal.ram
rv32ui-p-jalr.ram
rv32ui-p-j.ram
......@@ -21,14 +21,14 @@ rv32ui-p-lh.ram
rv32ui-p-lhu.ram
rv32ui-p-lui.ram
rv32ui-p-lw.ram
#rv32ui-p-mulh.ram
#rv32ui-p-mulhsu.ram
#rv32ui-p-mulhu.ram
rv32ui-p-mulh.ram
rv32ui-p-mulhsu.ram
rv32ui-p-mulhu.ram
rv32ui-p-mul.ram
rv32ui-p-ori.ram
rv32ui-p-or.ram
#rv32ui-p-rem.ram
#rv32ui-p-remu.ram
rv32ui-p-rem.ram
rv32ui-p-remu.ram
rv32ui-p-sb.ram
rv32ui-p-sh.ram
rv32ui-p-simple.ram
......
......@@ -6,4 +6,4 @@ set NumericStdNoWarnings 1
#do wave.do
radix -hexadecimal
run 1ms
run 2ms
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment