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



Module Instance : tb.dut.u_dm_top.i_dm_mem

Instance :
SCORELINECONDTOGGLEFSMBRANCHASSERT
87.55 89.30 72.41 100.00 88.46


Instance's subtree :
SCORELINECONDTOGGLEFSMBRANCHASSERT
88.08 89.69 73.33 100.00 89.29


Parent :
SCORELINECONDTOGGLEFSMBRANCHASSERTNAME
100.00 100.00 u_dm_top


Subtrees :
NAMESCORELINECONDTOGGLEFSMBRANCHASSERT
gen_rom_snd_scratch.i_debug_rom 100.00 100.00 100.00 100.00

Line Coverage for Module : dm_mem
Line No.TotalCoveredPercent
TOTAL19016787.89
CONT_ASSIGN11211100.00
CONT_ASSIGN11311100.00
CONT_ASSIGN12011100.00
CONT_ASSIGN12111100.00
CONT_ASSIGN12211100.00
CONT_ASSIGN12411100.00
CONT_ASSIGN12511100.00
CONT_ASSIGN12611100.00
CONT_ASSIGN12711100.00
CONT_ASSIGN13511100.00
CONT_ASSIGN13611100.00
CONT_ASSIGN13711100.00
CONT_ASSIGN13811100.00
CONT_ASSIGN14111100.00
ALWAYS1483737100.00
CONT_ASSIGN22611100.00
CONT_ASSIGN23111100.00
ALWAYS239484695.83
ROUTINE37511100.00
ALWAYS388151493.33
ALWAYS41133100.00
CONT_ASSIGN41811100.00
ALWAYS422543462.96
CONT_ASSIGN55711100.00
ALWAYS58799100.00
ALWAYS60155100.00

111 112 1/1 assign hartsel = hartsel_i[HartSelLen-1:0]; Tests: T1 T2 T3  113 1/1 assign wdata_hartsel = wdata_i[HartSelLen-1:0]; Tests: T1 T2 T3  114 115 logic [NrHartsAligned-1:0] resumereq_aligned, haltreq_aligned, 116 halted_d_aligned, halted_q_aligned, 117 halted_aligned, resumereq_wdata_aligned, 118 resuming_d_aligned, resuming_q_aligned; 119 120 1/1 assign resumereq_aligned = NrHartsAligned'(resumereq_i); Tests: T5 T39 T24  121 1/1 assign haltreq_aligned = NrHartsAligned'(haltreq_i); Tests: T1 T2 T3  122 1/1 assign resumereq_wdata_aligned = NrHartsAligned'(resumereq_i); Tests: T5 T39 T24  123 124 1/1 assign halted_q_aligned = NrHartsAligned'(halted_q); Tests: T1 T2 T3  125 1/1 assign halted_d = NrHarts'(halted_d_aligned); Tests: T1 T2 T3  126 1/1 assign resuming_q_aligned = NrHartsAligned'(resuming_q); Tests: T1 T2 T3  127 1/1 assign resuming_d = NrHarts'(resuming_d_aligned); Tests: T1 T2 T3  128 129 // distinguish whether we need to forward data from the ROM or the FSM 130 // latch the address for this 131 logic fwd_rom_d, fwd_rom_q; 132 dm::ac_ar_cmd_t ac_ar; 133 134 // Abstract Command Access Register 135 1/1 assign ac_ar = dm::ac_ar_cmd_t'(cmd_i.control); Tests: T1 T2 T3  136 1/1 assign debug_req_o = haltreq_i; Tests: T1 T2 T3  137 1/1 assign halted_o = halted_q; Tests: T1 T2 T3  138 1/1 assign resuming_o = resuming_q; Tests: T1 T2 T3  139 140 // reshape progbuf 141 1/1 assign progbuf = progbuf_i; Tests: T1 T2 T3  142 143 typedef enum logic [1:0] { Idle, Go, Resume, CmdExecuting } state_e; 144 state_e state_d, state_q; 145 146 // hart ctrl queue 147 always_comb begin : p_hart_ctrl_queue 148 1/1 cmderror_valid_o = 1'b0; Tests: T1 T2 T3  149 1/1 cmderror_o = dm::CmdErrNone; Tests: T1 T2 T3  150 1/1 state_d = state_q; Tests: T1 T2 T3  151 1/1 go = 1'b0; Tests: T1 T2 T3  152 1/1 resume = 1'b0; Tests: T1 T2 T3  153 1/1 cmdbusy_o = 1'b1; Tests: T1 T2 T3  154 155 1/1 unique case (state_q) Tests: T1 T2 T3  156 Idle: begin 157 1/1 cmdbusy_o = 1'b0; Tests: T1 T2 T3  158 1/1 if (cmd_valid_i && halted_q_aligned[hartsel] && !unsupported_command) begin Tests: T1 T2 T3  159 // give the go signal 160 1/1 state_d = Go; Tests: T1 T3 T25  161 1/1 end else if (cmd_valid_i) begin Tests: T1 T2 T3  162 // hart must be halted for all requests 163 1/1 cmderror_valid_o = 1'b1; Tests: T2 T35 T49  164 1/1 cmderror_o = dm::CmdErrorHaltResume; Tests: T2 T35 T49  165 end MISSING_ELSE 166 // CSRs want to resume, the request is ignored when the hart is 167 // requested to halt or it didn't clear the resuming_q bit before 168 1/1 if (resumereq_aligned[hartsel] && !resuming_q_aligned[hartsel] && Tests: T1 T2 T3  169 !haltreq_aligned[hartsel] && halted_q_aligned[hartsel]) begin 170 1/1 state_d = Resume; Tests: T5 T39 T24  171 end MISSING_ELSE 172 end 173 174 Go: begin 175 // we are already busy here since we scheduled the execution of a program 176 1/1 cmdbusy_o = 1'b1; Tests: T1 T3 T25  177 1/1 go = 1'b1; Tests: T1 T3 T25  178 // the thread is now executing the command, track its state 179 1/1 if (going) begin Tests: T1 T3 T25  180 1/1 state_d = CmdExecuting; Tests: T1 T3 T39  181 end MISSING_ELSE 182 end 183 184 Resume: begin 185 1/1 cmdbusy_o = 1'b1; Tests: T5 T39 T24  186 1/1 resume = 1'b1; Tests: T5 T39 T24  187 1/1 if (resuming_q_aligned[hartsel]) begin Tests: T5 T39 T24  188 1/1 state_d = Idle; Tests: T5 T39 T24  189 end MISSING_ELSE 190 end 191 192 CmdExecuting: begin 193 1/1 cmdbusy_o = 1'b1; Tests: T1 T3 T39  194 1/1 go = 1'b0; Tests: T1 T3 T39  195 // wait until the hart has halted again 196 1/1 if (halted_aligned[hartsel]) begin Tests: T1 T3 T39  197 1/1 state_d = Idle; Tests: T1 T3 T39  198 end MISSING_ELSE 199 end 200 201 default: ; 202 endcase 203 204 // only signal once that cmd is unsupported so that we can clear cmderr 205 // in subsequent writes to abstractcs 206 1/1 if (unsupported_command && cmd_valid_i) begin Tests: T1 T2 T3  207 1/1 cmderror_valid_o = 1'b1; Tests: T2 T50 T51  208 1/1 cmderror_o = dm::CmdErrNotSupported; Tests: T2 T50 T51  209 end MISSING_ELSE 210 211 1/1 if (exception) begin Tests: T1 T2 T3  212 1/1 cmderror_valid_o = 1'b1; Tests: T25 T26  213 1/1 cmderror_o = dm::CmdErrorException; Tests: T25 T26  214 end MISSING_ELSE 215 216 1/1 if (ndmreset_i) begin Tests: T1 T2 T3  217 // Clear state of hart and its control signals when it is being reset. 218 1/1 state_d = Idle; Tests: T1 T52 T10  219 1/1 go = 1'b0; Tests: T1 T52 T10  220 1/1 resume = 1'b0; Tests: T1 T52 T10  221 end MISSING_ELSE 222 end 223 224 // word mux for 32bit and 64bit buses 225 logic [63:0] word_mux; 226 1/1 assign word_mux = (fwd_rom_q) ? rom_rdata : rdata_q; Tests: T1 T2 T3  227 228 if (BusWidth == 64) begin : gen_word_mux64 229 assign rdata_o = word_mux; 230 end else begin : gen_word_mux32 231 1/1 assign rdata_o = (word_enable32_q) ? word_mux[32 +: 32] : word_mux[0 +: 32]; Tests: T1 T2 T3  232 end 233 234 // read/write logic 235 logic [dm::DataCount-1:0][31:0] data_bits; 236 logic [7:0][7:0] rdata; 237 always_comb (* xprop_off *) begin : p_rw_logic 238 239 1/1 halted_d_aligned = NrHartsAligned'(halted_q); Tests: T1 T2 T3  240 1/1 resuming_d_aligned = NrHartsAligned'(resuming_q); Tests: T1 T2 T3  241 1/1 rdata_d = rdata_q; Tests: T1 T2 T3  242 1/1 data_bits = data_i; Tests: T1 T2 T3  243 1/1 rdata = '0; Tests: T1 T2 T3  244 1/1 fwd_rom_d = 1'b0; Tests: T1 T2 T3  245 246 // write data in csr register 247 1/1 data_valid_o = 1'b0; Tests: T1 T2 T3  248 1/1 exception = 1'b0; Tests: T1 T2 T3  249 1/1 halted_aligned = '0; Tests: T1 T2 T3  250 1/1 going = 1'b0; Tests: T1 T2 T3  251 252 // The resume ack signal is lowered when the resume request is deasserted 253 1/1 if (clear_resumeack_i) begin Tests: T1 T2 T3  254 1/1 resuming_d_aligned[hartsel] = 1'b0; Tests: T5 T39 T24  255 end MISSING_ELSE 256 // we've got a new request 257 1/1 if (req_i) begin Tests: T1 T2 T3  258 // this is a write 259 1/1 if (we_i) begin Tests: T1 T2 T3  260 1/1 unique case (addr_i[DbgAddressBits-1:0]) inside Tests: T1 T2 T3  261 HaltedAddr: begin 262 1/1 halted_aligned[wdata_hartsel] = 1'b1; Tests: T1 T2 T3  263 1/1 halted_d_aligned[wdata_hartsel] = 1'b1; Tests: T1 T2 T3  264 end 265 GoingAddr: begin 266 1/1 going = 1'b1; Tests: T1 T3 T39  267 end 268 ResumingAddr: begin 269 // clear the halted flag as the hart resumed execution 270 1/1 halted_d_aligned[wdata_hartsel] = 1'b0; Tests: T5 T39 T24  271 // set the resuming flag which needs to be cleared by the debugger 272 1/1 resuming_d_aligned[wdata_hartsel] = 1'b1; Tests: T5 T39 T24  273 end 274 // an exception occurred during execution 275 1/1 ExceptionAddr: exception = 1'b1; Tests: T25 T26  276 // core can write data registers 277 [DataBaseAddr:DataEndAddr]: begin 278 1/1 data_valid_o = 1'b1; Tests: T1 T6 T10  279 1/1 for (int unsigned dc = 0; dc < dm::DataCount; dc++) begin Tests: T1 T6 T10  280 1/1 if ((addr_i[DbgAddressBits-1:2] - DataBaseAddr[DbgAddressBits-1:2]) == dc) begin Tests: T1 T6 T10  281 1/1 for (int unsigned i = 0; i < $bits(be_i); i++) begin Tests: T1 T6 T10  282 1/1 if (be_i[i]) begin Tests: T1 T6 T10  283 1/1 if (i>3) begin // for upper 32bit data write (only used for BusWidth == 64) Tests: T1 T6 T10  284 // ensure we write to an implemented data register 285 0/1 ==> if (dc < (dm::DataCount - 1)) begin 286 0/1 ==> data_bits[dc+1][(i-4)*8+:8] = wdata_i[i*8+:8]; 287 end ==> MISSING_ELSE 288 end else begin // for lower 32bit data write 289 1/1 data_bits[dc][i*8+:8] = wdata_i[i*8+:8]; Tests: T1 T6 T10  290 end 291 end ==> MISSING_ELSE 292 end 293 end MISSING_ELSE 294 end 295 end 296 default: ; 297 endcase 298 299 // this is a read 300 end else begin 301 1/1 unique case (addr_i[DbgAddressBits-1:0]) inside Tests: T1 T5 T39  302 // variable ROM content 303 WhereToAddr: begin 304 // variable jump to abstract cmd, program_buffer or resume 305 1/1 if (resumereq_wdata_aligned[wdata_hartsel]) begin Tests: T39 T53 T51  306 1/1 rdata_d = {32'b0, dm::jal('0, 21'(dm::ResumeAddress[11:0])-21'(WhereToAddr))}; Tests: T54 T55  307 end MISSING_ELSE 308 309 // there is a command active so jump there 310 1/1 if (cmdbusy_o) begin Tests: T39 T53 T51  311 // transfer not set is shortcut to the program buffer if postexec is set 312 // keep this statement narrow to not catch invalid commands 313 1/1 if (cmd_i.cmdtype == dm::AccessRegister && Tests: T39 T53 T51  314 !ac_ar.transfer && ac_ar.postexec) begin 315 1/1 rdata_d = {32'b0, dm::jal('0, 21'(ProgBufBaseAddr)-21'(WhereToAddr))}; Tests: T56 T57 T58  316 // this is a legit abstract cmd -> execute it 317 end else begin 318 1/1 rdata_d = {32'b0, dm::jal('0, 21'(AbstractCmdBaseAddr)-21'(WhereToAddr))}; Tests: T39 T53 T51  319 end 320 end MISSING_ELSE 321 end 322 323 [DataBaseAddr:DataEndAddr]: begin 324 1/1 rdata_d = { Tests: T1 T10 T36  325 data_i[$clog2(dm::DataCount)'(((addr_i[DbgAddressBits-1:3] 326 - DataBaseAddr[DbgAddressBits-1:3]) << 1) 327 + 1'b1)], 328 data_i[$clog2(dm::DataCount)'(((addr_i[DbgAddressBits-1:3] 329 - DataBaseAddr[DbgAddressBits-1:3]) << 1))] 330 }; 331 end 332 333 [ProgBufBaseAddr:ProgBufEndAddr]: begin 334 1/1 rdata_d = progbuf[ProgBuf64AddrSize'(addr_i[DbgAddressBits-1:3] - Tests: T41 T59 T60  335 ProgBufBaseAddr[DbgAddressBits-1:3])]; 336 end 337 338 // two slots for abstract command 339 [AbstractCmdBaseAddr:AbstractCmdEndAddr]: begin 340 // return the correct address index 341 1/1 rdata_d = abstract_cmd[3'(addr_i[DbgAddressBits-1:3] - Tests: T40 T61 T62  342 AbstractCmdBaseAddr[DbgAddressBits-1:3])]; 343 end 344 // harts are polling for flags here 345 [FlagsBaseAddr:FlagsEndAddr]: begin 346 // release the corresponding hart 347 1/1 if (({addr_i[DbgAddressBits-1:3], 3'b0} - FlagsBaseAddr[DbgAddressBits-1:0]) == Tests: T5 T39 T24  348 (DbgAddressBits'(hartsel) & {{(DbgAddressBits-3){1'b1}}, 3'b0})) begin 349 1/1 rdata[DbgAddressBits'(hartsel) & DbgAddressBits'(3'b111)] = {6'b0, resume, go}; Tests: T5 T39 T24  350 end MISSING_ELSE 351 1/1 rdata_d = rdata; Tests: T5 T39 T24  352 end 353 // Access has to be forwarded to the ROM. The ROM starts at the HaltAddress of the core 354 // e.g.: it immediately jumps to the ROM base address. 355 [RomBaseAddr:RomEndAddr]: begin 356 1/1 fwd_rom_d = 1'b1; Tests: T63 T64  357 end 358 default: ; 359 endcase 360 end 361 end MISSING_ELSE 362 363 1/1 if (ndmreset_i) begin Tests: T1 T2 T3  364 // When harts are reset, they are neither halted nor resuming. 365 1/1 halted_d_aligned = '0; Tests: T1 T52 T10  366 1/1 resuming_d_aligned = '0; Tests: T1 T52 T10  367 end MISSING_ELSE 368 369 1/1 data_o = data_bits; Tests: T1 T2 T3  370 end 371 372 // This flags subword writes that are shorter than the defined width of the register. 373 // Other writes are ignored. 374 function automatic logic gen_wr_err(logic we, logic [BeWidth-1:0] be, logic [BeWidth-1:0] mask); 375 1/1 return we && (|(~be & mask)); Tests: T1 T2 T3  376 endfunction 377 378 // Relevant bus error cases 379 // - access unmapped address 380 // - write a CSR with unaligned address, e.g. `a_address[1:0] != 0` 381 // - write a CSR less than its width, e.g. when CSR is 2 bytes wide, only write 1 byte 382 // - write a RO (read-only) memory 383 localparam logic[BeWidth-1:0] FullRegMask = {BeWidth{1'b1}}; 384 localparam logic[BeWidth-1:0] OneBitMask = BeWidth'(1'b1); 385 localparam logic[BeWidth-1:0] HartSelMask = BeWidth'(2**HartSelLen-1); 386 logic err_d, err_q; 387 always_comb begin 388 1/1 err_d = 1'b0; Tests: T1 T2 T3  389 1/1 if (req_i) begin Tests: T1 T2 T3  390 1/1 unique case (addr_i[DbgAddressBits-1:0]) inside Tests: T1 T2 T3  391 1/1 WhereToAddr: err_d = gen_wr_err(we_i, be_i, FullRegMask); Tests: T39 T53 T51  392 1/1 HaltedAddr: err_d = gen_wr_err(we_i, be_i, HartSelMask); Tests: T1 T2 T3  393 1/1 GoingAddr: err_d = gen_wr_err(we_i, be_i, OneBitMask); Tests: T1 T3 T39  394 1/1 ResumingAddr: err_d = gen_wr_err(we_i, be_i, HartSelMask); Tests: T5 T39 T24  395 1/1 ExceptionAddr: err_d = gen_wr_err(we_i, be_i, OneBitMask); Tests: T25 T26 T60  396 1/1 [DataBaseAddr:DataEndAddr]: err_d = gen_wr_err(we_i, be_i, FullRegMask); Tests: T1 T6 T10  397 1/1 [ProgBufBaseAddr:ProgBufEndAddr]: err_d = gen_wr_err(we_i, be_i, FullRegMask); Tests: T41 T59 T60  398 1/1 [AbstractCmdBaseAddr:AbstractCmdEndAddr]: err_d = gen_wr_err(we_i, be_i, FullRegMask); Tests: T40 T61 T62  399 1/1 [FlagsBaseAddr:FlagsEndAddr]: err_d = gen_wr_err(we_i, be_i, FullRegMask); Tests: T5 T39 T24  400 1/1 [RomBaseAddr:RomEndAddr]: err_d = we_i; // Writing ROM area always errors. Tests: T63 T64 T60  401 default: err_d = 1'b1; 402 endcase 403 // Unaligned accesses 404 1/1 if (addr_i[$clog2(BeWidth)-1:0] != '0) begin Tests: T1 T2 T3  405 0/1 ==> err_d = 1'b1; 406 end MISSING_ELSE 407 end MISSING_ELSE 408 end 409 410 always_ff @(posedge clk_i or negedge rst_ni) begin : p_err_reg 411 1/1 if (!rst_ni) begin Tests: T1 T2 T3  412 1/1 err_q <= 1'b0; Tests: T1 T2 T3  413 end else begin 414 1/1 err_q <= err_d; Tests: T1 T2 T3  415 end 416 end 417 418 1/1 assign err_o = err_q; Tests: T1 T2 T3  419 420 always_comb begin : p_abstract_cmd_rom 421 // this abstract command is currently unsupported 422 1/1 unsupported_command = 1'b0; Tests: T1 T2 T3  423 // default memory 424 // if ac_ar.transfer is not set then we can take a shortcut to the program buffer 425 1/1 abstract_cmd[0][31:0] = dm::illegal(); Tests: T1 T2 T3  426 // load debug module base address into a0, this is shared among all commands 427 1/1 abstract_cmd[0][63:32] = HasSndScratch ? dm::auipc(5'd10, '0) : dm::nop(); Tests: T1 T2 T3  428 // clr lowest 12b -> DM base offset 429 1/1 abstract_cmd[1][31:0] = HasSndScratch ? dm::srli(5'd10, 5'd10, 6'd12) : dm::nop(); Tests: T1 T2 T3  430 1/1 abstract_cmd[1][63:32] = HasSndScratch ? dm::slli(5'd10, 5'd10, 6'd12) : dm::nop(); Tests: T1 T2 T3  431 1/1 abstract_cmd[2][31:0] = dm::nop(); Tests: T1 T2 T3  432 1/1 abstract_cmd[2][63:32] = dm::nop(); Tests: T1 T2 T3  433 1/1 abstract_cmd[3][31:0] = dm::nop(); Tests: T1 T2 T3  434 1/1 abstract_cmd[3][63:32] = dm::nop(); Tests: T1 T2 T3  435 1/1 abstract_cmd[4][31:0] = HasSndScratch ? dm::csrr(dm::CSR_DSCRATCH1, 5'd10) : dm::nop(); Tests: T1 T2 T3  436 1/1 abstract_cmd[4][63:32] = dm::ebreak(); Tests: T1 T2 T3  437 1/1 abstract_cmd[7:5] = '0; Tests: T1 T2 T3  438 439 // this depends on the command being executed 440 1/1 unique case (cmd_i.cmdtype) Tests: T1 T2 T3  441 // -------------------- 442 // Access Register 443 // -------------------- 444 dm::AccessRegister: begin 445 1/1 if (32'(ac_ar.aarsize) < MaxAar && ac_ar.transfer && ac_ar.write) begin Tests: T1 T2 T3  446 // store a0 in dscratch1 447 1/1 abstract_cmd[0][31:0] = HasSndScratch ? dm::csrw(dm::CSR_DSCRATCH1, 5'd10) : dm::nop(); Tests: T39 T40 T61  448 // this range is reserved 449 1/1 if (ac_ar.regno[15:14] != '0) begin Tests: T39 T40 T61  450 0/1 ==> abstract_cmd[0][31:0] = dm::ebreak(); // we leave asap 451 0/1 ==> unsupported_command = 1'b1; 452 // A0 access needs to be handled separately, as we use A0 to load 453 // the DM address offset need to access DSCRATCH1 in this case 454 1/1 end else if (HasSndScratch && ac_ar.regno[12] && (!ac_ar.regno[5]) && Tests: T39 T40 T61  455 (ac_ar.regno[4:0] == 5'd10)) begin 456 // store s0 in dscratch 457 0/1 ==> abstract_cmd[2][31:0] = dm::csrw(dm::CSR_DSCRATCH0, 5'd8); 458 // load from data register 459 0/1 ==> abstract_cmd[2][63:32] = dm::load(ac_ar.aarsize, 5'd8, LoadBaseAddr, dm::DataAddr); 460 // and store it in the corresponding CSR 461 0/1 ==> abstract_cmd[3][31:0] = dm::csrw(dm::CSR_DSCRATCH1, 5'd8); 462 // restore s0 again from dscratch 463 0/1 ==> abstract_cmd[3][63:32] = dm::csrr(dm::CSR_DSCRATCH0, 5'd8); 464 // GPR/FPR access 465 1/1 end else if (ac_ar.regno[12]) begin Tests: T39 T40 T61  466 // determine whether we want to access the floating point register or not 467 0/1 ==> if (ac_ar.regno[5]) begin 468 0/1 ==> abstract_cmd[2][31:0] = 469 dm::float_load(ac_ar.aarsize, ac_ar.regno[4:0], LoadBaseAddr, dm::DataAddr); 470 end else begin 471 0/1 ==> abstract_cmd[2][31:0] = 472 dm::load(ac_ar.aarsize, ac_ar.regno[4:0], LoadBaseAddr, dm::DataAddr); 473 end 474 // CSR access 475 end else begin 476 // data register to CSR 477 // store s0 in dscratch 478 1/1 abstract_cmd[2][31:0] = dm::csrw(dm::CSR_DSCRATCH0, 5'd8); Tests: T39 T40 T61  479 // load from data register 480 1/1 abstract_cmd[2][63:32] = dm::load(ac_ar.aarsize, 5'd8, LoadBaseAddr, dm::DataAddr); Tests: T39 T40 T61  481 // and store it in the corresponding CSR 482 1/1 abstract_cmd[3][31:0] = dm::csrw(dm::csr_reg_t'(ac_ar.regno[11:0]), 5'd8); Tests: T39 T40 T61  483 // restore s0 again from dscratch 484 1/1 abstract_cmd[3][63:32] = dm::csrr(dm::CSR_DSCRATCH0, 5'd8); Tests: T39 T40 T61  485 end 486 1/1 end else if (32'(ac_ar.aarsize) < MaxAar && ac_ar.transfer && !ac_ar.write) begin Tests: T1 T2 T3  487 // store a0 in dscratch1 488 1/1 abstract_cmd[0][31:0] = HasSndScratch ? Tests: T65 T30 T8  489 dm::csrw(dm::CSR_DSCRATCH1, LoadBaseAddr) : 490 dm::nop(); 491 // this range is reserved 492 1/1 if (ac_ar.regno[15:14] != '0) begin Tests: T65 T30 T8  493 0/1 ==> abstract_cmd[0][31:0] = dm::ebreak(); // we leave asap 494 0/1 ==> unsupported_command = 1'b1; 495 // A0 access needs to be handled separately, as we use A0 to load 496 // the DM address offset need to access DSCRATCH1 in this case 497 1/1 end else if (HasSndScratch && ac_ar.regno[12] && (!ac_ar.regno[5]) && Tests: T65 T30 T8  498 (ac_ar.regno[4:0] == 5'd10)) begin 499 // store s0 in dscratch 500 0/1 ==> abstract_cmd[2][31:0] = dm::csrw(dm::CSR_DSCRATCH0, 5'd8); 501 // read value from CSR into s0 502 0/1 ==> abstract_cmd[2][63:32] = dm::csrr(dm::CSR_DSCRATCH1, 5'd8); 503 // and store s0 into data section 504 0/1 ==> abstract_cmd[3][31:0] = dm::store(ac_ar.aarsize, 5'd8, LoadBaseAddr, dm::DataAddr); 505 // restore s0 again from dscratch 506 0/1 ==> abstract_cmd[3][63:32] = dm::csrr(dm::CSR_DSCRATCH0, 5'd8); 507 // GPR/FPR access 508 1/1 end else if (ac_ar.regno[12]) begin Tests: T65 T30 T8  509 // determine whether we want to access the floating point register or not 510 0/1 ==> if (ac_ar.regno[5]) begin 511 0/1 ==> abstract_cmd[2][31:0] = 512 dm::float_store(ac_ar.aarsize, ac_ar.regno[4:0], LoadBaseAddr, dm::DataAddr); 513 end else begin 514 0/1 ==> abstract_cmd[2][31:0] = 515 dm::store(ac_ar.aarsize, ac_ar.regno[4:0], LoadBaseAddr, dm::DataAddr); 516 end 517 // CSR access 518 end else begin 519 // CSR register to data 520 // store s0 in dscratch 521 1/1 abstract_cmd[2][31:0] = dm::csrw(dm::CSR_DSCRATCH0, 5'd8); Tests: T65 T30 T8  522 // read value from CSR into s0 523 1/1 abstract_cmd[2][63:32] = dm::csrr(dm::csr_reg_t'(ac_ar.regno[11:0]), 5'd8); Tests: T65 T30 T8  524 // and store s0 into data section 525 1/1 abstract_cmd[3][31:0] = dm::store(ac_ar.aarsize, 5'd8, LoadBaseAddr, dm::DataAddr); Tests: T65 T30 T8  526 // restore s0 again from dscratch 527 1/1 abstract_cmd[3][63:32] = dm::csrr(dm::CSR_DSCRATCH0, 5'd8); Tests: T65 T30 T8  528 end 529 1/1 end else if (32'(ac_ar.aarsize) >= MaxAar || ac_ar.aarpostincrement == 1'b1) begin Tests: T1 T2 T3  530 // this should happend when e.g. ac_ar.aarsize >= MaxAar 531 // Openocd will try to do an access with aarsize=64 bits 532 // first before falling back to 32 bits. 533 0/1 ==> abstract_cmd[0][31:0] = dm::ebreak(); // we leave asap 534 0/1 ==> unsupported_command = 1'b1; 535 end MISSING_ELSE 536 537 // Check whether we need to execute the program buffer. When we 538 // get an unsupported command we really should abort instead of 539 // still trying to execute the program buffer, makes it easier 540 // for the debugger to recover 541 1/1 if (ac_ar.postexec && !unsupported_command) begin Tests: T1 T2 T3  542 // issue a nop, we will automatically run into the program buffer 543 1/1 abstract_cmd[4][63:32] = dm::nop(); Tests: T56 T57 T58  544 end MISSING_ELSE 545 end 546 // not supported at the moment 547 // dm::QuickAccess:; 548 // dm::AccessMemory:; 549 default: begin 550 abstract_cmd[0][31:0] = dm::ebreak(); 551 unsupported_command = 1'b1; 552 end 553 endcase 554 end 555 556 logic [63:0] rom_addr; 557 1/1 assign rom_addr = 64'(addr_i); Tests: T1 T2 T3  558 559 // Depending on whether the debug module is located 560 // at the zero page we can instantiate a simplified version 561 // which only requires one scratch register per hart. 562 // For all other cases we need to set aside 563 // two registers per hart, hence we also need 564 // two scratch registers. 565 if (HasSndScratch) begin : gen_rom_snd_scratch 566 debug_rom i_debug_rom ( 567 .clk_i, 568 .rst_ni, 569 .req_i, 570 .addr_i ( rom_addr ), 571 .rdata_o ( rom_rdata ) 572 ); 573 end else begin : gen_rom_one_scratch 574 // It uses the zero register (`x0`) as the base 575 // for its loads. The zero register does not need to 576 // be saved. 577 debug_rom_one_scratch i_debug_rom ( 578 .clk_i, 579 .rst_ni, 580 .req_i, 581 .addr_i ( rom_addr ), 582 .rdata_o ( rom_rdata ) 583 ); 584 end 585 586 always_ff @(posedge clk_i or negedge rst_ni) begin : p_regs 587 1/1 if (!rst_ni) begin Tests: T1 T2 T3  588 1/1 fwd_rom_q <= 1'b0; Tests: T1 T2 T3  589 1/1 rdata_q <= '0; Tests: T1 T2 T3  590 1/1 state_q <= Idle; Tests: T1 T2 T3  591 1/1 word_enable32_q <= 1'b0; Tests: T1 T2 T3  592 end else begin 593 1/1 fwd_rom_q <= fwd_rom_d; Tests: T1 T2 T3  594 1/1 rdata_q <= rdata_d; Tests: T1 T2 T3  595 1/1 state_q <= state_d; Tests: T1 T2 T3  596 1/1 word_enable32_q <= addr_i[2]; Tests: T1 T2 T3  597 end 598 end 599 600 always_ff @(posedge clk_i or negedge rst_ni) begin 601 1/1 if (!rst_ni) begin Tests: T1 T2 T3  602 1/1 halted_q <= 1'b0; Tests: T1 T2 T3  603 1/1 resuming_q <= 1'b0; Tests: T1 T2 T3  604 end else begin 605 1/1 halted_q <= SelectableHarts & halted_d; Tests: T1 T2 T3  606 1/1 resuming_q <= SelectableHarts & resuming_d; Tests: T1 T2 T3 

Cond Coverage for Module : dm_mem
TotalCoveredPercent
Conditions624267.74
Logical624267.74
Non-Logical00
Event00

 LINE       158
 EXPRESSION (cmd_valid_i && halted_q_aligned[hartsel] && ((!unsupported_command)))
             -----1-----    ------------2------------    ------------3-----------
-1--2--3-StatusTests
011CoveredT1,T2,T3
101CoveredT35,T49
110CoveredT2,T50,T51
111CoveredT1,T3,T25

 LINE       168
 EXPRESSION (resumereq_aligned[hartsel] && ((!resuming_q_aligned[hartsel])) && ((!haltreq_aligned[hartsel])) && halted_q_aligned[hartsel])
             -------------1------------    ----------------2---------------    --------------3--------------    ------------4------------
-1--2--3--4-StatusTests
0111CoveredT5,T39,T24
1011Not Covered
1101CoveredT51,T66,T67
1110CoveredT39,T53,T51
1111CoveredT5,T39,T24

 LINE       206
 EXPRESSION (unsupported_command && cmd_valid_i)
             ---------1---------    -----2-----
-1--2-StatusTests
01CoveredT1,T3,T25
10CoveredT2,T50,T51
11CoveredT2,T50,T51

 LINE       226
 EXPRESSION (fwd_rom_q ? rom_rdata : rdata_q)
             ----1----
-1-StatusTests
0CoveredT1,T2,T3
1CoveredT63,T64

 LINE       231
 EXPRESSION (word_enable32_q ? word_mux[32+:32] : word_mux[0+:32])
             -------1-------
-1-StatusTests
0CoveredT1,T2,T3
1CoveredT1,T6,T39

 LINE       280
 EXPRESSION ((addr_i[(DbgAddressBits - 1):2] - DataBaseAddr[(DbgAddressBits - 1):2]) == dc)
            ---------------------------------------1---------------------------------------
-1-StatusTests
0CoveredT1,T6,T10
1CoveredT1,T6,T10

 LINE       313
 EXPRESSION ((cmd_i.cmdtype == AccessRegister) && ((!ac_ar.transfer)) && ac_ar.postexec)
             ----------------1----------------    ---------2---------    -------3------
-1--2--3-StatusTests
011Not Covered
101CoveredT34,T68,T69
110CoveredT53,T51,T70
111CoveredT56,T57,T58

 LINE       313
 SUB-EXPRESSION (cmd_i.cmdtype == AccessRegister)
                ----------------1----------------
-1-StatusTests
0Not Covered
1CoveredT39,T53,T51

 LINE       347
 EXPRESSION (({addr_i[(DbgAddressBits - 1):3], 3'b0} - FlagsBaseAddr[(DbgAddressBits - 1):0]) == (12'(hartsel) & {{(DbgAddressBits - 3) {1'b1}}, 3'b0}))
            ----------------------------------------------------------------------1---------------------------------------------------------------------
-1-StatusTests
0CoveredT60,T66,T71
1CoveredT5,T39,T24

 LINE       445
 EXPRESSION ((32'(ac_ar.aarsize) < MaxAar) && ac_ar.transfer && ac_ar.write)
             --------------1--------------    -------2------    -----3-----
-1--2--3-StatusTests
011Not Covered
101CoveredT53,T58,T72
110CoveredT65,T30,T8
111CoveredT39,T40,T61

 LINE       449
 EXPRESSION (ac_ar.regno[15:14] != '0)
            -------------1------------
-1-StatusTests
0CoveredT39,T40,T61
1Not Covered

 LINE       454
 EXPRESSION (HasSndScratch && ac_ar.regno[12] && ((!ac_ar.regno[5])) && (ac_ar.regno[4:0] == 5'd10))
             ------1------    -------2-------    ---------3---------    -------------4-------------
-1--2--3--4-StatusTests
-011Not Covered
-101Not Covered
-110Not Covered
-111Not Covered

 LINE       454
 SUB-EXPRESSION (ac_ar.regno[4:0] == 5'd10)
                -------------1-------------
-1-StatusTests
0CoveredT39,T40,T61
1Not Covered

 LINE       486
 EXPRESSION ((32'(ac_ar.aarsize) < MaxAar) && ac_ar.transfer && ((!ac_ar.write)))
             --------------1--------------    -------2------    --------3-------
-1--2--3-StatusTests
011Not Covered
101CoveredT1,T2,T3
110Not Covered
111CoveredT65,T30,T8

 LINE       492
 EXPRESSION (ac_ar.regno[15:14] != '0)
            -------------1------------
-1-StatusTests
0CoveredT65,T30,T8
1Not Covered

 LINE       497
 EXPRESSION (HasSndScratch && ac_ar.regno[12] && ((!ac_ar.regno[5])) && (ac_ar.regno[4:0] == 5'd10))
             ------1------    -------2-------    ---------3---------    -------------4-------------
-1--2--3--4-StatusTests
-011CoveredT68
-101Not Covered
-110Not Covered
-111Not Covered

 LINE       497
 SUB-EXPRESSION (ac_ar.regno[4:0] == 5'd10)
                -------------1-------------
-1-StatusTests
0CoveredT65,T30,T8
1CoveredT68

 LINE       529
 EXPRESSION ((32'(ac_ar.aarsize) >= MaxAar) || (ac_ar.aarpostincrement == 1'b1))
             ---------------1--------------    ----------------2---------------
-1--2-StatusTests
00CoveredT1,T2,T3
01Not Covered
10Not Covered

 LINE       529
 SUB-EXPRESSION (ac_ar.aarpostincrement == 1'b1)
                ----------------1---------------
-1-StatusTests
0CoveredT1,T2,T3
1Not Covered

 LINE       541
 EXPRESSION (ac_ar.postexec && ((!unsupported_command)))
             -------1------    ------------2-----------
-1--2-StatusTests
01CoveredT1,T2,T3
10Not Covered
11CoveredT56,T57,T58

 LINE       605
 EXPRESSION (SelectableHarts & halted_d)
             -------1-------   ----2---
-1--2-StatusTests
-0CoveredT1,T2,T3
-1CoveredT1,T2,T3

 LINE       606
 EXPRESSION (SelectableHarts & resuming_d)
             -------1-------   -----2----
-1--2-StatusTests
-0CoveredT1,T2,T3
-1CoveredT5,T39,T24

FSM Coverage for Module : dm_mem
Summary for FSM :: state_q
TotalCoveredPercent
States 4 4 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
CmdExecuting 180 Covered T1,T3,T39
Go 160 Covered T1,T3,T25
Idle 188 Covered T1,T2,T3
Resume 170 Covered T5,T39,T24


transitionsLine No.CoveredTests
CmdExecuting->Idle 197 Covered T1,T3,T39
Go->CmdExecuting 180 Covered T1,T3,T39
Go->Idle 218 Covered T66
Idle->Go 160 Covered T1,T3,T25
Idle->Resume 170 Covered T5,T39,T24
Resume->Idle 188 Covered T5,T39,T24



Branch Coverage for Module : dm_mem
Line No.TotalCoveredPercent
Branches 80 69 86.25
TERNARY 226 2 2 100.00
TERNARY 231 2 2 100.00
CASE 155 12 11 91.67
IF 206 2 2 100.00
IF 211 2 2 100.00
IF 216 2 2 100.00
IF 253 2 2 100.00
IF 257 19 19 100.00
IF 363 2 2 100.00
IF 389 14 13 92.86
IF 411 2 2 100.00
CASE 440 15 6 40.00
IF 587 2 2 100.00
IF 601 2 2 100.00


226 assign word_mux = (fwd_rom_q) ? rom_rdata : rdata_q; -1- ==> ==>

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


231 assign rdata_o = (word_enable32_q) ? word_mux[32 +: 32] : word_mux[0 +: 32]; -1- ==> ==>

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


155 unique case (state_q) -1- 156 Idle: begin 157 cmdbusy_o = 1'b0; 158 if (cmd_valid_i && halted_q_aligned[hartsel] && !unsupported_command) begin -2- 159 // give the go signal 160 state_d = Go; ==> 161 end else if (cmd_valid_i) begin -3- 162 // hart must be halted for all requests 163 cmderror_valid_o = 1'b1; ==> 164 cmderror_o = dm::CmdErrorHaltResume; 165 end MISSING_ELSE ==> 166 // CSRs want to resume, the request is ignored when the hart is 167 // requested to halt or it didn't clear the resuming_q bit before 168 if (resumereq_aligned[hartsel] && !resuming_q_aligned[hartsel] && -4- 169 !haltreq_aligned[hartsel] && halted_q_aligned[hartsel]) begin 170 state_d = Resume; ==> 171 end MISSING_ELSE ==> 172 end 173 174 Go: begin 175 // we are already busy here since we scheduled the execution of a program 176 cmdbusy_o = 1'b1; 177 go = 1'b1; 178 // the thread is now executing the command, track its state 179 if (going) begin -5- 180 state_d = CmdExecuting; ==> 181 end MISSING_ELSE ==> 182 end 183 184 Resume: begin 185 cmdbusy_o = 1'b1; 186 resume = 1'b1; 187 if (resuming_q_aligned[hartsel]) begin -6- 188 state_d = Idle; ==> 189 end MISSING_ELSE ==> 190 end 191 192 CmdExecuting: begin 193 cmdbusy_o = 1'b1; 194 go = 1'b0; 195 // wait until the hart has halted again 196 if (halted_aligned[hartsel]) begin -7- 197 state_d = Idle; ==> 198 end MISSING_ELSE ==> 199 end 200 201 default: ; ==>

Branches:
-1--2--3--4--5--6--7-StatusTests
Idle 1 - - - - - Covered T1,T3,T25
Idle 0 1 - - - - Covered T2,T35,T49
Idle 0 0 - - - - Covered T1,T2,T3
Idle - - 1 - - - Covered T5,T39,T24
Idle - - 0 - - - Covered T1,T2,T3
Go - - - 1 - - Covered T1,T3,T39
Go - - - 0 - - Covered T1,T3,T25
Resume - - - - 1 - Covered T5,T39,T24
Resume - - - - 0 - Covered T5,T39,T24
CmdExecuting - - - - - 1 Covered T1,T3,T39
CmdExecuting - - - - - 0 Covered T1,T3,T39
default - - - - - - Not Covered


206 if (unsupported_command && cmd_valid_i) begin -1- 207 cmderror_valid_o = 1'b1; ==> 208 cmderror_o = dm::CmdErrNotSupported; 209 end MISSING_ELSE ==>

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


211 if (exception) begin -1- 212 cmderror_valid_o = 1'b1; ==> 213 cmderror_o = dm::CmdErrorException; 214 end MISSING_ELSE ==>

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


216 if (ndmreset_i) begin -1- 217 // Clear state of hart and its control signals when it is being reset. 218 state_d = Idle; ==> 219 go = 1'b0; 220 resume = 1'b0; 221 end MISSING_ELSE ==>

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


253 if (clear_resumeack_i) begin -1- 254 resuming_d_aligned[hartsel] = 1'b0; ==> 255 end MISSING_ELSE ==>

Branches:
-1-StatusTests
1 Covered T5,T39,T24
0 Covered T1,T2,T3


257 if (req_i) begin -1- 258 // this is a write 259 if (we_i) begin -2- 260 unique case (addr_i[DbgAddressBits-1:0]) inside -3- 261 HaltedAddr: begin 262 halted_aligned[wdata_hartsel] = 1'b1; ==> 263 halted_d_aligned[wdata_hartsel] = 1'b1; 264 end 265 GoingAddr: begin 266 going = 1'b1; ==> 267 end 268 ResumingAddr: begin 269 // clear the halted flag as the hart resumed execution 270 halted_d_aligned[wdata_hartsel] = 1'b0; ==> 271 // set the resuming flag which needs to be cleared by the debugger 272 resuming_d_aligned[wdata_hartsel] = 1'b1; 273 end 274 // an exception occurred during execution 275 ExceptionAddr: exception = 1'b1; ==> 276 // core can write data registers 277 [DataBaseAddr:DataEndAddr]: begin 278 data_valid_o = 1'b1; ==> 279 for (int unsigned dc = 0; dc < dm::DataCount; dc++) begin 280 if ((addr_i[DbgAddressBits-1:2] - DataBaseAddr[DbgAddressBits-1:2]) == dc) begin 281 for (int unsigned i = 0; i < $bits(be_i); i++) begin 282 if (be_i[i]) begin 283 if (i>3) begin // for upper 32bit data write (only used for BusWidth == 64) 284 // ensure we write to an implemented data register 285 if (dc < (dm::DataCount - 1)) begin 286 data_bits[dc+1][(i-4)*8+:8] = wdata_i[i*8+:8]; 287 end 288 end else begin // for lower 32bit data write 289 data_bits[dc][i*8+:8] = wdata_i[i*8+:8]; 290 end 291 end 292 end 293 end 294 end 295 end 296 default: ; ==> 297 endcase 298 299 // this is a read 300 end else begin 301 unique case (addr_i[DbgAddressBits-1:0]) inside -4- 302 // variable ROM content 303 WhereToAddr: begin 304 // variable jump to abstract cmd, program_buffer or resume 305 if (resumereq_wdata_aligned[wdata_hartsel]) begin -5- 306 rdata_d = {32'b0, dm::jal('0, 21'(dm::ResumeAddress[11:0])-21'(WhereToAddr))}; ==> 307 end MISSING_ELSE ==> 308 309 // there is a command active so jump there 310 if (cmdbusy_o) begin -6- 311 // transfer not set is shortcut to the program buffer if postexec is set 312 // keep this statement narrow to not catch invalid commands 313 if (cmd_i.cmdtype == dm::AccessRegister && -7- 314 !ac_ar.transfer && ac_ar.postexec) begin 315 rdata_d = {32'b0, dm::jal('0, 21'(ProgBufBaseAddr)-21'(WhereToAddr))}; ==> 316 // this is a legit abstract cmd -> execute it 317 end else begin 318 rdata_d = {32'b0, dm::jal('0, 21'(AbstractCmdBaseAddr)-21'(WhereToAddr))}; ==> 319 end 320 end MISSING_ELSE ==> 321 end 322 323 [DataBaseAddr:DataEndAddr]: begin 324 rdata_d = { ==> 325 data_i[$clog2(dm::DataCount)'(((addr_i[DbgAddressBits-1:3] 326 - DataBaseAddr[DbgAddressBits-1:3]) << 1) 327 + 1'b1)], 328 data_i[$clog2(dm::DataCount)'(((addr_i[DbgAddressBits-1:3] 329 - DataBaseAddr[DbgAddressBits-1:3]) << 1))] 330 }; 331 end 332 333 [ProgBufBaseAddr:ProgBufEndAddr]: begin 334 rdata_d = progbuf[ProgBuf64AddrSize'(addr_i[DbgAddressBits-1:3] - ==> 335 ProgBufBaseAddr[DbgAddressBits-1:3])]; 336 end 337 338 // two slots for abstract command 339 [AbstractCmdBaseAddr:AbstractCmdEndAddr]: begin 340 // return the correct address index 341 rdata_d = abstract_cmd[3'(addr_i[DbgAddressBits-1:3] - ==> 342 AbstractCmdBaseAddr[DbgAddressBits-1:3])]; 343 end 344 // harts are polling for flags here 345 [FlagsBaseAddr:FlagsEndAddr]: begin 346 // release the corresponding hart 347 if (({addr_i[DbgAddressBits-1:3], 3'b0} - FlagsBaseAddr[DbgAddressBits-1:0]) == -8- 348 (DbgAddressBits'(hartsel) & {{(DbgAddressBits-3){1'b1}}, 3'b0})) begin 349 rdata[DbgAddressBits'(hartsel) & DbgAddressBits'(3'b111)] = {6'b0, resume, go}; ==> 350 end MISSING_ELSE ==> 351 rdata_d = rdata; 352 end 353 // Access has to be forwarded to the ROM. The ROM starts at the HaltAddress of the core 354 // e.g.: it immediately jumps to the ROM base address. 355 [RomBaseAddr:RomEndAddr]: begin 356 fwd_rom_d = 1'b1; ==> 357 end 358 default: ; ==> 359 endcase 360 end 361 end MISSING_ELSE ==>

Branches:
-1--2--3--4--5--6--7--8-StatusTests
1 1 HaltedAddr - - - - - Covered T1,T2,T3
1 1 GoingAddr - - - - - Covered T1,T3,T39
1 1 ResumingAddr - - - - - Covered T5,T39,T24
1 1 ExceptionAddr - - - - - Covered T25,T26
1 1 DataBaseAddr DataEndAddr - - - - - Covered T1,T6,T10
1 1 default - - - - - Covered T60,T66,T71
1 0 - WhereToAddr 1 - - - Covered T54,T55
1 0 - WhereToAddr 0 - - - Covered T39,T53,T51
1 0 - WhereToAddr - 1 1 - Covered T56,T57,T58
1 0 - WhereToAddr - 1 0 - Covered T39,T53,T51
1 0 - WhereToAddr - 0 - - Covered T73,T74,T60
1 0 - DataBaseAddr DataEndAddr - - - - Covered T1,T10,T36
1 0 - ProgBufBaseAddr ProgBufEndAddr - - - - Covered T41,T59,T60
1 0 - AbstractCmdBaseAddr AbstractCmdEndAddr - - - - Covered T40,T61,T62
1 0 - FlagsBaseAddr FlagsEndAddr - - - 1 Covered T5,T39,T24
1 0 - FlagsBaseAddr FlagsEndAddr - - - 0 Covered T60,T66,T71
1 0 - RomBaseAddr RomEndAddr - - - - Covered T63,T64
1 0 - default - - - - Covered T60,T66,T71
0 - - - - - - - Covered T1,T2,T3


363 if (ndmreset_i) begin -1- 364 // When harts are reset, they are neither halted nor resuming. 365 halted_d_aligned = '0; ==> 366 resuming_d_aligned = '0; 367 end MISSING_ELSE ==>

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


389 if (req_i) begin -1- 390 unique case (addr_i[DbgAddressBits-1:0]) inside -2- 391 WhereToAddr: err_d = gen_wr_err(we_i, be_i, FullRegMask); ==> 392 HaltedAddr: err_d = gen_wr_err(we_i, be_i, HartSelMask); ==> 393 GoingAddr: err_d = gen_wr_err(we_i, be_i, OneBitMask); ==> 394 ResumingAddr: err_d = gen_wr_err(we_i, be_i, HartSelMask); ==> 395 ExceptionAddr: err_d = gen_wr_err(we_i, be_i, OneBitMask); ==> 396 [DataBaseAddr:DataEndAddr]: err_d = gen_wr_err(we_i, be_i, FullRegMask); ==> 397 [ProgBufBaseAddr:ProgBufEndAddr]: err_d = gen_wr_err(we_i, be_i, FullRegMask); ==> 398 [AbstractCmdBaseAddr:AbstractCmdEndAddr]: err_d = gen_wr_err(we_i, be_i, FullRegMask); ==> 399 [FlagsBaseAddr:FlagsEndAddr]: err_d = gen_wr_err(we_i, be_i, FullRegMask); ==> 400 [RomBaseAddr:RomEndAddr]: err_d = we_i; // Writing ROM area always errors. ==> 401 default: err_d = 1'b1; ==> 402 endcase 403 // Unaligned accesses 404 if (addr_i[$clog2(BeWidth)-1:0] != '0) begin -3- 405 err_d = 1'b1; ==> 406 end MISSING_ELSE ==> 407 end MISSING_ELSE ==>

Branches:
-1--2--3-StatusTests
1 WhereToAddr - Covered T39,T53,T51
1 HaltedAddr - Covered T1,T2,T3
1 GoingAddr - Covered T1,T3,T39
1 ResumingAddr - Covered T5,T39,T24
1 ExceptionAddr - Covered T25,T26,T60
1 DataBaseAddr DataEndAddr - Covered T1,T6,T10
1 ProgBufBaseAddr ProgBufEndAddr - Covered T41,T59,T60
1 AbstractCmdBaseAddr AbstractCmdEndAddr - Covered T40,T61,T62
1 FlagsBaseAddr FlagsEndAddr - Covered T5,T39,T24
1 RomBaseAddr RomEndAddr - Covered T63,T64,T60
1 default - Covered T60,T66,T71
1 - 1 Not Covered
1 - 0 Covered T1,T2,T3
0 - - Covered T1,T2,T3


411 if (!rst_ni) begin -1- 412 err_q <= 1'b0; ==> 413 end else begin 414 err_q <= err_d; ==>

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


440 unique case (cmd_i.cmdtype) -1- 441 // -------------------- 442 // Access Register 443 // -------------------- 444 dm::AccessRegister: begin 445 if (32'(ac_ar.aarsize) < MaxAar && ac_ar.transfer && ac_ar.write) begin -2- 446 // store a0 in dscratch1 447 abstract_cmd[0][31:0] = HasSndScratch ? dm::csrw(dm::CSR_DSCRATCH1, 5'd10) : dm::nop(); 448 // this range is reserved 449 if (ac_ar.regno[15:14] != '0) begin -3- 450 abstract_cmd[0][31:0] = dm::ebreak(); // we leave asap ==> 451 unsupported_command = 1'b1; 452 // A0 access needs to be handled separately, as we use A0 to load 453 // the DM address offset need to access DSCRATCH1 in this case 454 end else if (HasSndScratch && ac_ar.regno[12] && (!ac_ar.regno[5]) && -4- 455 (ac_ar.regno[4:0] == 5'd10)) begin 456 // store s0 in dscratch 457 abstract_cmd[2][31:0] = dm::csrw(dm::CSR_DSCRATCH0, 5'd8); ==> 458 // load from data register 459 abstract_cmd[2][63:32] = dm::load(ac_ar.aarsize, 5'd8, LoadBaseAddr, dm::DataAddr); 460 // and store it in the corresponding CSR 461 abstract_cmd[3][31:0] = dm::csrw(dm::CSR_DSCRATCH1, 5'd8); 462 // restore s0 again from dscratch 463 abstract_cmd[3][63:32] = dm::csrr(dm::CSR_DSCRATCH0, 5'd8); 464 // GPR/FPR access 465 end else if (ac_ar.regno[12]) begin -5- 466 // determine whether we want to access the floating point register or not 467 if (ac_ar.regno[5]) begin -6- 468 abstract_cmd[2][31:0] = ==> 469 dm::float_load(ac_ar.aarsize, ac_ar.regno[4:0], LoadBaseAddr, dm::DataAddr); 470 end else begin 471 abstract_cmd[2][31:0] = ==> 472 dm::load(ac_ar.aarsize, ac_ar.regno[4:0], LoadBaseAddr, dm::DataAddr); 473 end 474 // CSR access 475 end else begin 476 // data register to CSR 477 // store s0 in dscratch 478 abstract_cmd[2][31:0] = dm::csrw(dm::CSR_DSCRATCH0, 5'd8); ==> 479 // load from data register 480 abstract_cmd[2][63:32] = dm::load(ac_ar.aarsize, 5'd8, LoadBaseAddr, dm::DataAddr); 481 // and store it in the corresponding CSR 482 abstract_cmd[3][31:0] = dm::csrw(dm::csr_reg_t'(ac_ar.regno[11:0]), 5'd8); 483 // restore s0 again from dscratch 484 abstract_cmd[3][63:32] = dm::csrr(dm::CSR_DSCRATCH0, 5'd8); 485 end 486 end else if (32'(ac_ar.aarsize) < MaxAar && ac_ar.transfer && !ac_ar.write) begin -7- 487 // store a0 in dscratch1 488 abstract_cmd[0][31:0] = HasSndScratch ? 489 dm::csrw(dm::CSR_DSCRATCH1, LoadBaseAddr) : 490 dm::nop(); 491 // this range is reserved 492 if (ac_ar.regno[15:14] != '0) begin -8- 493 abstract_cmd[0][31:0] = dm::ebreak(); // we leave asap ==> 494 unsupported_command = 1'b1; 495 // A0 access needs to be handled separately, as we use A0 to load 496 // the DM address offset need to access DSCRATCH1 in this case 497 end else if (HasSndScratch && ac_ar.regno[12] && (!ac_ar.regno[5]) && -9- 498 (ac_ar.regno[4:0] == 5'd10)) begin 499 // store s0 in dscratch 500 abstract_cmd[2][31:0] = dm::csrw(dm::CSR_DSCRATCH0, 5'd8); ==> 501 // read value from CSR into s0 502 abstract_cmd[2][63:32] = dm::csrr(dm::CSR_DSCRATCH1, 5'd8); 503 // and store s0 into data section 504 abstract_cmd[3][31:0] = dm::store(ac_ar.aarsize, 5'd8, LoadBaseAddr, dm::DataAddr); 505 // restore s0 again from dscratch 506 abstract_cmd[3][63:32] = dm::csrr(dm::CSR_DSCRATCH0, 5'd8); 507 // GPR/FPR access 508 end else if (ac_ar.regno[12]) begin -10- 509 // determine whether we want to access the floating point register or not 510 if (ac_ar.regno[5]) begin -11- 511 abstract_cmd[2][31:0] = ==> 512 dm::float_store(ac_ar.aarsize, ac_ar.regno[4:0], LoadBaseAddr, dm::DataAddr); 513 end else begin 514 abstract_cmd[2][31:0] = ==> 515 dm::store(ac_ar.aarsize, ac_ar.regno[4:0], LoadBaseAddr, dm::DataAddr); 516 end 517 // CSR access 518 end else begin 519 // CSR register to data 520 // store s0 in dscratch 521 abstract_cmd[2][31:0] = dm::csrw(dm::CSR_DSCRATCH0, 5'd8); ==> 522 // read value from CSR into s0 523 abstract_cmd[2][63:32] = dm::csrr(dm::csr_reg_t'(ac_ar.regno[11:0]), 5'd8); 524 // and store s0 into data section 525 abstract_cmd[3][31:0] = dm::store(ac_ar.aarsize, 5'd8, LoadBaseAddr, dm::DataAddr); 526 // restore s0 again from dscratch 527 abstract_cmd[3][63:32] = dm::csrr(dm::CSR_DSCRATCH0, 5'd8); 528 end 529 end else if (32'(ac_ar.aarsize) >= MaxAar || ac_ar.aarpostincrement == 1'b1) begin -12- 530 // this should happend when e.g. ac_ar.aarsize >= MaxAar 531 // Openocd will try to do an access with aarsize=64 bits 532 // first before falling back to 32 bits. 533 abstract_cmd[0][31:0] = dm::ebreak(); // we leave asap ==> 534 unsupported_command = 1'b1; 535 end MISSING_ELSE ==> 536 537 // Check whether we need to execute the program buffer. When we 538 // get an unsupported command we really should abort instead of 539 // still trying to execute the program buffer, makes it easier 540 // for the debugger to recover 541 if (ac_ar.postexec && !unsupported_command) begin -13- 542 // issue a nop, we will automatically run into the program buffer 543 abstract_cmd[4][63:32] = dm::nop(); ==> 544 end MISSING_ELSE ==> 545 end 546 // not supported at the moment 547 // dm::QuickAccess:; 548 // dm::AccessMemory:; 549 default: begin 550 abstract_cmd[0][31:0] = dm::ebreak(); ==>

Branches:
-1--2--3--4--5--6--7--8--9--10--11--12--13-StatusTests
AccessRegister 1 1 - - - - - - - - - - Not Covered
AccessRegister 1 0 1 - - - - - - - - - Not Covered
AccessRegister 1 0 0 1 1 - - - - - - - Not Covered
AccessRegister 1 0 0 1 0 - - - - - - - Not Covered
AccessRegister 1 0 0 0 - - - - - - - - Covered T39,T40,T61
AccessRegister 0 - - - - 1 1 - - - - - Not Covered
AccessRegister 0 - - - - 1 0 1 - - - - Not Covered
AccessRegister 0 - - - - 1 0 0 1 1 - - Not Covered
AccessRegister 0 - - - - 1 0 0 1 0 - - Not Covered
AccessRegister 0 - - - - 1 0 0 0 - - - Covered T65,T30,T8
AccessRegister 0 - - - - 0 - - - - 1 - Not Covered
AccessRegister 0 - - - - 0 - - - - 0 - Covered T1,T2,T3
AccessRegister - - - - - - - - - - - 1 Covered T56,T57,T58
AccessRegister - - - - - - - - - - - 0 Covered T1,T2,T3
default - - - - - - - - - - - - Covered T2,T50,T51


587 if (!rst_ni) begin -1- 588 fwd_rom_q <= 1'b0; ==> 589 rdata_q <= '0; 590 state_q <= Idle; 591 word_enable32_q <= 1'b0; 592 end else begin 593 fwd_rom_q <= fwd_rom_d; ==>

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


601 if (!rst_ni) begin -1- 602 halted_q <= 1'b0; ==> 603 resuming_q <= 1'b0; 604 end else begin 605 halted_q <= SelectableHarts & halted_d; ==>

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

Line Coverage for Instance : tb.dut.u_dm_top.i_dm_mem
Line No.TotalCoveredPercent
TOTAL18716789.30
CONT_ASSIGN11211100.00
CONT_ASSIGN11311100.00
CONT_ASSIGN12011100.00
CONT_ASSIGN12111100.00
CONT_ASSIGN12211100.00
CONT_ASSIGN12411100.00
CONT_ASSIGN12511100.00
CONT_ASSIGN12611100.00
CONT_ASSIGN12711100.00
CONT_ASSIGN13511100.00
CONT_ASSIGN13611100.00
CONT_ASSIGN13711100.00
CONT_ASSIGN13811100.00
CONT_ASSIGN14111100.00
ALWAYS1483737100.00
CONT_ASSIGN22611100.00
CONT_ASSIGN23111100.00
ALWAYS2394646100.00
ROUTINE37511100.00
ALWAYS3881414100.00
ALWAYS41133100.00
CONT_ASSIGN41811100.00
ALWAYS422543462.96
CONT_ASSIGN55711100.00
ALWAYS58799100.00
ALWAYS60155100.00

111 112 1/1 assign hartsel = hartsel_i[HartSelLen-1:0]; Tests: T1 T2 T3  113 1/1 assign wdata_hartsel = wdata_i[HartSelLen-1:0]; Tests: T1 T2 T3  114 115 logic [NrHartsAligned-1:0] resumereq_aligned, haltreq_aligned, 116 halted_d_aligned, halted_q_aligned, 117 halted_aligned, resumereq_wdata_aligned, 118 resuming_d_aligned, resuming_q_aligned; 119 120 1/1 assign resumereq_aligned = NrHartsAligned'(resumereq_i); Tests: T5 T39 T24  121 1/1 assign haltreq_aligned = NrHartsAligned'(haltreq_i); Tests: T1 T2 T3  122 1/1 assign resumereq_wdata_aligned = NrHartsAligned'(resumereq_i); Tests: T5 T39 T24  123 124 1/1 assign halted_q_aligned = NrHartsAligned'(halted_q); Tests: T1 T2 T3  125 1/1 assign halted_d = NrHarts'(halted_d_aligned); Tests: T1 T2 T3  126 1/1 assign resuming_q_aligned = NrHartsAligned'(resuming_q); Tests: T1 T2 T3  127 1/1 assign resuming_d = NrHarts'(resuming_d_aligned); Tests: T1 T2 T3  128 129 // distinguish whether we need to forward data from the ROM or the FSM 130 // latch the address for this 131 logic fwd_rom_d, fwd_rom_q; 132 dm::ac_ar_cmd_t ac_ar; 133 134 // Abstract Command Access Register 135 1/1 assign ac_ar = dm::ac_ar_cmd_t'(cmd_i.control); Tests: T1 T2 T3  136 1/1 assign debug_req_o = haltreq_i; Tests: T1 T2 T3  137 1/1 assign halted_o = halted_q; Tests: T1 T2 T3  138 1/1 assign resuming_o = resuming_q; Tests: T1 T2 T3  139 140 // reshape progbuf 141 1/1 assign progbuf = progbuf_i; Tests: T1 T2 T3  142 143 typedef enum logic [1:0] { Idle, Go, Resume, CmdExecuting } state_e; 144 state_e state_d, state_q; 145 146 // hart ctrl queue 147 always_comb begin : p_hart_ctrl_queue 148 1/1 cmderror_valid_o = 1'b0; Tests: T1 T2 T3  149 1/1 cmderror_o = dm::CmdErrNone; Tests: T1 T2 T3  150 1/1 state_d = state_q; Tests: T1 T2 T3  151 1/1 go = 1'b0; Tests: T1 T2 T3  152 1/1 resume = 1'b0; Tests: T1 T2 T3  153 1/1 cmdbusy_o = 1'b1; Tests: T1 T2 T3  154 155 1/1 unique case (state_q) Tests: T1 T2 T3  156 Idle: begin 157 1/1 cmdbusy_o = 1'b0; Tests: T1 T2 T3  158 1/1 if (cmd_valid_i && halted_q_aligned[hartsel] && !unsupported_command) begin Tests: T1 T2 T3  159 // give the go signal 160 1/1 state_d = Go; Tests: T1 T3 T25  161 1/1 end else if (cmd_valid_i) begin Tests: T1 T2 T3  162 // hart must be halted for all requests 163 1/1 cmderror_valid_o = 1'b1; Tests: T2 T35 T49  164 1/1 cmderror_o = dm::CmdErrorHaltResume; Tests: T2 T35 T49  165 end MISSING_ELSE 166 // CSRs want to resume, the request is ignored when the hart is 167 // requested to halt or it didn't clear the resuming_q bit before 168 1/1 if (resumereq_aligned[hartsel] && !resuming_q_aligned[hartsel] && Tests: T1 T2 T3  169 !haltreq_aligned[hartsel] && halted_q_aligned[hartsel]) begin 170 1/1 state_d = Resume; Tests: T5 T39 T24  171 end MISSING_ELSE 172 end 173 174 Go: begin 175 // we are already busy here since we scheduled the execution of a program 176 1/1 cmdbusy_o = 1'b1; Tests: T1 T3 T25  177 1/1 go = 1'b1; Tests: T1 T3 T25  178 // the thread is now executing the command, track its state 179 1/1 if (going) begin Tests: T1 T3 T25  180 1/1 state_d = CmdExecuting; Tests: T1 T3 T39  181 end MISSING_ELSE 182 end 183 184 Resume: begin 185 1/1 cmdbusy_o = 1'b1; Tests: T5 T39 T24  186 1/1 resume = 1'b1; Tests: T5 T39 T24  187 1/1 if (resuming_q_aligned[hartsel]) begin Tests: T5 T39 T24  188 1/1 state_d = Idle; Tests: T5 T39 T24  189 end MISSING_ELSE 190 end 191 192 CmdExecuting: begin 193 1/1 cmdbusy_o = 1'b1; Tests: T1 T3 T39  194 1/1 go = 1'b0; Tests: T1 T3 T39  195 // wait until the hart has halted again 196 1/1 if (halted_aligned[hartsel]) begin Tests: T1 T3 T39  197 1/1 state_d = Idle; Tests: T1 T3 T39  198 end MISSING_ELSE 199 end 200 201 default: ; Exclude Annotation: VC_COV_UNR 202 endcase 203 204 // only signal once that cmd is unsupported so that we can clear cmderr 205 // in subsequent writes to abstractcs 206 1/1 if (unsupported_command && cmd_valid_i) begin Tests: T1 T2 T3  207 1/1 cmderror_valid_o = 1'b1; Tests: T2 T50 T51  208 1/1 cmderror_o = dm::CmdErrNotSupported; Tests: T2 T50 T51  209 end MISSING_ELSE 210 211 1/1 if (exception) begin Tests: T1 T2 T3  212 1/1 cmderror_valid_o = 1'b1; Tests: T25 T26  213 1/1 cmderror_o = dm::CmdErrorException; Tests: T25 T26  214 end MISSING_ELSE 215 216 1/1 if (ndmreset_i) begin Tests: T1 T2 T3  217 // Clear state of hart and its control signals when it is being reset. 218 1/1 state_d = Idle; Tests: T1 T52 T10  219 1/1 go = 1'b0; Tests: T1 T52 T10  220 1/1 resume = 1'b0; Tests: T1 T52 T10  221 end MISSING_ELSE 222 end 223 224 // word mux for 32bit and 64bit buses 225 logic [63:0] word_mux; 226 1/1 assign word_mux = (fwd_rom_q) ? rom_rdata : rdata_q; Tests: T1 T2 T3  227 228 if (BusWidth == 64) begin : gen_word_mux64 229 assign rdata_o = word_mux; 230 end else begin : gen_word_mux32 231 1/1 assign rdata_o = (word_enable32_q) ? word_mux[32 +: 32] : word_mux[0 +: 32]; Tests: T1 T2 T3  232 end 233 234 // read/write logic 235 logic [dm::DataCount-1:0][31:0] data_bits; 236 logic [7:0][7:0] rdata; 237 always_comb (* xprop_off *) begin : p_rw_logic 238 239 1/1 halted_d_aligned = NrHartsAligned'(halted_q); Tests: T1 T2 T3  240 1/1 resuming_d_aligned = NrHartsAligned'(resuming_q); Tests: T1 T2 T3  241 1/1 rdata_d = rdata_q; Tests: T1 T2 T3  242 1/1 data_bits = data_i; Tests: T1 T2 T3  243 1/1 rdata = '0; Tests: T1 T2 T3  244 1/1 fwd_rom_d = 1'b0; Tests: T1 T2 T3  245 246 // write data in csr register 247 1/1 data_valid_o = 1'b0; Tests: T1 T2 T3  248 1/1 exception = 1'b0; Tests: T1 T2 T3  249 1/1 halted_aligned = '0; Tests: T1 T2 T3  250 1/1 going = 1'b0; Tests: T1 T2 T3  251 252 // The resume ack signal is lowered when the resume request is deasserted 253 1/1 if (clear_resumeack_i) begin Tests: T1 T2 T3  254 1/1 resuming_d_aligned[hartsel] = 1'b0; Tests: T5 T39 T24  255 end MISSING_ELSE 256 // we've got a new request 257 1/1 if (req_i) begin Tests: T1 T2 T3  258 // this is a write 259 1/1 if (we_i) begin Tests: T1 T2 T3  260 1/1 unique case (addr_i[DbgAddressBits-1:0]) inside Tests: T1 T2 T3  261 HaltedAddr: begin 262 1/1 halted_aligned[wdata_hartsel] = 1'b1; Tests: T1 T2 T3  263 1/1 halted_d_aligned[wdata_hartsel] = 1'b1; Tests: T1 T2 T3  264 end 265 GoingAddr: begin 266 1/1 going = 1'b1; Tests: T1 T3 T39  267 end 268 ResumingAddr: begin 269 // clear the halted flag as the hart resumed execution 270 1/1 halted_d_aligned[wdata_hartsel] = 1'b0; Tests: T5 T39 T24  271 // set the resuming flag which needs to be cleared by the debugger 272 1/1 resuming_d_aligned[wdata_hartsel] = 1'b1; Tests: T5 T39 T24  273 end 274 // an exception occurred during execution 275 1/1 ExceptionAddr: exception = 1'b1; Tests: T25 T26  276 // core can write data registers 277 [DataBaseAddr:DataEndAddr]: begin 278 1/1 data_valid_o = 1'b1; Tests: T1 T6 T10  279 1/1 for (int unsigned dc = 0; dc < dm::DataCount; dc++) begin Tests: T1 T6 T10  280 1/1 if ((addr_i[DbgAddressBits-1:2] - DataBaseAddr[DbgAddressBits-1:2]) == dc) begin Tests: T1 T6 T10  281 1/1 for (int unsigned i = 0; i < $bits(be_i); i++) begin Tests: T1 T6 T10  282 1/1 if (be_i[i]) begin Tests: T1 T6 T10  283 1/1 if (i>3) begin // for upper 32bit data write (only used for BusWidth == 64) Tests: T1 T6 T10  284 // ensure we write to an implemented data register 285 excluded if (dc < (dm::DataCount - 1)) begin Exclude Annotation: VC_COV_UNR 286 excluded data_bits[dc+1][(i-4)*8+:8] = wdata_i[i*8+:8]; Exclude Annotation: VC_COV_UNR 287 end ==> MISSING_ELSE 288 end else begin // for lower 32bit data write 289 1/1 data_bits[dc][i*8+:8] = wdata_i[i*8+:8]; Tests: T1 T6 T10  290 end 291 end ==> MISSING_ELSE 292 end 293 end MISSING_ELSE 294 end 295 end 296 default: ; 297 endcase 298 299 // this is a read 300 end else begin 301 1/1 unique case (addr_i[DbgAddressBits-1:0]) inside Tests: T1 T5 T39  302 // variable ROM content 303 WhereToAddr: begin 304 // variable jump to abstract cmd, program_buffer or resume 305 1/1 if (resumereq_wdata_aligned[wdata_hartsel]) begin Tests: T39 T53 T51  306 1/1 rdata_d = {32'b0, dm::jal('0, 21'(dm::ResumeAddress[11:0])-21'(WhereToAddr))}; Tests: T54 T55  307 end MISSING_ELSE 308 309 // there is a command active so jump there 310 1/1 if (cmdbusy_o) begin Tests: T39 T53 T51  311 // transfer not set is shortcut to the program buffer if postexec is set 312 // keep this statement narrow to not catch invalid commands 313 1/1 if (cmd_i.cmdtype == dm::AccessRegister && Tests: T39 T53 T51  314 !ac_ar.transfer && ac_ar.postexec) begin 315 1/1 rdata_d = {32'b0, dm::jal('0, 21'(ProgBufBaseAddr)-21'(WhereToAddr))}; Tests: T56 T57 T58  316 // this is a legit abstract cmd -> execute it 317 end else begin 318 1/1 rdata_d = {32'b0, dm::jal('0, 21'(AbstractCmdBaseAddr)-21'(WhereToAddr))}; Tests: T39 T53 T51  319 end 320 end MISSING_ELSE 321 end 322 323 [DataBaseAddr:DataEndAddr]: begin 324 1/1 rdata_d = { Tests: T1 T10 T36  325 data_i[$clog2(dm::DataCount)'(((addr_i[DbgAddressBits-1:3] 326 - DataBaseAddr[DbgAddressBits-1:3]) << 1) 327 + 1'b1)], 328 data_i[$clog2(dm::DataCount)'(((addr_i[DbgAddressBits-1:3] 329 - DataBaseAddr[DbgAddressBits-1:3]) << 1))] 330 }; 331 end 332 333 [ProgBufBaseAddr:ProgBufEndAddr]: begin 334 1/1 rdata_d = progbuf[ProgBuf64AddrSize'(addr_i[DbgAddressBits-1:3] - Tests: T41 T59 T60  335 ProgBufBaseAddr[DbgAddressBits-1:3])]; 336 end 337 338 // two slots for abstract command 339 [AbstractCmdBaseAddr:AbstractCmdEndAddr]: begin 340 // return the correct address index 341 1/1 rdata_d = abstract_cmd[3'(addr_i[DbgAddressBits-1:3] - Tests: T40 T61 T62  342 AbstractCmdBaseAddr[DbgAddressBits-1:3])]; 343 end 344 // harts are polling for flags here 345 [FlagsBaseAddr:FlagsEndAddr]: begin 346 // release the corresponding hart 347 1/1 if (({addr_i[DbgAddressBits-1:3], 3'b0} - FlagsBaseAddr[DbgAddressBits-1:0]) == Tests: T5 T39 T24  348 (DbgAddressBits'(hartsel) & {{(DbgAddressBits-3){1'b1}}, 3'b0})) begin 349 1/1 rdata[DbgAddressBits'(hartsel) & DbgAddressBits'(3'b111)] = {6'b0, resume, go}; Tests: T5 T39 T24  350 end MISSING_ELSE 351 1/1 rdata_d = rdata; Tests: T5 T39 T24  352 end 353 // Access has to be forwarded to the ROM. The ROM starts at the HaltAddress of the core 354 // e.g.: it immediately jumps to the ROM base address. 355 [RomBaseAddr:RomEndAddr]: begin 356 1/1 fwd_rom_d = 1'b1; Tests: T63 T64  357 end 358 default: ; 359 endcase 360 end 361 end MISSING_ELSE 362 363 1/1 if (ndmreset_i) begin Tests: T1 T2 T3  364 // When harts are reset, they are neither halted nor resuming. 365 1/1 halted_d_aligned = '0; Tests: T1 T52 T10  366 1/1 resuming_d_aligned = '0; Tests: T1 T52 T10  367 end MISSING_ELSE 368 369 1/1 data_o = data_bits; Tests: T1 T2 T3  370 end 371 372 // This flags subword writes that are shorter than the defined width of the register. 373 // Other writes are ignored. 374 function automatic logic gen_wr_err(logic we, logic [BeWidth-1:0] be, logic [BeWidth-1:0] mask); 375 1/1 return we && (|(~be & mask)); Tests: T1 T2 T3  376 endfunction 377 378 // Relevant bus error cases 379 // - access unmapped address 380 // - write a CSR with unaligned address, e.g. `a_address[1:0] != 0` 381 // - write a CSR less than its width, e.g. when CSR is 2 bytes wide, only write 1 byte 382 // - write a RO (read-only) memory 383 localparam logic[BeWidth-1:0] FullRegMask = {BeWidth{1'b1}}; 384 localparam logic[BeWidth-1:0] OneBitMask = BeWidth'(1'b1); 385 localparam logic[BeWidth-1:0] HartSelMask = BeWidth'(2**HartSelLen-1); 386 logic err_d, err_q; 387 always_comb begin 388 1/1 err_d = 1'b0; Tests: T1 T2 T3  389 1/1 if (req_i) begin Tests: T1 T2 T3  390 1/1 unique case (addr_i[DbgAddressBits-1:0]) inside Tests: T1 T2 T3  391 1/1 WhereToAddr: err_d = gen_wr_err(we_i, be_i, FullRegMask); Tests: T39 T53 T51  392 1/1 HaltedAddr: err_d = gen_wr_err(we_i, be_i, HartSelMask); Tests: T1 T2 T3  393 1/1 GoingAddr: err_d = gen_wr_err(we_i, be_i, OneBitMask); Tests: T1 T3 T39  394 1/1 ResumingAddr: err_d = gen_wr_err(we_i, be_i, HartSelMask); Tests: T5 T39 T24  395 1/1 ExceptionAddr: err_d = gen_wr_err(we_i, be_i, OneBitMask); Tests: T25 T26 T60  396 1/1 [DataBaseAddr:DataEndAddr]: err_d = gen_wr_err(we_i, be_i, FullRegMask); Tests: T1 T6 T10  397 1/1 [ProgBufBaseAddr:ProgBufEndAddr]: err_d = gen_wr_err(we_i, be_i, FullRegMask); Tests: T41 T59 T60  398 1/1 [AbstractCmdBaseAddr:AbstractCmdEndAddr]: err_d = gen_wr_err(we_i, be_i, FullRegMask); Tests: T40 T61 T62  399 1/1 [FlagsBaseAddr:FlagsEndAddr]: err_d = gen_wr_err(we_i, be_i, FullRegMask); Tests: T5 T39 T24  400 1/1 [RomBaseAddr:RomEndAddr]: err_d = we_i; // Writing ROM area always errors. Tests: T63 T64 T60  401 default: err_d = 1'b1; 402 endcase 403 // Unaligned accesses 404 1/1 if (addr_i[$clog2(BeWidth)-1:0] != '0) begin Tests: T1 T2 T3  405 excluded err_d = 1'b1; Exclude Annotation: VC_COV_UNR 406 end MISSING_ELSE 407 end MISSING_ELSE 408 end 409 410 always_ff @(posedge clk_i or negedge rst_ni) begin : p_err_reg 411 1/1 if (!rst_ni) begin Tests: T1 T2 T3  412 1/1 err_q <= 1'b0; Tests: T1 T2 T3  413 end else begin 414 1/1 err_q <= err_d; Tests: T1 T2 T3  415 end 416 end 417 418 1/1 assign err_o = err_q; Tests: T1 T2 T3  419 420 always_comb begin : p_abstract_cmd_rom 421 // this abstract command is currently unsupported 422 1/1 unsupported_command = 1'b0; Tests: T1 T2 T3  423 // default memory 424 // if ac_ar.transfer is not set then we can take a shortcut to the program buffer 425 1/1 abstract_cmd[0][31:0] = dm::illegal(); Tests: T1 T2 T3  426 // load debug module base address into a0, this is shared among all commands 427 1/1 abstract_cmd[0][63:32] = HasSndScratch ? dm::auipc(5'd10, '0) : dm::nop(); Tests: T1 T2 T3  428 // clr lowest 12b -> DM base offset 429 1/1 abstract_cmd[1][31:0] = HasSndScratch ? dm::srli(5'd10, 5'd10, 6'd12) : dm::nop(); Tests: T1 T2 T3  430 1/1 abstract_cmd[1][63:32] = HasSndScratch ? dm::slli(5'd10, 5'd10, 6'd12) : dm::nop(); Tests: T1 T2 T3  431 1/1 abstract_cmd[2][31:0] = dm::nop(); Tests: T1 T2 T3  432 1/1 abstract_cmd[2][63:32] = dm::nop(); Tests: T1 T2 T3  433 1/1 abstract_cmd[3][31:0] = dm::nop(); Tests: T1 T2 T3  434 1/1 abstract_cmd[3][63:32] = dm::nop(); Tests: T1 T2 T3  435 1/1 abstract_cmd[4][31:0] = HasSndScratch ? dm::csrr(dm::CSR_DSCRATCH1, 5'd10) : dm::nop(); Tests: T1 T2 T3  436 1/1 abstract_cmd[4][63:32] = dm::ebreak(); Tests: T1 T2 T3  437 1/1 abstract_cmd[7:5] = '0; Tests: T1 T2 T3  438 439 // this depends on the command being executed 440 1/1 unique case (cmd_i.cmdtype) Tests: T1 T2 T3  441 // -------------------- 442 // Access Register 443 // -------------------- 444 dm::AccessRegister: begin 445 1/1 if (32'(ac_ar.aarsize) < MaxAar && ac_ar.transfer && ac_ar.write) begin Tests: T1 T2 T3  446 // store a0 in dscratch1 447 1/1 abstract_cmd[0][31:0] = HasSndScratch ? dm::csrw(dm::CSR_DSCRATCH1, 5'd10) : dm::nop(); Tests: T39 T40 T61  448 // this range is reserved 449 1/1 if (ac_ar.regno[15:14] != '0) begin Tests: T39 T40 T61  450 0/1 ==> abstract_cmd[0][31:0] = dm::ebreak(); // we leave asap 451 0/1 ==> unsupported_command = 1'b1; 452 // A0 access needs to be handled separately, as we use A0 to load 453 // the DM address offset need to access DSCRATCH1 in this case 454 1/1 end else if (HasSndScratch && ac_ar.regno[12] && (!ac_ar.regno[5]) && Tests: T39 T40 T61  455 (ac_ar.regno[4:0] == 5'd10)) begin 456 // store s0 in dscratch 457 0/1 ==> abstract_cmd[2][31:0] = dm::csrw(dm::CSR_DSCRATCH0, 5'd8); 458 // load from data register 459 0/1 ==> abstract_cmd[2][63:32] = dm::load(ac_ar.aarsize, 5'd8, LoadBaseAddr, dm::DataAddr); 460 // and store it in the corresponding CSR 461 0/1 ==> abstract_cmd[3][31:0] = dm::csrw(dm::CSR_DSCRATCH1, 5'd8); 462 // restore s0 again from dscratch 463 0/1 ==> abstract_cmd[3][63:32] = dm::csrr(dm::CSR_DSCRATCH0, 5'd8); 464 // GPR/FPR access 465 1/1 end else if (ac_ar.regno[12]) begin Tests: T39 T40 T61  466 // determine whether we want to access the floating point register or not 467 0/1 ==> if (ac_ar.regno[5]) begin 468 0/1 ==> abstract_cmd[2][31:0] = 469 dm::float_load(ac_ar.aarsize, ac_ar.regno[4:0], LoadBaseAddr, dm::DataAddr); 470 end else begin 471 0/1 ==> abstract_cmd[2][31:0] = 472 dm::load(ac_ar.aarsize, ac_ar.regno[4:0], LoadBaseAddr, dm::DataAddr); 473 end 474 // CSR access 475 end else begin 476 // data register to CSR 477 // store s0 in dscratch 478 1/1 abstract_cmd[2][31:0] = dm::csrw(dm::CSR_DSCRATCH0, 5'd8); Tests: T39 T40 T61  479 // load from data register 480 1/1 abstract_cmd[2][63:32] = dm::load(ac_ar.aarsize, 5'd8, LoadBaseAddr, dm::DataAddr); Tests: T39 T40 T61  481 // and store it in the corresponding CSR 482 1/1 abstract_cmd[3][31:0] = dm::csrw(dm::csr_reg_t'(ac_ar.regno[11:0]), 5'd8); Tests: T39 T40 T61  483 // restore s0 again from dscratch 484 1/1 abstract_cmd[3][63:32] = dm::csrr(dm::CSR_DSCRATCH0, 5'd8); Tests: T39 T40 T61  485 end 486 1/1 end else if (32'(ac_ar.aarsize) < MaxAar && ac_ar.transfer && !ac_ar.write) begin Tests: T1 T2 T3  487 // store a0 in dscratch1 488 1/1 abstract_cmd[0][31:0] = HasSndScratch ? Tests: T65 T30 T8  489 dm::csrw(dm::CSR_DSCRATCH1, LoadBaseAddr) : 490 dm::nop(); 491 // this range is reserved 492 1/1 if (ac_ar.regno[15:14] != '0) begin Tests: T65 T30 T8  493 0/1 ==> abstract_cmd[0][31:0] = dm::ebreak(); // we leave asap 494 0/1 ==> unsupported_command = 1'b1; 495 // A0 access needs to be handled separately, as we use A0 to load 496 // the DM address offset need to access DSCRATCH1 in this case 497 1/1 end else if (HasSndScratch && ac_ar.regno[12] && (!ac_ar.regno[5]) && Tests: T65 T30 T8  498 (ac_ar.regno[4:0] == 5'd10)) begin 499 // store s0 in dscratch 500 0/1 ==> abstract_cmd[2][31:0] = dm::csrw(dm::CSR_DSCRATCH0, 5'd8); 501 // read value from CSR into s0 502 0/1 ==> abstract_cmd[2][63:32] = dm::csrr(dm::CSR_DSCRATCH1, 5'd8); 503 // and store s0 into data section 504 0/1 ==> abstract_cmd[3][31:0] = dm::store(ac_ar.aarsize, 5'd8, LoadBaseAddr, dm::DataAddr); 505 // restore s0 again from dscratch 506 0/1 ==> abstract_cmd[3][63:32] = dm::csrr(dm::CSR_DSCRATCH0, 5'd8); 507 // GPR/FPR access 508 1/1 end else if (ac_ar.regno[12]) begin Tests: T65 T30 T8  509 // determine whether we want to access the floating point register or not 510 0/1 ==> if (ac_ar.regno[5]) begin 511 0/1 ==> abstract_cmd[2][31:0] = 512 dm::float_store(ac_ar.aarsize, ac_ar.regno[4:0], LoadBaseAddr, dm::DataAddr); 513 end else begin 514 0/1 ==> abstract_cmd[2][31:0] = 515 dm::store(ac_ar.aarsize, ac_ar.regno[4:0], LoadBaseAddr, dm::DataAddr); 516 end 517 // CSR access 518 end else begin 519 // CSR register to data 520 // store s0 in dscratch 521 1/1 abstract_cmd[2][31:0] = dm::csrw(dm::CSR_DSCRATCH0, 5'd8); Tests: T65 T30 T8  522 // read value from CSR into s0 523 1/1 abstract_cmd[2][63:32] = dm::csrr(dm::csr_reg_t'(ac_ar.regno[11:0]), 5'd8); Tests: T65 T30 T8  524 // and store s0 into data section 525 1/1 abstract_cmd[3][31:0] = dm::store(ac_ar.aarsize, 5'd8, LoadBaseAddr, dm::DataAddr); Tests: T65 T30 T8  526 // restore s0 again from dscratch 527 1/1 abstract_cmd[3][63:32] = dm::csrr(dm::CSR_DSCRATCH0, 5'd8); Tests: T65 T30 T8  528 end 529 1/1 end else if (32'(ac_ar.aarsize) >= MaxAar || ac_ar.aarpostincrement == 1'b1) begin Tests: T1 T2 T3  530 // this should happend when e.g. ac_ar.aarsize >= MaxAar 531 // Openocd will try to do an access with aarsize=64 bits 532 // first before falling back to 32 bits. 533 0/1 ==> abstract_cmd[0][31:0] = dm::ebreak(); // we leave asap 534 0/1 ==> unsupported_command = 1'b1; 535 end MISSING_ELSE 536 537 // Check whether we need to execute the program buffer. When we 538 // get an unsupported command we really should abort instead of 539 // still trying to execute the program buffer, makes it easier 540 // for the debugger to recover 541 1/1 if (ac_ar.postexec && !unsupported_command) begin Tests: T1 T2 T3  542 // issue a nop, we will automatically run into the program buffer 543 1/1 abstract_cmd[4][63:32] = dm::nop(); Tests: T56 T57 T58  544 end MISSING_ELSE 545 end 546 // not supported at the moment 547 // dm::QuickAccess:; 548 // dm::AccessMemory:; 549 default: begin 550 abstract_cmd[0][31:0] = dm::ebreak(); 551 unsupported_command = 1'b1; 552 end 553 endcase 554 end 555 556 logic [63:0] rom_addr; 557 1/1 assign rom_addr = 64'(addr_i); Tests: T1 T2 T3  558 559 // Depending on whether the debug module is located 560 // at the zero page we can instantiate a simplified version 561 // which only requires one scratch register per hart. 562 // For all other cases we need to set aside 563 // two registers per hart, hence we also need 564 // two scratch registers. 565 if (HasSndScratch) begin : gen_rom_snd_scratch 566 debug_rom i_debug_rom ( 567 .clk_i, 568 .rst_ni, 569 .req_i, 570 .addr_i ( rom_addr ), 571 .rdata_o ( rom_rdata ) 572 ); 573 end else begin : gen_rom_one_scratch 574 // It uses the zero register (`x0`) as the base 575 // for its loads. The zero register does not need to 576 // be saved. 577 debug_rom_one_scratch i_debug_rom ( 578 .clk_i, 579 .rst_ni, 580 .req_i, 581 .addr_i ( rom_addr ), 582 .rdata_o ( rom_rdata ) 583 ); 584 end 585 586 always_ff @(posedge clk_i or negedge rst_ni) begin : p_regs 587 1/1 if (!rst_ni) begin Tests: T1 T2 T3  588 1/1 fwd_rom_q <= 1'b0; Tests: T1 T2 T3  589 1/1 rdata_q <= '0; Tests: T1 T2 T3  590 1/1 state_q <= Idle; Tests: T1 T2 T3  591 1/1 word_enable32_q <= 1'b0; Tests: T1 T2 T3  592 end else begin 593 1/1 fwd_rom_q <= fwd_rom_d; Tests: T1 T2 T3  594 1/1 rdata_q <= rdata_d; Tests: T1 T2 T3  595 1/1 state_q <= state_d; Tests: T1 T2 T3  596 1/1 word_enable32_q <= addr_i[2]; Tests: T1 T2 T3  597 end 598 end 599 600 always_ff @(posedge clk_i or negedge rst_ni) begin 601 1/1 if (!rst_ni) begin Tests: T1 T2 T3  602 1/1 halted_q <= 1'b0; Tests: T1 T2 T3  603 1/1 resuming_q <= 1'b0; Tests: T1 T2 T3  604 end else begin 605 1/1 halted_q <= SelectableHarts & halted_d; Tests: T1 T2 T3  606 1/1 resuming_q <= SelectableHarts & resuming_d; Tests: T1 T2 T3 

Cond Coverage for Instance : tb.dut.u_dm_top.i_dm_mem
TotalCoveredPercent
Conditions584272.41
Logical584272.41
Non-Logical00
Event00

 LINE       158
 EXPRESSION (cmd_valid_i && halted_q_aligned[hartsel] && ((!unsupported_command)))
             -----1-----    ------------2------------    ------------3-----------
-1--2--3-StatusTests
011CoveredT1,T2,T3
101CoveredT35,T49
110CoveredT2,T50,T51
111CoveredT1,T3,T25

 LINE       168
 EXPRESSION (resumereq_aligned[hartsel] && ((!resuming_q_aligned[hartsel])) && ((!haltreq_aligned[hartsel])) && halted_q_aligned[hartsel])
             -------------1------------    ----------------2---------------    --------------3--------------    ------------4------------
-1--2--3--4-StatusTestsExclude Annotation
0111CoveredT5,T39,T24
1011Excluded VC_COV_UNR
1101CoveredT51,T66,T67
1110CoveredT39,T53,T51
1111CoveredT5,T39,T24

 LINE       206
 EXPRESSION (unsupported_command && cmd_valid_i)
             ---------1---------    -----2-----
-1--2-StatusTests
01CoveredT1,T3,T25
10CoveredT2,T50,T51
11CoveredT2,T50,T51

 LINE       226
 EXPRESSION (fwd_rom_q ? rom_rdata : rdata_q)
             ----1----
-1-StatusTests
0CoveredT1,T2,T3
1CoveredT63,T64

 LINE       231
 EXPRESSION (word_enable32_q ? word_mux[32+:32] : word_mux[0+:32])
             -------1-------
-1-StatusTests
0CoveredT1,T2,T3
1CoveredT1,T6,T39

 LINE       280
 EXPRESSION ((addr_i[(DbgAddressBits - 1):2] - DataBaseAddr[(DbgAddressBits - 1):2]) == dc)
            ---------------------------------------1---------------------------------------
-1-StatusTests
0CoveredT1,T6,T10
1CoveredT1,T6,T10

 LINE       313
 EXPRESSION ((cmd_i.cmdtype == AccessRegister) && ((!ac_ar.transfer)) && ac_ar.postexec)
             ----------------1----------------    ---------2---------    -------3------
-1--2--3-StatusTestsExclude Annotation
011Excluded Cannot have running command other than AccessRegister
101CoveredT34,T68,T69
110CoveredT53,T51,T70
111CoveredT56,T57,T58

 LINE       313
 SUB-EXPRESSION (cmd_i.cmdtype == AccessRegister)
                ----------------1----------------
-1-StatusTests
0Excluded
1CoveredT39,T53,T51

 LINE       347
 EXPRESSION (({addr_i[(DbgAddressBits - 1):3], 3'b0} - FlagsBaseAddr[(DbgAddressBits - 1):0]) == (12'(hartsel) & {{(DbgAddressBits - 3) {1'b1}}, 3'b0}))
            ----------------------------------------------------------------------1---------------------------------------------------------------------
-1-StatusTests
0CoveredT60,T66,T71
1CoveredT5,T39,T24

 LINE       445
 EXPRESSION ((32'(ac_ar.aarsize) < MaxAar) && ac_ar.transfer && ac_ar.write)
             --------------1--------------    -------2------    -----3-----
-1--2--3-StatusTests
011Not Covered
101CoveredT53,T58,T72
110CoveredT65,T30,T8
111CoveredT39,T40,T61

 LINE       449
 EXPRESSION (ac_ar.regno[15:14] != '0)
            -------------1------------
-1-StatusTests
0CoveredT39,T40,T61
1Not Covered

 LINE       454
 EXPRESSION (HasSndScratch && ac_ar.regno[12] && ((!ac_ar.regno[5])) && (ac_ar.regno[4:0] == 5'd10))
             ------1------    -------2-------    ---------3---------    -------------4-------------
-1--2--3--4-StatusTests
-011Not Covered
-101Not Covered
-110Not Covered
-111Not Covered

 LINE       454
 SUB-EXPRESSION (ac_ar.regno[4:0] == 5'd10)
                -------------1-------------
-1-StatusTests
0CoveredT39,T40,T61
1Not Covered

 LINE       486
 EXPRESSION ((32'(ac_ar.aarsize) < MaxAar) && ac_ar.transfer && ((!ac_ar.write)))
             --------------1--------------    -------2------    --------3-------
-1--2--3-StatusTestsExclude Annotation
011Not Covered
101CoveredT1,T2,T3
110Excluded VC_COV_UNR
111CoveredT65,T30,T8

 LINE       492
 EXPRESSION (ac_ar.regno[15:14] != '0)
            -------------1------------
-1-StatusTests
0CoveredT65,T30,T8
1Not Covered

 LINE       497
 EXPRESSION (HasSndScratch && ac_ar.regno[12] && ((!ac_ar.regno[5])) && (ac_ar.regno[4:0] == 5'd10))
             ------1------    -------2-------    ---------3---------    -------------4-------------
-1--2--3--4-StatusTests
-011CoveredT68
-101Not Covered
-110Not Covered
-111Not Covered

 LINE       497
 SUB-EXPRESSION (ac_ar.regno[4:0] == 5'd10)
                -------------1-------------
-1-StatusTests
0CoveredT65,T30,T8
1CoveredT68

 LINE       529
 EXPRESSION ((32'(ac_ar.aarsize) >= MaxAar) || (ac_ar.aarpostincrement == 1'b1))
             ---------------1--------------    ----------------2---------------
-1--2-StatusTests
00CoveredT1,T2,T3
01Not Covered
10Not Covered

 LINE       529
 SUB-EXPRESSION (ac_ar.aarpostincrement == 1'b1)
                ----------------1---------------
-1-StatusTests
0CoveredT1,T2,T3
1Not Covered

 LINE       541
 EXPRESSION (ac_ar.postexec && ((!unsupported_command)))
             -------1------    ------------2-----------
-1--2-StatusTests
01CoveredT1,T2,T3
10Not Covered
11CoveredT56,T57,T58

 LINE       605
 EXPRESSION (SelectableHarts & halted_d)
             -------1-------   ----2---
-1--2-StatusTests
-0CoveredT1,T2,T3
-1CoveredT1,T2,T3

 LINE       606
 EXPRESSION (SelectableHarts & resuming_d)
             -------1-------   -----2----
-1--2-StatusTests
-0CoveredT1,T2,T3
-1CoveredT5,T39,T24

FSM Coverage for Instance : tb.dut.u_dm_top.i_dm_mem
Summary for FSM :: state_q
TotalCoveredPercent
States 4 4 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
CmdExecuting 180 Covered T1,T3,T39
Go 160 Covered T1,T3,T25
Idle 188 Covered T1,T2,T3
Resume 170 Covered T5,T39,T24


transitionsLine No.CoveredTests
CmdExecuting->Idle 197 Covered T1,T3,T39
Go->CmdExecuting 180 Covered T1,T3,T39
Go->Idle 218 Covered T66
Idle->Go 160 Covered T1,T3,T25
Idle->Resume 170 Covered T5,T39,T24
Resume->Idle 188 Covered T5,T39,T24



Branch Coverage for Instance : tb.dut.u_dm_top.i_dm_mem
Line No.TotalCoveredPercent
Branches 78 69 88.46
TERNARY 226 2 2 100.00
TERNARY 231 2 2 100.00
CASE 155 11 11 100.00
IF 206 2 2 100.00
IF 211 2 2 100.00
IF 216 2 2 100.00
IF 253 2 2 100.00
IF 257 19 19 100.00
IF 363 2 2 100.00
IF 389 13 13 100.00
IF 411 2 2 100.00
CASE 440 15 6 40.00
IF 587 2 2 100.00
IF 601 2 2 100.00


226 assign word_mux = (fwd_rom_q) ? rom_rdata : rdata_q; -1- ==> ==>

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


231 assign rdata_o = (word_enable32_q) ? word_mux[32 +: 32] : word_mux[0 +: 32]; -1- ==> ==>

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


155 unique case (state_q) -1- 156 Idle: begin 157 cmdbusy_o = 1'b0; 158 if (cmd_valid_i && halted_q_aligned[hartsel] && !unsupported_command) begin -2- 159 // give the go signal 160 state_d = Go; ==> 161 end else if (cmd_valid_i) begin -3- 162 // hart must be halted for all requests 163 cmderror_valid_o = 1'b1; ==> 164 cmderror_o = dm::CmdErrorHaltResume; 165 end MISSING_ELSE ==> 166 // CSRs want to resume, the request is ignored when the hart is 167 // requested to halt or it didn't clear the resuming_q bit before 168 if (resumereq_aligned[hartsel] && !resuming_q_aligned[hartsel] && -4- 169 !haltreq_aligned[hartsel] && halted_q_aligned[hartsel]) begin 170 state_d = Resume; ==> 171 end MISSING_ELSE ==> 172 end 173 174 Go: begin 175 // we are already busy here since we scheduled the execution of a program 176 cmdbusy_o = 1'b1; 177 go = 1'b1; 178 // the thread is now executing the command, track its state 179 if (going) begin -5- 180 state_d = CmdExecuting; ==> 181 end MISSING_ELSE ==> 182 end 183 184 Resume: begin 185 cmdbusy_o = 1'b1; 186 resume = 1'b1; 187 if (resuming_q_aligned[hartsel]) begin -6- 188 state_d = Idle; ==> 189 end MISSING_ELSE ==> 190 end 191 192 CmdExecuting: begin 193 cmdbusy_o = 1'b1; 194 go = 1'b0; 195 // wait until the hart has halted again 196 if (halted_aligned[hartsel]) begin -7- 197 state_d = Idle; ==> 198 end MISSING_ELSE ==> 199 end 200 201 default: ; ==> (Excluded) Exclude Annotation: VC_COV_UNR

Branches:
-1--2--3--4--5--6--7-StatusTestsExclude Annotation
Idle 1 - - - - - Covered T1,T3,T25
Idle 0 1 - - - - Covered T2,T35,T49
Idle 0 0 - - - - Covered T1,T2,T3
Idle - - 1 - - - Covered T5,T39,T24
Idle - - 0 - - - Covered T1,T2,T3
Go - - - 1 - - Covered T1,T3,T39
Go - - - 0 - - Covered T1,T3,T25
Resume - - - - 1 - Covered T5,T39,T24
Resume - - - - 0 - Covered T5,T39,T24
CmdExecuting - - - - - 1 Covered T1,T3,T39
CmdExecuting - - - - - 0 Covered T1,T3,T39
default - - - - - - Excluded VC_COV_UNR


206 if (unsupported_command && cmd_valid_i) begin -1- 207 cmderror_valid_o = 1'b1; ==> 208 cmderror_o = dm::CmdErrNotSupported; 209 end MISSING_ELSE ==>

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


211 if (exception) begin -1- 212 cmderror_valid_o = 1'b1; ==> 213 cmderror_o = dm::CmdErrorException; 214 end MISSING_ELSE ==>

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


216 if (ndmreset_i) begin -1- 217 // Clear state of hart and its control signals when it is being reset. 218 state_d = Idle; ==> 219 go = 1'b0; 220 resume = 1'b0; 221 end MISSING_ELSE ==>

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


253 if (clear_resumeack_i) begin -1- 254 resuming_d_aligned[hartsel] = 1'b0; ==> 255 end MISSING_ELSE ==>

Branches:
-1-StatusTests
1 Covered T5,T39,T24
0 Covered T1,T2,T3


257 if (req_i) begin -1- 258 // this is a write 259 if (we_i) begin -2- 260 unique case (addr_i[DbgAddressBits-1:0]) inside -3- 261 HaltedAddr: begin 262 halted_aligned[wdata_hartsel] = 1'b1; ==> 263 halted_d_aligned[wdata_hartsel] = 1'b1; 264 end 265 GoingAddr: begin 266 going = 1'b1; ==> 267 end 268 ResumingAddr: begin 269 // clear the halted flag as the hart resumed execution 270 halted_d_aligned[wdata_hartsel] = 1'b0; ==> 271 // set the resuming flag which needs to be cleared by the debugger 272 resuming_d_aligned[wdata_hartsel] = 1'b1; 273 end 274 // an exception occurred during execution 275 ExceptionAddr: exception = 1'b1; ==> 276 // core can write data registers 277 [DataBaseAddr:DataEndAddr]: begin 278 data_valid_o = 1'b1; ==> 279 for (int unsigned dc = 0; dc < dm::DataCount; dc++) begin 280 if ((addr_i[DbgAddressBits-1:2] - DataBaseAddr[DbgAddressBits-1:2]) == dc) begin 281 for (int unsigned i = 0; i < $bits(be_i); i++) begin 282 if (be_i[i]) begin 283 if (i>3) begin // for upper 32bit data write (only used for BusWidth == 64) 284 // ensure we write to an implemented data register 285 if (dc < (dm::DataCount - 1)) begin 286 data_bits[dc+1][(i-4)*8+:8] = wdata_i[i*8+:8]; 287 end 288 end else begin // for lower 32bit data write 289 data_bits[dc][i*8+:8] = wdata_i[i*8+:8]; 290 end 291 end 292 end 293 end 294 end 295 end 296 default: ; ==> 297 endcase 298 299 // this is a read 300 end else begin 301 unique case (addr_i[DbgAddressBits-1:0]) inside -4- 302 // variable ROM content 303 WhereToAddr: begin 304 // variable jump to abstract cmd, program_buffer or resume 305 if (resumereq_wdata_aligned[wdata_hartsel]) begin -5- 306 rdata_d = {32'b0, dm::jal('0, 21'(dm::ResumeAddress[11:0])-21'(WhereToAddr))}; ==> 307 end MISSING_ELSE ==> 308 309 // there is a command active so jump there 310 if (cmdbusy_o) begin -6- 311 // transfer not set is shortcut to the program buffer if postexec is set 312 // keep this statement narrow to not catch invalid commands 313 if (cmd_i.cmdtype == dm::AccessRegister && -7- 314 !ac_ar.transfer && ac_ar.postexec) begin 315 rdata_d = {32'b0, dm::jal('0, 21'(ProgBufBaseAddr)-21'(WhereToAddr))}; ==> 316 // this is a legit abstract cmd -> execute it 317 end else begin 318 rdata_d = {32'b0, dm::jal('0, 21'(AbstractCmdBaseAddr)-21'(WhereToAddr))}; ==> 319 end 320 end MISSING_ELSE ==> 321 end 322 323 [DataBaseAddr:DataEndAddr]: begin 324 rdata_d = { ==> 325 data_i[$clog2(dm::DataCount)'(((addr_i[DbgAddressBits-1:3] 326 - DataBaseAddr[DbgAddressBits-1:3]) << 1) 327 + 1'b1)], 328 data_i[$clog2(dm::DataCount)'(((addr_i[DbgAddressBits-1:3] 329 - DataBaseAddr[DbgAddressBits-1:3]) << 1))] 330 }; 331 end 332 333 [ProgBufBaseAddr:ProgBufEndAddr]: begin 334 rdata_d = progbuf[ProgBuf64AddrSize'(addr_i[DbgAddressBits-1:3] - ==> 335 ProgBufBaseAddr[DbgAddressBits-1:3])]; 336 end 337 338 // two slots for abstract command 339 [AbstractCmdBaseAddr:AbstractCmdEndAddr]: begin 340 // return the correct address index 341 rdata_d = abstract_cmd[3'(addr_i[DbgAddressBits-1:3] - ==> 342 AbstractCmdBaseAddr[DbgAddressBits-1:3])]; 343 end 344 // harts are polling for flags here 345 [FlagsBaseAddr:FlagsEndAddr]: begin 346 // release the corresponding hart 347 if (({addr_i[DbgAddressBits-1:3], 3'b0} - FlagsBaseAddr[DbgAddressBits-1:0]) == -8- 348 (DbgAddressBits'(hartsel) & {{(DbgAddressBits-3){1'b1}}, 3'b0})) begin 349 rdata[DbgAddressBits'(hartsel) & DbgAddressBits'(3'b111)] = {6'b0, resume, go}; ==> 350 end MISSING_ELSE ==> 351 rdata_d = rdata; 352 end 353 // Access has to be forwarded to the ROM. The ROM starts at the HaltAddress of the core 354 // e.g.: it immediately jumps to the ROM base address. 355 [RomBaseAddr:RomEndAddr]: begin 356 fwd_rom_d = 1'b1; ==> 357 end 358 default: ; ==> 359 endcase 360 end 361 end MISSING_ELSE ==>

Branches:
-1--2--3--4--5--6--7--8-StatusTests
1 1 HaltedAddr - - - - - Covered T1,T2,T3
1 1 GoingAddr - - - - - Covered T1,T3,T39
1 1 ResumingAddr - - - - - Covered T5,T39,T24
1 1 ExceptionAddr - - - - - Covered T25,T26
1 1 DataBaseAddr DataEndAddr - - - - - Covered T1,T6,T10
1 1 default - - - - - Covered T60,T66,T71
1 0 - WhereToAddr 1 - - - Covered T54,T55
1 0 - WhereToAddr 0 - - - Covered T39,T53,T51
1 0 - WhereToAddr - 1 1 - Covered T56,T57,T58
1 0 - WhereToAddr - 1 0 - Covered T39,T53,T51
1 0 - WhereToAddr - 0 - - Covered T73,T74,T60
1 0 - DataBaseAddr DataEndAddr - - - - Covered T1,T10,T36
1 0 - ProgBufBaseAddr ProgBufEndAddr - - - - Covered T41,T59,T60
1 0 - AbstractCmdBaseAddr AbstractCmdEndAddr - - - - Covered T40,T61,T62
1 0 - FlagsBaseAddr FlagsEndAddr - - - 1 Covered T5,T39,T24
1 0 - FlagsBaseAddr FlagsEndAddr - - - 0 Covered T60,T66,T71
1 0 - RomBaseAddr RomEndAddr - - - - Covered T63,T64
1 0 - default - - - - Covered T60,T66,T71
0 - - - - - - - Covered T1,T2,T3


363 if (ndmreset_i) begin -1- 364 // When harts are reset, they are neither halted nor resuming. 365 halted_d_aligned = '0; ==> 366 resuming_d_aligned = '0; 367 end MISSING_ELSE ==>

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


389 if (req_i) begin -1- 390 unique case (addr_i[DbgAddressBits-1:0]) inside -2- 391 WhereToAddr: err_d = gen_wr_err(we_i, be_i, FullRegMask); ==> 392 HaltedAddr: err_d = gen_wr_err(we_i, be_i, HartSelMask); ==> 393 GoingAddr: err_d = gen_wr_err(we_i, be_i, OneBitMask); ==> 394 ResumingAddr: err_d = gen_wr_err(we_i, be_i, HartSelMask); ==> 395 ExceptionAddr: err_d = gen_wr_err(we_i, be_i, OneBitMask); ==> 396 [DataBaseAddr:DataEndAddr]: err_d = gen_wr_err(we_i, be_i, FullRegMask); ==> 397 [ProgBufBaseAddr:ProgBufEndAddr]: err_d = gen_wr_err(we_i, be_i, FullRegMask); ==> 398 [AbstractCmdBaseAddr:AbstractCmdEndAddr]: err_d = gen_wr_err(we_i, be_i, FullRegMask); ==> 399 [FlagsBaseAddr:FlagsEndAddr]: err_d = gen_wr_err(we_i, be_i, FullRegMask); ==> 400 [RomBaseAddr:RomEndAddr]: err_d = we_i; // Writing ROM area always errors. ==> 401 default: err_d = 1'b1; ==> 402 endcase 403 // Unaligned accesses 404 if (addr_i[$clog2(BeWidth)-1:0] != '0) begin -3- 405 err_d = 1'b1; ==> (Excluded) Exclude Annotation: VC_COV_UNR 406 end MISSING_ELSE ==> 407 end MISSING_ELSE ==>

Branches:
-1--2--3-StatusTestsExclude Annotation
1 WhereToAddr - Covered T39,T53,T51
1 HaltedAddr - Covered T1,T2,T3
1 GoingAddr - Covered T1,T3,T39
1 ResumingAddr - Covered T5,T39,T24
1 ExceptionAddr - Covered T25,T26,T60
1 DataBaseAddr DataEndAddr - Covered T1,T6,T10
1 ProgBufBaseAddr ProgBufEndAddr - Covered T41,T59,T60
1 AbstractCmdBaseAddr AbstractCmdEndAddr - Covered T40,T61,T62
1 FlagsBaseAddr FlagsEndAddr - Covered T5,T39,T24
1 RomBaseAddr RomEndAddr - Covered T63,T64,T60
1 default - Covered T60,T66,T71
1 - 1 Excluded VC_COV_UNR
1 - 0 Covered T1,T2,T3
0 - - Covered T1,T2,T3


411 if (!rst_ni) begin -1- 412 err_q <= 1'b0; ==> 413 end else begin 414 err_q <= err_d; ==>

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


440 unique case (cmd_i.cmdtype) -1- 441 // -------------------- 442 // Access Register 443 // -------------------- 444 dm::AccessRegister: begin 445 if (32'(ac_ar.aarsize) < MaxAar && ac_ar.transfer && ac_ar.write) begin -2- 446 // store a0 in dscratch1 447 abstract_cmd[0][31:0] = HasSndScratch ? dm::csrw(dm::CSR_DSCRATCH1, 5'd10) : dm::nop(); 448 // this range is reserved 449 if (ac_ar.regno[15:14] != '0) begin -3- 450 abstract_cmd[0][31:0] = dm::ebreak(); // we leave asap ==> 451 unsupported_command = 1'b1; 452 // A0 access needs to be handled separately, as we use A0 to load 453 // the DM address offset need to access DSCRATCH1 in this case 454 end else if (HasSndScratch && ac_ar.regno[12] && (!ac_ar.regno[5]) && -4- 455 (ac_ar.regno[4:0] == 5'd10)) begin 456 // store s0 in dscratch 457 abstract_cmd[2][31:0] = dm::csrw(dm::CSR_DSCRATCH0, 5'd8); ==> 458 // load from data register 459 abstract_cmd[2][63:32] = dm::load(ac_ar.aarsize, 5'd8, LoadBaseAddr, dm::DataAddr); 460 // and store it in the corresponding CSR 461 abstract_cmd[3][31:0] = dm::csrw(dm::CSR_DSCRATCH1, 5'd8); 462 // restore s0 again from dscratch 463 abstract_cmd[3][63:32] = dm::csrr(dm::CSR_DSCRATCH0, 5'd8); 464 // GPR/FPR access 465 end else if (ac_ar.regno[12]) begin -5- 466 // determine whether we want to access the floating point register or not 467 if (ac_ar.regno[5]) begin -6- 468 abstract_cmd[2][31:0] = ==> 469 dm::float_load(ac_ar.aarsize, ac_ar.regno[4:0], LoadBaseAddr, dm::DataAddr); 470 end else begin 471 abstract_cmd[2][31:0] = ==> 472 dm::load(ac_ar.aarsize, ac_ar.regno[4:0], LoadBaseAddr, dm::DataAddr); 473 end 474 // CSR access 475 end else begin 476 // data register to CSR 477 // store s0 in dscratch 478 abstract_cmd[2][31:0] = dm::csrw(dm::CSR_DSCRATCH0, 5'd8); ==> 479 // load from data register 480 abstract_cmd[2][63:32] = dm::load(ac_ar.aarsize, 5'd8, LoadBaseAddr, dm::DataAddr); 481 // and store it in the corresponding CSR 482 abstract_cmd[3][31:0] = dm::csrw(dm::csr_reg_t'(ac_ar.regno[11:0]), 5'd8); 483 // restore s0 again from dscratch 484 abstract_cmd[3][63:32] = dm::csrr(dm::CSR_DSCRATCH0, 5'd8); 485 end 486 end else if (32'(ac_ar.aarsize) < MaxAar && ac_ar.transfer && !ac_ar.write) begin -7- 487 // store a0 in dscratch1 488 abstract_cmd[0][31:0] = HasSndScratch ? 489 dm::csrw(dm::CSR_DSCRATCH1, LoadBaseAddr) : 490 dm::nop(); 491 // this range is reserved 492 if (ac_ar.regno[15:14] != '0) begin -8- 493 abstract_cmd[0][31:0] = dm::ebreak(); // we leave asap ==> 494 unsupported_command = 1'b1; 495 // A0 access needs to be handled separately, as we use A0 to load 496 // the DM address offset need to access DSCRATCH1 in this case 497 end else if (HasSndScratch && ac_ar.regno[12] && (!ac_ar.regno[5]) && -9- 498 (ac_ar.regno[4:0] == 5'd10)) begin 499 // store s0 in dscratch 500 abstract_cmd[2][31:0] = dm::csrw(dm::CSR_DSCRATCH0, 5'd8); ==> 501 // read value from CSR into s0 502 abstract_cmd[2][63:32] = dm::csrr(dm::CSR_DSCRATCH1, 5'd8); 503 // and store s0 into data section 504 abstract_cmd[3][31:0] = dm::store(ac_ar.aarsize, 5'd8, LoadBaseAddr, dm::DataAddr); 505 // restore s0 again from dscratch 506 abstract_cmd[3][63:32] = dm::csrr(dm::CSR_DSCRATCH0, 5'd8); 507 // GPR/FPR access 508 end else if (ac_ar.regno[12]) begin -10- 509 // determine whether we want to access the floating point register or not 510 if (ac_ar.regno[5]) begin -11- 511 abstract_cmd[2][31:0] = ==> 512 dm::float_store(ac_ar.aarsize, ac_ar.regno[4:0], LoadBaseAddr, dm::DataAddr); 513 end else begin 514 abstract_cmd[2][31:0] = ==> 515 dm::store(ac_ar.aarsize, ac_ar.regno[4:0], LoadBaseAddr, dm::DataAddr); 516 end 517 // CSR access 518 end else begin 519 // CSR register to data 520 // store s0 in dscratch 521 abstract_cmd[2][31:0] = dm::csrw(dm::CSR_DSCRATCH0, 5'd8); ==> 522 // read value from CSR into s0 523 abstract_cmd[2][63:32] = dm::csrr(dm::csr_reg_t'(ac_ar.regno[11:0]), 5'd8); 524 // and store s0 into data section 525 abstract_cmd[3][31:0] = dm::store(ac_ar.aarsize, 5'd8, LoadBaseAddr, dm::DataAddr); 526 // restore s0 again from dscratch 527 abstract_cmd[3][63:32] = dm::csrr(dm::CSR_DSCRATCH0, 5'd8); 528 end 529 end else if (32'(ac_ar.aarsize) >= MaxAar || ac_ar.aarpostincrement == 1'b1) begin -12- 530 // this should happend when e.g. ac_ar.aarsize >= MaxAar 531 // Openocd will try to do an access with aarsize=64 bits 532 // first before falling back to 32 bits. 533 abstract_cmd[0][31:0] = dm::ebreak(); // we leave asap ==> 534 unsupported_command = 1'b1; 535 end MISSING_ELSE ==> 536 537 // Check whether we need to execute the program buffer. When we 538 // get an unsupported command we really should abort instead of 539 // still trying to execute the program buffer, makes it easier 540 // for the debugger to recover 541 if (ac_ar.postexec && !unsupported_command) begin -13- 542 // issue a nop, we will automatically run into the program buffer 543 abstract_cmd[4][63:32] = dm::nop(); ==> 544 end MISSING_ELSE ==> 545 end 546 // not supported at the moment 547 // dm::QuickAccess:; 548 // dm::AccessMemory:; 549 default: begin 550 abstract_cmd[0][31:0] = dm::ebreak(); ==>

Branches:
-1--2--3--4--5--6--7--8--9--10--11--12--13-StatusTests
AccessRegister 1 1 - - - - - - - - - - Not Covered
AccessRegister 1 0 1 - - - - - - - - - Not Covered
AccessRegister 1 0 0 1 1 - - - - - - - Not Covered
AccessRegister 1 0 0 1 0 - - - - - - - Not Covered
AccessRegister 1 0 0 0 - - - - - - - - Covered T39,T40,T61
AccessRegister 0 - - - - 1 1 - - - - - Not Covered
AccessRegister 0 - - - - 1 0 1 - - - - Not Covered
AccessRegister 0 - - - - 1 0 0 1 1 - - Not Covered
AccessRegister 0 - - - - 1 0 0 1 0 - - Not Covered
AccessRegister 0 - - - - 1 0 0 0 - - - Covered T65,T30,T8
AccessRegister 0 - - - - 0 - - - - 1 - Not Covered
AccessRegister 0 - - - - 0 - - - - 0 - Covered T1,T2,T3
AccessRegister - - - - - - - - - - - 1 Covered T56,T57,T58
AccessRegister - - - - - - - - - - - 0 Covered T1,T2,T3
default - - - - - - - - - - - - Covered T2,T50,T51


587 if (!rst_ni) begin -1- 588 fwd_rom_q <= 1'b0; ==> 589 rdata_q <= '0; 590 state_q <= Idle; 591 word_enable32_q <= 1'b0; 592 end else begin 593 fwd_rom_q <= fwd_rom_d; ==>

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


601 if (!rst_ni) begin -1- 602 halted_q <= 1'b0; ==> 603 resuming_q <= 1'b0; 604 end else begin 605 halted_q <= SelectableHarts & halted_d; ==>

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

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