From 453a9a3849049cc38052d8a5b73e19f31dd79fd2 Mon Sep 17 00:00:00 2001 From: Oystein Knauserud Date: Wed, 16 Nov 2022 14:26:04 +0100 Subject: [PATCH 1/3] Added support for DBG_NUM_TRIGGER parameter.If 0, the debug_triggers module will not be instantiated and any access to trigger CSR will result in an illegal instruction. debug_triggers will instantiate DBG_NUM_TRIGGERS instances of tdata1 and tdata2 and perform instruction address match checks for any enabled triggers. Converted trigger type 2 (mcontrol) to 6 (mcontrol6) and updated trigger match to take EXECUTE and M bit into account. (Passed modified debug_trigger_test). Reset value for tdata1 is updated to reflect mcontrol6. Signed-off-by: Oystein Knauserud --- bhv/cv32e40x_rvfi.sv | 18 ++-- bhv/cv32e40x_wrapper.sv | 15 ++-- rtl/cv32e40x_cs_registers.sv | 141 +++++++++++++++++++---------- rtl/cv32e40x_debug_triggers.sv | 160 +++++++++++++++++++++------------ rtl/include/cv32e40x_pkg.sv | 40 ++++----- 5 files changed, 242 insertions(+), 132 deletions(-) diff --git a/bhv/cv32e40x_rvfi.sv b/bhv/cv32e40x_rvfi.sv index 2620d12b..214043f4 100644 --- a/bhv/cv32e40x_rvfi.sv +++ b/bhv/cv32e40x_rvfi.sv @@ -181,12 +181,18 @@ module cv32e40x_rvfi input logic [31:0] csr_tdata2_n_i, input logic [31:0] csr_tdata2_q_i, input logic csr_tdata2_we_i, + input logic [31:0] csr_tdata3_n_i, + input logic [31:0] csr_tdata3_q_i, + input logic csr_tdata3_we_i, input logic [31:0] csr_tinfo_n_i, input logic [31:0] csr_tinfo_q_i, input logic csr_tinfo_we_i, input logic [31:0] csr_tcontrol_n_i, input logic [31:0] csr_tcontrol_q_i, input logic csr_tcontrol_we_i, + input logic [31:0] csr_tselect_n_i, + input logic [31:0] csr_tselect_q_i, + input logic csr_tselect_we_i, input dcsr_t csr_dcsr_n_i, input dcsr_t csr_dcsr_q_i, input logic csr_dcsr_we_i, @@ -1307,9 +1313,9 @@ module cv32e40x_rvfi assign rvfi_csr_wmask_d.mclicbase = csr_mclicbase_we_i ? '1 : '0; // Trigger - assign rvfi_csr_rdata_d.tselect = '0; - assign rvfi_csr_wdata_d.tselect = '0; // Not implemented, read 0 - assign rvfi_csr_wmask_d.tselect = '0; + assign rvfi_csr_rdata_d.tselect = csr_tselect_q_i; + assign rvfi_csr_wdata_d.tselect = csr_tselect_n_i; + assign rvfi_csr_wmask_d.tselect = csr_tselect_we_i; assign rvfi_csr_rdata_d.tdata[0] = 'Z; assign rvfi_csr_wdata_d.tdata[0] = 'Z; // Does not exist @@ -1323,9 +1329,9 @@ module cv32e40x_rvfi assign rvfi_csr_wdata_d.tdata[2] = csr_tdata2_n_i; assign rvfi_csr_wmask_d.tdata[2] = csr_tdata2_we_i ? '1 : '0; - assign rvfi_csr_rdata_d.tdata[3] = '0; - assign rvfi_csr_wdata_d.tdata[3] = '0; // Not implemented, read 0 - assign rvfi_csr_wmask_d.tdata[3] = '0; + assign rvfi_csr_rdata_d.tdata[3] = csr_tdata3_q_i; + assign rvfi_csr_wdata_d.tdata[3] = csr_tdata3_n_i; + assign rvfi_csr_wmask_d.tdata[3] = csr_tdata3_we_i; assign rvfi_csr_rdata_d.tinfo = csr_tinfo_q_i; assign rvfi_csr_wdata_d.tinfo = csr_tinfo_n_i; diff --git a/bhv/cv32e40x_wrapper.sv b/bhv/cv32e40x_wrapper.sv index b354353b..21b6e017 100644 --- a/bhv/cv32e40x_wrapper.sv +++ b/bhv/cv32e40x_wrapper.sv @@ -560,13 +560,16 @@ endgenerate .csr_mclicbase_n_i ( core_i.cs_registers_i.mclicbase_n ), .csr_mclicbase_q_i ( core_i.cs_registers_i.mclicbase_rdata ), .csr_mclicbase_we_i ( core_i.cs_registers_i.mclicbase_we ), - .csr_tdata1_n_i ( core_i.cs_registers_i.debug_triggers_i.tdata1_n ), + .csr_tdata1_n_i ( core_i.cs_registers_i.triggers.debug_triggers_i.tdata1_n ), // If DBG_NUM_TRIGGERS=0 this connection will fail .csr_tdata1_q_i ( core_i.cs_registers_i.tdata1_rdata ), .csr_tdata1_we_i ( core_i.cs_registers_i.tdata1_we ), - .csr_tdata2_n_i ( core_i.cs_registers_i.debug_triggers_i.tdata2_n ), + .csr_tdata2_n_i ( core_i.cs_registers_i.triggers.debug_triggers_i.tdata2_n ), // If DBG_NUM_TRIGGERS=0 this connection will fail .csr_tdata2_q_i ( core_i.cs_registers_i.tdata2_rdata ), .csr_tdata2_we_i ( core_i.cs_registers_i.tdata2_we ), - .csr_tinfo_n_i ( core_i.cs_registers_i.debug_triggers_i.tinfo_n ), + .csr_tdata3_n_i ( core_i.cs_registers_i.triggers.debug_triggers_i.tdata3_n ), // If DBG_NUM_TRIGGERS=0 this connection will fail + .csr_tdata3_q_i ( core_i.cs_registers_i.tdata3_rdata ), + .csr_tdata3_we_i ( core_i.cs_registers_i.tdata3_we ), + .csr_tinfo_n_i ( core_i.cs_registers_i.triggers.debug_triggers_i.tinfo_n ), // If DBG_NUM_TRIGGERS=0 this connection will fail .csr_tinfo_q_i ( core_i.cs_registers_i.tinfo_rdata ), .csr_tinfo_we_i ( core_i.cs_registers_i.tinfo_we ), .csr_dcsr_n_i ( core_i.cs_registers_i.dcsr_n ), @@ -592,10 +595,12 @@ endgenerate .csr_mstatush_n_i ( core_i.cs_registers_i.mstatush_n ), .csr_mstatush_q_i ( core_i.cs_registers_i.mstatush_rdata ), .csr_mstatush_we_i ( core_i.cs_registers_i.mstatush_we ), - .csr_tcontrol_n_i ( core_i.cs_registers_i.debug_triggers_i.tcontrol_n ), + .csr_tcontrol_n_i ( core_i.cs_registers_i.triggers.debug_triggers_i.tcontrol_n ), // If DBG_NUM_TRIGGERS=0 this connection will fail .csr_tcontrol_q_i ( core_i.cs_registers_i.tcontrol_rdata ), .csr_tcontrol_we_i ( core_i.cs_registers_i.tcontrol_we ), -//todo: add tselect, tdata3 + .csr_tselect_n_i ( core_i.cs_registers_i.triggers.debug_triggers_i.tselect_n ), // If DBG_NUM_TRIGGERS=0 this connection will fail + .csr_tselect_q_i ( core_i.cs_registers_i.tselect_rdata ), + .csr_tselect_we_i ( core_i.cs_registers_i.tselect_we ), .csr_mcounteren_n_i ( '0 /* Not supported in cv32e40x*/ ), .csr_mcounteren_q_i ( '0 /* Not supported in cv32e40x*/ ), diff --git a/rtl/cv32e40x_cs_registers.sv b/rtl/cv32e40x_cs_registers.sv index bcaa058d..f23720ba 100644 --- a/rtl/cv32e40x_cs_registers.sv +++ b/rtl/cv32e40x_cs_registers.sv @@ -470,17 +470,59 @@ module cv32e40x_cs_registers import cv32e40x_pkg::*; end end - CSR_TSELECT: csr_rdata_int = tselect_rdata; + CSR_TSELECT: begin + if (DBG_NUM_TRIGGERS > 0) begin + csr_rdata_int = tselect_rdata; + end else begin + csr_rdata_int = '0; + illegal_csr_read = 1'b1; + end + end - CSR_TDATA1: csr_rdata_int = tdata1_rdata; + CSR_TDATA1: begin + if (DBG_NUM_TRIGGERS > 0) begin + csr_rdata_int = tdata1_rdata; + end else begin + csr_rdata_int = '0; + illegal_csr_read = 1'b1; + end + end - CSR_TDATA2: csr_rdata_int = tdata2_rdata; + CSR_TDATA2: begin + if (DBG_NUM_TRIGGERS > 0) begin + csr_rdata_int = tdata2_rdata; + end else begin + csr_rdata_int = '0; + illegal_csr_read = 1'b1; + end + end - CSR_TDATA3: csr_rdata_int = tdata3_rdata; + CSR_TDATA3: begin + if (DBG_NUM_TRIGGERS > 0) begin + csr_rdata_int = tdata3_rdata; + end else begin + csr_rdata_int = '0; + illegal_csr_read = 1'b1; + end + end - CSR_TINFO: csr_rdata_int = tinfo_rdata; + CSR_TINFO: begin + if (DBG_NUM_TRIGGERS > 0) begin + csr_rdata_int = tinfo_rdata; + end else begin + csr_rdata_int = '0; + illegal_csr_read = 1'b1; + end + end - CSR_TCONTROL: csr_rdata_int = tcontrol_rdata; + CSR_TCONTROL: begin + if (DBG_NUM_TRIGGERS > 0) begin + csr_rdata_int = tcontrol_rdata; + end else begin + csr_rdata_int = '0; + illegal_csr_read = 1'b1; + end + end CSR_DCSR: begin csr_rdata_int = dcsr_rdata; @@ -1444,45 +1486,54 @@ module cv32e40x_cs_registers import cv32e40x_pkg::*; // |____/ \___|_.__/ \__,_|\__, | |_||_| |_|\__, |\__, |\___|_| // // |___/ |___/ |___/ // //////////////////////////////////////////////////////////////////////// - - cv32e40x_debug_triggers - #( - .DBG_NUM_TRIGGERS (DBG_NUM_TRIGGERS) - ) - debug_triggers_i - ( - .clk ( clk ), - .rst_n ( rst_n ), - - // CSR inputs write inputs - .csr_wdata_i ( csr_wdata_int), - .tselect_we_i ( tselect_we ), - .tdata1_we_i ( tdata1_we ), - .tdata2_we_i ( tdata2_we ), - .tdata3_we_i ( tdata3_we ), - .tinfo_we_i ( tinfo_we ), - .tcontrol_we_i ( tcontrol_we ), - - // CSR read data outputs - .tselect_rdata_o ( tselect_rdata ), - .tdata1_rdata_o ( tdata1_rdata ), - .tdata2_rdata_o ( tdata2_rdata ), - .tdata3_rdata_o ( tdata3_rdata ), - .tinfo_rdata_o ( tinfo_rdata ), - .tcontrol_rdata_o ( tcontrol_rdata), - - // IF stage inputs - .pc_if_i ( pc_if_i ), - .ptr_in_if_i ( ptr_in_if_i ), - - // Controller inputs - .ctrl_fsm_i ( ctrl_fsm_i ), - - // Trigger match output - .trigger_match_o ( trigger_match_o ) - - - ); + generate + if (DBG_NUM_TRIGGERS > 0) begin : triggers + cv32e40x_debug_triggers + #( + .DBG_NUM_TRIGGERS (DBG_NUM_TRIGGERS) + ) + debug_triggers_i + ( + .clk ( clk ), + .rst_n ( rst_n ), + + // CSR inputs write inputs + .csr_wdata_i ( csr_wdata_int), + .tselect_we_i ( tselect_we ), + .tdata1_we_i ( tdata1_we ), + .tdata2_we_i ( tdata2_we ), + .tdata3_we_i ( tdata3_we ), + .tinfo_we_i ( tinfo_we ), + .tcontrol_we_i ( tcontrol_we ), + + // CSR read data outputs + .tselect_rdata_o ( tselect_rdata ), + .tdata1_rdata_o ( tdata1_rdata ), + .tdata2_rdata_o ( tdata2_rdata ), + .tdata3_rdata_o ( tdata3_rdata ), + .tinfo_rdata_o ( tinfo_rdata ), + .tcontrol_rdata_o ( tcontrol_rdata), + + // IF stage inputs + .pc_if_i ( pc_if_i ), + .ptr_in_if_i ( ptr_in_if_i ), + + // Controller inputs + .ctrl_fsm_i ( ctrl_fsm_i ), + + // Trigger match output + .trigger_match_o ( trigger_match_o ) + ); + end else begin : notriggers + assign trigger_match_o = 1'b0; + assign tselect_rdata = '0; + assign tdata1_rdata = '0; + assign tdata2_rdata = '0; + assign tdata3_rdata = '0; + assign tinfo_rdata = '0; + assign tcontrol_rdata = '0; + end +endgenerate ///////////////////////////////////////////////////////////////// diff --git a/rtl/cv32e40x_debug_triggers.sv b/rtl/cv32e40x_debug_triggers.sv index 8b0ac4fb..bbd02500 100644 --- a/rtl/cv32e40x_debug_triggers.sv +++ b/rtl/cv32e40x_debug_triggers.sv @@ -74,35 +74,44 @@ import cv32e40x_pkg::*; logic [31:0] tinfo_n; logic [31:0] tcontrol_n; + // Internal CSR write enables + logic [DBG_NUM_TRIGGERS-1 : 0] tdata1_we_int; + logic [DBG_NUM_TRIGGERS-1 : 0] tdata2_we_int; + // CSR instance outputs - logic [31:0] tdata1_q; - logic [31:0] tdata2_q; + logic [31:0] tdata1_q[DBG_NUM_TRIGGERS]; + logic [31:0] tdata2_q[DBG_NUM_TRIGGERS]; + logic [31:0] tselect_q; + + // Fetch stage trigger match + logic [DBG_NUM_TRIGGERS-1 : 0] trigger_match_if; logic unused_signals; // Write data always_comb begin - tselect_n = tselect_rdata_o; // todo + // Tselect is WARL (0 -> DBG_NUM_TRIGGERS-1) + tselect_n = (csr_wdata_i < DBG_NUM_TRIGGERS) ? csr_wdata_i : (DBG_NUM_TRIGGERS - 1); + // todo: handle WARL based on trigger type tdata1_n = { - TTYPE_MCONTROL, // type : address/data match - 1'b1, // dmode : access from D mode only - 6'h00, // maskmax : exact match only - 1'b0, // hit : not supported - 1'b0, // select : address match only - 1'b0, // timing : match before execution - 2'b00, // sizelo : match any access - 4'h1, // action : enter debug mode - 1'b0, // chain : not supported - 4'h0, // match : simple match - 1'b1, // m : match in m-mode - 1'b0, // 0 : zero - 1'b0, // s : not supported - 1'b0, // u : match in u-mode - csr_wdata_i[2], // execute : match instruction address - 1'b0, // store : not supported - 1'b0 // load : not supported - }; + TTYPE_MCONTROL6, // type : address/data match + 1'b1, // dmode : access from D mode only + 2'b00, // zero 26:25 + 3'b000, // zero, vs, vu, hit 24:22 + 1'b0, // zero, select 21 + 1'b0, // zero, timing 20 + 4'b0000, // zero, size (match any size) 19:16 + 4'b0001, // action, WARL(1), enter debug 15:12 + 1'b0, // zero, chain 11 + 4'b0000, // match, WARL(0,2,3) 10:7 todo: resolve WARL + csr_wdata_i[6], // M 6 + 1'b0, // zero 5 + 1'b0, // zero, S 4 + 1'b0, // zero, U 3 + csr_wdata_i[2], // EXECUTE 2 + csr_wdata_i[1], // STORE 1 + csr_wdata_i[0]}; // LOAD 0 tdata2_n = csr_wdata_i; tdata3_n = tdata3_rdata_o; // Read only @@ -110,53 +119,94 @@ import cv32e40x_pkg::*; tcontrol_n = tcontrol_rdata_o; // Read only end - // Breakpoint matching - // We match against the next address, as the breakpoint must be taken before execution - // Matching is disabled when ctrl_fsm_i.debug_mode == 1'b1 - // Trigger CSRs can only be written from debug mode, writes from any other privilege level are ignored. - // Thus we do not have an issue where a write to the tdata2 CSR immediately before the matched instruction - // could be missed since we must write in debug mode, then dret to machine mode (kills pipeline) before - // returning to dpc. - // Todo: There is no CLIC spec for trigger matches for pointers. - assign trigger_match_o = tdata1_rdata_o[2] && !ctrl_fsm_i.debug_mode && !ptr_in_if_i && - (pc_if_i[31:0] == tdata2_rdata_o[31:0]); - - - cv32e40x_csr - #( - .WIDTH (32), - .RESETVALUE (TDATA1_RST_VAL) - ) - tdata1_csr_i - ( - .clk ( clk ), - .rst_n ( rst_n ), - .wr_data_i ( tdata1_n ), - .wr_en_i ( tdata1_we_i ), - .rd_data_o ( tdata1_q ) - ); - + // Generate DBG_NUM_TRIGGERS instances of tdata1, tdata2 and match checks + genvar idx; + generate + for (idx=0; idx Date: Thu, 17 Nov 2022 10:11:47 +0100 Subject: [PATCH 2/3] - Fixed WARL resolution of tselect CSR. - Always including debug_triggers in cs_registers, not including logic if DBG_NUM_TRIGGERS=0. Makes RVFI connection easier. Signed-off-by: Oystein Knauserud --- bhv/cv32e40x_wrapper.sv | 12 +- rtl/cv32e40x_cs_registers.sv | 86 +++++------ rtl/cv32e40x_debug_triggers.sv | 260 ++++++++++++++++++--------------- 3 files changed, 185 insertions(+), 173 deletions(-) diff --git a/bhv/cv32e40x_wrapper.sv b/bhv/cv32e40x_wrapper.sv index 21b6e017..a466e4eb 100644 --- a/bhv/cv32e40x_wrapper.sv +++ b/bhv/cv32e40x_wrapper.sv @@ -560,16 +560,16 @@ endgenerate .csr_mclicbase_n_i ( core_i.cs_registers_i.mclicbase_n ), .csr_mclicbase_q_i ( core_i.cs_registers_i.mclicbase_rdata ), .csr_mclicbase_we_i ( core_i.cs_registers_i.mclicbase_we ), - .csr_tdata1_n_i ( core_i.cs_registers_i.triggers.debug_triggers_i.tdata1_n ), // If DBG_NUM_TRIGGERS=0 this connection will fail + .csr_tdata1_n_i ( core_i.cs_registers_i.debug_triggers_i.tdata1_n ), .csr_tdata1_q_i ( core_i.cs_registers_i.tdata1_rdata ), .csr_tdata1_we_i ( core_i.cs_registers_i.tdata1_we ), - .csr_tdata2_n_i ( core_i.cs_registers_i.triggers.debug_triggers_i.tdata2_n ), // If DBG_NUM_TRIGGERS=0 this connection will fail + .csr_tdata2_n_i ( core_i.cs_registers_i.debug_triggers_i.tdata2_n ), .csr_tdata2_q_i ( core_i.cs_registers_i.tdata2_rdata ), .csr_tdata2_we_i ( core_i.cs_registers_i.tdata2_we ), - .csr_tdata3_n_i ( core_i.cs_registers_i.triggers.debug_triggers_i.tdata3_n ), // If DBG_NUM_TRIGGERS=0 this connection will fail + .csr_tdata3_n_i ( core_i.cs_registers_i.debug_triggers_i.tdata3_n ), .csr_tdata3_q_i ( core_i.cs_registers_i.tdata3_rdata ), .csr_tdata3_we_i ( core_i.cs_registers_i.tdata3_we ), - .csr_tinfo_n_i ( core_i.cs_registers_i.triggers.debug_triggers_i.tinfo_n ), // If DBG_NUM_TRIGGERS=0 this connection will fail + .csr_tinfo_n_i ( core_i.cs_registers_i.debug_triggers_i.tinfo_n ), .csr_tinfo_q_i ( core_i.cs_registers_i.tinfo_rdata ), .csr_tinfo_we_i ( core_i.cs_registers_i.tinfo_we ), .csr_dcsr_n_i ( core_i.cs_registers_i.dcsr_n ), @@ -595,10 +595,10 @@ endgenerate .csr_mstatush_n_i ( core_i.cs_registers_i.mstatush_n ), .csr_mstatush_q_i ( core_i.cs_registers_i.mstatush_rdata ), .csr_mstatush_we_i ( core_i.cs_registers_i.mstatush_we ), - .csr_tcontrol_n_i ( core_i.cs_registers_i.triggers.debug_triggers_i.tcontrol_n ), // If DBG_NUM_TRIGGERS=0 this connection will fail + .csr_tcontrol_n_i ( core_i.cs_registers_i.debug_triggers_i.tcontrol_n ), .csr_tcontrol_q_i ( core_i.cs_registers_i.tcontrol_rdata ), .csr_tcontrol_we_i ( core_i.cs_registers_i.tcontrol_we ), - .csr_tselect_n_i ( core_i.cs_registers_i.triggers.debug_triggers_i.tselect_n ), // If DBG_NUM_TRIGGERS=0 this connection will fail + .csr_tselect_n_i ( core_i.cs_registers_i.debug_triggers_i.tselect_n ), .csr_tselect_q_i ( core_i.cs_registers_i.tselect_rdata ), .csr_tselect_we_i ( core_i.cs_registers_i.tselect_we ), diff --git a/rtl/cv32e40x_cs_registers.sv b/rtl/cv32e40x_cs_registers.sv index f23720ba..6ae05951 100644 --- a/rtl/cv32e40x_cs_registers.sv +++ b/rtl/cv32e40x_cs_registers.sv @@ -1486,54 +1486,44 @@ module cv32e40x_cs_registers import cv32e40x_pkg::*; // |____/ \___|_.__/ \__,_|\__, | |_||_| |_|\__, |\__, |\___|_| // // |___/ |___/ |___/ // //////////////////////////////////////////////////////////////////////// - generate - if (DBG_NUM_TRIGGERS > 0) begin : triggers - cv32e40x_debug_triggers - #( - .DBG_NUM_TRIGGERS (DBG_NUM_TRIGGERS) - ) - debug_triggers_i - ( - .clk ( clk ), - .rst_n ( rst_n ), - - // CSR inputs write inputs - .csr_wdata_i ( csr_wdata_int), - .tselect_we_i ( tselect_we ), - .tdata1_we_i ( tdata1_we ), - .tdata2_we_i ( tdata2_we ), - .tdata3_we_i ( tdata3_we ), - .tinfo_we_i ( tinfo_we ), - .tcontrol_we_i ( tcontrol_we ), - - // CSR read data outputs - .tselect_rdata_o ( tselect_rdata ), - .tdata1_rdata_o ( tdata1_rdata ), - .tdata2_rdata_o ( tdata2_rdata ), - .tdata3_rdata_o ( tdata3_rdata ), - .tinfo_rdata_o ( tinfo_rdata ), - .tcontrol_rdata_o ( tcontrol_rdata), - - // IF stage inputs - .pc_if_i ( pc_if_i ), - .ptr_in_if_i ( ptr_in_if_i ), - - // Controller inputs - .ctrl_fsm_i ( ctrl_fsm_i ), - - // Trigger match output - .trigger_match_o ( trigger_match_o ) - ); - end else begin : notriggers - assign trigger_match_o = 1'b0; - assign tselect_rdata = '0; - assign tdata1_rdata = '0; - assign tdata2_rdata = '0; - assign tdata3_rdata = '0; - assign tinfo_rdata = '0; - assign tcontrol_rdata = '0; - end -endgenerate + + cv32e40x_debug_triggers + #( + .DBG_NUM_TRIGGERS (DBG_NUM_TRIGGERS) + ) + debug_triggers_i + ( + .clk ( clk ), + .rst_n ( rst_n ), + + // CSR inputs write inputs + .csr_wdata_i ( csr_wdata_int), + .tselect_we_i ( tselect_we ), + .tdata1_we_i ( tdata1_we ), + .tdata2_we_i ( tdata2_we ), + .tdata3_we_i ( tdata3_we ), + .tinfo_we_i ( tinfo_we ), + .tcontrol_we_i ( tcontrol_we ), + + // CSR read data outputs + .tselect_rdata_o ( tselect_rdata ), + .tdata1_rdata_o ( tdata1_rdata ), + .tdata2_rdata_o ( tdata2_rdata ), + .tdata3_rdata_o ( tdata3_rdata ), + .tinfo_rdata_o ( tinfo_rdata ), + .tcontrol_rdata_o ( tcontrol_rdata), + + // IF stage inputs + .pc_if_i ( pc_if_i ), + .ptr_in_if_i ( ptr_in_if_i ), + + // Controller inputs + .ctrl_fsm_i ( ctrl_fsm_i ), + + // Trigger match output + .trigger_match_o ( trigger_match_o ) + ); + ///////////////////////////////////////////////////////////////// diff --git a/rtl/cv32e40x_debug_triggers.sv b/rtl/cv32e40x_debug_triggers.sv index bbd02500..cb2acb8f 100644 --- a/rtl/cv32e40x_debug_triggers.sv +++ b/rtl/cv32e40x_debug_triggers.sv @@ -74,139 +74,161 @@ import cv32e40x_pkg::*; logic [31:0] tinfo_n; logic [31:0] tcontrol_n; - // Internal CSR write enables - logic [DBG_NUM_TRIGGERS-1 : 0] tdata1_we_int; - logic [DBG_NUM_TRIGGERS-1 : 0] tdata2_we_int; - - // CSR instance outputs - logic [31:0] tdata1_q[DBG_NUM_TRIGGERS]; - logic [31:0] tdata2_q[DBG_NUM_TRIGGERS]; - logic [31:0] tselect_q; - - // Fetch stage trigger match - logic [DBG_NUM_TRIGGERS-1 : 0] trigger_match_if; - + // Signal for or'ing unused signals for easier lint logic unused_signals; - // Write data - always_comb begin - // Tselect is WARL (0 -> DBG_NUM_TRIGGERS-1) - tselect_n = (csr_wdata_i < DBG_NUM_TRIGGERS) ? csr_wdata_i : (DBG_NUM_TRIGGERS - 1); - - // todo: handle WARL based on trigger type - tdata1_n = { - TTYPE_MCONTROL6, // type : address/data match - 1'b1, // dmode : access from D mode only - 2'b00, // zero 26:25 - 3'b000, // zero, vs, vu, hit 24:22 - 1'b0, // zero, select 21 - 1'b0, // zero, timing 20 - 4'b0000, // zero, size (match any size) 19:16 - 4'b0001, // action, WARL(1), enter debug 15:12 - 1'b0, // zero, chain 11 - 4'b0000, // match, WARL(0,2,3) 10:7 todo: resolve WARL - csr_wdata_i[6], // M 6 - 1'b0, // zero 5 - 1'b0, // zero, S 4 - 1'b0, // zero, U 3 - csr_wdata_i[2], // EXECUTE 2 - csr_wdata_i[1], // STORE 1 - csr_wdata_i[0]}; // LOAD 0 - - tdata2_n = csr_wdata_i; - tdata3_n = tdata3_rdata_o; // Read only - tinfo_n = tinfo_rdata_o; // Read only - tcontrol_n = tcontrol_rdata_o; // Read only - end - - // Generate DBG_NUM_TRIGGERS instances of tdata1, tdata2 and match checks - genvar idx; generate - for (idx=0; idx 0) begin : gen_triggers + // Internal CSR write enables + logic [DBG_NUM_TRIGGERS-1 : 0] tdata1_we_int; + logic [DBG_NUM_TRIGGERS-1 : 0] tdata2_we_int; + + // CSR instance outputs + logic [31:0] tdata1_q[DBG_NUM_TRIGGERS]; + logic [31:0] tdata2_q[DBG_NUM_TRIGGERS]; + logic [31:0] tselect_q; + + // Fetch stage trigger match + logic [DBG_NUM_TRIGGERS-1 : 0] trigger_match_if; + + + // Write data + always_comb begin + // Tselect is WARL (0 -> DBG_NUM_TRIGGERS-1) + tselect_n = (csr_wdata_i < DBG_NUM_TRIGGERS) ? csr_wdata_i : tselect_rdata_o; + + // todo: handle WARL based on trigger type + tdata1_n = { + TTYPE_MCONTROL6, // type : address/data match + 1'b1, // dmode : access from D mode only + 2'b00, // zero 26:25 + 3'b000, // zero, vs, vu, hit 24:22 + 1'b0, // zero, select 21 + 1'b0, // zero, timing 20 + 4'b0000, // zero, size (match any size) 19:16 + 4'b0001, // action, WARL(1), enter debug 15:12 + 1'b0, // zero, chain 11 + 4'b0000, // match, WARL(0,2,3) 10:7 todo: resolve WARL + csr_wdata_i[6], // M 6 + 1'b0, // zero 5 + 1'b0, // zero, S 4 + 1'b0, // zero, U 3 + csr_wdata_i[2], // EXECUTE 2 + csr_wdata_i[1], // STORE 1 + csr_wdata_i[0]}; // LOAD 0 + + tdata2_n = csr_wdata_i; + tdata3_n = tdata3_rdata_o; // Read only + tinfo_n = tinfo_rdata_o; // Read only + tcontrol_n = tcontrol_rdata_o; // Read only + end + // Generate DBG_NUM_TRIGGERS instances of tdata1, tdata2 and match checks + for (genvar idx=0; idx