Skip to content

Conversation

weiren2
Copy link

@weiren2 weiren2 commented Jul 29, 2025

Issue

When compiling with -march=x86-64-v4 or -march=znver4, test case br1029b fail to pass. Based on PR #919 and discussion in #917, I think the following

iverilog/vvp/vthread.cc

Lines 2383 to 2386 in db82380

if (r >= 0.0)
thr->words[cp->bit_idx[0]].w_uint = (uint64_t)floor(r+0.5);
else
thr->words[cp->bit_idx[0]].w_uint = (uint64_t)ceil(r-0.5);
is the root cause. Basically there are still direct double-to-unsigned-integer casts (undefined behavior) in vpi_vthr_vector.cc and vthread.cc.

This PR fixes:

  • Replaced custom rounding with rounding functions from standard library (<cmath> is already included in the code and I noticed that c++11 is in the default flags).
  • Used a common utility header for vlg_round_to_u64 to safely cast form double to uint64_t and reuse across files.
  • Refactor binary string value conversion logic that used in vpi_callback.cc and vpi_vthr_vector.c.

I have tested this PR locally on my x86 machine both with and without -march=x86-64-v4. Test case br1029b passes in both configurations, and no regressions were introduced. It probably needs to be tested on other architectures as well but I don't have ARM machines at the moment.

Please let me know if there are any comments and feel free to make edits.

@weiren2 weiren2 changed the title Fix and refactor conversion from double to uint64_t Fix and refactor conversion from double to uint64_t (fixes test br1029b on x86-64-v4) Jul 30, 2025
@caryr
Copy link
Collaborator

caryr commented Aug 1, 2025

I looked at this briefly and I think there should be a few minor changes.

First the string conversions are not maintaining the indentation so it's harder to see what you changed and the original code in the diff. I still need to review this in detail.

Second the rounding items should likely be added to the config.h.in file where we determine if round() is available and if so use it otherwise the work around. The conversion to uint64_t should use the existing int64_t conversion that determines if lround or llround are appropriate. That can just be an inline function after the int64_t conversion has been determined.

This should ideally be checked in both the run time as well as the compiler. I can help with the configure part if needed. Also, ideally refactor this into two commits. One for the rounding issue and one for the conversion change.

@weiren2 weiren2 marked this pull request as draft August 2, 2025 05:26
@weiren2
Copy link
Author

weiren2 commented Aug 2, 2025

Thanks for the feedback. I'll check config.h.in to understand the required changes there, and make sure the indentation matches the existing style. As suggested, I can refactor this into two commits.

@caryr
Copy link
Collaborator

caryr commented Aug 2, 2025

You are welcome and thank you for your contribution!

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

Successfully merging this pull request may close these issues.

2 participants