Merge pull request #829 from abdelrahmanhosny/master
[yosys.git] / passes / techmap / hilomap.cc
1 /*
2 * yosys -- Yosys Open SYnthesis Suite
3 *
4 * Copyright (C) 2012 Clifford Wolf <clifford@clifford.at>
5 *
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.
9 *
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.
17 *
18 */
19
20 #include "kernel/register.h"
21 #include "kernel/rtlil.h"
22 #include "kernel/log.h"
23
24 USING_YOSYS_NAMESPACE
25 PRIVATE_NAMESPACE_BEGIN
26
27 static std::string hicell_celltype, hicell_portname;
28 static std::string locell_celltype, locell_portname;
29 static bool singleton_mode;
30
31 static RTLIL::Module *module;
32 static RTLIL::SigBit last_hi, last_lo;
33
34 void hilomap_worker(RTLIL::SigSpec &sig)
35 {
36 for (auto &bit : sig) {
37 if (bit == RTLIL::State::S1 && !hicell_celltype.empty()) {
38 if (!singleton_mode || last_hi == RTLIL::State::Sm) {
39 last_hi = module->addWire(NEW_ID);
40 RTLIL::Cell *cell = module->addCell(NEW_ID, RTLIL::escape_id(hicell_celltype));
41 cell->setPort(RTLIL::escape_id(hicell_portname), last_hi);
42 }
43 bit = last_hi;
44 }
45 if (bit == RTLIL::State::S0 && !locell_celltype.empty()) {
46 if (!singleton_mode || last_lo == RTLIL::State::Sm) {
47 last_lo = module->addWire(NEW_ID);
48 RTLIL::Cell *cell = module->addCell(NEW_ID, RTLIL::escape_id(locell_celltype));
49 cell->setPort(RTLIL::escape_id(locell_portname), last_lo);
50 }
51 bit = last_lo;
52 }
53 }
54 }
55
56 struct HilomapPass : public Pass {
57 HilomapPass() : Pass("hilomap", "technology mapping of constant hi- and/or lo-drivers") { }
58 void help() YS_OVERRIDE
59 {
60 log("\n");
61 log(" hilomap [options] [selection]\n");
62 log("\n");
63 log("Map constants to 'tielo' and 'tiehi' driver cells.\n");
64 log("\n");
65 log(" -hicell <celltype> <portname>\n");
66 log(" Replace constant hi bits with this cell.\n");
67 log("\n");
68 log(" -locell <celltype> <portname>\n");
69 log(" Replace constant lo bits with this cell.\n");
70 log("\n");
71 log(" -singleton\n");
72 log(" Create only one hi/lo cell and connect all constant bits\n");
73 log(" to that cell. Per default a separate cell is created for\n");
74 log(" each constant bit.\n");
75 log("\n");
76 }
77 void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
78 {
79 log_header(design, "Executing HILOMAP pass (mapping to constant drivers).\n");
80
81 hicell_celltype = std::string();
82 hicell_portname = std::string();
83 locell_celltype = std::string();
84 locell_portname = std::string();
85 singleton_mode = false;
86
87 size_t argidx;
88 for (argidx = 1; argidx < args.size(); argidx++)
89 {
90 if (args[argidx] == "-hicell" && argidx+2 < args.size()) {
91 hicell_celltype = args[++argidx];
92 hicell_portname = args[++argidx];
93 continue;
94 }
95 if (args[argidx] == "-locell" && argidx+2 < args.size()) {
96 locell_celltype = args[++argidx];
97 locell_portname = args[++argidx];
98 continue;
99 }
100 if (args[argidx] == "-singleton") {
101 singleton_mode = true;
102 continue;
103 }
104 break;
105 }
106 extra_args(args, argidx, design);
107
108 for (auto &it : design->modules_)
109 {
110 module = it.second;
111
112 if (!design->selected(module))
113 continue;
114
115 last_hi = RTLIL::State::Sm;
116 last_lo = RTLIL::State::Sm;
117
118 module->rewrite_sigspecs(hilomap_worker);
119 }
120 }
121 } HilomapPass;
122
123 PRIVATE_NAMESPACE_END