Skip to content

Commit

Permalink
Merge pull request #898 from silabs-oysteink/silabs-oysteink_clic-todo
Browse files Browse the repository at this point in the history
Removed todo in clic_int_controller.
  • Loading branch information
Silabs-ArjanB authored Aug 4, 2023
2 parents 7d367ca + 2406ca9 commit f7452ad
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 5 deletions.
5 changes: 4 additions & 1 deletion rtl/cv32e40x_clic_int_controller.sv
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,10 @@ module cv32e40x_clic_int_controller import cv32e40x_pkg::*;
// and the incoming irq level is above the core's current effective interrupt level. Machine mode interrupts
// during user mode shall always be taken if their level is > 0

// Cannot use flopped comparator results from the irq_wu_ctrl_o logic, as the effective_irq_level
// may change from one cycle to the next due to CSR updates. However, as the irq_wu_ctrl_o is only used
// when the core is in the SLEEP state (where no CSR updates can happen), an assertion exists to check that the cycle after a core wakes up
// due to an interupt the irq_req_ctrl_o must be asserted if global_irq_enable == 1;
assign irq_req_ctrl_o = clic_irq_q && global_irq_enable &&
((priv_lvl_i == PRIV_LVL_M) ? (clic_irq_level_q > effective_irq_level) : (clic_irq_level_q > '0));

Expand All @@ -135,7 +139,6 @@ module cv32e40x_clic_int_controller import cv32e40x_pkg::*;
// - priv mode == current, irq i is max (done in external CLIC), level > max(mintstatus.mil, mintthresh.th)
// - priv mode > current, irq i is max (done in external CLIC), level != 0

// todo: can we share the comparator below and flop the result for irq_req_ctrl_o?
assign irq_wu_ctrl_o = clic_irq_i &&
((priv_lvl_i == PRIV_LVL_M) ? (clic_irq_level_i > effective_irq_level) : (clic_irq_level_i > '0));

Expand Down
24 changes: 21 additions & 3 deletions sva/cv32e40x_clic_int_controller_sva.sv
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ module cv32e40x_clic_int_controller_sva
input logic clic_irq_q,
input logic [7:0] clic_irq_level_q,

input logic global_irq_enable,
input logic irq_wu_ctrl_o,

input logic ctrl_pending_interrupt,
input logic ctrl_interrupt_allowed,
input logic ctrl_pending_nmi,
Expand All @@ -60,7 +63,7 @@ module cv32e40x_clic_int_controller_sva
endproperty;

a_clic_enable: assert property(p_clic_enable)
else `uvm_error("core", "Interrupt not taken soon enough after enabling");
else `uvm_error("clic_int_controller", "Interrupt not taken soon enough after enabling");

// Check that only NMI and external debug take presedence over interrupts after being enabled by mret or CSR writes
property p_irq_pri;
Expand All @@ -76,7 +79,7 @@ module cv32e40x_clic_int_controller_sva
endproperty;

a_irq_pri: assert property(p_irq_pri)
else `uvm_error("core", "Interrupt not taken soon enough after enabling")
else `uvm_error("clic_int_controller", "Interrupt not taken soon enough after enabling")

// Check a pending interrupt that is disabled is actually not taken
property p_clic_disable;
Expand All @@ -88,7 +91,22 @@ module cv32e40x_clic_int_controller_sva
endproperty;

a_clic_disable: assert property(p_clic_disable)
else `uvm_error("core", "Interrupt taken after disabling");
else `uvm_error("clic_int_controller", "Interrupt taken after disabling");

// If an interrupt wakeup is signalled while the core is in the SLEEP state, an interrupt
// request must be asserted in the next cycle if the signal global_irq_enable is set.
property p_req_after_wake;
@(posedge clk) disable iff (!rst_n)
( (ctrl_fsm_cs == SLEEP) && // Core is in sleep state
irq_wu_ctrl_o // Wakeup requested
|=>
(irq_req_ctrl_o) // interrupts must be requested
or
(!irq_req_ctrl_o && !global_irq_enable)); // unless interrupts are not enabled
endproperty;

a_req_after_wake: assert property(p_req_after_wake)
else `uvm_error("clic_int_controller", "No request after wakeup signal");

endmodule

19 changes: 18 additions & 1 deletion sva/cv32e40x_core_sva.sv
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ module cv32e40x_core_sva
input logic irq_ack, // irq ack output
input logic irq_clic_shv, // ack'ed irq is a CLIC SHV
input logic irq_req_ctrl, // Interrupt controller request an interrupt
input logic irq_wu_ctrl,
input ex_wb_pipe_t ex_wb_pipe,
input logic wb_valid,
input logic branch_taken_in_ex,
Expand Down Expand Up @@ -131,7 +132,8 @@ module cv32e40x_core_sva
input logic [1:0] lsu_cnt_q,
input logic [1:0] resp_filter_bus_cnt_q,
input logic [1:0] resp_filter_core_cnt_q,
input write_buffer_state_e write_buffer_state
input write_buffer_state_e write_buffer_state,
input privlvl_t priv_lvl
);

if (CLIC) begin
Expand Down Expand Up @@ -690,6 +692,21 @@ if (!CLIC) begin

a_mip_mie_write_disable: assert property(p_mip_mie_write_disable)
else `uvm_error("core", "Interrupt taken after disabling");

// If an interrupt wakeup is signalled while the core is in the SLEEP state, an interrupt
// request must be asserted in the next cycle if interrupts are globally enabled.
property p_req_after_wake;
@(posedge clk) disable iff (!rst_ni)
( (ctrl_fsm_cs == SLEEP) && // Core is in sleep state
irq_wu_ctrl // Wakeup requested
|=>
(irq_req_ctrl) // interrupt must be requested
or
(!irq_req_ctrl && !(cs_registers_mstatus_q.mie || (priv_lvl < PRIV_LVL_M)))); // unless interrupts are disabled
endproperty;

a_req_after_wake: assert property(p_req_after_wake)
else `uvm_error("core", "No interrupt request after wakeup signal");
end

// Clearing external interrupts via a store instruction causes irq_i to go low the next cycle.
Expand Down

0 comments on commit f7452ad

Please sign in to comment.