From d58a45d6a87921b1491df82fa38fac6f4d004fea Mon Sep 17 00:00:00 2001 From: Alan Green Date: Sat, 5 Feb 2022 10:57:42 +1100 Subject: [PATCH] fix for signed comparison bug --- proj/hps_accel/gateware/gen2/hps_cfu.py | 12 +++++++----- proj/hps_accel/gateware/gen2/test_hps_cfu.py | 2 ++ 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/proj/hps_accel/gateware/gen2/hps_cfu.py b/proj/hps_accel/gateware/gen2/hps_cfu.py index c4d07dbba..b11a35630 100644 --- a/proj/hps_accel/gateware/gen2/hps_cfu.py +++ b/proj/hps_accel/gateware/gen2/hps_cfu.py @@ -205,11 +205,12 @@ def max_(word0, word1): bytes0 = [word0[i:i + 8] for i in range(0, 32, 8)] bytes1 = [word1[i:i + 8] for i in range(0, 32, 8)] for r, b0, b1 in zip(result, bytes0, bytes1): - sb0 = Signal(signed(8)) - m.d.comb += sb0.eq(b0) - sb1 = Signal(signed(8)) - m.d.comb += sb1.eq(b1) - m.d.comb += r.eq(Mux(sb1 > sb0, b1, b0)) + # the bytes represent signed values, but signed comparison + # appears to trigger a bug + # https://github.com/google/CFU-Playground/issues/451 + # To avoid that bug, we flip the sign bits (i.e add 128) + # and do an unsigned comparison instead. + m.d.comb += r.eq(Mux((b1 ^ 0x80) > (b0 ^ 0x80), b1, b0)) return Cat(*result) last2 = Signal(32) @@ -225,6 +226,7 @@ def max_(word0, word1): class HpsCfu(Cfu): """Gen2 accelerator CFU. """ + def __init__(self, specialize_nx=False): """Constructor diff --git a/proj/hps_accel/gateware/gen2/test_hps_cfu.py b/proj/hps_accel/gateware/gen2/test_hps_cfu.py index 3acee4f9a..c5e701bcf 100644 --- a/proj/hps_accel/gateware/gen2/test_hps_cfu.py +++ b/proj/hps_accel/gateware/gen2/test_hps_cfu.py @@ -238,6 +238,8 @@ def test_pool(self): ((Constants.INS_POOL, 0x80808080, 0x80808080), 0x80808080), ((Constants.INS_POOL, 0x08030601, 0x04070205), 0x08070605), ((Constants.INS_POOL, 0x00660000, 0x00007700), 0x08667705), + ((Constants.INS_POOL, 0x12808080, 0x88808080), None), + ((Constants.INS_POOL, 0x1a808080, 0x81808080), 0x1a808080), ] self.run_ops(OPS, False)