2 * yosys -- Yosys Open SYnthesis Suite
4 * Copyright (C) 2018 whitequark <whitequark@whitequark.org>
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/register.h"
23 PRIVATE_NAMESPACE_BEGIN
25 struct EquivOptPass
:public ScriptPass
27 EquivOptPass() : ScriptPass("equiv_opt", "prove equivalence for optimized circuit") { }
29 void help() YS_OVERRIDE
31 // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
33 log(" equiv_opt [options] [command]\n");
35 log("This command uses temporal induction to check circuit equivalence before and\n");
36 log("after an optimization pass.\n");
38 log(" -run <from_label>:<to_label>\n");
39 log(" only run the commands between the labels (see below). an empty\n");
40 log(" from label is synonymous to the start of the command list, and empty to\n");
41 log(" label is synonymous to the end of the command list.\n");
43 log(" -map <filename>\n");
44 log(" expand the modules in this file before proving equivalence. this is\n");
45 log(" useful for handling architecture-specific primitives.\n");
48 log(" produce an error if the circuits are not equivalent.\n");
50 log(" -multiclock\n");
51 log(" run clk2fflogic before equivalence checking.\n");
53 log(" -async2sync\n");
54 log(" run async2sync before equivalence checking.\n");
57 log(" enable modelling of undef states during equiv_induct.\n");
59 log("The following commands are executed by this verification command:\n");
64 std::string command
, techmap_opts
;
65 bool assert, undef
, multiclock
, async2sync
;
67 void clear_flags() YS_OVERRIDE
77 void execute(std::vector
< std::string
> args
, RTLIL::Design
* design
) YS_OVERRIDE
79 string run_from
, run_to
;
83 for (argidx
= 1; argidx
< args
.size(); argidx
++) {
84 if (args
[argidx
] == "-run" && argidx
+ 1 < args
.size()) {
85 size_t pos
= args
[argidx
+ 1].find(':');
86 if (pos
== std::string::npos
)
88 run_from
= args
[++argidx
].substr(0, pos
);
89 run_to
= args
[argidx
].substr(pos
+ 1);
92 if (args
[argidx
] == "-map" && argidx
+ 1 < args
.size()) {
93 techmap_opts
+= " -map " + args
[++argidx
];
96 if (args
[argidx
] == "-assert") {
100 if (args
[argidx
] == "-undef") {
104 if (args
[argidx
] == "-multiclock") {
108 if (args
[argidx
] == "-async2sync") {
115 for (; argidx
< args
.size(); argidx
++) {
116 if (command
.empty()) {
117 if (args
[argidx
].compare(0, 1, "-") == 0)
118 cmd_error(args
, argidx
, "Unknown option.");
122 command
+= args
[argidx
];
126 log_cmd_error("No optimization pass specified!\n");
128 if (!design
->full_selection())
129 log_cmd_error("This command only operates on fully selected designs!\n");
131 if (async2sync
&& multiclock
)
132 log_cmd_error("The '-async2sync' and '-multiclock' options are mutually exclusive!\n");
134 log_header(design
, "Executing EQUIV_OPT pass.\n");
137 run_script(design
, run_from
, run_to
);
142 void script() YS_OVERRIDE
144 if (check_label("run_pass")) {
145 run("hierarchy -auto-top");
146 run("design -save preopt");
151 run("design -stash postopt");
154 if (check_label("prepare")) {
155 run("design -copy-from preopt -as gold A:top");
156 run("design -copy-from postopt -as gate A:top");
159 if ((!techmap_opts
.empty() || help_mode
) && check_label("techmap", "(only with -map)")) {
162 opts
= " -map <filename> ...";
165 run("techmap -wb -D EQUIV -autoproc" + opts
);
168 if (check_label("prove")) {
169 if (multiclock
|| help_mode
)
170 run("clk2fflogic", "(only with -multiclock)");
171 if (async2sync
|| help_mode
)
172 run("async2sync", " (only with -async2sync)");
173 run("equiv_make gold gate equiv");
175 run("equiv_induct [-undef] equiv");
177 run("equiv_induct -undef equiv");
179 run("equiv_induct equiv");
181 run("equiv_status [-assert] equiv");
183 run("equiv_status -assert equiv");
185 run("equiv_status equiv");
188 if (check_label("restore")) {
189 run("design -load preopt");
194 PRIVATE_NAMESPACE_END