Vaguely implement wfi
This commit is contained in:
parent
375a6d60b7
commit
cc6a6c09ba
|
@ -185,6 +185,7 @@ wire [W_ADDR-1:0] d_jump_offs;
|
|||
wire d_jump_is_regoffs;
|
||||
wire [W_ADDR-1:0] d_pc;
|
||||
wire [W_EXCEPT-1:0] d_except;
|
||||
wire d_wfi;
|
||||
wire d_csr_ren;
|
||||
wire d_csr_wen;
|
||||
wire [1:0] d_csr_wtype;
|
||||
|
@ -229,7 +230,8 @@ hazard3_decode #(
|
|||
.d_branchcond (d_branchcond),
|
||||
.d_jump_offs (d_jump_offs),
|
||||
.d_jump_is_regoffs (d_jump_is_regoffs),
|
||||
.d_except (d_except)
|
||||
.d_except (d_except),
|
||||
.d_wfi (d_wfi)
|
||||
);
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@ -267,6 +269,7 @@ reg [W_DATA-1:0] xm_result;
|
|||
reg [W_DATA-1:0] xm_store_data;
|
||||
reg [W_MEMOP-1:0] xm_memop;
|
||||
reg [W_EXCEPT-1:0] xm_except;
|
||||
reg xm_wfi;
|
||||
reg xm_delay_irq_entry;
|
||||
|
||||
|
||||
|
@ -496,6 +499,7 @@ always @ (posedge clk or negedge rst_n) begin
|
|||
end
|
||||
|
||||
wire [W_ADDR-1:0] m_exception_return_addr;
|
||||
wire m_wfi_stall_clear;
|
||||
|
||||
// If an instruction causes an exceptional condition we do not consider it to have retired.
|
||||
wire x_except_counts_as_retire = x_except == EXCEPT_EBREAK || x_except == EXCEPT_MRET || x_except == EXCEPT_ECALL;
|
||||
|
@ -542,6 +546,7 @@ hazard3_csr #(
|
|||
.trap_enter_rdy (m_trap_enter_rdy),
|
||||
.loadstore_dphase_pending (!xm_memop[3]),
|
||||
.mepc_in (m_exception_return_addr),
|
||||
.wfi_stall_clear (m_wfi_stall_clear),
|
||||
|
||||
// IRQ and exception requests
|
||||
.delay_irq_entry (xm_delay_irq_entry),
|
||||
|
@ -565,6 +570,7 @@ always @ (posedge clk or negedge rst_n) begin
|
|||
if (!rst_n) begin
|
||||
xm_memop <= MEMOP_NONE;
|
||||
xm_except <= EXCEPT_NONE;
|
||||
xm_wfi <= 1'b0;
|
||||
{xm_rs1, xm_rs2, xm_rd} <= {3 * W_REGADDR{1'b0}};
|
||||
end else begin
|
||||
if (!m_stall) begin
|
||||
|
@ -572,11 +578,13 @@ always @ (posedge clk or negedge rst_n) begin
|
|||
// If the transfer is unaligned, make sure it is completely NOP'd on the bus
|
||||
xm_memop <= d_memop | {x_unaligned_addr, 3'h0};
|
||||
xm_except <= x_except;
|
||||
xm_wfi <= d_wfi;
|
||||
if (x_stall || m_trap_enter_soon) begin
|
||||
// Insert bubble
|
||||
xm_rd <= {W_REGADDR{1'b0}};
|
||||
xm_memop <= MEMOP_NONE;
|
||||
xm_except <= EXCEPT_NONE;
|
||||
xm_wfi <= 1'b0;
|
||||
end
|
||||
end else if (bus_dph_err_d) begin
|
||||
// First phase of 2-phase AHBL error response. Pass the exception along on
|
||||
|
@ -586,6 +594,7 @@ always @ (posedge clk or negedge rst_n) begin
|
|||
assert(!xm_memop[3]); // Not NONE
|
||||
`endif
|
||||
xm_except <= xm_memop <= MEMOP_LBU ? EXCEPT_LOAD_FAULT : EXCEPT_STORE_FAULT;
|
||||
xm_wfi <= 1'b0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -624,7 +633,9 @@ assign f_jump_target = m_trap_enter_vld ? m_trap_addr : x_jump_target;
|
|||
assign x_jump_not_except = !m_trap_enter_vld;
|
||||
|
||||
wire m_bus_stall = !xm_memop[3] && !bus_dph_ready_d;
|
||||
assign m_stall = m_bus_stall || (m_trap_enter_vld && !m_trap_enter_rdy && !m_trap_is_irq);
|
||||
assign m_stall = m_bus_stall ||
|
||||
(m_trap_enter_vld && !m_trap_enter_rdy && !m_trap_is_irq) ||
|
||||
(xm_wfi && !m_wfi_stall_clear);
|
||||
|
||||
// Exception is taken against the instruction currently in M, so walk the PC
|
||||
// back. IRQ is taken "in between" the instruction in M and the instruction
|
||||
|
|
|
@ -91,6 +91,7 @@ module hazard3_csr #(
|
|||
// mode.
|
||||
input wire loadstore_dphase_pending,
|
||||
input wire [XLEN-1:0] mepc_in,
|
||||
output wire wfi_stall_clear,
|
||||
|
||||
// Exceptions must *not* be a function of bus stall.
|
||||
input wire [W_EXCEPT-1:0] except,
|
||||
|
@ -1019,6 +1020,10 @@ wire [31:0] mip_no_global = mip & ~(32'h800 & ~{XLEN{midcr_eivect}});
|
|||
wire standard_irq_active = |(mip_no_global & mie) && mstatus_mie && !dcsr_step;
|
||||
wire external_irq_active = external_irq_pending && mstatus_mie && !dcsr_step && mie_meie;
|
||||
|
||||
// WFI clear respects individual interrupt enables but ignores mstatus.mie.
|
||||
// Additionally, wfi is treated as a nop during single-stepping and D-mode.
|
||||
assign wfi_stall_clear = |(mip & mie) || dcsr_step || debug_mode || want_halt_irq_if_no_exception;
|
||||
|
||||
wire [4:0] external_irq_num;
|
||||
wire [3:0] standard_irq_num;
|
||||
assign mlei = external_irq_num;
|
||||
|
|
|
@ -56,7 +56,8 @@ module hazard3_decode #(
|
|||
output reg [W_BCOND-1:0] d_branchcond,
|
||||
output reg [W_ADDR-1:0] d_jump_offs,
|
||||
output reg d_jump_is_regoffs,
|
||||
output reg [W_EXCEPT-1:0] d_except
|
||||
output reg [W_EXCEPT-1:0] d_except,
|
||||
output reg d_wfi
|
||||
);
|
||||
|
||||
`include "rv_opcodes.vh"
|
||||
|
@ -193,6 +194,7 @@ always @ (*) begin
|
|||
d_jump_is_regoffs = 1'b0;
|
||||
d_invalid_32bit = 1'b0;
|
||||
d_except = EXCEPT_NONE;
|
||||
d_wfi = 1'b0;
|
||||
|
||||
casez (d_instr)
|
||||
RV_BEQ: begin d_invalid_32bit = DEBUG_SUPPORT && debug_mode; d_rd = X0; d_aluop = ALUOP_SUB; d_branchcond = BCOND_ZERO; end
|
||||
|
@ -251,6 +253,7 @@ always @ (*) begin
|
|||
RV_ECALL: if (HAVE_CSR) begin d_except = EXCEPT_ECALL; d_rs2 = X0; d_rs1 = X0; d_rd = X0; end else begin d_invalid_32bit = 1'b1; end
|
||||
RV_EBREAK: if (HAVE_CSR) begin d_except = EXCEPT_EBREAK; d_rs2 = X0; d_rs1 = X0; d_rd = X0; end else begin d_invalid_32bit = 1'b1; end
|
||||
RV_MRET: if (HAVE_CSR) begin d_except = EXCEPT_MRET; d_rs2 = X0; d_rs1 = X0; d_rd = X0; end else begin d_invalid_32bit = 1'b1; end
|
||||
RV_WFI: if (HAVE_CSR) begin d_wfi = 1'b1; d_rs2 = X0; d_rs1 = X0; d_rd = X0; end else begin d_invalid_32bit = 1'b1; end
|
||||
default: begin d_invalid_32bit = 1'b1; end
|
||||
endcase
|
||||
|
||||
|
@ -263,6 +266,7 @@ always @ (*) begin
|
|||
d_csr_ren = 1'b0;
|
||||
d_csr_wen = 1'b0;
|
||||
d_except = EXCEPT_NONE;
|
||||
d_wfi = 1'b0;
|
||||
if (EXTENSION_M)
|
||||
d_aluop = ALUOP_ADD;
|
||||
|
||||
|
|
|
@ -55,6 +55,7 @@ localparam RV_CSRRSI = 32'b?????????????????110?????1110011;
|
|||
localparam RV_CSRRCI = 32'b?????????????????111?????1110011;
|
||||
localparam RV_MRET = 32'b00110000001000000000000001110011;
|
||||
localparam RV_SYSTEM = 32'b?????????????????????????1110011;
|
||||
localparam RV_WFI = 32'b00010000010100000000000001110011;
|
||||
|
||||
// M extension
|
||||
localparam RV_MUL = 32'b0000001??????????000?????0110011;
|
||||
|
@ -144,4 +145,4 @@ localparam RV_NOZ_CSRRC = 32'b00000000000000000011000001110011;
|
|||
localparam RV_NOZ_CSRRWI = 32'b00000000000000000101000001110011;
|
||||
localparam RV_NOZ_CSRRSI = 32'b00000000000000000110000001110011;
|
||||
localparam RV_NOZ_CSRRCI = 32'b00000000000000000111000001110011;
|
||||
localparam RV_NOZ_SYSTEM = 32'b00000000000000000000000001110011;
|
||||
localparam RV_NOZ_SYSTEM = 32'b00000000000000000000000001110011;
|
||||
|
|
Loading…
Reference in New Issue