Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Errors with VLEN == 32 configuration #1956

Open
gregdavill opened this issue Apr 11, 2025 · 0 comments
Open

Errors with VLEN == 32 configuration #1956

gregdavill opened this issue Apr 11, 2025 · 0 comments

Comments

@gregdavill
Copy link

gregdavill commented Apr 11, 2025

Summary

The riscv vector specification lists an embedded configuration: zve32x, and lists that it has a minimum VLEN of 32. Spike accepts this as options on the isa string, and some vector operation work, But many cause an assertion error.

spike: ../riscv/vector_unit.cc:71: T& vectorUnit_t::elt(reg_t, reg_t, bool) [with T = long unsigned int; reg_t = long unsigned int]: Assertion `(VLEN >> 3)/sizeof(T) > 0' failed.

It seems that in the vector implementation internal working copies and masks currently create 64bit types, this causes an assertion to trip.

I think this is the underlying issue faced in #1685. Here is a test-case which activates this with vanilla spike.

Test case

vlen32.S

.globl _start
.section .text
_start:
    // Enable vector instructions
    li x10, 0x200
    csrs mstatus, x10

    li x11, 2
    vsetvli x11, x0, e32, m1, ta, ma
    vadd.vx v24, v28, x12, v0.t
    ret

link.ld

OUTPUT_ARCH("riscv")
ENTRY(_start)

SECTIONS
{
    . = 0x80000000;
    .text : { *(.text) }
}

Commands to build and run

$ riscv-none-elf-gcc -nostdlib -nostartfiles -march=rv32imac_zve32x_zicsr -T link.ld vlen32.S -o vlen32.elf
$ spike --isa=rv32imac_zve32x_zvl32b -l --log-commits --instructions=32 vlen32.elf
core   0: 0x00001000 (0x00000297) auipc   t0, 0x0
core   0: 3 0x00001000 (0x00000297) x5  0x00001000
core   0: 0x00001004 (0x02028593) addi    a1, t0, 32
core   0: 3 0x00001004 (0x02028593) x11 0x00001020
core   0: 0x00001008 (0xf1402573) csrr    a0, mhartid
core   0: 3 0x00001008 (0xf1402573) x10 0x00000000
core   0: 0x0000100c (0x0182a283) lw      t0, 24(t0)
core   0: 3 0x0000100c (0x0182a283) x5  0x80000000 mem 0x00001018
core   0: 0x00001010 (0x00028067) jr      t0
core   0: 3 0x00001010 (0x00028067)
core   0: 0x80000000 (0x20000513) li      a0, 512
core   0: 3 0x80000000 (0x20000513) x10 0x00000200
core   0: 0x80000004 (0x30052073) csrs    mstatus, a0
core   0: 3 0x80000004 (0x30052073) c768_mstatus 0x00000200
core   0: 0x80000008 (0x00004589) c.li    a1, 2
core   0: 3 0x80000008 (0x4589) x11 0x00000002
core   0: 0x8000000a (0x0d0075d7) vsetvli a1, zero, e32, m1, ta, ma
core   0: 3 0x8000000a (0x0d0075d7) c8_vstart 0x00000000 x11 0x00000001 c768_mstatus 0x80000600 c3104_vl 0x00000001 c3105_vtype 0x000000d0
core   0: 0x8000000e (0x01c64c57) vadd.vx v24, v28, a2, v0.t
spike: ../riscv/vector_unit.cc:71: T& vectorUnit_t::elt(reg_t, reg_t, bool) [with T = long unsigned int; reg_t = long unsigned int]: Assertion `(VLEN >> 3)/sizeof(T) > 0' failed.

If I adjust the isa string to --isa=rv32imac_zve32x_zvl64b this test-case passes.

Troubleshooting

I've dug into the code a little and it appears that for any instruction with a mask, the mask is created using a VU.elt<uint64_t> type. This correctly trips the assertion since VLEN was configured as 32bits.

I've managed to perform a trivial change mostly in v_ext_macros.h, and some vector instructions, with a direct repalcement uint64_t > uint32_t. This fixes my use_case, but obviously breaks the more typical VLEN >= 64.

I'm happy to rework this into a more general fix and open a PR.

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

No branches or pull requests

1 participant