Detect and reject cases that do not map well to iCE40 DSPs (yet)
authorClifford Wolf <clifford@clifford.at>
Wed, 20 Feb 2019 10:18:19 +0000 (11:18 +0100)
committerClifford Wolf <clifford@clifford.at>
Wed, 20 Feb 2019 10:18:19 +0000 (11:18 +0100)
Signed-off-by: Clifford Wolf <clifford@clifford.at>
passes/pmgen/ice40_dsp.cc
passes/pmgen/ice40_dsp.pmg

index 7463d598f1fd1c8570177f51ca92efbfb2e2c84c..8c50a93938beb12c7687f235db6ee25264c1b9ae 100644 (file)
@@ -59,10 +59,15 @@ void create_ice40_dsp(ice40_dsp_pm &pm)
                return;
        }
 
-       log("  replacing $mul with SB_MAC16 cell.\n");
-
        bool mul_signed = pm.st.mul->getParam("\\A_SIGNED").as_bool();
 
+       if (mul_signed) {
+               log("  inference of signed iCE40 DSP arithmetic is currently not supported.\n");
+               return;
+       }
+
+       log("  replacing $mul with SB_MAC16 cell.\n");
+
        Cell *cell = pm.module->addCell(NEW_ID, "\\SB_MAC16");
        pm.module->swap_names(cell, pm.st.mul);
 
index 58e1ce0e0455c5e867409e326e4fe65543456c28..96c62e313b3991d90d28ba111cb16c1e534814dc 100644 (file)
@@ -100,6 +100,16 @@ code addAB sigS
                addAB = addB;
                sigS = port(addB, \A);
        }
+       if (addAB) {
+               int natural_mul_width = GetSize(sigA) + GetSize(sigB);
+               int actual_mul_width = GetSize(sigY);
+               int actual_acc_width = GetSize(sigS);
+
+               if ((actual_acc_width > actual_mul_width) && (natural_mul_width > actual_mul_width))
+                       reject;
+               if ((actual_acc_width != actual_mul_width) && (param(mul, \A_SIGNED).as_bool() != param(addAB, \A_SIGNED).as_bool()))
+                       reject;
+       }
 endcode
 
 match muxA