🔍 top.irq_independent_clear_test

Individual debug report — smoke regression.

← Back to regression report

top.irq_independent_clear_test

Verified
Fail signature (UVMFatalError)
UVMFatalError: IRQ_INDEPENDENT_CLEAR: clearing CMD_ERROR alone should leave CMD…

Attempt

Attempt 1 of 1 Approved
Investigation plan
  1. Searched the design spec for expected behavior (IRQ_INDEPENDENT_CLEAR)
  2. Searched the design spec for expected behavior (CMD_ERROR CMD_DONE)
  3. Searched the design graph (IRQ_INDEPENDENT_CLEAR)
  4. Searched the design spec for expected behavior (interrupt clear independent)
  5. Searched the design spec for expected behavior (CMD_ERROR register)
  6. Searched the design graph (CMD_ERROR)
  7. Read the RTL source (verif/cocotb_tb/top/test_top.py)
  8. Searched the design graph (irq)
  9. Searched the design graph (CMD_DONE)
  10. Searched the design graph (interrupt)
  11. Searched the design graph (status)
  12. Searched the design graph (clear)
  13. Searched the design spec for expected behavior (status register)
  14. Read the RTL source (rtl/command_processor/tpe_cmd_proc.sv)
  15. Traced the signal's driver (irq_status_q)
  16. Read the RTL source (rtl/command_processor/tpe_cmd_proc.sv)
  17. Searched the design spec for expected behavior (CP_IRQ_STATUS)
  18. Searched the design spec for expected behavior (register map IRQ)
  19. Searched the design graph (CP_IRQ_STATUS_ADDR)
  20. Read the RTL source (rtl/command_processor/tpe_cmd_proc.sv)
Hypothesis / root causertl/command_processor/tpe_cmd_proc.sv:244
Confidence
94%

The IRQ status register (irq_status_q = {CMD_ERROR, CMD_DONE}) implements write-1-to-clear (W1C) semantics for the host. The clear mask on line 244 is built as `~{2{s_wdata[0]}}`, which replicates only bit 0 of the write data across both bits of the mask. This means the clear operation cannot target CMD_ERROR (bit 1) and CMD_DONE (bit 0) independently: writing s_wdata[0]=0 (e.g. 0x2, intending to clear only CMD_ERROR) clears nothing, and writing s_wdata[0]=1 clears both bits regardless of bit 1. This is why the test's write of 0x2 (clear CMD_ERROR only) left irq_status_q unchanged at 0x3 instead of becoming 0x1 (CMD_DONE preserved, CMD_ERROR cleared). The fix is to use the full 2-bit write data as the per-bit clear mask: `irq_status_q <= irq_status_q & ~s_wdata[1:0];`, which allows each status bit to be cleared independently as the W1C comment above the block (lines 227-231) describes.

Retrieved evidence (20 steps)
  1. Step 1: Searched the design spec for expected behavior (IRQ_INDEPENDENT_CLEAR)
    (no spec sections matched 'IRQ_INDEPENDENT_CLEAR')
  2. Step 2: Searched the design spec for expected behavior (CMD_ERROR CMD_DONE)
    (no spec sections matched 'CMD_ERROR CMD_DONE')
  3. Step 3: Searched the design graph (IRQ_INDEPENDENT_CLEAR)
    (no matches)
  4. Step 4: Searched the design spec for expected behavior (interrupt clear independent)
    (no spec sections matched 'interrupt clear independent')
  5. Step 5: Searched the design spec for expected behavior (CMD_ERROR register)
    (no spec sections matched 'CMD_ERROR register')
  6. Step 6: Searched the design graph (CMD_ERROR)
    (no matches)
  7. Step 7: Read the RTL source (verif/cocotb_tb/top/test_top.py)
    (denied) 'verif/cocotb_tb/top/test_top.py' is outside rtl/ — only RTL source is readable
  8. Step 8: Searched the design graph (irq)
    - Port:irq (id=port:tpe_top.irq, module=tpe_top)
    - Port:irq (id=port:tpe_cmd_proc.irq, module=tpe_cmd_proc)
    - Register:irq_q (id=register:tpe_top.irq_q, module=tpe_top)
    - Register:irq_status_q (id=register:tpe_cmd_proc.irq_status_q, module=tpe_cmd_proc)
    - Register:irq_enable_q (id=register:tpe_cmd_proc.irq_enable_q, module=tpe_cmd_proc)
  9. Step 9: Searched the design graph (CMD_DONE)
    - Port:cmd_done_valid (id=port:tpe_pmu.cmd_done_valid, module=tpe_pmu)
  10. Step 10: Searched the design graph (interrupt)
    (no matches)
  11. Step 11: Searched the design graph (status)
    - Signal:sched_done_status (id=signal:tpe_top.sched_done_status, module=tpe_top)
    - Port:sched_done_status (id=port:tpe_cmd_proc.sched_done_status, module=tpe_cmd_proc)
    - Port:sched_done_status (id=port:tpe_debug.sched_done_status, module=tpe_debug)
    - Port:sched_done_status (id=port:tpe_scheduler__R10_C10.sched_done_status, module=tpe_scheduler__R10_C10)
    - Register:status_q (id=register:tpe_scheduler__R10_C10.status_q, module=tpe_scheduler__R10_C10)
    - Signal:status_word (id=signal:tpe_cmd_proc.st
  12. Step 12: Searched the design graph (clear)
    (no matches)
  13. Step 13: Searched the design spec for expected behavior (status register)
    (no spec sections matched 'status register')
  14. Step 14: Read the RTL source (rtl/command_processor/tpe_cmd_proc.sv)
    --- rtl/command_processor/tpe_cmd_proc.sv (lines 1-100 of 294) ---
        1: // Command Processor: the accelerator's "front door". AXI4-Lite MMIO slave
        2: // implementing the `cp` register block (docs/register_map/tpe_regs.yaml,
        3: // generated into tpe_regs_pkg.sv), a command-staging register set, and the
        4: // command FIFO the Scheduler drains. Per
        5: // docs/architecture/tpe_architecture_spec.md section 3.1.
        6: //
        7: // V1 AXI4-Lite simplification: this slave expects AWVA
  15. Step 15: Traced the signal's driver (irq_status_q)
    - Assignment:assignment:tpe_cmd_proc.assign_410 inside AlwaysBlock:always:tpe_cmd_proc.always_404 [rtl/command_processor/tpe_cmd_proc.sv:232:3]
    - Assignment:assignment:tpe_cmd_proc.assign_412 inside AlwaysBlock:always:tpe_cmd_proc.always_404 [rtl/command_processor/tpe_cmd_proc.sv:232:3]
    - Assignment:assignment:tpe_cmd_proc.assign_414 inside AlwaysBlock:always:tpe_cmd_proc.always_404 [rtl/command_processor/tpe_cmd_proc.sv:232:3]
    - Assignment:assignment:tpe_cmd_proc.assign_416 inside AlwaysBlock:a
  16. Step 16: Read the RTL source (rtl/command_processor/tpe_cmd_proc.sv)
    --- rtl/command_processor/tpe_cmd_proc.sv (lines 220-280 of 294) ---
      220:         CP_CMD_DIM_N_ADDR:  stg_dim_n_q  <= s_wdata[CP_CMD_DIM_N_DIM_N_LSB+TILE_DIM_WIDTH-1:CP_CMD_DIM_N_DIM_N_LSB];
      221:         CP_IRQ_ENABLE_ADDR: irq_enable_q <= s_wdata[1:0];
      222:         default: ;
      223:       endcase
      224:     end
      225:   end
      226: 
      227:   // ---- IRQ status: set by scheduler completion, W1C by host --------------
      228:   // A same-cycle completion always wins over a host clear (necessa
  17. Step 17: Searched the design spec for expected behavior (CP_IRQ_STATUS)
    (no spec sections matched 'CP_IRQ_STATUS')
  18. Step 18: Searched the design spec for expected behavior (register map IRQ)
    (no spec sections matched 'register map IRQ')
  19. Step 19: Searched the design graph (CP_IRQ_STATUS_ADDR)
    (no matches)
  20. Step 20: Read the RTL source (rtl/command_processor/tpe_cmd_proc.sv)
    --- rtl/command_processor/tpe_cmd_proc.sv (lines 1-30 of 294) ---
        1: // Command Processor: the accelerator's "front door". AXI4-Lite MMIO slave
        2: // implementing the `cp` register block (docs/register_map/tpe_regs.yaml,
        3: // generated into tpe_regs_pkg.sv), a command-staging register set, and the
        4: // command FIFO the Scheduler drains. Per
        5: // docs/architecture/tpe_architecture_spec.md section 3.1.
        6: //
        7: // V1 AXI4-Lite simplification: this slave expects AWVAL
Proposed patch
--- a/rtl/command_processor/tpe_cmd_proc.sv
+++ b/rtl/command_processor/tpe_cmd_proc.sv
@@ -241,7 +241,7 @@
       end
 
       if (do_write && (s_awaddr == CP_IRQ_STATUS_ADDR)) begin
-        irq_status_q <= irq_status_q & ~{2{s_wdata[0]}};
+        irq_status_q <= irq_status_q & ~s_wdata[1:0];
       end
 
       if (sched_done_valid) begin
Answer-key check (final attempt)Correct expected bug #6 — rtl/command_processor/tpe_cmd_proc.sv:[242]
Rerun PASS agent-fix/top-irq_independent_clear_test-0fde221b
Tokens (all attempts)13,738 (~$0.0562)