From aa462da39513505a66840dca49a5f4499531d952 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 5 Sep 2019 10:07:26 -0700 Subject: [PATCH] Support CEA --- passes/pmgen/xilinx_dsp.cc | 17 +++++++++++------ passes/pmgen/xilinx_dsp.pmg | 26 +++++++++++++++++++++++--- 2 files changed, 34 insertions(+), 9 deletions(-) diff --git a/passes/pmgen/xilinx_dsp.cc b/passes/pmgen/xilinx_dsp.cc index c742ef84d..2f36a5bde 100644 --- a/passes/pmgen/xilinx_dsp.cc +++ b/passes/pmgen/xilinx_dsp.cc @@ -32,6 +32,7 @@ void pack_xilinx_dsp(dict &bit_to_driver, xilinx_dsp_pm &pm) #if 1 log("\n"); 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("dsp: %s\n", log_id(st.dsp, "--")); log("ffM: %s\n", log_id(st.ffM, "--")); @@ -78,15 +79,19 @@ void pack_xilinx_dsp(dict &bit_to_driver, xilinx_dsp_pm &pm) if (st.ffA) { SigSpec A = cell->getPort("\\A"); SigSpec D = st.ffA->getPort("\\D"); - SigSpec Q = st.ffA->getPort("\\Q"); + SigSpec Q = pm.sigmap(st.ffA->getPort("\\Q")); A.replace(Q, D); - cell->setPort("\\A", A); + cell->setParam("\\AREG", 1); - if (st.ffA->type == "$dff") + if (st.ffAmux) { + SigSpec Y = st.ffAmux->getPort("\\Y"); + SigSpec AB = st.ffAmux->getPort(st.ffAmuxAB == "\\A" ? "\\B" : "\\A"); + A.replace(Y, AB); + cell->setPort("\\CEA2", st.ffAmux->getPort("\\S")); + } + else cell->setPort("\\CEA2", State::S1); - //else if (st.ffA->type == "$dffe") - // cell->setPort("\\CEA2", st.ffA->getPort("\\EN")); - else log_abort(); + cell->setPort("\\A", A); } if (st.ffB) { SigSpec B = cell->getPort("\\B"); diff --git a/passes/pmgen/xilinx_dsp.pmg b/passes/pmgen/xilinx_dsp.pmg index d37792b29..339ac646c 100644 --- a/passes/pmgen/xilinx_dsp.pmg +++ b/passes/pmgen/xilinx_dsp.pmg @@ -1,8 +1,8 @@ pattern xilinx_dsp state clock -state sigA sigB sigC sigM sigP sigPused -state ffMmuxAB postAddAB postAddMuxAB +state sigA sigffAmux sigB sigC sigM sigP sigPused +state ffAmuxAB ffMmuxAB postAddAB postAddMuxAB match dsp select dsp->type.in(\DSP48E1) @@ -14,11 +14,17 @@ code sigA sigB for (i = GetSize(sigA)-1; i > 0; i--) if (sigA[i] != sigA[i-1]) break; + // Do not remove non-const sign bit + if (sigA[i].wire) + ++i; sigA.remove(i, GetSize(sigA)-i); sigB = port(dsp, \B); for (i = GetSize(sigB)-1; i > 0; i--) if (sigB[i] != sigB[i-1]) break; + // Do not remove non-const sign bit + if (sigB[i].wire) + ++i; sigB.remove(i, GetSize(sigB)-i); endcode @@ -43,20 +49,34 @@ 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 -code clock +code sigA sigffAmux clock if (ffA) { for (auto b : port(ffA, \Q)) if (b.wire->get_bool_attribute(\keep)) reject; clock = port(ffA, \CLK).as_bit(); + + if (nusers(sigA) == 3) + sigffAmux = sigA; + sigA.replace(port(ffA, \Q), port(ffA, \D)); } endcode +match ffAmux + if sigffAmux != SigSpec() + select ffAmux->type.in($mux) + choice AB {\A, \B} + index port(ffAmux, \Y) === sigA + index port(ffAmux, AB) === sigffAmux + set ffAmuxAB AB +endmatch + match ffB if param(dsp, \BREG).as_int() == 0 select ffB->type.in($dff) -- 2.30.2