Line Coverage for Module :
dm_csrs
| Line No. | Total | Covered | Percent |
TOTAL | | 277 | 239 | 86.28 |
CONT_ASSIGN | 90 | 1 | 1 | 100.00 |
ALWAYS | 107 | 7 | 7 | 100.00 |
ALWAYS | 120 | 8 | 8 | 100.00 |
ALWAYS | 137 | 8 | 8 | 100.00 |
ALWAYS | 153 | 4 | 4 | 100.00 |
CONT_ASSIGN | 182 | 1 | 1 | 100.00 |
CONT_ASSIGN | 183 | 1 | 1 | 100.00 |
CONT_ASSIGN | 184 | 1 | 1 | 100.00 |
CONT_ASSIGN | 185 | 1 | 1 | 100.00 |
CONT_ASSIGN | 186 | 1 | 1 | 100.00 |
CONT_ASSIGN | 187 | 1 | 1 | 100.00 |
CONT_ASSIGN | 189 | 1 | 1 | 100.00 |
CONT_ASSIGN | 195 | 1 | 1 | 100.00 |
CONT_ASSIGN | 196 | 1 | 1 | 100.00 |
CONT_ASSIGN | 197 | 1 | 1 | 100.00 |
CONT_ASSIGN | 199 | 1 | 1 | 100.00 |
CONT_ASSIGN | 200 | 1 | 1 | 100.00 |
ALWAYS | 204 | 2 | 0 | 0.00 |
CONT_ASSIGN | 215 | 1 | 1 | 100.00 |
CONT_ASSIGN | 217 | 1 | 1 | 100.00 |
CONT_ASSIGN | 221 | 1 | 1 | 100.00 |
ALWAYS | 228 | 173 | 138 | 79.77 |
ALWAYS | 568 | 6 | 6 | 100.00 |
CONT_ASSIGN | 578 | 1 | 1 | 100.00 |
CONT_ASSIGN | 579 | 1 | 1 | 100.00 |
CONT_ASSIGN | 580 | 1 | 1 | 100.00 |
CONT_ASSIGN | 581 | 1 | 1 | 100.00 |
CONT_ASSIGN | 582 | 1 | 1 | 100.00 |
CONT_ASSIGN | 584 | 1 | 1 | 100.00 |
CONT_ASSIGN | 587 | 1 | 0 | 0.00 |
ALWAYS | 611 | 46 | 46 | 100.00 |
89 dm::dtm_op_e dtm_op;
90 1/1 assign dtm_op = dm::dtm_op_e'(dmi_req_i.op);
Tests: T1 T2 T3
91
92 localparam dm::dm_csr_e DataEnd = dm::dm_csr_e'(dm::Data0 + {4'h0, dm::DataCount} - 8'h1);
93 localparam dm::dm_csr_e ProgBufEnd = dm::dm_csr_e'(dm::ProgBuf0 + {4'h0, dm::ProgBufSize} - 8'h1);
94
95 logic [31:0] haltsum0, haltsum1, haltsum2, haltsum3;
96 logic [((NrHarts-1)/2**5 + 1) * 32 - 1 : 0] halted;
97 logic [(NrHarts-1)/2**5:0][31:0] halted_reshaped0;
98 logic [(NrHarts-1)/2**10:0][31:0] halted_reshaped1;
99 logic [(NrHarts-1)/2**15:0][31:0] halted_reshaped2;
100 logic [((NrHarts-1)/2**10+1)*32-1:0] halted_flat1;
101 logic [((NrHarts-1)/2**15+1)*32-1:0] halted_flat2;
102 logic [31:0] halted_flat3;
103
104 // haltsum0
105 logic [14:0] hartsel_idx0;
106 always_comb begin : p_haltsum0
107 1/1 halted = '0;
Tests: T1 T2 T3
108 1/1 haltsum0 = '0;
Tests: T1 T2 T3
109 1/1 hartsel_idx0 = hartsel_o[19:5];
Tests: T1 T2 T3
110 1/1 halted[NrHarts-1:0] = halted_i;
Tests: T1 T2 T3
111 1/1 halted_reshaped0 = halted;
Tests: T1 T2 T3
112 1/1 if (hartsel_idx0 < 15'((NrHarts-1)/2**5+1)) begin
Tests: T1 T2 T3
113 1/1 haltsum0 = halted_reshaped0[hartsel_idx0];
Tests: T1 T2 T3
114 end
==> MISSING_ELSE
115 end
116
117 // haltsum1
118 logic [9:0] hartsel_idx1;
119 always_comb begin : p_reduction1
120 1/1 halted_flat1 = '0;
Tests: T1 T2 T3
121 1/1 haltsum1 = '0;
Tests: T1 T2 T3
122 1/1 hartsel_idx1 = hartsel_o[19:10];
Tests: T1 T2 T3
123
124 1/1 for (int unsigned k = 0; k < (NrHarts-1)/2**5+1; k++) begin
Tests: T1 T2 T3
125 1/1 halted_flat1[k] = |halted_reshaped0[k];
Tests: T1 T2 T3
126 end
127 1/1 halted_reshaped1 = halted_flat1;
Tests: T1 T2 T3
128
129 1/1 if (hartsel_idx1 < 10'(((NrHarts-1)/2**10+1))) begin
Tests: T1 T2 T3
130 1/1 haltsum1 = halted_reshaped1[hartsel_idx1];
Tests: T1 T2 T3
131 end
==> MISSING_ELSE
132 end
133
134 // haltsum2
135 logic [4:0] hartsel_idx2;
136 always_comb begin : p_reduction2
137 1/1 halted_flat2 = '0;
Tests: T1 T2 T3
138 1/1 haltsum2 = '0;
Tests: T1 T2 T3
139 1/1 hartsel_idx2 = hartsel_o[19:15];
Tests: T1 T2 T3
140
141 1/1 for (int unsigned k = 0; k < (NrHarts-1)/2**10+1; k++) begin
Tests: T1 T2 T3
142 1/1 halted_flat2[k] = |halted_reshaped1[k];
Tests: T1 T2 T3
143 end
144 1/1 halted_reshaped2 = halted_flat2;
Tests: T1 T2 T3
145
146 1/1 if (hartsel_idx2 < 5'(((NrHarts-1)/2**15+1))) begin
Tests: T1 T2 T3
147 1/1 haltsum2 = halted_reshaped2[hartsel_idx2];
Tests: T1 T2 T3
148 end
==> MISSING_ELSE
149 end
150
151 // haltsum3
152 always_comb begin : p_reduction3
153 1/1 halted_flat3 = '0;
Tests: T1 T2 T3
154 1/1 for (int unsigned k = 0; k < NrHarts/2**15+1; k++) begin
Tests: T1 T2 T3
155 1/1 halted_flat3[k] = |halted_reshaped2[k];
Tests: T1 T2 T3
156 end
157 1/1 haltsum3 = halted_flat3;
Tests: T1 T2 T3
158 end
159
160
161 dm::dmstatus_t dmstatus;
162 dm::dmcontrol_t dmcontrol_d, dmcontrol_q;
163 dm::abstractcs_t abstractcs;
164 dm::cmderr_e cmderr_d, cmderr_q;
165 dm::command_t command_d, command_q;
166 logic cmd_valid_d, cmd_valid_q;
167 dm::abstractauto_t abstractauto_d, abstractauto_q;
168 dm::sbcs_t sbcs_d, sbcs_q;
169 logic [63:0] sbaddr_d, sbaddr_q;
170 logic [63:0] sbdata_d, sbdata_q;
171
172 logic [NrHarts-1:0] havereset_d, havereset_q;
173 // program buffer
174 logic [dm::ProgBufSize-1:0][31:0] progbuf_d, progbuf_q;
175 logic [dm::DataCount-1:0][31:0] data_d, data_q;
176
177 logic [HartSelLen-1:0] selected_hart;
178
179 dm::dmi_resp_t resp_queue_inp;
180
181 // SBA
182 1/1 assign sbautoincrement_o = sbcs_q.sbautoincrement;
Tests: T1 T2 T3
183 1/1 assign sbreadonaddr_o = sbcs_q.sbreadonaddr;
Tests: T1 T2 T3
184 1/1 assign sbreadondata_o = sbcs_q.sbreadondata;
Tests: T1 T2 T3
185 1/1 assign sbaccess_o = sbcs_q.sbaccess;
Tests: T1 T2 T3
186 1/1 assign sbdata_o = sbdata_q[BusWidth-1:0];
Tests: T1 T2 T3
187 1/1 assign sbaddress_o = sbaddr_q[BusWidth-1:0];
Tests: T1 T2 T3
188
189 1/1 assign hartsel_o = {dmcontrol_q.hartselhi, dmcontrol_q.hartsello};
Tests: T1 T2 T3
190
191 // needed to avoid lint warnings
192 logic [NrHartsAligned-1:0] havereset_d_aligned, havereset_q_aligned,
193 resumeack_aligned, unavailable_aligned,
194 halted_aligned;
195 1/1 assign resumeack_aligned = NrHartsAligned'(resumeack_i);
Tests: T1 T2 T3
196 1/1 assign unavailable_aligned = NrHartsAligned'(unavailable_i);
Tests: T1 T4 T5
197 1/1 assign halted_aligned = NrHartsAligned'(halted_i);
Tests: T1 T2 T3
198
199 1/1 assign havereset_d = NrHarts'(havereset_d_aligned);
Tests: T1 T2 T3
200 1/1 assign havereset_q_aligned = NrHartsAligned'(havereset_q);
Tests: T1 T2 T3
201
202 dm::hartinfo_t [NrHartsAligned-1:0] hartinfo_aligned;
203 always_comb begin : p_hartinfo_align
204 0/1 ==> hartinfo_aligned = '0;
205 0/1 ==> hartinfo_aligned[NrHarts-1:0] = hartinfo_i;
206 end
207
208 // helper variables
209 dm::dm_csr_e dm_csr_addr;
210 dm::sbcs_t sbcs;
211 dm::abstractcs_t a_abstractcs;
212 logic [3:0] autoexecdata_idx; // 0 == Data0 ... 11 == Data11
213
214 // Get the data index, i.e. 0 for dm::Data0 up to 11 for dm::Data11
215 1/1 assign dm_csr_addr = dm::dm_csr_e'({1'b0, dmi_req_i.addr});
Tests: T1 T2 T3
216 logic unused_addr_bits;
217 1/1 assign unused_addr_bits = ^dmi_req_i.addr[31:$bits(dm_csr_addr)];
Tests: T1 T2 T3
218
219 // Xilinx Vivado 2020.1 does not allow subtraction of two enums; do the subtraction with logic
220 // types instead.
221 1/1 assign autoexecdata_idx = 4'({dm_csr_addr} - {dm::Data0});
Tests: T1 T2 T3
222
223 always_comb (*xprop_off *) begin : csr_read_write
224 // --------------------
225 // Static Values (R/O)
226 // --------------------
227 // dmstatus
228 1/1 dmstatus = '0;
Tests: T1 T2 T3
229 1/1 dmstatus.version = dm::DbgVersion013;
Tests: T1 T2 T3
230 // no authentication implemented
231 1/1 dmstatus.authenticated = 1'b1;
Tests: T1 T2 T3
232 // we do not support halt-on-reset sequence
233 1/1 dmstatus.hasresethaltreq = 1'b0;
Tests: T1 T2 T3
234 // TODO(zarubaf) things need to change here if we implement the array mask
235 1/1 dmstatus.allhavereset = havereset_q_aligned[selected_hart];
Tests: T1 T2 T3
236 1/1 dmstatus.anyhavereset = havereset_q_aligned[selected_hart];
Tests: T1 T2 T3
237
238 1/1 dmstatus.allresumeack = resumeack_aligned[selected_hart];
Tests: T1 T2 T3
239 1/1 dmstatus.anyresumeack = resumeack_aligned[selected_hart];
Tests: T1 T2 T3
240
241 1/1 dmstatus.allunavail = unavailable_aligned[selected_hart];
Tests: T1 T2 T3
242 1/1 dmstatus.anyunavail = unavailable_aligned[selected_hart];
Tests: T1 T2 T3
243
244 // as soon as we are out of the legal Hart region tell the debugger
245 // that there are only non-existent harts
246 1/1 dmstatus.allnonexistent = logic'(32'(hartsel_o) > (NrHarts - 1));
Tests: T1 T2 T3
247 1/1 dmstatus.anynonexistent = logic'(32'(hartsel_o) > (NrHarts - 1));
Tests: T1 T2 T3
248
249 // We are not allowed to be in multiple states at once. This is a to
250 // make the running/halted and unavailable states exclusive.
251 1/1 dmstatus.allhalted = halted_aligned[selected_hart] & ~unavailable_aligned[selected_hart];
Tests: T1 T2 T3
252 1/1 dmstatus.anyhalted = halted_aligned[selected_hart] & ~unavailable_aligned[selected_hart];
Tests: T1 T2 T3
253
254 1/1 dmstatus.allrunning = ~halted_aligned[selected_hart] & ~unavailable_aligned[selected_hart];
Tests: T1 T2 T3
255 1/1 dmstatus.anyrunning = ~halted_aligned[selected_hart] & ~unavailable_aligned[selected_hart];
Tests: T1 T2 T3
256
257 // abstractcs
258 1/1 abstractcs = '0;
Tests: T1 T2 T3
259 1/1 abstractcs.datacount = dm::DataCount;
Tests: T1 T2 T3
260 1/1 abstractcs.progbufsize = dm::ProgBufSize;
Tests: T1 T2 T3
261 1/1 abstractcs.busy = cmdbusy_i;
Tests: T1 T2 T3
262 1/1 abstractcs.cmderr = cmderr_q;
Tests: T1 T2 T3
263
264 // abstractautoexec
265 1/1 abstractauto_d = abstractauto_q;
Tests: T1 T2 T3
266 1/1 abstractauto_d.zero0 = '0;
Tests: T1 T2 T3
267
268 // default assignments
269 1/1 havereset_d_aligned = NrHartsAligned'(havereset_q);
Tests: T1 T2 T3
270 1/1 dmcontrol_d = dmcontrol_q;
Tests: T1 T2 T3
271 1/1 cmderr_d = cmderr_q;
Tests: T1 T2 T3
272 1/1 command_d = command_q;
Tests: T1 T2 T3
273 1/1 progbuf_d = progbuf_q;
Tests: T1 T2 T3
274 1/1 data_d = data_q;
Tests: T1 T2 T3
275 1/1 sbcs_d = sbcs_q;
Tests: T1 T2 T3
276 1/1 sbaddr_d = 64'(sbaddress_i);
Tests: T1 T2 T3
277 1/1 sbdata_d = sbdata_q;
Tests: T1 T2 T3
278
279 1/1 resp_queue_inp.data = 32'h0;
Tests: T1 T2 T3
280 1/1 resp_queue_inp.resp = dm::DTM_SUCCESS;
Tests: T1 T2 T3
281 1/1 cmd_valid_d = 1'b0;
Tests: T1 T2 T3
282 1/1 sbaddress_write_valid_o = 1'b0;
Tests: T1 T2 T3
283 1/1 sbdata_read_valid_o = 1'b0;
Tests: T1 T2 T3
284 1/1 sbdata_write_valid_o = 1'b0;
Tests: T1 T2 T3
285 1/1 clear_resumeack_o = 1'b0;
Tests: T1 T2 T3
286
287 // helper variables
288 1/1 sbcs = '0;
Tests: T1 T2 T3
289 1/1 a_abstractcs = '0;
Tests: T1 T2 T3
290
291 // reads
292 1/1 if (dmi_req_ready_o && dmi_req_valid_i && dtm_op == dm::DTM_READ) begin
Tests: T1 T2 T3
293 1/1 unique case (dm_csr_addr) inside
Tests: T1 T2 T3
294 [(dm::Data0):DataEnd]: begin
295 1/1 resp_queue_inp.data = data_q[$clog2(dm::DataCount)'(autoexecdata_idx)];
Tests: T1 T6 T7
296 1/1 if (!cmdbusy_i) begin
Tests: T1 T6 T7
297 // check whether we need to re-execute the command (just give a cmd_valid)
298 1/1 cmd_valid_d = abstractauto_q.autoexecdata[autoexecdata_idx];
Tests: T1 T6 T7
299 // An abstract command was executing while one of the data registers was read
300 end else begin
301 1/1 resp_queue_inp.resp = dm::DTM_BUSY;
Tests: T1 T8 T9
302 1/1 if (cmderr_q == dm::CmdErrNone) begin
Tests: T1 T8 T9
303 1/1 cmderr_d = dm::CmdErrBusy;
Tests: T1 T8 T9
304 end
==> MISSING_ELSE
305 end
306 end
307 1/1 dm::DMControl: resp_queue_inp.data = dmcontrol_q;
Tests: T1 T2 T3
308 1/1 dm::DMStatus: resp_queue_inp.data = dmstatus;
Tests: T1 T4 T5
309 0/1 ==> dm::Hartinfo: resp_queue_inp.data = hartinfo_aligned[selected_hart];
310 1/1 dm::AbstractCS: resp_queue_inp.data = abstractcs;
Tests: T1 T2 T3
311 0/1 ==> dm::AbstractAuto: resp_queue_inp.data = abstractauto_q;
312 0/1 ==> dm::Command: resp_queue_inp.data = '0;
313 0/1 ==> dm::NextDM: resp_queue_inp.data = next_dm_addr_i;
314 [(dm::ProgBuf0):ProgBufEnd]: begin
315 1/1 resp_queue_inp.data = progbuf_q[dmi_req_i.addr[$clog2(dm::ProgBufSize)-1:0]];
Tests: T1 T7 T10
316 1/1 if (!cmdbusy_i) begin
Tests: T1 T7 T10
317 // check whether we need to re-execute the command (just give a cmd_valid)
318 // range of autoexecprogbuf is 31:16
319 1/1 cmd_valid_d = abstractauto_q.autoexecprogbuf[{1'b1, dmi_req_i.addr[3:0]}];
Tests: T1 T7 T10
320
321 // An abstract command was executing while one of the progbuf registers was read
322 end else begin
323 1/1 resp_queue_inp.resp = dm::DTM_BUSY;
Tests: T11 T12 T13
324 1/1 if (cmderr_q == dm::CmdErrNone) begin
Tests: T11 T12 T13
325 1/1 cmderr_d = dm::CmdErrBusy;
Tests: T11 T12 T13
326 end
==> MISSING_ELSE
327 end
328 end
329 0/1 ==> dm::HaltSum0: resp_queue_inp.data = haltsum0;
330 0/1 ==> dm::HaltSum1: resp_queue_inp.data = haltsum1;
331 0/1 ==> dm::HaltSum2: resp_queue_inp.data = haltsum2;
332 0/1 ==> dm::HaltSum3: resp_queue_inp.data = haltsum3;
333 dm::SBCS: begin
334 1/1 resp_queue_inp.data = sbcs_q;
Tests: T14 T15 T16
335 end
336 dm::SBAddress0: begin
337 1/1 resp_queue_inp.data = sbaddr_q[31:0];
Tests: T17 T18 T19
338 end
339 dm::SBAddress1: begin
340 0/1 ==> resp_queue_inp.data = sbaddr_q[63:32];
341 end
342 dm::SBData0: begin
343 // access while the SBA was busy
344 1/1 if (sbbusy_i || sbcs_q.sbbusyerror) begin
Tests: T14 T15 T16
345 0/1 ==> sbcs_d.sbbusyerror = 1'b1;
346 0/1 ==> resp_queue_inp.resp = dm::DTM_BUSY;
347 end else begin
348 1/1 sbdata_read_valid_o = (sbcs_q.sberror == '0);
Tests: T14 T15 T16
349 1/1 resp_queue_inp.data = sbdata_q[31:0];
Tests: T14 T15 T16
350 end
351 end
352 dm::SBData1: begin
353 // access while the SBA was busy
354 0/1 ==> if (sbbusy_i || sbcs_q.sbbusyerror) begin
355 0/1 ==> sbcs_d.sbbusyerror = 1'b1;
356 0/1 ==> resp_queue_inp.resp = dm::DTM_BUSY;
357 end else begin
358 0/1 ==> resp_queue_inp.data = sbdata_q[63:32];
359 end
360 end
361 default:;
362 endcase
363 end
MISSING_ELSE
364
365 // write
366 1/1 if (dmi_req_ready_o && dmi_req_valid_i && dtm_op == dm::DTM_WRITE) begin
Tests: T1 T2 T3
367 1/1 unique case (dm_csr_addr) inside
Tests: T1 T2 T3
368 [(dm::Data0):DataEnd]: begin
369 1/1 if (dm::DataCount > 0) begin
Tests: T1 T20 T7
370 // attempts to write them while busy is set does not change their value
371 1/1 if (!cmdbusy_i) begin
Tests: T1 T20 T7
372 1/1 data_d[dmi_req_i.addr[$clog2(dm::DataCount)-1:0]] = dmi_req_i.data;
Tests: T1 T20 T7
373 // check whether we need to re-execute the command (just give a cmd_valid)
374 1/1 cmd_valid_d = abstractauto_q.autoexecdata[autoexecdata_idx];
Tests: T1 T20 T7
375 //An abstract command was executing while one of the data registers was written
376 end else begin
377 1/1 resp_queue_inp.resp = dm::DTM_BUSY;
Tests: T21 T22
378 1/1 if (cmderr_q == dm::CmdErrNone) begin
Tests: T21 T22
379 1/1 cmderr_d = dm::CmdErrBusy;
Tests: T21 T22
380 end
==> MISSING_ELSE
381 end
382 end
==> MISSING_ELSE
383 end
384 dm::DMControl: begin
385 1/1 dmcontrol_d = dmi_req_i.data;
Tests: T1 T2 T3
386 // clear the havreset of the selected hart
387 1/1 if (dmcontrol_d.ackhavereset) begin
Tests: T1 T2 T3
388 1/1 havereset_d_aligned[selected_hart] = 1'b0;
Tests: T5 T23 T24
389 end
MISSING_ELSE
390 end
391 0/1 ==> dm::DMStatus:; // write are ignored to R/O register
392 0/1 ==> dm::Hartinfo:; // hartinfo is R/O
393 // only command error is write-able
394 dm::AbstractCS: begin // W1C
395 // Gets set if an abstract command fails. The bits in this
396 // field remain set until they are cleared by writing 1 to
397 // them. No abstract command is started until the value is
398 // reset to 0.
399 1/1 a_abstractcs = dm::abstractcs_t'(dmi_req_i.data);
Tests: T1 T2 T3
400 // reads during abstract command execution are not allowed
401 1/1 if (!cmdbusy_i) begin
Tests: T1 T2 T3
402 1/1 cmderr_d = dm::cmderr_e'(~a_abstractcs.cmderr & cmderr_q);
Tests: T1 T2 T3
403 end else begin
404 1/1 resp_queue_inp.resp = dm::DTM_BUSY;
Tests: T25 T26 T27
405 1/1 if (cmderr_q == dm::CmdErrNone) begin
Tests: T25 T26 T27
406 1/1 cmderr_d = dm::CmdErrBusy;
Tests: T27 T28 T29
407 end
MISSING_ELSE
408 end
409 end
410 dm::Command: begin
411 // writes are ignored if a command is already busy
412 1/1 if (!cmdbusy_i) begin
Tests: T1 T2 T3
413 1/1 cmd_valid_d = 1'b1;
Tests: T1 T2 T3
414 1/1 command_d = dm::command_t'(dmi_req_i.data);
Tests: T1 T2 T3
415 // if there was an attempted to write during a busy execution
416 // and the cmderror field is zero set the busy error
417 end else begin
418 1/1 resp_queue_inp.resp = dm::DTM_BUSY;
Tests: T30 T12 T28
419 1/1 if (cmderr_q == dm::CmdErrNone) begin
Tests: T30 T12 T28
420 1/1 cmderr_d = dm::CmdErrBusy;
Tests: T30 T12 T28
421 end
==> MISSING_ELSE
422 end
423 end
424 0/1 ==> dm::NextDM:; // nextdm is R/O
425 dm::AbstractAuto: begin
426 // this field can only be written legally when there is no command executing
427 1/1 if (!cmdbusy_i) begin
Tests: T31 T22 T32
428 0/1 ==> abstractauto_d = 32'h0;
429 0/1 ==> abstractauto_d.autoexecdata = 12'(dmi_req_i.data[dm::DataCount-1:0]);
430 0/1 ==> abstractauto_d.autoexecprogbuf = 16'(dmi_req_i.data[dm::ProgBufSize-1+16:16]);
431 end else begin
432 1/1 resp_queue_inp.resp = dm::DTM_BUSY;
Tests: T31 T22 T32
433 1/1 if (cmderr_q == dm::CmdErrNone) begin
Tests: T31 T22 T32
434 1/1 cmderr_d = dm::CmdErrBusy;
Tests: T31 T22 T32
435 end
==> MISSING_ELSE
436 end
437 end
438 [(dm::ProgBuf0):ProgBufEnd]: begin
439 // attempts to write them while busy is set does not change their value
440 1/1 if (!cmdbusy_i) begin
Tests: T1 T3 T20
441 1/1 progbuf_d[dmi_req_i.addr[$clog2(dm::ProgBufSize)-1:0]] = dmi_req_i.data;
Tests: T1 T20 T7
442 // check whether we need to re-execute the command (just give a cmd_valid)
443 // this should probably throw an error if executed during another command
444 // was busy
445 // range of autoexecprogbuf is 31:16
446 1/1 cmd_valid_d = abstractauto_q.autoexecprogbuf[{1'b1, dmi_req_i.addr[3:0]}];
Tests: T1 T20 T7
447 //An abstract command was executing while one of the progbuf registers was written
448 end else begin
449 1/1 resp_queue_inp.resp = dm::DTM_BUSY;
Tests: T3 T33 T34
450 1/1 if (cmderr_q == dm::CmdErrNone) begin
Tests: T3 T33 T34
451 1/1 cmderr_d = dm::CmdErrBusy;
Tests: T3 T33 T34
452 end
==> MISSING_ELSE
453 end
454 end
455 dm::SBCS: begin
456 // access while the SBA was busy
457 1/1 if (sbbusy_i) begin
Tests: T14 T15 T16
458 0/1 ==> sbcs_d.sbbusyerror = 1'b1;
459 0/1 ==> resp_queue_inp.resp = dm::DTM_BUSY;
460 end else begin
461 1/1 sbcs = dm::sbcs_t'(dmi_req_i.data);
Tests: T14 T15 T16
462 1/1 sbcs_d = sbcs;
Tests: T14 T15 T16
463 // R/W1C
464 1/1 sbcs_d.sbbusyerror = sbcs_q.sbbusyerror & (~sbcs.sbbusyerror);
Tests: T14 T15 T16
465 1/1 sbcs_d.sberror = (|sbcs.sberror) ? 3'b0 : sbcs_q.sberror;
Tests: T14 T15 T16
466 end
467 end
468 dm::SBAddress0: begin
469 // access while the SBA was busy
470 1/1 if (sbbusy_i || sbcs_q.sbbusyerror) begin
Tests: T14 T15 T16
471 0/1 ==> sbcs_d.sbbusyerror = 1'b1;
472 0/1 ==> resp_queue_inp.resp = dm::DTM_BUSY;
473 end else begin
474 1/1 sbaddr_d[31:0] = dmi_req_i.data;
Tests: T14 T15 T16
475 1/1 sbaddress_write_valid_o = (sbcs_q.sberror == '0);
Tests: T14 T15 T16
476 end
477 end
478 dm::SBAddress1: begin
479 // access while the SBA was busy
480 0/1 ==> if (sbbusy_i || sbcs_q.sbbusyerror) begin
481 0/1 ==> sbcs_d.sbbusyerror = 1'b1;
482 0/1 ==> resp_queue_inp.resp = dm::DTM_BUSY;
483 end else begin
484 0/1 ==> sbaddr_d[63:32] = dmi_req_i.data;
485 end
486 end
487 dm::SBData0: begin
488 // access while the SBA was busy
489 1/1 if (sbbusy_i || sbcs_q.sbbusyerror) begin
Tests: T14 T15 T16
490 0/1 ==> sbcs_d.sbbusyerror = 1'b1;
491 0/1 ==> resp_queue_inp.resp = dm::DTM_BUSY;
492 end else begin
493 1/1 sbdata_d[31:0] = dmi_req_i.data;
Tests: T14 T15 T16
494 1/1 sbdata_write_valid_o = (sbcs_q.sberror == '0);
Tests: T14 T15 T16
495 end
496 end
497 dm::SBData1: begin
498 // access while the SBA was busy
499 0/1 ==> if (sbbusy_i || sbcs_q.sbbusyerror) begin
500 0/1 ==> sbcs_d.sbbusyerror = 1'b1;
501 0/1 ==> resp_queue_inp.resp = dm::DTM_BUSY;
502 end else begin
503 0/1 ==> sbdata_d[63:32] = dmi_req_i.data;
504 end
505 end
506 default:;
507 endcase
508 end
MISSING_ELSE
509 // hart threw a command error and has precedence over bus writes
510 1/1 if (cmderror_valid_i) begin
Tests: T1 T2 T3
511 1/1 cmderr_d = cmderror_i;
Tests: T2 T25 T35
512 end
MISSING_ELSE
513
514 // update data registers
515 1/1 if (data_valid_i) begin
Tests: T1 T2 T3
516 1/1 data_d = data_i;
Tests: T1 T6 T10
517 end
MISSING_ELSE
518
519 // set the havereset flag when the ndmreset completed
520 1/1 if (ndmreset_ack_i) begin
Tests: T1 T2 T3
521 1/1 havereset_d_aligned[NrHarts-1:0] = '1;
Tests: T1 T10 T36
522 end
MISSING_ELSE
523 // -------------
524 // System Bus
525 // -------------
526 // set bus error
527 1/1 if (sberror_valid_i) begin
Tests: T1 T2 T3
528 1/1 sbcs_d.sberror = sberror_i;
Tests: T15 T37 T38
529 end
MISSING_ELSE
530 // update read data
531 1/1 if (sbdata_valid_i) begin
Tests: T1 T2 T3
532 1/1 sbdata_d = 64'(sbdata_i);
Tests: T14 T15 T16
533 end
MISSING_ELSE
534
535 // dmcontrol
536 // TODO(zarubaf) we currently do not implement the hartarry mask
537 1/1 dmcontrol_d.hasel = 1'b0;
Tests: T1 T2 T3
538 // we do not support resetting an individual hart
539 1/1 dmcontrol_d.hartreset = 1'b0;
Tests: T1 T2 T3
540 1/1 dmcontrol_d.setresethaltreq = 1'b0;
Tests: T1 T2 T3
541 1/1 dmcontrol_d.clrresethaltreq = 1'b0;
Tests: T1 T2 T3
542 1/1 dmcontrol_d.zero1 = '0;
Tests: T1 T2 T3
543 1/1 dmcontrol_d.zero0 = '0;
Tests: T1 T2 T3
544 // Non-writeable, clear only
545 1/1 dmcontrol_d.ackhavereset = 1'b0;
Tests: T1 T2 T3
546 1/1 if (!dmcontrol_q.resumereq && dmcontrol_d.resumereq) begin
Tests: T1 T2 T3
547 1/1 clear_resumeack_o = 1'b1;
Tests: T5 T39 T24
548 end
MISSING_ELSE
549 1/1 if (dmcontrol_q.resumereq && resumeack_i) begin
Tests: T1 T2 T3
550 1/1 dmcontrol_d.resumereq = 1'b0;
Tests: T5 T39 T24
551 end
MISSING_ELSE
552 // WARL behavior of hartsel, depending on NrHarts.
553 // If NrHarts = 1 this is just masked to all-zeros.
554 1/1 {dmcontrol_d.hartselhi, dmcontrol_d.hartsello} &= (2**$clog2(NrHarts))-1;
Tests: T1 T2 T3
555 // static values for dcsr
556 1/1 sbcs_d.sbversion = 3'd1;
Tests: T1 T2 T3
557 1/1 sbcs_d.sbbusy = sbbusy_i;
Tests: T1 T2 T3
558 1/1 sbcs_d.sbasize = $bits(sbcs_d.sbasize)'(BusWidth);
Tests: T1 T2 T3
559 1/1 sbcs_d.sbaccess128 = logic'(BusWidth >= 32'd128);
Tests: T1 T2 T3
560 1/1 sbcs_d.sbaccess64 = logic'(BusWidth >= 32'd64);
Tests: T1 T2 T3
561 1/1 sbcs_d.sbaccess32 = logic'(BusWidth >= 32'd32);
Tests: T1 T2 T3
562 1/1 sbcs_d.sbaccess16 = logic'(BusWidth >= 32'd16);
Tests: T1 T2 T3
563 1/1 sbcs_d.sbaccess8 = logic'(BusWidth >= 32'd8);
Tests: T1 T2 T3
564 end
565
566 // output multiplexer
567 always_comb begin : p_outmux
568 1/1 selected_hart = hartsel_o[HartSelLen-1:0];
Tests: T1 T2 T3
569 // default assignment
570 1/1 haltreq_o = '0;
Tests: T1 T2 T3
571 1/1 resumereq_o = '0;
Tests: T1 T2 T3
572 1/1 if (selected_hart <= HartSelLen'(NrHarts-1)) begin
Tests: T1 T2 T3
573 1/1 haltreq_o[selected_hart] = dmcontrol_q.haltreq;
Tests: T1 T2 T3
574 1/1 resumereq_o[selected_hart] = dmcontrol_q.resumereq;
Tests: T1 T2 T3
575 end
==> MISSING_ELSE
576 end
577
578 1/1 assign dmactive_o = dmcontrol_q.dmactive;
Tests: T1 T2 T3
579 1/1 assign cmd_o = command_q;
Tests: T1 T2 T3
580 1/1 assign cmd_valid_o = cmd_valid_q;
Tests: T1 T2 T3
581 1/1 assign progbuf_o = progbuf_q;
Tests: T1 T2 T3
582 1/1 assign data_o = data_q;
Tests: T1 T2 T3
583
584 1/1 assign ndmreset_o = dmcontrol_q.ndmreset;
Tests: T1 T2 T3
585
586 logic unused_testmode;
587 0/1 ==> assign unused_testmode = testmode_i;
588
589 // response FIFO
590 prim_fifo_sync #(
591 .Width ($bits(dmi_resp_o)),
592 .Pass (1'b0),
593 .Depth (2)
594 ) i_fifo (
595 .clk_i ( clk_i ),
596 .rst_ni ( dmi_rst_ni ), // reset only when system is re-set
597 .clr_i ( 1'b0 ),
598 .wdata_i ( resp_queue_inp ),
599 .wvalid_i( dmi_req_valid_i ),
600 .wready_o( dmi_req_ready_o ),
601 .rdata_o ( dmi_resp_o ),
602 .rvalid_o( dmi_resp_valid_o ),
603 .rready_i( dmi_resp_ready_i ),
604 .full_o ( ), // Unused
605 .depth_o ( ), // Unused
606 .err_o ( ) // Unused
607 );
608
609 always_ff @(posedge clk_i or negedge rst_ni) begin : p_regs
610 // PoR
611 1/1 if (!rst_ni) begin
Tests: T1 T2 T3
612 1/1 dmcontrol_q <= '0;
Tests: T1 T2 T3
613 // this is the only write-able bit during reset
614 1/1 cmderr_q <= dm::CmdErrNone;
Tests: T1 T2 T3
615 1/1 command_q <= '0;
Tests: T1 T2 T3
616 1/1 cmd_valid_q <= '0;
Tests: T1 T2 T3
617 1/1 abstractauto_q <= '0;
Tests: T1 T2 T3
618 1/1 progbuf_q <= '0;
Tests: T1 T2 T3
619 1/1 data_q <= '0;
Tests: T1 T2 T3
620 1/1 sbcs_q <= '{default: '0, sbaccess: 3'd2};
Tests: T1 T2 T3
621 1/1 sbaddr_q <= '0;
Tests: T1 T2 T3
622 1/1 sbdata_q <= '0;
Tests: T1 T2 T3
623 1/1 havereset_q <= '1;
Tests: T1 T2 T3
624 end else begin
625 1/1 havereset_q <= SelectableHarts & havereset_d;
Tests: T1 T2 T3
626 // synchronous re-set of debug module, active-low, except for dmactive
627 1/1 if (!dmcontrol_q.dmactive) begin
Tests: T1 T2 T3
628 1/1 dmcontrol_q.haltreq <= '0;
Tests: T1 T2 T3
629 1/1 dmcontrol_q.resumereq <= '0;
Tests: T1 T2 T3
630 1/1 dmcontrol_q.hartreset <= '0;
Tests: T1 T2 T3
631 1/1 dmcontrol_q.ackhavereset <= '0;
Tests: T1 T2 T3
632 1/1 dmcontrol_q.zero1 <= '0;
Tests: T1 T2 T3
633 1/1 dmcontrol_q.hasel <= '0;
Tests: T1 T2 T3
634 1/1 dmcontrol_q.hartsello <= '0;
Tests: T1 T2 T3
635 1/1 dmcontrol_q.hartselhi <= '0;
Tests: T1 T2 T3
636 1/1 dmcontrol_q.zero0 <= '0;
Tests: T1 T2 T3
637 1/1 dmcontrol_q.setresethaltreq <= '0;
Tests: T1 T2 T3
638 1/1 dmcontrol_q.clrresethaltreq <= '0;
Tests: T1 T2 T3
639 1/1 dmcontrol_q.ndmreset <= '0;
Tests: T1 T2 T3
640 // this is the only write-able bit during reset
641 1/1 dmcontrol_q.dmactive <= dmcontrol_d.dmactive;
Tests: T1 T2 T3
642 1/1 cmderr_q <= dm::CmdErrNone;
Tests: T1 T2 T3
643 1/1 command_q <= '0;
Tests: T1 T2 T3
644 1/1 cmd_valid_q <= '0;
Tests: T1 T2 T3
645 1/1 abstractauto_q <= '0;
Tests: T1 T2 T3
646 1/1 progbuf_q <= '0;
Tests: T1 T2 T3
647 1/1 data_q <= '0;
Tests: T1 T2 T3
648 1/1 sbcs_q <= '{default: '0, sbaccess: 3'd2};
Tests: T1 T2 T3
649 1/1 sbaddr_q <= '0;
Tests: T1 T2 T3
650 1/1 sbdata_q <= '0;
Tests: T1 T2 T3
651 end else begin
652 1/1 dmcontrol_q <= dmcontrol_d;
Tests: T1 T2 T3
653 1/1 cmderr_q <= cmderr_d;
Tests: T1 T2 T3
654 1/1 command_q <= command_d;
Tests: T1 T2 T3
655 1/1 cmd_valid_q <= cmd_valid_d;
Tests: T1 T2 T3
656 1/1 abstractauto_q <= abstractauto_d;
Tests: T1 T2 T3
657 1/1 progbuf_q <= progbuf_d;
Tests: T1 T2 T3
658 1/1 data_q <= data_d;
Tests: T1 T2 T3
659 1/1 sbcs_q <= sbcs_d;
Tests: T1 T2 T3
660 1/1 sbaddr_q <= sbaddr_d;
Tests: T1 T2 T3
661 1/1 sbdata_q <= sbdata_d;
Tests: T1 T2 T3
Cond Coverage for Module :
dm_csrs
| Total | Covered | Percent |
Conditions | 75 | 47 | 62.67 |
Logical | 75 | 47 | 62.67 |
Non-Logical | 0 | 0 | |
Event | 0 | 0 | |
LINE 251
EXPRESSION (halted_aligned[selected_hart] & ((~unavailable_aligned[selected_hart])))
--------------1-------------- -------------------2-------------------
-1- | -2- | Status | Tests |
0 | 1 | Covered | T1,T2,T3 |
1 | 0 | Covered | T1,T40,T41 |
1 | 1 | Covered | T2,T3,T25 |
LINE 252
EXPRESSION (halted_aligned[selected_hart] & ((~unavailable_aligned[selected_hart])))
--------------1-------------- -------------------2-------------------
-1- | -2- | Status | Tests |
0 | 1 | Covered | T1,T2,T3 |
1 | 0 | Covered | T1,T40,T41 |
1 | 1 | Covered | T2,T3,T25 |
LINE 254
EXPRESSION (((~halted_aligned[selected_hart])) & ((~unavailable_aligned[selected_hart])))
-----------------1---------------- -------------------2-------------------
-1- | -2- | Status | Tests |
0 | 1 | Covered | T2,T3,T25 |
1 | 0 | Covered | T1,T4,T6 |
1 | 1 | Covered | T1,T2,T3 |
LINE 255
EXPRESSION (((~halted_aligned[selected_hart])) & ((~unavailable_aligned[selected_hart])))
-----------------1---------------- -------------------2-------------------
-1- | -2- | Status | Tests |
0 | 1 | Covered | T2,T3,T25 |
1 | 0 | Covered | T1,T4,T6 |
1 | 1 | Covered | T1,T2,T3 |
LINE 292
EXPRESSION (dmi_req_ready_o && dmi_req_valid_i && (dtm_op == DTM_READ))
-------1------- -------2------- ----------3---------
-1- | -2- | -3- | Status | Tests |
0 | 1 | 1 | Not Covered | |
1 | 0 | 1 | Covered | T1,T2,T3 |
1 | 1 | 0 | Covered | T1,T2,T3 |
1 | 1 | 1 | Covered | T1,T2,T3 |
LINE 292
SUB-EXPRESSION (dtm_op == DTM_READ)
----------1---------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T1,T2,T3 |
LINE 302
EXPRESSION (cmderr_q == CmdErrNone)
------------1-----------
-1- | Status | Tests |
0 | Not Covered | |
1 | Covered | T1,T8,T9 |
LINE 324
EXPRESSION (cmderr_q == CmdErrNone)
------------1-----------
-1- | Status | Tests |
0 | Not Covered | |
1 | Covered | T11,T12,T13 |
LINE 344
EXPRESSION (sbbusy_i || sbcs_q.sbbusyerror)
----1--- ---------2--------
-1- | -2- | Status | Tests |
0 | 0 | Covered | T14,T15,T16 |
0 | 1 | Not Covered | |
1 | 0 | Not Covered | |
LINE 348
EXPRESSION (sbcs_q.sberror == '0)
-----------1----------
-1- | Status | Tests |
0 | Not Covered | |
1 | Covered | T14,T15,T16 |
LINE 354
EXPRESSION (sbbusy_i || sbcs_q.sbbusyerror)
----1--- ---------2--------
-1- | -2- | Status | Tests |
0 | 0 | Not Covered | |
0 | 1 | Not Covered | |
1 | 0 | Not Covered | |
LINE 366
EXPRESSION (dmi_req_ready_o && dmi_req_valid_i && (dtm_op == DTM_WRITE))
-------1------- -------2------- ----------3----------
-1- | -2- | -3- | Status | Tests |
0 | 1 | 1 | Not Covered | |
1 | 0 | 1 | Covered | T1,T2,T3 |
1 | 1 | 0 | Covered | T1,T2,T3 |
1 | 1 | 1 | Covered | T1,T2,T3 |
LINE 366
SUB-EXPRESSION (dtm_op == DTM_WRITE)
----------1----------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T1,T2,T3 |
LINE 378
EXPRESSION (cmderr_q == CmdErrNone)
------------1-----------
-1- | Status | Tests |
0 | Not Covered | |
1 | Covered | T21,T22 |
LINE 405
EXPRESSION (cmderr_q == CmdErrNone)
------------1-----------
-1- | Status | Tests |
0 | Covered | T25,T26 |
1 | Covered | T27,T28,T29 |
LINE 419
EXPRESSION (cmderr_q == CmdErrNone)
------------1-----------
-1- | Status | Tests |
0 | Not Covered | |
1 | Covered | T30,T12,T28 |
LINE 433
EXPRESSION (cmderr_q == CmdErrNone)
------------1-----------
-1- | Status | Tests |
0 | Not Covered | |
1 | Covered | T31,T22,T32 |
LINE 450
EXPRESSION (cmderr_q == CmdErrNone)
------------1-----------
-1- | Status | Tests |
0 | Not Covered | |
1 | Covered | T3,T33,T34 |
LINE 464
EXPRESSION (sbcs_q.sbbusyerror & ((~sbcs.sbbusyerror)))
---------1-------- ----------2----------
-1- | -2- | Status | Tests |
0 | 1 | Covered | T14,T15,T16 |
1 | 0 | Not Covered | |
1 | 1 | Not Covered | |
LINE 465
EXPRESSION (((|sbcs.sberror)) ? 3'b0 : sbcs_q.sberror)
--------1--------
-1- | Status | Tests |
0 | Covered | T14,T15,T16 |
1 | Covered | T15,T37,T38 |
LINE 470
EXPRESSION (sbbusy_i || sbcs_q.sbbusyerror)
----1--- ---------2--------
-1- | -2- | Status | Tests |
0 | 0 | Covered | T14,T15,T16 |
0 | 1 | Not Covered | |
1 | 0 | Not Covered | |
LINE 475
EXPRESSION (sbcs_q.sberror == '0)
-----------1----------
-1- | Status | Tests |
0 | Not Covered | |
1 | Covered | T14,T15,T16 |
LINE 480
EXPRESSION (sbbusy_i || sbcs_q.sbbusyerror)
----1--- ---------2--------
-1- | -2- | Status | Tests |
0 | 0 | Not Covered | |
0 | 1 | Not Covered | |
1 | 0 | Not Covered | |
LINE 489
EXPRESSION (sbbusy_i || sbcs_q.sbbusyerror)
----1--- ---------2--------
-1- | -2- | Status | Tests |
0 | 0 | Covered | T14,T15,T16 |
0 | 1 | Not Covered | |
1 | 0 | Not Covered | |
LINE 494
EXPRESSION (sbcs_q.sberror == '0)
-----------1----------
-1- | Status | Tests |
0 | Not Covered | |
1 | Covered | T14,T15,T16 |
LINE 499
EXPRESSION (sbbusy_i || sbcs_q.sbbusyerror)
----1--- ---------2--------
-1- | -2- | Status | Tests |
0 | 0 | Not Covered | |
0 | 1 | Not Covered | |
1 | 0 | Not Covered | |
LINE 546
EXPRESSION (((!dmcontrol_q.resumereq)) && dmcontrol_d.resumereq)
-------------1------------ ----------2----------
-1- | -2- | Status | Tests |
0 | 1 | Covered | T5,T39,T24 |
1 | 0 | Covered | T1,T2,T3 |
1 | 1 | Covered | T5,T39,T24 |
LINE 549
EXPRESSION (dmcontrol_q.resumereq && resumeack_i)
----------1---------- -----2-----
-1- | -2- | Status | Tests |
0 | 1 | Covered | T5,T39,T24 |
1 | 0 | Covered | T5,T39,T24 |
1 | 1 | Covered | T5,T39,T24 |
LINE 625
EXPRESSION (SelectableHarts & havereset_d)
-------1------- -----2-----
-1- | -2- | Status | Tests |
- | 0 | Covered | T5,T23,T24 |
- | 1 | Covered | T1,T2,T3 |
Branch Coverage for Module :
dm_csrs
| Line No. | Total | Covered | Percent |
Branches |
|
85 |
49 |
57.65 |
IF |
112 |
2 |
1 |
50.00 |
IF |
129 |
2 |
1 |
50.00 |
IF |
146 |
2 |
1 |
50.00 |
IF |
292 |
26 |
11 |
42.31 |
IF |
366 |
34 |
17 |
50.00 |
IF |
510 |
2 |
2 |
100.00 |
IF |
515 |
2 |
2 |
100.00 |
IF |
520 |
2 |
2 |
100.00 |
IF |
527 |
2 |
2 |
100.00 |
IF |
531 |
2 |
2 |
100.00 |
IF |
546 |
2 |
2 |
100.00 |
IF |
549 |
2 |
2 |
100.00 |
IF |
572 |
2 |
1 |
50.00 |
IF |
611 |
3 |
3 |
100.00 |
112 if (hartsel_idx0 < 15'((NrHarts-1)/2**5+1)) begin
-1-
113 haltsum0 = halted_reshaped0[hartsel_idx0];
==>
114 end
MISSING_ELSE
==>
Branches:
-1- | Status | Tests |
1 |
Covered |
T1,T2,T3 |
0 |
Not Covered |
|
129 if (hartsel_idx1 < 10'(((NrHarts-1)/2**10+1))) begin
-1-
130 haltsum1 = halted_reshaped1[hartsel_idx1];
==>
131 end
MISSING_ELSE
==>
Branches:
-1- | Status | Tests |
1 |
Covered |
T1,T2,T3 |
0 |
Not Covered |
|
146 if (hartsel_idx2 < 5'(((NrHarts-1)/2**15+1))) begin
-1-
147 haltsum2 = halted_reshaped2[hartsel_idx2];
==>
148 end
MISSING_ELSE
==>
Branches:
-1- | Status | Tests |
1 |
Covered |
T1,T2,T3 |
0 |
Not Covered |
|
292 if (dmi_req_ready_o && dmi_req_valid_i && dtm_op == dm::DTM_READ) begin
-1-
293 unique case (dm_csr_addr) inside
-2-
294 [(dm::Data0):DataEnd]: begin
295 resp_queue_inp.data = data_q[$clog2(dm::DataCount)'(autoexecdata_idx)];
296 if (!cmdbusy_i) begin
-3-
297 // check whether we need to re-execute the command (just give a cmd_valid)
298 cmd_valid_d = abstractauto_q.autoexecdata[autoexecdata_idx];
==>
299 // An abstract command was executing while one of the data registers was read
300 end else begin
301 resp_queue_inp.resp = dm::DTM_BUSY;
302 if (cmderr_q == dm::CmdErrNone) begin
-4-
303 cmderr_d = dm::CmdErrBusy;
==>
304 end
MISSING_ELSE
==>
305 end
306 end
307 dm::DMControl: resp_queue_inp.data = dmcontrol_q;
==>
308 dm::DMStatus: resp_queue_inp.data = dmstatus;
==>
309 dm::Hartinfo: resp_queue_inp.data = hartinfo_aligned[selected_hart];
==>
310 dm::AbstractCS: resp_queue_inp.data = abstractcs;
==>
311 dm::AbstractAuto: resp_queue_inp.data = abstractauto_q;
==>
312 dm::Command: resp_queue_inp.data = '0;
==>
313 dm::NextDM: resp_queue_inp.data = next_dm_addr_i;
==>
314 [(dm::ProgBuf0):ProgBufEnd]: begin
315 resp_queue_inp.data = progbuf_q[dmi_req_i.addr[$clog2(dm::ProgBufSize)-1:0]];
316 if (!cmdbusy_i) begin
-5-
317 // check whether we need to re-execute the command (just give a cmd_valid)
318 // range of autoexecprogbuf is 31:16
319 cmd_valid_d = abstractauto_q.autoexecprogbuf[{1'b1, dmi_req_i.addr[3:0]}];
==>
320
321 // An abstract command was executing while one of the progbuf registers was read
322 end else begin
323 resp_queue_inp.resp = dm::DTM_BUSY;
324 if (cmderr_q == dm::CmdErrNone) begin
-6-
325 cmderr_d = dm::CmdErrBusy;
==>
326 end
MISSING_ELSE
==>
327 end
328 end
329 dm::HaltSum0: resp_queue_inp.data = haltsum0;
==>
330 dm::HaltSum1: resp_queue_inp.data = haltsum1;
==>
331 dm::HaltSum2: resp_queue_inp.data = haltsum2;
==>
332 dm::HaltSum3: resp_queue_inp.data = haltsum3;
==>
333 dm::SBCS: begin
334 resp_queue_inp.data = sbcs_q;
==>
335 end
336 dm::SBAddress0: begin
337 resp_queue_inp.data = sbaddr_q[31:0];
==>
338 end
339 dm::SBAddress1: begin
340 resp_queue_inp.data = sbaddr_q[63:32];
==>
341 end
342 dm::SBData0: begin
343 // access while the SBA was busy
344 if (sbbusy_i || sbcs_q.sbbusyerror) begin
-7-
345 sbcs_d.sbbusyerror = 1'b1;
==>
346 resp_queue_inp.resp = dm::DTM_BUSY;
347 end else begin
348 sbdata_read_valid_o = (sbcs_q.sberror == '0);
==>
349 resp_queue_inp.data = sbdata_q[31:0];
350 end
351 end
352 dm::SBData1: begin
353 // access while the SBA was busy
354 if (sbbusy_i || sbcs_q.sbbusyerror) begin
-8-
355 sbcs_d.sbbusyerror = 1'b1;
==>
356 resp_queue_inp.resp = dm::DTM_BUSY;
357 end else begin
358 resp_queue_inp.data = sbdata_q[63:32];
==>
359 end
360 end
361 default:;
==>
362 endcase
363 end
MISSING_ELSE
==>
Branches:
-1- | -2- | -3- | -4- | -5- | -6- | -7- | -8- | Status | Tests |
1 |
Data0 DataEnd |
1 |
- |
- |
- |
- |
- |
Covered |
T1,T6,T7 |
1 |
Data0 DataEnd |
0 |
1 |
- |
- |
- |
- |
Covered |
T1,T8,T9 |
1 |
Data0 DataEnd |
0 |
0 |
- |
- |
- |
- |
Not Covered |
|
1 |
DMControl |
- |
- |
- |
- |
- |
- |
Covered |
T1,T2,T3 |
1 |
DMStatus |
- |
- |
- |
- |
- |
- |
Covered |
T1,T4,T5 |
1 |
Hartinfo |
- |
- |
- |
- |
- |
- |
Not Covered |
|
1 |
AbstractCS |
- |
- |
- |
- |
- |
- |
Covered |
T1,T2,T3 |
1 |
AbstractAuto |
- |
- |
- |
- |
- |
- |
Not Covered |
|
1 |
Command |
- |
- |
- |
- |
- |
- |
Not Covered |
|
1 |
NextDM |
- |
- |
- |
- |
- |
- |
Not Covered |
|
1 |
ProgBuf0 ProgBufEnd |
- |
- |
1 |
- |
- |
- |
Covered |
T1,T7,T10 |
1 |
ProgBuf0 ProgBufEnd |
- |
- |
0 |
1 |
- |
- |
Covered |
T11,T12,T13 |
1 |
ProgBuf0 ProgBufEnd |
- |
- |
0 |
0 |
- |
- |
Not Covered |
|
1 |
HaltSum0 |
- |
- |
- |
- |
- |
- |
Not Covered |
|
1 |
HaltSum1 |
- |
- |
- |
- |
- |
- |
Not Covered |
|
1 |
HaltSum2 |
- |
- |
- |
- |
- |
- |
Not Covered |
|
1 |
HaltSum3 |
- |
- |
- |
- |
- |
- |
Not Covered |
|
1 |
SBCS |
- |
- |
- |
- |
- |
- |
Covered |
T14,T15,T16 |
1 |
SBAddress0 |
- |
- |
- |
- |
- |
- |
Covered |
T17,T18,T19 |
1 |
SBAddress1 |
- |
- |
- |
- |
- |
- |
Not Covered |
|
1 |
SBData0 |
- |
- |
- |
- |
1 |
- |
Not Covered |
|
1 |
SBData0 |
- |
- |
- |
- |
0 |
- |
Covered |
T14,T15,T16 |
1 |
SBData1 |
- |
- |
- |
- |
- |
1 |
Not Covered |
|
1 |
SBData1 |
- |
- |
- |
- |
- |
0 |
Not Covered |
|
1 |
default |
- |
- |
- |
- |
- |
- |
Not Covered |
|
0 |
- |
- |
- |
- |
- |
- |
- |
Covered |
T1,T2,T3 |
366 if (dmi_req_ready_o && dmi_req_valid_i && dtm_op == dm::DTM_WRITE) begin
-1-
367 unique case (dm_csr_addr) inside
-2-
368 [(dm::Data0):DataEnd]: begin
369 if (dm::DataCount > 0) begin
-3-
370 // attempts to write them while busy is set does not change their value
371 if (!cmdbusy_i) begin
-4-
372 data_d[dmi_req_i.addr[$clog2(dm::DataCount)-1:0]] = dmi_req_i.data;
==>
373 // check whether we need to re-execute the command (just give a cmd_valid)
374 cmd_valid_d = abstractauto_q.autoexecdata[autoexecdata_idx];
375 //An abstract command was executing while one of the data registers was written
376 end else begin
377 resp_queue_inp.resp = dm::DTM_BUSY;
378 if (cmderr_q == dm::CmdErrNone) begin
-5-
379 cmderr_d = dm::CmdErrBusy;
==>
380 end
MISSING_ELSE
==>
381 end
382 end
MISSING_ELSE
==>
383 end
384 dm::DMControl: begin
385 dmcontrol_d = dmi_req_i.data;
386 // clear the havreset of the selected hart
387 if (dmcontrol_d.ackhavereset) begin
-6-
388 havereset_d_aligned[selected_hart] = 1'b0;
==>
389 end
MISSING_ELSE
==>
390 end
391 dm::DMStatus:; // write are ignored to R/O register
==>
392 dm::Hartinfo:; // hartinfo is R/O
==>
393 // only command error is write-able
394 dm::AbstractCS: begin // W1C
395 // Gets set if an abstract command fails. The bits in this
396 // field remain set until they are cleared by writing 1 to
397 // them. No abstract command is started until the value is
398 // reset to 0.
399 a_abstractcs = dm::abstractcs_t'(dmi_req_i.data);
400 // reads during abstract command execution are not allowed
401 if (!cmdbusy_i) begin
-7-
402 cmderr_d = dm::cmderr_e'(~a_abstractcs.cmderr & cmderr_q);
==>
403 end else begin
404 resp_queue_inp.resp = dm::DTM_BUSY;
405 if (cmderr_q == dm::CmdErrNone) begin
-8-
406 cmderr_d = dm::CmdErrBusy;
==>
407 end
MISSING_ELSE
==>
408 end
409 end
410 dm::Command: begin
411 // writes are ignored if a command is already busy
412 if (!cmdbusy_i) begin
-9-
413 cmd_valid_d = 1'b1;
==>
414 command_d = dm::command_t'(dmi_req_i.data);
415 // if there was an attempted to write during a busy execution
416 // and the cmderror field is zero set the busy error
417 end else begin
418 resp_queue_inp.resp = dm::DTM_BUSY;
419 if (cmderr_q == dm::CmdErrNone) begin
-10-
420 cmderr_d = dm::CmdErrBusy;
==>
421 end
MISSING_ELSE
==>
422 end
423 end
424 dm::NextDM:; // nextdm is R/O
==>
425 dm::AbstractAuto: begin
426 // this field can only be written legally when there is no command executing
427 if (!cmdbusy_i) begin
-11-
428 abstractauto_d = 32'h0;
==>
429 abstractauto_d.autoexecdata = 12'(dmi_req_i.data[dm::DataCount-1:0]);
430 abstractauto_d.autoexecprogbuf = 16'(dmi_req_i.data[dm::ProgBufSize-1+16:16]);
431 end else begin
432 resp_queue_inp.resp = dm::DTM_BUSY;
433 if (cmderr_q == dm::CmdErrNone) begin
-12-
434 cmderr_d = dm::CmdErrBusy;
==>
435 end
MISSING_ELSE
==>
436 end
437 end
438 [(dm::ProgBuf0):ProgBufEnd]: begin
439 // attempts to write them while busy is set does not change their value
440 if (!cmdbusy_i) begin
-13-
441 progbuf_d[dmi_req_i.addr[$clog2(dm::ProgBufSize)-1:0]] = dmi_req_i.data;
==>
442 // check whether we need to re-execute the command (just give a cmd_valid)
443 // this should probably throw an error if executed during another command
444 // was busy
445 // range of autoexecprogbuf is 31:16
446 cmd_valid_d = abstractauto_q.autoexecprogbuf[{1'b1, dmi_req_i.addr[3:0]}];
447 //An abstract command was executing while one of the progbuf registers was written
448 end else begin
449 resp_queue_inp.resp = dm::DTM_BUSY;
450 if (cmderr_q == dm::CmdErrNone) begin
-14-
451 cmderr_d = dm::CmdErrBusy;
==>
452 end
MISSING_ELSE
==>
453 end
454 end
455 dm::SBCS: begin
456 // access while the SBA was busy
457 if (sbbusy_i) begin
-15-
458 sbcs_d.sbbusyerror = 1'b1;
==>
459 resp_queue_inp.resp = dm::DTM_BUSY;
460 end else begin
461 sbcs = dm::sbcs_t'(dmi_req_i.data);
462 sbcs_d = sbcs;
463 // R/W1C
464 sbcs_d.sbbusyerror = sbcs_q.sbbusyerror & (~sbcs.sbbusyerror);
465 sbcs_d.sberror = (|sbcs.sberror) ? 3'b0 : sbcs_q.sberror;
-16-
==>
==>
466 end
467 end
468 dm::SBAddress0: begin
469 // access while the SBA was busy
470 if (sbbusy_i || sbcs_q.sbbusyerror) begin
-17-
471 sbcs_d.sbbusyerror = 1'b1;
==>
472 resp_queue_inp.resp = dm::DTM_BUSY;
473 end else begin
474 sbaddr_d[31:0] = dmi_req_i.data;
==>
475 sbaddress_write_valid_o = (sbcs_q.sberror == '0);
476 end
477 end
478 dm::SBAddress1: begin
479 // access while the SBA was busy
480 if (sbbusy_i || sbcs_q.sbbusyerror) begin
-18-
481 sbcs_d.sbbusyerror = 1'b1;
==>
482 resp_queue_inp.resp = dm::DTM_BUSY;
483 end else begin
484 sbaddr_d[63:32] = dmi_req_i.data;
==>
485 end
486 end
487 dm::SBData0: begin
488 // access while the SBA was busy
489 if (sbbusy_i || sbcs_q.sbbusyerror) begin
-19-
490 sbcs_d.sbbusyerror = 1'b1;
==>
491 resp_queue_inp.resp = dm::DTM_BUSY;
492 end else begin
493 sbdata_d[31:0] = dmi_req_i.data;
==>
494 sbdata_write_valid_o = (sbcs_q.sberror == '0);
495 end
496 end
497 dm::SBData1: begin
498 // access while the SBA was busy
499 if (sbbusy_i || sbcs_q.sbbusyerror) begin
-20-
500 sbcs_d.sbbusyerror = 1'b1;
==>
501 resp_queue_inp.resp = dm::DTM_BUSY;
502 end else begin
503 sbdata_d[63:32] = dmi_req_i.data;
==>
504 end
505 end
506 default:;
==>
507 endcase
508 end
MISSING_ELSE
==>
Branches:
-1- | -2- | -3- | -4- | -5- | -6- | -7- | -8- | -9- | -10- | -11- | -12- | -13- | -14- | -15- | -16- | -17- | -18- | -19- | -20- | Status | Tests |
1 |
Data0 DataEnd |
1 |
1 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T1,T20,T7 |
1 |
Data0 DataEnd |
1 |
0 |
1 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T21,T22 |
1 |
Data0 DataEnd |
1 |
0 |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Not Covered |
|
1 |
Data0 DataEnd |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Not Covered |
|
1 |
DMControl |
- |
- |
- |
1 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T5,T23,T24 |
1 |
DMControl |
- |
- |
- |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T1,T2,T3 |
1 |
DMStatus |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Not Covered |
|
1 |
Hartinfo |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Not Covered |
|
1 |
AbstractCS |
- |
- |
- |
- |
1 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T1,T2,T3 |
1 |
AbstractCS |
- |
- |
- |
- |
0 |
1 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T27,T28,T29 |
1 |
AbstractCS |
- |
- |
- |
- |
0 |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T25,T26 |
1 |
Command |
- |
- |
- |
- |
- |
- |
1 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T1,T2,T3 |
1 |
Command |
- |
- |
- |
- |
- |
- |
0 |
1 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T30,T12,T28 |
1 |
Command |
- |
- |
- |
- |
- |
- |
0 |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Not Covered |
|
1 |
NextDM |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Not Covered |
|
1 |
AbstractAuto |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Not Covered |
|
1 |
AbstractAuto |
- |
- |
- |
- |
- |
- |
- |
- |
0 |
1 |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T31,T22,T32 |
1 |
AbstractAuto |
- |
- |
- |
- |
- |
- |
- |
- |
0 |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
Not Covered |
|
1 |
ProgBuf0 ProgBufEnd |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
- |
- |
- |
- |
- |
- |
- |
Covered |
T1,T20,T7 |
1 |
ProgBuf0 ProgBufEnd |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
0 |
1 |
- |
- |
- |
- |
- |
- |
Covered |
T3,T33,T34 |
1 |
ProgBuf0 ProgBufEnd |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
0 |
0 |
- |
- |
- |
- |
- |
- |
Not Covered |
|
1 |
SBCS |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
- |
- |
- |
- |
- |
Not Covered |
|
1 |
SBCS |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
0 |
1 |
- |
- |
- |
- |
Covered |
T15,T37,T38 |
1 |
SBCS |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
0 |
0 |
- |
- |
- |
- |
Covered |
T14,T15,T16 |
1 |
SBAddress0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
- |
- |
- |
Not Covered |
|
1 |
SBAddress0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
0 |
- |
- |
- |
Covered |
T14,T15,T16 |
1 |
SBAddress1 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
- |
- |
Not Covered |
|
1 |
SBAddress1 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
0 |
- |
- |
Not Covered |
|
1 |
SBData0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
- |
Not Covered |
|
1 |
SBData0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
0 |
- |
Covered |
T14,T15,T16 |
1 |
SBData1 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
Not Covered |
|
1 |
SBData1 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
0 |
Not Covered |
|
1 |
default |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Not Covered |
|
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T1,T2,T3 |
510 if (cmderror_valid_i) begin
-1-
511 cmderr_d = cmderror_i;
==>
512 end
MISSING_ELSE
==>
Branches:
-1- | Status | Tests |
1 |
Covered |
T2,T25,T35 |
0 |
Covered |
T1,T2,T3 |
515 if (data_valid_i) begin
-1-
516 data_d = data_i;
==>
517 end
MISSING_ELSE
==>
Branches:
-1- | Status | Tests |
1 |
Covered |
T1,T6,T10 |
0 |
Covered |
T1,T2,T3 |
520 if (ndmreset_ack_i) begin
-1-
521 havereset_d_aligned[NrHarts-1:0] = '1;
==>
522 end
MISSING_ELSE
==>
Branches:
-1- | Status | Tests |
1 |
Covered |
T1,T10,T36 |
0 |
Covered |
T1,T2,T3 |
527 if (sberror_valid_i) begin
-1-
528 sbcs_d.sberror = sberror_i;
==>
529 end
MISSING_ELSE
==>
Branches:
-1- | Status | Tests |
1 |
Covered |
T15,T37,T38 |
0 |
Covered |
T1,T2,T3 |
531 if (sbdata_valid_i) begin
-1-
532 sbdata_d = 64'(sbdata_i);
==>
533 end
MISSING_ELSE
==>
Branches:
-1- | Status | Tests |
1 |
Covered |
T14,T15,T16 |
0 |
Covered |
T1,T2,T3 |
546 if (!dmcontrol_q.resumereq && dmcontrol_d.resumereq) begin
-1-
547 clear_resumeack_o = 1'b1;
==>
548 end
MISSING_ELSE
==>
Branches:
-1- | Status | Tests |
1 |
Covered |
T5,T39,T24 |
0 |
Covered |
T1,T2,T3 |
549 if (dmcontrol_q.resumereq && resumeack_i) begin
-1-
550 dmcontrol_d.resumereq = 1'b0;
==>
551 end
MISSING_ELSE
==>
Branches:
-1- | Status | Tests |
1 |
Covered |
T5,T39,T24 |
0 |
Covered |
T1,T2,T3 |
572 if (selected_hart <= HartSelLen'(NrHarts-1)) begin
-1-
573 haltreq_o[selected_hart] = dmcontrol_q.haltreq;
==>
574 resumereq_o[selected_hart] = dmcontrol_q.resumereq;
575 end
MISSING_ELSE
==>
Branches:
-1- | Status | Tests |
1 |
Covered |
T1,T2,T3 |
0 |
Not Covered |
|
611 if (!rst_ni) begin
-1-
612 dmcontrol_q <= '0;
==>
613 // this is the only write-able bit during reset
614 cmderr_q <= dm::CmdErrNone;
615 command_q <= '0;
616 cmd_valid_q <= '0;
617 abstractauto_q <= '0;
618 progbuf_q <= '0;
619 data_q <= '0;
620 sbcs_q <= '{default: '0, sbaccess: 3'd2};
621 sbaddr_q <= '0;
622 sbdata_q <= '0;
623 havereset_q <= '1;
624 end else begin
625 havereset_q <= SelectableHarts & havereset_d;
626 // synchronous re-set of debug module, active-low, except for dmactive
627 if (!dmcontrol_q.dmactive) begin
-2-
628 dmcontrol_q.haltreq <= '0;
==>
629 dmcontrol_q.resumereq <= '0;
630 dmcontrol_q.hartreset <= '0;
631 dmcontrol_q.ackhavereset <= '0;
632 dmcontrol_q.zero1 <= '0;
633 dmcontrol_q.hasel <= '0;
634 dmcontrol_q.hartsello <= '0;
635 dmcontrol_q.hartselhi <= '0;
636 dmcontrol_q.zero0 <= '0;
637 dmcontrol_q.setresethaltreq <= '0;
638 dmcontrol_q.clrresethaltreq <= '0;
639 dmcontrol_q.ndmreset <= '0;
640 // this is the only write-able bit during reset
641 dmcontrol_q.dmactive <= dmcontrol_d.dmactive;
642 cmderr_q <= dm::CmdErrNone;
643 command_q <= '0;
644 cmd_valid_q <= '0;
645 abstractauto_q <= '0;
646 progbuf_q <= '0;
647 data_q <= '0;
648 sbcs_q <= '{default: '0, sbaccess: 3'd2};
649 sbaddr_q <= '0;
650 sbdata_q <= '0;
651 end else begin
652 dmcontrol_q <= dmcontrol_d;
==>
Branches:
-1- | -2- | Status | Tests |
1 |
- |
Covered |
T1,T2,T3 |
0 |
1 |
Covered |
T1,T2,T3 |
0 |
0 |
Covered |
T1,T2,T3 |
Line Coverage for Instance : tb.dut.u_dm_top.i_dm_csrs
| Line No. | Total | Covered | Percent |
TOTAL | | 277 | 239 | 86.28 |
CONT_ASSIGN | 90 | 1 | 1 | 100.00 |
ALWAYS | 107 | 7 | 7 | 100.00 |
ALWAYS | 120 | 8 | 8 | 100.00 |
ALWAYS | 137 | 8 | 8 | 100.00 |
ALWAYS | 153 | 4 | 4 | 100.00 |
CONT_ASSIGN | 182 | 1 | 1 | 100.00 |
CONT_ASSIGN | 183 | 1 | 1 | 100.00 |
CONT_ASSIGN | 184 | 1 | 1 | 100.00 |
CONT_ASSIGN | 185 | 1 | 1 | 100.00 |
CONT_ASSIGN | 186 | 1 | 1 | 100.00 |
CONT_ASSIGN | 187 | 1 | 1 | 100.00 |
CONT_ASSIGN | 189 | 1 | 1 | 100.00 |
CONT_ASSIGN | 195 | 1 | 1 | 100.00 |
CONT_ASSIGN | 196 | 1 | 1 | 100.00 |
CONT_ASSIGN | 197 | 1 | 1 | 100.00 |
CONT_ASSIGN | 199 | 1 | 1 | 100.00 |
CONT_ASSIGN | 200 | 1 | 1 | 100.00 |
ALWAYS | 204 | 2 | 0 | 0.00 |
CONT_ASSIGN | 215 | 1 | 1 | 100.00 |
CONT_ASSIGN | 217 | 1 | 1 | 100.00 |
CONT_ASSIGN | 221 | 1 | 1 | 100.00 |
ALWAYS | 228 | 173 | 138 | 79.77 |
ALWAYS | 568 | 6 | 6 | 100.00 |
CONT_ASSIGN | 578 | 1 | 1 | 100.00 |
CONT_ASSIGN | 579 | 1 | 1 | 100.00 |
CONT_ASSIGN | 580 | 1 | 1 | 100.00 |
CONT_ASSIGN | 581 | 1 | 1 | 100.00 |
CONT_ASSIGN | 582 | 1 | 1 | 100.00 |
CONT_ASSIGN | 584 | 1 | 1 | 100.00 |
CONT_ASSIGN | 587 | 1 | 0 | 0.00 |
ALWAYS | 611 | 46 | 46 | 100.00 |
89 dm::dtm_op_e dtm_op;
90 1/1 assign dtm_op = dm::dtm_op_e'(dmi_req_i.op);
Tests: T1 T2 T3
91
92 localparam dm::dm_csr_e DataEnd = dm::dm_csr_e'(dm::Data0 + {4'h0, dm::DataCount} - 8'h1);
93 localparam dm::dm_csr_e ProgBufEnd = dm::dm_csr_e'(dm::ProgBuf0 + {4'h0, dm::ProgBufSize} - 8'h1);
94
95 logic [31:0] haltsum0, haltsum1, haltsum2, haltsum3;
96 logic [((NrHarts-1)/2**5 + 1) * 32 - 1 : 0] halted;
97 logic [(NrHarts-1)/2**5:0][31:0] halted_reshaped0;
98 logic [(NrHarts-1)/2**10:0][31:0] halted_reshaped1;
99 logic [(NrHarts-1)/2**15:0][31:0] halted_reshaped2;
100 logic [((NrHarts-1)/2**10+1)*32-1:0] halted_flat1;
101 logic [((NrHarts-1)/2**15+1)*32-1:0] halted_flat2;
102 logic [31:0] halted_flat3;
103
104 // haltsum0
105 logic [14:0] hartsel_idx0;
106 always_comb begin : p_haltsum0
107 1/1 halted = '0;
Tests: T1 T2 T3
108 1/1 haltsum0 = '0;
Tests: T1 T2 T3
109 1/1 hartsel_idx0 = hartsel_o[19:5];
Tests: T1 T2 T3
110 1/1 halted[NrHarts-1:0] = halted_i;
Tests: T1 T2 T3
111 1/1 halted_reshaped0 = halted;
Tests: T1 T2 T3
112 1/1 if (hartsel_idx0 < 15'((NrHarts-1)/2**5+1)) begin
Tests: T1 T2 T3
113 1/1 haltsum0 = halted_reshaped0[hartsel_idx0];
Tests: T1 T2 T3
114 end
==> MISSING_ELSE
115 end
116
117 // haltsum1
118 logic [9:0] hartsel_idx1;
119 always_comb begin : p_reduction1
120 1/1 halted_flat1 = '0;
Tests: T1 T2 T3
121 1/1 haltsum1 = '0;
Tests: T1 T2 T3
122 1/1 hartsel_idx1 = hartsel_o[19:10];
Tests: T1 T2 T3
123
124 1/1 for (int unsigned k = 0; k < (NrHarts-1)/2**5+1; k++) begin
Tests: T1 T2 T3
125 1/1 halted_flat1[k] = |halted_reshaped0[k];
Tests: T1 T2 T3
126 end
127 1/1 halted_reshaped1 = halted_flat1;
Tests: T1 T2 T3
128
129 1/1 if (hartsel_idx1 < 10'(((NrHarts-1)/2**10+1))) begin
Tests: T1 T2 T3
130 1/1 haltsum1 = halted_reshaped1[hartsel_idx1];
Tests: T1 T2 T3
131 end
==> MISSING_ELSE
132 end
133
134 // haltsum2
135 logic [4:0] hartsel_idx2;
136 always_comb begin : p_reduction2
137 1/1 halted_flat2 = '0;
Tests: T1 T2 T3
138 1/1 haltsum2 = '0;
Tests: T1 T2 T3
139 1/1 hartsel_idx2 = hartsel_o[19:15];
Tests: T1 T2 T3
140
141 1/1 for (int unsigned k = 0; k < (NrHarts-1)/2**10+1; k++) begin
Tests: T1 T2 T3
142 1/1 halted_flat2[k] = |halted_reshaped1[k];
Tests: T1 T2 T3
143 end
144 1/1 halted_reshaped2 = halted_flat2;
Tests: T1 T2 T3
145
146 1/1 if (hartsel_idx2 < 5'(((NrHarts-1)/2**15+1))) begin
Tests: T1 T2 T3
147 1/1 haltsum2 = halted_reshaped2[hartsel_idx2];
Tests: T1 T2 T3
148 end
==> MISSING_ELSE
149 end
150
151 // haltsum3
152 always_comb begin : p_reduction3
153 1/1 halted_flat3 = '0;
Tests: T1 T2 T3
154 1/1 for (int unsigned k = 0; k < NrHarts/2**15+1; k++) begin
Tests: T1 T2 T3
155 1/1 halted_flat3[k] = |halted_reshaped2[k];
Tests: T1 T2 T3
156 end
157 1/1 haltsum3 = halted_flat3;
Tests: T1 T2 T3
158 end
159
160
161 dm::dmstatus_t dmstatus;
162 dm::dmcontrol_t dmcontrol_d, dmcontrol_q;
163 dm::abstractcs_t abstractcs;
164 dm::cmderr_e cmderr_d, cmderr_q;
165 dm::command_t command_d, command_q;
166 logic cmd_valid_d, cmd_valid_q;
167 dm::abstractauto_t abstractauto_d, abstractauto_q;
168 dm::sbcs_t sbcs_d, sbcs_q;
169 logic [63:0] sbaddr_d, sbaddr_q;
170 logic [63:0] sbdata_d, sbdata_q;
171
172 logic [NrHarts-1:0] havereset_d, havereset_q;
173 // program buffer
174 logic [dm::ProgBufSize-1:0][31:0] progbuf_d, progbuf_q;
175 logic [dm::DataCount-1:0][31:0] data_d, data_q;
176
177 logic [HartSelLen-1:0] selected_hart;
178
179 dm::dmi_resp_t resp_queue_inp;
180
181 // SBA
182 1/1 assign sbautoincrement_o = sbcs_q.sbautoincrement;
Tests: T1 T2 T3
183 1/1 assign sbreadonaddr_o = sbcs_q.sbreadonaddr;
Tests: T1 T2 T3
184 1/1 assign sbreadondata_o = sbcs_q.sbreadondata;
Tests: T1 T2 T3
185 1/1 assign sbaccess_o = sbcs_q.sbaccess;
Tests: T1 T2 T3
186 1/1 assign sbdata_o = sbdata_q[BusWidth-1:0];
Tests: T1 T2 T3
187 1/1 assign sbaddress_o = sbaddr_q[BusWidth-1:0];
Tests: T1 T2 T3
188
189 1/1 assign hartsel_o = {dmcontrol_q.hartselhi, dmcontrol_q.hartsello};
Tests: T1 T2 T3
190
191 // needed to avoid lint warnings
192 logic [NrHartsAligned-1:0] havereset_d_aligned, havereset_q_aligned,
193 resumeack_aligned, unavailable_aligned,
194 halted_aligned;
195 1/1 assign resumeack_aligned = NrHartsAligned'(resumeack_i);
Tests: T1 T2 T3
196 1/1 assign unavailable_aligned = NrHartsAligned'(unavailable_i);
Tests: T1 T4 T5
197 1/1 assign halted_aligned = NrHartsAligned'(halted_i);
Tests: T1 T2 T3
198
199 1/1 assign havereset_d = NrHarts'(havereset_d_aligned);
Tests: T1 T2 T3
200 1/1 assign havereset_q_aligned = NrHartsAligned'(havereset_q);
Tests: T1 T2 T3
201
202 dm::hartinfo_t [NrHartsAligned-1:0] hartinfo_aligned;
203 always_comb begin : p_hartinfo_align
204 0/1 ==> hartinfo_aligned = '0;
205 0/1 ==> hartinfo_aligned[NrHarts-1:0] = hartinfo_i;
206 end
207
208 // helper variables
209 dm::dm_csr_e dm_csr_addr;
210 dm::sbcs_t sbcs;
211 dm::abstractcs_t a_abstractcs;
212 logic [3:0] autoexecdata_idx; // 0 == Data0 ... 11 == Data11
213
214 // Get the data index, i.e. 0 for dm::Data0 up to 11 for dm::Data11
215 1/1 assign dm_csr_addr = dm::dm_csr_e'({1'b0, dmi_req_i.addr});
Tests: T1 T2 T3
216 logic unused_addr_bits;
217 1/1 assign unused_addr_bits = ^dmi_req_i.addr[31:$bits(dm_csr_addr)];
Tests: T1 T2 T3
218
219 // Xilinx Vivado 2020.1 does not allow subtraction of two enums; do the subtraction with logic
220 // types instead.
221 1/1 assign autoexecdata_idx = 4'({dm_csr_addr} - {dm::Data0});
Tests: T1 T2 T3
222
223 always_comb (*xprop_off *) begin : csr_read_write
224 // --------------------
225 // Static Values (R/O)
226 // --------------------
227 // dmstatus
228 1/1 dmstatus = '0;
Tests: T1 T2 T3
229 1/1 dmstatus.version = dm::DbgVersion013;
Tests: T1 T2 T3
230 // no authentication implemented
231 1/1 dmstatus.authenticated = 1'b1;
Tests: T1 T2 T3
232 // we do not support halt-on-reset sequence
233 1/1 dmstatus.hasresethaltreq = 1'b0;
Tests: T1 T2 T3
234 // TODO(zarubaf) things need to change here if we implement the array mask
235 1/1 dmstatus.allhavereset = havereset_q_aligned[selected_hart];
Tests: T1 T2 T3
236 1/1 dmstatus.anyhavereset = havereset_q_aligned[selected_hart];
Tests: T1 T2 T3
237
238 1/1 dmstatus.allresumeack = resumeack_aligned[selected_hart];
Tests: T1 T2 T3
239 1/1 dmstatus.anyresumeack = resumeack_aligned[selected_hart];
Tests: T1 T2 T3
240
241 1/1 dmstatus.allunavail = unavailable_aligned[selected_hart];
Tests: T1 T2 T3
242 1/1 dmstatus.anyunavail = unavailable_aligned[selected_hart];
Tests: T1 T2 T3
243
244 // as soon as we are out of the legal Hart region tell the debugger
245 // that there are only non-existent harts
246 1/1 dmstatus.allnonexistent = logic'(32'(hartsel_o) > (NrHarts - 1));
Tests: T1 T2 T3
247 1/1 dmstatus.anynonexistent = logic'(32'(hartsel_o) > (NrHarts - 1));
Tests: T1 T2 T3
248
249 // We are not allowed to be in multiple states at once. This is a to
250 // make the running/halted and unavailable states exclusive.
251 1/1 dmstatus.allhalted = halted_aligned[selected_hart] & ~unavailable_aligned[selected_hart];
Tests: T1 T2 T3
252 1/1 dmstatus.anyhalted = halted_aligned[selected_hart] & ~unavailable_aligned[selected_hart];
Tests: T1 T2 T3
253
254 1/1 dmstatus.allrunning = ~halted_aligned[selected_hart] & ~unavailable_aligned[selected_hart];
Tests: T1 T2 T3
255 1/1 dmstatus.anyrunning = ~halted_aligned[selected_hart] & ~unavailable_aligned[selected_hart];
Tests: T1 T2 T3
256
257 // abstractcs
258 1/1 abstractcs = '0;
Tests: T1 T2 T3
259 1/1 abstractcs.datacount = dm::DataCount;
Tests: T1 T2 T3
260 1/1 abstractcs.progbufsize = dm::ProgBufSize;
Tests: T1 T2 T3
261 1/1 abstractcs.busy = cmdbusy_i;
Tests: T1 T2 T3
262 1/1 abstractcs.cmderr = cmderr_q;
Tests: T1 T2 T3
263
264 // abstractautoexec
265 1/1 abstractauto_d = abstractauto_q;
Tests: T1 T2 T3
266 1/1 abstractauto_d.zero0 = '0;
Tests: T1 T2 T3
267
268 // default assignments
269 1/1 havereset_d_aligned = NrHartsAligned'(havereset_q);
Tests: T1 T2 T3
270 1/1 dmcontrol_d = dmcontrol_q;
Tests: T1 T2 T3
271 1/1 cmderr_d = cmderr_q;
Tests: T1 T2 T3
272 1/1 command_d = command_q;
Tests: T1 T2 T3
273 1/1 progbuf_d = progbuf_q;
Tests: T1 T2 T3
274 1/1 data_d = data_q;
Tests: T1 T2 T3
275 1/1 sbcs_d = sbcs_q;
Tests: T1 T2 T3
276 1/1 sbaddr_d = 64'(sbaddress_i);
Tests: T1 T2 T3
277 1/1 sbdata_d = sbdata_q;
Tests: T1 T2 T3
278
279 1/1 resp_queue_inp.data = 32'h0;
Tests: T1 T2 T3
280 1/1 resp_queue_inp.resp = dm::DTM_SUCCESS;
Tests: T1 T2 T3
281 1/1 cmd_valid_d = 1'b0;
Tests: T1 T2 T3
282 1/1 sbaddress_write_valid_o = 1'b0;
Tests: T1 T2 T3
283 1/1 sbdata_read_valid_o = 1'b0;
Tests: T1 T2 T3
284 1/1 sbdata_write_valid_o = 1'b0;
Tests: T1 T2 T3
285 1/1 clear_resumeack_o = 1'b0;
Tests: T1 T2 T3
286
287 // helper variables
288 1/1 sbcs = '0;
Tests: T1 T2 T3
289 1/1 a_abstractcs = '0;
Tests: T1 T2 T3
290
291 // reads
292 1/1 if (dmi_req_ready_o && dmi_req_valid_i && dtm_op == dm::DTM_READ) begin
Tests: T1 T2 T3
293 1/1 unique case (dm_csr_addr) inside
Tests: T1 T2 T3
294 [(dm::Data0):DataEnd]: begin
295 1/1 resp_queue_inp.data = data_q[$clog2(dm::DataCount)'(autoexecdata_idx)];
Tests: T1 T6 T7
296 1/1 if (!cmdbusy_i) begin
Tests: T1 T6 T7
297 // check whether we need to re-execute the command (just give a cmd_valid)
298 1/1 cmd_valid_d = abstractauto_q.autoexecdata[autoexecdata_idx];
Tests: T1 T6 T7
299 // An abstract command was executing while one of the data registers was read
300 end else begin
301 1/1 resp_queue_inp.resp = dm::DTM_BUSY;
Tests: T1 T8 T9
302 1/1 if (cmderr_q == dm::CmdErrNone) begin
Tests: T1 T8 T9
303 1/1 cmderr_d = dm::CmdErrBusy;
Tests: T1 T8 T9
304 end
==> MISSING_ELSE
305 end
306 end
307 1/1 dm::DMControl: resp_queue_inp.data = dmcontrol_q;
Tests: T1 T2 T3
308 1/1 dm::DMStatus: resp_queue_inp.data = dmstatus;
Tests: T1 T4 T5
309 0/1 ==> dm::Hartinfo: resp_queue_inp.data = hartinfo_aligned[selected_hart];
310 1/1 dm::AbstractCS: resp_queue_inp.data = abstractcs;
Tests: T1 T2 T3
311 0/1 ==> dm::AbstractAuto: resp_queue_inp.data = abstractauto_q;
312 0/1 ==> dm::Command: resp_queue_inp.data = '0;
313 0/1 ==> dm::NextDM: resp_queue_inp.data = next_dm_addr_i;
314 [(dm::ProgBuf0):ProgBufEnd]: begin
315 1/1 resp_queue_inp.data = progbuf_q[dmi_req_i.addr[$clog2(dm::ProgBufSize)-1:0]];
Tests: T1 T7 T10
316 1/1 if (!cmdbusy_i) begin
Tests: T1 T7 T10
317 // check whether we need to re-execute the command (just give a cmd_valid)
318 // range of autoexecprogbuf is 31:16
319 1/1 cmd_valid_d = abstractauto_q.autoexecprogbuf[{1'b1, dmi_req_i.addr[3:0]}];
Tests: T1 T7 T10
320
321 // An abstract command was executing while one of the progbuf registers was read
322 end else begin
323 1/1 resp_queue_inp.resp = dm::DTM_BUSY;
Tests: T11 T12 T13
324 1/1 if (cmderr_q == dm::CmdErrNone) begin
Tests: T11 T12 T13
325 1/1 cmderr_d = dm::CmdErrBusy;
Tests: T11 T12 T13
326 end
==> MISSING_ELSE
327 end
328 end
329 0/1 ==> dm::HaltSum0: resp_queue_inp.data = haltsum0;
330 0/1 ==> dm::HaltSum1: resp_queue_inp.data = haltsum1;
331 0/1 ==> dm::HaltSum2: resp_queue_inp.data = haltsum2;
332 0/1 ==> dm::HaltSum3: resp_queue_inp.data = haltsum3;
333 dm::SBCS: begin
334 1/1 resp_queue_inp.data = sbcs_q;
Tests: T14 T15 T16
335 end
336 dm::SBAddress0: begin
337 1/1 resp_queue_inp.data = sbaddr_q[31:0];
Tests: T17 T18 T19
338 end
339 dm::SBAddress1: begin
340 0/1 ==> resp_queue_inp.data = sbaddr_q[63:32];
341 end
342 dm::SBData0: begin
343 // access while the SBA was busy
344 1/1 if (sbbusy_i || sbcs_q.sbbusyerror) begin
Tests: T14 T15 T16
345 0/1 ==> sbcs_d.sbbusyerror = 1'b1;
346 0/1 ==> resp_queue_inp.resp = dm::DTM_BUSY;
347 end else begin
348 1/1 sbdata_read_valid_o = (sbcs_q.sberror == '0);
Tests: T14 T15 T16
349 1/1 resp_queue_inp.data = sbdata_q[31:0];
Tests: T14 T15 T16
350 end
351 end
352 dm::SBData1: begin
353 // access while the SBA was busy
354 0/1 ==> if (sbbusy_i || sbcs_q.sbbusyerror) begin
355 0/1 ==> sbcs_d.sbbusyerror = 1'b1;
356 0/1 ==> resp_queue_inp.resp = dm::DTM_BUSY;
357 end else begin
358 0/1 ==> resp_queue_inp.data = sbdata_q[63:32];
359 end
360 end
361 default:;
362 endcase
363 end
MISSING_ELSE
364
365 // write
366 1/1 if (dmi_req_ready_o && dmi_req_valid_i && dtm_op == dm::DTM_WRITE) begin
Tests: T1 T2 T3
367 1/1 unique case (dm_csr_addr) inside
Tests: T1 T2 T3
368 [(dm::Data0):DataEnd]: begin
369 1/1 if (dm::DataCount > 0) begin
Tests: T1 T20 T7
370 // attempts to write them while busy is set does not change their value
371 1/1 if (!cmdbusy_i) begin
Tests: T1 T20 T7
372 1/1 data_d[dmi_req_i.addr[$clog2(dm::DataCount)-1:0]] = dmi_req_i.data;
Tests: T1 T20 T7
373 // check whether we need to re-execute the command (just give a cmd_valid)
374 1/1 cmd_valid_d = abstractauto_q.autoexecdata[autoexecdata_idx];
Tests: T1 T20 T7
375 //An abstract command was executing while one of the data registers was written
376 end else begin
377 1/1 resp_queue_inp.resp = dm::DTM_BUSY;
Tests: T21 T22
378 1/1 if (cmderr_q == dm::CmdErrNone) begin
Tests: T21 T22
379 1/1 cmderr_d = dm::CmdErrBusy;
Tests: T21 T22
380 end
==> MISSING_ELSE
381 end
382 end
==> MISSING_ELSE
383 end
384 dm::DMControl: begin
385 1/1 dmcontrol_d = dmi_req_i.data;
Tests: T1 T2 T3
386 // clear the havreset of the selected hart
387 1/1 if (dmcontrol_d.ackhavereset) begin
Tests: T1 T2 T3
388 1/1 havereset_d_aligned[selected_hart] = 1'b0;
Tests: T5 T23 T24
389 end
MISSING_ELSE
390 end
391 0/1 ==> dm::DMStatus:; // write are ignored to R/O register
392 0/1 ==> dm::Hartinfo:; // hartinfo is R/O
393 // only command error is write-able
394 dm::AbstractCS: begin // W1C
395 // Gets set if an abstract command fails. The bits in this
396 // field remain set until they are cleared by writing 1 to
397 // them. No abstract command is started until the value is
398 // reset to 0.
399 1/1 a_abstractcs = dm::abstractcs_t'(dmi_req_i.data);
Tests: T1 T2 T3
400 // reads during abstract command execution are not allowed
401 1/1 if (!cmdbusy_i) begin
Tests: T1 T2 T3
402 1/1 cmderr_d = dm::cmderr_e'(~a_abstractcs.cmderr & cmderr_q);
Tests: T1 T2 T3
403 end else begin
404 1/1 resp_queue_inp.resp = dm::DTM_BUSY;
Tests: T25 T26 T27
405 1/1 if (cmderr_q == dm::CmdErrNone) begin
Tests: T25 T26 T27
406 1/1 cmderr_d = dm::CmdErrBusy;
Tests: T27 T28 T29
407 end
MISSING_ELSE
408 end
409 end
410 dm::Command: begin
411 // writes are ignored if a command is already busy
412 1/1 if (!cmdbusy_i) begin
Tests: T1 T2 T3
413 1/1 cmd_valid_d = 1'b1;
Tests: T1 T2 T3
414 1/1 command_d = dm::command_t'(dmi_req_i.data);
Tests: T1 T2 T3
415 // if there was an attempted to write during a busy execution
416 // and the cmderror field is zero set the busy error
417 end else begin
418 1/1 resp_queue_inp.resp = dm::DTM_BUSY;
Tests: T30 T12 T28
419 1/1 if (cmderr_q == dm::CmdErrNone) begin
Tests: T30 T12 T28
420 1/1 cmderr_d = dm::CmdErrBusy;
Tests: T30 T12 T28
421 end
==> MISSING_ELSE
422 end
423 end
424 0/1 ==> dm::NextDM:; // nextdm is R/O
425 dm::AbstractAuto: begin
426 // this field can only be written legally when there is no command executing
427 1/1 if (!cmdbusy_i) begin
Tests: T31 T22 T32
428 0/1 ==> abstractauto_d = 32'h0;
429 0/1 ==> abstractauto_d.autoexecdata = 12'(dmi_req_i.data[dm::DataCount-1:0]);
430 0/1 ==> abstractauto_d.autoexecprogbuf = 16'(dmi_req_i.data[dm::ProgBufSize-1+16:16]);
431 end else begin
432 1/1 resp_queue_inp.resp = dm::DTM_BUSY;
Tests: T31 T22 T32
433 1/1 if (cmderr_q == dm::CmdErrNone) begin
Tests: T31 T22 T32
434 1/1 cmderr_d = dm::CmdErrBusy;
Tests: T31 T22 T32
435 end
==> MISSING_ELSE
436 end
437 end
438 [(dm::ProgBuf0):ProgBufEnd]: begin
439 // attempts to write them while busy is set does not change their value
440 1/1 if (!cmdbusy_i) begin
Tests: T1 T3 T20
441 1/1 progbuf_d[dmi_req_i.addr[$clog2(dm::ProgBufSize)-1:0]] = dmi_req_i.data;
Tests: T1 T20 T7
442 // check whether we need to re-execute the command (just give a cmd_valid)
443 // this should probably throw an error if executed during another command
444 // was busy
445 // range of autoexecprogbuf is 31:16
446 1/1 cmd_valid_d = abstractauto_q.autoexecprogbuf[{1'b1, dmi_req_i.addr[3:0]}];
Tests: T1 T20 T7
447 //An abstract command was executing while one of the progbuf registers was written
448 end else begin
449 1/1 resp_queue_inp.resp = dm::DTM_BUSY;
Tests: T3 T33 T34
450 1/1 if (cmderr_q == dm::CmdErrNone) begin
Tests: T3 T33 T34
451 1/1 cmderr_d = dm::CmdErrBusy;
Tests: T3 T33 T34
452 end
==> MISSING_ELSE
453 end
454 end
455 dm::SBCS: begin
456 // access while the SBA was busy
457 1/1 if (sbbusy_i) begin
Tests: T14 T15 T16
458 0/1 ==> sbcs_d.sbbusyerror = 1'b1;
459 0/1 ==> resp_queue_inp.resp = dm::DTM_BUSY;
460 end else begin
461 1/1 sbcs = dm::sbcs_t'(dmi_req_i.data);
Tests: T14 T15 T16
462 1/1 sbcs_d = sbcs;
Tests: T14 T15 T16
463 // R/W1C
464 1/1 sbcs_d.sbbusyerror = sbcs_q.sbbusyerror & (~sbcs.sbbusyerror);
Tests: T14 T15 T16
465 1/1 sbcs_d.sberror = (|sbcs.sberror) ? 3'b0 : sbcs_q.sberror;
Tests: T14 T15 T16
466 end
467 end
468 dm::SBAddress0: begin
469 // access while the SBA was busy
470 1/1 if (sbbusy_i || sbcs_q.sbbusyerror) begin
Tests: T14 T15 T16
471 0/1 ==> sbcs_d.sbbusyerror = 1'b1;
472 0/1 ==> resp_queue_inp.resp = dm::DTM_BUSY;
473 end else begin
474 1/1 sbaddr_d[31:0] = dmi_req_i.data;
Tests: T14 T15 T16
475 1/1 sbaddress_write_valid_o = (sbcs_q.sberror == '0);
Tests: T14 T15 T16
476 end
477 end
478 dm::SBAddress1: begin
479 // access while the SBA was busy
480 0/1 ==> if (sbbusy_i || sbcs_q.sbbusyerror) begin
481 0/1 ==> sbcs_d.sbbusyerror = 1'b1;
482 0/1 ==> resp_queue_inp.resp = dm::DTM_BUSY;
483 end else begin
484 0/1 ==> sbaddr_d[63:32] = dmi_req_i.data;
485 end
486 end
487 dm::SBData0: begin
488 // access while the SBA was busy
489 1/1 if (sbbusy_i || sbcs_q.sbbusyerror) begin
Tests: T14 T15 T16
490 0/1 ==> sbcs_d.sbbusyerror = 1'b1;
491 0/1 ==> resp_queue_inp.resp = dm::DTM_BUSY;
492 end else begin
493 1/1 sbdata_d[31:0] = dmi_req_i.data;
Tests: T14 T15 T16
494 1/1 sbdata_write_valid_o = (sbcs_q.sberror == '0);
Tests: T14 T15 T16
495 end
496 end
497 dm::SBData1: begin
498 // access while the SBA was busy
499 0/1 ==> if (sbbusy_i || sbcs_q.sbbusyerror) begin
500 0/1 ==> sbcs_d.sbbusyerror = 1'b1;
501 0/1 ==> resp_queue_inp.resp = dm::DTM_BUSY;
502 end else begin
503 0/1 ==> sbdata_d[63:32] = dmi_req_i.data;
504 end
505 end
506 default:;
507 endcase
508 end
MISSING_ELSE
509 // hart threw a command error and has precedence over bus writes
510 1/1 if (cmderror_valid_i) begin
Tests: T1 T2 T3
511 1/1 cmderr_d = cmderror_i;
Tests: T2 T25 T35
512 end
MISSING_ELSE
513
514 // update data registers
515 1/1 if (data_valid_i) begin
Tests: T1 T2 T3
516 1/1 data_d = data_i;
Tests: T1 T6 T10
517 end
MISSING_ELSE
518
519 // set the havereset flag when the ndmreset completed
520 1/1 if (ndmreset_ack_i) begin
Tests: T1 T2 T3
521 1/1 havereset_d_aligned[NrHarts-1:0] = '1;
Tests: T1 T10 T36
522 end
MISSING_ELSE
523 // -------------
524 // System Bus
525 // -------------
526 // set bus error
527 1/1 if (sberror_valid_i) begin
Tests: T1 T2 T3
528 1/1 sbcs_d.sberror = sberror_i;
Tests: T15 T37 T38
529 end
MISSING_ELSE
530 // update read data
531 1/1 if (sbdata_valid_i) begin
Tests: T1 T2 T3
532 1/1 sbdata_d = 64'(sbdata_i);
Tests: T14 T15 T16
533 end
MISSING_ELSE
534
535 // dmcontrol
536 // TODO(zarubaf) we currently do not implement the hartarry mask
537 1/1 dmcontrol_d.hasel = 1'b0;
Tests: T1 T2 T3
538 // we do not support resetting an individual hart
539 1/1 dmcontrol_d.hartreset = 1'b0;
Tests: T1 T2 T3
540 1/1 dmcontrol_d.setresethaltreq = 1'b0;
Tests: T1 T2 T3
541 1/1 dmcontrol_d.clrresethaltreq = 1'b0;
Tests: T1 T2 T3
542 1/1 dmcontrol_d.zero1 = '0;
Tests: T1 T2 T3
543 1/1 dmcontrol_d.zero0 = '0;
Tests: T1 T2 T3
544 // Non-writeable, clear only
545 1/1 dmcontrol_d.ackhavereset = 1'b0;
Tests: T1 T2 T3
546 1/1 if (!dmcontrol_q.resumereq && dmcontrol_d.resumereq) begin
Tests: T1 T2 T3
547 1/1 clear_resumeack_o = 1'b1;
Tests: T5 T39 T24
548 end
MISSING_ELSE
549 1/1 if (dmcontrol_q.resumereq && resumeack_i) begin
Tests: T1 T2 T3
550 1/1 dmcontrol_d.resumereq = 1'b0;
Tests: T5 T39 T24
551 end
MISSING_ELSE
552 // WARL behavior of hartsel, depending on NrHarts.
553 // If NrHarts = 1 this is just masked to all-zeros.
554 1/1 {dmcontrol_d.hartselhi, dmcontrol_d.hartsello} &= (2**$clog2(NrHarts))-1;
Tests: T1 T2 T3
555 // static values for dcsr
556 1/1 sbcs_d.sbversion = 3'd1;
Tests: T1 T2 T3
557 1/1 sbcs_d.sbbusy = sbbusy_i;
Tests: T1 T2 T3
558 1/1 sbcs_d.sbasize = $bits(sbcs_d.sbasize)'(BusWidth);
Tests: T1 T2 T3
559 1/1 sbcs_d.sbaccess128 = logic'(BusWidth >= 32'd128);
Tests: T1 T2 T3
560 1/1 sbcs_d.sbaccess64 = logic'(BusWidth >= 32'd64);
Tests: T1 T2 T3
561 1/1 sbcs_d.sbaccess32 = logic'(BusWidth >= 32'd32);
Tests: T1 T2 T3
562 1/1 sbcs_d.sbaccess16 = logic'(BusWidth >= 32'd16);
Tests: T1 T2 T3
563 1/1 sbcs_d.sbaccess8 = logic'(BusWidth >= 32'd8);
Tests: T1 T2 T3
564 end
565
566 // output multiplexer
567 always_comb begin : p_outmux
568 1/1 selected_hart = hartsel_o[HartSelLen-1:0];
Tests: T1 T2 T3
569 // default assignment
570 1/1 haltreq_o = '0;
Tests: T1 T2 T3
571 1/1 resumereq_o = '0;
Tests: T1 T2 T3
572 1/1 if (selected_hart <= HartSelLen'(NrHarts-1)) begin
Tests: T1 T2 T3
573 1/1 haltreq_o[selected_hart] = dmcontrol_q.haltreq;
Tests: T1 T2 T3
574 1/1 resumereq_o[selected_hart] = dmcontrol_q.resumereq;
Tests: T1 T2 T3
575 end
==> MISSING_ELSE
576 end
577
578 1/1 assign dmactive_o = dmcontrol_q.dmactive;
Tests: T1 T2 T3
579 1/1 assign cmd_o = command_q;
Tests: T1 T2 T3
580 1/1 assign cmd_valid_o = cmd_valid_q;
Tests: T1 T2 T3
581 1/1 assign progbuf_o = progbuf_q;
Tests: T1 T2 T3
582 1/1 assign data_o = data_q;
Tests: T1 T2 T3
583
584 1/1 assign ndmreset_o = dmcontrol_q.ndmreset;
Tests: T1 T2 T3
585
586 logic unused_testmode;
587 0/1 ==> assign unused_testmode = testmode_i;
588
589 // response FIFO
590 prim_fifo_sync #(
591 .Width ($bits(dmi_resp_o)),
592 .Pass (1'b0),
593 .Depth (2)
594 ) i_fifo (
595 .clk_i ( clk_i ),
596 .rst_ni ( dmi_rst_ni ), // reset only when system is re-set
597 .clr_i ( 1'b0 ),
598 .wdata_i ( resp_queue_inp ),
599 .wvalid_i( dmi_req_valid_i ),
600 .wready_o( dmi_req_ready_o ),
601 .rdata_o ( dmi_resp_o ),
602 .rvalid_o( dmi_resp_valid_o ),
603 .rready_i( dmi_resp_ready_i ),
604 .full_o ( ), // Unused
605 .depth_o ( ), // Unused
606 .err_o ( ) // Unused
607 );
608
609 always_ff @(posedge clk_i or negedge rst_ni) begin : p_regs
610 // PoR
611 1/1 if (!rst_ni) begin
Tests: T1 T2 T3
612 1/1 dmcontrol_q <= '0;
Tests: T1 T2 T3
613 // this is the only write-able bit during reset
614 1/1 cmderr_q <= dm::CmdErrNone;
Tests: T1 T2 T3
615 1/1 command_q <= '0;
Tests: T1 T2 T3
616 1/1 cmd_valid_q <= '0;
Tests: T1 T2 T3
617 1/1 abstractauto_q <= '0;
Tests: T1 T2 T3
618 1/1 progbuf_q <= '0;
Tests: T1 T2 T3
619 1/1 data_q <= '0;
Tests: T1 T2 T3
620 1/1 sbcs_q <= '{default: '0, sbaccess: 3'd2};
Tests: T1 T2 T3
621 1/1 sbaddr_q <= '0;
Tests: T1 T2 T3
622 1/1 sbdata_q <= '0;
Tests: T1 T2 T3
623 1/1 havereset_q <= '1;
Tests: T1 T2 T3
624 end else begin
625 1/1 havereset_q <= SelectableHarts & havereset_d;
Tests: T1 T2 T3
626 // synchronous re-set of debug module, active-low, except for dmactive
627 1/1 if (!dmcontrol_q.dmactive) begin
Tests: T1 T2 T3
628 1/1 dmcontrol_q.haltreq <= '0;
Tests: T1 T2 T3
629 1/1 dmcontrol_q.resumereq <= '0;
Tests: T1 T2 T3
630 1/1 dmcontrol_q.hartreset <= '0;
Tests: T1 T2 T3
631 1/1 dmcontrol_q.ackhavereset <= '0;
Tests: T1 T2 T3
632 1/1 dmcontrol_q.zero1 <= '0;
Tests: T1 T2 T3
633 1/1 dmcontrol_q.hasel <= '0;
Tests: T1 T2 T3
634 1/1 dmcontrol_q.hartsello <= '0;
Tests: T1 T2 T3
635 1/1 dmcontrol_q.hartselhi <= '0;
Tests: T1 T2 T3
636 1/1 dmcontrol_q.zero0 <= '0;
Tests: T1 T2 T3
637 1/1 dmcontrol_q.setresethaltreq <= '0;
Tests: T1 T2 T3
638 1/1 dmcontrol_q.clrresethaltreq <= '0;
Tests: T1 T2 T3
639 1/1 dmcontrol_q.ndmreset <= '0;
Tests: T1 T2 T3
640 // this is the only write-able bit during reset
641 1/1 dmcontrol_q.dmactive <= dmcontrol_d.dmactive;
Tests: T1 T2 T3
642 1/1 cmderr_q <= dm::CmdErrNone;
Tests: T1 T2 T3
643 1/1 command_q <= '0;
Tests: T1 T2 T3
644 1/1 cmd_valid_q <= '0;
Tests: T1 T2 T3
645 1/1 abstractauto_q <= '0;
Tests: T1 T2 T3
646 1/1 progbuf_q <= '0;
Tests: T1 T2 T3
647 1/1 data_q <= '0;
Tests: T1 T2 T3
648 1/1 sbcs_q <= '{default: '0, sbaccess: 3'd2};
Tests: T1 T2 T3
649 1/1 sbaddr_q <= '0;
Tests: T1 T2 T3
650 1/1 sbdata_q <= '0;
Tests: T1 T2 T3
651 end else begin
652 1/1 dmcontrol_q <= dmcontrol_d;
Tests: T1 T2 T3
653 1/1 cmderr_q <= cmderr_d;
Tests: T1 T2 T3
654 1/1 command_q <= command_d;
Tests: T1 T2 T3
655 1/1 cmd_valid_q <= cmd_valid_d;
Tests: T1 T2 T3
656 1/1 abstractauto_q <= abstractauto_d;
Tests: T1 T2 T3
657 1/1 progbuf_q <= progbuf_d;
Tests: T1 T2 T3
658 1/1 data_q <= data_d;
Tests: T1 T2 T3
659 1/1 sbcs_q <= sbcs_d;
Tests: T1 T2 T3
660 1/1 sbaddr_q <= sbaddr_d;
Tests: T1 T2 T3
661 1/1 sbdata_q <= sbdata_d;
Tests: T1 T2 T3
Cond Coverage for Instance : tb.dut.u_dm_top.i_dm_csrs
| Total | Covered | Percent |
Conditions | 75 | 47 | 62.67 |
Logical | 75 | 47 | 62.67 |
Non-Logical | 0 | 0 | |
Event | 0 | 0 | |
LINE 251
EXPRESSION (halted_aligned[selected_hart] & ((~unavailable_aligned[selected_hart])))
--------------1-------------- -------------------2-------------------
-1- | -2- | Status | Tests |
0 | 1 | Covered | T1,T2,T3 |
1 | 0 | Covered | T1,T40,T41 |
1 | 1 | Covered | T2,T3,T25 |
LINE 252
EXPRESSION (halted_aligned[selected_hart] & ((~unavailable_aligned[selected_hart])))
--------------1-------------- -------------------2-------------------
-1- | -2- | Status | Tests |
0 | 1 | Covered | T1,T2,T3 |
1 | 0 | Covered | T1,T40,T41 |
1 | 1 | Covered | T2,T3,T25 |
LINE 254
EXPRESSION (((~halted_aligned[selected_hart])) & ((~unavailable_aligned[selected_hart])))
-----------------1---------------- -------------------2-------------------
-1- | -2- | Status | Tests |
0 | 1 | Covered | T2,T3,T25 |
1 | 0 | Covered | T1,T4,T6 |
1 | 1 | Covered | T1,T2,T3 |
LINE 255
EXPRESSION (((~halted_aligned[selected_hart])) & ((~unavailable_aligned[selected_hart])))
-----------------1---------------- -------------------2-------------------
-1- | -2- | Status | Tests |
0 | 1 | Covered | T2,T3,T25 |
1 | 0 | Covered | T1,T4,T6 |
1 | 1 | Covered | T1,T2,T3 |
LINE 292
EXPRESSION (dmi_req_ready_o && dmi_req_valid_i && (dtm_op == DTM_READ))
-------1------- -------2------- ----------3---------
-1- | -2- | -3- | Status | Tests |
0 | 1 | 1 | Not Covered | |
1 | 0 | 1 | Covered | T1,T2,T3 |
1 | 1 | 0 | Covered | T1,T2,T3 |
1 | 1 | 1 | Covered | T1,T2,T3 |
LINE 292
SUB-EXPRESSION (dtm_op == DTM_READ)
----------1---------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T1,T2,T3 |
LINE 302
EXPRESSION (cmderr_q == CmdErrNone)
------------1-----------
-1- | Status | Tests |
0 | Not Covered | |
1 | Covered | T1,T8,T9 |
LINE 324
EXPRESSION (cmderr_q == CmdErrNone)
------------1-----------
-1- | Status | Tests |
0 | Not Covered | |
1 | Covered | T11,T12,T13 |
LINE 344
EXPRESSION (sbbusy_i || sbcs_q.sbbusyerror)
----1--- ---------2--------
-1- | -2- | Status | Tests |
0 | 0 | Covered | T14,T15,T16 |
0 | 1 | Not Covered | |
1 | 0 | Not Covered | |
LINE 348
EXPRESSION (sbcs_q.sberror == '0)
-----------1----------
-1- | Status | Tests |
0 | Not Covered | |
1 | Covered | T14,T15,T16 |
LINE 354
EXPRESSION (sbbusy_i || sbcs_q.sbbusyerror)
----1--- ---------2--------
-1- | -2- | Status | Tests |
0 | 0 | Not Covered | |
0 | 1 | Not Covered | |
1 | 0 | Not Covered | |
LINE 366
EXPRESSION (dmi_req_ready_o && dmi_req_valid_i && (dtm_op == DTM_WRITE))
-------1------- -------2------- ----------3----------
-1- | -2- | -3- | Status | Tests |
0 | 1 | 1 | Not Covered | |
1 | 0 | 1 | Covered | T1,T2,T3 |
1 | 1 | 0 | Covered | T1,T2,T3 |
1 | 1 | 1 | Covered | T1,T2,T3 |
LINE 366
SUB-EXPRESSION (dtm_op == DTM_WRITE)
----------1----------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T1,T2,T3 |
LINE 378
EXPRESSION (cmderr_q == CmdErrNone)
------------1-----------
-1- | Status | Tests |
0 | Not Covered | |
1 | Covered | T21,T22 |
LINE 405
EXPRESSION (cmderr_q == CmdErrNone)
------------1-----------
-1- | Status | Tests |
0 | Covered | T25,T26 |
1 | Covered | T27,T28,T29 |
LINE 419
EXPRESSION (cmderr_q == CmdErrNone)
------------1-----------
-1- | Status | Tests |
0 | Not Covered | |
1 | Covered | T30,T12,T28 |
LINE 433
EXPRESSION (cmderr_q == CmdErrNone)
------------1-----------
-1- | Status | Tests |
0 | Not Covered | |
1 | Covered | T31,T22,T32 |
LINE 450
EXPRESSION (cmderr_q == CmdErrNone)
------------1-----------
-1- | Status | Tests |
0 | Not Covered | |
1 | Covered | T3,T33,T34 |
LINE 464
EXPRESSION (sbcs_q.sbbusyerror & ((~sbcs.sbbusyerror)))
---------1-------- ----------2----------
-1- | -2- | Status | Tests |
0 | 1 | Covered | T14,T15,T16 |
1 | 0 | Not Covered | |
1 | 1 | Not Covered | |
LINE 465
EXPRESSION (((|sbcs.sberror)) ? 3'b0 : sbcs_q.sberror)
--------1--------
-1- | Status | Tests |
0 | Covered | T14,T15,T16 |
1 | Covered | T15,T37,T38 |
LINE 470
EXPRESSION (sbbusy_i || sbcs_q.sbbusyerror)
----1--- ---------2--------
-1- | -2- | Status | Tests |
0 | 0 | Covered | T14,T15,T16 |
0 | 1 | Not Covered | |
1 | 0 | Not Covered | |
LINE 475
EXPRESSION (sbcs_q.sberror == '0)
-----------1----------
-1- | Status | Tests |
0 | Not Covered | |
1 | Covered | T14,T15,T16 |
LINE 480
EXPRESSION (sbbusy_i || sbcs_q.sbbusyerror)
----1--- ---------2--------
-1- | -2- | Status | Tests |
0 | 0 | Not Covered | |
0 | 1 | Not Covered | |
1 | 0 | Not Covered | |
LINE 489
EXPRESSION (sbbusy_i || sbcs_q.sbbusyerror)
----1--- ---------2--------
-1- | -2- | Status | Tests |
0 | 0 | Covered | T14,T15,T16 |
0 | 1 | Not Covered | |
1 | 0 | Not Covered | |
LINE 494
EXPRESSION (sbcs_q.sberror == '0)
-----------1----------
-1- | Status | Tests |
0 | Not Covered | |
1 | Covered | T14,T15,T16 |
LINE 499
EXPRESSION (sbbusy_i || sbcs_q.sbbusyerror)
----1--- ---------2--------
-1- | -2- | Status | Tests |
0 | 0 | Not Covered | |
0 | 1 | Not Covered | |
1 | 0 | Not Covered | |
LINE 546
EXPRESSION (((!dmcontrol_q.resumereq)) && dmcontrol_d.resumereq)
-------------1------------ ----------2----------
-1- | -2- | Status | Tests |
0 | 1 | Covered | T5,T39,T24 |
1 | 0 | Covered | T1,T2,T3 |
1 | 1 | Covered | T5,T39,T24 |
LINE 549
EXPRESSION (dmcontrol_q.resumereq && resumeack_i)
----------1---------- -----2-----
-1- | -2- | Status | Tests |
0 | 1 | Covered | T5,T39,T24 |
1 | 0 | Covered | T5,T39,T24 |
1 | 1 | Covered | T5,T39,T24 |
LINE 625
EXPRESSION (SelectableHarts & havereset_d)
-------1------- -----2-----
-1- | -2- | Status | Tests |
- | 0 | Covered | T5,T23,T24 |
- | 1 | Covered | T1,T2,T3 |
Branch Coverage for Instance : tb.dut.u_dm_top.i_dm_csrs
| Line No. | Total | Covered | Percent |
Branches |
|
80 |
49 |
61.25 |
IF |
112 |
1 |
1 |
100.00 |
IF |
129 |
1 |
1 |
100.00 |
IF |
146 |
1 |
1 |
100.00 |
IF |
292 |
26 |
11 |
42.31 |
IF |
366 |
33 |
17 |
51.52 |
IF |
510 |
2 |
2 |
100.00 |
IF |
515 |
2 |
2 |
100.00 |
IF |
520 |
2 |
2 |
100.00 |
IF |
527 |
2 |
2 |
100.00 |
IF |
531 |
2 |
2 |
100.00 |
IF |
546 |
2 |
2 |
100.00 |
IF |
549 |
2 |
2 |
100.00 |
IF |
572 |
1 |
1 |
100.00 |
IF |
611 |
3 |
3 |
100.00 |
112 if (hartsel_idx0 < 15'((NrHarts-1)/2**5+1)) begin
-1-
113 haltsum0 = halted_reshaped0[hartsel_idx0];
==>
114 end
MISSING_ELSE
==> (Excluded)
Exclude Annotation: VC_COV_UNR
Branches:
-1- | Status | Tests | Exclude Annotation |
1 |
Covered |
T1,T2,T3 |
|
0 |
Excluded |
|
VC_COV_UNR |
129 if (hartsel_idx1 < 10'(((NrHarts-1)/2**10+1))) begin
-1-
130 haltsum1 = halted_reshaped1[hartsel_idx1];
==>
131 end
MISSING_ELSE
==> (Excluded)
Exclude Annotation: VC_COV_UNR
Branches:
-1- | Status | Tests | Exclude Annotation |
1 |
Covered |
T1,T2,T3 |
|
0 |
Excluded |
|
VC_COV_UNR |
146 if (hartsel_idx2 < 5'(((NrHarts-1)/2**15+1))) begin
-1-
147 haltsum2 = halted_reshaped2[hartsel_idx2];
==>
148 end
MISSING_ELSE
==> (Excluded)
Exclude Annotation: VC_COV_UNR
Branches:
-1- | Status | Tests | Exclude Annotation |
1 |
Covered |
T1,T2,T3 |
|
0 |
Excluded |
|
VC_COV_UNR |
292 if (dmi_req_ready_o && dmi_req_valid_i && dtm_op == dm::DTM_READ) begin
-1-
293 unique case (dm_csr_addr) inside
-2-
294 [(dm::Data0):DataEnd]: begin
295 resp_queue_inp.data = data_q[$clog2(dm::DataCount)'(autoexecdata_idx)];
296 if (!cmdbusy_i) begin
-3-
297 // check whether we need to re-execute the command (just give a cmd_valid)
298 cmd_valid_d = abstractauto_q.autoexecdata[autoexecdata_idx];
==>
299 // An abstract command was executing while one of the data registers was read
300 end else begin
301 resp_queue_inp.resp = dm::DTM_BUSY;
302 if (cmderr_q == dm::CmdErrNone) begin
-4-
303 cmderr_d = dm::CmdErrBusy;
==>
304 end
MISSING_ELSE
==>
305 end
306 end
307 dm::DMControl: resp_queue_inp.data = dmcontrol_q;
==>
308 dm::DMStatus: resp_queue_inp.data = dmstatus;
==>
309 dm::Hartinfo: resp_queue_inp.data = hartinfo_aligned[selected_hart];
==>
310 dm::AbstractCS: resp_queue_inp.data = abstractcs;
==>
311 dm::AbstractAuto: resp_queue_inp.data = abstractauto_q;
==>
312 dm::Command: resp_queue_inp.data = '0;
==>
313 dm::NextDM: resp_queue_inp.data = next_dm_addr_i;
==>
314 [(dm::ProgBuf0):ProgBufEnd]: begin
315 resp_queue_inp.data = progbuf_q[dmi_req_i.addr[$clog2(dm::ProgBufSize)-1:0]];
316 if (!cmdbusy_i) begin
-5-
317 // check whether we need to re-execute the command (just give a cmd_valid)
318 // range of autoexecprogbuf is 31:16
319 cmd_valid_d = abstractauto_q.autoexecprogbuf[{1'b1, dmi_req_i.addr[3:0]}];
==>
320
321 // An abstract command was executing while one of the progbuf registers was read
322 end else begin
323 resp_queue_inp.resp = dm::DTM_BUSY;
324 if (cmderr_q == dm::CmdErrNone) begin
-6-
325 cmderr_d = dm::CmdErrBusy;
==>
326 end
MISSING_ELSE
==>
327 end
328 end
329 dm::HaltSum0: resp_queue_inp.data = haltsum0;
==>
330 dm::HaltSum1: resp_queue_inp.data = haltsum1;
==>
331 dm::HaltSum2: resp_queue_inp.data = haltsum2;
==>
332 dm::HaltSum3: resp_queue_inp.data = haltsum3;
==>
333 dm::SBCS: begin
334 resp_queue_inp.data = sbcs_q;
==>
335 end
336 dm::SBAddress0: begin
337 resp_queue_inp.data = sbaddr_q[31:0];
==>
338 end
339 dm::SBAddress1: begin
340 resp_queue_inp.data = sbaddr_q[63:32];
==>
341 end
342 dm::SBData0: begin
343 // access while the SBA was busy
344 if (sbbusy_i || sbcs_q.sbbusyerror) begin
-7-
345 sbcs_d.sbbusyerror = 1'b1;
==>
346 resp_queue_inp.resp = dm::DTM_BUSY;
347 end else begin
348 sbdata_read_valid_o = (sbcs_q.sberror == '0);
==>
349 resp_queue_inp.data = sbdata_q[31:0];
350 end
351 end
352 dm::SBData1: begin
353 // access while the SBA was busy
354 if (sbbusy_i || sbcs_q.sbbusyerror) begin
-8-
355 sbcs_d.sbbusyerror = 1'b1;
==>
356 resp_queue_inp.resp = dm::DTM_BUSY;
357 end else begin
358 resp_queue_inp.data = sbdata_q[63:32];
==>
359 end
360 end
361 default:;
==>
362 endcase
363 end
MISSING_ELSE
==>
Branches:
-1- | -2- | -3- | -4- | -5- | -6- | -7- | -8- | Status | Tests |
1 |
Data0 DataEnd |
1 |
- |
- |
- |
- |
- |
Covered |
T1,T6,T7 |
1 |
Data0 DataEnd |
0 |
1 |
- |
- |
- |
- |
Covered |
T1,T8,T9 |
1 |
Data0 DataEnd |
0 |
0 |
- |
- |
- |
- |
Not Covered |
|
1 |
DMControl |
- |
- |
- |
- |
- |
- |
Covered |
T1,T2,T3 |
1 |
DMStatus |
- |
- |
- |
- |
- |
- |
Covered |
T1,T4,T5 |
1 |
Hartinfo |
- |
- |
- |
- |
- |
- |
Not Covered |
|
1 |
AbstractCS |
- |
- |
- |
- |
- |
- |
Covered |
T1,T2,T3 |
1 |
AbstractAuto |
- |
- |
- |
- |
- |
- |
Not Covered |
|
1 |
Command |
- |
- |
- |
- |
- |
- |
Not Covered |
|
1 |
NextDM |
- |
- |
- |
- |
- |
- |
Not Covered |
|
1 |
ProgBuf0 ProgBufEnd |
- |
- |
1 |
- |
- |
- |
Covered |
T1,T7,T10 |
1 |
ProgBuf0 ProgBufEnd |
- |
- |
0 |
1 |
- |
- |
Covered |
T11,T12,T13 |
1 |
ProgBuf0 ProgBufEnd |
- |
- |
0 |
0 |
- |
- |
Not Covered |
|
1 |
HaltSum0 |
- |
- |
- |
- |
- |
- |
Not Covered |
|
1 |
HaltSum1 |
- |
- |
- |
- |
- |
- |
Not Covered |
|
1 |
HaltSum2 |
- |
- |
- |
- |
- |
- |
Not Covered |
|
1 |
HaltSum3 |
- |
- |
- |
- |
- |
- |
Not Covered |
|
1 |
SBCS |
- |
- |
- |
- |
- |
- |
Covered |
T14,T15,T16 |
1 |
SBAddress0 |
- |
- |
- |
- |
- |
- |
Covered |
T17,T18,T19 |
1 |
SBAddress1 |
- |
- |
- |
- |
- |
- |
Not Covered |
|
1 |
SBData0 |
- |
- |
- |
- |
1 |
- |
Not Covered |
|
1 |
SBData0 |
- |
- |
- |
- |
0 |
- |
Covered |
T14,T15,T16 |
1 |
SBData1 |
- |
- |
- |
- |
- |
1 |
Not Covered |
|
1 |
SBData1 |
- |
- |
- |
- |
- |
0 |
Not Covered |
|
1 |
default |
- |
- |
- |
- |
- |
- |
Not Covered |
|
0 |
- |
- |
- |
- |
- |
- |
- |
Covered |
T1,T2,T3 |
366 if (dmi_req_ready_o && dmi_req_valid_i && dtm_op == dm::DTM_WRITE) begin
-1-
367 unique case (dm_csr_addr) inside
-2-
368 [(dm::Data0):DataEnd]: begin
369 if (dm::DataCount > 0) begin
-3-
370 // attempts to write them while busy is set does not change their value
371 if (!cmdbusy_i) begin
-4-
372 data_d[dmi_req_i.addr[$clog2(dm::DataCount)-1:0]] = dmi_req_i.data;
==>
373 // check whether we need to re-execute the command (just give a cmd_valid)
374 cmd_valid_d = abstractauto_q.autoexecdata[autoexecdata_idx];
375 //An abstract command was executing while one of the data registers was written
376 end else begin
377 resp_queue_inp.resp = dm::DTM_BUSY;
378 if (cmderr_q == dm::CmdErrNone) begin
-5-
379 cmderr_d = dm::CmdErrBusy;
==>
380 end
MISSING_ELSE
==>
381 end
382 end
MISSING_ELSE
==> (Excluded)
Exclude Annotation: VC_COV_UNR
383 end
384 dm::DMControl: begin
385 dmcontrol_d = dmi_req_i.data;
386 // clear the havreset of the selected hart
387 if (dmcontrol_d.ackhavereset) begin
-6-
388 havereset_d_aligned[selected_hart] = 1'b0;
==>
389 end
MISSING_ELSE
==>
390 end
391 dm::DMStatus:; // write are ignored to R/O register
==>
392 dm::Hartinfo:; // hartinfo is R/O
==>
393 // only command error is write-able
394 dm::AbstractCS: begin // W1C
395 // Gets set if an abstract command fails. The bits in this
396 // field remain set until they are cleared by writing 1 to
397 // them. No abstract command is started until the value is
398 // reset to 0.
399 a_abstractcs = dm::abstractcs_t'(dmi_req_i.data);
400 // reads during abstract command execution are not allowed
401 if (!cmdbusy_i) begin
-7-
402 cmderr_d = dm::cmderr_e'(~a_abstractcs.cmderr & cmderr_q);
==>
403 end else begin
404 resp_queue_inp.resp = dm::DTM_BUSY;
405 if (cmderr_q == dm::CmdErrNone) begin
-8-
406 cmderr_d = dm::CmdErrBusy;
==>
407 end
MISSING_ELSE
==>
408 end
409 end
410 dm::Command: begin
411 // writes are ignored if a command is already busy
412 if (!cmdbusy_i) begin
-9-
413 cmd_valid_d = 1'b1;
==>
414 command_d = dm::command_t'(dmi_req_i.data);
415 // if there was an attempted to write during a busy execution
416 // and the cmderror field is zero set the busy error
417 end else begin
418 resp_queue_inp.resp = dm::DTM_BUSY;
419 if (cmderr_q == dm::CmdErrNone) begin
-10-
420 cmderr_d = dm::CmdErrBusy;
==>
421 end
MISSING_ELSE
==>
422 end
423 end
424 dm::NextDM:; // nextdm is R/O
==>
425 dm::AbstractAuto: begin
426 // this field can only be written legally when there is no command executing
427 if (!cmdbusy_i) begin
-11-
428 abstractauto_d = 32'h0;
==>
429 abstractauto_d.autoexecdata = 12'(dmi_req_i.data[dm::DataCount-1:0]);
430 abstractauto_d.autoexecprogbuf = 16'(dmi_req_i.data[dm::ProgBufSize-1+16:16]);
431 end else begin
432 resp_queue_inp.resp = dm::DTM_BUSY;
433 if (cmderr_q == dm::CmdErrNone) begin
-12-
434 cmderr_d = dm::CmdErrBusy;
==>
435 end
MISSING_ELSE
==>
436 end
437 end
438 [(dm::ProgBuf0):ProgBufEnd]: begin
439 // attempts to write them while busy is set does not change their value
440 if (!cmdbusy_i) begin
-13-
441 progbuf_d[dmi_req_i.addr[$clog2(dm::ProgBufSize)-1:0]] = dmi_req_i.data;
==>
442 // check whether we need to re-execute the command (just give a cmd_valid)
443 // this should probably throw an error if executed during another command
444 // was busy
445 // range of autoexecprogbuf is 31:16
446 cmd_valid_d = abstractauto_q.autoexecprogbuf[{1'b1, dmi_req_i.addr[3:0]}];
447 //An abstract command was executing while one of the progbuf registers was written
448 end else begin
449 resp_queue_inp.resp = dm::DTM_BUSY;
450 if (cmderr_q == dm::CmdErrNone) begin
-14-
451 cmderr_d = dm::CmdErrBusy;
==>
452 end
MISSING_ELSE
==>
453 end
454 end
455 dm::SBCS: begin
456 // access while the SBA was busy
457 if (sbbusy_i) begin
-15-
458 sbcs_d.sbbusyerror = 1'b1;
==>
459 resp_queue_inp.resp = dm::DTM_BUSY;
460 end else begin
461 sbcs = dm::sbcs_t'(dmi_req_i.data);
462 sbcs_d = sbcs;
463 // R/W1C
464 sbcs_d.sbbusyerror = sbcs_q.sbbusyerror & (~sbcs.sbbusyerror);
465 sbcs_d.sberror = (|sbcs.sberror) ? 3'b0 : sbcs_q.sberror;
-16-
==>
==>
466 end
467 end
468 dm::SBAddress0: begin
469 // access while the SBA was busy
470 if (sbbusy_i || sbcs_q.sbbusyerror) begin
-17-
471 sbcs_d.sbbusyerror = 1'b1;
==>
472 resp_queue_inp.resp = dm::DTM_BUSY;
473 end else begin
474 sbaddr_d[31:0] = dmi_req_i.data;
==>
475 sbaddress_write_valid_o = (sbcs_q.sberror == '0);
476 end
477 end
478 dm::SBAddress1: begin
479 // access while the SBA was busy
480 if (sbbusy_i || sbcs_q.sbbusyerror) begin
-18-
481 sbcs_d.sbbusyerror = 1'b1;
==>
482 resp_queue_inp.resp = dm::DTM_BUSY;
483 end else begin
484 sbaddr_d[63:32] = dmi_req_i.data;
==>
485 end
486 end
487 dm::SBData0: begin
488 // access while the SBA was busy
489 if (sbbusy_i || sbcs_q.sbbusyerror) begin
-19-
490 sbcs_d.sbbusyerror = 1'b1;
==>
491 resp_queue_inp.resp = dm::DTM_BUSY;
492 end else begin
493 sbdata_d[31:0] = dmi_req_i.data;
==>
494 sbdata_write_valid_o = (sbcs_q.sberror == '0);
495 end
496 end
497 dm::SBData1: begin
498 // access while the SBA was busy
499 if (sbbusy_i || sbcs_q.sbbusyerror) begin
-20-
500 sbcs_d.sbbusyerror = 1'b1;
==>
501 resp_queue_inp.resp = dm::DTM_BUSY;
502 end else begin
503 sbdata_d[63:32] = dmi_req_i.data;
==>
504 end
505 end
506 default:;
==>
507 endcase
508 end
MISSING_ELSE
==>
Branches:
-1- | -2- | -3- | -4- | -5- | -6- | -7- | -8- | -9- | -10- | -11- | -12- | -13- | -14- | -15- | -16- | -17- | -18- | -19- | -20- | Status | Tests | Exclude Annotation |
1 |
Data0 DataEnd |
1 |
1 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T1,T20,T7 |
|
1 |
Data0 DataEnd |
1 |
0 |
1 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T21,T22 |
|
1 |
Data0 DataEnd |
1 |
0 |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Not Covered |
|
|
1 |
Data0 DataEnd |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Excluded |
|
VC_COV_UNR |
1 |
DMControl |
- |
- |
- |
1 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T5,T23,T24 |
|
1 |
DMControl |
- |
- |
- |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T1,T2,T3 |
|
1 |
DMStatus |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Not Covered |
|
|
1 |
Hartinfo |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Not Covered |
|
|
1 |
AbstractCS |
- |
- |
- |
- |
1 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T1,T2,T3 |
|
1 |
AbstractCS |
- |
- |
- |
- |
0 |
1 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T27,T28,T29 |
|
1 |
AbstractCS |
- |
- |
- |
- |
0 |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T25,T26 |
|
1 |
Command |
- |
- |
- |
- |
- |
- |
1 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T1,T2,T3 |
|
1 |
Command |
- |
- |
- |
- |
- |
- |
0 |
1 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T30,T12,T28 |
|
1 |
Command |
- |
- |
- |
- |
- |
- |
0 |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Not Covered |
|
|
1 |
NextDM |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Not Covered |
|
|
1 |
AbstractAuto |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Not Covered |
|
|
1 |
AbstractAuto |
- |
- |
- |
- |
- |
- |
- |
- |
0 |
1 |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T31,T22,T32 |
|
1 |
AbstractAuto |
- |
- |
- |
- |
- |
- |
- |
- |
0 |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
Not Covered |
|
|
1 |
ProgBuf0 ProgBufEnd |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
- |
- |
- |
- |
- |
- |
- |
Covered |
T1,T20,T7 |
|
1 |
ProgBuf0 ProgBufEnd |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
0 |
1 |
- |
- |
- |
- |
- |
- |
Covered |
T3,T33,T34 |
|
1 |
ProgBuf0 ProgBufEnd |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
0 |
0 |
- |
- |
- |
- |
- |
- |
Not Covered |
|
|
1 |
SBCS |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
- |
- |
- |
- |
- |
Not Covered |
|
|
1 |
SBCS |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
0 |
1 |
- |
- |
- |
- |
Covered |
T15,T37,T38 |
|
1 |
SBCS |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
0 |
0 |
- |
- |
- |
- |
Covered |
T14,T15,T16 |
|
1 |
SBAddress0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
- |
- |
- |
Not Covered |
|
|
1 |
SBAddress0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
0 |
- |
- |
- |
Covered |
T14,T15,T16 |
|
1 |
SBAddress1 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
- |
- |
Not Covered |
|
|
1 |
SBAddress1 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
0 |
- |
- |
Not Covered |
|
|
1 |
SBData0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
- |
Not Covered |
|
|
1 |
SBData0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
0 |
- |
Covered |
T14,T15,T16 |
|
1 |
SBData1 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
Not Covered |
|
|
1 |
SBData1 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
0 |
Not Covered |
|
|
1 |
default |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Not Covered |
|
|
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T1,T2,T3 |
|
510 if (cmderror_valid_i) begin
-1-
511 cmderr_d = cmderror_i;
==>
512 end
MISSING_ELSE
==>
Branches:
-1- | Status | Tests |
1 |
Covered |
T2,T25,T35 |
0 |
Covered |
T1,T2,T3 |
515 if (data_valid_i) begin
-1-
516 data_d = data_i;
==>
517 end
MISSING_ELSE
==>
Branches:
-1- | Status | Tests |
1 |
Covered |
T1,T6,T10 |
0 |
Covered |
T1,T2,T3 |
520 if (ndmreset_ack_i) begin
-1-
521 havereset_d_aligned[NrHarts-1:0] = '1;
==>
522 end
MISSING_ELSE
==>
Branches:
-1- | Status | Tests |
1 |
Covered |
T1,T10,T36 |
0 |
Covered |
T1,T2,T3 |
527 if (sberror_valid_i) begin
-1-
528 sbcs_d.sberror = sberror_i;
==>
529 end
MISSING_ELSE
==>
Branches:
-1- | Status | Tests |
1 |
Covered |
T15,T37,T38 |
0 |
Covered |
T1,T2,T3 |
531 if (sbdata_valid_i) begin
-1-
532 sbdata_d = 64'(sbdata_i);
==>
533 end
MISSING_ELSE
==>
Branches:
-1- | Status | Tests |
1 |
Covered |
T14,T15,T16 |
0 |
Covered |
T1,T2,T3 |
546 if (!dmcontrol_q.resumereq && dmcontrol_d.resumereq) begin
-1-
547 clear_resumeack_o = 1'b1;
==>
548 end
MISSING_ELSE
==>
Branches:
-1- | Status | Tests |
1 |
Covered |
T5,T39,T24 |
0 |
Covered |
T1,T2,T3 |
549 if (dmcontrol_q.resumereq && resumeack_i) begin
-1-
550 dmcontrol_d.resumereq = 1'b0;
==>
551 end
MISSING_ELSE
==>
Branches:
-1- | Status | Tests |
1 |
Covered |
T5,T39,T24 |
0 |
Covered |
T1,T2,T3 |
572 if (selected_hart <= HartSelLen'(NrHarts-1)) begin
-1-
573 haltreq_o[selected_hart] = dmcontrol_q.haltreq;
==>
574 resumereq_o[selected_hart] = dmcontrol_q.resumereq;
575 end
MISSING_ELSE
==> (Excluded)
Exclude Annotation: VC_COV_UNR
Branches:
-1- | Status | Tests | Exclude Annotation |
1 |
Covered |
T1,T2,T3 |
|
0 |
Excluded |
|
VC_COV_UNR |
611 if (!rst_ni) begin
-1-
612 dmcontrol_q <= '0;
==>
613 // this is the only write-able bit during reset
614 cmderr_q <= dm::CmdErrNone;
615 command_q <= '0;
616 cmd_valid_q <= '0;
617 abstractauto_q <= '0;
618 progbuf_q <= '0;
619 data_q <= '0;
620 sbcs_q <= '{default: '0, sbaccess: 3'd2};
621 sbaddr_q <= '0;
622 sbdata_q <= '0;
623 havereset_q <= '1;
624 end else begin
625 havereset_q <= SelectableHarts & havereset_d;
626 // synchronous re-set of debug module, active-low, except for dmactive
627 if (!dmcontrol_q.dmactive) begin
-2-
628 dmcontrol_q.haltreq <= '0;
==>
629 dmcontrol_q.resumereq <= '0;
630 dmcontrol_q.hartreset <= '0;
631 dmcontrol_q.ackhavereset <= '0;
632 dmcontrol_q.zero1 <= '0;
633 dmcontrol_q.hasel <= '0;
634 dmcontrol_q.hartsello <= '0;
635 dmcontrol_q.hartselhi <= '0;
636 dmcontrol_q.zero0 <= '0;
637 dmcontrol_q.setresethaltreq <= '0;
638 dmcontrol_q.clrresethaltreq <= '0;
639 dmcontrol_q.ndmreset <= '0;
640 // this is the only write-able bit during reset
641 dmcontrol_q.dmactive <= dmcontrol_d.dmactive;
642 cmderr_q <= dm::CmdErrNone;
643 command_q <= '0;
644 cmd_valid_q <= '0;
645 abstractauto_q <= '0;
646 progbuf_q <= '0;
647 data_q <= '0;
648 sbcs_q <= '{default: '0, sbaccess: 3'd2};
649 sbaddr_q <= '0;
650 sbdata_q <= '0;
651 end else begin
652 dmcontrol_q <= dmcontrol_d;
==>
Branches:
-1- | -2- | Status | Tests |
1 |
- |
Covered |
T1,T2,T3 |
0 |
1 |
Covered |
T1,T2,T3 |
0 |
0 |
Covered |
T1,T2,T3 |