wokwi / rp2040js

A Raspberry Pi Pico Emulator in JavaScript
MIT License
384 stars 40 forks source link

pico-sdk float_test and double_test fail #44

Closed urish closed 3 years ago

urish commented 3 years ago

Both tests fail when running from raspberrypi/pico-sdk@e0872a32cceaa2f3aac5f9dcc180e62f5f3ab103 (develop branch):

float_test fail
double_test fail

When running from master branch (1.1.2 release), float_test passes and double_test fails.

Both tests seem to fail on SINCOS.

It might be a good idea to use gdbdiff to investigate this issue.

float_test

SINCOS 0.000000000000000000 1.000000000000000000 SINCOS mismatch

double_test

SINCOS -1.000000000000000000 1.000000000000000000 SINCOS mismatch

Turro75 commented 3 years ago

I don't know if it is related but I tried also pico_divider_test, seems the emulator is not able to process the %f in printf

urish commented 3 years ago

What do you expect to get and what do you get?

Did you try with the bootrom from the silicone?

Turro75 commented 3 years ago

let gdbdiff running overnight:

> rp2040js@0.6.0 start
> ts-node demo/emulator-run.ts

RP2040 GDB Server ready! Listening on port 3334
GDB connected

Read from invalid memory address: ffffffc
Read from invalid memory address: ffffffc
Read from invalid memory address: ffffffc
Read from invalid memory address: ffffffc
Read from invalid memory address: ffffffc
Read from invalid memory address: ffffffc
Read from invalid memory address: ffffffc
Read from invalid memory address: ffffffc
Read from invalid memory address: ffffffc
Read from invalid memory address: ffffffc
Read from invalid memory address: ffffffc
Read from invalid memory address: ffffffc
Read from invalid memory address: ffffffc
Read from invalid memory address: ffffffc
Read from invalid memory address: ffffffc
Read from invalid memory address: ffffffc
Read from invalid memory address: ffffffc
Read from invalid memory address: ffffffc
Read from invalid memory address: ffffffc
Read from invalid memory address: ffffffc
Read from invalid memory address: ffffffc
Read from invalid memory address: ffffffc
Read from invalid memory address: ffffffc
Read from invalid memory address: ffffffc
write 1 to 10001a14
write de to 10001a15
Write to undefined address: 18000008
Write to undefined address: 18000014
Write to undefined address: 180000f0
Write to undefined address: 18000000
Write to undefined address: 18000008
Write to undefined address: 18000008
Write to undefined address: 18000000
Write to undefined address: 18000004
Write to undefined address: 180000f4
Write to undefined address: 18000008
Write to undefined address: 18000008
Write to undefined address: 180000f4
Write to undefined address: 18000008
Unimplemented peripheral WATCHDOG_BASE write to 2c: 524
Unimplemented peripheral TBMAN_BASE read from 0
Unimplemented peripheral UART0 write to 24: 26
Unimplemented peripheral UART0 write to 28: 3
Unimplemented peripheral UART0 write to 48: 3
write 1a to 10001a14
write 60 to 10001a15
GDB disconnected
GDB connected

  S32 30 302.741000     148.603000
SEV
GDB disconnected

while on silicone:

  S32 30 60.064000      34.552000
  S32 29 61.573000      34.000000
  S32 28 67.785000      34.000000
  S32 27 72.360000      34.000000
  S32 26 77.670000      34.000000
  S32 25 83.728000      34.000000
  S32 24 92.165000      34.000000
  S32 23 98.439000      34.000000
  S32 22 105.552000     34.000000
  S32 21 114.015000     34.000000
  S32 20 122.658000     34.000000
......and many more....

I have to debug it, it smells as randomize() not working.

If I run the test_divider_pico I get all zero:

RP2040 GDB Server ready! Listening on port 3334
Write to undefined address: 18000008
Write to undefined address: 18000014
Write to undefined address: 180000f0
Write to undefined address: 18000000
Write to undefined address: 18000008
Write to undefined address: 18000008
Write to undefined address: 18000000
Write to undefined address: 18000004
Write to undefined address: 180000f4
Write to undefined address: 18000008
Write to undefined address: 18000008
Write to undefined address: 180000f4
Write to undefined address: 18000008
Unimplemented peripheral WATCHDOG_BASE write to 2c: 524
Unimplemented peripheral TBMAN_BASE read from 0
Unimplemented peripheral UART0 write to 24: 26
Unimplemented peripheral UART0 write to 28: 3
Unimplemented peripheral UART0 write to 48: 3
  S32 30 0.000000       0.000000
SEV
  S32 29 0.000000       0.000000
SEV
  S32 28 0.000000       0.000000
SEV
  S32 27 0.000000       0.000000
SEV
  S32 26 0.000000       0.000000
SEV
  S32 25 0.000000       0.000000
SEV
  S32 24 0.000000       0.000000
SEV
  S32 23 0.000000       0.000000
SEV
  S32 22 0.000000       0.000000
SEV
  S32 21 0.000000       0.000000
SEV
  S32 20 0.000000       0.000000
SEV
  S32 19 0.000000       0.000000
SEV
  S32 18 0.000000       0.000000
SEV
  S32 17 0.000000       0.000000
SEV
  S32 16 0.000000       0.000000
SEV
  S32 15 0.000000       0.000000
SEV
  S32 14 0.000000       0.000000
SEV
  S32 13 0.000000       0.000000
SEV
  S32 12 0.000000       0.000000
SEV
^C 
urish commented 3 years ago

These zeroes are coming probably coming from Systick. They are calculated here, and are based on the value returned by time32().

It's interesting to see why they are always zero, probably some issue with our Systick implementation, but I'd not worry about them too much. Getting them exactly the same as the silicone means we have truly cycle-accurate emulation, which is not trivial at all, and is not a goal right now.

Turro75 commented 3 years ago

Just tested both float and double test against this commit https://github.com/wokwi/rp2040js/pull/64 and it passes!! I compared with diff the output of sil vs emu and they resulted exactly the same.

urish commented 3 years ago

That's wonderful 🎉

Thank you so much for spotting all those small-but-important bugs!

urish commented 3 years ago

Interestingly, float test still fails here:

...
 ----- 1.000000
FSQRT 1.000000000000000000
FCOS 0.540302277000000000
FSIN 0.841470957000000000
FSINCOS 0.841470957000000000 0.540302277000000000
FTAN 1.557407737000000000
FATAN2 0.099668637000000000
FATAN2 1.471127629000000000
FEXP 2.718281746000000000
FLN 0.000000000000000000
POWF 1.000000000000000000
TRUNCF 1.000000000000000000
LDEXPF 2.000000000000000000
FMODF 1.000000000000000000
SINCOS 0.841470957000000000 0.540302277000000000
SINCOS mismatch

 ----- 2.000000
FSQRT 1.414213538000000000
FCOS -0.416146815000000000
FSIN 0.909297407000000000
FSINCOS 0.909297407000000000 -0.416146815000000000
FTAN -2.185039997000000000
FATAN2 0.197395563000000000
FATAN2 1.373400807000000000
FEXP 7.389055729000000000
FLN 0.693147182000000000
POWF 4.000000000000000000
TRUNCF 2.000000000000000000
LDEXPF 8.000000000000000000
FMODF 2.000000000000000000
SINCOS 0.909297407000000000 -0.416146815000000000
SINCOS mismatch
...
d2i32 16.000000->16
d2i32 8.000000->8
d2i32 4.000000->4
d2i32 2.000000->2
d2i32 1.000000->1
d2i32 0.500000->0
1.00000 1.00000000000000000 1.37777781500000000, 0.622222185000000000, 1.00000000000000000 1.23456792000000000e+08
3.00000 9.00000000000000000 3.37777781500000000, 2.62222218500000000, 0.333333343000000000 4.11522640000000000e+07
5.00000 25.0000000000000000 5.37777757600000000, 4.62222242400000000, 0.200000003000000000 2.46913580000000000e+07
7.00000 49.0000000000000000 7.37777757600000000, 6.62222242400000000, 0.142857149000000000 1.76366840000000000e+07
9.00000 81.0000000000000000 9.37777805300000000, 8.62222194700000000, 0.111111112000000000 1.37174210000000000e+07
FAILED

does it PASS for you? The same HEX file I uploaded to this issue?

but double test now passes for me too :-)

Turro75 commented 3 years ago

Yep, the same on my side with Your hex, I'm running gdbdiff, let's see if something turns out.

I moved to the develop branch and both passes but my hex is 85k against 125k of Your so I think I'm compiling with some optimization activated.

urish commented 3 years ago

I think I compiled everything in debug mode (cmake -DCMAKE_BUILD_TYPE=Debug ..)

Turro75 commented 3 years ago

I tried again with cmake -DCMAKE_BUILD_TYPE=Debug -DPICO_DEOPTIMIZED_DEBUG=1 .. and it worked. the hex file is now roughly 125k. Try to fetch current develop branch as it is updated every hour or so, may be You compiled the test in "the bad moment"?

Turro75 commented 3 years ago

I confirm, Your hex fails also on silicone. EDIT The good news is that the emulator provides exactly the same result numbers as silicone. Perfect emulation!!! The mismatch occurs on 2 sincos while with previous commits the test failed on all 3 sincos test. so the PR has fixed something.

urish commented 3 years ago

Okay that's amazing! I think that's exactly what @kilograham wanted: it passes when the silicone passes, and fails when the silicone fails. I really appreciate your efforts making this happen!

kilograham commented 3 years ago

Yes, that is awesome... i need to go see why the test fails with DEDOPTIMIZED_DEBUG (not something I run with often), but reassuring to see it works the same on silicon.

Thanks for this, definitely will get in touch soon, as rp2040js is just the sort of thing we need for improving our testing!!