Fix vsubs.u Fix the overflow cap of unsigned saturated subtraction. Bug: 296483050 Change-Id: If675412b6b873b1dc6554c5e7a7941d9329a6e74
diff --git a/hdl/chisel/src/kelvin/vector/VAluInt.scala b/hdl/chisel/src/kelvin/vector/VAluInt.scala index 619f5d1..3f81781 100644 --- a/hdl/chisel/src/kelvin/vector/VAluInt.scala +++ b/hdl/chisel/src/kelvin/vector/VAluInt.scala
@@ -971,7 +971,7 @@ val satsubsel = Cat( signed && satsubmsb === 2.U, // vsub.s -ve signed && satsubmsb === 1.U, // vsub.s +ve - !signed && satsubmsb(1)) // vsub.su +ve + !signed && satsubmsb(1)) // vsub.su 0 assert(PopCount(satsubsel) <= 1.U) val rsubtr = rsub_b(m,l) - rsub_a(m,l) @@ -1330,7 +1330,7 @@ val sub = MuxOR(satsubsel(2) && io.op.sub.subs, Cat(1.U(1.W), 0.U((size - 1).W))) | MuxOR(satsubsel(1) && io.op.sub.subs, ~0.U((size - 1).W)) | - MuxOR(satsubsel(0) && io.op.sub.subs, ~0.U(size.W)) | + MuxOR(satsubsel(0) && io.op.sub.subs, 0.U(size.W)) | MuxOR(satsubsel === 0.U && io.op.sub.subs || io.op.sub.sub, subtr(size - 1, 0)) | MuxOR(io.op.sub.hsub, subtr(size, 1))
diff --git a/tests/verilator_sim/kelvin/alu_ref.h b/tests/verilator_sim/kelvin/alu_ref.h index 82d950f..6ab9372 100644 --- a/tests/verilator_sim/kelvin/alu_ref.h +++ b/tests/verilator_sim/kelvin/alu_ref.h
@@ -422,9 +422,7 @@ std::numeric_limits<T>::max()); return m; } - uint64_t m = static_cast<uint64_t>(a) - static_cast<uint64_t>(b); - m = std::min<uint64_t>(m, std::numeric_limits<T>::max()); - return m; + return a < b ? 0 : a - b; } template <typename T>