Use choices for addAB, now called postAdd
authorEddie Hung <eddie@fpgeh.com>
Tue, 3 Sep 2019 23:10:16 +0000 (16:10 -0700)
committerEddie Hung <eddie@fpgeh.com>
Tue, 3 Sep 2019 23:10:16 +0000 (16:10 -0700)
passes/pmgen/xilinx_dsp.cc
passes/pmgen/xilinx_dsp.pmg

index b3d302071ef367250e34dbf2f6a93b4c96f4d979..7f51d29f625a3cc6d395c32605bb573842a63d94 100644 (file)
@@ -39,7 +39,7 @@ void pack_xilinx_dsp(dict<SigBit, Cell*> &bit_to_driver, xilinx_dsp_pm &pm)
        log("ffB:     %s\n", log_id(st.ffB, "--"));
        log("dsp:     %s\n", log_id(st.dsp, "--"));
        log("ffM:     %s\n", log_id(st.ffM, "--"));
-       log("addAB:   %s\n", log_id(st.addAB, "--"));
+       log("postAdd: %s\n", log_id(st.postAdd, "--"));
        log("muxAB:   %s\n", log_id(st.muxAB, "--"));
        log("ffP:     %s\n", log_id(st.ffP, "--"));
        //log("muxP:  %s\n", log_id(st.muxP, "--"));
@@ -53,10 +53,10 @@ void pack_xilinx_dsp(dict<SigBit, Cell*> &bit_to_driver, xilinx_dsp_pm &pm)
        SigSpec C = st.sigC;
        SigSpec P = st.sigP;
 
-       if (st.addAB) {
-               log_assert(st.addAB->getParam("\\A_SIGNED").as_bool());
-               log_assert(st.addAB->getParam("\\B_SIGNED").as_bool());
-               log("  adder %s (%s)\n", log_id(st.addAB), log_id(st.addAB->type));
+       if (st.postAdd) {
+               log_assert(st.postAdd->getParam("\\A_SIGNED").as_bool());
+               log_assert(st.postAdd->getParam("\\B_SIGNED").as_bool());
+               log("  adder %s (%s)\n", log_id(st.postAdd), log_id(st.postAdd->type));
 
                SigSpec &opmode = cell->connections_.at("\\OPMODE");
                if (st.ffP && st.muxAB) {
@@ -72,7 +72,7 @@ void pack_xilinx_dsp(dict<SigBit, Cell*> &bit_to_driver, xilinx_dsp_pm &pm)
                opmode[6] = State::S0;
                opmode[5] = State::S1;
 
-               pm.autoremove(st.addAB);
+               pm.autoremove(st.postAdd);
        }
 
        if (st.clock != SigBit())
index fdc3fa5e77ddf055016ca9a0075918c20bb69d48..0aafc9e4099a90a7d137829af3eb79653a5ca56c 100644 (file)
@@ -3,7 +3,8 @@ pattern xilinx_dsp
 state <SigBit> clock
 state <std::set<SigBit>> sigAset sigBset
 state <SigSpec> sigC sigM sigMused sigP sigPused
-state <Cell*> addAB muxAB
+state <Cell*> postAdd muxAB
+state <IdString> postAddAB
 
 match dsp
        select dsp->type.in(\DSP48E1)
@@ -100,43 +101,25 @@ code clock sigM sigP
        sigP = sigM;
 endcode
 
-match addA
-       select addA->type.in($add)
-       select param(addA, \A_SIGNED).as_bool() && param(addA, \B_SIGNED).as_bool()
-       select nusers(port(addA, \A)) == 2
-       //index <SigSpec> port(addA, \A) === sigP.extract(0, param(addA, \A_WIDTH).as_int()) // TODO: Why doesn't this work!?!
-       filter GetSize(port(addA, \A)) <= GetSize(sigP)
-       filter port(addA, \A) == sigP.extract(0, GetSize(port(addA, \A)))
-       filter nusers(sigP.extract_end(GetSize(port(addA, \A)))) <= 1
+match postAdd
+       // Ensure that Z mux is not already used
+       if port(dsp, \OPMODE).extract(4,3).is_fully_zero()
+
+       select postAdd->type.in($postAdd)
+       select param(postAdd, \A_SIGNED).as_bool() && param(postAdd, \B_SIGNED).as_bool()
+       choice <IdString> AB {\A, \B}
+       define <IdString> AB_WIDTH (AB == \A ? \A_WIDTH : \B_WIDTH)
+       select nusers(port(postAdd, AB)) == 2
+       filter GetSize(port(postAdd, AB)) <= GetSize(sigP)
+       filter port(postAdd, AB) == sigP.extract(0, GetSize(port(postAdd, AB)))
+       filter nusers(sigP.extract_end(GetSize(port(postAdd, AB)))) <= 1
+       set postAddAB AB
        optional
 endmatch
 
-match addB
-       if !addA
-       select addB->type.in($add, $sub)
-       select param(addB, \A_SIGNED).as_bool() && param(addB, \B_SIGNED).as_bool()
-       index <int> nusers(port(addB, \B)) === 2
-       //index <SigSpec> port(addB, \B) === sigP.extract(0, param(addB, \B_WIDTH).as_int()) // TODO: Why doesn't this work!?!
-       filter GetSize(port(addB, \B)) <= GetSize(sigP)
-       filter port(addB, \B) == sigP.extract(0, GetSize(port(addB, \B)))
-       filter nusers(sigP.extract_end(GetSize(port(addB, \B)))) <= 1
-       optional
-endmatch
-
-code addAB sigC sigP
-       if (addA) {
-               addAB = addA;
-               sigC = port(addAB, \B);
-       }
-       if (addB) {
-               addAB = addB;
-               sigC = port(addAB, \A);
-       }
-       if (addAB) {
-               // Ensure that adder is not used
-               SigSpec opmodeZ = port(dsp, \OPMODE).extract(4,3);
-               if (!opmodeZ.is_fully_zero())
-                       reject;
+code sigC sigP
+       if (postAdd) {
+               sigC = port(postAdd, postAddAB == \A ? \B : \A);
 
                // TODO for DSP48E1, which will have sign extended inputs/outputs
                //int natural_mul_width = GetSize(port(dsp, \A)) + GetSize(port(dsp, \B));
@@ -145,10 +128,10 @@ code addAB sigC sigP
 
                //if ((actual_acc_width > actual_mul_width) && (natural_mul_width > actual_mul_width))
                //      reject;
-               //if ((actual_acc_width != actual_mul_width) && (param(dsp, \A_SIGNED).as_bool() != param(addAB, \A_SIGNED).as_bool()))
+               //if ((actual_acc_width != actual_mul_width) && (param(dsp, \A_SIGNED).as_bool() != param(postAdd, \A_SIGNED).as_bool()))
                //      reject;
 
-               sigP = port(addAB, \Y);
+               sigP = port(postAdd, \Y);
        }
 endcode
 
@@ -190,7 +173,7 @@ code ffP sigP clock
 endcode
 
 match muxA
-       if addAB
+       if postAdd
        select muxA->type.in($mux)
        select nusers(port(muxA, \Y)) == 2
        index <SigSpec> port(muxA, \A) === sigP
@@ -199,7 +182,7 @@ match muxA
 endmatch
 
 match muxB
-       if addAB
+       if postAdd
        select muxB->type.in($mux)
        select nusers(port(muxB, \Y)) == 2
        index <SigSpec> port(muxB, \B) === sigP
@@ -217,7 +200,7 @@ code sigC muxAB
                sigC = port(muxAB, \A);
        }
        if (muxAB) {
-               // Ensure that adder is not used
+               // Ensure that postAdder is not used
                SigSpec opmodeZ = port(dsp, \OPMODE).extract(4,3);
                if (!opmodeZ.is_fully_zero())
                        reject;