Skip to content

[hw] Do not track vl=0 vector instructions in running_insn - #118

Open
emiliengnr wants to merge 1 commit into
pulp-platform:mainfrom
emiliengnr:fix/vl0-running-insn
Open

[hw] Do not track vl=0 vector instructions in running_insn#118
emiliengnr wants to merge 1 commit into
pulp-platform:mainfrom
emiliengnr:fix/vl0-running-insn

Conversation

@emiliengnr

Copy link
Copy Markdown
Contributor

Hello, here is a pull request for a bug I found.

A vector instruction issued while vl=0 wedges the core on the next FP CSR access.

vl=0 is the reset value, so this fires on any vector op issued before the first vsetvli, and
also whenever a vsetvli computes vl=0 from AVL=0.

The issue

The controller sets running_insn for every non-CON request at issue:

// New instruction!
if (spatz_req_valid && spatz_req.ex_unit != CON)
  running_insn_d[next_insn_id] = 1'b1;

and clears it when a unit responds. A vl=0 op never produces that response. In the VFU,
vl_d >= spatz_req.vl already holds on the first cycle, so spatz_req_ready pulses and the unit
declares itself done, but vfu_rsp_valid_o fires only on the result-emit path, which needs
result_tag.last && &(result_valid | ~pending_results). With no element processed, result_valid
never rises. The unit thinks the op is finished, the controller still thinks it is in flight, and
nothing will ever reconcile them.

issue_rsp_o.isfloat is |running_insn_q, and Snitch stalls on read_fcsr && acc_qrsp_i.isfloat,
so the next csrr fcsr, csrw frm, fssr or similar never retires. One core spins silently, and
with both cores blocked Verilator reports Resource deadlock avoided.

Reproducer

Five instructions, no vsetvli, no FP arithmetic:

    li      t0, 0x6000
    csrrs   zero, mstatus, t0   # mstatus.FS = dirty

    .word   0x02408057          # vadd.vv v0, v4, v8, a no-op at vl=0

    li      x1, 0
    fssr    x1                  # any fcsr access, never retires

Step one can be any vector op routed to VFU, VLSU or VSLDU. Step two can be any read or write of
fcsr, frm or fflags. The program never reaches its halt.

The fix

Do not set running_insn for a vl=0 op, since there is no response coming to clear it.
Reductions keep their slot: they retire through the scalar result buffer and do send a response.
Ops with vl>0 take the original path unchanged, set on issue and cleared on response.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant