Skip to content

Use C++ Sail output - #1274

Merged
Tim Hutt (Timmmm) merged 3 commits into
riscv:masterfrom
Timmmm:user/timh/cpp
Dec 5, 2025
Merged

Use C++ Sail output#1274
Tim Hutt (Timmmm) merged 3 commits into
riscv:masterfrom
Timmmm:user/timh/cpp

Conversation

@Timmmm

@Timmmm Tim Hutt (Timmmm) commented Sep 12, 2025

Copy link
Copy Markdown
Collaborator

This switches from using Sail's C output to using C++. The output code gets wrapped in a class, which means we can create more than one instance of it (e.g. for multicore).

The Model class is currently not thread safe due to the use of temporary globals in sail.c. So although you can simulate multicore systems, you have to execute them one at a time.

The handling of platform callbacks is a little convoluted but I think this is a quite flexible solution. Sail is instructed to derive the Model class from PlatformImpl which has virtual methods for all of the platform callbacks with default nop implementations.

This means the default Model can be constructed and has a "nop" platform. Then we add our implementation of the platform with ModelImpl which overrides those methods.

ModelImpl also allows registering callback receivers.

This is not 100% perfect yet. We still have a global g_model, which is not ideal.

Comment thread model/core/prelude.sail Outdated
@Timmmm Tim Hutt (Timmmm) added the pending sail compiler PRs/issues that can only be resolved with a newer release of the Sail compiler label Sep 25, 2025
@nadime15

Copy link
Copy Markdown
Collaborator

This is probably unrelated for now, but enabling multi-hart simulation would affect the Debug Module we are working on.
At the moment, we assume only a single hart is available, but in theory the Debug Module can manage a large number of harts.

So far, all of our code has been written in Sail (since it makes handling the many registers and bitfields easier), but I think parts of the Debug Module would need to be moved back to C++ to properly support 1+N harts.

@Timmmm

Copy link
Copy Markdown
Collaborator Author

That's a good point. I was sort of vaguely aware of that. I guess in theory you could still write it in Sail as long as it was a completely separate Sail model, and then you'd need to connect them somehow.

@nadime15

Copy link
Copy Markdown
Collaborator

I guess in theory you could still write it in Sail as long as it was a completely separate Sail model, and then you'd need to connect them somehow.

Yeah, that would be perfect if this was possible! We can revisit this topic once this PR is merged, along with the debug stuff.

Comment thread c_emulator/riscv_callbacks_log.cpp Outdated
@Timmmm
Tim Hutt (Timmmm) marked this pull request as ready for review November 10, 2025 17:06
@Timmmm
Tim Hutt (Timmmm) force-pushed the user/timh/cpp branch 3 times, most recently from 0595c87 to 1d5c593 Compare November 11, 2025 10:11
@Timmmm Tim Hutt (Timmmm) removed the pending sail compiler PRs/issues that can only be resolved with a newer release of the Sail compiler label Nov 11, 2025
@github-actions

github-actions Bot commented Nov 11, 2025

Copy link
Copy Markdown

Test Results

2 115 tests  ±0   2 115 ✅ ±0   21m 7s ⏱️ -1s
    1 suites ±0       0 💤 ±0 
    1 files   ±0       0 ❌ ±0 

Results for commit 7716f79. ± Comparison against base commit 2eafe6d.

♻️ This comment has been updated with latest results.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some initial comments. Will review in more detail later.

I also think it might be worth renaming the c_emulator directory to cpp_emulator.

Comment thread c_emulator/riscv_sim.cpp Outdated
Comment thread model/CMakeLists.txt Outdated
Comment thread c_emulator/riscv_sail.h Outdated
Comment thread model/CMakeLists.txt Outdated
@arichardson

Copy link
Copy Markdown
Collaborator

Some initial comments. Will review in more detail later.

I also think it might be worth renaming the c_emulator directory to cpp_emulator.

Or just emulator since the ocaml one no longe exists?

@Timmmm

Copy link
Copy Markdown
Collaborator Author

Or just emulator since the ocaml one no longe exists?

I think I originally did that when the OCaml emulator was removed but people wanted to keep the c_. I can't remember why exactly. Maybe in case we add the OCaml one back one day? Or a Rust one? :-D

@Timmmm

Copy link
Copy Markdown
Collaborator Author

Rebased. That was fairly painful so I'm afraid I had to remove the reservation printing option. I don't think it's too bad since it didn't really exist until very recently. We can add it back later.

It would be good to get this merged fairly soon to avoid more painful rebases!

Comment thread c_emulator/riscv_callbacks_if.h Outdated
Comment thread c_emulator/riscv_model_impl.h Outdated

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems fine to me. Thanks for the hard work on adding C++ output!

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Couple of minor nits, but overall looks great. Make sure to update all of the references in the README that talk about the C emulator/generated C code.

I'd also still like to see the c_emulator directory renamed to either cpp_emulator or just emulator.

@@ -6,7 +6,7 @@
// Generated in the model C code. This is a simple test runner that just

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// Generated in the model C code. This is a simple test runner that just
// Generated in the model C++ code. This is a simple test runner that just

Comment thread doc/ReadingGuide.md Outdated
Comment thread c_emulator/riscv_platform_if.h Outdated
// The Model class derives from this one so when Sail calls C callback
// functions it actually calls methods of this class. However they are
// virtual functions so they actually call the Platform implementations
// (see riscv_platform_impl.h). It's done this way because:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

riscv_model_impl.h? There is no riscv_platform_impl.h. And if so, should we rename this file to riscv_model_if.h (or vice versa)?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops yeah should have been riscv_model_impl.h. I think platform is still an ok name though because this is an interface to the platform for the model... if that makes sense?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fine either way, but I think it would be easier to follow the logic if the interface and implementation names match.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR migrates the RISC-V Sail model from C to C++ output, enabling multiple model instances for multicore simulation. The Sail-generated code is now wrapped in a hart::Model class derived from PlatformInterface, allowing flexible platform callback implementations through virtual methods. The ModelImpl class provides the concrete platform implementation and manages callback registration.

Key changes:

  • Sail external function declarations changed from c: to cpp: target
  • Model generated as C++ class in hart namespace, derived from PlatformInterface
  • Platform callbacks implemented as virtual methods in ModelImpl

Reviewed changes

Copilot reviewed 36 out of 36 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
model/**/*.sail Updated external function declarations from c: to cpp: target
model/CMakeLists.txt Changed Sail compiler to generate C++ with namespace and class derivation
c_emulator/riscv_platform_if.h New platform interface base class with virtual callback methods
c_emulator/riscv_model_impl.h/cpp New model implementation with platform callbacks and helper methods
c_emulator/riscv_callbacks_if.h Updated callback interface to accept Model reference parameter
c_emulator/riscv_callbacks_*.cpp Updated callback implementations to use Model reference
c_emulator/riscv_softfloat.h/cpp Removed extern "C" wrapping for C++ compatibility
c_emulator/riscv_sim.cpp Updated to use global g_model instance and new API
c_emulator/rvfi_dii.h/cpp Updated RVFI handler to use Model instance and member function pointers
c_emulator/CMakeLists.txt Updated build to compile .cpp instead of .c for generated model
test/unit_tests/main_unit_tests.cpp Removed extern "C" and init_sail_configured_types() call
doc/ReadingGuide.md Marked documentation as needing update
c_emulator/riscv_*.h/cpp (deleted) Removed old C-style platform and callback implementations

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread c_emulator/riscv_platform_if.h Outdated
Comment thread c_emulator/riscv_platform_if.h Outdated
Comment thread c_emulator/riscv_platform_if.h
Comment thread test/unit_tests/main_unit_tests.cpp
Comment thread c_emulator/riscv_callbacks_log.cpp
Comment thread c_emulator/riscv_callbacks_log.cpp
@jordancarlin

Copy link
Copy Markdown
Collaborator

Oops. Seems like I hit the wrong button and triggered a review from Copilot. Feel free to disregard.

This switches from using Sail's C output to using C++. The output code gets wrapped in a `class`, which means we can create more than one instance of it (e.g. for multicore).

The `Model` class is currently *not* thread safe due to the use of temporary globals in `sail.c`. So although you can simulate multicore systems, you have to execute them one at a time.

The handling of platform callbacks is a little convoluted but I think this is a quite flexible solution. Sail is instructed to derive the `Model` class from `PlatformImpl` which has virtual methods for all of the platform callbacks with default nop implementations.

This means the default `Model` can be constructed and has a "nop" platform. Then we add our implementation of the platform with `ModelImpl` which overrides those methods.

`ModelImpl` also allows registering callback receivers.

This is not 100% perfect yet. We still have a global `g_model`, which is not ideal.
@Timmmm

Copy link
Copy Markdown
Collaborator Author

It caught a couple of very minor issues at least...

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried my best to review it. I am a C++ noob, but it looks good to me! :D

Comment thread c_emulator/riscv_model_impl.cpp
Co-authored-by: Nadime Barhoumi <nadime@riscv.org>
Signed-off-by: Tim Hutt <tdhutt@gmail.com>
@Timmmm Tim Hutt (Timmmm) self-assigned this Dec 1, 2025

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably good to get this merged ASAP to avoid further conflicts.

Comment thread c_emulator/riscv_platform_if.h

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should merge this and then we can follow up with smaller PRs for any other improvements.

@Timmmm

Copy link
Copy Markdown
Collaborator Author

Ok I'll give it a good few days, seeing as this is a pretty huge change, and then merge it.

@Timmmm Tim Hutt (Timmmm) added the will be merged Scheduled to be merged soon if nobody objects label Dec 1, 2025
@Timmmm
Tim Hutt (Timmmm) added this pull request to the merge queue Dec 5, 2025
Merged via the queue into riscv:master with commit da1eb87 Dec 5, 2025
12 of 13 checks passed
@Arielfoever

Copy link
Copy Markdown
Contributor

Oops. Seems like I hit the wrong button and triggered a review from Copilot. Feel free to disregard.

little bit off topic.

Just wondering where is the button? Want to try in #1370

@jordancarlin

Copy link
Copy Markdown
Collaborator

Oops. Seems like I hit the wrong button and triggered a review from Copilot. Feel free to disregard.

little bit off topic.

Just wondering where is the button? Want to try in #1370

In the top right where you can request reviews from anyone else.

@Timmmm
Tim Hutt (Timmmm) deleted the user/timh/cpp branch December 10, 2025 10:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

will be merged Scheduled to be merged soon if nobody objects

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants