aboutsummaryrefslogtreecommitdiffstats
path: root/passes
diff options
context:
space:
mode:
Diffstat (limited to 'passes')
-rw-r--r--passes/cmds/Makefile.inc1
-rw-r--r--passes/cmds/chtype.cc83
-rw-r--r--passes/cmds/design.cc97
-rw-r--r--passes/opt/opt_expr.cc4
-rw-r--r--passes/opt/opt_merge.cc2
-rw-r--r--passes/techmap/abc.cc359
6 files changed, 386 insertions, 160 deletions
diff --git a/passes/cmds/Makefile.inc b/passes/cmds/Makefile.inc
index 0a4ed1537..1dbb439ca 100644
--- a/passes/cmds/Makefile.inc
+++ b/passes/cmds/Makefile.inc
@@ -26,4 +26,5 @@ OBJS += passes/cmds/check.o
OBJS += passes/cmds/qwp.o
OBJS += passes/cmds/edgetypes.o
OBJS += passes/cmds/chformal.o
+OBJS += passes/cmds/chtype.o
diff --git a/passes/cmds/chtype.cc b/passes/cmds/chtype.cc
new file mode 100644
index 000000000..90d51667c
--- /dev/null
+++ b/passes/cmds/chtype.cc
@@ -0,0 +1,83 @@
+/*
+ * yosys -- Yosys Open SYnthesis Suite
+ *
+ * Copyright (C) 2012 Clifford Wolf <clifford@clifford.at>
+ *
+ * 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/yosys.h"
+
+USING_YOSYS_NAMESPACE
+PRIVATE_NAMESPACE_BEGIN
+
+struct ChtypePass : public Pass {
+ ChtypePass() : Pass("chtype", "change type of cells in the design") { }
+ virtual void help()
+ {
+ // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
+ log("\n");
+ log(" chtype [options] [selection]\n");
+ log("\n");
+ log("Change the types of cells in the design.\n");
+ log("\n");
+ log(" -set <type>\n");
+ log(" set the cell type to the given type\n");
+ log("\n");
+ log(" -map <old_type> <new_type>\n");
+ log(" change cells types that match <old_type> to <new_type>\n");
+ log("\n");
+ log("\n");
+ }
+ virtual void execute(std::vector<std::string> args, RTLIL::Design *design)
+ {
+ IdString set_type;
+ dict<IdString, IdString> map_types;
+
+ size_t argidx;
+ for (argidx = 1; argidx < args.size(); argidx++)
+ {
+ if (set_type == IdString() && args[argidx] == "-set" && argidx+1 < args.size()) {
+ set_type = RTLIL::escape_id(args[++argidx]);
+ continue;
+ }
+ if (args[argidx] == "-map" && argidx+2 < args.size()) {
+ IdString old_type = RTLIL::escape_id(args[++argidx]);
+ IdString new_type = RTLIL::escape_id(args[++argidx]);
+ map_types[old_type] = new_type;
+ continue;
+ }
+ break;
+ }
+ extra_args(args, argidx, design);
+
+ for (auto module : design->selected_modules())
+ {
+ for (auto cell : module->selected_cells())
+ {
+ if (map_types.count(cell->type)) {
+ cell->type = map_types.at(cell->type);
+ continue;
+ }
+
+ if (set_type != IdString()) {
+ cell->type = set_type;
+ continue;
+ }
+ }
+ }
+ }
+} ChtypePass;
+
+PRIVATE_NAMESPACE_END
diff --git a/passes/cmds/design.cc b/passes/cmds/design.cc
index fad1d9c0f..490c8dde5 100644
--- a/passes/cmds/design.cc
+++ b/passes/cmds/design.cc
@@ -81,6 +81,13 @@ struct DesignPass : public Pass {
log("Copy modules from the current design into the specified one.\n");
log("\n");
log("\n");
+ log(" design -import <name> [-as <new_top_name>] [selection]\n");
+ log("\n");
+ log("Import the specified design into the current design. The source design must\n");
+ log("either have a selected top module or the selection must contain exactly one\n");
+ log("module that is then used as top module for this command.\n");
+ log("\n");
+ log("\n");
log(" design -reset-vlog\n");
log("\n");
log("The Verilog front-end remembers defined macros and top-level declarations\n");
@@ -94,6 +101,7 @@ struct DesignPass : public Pass {
bool reset_vlog_mode = false;
bool push_mode = false;
bool pop_mode = false;
+ bool import_mode = false;
RTLIL::Design *copy_from_design = NULL, *copy_to_design = NULL;
std::string save_name, load_name, as_name;
std::vector<RTLIL::Module*> copy_src_modules;
@@ -156,8 +164,17 @@ struct DesignPass : public Pass {
copy_from_design = design;
continue;
}
- if (copy_from_design != NULL && args[argidx] == "-as" && argidx+1 < args.size()) {
+ if (!got_mode && args[argidx] == "-import" && argidx+1 < args.size()) {
got_mode = true;
+ import_mode = true;
+ if (saved_designs.count(args[++argidx]) == 0)
+ log_cmd_error("No saved design '%s' found!\n", args[argidx].c_str());
+ copy_from_design = saved_designs.at(args[argidx]);
+ copy_to_design = design;
+ as_name = args[argidx];
+ continue;
+ }
+ if (copy_from_design != NULL && args[argidx] == "-as" && argidx+1 < args.size()) {
as_name = args[++argidx];
continue;
}
@@ -166,10 +183,10 @@ struct DesignPass : public Pass {
if (copy_from_design != NULL)
{
- if (copy_from_design != design && argidx == args.size())
+ if (copy_from_design != design && argidx == args.size() && !import_mode)
cmd_error(args, argidx, "Missing selection.");
- RTLIL::Selection sel = design->selection_stack.back();
+ RTLIL::Selection sel;
if (argidx != args.size()) {
handle_extra_select_args(this, args, argidx, args.size(), copy_from_design);
sel = copy_from_design->selection_stack.back();
@@ -185,6 +202,17 @@ struct DesignPass : public Pass {
if (sel.selected_module(it.first))
log_cmd_error("Module %s is only partly selected.\n", RTLIL::id2cstr(it.first));
}
+
+ if (import_mode) {
+ for (auto module : copy_src_modules)
+ {
+ if (module->get_bool_attribute("\\top")) {
+ copy_src_modules.clear();
+ copy_src_modules.push_back(module);
+ break;
+ }
+ }
+ }
}
extra_args(args, argidx, design, false);
@@ -195,6 +223,68 @@ struct DesignPass : public Pass {
if (pop_mode && pushed_designs.empty())
log_cmd_error("No pushed designs.\n");
+ if (import_mode)
+ {
+ std::string prefix = RTLIL::escape_id(as_name);
+
+ pool<Module*> queue;
+ dict<IdString, IdString> done;
+
+ if (copy_to_design->modules_.count(prefix))
+ delete copy_to_design->modules_.at(prefix);
+
+ if (GetSize(copy_src_modules) != 1)
+ log_cmd_error("No top module found in source design.\n");
+
+ for (auto mod : copy_src_modules)
+ {
+ log("Importing %s as %s.\n", log_id(mod), log_id(prefix));
+
+ copy_to_design->modules_[prefix] = mod->clone();
+ copy_to_design->modules_[prefix]->name = prefix;
+ copy_to_design->modules_[prefix]->design = copy_to_design;
+ copy_to_design->modules_[prefix]->attributes.erase("\\top");
+
+ queue.insert(copy_to_design->modules_[prefix]);
+ done[mod->name] = prefix;
+ }
+
+ while (!queue.empty())
+ {
+ pool<Module*> old_queue;
+ old_queue.swap(queue);
+
+ for (auto mod : old_queue)
+ for (auto cell : mod->cells())
+ {
+ Module *fmod = copy_from_design->module(cell->type);
+
+ if (fmod == nullptr)
+ continue;
+
+ if (done.count(cell->type) == 0)
+ {
+ std::string trg_name = prefix + "." + (cell->type.c_str() + (*cell->type.c_str() == '\\'));
+
+ log("Importing %s as %s.\n", log_id(fmod), log_id(trg_name));
+
+ if (copy_to_design->modules_.count(trg_name))
+ delete copy_to_design->modules_.at(trg_name);
+
+ copy_to_design->modules_[trg_name] = fmod->clone();
+ copy_to_design->modules_[trg_name]->name = trg_name;
+ copy_to_design->modules_[trg_name]->design = copy_to_design;
+ copy_to_design->modules_[trg_name]->attributes.erase("\\top");
+
+ queue.insert(copy_to_design->modules_[trg_name]);
+ done[cell->type] = trg_name;
+ }
+
+ cell->type = done.at(cell->type);
+ }
+ }
+ }
+ else
if (copy_to_design != NULL)
{
if (!as_name.empty() && copy_src_modules.size() > 1)
@@ -206,6 +296,7 @@ struct DesignPass : public Pass {
if (copy_to_design->modules_.count(trg_name))
delete copy_to_design->modules_.at(trg_name);
+
copy_to_design->modules_[trg_name] = mod->clone();
copy_to_design->modules_[trg_name]->name = trg_name;
copy_to_design->modules_[trg_name]->design = copy_to_design;
diff --git a/passes/opt/opt_expr.cc b/passes/opt/opt_expr.cc
index 07cdf4652..f9e40869d 100644
--- a/passes/opt/opt_expr.cc
+++ b/passes/opt/opt_expr.cc
@@ -371,13 +371,13 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
if (cell->type.in("$reduce_and", "$_AND_"))
detect_const_and = true;
- if (cell->type.in("$and", "$logic_and") && GetSize(cell->getPort("\\A")) == 1 && GetSize(cell->getPort("\\B")) == 1)
+ if (cell->type.in("$and", "$logic_and") && GetSize(cell->getPort("\\A")) == 1 && GetSize(cell->getPort("\\B")) == 1 && !cell->getParam("\\A_SIGNED").as_bool())
detect_const_and = true;
if (cell->type.in("$reduce_or", "$reduce_bool", "$_OR_"))
detect_const_or = true;
- if (cell->type.in("$or", "$logic_or") && GetSize(cell->getPort("\\A")) == 1 && GetSize(cell->getPort("\\B")) == 1)
+ if (cell->type.in("$or", "$logic_or") && GetSize(cell->getPort("\\A")) == 1 && GetSize(cell->getPort("\\B")) == 1 && !cell->getParam("\\A_SIGNED").as_bool())
detect_const_or = true;
if (detect_const_and || detect_const_or)
diff --git a/passes/opt/opt_merge.cc b/passes/opt/opt_merge.cc
index b63fd3c8d..93d9f012f 100644
--- a/passes/opt/opt_merge.cc
+++ b/passes/opt/opt_merge.cc
@@ -275,6 +275,8 @@ struct OptMergeWorker
ct.cell_types.erase("$pmux");
}
+ ct.cell_types.erase("$tribuf");
+ ct.cell_types.erase("$_TBUF_");
ct.cell_types.erase("$anyseq");
ct.cell_types.erase("$anyconst");
diff --git a/passes/techmap/abc.cc b/passes/techmap/abc.cc
index dd2469839..341e65ddc 100644
--- a/passes/techmap/abc.cc
+++ b/passes/techmap/abc.cc
@@ -92,6 +92,7 @@ struct gate_t
int in1, in2, in3, in4;
bool is_port;
RTLIL::SigBit bit;
+ RTLIL::State init;
};
bool map_mux4;
@@ -104,7 +105,9 @@ SigMap assign_map;
RTLIL::Module *module;
std::vector<gate_t> signal_list;
std::map<RTLIL::SigBit, int> signal_map;
+std::map<RTLIL::SigBit, RTLIL::State> signal_init;
pool<std::string> enabled_gates;
+bool recover_init;
bool clk_polarity, en_polarity;
RTLIL::SigSpec clk_sig, en_sig;
@@ -123,6 +126,10 @@ int map_signal(RTLIL::SigBit bit, gate_type_t gate_type = G(NONE), int in1 = -1,
gate.in4 = -1;
gate.is_port = false;
gate.bit = bit;
+ if (signal_init.count(bit))
+ gate.init = signal_init.at(bit);
+ else
+ gate.init = State::Sx;
signal_list.push_back(gate);
signal_map[bit] = gate.id;
}
@@ -609,11 +616,10 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin
signal_map.clear();
signal_list.clear();
+ recover_init = false;
if (clk_str != "$")
{
- assign_map.set(module);
-
clk_polarity = true;
clk_sig = RTLIL::SigSpec();
@@ -621,6 +627,30 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin
en_sig = RTLIL::SigSpec();
}
+ if (!clk_str.empty() && clk_str != "$")
+ {
+ if (clk_str.find(',') != std::string::npos) {
+ int pos = clk_str.find(',');
+ std::string en_str = clk_str.substr(pos+1);
+ clk_str = clk_str.substr(0, pos);
+ if (en_str[0] == '!') {
+ en_polarity = false;
+ en_str = en_str.substr(1);
+ }
+ if (module->wires_.count(RTLIL::escape_id(en_str)) != 0)
+ en_sig = assign_map(RTLIL::SigSpec(module->wires_.at(RTLIL::escape_id(en_str)), 0));
+ }
+ if (clk_str[0] == '!') {
+ clk_polarity = false;
+ clk_str = clk_str.substr(1);
+ }
+ if (module->wires_.count(RTLIL::escape_id(clk_str)) != 0)
+ clk_sig = assign_map(RTLIL::SigSpec(module->wires_.at(RTLIL::escape_id(clk_str)), 0));
+ }
+
+ if (dff_mode && clk_sig.empty())
+ log_cmd_error("Clock domain %s not found.\n", clk_str.c_str());
+
std::string tempdir_name = "/tmp/yosys-abc-XXXXXX";
if (!cleanup)
tempdir_name[0] = tempdir_name[4] = '_';
@@ -693,30 +723,6 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin
fprintf(f, "%s\n", abc_script.c_str());
fclose(f);
- if (!clk_str.empty() && clk_str != "$")
- {
- if (clk_str.find(',') != std::string::npos) {
- int pos = clk_str.find(',');
- std::string en_str = clk_str.substr(pos+1);
- clk_str = clk_str.substr(0, pos);
- if (en_str[0] == '!') {
- en_polarity = false;
- en_str = en_str.substr(1);
- }
- if (module->wires_.count(RTLIL::escape_id(en_str)) != 0)
- en_sig = assign_map(RTLIL::SigSpec(module->wires_.at(RTLIL::escape_id(en_str)), 0));
- }
- if (clk_str[0] == '!') {
- clk_polarity = false;
- clk_str = clk_str.substr(1);
- }
- if (module->wires_.count(RTLIL::escape_id(clk_str)) != 0)
- clk_sig = assign_map(RTLIL::SigSpec(module->wires_.at(RTLIL::escape_id(clk_str)), 0));
- }
-
- if (dff_mode && clk_sig.empty())
- log_error("Clock domain %s not found.\n", clk_str.c_str());
-
if (dff_mode || !clk_str.empty())
{
if (clk_sig.size() == 0)
@@ -849,7 +855,11 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin
fprintf(f, "00-- 1\n");
fprintf(f, "--00 1\n");
} else if (si.type == G(FF)) {
- fprintf(f, ".latch n%d n%d\n", si.in1, si.id);
+ if (si.init == State::S0 || si.init == State::S1) {
+ fprintf(f, ".latch n%d n%d %d\n", si.in1, si.id, si.init == State::S1 ? 1 : 0);
+ recover_init = true;
+ } else
+ fprintf(f, ".latch n%d n%d 2\n", si.in1, si.id);
} else if (si.type != G(NONE))
log_abort();
if (si.type != G(NONE))
@@ -1155,6 +1165,15 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin
module->connect(conn);
}
+ if (recover_init)
+ for (auto wire : mapped_mod->wires()) {
+ if (wire->attributes.count("\\init")) {
+ Wire *w = module->wires_[remap_name(wire->name)];
+ log_assert(w->attributes.count("\\init") == 0);
+ w->attributes["\\init"] = wire->attributes.at("\\init");
+ }
+ }
+
for (auto &it : cell_stats)
log("ABC RESULTS: %15s cells: %8d\n", it.first.c_str(), it.second);
int in_wires = 0, out_wires = 0;
@@ -1369,6 +1388,11 @@ struct AbcPass : public Pass {
log_header(design, "Executing ABC pass (technology mapping using ABC).\n");
log_push();
+ assign_map.clear();
+ signal_list.clear();
+ signal_map.clear();
+ signal_init.clear();
+
#ifdef ABCEXTERNAL
std::string exe_file = ABCEXTERNAL;
#else
@@ -1610,163 +1634,188 @@ struct AbcPass : public Pass {
log_cmd_error("Got -constr but no -liberty!\n");
for (auto mod : design->selected_modules())
- if (mod->processes.size() > 0)
+ {
+ if (mod->processes.size() > 0) {
log("Skipping module %s as it contains processes.\n", log_id(mod));
- else if (!dff_mode || !clk_str.empty())
+ continue;
+ }
+
+ assign_map.set(mod);
+ signal_init.clear();
+
+ for (Wire *wire : mod->wires())
+ if (wire->attributes.count("\\init")) {
+ SigSpec initsig = assign_map(wire);
+ Const initval = wire->attributes.at("\\init");
+ for (int i = 0; i < GetSize(initsig) && i < GetSize(initval); i++)
+ switch (initval[i]) {
+ case State::S0:
+ signal_init[initsig[i]] = State::S0;
+ break;
+ case State::S1:
+ signal_init[initsig[i]] = State::S0;
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (!dff_mode || !clk_str.empty()) {
abc_module(design, mod, script_file, exe_file, liberty_file, constr_file, cleanup, lut_costs, dff_mode, clk_str, keepff,
delay_target, sop_inputs, sop_products, lutin_shared, fast_mode, mod->selected_cells(), show_tempdir, sop_mode);
- else
- {
- assign_map.set(mod);
- CellTypes ct(design);
+ continue;
+ }
- std::vector<RTLIL::Cell*> all_cells = mod->selected_cells();
- std::set<RTLIL::Cell*> unassigned_cells(all_cells.begin(), all_cells.end());
+ CellTypes ct(design);
- std::set<RTLIL::Cell*> expand_queue, next_expand_queue;
- std::set<RTLIL::Cell*> expand_queue_up, next_expand_queue_up;
- std::set<RTLIL::Cell*> expand_queue_down, next_expand_queue_down;
+ std::vector<RTLIL::Cell*> all_cells = mod->selected_cells();
+ std::set<RTLIL::Cell*> unassigned_cells(all_cells.begin(), all_cells.end());
- typedef tuple<bool, RTLIL::SigSpec, bool, RTLIL::SigSpec> clkdomain_t;
- std::map<clkdomain_t, std::vector<RTLIL::Cell*>> assigned_cells;
- std::map<RTLIL::Cell*, clkdomain_t> assigned_cells_reverse;
+ std::set<RTLIL::Cell*> expand_queue, next_expand_queue;
+ std::set<RTLIL::Cell*> expand_queue_up, next_expand_queue_up;
+ std::set<RTLIL::Cell*> expand_queue_down, next_expand_queue_down;
- std::map<RTLIL::Cell*, std::set<RTLIL::SigBit>> cell_to_bit, cell_to_bit_up, cell_to_bit_down;
- std::map<RTLIL::SigBit, std::set<RTLIL::Cell*>> bit_to_cell, bit_to_cell_up, bit_to_cell_down;
+ typedef tuple<bool, RTLIL::SigSpec, bool, RTLIL::SigSpec> clkdomain_t;
+ std::map<clkdomain_t, std::vector<RTLIL::Cell*>> assigned_cells;
+ std::map<RTLIL::Cell*, clkdomain_t> assigned_cells_reverse;
- for (auto cell : all_cells)
- {
- clkdomain_t key;
-
- for (auto &conn : cell->connections())
- for (auto bit : conn.second) {
- bit = assign_map(bit);
- if (bit.wire != nullptr) {
- cell_to_bit[cell].insert(bit);
- bit_to_cell[bit].insert(cell);
- if (ct.cell_input(cell->type, conn.first)) {
- cell_to_bit_up[cell].insert(bit);
- bit_to_cell_down[bit].insert(cell);
- }
- if (ct.cell_output(cell->type, conn.first)) {
- cell_to_bit_down[cell].insert(bit);
- bit_to_cell_up[bit].insert(cell);
- }
- }
- }
+ std::map<RTLIL::Cell*, std::set<RTLIL::SigBit>> cell_to_bit, cell_to_bit_up, cell_to_bit_down;
+ std::map<RTLIL::SigBit, std::set<RTLIL::Cell*>> bit_to_cell, bit_to_cell_up, bit_to_cell_down;
- if (cell->type == "$_DFF_N_" || cell->type == "$_DFF_P_")
- {
- key = clkdomain_t(cell->type == "$_DFF_P_", assign_map(cell->getPort("\\C")), true, RTLIL::SigSpec());
- }
- else
- if (cell->type == "$_DFFE_NN_" || cell->type == "$_DFFE_NP_" || cell->type == "$_DFFE_PN_" || cell->type == "$_DFFE_PP_")
- {
- bool this_clk_pol = cell->type == "$_DFFE_PN_" || cell->type == "$_DFFE_PP_";
- bool this_en_pol = cell->type == "$_DFFE_NP_" || cell->type == "$_DFFE_PP_";
- key = clkdomain_t(this_clk_pol, assign_map(cell->getPort("\\C")), this_en_pol, assign_map(cell->getPort("\\E")));
+ for (auto cell : all_cells)
+ {
+ clkdomain_t key;
+
+ for (auto &conn : cell->connections())
+ for (auto bit : conn.second) {
+ bit = assign_map(bit);
+ if (bit.wire != nullptr) {
+ cell_to_bit[cell].insert(bit);
+ bit_to_cell[bit].insert(cell);
+ if (ct.cell_input(cell->type, conn.first)) {
+ cell_to_bit_up[cell].insert(bit);
+ bit_to_cell_down[bit].insert(cell);
+ }
+ if (ct.cell_output(cell->type, conn.first)) {
+ cell_to_bit_down[cell].insert(bit);
+ bit_to_cell_up[bit].insert(cell);
+ }
}
- else
- continue;
-
- unassigned_cells.erase(cell);
- expand_queue.insert(cell);
- expand_queue_up.insert(cell);
- expand_queue_down.insert(cell);
-
- assigned_cells[key].push_back(cell);
- assigned_cells_reverse[cell] = key;
}
- while (!expand_queue_up.empty() || !expand_queue_down.empty())
+ if (cell->type == "$_DFF_N_" || cell->type == "$_DFF_P_")
{
- if (!expand_queue_up.empty())
- {
- RTLIL::Cell *cell = *expand_queue_up.begin();
- clkdomain_t key = assigned_cells_reverse.at(cell);
- expand_queue_up.erase(cell);
-
- for (auto bit : cell_to_bit_up[cell])
- for (auto c : bit_to_cell_up[bit])
- if (unassigned_cells.count(c)) {
- unassigned_cells.erase(c);
- next_expand_queue_up.insert(c);
- assigned_cells[key].push_back(c);
- assigned_cells_reverse[c] = key;
- expand_queue.insert(c);
- }
- }
+ key = clkdomain_t(cell->type == "$_DFF_P_", assign_map(cell->getPort("\\C")), true, RTLIL::SigSpec());
+ }
+ else
+ if (cell->type == "$_DFFE_NN_" || cell->type == "$_DFFE_NP_" || cell->type == "$_DFFE_PN_" || cell->type == "$_DFFE_PP_")
+ {
+ bool this_clk_pol = cell->type == "$_DFFE_PN_" || cell->type == "$_DFFE_PP_";
+ bool this_en_pol = cell->type == "$_DFFE_NP_" || cell->type == "$_DFFE_PP_";
+ key = clkdomain_t(this_clk_pol, assign_map(cell->getPort("\\C")), this_en_pol, assign_map(cell->getPort("\\E")));
+ }
+ else
+ continue;
- if (!expand_queue_down.empty())
- {
- RTLIL::Cell *cell = *expand_queue_down.begin();
- clkdomain_t key = assigned_cells_reverse.at(cell);
- expand_queue_down.erase(cell);
-
- for (auto bit : cell_to_bit_down[cell])
- for (auto c : bit_to_cell_down[bit])
- if (unassigned_cells.count(c)) {
- unassigned_cells.erase(c);
- next_expand_queue_up.insert(c);
- assigned_cells[key].push_back(c);
- assigned_cells_reverse[c] = key;
- expand_queue.insert(c);
- }
- }
+ unassigned_cells.erase(cell);
+ expand_queue.insert(cell);
+ expand_queue_up.insert(cell);
+ expand_queue_down.insert(cell);
- if (expand_queue_up.empty() && expand_queue_down.empty()) {
- expand_queue_up.swap(next_expand_queue_up);
- expand_queue_down.swap(next_expand_queue_down);
- }
- }
+ assigned_cells[key].push_back(cell);
+ assigned_cells_reverse[cell] = key;
+ }
- while (!expand_queue.empty())
+ while (!expand_queue_up.empty() || !expand_queue_down.empty())
+ {
+ if (!expand_queue_up.empty())
{
- RTLIL::Cell *cell = *expand_queue.begin();
+ RTLIL::Cell *cell = *expand_queue_up.begin();
clkdomain_t key = assigned_cells_reverse.at(cell);
- expand_queue.erase(cell);
-
- for (auto bit : cell_to_bit.at(cell)) {
- for (auto c : bit_to_cell[bit])
- if (unassigned_cells.count(c)) {
- unassigned_cells.erase(c);
- next_expand_queue.insert(c);
- assigned_cells[key].push_back(c);
- assigned_cells_reverse[c] = key;
- }
- bit_to_cell[bit].clear();
- }
+ expand_queue_up.erase(cell);
+
+ for (auto bit : cell_to_bit_up[cell])
+ for (auto c : bit_to_cell_up[bit])
+ if (unassigned_cells.count(c)) {
+ unassigned_cells.erase(c);
+ next_expand_queue_up.insert(c);
+ assigned_cells[key].push_back(c);
+ assigned_cells_reverse[c] = key;
+ expand_queue.insert(c);
+ }
+ }
- if (expand_queue.empty())
- expand_queue.swap(next_expand_queue);
+ if (!expand_queue_down.empty())
+ {
+ RTLIL::Cell *cell = *expand_queue_down.begin();
+ clkdomain_t key = assigned_cells_reverse.at(cell);
+ expand_queue_down.erase(cell);
+
+ for (auto bit : cell_to_bit_down[cell])
+ for (auto c : bit_to_cell_down[bit])
+ if (unassigned_cells.count(c)) {
+ unassigned_cells.erase(c);
+ next_expand_queue_up.insert(c);
+ assigned_cells[key].push_back(c);
+ assigned_cells_reverse[c] = key;
+ expand_queue.insert(c);
+ }
}
- clkdomain_t key(true, RTLIL::SigSpec(), true, RTLIL::SigSpec());
- for (auto cell : unassigned_cells) {
- assigned_cells[key].push_back(cell);
- assigned_cells_reverse[cell] = key;
+ if (expand_queue_up.empty() && expand_queue_down.empty()) {
+ expand_queue_up.swap(next_expand_queue_up);
+ expand_queue_down.swap(next_expand_queue_down);
}
+ }
- log_header(design, "Summary of detected clock domains:\n");
- for (auto &it : assigned_cells)
- log(" %d cells in clk=%s%s, en=%s%s\n", GetSize(it.second),
- std::get<0>(it.first) ? "" : "!", log_signal(std::get<1>(it.first)),
- std::get<2>(it.first) ? "" : "!", log_signal(std::get<3>(it.first)));
-
- for (auto &it : assigned_cells) {
- clk_polarity = std::get<0>(it.first);
- clk_sig = assign_map(std::get<1>(it.first));
- en_polarity = std::get<2>(it.first);
- en_sig = assign_map(std::get<3>(it.first));
- abc_module(design, mod, script_file, exe_file, liberty_file, constr_file, cleanup, lut_costs, !clk_sig.empty(), "$",
- keepff, delay_target, sop_inputs, sop_products, lutin_shared, fast_mode, it.second, show_tempdir, sop_mode);
- assign_map.set(mod);
+ while (!expand_queue.empty())
+ {
+ RTLIL::Cell *cell = *expand_queue.begin();
+ clkdomain_t key = assigned_cells_reverse.at(cell);
+ expand_queue.erase(cell);
+
+ for (auto bit : cell_to_bit.at(cell)) {
+ for (auto c : bit_to_cell[bit])
+ if (unassigned_cells.count(c)) {
+ unassigned_cells.erase(c);
+ next_expand_queue.insert(c);
+ assigned_cells[key].push_back(c);
+ assigned_cells_reverse[c] = key;
+ }
+ bit_to_cell[bit].clear();
}
+
+ if (expand_queue.empty())
+ expand_queue.swap(next_expand_queue);
}
+ clkdomain_t key(true, RTLIL::SigSpec(), true, RTLIL::SigSpec());
+ for (auto cell : unassigned_cells) {
+ assigned_cells[key].push_back(cell);
+ assigned_cells_reverse[cell] = key;
+ }
+
+ log_header(design, "Summary of detected clock domains:\n");
+ for (auto &it : assigned_cells)
+ log(" %d cells in clk=%s%s, en=%s%s\n", GetSize(it.second),
+ std::get<0>(it.first) ? "" : "!", log_signal(std::get<1>(it.first)),
+ std::get<2>(it.first) ? "" : "!", log_signal(std::get<3>(it.first)));
+
+ for (auto &it : assigned_cells) {
+ clk_polarity = std::get<0>(it.first);
+ clk_sig = assign_map(std::get<1>(it.first));
+ en_polarity = std::get<2>(it.first);
+ en_sig = assign_map(std::get<3>(it.first));
+ abc_module(design, mod, script_file, exe_file, liberty_file, constr_file, cleanup, lut_costs, !clk_sig.empty(), "$",
+ keepff, delay_target, sop_inputs, sop_products, lutin_shared, fast_mode, it.second, show_tempdir, sop_mode);
+ assign_map.set(mod);
+ }
+ }
+
assign_map.clear();
signal_list.clear();
signal_map.clear();
+ signal_init.clear();
log_pop();
}