Merge remote-tracking branch 'origin/xaig_dff' into eddie/exp
diff --git a/passes/memory/memory_bram.cc b/passes/memory/memory_bram.cc index aa8f941..cd8c9c5 100644 --- a/passes/memory/memory_bram.cc +++ b/passes/memory/memory_bram.cc
@@ -134,6 +134,8 @@ dict<string, int> min_limits, max_limits; bool or_next_if_better, make_transp, make_outreg; char shuffle_enable; + IdString attr; + Const value; }; dict<IdString, vector<bram_t>> brams; @@ -327,6 +329,13 @@ continue; } + if (GetSize(tokens) >= 2 && tokens[0] == "attribute") { + data.attr = RTLIL::escape_id(tokens[1]); + if (GetSize(tokens) > 2) + data.value = tokens[2]; + continue; + } + syntax_error(); } } @@ -813,6 +822,23 @@ return false; } + if (!match.attr.empty()) { + auto it = cell->attributes.find(match.attr); + if (it == cell->attributes.end()) { + if (!match.value.empty()) + log(" Rule for bram type %s rejected: requirement 'attribute %s=\"%s\"' not met.\n", + log_id(match.name), log_id(match.attr), match.value.decode_string().c_str()); + return false; + } + else { + if (it->second != match.value) { + log(" Rule for bram type %s rejected: requirement 'attribute %s=\"%s\"' not met.\n", + log_id(match.name), log_id(match.attr), match.value.decode_string().c_str()); + return false; + } + } + } + if (mode == 1) return true; } @@ -1100,6 +1126,24 @@ goto next_match_rule; } + if (!match.attr.empty()) { + auto it = cell->attributes.find(match.attr); + if (it == cell->attributes.end()) { + if (!match.value.empty()) { + log(" Rule for bram type %s rejected: requirement 'attribute %s=\"%s\"' not met.\n", + log_id(match.name), log_id(match.attr), match.value.decode_string().c_str()); + goto next_match_rule; + } + } + else { + if (it->second != match.value) { + log(" Rule for bram type %s rejected: requirement 'attribute %s=\"%s\"' not met.\n", + log_id(match.name), log_id(match.attr), match.value.decode_string().c_str()); + goto next_match_rule; + } + } + } + log(" Rule #%d for bram type %s (variant %d) accepted.\n", i+1, log_id(bram.name), bram.variant); if (or_next_if_better || !best_rule_cache.empty()) @@ -1225,6 +1269,11 @@ log(" dcells ....... number of cells in 'data-direction'\n"); log(" cells ........ total number of cells (acells*dcells*dups)\n"); log("\n"); + log("A match containing the condition 'attribute' followed by a name and optional\n"); + log("value requires that the memory contains the given attribute name and value\n"); + log("(if specified) or that the attribute is not present or the value is empty (if\n"); + log("value is not specified\n)."); + log("\n"); log("The interface for the created bram instances is derived from the bram\n"); log("description. Use 'techmap' to convert the created bram instances into\n"); log("instances of the actual bram cells of your target architecture.\n");
diff --git a/passes/memory/memory_collect.cc b/passes/memory/memory_collect.cc index 9dcb3f0..6acbce6 100644 --- a/passes/memory/memory_collect.cc +++ b/passes/memory/memory_collect.cc
@@ -218,10 +218,6 @@ mem->setPort("\\RD_DATA", sig_rd_data); mem->setPort("\\RD_EN", sig_rd_en); - // Copy attributes from RTLIL memory to $mem - for (auto attr : memory->attributes) - mem->attributes[attr.first] = attr.second; - for (auto c : memcells) module->remove(c);
diff --git a/passes/pmgen/Makefile.inc b/passes/pmgen/Makefile.inc index 145d2eb..a4d9d42 100644 --- a/passes/pmgen/Makefile.inc +++ b/passes/pmgen/Makefile.inc
@@ -45,3 +45,9 @@ OBJS += passes/pmgen/xilinx_srl.o passes/pmgen/xilinx_srl.o: passes/pmgen/xilinx_srl_pm.h $(eval $(call add_extra_objs,passes/pmgen/xilinx_srl_pm.h)) + +# -------------------------------------- + +OBJS += passes/pmgen/xilinx_dff.o +passes/pmgen/xilinx_dff.o: passes/pmgen/xilinx_dff_pm.h +$(eval $(call add_extra_objs,passes/pmgen/xilinx_dff_pm.h))
diff --git a/passes/pmgen/xilinx_dff.cc b/passes/pmgen/xilinx_dff.cc new file mode 100644 index 0000000..bf0c735 --- /dev/null +++ b/passes/pmgen/xilinx_dff.cc
@@ -0,0 +1,62 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2012 Clifford Wolf <clifford@clifford.at> + * 2019 Eddie Hung <eddie@fpgeh.com> + * + * 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" +#include "kernel/sigtools.h" + +USING_YOSYS_NAMESPACE +PRIVATE_NAMESPACE_BEGIN + +#include "passes/pmgen/xilinx_dff_pm.h" + +struct XilinxDffPass : public Pass { + XilinxDffPass() : Pass("xilinx_dff", "Xilinx: TODO") { } + void help() YS_OVERRIDE + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" xilinx_dff [options] [selection]\n"); + log("\n"); + log("TODO\n"); + log("\n"); + } + void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + { + log_header(design, "Executing XILINX_DFF pass (TODO).\n"); + + size_t argidx; + for (argidx = 1; argidx < args.size(); argidx++) + { + // if (args[argidx] == "-singleton") { + // singleton_mode = true; + // continue; + // } + break; + } + extra_args(args, argidx, design); + + for (auto module : design->selected_modules()) { + xilinx_dff_pm pm(module, module->selected_cells()); + pm.run_xilinx_dff(); + } + } +} XilinxDffPass; + +PRIVATE_NAMESPACE_END
diff --git a/passes/pmgen/xilinx_dff.pmg b/passes/pmgen/xilinx_dff.pmg new file mode 100644 index 0000000..4de25c3 --- /dev/null +++ b/passes/pmgen/xilinx_dff.pmg
@@ -0,0 +1,26 @@ +pattern xilinx_dff + +match fd + select fd->type.in(\FDRE) + select port(fd, \R).is_fully_zero() + select port(fd, \CE).is_fully_ones() +endmatch + +match lut + select lut->type.in(\LUT2) + index <SigSpec> port(lut, \O) === port(fd, \D) +endmatch + +code + if (lut->type == \LUT2) { + if (param(lut, \INIT) == Const::from_string("0010")) { + fd->setPort(\D, port(lut, \I0)); + fd->setPort(\R, port(lut, \I1)); + } + else if (param(lut, \INIT) == Const::from_string("0100")) { + fd->setPort(\R, port(lut, \I0)); + fd->setPort(\D, port(lut, \I1)); + } + } + else log_abort(); +endcode
diff --git a/techlibs/xilinx/synth_xilinx.cc b/techlibs/xilinx/synth_xilinx.cc index 554c42d..df7514f 100644 --- a/techlibs/xilinx/synth_xilinx.cc +++ b/techlibs/xilinx/synth_xilinx.cc
@@ -559,6 +559,7 @@ else techmap_args += " -map " + ff_map_file; run("techmap " + techmap_args); + run("xilinx_dff"); } if (check_label("finalize")) {
diff --git a/techlibs/xilinx/xc7_xcu_brams.txt b/techlibs/xilinx/xc7_xcu_brams.txt index f116111..7d3d997 100644 --- a/techlibs/xilinx/xc7_xcu_brams.txt +++ b/techlibs/xilinx/xc7_xcu_brams.txt
@@ -81,10 +81,18 @@ endmatch match $__XILINX_RAMB18_SDP - min bits 4096 + min bits 1024 min efficiency 5 shuffle_enable B make_transp + attribute ram_style + or_next_if_better +endmatch + +match $__XILINX_RAMB18_SDP + shuffle_enable B + make_transp + attribute ram_style block or_next_if_better endmatch @@ -97,7 +105,7 @@ endmatch match $__XILINX_RAMB18_TDP - min bits 4096 + min bits 1024 min efficiency 5 shuffle_enable B make_transp