-
Notifications
You must be signed in to change notification settings - Fork 53
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
Fix for issue #589. #661
Fix for issue #589. #661
Conversation
Removed instances for mscratchcsw and mscratchcswl CSRs. These CSRs now conditioinally operate on mscratch according to the CLIC spec. Signed-off-by: Oystein Knauserud <[email protected]>
|=> $stable(mscratch_rdata)); | ||
endproperty; | ||
|
||
a_mscratchcswl_mscratch: assert property(p_mscratchcswl_mscratch) |
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.
Should we have a similar assertion for mscratchsw ?
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 will add that to the E40S, on E40X such an assertions would not be reachable since mcause.mpp can only be of value PRIV_LVL_M.
rtl/cv32e40x_cs_registers.sv
Outdated
@@ -646,10 +668,10 @@ module cv32e40x_cs_registers import cv32e40x_pkg::*; | |||
mintthresh_n = csr_wdata_int & CSR_MINTTHRESH_MASK; | |||
mintthresh_we = 1'b0; | |||
|
|||
mscratchcsw_n = csr_wdata_int; // todo: isssue 589 | |||
mscratchcsw_n = mstatus_n; // mscratchcsw operates conditionally on mscratch |
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.
Should this be mscratch_n ? IF not, the comment is confusing.
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.
Good catch, not the first time I type the wrong CSR name. Proves why we need reviews. I'll push a fix
rtl/cv32e40x_cs_registers.sv
Outdated
mscratchcsw_we = 1'b0; | ||
|
||
mscratchcswl_n = csr_wdata_int; // todo: isssue 589 | ||
mscratchcswl_n = mstatus_n; // mscratchcswl operates conditionally on mscratch |
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.
Same as above
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.
Same answer as above
…n by mistake. Signed-off-by: Oystein Knauserud <[email protected]>
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.
From what I understand, and from your explanations, this looks good to me
// Depending on MPP, we return either mscratch_rdata or rs1 to rd. | ||
// Safe to use mcause_rdata here (EX timing), as there is a generic stall of the ID stage | ||
// whenever a CSR instruction follows another CSR instruction. Alternative implementation using | ||
// a local forward of mcause_rdata is identical (SEC). |
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.
Document this case in the controller_bypass module. The currently implemented stall has a todo to make it more specific and this code relies on a stall that therefore might not exist in the future. Note that the 'generic stall' in the bypass module needs to be fixed as we definitely do not want stalls for the common scenarios of back to back CSR reads and back to back CSR writes.
Also explain why this generic stall actually works as that stall is about a CSR instruction in ID and another one in EX/WB, whether the read/write conflict here is about EX vs. WB.
// Safe to use mcause_rdata here (EX timing), as there is a generic stall of the ID stage | ||
// whenever a CSR instruction follows another CSR instruction. Alternative implementation using | ||
// a local forward of mcause_rdata is identical (SEC). | ||
if (mcause_rdata.mpp != PRIV_LVL_M) begin |
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.
The github issue asked to take riscv/riscv-fast-interrupt#241 into account, which was not done. Please follow the pseudo code from https://github.com/riscv/riscv-fast-interrupt/blob/master/clic.adoc#optional-scratch-swap-csr-xscratchcsw-for-multiple-privilege-modes that already is based on that pull request. (This change should be SEC clean)
mscratchcsw_we = 1'b1; | ||
// mscratchcsw operates on mscratch | ||
// Writing only when mcause.mpp != PRIV_LVL_M | ||
if (mcause_rdata.mpp != PRIV_LVL_M) begin |
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.
Use mstatus, also in comment (should be SEC clean)
@@ -1356,6 +1353,15 @@ module cv32e40x_cs_registers import cv32e40x_pkg::*; | |||
// if no interrupt is pending. | |||
assign mnxti_rdata = mnxti_irq_pending_i ? {mtvt_addr_o, mnxti_irq_id_i, 2'b00} : 32'h00000000; | |||
|
|||
// mscratchcsw_rdata breaks the regular convension for CSrs. Read data depend on mcause.mpp |
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.
CSrs -> CSRs
depend -> depends
mcause -> mstatus (update in all related comments and RTL code)
// mscratchcsw_rdata breaks the regular convension for CSrs. Read data depend on mcause.mpp | ||
// mscratch_rdata is returned if mcause.mpp differs from PRIV_LVL_M, otherwise rs1 is returned. | ||
// This signal is only used by RVFI, and has WB timing (rs1 comes from ex_wb_pipe_i.csr_wdata, flopped version of id_ex_pipe.alu_operand_a) | ||
assign mscratchcsw_rdata = (mcause_rdata.mpp != PRIV_LVL_M) ? mscratch_rdata : ex_wb_pipe_i.csr_wdata; |
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 will not return the correct value for machine mode at other cycles than while just handling a related CSR instruction because ex_wb_pipe_i.csr_wdata might be completely unrelated to this CSR. Therefore this expression cannot be used for checking this CSR against the ISS in each cycle.
// mscratchcsw_rdata breaks the regular convension for CSrs. Read data depend on mcause.mpp | ||
// mscratch_rdata is returned if mcause.mpp differs from PRIV_LVL_M, otherwise rs1 is returned. | ||
// This signal is only used by RVFI, and has WB timing (rs1 comes from ex_wb_pipe_i.csr_wdata, flopped version of id_ex_pipe.alu_operand_a) | ||
assign mscratchcsw_rdata = (mcause_rdata.mpp != PRIV_LVL_M) ? mscratch_rdata : ex_wb_pipe_i.csr_wdata; |
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.
Use mstatus
|
||
// mscratchcswl_rdata breaks the regular convension for CSrs. Read data depend on mcause.pil and mintstatus.mil. | ||
// This signal is only used by RVFI, and has WB timing (rs1 comes from ex_wb_pipe_i.csr_wdata, flopped version of id_ex_pipe.alu_operand_a) | ||
assign mscratchcswl_rdata = ((mcause_rdata.mpil == '0) != (mintstatus_rdata.mil == 0)) ? mscratch_rdata : ex_wb_pipe_i.csr_wdata; |
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.
Not accurate because of the csr_wdata usage
input privlvl_t priv_lvl_rdata | ||
input privlvl_t priv_lvl_rdata, | ||
input logic [31:0] mscratch_rdata, | ||
input mcause_t mcause_rdata, |
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.
use mstatus instead of mcause everywhere related to mscratchcsw
@@ -90,6 +96,38 @@ module cv32e40x_cs_registers_sva | |||
|
|||
a_htrap_interrupt_level: assert property(p_htrap_interrupt_level) | |||
else `uvm_error("cs_registers", "Horizontal trap taken caused interrupt level to change"); | |||
|
|||
// Check that mscratch do not update due to mscratchcsw if the conditions are not right | |||
property p_mscratchcsw_mscratch; |
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.
These assertions are self fullfilling as they basically just match the RTL. Could an alternative implementation that is closer to the actual CLIC specification be used here instead? I.e. use the for this one use a mstatus bypass instead of the mcause/mstatus rdata which has the dangerous timing.
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.
Same remark for all assertions; use the 'bypass' (i.e. _q value of the CSR or to be written value of the CSR)
Removed instances for mscratchcsw and mscratchcswl CSRs. These CSRs now conditionally operate on mscratch according to the CLIC spec.
Signed-off-by: Oystein Knauserud [email protected]