Add support for overflow using pattern detector
authorEddie Hung <eddie@fpgeh.com>
Wed, 18 Sep 2019 16:39:59 +0000 (09:39 -0700)
committerEddie Hung <eddie@fpgeh.com>
Wed, 18 Sep 2019 16:39:59 +0000 (09:39 -0700)
passes/pmgen/xilinx_dsp.cc
passes/pmgen/xilinx_dsp.pmg

index e0c7823ededbd797bf060138c1f21684271e8328..786582cfa255de49faffefe76cb0945d34e4e6ec 100644 (file)
@@ -271,6 +271,7 @@ void pack_xilinx_dsp(dict<SigBit, Cell*> &bit_to_driver, xilinx_dsp_pm &pm)
        log("postAdd:    %s\n", log_id(st.postAdd, "--"));
        log("postAddMux: %s\n", log_id(st.postAddMux, "--"));
        log("ffP:        %s %s %s\n", log_id(st.ffP, "--"), log_id(st.ffPcemux, "--"), log_id(st.ffPrstmux, "--"));
+       log("overflow:   %s\n", log_id(st.overflow, "--"));
 #endif
 
        log("Analysing %s.%s for Xilinx DSP packing.\n", log_id(pm.module), log_id(st.dsp));
@@ -329,6 +330,24 @@ void pack_xilinx_dsp(dict<SigBit, Cell*> &bit_to_driver, xilinx_dsp_pm &pm)
 
                pm.autoremove(st.postAdd);
        }
+       if (st.overflow) {
+               log("  overflow %s (%s)\n", log_id(st.overflow), log_id(st.overflow->type));
+               cell->setParam("\\USE_PATTERN_DETECT", Const("PATDET"));
+               cell->setParam("\\SEL_PATTERN", Const("PATTERN"));
+               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
+
+                       cell->setParam("\\MASK", Const(B-1, 48));
+                       cell->setParam("\\PATTERN", Const(0, 48));
+                       cell->setPort("\\OVERFLOW", st.overflow->getPort("\\Y"));
+               }
+               else log_abort();
+
+               pm.autoremove(st.overflow);
+       }
 
        if (st.clock != SigBit())
        {
index 4074896582167253ea2c38addb41ae6b44234c6c..b93162a0e0ece618b69f9ed2de1bc49cbdbddad2 100644 (file)
@@ -264,7 +264,6 @@ match postAdd
 
        select postAdd->type.in($add)
        select GetSize(port(postAdd, \Y)) <= 48
-       select nusers(port(postAdd, \Y)) == 2
        choice <IdString> AB {\A, \B}
        select nusers(port(postAdd, AB)) <= 3
        filter ffMcemux || nusers(port(postAdd, AB)) == 2
@@ -356,6 +355,18 @@ code argQ ffC ffCcemux ffCrstmux ffCcepol ffCrstpol sigC clock
        }
 endcode
 
+match overflow
+       if ffP
+       if dsp->parameters.at(\USE_PATTERN_DETECT, Const("NO_PATDET")).decode_string() == "NO_PATDET"
+       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
+       index <SigSpec> port(overflow, \A) === sigP
+       optional
+endmatch
+
 code
        accept;
 endcode