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

insn_div.v and insn_rem.v do not actually perform signed division in all cases #30

Open
kimmeljo opened this issue Dec 2, 2024 · 0 comments

Comments

@kimmeljo
Copy link

kimmeljo commented Dec 2, 2024

Specifically referring to this line (in insn_div.v but same idea applies to insn_rem.v):

wire [`RISCV_FORMAL_XLEN-1:0] result = rvfi_rs2_rdata == `RISCV_FORMAL_XLEN'b0 ? {`RISCV_FORMAL_XLEN{1'b1}} :
                                         rvfi_rs1_rdata == {1'b1, {`RISCV_FORMAL_XLEN-1{1'b0}}} && rvfi_rs2_rdata == {`RISCV_FORMAL_XLEN{1'b1}} ? {1'b1, {`RISCV_FORMAL_XLEN-1{1'b0}}} :
                                         **$signed(rvfi_rs1_rdata) / $signed(rvfi_rs2_rdata)**;

If rvfi_rs1_rdata is a negative number and rvfi_rs2_rdata is a positive number with a larger absolute value, an assertion on rd_wdata fails if the HW correctly returns 0.

Fix (confirmed by shimming locally):

  wire [`RISCV_FORMAL_XLEN-1:0] result = rvfi_rs2_rdata == `RISCV_FORMAL_XLEN'b0 ? {`RISCV_FORMAL_XLEN{1'b1}} :
                                         rvfi_rs1_rdata == {1'b1, {`RISCV_FORMAL_XLEN-1{1'b0}}} && rvfi_rs2_rdata == {`RISCV_FORMAL_XLEN{1'b1}} ? {1'b1, {`RISCV_FORMAL_XLEN-1{1'b0}}} :
                                         **{$signed(rvfi_rs1_rdata) / $signed(rvfi_rs2_rdata)}**;

(surrounding the division expression in {...})

Note that local testing was only performed for RV32*

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

No branches or pull requests

1 participant