Hey @Aquaticfuller @DiyouS,
found when running some custom kernels. AI:
vmv.v.x and vmv.v.i splat a scalar (or an immediate) into every element.
They have no vector source operand: their encodings leave vs2
(bits 24:20) reserved, i.e. zero. But the ISA description gave them formats that
declare that field as a vector input:
Format_OPV = [ OutVReg(0, Range(7,5)), InVReg(0, Range(15,5)), InVReg(1, Range(20,5)), ... ]
Format_OPIVI = [ OutVReg(0, Range(7,5)), InVReg(1, Range(20,5)), SignedImm(0, Range(15,5)), ... ]
Instr('vmv.v.x', Format_OPV , '010111 - ----- ----- 100 ----- 1010111', ...)
Instr('vmv.v.i', Format_OPIVI, '010111 - ----- ----- 011 ----- 1010111', ...)
Because the reserved field reads as register number 0, the model believes
every vmv.v.x reads v0. (For vmv.v.x the same format also mis-declares
the scalar rs1 as a vector register, though that one is harmless: the
execution function reads it with REG_GET(0) from the integer file.)
The declaration never affected execution — vmv_v_x_exec uses REG_GET(0) and
vmv_v_i_exec uses SIM_GET(0) — only dependency tracking.
Why it deadlocks
AraVcompute::fsm_handler() finishes a chained instruction only once every
one of its vector input registers has drained:
if (_this->ara.scoreboard_committed[insn->in_regs[i]] != 0) { done = false; break; }
so a vmv.v.x waits for scoreboard_committed[v0]. If the program uses v0 as
an ordinary data register — entirely legal, v0 is architecturally special only
as a mask, and only when vm=0 — that wait never ends.
Fix
Give the two instructions formats without the reserved vs2 field
(Format_VMV_X, Format_VMV_I).
Hey @Aquaticfuller @DiyouS,
found when running some custom kernels. AI:
vmv.v.xandvmv.v.isplat a scalar (or an immediate) into every element.They have no vector source operand: their encodings leave
vs2(bits 24:20) reserved, i.e. zero. But the ISA description gave them formats that
declare that field as a vector input:
Because the reserved field reads as register number 0, the model believes
every
vmv.v.xreadsv0. (Forvmv.v.xthe same format also mis-declaresthe scalar
rs1as a vector register, though that one is harmless: theexecution function reads it with
REG_GET(0)from the integer file.)The declaration never affected execution —
vmv_v_x_execusesREG_GET(0)andvmv_v_i_execusesSIM_GET(0)— only dependency tracking.Why it deadlocks
AraVcompute::fsm_handler()finishes a chained instruction only once everyone of its vector input registers has drained:
so a
vmv.v.xwaits forscoreboard_committed[v0]. If the program usesv0asan ordinary data register — entirely legal,
v0is architecturally special onlyas a mask, and only when
vm=0— that wait never ends.Fix
Give the two instructions formats without the reserved
vs2field(
Format_VMV_X,Format_VMV_I).