mirror of
https://github.com/olofk/serv.git
synced 2025-04-23 05:17:06 -04:00
Simplify and document trap handling
This commit is contained in:
parent
4a5c5bd588
commit
d5febe8f63
7 changed files with 33 additions and 36 deletions
Binary file not shown.
Before Width: | Height: | Size: 66 KiB After Width: | Height: | Size: 67 KiB |
Binary file not shown.
Before Width: | Height: | Size: 64 KiB After Width: | Height: | Size: 62 KiB |
|
@ -8,9 +8,9 @@ module serv_csr
|
|||
input wire i_cnt3,
|
||||
input wire i_cnt7,
|
||||
input wire i_cnt_done,
|
||||
input wire i_mem_misalign,
|
||||
input wire i_mem_op,
|
||||
input wire i_mtip,
|
||||
input wire i_trap_taken,
|
||||
input wire i_trap,
|
||||
input wire i_pending_irq,
|
||||
output wire o_new_irq,
|
||||
//Control
|
||||
|
@ -90,14 +90,14 @@ module serv_csr
|
|||
|
||||
These conditions are all mutually exclusibe
|
||||
*/
|
||||
if (i_trap_taken | i_mstatus_en & i_cnt3 | i_mret)
|
||||
mstatus_mie <= !i_trap_taken & (i_mret ? mstatus_mpie : csr_in);
|
||||
if ((i_trap & i_cnt_done) | i_mstatus_en & i_cnt3 | i_mret)
|
||||
mstatus_mie <= !i_trap & (i_mret ? mstatus_mpie : csr_in);
|
||||
|
||||
/*
|
||||
Note: To save resources mstatus_mpie (mstatus bit 7) is not
|
||||
readable or writable from sw
|
||||
*/
|
||||
if (i_trap_taken)
|
||||
if (i_trap & i_cnt_done)
|
||||
mstatus_mpie <= mstatus_mie;
|
||||
|
||||
/*
|
||||
|
@ -115,16 +115,21 @@ module serv_csr
|
|||
if it was caused by an ebreak instruction (3),
|
||||
ecall instruction (11), misaligned load (4), misaligned store (6)
|
||||
or misaligned jump (0)
|
||||
*/
|
||||
if (i_mcause_en & i_en & i_cnt0to3 | i_trap_taken)
|
||||
mcause3_0 <= !i_trap_taken ? {csr_in, mcause3_0[3:1]} :
|
||||
i_pending_irq ? 4'd7 :
|
||||
i_e_op ? {!i_ebreak, 3'b011} :
|
||||
i_mem_misalign ? {2'b01, i_mem_cmd, 1'b0} :
|
||||
4'd0;
|
||||
|
||||
if (i_mcause_en & i_cnt_done | i_trap_taken)
|
||||
mcause31 <= i_trap_taken ? i_pending_irq : csr_in;
|
||||
The expressions below are derived from the following truth table
|
||||
irq => 0111 (timer=7)
|
||||
e_op => x011 (ebreak=3, ecall=11)
|
||||
mem => 01x0 (store=6, load=4)
|
||||
ctrl => 0000 (jump=0)
|
||||
*/
|
||||
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]);
|
||||
end
|
||||
if (i_mcause_en & i_cnt_done | i_trap)
|
||||
mcause31 <= i_trap ? i_pending_irq : csr_in;
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
|
@ -59,15 +59,12 @@ module serv_mem_if
|
|||
if (dat_valid)
|
||||
signbit <= dat_cur;
|
||||
end
|
||||
generate
|
||||
if (WITH_CSR) begin
|
||||
reg misalign;
|
||||
always @(posedge i_clk)
|
||||
misalign <= (i_lsb[0] & (i_word | i_half)) | (i_lsb[1] & i_word);
|
||||
assign o_misalign = misalign & i_mem_op;
|
||||
end else begin
|
||||
assign o_misalign = 1'b0;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
/*
|
||||
mem_misalign is checked after the init stage to decide whether to do a data
|
||||
bus transaction or go to the trap state. It is only guaranteed to be correct
|
||||
at this time
|
||||
*/
|
||||
assign o_misalign = WITH_CSR & ((i_lsb[0] & (i_word | i_half)) | (i_lsb[1] & i_word));
|
||||
|
||||
endmodule
|
||||
|
|
|
@ -17,7 +17,7 @@ module serv_rf_if
|
|||
input wire i_trap,
|
||||
input wire i_mret,
|
||||
input wire i_mepc,
|
||||
input wire i_mem_misalign,
|
||||
input wire i_mem_op,
|
||||
input wire i_bufreg_q,
|
||||
input wire i_bad_pc,
|
||||
output wire o_csr_pc,
|
||||
|
@ -59,7 +59,7 @@ module serv_rf_if
|
|||
(i_csr_rd & i_rd_csr_en) |
|
||||
(i_mem_rd);
|
||||
|
||||
wire mtval = i_mem_misalign ? i_bufreg_q : i_bad_pc;
|
||||
wire mtval = i_mem_op ? i_bufreg_q : i_bad_pc;
|
||||
|
||||
assign o_wdata0 = i_trap ? mtval : rd;
|
||||
assign o_wdata1 = i_trap ? i_mepc : i_csr;
|
||||
|
|
|
@ -5,7 +5,6 @@ module serv_state
|
|||
input wire i_clk,
|
||||
input wire i_rst,
|
||||
input wire i_new_irq,
|
||||
output wire o_trap_taken,
|
||||
output reg o_pending_irq,
|
||||
input wire i_dbus_ack,
|
||||
output wire o_ibus_cyc,
|
||||
|
@ -83,7 +82,7 @@ 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_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)
|
||||
|
@ -174,7 +173,6 @@ module serv_state
|
|||
reg misalign_trap_sync;
|
||||
|
||||
assign o_ctrl_trap = i_e_op | o_pending_irq | misalign_trap_sync;
|
||||
assign o_trap_taken = i_ibus_ack & o_ctrl_trap;
|
||||
|
||||
always @(posedge i_clk) begin
|
||||
if (i_ibus_ack)
|
||||
|
@ -187,7 +185,7 @@ module serv_state
|
|||
|
||||
if (stage_two_req)
|
||||
misalign_trap_sync <= trap_pending;
|
||||
if (i_ibus_ack)
|
||||
if (o_cnt_done)
|
||||
misalign_trap_sync <= 1'b0;
|
||||
if (i_rst)
|
||||
if (RESET_STRATEGY != "NONE") begin
|
||||
|
@ -198,7 +196,6 @@ module serv_state
|
|||
|
||||
end // always @ (posedge i_clk)
|
||||
end else begin
|
||||
assign o_trap_taken = 0;
|
||||
assign o_ctrl_trap = 0;
|
||||
always @(*)
|
||||
o_pending_irq = 1'b0;
|
||||
|
|
|
@ -148,7 +148,6 @@ module serv_top
|
|||
wire rf_csr_out;
|
||||
|
||||
wire new_irq;
|
||||
wire trap_taken;
|
||||
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_trap_taken (trap_taken),
|
||||
.o_pending_irq (pending_irq),
|
||||
.i_alu_cmp (alu_cmp),
|
||||
.o_init (init),
|
||||
|
@ -371,7 +369,7 @@ module serv_top
|
|||
.i_trap (trap),
|
||||
.i_mret (mret),
|
||||
.i_mepc (o_ibus_adr[0]),
|
||||
.i_mem_misalign (mem_misalign),
|
||||
.i_mem_op (mem_op),
|
||||
.i_bufreg_q (bufreg_q),
|
||||
.i_bad_pc (bad_pc),
|
||||
.o_csr_pc (csr_pc),
|
||||
|
@ -434,9 +432,9 @@ module serv_top
|
|||
.i_cnt3 (cnt3),
|
||||
.i_cnt7 (cnt7),
|
||||
.i_cnt_done (cnt_done),
|
||||
.i_mem_misalign (mem_misalign),
|
||||
.i_mem_op (mem_op),
|
||||
.i_mtip (i_timer_irq),
|
||||
.i_trap_taken (trap_taken),
|
||||
.i_trap (trap),
|
||||
.i_pending_irq (pending_irq),
|
||||
.o_new_irq (new_irq),
|
||||
//Control
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue