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
Initial introduction of zfinx #75
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- This is a lot to review in a single commit. It would be preferable to break it up into many smaller commits.
- This appears to include changes to support XLEN != FLEN. Is that so? If so that should be a separate commit or even a separate pull request.
- There is extreme copypasta in the implementation. I'm not that familiar with the Sail language but I hope there is a better way to do this than copy/pasting the same code all over. I've added individual comments on several of them but there are many more cases that I did not comment.
Thanks for implementing the Sail model of the Zfinx (or ZfinX?) extension, and for your pull request! Some suggestions to improve your Zfinx model:
There are minor syntactic issues like a few cases of broken indentation and trailing whitespace (please remove!) that could be made when incorporating these suggestions. |
Hello Prashanth, Thank you very much for your comments, they were quite helpful. I am currently working on all the issues listed, and I faced an Issue I would like your input on. I am trying to implement a global immutable variable of type bit, that is assigned to the system argument that we used to enable ZFinx, and then use that for mapping statements through out the code. Quickly reading through the generated C emulator, it appears that global variables are assigned before emulator arguments are parsed, if this is the case, how is it possible to assign an immutable global variable to a value passed as an argument to the emulator ? Kind regards, |
One way is to to make it a register, and initialize it in |
This is what I was thinking of doing, but was wondering what is the reason behind initialising the model before parsing the input arguments ? Its not strictly necessary, however since I need that value in many mapping statements, and I would want to avoid calling the function and converting its returned value on every floating point operation, I was thinking it make sense just to have a global immutable variable always assigned the correct value in the correct representations, especially since this value cannot be changed midway through the emulation. (This would reduce the repetition in the code significantly and would increase its performance since we are not calling a C function on every instance we need that value) |
I see what you mean. To answer your earlier question about initialization, the simulator does a consistency check to ensure that it loads an elf file that matches the RV32/RV64 architecture it was generated for. To do this, it needs to initialize the xlen_val value; so the simulator has a I'd use the less performant and repetitious way for now. The way to configure the model will probably change anyway to get these values from a yaml file. |
I fixed all of the issues that were pointed out earlier, but I am stuck on trying to reduce the repetitions in the code, and I am wondering if you can help me with this ? I am trying to use forall to make a single function that would return the correct register depending on if the zfinx is enabled, the following function works correctly, however I am not sure how one would do such implementation using bits(1) or Boolean input as that cannot be size dependent as far as I am concerned, any input would be appreciated ?
The following was also my other attempt at implementing a function that would return the correct register, however similar to the previous one, it needs int' !
ReYAML configuration: That would be really really nice as it would eliminate a number of issues I faced when working with the model ReSetting Variable from C: It appears that the model assumes that the generated C variables names are consistent between builds, is there anything that guarantees such? |
19c9ce8
to
b28bfc2
Compare
The following issues were addressed in the previous two commits
|
Hello Jessica, Thank you very much for your comments. Sorry for late reply, I was trying to see what will happen with this issue "riscvarchive/riscv-zfinx#8 " before replying. Regarding formatting issues (trailing white spaces, empty lines, etc), I am sorry for these, I will go through the PR and make sure I fix them all. Regarding other issues, please check my inline replies. Kind regards, |
02b7d9c
to
2d0c506
Compare
Hello everyone, I am back working on this, and I have managed to make all the required changes in just couple of overloaded functions in a single place. I will try to update the PR soon. Regards, Ibrahim. |
Adds new mapping to swap register names, and use it in all assembly clauses
…ters for floating points Changes register accessed for floating point instructions and modify nan boxing functions for zfinx
2d0c506
to
24d0dc3
Compare
Hi everyone, |
Remove couple of misplaced whitespace, unnecessary parens
Hello everyone, @jrtc27 @pmundkur @scottj97 Short overview: This PR introduce an enable flag for zfinx extension, makes floating point instructions use general purpose register file , and hardwire misa.{F,D} and mstatus.FS to 0 (when zfinx is enabled). Kind regards, |
Please properly format your code; you have missing spaces, too many spaces, inconsistent indentation and inconsistent use of line breaks that make it difficult to read |
Do we have a guideline what the code-format should be? |
No, but it's easy to compare code you write against code that exists in the same file and note that it's not formatted the same way wrt spaces after commas, indentation, etc |
(nor even consistent between functions added in this PR next to each other in the same file) |
I found couple of inconsistent indentation in insts_dext file that I already fixed. I will have a good look and try to find any other inconstancies and fix them. |
"To achieve great things, two things are needed; a plan, and not quite enough time." Attributed to many, including Leonard Bernstein. When do you expect that Ibrahim can exhale? @jrtc27 |
@jrtc27 we can't afford to spend more time on this. Due to our internal policies it is very time consuming making changes and submitting patches, which need to also go through an internal approval flow. Unless there are actual bugs in the code then we need to merge it now. If the suggestions are stylistic then they can be fixed after the merge. We have been trying to merge this for more than 1 year now, your feedback has been invaluable and has been the only way to make the code reusable, scalable and to reduce repetition (as the SAIL documentation is very limited you are our authority on how to write it) and I thank you for this. But now we need to move on and get it merged. @abukharmeh has a lot of other work to complete this year. |
No. Internal policy issues are not an excuse to force others to approve sub-standard patches. That's your problem. |
And if you can't drive the patch to completion, then hand it off to someone else in the community to finish. I'm not merging bad code. |
If you think the code is bad after all this effort then I have no words to describe your attitude. @martinberger what you do next is up to you. We will not submit another patch if this is what we have to put up with. Also I may remind you @jrtc27 that you don't merge the code, that's not your job. |
There are clear issues still with its style, the main one being the fact that it turns |
We have over a dozen specs being ratified this week ... we need to get going ... |
Most of which have no Sail PRs |
There is no rush for Zfinx over and above anything else. The style changes will be simple to fix, this can wait until that happens. |
I have reverted the merge, but will just take it upon myself to re-file a fixed PR since nobody else wants to |
(i.e. it will reappear soon, I just want to keep master clean, so don't get too upset with me...) |
Thanks for your help. We need to avoid the impression that the Sail model is a bottleneck holding RISCV back, because otherwise some communities might not bother. There is little Sail knowledge outside Cambridge, and not much documentation on Sail, and the expected way in which to write the RISCV model. The average computer architect has not come across liquid types before ... For this reason, it's unavoidable that the code that we get might be less than perfect. Raising a sustainable Sail/RISCV community will take a while. |
Have you got any recommendations for an order in which to merge the PRs? |
I realise and understand that, which is why I don't mind taking the time to help people. What I take issue with is the "I don't have time to fix my code so it should just be merged" attitude etc; had it instead be "I don't have time to fix my code can someone please take it over the line for me" it would've been a different story (i.e. what I'm now doing to attempt to keep the peace). |
I don't think there's much of an interdependence, so just whenever things become ready. I suspect the Zb* PRs will soon be merge candidates, those were looking close to ready last I checked, though I haven't closely been following the recent changes. I've just been a bit more swamped with work and life things the past week or so compared with normal so not reviewing as promptly as I'd like. |
I don't know who any of you are but thank you @jrtc27 for your efforts at keeping the model clean. I concur that more documentation and examples could help people write Sail code but that's no excuse for merging substandard code. Of the year this PR has been open, 8 months of that was waiting for @abukharmeh to respond to feedback (Feb to Oct), so the long time frame is no excuse for merging prematurely. The original PR was quite nasty and would have made a mess of this repo. We must have people like @jrtc27 to uphold quality standards or this project will not survive long-term. |
val supports_RV32D_or_RV64D : forall 'n, 'n > 0. (implicit('n), vector('n, dec, bits(5))) -> bool effect {rreg} | ||
function supports_RV32D_or_RV64D (reg_vec_len, registers) = { | ||
if ~ (sys_enable_zfinx()) then is_RV32D_or_RV64D() | ||
else if sys_enable_zfinx() & is_RV64D() then true |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need to check sys_enable_zfinx()
again here; we already know it's true
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, hadn't even seen that code yet. The register checking should also be a different function, it's not related to whether RV32D or RV64D are supported.
@@ -673,22 +659,22 @@ mapping clause encdec = | |||
/* Execution semantics ================================ */ | |||
|
|||
function clause execute (F_UN_RM_TYPE_S(rs1, rm, rd, FSQRT_S)) = { | |||
let rs1_val_S = nan_unbox (F(rs1)); | |||
let rs1_val_S = X_or_F_S(sys_enable_zfinx(), rs1); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can't X_or_F_S()
call sys_enable_zfinx()
itself? Unfortunate that we have to keep repeating this all over the place.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah that's one of the things I'll be changing
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(I suspect that's why the register assignment syntax was abandoned, as I could believe Sail not supporting that when you have more than one argument since that doesn't really make sense normally)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi, thank you for your valuable help. Its indeed why the register assignment was abandoned, I was passing Zfinx status as argument to make it obvious what's happening if this was to be placed as part of a manual of some sort.
@@ -144,6 +144,8 @@ val sys_enable_writable_misa = {c: "sys_enable_writable_misa", ocaml: "Platform. | |||
val sys_enable_rvc = {c: "sys_enable_rvc", ocaml: "Platform.enable_rvc", _: "sys_enable_rvc"} : unit -> bool | |||
/* whether misa.{f,d} were enabled at boot */ | |||
val sys_enable_fdext = {c: "sys_enable_fdext", ocaml: "Platform.enable_fdext", _: "sys_enable_fdext"} : unit -> bool | |||
/* whether zfinx was enabled at boot */ | |||
val sys_enable_zfinx = {c: "sys_enable_zfinx",ocaml: "Platform.enable_zfinx", _: "sys_enable_zfinx"} : unit -> bool |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Space missing after comma
@@ -363,6 +456,6 @@ function accrue_fflags(flags) = { | |||
then { | |||
fcsr->FFLAGS() = f; | |||
update_softfloat_fflags(f); | |||
dirty_fd_context(); | |||
if ~ (sys_enable_zfinx()) then dirty_fd_context(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are three places here that consider sys_enable_zfinx()
before calling dirty_fd_context()
; could that qualification be inside dirty_fd_context()
instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think both are ok, I could go either way on it, though I think I prefer this, since there is no FD context on Zfinx and there should probably be an assert in dirty_fd_context that it's not Zfinx (haven't checked if this patch adds it or not).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rename the function to dirty_fd_context_if_exists()
then? It's not great to keep repeating the conditional like this. Whether those bits exist or not should be defined in exactly one place.
One bug I've already found going through the diff and cleaning it up is that this NaN boxes on Zfinx, i.e. always puts 32 ones in the upper half of X registers when writing a single-precision float on RV64, whereas for Zfinx it's different to F and is supposed to sign-extend. It is at least doing the right thing for the other half of that, namely ignoring the upper 32 bits rather than ensuring they are all ones like for RV32D. |
I wonder if there are any lint-style warnings we could add to Sail itself that might help catch common style issues and pitfalls? I'd be interested in suggestions both from those writing PRs and reviewing them - I'm not involved in either so it can hard for me to have a good perspective on this. If some amount of effort from me could possible save time getting PRs into sail-riscv it might be worthwhile? |
@Alasdair There are two distinct issues that it might be worthwhile to think about separately.
The former would be solved by a code formatter. The latter is more substantial, but probably not so easy to write linters for. |
I had several undergraduate interns from Cambridge and Imperial this summer, who did quite a bit of Sail work. They have gone back to university, but they might be interested in doing paid Sail work. They'd be ideal for this, but they would probably want to be paid (or at least get some recognition) in some form of shape. If there was interest in this, I'll contact them! @Alasdair @jrtc27 @tariqkurd-repo @PeterSewell @allenjbaum @cetola @jjscheel |
@jrtc27 Re Nanboxing, the original spec was to always nanbox but not check for it in zfinx, it appears that it got changed to sign extend, and I didn't notice it. If I fix that along and remove the redundant check in supports_RV32_or_RV64D function. Would you be happy to merge this PR ? I am not too keen on changing X_or_F functions to remove the status flag from the arguments as that would make it less obvious what is happening ! |
Hi! |
Oh I had already started trying to clean things up a bit more on Wednesday between meetings, finishing that off is something I had planned for the weekend, so assuming you/Tariq/Martin/Scott don't spot anything else that should be changed I imagine we should be able to get it merged next week. Re removing the flag from X_or_F, reg_or_freg already implicitly checks whether Zfinx is enabled, so I think it's better to be consistent, as well as avoid all the repetition. |
The term "X_or_F" makes it abundantly clear what's happening. If someone cares to know how the choice is made between X or F they can look in that function. Especially if passing |
@Alasdair +1 for some kind of code formatter, it would help everyone trying to submit PRs to the model, and would reduce the amount of reviewing if the style is consistent across all PRs. Suggestion for lint warning, it appears that the convention here to enforce spaces around commas, though I am not sure that's it make sense for the compiler to warn about such things. Perhaps we can have couple of such rules enabled by strict lint argument or something similar. |
This request introduces ZFinX extension (https://github.com/riscv/riscv-zfinx/blob/master/Zfinx_spec.adoc) to the model
Huawei Technologies Research & Development (Uk) Limited, November 2020