Check overflow condition is power of 2 without using int32
authorEddie Hung <eddie@fpgeh.com>
Wed, 18 Sep 2019 19:16:03 +0000 (12:16 -0700)
committerEddie Hung <eddie@fpgeh.com>
Wed, 18 Sep 2019 19:16:03 +0000 (12:16 -0700)
passes/pmgen/xilinx_dsp.cc
passes/pmgen/xilinx_dsp.pmg

index 786582cfa255de49faffefe76cb0945d34e4e6ec..8500a60722f405fe28fec17ba5f640238711715e 100644 (file)
@@ -337,10 +337,20 @@ void pack_xilinx_dsp(dict<SigBit, Cell*> &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"));
                }
index b93162a0e0ece618b69f9ed2de1bc49cbdbddad2..08cb1f51b3ea6c3a71e8fc1f380b7618abd8fe14 100644 (file)
@@ -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 <Const> B port(overflow, \B).as_const()
+       select std::count(B.bits.begin(), B.bits.end(), State::S1) == 1
        index <SigSpec> port(overflow, \A) === sigP
        optional
 endmatch