mirror of
https://github.com/olofk/serv.git
synced 2026-01-11 23:42:50 +00:00
Optimize trap handling
This commit is contained in:
parent
8d5dd77a26
commit
6fbdea58d6
Binary file not shown.
|
Before Width: | Height: | Size: 67 KiB After Width: | Height: | Size: 71 KiB |
@ -3,6 +3,7 @@ module serv_csr
|
||||
(
|
||||
input wire i_clk,
|
||||
//State
|
||||
input wire i_init,
|
||||
input wire i_en,
|
||||
input wire i_cnt0to3,
|
||||
input wire i_cnt3,
|
||||
@ -11,8 +12,7 @@ module serv_csr
|
||||
input wire i_mem_op,
|
||||
input wire i_mtip,
|
||||
input wire i_trap,
|
||||
input wire i_pending_irq,
|
||||
output wire o_new_irq,
|
||||
output reg o_new_irq,
|
||||
//Control
|
||||
input wire i_e_op,
|
||||
input wire i_ebreak,
|
||||
@ -71,15 +71,15 @@ module serv_csr
|
||||
|
||||
assign o_csr_in = csr_in;
|
||||
|
||||
assign o_new_irq = !timer_irq_r & timer_irq;
|
||||
|
||||
|
||||
always @(posedge i_clk) begin
|
||||
if (!i_init & i_cnt_done) begin
|
||||
timer_irq_r <= timer_irq;
|
||||
o_new_irq <= timer_irq & !timer_irq_r;
|
||||
end
|
||||
|
||||
if (i_mie_en & i_cnt7)
|
||||
mie_mtie <= csr_in;
|
||||
|
||||
timer_irq_r <= timer_irq;
|
||||
|
||||
/*
|
||||
The mie bit in mstatus gets updated under three conditions
|
||||
|
||||
@ -124,12 +124,12 @@ module serv_csr
|
||||
*/
|
||||
if (i_mcause_en & i_en & i_cnt0to3 | (i_trap & i_cnt_done)) begin
|
||||
mcause3_0[3] <= (i_e_op & !i_ebreak) | (!i_trap & csr_in);
|
||||
mcause3_0[2] <= i_pending_irq | i_mem_op | (!i_trap & mcause3_0[3]);
|
||||
mcause3_0[1] <= i_pending_irq | i_e_op | (i_mem_op & i_mem_cmd) | (!i_trap & mcause3_0[2]);
|
||||
mcause3_0[0] <= i_pending_irq | i_e_op | (!i_trap & mcause3_0[1]);
|
||||
mcause3_0[2] <= o_new_irq | i_mem_op | (!i_trap & mcause3_0[3]);
|
||||
mcause3_0[1] <= o_new_irq | i_e_op | (i_mem_op & i_mem_cmd) | (!i_trap & mcause3_0[2]);
|
||||
mcause3_0[0] <= o_new_irq | i_e_op | (!i_trap & mcause3_0[1]);
|
||||
end
|
||||
if (i_mcause_en & i_cnt_done | i_trap)
|
||||
mcause31 <= i_trap ? i_pending_irq : csr_in;
|
||||
mcause31 <= i_trap ? o_new_irq : csr_in;
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
@ -5,7 +5,6 @@ module serv_state
|
||||
input wire i_clk,
|
||||
input wire i_rst,
|
||||
input wire i_new_irq,
|
||||
output reg o_pending_irq,
|
||||
input wire i_dbus_ack,
|
||||
output wire o_ibus_cyc,
|
||||
input wire i_ibus_ack,
|
||||
@ -49,6 +48,7 @@ module serv_state
|
||||
|
||||
reg stage_two_req;
|
||||
reg init_done;
|
||||
reg misalign_trap_sync;
|
||||
|
||||
reg [4:2] o_cnt;
|
||||
reg [3:0] o_cnt_r;
|
||||
@ -70,7 +70,7 @@ module serv_state
|
||||
assign cnt4 = (o_cnt[4:2] == 3'd1) & o_cnt_r[0];
|
||||
assign o_cnt7 = (o_cnt[4:2] == 3'd1) & o_cnt_r[3];
|
||||
|
||||
|
||||
|
||||
assign o_alu_shamt_en = o_cnt0to3 | cnt4 | !o_init;
|
||||
|
||||
//Take branch for jump or branch instructions (opcode == 1x0xx) if
|
||||
@ -86,14 +86,16 @@ module serv_state
|
||||
|
||||
assign o_dbus_cyc = !o_cnt_en & init_done & i_mem_op & !i_mem_misalign;
|
||||
|
||||
wire trap_pending = WITH_CSR & ((o_ctrl_jump & i_ctrl_misalign) | (i_mem_op & i_mem_misalign));
|
||||
|
||||
//Prepare RF for reads when a new instruction is fetched
|
||||
// or when stage one caused an exception (rreq implies a write request too)
|
||||
assign o_rf_rreq = i_ibus_ack | (stage_two_req & trap_pending);
|
||||
assign o_rf_rreq = i_ibus_ack | (stage_two_req & misalign_trap_sync);
|
||||
|
||||
//Prepare RF for writes when everything is ready to enter stage two
|
||||
assign o_rf_wreq = ((i_shift_op & (i_alu_sh_done | !i_sh_right) & init_done) | (i_mem_op & i_dbus_ack) | (stage_two_req & (i_slt_op | i_branch_op))) & !trap_pending;
|
||||
// and the first stage didn't cause a misalign exception
|
||||
assign o_rf_wreq = !misalign_trap_sync &
|
||||
((i_shift_op & (i_alu_sh_done | !i_sh_right) & init_done) |
|
||||
(i_mem_op & i_dbus_ack) |
|
||||
(stage_two_req & (i_slt_op | i_branch_op)));
|
||||
|
||||
assign o_rf_rd_en = i_rd_op & o_cnt_en & !o_init;
|
||||
|
||||
@ -112,7 +114,7 @@ module serv_state
|
||||
|
||||
assign o_ibus_cyc = ibus_cyc & !i_rst;
|
||||
|
||||
assign o_init = two_stage_op & !o_pending_irq & !init_done;
|
||||
assign o_init = two_stage_op & !i_new_irq & !init_done;
|
||||
|
||||
always @(posedge i_clk) begin
|
||||
//ibus_cyc changes on three conditions.
|
||||
@ -170,38 +172,24 @@ module serv_state
|
||||
end
|
||||
end
|
||||
|
||||
assign o_ctrl_trap = WITH_CSR & (i_e_op | i_new_irq | misalign_trap_sync);
|
||||
|
||||
generate
|
||||
if (WITH_CSR) begin
|
||||
reg irq_sync;
|
||||
reg misalign_trap_sync;
|
||||
//trap_pending is only guaranteed to have correct value during the
|
||||
// last cycle of the init stage
|
||||
wire trap_pending = WITH_CSR & ((take_branch & i_ctrl_misalign) |
|
||||
(i_mem_op & i_mem_misalign));
|
||||
|
||||
assign o_ctrl_trap = i_e_op | o_pending_irq | misalign_trap_sync;
|
||||
|
||||
always @(posedge i_clk) begin
|
||||
if (i_ibus_ack)
|
||||
irq_sync <= 1'b0;
|
||||
if (i_new_irq)
|
||||
irq_sync <= 1'b1;
|
||||
|
||||
if (i_ibus_ack)
|
||||
o_pending_irq <= irq_sync;
|
||||
|
||||
if (stage_two_req)
|
||||
misalign_trap_sync <= trap_pending;
|
||||
if (o_cnt_done)
|
||||
misalign_trap_sync <= 1'b0;
|
||||
if (i_rst)
|
||||
if (RESET_STRATEGY != "NONE") begin
|
||||
misalign_trap_sync <= 1'b0;
|
||||
irq_sync <= 1'b0;
|
||||
o_pending_irq <= 1'b0;
|
||||
end
|
||||
|
||||
end // always @ (posedge i_clk)
|
||||
end else begin
|
||||
assign o_ctrl_trap = 0;
|
||||
always @(*)
|
||||
o_pending_irq = 1'b0;
|
||||
end
|
||||
always @(posedge i_clk) begin
|
||||
if (o_cnt_done)
|
||||
misalign_trap_sync <= trap_pending & o_init;
|
||||
if (i_rst)
|
||||
if (RESET_STRATEGY != "NONE")
|
||||
misalign_trap_sync <= 1'b0;
|
||||
end
|
||||
end else
|
||||
always @(*)
|
||||
misalign_trap_sync = 1'b0;
|
||||
endgenerate
|
||||
endmodule
|
||||
|
||||
@ -149,7 +149,6 @@ module serv_top
|
||||
wire rf_csr_out;
|
||||
|
||||
wire new_irq;
|
||||
wire pending_irq;
|
||||
|
||||
wire [1:0] lsb;
|
||||
|
||||
@ -162,7 +161,6 @@ module serv_top
|
||||
.i_rst (i_rst),
|
||||
//State
|
||||
.i_new_irq (new_irq),
|
||||
.o_pending_irq (pending_irq),
|
||||
.i_alu_cmp (alu_cmp),
|
||||
.o_init (init),
|
||||
.o_cnt_en (cnt_en),
|
||||
@ -428,6 +426,7 @@ module serv_top
|
||||
(
|
||||
.i_clk (clk),
|
||||
//State
|
||||
.i_init (init),
|
||||
.i_en (cnt_en),
|
||||
.i_cnt0to3 (cnt0to3),
|
||||
.i_cnt3 (cnt3),
|
||||
@ -436,7 +435,6 @@ module serv_top
|
||||
.i_mem_op (mem_op),
|
||||
.i_mtip (i_timer_irq),
|
||||
.i_trap (trap),
|
||||
.i_pending_irq (pending_irq),
|
||||
.o_new_irq (new_irq),
|
||||
//Control
|
||||
.i_e_op (e_op),
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user