Add support for CEB, remove check on nusers
authorEddie Hung <eddie@fpgeh.com>
Thu, 5 Sep 2019 17:46:33 +0000 (10:46 -0700)
committerEddie Hung <eddie@fpgeh.com>
Thu, 5 Sep 2019 17:46:33 +0000 (10:46 -0700)
passes/pmgen/xilinx_dsp.cc
passes/pmgen/xilinx_dsp.pmg

index 2f36a5bdecbfd76349df57e49f8d2a1f4c2ba281..5ae34a1f70837d03659cb51be97b6becc566ce06 100644 (file)
@@ -34,6 +34,7 @@ void pack_xilinx_dsp(dict<SigBit, Cell*> &bit_to_driver, xilinx_dsp_pm &pm)
        log("ffA:        %s\n", log_id(st.ffA, "--"));
        log("ffAmux:     %s\n", log_id(st.ffAmux, "--"));
        log("ffB:        %s\n", log_id(st.ffB, "--"));
+       log("ffBmux:     %s\n", log_id(st.ffBmux, "--"));
        log("dsp:        %s\n", log_id(st.dsp, "--"));
        log("ffM:        %s\n", log_id(st.ffM, "--"));
        log("ffMmux:     %s\n", log_id(st.ffMmux, "--"));
@@ -81,8 +82,6 @@ void pack_xilinx_dsp(dict<SigBit, Cell*> &bit_to_driver, xilinx_dsp_pm &pm)
                        SigSpec D = st.ffA->getPort("\\D");
                        SigSpec Q = pm.sigmap(st.ffA->getPort("\\Q"));
                        A.replace(Q, D);
-
-                       cell->setParam("\\AREG", 1);
                        if (st.ffAmux) {
                                SigSpec Y = st.ffAmux->getPort("\\Y");
                                SigSpec AB = st.ffAmux->getPort(st.ffAmuxAB == "\\A" ? "\\B" : "\\A");
@@ -92,19 +91,25 @@ void pack_xilinx_dsp(dict<SigBit, Cell*> &bit_to_driver, xilinx_dsp_pm &pm)
                        else
                                cell->setPort("\\CEA2", State::S1);
                        cell->setPort("\\A", A);
+
+                       cell->setParam("\\AREG", 1);
                }
                if (st.ffB) {
                        SigSpec B = cell->getPort("\\B");
                        SigSpec D = st.ffB->getPort("\\D");
                        SigSpec Q = st.ffB->getPort("\\Q");
                        B.replace(Q, D);
+                       if (st.ffBmux) {
+                               SigSpec Y = st.ffBmux->getPort("\\Y");
+                               SigSpec AB = st.ffBmux->getPort(st.ffBmuxAB == "\\A" ? "\\B" : "\\A");
+                               B.replace(Y, AB);
+                               cell->setPort("\\CEB2", st.ffBmux->getPort("\\S"));
+                       }
+                       else
+                               cell->setPort("\\CEB2", State::S1);
                        cell->setPort("\\B", B);
+
                        cell->setParam("\\BREG", 1);
-                       if (st.ffB->type == "$dff")
-                               cell->setPort("\\CEB2", State::S1);
-                       //else if (st.ffB->type == "$dffe")
-                       //      cell->setPort("\\CEB2", st.ffB->getPort("\\EN"));
-                       else log_abort();
                }
                if (st.ffM) {
                        SigSpec D = st.ffM->getPort("\\D");
index ed5bd3aaecd5a1b0e8a29f2a6085fe126709b78e..2681cdbca53e3b340849dda5159f6ae832c69d0a 100644 (file)
@@ -1,14 +1,14 @@
 pattern xilinx_dsp
 
 state <SigBit> clock
-state <SigSpec> sigA sigffAmux sigB sigC sigM sigP
-state <IdString> ffAmuxAB ffMmuxAB postAddAB postAddMuxAB
+state <SigSpec> sigA sigffAmux sigB sigffBmux sigC sigM sigP
+state <IdString> ffAmuxAB ffBmuxAB ffMmuxAB postAddAB postAddMuxAB
 
 match dsp
        select dsp->type.in(\DSP48E1)
 endmatch
 
-code sigA sigffAmux sigB sigM
+code sigA sigffAmux sigB sigffBmux sigM
        sigA = port(dsp, \A);
        int i;
        for (i = GetSize(sigA)-1; i > 0; i--)
@@ -46,7 +46,6 @@ match ffA
        select param(ffA, \CLK_POLARITY).as_bool()
        filter GetSize(port(ffA, \Q)) >= GetSize(sigA)
        slice offset GetSize(port(ffA, \Q))
-       filter offset+GetSize(sigA) <= GetSize(port(ffA, \Q)) && nusers(port(ffA, \Q).extract(offset, GetSize(sigA))) <= 3
        filter offset+GetSize(sigA) <= GetSize(port(ffA, \Q)) && port(ffA, \Q).extract(offset, GetSize(sigA)) == sigA
        optional
 endmatch
@@ -59,19 +58,19 @@ code sigA sigffAmux clock
 
                clock = port(ffA, \CLK).as_bit();
 
-               if (nusers(sigA) == 3)
-                       sigffAmux = sigA;
+               sigffAmux = sigA;
                sigA.replace(port(ffA, \Q), port(ffA, \D));
        }
 endcode
 
 match ffAmux
-       if sigffAmux != SigSpec()
+       if ffA
        select ffAmux->type.in($mux)
        choice <IdString> AB {\A, \B}
        index <SigSpec> port(ffAmux, \Y) === sigA
        index <SigSpec> port(ffAmux, AB) === sigffAmux
        set ffAmuxAB AB
+       semioptional
 endmatch
 
 match ffB
@@ -85,7 +84,7 @@ match ffB
        optional
 endmatch
 
-code clock
+code sigB sigffBmux clock
        if (ffB) {
                for (auto b : port(ffB, \Q))
                        if (b.wire->get_bool_attribute(\keep))
@@ -97,9 +96,22 @@ code clock
                        reject;
 
                clock = c;
+
+               sigffBmux = sigB;
+               sigB.replace(port(ffB, \Q), port(ffB, \D));
        }
 endcode
 
+match ffBmux
+       if ffB
+       select ffBmux->type.in($mux)
+       choice <IdString> AB {\A, \B}
+       index <SigSpec> port(ffBmux, \Y) === sigB
+       index <SigSpec> port(ffBmux, AB) === sigffBmux
+       set ffBmuxAB AB
+       semioptional
+endmatch
+
 match ffMmux
        select ffMmux->type.in($mux)
        select nusers(port(ffMmux, \Y)) == 2