2 * yosys -- Yosys Open SYnthesis Suite
4 * Copyright (C) 2012 Clifford Wolf <clifford@clifford.at>
5 * Copyright (C) 2019 David Shah <david@symbioticeda.com>
7 * Permission to use, copy, modify, and/or distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21 #include "kernel/yosys.h"
22 #include "kernel/sigtools.h"
25 PRIVATE_NAMESPACE_BEGIN
27 struct Ecp5GsrPass
: public Pass
{
28 Ecp5GsrPass() : Pass("ecp5_gsr", "ECP5: handle GSR") { }
29 void help() YS_OVERRIDE
31 // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
33 log(" ecp5_gsr [options] [selection]\n");
35 log("Trim active low async resets connected to GSR and resolve GSR parameter,\n");
36 log("if a GSR or SGSR primitive is used in the design.\n");
38 log("If any cell has the GSR parameter set to \"AUTO\", this will be resolved\n");
39 log("to \"ENABLED\" if a GSR primitive is present and the (* nogsr *) attribute\n");
40 log("is not set, otherwise it will be resolved to \"DISABLED\".\n");
43 void execute(std::vector
<std::string
> args
, RTLIL::Design
*design
) YS_OVERRIDE
45 log_header(design
, "Executing ECP5_GSR pass (implement FF init values).\n");
48 for (argidx
= 1; argidx
< args
.size(); argidx
++)
50 // if (args[argidx] == "-singleton") {
51 // singleton_mode = true;
56 extra_args(args
, argidx
, design
);
58 for (auto module
: design
->selected_modules())
60 log("Handling GSR in %s.\n", log_id(module
));
62 SigMap
sigmap(module
);
65 bool found_gsr
= false;
67 for (auto cell
: module
->selected_cells())
69 if (cell
->type
!= ID(GSR
) && cell
->type
!= ID(SGSR
))
72 log_error("Found more than one GSR or SGSR cell in module %s.\n", log_id(module
));
74 SigSpec sig_gsr
= cell
->getPort(ID(GSR
));
75 if (GetSize(sig_gsr
) < 1)
76 log_error("GSR cell %s has disconnected GSR input.\n", log_id(cell
));
77 gsr
= sigmap(sig_gsr
[0]);
80 // Resolve GSR parameter
82 for (auto cell
: module
->selected_cells())
84 if (!cell
->hasParam(ID(GSR
)) || cell
->getParam(ID(GSR
)).decode_string() != "AUTO")
87 bool gsren
= found_gsr
;
88 if (cell
->get_bool_attribute("\\nogsr"))
90 cell
->setParam(ID(GSR
), gsren
? Const("ENABLED") : Const("DISABLED"));
97 // For finding active low FF inputs
98 pool
<SigBit
> inverted_gsr
;
100 log_debug("GSR net in module %s is %s.\n", log_id(module
), log_signal(gsr
));
101 for (auto cell
: module
->selected_cells())
103 if (cell
->type
!= ID($_NOT_
))
105 SigSpec sig_a
= cell
->getPort(ID(A
)), sig_y
= cell
->getPort(ID(Y
));
106 if (GetSize(sig_a
) < 1 || GetSize(sig_y
) < 1)
108 SigBit a
= sigmap(sig_a
[0]);
110 inverted_gsr
.insert(sigmap(sig_y
[0]));
113 for (auto cell
: module
->selected_cells())
115 if (cell
->type
!= ID(TRELLIS_FF
))
117 if (!cell
->hasParam(ID(GSR
)) || cell
->getParam(ID(GSR
)).decode_string() != "ENABLED")
119 if (!cell
->hasParam(ID(SRMODE
)) || cell
->getParam(ID(SRMODE
)).decode_string() != "ASYNC")
121 SigSpec sig_lsr
= cell
->getPort(ID(LSR
));
122 if (GetSize(sig_lsr
) < 1)
124 SigBit lsr
= sigmap(sig_lsr
[0]);
125 if (!inverted_gsr
.count(lsr
))
127 cell
->setParam(ID(SRMODE
), Const("LSR_OVER_CE"));
128 cell
->unsetPort(ID(LSR
));
135 PRIVATE_NAMESPACE_END