From 347cbf59bd45345663defa9c99c7fc6563404da6 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 18 Sep 2019 12:16:03 -0700 Subject: [PATCH] Check overflow condition is power of 2 without using int32 --- passes/pmgen/xilinx_dsp.cc | 16 +++++++++++++--- passes/pmgen/xilinx_dsp.pmg | 4 ++-- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/passes/pmgen/xilinx_dsp.cc b/passes/pmgen/xilinx_dsp.cc index 786582cfa..8500a6072 100644 --- a/passes/pmgen/xilinx_dsp.cc +++ b/passes/pmgen/xilinx_dsp.cc @@ -337,10 +337,20 @@ void pack_xilinx_dsp(dict &bit_to_driver, xilinx_dsp_pm &pm) cell->setParam("\\SEL_MASK", Const("MASK")); if (st.overflow->type == "$ge") { - int B = st.overflow->getPort("\\B").as_int(); - log_assert((B & (B-1)) == 0); // Exact power of 2 + Const B = st.overflow->getPort("\\B").as_const(); + log_assert(std::count(B.bits.begin(), B.bits.end(), State::S1) == 1); + // Since B is an exact power of 2, subtract 1 + // by inverting all bits up until hitting + // that one hi bit + for (auto &b : B.bits) + if (b == State::S0) b = State::S1; + else if (b == State::S1) { + b = State::S0; + break; + } + B.extu(48); - cell->setParam("\\MASK", Const(B-1, 48)); + cell->setParam("\\MASK", B); cell->setParam("\\PATTERN", Const(0, 48)); cell->setPort("\\OVERFLOW", st.overflow->getPort("\\Y")); } diff --git a/passes/pmgen/xilinx_dsp.pmg b/passes/pmgen/xilinx_dsp.pmg index b93162a0e..08cb1f51b 100644 --- a/passes/pmgen/xilinx_dsp.pmg +++ b/passes/pmgen/xilinx_dsp.pmg @@ -361,8 +361,8 @@ match overflow select overflow->type.in($ge) select GetSize(port(overflow, \Y)) <= 48 select port(overflow, \B).is_fully_const() - // Check is exact power of 2 - select (port(overflow, \B).as_int() & (port(overflow, \B).as_int()-1)) == 0 + define B port(overflow, \B).as_const() + select std::count(B.bits.begin(), B.bits.end(), State::S1) == 1 index port(overflow, \A) === sigP optional endmatch -- 2.30.2