aboutsummaryrefslogtreecommitdiffstats
path: root/backends/cxxrtl
diff options
context:
space:
mode:
authorAndy Knowles <andy.knowles@gmail.com>2020-08-12 11:32:57 +0200
committerAndy Knowles <andy.knowles@gmail.com>2020-08-12 11:32:57 +0200
commit1227c3681be8e6365e91e77b06dcbe58ff6c7593 (patch)
tree5c71baa228456d2a286d1788b8261e609801de11 /backends/cxxrtl
parent04f6158bf2ce9a95970f1be435351786f59bed92 (diff)
downloadyosys-1227c3681be8e6365e91e77b06dcbe58ff6c7593.tar.gz
yosys-1227c3681be8e6365e91e77b06dcbe58ff6c7593.tar.bz2
yosys-1227c3681be8e6365e91e77b06dcbe58ff6c7593.zip
cxxrtl.h: Fix incorrect CarryOut in alu when Bits % 32 != 0 && Invert == False
Diffstat (limited to 'backends/cxxrtl')
-rw-r--r--backends/cxxrtl/cxxrtl.h10
1 files changed, 8 insertions, 2 deletions
diff --git a/backends/cxxrtl/cxxrtl.h b/backends/cxxrtl/cxxrtl.h
index f0d7b9fc7..dfdb49929 100644
--- a/backends/cxxrtl/cxxrtl.h
+++ b/backends/cxxrtl/cxxrtl.h
@@ -450,12 +450,18 @@ struct value : public expr_base<value<Bits>> {
std::pair<value<Bits>, bool /*CarryOut*/> alu(const value<Bits> &other) const {
value<Bits> result;
bool carry = CarryIn;
- for (size_t n = 0; n < result.chunks; n++) {
+ // Handle full chunks first
+ for (size_t n = 0; n < result.chunks - 1; n++) {
result.data[n] = data[n] + (Invert ? ~other.data[n] : other.data[n]) + carry;
carry = (result.data[n] < data[n]) ||
(result.data[n] == data[n] && carry);
}
- result.data[result.chunks - 1] &= result.msb_mask;
+ // Handle last chunk (mask before updating carry)
+ constexpr size_t last = result.chunks - 1;
+ result.data[last] = data[last] + (Invert ? ~other.data[last] : other.data[last]) + carry;
+ result.data[last] &= result.msb_mask;
+ carry = (result.data[last] < data[last]) ||
+ (result.data[last] == data[last] && carry);
return {result, carry};
}