| // Copyright 2022 AUC Open Source Hardware Lab | 
 | // | 
 | // Licensed under the Apache License, Version 2.0 (the "License"); | 
 | // you may not use this file except in compliance with the License. | 
 | // You may obtain a copy of the License at: | 
 | // | 
 | //     http://www.apache.org/licenses/LICENSE-2.0 | 
 | // | 
 | // Unless required by applicable law or agreed to in writing, software | 
 | // distributed under the License is distributed on an "AS IS" BASIS, | 
 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
 | // See the License for the specific language governing permissions and | 
 | // limitations under the License. | 
 | // | 
 | // SPDX-License-Identifier: Apache-2.0 | 
 |  | 
 | #include "kernel/yosys.h" | 
 |  | 
 | USING_YOSYS_NAMESPACE | 
 | #include <iostream> | 
 | struct CLK_Gating_Pass : public Pass { | 
 |  | 
 |     CLK_Gating_Pass() : Pass("reg_clock_gating", "performs flipflop clock gating") {} | 
 |  | 
 |     void help() override | 
 |     { | 
 |         //   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| | 
 |         log("\n"); | 
 |         log("     reg_clock_gating [-map CG_map_filename] [selection]\n"); | 
 |         log("\n"); | 
 |         log("\n"); | 
 |         log("    -map filename\n"); | 
 |         log("        the mapfile for clock gating cells implementations to be used.\n"); | 
 |         log("        maps from enable-flipflops to clock gated flipflops.\n"); | 
 |         log("        without this parameter a builtin library is used that\n"); | 
 |         log("        transforms the internal RTL cells to the internal gate\n"); | 
 |         log("        library.\n"); | 
 |         log("        check techmap command for mare details.\n"); | 
 |         log("     selection\n"); | 
 |         log("        this option is used to specify the flipflops to be clockgated.\n"); | 
 |         log("        for example:.\n"); | 
 |         log("        put the following attribute in you design: \n"); | 
 |         log("        (* clock gating *).\n"); | 
 |         log("        and use the following command: .\n"); | 
 |         log("        reg_clock_gating -map CG_map_filename.v a:clock_gate.\n"); | 
 |         log("\n"); | 
 |         log("This pass calls the following passes to perform technology mapping \n"); | 
 |         log("of enabled flip_flops to clock-gated flipflops.\n"); | 
 |         log("\n"); | 
 |         log("    procs\n"); | 
 |         log("    opt;;\n"); | 
 |         log("    memory_collect\n"); | 
 |         log("    memory_map\n"); | 
 |         log("    opt;; \n"); | 
 |         log("    techmap -map [-map CG_map_filename] [selection]\n"); | 
 |         log("    opt;;\n"); | 
 |         log("\n"); | 
 |     } | 
 |  | 
 |     virtual void execute(std::vector<std::string> args, RTLIL::Design *design) | 
 |     { | 
 |  | 
 |         if (args.size() < 2) { | 
 |             log_error("Incorrect number of arguments \nClock gating map file is required \n"); | 
 |         } | 
 |  | 
 |         string map_file = ""; | 
 |  | 
 |         size_t argidx; | 
 |         for (argidx = 1; argidx < args.size(); argidx++) { | 
 |             if (args[argidx] == "-map" && argidx + 1 < args.size()) { | 
 |                 map_file = args[++argidx]; | 
 |                 continue; | 
 |             } | 
 |             break; | 
 |         } | 
 |         int x = 0; | 
 |         std::stringstream selection_string_stream; | 
 |         for (unsigned long i = argidx; i < args.size(); i++) { | 
 |             if (x != 0) | 
 |                 selection_string_stream << " "; | 
 |             selection_string_stream << args[i]; | 
 |             x++; | 
 |         } | 
 |         std::string selection = selection_string_stream.str(); | 
 |  | 
 |         std::cout << selection << "\n"; | 
 |  | 
 |         log_header(design, "Executing Clock gating pass.\n"); | 
 |         log_push(); | 
 |  | 
 |         Pass::call(design, "proc"); | 
 |         Pass::call(design, "opt;;"); | 
 |         Pass::call(design, "memory_collect " + selection); | 
 |         Pass::call(design, "memory_map " + selection); | 
 |         Pass::call(design, "opt;;"); | 
 |         Pass::call(design, "techmap -map " + map_file + " " + selection); | 
 |         Pass::call(design, "opt;;"); | 
 |  | 
 |         design->optimize(); | 
 |         design->sort(); | 
 |         design->check(); | 
 |  | 
 |         log_header(design, "Finished Clock gating pass.\n"); | 
 |         log_pop(); | 
 |     } | 
 | } CLK_Gating_Pass; |