google / google/CFU-Playground
Instruction after CFU instruction is getting wrong result
- Dominant language
- Verilog
- Stars
- 565
- Forks
- 160
- PR merge metrics
- No merged PRs in 30d
Description
Create `proj/hps_accel/src/main.c` with the following contents:
```cc
#include
#include "base.h"
#include "riscv.h"
__attribute__((optimize("align-functions=32"))) int check_post_cfu_instruction(
int input) {
register int output;
int tmp;
asm volatile(
// Some padding. The alignment of the CFU instruction seems to matter.
"nop \n\t"
"nop \n\t"
"nop \n\t"
"nop \n\t"
"nop \n\t"
"nop \n\t"
// Set up an input to our CFU instruction.
"li a6, 0; \n\t"
// These four instructions seem to need to be stores.
"sw %[input],%[tmp] \n\t"
"sw %[input],%[tmp] \n\t"
"sw %[input],%[tmp] \n\t"
"sw %[input],%[tmp] \n\t"
// This can be any instruction.
"nop \n\t"
// Our CFU instruction.
".word ((CUSTOM0) | (regnum_a7 << 7) | (regnum_a6 << 15) | (regnum_a6 << "
"20) | ((0) << 12) | ((5) << 25)) \n\t"
// The value stored into %[output] is wrong.
"mv %[output],%[input] \n\t"
// Changing the following nop to repeat the line above, or swapping it
// with the line above "fixes" the bug.
"nop \n\t"
"nop \n\t"
"nop \n\t"
: [output] "=r"(output), [tmp] "=m"(tmp)
: [input] "r"(input)
: "a6", "a7"
);
return output;
}
int main(void) {
init_runtime();
int v = check_post_cfu_instruction(42);
// This should print the value 42, but when the bug is occurring, it prints 0.
printf("Value: %d\n", v);
return (0);
}
```
Then run:
```sh
(source environment; cd proj/hps_accel/; make PLATFORM=sim load)
```
Expected output:
```
....
Value: 42
```
Actual output:
```
....
Value: 0
```
Swapping the `mv` instruction with the `nop` that follows it, adjusting the alignment +/- 8 or changing some of the store instructions to `nop`s makes the problem go away.
I'm guessing this is probably a bug in VexRiscv's CFU interface - possibly some bad interaction with instruction pipelining.
Contributor guide
Assessment
This issue has not been assessed yet.