Module Definition
dashboard | hierarchy | modlist | groups | tests | asserts



Module Instance : tb.dut.u_ping_timer

Instance :
SCORELINECONDTOGGLEFSMBRANCHASSERT
99.46 100.00 97.30 100.00 100.00 100.00


Instance's subtree :
SCORELINECONDTOGGLEFSMBRANCHASSERT
99.57 100.00 97.44 100.00 100.00 100.00 100.00


Parent :
SCORELINECONDTOGGLEFSMBRANCHASSERTNAME
100.00 100.00 100.00 100.00 dut


Subtrees :
NAMESCORELINECONDTOGGLEFSMBRANCHASSERT
u_prim_buf_spurious_alert_ping 100.00 100.00
u_prim_buf_spurious_esc_ping 100.00 100.00
u_prim_count_cnt 100.00 100.00
u_prim_count_esc_cnt 100.00 100.00
u_prim_double_lfsr 100.00 100.00 100.00 100.00 100.00
u_state_regs 100.00 100.00 100.00 100.00

Line Coverage for Module : alert_handler_ping_timer
Line No.TotalCoveredPercent
TOTAL6262100.00
CONT_ASSIGN7811100.00
CONT_ASSIGN8111100.00
CONT_ASSIGN8211100.00
ALWAYS8533100.00
CONT_ASSIGN9911100.00
CONT_ASSIGN13411100.00
ALWAYS14144100.00
CONT_ASSIGN15211100.00
CONT_ASSIGN15611100.00
CONT_ASSIGN19611100.00
CONT_ASSIGN23311100.00
CONT_ASSIGN23411100.00
CONT_ASSIGN26411100.00
CONT_ASSIGN26511100.00
CONT_ASSIGN26811100.00
CONT_ASSIGN27811100.00
CONT_ASSIGN27911100.00
ALWAYS3313737100.00
ALWAYS42633100.00

77 78 1/1 assign reseed_timer_d = (reseed_timer_q > '0) ? reseed_timer_q - 1'b1 : Tests: T1 T2 T3  79 (reseed_en) ? {wait_cyc_mask_i, 80 {ReseedLfsrExtraBits{1'b1}}} : '0; 81 1/1 assign edn_req_o = (reseed_timer_q == '0); Tests: T1 T2 T3  82 1/1 assign reseed_en = edn_req_o & edn_ack_i; Tests: T1 T2 T3  83 84 always_ff @(posedge clk_i or negedge rst_ni) begin : p_regs 85 1/1 if (!rst_ni) begin Tests: T1 T2 T3  86 1/1 reseed_timer_q <= '0; Tests: T1 T2 T3  87 end else begin 88 1/1 reseed_timer_q <= reseed_timer_d; Tests: T1 T2 T3  89 end 90 end 91 92 /////////////////////////// 93 // Tandem LFSR Instances // 94 /////////////////////////// 95 96 logic cnt_set, lfsr_err; 97 logic [LfsrWidth-1:0] entropy; 98 logic [PING_CNT_DW + IdDw - 1:0] lfsr_state; 99 1/1 assign entropy = (reseed_en) ? edn_data_i[LfsrWidth-1:0] : '0; Tests: T1 T2 T3  100 101 // SEC_CM: PING_TIMER.LFSR.REDUN 102 // We employ two redundant LFSRs to guard against FI attacks. 103 // If any of the two is glitched and the two LFSR states do not agree, 104 // the FSM below is moved into a terminal error state and all ping alerts 105 // are permanently asserted. 106 prim_double_lfsr #( 107 .LfsrDw ( LfsrWidth ), 108 .EntropyDw ( LfsrWidth ), 109 .StateOutDw ( PING_CNT_DW + IdDw ), 110 .DefaultSeed ( RndCnstLfsrSeed ), 111 .StatePermEn ( 1'b1 ), 112 .StatePerm ( RndCnstLfsrPerm ), 113 .MaxLenSVA ( MaxLenSVA ), 114 .LockupSVA ( LockupSVA ), 115 .ExtSeedSVA ( 1'b0 ), // ext seed is unused 116 .EnableAlertTriggerSVA ( 1'b0 ) 117 ) u_prim_double_lfsr ( 118 .clk_i, 119 .rst_ni, 120 .seed_en_i ( 1'b0 ), 121 .seed_i ( '0 ), 122 .lfsr_en_i ( reseed_en || cnt_set ), 123 .entropy_i ( entropy ), 124 .state_o ( lfsr_state ), 125 .err_o ( lfsr_err ) 126 ); 127 128 logic [IdDw-1:0] id_to_ping_d, id_to_ping_q; 129 // The subtraction below ensures that the alert ID is always in range. If 130 // all alerts are enabled, an alert ID drawn in this way will always be 131 // valid. This comes at the cost of a bias towards certain alert IDs that 132 // will be pinged twice as often on average - but it ensures that we have 133 // less alert IDs that need to be skipped since they are invalid. 134 1/1 assign id_to_ping_d = (lfsr_state[PING_CNT_DW +: IdDw] >= NAlerts) ? Tests: T1 T2 T3  135 lfsr_state[PING_CNT_DW +: IdDw] - NAlerts : 136 lfsr_state[PING_CNT_DW +: IdDw]; 137 138 // we need to hold the ID stable while the ping is ongoing since this will result in 139 // spurious ping responses otherwise. 140 always_ff @(posedge clk_i or negedge rst_ni) begin : p_id_reg 141 1/1 if (!rst_ni) begin Tests: T1 T2 T3  142 1/1 id_to_ping_q <= '0; Tests: T1 T2 T3  143 end else begin 144 1/1 if (cnt_set) begin Tests: T1 T2 T3  145 1/1 id_to_ping_q <= id_to_ping_d; Tests: T9 T4 T5  146 end MISSING_ELSE 147 end 148 end 149 150 // align the enable mask with powers of two for the indexing operation below. 151 logic [2**IdDw-1:0] enable_mask; 152 1/1 assign enable_mask = (2**IdDw)'(alert_ping_en_i); Tests: T1 T2 T3  153 154 // check if the randomly drawn alert ID is actually valid and the alert is enabled 155 logic id_vld; 156 1/1 assign id_vld = enable_mask[id_to_ping_q]; Tests: T1 T2 T3  157 158 ////////////////////////////////// 159 // Escalation Counter Instances // 160 ////////////////////////////////// 161 162 // As opposed to the alert ID, the escalation sender ID to be pinged is not drawn at random. 163 // Rather, we cycle through the escalation senders one by one in a deterministic fashion. 164 // This allows us to provide guarantees needed for the ping timeout / auto escalation feature 165 // implemented at the escalation receiver side. 166 // 167 // In particular, with N_ESC_SEV escalation senders in the design, we can guarantee 168 // that each escalation channel will be pinged at least once every 169 // 170 // N_ESC_SEV x (NUM_WAIT_COUNT + NUM_TIMEOUT_COUNT) x 2**PING_CNT_DW 171 // 172 // cycles - independently of the reseeding operation. 173 // 174 // - N_ESC_SEV: # escalation channels to ping. 175 // - NUM_WAIT_COUNT: # wait counts between subsequent escalation channel pings. 176 // - NUM_TIMEOUT_COUNT: # timeout counts between subsequent escalation channel pings. 177 // - 2**PING_CNT_DW: # maximum counter value. 178 // 179 // This guarantee is used inside the escalation receivers to monitor the pings sent out by the 180 // alert handler. I.e., once the alert handler has started to send out pings, each escalation 181 // receiver employs a timeout window within which it expects the next ping to arrive. If 182 // escalation pings cease to arrive at an escalation receiver for any reason, this will 183 // automatically trigger the associated escalation countermeasure. 184 // 185 // In order to have enough margin, the escalation receiver timeout counters use a threshold that 186 // is 4x higher than the value calculated above. With N_ESC_SEV = 4, PING_CNT_DW = 16 and 187 // NUM_WAIT_COUNT = NUM_TIMEOUT_COUNT = 2 this amounts to a 22bit timeout threshold. 188 // 189 // We employ two redundant counters to guard against FI attacks. 190 // If any of the two is glitched and the two counter states do not agree, 191 // the FSM below is moved into a terminal error state and all ping alerts 192 // are permanently asserted. 193 194 logic esc_cnt_en, esc_cnt_clr, esc_cnt_error; 195 logic [EscSenderIdxWidth-1:0] esc_cnt; 196 1/1 assign esc_cnt_clr = (esc_cnt >= EscSenderIdxWidth'(N_ESC_SEV-1)) && esc_cnt_en; Tests: T1 T2 T3  197 198 // SEC_CM: PING_TIMER.CTR.REDUN 199 prim_count #( 200 .Width(EscSenderIdxWidth), 201 // The alert handler behaves differently than other comportable IP. I.e., instead of sending out 202 // an alert signal, this condition is handled internally in the alert handler. 203 .EnableAlertTriggerSVA(0), 204 // Pass a parameter to disable coverage for some assertions that are unreachable because set_i 205 // and decr_en_i are tied to zero. 206 .PossibleActions(prim_count_pkg::Clr | 207 prim_count_pkg::Incr) 208 ) u_prim_count_esc_cnt ( 209 .clk_i, 210 .rst_ni, 211 .clr_i(esc_cnt_clr), 212 .set_i(1'b0), 213 .set_cnt_i('0), 214 .incr_en_i(esc_cnt_en), 215 .decr_en_i(1'b0), 216 .step_i(EscSenderIdxWidth'(1)), 217 .commit_i(1'b1), 218 .cnt_o(esc_cnt), 219 .cnt_after_commit_o(), 220 .err_o(esc_cnt_error) 221 ); 222 223 ///////////////////////////// 224 // Timer Counter Instances // 225 ///////////////////////////// 226 227 // We employ two redundant counters to guard against FI attacks. 228 // If any of the two is glitched and the two counter states do not agree, 229 // the FSM below is moved into a terminal error state and all ping alerts 230 // are permanently asserted. 231 logic [PING_CNT_DW-1:0] cnt, cnt_setval; 232 logic wait_cnt_set, timeout_cnt_set, timer_expired, cnt_error; 233 1/1 assign timer_expired = (cnt == '0); Tests: T1 T2 T3  234 1/1 assign cnt_set = wait_cnt_set || timeout_cnt_set; Tests: T1 T2 T3  235 236 // SEC_CM: PING_TIMER.CTR.REDUN 237 prim_count #( 238 .Width(PING_CNT_DW), 239 // The alert handler behaves differently than other comportable IP. I.e., instead of sending out 240 // an alert signal, this condition is handled internally in the alert handler. 241 .EnableAlertTriggerSVA(0), 242 // Pass a parameter to disable coverage for some assertions that are unreachable because clr_i 243 // and incr_en_i are tied to zero. 244 .PossibleActions(prim_count_pkg::Set | 245 prim_count_pkg::Decr) 246 ) u_prim_count_cnt ( 247 .clk_i, 248 .rst_ni, 249 .clr_i(1'b0), 250 .set_i(cnt_set), 251 .set_cnt_i(cnt_setval), 252 .incr_en_i(1'b0), 253 .decr_en_i(1'b1), // we are counting down here. 254 .step_i(PING_CNT_DW'(1'b1)), 255 .commit_i(1'b1), 256 .cnt_o(cnt), 257 .cnt_after_commit_o(), 258 .err_o(cnt_error) 259 ); 260 261 // the constant offset ensures a minimum cycle spacing between pings. 262 logic unused_bits; 263 logic [PING_CNT_DW-1:0] wait_cyc; 264 1/1 assign wait_cyc = (lfsr_state[PING_CNT_DW-1:0] | PING_CNT_DW'(3'b100)); Tests: T1 T2 T3  265 1/1 assign unused_bits = lfsr_state[2]; Tests: T1 T2 T3  266 267 // note that the masks are used for DV/FPV only in order to reduce the state space. 268 1/1 assign cnt_setval = (wait_cnt_set) ? (wait_cyc & wait_cyc_mask_i) : ping_timeout_cyc_i; Tests: T1 T2 T3  269 270 //////////////////////////// 271 // Ping and Timeout Logic // 272 //////////////////////////// 273 274 logic alert_ping_en, esc_ping_en; 275 logic spurious_alert_ping, spurious_esc_ping; 276 277 // generate ping enable vector 278 1/1 assign alert_ping_req_o = NAlerts'(alert_ping_en) << id_to_ping_q; Tests: T1 T2 T3  279 1/1 assign esc_ping_req_o = EscSenderIdxWidth'(esc_ping_en) << esc_cnt; Tests: T1 T2 T3  280 281 // under normal operation, these signals should never be asserted. 282 // we place hand instantiated buffers here such that these signals are not 283 // optimized away during synthesis (these buffers will receive a keep or size_only 284 // attribute in our Vivado and DC synthesis flows). 285 prim_buf u_prim_buf_spurious_alert_ping ( 286 .in_i(|(alert_ping_ok_i & ~alert_ping_req_o)), 287 .out_o(spurious_alert_ping) 288 ); 289 prim_buf u_prim_buf_spurious_esc_ping ( 290 .in_i(|(esc_ping_ok_i & ~esc_ping_req_o)), 291 .out_o(spurious_esc_ping) 292 ); 293 294 // SEC_CM: PING_TIMER.FSM.SPARSE 295 // Encoding generated with: 296 // $ ./util/design/sparse-fsm-encode.py -d 5 -m 6 -n 9 \ 297 // -s 728582219 --language=sv 298 // 299 // Hamming distance histogram: 300 // 301 // 0: -- 302 // 1: -- 303 // 2: -- 304 // 3: -- 305 // 4: -- 306 // 5: |||||||||||||||||||| (60.00%) 307 // 6: ||||||||||||| (40.00%) 308 // 7: -- 309 // 8: -- 310 // 9: -- 311 // 312 // Minimum Hamming distance: 5 313 // Maximum Hamming distance: 6 314 // Minimum Hamming weight: 2 315 // Maximum Hamming weight: 6 316 // 317 localparam int StateWidth = 9; 318 typedef enum logic [StateWidth-1:0] { 319 InitSt = 9'b011001011, 320 AlertWaitSt = 9'b110000000, 321 AlertPingSt = 9'b101110001, 322 EscWaitSt = 9'b010110110, 323 EscPingSt = 9'b000011101, 324 FsmErrorSt = 9'b101101110 325 } state_e; 326 327 state_e state_d, state_q; 328 329 always_comb begin : p_fsm 330 // default 331 1/1 state_d = state_q; Tests: T1 T2 T3  332 1/1 wait_cnt_set = 1'b0; Tests: T1 T2 T3  333 1/1 timeout_cnt_set = 1'b0; Tests: T1 T2 T3  334 1/1 esc_cnt_en = 1'b0; Tests: T1 T2 T3  335 1/1 alert_ping_en = 1'b0; Tests: T1 T2 T3  336 1/1 esc_ping_en = 1'b0; Tests: T1 T2 T3  337 // this captures spurious ping responses 338 1/1 alert_ping_fail_o = spurious_alert_ping; Tests: T1 T2 T3  339 1/1 esc_ping_fail_o = spurious_esc_ping; Tests: T1 T2 T3  340 341 1/1 unique case (state_q) Tests: T1 T2 T3  342 // wait until activated 343 // we never return to this state 344 // once activated! 345 InitSt: begin 346 1/1 if (en_i) begin Tests: T1 T2 T3  347 1/1 state_d = AlertWaitSt; Tests: T9 T4 T5  348 1/1 wait_cnt_set = 1'b1; Tests: T9 T4 T5  349 end MISSING_ELSE 350 end 351 // wait for random amount of cycles 352 AlertWaitSt: begin 353 1/1 if (timer_expired) begin Tests: T9 T4 T5  354 1/1 state_d = AlertPingSt; Tests: T9 T4 T7  355 1/1 timeout_cnt_set = 1'b1; Tests: T9 T4 T7  356 end MISSING_ELSE 357 end 358 // SEC_CM: ALERT_RX.INTERSIG.BKGN_CHK 359 // send out an alert ping request and wait for a ping 360 // response or a ping timeout (whatever comes first). 361 // if the alert ID is not valid, we drop the request and 362 // proceed to the next ping. 363 AlertPingSt: begin 364 1/1 alert_ping_en = id_vld; Tests: T9 T4 T7  365 1/1 if (timer_expired || |(alert_ping_ok_i & alert_ping_req_o) || !id_vld) begin Tests: T9 T4 T7  366 1/1 state_d = EscWaitSt; Tests: T9 T4 T7  367 1/1 wait_cnt_set = 1'b1; Tests: T9 T4 T7  368 1/1 if (timer_expired) begin Tests: T9 T4 T7  369 1/1 alert_ping_fail_o = 1'b1; Tests: T14 T15 T16  370 end MISSING_ELSE 371 end MISSING_ELSE 372 end 373 // wait for random amount of cycles 374 EscWaitSt: begin 375 1/1 if (timer_expired) begin Tests: T9 T4 T7  376 1/1 state_d = EscPingSt; Tests: T9 T4 T7  377 1/1 timeout_cnt_set = 1'b1; Tests: T9 T4 T7  378 end MISSING_ELSE 379 end 380 // SEC_CM: ESC_TX.INTERSIG.BKGN_CHK 381 // send out an escalation ping request and wait for a ping 382 // response or a ping timeout (whatever comes first) 383 EscPingSt: begin 384 1/1 esc_ping_en = 1'b1; Tests: T9 T4 T7  385 1/1 if (timer_expired || |(esc_ping_ok_i & esc_ping_req_o)) begin Tests: T9 T4 T7  386 1/1 state_d = AlertWaitSt; Tests: T9 T4 T7  387 1/1 wait_cnt_set = 1'b1; Tests: T9 T4 T7  388 1/1 esc_cnt_en = 1'b1; Tests: T9 T4 T7  389 1/1 if (timer_expired) begin Tests: T9 T4 T7  390 1/1 esc_ping_fail_o = 1'b1; Tests: T14 T15 T16  391 end MISSING_ELSE 392 end MISSING_ELSE 393 end 394 // SEC_CM: PING_TIMER.FSM.LOCAL_ESC 395 // terminal FSM error state. 396 // if we for some reason end up in this state (e.g. malicious glitching) 397 // we are going to assert both ping fails continuously 398 FsmErrorSt: begin 399 1/1 alert_ping_fail_o = 1'b1; Tests: T5 T6 T10  400 1/1 esc_ping_fail_o = 1'b1; Tests: T5 T6 T10  401 end 402 default: begin 403 state_d = FsmErrorSt; 404 alert_ping_fail_o = 1'b1; 405 esc_ping_fail_o = 1'b1; 406 end 407 endcase 408 409 // SEC_CM: PING_TIMER.FSM.LOCAL_ESC 410 // if the two LFSR or counter states do not agree, 411 // we move into the terminal state. 412 1/1 if (lfsr_err || cnt_error || esc_cnt_error) begin Tests: T1 T2 T3  413 1/1 state_d = FsmErrorSt; Tests: T5 T6 T10  414 1/1 alert_ping_fail_o = 1'b1; Tests: T5 T6 T10  415 1/1 esc_ping_fail_o = 1'b1; Tests: T5 T6 T10  416 end MISSING_ELSE 417 end 418 419 /////////////////// 420 // FSM Registers // 421 /////////////////// 422 423 // The alert handler behaves differently than other comportable IP. I.e., instead of sending out 424 // an alert signal, this condition is handled internally in the alert handler. The 425 // EnableAlertTriggerSVA parameter is therefore set to 0. 426 3/3 `PRIM_FLOP_SPARSE_FSM(u_state_regs, state_d, state_q, state_e, InitSt, clk_i, rst_ni, 0) Tests: T1 T2 T3  | T1 T2 T3  | T1 T2 T3 
PRIM_FLOP_SPARSE_FSM(u_state_regs, state_d, state_q, state_e, InitSt, clk_i, rst_ni, 0): 426.1 `ifdef SIMULATION 426.2 prim_sparse_fsm_flop #( 426.3 .StateEnumT(state_e), 426.4 .Width($bits(state_e)), 426.5 .ResetValue($bits(state_e)'(InitSt)), 426.6 .EnableAlertTriggerSVA(0), 426.7 .CustomForceName("state_q") 426.8 ) u_state_regs ( 426.9 .clk_i ( clk_i ), 426.10 .rst_ni ( rst_ni ), 426.11 .state_i ( state_d ), 426.12 .state_o ( ) 426.13 ); 426.14 always_ff @(posedge clk_i or negedge rst_ni) begin 426.15 1/1 if (!rst_ni) begin Tests: T1 T2 T3  426.16 1/1 state_q <= InitSt; Tests: T1 T2 T3  426.17 end else begin 426.18 1/1 state_q <= state_d; Tests: T1 T2 T3  426.19 end 426.20 end 426.21 u_state_regs_A: assert property (@(posedge clk_i) disable iff ((!rst_ni) !== '0) (state_q === u_state_regs.state_o)) 426.22 else begin 426.23 `ifdef UVM 426.24 uvm_pkg::uvm_report_error("ASSERT FAILED", "u_state_regs_A", uvm_pkg::UVM_NONE, 426.25 "../src/lowrisc_ip_alert_handler_component_0.1/rtl/alert_handler_ping_timer.sv", 426, "", 1); 426.26 `else 426.27 $error("%0t: (%0s:%0d) [%m] [ASSERT FAILED] %0s", $time, `__FILE__, `__LINE__, 426.28 `PRIM_STRINGIFY(u_state_regs_A)); 426.29 `endif 426.30 end 426.31 `else 426.32 prim_sparse_fsm_flop #( 426.33 .StateEnumT(state_e), 426.34 .Width($bits(state_e)), 426.35 .ResetValue($bits(state_e)'(InitSt)), 426.36 .EnableAlertTriggerSVA(0) 426.37 ) u_state_regs ( 426.38 .clk_i ( clk_i ), 426.39 .rst_ni ( rst_ni ), 426.40 .state_i ( state_d ), 426.41 .state_o ( state_q ) 426.42 ); 426.43 `endif

Cond Coverage for Module : alert_handler_ping_timer
TotalCoveredPercent
Conditions373697.30
Logical373697.30
Non-Logical00
Event00

 LINE       78
 EXPRESSION ((reseed_timer_q > '0) ? ((reseed_timer_q - 1'b1)) : (reseed_en ? ({wait_cyc_mask_i, {ReseedLfsrExtraBits {1'b1}}}) : '0))
             ----------1----------
-1-StatusTests
0CoveredT1,T2,T3
1CoveredT1,T2,T3

 LINE       78
 SUB-EXPRESSION (reseed_en ? ({wait_cyc_mask_i, {ReseedLfsrExtraBits {1'b1}}}) : '0)
                 ----1----
-1-StatusTests
0CoveredT1,T2,T3
1CoveredT1,T2,T3

 LINE       81
 EXPRESSION (reseed_timer_q == '0)
            -----------1----------
-1-StatusTests
0CoveredT1,T2,T3
1CoveredT1,T2,T3

 LINE       82
 EXPRESSION (edn_req_o & edn_ack_i)
             ----1----   ----2----
-1--2-StatusTests
01Not Covered
10CoveredT1,T2,T3
11CoveredT1,T2,T3

 LINE       99
 EXPRESSION (reseed_en ? edn_data_i[(alert_pkg::LfsrWidth - 1):0] : '0)
             ----1----
-1-StatusTests
0CoveredT1,T2,T3
1CoveredT1,T2,T3

 LINE       117
 EXPRESSION (reseed_en || cnt_set)
             ----1----    ---2---
-1--2-StatusTests
00CoveredT1,T2,T3
01CoveredT9,T4,T5
10CoveredT1,T2,T3

 LINE       134
 EXPRESSION 
 Number  Term
      1  (lfsr_state[alert_pkg::PING_CNT_DW+:IdDw] >= alert_pkg::NAlerts) ? ((lfsr_state[alert_pkg::PING_CNT_DW+:IdDw] - alert_pkg::NAlerts)) : lfsr_state[alert_pkg::PING_CNT_DW+:IdDw])
-1-StatusTests
0CoveredT1,T2,T3
1CoveredT2,T11,T9

 LINE       196
 EXPRESSION ((esc_cnt >= 2'((alert_pkg::N_ESC_SEV - 1))) && esc_cnt_en)
             ---------------------1---------------------    -----2----
-1--2-StatusTests
01CoveredT9,T4,T7
10CoveredT4,T5,T7
11CoveredT4,T7,T8

 LINE       233
 EXPRESSION (cnt == '0)
            -----1-----
-1-StatusTests
0CoveredT1,T2,T3
1CoveredT1,T2,T3

 LINE       234
 EXPRESSION (wait_cnt_set || timeout_cnt_set)
             ------1-----    -------2-------
-1--2-StatusTests
00CoveredT1,T2,T3
01CoveredT9,T4,T7
10CoveredT9,T4,T5

 LINE       268
 EXPRESSION (wait_cnt_set ? ((wait_cyc & wait_cyc_mask_i)) : ping_timeout_cyc_i)
             ------1-----
-1-StatusTests
0CoveredT1,T2,T3
1CoveredT9,T4,T5

 LINE       365
 EXPRESSION (timer_expired || ((|(alert_ping_ok_i & alert_ping_req_o))) || ((!id_vld)))
             ------1------    --------------------2--------------------    -----3-----
-1--2--3-StatusTests
000CoveredT4,T7,T8
001CoveredT9,T4,T8
010CoveredT4,T7,T8
100CoveredT14,T15,T16

 LINE       385
 EXPRESSION (timer_expired || ((|(esc_ping_ok_i & esc_ping_req_o))))
             ------1------    ------------------2------------------
-1--2-StatusTests
00CoveredT9,T4,T7
01CoveredT9,T4,T7
10CoveredT14,T15,T16

 LINE       412
 EXPRESSION (lfsr_err || cnt_error || esc_cnt_error)
             ----1---    ----2----    ------3------
-1--2--3-StatusTests
000CoveredT1,T2,T3
001CoveredT5,T6,T10
010CoveredT5,T6,T10
100CoveredT5,T6,T10

FSM Coverage for Module : alert_handler_ping_timer
Summary for FSM :: state_q
TotalCoveredPercent
States 6 6 100.00 (Not included in score)
Transitions 10 6 60.00
Sequences 0 0

State, Transition and Sequence Details for FSM :: state_q
statesLine No.CoveredTests
AlertPingSt 354 Covered T9,T4,T7
AlertWaitSt 347 Covered T9,T4,T5
EscPingSt 376 Covered T9,T4,T7
EscWaitSt 366 Covered T9,T4,T7
FsmErrorSt 413 Covered T5,T6,T10
InitSt 345 Covered T1,T2,T3


transitionsLine No.CoveredTests
AlertPingSt->EscWaitSt 366 Covered T9,T4,T7
AlertPingSt->FsmErrorSt 413 Not Covered
AlertWaitSt->AlertPingSt 354 Covered T9,T4,T7
AlertWaitSt->FsmErrorSt 413 Covered T5,T6,T10
EscPingSt->AlertWaitSt 386 Covered T9,T4,T7
EscPingSt->FsmErrorSt 413 Not Covered
EscWaitSt->EscPingSt 376 Covered T9,T4,T7
EscWaitSt->FsmErrorSt 413 Not Covered
InitSt->AlertWaitSt 347 Covered T9,T4,T5
InitSt->FsmErrorSt 413 Not Covered



Branch Coverage for Module : alert_handler_ping_timer
Line No.TotalCoveredPercent
Branches 32 32 100.00
TERNARY 78 3 3 100.00
TERNARY 99 2 2 100.00
TERNARY 134 2 2 100.00
TERNARY 268 2 2 100.00
IF 85 2 2 100.00
IF 141 3 3 100.00
CASE 341 14 14 100.00
IF 412 2 2 100.00
IF 426 2 2 100.00


78 assign reseed_timer_d = (reseed_timer_q > '0) ? reseed_timer_q - 1'b1 : -1- ==> 79 (reseed_en) ? {wait_cyc_mask_i, -2- ==> ==>

Branches:
-1--2-StatusTests
1 - Covered T1,T2,T3
0 1 Covered T1,T2,T3
0 0 Covered T1,T2,T3


99 assign entropy = (reseed_en) ? edn_data_i[LfsrWidth-1:0] : '0; -1- ==> ==>

Branches:
-1-StatusTests
1 Covered T1,T2,T3
0 Covered T1,T2,T3


134 assign id_to_ping_d = (lfsr_state[PING_CNT_DW +: IdDw] >= NAlerts) ? -1- ==> ==>

Branches:
-1-StatusTests
1 Covered T2,T11,T9
0 Covered T1,T2,T3


268 assign cnt_setval = (wait_cnt_set) ? (wait_cyc & wait_cyc_mask_i) : ping_timeout_cyc_i; -1- ==> ==>

Branches:
-1-StatusTests
1 Covered T9,T4,T5
0 Covered T1,T2,T3


85 if (!rst_ni) begin -1- 86 reseed_timer_q <= '0; ==> 87 end else begin 88 reseed_timer_q <= reseed_timer_d; ==>

Branches:
-1-StatusTests
1 Covered T1,T2,T3
0 Covered T1,T2,T3


141 if (!rst_ni) begin -1- 142 id_to_ping_q <= '0; ==> 143 end else begin 144 if (cnt_set) begin -2- 145 id_to_ping_q <= id_to_ping_d; ==> 146 end MISSING_ELSE ==>

Branches:
-1--2-StatusTests
1 - Covered T1,T2,T3
0 1 Covered T9,T4,T5
0 0 Covered T1,T2,T3


341 unique case (state_q) -1- 342 // wait until activated 343 // we never return to this state 344 // once activated! 345 InitSt: begin 346 if (en_i) begin -2- 347 state_d = AlertWaitSt; ==> 348 wait_cnt_set = 1'b1; 349 end MISSING_ELSE ==> 350 end 351 // wait for random amount of cycles 352 AlertWaitSt: begin 353 if (timer_expired) begin -3- 354 state_d = AlertPingSt; ==> 355 timeout_cnt_set = 1'b1; 356 end MISSING_ELSE ==> 357 end 358 // SEC_CM: ALERT_RX.INTERSIG.BKGN_CHK 359 // send out an alert ping request and wait for a ping 360 // response or a ping timeout (whatever comes first). 361 // if the alert ID is not valid, we drop the request and 362 // proceed to the next ping. 363 AlertPingSt: begin 364 alert_ping_en = id_vld; 365 if (timer_expired || |(alert_ping_ok_i & alert_ping_req_o) || !id_vld) begin -4- 366 state_d = EscWaitSt; 367 wait_cnt_set = 1'b1; 368 if (timer_expired) begin -5- 369 alert_ping_fail_o = 1'b1; ==> 370 end MISSING_ELSE ==> 371 end MISSING_ELSE ==> 372 end 373 // wait for random amount of cycles 374 EscWaitSt: begin 375 if (timer_expired) begin -6- 376 state_d = EscPingSt; ==> 377 timeout_cnt_set = 1'b1; 378 end MISSING_ELSE ==> 379 end 380 // SEC_CM: ESC_TX.INTERSIG.BKGN_CHK 381 // send out an escalation ping request and wait for a ping 382 // response or a ping timeout (whatever comes first) 383 EscPingSt: begin 384 esc_ping_en = 1'b1; 385 if (timer_expired || |(esc_ping_ok_i & esc_ping_req_o)) begin -7- 386 state_d = AlertWaitSt; 387 wait_cnt_set = 1'b1; 388 esc_cnt_en = 1'b1; 389 if (timer_expired) begin -8- 390 esc_ping_fail_o = 1'b1; ==> 391 end MISSING_ELSE ==> 392 end MISSING_ELSE ==> 393 end 394 // SEC_CM: PING_TIMER.FSM.LOCAL_ESC 395 // terminal FSM error state. 396 // if we for some reason end up in this state (e.g. malicious glitching) 397 // we are going to assert both ping fails continuously 398 FsmErrorSt: begin 399 alert_ping_fail_o = 1'b1; ==> 400 esc_ping_fail_o = 1'b1; 401 end 402 default: begin 403 state_d = FsmErrorSt; ==>

Branches:
-1--2--3--4--5--6--7--8-StatusTests
InitSt 1 - - - - - - Covered T9,T4,T5
InitSt 0 - - - - - - Covered T1,T2,T3
AlertWaitSt - 1 - - - - - Covered T9,T4,T7
AlertWaitSt - 0 - - - - - Covered T9,T4,T5
AlertPingSt - - 1 1 - - - Covered T14,T15,T16
AlertPingSt - - 1 0 - - - Covered T9,T4,T7
AlertPingSt - - 0 - - - - Covered T4,T7,T8
EscWaitSt - - - - 1 - - Covered T9,T4,T7
EscWaitSt - - - - 0 - - Covered T9,T4,T7
EscPingSt - - - - - 1 1 Covered T14,T15,T16
EscPingSt - - - - - 1 0 Covered T9,T4,T7
EscPingSt - - - - - 0 - Covered T9,T4,T7
FsmErrorSt - - - - - - - Covered T5,T6,T10
default - - - - - - - Covered T5,T6,T10


412 if (lfsr_err || cnt_error || esc_cnt_error) begin -1- 413 state_d = FsmErrorSt; ==> 414 alert_ping_fail_o = 1'b1; 415 esc_ping_fail_o = 1'b1; 416 end MISSING_ELSE ==>

Branches:
-1-StatusTests
1 Covered T5,T6,T10
0 Covered T1,T2,T3


426 `PRIM_FLOP_SPARSE_FSM(u_state_regs, state_d, state_q, state_e, InitSt, clk_i, rst_ni, 0) -1- ==> ==>

Branches:
-1-StatusTests
1 Covered T1,T2,T3
0 Covered T1,T2,T3


Assert Coverage for Module : alert_handler_ping_timer
TotalAttemptedPercentSucceeded/MatchedPercent
Assertions 7 7 100.00 7 100.00
Cover properties 0 0 0
Cover sequences 0 0 0
Total 7 7 100.00 7 100.00




Assertion Details

NameAttemptsReal SuccessesFailuresIncomplete
AlertPingOH_A 551568653 187458 0 0
EscPingOH_A 551568653 129251 0 0
MaxIdDw_A 620 620 0 0
PingOH0_A 551568653 551399471 0 0
WaitCycMaskIsRightAlignedMask_A 551568653 551399471 0 0
WaitCycMaskMin_A 551568653 551399471 0 0
u_state_regs_A 551568653 551399471 0 0


AlertPingOH_A
NameAttemptsReal SuccessesFailuresIncomplete
Total 551568653 187458 0 0
T4 39376 2402 0 0
T5 44267 0 0 0
T6 44863 0 0 0
T7 0 2024 0 0
T8 0 2459 0 0
T12 30323 0 0 0
T13 17225 0 0 0
T14 0 725 0 0
T15 0 1686 0 0
T16 0 3554 0 0
T17 0 1652 0 0
T18 0 2132 0 0
T19 0 3526 0 0
T20 0 2726 0 0
T21 56602 0 0 0
T22 978 0 0 0
T23 61429 0 0 0
T24 68915 0 0 0
T25 7373 0 0 0

EscPingOH_A
NameAttemptsReal SuccessesFailuresIncomplete
Total 551568653 129251 0 0
T4 39376 2380 0 0
T5 44267 0 0 0
T6 44863 0 0 0
T7 0 1950 0 0
T8 0 2430 0 0
T9 21505 5 0 0
T12 30323 0 0 0
T13 17225 0 0 0
T14 0 305 0 0
T15 0 526 0 0
T17 0 1645 0 0
T18 0 2105 0 0
T19 0 3485 0 0
T21 56602 0 0 0
T22 978 0 0 0
T23 61429 0 0 0
T24 68915 0 0 0
T26 0 5 0 0

MaxIdDw_A
NameAttemptsReal SuccessesFailuresIncomplete
Total 620 620 0 0
T1 1 1 0 0
T2 1 1 0 0
T3 1 1 0 0
T4 1 1 0 0
T5 1 1 0 0
T9 1 1 0 0
T11 1 1 0 0
T12 1 1 0 0
T21 1 1 0 0
T22 1 1 0 0

PingOH0_A
NameAttemptsReal SuccessesFailuresIncomplete
Total 551568653 551399471 0 0
T1 4132 4034 0 0
T2 10946 10859 0 0
T3 16605 16517 0 0
T4 39376 39218 0 0
T5 44267 18769 0 0
T9 21505 21433 0 0
T11 12961 12876 0 0
T12 30323 30241 0 0
T21 56602 56503 0 0
T22 978 922 0 0

WaitCycMaskIsRightAlignedMask_A
NameAttemptsReal SuccessesFailuresIncomplete
Total 551568653 551399471 0 0
T1 4132 4034 0 0
T2 10946 10859 0 0
T3 16605 16517 0 0
T4 39376 39218 0 0
T5 44267 18769 0 0
T9 21505 21433 0 0
T11 12961 12876 0 0
T12 30323 30241 0 0
T21 56602 56503 0 0
T22 978 922 0 0

WaitCycMaskMin_A
NameAttemptsReal SuccessesFailuresIncomplete
Total 551568653 551399471 0 0
T1 4132 4034 0 0
T2 10946 10859 0 0
T3 16605 16517 0 0
T4 39376 39218 0 0
T5 44267 18769 0 0
T9 21505 21433 0 0
T11 12961 12876 0 0
T12 30323 30241 0 0
T21 56602 56503 0 0
T22 978 922 0 0

u_state_regs_A
NameAttemptsReal SuccessesFailuresIncomplete
Total 551568653 551399471 0 0
T1 4132 4034 0 0
T2 10946 10859 0 0
T3 16605 16517 0 0
T4 39376 39218 0 0
T5 44267 18769 0 0
T9 21505 21433 0 0
T11 12961 12876 0 0
T12 30323 30241 0 0
T21 56602 56503 0 0
T22 978 922 0 0

Line Coverage for Instance : tb.dut.u_ping_timer
Line No.TotalCoveredPercent
TOTAL6262100.00
CONT_ASSIGN7811100.00
CONT_ASSIGN8111100.00
CONT_ASSIGN8211100.00
ALWAYS8533100.00
CONT_ASSIGN9911100.00
CONT_ASSIGN13411100.00
ALWAYS14144100.00
CONT_ASSIGN15211100.00
CONT_ASSIGN15611100.00
CONT_ASSIGN19611100.00
CONT_ASSIGN23311100.00
CONT_ASSIGN23411100.00
CONT_ASSIGN26411100.00
CONT_ASSIGN26511100.00
CONT_ASSIGN26811100.00
CONT_ASSIGN27811100.00
CONT_ASSIGN27911100.00
ALWAYS3313737100.00
ALWAYS42633100.00

77 78 1/1 assign reseed_timer_d = (reseed_timer_q > '0) ? reseed_timer_q - 1'b1 : Tests: T1 T2 T3  79 (reseed_en) ? {wait_cyc_mask_i, 80 {ReseedLfsrExtraBits{1'b1}}} : '0; 81 1/1 assign edn_req_o = (reseed_timer_q == '0); Tests: T1 T2 T3  82 1/1 assign reseed_en = edn_req_o & edn_ack_i; Tests: T1 T2 T3  83 84 always_ff @(posedge clk_i or negedge rst_ni) begin : p_regs 85 1/1 if (!rst_ni) begin Tests: T1 T2 T3  86 1/1 reseed_timer_q <= '0; Tests: T1 T2 T3  87 end else begin 88 1/1 reseed_timer_q <= reseed_timer_d; Tests: T1 T2 T3  89 end 90 end 91 92 /////////////////////////// 93 // Tandem LFSR Instances // 94 /////////////////////////// 95 96 logic cnt_set, lfsr_err; 97 logic [LfsrWidth-1:0] entropy; 98 logic [PING_CNT_DW + IdDw - 1:0] lfsr_state; 99 1/1 assign entropy = (reseed_en) ? edn_data_i[LfsrWidth-1:0] : '0; Tests: T1 T2 T3  100 101 // SEC_CM: PING_TIMER.LFSR.REDUN 102 // We employ two redundant LFSRs to guard against FI attacks. 103 // If any of the two is glitched and the two LFSR states do not agree, 104 // the FSM below is moved into a terminal error state and all ping alerts 105 // are permanently asserted. 106 prim_double_lfsr #( 107 .LfsrDw ( LfsrWidth ), 108 .EntropyDw ( LfsrWidth ), 109 .StateOutDw ( PING_CNT_DW + IdDw ), 110 .DefaultSeed ( RndCnstLfsrSeed ), 111 .StatePermEn ( 1'b1 ), 112 .StatePerm ( RndCnstLfsrPerm ), 113 .MaxLenSVA ( MaxLenSVA ), 114 .LockupSVA ( LockupSVA ), 115 .ExtSeedSVA ( 1'b0 ), // ext seed is unused 116 .EnableAlertTriggerSVA ( 1'b0 ) 117 ) u_prim_double_lfsr ( 118 .clk_i, 119 .rst_ni, 120 .seed_en_i ( 1'b0 ), 121 .seed_i ( '0 ), 122 .lfsr_en_i ( reseed_en || cnt_set ), 123 .entropy_i ( entropy ), 124 .state_o ( lfsr_state ), 125 .err_o ( lfsr_err ) 126 ); 127 128 logic [IdDw-1:0] id_to_ping_d, id_to_ping_q; 129 // The subtraction below ensures that the alert ID is always in range. If 130 // all alerts are enabled, an alert ID drawn in this way will always be 131 // valid. This comes at the cost of a bias towards certain alert IDs that 132 // will be pinged twice as often on average - but it ensures that we have 133 // less alert IDs that need to be skipped since they are invalid. 134 1/1 assign id_to_ping_d = (lfsr_state[PING_CNT_DW +: IdDw] >= NAlerts) ? Tests: T1 T2 T3  135 lfsr_state[PING_CNT_DW +: IdDw] - NAlerts : 136 lfsr_state[PING_CNT_DW +: IdDw]; 137 138 // we need to hold the ID stable while the ping is ongoing since this will result in 139 // spurious ping responses otherwise. 140 always_ff @(posedge clk_i or negedge rst_ni) begin : p_id_reg 141 1/1 if (!rst_ni) begin Tests: T1 T2 T3  142 1/1 id_to_ping_q <= '0; Tests: T1 T2 T3  143 end else begin 144 1/1 if (cnt_set) begin Tests: T1 T2 T3  145 1/1 id_to_ping_q <= id_to_ping_d; Tests: T9 T4 T5  146 end MISSING_ELSE 147 end 148 end 149 150 // align the enable mask with powers of two for the indexing operation below. 151 logic [2**IdDw-1:0] enable_mask; 152 1/1 assign enable_mask = (2**IdDw)'(alert_ping_en_i); Tests: T1 T2 T3  153 154 // check if the randomly drawn alert ID is actually valid and the alert is enabled 155 logic id_vld; 156 1/1 assign id_vld = enable_mask[id_to_ping_q]; Tests: T1 T2 T3  157 158 ////////////////////////////////// 159 // Escalation Counter Instances // 160 ////////////////////////////////// 161 162 // As opposed to the alert ID, the escalation sender ID to be pinged is not drawn at random. 163 // Rather, we cycle through the escalation senders one by one in a deterministic fashion. 164 // This allows us to provide guarantees needed for the ping timeout / auto escalation feature 165 // implemented at the escalation receiver side. 166 // 167 // In particular, with N_ESC_SEV escalation senders in the design, we can guarantee 168 // that each escalation channel will be pinged at least once every 169 // 170 // N_ESC_SEV x (NUM_WAIT_COUNT + NUM_TIMEOUT_COUNT) x 2**PING_CNT_DW 171 // 172 // cycles - independently of the reseeding operation. 173 // 174 // - N_ESC_SEV: # escalation channels to ping. 175 // - NUM_WAIT_COUNT: # wait counts between subsequent escalation channel pings. 176 // - NUM_TIMEOUT_COUNT: # timeout counts between subsequent escalation channel pings. 177 // - 2**PING_CNT_DW: # maximum counter value. 178 // 179 // This guarantee is used inside the escalation receivers to monitor the pings sent out by the 180 // alert handler. I.e., once the alert handler has started to send out pings, each escalation 181 // receiver employs a timeout window within which it expects the next ping to arrive. If 182 // escalation pings cease to arrive at an escalation receiver for any reason, this will 183 // automatically trigger the associated escalation countermeasure. 184 // 185 // In order to have enough margin, the escalation receiver timeout counters use a threshold that 186 // is 4x higher than the value calculated above. With N_ESC_SEV = 4, PING_CNT_DW = 16 and 187 // NUM_WAIT_COUNT = NUM_TIMEOUT_COUNT = 2 this amounts to a 22bit timeout threshold. 188 // 189 // We employ two redundant counters to guard against FI attacks. 190 // If any of the two is glitched and the two counter states do not agree, 191 // the FSM below is moved into a terminal error state and all ping alerts 192 // are permanently asserted. 193 194 logic esc_cnt_en, esc_cnt_clr, esc_cnt_error; 195 logic [EscSenderIdxWidth-1:0] esc_cnt; 196 1/1 assign esc_cnt_clr = (esc_cnt >= EscSenderIdxWidth'(N_ESC_SEV-1)) && esc_cnt_en; Tests: T1 T2 T3  197 198 // SEC_CM: PING_TIMER.CTR.REDUN 199 prim_count #( 200 .Width(EscSenderIdxWidth), 201 // The alert handler behaves differently than other comportable IP. I.e., instead of sending out 202 // an alert signal, this condition is handled internally in the alert handler. 203 .EnableAlertTriggerSVA(0), 204 // Pass a parameter to disable coverage for some assertions that are unreachable because set_i 205 // and decr_en_i are tied to zero. 206 .PossibleActions(prim_count_pkg::Clr | 207 prim_count_pkg::Incr) 208 ) u_prim_count_esc_cnt ( 209 .clk_i, 210 .rst_ni, 211 .clr_i(esc_cnt_clr), 212 .set_i(1'b0), 213 .set_cnt_i('0), 214 .incr_en_i(esc_cnt_en), 215 .decr_en_i(1'b0), 216 .step_i(EscSenderIdxWidth'(1)), 217 .commit_i(1'b1), 218 .cnt_o(esc_cnt), 219 .cnt_after_commit_o(), 220 .err_o(esc_cnt_error) 221 ); 222 223 ///////////////////////////// 224 // Timer Counter Instances // 225 ///////////////////////////// 226 227 // We employ two redundant counters to guard against FI attacks. 228 // If any of the two is glitched and the two counter states do not agree, 229 // the FSM below is moved into a terminal error state and all ping alerts 230 // are permanently asserted. 231 logic [PING_CNT_DW-1:0] cnt, cnt_setval; 232 logic wait_cnt_set, timeout_cnt_set, timer_expired, cnt_error; 233 1/1 assign timer_expired = (cnt == '0); Tests: T1 T2 T3  234 1/1 assign cnt_set = wait_cnt_set || timeout_cnt_set; Tests: T1 T2 T3  235 236 // SEC_CM: PING_TIMER.CTR.REDUN 237 prim_count #( 238 .Width(PING_CNT_DW), 239 // The alert handler behaves differently than other comportable IP. I.e., instead of sending out 240 // an alert signal, this condition is handled internally in the alert handler. 241 .EnableAlertTriggerSVA(0), 242 // Pass a parameter to disable coverage for some assertions that are unreachable because clr_i 243 // and incr_en_i are tied to zero. 244 .PossibleActions(prim_count_pkg::Set | 245 prim_count_pkg::Decr) 246 ) u_prim_count_cnt ( 247 .clk_i, 248 .rst_ni, 249 .clr_i(1'b0), 250 .set_i(cnt_set), 251 .set_cnt_i(cnt_setval), 252 .incr_en_i(1'b0), 253 .decr_en_i(1'b1), // we are counting down here. 254 .step_i(PING_CNT_DW'(1'b1)), 255 .commit_i(1'b1), 256 .cnt_o(cnt), 257 .cnt_after_commit_o(), 258 .err_o(cnt_error) 259 ); 260 261 // the constant offset ensures a minimum cycle spacing between pings. 262 logic unused_bits; 263 logic [PING_CNT_DW-1:0] wait_cyc; 264 1/1 assign wait_cyc = (lfsr_state[PING_CNT_DW-1:0] | PING_CNT_DW'(3'b100)); Tests: T1 T2 T3  265 1/1 assign unused_bits = lfsr_state[2]; Tests: T1 T2 T3  266 267 // note that the masks are used for DV/FPV only in order to reduce the state space. 268 1/1 assign cnt_setval = (wait_cnt_set) ? (wait_cyc & wait_cyc_mask_i) : ping_timeout_cyc_i; Tests: T1 T2 T3  269 270 //////////////////////////// 271 // Ping and Timeout Logic // 272 //////////////////////////// 273 274 logic alert_ping_en, esc_ping_en; 275 logic spurious_alert_ping, spurious_esc_ping; 276 277 // generate ping enable vector 278 1/1 assign alert_ping_req_o = NAlerts'(alert_ping_en) << id_to_ping_q; Tests: T1 T2 T3  279 1/1 assign esc_ping_req_o = EscSenderIdxWidth'(esc_ping_en) << esc_cnt; Tests: T1 T2 T3  280 281 // under normal operation, these signals should never be asserted. 282 // we place hand instantiated buffers here such that these signals are not 283 // optimized away during synthesis (these buffers will receive a keep or size_only 284 // attribute in our Vivado and DC synthesis flows). 285 prim_buf u_prim_buf_spurious_alert_ping ( 286 .in_i(|(alert_ping_ok_i & ~alert_ping_req_o)), 287 .out_o(spurious_alert_ping) 288 ); 289 prim_buf u_prim_buf_spurious_esc_ping ( 290 .in_i(|(esc_ping_ok_i & ~esc_ping_req_o)), 291 .out_o(spurious_esc_ping) 292 ); 293 294 // SEC_CM: PING_TIMER.FSM.SPARSE 295 // Encoding generated with: 296 // $ ./util/design/sparse-fsm-encode.py -d 5 -m 6 -n 9 \ 297 // -s 728582219 --language=sv 298 // 299 // Hamming distance histogram: 300 // 301 // 0: -- 302 // 1: -- 303 // 2: -- 304 // 3: -- 305 // 4: -- 306 // 5: |||||||||||||||||||| (60.00%) 307 // 6: ||||||||||||| (40.00%) 308 // 7: -- 309 // 8: -- 310 // 9: -- 311 // 312 // Minimum Hamming distance: 5 313 // Maximum Hamming distance: 6 314 // Minimum Hamming weight: 2 315 // Maximum Hamming weight: 6 316 // 317 localparam int StateWidth = 9; 318 typedef enum logic [StateWidth-1:0] { 319 InitSt = 9'b011001011, 320 AlertWaitSt = 9'b110000000, 321 AlertPingSt = 9'b101110001, 322 EscWaitSt = 9'b010110110, 323 EscPingSt = 9'b000011101, 324 FsmErrorSt = 9'b101101110 325 } state_e; 326 327 state_e state_d, state_q; 328 329 always_comb begin : p_fsm 330 // default 331 1/1 state_d = state_q; Tests: T1 T2 T3  332 1/1 wait_cnt_set = 1'b0; Tests: T1 T2 T3  333 1/1 timeout_cnt_set = 1'b0; Tests: T1 T2 T3  334 1/1 esc_cnt_en = 1'b0; Tests: T1 T2 T3  335 1/1 alert_ping_en = 1'b0; Tests: T1 T2 T3  336 1/1 esc_ping_en = 1'b0; Tests: T1 T2 T3  337 // this captures spurious ping responses 338 1/1 alert_ping_fail_o = spurious_alert_ping; Tests: T1 T2 T3  339 1/1 esc_ping_fail_o = spurious_esc_ping; Tests: T1 T2 T3  340 341 1/1 unique case (state_q) Tests: T1 T2 T3  342 // wait until activated 343 // we never return to this state 344 // once activated! 345 InitSt: begin 346 1/1 if (en_i) begin Tests: T1 T2 T3  347 1/1 state_d = AlertWaitSt; Tests: T9 T4 T5  348 1/1 wait_cnt_set = 1'b1; Tests: T9 T4 T5  349 end MISSING_ELSE 350 end 351 // wait for random amount of cycles 352 AlertWaitSt: begin 353 1/1 if (timer_expired) begin Tests: T9 T4 T5  354 1/1 state_d = AlertPingSt; Tests: T9 T4 T7  355 1/1 timeout_cnt_set = 1'b1; Tests: T9 T4 T7  356 end MISSING_ELSE 357 end 358 // SEC_CM: ALERT_RX.INTERSIG.BKGN_CHK 359 // send out an alert ping request and wait for a ping 360 // response or a ping timeout (whatever comes first). 361 // if the alert ID is not valid, we drop the request and 362 // proceed to the next ping. 363 AlertPingSt: begin 364 1/1 alert_ping_en = id_vld; Tests: T9 T4 T7  365 1/1 if (timer_expired || |(alert_ping_ok_i & alert_ping_req_o) || !id_vld) begin Tests: T9 T4 T7  366 1/1 state_d = EscWaitSt; Tests: T9 T4 T7  367 1/1 wait_cnt_set = 1'b1; Tests: T9 T4 T7  368 1/1 if (timer_expired) begin Tests: T9 T4 T7  369 1/1 alert_ping_fail_o = 1'b1; Tests: T14 T15 T16  370 end MISSING_ELSE 371 end MISSING_ELSE 372 end 373 // wait for random amount of cycles 374 EscWaitSt: begin 375 1/1 if (timer_expired) begin Tests: T9 T4 T7  376 1/1 state_d = EscPingSt; Tests: T9 T4 T7  377 1/1 timeout_cnt_set = 1'b1; Tests: T9 T4 T7  378 end MISSING_ELSE 379 end 380 // SEC_CM: ESC_TX.INTERSIG.BKGN_CHK 381 // send out an escalation ping request and wait for a ping 382 // response or a ping timeout (whatever comes first) 383 EscPingSt: begin 384 1/1 esc_ping_en = 1'b1; Tests: T9 T4 T7  385 1/1 if (timer_expired || |(esc_ping_ok_i & esc_ping_req_o)) begin Tests: T9 T4 T7  386 1/1 state_d = AlertWaitSt; Tests: T9 T4 T7  387 1/1 wait_cnt_set = 1'b1; Tests: T9 T4 T7  388 1/1 esc_cnt_en = 1'b1; Tests: T9 T4 T7  389 1/1 if (timer_expired) begin Tests: T9 T4 T7  390 1/1 esc_ping_fail_o = 1'b1; Tests: T14 T15 T16  391 end MISSING_ELSE 392 end MISSING_ELSE 393 end 394 // SEC_CM: PING_TIMER.FSM.LOCAL_ESC 395 // terminal FSM error state. 396 // if we for some reason end up in this state (e.g. malicious glitching) 397 // we are going to assert both ping fails continuously 398 FsmErrorSt: begin 399 1/1 alert_ping_fail_o = 1'b1; Tests: T5 T6 T10  400 1/1 esc_ping_fail_o = 1'b1; Tests: T5 T6 T10  401 end 402 default: begin 403 state_d = FsmErrorSt; 404 alert_ping_fail_o = 1'b1; 405 esc_ping_fail_o = 1'b1; 406 end 407 endcase 408 409 // SEC_CM: PING_TIMER.FSM.LOCAL_ESC 410 // if the two LFSR or counter states do not agree, 411 // we move into the terminal state. 412 1/1 if (lfsr_err || cnt_error || esc_cnt_error) begin Tests: T1 T2 T3  413 1/1 state_d = FsmErrorSt; Tests: T5 T6 T10  414 1/1 alert_ping_fail_o = 1'b1; Tests: T5 T6 T10  415 1/1 esc_ping_fail_o = 1'b1; Tests: T5 T6 T10  416 end MISSING_ELSE 417 end 418 419 /////////////////// 420 // FSM Registers // 421 /////////////////// 422 423 // The alert handler behaves differently than other comportable IP. I.e., instead of sending out 424 // an alert signal, this condition is handled internally in the alert handler. The 425 // EnableAlertTriggerSVA parameter is therefore set to 0. 426 3/3 `PRIM_FLOP_SPARSE_FSM(u_state_regs, state_d, state_q, state_e, InitSt, clk_i, rst_ni, 0) Tests: T1 T2 T3  | T1 T2 T3  | T1 T2 T3 
PRIM_FLOP_SPARSE_FSM(u_state_regs, state_d, state_q, state_e, InitSt, clk_i, rst_ni, 0): 426.1 `ifdef SIMULATION 426.2 prim_sparse_fsm_flop #( 426.3 .StateEnumT(state_e), 426.4 .Width($bits(state_e)), 426.5 .ResetValue($bits(state_e)'(InitSt)), 426.6 .EnableAlertTriggerSVA(0), 426.7 .CustomForceName("state_q") 426.8 ) u_state_regs ( 426.9 .clk_i ( clk_i ), 426.10 .rst_ni ( rst_ni ), 426.11 .state_i ( state_d ), 426.12 .state_o ( ) 426.13 ); 426.14 always_ff @(posedge clk_i or negedge rst_ni) begin 426.15 1/1 if (!rst_ni) begin Tests: T1 T2 T3  426.16 1/1 state_q <= InitSt; Tests: T1 T2 T3  426.17 end else begin 426.18 1/1 state_q <= state_d; Tests: T1 T2 T3  426.19 end 426.20 end 426.21 u_state_regs_A: assert property (@(posedge clk_i) disable iff ((!rst_ni) !== '0) (state_q === u_state_regs.state_o)) 426.22 else begin 426.23 `ifdef UVM 426.24 uvm_pkg::uvm_report_error("ASSERT FAILED", "u_state_regs_A", uvm_pkg::UVM_NONE, 426.25 "../src/lowrisc_ip_alert_handler_component_0.1/rtl/alert_handler_ping_timer.sv", 426, "", 1); 426.26 `else 426.27 $error("%0t: (%0s:%0d) [%m] [ASSERT FAILED] %0s", $time, `__FILE__, `__LINE__, 426.28 `PRIM_STRINGIFY(u_state_regs_A)); 426.29 `endif 426.30 end 426.31 `else 426.32 prim_sparse_fsm_flop #( 426.33 .StateEnumT(state_e), 426.34 .Width($bits(state_e)), 426.35 .ResetValue($bits(state_e)'(InitSt)), 426.36 .EnableAlertTriggerSVA(0) 426.37 ) u_state_regs ( 426.38 .clk_i ( clk_i ), 426.39 .rst_ni ( rst_ni ), 426.40 .state_i ( state_d ), 426.41 .state_o ( state_q ) 426.42 ); 426.43 `endif

Cond Coverage for Instance : tb.dut.u_ping_timer
TotalCoveredPercent
Conditions373697.30
Logical373697.30
Non-Logical00
Event00

 LINE       78
 EXPRESSION ((reseed_timer_q > '0) ? ((reseed_timer_q - 1'b1)) : (reseed_en ? ({wait_cyc_mask_i, {ReseedLfsrExtraBits {1'b1}}}) : '0))
             ----------1----------
-1-StatusTests
0CoveredT1,T2,T3
1CoveredT1,T2,T3

 LINE       78
 SUB-EXPRESSION (reseed_en ? ({wait_cyc_mask_i, {ReseedLfsrExtraBits {1'b1}}}) : '0)
                 ----1----
-1-StatusTests
0CoveredT1,T2,T3
1CoveredT1,T2,T3

 LINE       81
 EXPRESSION (reseed_timer_q == '0)
            -----------1----------
-1-StatusTests
0CoveredT1,T2,T3
1CoveredT1,T2,T3

 LINE       82
 EXPRESSION (edn_req_o & edn_ack_i)
             ----1----   ----2----
-1--2-StatusTests
01Not Covered
10CoveredT1,T2,T3
11CoveredT1,T2,T3

 LINE       99
 EXPRESSION (reseed_en ? edn_data_i[(alert_pkg::LfsrWidth - 1):0] : '0)
             ----1----
-1-StatusTests
0CoveredT1,T2,T3
1CoveredT1,T2,T3

 LINE       117
 EXPRESSION (reseed_en || cnt_set)
             ----1----    ---2---
-1--2-StatusTests
00CoveredT1,T2,T3
01CoveredT9,T4,T5
10CoveredT1,T2,T3

 LINE       134
 EXPRESSION 
 Number  Term
      1  (lfsr_state[alert_pkg::PING_CNT_DW+:IdDw] >= alert_pkg::NAlerts) ? ((lfsr_state[alert_pkg::PING_CNT_DW+:IdDw] - alert_pkg::NAlerts)) : lfsr_state[alert_pkg::PING_CNT_DW+:IdDw])
-1-StatusTests
0CoveredT1,T2,T3
1CoveredT2,T11,T9

 LINE       196
 EXPRESSION ((esc_cnt >= 2'((alert_pkg::N_ESC_SEV - 1))) && esc_cnt_en)
             ---------------------1---------------------    -----2----
-1--2-StatusTests
01CoveredT9,T4,T7
10CoveredT4,T5,T7
11CoveredT4,T7,T8

 LINE       233
 EXPRESSION (cnt == '0)
            -----1-----
-1-StatusTests
0CoveredT1,T2,T3
1CoveredT1,T2,T3

 LINE       234
 EXPRESSION (wait_cnt_set || timeout_cnt_set)
             ------1-----    -------2-------
-1--2-StatusTests
00CoveredT1,T2,T3
01CoveredT9,T4,T7
10CoveredT9,T4,T5

 LINE       268
 EXPRESSION (wait_cnt_set ? ((wait_cyc & wait_cyc_mask_i)) : ping_timeout_cyc_i)
             ------1-----
-1-StatusTests
0CoveredT1,T2,T3
1CoveredT9,T4,T5

 LINE       365
 EXPRESSION (timer_expired || ((|(alert_ping_ok_i & alert_ping_req_o))) || ((!id_vld)))
             ------1------    --------------------2--------------------    -----3-----
-1--2--3-StatusTests
000CoveredT4,T7,T8
001CoveredT9,T4,T8
010CoveredT4,T7,T8
100CoveredT14,T15,T16

 LINE       385
 EXPRESSION (timer_expired || ((|(esc_ping_ok_i & esc_ping_req_o))))
             ------1------    ------------------2------------------
-1--2-StatusTests
00CoveredT9,T4,T7
01CoveredT9,T4,T7
10CoveredT14,T15,T16

 LINE       412
 EXPRESSION (lfsr_err || cnt_error || esc_cnt_error)
             ----1---    ----2----    ------3------
-1--2--3-StatusTests
000CoveredT1,T2,T3
001CoveredT5,T6,T10
010CoveredT5,T6,T10
100CoveredT5,T6,T10

FSM Coverage for Instance : tb.dut.u_ping_timer
Summary for FSM :: state_q
TotalCoveredPercent
States 6 6 100.00 (Not included in score)
Transitions 6 6 100.00
Sequences 0 0

State, Transition and Sequence Details for FSM :: state_q
statesLine No.CoveredTests
AlertPingSt 354 Covered T9,T4,T7
AlertWaitSt 347 Covered T9,T4,T5
EscPingSt 376 Covered T9,T4,T7
EscWaitSt 366 Covered T9,T4,T7
FsmErrorSt 413 Covered T5,T6,T10
InitSt 345 Covered T1,T2,T3


transitionsLine No.CoveredTestsExclude Annotation
AlertPingSt->EscWaitSt 366 Covered T9,T4,T7
AlertPingSt->FsmErrorSt 413 Excluded [LOW_RISK]: Forcing from any state other than IdleSt to FSMErrorSt is covered in FPV.
AlertWaitSt->AlertPingSt 354 Covered T9,T4,T7
AlertWaitSt->FsmErrorSt 413 Covered T5,T6,T10
EscPingSt->AlertWaitSt 386 Covered T9,T4,T7
EscPingSt->FsmErrorSt 413 Excluded [LOW_RISK]: Forcing from any state other than IdleSt to FSMErrorSt is covered in FPV.
EscWaitSt->EscPingSt 376 Covered T9,T4,T7
EscWaitSt->FsmErrorSt 413 Excluded [LOW_RISK]: Forcing from any state other than IdleSt to FSMErrorSt is covered in FPV.
InitSt->AlertWaitSt 347 Covered T9,T4,T5
InitSt->FsmErrorSt 413 Excluded [LOW_RISK]: Forcing from any state other than IdleSt to FSMErrorSt is covered in FPV.



Branch Coverage for Instance : tb.dut.u_ping_timer
Line No.TotalCoveredPercent
Branches 32 32 100.00
TERNARY 78 3 3 100.00
TERNARY 99 2 2 100.00
TERNARY 134 2 2 100.00
TERNARY 268 2 2 100.00
IF 85 2 2 100.00
IF 141 3 3 100.00
CASE 341 14 14 100.00
IF 412 2 2 100.00
IF 426 2 2 100.00


78 assign reseed_timer_d = (reseed_timer_q > '0) ? reseed_timer_q - 1'b1 : -1- ==> 79 (reseed_en) ? {wait_cyc_mask_i, -2- ==> ==>

Branches:
-1--2-StatusTests
1 - Covered T1,T2,T3
0 1 Covered T1,T2,T3
0 0 Covered T1,T2,T3


99 assign entropy = (reseed_en) ? edn_data_i[LfsrWidth-1:0] : '0; -1- ==> ==>

Branches:
-1-StatusTests
1 Covered T1,T2,T3
0 Covered T1,T2,T3


134 assign id_to_ping_d = (lfsr_state[PING_CNT_DW +: IdDw] >= NAlerts) ? -1- ==> ==>

Branches:
-1-StatusTests
1 Covered T2,T11,T9
0 Covered T1,T2,T3


268 assign cnt_setval = (wait_cnt_set) ? (wait_cyc & wait_cyc_mask_i) : ping_timeout_cyc_i; -1- ==> ==>

Branches:
-1-StatusTests
1 Covered T9,T4,T5
0 Covered T1,T2,T3


85 if (!rst_ni) begin -1- 86 reseed_timer_q <= '0; ==> 87 end else begin 88 reseed_timer_q <= reseed_timer_d; ==>

Branches:
-1-StatusTests
1 Covered T1,T2,T3
0 Covered T1,T2,T3


141 if (!rst_ni) begin -1- 142 id_to_ping_q <= '0; ==> 143 end else begin 144 if (cnt_set) begin -2- 145 id_to_ping_q <= id_to_ping_d; ==> 146 end MISSING_ELSE ==>

Branches:
-1--2-StatusTests
1 - Covered T1,T2,T3
0 1 Covered T9,T4,T5
0 0 Covered T1,T2,T3


341 unique case (state_q) -1- 342 // wait until activated 343 // we never return to this state 344 // once activated! 345 InitSt: begin 346 if (en_i) begin -2- 347 state_d = AlertWaitSt; ==> 348 wait_cnt_set = 1'b1; 349 end MISSING_ELSE ==> 350 end 351 // wait for random amount of cycles 352 AlertWaitSt: begin 353 if (timer_expired) begin -3- 354 state_d = AlertPingSt; ==> 355 timeout_cnt_set = 1'b1; 356 end MISSING_ELSE ==> 357 end 358 // SEC_CM: ALERT_RX.INTERSIG.BKGN_CHK 359 // send out an alert ping request and wait for a ping 360 // response or a ping timeout (whatever comes first). 361 // if the alert ID is not valid, we drop the request and 362 // proceed to the next ping. 363 AlertPingSt: begin 364 alert_ping_en = id_vld; 365 if (timer_expired || |(alert_ping_ok_i & alert_ping_req_o) || !id_vld) begin -4- 366 state_d = EscWaitSt; 367 wait_cnt_set = 1'b1; 368 if (timer_expired) begin -5- 369 alert_ping_fail_o = 1'b1; ==> 370 end MISSING_ELSE ==> 371 end MISSING_ELSE ==> 372 end 373 // wait for random amount of cycles 374 EscWaitSt: begin 375 if (timer_expired) begin -6- 376 state_d = EscPingSt; ==> 377 timeout_cnt_set = 1'b1; 378 end MISSING_ELSE ==> 379 end 380 // SEC_CM: ESC_TX.INTERSIG.BKGN_CHK 381 // send out an escalation ping request and wait for a ping 382 // response or a ping timeout (whatever comes first) 383 EscPingSt: begin 384 esc_ping_en = 1'b1; 385 if (timer_expired || |(esc_ping_ok_i & esc_ping_req_o)) begin -7- 386 state_d = AlertWaitSt; 387 wait_cnt_set = 1'b1; 388 esc_cnt_en = 1'b1; 389 if (timer_expired) begin -8- 390 esc_ping_fail_o = 1'b1; ==> 391 end MISSING_ELSE ==> 392 end MISSING_ELSE ==> 393 end 394 // SEC_CM: PING_TIMER.FSM.LOCAL_ESC 395 // terminal FSM error state. 396 // if we for some reason end up in this state (e.g. malicious glitching) 397 // we are going to assert both ping fails continuously 398 FsmErrorSt: begin 399 alert_ping_fail_o = 1'b1; ==> 400 esc_ping_fail_o = 1'b1; 401 end 402 default: begin 403 state_d = FsmErrorSt; ==>

Branches:
-1--2--3--4--5--6--7--8-StatusTests
InitSt 1 - - - - - - Covered T9,T4,T5
InitSt 0 - - - - - - Covered T1,T2,T3
AlertWaitSt - 1 - - - - - Covered T9,T4,T7
AlertWaitSt - 0 - - - - - Covered T9,T4,T5
AlertPingSt - - 1 1 - - - Covered T14,T15,T16
AlertPingSt - - 1 0 - - - Covered T9,T4,T7
AlertPingSt - - 0 - - - - Covered T4,T7,T8
EscWaitSt - - - - 1 - - Covered T9,T4,T7
EscWaitSt - - - - 0 - - Covered T9,T4,T7
EscPingSt - - - - - 1 1 Covered T14,T15,T16
EscPingSt - - - - - 1 0 Covered T9,T4,T7
EscPingSt - - - - - 0 - Covered T9,T4,T7
FsmErrorSt - - - - - - - Covered T5,T6,T10
default - - - - - - - Covered T5,T6,T10


412 if (lfsr_err || cnt_error || esc_cnt_error) begin -1- 413 state_d = FsmErrorSt; ==> 414 alert_ping_fail_o = 1'b1; 415 esc_ping_fail_o = 1'b1; 416 end MISSING_ELSE ==>

Branches:
-1-StatusTests
1 Covered T5,T6,T10
0 Covered T1,T2,T3


426 `PRIM_FLOP_SPARSE_FSM(u_state_regs, state_d, state_q, state_e, InitSt, clk_i, rst_ni, 0) -1- ==> ==>

Branches:
-1-StatusTests
1 Covered T1,T2,T3
0 Covered T1,T2,T3


Assert Coverage for Instance : tb.dut.u_ping_timer
TotalAttemptedPercentSucceeded/MatchedPercent
Assertions 7 7 100.00 7 100.00
Cover properties 0 0 0
Cover sequences 0 0 0
Total 7 7 100.00 7 100.00




Assertion Details

NameAttemptsReal SuccessesFailuresIncomplete
AlertPingOH_A 551568653 187458 0 0
EscPingOH_A 551568653 129251 0 0
MaxIdDw_A 620 620 0 0
PingOH0_A 551568653 551399471 0 0
WaitCycMaskIsRightAlignedMask_A 551568653 551399471 0 0
WaitCycMaskMin_A 551568653 551399471 0 0
u_state_regs_A 551568653 551399471 0 0


AlertPingOH_A
NameAttemptsReal SuccessesFailuresIncomplete
Total 551568653 187458 0 0
T4 39376 2402 0 0
T5 44267 0 0 0
T6 44863 0 0 0
T7 0 2024 0 0
T8 0 2459 0 0
T12 30323 0 0 0
T13 17225 0 0 0
T14 0 725 0 0
T15 0 1686 0 0
T16 0 3554 0 0
T17 0 1652 0 0
T18 0 2132 0 0
T19 0 3526 0 0
T20 0 2726 0 0
T21 56602 0 0 0
T22 978 0 0 0
T23 61429 0 0 0
T24 68915 0 0 0
T25 7373 0 0 0

EscPingOH_A
NameAttemptsReal SuccessesFailuresIncomplete
Total 551568653 129251 0 0
T4 39376 2380 0 0
T5 44267 0 0 0
T6 44863 0 0 0
T7 0 1950 0 0
T8 0 2430 0 0
T9 21505 5 0 0
T12 30323 0 0 0
T13 17225 0 0 0
T14 0 305 0 0
T15 0 526 0 0
T17 0 1645 0 0
T18 0 2105 0 0
T19 0 3485 0 0
T21 56602 0 0 0
T22 978 0 0 0
T23 61429 0 0 0
T24 68915 0 0 0
T26 0 5 0 0

MaxIdDw_A
NameAttemptsReal SuccessesFailuresIncomplete
Total 620 620 0 0
T1 1 1 0 0
T2 1 1 0 0
T3 1 1 0 0
T4 1 1 0 0
T5 1 1 0 0
T9 1 1 0 0
T11 1 1 0 0
T12 1 1 0 0
T21 1 1 0 0
T22 1 1 0 0

PingOH0_A
NameAttemptsReal SuccessesFailuresIncomplete
Total 551568653 551399471 0 0
T1 4132 4034 0 0
T2 10946 10859 0 0
T3 16605 16517 0 0
T4 39376 39218 0 0
T5 44267 18769 0 0
T9 21505 21433 0 0
T11 12961 12876 0 0
T12 30323 30241 0 0
T21 56602 56503 0 0
T22 978 922 0 0

WaitCycMaskIsRightAlignedMask_A
NameAttemptsReal SuccessesFailuresIncomplete
Total 551568653 551399471 0 0
T1 4132 4034 0 0
T2 10946 10859 0 0
T3 16605 16517 0 0
T4 39376 39218 0 0
T5 44267 18769 0 0
T9 21505 21433 0 0
T11 12961 12876 0 0
T12 30323 30241 0 0
T21 56602 56503 0 0
T22 978 922 0 0

WaitCycMaskMin_A
NameAttemptsReal SuccessesFailuresIncomplete
Total 551568653 551399471 0 0
T1 4132 4034 0 0
T2 10946 10859 0 0
T3 16605 16517 0 0
T4 39376 39218 0 0
T5 44267 18769 0 0
T9 21505 21433 0 0
T11 12961 12876 0 0
T12 30323 30241 0 0
T21 56602 56503 0 0
T22 978 922 0 0

u_state_regs_A
NameAttemptsReal SuccessesFailuresIncomplete
Total 551568653 551399471 0 0
T1 4132 4034 0 0
T2 10946 10859 0 0
T3 16605 16517 0 0
T4 39376 39218 0 0
T5 44267 18769 0 0
T9 21505 21433 0 0
T11 12961 12876 0 0
T12 30323 30241 0 0
T21 56602 56503 0 0
T22 978 922 0 0

0% 10% 20% 30% 40% 50% 60% 70% 80% 90% 100%