From 0dadfed46d938282d7651c9a817f33b1d87397c7 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 20 Feb 2014 20:44:11 +0100 Subject: Added connwrappers command --- passes/cmds/connwrappers.cc | 205 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 205 insertions(+) create mode 100644 passes/cmds/connwrappers.cc (limited to 'passes/cmds/connwrappers.cc') diff --git a/passes/cmds/connwrappers.cc b/passes/cmds/connwrappers.cc new file mode 100644 index 000000000..dd8b4fede --- /dev/null +++ b/passes/cmds/connwrappers.cc @@ -0,0 +1,205 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2012 Clifford Wolf + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +#include "kernel/register.h" +#include "kernel/sigtools.h" +#include "kernel/rtlil.h" +#include "kernel/log.h" + +struct ConnwrappersWorker +{ + struct portdecl_t { + // key: celltype, portname; + std::string widthparam, signparam; + bool is_signed; + }; + + std::set decl_celltypes; + std::map, portdecl_t> decls; + + void add_port(std::string celltype, std::string portname, std::string widthparam, std::string signparam) + { + std::pair key(RTLIL::escape_id(celltype), RTLIL::escape_id(portname)); + decl_celltypes.insert(key.first); + + if (decls.count(key)) + log_cmd_error("Duplicate port decl: %s %s\n", celltype.c_str(), portname.c_str()); + + portdecl_t decl; + decl.widthparam = RTLIL::escape_id(widthparam); + decl.signparam = RTLIL::escape_id(signparam); + decl.is_signed = false; + decls[key] = decl; + } + + void add_port(std::string celltype, std::string portname, std::string widthparam, bool is_signed) + { + std::pair key(RTLIL::escape_id(celltype), RTLIL::escape_id(portname)); + decl_celltypes.insert(key.first); + + if (decls.count(key)) + log_cmd_error("Duplicate port decl: %s %s\n", celltype.c_str(), portname.c_str()); + + portdecl_t decl; + decl.widthparam = RTLIL::escape_id(widthparam); + decl.is_signed = is_signed; + decls[key] = decl; + } + + void work(RTLIL::Design *design, RTLIL::Module *module) + { + std::map> extend_map; + SigMap sigmap(module); + + for (auto &it : module->cells) + { + RTLIL::Cell *cell = it.second; + + if (!decl_celltypes.count(cell->type)) + continue; + + for (auto &conn : cell->connections) + { + std::pair key(cell->type, conn.first); + + if (!decls.count(key)) + continue; + + portdecl_t &decl = decls.at(key); + + if (!cell->parameters.count(decl.widthparam)) + continue; + + if (!decl.signparam.empty() && !cell->parameters.count(decl.signparam)) + continue; + + int inner_width = cell->parameters.at(decl.widthparam).as_int(); + int outer_width = conn.second.width; + bool is_signed = decl.signparam.empty() ? decl.is_signed : cell->parameters.at(decl.signparam).as_bool(); + + if (inner_width >= outer_width) + continue; + + RTLIL::SigSpec sig = sigmap(conn.second); + extend_map[sig.extract(inner_width - 1, 1)] = std::pair(is_signed, + sig.extract(inner_width, outer_width - inner_width)); + } + } + + for (auto &it : module->cells) + { + RTLIL::Cell *cell = it.second; + + if (!design->selected(module, cell)) + continue; + + for (auto &conn : cell->connections) + { + std::vector sigbits = sigmap(conn.second).to_sigbit_vector(); + RTLIL::SigSpec old_sig; + + for (size_t i = 0; i < sigbits.size(); i++) + { + if (!extend_map.count(sigbits[i])) + continue; + + bool is_signed = extend_map.at(sigbits[i]).first; + RTLIL::SigSpec extend_sig = extend_map.at(sigbits[i]).second; + + int extend_width = 0; + RTLIL::SigBit extend_bit = is_signed ? sigbits[i] : RTLIL::SigBit(RTLIL::State::S0); + while (extend_width < extend_sig.width && i + extend_width + 1 < sigbits.size() && + sigbits[i + extend_width + 1] == extend_bit) extend_width++; + + if (extend_width == 0) + continue; + + if (old_sig.width == 0) + old_sig = conn.second; + + conn.second.replace(i+1, extend_sig.extract(0, extend_width)); + i += extend_width; + } + + if (old_sig.width) + log("Connected extended bits of %s.%s:%s: %s -> %s\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(cell->name), + RTLIL::id2cstr(conn.first), log_signal(old_sig), log_signal(conn.second)); + } + } + } +}; + +struct ConnwrappersPass : public Pass { + ConnwrappersPass() : Pass("connwrappers", "replace undef values with defined constants") { } + virtual void help() + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" connwrappers [options] [selection]\n"); + log("\n"); + log("Wrappers are used in coarse-grain synthesis to wrap cells with smaller ports\n"); + log("in wrapper cells with a (larger) constant port size. I.e. the upper bits\n"); + log("of the wrapper outut are signed/unsigned bit extended. This command uses this\n"); + log("knowlege to rewire the inputs of the driven cells to match the output of\n"); + log("the driving cell.\n"); + log("\n"); + log(" -signed \n"); + log(" -unsigned \n"); + log(" consider the specified signed/unsigned wrapper output\n"); + log("\n"); + log(" -port \n"); + log(" use the specified parameter to decide if signed or unsigned\n"); + log("\n"); + log("The options -signed, -unsigned, and -port can be specified multiple times.\n"); + log("\n"); + } + virtual void execute(std::vector args, RTLIL::Design *design) + { + ConnwrappersWorker worker; + + size_t argidx; + for (argidx = 1; argidx < args.size(); argidx++) + { + if (args[argidx] == "-signed" && argidx+3 < args.size()) { + worker.add_port(args[argidx+1], args[argidx+2], args[argidx+3], true); + argidx += 3; + continue; + } + if (args[argidx] == "-unsigned" && argidx+3 < args.size()) { + worker.add_port(args[argidx+1], args[argidx+2], args[argidx+3], false); + argidx += 3; + continue; + } + if (args[argidx] == "-port" && argidx+4 < args.size()) { + worker.add_port(args[argidx+1], args[argidx+2], args[argidx+3], args[argidx+4]); + argidx += 4; + continue; + } + break; + } + extra_args(args, argidx, design); + + log_header("Executing CONNWRAPPERS pass (connect extended ports of wrapper cells).\n"); + + for (auto &mod_it : design->modules) + if (design->selected(mod_it.second)) + worker.work(design, mod_it.second); + } +} ConnwrappersPass; + -- cgit v1.2.3 From a233762a815fc180b371f699e865a7d7aed77bca Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 22 Jul 2014 19:56:17 +0200 Subject: SigSpec refactoring: renamed chunks and width to __chunks and __width --- passes/cmds/connwrappers.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'passes/cmds/connwrappers.cc') diff --git a/passes/cmds/connwrappers.cc b/passes/cmds/connwrappers.cc index dd8b4fede..426d2b624 100644 --- a/passes/cmds/connwrappers.cc +++ b/passes/cmds/connwrappers.cc @@ -90,7 +90,7 @@ struct ConnwrappersWorker continue; int inner_width = cell->parameters.at(decl.widthparam).as_int(); - int outer_width = conn.second.width; + int outer_width = conn.second.__width; bool is_signed = decl.signparam.empty() ? decl.is_signed : cell->parameters.at(decl.signparam).as_bool(); if (inner_width >= outer_width) @@ -124,20 +124,20 @@ struct ConnwrappersWorker int extend_width = 0; RTLIL::SigBit extend_bit = is_signed ? sigbits[i] : RTLIL::SigBit(RTLIL::State::S0); - while (extend_width < extend_sig.width && i + extend_width + 1 < sigbits.size() && + while (extend_width < extend_sig.__width && i + extend_width + 1 < sigbits.size() && sigbits[i + extend_width + 1] == extend_bit) extend_width++; if (extend_width == 0) continue; - if (old_sig.width == 0) + if (old_sig.__width == 0) old_sig = conn.second; conn.second.replace(i+1, extend_sig.extract(0, extend_width)); i += extend_width; } - if (old_sig.width) + if (old_sig.__width) log("Connected extended bits of %s.%s:%s: %s -> %s\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(cell->name), RTLIL::id2cstr(conn.first), log_signal(old_sig), log_signal(conn.second)); } -- cgit v1.2.3 From 4b4048bc5feba1ab05c7a63f12c0a17879cb7e04 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 22 Jul 2014 20:15:14 +0200 Subject: SigSpec refactoring: using the accessor functions everywhere --- passes/cmds/connwrappers.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'passes/cmds/connwrappers.cc') diff --git a/passes/cmds/connwrappers.cc b/passes/cmds/connwrappers.cc index 426d2b624..6cb2a892c 100644 --- a/passes/cmds/connwrappers.cc +++ b/passes/cmds/connwrappers.cc @@ -90,7 +90,7 @@ struct ConnwrappersWorker continue; int inner_width = cell->parameters.at(decl.widthparam).as_int(); - int outer_width = conn.second.__width; + int outer_width = conn.second.size(); bool is_signed = decl.signparam.empty() ? decl.is_signed : cell->parameters.at(decl.signparam).as_bool(); if (inner_width >= outer_width) @@ -124,20 +124,20 @@ struct ConnwrappersWorker int extend_width = 0; RTLIL::SigBit extend_bit = is_signed ? sigbits[i] : RTLIL::SigBit(RTLIL::State::S0); - while (extend_width < extend_sig.__width && i + extend_width + 1 < sigbits.size() && + while (extend_width < extend_sig.size() && i + extend_width + 1 < sigbits.size() && sigbits[i + extend_width + 1] == extend_bit) extend_width++; if (extend_width == 0) continue; - if (old_sig.__width == 0) + if (old_sig.size() == 0) old_sig = conn.second; conn.second.replace(i+1, extend_sig.extract(0, extend_width)); i += extend_width; } - if (old_sig.__width) + if (old_sig.size()) log("Connected extended bits of %s.%s:%s: %s -> %s\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(cell->name), RTLIL::id2cstr(conn.first), log_signal(old_sig), log_signal(conn.second)); } -- cgit v1.2.3 From cc4f10883bcc5f0a3c1b4f0937e60be3c6a1b121 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 26 Jul 2014 11:58:03 +0200 Subject: Renamed RTLIL::{Module,Cell}::connections to connections_ --- passes/cmds/connwrappers.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'passes/cmds/connwrappers.cc') diff --git a/passes/cmds/connwrappers.cc b/passes/cmds/connwrappers.cc index 6cb2a892c..87ed3d856 100644 --- a/passes/cmds/connwrappers.cc +++ b/passes/cmds/connwrappers.cc @@ -74,7 +74,7 @@ struct ConnwrappersWorker if (!decl_celltypes.count(cell->type)) continue; - for (auto &conn : cell->connections) + for (auto &conn : cell->connections_) { std::pair key(cell->type, conn.first); @@ -109,7 +109,7 @@ struct ConnwrappersWorker if (!design->selected(module, cell)) continue; - for (auto &conn : cell->connections) + for (auto &conn : cell->connections_) { std::vector sigbits = sigmap(conn.second).to_sigbit_vector(); RTLIL::SigSpec old_sig; -- cgit v1.2.3 From b7dda723022ad00c6c0089be888eab319953faa8 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 26 Jul 2014 14:32:50 +0200 Subject: Changed users of cell->connections_ to the new API (sed command) git grep -l 'connections_' | xargs sed -i -r -e ' s/(->|\.)connections_\["([^"]*)"\] = (.*);/\1set("\2", \3);/g; s/(->|\.)connections_\["([^"]*)"\]/\1get("\2")/g; s/(->|\.)connections_.at\("([^"]*)"\)/\1get("\2")/g; s/(->|\.)connections_.push_back/\1connect/g; s/(->|\.)connections_/\1connections()/g;' --- passes/cmds/connwrappers.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'passes/cmds/connwrappers.cc') diff --git a/passes/cmds/connwrappers.cc b/passes/cmds/connwrappers.cc index 87ed3d856..d7560ab1a 100644 --- a/passes/cmds/connwrappers.cc +++ b/passes/cmds/connwrappers.cc @@ -74,7 +74,7 @@ struct ConnwrappersWorker if (!decl_celltypes.count(cell->type)) continue; - for (auto &conn : cell->connections_) + for (auto &conn : cell->connections()) { std::pair key(cell->type, conn.first); @@ -109,7 +109,7 @@ struct ConnwrappersWorker if (!design->selected(module, cell)) continue; - for (auto &conn : cell->connections_) + for (auto &conn : cell->connections()) { std::vector sigbits = sigmap(conn.second).to_sigbit_vector(); RTLIL::SigSpec old_sig; -- cgit v1.2.3 From f8fdc47d3361c1a3445a9357ca26cfe75907d6b0 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 26 Jul 2014 15:57:57 +0200 Subject: Manual fixes for new cell connections API --- passes/cmds/connwrappers.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'passes/cmds/connwrappers.cc') diff --git a/passes/cmds/connwrappers.cc b/passes/cmds/connwrappers.cc index d7560ab1a..9faeffafa 100644 --- a/passes/cmds/connwrappers.cc +++ b/passes/cmds/connwrappers.cc @@ -109,7 +109,7 @@ struct ConnwrappersWorker if (!design->selected(module, cell)) continue; - for (auto &conn : cell->connections()) + for (auto &conn : cell->connections_) { std::vector sigbits = sigmap(conn.second).to_sigbit_vector(); RTLIL::SigSpec old_sig; -- cgit v1.2.3 From 4c4b6021562c598c4510831bd547edaa97d14dac Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 27 Jul 2014 01:51:45 +0200 Subject: Refactoring: Renamed RTLIL::Module::cells to cells_ --- passes/cmds/connwrappers.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'passes/cmds/connwrappers.cc') diff --git a/passes/cmds/connwrappers.cc b/passes/cmds/connwrappers.cc index 9faeffafa..cc8147c53 100644 --- a/passes/cmds/connwrappers.cc +++ b/passes/cmds/connwrappers.cc @@ -67,7 +67,7 @@ struct ConnwrappersWorker std::map> extend_map; SigMap sigmap(module); - for (auto &it : module->cells) + for (auto &it : module->cells_) { RTLIL::Cell *cell = it.second; @@ -102,7 +102,7 @@ struct ConnwrappersWorker } } - for (auto &it : module->cells) + for (auto &it : module->cells_) { RTLIL::Cell *cell = it.second; -- cgit v1.2.3 From 10e5791c5e5660cb784503d36439ee90d61eb06b Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 27 Jul 2014 10:18:00 +0200 Subject: Refactoring: Renamed RTLIL::Design::modules to modules_ --- passes/cmds/connwrappers.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'passes/cmds/connwrappers.cc') diff --git a/passes/cmds/connwrappers.cc b/passes/cmds/connwrappers.cc index cc8147c53..5125ff5e2 100644 --- a/passes/cmds/connwrappers.cc +++ b/passes/cmds/connwrappers.cc @@ -197,7 +197,7 @@ struct ConnwrappersPass : public Pass { log_header("Executing CONNWRAPPERS pass (connect extended ports of wrapper cells).\n"); - for (auto &mod_it : design->modules) + for (auto &mod_it : design->modules_) if (design->selected(mod_it.second)) worker.work(design, mod_it.second); } -- cgit v1.2.3 From b9bd22b8c8d46284fba4d4c1cbd09092a9ccc5c3 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 2 Aug 2014 13:11:01 +0200 Subject: More cleanups related to RTLIL::IdString usage --- passes/cmds/connwrappers.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'passes/cmds/connwrappers.cc') diff --git a/passes/cmds/connwrappers.cc b/passes/cmds/connwrappers.cc index 5125ff5e2..aac117169 100644 --- a/passes/cmds/connwrappers.cc +++ b/passes/cmds/connwrappers.cc @@ -30,8 +30,8 @@ struct ConnwrappersWorker bool is_signed; }; - std::set decl_celltypes; - std::map, portdecl_t> decls; + std::set decl_celltypes; + std::map, portdecl_t> decls; void add_port(std::string celltype, std::string portname, std::string widthparam, std::string signparam) { @@ -76,7 +76,7 @@ struct ConnwrappersWorker for (auto &conn : cell->connections()) { - std::pair key(cell->type, conn.first); + std::pair key(cell->type, conn.first); if (!decls.count(key)) continue; -- cgit v1.2.3