| // 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; |