2 * yosys -- Yosys Open SYnthesis Suite
4 * Copyright (C) 2012 Clifford Wolf <clifford@clifford.at>
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20 #include "kernel/yosys.h"
21 #include "kernel/sigtools.h"
24 PRIVATE_NAMESPACE_BEGIN
29 #include "passes/pmgen/xilinx_srl_pm.h"
30 #include "passes/pmgen/ice40_dsp_pm.h"
31 #include "passes/pmgen/peepopt_pm.h"
33 void reduce_chain(xilinx_srl_pm
&pm
)
35 auto &st
= pm
.st_reduce
;
36 auto &ud
= pm
.ud_reduce
;
38 log("Found chain of length %d (%s):\n", GetSize(ud
.longest_chain
), log_id(st
.first
->type
));
40 auto last_cell
= ud
.longest_chain
.back();
43 for (auto cell
: ud
.longest_chain
) {
44 log_debug(" %s\n", log_id(cell
));
45 SigBit Q
= cell
->getPort(ID(Q
));
47 auto it
= Q
.wire
->attributes
.find(ID(init
));
48 if (it
!= Q
.wire
->attributes
.end()) {
49 initval
.append(it
->second
[Q
.offset
]);
52 initval
.append(State::Sx
);
53 if (cell
!= last_cell
)
58 SigBit Q
= st
.first
->getPort(ID(Q
));
61 if (c
->type
.in(ID($_DFF_N_
), ID($_DFF_P_
), ID($_DFFE_NN_
), ID($_DFFE_NP_
), ID($_DFFE_PN_
), ID($_DFFE_PP_
), ID(FDRE
), ID(FDRE_1
))) {
62 c
->parameters
.clear();
63 c
->setParam(ID(DEPTH
), GetSize(ud
.longest_chain
));
64 c
->setParam(ID(INIT
), initval
.as_const());
65 if (c
->type
.in(ID($_DFF_P_
), ID($_DFFE_PN_
), ID($_DFFE_PP_
)))
66 c
->setParam(ID(CLKPOL
), 1);
67 else if (c
->type
.in(ID($_DFF_N_
), ID($DFFE_NN_
), ID($_DFFE_NP_
), ID(FDRE_1
)))
68 c
->setParam(ID(CLKPOL
), 0);
71 if (c
->type
.in(ID($_DFFE_NP_
), ID($_DFFE_PP_
)))
72 c
->setParam(ID(ENPOL
), 1);
73 else if (c
->type
.in(ID($_DFFE_NN_
), ID($_DFFE_PN_
)))
74 c
->setParam(ID(ENPOL
), 0);
76 c
->setParam(ID(ENPOL
), 2);
77 if (c
->type
.in(ID($_DFF_N_
), ID($_DFF_P_
)))
78 c
->setPort(ID(E
), State::S1
);
79 c
->setPort(ID(L
), GetSize(ud
.longest_chain
)-1);
80 c
->type
= ID($__XILINX_SHREG_
);
85 log(" -> %s (%s)\n", log_id(c
), log_id(c
->type
));
88 struct XilinxSrlPass
: public Pass
{
89 XilinxSrlPass() : Pass("xilinx_srl", "Xilinx shift register extraction") { }
90 void help() YS_OVERRIDE
92 // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
94 log(" xilinx_srl [options] [selection]\n");
100 void execute(std::vector
<std::string
> args
, RTLIL::Design
*design
) YS_OVERRIDE
102 log_header(design
, "Executing XILINX_SRL pass (Xilinx shift register extraction).\n");
107 for (argidx
= 1; argidx
< args
.size(); argidx
++)
109 if (args
[argidx
] == "-minlen" && argidx
+1 < args
.size()) {
110 minlen
= atoi(args
[++argidx
].c_str());
115 extra_args(args
, argidx
, design
);
117 for (auto module
: design
->selected_modules()) {
118 bool did_something
= false;
120 auto pm
= xilinx_srl_pm(module
, module
->selected_cells());
121 pm
.ud_reduce
.minlen
= minlen
;
122 did_something
= pm
.run_reduce(reduce_chain
);
123 } while (did_something
);
128 PRIVATE_NAMESPACE_END