Line Coverage for Module :
dm_mem
| Line No. | Total | Covered | Percent |
TOTAL | | 190 | 167 | 87.89 |
CONT_ASSIGN | 112 | 1 | 1 | 100.00 |
CONT_ASSIGN | 113 | 1 | 1 | 100.00 |
CONT_ASSIGN | 120 | 1 | 1 | 100.00 |
CONT_ASSIGN | 121 | 1 | 1 | 100.00 |
CONT_ASSIGN | 122 | 1 | 1 | 100.00 |
CONT_ASSIGN | 124 | 1 | 1 | 100.00 |
CONT_ASSIGN | 125 | 1 | 1 | 100.00 |
CONT_ASSIGN | 126 | 1 | 1 | 100.00 |
CONT_ASSIGN | 127 | 1 | 1 | 100.00 |
CONT_ASSIGN | 135 | 1 | 1 | 100.00 |
CONT_ASSIGN | 136 | 1 | 1 | 100.00 |
CONT_ASSIGN | 137 | 1 | 1 | 100.00 |
CONT_ASSIGN | 138 | 1 | 1 | 100.00 |
CONT_ASSIGN | 141 | 1 | 1 | 100.00 |
ALWAYS | 148 | 37 | 37 | 100.00 |
CONT_ASSIGN | 226 | 1 | 1 | 100.00 |
CONT_ASSIGN | 231 | 1 | 1 | 100.00 |
ALWAYS | 239 | 48 | 46 | 95.83 |
ROUTINE | 375 | 1 | 1 | 100.00 |
ALWAYS | 388 | 15 | 14 | 93.33 |
ALWAYS | 411 | 3 | 3 | 100.00 |
CONT_ASSIGN | 418 | 1 | 1 | 100.00 |
ALWAYS | 422 | 54 | 34 | 62.96 |
CONT_ASSIGN | 557 | 1 | 1 | 100.00 |
ALWAYS | 587 | 9 | 9 | 100.00 |
ALWAYS | 601 | 5 | 5 | 100.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: T1 T12 T46
121 1/1 assign haltreq_aligned = NrHartsAligned'(haltreq_i);
Tests: T1 T3 T12
122 1/1 assign resumereq_wdata_aligned = NrHartsAligned'(resumereq_i);
Tests: T1 T12 T46
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 T3 T12
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: T3 T12 T28
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 T41 T55
164 1/1 cmderror_o = dm::CmdErrorHaltResume;
Tests: T2 T41 T55
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: T1 T12 T46
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: T3 T12 T28
177 1/1 go = 1'b1;
Tests: T3 T12 T28
178 // the thread is now executing the command, track its state
179 1/1 if (going) begin
Tests: T3 T12 T28
180 1/1 state_d = CmdExecuting;
Tests: T3 T12 T28
181 end
MISSING_ELSE
182 end
183
184 Resume: begin
185 1/1 cmdbusy_o = 1'b1;
Tests: T1 T12 T46
186 1/1 resume = 1'b1;
Tests: T1 T12 T46
187 1/1 if (resuming_q_aligned[hartsel]) begin
Tests: T1 T12 T46
188 1/1 state_d = Idle;
Tests: T1 T12 T46
189 end
MISSING_ELSE
190 end
191
192 CmdExecuting: begin
193 1/1 cmdbusy_o = 1'b1;
Tests: T3 T12 T28
194 1/1 go = 1'b0;
Tests: T3 T12 T28
195 // wait until the hart has halted again
196 1/1 if (halted_aligned[hartsel]) begin
Tests: T3 T12 T28
197 1/1 state_d = Idle;
Tests: T3 T12 T28
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: T41 T55 T38
208 1/1 cmderror_o = dm::CmdErrNotSupported;
Tests: T41 T55 T38
209 end
MISSING_ELSE
210
211 1/1 if (exception) begin
Tests: T1 T2 T3
212 1/1 cmderror_valid_o = 1'b1;
Tests: T29 T30
213 1/1 cmderror_o = dm::CmdErrorException;
Tests: T29 T30
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: T4 T43 T9
219 1/1 go = 1'b0;
Tests: T4 T43 T9
220 1/1 resume = 1'b0;
Tests: T4 T43 T9
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: T1 T12 T46
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 T3 T12
260 1/1 unique case (addr_i[DbgAddressBits-1:0]) inside
Tests: T1 T3 T12
261 HaltedAddr: begin
262 1/1 halted_aligned[wdata_hartsel] = 1'b1;
Tests: T1 T3 T12
263 1/1 halted_d_aligned[wdata_hartsel] = 1'b1;
Tests: T1 T3 T12
264 end
265 GoingAddr: begin
266 1/1 going = 1'b1;
Tests: T3 T12 T28
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: T1 T12 T46
271 // set the resuming flag which needs to be cleared by the debugger
272 1/1 resuming_d_aligned[wdata_hartsel] = 1'b1;
Tests: T1 T12 T46
273 end
274 // an exception occurred during execution
275 1/1 ExceptionAddr: exception = 1'b1;
Tests: T29 T30
276 // core can write data registers
277 [DataBaseAddr:DataEndAddr]: begin
278 1/1 data_valid_o = 1'b1;
Tests: T4 T42 T43
279 1/1 for (int unsigned dc = 0; dc < dm::DataCount; dc++) begin
Tests: T4 T42 T43
280 1/1 if ((addr_i[DbgAddressBits-1:2] - DataBaseAddr[DbgAddressBits-1:2]) == dc) begin
Tests: T4 T42 T43
281 1/1 for (int unsigned i = 0; i < $bits(be_i); i++) begin
Tests: T4 T42 T43
282 1/1 if (be_i[i]) begin
Tests: T4 T42 T43
283 1/1 if (i>3) begin // for upper 32bit data write (only used for BusWidth == 64)
Tests: T4 T42 T43
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: T4 T42 T43
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 T12 T50
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: T12 T46 T56
306 1/1 rdata_d = {32'b0, dm::jal('0, 21'(dm::ResumeAddress[11:0])-21'(WhereToAddr))};
Tests: T36
307 end
MISSING_ELSE
308
309 // there is a command active so jump there
310 1/1 if (cmdbusy_o) begin
Tests: T12 T46 T56
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: T12 T46 T56
314 !ac_ar.transfer && ac_ar.postexec) begin
315 1/1 rdata_d = {32'b0, dm::jal('0, 21'(ProgBufBaseAddr)-21'(WhereToAddr))};
Tests: T57 T58 T59
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: T12 T46 T56
319 end
320 end
MISSING_ELSE
321 end
322
323 [DataBaseAddr:DataEndAddr]: begin
324 1/1 rdata_d = {
Tests: T4 T43 T44
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: T60 T61 T62
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: T47 T63 T45
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: T1 T12 T46
348 (DbgAddressBits'(hartsel) & {{(DbgAddressBits-3){1'b1}}, 3'b0})) begin
349 1/1 rdata[DbgAddressBits'(hartsel) & DbgAddressBits'(3'b111)] = {6'b0, resume, go};
Tests: T1 T12 T46
350 end
MISSING_ELSE
351 1/1 rdata_d = rdata;
Tests: T1 T12 T46
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: T50 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: T4 T43 T9
366 1/1 resuming_d_aligned = '0;
Tests: T4 T43 T9
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 T3 T12
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 T3 T12
391 1/1 WhereToAddr: err_d = gen_wr_err(we_i, be_i, FullRegMask);
Tests: T12 T46 T56
392 1/1 HaltedAddr: err_d = gen_wr_err(we_i, be_i, HartSelMask);
Tests: T1 T3 T12
393 1/1 GoingAddr: err_d = gen_wr_err(we_i, be_i, OneBitMask);
Tests: T3 T12 T28
394 1/1 ResumingAddr: err_d = gen_wr_err(we_i, be_i, HartSelMask);
Tests: T1 T12 T46
395 1/1 ExceptionAddr: err_d = gen_wr_err(we_i, be_i, OneBitMask);
Tests: T29 T30 T62
396 1/1 [DataBaseAddr:DataEndAddr]: err_d = gen_wr_err(we_i, be_i, FullRegMask);
Tests: T4 T42 T43
397 1/1 [ProgBufBaseAddr:ProgBufEndAddr]: err_d = gen_wr_err(we_i, be_i, FullRegMask);
Tests: T60 T61 T62
398 1/1 [AbstractCmdBaseAddr:AbstractCmdEndAddr]: err_d = gen_wr_err(we_i, be_i, FullRegMask);
Tests: T47 T63 T45
399 1/1 [FlagsBaseAddr:FlagsEndAddr]: err_d = gen_wr_err(we_i, be_i, FullRegMask);
Tests: T1 T12 T46
400 1/1 [RomBaseAddr:RomEndAddr]: err_d = we_i; // Writing ROM area always errors.
Tests: T50 T64 T62
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 T3 T12
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: T47 T63 T65
448 // this range is reserved
449 1/1 if (ac_ar.regno[15:14] != '0) begin
Tests: T47 T63 T65
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: T47 T63 T65
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: T47 T63 T65
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: T47 T63 T65
479 // load from data register
480 1/1 abstract_cmd[2][63:32] = dm::load(ac_ar.aarsize, 5'd8, LoadBaseAddr, dm::DataAddr);
Tests: T47 T63 T65
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: T47 T63 T65
483 // restore s0 again from dscratch
484 1/1 abstract_cmd[3][63:32] = dm::csrr(dm::CSR_DSCRATCH0, 5'd8);
Tests: T47 T63 T65
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: T12 T46 T66
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: T12 T46 T66
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: T12 T46 T66
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: T12 T46 T66
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: T12 T46 T66
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: T12 T46 T66
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: T12 T46 T66
526 // restore s0 again from dscratch
527 1/1 abstract_cmd[3][63:32] = dm::csrr(dm::CSR_DSCRATCH0, 5'd8);
Tests: T12 T46 T66
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: T65 T44 T57
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
| Total | Covered | Percent |
Conditions | 62 | 42 | 67.74 |
Logical | 62 | 42 | 67.74 |
Non-Logical | 0 | 0 | |
Event | 0 | 0 | |
LINE 158
EXPRESSION (cmd_valid_i && halted_q_aligned[hartsel] && ((!unsupported_command)))
-----1----- ------------2------------ ------------3-----------
-1- | -2- | -3- | Status | Tests |
0 | 1 | 1 | Covered | T1,T3,T12 |
1 | 0 | 1 | Covered | T2,T67 |
1 | 1 | 0 | Covered | T41,T55,T38 |
1 | 1 | 1 | Covered | T3,T12,T28 |
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- | Status | Tests |
0 | 1 | 1 | 1 | Covered | T1,T12,T46 |
1 | 0 | 1 | 1 | Not Covered | |
1 | 1 | 0 | 1 | Covered | T57,T11,T68 |
1 | 1 | 1 | 0 | Covered | T12,T46,T56 |
1 | 1 | 1 | 1 | Covered | T1,T12,T46 |
LINE 206
EXPRESSION (unsupported_command && cmd_valid_i)
---------1--------- -----2-----
-1- | -2- | Status | Tests |
0 | 1 | Covered | T2,T3,T12 |
1 | 0 | Covered | T41,T55,T38 |
1 | 1 | Covered | T41,T55,T38 |
LINE 226
EXPRESSION (fwd_rom_q ? rom_rdata : rdata_q)
----1----
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T50,T64 |
LINE 231
EXPRESSION (word_enable32_q ? word_mux[32+:32] : word_mux[0+:32])
-------1-------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T17,T12,T50 |
LINE 280
EXPRESSION ((addr_i[(DbgAddressBits - 1):2] - DataBaseAddr[(DbgAddressBits - 1):2]) == dc)
---------------------------------------1---------------------------------------
-1- | Status | Tests |
0 | Covered | T4,T42,T43 |
1 | Covered | T4,T42,T43 |
LINE 313
EXPRESSION ((cmd_i.cmdtype == AccessRegister) && ((!ac_ar.transfer)) && ac_ar.postexec)
----------------1---------------- ---------2--------- -------3------
-1- | -2- | -3- | Status | Tests |
0 | 1 | 1 | Not Covered | |
1 | 0 | 1 | Covered | T65,T44,T69 |
1 | 1 | 0 | Covered | T56,T70,T39 |
1 | 1 | 1 | Covered | T57,T58,T59 |
LINE 313
SUB-EXPRESSION (cmd_i.cmdtype == AccessRegister)
----------------1----------------
-1- | Status | Tests |
0 | Not Covered | |
1 | Covered | T12,T46,T56 |
LINE 347
EXPRESSION (({addr_i[(DbgAddressBits - 1):3], 3'b0} - FlagsBaseAddr[(DbgAddressBits - 1):0]) == (12'(hartsel) & {{(DbgAddressBits - 3) {1'b1}}, 3'b0}))
----------------------------------------------------------------------1---------------------------------------------------------------------
-1- | Status | Tests |
0 | Covered | T62,T36,T34 |
1 | Covered | T1,T12,T46 |
LINE 445
EXPRESSION ((32'(ac_ar.aarsize) < MaxAar) && ac_ar.transfer && ac_ar.write)
--------------1-------------- -------2------ -----3-----
-1- | -2- | -3- | Status | Tests |
0 | 1 | 1 | Not Covered | |
1 | 0 | 1 | Covered | T70,T57,T58 |
1 | 1 | 0 | Covered | T12,T46,T66 |
1 | 1 | 1 | Covered | T47,T63,T65 |
LINE 449
EXPRESSION (ac_ar.regno[15:14] != '0)
-------------1------------
-1- | Status | Tests |
0 | Covered | T47,T63,T65 |
1 | Not 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- | Status | Tests |
- | 0 | 1 | 1 | Not Covered | |
- | 1 | 0 | 1 | Not Covered | |
- | 1 | 1 | 0 | Not Covered | |
- | 1 | 1 | 1 | Not Covered | |
LINE 454
SUB-EXPRESSION (ac_ar.regno[4:0] == 5'd10)
-------------1-------------
-1- | Status | Tests |
0 | Covered | T47,T63,T65 |
1 | Not Covered | |
LINE 486
EXPRESSION ((32'(ac_ar.aarsize) < MaxAar) && ac_ar.transfer && ((!ac_ar.write)))
--------------1-------------- -------2------ --------3-------
-1- | -2- | -3- | Status | Tests |
0 | 1 | 1 | Not Covered | |
1 | 0 | 1 | Covered | T1,T2,T3 |
1 | 1 | 0 | Not Covered | |
1 | 1 | 1 | Covered | T12,T46,T66 |
LINE 492
EXPRESSION (ac_ar.regno[15:14] != '0)
-------------1------------
-1- | Status | Tests |
0 | Covered | T12,T46,T66 |
1 | Not 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- | Status | Tests |
- | 0 | 1 | 1 | Covered | T69 |
- | 1 | 0 | 1 | Not Covered | |
- | 1 | 1 | 0 | Not Covered | |
- | 1 | 1 | 1 | Not Covered | |
LINE 497
SUB-EXPRESSION (ac_ar.regno[4:0] == 5'd10)
-------------1-------------
-1- | Status | Tests |
0 | Covered | T12,T46,T66 |
1 | Covered | T69 |
LINE 529
EXPRESSION ((32'(ac_ar.aarsize) >= MaxAar) || (ac_ar.aarpostincrement == 1'b1))
---------------1-------------- ----------------2---------------
-1- | -2- | Status | Tests |
0 | 0 | Covered | T1,T2,T3 |
0 | 1 | Not Covered | |
1 | 0 | Not Covered | |
LINE 529
SUB-EXPRESSION (ac_ar.aarpostincrement == 1'b1)
----------------1---------------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Not Covered | |
LINE 541
EXPRESSION (ac_ar.postexec && ((!unsupported_command)))
-------1------ ------------2-----------
-1- | -2- | Status | Tests |
0 | 1 | Covered | T1,T2,T3 |
1 | 0 | Not Covered | |
1 | 1 | Covered | T65,T44,T57 |
LINE 605
EXPRESSION (SelectableHarts & halted_d)
-------1------- ----2---
-1- | -2- | Status | Tests |
- | 0 | Covered | T1,T2,T3 |
- | 1 | Covered | T1,T3,T12 |
LINE 606
EXPRESSION (SelectableHarts & resuming_d)
-------1------- -----2----
-1- | -2- | Status | Tests |
- | 0 | Covered | T1,T2,T3 |
- | 1 | Covered | T1,T12,T46 |
FSM Coverage for Module :
dm_mem
Summary for FSM :: state_q
| Total | Covered | Percent | |
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
states | Line No. | Covered | Tests |
CmdExecuting |
180 |
Covered |
T3,T12,T28 |
Go |
160 |
Covered |
T3,T12,T28 |
Idle |
188 |
Covered |
T1,T2,T3 |
Resume |
170 |
Covered |
T1,T12,T46 |
transitions | Line No. | Covered | Tests |
CmdExecuting->Idle |
197 |
Covered |
T3,T12,T28 |
Go->CmdExecuting |
180 |
Covered |
T3,T12,T28 |
Go->Idle |
218 |
Covered |
T71 |
Idle->Go |
160 |
Covered |
T3,T12,T28 |
Idle->Resume |
170 |
Covered |
T1,T12,T46 |
Resume->Idle |
188 |
Covered |
T1,T12,T46 |
Branch Coverage for Module :
dm_mem
| Line No. | Total | Covered | Percent |
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- | Status | Tests |
1 |
Covered |
T50,T64 |
0 |
Covered |
T1,T2,T3 |
231 assign rdata_o = (word_enable32_q) ? word_mux[32 +: 32] : word_mux[0 +: 32];
-1-
==>
==>
Branches:
-1- | Status | Tests |
1 |
Covered |
T17,T12,T50 |
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- | Status | Tests |
Idle |
1 |
- |
- |
- |
- |
- |
Covered |
T3,T12,T28 |
Idle |
0 |
1 |
- |
- |
- |
- |
Covered |
T2,T41,T55 |
Idle |
0 |
0 |
- |
- |
- |
- |
Covered |
T1,T2,T3 |
Idle |
- |
- |
1 |
- |
- |
- |
Covered |
T1,T12,T46 |
Idle |
- |
- |
0 |
- |
- |
- |
Covered |
T1,T2,T3 |
Go |
- |
- |
- |
1 |
- |
- |
Covered |
T3,T12,T28 |
Go |
- |
- |
- |
0 |
- |
- |
Covered |
T3,T12,T28 |
Resume |
- |
- |
- |
- |
1 |
- |
Covered |
T1,T12,T46 |
Resume |
- |
- |
- |
- |
0 |
- |
Covered |
T1,T12,T46 |
CmdExecuting |
- |
- |
- |
- |
- |
1 |
Covered |
T3,T12,T28 |
CmdExecuting |
- |
- |
- |
- |
- |
0 |
Covered |
T3,T12,T28 |
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- | Status | Tests |
1 |
Covered |
T41,T55,T38 |
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- | Status | Tests |
1 |
Covered |
T29,T30 |
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- | Status | Tests |
1 |
Covered |
T4,T43,T9 |
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- | Status | Tests |
1 |
Covered |
T1,T12,T46 |
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- | Status | Tests |
1 |
1 |
HaltedAddr |
- |
- |
- |
- |
- |
Covered |
T1,T3,T12 |
1 |
1 |
GoingAddr |
- |
- |
- |
- |
- |
Covered |
T3,T12,T28 |
1 |
1 |
ResumingAddr |
- |
- |
- |
- |
- |
Covered |
T1,T12,T46 |
1 |
1 |
ExceptionAddr |
- |
- |
- |
- |
- |
Covered |
T29,T30 |
1 |
1 |
DataBaseAddr DataEndAddr |
- |
- |
- |
- |
- |
Covered |
T4,T42,T43 |
1 |
1 |
default |
- |
- |
- |
- |
- |
Covered |
T62,T36,T34 |
1 |
0 |
- |
WhereToAddr |
1 |
- |
- |
- |
Covered |
T36 |
1 |
0 |
- |
WhereToAddr |
0 |
- |
- |
- |
Covered |
T12,T46,T56 |
1 |
0 |
- |
WhereToAddr |
- |
1 |
1 |
- |
Covered |
T57,T58,T59 |
1 |
0 |
- |
WhereToAddr |
- |
1 |
0 |
- |
Covered |
T12,T46,T56 |
1 |
0 |
- |
WhereToAddr |
- |
0 |
- |
- |
Covered |
T72,T73,T62 |
1 |
0 |
- |
DataBaseAddr DataEndAddr |
- |
- |
- |
- |
Covered |
T4,T43,T44 |
1 |
0 |
- |
ProgBufBaseAddr ProgBufEndAddr |
- |
- |
- |
- |
Covered |
T60,T61,T62 |
1 |
0 |
- |
AbstractCmdBaseAddr AbstractCmdEndAddr |
- |
- |
- |
- |
Covered |
T47,T63,T45 |
1 |
0 |
- |
FlagsBaseAddr FlagsEndAddr |
- |
- |
- |
1 |
Covered |
T1,T12,T46 |
1 |
0 |
- |
FlagsBaseAddr FlagsEndAddr |
- |
- |
- |
0 |
Covered |
T62,T36,T34 |
1 |
0 |
- |
RomBaseAddr RomEndAddr |
- |
- |
- |
- |
Covered |
T50,T64 |
1 |
0 |
- |
default |
- |
- |
- |
- |
Covered |
T62,T36,T34 |
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- | Status | Tests |
1 |
Covered |
T4,T43,T9 |
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- | Status | Tests |
1 |
WhereToAddr |
- |
Covered |
T12,T46,T56 |
1 |
HaltedAddr |
- |
Covered |
T1,T3,T12 |
1 |
GoingAddr |
- |
Covered |
T3,T12,T28 |
1 |
ResumingAddr |
- |
Covered |
T1,T12,T46 |
1 |
ExceptionAddr |
- |
Covered |
T29,T30,T62 |
1 |
DataBaseAddr DataEndAddr |
- |
Covered |
T4,T42,T43 |
1 |
ProgBufBaseAddr ProgBufEndAddr |
- |
Covered |
T60,T61,T62 |
1 |
AbstractCmdBaseAddr AbstractCmdEndAddr |
- |
Covered |
T47,T63,T45 |
1 |
FlagsBaseAddr FlagsEndAddr |
- |
Covered |
T1,T12,T46 |
1 |
RomBaseAddr RomEndAddr |
- |
Covered |
T50,T64,T62 |
1 |
default |
- |
Covered |
T62,T36,T34 |
1 |
- |
1 |
Not Covered |
|
1 |
- |
0 |
Covered |
T1,T3,T12 |
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- | Status | Tests |
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- | Status | Tests |
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 |
T47,T63,T65 |
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 |
T12,T46,T66 |
AccessRegister |
0 |
- |
- |
- |
- |
0 |
- |
- |
- |
- |
1 |
- |
Not Covered |
|
AccessRegister |
0 |
- |
- |
- |
- |
0 |
- |
- |
- |
- |
0 |
- |
Covered |
T1,T2,T3 |
AccessRegister |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
Covered |
T65,T44,T57 |
AccessRegister |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
0 |
Covered |
T1,T2,T3 |
default |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T41,T55,T38 |
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- | Status | Tests |
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- | Status | Tests |
1 |
Covered |
T1,T2,T3 |
0 |
Covered |
T1,T2,T3 |
Line Coverage for Instance : tb.dut.u_dm_top.i_dm_mem
| Line No. | Total | Covered | Percent |
TOTAL | | 187 | 167 | 89.30 |
CONT_ASSIGN | 112 | 1 | 1 | 100.00 |
CONT_ASSIGN | 113 | 1 | 1 | 100.00 |
CONT_ASSIGN | 120 | 1 | 1 | 100.00 |
CONT_ASSIGN | 121 | 1 | 1 | 100.00 |
CONT_ASSIGN | 122 | 1 | 1 | 100.00 |
CONT_ASSIGN | 124 | 1 | 1 | 100.00 |
CONT_ASSIGN | 125 | 1 | 1 | 100.00 |
CONT_ASSIGN | 126 | 1 | 1 | 100.00 |
CONT_ASSIGN | 127 | 1 | 1 | 100.00 |
CONT_ASSIGN | 135 | 1 | 1 | 100.00 |
CONT_ASSIGN | 136 | 1 | 1 | 100.00 |
CONT_ASSIGN | 137 | 1 | 1 | 100.00 |
CONT_ASSIGN | 138 | 1 | 1 | 100.00 |
CONT_ASSIGN | 141 | 1 | 1 | 100.00 |
ALWAYS | 148 | 37 | 37 | 100.00 |
CONT_ASSIGN | 226 | 1 | 1 | 100.00 |
CONT_ASSIGN | 231 | 1 | 1 | 100.00 |
ALWAYS | 239 | 46 | 46 | 100.00 |
ROUTINE | 375 | 1 | 1 | 100.00 |
ALWAYS | 388 | 14 | 14 | 100.00 |
ALWAYS | 411 | 3 | 3 | 100.00 |
CONT_ASSIGN | 418 | 1 | 1 | 100.00 |
ALWAYS | 422 | 54 | 34 | 62.96 |
CONT_ASSIGN | 557 | 1 | 1 | 100.00 |
ALWAYS | 587 | 9 | 9 | 100.00 |
ALWAYS | 601 | 5 | 5 | 100.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: T1 T12 T46
121 1/1 assign haltreq_aligned = NrHartsAligned'(haltreq_i);
Tests: T1 T3 T12
122 1/1 assign resumereq_wdata_aligned = NrHartsAligned'(resumereq_i);
Tests: T1 T12 T46
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 T3 T12
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: T3 T12 T28
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 T41 T55
164 1/1 cmderror_o = dm::CmdErrorHaltResume;
Tests: T2 T41 T55
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: T1 T12 T46
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: T3 T12 T28
177 1/1 go = 1'b1;
Tests: T3 T12 T28
178 // the thread is now executing the command, track its state
179 1/1 if (going) begin
Tests: T3 T12 T28
180 1/1 state_d = CmdExecuting;
Tests: T3 T12 T28
181 end
MISSING_ELSE
182 end
183
184 Resume: begin
185 1/1 cmdbusy_o = 1'b1;
Tests: T1 T12 T46
186 1/1 resume = 1'b1;
Tests: T1 T12 T46
187 1/1 if (resuming_q_aligned[hartsel]) begin
Tests: T1 T12 T46
188 1/1 state_d = Idle;
Tests: T1 T12 T46
189 end
MISSING_ELSE
190 end
191
192 CmdExecuting: begin
193 1/1 cmdbusy_o = 1'b1;
Tests: T3 T12 T28
194 1/1 go = 1'b0;
Tests: T3 T12 T28
195 // wait until the hart has halted again
196 1/1 if (halted_aligned[hartsel]) begin
Tests: T3 T12 T28
197 1/1 state_d = Idle;
Tests: T3 T12 T28
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: T41 T55 T38
208 1/1 cmderror_o = dm::CmdErrNotSupported;
Tests: T41 T55 T38
209 end
MISSING_ELSE
210
211 1/1 if (exception) begin
Tests: T1 T2 T3
212 1/1 cmderror_valid_o = 1'b1;
Tests: T29 T30
213 1/1 cmderror_o = dm::CmdErrorException;
Tests: T29 T30
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: T4 T43 T9
219 1/1 go = 1'b0;
Tests: T4 T43 T9
220 1/1 resume = 1'b0;
Tests: T4 T43 T9
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: T1 T12 T46
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 T3 T12
260 1/1 unique case (addr_i[DbgAddressBits-1:0]) inside
Tests: T1 T3 T12
261 HaltedAddr: begin
262 1/1 halted_aligned[wdata_hartsel] = 1'b1;
Tests: T1 T3 T12
263 1/1 halted_d_aligned[wdata_hartsel] = 1'b1;
Tests: T1 T3 T12
264 end
265 GoingAddr: begin
266 1/1 going = 1'b1;
Tests: T3 T12 T28
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: T1 T12 T46
271 // set the resuming flag which needs to be cleared by the debugger
272 1/1 resuming_d_aligned[wdata_hartsel] = 1'b1;
Tests: T1 T12 T46
273 end
274 // an exception occurred during execution
275 1/1 ExceptionAddr: exception = 1'b1;
Tests: T29 T30
276 // core can write data registers
277 [DataBaseAddr:DataEndAddr]: begin
278 1/1 data_valid_o = 1'b1;
Tests: T4 T42 T43
279 1/1 for (int unsigned dc = 0; dc < dm::DataCount; dc++) begin
Tests: T4 T42 T43
280 1/1 if ((addr_i[DbgAddressBits-1:2] - DataBaseAddr[DbgAddressBits-1:2]) == dc) begin
Tests: T4 T42 T43
281 1/1 for (int unsigned i = 0; i < $bits(be_i); i++) begin
Tests: T4 T42 T43
282 1/1 if (be_i[i]) begin
Tests: T4 T42 T43
283 1/1 if (i>3) begin // for upper 32bit data write (only used for BusWidth == 64)
Tests: T4 T42 T43
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: T4 T42 T43
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 T12 T50
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: T12 T46 T56
306 1/1 rdata_d = {32'b0, dm::jal('0, 21'(dm::ResumeAddress[11:0])-21'(WhereToAddr))};
Tests: T36
307 end
MISSING_ELSE
308
309 // there is a command active so jump there
310 1/1 if (cmdbusy_o) begin
Tests: T12 T46 T56
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: T12 T46 T56
314 !ac_ar.transfer && ac_ar.postexec) begin
315 1/1 rdata_d = {32'b0, dm::jal('0, 21'(ProgBufBaseAddr)-21'(WhereToAddr))};
Tests: T57 T58 T59
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: T12 T46 T56
319 end
320 end
MISSING_ELSE
321 end
322
323 [DataBaseAddr:DataEndAddr]: begin
324 1/1 rdata_d = {
Tests: T4 T43 T44
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: T60 T61 T62
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: T47 T63 T45
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: T1 T12 T46
348 (DbgAddressBits'(hartsel) & {{(DbgAddressBits-3){1'b1}}, 3'b0})) begin
349 1/1 rdata[DbgAddressBits'(hartsel) & DbgAddressBits'(3'b111)] = {6'b0, resume, go};
Tests: T1 T12 T46
350 end
MISSING_ELSE
351 1/1 rdata_d = rdata;
Tests: T1 T12 T46
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: T50 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: T4 T43 T9
366 1/1 resuming_d_aligned = '0;
Tests: T4 T43 T9
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 T3 T12
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 T3 T12
391 1/1 WhereToAddr: err_d = gen_wr_err(we_i, be_i, FullRegMask);
Tests: T12 T46 T56
392 1/1 HaltedAddr: err_d = gen_wr_err(we_i, be_i, HartSelMask);
Tests: T1 T3 T12
393 1/1 GoingAddr: err_d = gen_wr_err(we_i, be_i, OneBitMask);
Tests: T3 T12 T28
394 1/1 ResumingAddr: err_d = gen_wr_err(we_i, be_i, HartSelMask);
Tests: T1 T12 T46
395 1/1 ExceptionAddr: err_d = gen_wr_err(we_i, be_i, OneBitMask);
Tests: T29 T30 T62
396 1/1 [DataBaseAddr:DataEndAddr]: err_d = gen_wr_err(we_i, be_i, FullRegMask);
Tests: T4 T42 T43
397 1/1 [ProgBufBaseAddr:ProgBufEndAddr]: err_d = gen_wr_err(we_i, be_i, FullRegMask);
Tests: T60 T61 T62
398 1/1 [AbstractCmdBaseAddr:AbstractCmdEndAddr]: err_d = gen_wr_err(we_i, be_i, FullRegMask);
Tests: T47 T63 T45
399 1/1 [FlagsBaseAddr:FlagsEndAddr]: err_d = gen_wr_err(we_i, be_i, FullRegMask);
Tests: T1 T12 T46
400 1/1 [RomBaseAddr:RomEndAddr]: err_d = we_i; // Writing ROM area always errors.
Tests: T50 T64 T62
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 T3 T12
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: T47 T63 T65
448 // this range is reserved
449 1/1 if (ac_ar.regno[15:14] != '0) begin
Tests: T47 T63 T65
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: T47 T63 T65
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: T47 T63 T65
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: T47 T63 T65
479 // load from data register
480 1/1 abstract_cmd[2][63:32] = dm::load(ac_ar.aarsize, 5'd8, LoadBaseAddr, dm::DataAddr);
Tests: T47 T63 T65
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: T47 T63 T65
483 // restore s0 again from dscratch
484 1/1 abstract_cmd[3][63:32] = dm::csrr(dm::CSR_DSCRATCH0, 5'd8);
Tests: T47 T63 T65
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: T12 T46 T66
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: T12 T46 T66
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: T12 T46 T66
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: T12 T46 T66
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: T12 T46 T66
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: T12 T46 T66
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: T12 T46 T66
526 // restore s0 again from dscratch
527 1/1 abstract_cmd[3][63:32] = dm::csrr(dm::CSR_DSCRATCH0, 5'd8);
Tests: T12 T46 T66
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: T65 T44 T57
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
| Total | Covered | Percent |
Conditions | 58 | 42 | 72.41 |
Logical | 58 | 42 | 72.41 |
Non-Logical | 0 | 0 | |
Event | 0 | 0 | |
LINE 158
EXPRESSION (cmd_valid_i && halted_q_aligned[hartsel] && ((!unsupported_command)))
-----1----- ------------2------------ ------------3-----------
-1- | -2- | -3- | Status | Tests |
0 | 1 | 1 | Covered | T1,T3,T12 |
1 | 0 | 1 | Covered | T2,T67 |
1 | 1 | 0 | Covered | T41,T55,T38 |
1 | 1 | 1 | Covered | T3,T12,T28 |
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- | Status | Tests | Exclude Annotation |
0 | 1 | 1 | 1 | Covered | T1,T12,T46 |
1 | 0 | 1 | 1 | Excluded | |
VC_COV_UNR |
1 | 1 | 0 | 1 | Covered | T57,T11,T68 |
1 | 1 | 1 | 0 | Covered | T12,T46,T56 |
1 | 1 | 1 | 1 | Covered | T1,T12,T46 |
LINE 206
EXPRESSION (unsupported_command && cmd_valid_i)
---------1--------- -----2-----
-1- | -2- | Status | Tests |
0 | 1 | Covered | T2,T3,T12 |
1 | 0 | Covered | T41,T55,T38 |
1 | 1 | Covered | T41,T55,T38 |
LINE 226
EXPRESSION (fwd_rom_q ? rom_rdata : rdata_q)
----1----
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T50,T64 |
LINE 231
EXPRESSION (word_enable32_q ? word_mux[32+:32] : word_mux[0+:32])
-------1-------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T17,T12,T50 |
LINE 280
EXPRESSION ((addr_i[(DbgAddressBits - 1):2] - DataBaseAddr[(DbgAddressBits - 1):2]) == dc)
---------------------------------------1---------------------------------------
-1- | Status | Tests |
0 | Covered | T4,T42,T43 |
1 | Covered | T4,T42,T43 |
LINE 313
EXPRESSION ((cmd_i.cmdtype == AccessRegister) && ((!ac_ar.transfer)) && ac_ar.postexec)
----------------1---------------- ---------2--------- -------3------
-1- | -2- | -3- | Status | Tests | Exclude Annotation |
0 | 1 | 1 | Excluded | |
Cannot have running command other than AccessRegister |
1 | 0 | 1 | Covered | T65,T44,T69 |
1 | 1 | 0 | Covered | T56,T70,T39 |
1 | 1 | 1 | Covered | T57,T58,T59 |
LINE 313
SUB-EXPRESSION (cmd_i.cmdtype == AccessRegister)
----------------1----------------
-1- | Status | Tests |
0 | Excluded | |
1 | Covered | T12,T46,T56 |
LINE 347
EXPRESSION (({addr_i[(DbgAddressBits - 1):3], 3'b0} - FlagsBaseAddr[(DbgAddressBits - 1):0]) == (12'(hartsel) & {{(DbgAddressBits - 3) {1'b1}}, 3'b0}))
----------------------------------------------------------------------1---------------------------------------------------------------------
-1- | Status | Tests |
0 | Covered | T62,T36,T34 |
1 | Covered | T1,T12,T46 |
LINE 445
EXPRESSION ((32'(ac_ar.aarsize) < MaxAar) && ac_ar.transfer && ac_ar.write)
--------------1-------------- -------2------ -----3-----
-1- | -2- | -3- | Status | Tests |
0 | 1 | 1 | Not Covered | |
1 | 0 | 1 | Covered | T70,T57,T58 |
1 | 1 | 0 | Covered | T12,T46,T66 |
1 | 1 | 1 | Covered | T47,T63,T65 |
LINE 449
EXPRESSION (ac_ar.regno[15:14] != '0)
-------------1------------
-1- | Status | Tests |
0 | Covered | T47,T63,T65 |
1 | Not 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- | Status | Tests |
- | 0 | 1 | 1 | Not Covered | |
- | 1 | 0 | 1 | Not Covered | |
- | 1 | 1 | 0 | Not Covered | |
- | 1 | 1 | 1 | Not Covered | |
LINE 454
SUB-EXPRESSION (ac_ar.regno[4:0] == 5'd10)
-------------1-------------
-1- | Status | Tests |
0 | Covered | T47,T63,T65 |
1 | Not Covered | |
LINE 486
EXPRESSION ((32'(ac_ar.aarsize) < MaxAar) && ac_ar.transfer && ((!ac_ar.write)))
--------------1-------------- -------2------ --------3-------
-1- | -2- | -3- | Status | Tests | Exclude Annotation |
0 | 1 | 1 | Not Covered | |
1 | 0 | 1 | Covered | T1,T2,T3 |
1 | 1 | 0 | Excluded | |
VC_COV_UNR |
1 | 1 | 1 | Covered | T12,T46,T66 |
LINE 492
EXPRESSION (ac_ar.regno[15:14] != '0)
-------------1------------
-1- | Status | Tests |
0 | Covered | T12,T46,T66 |
1 | Not 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- | Status | Tests |
- | 0 | 1 | 1 | Covered | T69 |
- | 1 | 0 | 1 | Not Covered | |
- | 1 | 1 | 0 | Not Covered | |
- | 1 | 1 | 1 | Not Covered | |
LINE 497
SUB-EXPRESSION (ac_ar.regno[4:0] == 5'd10)
-------------1-------------
-1- | Status | Tests |
0 | Covered | T12,T46,T66 |
1 | Covered | T69 |
LINE 529
EXPRESSION ((32'(ac_ar.aarsize) >= MaxAar) || (ac_ar.aarpostincrement == 1'b1))
---------------1-------------- ----------------2---------------
-1- | -2- | Status | Tests |
0 | 0 | Covered | T1,T2,T3 |
0 | 1 | Not Covered | |
1 | 0 | Not Covered | |
LINE 529
SUB-EXPRESSION (ac_ar.aarpostincrement == 1'b1)
----------------1---------------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Not Covered | |
LINE 541
EXPRESSION (ac_ar.postexec && ((!unsupported_command)))
-------1------ ------------2-----------
-1- | -2- | Status | Tests |
0 | 1 | Covered | T1,T2,T3 |
1 | 0 | Not Covered | |
1 | 1 | Covered | T65,T44,T57 |
LINE 605
EXPRESSION (SelectableHarts & halted_d)
-------1------- ----2---
-1- | -2- | Status | Tests |
- | 0 | Covered | T1,T2,T3 |
- | 1 | Covered | T1,T3,T12 |
LINE 606
EXPRESSION (SelectableHarts & resuming_d)
-------1------- -----2----
-1- | -2- | Status | Tests |
- | 0 | Covered | T1,T2,T3 |
- | 1 | Covered | T1,T12,T46 |
FSM Coverage for Instance : tb.dut.u_dm_top.i_dm_mem
Summary for FSM :: state_q
| Total | Covered | Percent | |
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
states | Line No. | Covered | Tests |
CmdExecuting |
180 |
Covered |
T3,T12,T28 |
Go |
160 |
Covered |
T3,T12,T28 |
Idle |
188 |
Covered |
T1,T2,T3 |
Resume |
170 |
Covered |
T1,T12,T46 |
transitions | Line No. | Covered | Tests |
CmdExecuting->Idle |
197 |
Covered |
T3,T12,T28 |
Go->CmdExecuting |
180 |
Covered |
T3,T12,T28 |
Go->Idle |
218 |
Covered |
T71 |
Idle->Go |
160 |
Covered |
T3,T12,T28 |
Idle->Resume |
170 |
Covered |
T1,T12,T46 |
Resume->Idle |
188 |
Covered |
T1,T12,T46 |
Branch Coverage for Instance : tb.dut.u_dm_top.i_dm_mem
| Line No. | Total | Covered | Percent |
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- | Status | Tests |
1 |
Covered |
T50,T64 |
0 |
Covered |
T1,T2,T3 |
231 assign rdata_o = (word_enable32_q) ? word_mux[32 +: 32] : word_mux[0 +: 32];
-1-
==>
==>
Branches:
-1- | Status | Tests |
1 |
Covered |
T17,T12,T50 |
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- | Status | Tests | Exclude Annotation |
Idle |
1 |
- |
- |
- |
- |
- |
Covered |
T3,T12,T28 |
|
Idle |
0 |
1 |
- |
- |
- |
- |
Covered |
T2,T41,T55 |
|
Idle |
0 |
0 |
- |
- |
- |
- |
Covered |
T1,T2,T3 |
|
Idle |
- |
- |
1 |
- |
- |
- |
Covered |
T1,T12,T46 |
|
Idle |
- |
- |
0 |
- |
- |
- |
Covered |
T1,T2,T3 |
|
Go |
- |
- |
- |
1 |
- |
- |
Covered |
T3,T12,T28 |
|
Go |
- |
- |
- |
0 |
- |
- |
Covered |
T3,T12,T28 |
|
Resume |
- |
- |
- |
- |
1 |
- |
Covered |
T1,T12,T46 |
|
Resume |
- |
- |
- |
- |
0 |
- |
Covered |
T1,T12,T46 |
|
CmdExecuting |
- |
- |
- |
- |
- |
1 |
Covered |
T3,T12,T28 |
|
CmdExecuting |
- |
- |
- |
- |
- |
0 |
Covered |
T3,T12,T28 |
|
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- | Status | Tests |
1 |
Covered |
T41,T55,T38 |
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- | Status | Tests |
1 |
Covered |
T29,T30 |
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- | Status | Tests |
1 |
Covered |
T4,T43,T9 |
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- | Status | Tests |
1 |
Covered |
T1,T12,T46 |
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- | Status | Tests |
1 |
1 |
HaltedAddr |
- |
- |
- |
- |
- |
Covered |
T1,T3,T12 |
1 |
1 |
GoingAddr |
- |
- |
- |
- |
- |
Covered |
T3,T12,T28 |
1 |
1 |
ResumingAddr |
- |
- |
- |
- |
- |
Covered |
T1,T12,T46 |
1 |
1 |
ExceptionAddr |
- |
- |
- |
- |
- |
Covered |
T29,T30 |
1 |
1 |
DataBaseAddr DataEndAddr |
- |
- |
- |
- |
- |
Covered |
T4,T42,T43 |
1 |
1 |
default |
- |
- |
- |
- |
- |
Covered |
T62,T36,T34 |
1 |
0 |
- |
WhereToAddr |
1 |
- |
- |
- |
Covered |
T36 |
1 |
0 |
- |
WhereToAddr |
0 |
- |
- |
- |
Covered |
T12,T46,T56 |
1 |
0 |
- |
WhereToAddr |
- |
1 |
1 |
- |
Covered |
T57,T58,T59 |
1 |
0 |
- |
WhereToAddr |
- |
1 |
0 |
- |
Covered |
T12,T46,T56 |
1 |
0 |
- |
WhereToAddr |
- |
0 |
- |
- |
Covered |
T72,T73,T62 |
1 |
0 |
- |
DataBaseAddr DataEndAddr |
- |
- |
- |
- |
Covered |
T4,T43,T44 |
1 |
0 |
- |
ProgBufBaseAddr ProgBufEndAddr |
- |
- |
- |
- |
Covered |
T60,T61,T62 |
1 |
0 |
- |
AbstractCmdBaseAddr AbstractCmdEndAddr |
- |
- |
- |
- |
Covered |
T47,T63,T45 |
1 |
0 |
- |
FlagsBaseAddr FlagsEndAddr |
- |
- |
- |
1 |
Covered |
T1,T12,T46 |
1 |
0 |
- |
FlagsBaseAddr FlagsEndAddr |
- |
- |
- |
0 |
Covered |
T62,T36,T34 |
1 |
0 |
- |
RomBaseAddr RomEndAddr |
- |
- |
- |
- |
Covered |
T50,T64 |
1 |
0 |
- |
default |
- |
- |
- |
- |
Covered |
T62,T36,T34 |
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- | Status | Tests |
1 |
Covered |
T4,T43,T9 |
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- | Status | Tests | Exclude Annotation |
1 |
WhereToAddr |
- |
Covered |
T12,T46,T56 |
|
1 |
HaltedAddr |
- |
Covered |
T1,T3,T12 |
|
1 |
GoingAddr |
- |
Covered |
T3,T12,T28 |
|
1 |
ResumingAddr |
- |
Covered |
T1,T12,T46 |
|
1 |
ExceptionAddr |
- |
Covered |
T29,T30,T62 |
|
1 |
DataBaseAddr DataEndAddr |
- |
Covered |
T4,T42,T43 |
|
1 |
ProgBufBaseAddr ProgBufEndAddr |
- |
Covered |
T60,T61,T62 |
|
1 |
AbstractCmdBaseAddr AbstractCmdEndAddr |
- |
Covered |
T47,T63,T45 |
|
1 |
FlagsBaseAddr FlagsEndAddr |
- |
Covered |
T1,T12,T46 |
|
1 |
RomBaseAddr RomEndAddr |
- |
Covered |
T50,T64,T62 |
|
1 |
default |
- |
Covered |
T62,T36,T34 |
|
1 |
- |
1 |
Excluded |
|
VC_COV_UNR |
1 |
- |
0 |
Covered |
T1,T3,T12 |
|
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- | Status | Tests |
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- | Status | Tests |
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 |
T47,T63,T65 |
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 |
T12,T46,T66 |
AccessRegister |
0 |
- |
- |
- |
- |
0 |
- |
- |
- |
- |
1 |
- |
Not Covered |
|
AccessRegister |
0 |
- |
- |
- |
- |
0 |
- |
- |
- |
- |
0 |
- |
Covered |
T1,T2,T3 |
AccessRegister |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
Covered |
T65,T44,T57 |
AccessRegister |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
0 |
Covered |
T1,T2,T3 |
default |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T41,T55,T38 |
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- | Status | Tests |
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- | Status | Tests |
1 |
Covered |
T1,T2,T3 |
0 |
Covered |
T1,T2,T3 |