Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Spike modifications for cv32e40s reference model #2462

Open
wants to merge 3 commits into
base: cv32e40s/release
Choose a base branch
from

Conversation

torjeikenes
Copy link

This PR adds the changes to Spike necessary to support the reference model in #2432.
I have attempted to split it into two main contributions:

  • Added spike support for CV32E40S
    • Configuration of memory regions
    • Modifications to CSRs
    • Modifications to RVFI
  • Modified spike to work with the reference model
    • Injection of interrupts and debug requests
    • Modifications to interrupt handling in spike, adding an interrupt_allowed check and external interrupts
    • Store and revert to previous states

(@silabs-robin, I can't add reviewers)

- Inject interrupts and debug requests
- Store and revert to previous states
- Add a seperate interrupt_allowed bool
vendor/riscv/riscv-isa-sim/riscv/Proc.cc Show resolved Hide resolved
vendor/riscv/riscv-isa-sim/riscv/Proc.cc Show resolved Hide resolved
@@ -0,0 +1,415 @@
diff --git a/vendor/riscv/riscv-isa-sim/riscv/Proc.cc b/vendor/riscv/riscv-isa-sim/riscv/Proc.cc
Copy link
Contributor

Choose a reason for hiding this comment

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

Were these patch files the source which some vendorization scripts turned into the rest of the file changes? How was it done?

Copy link
Author

Choose a reason for hiding this comment

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

I did not use the script. I just used git diff redirected to a .patch file and applied this.

Copy link
Contributor

Choose a reason for hiding this comment

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

How do we know that everything new in this PR is compatible with the existing script-based flow?

Copy link
Author

Choose a reason for hiding this comment

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

With my current setup on a server with an older git version, I cannot run the script in this branch or on master. Can you check if it runs for you? I get a git error when running this python3 util/vendor.py vendor/riscv_riscv-isa-sim.vendor.hjson

vendor/riscv/riscv-isa-sim/riscv/Types.h Show resolved Hide resolved
openhw::reg::unlogged_write( openhw::reg::unlogged_read()-1);

// disable since we (at the moment) check mcounterinhibit
//openhw::reg::unlogged_write( openhw::reg::unlogged_read()-1);
Copy link
Contributor

Choose a reason for hiding this comment

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

What is this?

Copy link
Author

Choose a reason for hiding this comment

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

I modified this and the +1 below to add support for disabling mcycle counting with mcountinhibit to match cv32e40s. I have not tested this much with mcountinhibit enabled since mcycle would likely mismatch with the core anyway.

Copy link
Contributor

Choose a reason for hiding this comment

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

Is the old behavior preserved unless the new behavior is explicitly asked for?

Copy link
Author

Choose a reason for hiding this comment

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

I think so, but I have not done much testing with mcountinhibit enabled.
Since Spike "sees" fewer cycles than the core, mcycle would likely have a mismatch to a core anyway unless larger modifications are made.

return true;
}

reg_t wide_counter_csr_t::written_value() const noexcept {
// Re-adjust for upcoming bump()
return openhw::reg::unlogged_read() + 1;
return openhw::reg::unlogged_read(); //+ 1; // Disable since we dont always bump
Copy link
Contributor

Choose a reason for hiding this comment

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

Why didn't the +1 cause problems before? And should the code simply be deleted?

Copy link
Author

Choose a reason for hiding this comment

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

The +1 caused errors in cv32e40s_csr_access_test which reads the mcycle csr. Spike did not support disabling and enabling counting of mcycle with mcountinhibit. In 40S counting is disabled by default, so this caused a mismatch when the mcycle csr was read. Here mcycle counted up in Spike but not in the core, since mcountinhibit was enabled (disabling counting).

@@ -1239,9 +1242,10 @@ reg_t dcsr_csr_t::read() const noexcept {
v = set_field(v, DCSR_EBREAKH, ebreakh);
v = set_field(v, DCSR_EBREAKS, ebreaks);
v = set_field(v, DCSR_EBREAKU, ebreaku);
v = set_field(v, DCSR_STOPCYCLE, 0);
v = set_field(v, DCSR_STOPCYCLE, 1); //TODO: Make configurable
Copy link
Contributor

Choose a reason for hiding this comment

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

This TODO needs resolution.
Plus several others.

Copy link
Author

@torjeikenes torjeikenes Jun 11, 2024

Choose a reason for hiding this comment

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

Not sure if these changes also affect cva6, or if they need to be configurable to each core. This should also be checked with the script discussed above

Copy link
Contributor

Choose a reason for hiding this comment

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

DCSR_STOPCYCLE is bit 10, AKA dcsr.STOPCOUNT, and it is set to 1 to reflect https://docs.openhwgroup.org/projects/cv32e40s-user-manual/en/latest/control_status_registers.html#debug-control-and-status-dcsr ?
Is that correct?

If the entire Spike source now gets hardcoded to 40s-specifics, then I agree with the comment that it should be made configurable.

Copy link
Author

Choose a reason for hiding this comment

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

That is correct.
If these changes interfere with cva6, a parameter could be added to configure this. DCSR has changes both to DCSR_STOPCYCLE and DCSR_MPRVEN, so maybe one parameter could contain the full DCSR, or there could be multiple individual parameters to configure stopcycle and mprven .

@@ -643,7 +644,7 @@ void processor_t::set_mmu_capability(int cap)
void processor_t::take_interrupt(reg_t pending_interrupts)
{
// Do nothing if no pending interrupts
if (!pending_interrupts) {
if (!pending_interrupts || !interrupt_allowed) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Is the default case for interrupt_allowed handled such that other users won't get surprised by this?

Copy link
Author

Choose a reason for hiding this comment

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

Added a default value now

Copy link
Contributor

Choose a reason for hiding this comment

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

But is it possible for the surrounding logic to change this signal so that users of other processor cores get their Spike-based simulations tampered with unexpectedly?

Copy link
Author

Choose a reason for hiding this comment

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

Since interrupt_allowed is set to true by default and only modified by the added interrupt() method, this should not influence old behavior.

Copy link
Contributor

Choose a reason for hiding this comment

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

For the other PR, even if I couldn't compile even vanilla Spike I am still about to run ci_check for 40s to test the PR branch.

But here, I don't know how I can try this out myself.

@MikeOpenHWGroup and @MarioOpenHWGroup, the least net use of energy is most likely if one of you could run some check that you are already used to running, which uses some of the files involved in this PR.

@torjeikenes Would one very minimal way to test this simply be to mkdir build; cd build; ../configure; make as in building spike within the correct directory in vendor/?

Copy link
Author

Choose a reason for hiding this comment

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

yes, mkdir build; cd build; ../configure; make in vendor/riscv/riscv-isa-sim should test that it builds ok.

Copy link
Contributor

@silabs-robin silabs-robin left a comment

Choose a reason for hiding this comment

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

Just flagging all new TODOs in review comments, for visibility.

rvfi.trap |= 1 << 0; //trap [0]
rvfi.trap |= 1 << 1; //exception [1]
rvfi.trap |= 0x1F8 & ((this->which_trap) << 3); //exception_cause [8:3]
//TODO:
Copy link
Contributor

Choose a reason for hiding this comment

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

Just flagging all new TODOs in review comments, for visibility.

Copy link
Author

@torjeikenes torjeikenes Jun 21, 2024

Choose a reason for hiding this comment

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

The rvfi_trap signal is not fully implemented for debug mode like this. I think this has been fixed in a recent PR to master.

rvfi.rd1_wdata = 0;
}

bool mem_access = false; // TODO: support multiple memory writes/reads
Copy link
Contributor

Choose a reason for hiding this comment

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

Just flagging all new TODOs in review comments, for visibility.

Copy link
Author

Choose a reason for hiding this comment

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

At the moment, I only support reporting one memory read or write over RVFI per instruction. To account for this, I only compare the "lowest" bits in the comparison module. 40S can report multiple memory operations per instruction, so this should be added to fully match the core, but I did not prioritize implementing this since it is not essential.

bool Processor::interrupt(reg_t mip, reg_t mie, uint32_t revert_steps, bool interrupt_allowed) {
state_t *state = this->get_state();

reg_t mask = 0xFFFF0888; // TODO: automatically generate this
Copy link
Contributor

Choose a reason for hiding this comment

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

Just flagging all new TODOs in review comments, for visibility.

Copy link
Author

@torjeikenes torjeikenes Jun 21, 2024

Choose a reason for hiding this comment

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

This might be unnecessary since a similar mask is generated when mie is reset. But it should not be breaking to have as is either

v = set_field(v, DCSR_STOPTIME, 0);
v = set_field(v, DCSR_CAUSE, cause);
v = set_field(v, DCSR_MPRVEN, 1); // TODO: Make configurable
Copy link
Contributor

Choose a reason for hiding this comment

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

Just flagging all new TODOs in review comments, for visibility.

Copy link
Author

Choose a reason for hiding this comment

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

See the other comment about dcsr_stopcycle above

@@ -17,7 +17,7 @@

// These needs to match the link.ld
#define DEBUG_ROM_WHERETO 0x300
#define DEBUG_ROM_ENTRY 0x800
#define DEBUG_ROM_ENTRY 0x1A110800 //TODO: make configurable
Copy link
Contributor

Choose a reason for hiding this comment

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

Just flagging all new TODOs in review comments, for visibility.

Copy link
Author

Choose a reason for hiding this comment

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

It looks like a debug handler address parameter has been added to master, so this can probably be solved with a new merge from master

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants