riscv-boom / riscv-boom

SonicBOOM: The Berkeley Out-of-Order Machine
BSD 3-Clause "New" or "Revised" License
1.69k stars 417 forks source link

Dromajo/BOOM cosim sNAN bug with SQRT.s #550

Open renau opened 3 years ago

renau commented 3 years ago

Type of issue: bug report Impact: new rtl


I have a potential bug on SonicBoom. I did not try rocket, but this happens with top of the tree chipyard.

This sequence of assembly instructions fail in cosim. The issue is that there is a snan for float, and then a SQRT.s is performed. The result should signaling nan and the fflags should be set. Dromajo does but SonicBoom does not. The SQRT.d works fine.

# Float version (fails cosim)
    csrwi   fflags, 0
    flw fa5,snan32,a4
    fsqrt.s fa6,fa5
    csrr    a0, fflags  # incorrect value
...
snan32:
    .word   0x7F800001

The following version using doubles works fine:

    csrr    a5, fflags
# Double version
    csrwi   fflags, 0
    fld fa5,snan64,a4
    fsqrt.d fa6,fa5
    csrr    a0, fflags
...
snan64:
    .dword  0x7FF0000000000001

When I run the double precision version with cosim. I get:

make CONFIG=DromajoBoomConfig ENABLE_DROMAJO=1 BINARY=nan_test_d run-binary
...
[UART] UART0 is here (stdin/stdout).
testing is 0x000000000000010 value...

When I run the signal precision version with cosim. I get:

make CONFIG=DromajoBoomConfig ENABLE_DROMAJO=1 BINARY=nan_test_s run-binary
....
testing is 0xFAIL: Dromajo Simulation Failed with exit code:        8191
[64] %Error: SimDromajoCosimBlackBox.v:75: Assertion failed in TOP.TestHarness.dbridge.dromajo
%Error: /mada/users/renau/projs/chipyard/sims/verilator/generated-src/chipyard.TestHarness.DromajoBoomConfig/SimDromajoCosimBlackBox.v:75: Verilog $stop

The command line to compile:

riscv64-unknown-elf-gcc -march=rv64gc -mabi=lp64 -static -mcmodel=medany -nostdlib -nostartfiles nan_test.c mycall.S crt.S -lgcc -T test.ld -o nan_test_s

The nan_test.c (just to print and call the assembly)

/ Code based on Sifive HIFive uart base https://wiki.osdev.org/HiFive-1_Bare_Bones

#include <stddef.h>

#define UART0_CTRL_ADDR 0x54000000UL
#define UART_REG_TXFIFO         0x00

static inline unsigned int mmio_read_u32(unsigned long reg, unsigned int offset) {
  return (*(volatile unsigned int *) ((reg) + (offset)));
}

static inline void mmio_write_u8(unsigned long reg, unsigned int offset, unsigned char val) {
  (*(volatile unsigned int *) ((reg) + (offset))) = val;
}

static void __uart_write(unsigned char byte) {
  while (mmio_read_u32(UART0_CTRL_ADDR, UART_REG_TXFIFO) & 0x80000000)
    ;

  mmio_write_u8(UART0_CTRL_ADDR, UART_REG_TXFIFO, byte);
}

static void uart_write(unsigned char *buf, size_t len) {
  int i;
  for (i = 0; i < len; i ++) {
    __uart_write(buf[i]);
    /* If an LF was written, also write a CR */
    if (buf[i] == '\n') {
      __uart_write('\r');
    }
  }
}

static size_t strlen(char *str) {
  int len = 0;
  int i;

  for (i = 0; str[i] != 0; i ++)
    len ++;

  return len;
}

static void uart_write_string(unsigned char *buf) {
  uart_write(buf, strlen((char *) buf));
}

unsigned long int mycall();

//unsigned int snan32= 0x7F800001UL;
//unsigned long snan64= 0x7FF0000000000001;

char *tohex[16]={"0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"};
void _init(int cid, int nc) {
  unsigned long int a=0x3ab;

  uart_write_string("testing is 0x");
  a = mycall();
  for(int i=56;i>=0;i=i-4) {
    uart_write(tohex[(a>>i)&0xF],1);
  }
  uart_write_string(" value...\n");

  for (;;);
}

The mycall.S (comment the float code to create the test_nan_d, otherwise it creates test_nan_s)

    .file   "test-sqrt.c"
    .option nopic
  .section .text,"ax",@progbits
  .globl  mycall
  .type   mycall, @function
mycall:
  li      a1,1<<13
  csrr    a0,mstatus
  or      a0,a0,a1
  csrw    mstatus,a0
  # la      sp,end + 65536
  li      a1,0
  li      a0,0
  li      a4,0

    csrr    a5, fflags
# Double version
    csrwi   fflags, 0
    fld fa5,snan64,a4
    fsqrt.d fa6,fa5
    csrr    a0, fflags

# Float version (fails cosim)
    csrwi   fflags, 0
    flw fa5,snan32,a4
    fsqrt.s fa6,fa5
    csrr    a0, fflags

  ret

  .size   mycall, .-mycall

    .globl  snan32
    .section    .rodata
    .align  8
    .type   snan32, @object
    .size   snan32, 4
snan32:
    .word   0x7F800001

  .globl    snan64
  .section  .rodata
  .align    8
  .type snan64, @object
  .size snan64, 8
  /*0xff94ffff*/
snan64:
    .dword  0x7FF0000000000001

The crt.S comes from the dromajo repo https://github.com/chipsalliance/dromajo/blob/master/run/crt.S The test.ld is also at the dromajo repo https://github.com/chipsalliance/dromajo/blob/master/run/test.ld

@et-tommythorn contributed the assembly and checked dromajo which seems to be fine.

files.tar.gz

jerryz123 commented 3 years ago

Thanks. There are known issues with floating point flag handling

renau commented 3 years ago

I never saw a patch. Is there one or working on it?

jerryz123 commented 3 years ago

There is not one in progress, but I am aware of these issues.