-
Notifications
You must be signed in to change notification settings - Fork 3
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
Improve Handling of X0 register #95
Comments
I remember a while back @jopperm and I had a discussion about making aliases much more versatile by allowing concatenation aliases. We ultimately didn't continue with the idea, but it could almost solve the |
Actually this does not really solve the actual problem. The RISC-V ISA spaec says that x0 can be written but will always read 0. Defining a register as const or setting a constraint on it would prevent this behavior. |
Thank you for your feedback. I can totally live with that check in the behavior. |
What would you think about adding optional read/write wrappers to (subsets of) registers files? This would on the other hand make it easier to implement the RISC-V Exception/Interrupt Handling behavior in CoreDSL. See https://github.com/tum-ei-eda/etiss_arch_riscv/blob/2dca88c533a145b50d07194fc6c10b552d96ee71/tum_mod.core_desc#L100 by @ wysiwyng. Currently we need to overwrite each of the CSR* instructions with our own versions which calling With this supported it would be straightforward to handle the X0 special case by replacing its write-behavior with a no-op and read-behavior with a constant 0. In addition this might be helpful when implementing CSR/Memory-Mapped-Peripherals in CoreDSL (not sure if this is relevant). An example would be clearing an interrupt flag bit implicitly on a register read. Please let me now if this is nonsense or rather desirable? |
It doesn't work for all cases relevant for CSRs, but what about the following?
(please ignore any syntactical errors) |
@neithernut Thank you for that proposal. This makes sense at a first glance and is very minimalistic. However have we already settled on how always blocks are scheduled? I mean for this we would need to execute the always block after each instruction while for other usecases (implicit pc increment) it would make more sense to execute the always block first. |
@neithernut per the
would mean that |
i support the read/write overrides proposed above, i suggested them in the past especially for CSR handling. syntax suggestion 1 (using existing syntactical elements):
alternatively, a separate section for overrides could be introduced, using a syntax similar to Python or C# properties:
for the latter, it would be interesting whether the open questions for any such implementation:
|
I strongly dislike the idea of these accessors and override functions. All they do is introduce syntactic sugar that converts expressions of the form
The proposals above are way too involved if their only goal is to avoid a handful of |
The proposed accessor feature would be overkill for the X0 "problem" but essential for handling the CSRs in a straightforward fashion. @AtomCrafty Your proposed alternative would either require updating the upstream RISCV_ISA_COREDSL code (which is not always feasible) or reimplementing every CSR instruction in a downstream codebase (see |
Then I have fundamentally misunderstood the issue you're trying to solve here. Could you please explain that whole CSR issue? I'm not familiar with RISC-V, so this is going over my head. It sounds to me like you saying the accessors are necessary because they allow you to change the behavior of existing code without having to change the code itself. Wouldn't it make more sense to allow for underspecified ("abstract") functions in the base implementation that can then be specified by the derived cores? |
Let me try to motivate it using our implementations for the RVF, Zicsr and Zicntr Extensions. Currently using With the syntax proposed above, I was able to cut this down to just 32 (21 excluding constants) lines:
Of course there are more CSRs which require this handling such as MSTATUS/SSTATUS (shaddowing due to different privilege levels) or MISA (read only). |
@PhilippvK Thank you for the explanation, I think I understand the issue now. From a software developer's perspective, this should be solved by defining extension points in So now that I actually understand the issue, let me address the proposed solution properly. I will retract my previous disagreement with the approach, but let me propose a slight variation that could make this even more flexible. Currently, it only allows the interception of individual elements, but I could conceive a scenario where one would like to intercept entire ranges of an address space - e.g. memory mapped ROM. How practically relevant that is I cannot judge. Anyway, my idea would be to instead define filter layers. Instead of defining multiple interceptors, you would define one or more filters over the entire address space. The filters could check whether the index is in range and decide whether to take action. If that should not be the case, control can be passed to the next filter layer. This would allow the specification of features like Intel's APIC, which is memory mapped to a dynamically configurable range of addresses, so it cannot be modelled by accessors since those seem to have fixed indices. But I don't know whether modelling a memory controller is a valid use case for CoreDSL. I'm much more familiar with x86 than RISC-V, so that is usually my point of reference, but I don't think accurately specifying x86 is a design goal of CoreDSL. I realize this approach might not work in practice because these kinds of dynamic checks are prohibitively expensive compared to the zero overhead accessors. Maybe both are relevant for different scenarios. Or maybe one is just a special case of the other, where all indices are known at compile time and dynamic checks can be optimized away. |
As far as I can tell the whole dicussion took the wrong turn. First and foremost: the point was handling of X0. Secondly: CoreDSL as it stands describes instructions in an implementation independent way and not just for RSIC-V. All the discussion above bring implementation details into this description. Implementation details in the sense of platform specfiics like the existence and behavior of specific CSRs (which might vary from core to core) and in the sense of downstream tools consuming the CoreDSL descriptions (in this case ETISS). |
@eyck I agree that I should habe opened up a new issue for the topic. But the discussion was already going and I was too lazy to summarize everything again over there. The discussed approach would as a side effect also solve the X0 handling.
Yes for Zicsr and probably Interrupt/Exception Handling. But for the FCSR and MISA this behavior shouldn’t be implementation specific at all.
Yes, let’s not forget this completely. This issue however can be closed, since getting rid of the |
Similarly to #94, the
if(rd != 0)
behavior is coded into every single instruction. We probably should find a way to specify theX[0]==0
constraint on a higher level. (Alternatively we could add a way to set access rights (R/W) for memory ranges, which could also be reused for some CSRs)What do you think?
The text was updated successfully, but these errors were encountered: