Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
15 commits
Select commit Hold shift + click to select a range
aaf6a63
Disable the trigger when tdata1 is written with zero #3618
YazanHussnain-10x Oct 22, 2026
d90a139
Legalize the tdata1 action against dmode #3622
YazanHussnain-10x Oct 22, 2026
7aff44c
Report dcsr cause 2 when a trigger with action 1 enters Debug Mode #3624
YazanHussnain-10x Oct 22, 2026
273e717
Fire the etrigger only after an exception trap #3620
YazanHussnain-10x Oct 22, 2026
ffda439
Fire the itrigger before the first instruction of the trap handler #3646
YazanHussnain-10x Oct 22, 2026
beba32a
Fire the icount trigger on the next valid instruction to execute #3647
YazanHussnain-10x Oct 22, 2026
09d385a
Count icount matches only in the privilege modes where the trigger is…
YazanHussnain-10x Oct 22, 2026
5829c9c
Fire the etrigger and itrigger again when the hit bit is set
YazanHussnain-10x Oct 22, 2026
be90c56
Match lr as a load and an AMO as a load and a store in the mcontrol6 …
YazanHussnain-10x Oct 22, 2026
48a1745
Use the SdtrigSupportTextra option and match the trigger context in a…
YazanHussnain-10x Oct 22, 2026
4916618
Do not match or fire an action 0 trigger in M mode while MIE is 0 or …
YazanHussnain-10x Oct 22, 2026
c19af21
Ignore a write to tinfo instead of an illegal instruction exception
YazanHussnain-10x Oct 22, 2026
d33663c
Report in tinfo only the trigger types of the configuration
YazanHussnain-10x Oct 22, 2026
74e6fc4
Format trigger_module with verible
YazanHussnain-10x Oct 23, 2026
34437f0
Merge branch 'master' into sdtrig_issue_fix
fatimasaleem Oct 30, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions core/commit_stage.sv
Original file line number Diff line number Diff line change
Expand Up @@ -434,11 +434,14 @@ module commit_stage
exception_o.valid = 1'b0;
end

if ((CVA6Cfg.SdtrigIcount && sdtrig_commit_icount_valid_i && sdtrig_commit_icount_nr_instr_i == 'd0)
|| ((CVA6Cfg.SdtrigEtrigger || CVA6Cfg.SdtrigItrigger) && sdtrig_commit_std_exception_valid_i && commit_instr_i[0].valid)) begin
// The trigger action is taken on a valid instruction, when the commit stage is not halted
if (commit_instr_i[0].valid && !halt_i
&& ((CVA6Cfg.SdtrigIcount && sdtrig_commit_icount_valid_i && sdtrig_commit_icount_nr_instr_i == 'd0)
|| ((CVA6Cfg.SdtrigEtrigger || CVA6Cfg.SdtrigItrigger) && sdtrig_commit_std_exception_valid_i))) begin
exception_o.valid = 1'b1;
exception_o.cause = sdtrig_commit_action_i;
exception_o.tval = (CVA6Cfg.TvalEn) ? commit_instr_i[0].pc : '0;
// icount, itrigger and etrigger write 0 to tval
exception_o.tval = '0;
end

if(CVA6Cfg.SdtrigMcontrol6LoadData && ex_next_instr_q.timing && !commit_instr_i[0].ex.timing) begin
Expand Down
51 changes: 34 additions & 17 deletions core/csr_regfile.sv
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,7 @@ module csr_regfile
input logic [CVA6Cfg.VLEN-1:0] sdtrig_lsu_inputs_vaddr_i,
input logic [CVA6Cfg.XLEN-1:0] sdtrig_lsu_inputs_data_i,
input logic sdtrig_lsu_inputs_fu_i,
input ariane_pkg::fu_op sdtrig_lsu_inputs_op_i,
input logic sdtrig_lsu_inputs_valid_i,
input logic [CVA6Cfg.XLEN-1:0] sdtrig_load_data_i,
input logic sdtrig_load_valid_i,
Expand Down Expand Up @@ -482,9 +483,19 @@ module csr_regfile
else read_access_exception = 1'b1;
riscv::CSR_TINFO: begin
if (CVA6Cfg.Sdtrig) begin
// trigger info: the supported types icount = 3, itrigger = 4, etrigger = 5, mcontrol6 = 6, disabled = 15
csr_rdata = {
{CVA6Cfg.XLEN - 32{1'b0}}, 8'h1, 8'h0, 16'b1000_0000_0111_1000
}; // trigger info:icount = 3, itrigger = 4, etrigger = 5, mcontrol6 = 6, disable = 15
{CVA6Cfg.XLEN - 32{1'b0}},
8'h1,
8'h0,
1'b1,
8'b0,
CVA6Cfg.SdtrigMcontrol6,
CVA6Cfg.SdtrigEtrigger,
CVA6Cfg.SdtrigItrigger,
CVA6Cfg.SdtrigIcount,
3'b0
};
end else begin
read_access_exception = 1'b1;
end
Expand Down Expand Up @@ -1107,12 +1118,12 @@ module csr_regfile
end
mip_d = mip_q;
mie_d = mie_q;
mepc_d = (CVA6Cfg.SdtrigEtrigger && sdtrig_etrigger_context_saved_valid && mret) ? sdtrig_etrigger_context_mepc : mepc_q;
mcause_d = (CVA6Cfg.SdtrigEtrigger && sdtrig_etrigger_context_saved_valid && mret) ? sdtrig_etrigger_context_mcause : mcause_q;
mepc_d = ((CVA6Cfg.SdtrigEtrigger || CVA6Cfg.SdtrigItrigger) && sdtrig_etrigger_context_saved_valid && mret) ? sdtrig_etrigger_context_mepc : mepc_q;
mcause_d = ((CVA6Cfg.SdtrigEtrigger || CVA6Cfg.SdtrigItrigger) && sdtrig_etrigger_context_saved_valid && mret) ? sdtrig_etrigger_context_mcause : mcause_q;
mcounteren_d = mcounteren_q;
mscratch_d = mscratch_q;
if (CVA6Cfg.TvalEn)
mtval_d = (CVA6Cfg.SdtrigEtrigger && sdtrig_etrigger_context_saved_valid && mret) ? sdtrig_etrigger_context_mtval : mtval_q;
mtval_d = ((CVA6Cfg.SdtrigEtrigger || CVA6Cfg.SdtrigItrigger) && sdtrig_etrigger_context_saved_valid && mret) ? sdtrig_etrigger_context_mtval : mtval_q;
if (CVA6Cfg.RVH) begin
mtinst_d = mtinst_q;
mtval2_d = mtval2_q;
Expand Down Expand Up @@ -1299,6 +1310,10 @@ module csr_regfile
update_access_exception = 1'b1;
end
end
// tinfo has only read-only fields: a write is ignored
riscv::CSR_TINFO: begin
if (!CVA6Cfg.Sdtrig) update_access_exception = 1'b1;
end
riscv::CSR_SCONTEXT: begin
if (CVA6Cfg.Sdtrig && CVA6Cfg.SdtrigSupportTextra) begin
scontext_d = {{CVA6Cfg.XLEN - 32{1'b0}}, csr_wdata[31:0]};
Expand Down Expand Up @@ -1754,13 +1769,13 @@ module csr_regfile
riscv::CSR_MSCRATCH: mscratch_d = csr_wdata;
riscv::CSR_MEPC:
// bit[1] stays writable only with RVC; without RVC (IALIGN=32) mepc[1:0] are always zero
mepc_d = (CVA6Cfg.SdtrigEtrigger && sdtrig_etrigger_context_saved_valid && mret) ? sdtrig_etrigger_context_mepc
mepc_d = ((CVA6Cfg.SdtrigEtrigger || CVA6Cfg.SdtrigItrigger) && sdtrig_etrigger_context_saved_valid && mret) ? sdtrig_etrigger_context_mepc
: {csr_wdata[CVA6Cfg.XLEN-1:2], csr_wdata[1] & CVA6Cfg.RVC, 1'b0};
riscv::CSR_MCAUSE:
mcause_d = (CVA6Cfg.SdtrigEtrigger && sdtrig_etrigger_context_saved_valid && mret) ? sdtrig_etrigger_context_mcause : {csr_wdata[CVA6Cfg.XLEN - 1], {CVA6Cfg.XLEN - 6{1'b0}}, csr_wdata[4:0]};
mcause_d = ((CVA6Cfg.SdtrigEtrigger || CVA6Cfg.SdtrigItrigger) && sdtrig_etrigger_context_saved_valid && mret) ? sdtrig_etrigger_context_mcause : {csr_wdata[CVA6Cfg.XLEN - 1], {CVA6Cfg.XLEN - 6{1'b0}}, csr_wdata[4:0]};
riscv::CSR_MTVAL: begin
if (CVA6Cfg.TvalEn)
mtval_d = (CVA6Cfg.SdtrigEtrigger && sdtrig_etrigger_context_saved_valid && mret) ? sdtrig_etrigger_context_mtval : csr_wdata;
mtval_d = ((CVA6Cfg.SdtrigEtrigger || CVA6Cfg.SdtrigItrigger) && sdtrig_etrigger_context_saved_valid && mret) ? sdtrig_etrigger_context_mtval : csr_wdata;
end
riscv::CSR_MTINST:
if (CVA6Cfg.RVH) mtinst_d = {{CVA6Cfg.XLEN - 32{1'b0}}, csr_wdata[31:0]};
Expand Down Expand Up @@ -2107,7 +2122,7 @@ module csr_regfile
trap_to_v = 1'b0;
// Exception is taken and we are not in debug mode
// exceptions in debug mode don't update any fields
if ((CVA6Cfg.DebugEn && !debug_mode_q && ex_i.cause != riscv::DEBUG_REQUEST && ex_i.valid) || (!CVA6Cfg.DebugEn && ex_i.valid)) begin
if ((CVA6Cfg.DebugEn && !debug_mode_q && !(ex_i.cause inside {riscv::DEBUG_REQUEST, riscv::DEBUG_TRIGGER}) && ex_i.valid) || (!CVA6Cfg.DebugEn && ex_i.valid)) begin
// do not flush, flush is reserved for CSR writes with side effects
flush_o = 1'b0;
// figure out where to trap to
Expand Down Expand Up @@ -2201,11 +2216,11 @@ module csr_regfile
// save the previous privilege mode
mstatus_d.mpp = priv_lvl_q;
//set cause and epc adapted to etrigger
mcause_d = (CVA6Cfg.SdtrigEtrigger && sdtrig_etrigger_context_saved_valid && mret) ? sdtrig_etrigger_context_mcause : ex_i.cause;
mepc_d = (CVA6Cfg.SdtrigEtrigger && sdtrig_etrigger_context_saved_valid && mret) ? sdtrig_etrigger_context_mepc : {{CVA6Cfg.XLEN - CVA6Cfg.VLEN{pc_i[CVA6Cfg.VLEN-1]}}, pc_i};
mcause_d = ((CVA6Cfg.SdtrigEtrigger || CVA6Cfg.SdtrigItrigger) && sdtrig_etrigger_context_saved_valid && mret) ? sdtrig_etrigger_context_mcause : ex_i.cause;
mepc_d = ((CVA6Cfg.SdtrigEtrigger || CVA6Cfg.SdtrigItrigger) && sdtrig_etrigger_context_saved_valid && mret) ? sdtrig_etrigger_context_mepc : {{CVA6Cfg.XLEN - CVA6Cfg.VLEN{pc_i[CVA6Cfg.VLEN-1]}}, pc_i};
// set mtval or stval
if (CVA6Cfg.TvalEn) begin
if (CVA6Cfg.SdtrigEtrigger && sdtrig_etrigger_context_saved_valid && mret) begin
if ((CVA6Cfg.SdtrigEtrigger || CVA6Cfg.SdtrigItrigger) && sdtrig_etrigger_context_saved_valid && mret) begin
mtval_d = sdtrig_etrigger_context_mtval;
end else begin
mtval_d = ((ariane_pkg::ZERO_TVAL
Expand Down Expand Up @@ -2292,7 +2307,7 @@ module csr_regfile
end

// we've got a debug request
if (ex_i.valid && ex_i.cause == riscv::DEBUG_REQUEST) begin
if (ex_i.valid && ex_i.cause inside {riscv::DEBUG_REQUEST, riscv::DEBUG_TRIGGER}) begin
dcsr_d.prv = priv_lvl_o;
dcsr_d.v = (!CVA6Cfg.RVH) ? 1'b0 : v_q;
// save the PC
Expand All @@ -2301,8 +2316,8 @@ module csr_regfile
debug_mode_d = 1'b1;
// jump to the base address
set_debug_pc_o = 1'b1;
// save the cause as external debug request
dcsr_d.cause = ariane_pkg::CauseRequest;
// save the cause: a trigger or an external debug request
dcsr_d.cause = (ex_i.cause == riscv::DEBUG_TRIGGER) ? ariane_pkg::CauseTrigger : ariane_pkg::CauseRequest;
end

// single step enable and we just retired an instruction
Expand Down Expand Up @@ -3086,15 +3101,17 @@ module csr_regfile
.fetch_sdtrig_instr_i (fetch_sdtrig_instr_i),
.sdtrig_lsu_inputs_data_i (sdtrig_lsu_inputs_data_i),
.sdtrig_lsu_inputs_fu_i (sdtrig_lsu_inputs_fu_i),
.sdtrig_lsu_inputs_op_i (sdtrig_lsu_inputs_op_i),
.sdtrig_lsu_inputs_valid_i (sdtrig_lsu_inputs_valid_i),
.sdtrig_load_data_i (sdtrig_load_data_i),
.sdtrig_load_valid_i (sdtrig_load_valid_i),
.priv_lvl_i (priv_lvl_o),
.debug_mode_i (debug_mode_q),
.mret_i (mret),
.sret_i (sret),
.instr_count_d (instret_d[13:0]),
.instr_count_q (instret_q[13:0]),
.mstatus_mie_i (mstatus_q.mie),
.mstatus_sie_i (mstatus_q.sie),
.medeleg_breakpoint_i (medeleg_q[$clog2(CVA6Cfg.XLEN)'(riscv::BREAKPOINT)]),
.scontext_i (scontext_q),
.tselect_i (tselect_to_tm),
.tdata1_i (tdata1_to_tm),
Expand Down
3 changes: 3 additions & 0 deletions core/cva6.sv
Original file line number Diff line number Diff line change
Expand Up @@ -622,6 +622,7 @@ module cva6
logic [CVA6Cfg.VLEN-1:0] sdtrig_lsu_inputs_operand_a;
logic [CVA6Cfg.XLEN-1:0] sdtrig_lsu_inputs_operand_c;
logic sdtrig_lsu_inputs_we, sdtrig_lsu_inputs_valid;
fu_op sdtrig_lsu_inputs_op;
logic sdtrig_commit_icount_valid;
logic [$clog2(CVA6Cfg.NrCommitPorts)-1:0] sdtrig_commit_icount_nr_instr;

Expand Down Expand Up @@ -1140,6 +1141,7 @@ module cva6
.sdtrig_lsu_inputs_operand_a_o(sdtrig_lsu_inputs_operand_a),
.sdtrig_lsu_inputs_operand_c_o(sdtrig_lsu_inputs_operand_c),
.sdtrig_lsu_inputs_we_o (sdtrig_lsu_inputs_we),
.sdtrig_lsu_inputs_op_o (sdtrig_lsu_inputs_op),
.sdtrig_lsu_inputs_valid_o (sdtrig_lsu_inputs_valid)
);

Expand Down Expand Up @@ -1318,6 +1320,7 @@ module cva6
.sdtrig_lsu_inputs_vaddr_i (sdtrig_lsu_inputs_operand_a),
.sdtrig_lsu_inputs_data_i (sdtrig_lsu_inputs_operand_c),
.sdtrig_lsu_inputs_fu_i (sdtrig_lsu_inputs_we),
.sdtrig_lsu_inputs_op_i (sdtrig_lsu_inputs_op),
.sdtrig_lsu_inputs_valid_i (sdtrig_lsu_inputs_valid),
.sdtrig_load_data_i (load_result_ex_id),
.sdtrig_load_valid_i (load_valid_ex_id),
Expand Down
3 changes: 3 additions & 0 deletions core/ex_stage.sv
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,7 @@ module ex_stage
output logic [CVA6Cfg.VLEN-1:0] sdtrig_lsu_inputs_operand_a_o,
output logic [CVA6Cfg.XLEN-1:0] sdtrig_lsu_inputs_operand_c_o,
output logic sdtrig_lsu_inputs_we_o,
output fu_op sdtrig_lsu_inputs_op_o,
output logic sdtrig_lsu_inputs_valid_o,
input logic sdtrig_load_stall_i,
input logic sdtrig_load_cancel_i,
Expand Down Expand Up @@ -639,11 +640,13 @@ module ex_stage
assign sdtrig_lsu_inputs_operand_a_o = CVA6Cfg.VLEN'(lsu_data.operand_a + lsu_data.imm);
assign sdtrig_lsu_inputs_operand_c_o = lsu_data.operand_b;
assign sdtrig_lsu_inputs_we_o = lsu_data.fu == STORE;
assign sdtrig_lsu_inputs_op_o = lsu_data.operation;
assign sdtrig_lsu_inputs_valid_o = |lsu_valid_i;
end else begin
assign sdtrig_lsu_inputs_operand_a_o = '0;
assign sdtrig_lsu_inputs_operand_c_o = '0;
assign sdtrig_lsu_inputs_we_o = '0;
assign sdtrig_lsu_inputs_op_o = ADD;
assign sdtrig_lsu_inputs_valid_o = '0;
end

Expand Down
2 changes: 1 addition & 1 deletion core/include/build_config_pkg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ package build_config_pkg;
cfg.SdtrigTriggerChaining = CVA6Cfg.SdtrigMcontrol6 ? CVA6Cfg.SdtrigTriggerChaining : 1'b0;
cfg.SdtrigSupportedActions = CVA6Cfg.Sdtrig ? (CVA6Cfg.DebugEn ? CVA6Cfg.SdtrigSupportedActions : 2'b01) : 2'b00;
cfg.SdtrigSupportedMatch = CVA6Cfg.Sdtrig ? CVA6Cfg.SdtrigSupportedMatch : 10'b00_0000_0000;
cfg.SdtrigSupportTextra = 1'b0; //Trigger Extra not supported : no use implemented yet
cfg.SdtrigSupportTextra = CVA6Cfg.Sdtrig ? CVA6Cfg.SdtrigSupportTextra : 1'b0;

cfg.NonIdemPotenceEn = (CVA6Cfg.NrNonIdempotentRules > 0) && (CVA6Cfg.NonIdempotentLength > 0);
cfg.AxiBurstWriteEn = CVA6Cfg.AxiBurstWriteEn;
Expand Down
1 change: 1 addition & 0 deletions core/include/riscv_pkg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,7 @@ package riscv;
localparam logic [XLEN-1:0] VIRTUAL_INSTRUCTION = 22; // virtual instruction
localparam logic [XLEN-1:0] STORE_GUEST_PAGE_FAULT = 23; // Store guest-page fault
localparam logic [XLEN-1:0] DEBUG_REQUEST = 24; // Debug request
localparam logic [XLEN-1:0] DEBUG_TRIGGER = 25; // Debug request from a trigger with action=1

localparam int unsigned IRQ_S_SOFT = 1;
localparam int unsigned IRQ_VS_SOFT = 2;
Expand Down
4 changes: 2 additions & 2 deletions core/include/triggers_pkg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ package triggers_pkg;
if (scontext[8*b+:8] != svalue[8*b+:8]) match = 1'b0;
end
end
end else match = 1'b0;
end
return match;
endfunction

Expand All @@ -138,7 +138,7 @@ package triggers_pkg;
if (scontext[8*b+:8] != svalue[8*b+:8]) match = 1'b0;
end
end
end else match = 1'b0;
end
return match;
endfunction

Expand Down
Loading
Loading