Add support for ffM
authorEddie Hung <eddie@fpgeh.com>
Fri, 30 Aug 2019 22:00:56 +0000 (15:00 -0700)
committerEddie Hung <eddie@fpgeh.com>
Fri, 30 Aug 2019 22:00:56 +0000 (15:00 -0700)
passes/pmgen/xilinx_dsp.cc
passes/pmgen/xilinx_dsp.pmg

index e7b72e31209893e93d0e82d8d2f2ecc500de8f2c..105ad1fa16714b90c4193c8dbeacb2dab5800282 100644 (file)
@@ -39,6 +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("addAB:   %s\n", log_id(st.addAB, "--"));
+       log("ffM:     %s\n", log_id(st.ffM, "--"));
        log("ffP:     %s\n", log_id(st.ffP, "--"));
        //log("muxP:  %s\n", log_id(st.muxP, "--"));
        log("sigPused: %s\n", log_signal(st.sigPused));
@@ -95,6 +96,17 @@ void pack_xilinx_dsp(dict<SigBit, Cell*> &bit_to_driver, xilinx_dsp_pm &pm)
                        //      cell->setPort("\\CEB2", st.ffB->getPort("\\EN"));
                        else log_abort();
                }
+               if (st.ffM) {
+                       SigSpec D = st.ffM->getPort("\\D");
+                       SigSpec Q = st.ffM->getPort("\\Q");
+                       P.replace(pm.sigmap(D), Q);
+                       cell->setParam("\\MREG", State::S1);
+                       if (st.ffP->type == "$dff")
+                               cell->setPort("\\CEM", State::S1);
+                       //else if (st.ffP->type == "$dffe")
+                       //      cell->setPort("\\CEP", st.ffP->getPort("\\EN"));
+                       else log_abort();
+               }
                if (st.ffP) {
                        SigSpec D;
                        //if (st.muxP)
index 47e6a0050526578486a2ec01a7cd16858b23a618..08b432b8efb19e687f8c1d4e963541904c2d8e8e 100644 (file)
@@ -2,7 +2,7 @@ pattern xilinx_dsp
 
 state <SigBit> clock
 state <std::set<SigBit>> sigAset sigBset
-state <SigSpec> sigC sigP sigPused
+state <SigSpec> sigC sigM sigMused sigP sigPused
 state <Cell*> addAB
 
 match dsp
@@ -18,6 +18,12 @@ code sigAset sigBset
        sigBset = B.to_sigbit_set();
 endcode
 
+code sigM
+       sigM = port(dsp, \P);
+       //if (GetSize(sigH) <= 10)
+       //      reject;
+endcode
+
 match ffA
        if param(dsp, \AREG).as_int() == 0
        if !sigAset.empty()
@@ -63,8 +69,35 @@ code clock
        }
 endcode
 
-code sigP
-       sigP = port(dsp, \P);
+match ffM
+       if param(dsp, \MREG).as_int() == 0
+       select ffM->type.in($dff)
+       // DSP48E1 does not support clock inversion
+       select param(ffM, \CLK_POLARITY).as_bool()
+       select nusers(port(ffM, \D)) == 2
+       //index <SigSpec> port(ffM, \D) === sigM.extract(0, GetSize(port(ffM, \D))) // TODO: Why doesn't this work!?!
+       filter port(ffM, \D) == sigM.extract(0, GetSize(port(ffM, \D)))
+    filter nusers(sigM.extract_end(param(ffM, \WIDTH).as_int())) == 1
+       optional
+endmatch
+
+code clock sigM sigP
+       if (ffM) {
+        log_warning("M FOUND!\n");
+               sigM = port(ffM, \Q);
+               for (auto b : sigM)
+                       if (b.wire->get_bool_attribute(\keep))
+                               reject;
+
+               SigBit c = port(ffB, \CLK).as_bit();
+
+               if (clock != SigBit() && c != clock)
+                       reject;
+
+               clock = c;
+       }
+
+       sigP = sigM;
 endcode
 
 match addA