From b97fe6e86651b3a4736c46a49d76878beb088a8c Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 18 Jul 2019 14:20:43 -0700 Subject: [PATCH 01/94] Work in progress for renaming labels/options in synth_xilinx --- techlibs/xilinx/{drams.txt => lutrams.txt} | 0 .../xilinx/{drams_map.v => lutrams_map.v} | 0 techlibs/xilinx/synth_xilinx.cc | 31 ++++++++++--------- 3 files changed, 17 insertions(+), 14 deletions(-) rename techlibs/xilinx/{drams.txt => lutrams.txt} (100%) rename techlibs/xilinx/{drams_map.v => lutrams_map.v} (100%) diff --git a/techlibs/xilinx/drams.txt b/techlibs/xilinx/lutrams.txt similarity index 100% rename from techlibs/xilinx/drams.txt rename to techlibs/xilinx/lutrams.txt diff --git a/techlibs/xilinx/drams_map.v b/techlibs/xilinx/lutrams_map.v similarity index 100% rename from techlibs/xilinx/drams_map.v rename to techlibs/xilinx/lutrams_map.v diff --git a/techlibs/xilinx/synth_xilinx.cc b/techlibs/xilinx/synth_xilinx.cc index b672a0d4f..a6c1fa873 100644 --- a/techlibs/xilinx/synth_xilinx.cc +++ b/techlibs/xilinx/synth_xilinx.cc @@ -64,13 +64,13 @@ struct SynthXilinxPass : public ScriptPass log(" (this feature is experimental and incomplete)\n"); log("\n"); log(" -nobram\n"); - log(" disable inference of block rams\n"); + log(" do not use block RAM cells in output netlist\n"); log("\n"); - log(" -nodram\n"); - log(" disable inference of distributed rams\n"); + log(" -nolutram\n"); + log(" do not use distributed RAM cells in output netlist\n"); log("\n"); log(" -nosrl\n"); - log(" disable inference of shift registers\n"); + log(" do not use distributed SRL cells in output netlist\n"); log("\n"); log(" -nocarry\n"); log(" do not use XORCY/MUXCY/CARRY4 cells in output netlist\n"); @@ -104,7 +104,7 @@ struct SynthXilinxPass : public ScriptPass } std::string top_opt, edif_file, blif_file, family; - bool flatten, retime, vpr, nobram, nodram, nosrl, nocarry, nowidelut, abc9; + bool flatten, retime, vpr, nobram, nolutram, nosrl, nocarry, nowidelut, abc9; int widemux; void clear_flags() YS_OVERRIDE @@ -118,7 +118,7 @@ struct SynthXilinxPass : public ScriptPass vpr = false; nocarry = false; nobram = false; - nodram = false; + nolutram = false; nosrl = false; nocarry = false; nowidelut = false; @@ -186,8 +186,8 @@ struct SynthXilinxPass : public ScriptPass nobram = true; continue; } - if (args[argidx] == "-nodram") { - nodram = true; + if (args[argidx] == "-nolutram" || /*deprecated alias*/ args[argidx] == "-nodram") { + nolutram = true; continue; } if (args[argidx] == "-nosrl") { @@ -284,7 +284,7 @@ struct SynthXilinxPass : public ScriptPass run("opt_clean"); } - if (check_label("bram", "(skip if '-nobram')")) { + if (check_label("map_bram", "(skip if '-nobram')")) { if (help_mode) { run("memory_bram -rules +/xilinx/{family}_brams.txt"); run("techmap -map +/xilinx/{family}_brams_map.v"); @@ -301,20 +301,23 @@ struct SynthXilinxPass : public ScriptPass } } - if (check_label("dram", "(skip if '-nodram')")) { - if (!nodram || help_mode) { - run("memory_bram -rules +/xilinx/drams.txt"); - run("techmap -map +/xilinx/drams_map.v"); + if (check_label("map_lutram", "(skip if '-nolutram')")) { + if (!nolutram || help_mode) { + run("memory_bram -rules +/xilinx/lutrams.txt"); + run("techmap -map +/xilinx/lutrams_map.v"); } } - if (check_label("fine")) { + if (check_label("map_ffram")) { if (widemux > 0) run("opt -fast -mux_bool -undriven -fine"); // Necessary to omit -mux_undef otherwise muxcover // performs less efficiently else run("opt -fast -full"); run("memory_map"); + } + + if (check_label("fine")) { run("dffsr2dff"); run("dff2dffe"); if (help_mode) { From 4b71e6c42155d3359e0cca8529c12799209cf808 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 18 Jul 2019 14:21:04 -0700 Subject: [PATCH 02/94] Add CHANGELOG entry --- CHANGELOG | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index 44d83c1bf..b475ae423 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -14,6 +14,9 @@ Yosys 0.9 .. Yosys 0.9-dev - Added "synth -abc9" (experimental) - Added "script -scriptwire - "synth_xilinx" to now infer wide multiplexers (-widemux to enable) + - Renamed labels/options in synth_ice40 (e.g. map_dram -> map_lutram; -nodram -> -nolutram) + - Renamed labels/options in synth_ecp5 (e.g. map_dram -> map_lutram; -nodram -> -nolutram) + - Renamed labels/options in synth_xilinx (e.g. map_dram -> map_lutram; -nodram -> -nolutram) Yosys 0.8 .. Yosys 0.8-dev From 43616e1414ed3d98b44c4a55f4d08e2d10664aa1 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 18 Jul 2019 14:51:55 -0700 Subject: [PATCH 03/94] Update Makefile too --- techlibs/xilinx/Makefile.inc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/techlibs/xilinx/Makefile.inc b/techlibs/xilinx/Makefile.inc index 2c6e7432e..2b1af289c 100644 --- a/techlibs/xilinx/Makefile.inc +++ b/techlibs/xilinx/Makefile.inc @@ -32,8 +32,8 @@ $(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc6s_brams_bb.v)) $(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc7_brams.txt)) $(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc7_brams_map.v)) $(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc7_brams_bb.v)) -$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/drams.txt)) -$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/drams_map.v)) +$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/lutrams.txt)) +$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/lutrams_map.v)) $(eval $(call add_share_file,share/xilinx,techlibs/xilinx/arith_map.v)) $(eval $(call add_share_file,share/xilinx,techlibs/xilinx/ff_map.v)) $(eval $(call add_share_file,share/xilinx,techlibs/xilinx/lut_map.v)) From 280288a62abb97b4ffe8e3bc56896811f291bab5 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 22 Jul 2019 07:46:06 -0700 Subject: [PATCH 04/94] Update changelog --- CHANGELOG | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index b475ae423..b82a62495 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -14,9 +14,10 @@ Yosys 0.9 .. Yosys 0.9-dev - Added "synth -abc9" (experimental) - Added "script -scriptwire - "synth_xilinx" to now infer wide multiplexers (-widemux to enable) - - Renamed labels/options in synth_ice40 (e.g. map_dram -> map_lutram; -nodram -> -nolutram) - - Renamed labels/options in synth_ecp5 (e.g. map_dram -> map_lutram; -nodram -> -nolutram) - - Renamed labels/options in synth_xilinx (e.g. map_dram -> map_lutram; -nodram -> -nolutram) + - Renamed labels/options in synth_ice40 (e.g. dram -> map_lutram; -nodram -> -nolutram) + - Renamed labels/options in synth_ecp5 (e.g. dram -> map_lutram; -nodram -> -nolutram) + - Renamed labels in synth_intel (e.g. bram -> map_bram) + - Renamed labels/options in synth_xilinx (e.g. dram -> map_lutram; -nodram -> -nolutram) Yosys 0.8 .. Yosys 0.8-dev From 297a9802122817e143b1e4b87fd0d4e357606a72 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 25 Jul 2019 10:44:20 -0700 Subject: [PATCH 05/94] Bump abc to fix &mfs bug --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index d33f27b63..3bc119800 100644 --- a/Makefile +++ b/Makefile @@ -122,7 +122,7 @@ OBJS = kernel/version_$(GIT_REV).o # is just a symlink to your actual ABC working directory, as 'make mrproper' # will remove the 'abc' directory and you do not want to accidentally # delete your work on ABC.. -ABCREV = 62487de +ABCREV = 5776ad0 ABCPULL = 1 ABCURL ?= https://github.com/berkeley-abc/abc ABCMKARGS = CC="$(CXX)" CXX="$(CXX)" ABC_USE_LIBSTDCXX=1 From 07c4a7d4388cdacaa15512dd2f6f0f9e9fcb31f5 Mon Sep 17 00:00:00 2001 From: Bogdan Vukobratovic Date: Fri, 26 Jul 2019 11:36:48 +0200 Subject: [PATCH 06/94] Implement opt_share This pass identifies arithmetic operators that share an operand and whose results are used in mutually exclusive cases controlled by a multiplexer, and merges them together by multiplexing the other operands --- passes/opt/Makefile.inc | 2 +- passes/opt/opt_share.cc | 329 ++++++++++++++++++++++++++++++++ tests/opt/opt_share_cat.v | 15 ++ tests/opt/opt_share_cat.ys | 9 + tests/opt/opt_share_mux_tree.v | 19 ++ tests/opt/opt_share_mux_tree.ys | 10 + 6 files changed, 383 insertions(+), 1 deletion(-) create mode 100644 passes/opt/opt_share.cc create mode 100644 tests/opt/opt_share_cat.v create mode 100644 tests/opt/opt_share_cat.ys create mode 100644 tests/opt/opt_share_mux_tree.v create mode 100644 tests/opt/opt_share_mux_tree.ys diff --git a/passes/opt/Makefile.inc b/passes/opt/Makefile.inc index ea3646330..eb07e9452 100644 --- a/passes/opt/Makefile.inc +++ b/passes/opt/Makefile.inc @@ -4,6 +4,7 @@ OBJS += passes/opt/opt_merge.o OBJS += passes/opt/opt_muxtree.o OBJS += passes/opt/opt_reduce.o OBJS += passes/opt/opt_rmdff.o +OBJS += passes/opt/opt_share.o OBJS += passes/opt/opt_clean.o OBJS += passes/opt/opt_expr.o @@ -16,4 +17,3 @@ OBJS += passes/opt/opt_lut.o OBJS += passes/opt/pmux2shiftx.o OBJS += passes/opt/muxpack.o endif - diff --git a/passes/opt/opt_share.cc b/passes/opt/opt_share.cc new file mode 100644 index 000000000..9f6f59b64 --- /dev/null +++ b/passes/opt/opt_share.cc @@ -0,0 +1,329 @@ +/* + * 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/log.h" +#include "kernel/register.h" +#include "kernel/rtlil.h" +#include "kernel/sigtools.h" +#include + +#include +#include + +USING_YOSYS_NAMESPACE +PRIVATE_NAMESPACE_BEGIN + +SigMap assign_map; + +// Helper class that to track whether a SigSpec is signed and whether it is +// connected to the \\B port of the $sub cell, which makes its sign prefix +// negative. +struct ExtSigSpec { + RTLIL::SigSpec sig; + bool sign; + bool is_signed; + + ExtSigSpec() {} + + ExtSigSpec(RTLIL::SigSpec s, bool sign = false, bool is_signed = false) : sig(s), sign(sign), is_signed(is_signed) {} + + ExtSigSpec(RTLIL::Cell *cell, RTLIL::IdString port_name, SigMap *sigmap) + { + sign = (cell->type == "$sub") && (port_name == "\\B"); + sig = (*sigmap)(cell->getPort(port_name)); + + is_signed = false; + if (cell->hasParam(port_name.str() + "_SIGNED")) { + is_signed = cell->getParam(port_name.str() + "_SIGNED").as_bool(); + } + } + + bool empty() const { return sig.empty(); } + + bool operator<(const ExtSigSpec &other) const + { + if (sig != other.sig) + return sig < other.sig; + + if (sign != other.sign) + return sign < other.sign; + + return is_signed < other.is_signed; + } + + bool operator==(const RTLIL::SigSpec &other) const { return sign ? false : sig == other; } + bool operator==(const ExtSigSpec &other) const { return is_signed == other.is_signed && sign == other.sign && sig == other.sig; } +}; + +void merge_operators(RTLIL::Module *module, RTLIL::Cell *mux, const std::vector &operators, int offset, int width, + const ExtSigSpec &operand) +{ + + std::vector muxed_operands; + int max_width = 0; + for (auto op : operators) { + for (auto &conn : op->connections()) { + if (op->output(conn.first)) + continue; + + if (conn.second != operand.sig) { + auto operand = ExtSigSpec(op, conn.first, &assign_map); + if (operand.sig.size() > max_width) { + max_width = operand.sig.size(); + } + + muxed_operands.push_back(operand); + } + } + } + + for (auto &operand : muxed_operands) { + operand.sig.extend_u0(max_width, operand.is_signed); + } + + auto shared_op = operators[0]; + + for (auto op : operators) { + if (op == shared_op) + continue; + module->remove(op); + } + + RTLIL::SigSpec mux_out = mux->getPort("\\Y"); + + if (muxed_operands[0].sign != muxed_operands[1].sign) { + muxed_operands[1] = ExtSigSpec(module->Neg(NEW_ID, muxed_operands[1].sig, muxed_operands[1].is_signed)); + } + + auto mux_to_oper = module->Mux(NEW_ID, muxed_operands[0].sig, muxed_operands[1].sig, mux->getPort("\\S")); + + shared_op->setPort("\\Y", mux_out.extract(offset, width)); + shared_op->setParam("\\Y_WIDTH", width); + + auto dummy = module->addWire(NEW_ID, width); + + mux_out.replace(offset, dummy); + mux->setPort("\\Y", mux_out); + + if (shared_op->getPort("\\A") == operand.sig) { + shared_op->setPort("\\B", mux_to_oper); + shared_op->setParam("\\B_WIDTH", max_width); + } else { + shared_op->setPort("\\A", mux_to_oper); + shared_op->setParam("\\A_WIDTH", max_width); + } +} + +typedef struct { + RTLIL::Cell *mux; + std::vector operators; + int offset; + int width; + ExtSigSpec shared_operand; +} shared_op_t; + +bool find_op_res_width(int offset, int &width, RTLIL::SigSpec porta, RTLIL::SigSpec portb, + const dict &op_outbit_to_outsig, const dict &op_outbit_user_cnt) +{ + + std::array op_outsigs{op_outbit_to_outsig.at(porta[offset]), op_outbit_to_outsig.at(portb[offset])}; + + width = 0; + bool multi_user = false; + + while (true) { + for (const auto &op_outsig : op_outsigs) + if (op_outbit_user_cnt.at(op_outsig[width]) > 1) + multi_user = true; + + ++offset; + ++width; + + if ((offset >= porta.size()) || (width >= op_outsigs[0].size()) || (width >= op_outsigs[1].size())) + break; + + if ((porta[offset] != op_outsigs[0][width]) || (portb[offset] != op_outsigs[1][width])) + break; + } + + if (multi_user) + return false; + + for (const auto &outsig : op_outsigs) + for (int i = width; i < outsig.size(); i++) + if (op_outbit_user_cnt.count(outsig[i])) + return false; + + return true; +} + +ExtSigSpec find_shared_operand(const std::vector &operators, const std::map> &operand_to_users) +{ + + std::set operators_set(operators.begin(), operators.end()); + ExtSigSpec oper; + + auto op_a = operators[0]; + for (auto &conn : op_a->connections()) { + if (op_a->output(conn.first)) + continue; + + oper = ExtSigSpec(op_a, conn.first, &assign_map); + auto bundle = operand_to_users.at(oper); + + if (std::includes(bundle.begin(), bundle.end(), operators_set.begin(), operators_set.end())) + break; + } + + return oper; +} + +dict find_op_outbit_user_cnt(RTLIL::Module *module, const dict &op_outbit_to_outsig) +{ + dict op_outbit_user_cnt; + + std::function update_op_outbit_user_cnt = [&](SigSpec sig) { + auto outsig = assign_map(sig); + for (auto outbit : outsig) + if (op_outbit_to_outsig.count(outbit)) + op_outbit_user_cnt[outbit]++; + }; + + for (auto cell : module->cells()) + for (auto &conn : cell->connections()) + if (cell->input(conn.first)) + update_op_outbit_user_cnt(conn.second); + + for (auto w : module->wires()) { + if (!w->port_output) + continue; + + update_op_outbit_user_cnt(w); + } + + return op_outbit_user_cnt; +} + +struct OptRmdffPass : public Pass { + OptRmdffPass() : Pass("opt_share", "merge arithmetic operators that share an operand") {} + void help() YS_OVERRIDE + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" opt_share [selection]\n"); + log("\n"); + log("This pass identifies arithmetic operators that share an operand and whose\n"); + log("results are used in mutually exclusive cases controlled by a multiplexer,\n"); + log("and merges them together by multiplexing the other operands.\n"); + log("\n"); + } + void execute(std::vector, RTLIL::Design *design) YS_OVERRIDE + { + + log_header(design, "Executing OPT_SHARE pass.\n"); + + for (auto module : design->selected_modules()) { + assign_map.clear(); + assign_map.set(module); + + std::map> operand_to_users; + dict outsig_to_operator; + dict op_outbit_to_outsig; + bool any_shared_operands = false; + + for (auto cell : module->cells()) { + if (!cell->type.in("$add", "$sub")) + continue; + + for (auto &conn : cell->connections()) { + if (cell->output(conn.first)) { + auto outsig = assign_map(conn.second); + for (auto outbit : outsig) + op_outbit_to_outsig[outbit] = outsig; + + outsig_to_operator[outsig] = cell; + } else { + auto op_insig = ExtSigSpec(cell, conn.first, &assign_map); + operand_to_users[op_insig].insert(cell); + if (operand_to_users[op_insig].size() > 1) + any_shared_operands = true; + } + } + } + + if (!any_shared_operands) + continue; + + // Operator outputs need to be exclusively connected to the $mux inputs in order to be mergeable. Hence we count to + // how many points are operator output bits connected. + dict op_outbit_user_cnt = find_op_outbit_user_cnt(module, op_outbit_to_outsig); + std::vector shared_ops; + for (auto cell : module->cells()) { + if (!cell->type.in("$mux", "$_MUX_")) + continue; + + auto porta = assign_map(cell->getPort("\\A")); + auto portb = assign_map(cell->getPort("\\B")); + + // Look through the bits of the $mux inputs and see which of them are connected to the operator + // results. Operator results can be concatenated with other signals before led to the $mux. + for (int i = 0; i < porta.size(); ++i) { + std::array mux_inbits{porta[i], portb[i]}; + + // Are the results of an $add or $sub operators connected to both of this $mux inputs? + if (!op_outbit_to_outsig.count(mux_inbits[0]) or !op_outbit_to_outsig.count(mux_inbits[1])) + continue; + + std::vector operators; + for (const auto &b : mux_inbits) + operators.push_back(outsig_to_operator.at(op_outbit_to_outsig.at(b))); + + // Do these operators share an operand? + auto shared_operand = find_shared_operand(operators, operand_to_users); + if (shared_operand.empty()) + continue; + + // Some bits of the operator results might be unconnected. Calculate the number of conneted + // bits. + int width; + + if (find_op_res_width(i, width, porta, portb, op_outbit_to_outsig, op_outbit_user_cnt)) + shared_ops.push_back(shared_op_t{cell, operators, i, width, shared_operand}); + + i += width - 1; + } + } + + for (auto &shared : shared_ops) { + log(" Found arithmetic cells that share an operand and can be merged by moving the %s %s in front " + "of " + "them:\n", + log_id(shared.mux->type), log_id(shared.mux)); + for (auto op : shared.operators) + log(" %s\n", log_id(op)); + log("\n"); + + merge_operators(module, shared.mux, shared.operators, shared.offset, shared.width, shared.shared_operand); + } + } + } + +} OptRmdffPass; + +PRIVATE_NAMESPACE_END diff --git a/tests/opt/opt_share_cat.v b/tests/opt/opt_share_cat.v new file mode 100644 index 000000000..c32073360 --- /dev/null +++ b/tests/opt/opt_share_cat.v @@ -0,0 +1,15 @@ +module add_sub( + input [15:0] a, + input [15:0] b, + input [15:0] c, + input [15:0] d, + input sel, + output [63:0] res, + ); + + reg [31: 0] cat1 = {a+b, c+d}; + reg [31: 0] cat2 = {a-b, c-d}; + + assign res = {b, sel ? cat1 : cat2, a}; + +endmodule diff --git a/tests/opt/opt_share_cat.ys b/tests/opt/opt_share_cat.ys new file mode 100644 index 000000000..c3f2f5a2f --- /dev/null +++ b/tests/opt/opt_share_cat.ys @@ -0,0 +1,9 @@ +read_verilog opt_share_cat.v +prep -flatten +opt +pmuxtree +opt_share +opt_clean + +select -assert-count 2 t:$sub +select -assert-count 0 t:$add diff --git a/tests/opt/opt_share_mux_tree.v b/tests/opt/opt_share_mux_tree.v new file mode 100644 index 000000000..807ed2978 --- /dev/null +++ b/tests/opt/opt_share_mux_tree.v @@ -0,0 +1,19 @@ +module add_sub( + input [15:0] a, + input [15:0] b, + input [15:0] c, + input [1:0] sel, + output reg [15:0] res + ); + + + always @* begin + case(sel) + 0: res = a + b; + 1: res = a - b; + 2: res = a + c; + default: res = 16'bx; + endcase + end + +endmodule diff --git a/tests/opt/opt_share_mux_tree.ys b/tests/opt/opt_share_mux_tree.ys new file mode 100644 index 000000000..94d6aa7d2 --- /dev/null +++ b/tests/opt/opt_share_mux_tree.ys @@ -0,0 +1,10 @@ +read_verilog opt_share_mux_tree.v +prep -flatten +opt +pmuxtree +opt_share; +opt_share; +opt_clean + +select -assert-count 1 t:$add +select -assert-count 0 t:$sub From c075486c59155d16ed278922a3752366a95246ff Mon Sep 17 00:00:00 2001 From: Bogdan Vukobratovic Date: Sun, 28 Jul 2019 16:03:54 +0200 Subject: [PATCH 07/94] Reimplement opt_share to work on $alu and $pmux --- passes/opt/opt_share.cc | 322 ++++++++++++------ tests/opt/opt_share_add_sub.v | 10 + tests/opt/opt_share_add_sub.ys | 13 + tests/opt/opt_share_cat.v | 2 +- tests/opt/opt_share_cat.ys | 18 +- tests/opt/opt_share_cat_multiuser.v | 22 ++ tests/opt/opt_share_cat_multiuser.ys | 13 + tests/opt/opt_share_diff_port_widths.v | 21 ++ tests/opt/opt_share_diff_port_widths.ys | 13 + tests/opt/opt_share_extend.v | 19 ++ tests/opt/opt_share_extend.ys | 13 + tests/opt/opt_share_large_pmux_cat.v | 22 ++ tests/opt/opt_share_large_pmux_cat.ys | 13 + .../opt/opt_share_large_pmux_cat_multipart.v | 25 ++ .../opt/opt_share_large_pmux_cat_multipart.ys | 15 + tests/opt/opt_share_large_pmux_multipart.v | 24 ++ tests/opt/opt_share_large_pmux_multipart.ys | 13 + tests/opt/opt_share_large_pmux_part.v | 22 ++ tests/opt/opt_share_large_pmux_part.ys | 13 + tests/opt/opt_share_mux_tree.v | 2 +- tests/opt/opt_share_mux_tree.ys | 19 +- 21 files changed, 521 insertions(+), 113 deletions(-) create mode 100644 tests/opt/opt_share_add_sub.v create mode 100644 tests/opt/opt_share_add_sub.ys create mode 100644 tests/opt/opt_share_cat_multiuser.v create mode 100644 tests/opt/opt_share_cat_multiuser.ys create mode 100644 tests/opt/opt_share_diff_port_widths.v create mode 100644 tests/opt/opt_share_diff_port_widths.ys create mode 100644 tests/opt/opt_share_extend.v create mode 100644 tests/opt/opt_share_extend.ys create mode 100644 tests/opt/opt_share_large_pmux_cat.v create mode 100644 tests/opt/opt_share_large_pmux_cat.ys create mode 100644 tests/opt/opt_share_large_pmux_cat_multipart.v create mode 100644 tests/opt/opt_share_large_pmux_cat_multipart.ys create mode 100644 tests/opt/opt_share_large_pmux_multipart.v create mode 100644 tests/opt/opt_share_large_pmux_multipart.ys create mode 100644 tests/opt/opt_share_large_pmux_part.v create mode 100644 tests/opt/opt_share_large_pmux_part.ys diff --git a/passes/opt/opt_share.cc b/passes/opt/opt_share.cc index 9f6f59b64..e9a2f05f9 100644 --- a/passes/opt/opt_share.cc +++ b/passes/opt/opt_share.cc @@ -31,12 +31,21 @@ PRIVATE_NAMESPACE_BEGIN SigMap assign_map; +struct InPort { + RTLIL::SigSpec sig; + RTLIL::Cell *pmux; + int port_id; + RTLIL::Cell *alu; + + InPort(RTLIL::SigSpec s, RTLIL::Cell *c, int p, RTLIL::Cell *a = NULL) : sig(s), pmux(c), port_id(p), alu(a) {} +}; + // Helper class that to track whether a SigSpec is signed and whether it is // connected to the \\B port of the $sub cell, which makes its sign prefix // negative. struct ExtSigSpec { RTLIL::SigSpec sig; - bool sign; + RTLIL::SigSpec sign; bool is_signed; ExtSigSpec() {} @@ -45,7 +54,7 @@ struct ExtSigSpec { ExtSigSpec(RTLIL::Cell *cell, RTLIL::IdString port_name, SigMap *sigmap) { - sign = (cell->type == "$sub") && (port_name == "\\B"); + sign = (port_name == "\\B") ? cell->getPort("\\BI") : RTLIL::Const(0, 1); sig = (*sigmap)(cell->getPort(port_name)); is_signed = false; @@ -67,23 +76,22 @@ struct ExtSigSpec { return is_signed < other.is_signed; } - bool operator==(const RTLIL::SigSpec &other) const { return sign ? false : sig == other; } + bool operator==(const RTLIL::SigSpec &other) const { return (sign != RTLIL::Const(0, 1)) ? false : sig == other; } bool operator==(const ExtSigSpec &other) const { return is_signed == other.is_signed && sign == other.sign && sig == other.sig; } }; -void merge_operators(RTLIL::Module *module, RTLIL::Cell *mux, const std::vector &operators, int offset, int width, +void merge_operators(RTLIL::Module *module, RTLIL::Cell *mux, const std::vector &ports, int offset, int width, const ExtSigSpec &operand) { std::vector muxed_operands; int max_width = 0; - for (auto op : operators) { - for (auto &conn : op->connections()) { - if (op->output(conn.first)) - continue; + for (const auto& p : ports) { + auto op = p.alu; - if (conn.second != operand.sig) { - auto operand = ExtSigSpec(op, conn.first, &assign_map); + for (RTLIL::IdString port_name : {"\\A", "\\B"}) { + if (op->getPort(port_name) != operand.sig) { + auto operand = ExtSigSpec(op, port_name, &assign_map); if (operand.sig.size() > max_width) { max_width = operand.sig.size(); } @@ -97,30 +105,61 @@ void merge_operators(RTLIL::Module *module, RTLIL::Cell *mux, const std::vector< operand.sig.extend_u0(max_width, operand.is_signed); } - auto shared_op = operators[0]; + auto shared_op = ports[0].alu; - for (auto op : operators) { + for (const auto& p : ports) { + auto op = p.alu; if (op == shared_op) continue; module->remove(op); } - RTLIL::SigSpec mux_out = mux->getPort("\\Y"); - - if (muxed_operands[0].sign != muxed_operands[1].sign) { - muxed_operands[1] = ExtSigSpec(module->Neg(NEW_ID, muxed_operands[1].sig, muxed_operands[1].is_signed)); + for (auto &muxed_op : muxed_operands) { + if (muxed_op.sign != muxed_operands[0].sign) { + muxed_op = ExtSigSpec(module->Neg(NEW_ID, muxed_op.sig, muxed_op.is_signed)); + } } - auto mux_to_oper = module->Mux(NEW_ID, muxed_operands[0].sig, muxed_operands[1].sig, mux->getPort("\\S")); + RTLIL::SigSpec mux_y = mux->getPort("\\Y"); + RTLIL::SigSpec mux_a = mux->getPort("\\A"); + RTLIL::SigSpec mux_b = mux->getPort("\\B"); + RTLIL::SigSpec mux_s = mux->getPort("\\S"); - shared_op->setPort("\\Y", mux_out.extract(offset, width)); + RTLIL::SigSpec alu_x = shared_op->getPort("\\X"); + RTLIL::SigSpec alu_co = shared_op->getPort("\\CO"); + + RTLIL::SigSpec shared_pmux_a = RTLIL::Const(RTLIL::State::Sx, max_width); + RTLIL::SigSpec shared_pmux_b; + RTLIL::SigSpec shared_pmux_s; + + shared_op->setPort("\\Y", shared_op->getPort("\\Y").extract(0, width)); + + if (mux->type == "$pmux") { + shared_pmux_s = RTLIL::SigSpec(); + + for (const auto&p: ports) { + shared_pmux_s.append(mux_s[p.port_id]); + mux_b.replace(p.port_id * mux_a.size() + offset, shared_op->getPort("\\Y")); + } + } else { + shared_pmux_s = RTLIL::SigSpec{mux_s, module->Not(NEW_ID, mux_s)}; + mux_a.replace(offset, shared_op->getPort("\\Y")); + mux_b.replace(offset, shared_op->getPort("\\Y")); + } + + mux->setPort("\\Y", mux_y); + mux->setPort("\\S", mux_s); + mux->setPort("\\B", mux_b); + + for (const auto &op : muxed_operands) + shared_pmux_b.append(op.sig); + + auto mux_to_oper = module->Pmux(NEW_ID, shared_pmux_a, shared_pmux_b, shared_pmux_s); + + shared_op->setPort("\\X", alu_x.extract(0, width)); + shared_op->setPort("\\CO", alu_co.extract(0, width)); shared_op->setParam("\\Y_WIDTH", width); - auto dummy = module->addWire(NEW_ID, width); - - mux_out.replace(offset, dummy); - mux->setPort("\\Y", mux_out); - if (shared_op->getPort("\\A") == operand.sig) { shared_op->setPort("\\B", mux_to_oper); shared_op->setParam("\\B_WIDTH", max_width); @@ -128,81 +167,132 @@ void merge_operators(RTLIL::Module *module, RTLIL::Cell *mux, const std::vector< shared_op->setPort("\\A", mux_to_oper); shared_op->setParam("\\A_WIDTH", max_width); } + } typedef struct { RTLIL::Cell *mux; - std::vector operators; + std::vector ports; int offset; int width; ExtSigSpec shared_operand; } shared_op_t; -bool find_op_res_width(int offset, int &width, RTLIL::SigSpec porta, RTLIL::SigSpec portb, - const dict &op_outbit_to_outsig, const dict &op_outbit_user_cnt) + +template void remove_val(std::vector &v, const std::vector &vals) +{ + auto val_iter = vals.rbegin(); + for (auto i = v.rbegin(); i != v.rend(); ++i) + if ((val_iter != vals.rend()) && (*i == *val_iter)) { + v.erase(i.base() - 1); + ++val_iter; + } +} + +bool find_op_res_width(int offset, int &width, std::vector& ports, const dict &op_outbit_to_outsig) { - std::array op_outsigs{op_outbit_to_outsig.at(porta[offset]), op_outbit_to_outsig.at(portb[offset])}; + std::vector op_outsigs; + dict> op_outsig_span; + + std::transform(ports.begin(), ports.end(), std::back_inserter(op_outsigs), [&](InPort *p) { return op_outbit_to_outsig.at(p->sig[offset]); }); + + std::vector finished(ports.size(), false); width = 0; - bool multi_user = false; - while (true) { - for (const auto &op_outsig : op_outsigs) - if (op_outbit_user_cnt.at(op_outsig[width]) > 1) - multi_user = true; + std::function all_finished = [&] { return std::find(std::begin(finished), std::end(finished), false) == end(finished);}; + while (!all_finished()) + { ++offset; ++width; - if ((offset >= porta.size()) || (width >= op_outsigs[0].size()) || (width >= op_outsigs[1].size())) - break; + if (offset >= ports[0]->sig.size()) { + for (size_t i = 0; i < op_outsigs.size(); ++i) { + if (finished[i]) + continue; + + op_outsig_span[width].insert(ports[i]); + finished[i] = true; + } - if ((porta[offset] != op_outsigs[0][width]) || (portb[offset] != op_outsigs[1][width])) break; + } + + for (size_t i = 0; i < op_outsigs.size(); ++i) { + if (finished[i]) + continue; + + if ((width >= op_outsigs[i].size()) || (ports[i]->sig[offset] != op_outsigs[i][width])) { + op_outsig_span[width].insert(ports[i]); + finished[i] = true; + } + } } - if (multi_user) - return false; + for (auto w: op_outsig_span) { + if (w.second.size() > 1) { + width = w.first; - for (const auto &outsig : op_outsigs) - for (int i = width; i < outsig.size(); i++) - if (op_outbit_user_cnt.count(outsig[i])) - return false; + ports.erase(std::remove_if(ports.begin(), ports.end(), [&](InPort *p) { return !w.second.count(p); }), ports.end()); - return true; + return true; + } + } + + return false; } -ExtSigSpec find_shared_operand(const std::vector &operators, const std::map> &operand_to_users) +ExtSigSpec find_shared_operand(InPort* seed, std::vector &ports, const std::map> &operand_to_users) { + std::set alus_using_operand; + std::set alus_set; + for(const auto& p: ports) + alus_set.insert(p->alu); - std::set operators_set(operators.begin(), operators.end()); ExtSigSpec oper; - auto op_a = operators[0]; - for (auto &conn : op_a->connections()) { - if (op_a->output(conn.first)) + auto op_a = seed->alu; + + for (RTLIL::IdString port_name : {"\\A", "\\B"}) { + oper = ExtSigSpec(op_a, port_name, &assign_map); + auto operand_users = operand_to_users.at(oper); + + if (operand_users.size() == 1) continue; - oper = ExtSigSpec(op_a, conn.first, &assign_map); - auto bundle = operand_to_users.at(oper); + alus_using_operand.clear(); + std::set_intersection(operand_users.begin(), operand_users.end(), alus_set.begin(), alus_set.end(), + std::inserter(alus_using_operand, alus_using_operand.begin())); - if (std::includes(bundle.begin(), bundle.end(), operators_set.begin(), operators_set.end())) - break; + if (alus_using_operand.size() > 1) { + ports.erase(std::remove_if(ports.begin(), ports.end(), [&](InPort *p) { return !alus_using_operand.count(p->alu); }), + ports.end()); + return oper; + } } - return oper; + return ExtSigSpec(); } -dict find_op_outbit_user_cnt(RTLIL::Module *module, const dict &op_outbit_to_outsig) +void remove_multi_user_outbits(RTLIL::Module *module, dict &op_outbit_to_outsig) { dict op_outbit_user_cnt; std::function update_op_outbit_user_cnt = [&](SigSpec sig) { auto outsig = assign_map(sig); - for (auto outbit : outsig) - if (op_outbit_to_outsig.count(outbit)) - op_outbit_user_cnt[outbit]++; + for (auto outbit : outsig) { + if (!op_outbit_to_outsig.count(outbit)) + continue; + + if (++op_outbit_user_cnt[outbit] > 1) { + auto alu_outsig = op_outbit_to_outsig.at(outbit); + + for (auto outbit : alu_outsig) + op_outbit_to_outsig.erase(outbit); + } + } }; for (auto cell : module->cells()) @@ -216,8 +306,6 @@ dict find_op_outbit_user_cnt(RTLIL::Module *module, const di update_op_outbit_user_cnt(w); } - - return op_outbit_user_cnt; } struct OptRmdffPass : public Pass { @@ -246,24 +334,31 @@ struct OptRmdffPass : public Pass { dict outsig_to_operator; dict op_outbit_to_outsig; bool any_shared_operands = false; + std::vector op_insigs; for (auto cell : module->cells()) { - if (!cell->type.in("$add", "$sub")) + if (!cell->type.in("$alu")) continue; - for (auto &conn : cell->connections()) { - if (cell->output(conn.first)) { - auto outsig = assign_map(conn.second); - for (auto outbit : outsig) - op_outbit_to_outsig[outbit] = outsig; + RTLIL::SigSpec sig_bi = cell->getPort("\\BI"); + RTLIL::SigSpec sig_ci = cell->getPort("\\CI"); - outsig_to_operator[outsig] = cell; - } else { - auto op_insig = ExtSigSpec(cell, conn.first, &assign_map); - operand_to_users[op_insig].insert(cell); - if (operand_to_users[op_insig].size() > 1) - any_shared_operands = true; - } + if ((!sig_bi.is_fully_const()) || (!sig_ci.is_fully_const()) || (sig_bi != sig_ci)) + continue; + + RTLIL::SigSpec sig_y = cell->getPort("\\A"); + + auto outsig = assign_map(cell->getPort("\\Y")); + outsig_to_operator[outsig] = cell; + for (auto outbit : outsig) + op_outbit_to_outsig[outbit] = outsig; + + for (RTLIL::IdString port_name : {"\\A", "\\B"}) { + auto op_insig = ExtSigSpec(cell, port_name, &assign_map); + op_insigs.push_back(op_insig); + operand_to_users[op_insig].insert(cell); + if (operand_to_users[op_insig].size() > 1) + any_shared_operands = true; } } @@ -272,42 +367,77 @@ struct OptRmdffPass : public Pass { // Operator outputs need to be exclusively connected to the $mux inputs in order to be mergeable. Hence we count to // how many points are operator output bits connected. - dict op_outbit_user_cnt = find_op_outbit_user_cnt(module, op_outbit_to_outsig); + remove_multi_user_outbits(module, op_outbit_to_outsig); + std::vector shared_ops; for (auto cell : module->cells()) { - if (!cell->type.in("$mux", "$_MUX_")) + if (!cell->type.in("$mux", "$_MUX_", "$pmux")) continue; - auto porta = assign_map(cell->getPort("\\A")); - auto portb = assign_map(cell->getPort("\\B")); + RTLIL::SigSpec sig_a = cell->getPort("\\A"); + RTLIL::SigSpec sig_b = cell->getPort("\\B"); + RTLIL::SigSpec sig_s = cell->getPort("\\S"); + + std::vector ports; + + if (cell->type.in("$mux", "$_MUX_")) { + ports.push_back(InPort(assign_map(sig_a), cell, 0)); + ports.push_back(InPort(assign_map(sig_b), cell, 1)); + } else { + RTLIL::SigSpec sig_s = cell->getPort("\\S"); + for (int i = 0; i < sig_s.size(); i++) { + auto inp = sig_b.extract(i * sig_a.size(), sig_a.size()); + ports.push_back(InPort(assign_map(inp), cell, i)); + } + } // Look through the bits of the $mux inputs and see which of them are connected to the operator // results. Operator results can be concatenated with other signals before led to the $mux. - for (int i = 0; i < porta.size(); ++i) { - std::array mux_inbits{porta[i], portb[i]}; + for (int i = 0; i < sig_a.size(); ++i) { + std::vector alu_ports; + for (auto& p: ports) + if (op_outbit_to_outsig.count(p.sig[i])) { + p.alu = outsig_to_operator.at(op_outbit_to_outsig.at(p.sig[i])); + alu_ports.push_back(&p); + } - // Are the results of an $add or $sub operators connected to both of this $mux inputs? - if (!op_outbit_to_outsig.count(mux_inbits[0]) or !op_outbit_to_outsig.count(mux_inbits[1])) - continue; + int alu_port_width = 0; - std::vector operators; - for (const auto &b : mux_inbits) - operators.push_back(outsig_to_operator.at(op_outbit_to_outsig.at(b))); + while (alu_ports.size() > 1) { + std::vector shared_ports(alu_ports); - // Do these operators share an operand? - auto shared_operand = find_shared_operand(operators, operand_to_users); - if (shared_operand.empty()) - continue; + auto seed = alu_ports[0]; + alu_ports.erase(alu_ports.begin()); - // Some bits of the operator results might be unconnected. Calculate the number of conneted - // bits. - int width; + // Find ports whose $alu-s share an operand with $alu connected to the seed port + auto shared_operand = find_shared_operand(seed, shared_ports, operand_to_users); - if (find_op_res_width(i, width, porta, portb, op_outbit_to_outsig, op_outbit_user_cnt)) - shared_ops.push_back(shared_op_t{cell, operators, i, width, shared_operand}); + if (shared_operand.empty()) + continue; - i += width - 1; + // Some bits of the operator results might be unconnected. Calculate the number of conneted + // bits. + if (!find_op_res_width(i, alu_port_width, shared_ports, op_outbit_to_outsig)) + break; + + if (shared_ports.size() < 2) + break; + + // Remember the combination for the merger + std::vector shared_p; + for (auto p: shared_ports) + shared_p.push_back(*p); + + shared_ops.push_back(shared_op_t{cell, shared_p, i, alu_port_width, shared_operand}); + + // Remove merged ports from the list and try to find other mergers for the mux + remove_val(alu_ports, shared_ports); + } + + if (alu_port_width) + i += alu_port_width - 1; } + } for (auto &shared : shared_ops) { @@ -315,11 +445,11 @@ struct OptRmdffPass : public Pass { "of " "them:\n", log_id(shared.mux->type), log_id(shared.mux)); - for (auto op : shared.operators) - log(" %s\n", log_id(op)); + for (const auto& op : shared.ports) + log(" %s\n", log_id(op.alu)); log("\n"); - merge_operators(module, shared.mux, shared.operators, shared.offset, shared.width, shared.shared_operand); + merge_operators(module, shared.mux, shared.ports, shared.offset, shared.width, shared.shared_operand); } } } diff --git a/tests/opt/opt_share_add_sub.v b/tests/opt/opt_share_add_sub.v new file mode 100644 index 000000000..30e093a39 --- /dev/null +++ b/tests/opt/opt_share_add_sub.v @@ -0,0 +1,10 @@ +module opt_share_test( + input [15:0] a, + input [15:0] b, + input sel, + output [15:0] res, + ); + + assign res = {sel ? a + b : a - b}; + +endmodule diff --git a/tests/opt/opt_share_add_sub.ys b/tests/opt/opt_share_add_sub.ys new file mode 100644 index 000000000..4a5406791 --- /dev/null +++ b/tests/opt/opt_share_add_sub.ys @@ -0,0 +1,13 @@ +read_verilog opt_share_add_sub.v +proc;; +copy opt_share_test merged + +alumacc merged +opt merged +opt_share merged +opt_clean merged + +miter -equiv -flatten -ignore_gold_x -make_outputs -make_outcmp opt_share_test merged miter +sat -set-def-inputs -verify -prove trigger 0 -show-inputs -show-outputs miter + +select -assert-count 1 -module merged t:$alu diff --git a/tests/opt/opt_share_cat.v b/tests/opt/opt_share_cat.v index c32073360..605dcfe59 100644 --- a/tests/opt/opt_share_cat.v +++ b/tests/opt/opt_share_cat.v @@ -1,4 +1,4 @@ -module add_sub( +module opt_share_test( input [15:0] a, input [15:0] b, input [15:0] c, diff --git a/tests/opt/opt_share_cat.ys b/tests/opt/opt_share_cat.ys index c3f2f5a2f..7de69bfde 100644 --- a/tests/opt/opt_share_cat.ys +++ b/tests/opt/opt_share_cat.ys @@ -1,9 +1,13 @@ read_verilog opt_share_cat.v -prep -flatten -opt -pmuxtree -opt_share -opt_clean +proc;; +copy opt_share_test merged -select -assert-count 2 t:$sub -select -assert-count 0 t:$add +alumacc merged +opt merged +opt_share merged +opt_clean merged + +miter -equiv -flatten -ignore_gold_x -make_outputs -make_outcmp opt_share_test merged miter +sat -set-def-inputs -verify -prove trigger 0 -show-inputs -show-outputs miter + +select -assert-count 2 -module merged t:$alu diff --git a/tests/opt/opt_share_cat_multiuser.v b/tests/opt/opt_share_cat_multiuser.v new file mode 100644 index 000000000..9ac0ceec8 --- /dev/null +++ b/tests/opt/opt_share_cat_multiuser.v @@ -0,0 +1,22 @@ +module opt_share_test( + input [15:0] a, + input [15:0] b, + input [15:0] c, + input [15:0] d, + input sel, + output reg [47:0] res, + ); + + wire [15:0] add_res = a+b; + wire [15:0] sub_res = a-b; + wire [31: 0] cat1 = {add_res, c+d}; + wire [31: 0] cat2 = {sub_res, c-d}; + + always @* begin + case(sel) + 0: res = {cat1, add_res}; + 1: res = {cat2, add_res}; + endcase + end + +endmodule diff --git a/tests/opt/opt_share_cat_multiuser.ys b/tests/opt/opt_share_cat_multiuser.ys new file mode 100644 index 000000000..6a82fbd79 --- /dev/null +++ b/tests/opt/opt_share_cat_multiuser.ys @@ -0,0 +1,13 @@ +read_verilog opt_share_cat_multiuser.v +proc;; +copy opt_share_test merged + +alumacc merged +opt merged +opt_share merged +opt_clean merged + +miter -equiv -flatten -ignore_gold_x -make_outputs -make_outcmp opt_share_test merged miter +sat -set-def-inputs -verify -prove trigger 0 -show-inputs -show-outputs miter + +select -assert-count 3 -module merged t:$alu diff --git a/tests/opt/opt_share_diff_port_widths.v b/tests/opt/opt_share_diff_port_widths.v new file mode 100644 index 000000000..5e2971e30 --- /dev/null +++ b/tests/opt/opt_share_diff_port_widths.v @@ -0,0 +1,21 @@ +module opt_share_test( + input [15:0] a, + input [15:0] b, + input [15:0] c, + input [1:0] sel, + output reg [15:0] res + ); + + wire [15:0] add0_res = a+b; + wire [15:0] add1_res = a+c; + + always @* begin + case(sel) + 0: res = add0_res[10:0]; + 1: res = add1_res[10:0]; + 2: res = a - b; + default: res = 32'bx; + endcase + end + +endmodule diff --git a/tests/opt/opt_share_diff_port_widths.ys b/tests/opt/opt_share_diff_port_widths.ys new file mode 100644 index 000000000..ec5e9f7b0 --- /dev/null +++ b/tests/opt/opt_share_diff_port_widths.ys @@ -0,0 +1,13 @@ +read_verilog opt_share_diff_port_widths.v +proc;; +copy opt_share_test merged + +alumacc merged +opt merged +opt_share merged +opt_clean merged + +miter -equiv -flatten -ignore_gold_x -make_outputs -make_outcmp opt_share_test merged miter +sat -set-def-inputs -verify -prove trigger 0 -show-inputs -show-outputs miter + +select -assert-count 2 -module merged t:$alu diff --git a/tests/opt/opt_share_extend.v b/tests/opt/opt_share_extend.v new file mode 100644 index 000000000..5ed6bde6f --- /dev/null +++ b/tests/opt/opt_share_extend.v @@ -0,0 +1,19 @@ +module opt_share_test( + input signed [7:0] a, + input signed [10:0] b, + input signed [15:0] c, + input [1:0] sel, + output reg signed [15:0] res + ); + + + always @* begin + case(sel) + 0: res = a + b; + 1: res = a - b; + 2: res = a + c; + default: res = 16'bx; + endcase + end + +endmodule diff --git a/tests/opt/opt_share_extend.ys b/tests/opt/opt_share_extend.ys new file mode 100644 index 000000000..c553ee0fb --- /dev/null +++ b/tests/opt/opt_share_extend.ys @@ -0,0 +1,13 @@ +read_verilog opt_share_extend.v +proc;; +copy opt_share_test merged + +alumacc merged +opt merged +opt_share merged +opt_clean merged + +miter -equiv -flatten -ignore_gold_x -make_outputs -make_outcmp opt_share_test merged miter +sat -set-def-inputs -verify -prove trigger 0 -show-inputs -show-outputs miter + +select -assert-count 1 -module merged t:$alu diff --git a/tests/opt/opt_share_large_pmux_cat.v b/tests/opt/opt_share_large_pmux_cat.v new file mode 100644 index 000000000..6208c796b --- /dev/null +++ b/tests/opt/opt_share_large_pmux_cat.v @@ -0,0 +1,22 @@ +module opt_share_test( + input [15:0] a, + input [15:0] b, + input [15:0] c, + input [2:0] sel, + output reg [31:0] res + ); + + + always @* begin + case(sel) + 0: res = {a + b, a}; + 1: res = {a - b, b}; + 2: res = {a + c, c}; + 3: res = {a - c, a}; + 4: res = {b, b}; + 5: res = {c, c}; + default: res = 32'bx; + endcase + end + +endmodule diff --git a/tests/opt/opt_share_large_pmux_cat.ys b/tests/opt/opt_share_large_pmux_cat.ys new file mode 100644 index 000000000..4186ca52e --- /dev/null +++ b/tests/opt/opt_share_large_pmux_cat.ys @@ -0,0 +1,13 @@ +read_verilog opt_share_large_pmux_cat.v +proc;; +copy opt_share_test merged + +alumacc merged +opt merged +opt_share merged +opt_clean merged + +miter -equiv -flatten -ignore_gold_x -make_outputs -make_outcmp opt_share_test merged miter +sat -set-def-inputs -verify -prove trigger 0 -show-inputs -show-outputs miter + +select -assert-count 1 -module merged t:$alu diff --git a/tests/opt/opt_share_large_pmux_cat_multipart.v b/tests/opt/opt_share_large_pmux_cat_multipart.v new file mode 100644 index 000000000..f97971bf6 --- /dev/null +++ b/tests/opt/opt_share_large_pmux_cat_multipart.v @@ -0,0 +1,25 @@ +module opt_share_test( + input [15:0] a, + input [15:0] b, + input [15:0] c, + input [15:0] d, + input [2:0] sel, + output reg [31:0] res + ); + + wire [15:0] add0_res = a+d; + + always @* begin + case(sel) + 0: res = {add0_res, a}; + 1: res = {a - b, add0_res[7], 15'b0}; + 2: res = {b-a, b}; + 3: res = {d, b - c}; + 4: res = {d, b - a}; + 5: res = {c, d}; + 6: res = {a - c, b-d}; + default: res = 32'bx; + endcase + end + +endmodule diff --git a/tests/opt/opt_share_large_pmux_cat_multipart.ys b/tests/opt/opt_share_large_pmux_cat_multipart.ys new file mode 100644 index 000000000..54d200dc7 --- /dev/null +++ b/tests/opt/opt_share_large_pmux_cat_multipart.ys @@ -0,0 +1,15 @@ +read_verilog opt_share_large_pmux_cat_multipart.v +proc;; +copy opt_share_test merged + +alumacc merged +opt merged + +opt_share merged +opt_clean merged +opt -full + +miter -equiv -flatten -ignore_gold_x -make_outputs -make_outcmp opt_share_test merged miter +sat -set-def-inputs -verify -prove trigger 0 -show-inputs -show-outputs miter + +select -assert-count 4 -module merged t:$alu diff --git a/tests/opt/opt_share_large_pmux_multipart.v b/tests/opt/opt_share_large_pmux_multipart.v new file mode 100644 index 000000000..e7ba318ef --- /dev/null +++ b/tests/opt/opt_share_large_pmux_multipart.v @@ -0,0 +1,24 @@ +module opt_share_test( + input [15:0] a, + input [15:0] b, + input [15:0] c, + input [15:0] d, + input [2:0] sel, + output reg [15:0] res + ); + + + always @* begin + case(sel) + 0: res = a + d; + 1: res = a - b; + 2: res = b; + 3: res = b - c; + 4: res = b - a; + 5: res = c; + 6: res = a - c; + default: res = 16'bx; + endcase + end + +endmodule diff --git a/tests/opt/opt_share_large_pmux_multipart.ys b/tests/opt/opt_share_large_pmux_multipart.ys new file mode 100644 index 000000000..11182df1a --- /dev/null +++ b/tests/opt/opt_share_large_pmux_multipart.ys @@ -0,0 +1,13 @@ +read_verilog opt_share_large_pmux_multipart.v +proc;; +copy opt_share_test merged + +alumacc merged +opt merged +opt_share merged +opt_clean merged + +miter -equiv -flatten -ignore_gold_x -make_outputs -make_outcmp opt_share_test merged miter +sat -set-def-inputs -verify -prove trigger 0 -show-inputs -show-outputs miter + +select -assert-count 2 -module merged t:$alu diff --git a/tests/opt/opt_share_large_pmux_part.v b/tests/opt/opt_share_large_pmux_part.v new file mode 100644 index 000000000..138be0cd6 --- /dev/null +++ b/tests/opt/opt_share_large_pmux_part.v @@ -0,0 +1,22 @@ +module opt_share_test( + input [15:0] a, + input [15:0] b, + input [15:0] c, + input [2:0] sel, + output reg [15:0] res + ); + + + always @* begin + case(sel) + 0: res = a + b; + 1: res = a - b; + 2: res = a + c; + 3: res = a - c; + 4: res = b; + 5: res = c; + default: res = 16'bx; + endcase + end + +endmodule diff --git a/tests/opt/opt_share_large_pmux_part.ys b/tests/opt/opt_share_large_pmux_part.ys new file mode 100644 index 000000000..6b594a3d6 --- /dev/null +++ b/tests/opt/opt_share_large_pmux_part.ys @@ -0,0 +1,13 @@ +read_verilog opt_share_large_pmux_part.v +proc;; +copy opt_share_test merged + +alumacc merged +opt merged +opt_share merged +opt_clean merged + +miter -equiv -flatten -ignore_gold_x -make_outputs -make_outcmp opt_share_test merged miter +sat -set-def-inputs -verify -prove trigger 0 -show-inputs -show-outputs miter + +select -assert-count 1 -module merged t:$alu diff --git a/tests/opt/opt_share_mux_tree.v b/tests/opt/opt_share_mux_tree.v index 807ed2978..c90826204 100644 --- a/tests/opt/opt_share_mux_tree.v +++ b/tests/opt/opt_share_mux_tree.v @@ -1,4 +1,4 @@ -module add_sub( +module opt_share_test( input [15:0] a, input [15:0] b, input [15:0] c, diff --git a/tests/opt/opt_share_mux_tree.ys b/tests/opt/opt_share_mux_tree.ys index 94d6aa7d2..58473039f 100644 --- a/tests/opt/opt_share_mux_tree.ys +++ b/tests/opt/opt_share_mux_tree.ys @@ -1,10 +1,13 @@ read_verilog opt_share_mux_tree.v -prep -flatten -opt -pmuxtree -opt_share; -opt_share; -opt_clean +proc;; +copy opt_share_test merged -select -assert-count 1 t:$add -select -assert-count 0 t:$sub +alumacc merged +opt merged +opt_share merged +opt_clean merged + +miter -equiv -flatten -ignore_gold_x -make_outputs -make_outcmp opt_share_test merged miter +sat -set-def-inputs -verify -prove trigger 0 -show-inputs -show-outputs miter + +select -assert-count 1 -module merged t:$alu From 280c4e7794543e99244aafffc62a2dd4454bcb06 Mon Sep 17 00:00:00 2001 From: Bogdan Vukobratovic Date: Sat, 3 Aug 2019 12:28:46 +0200 Subject: [PATCH 08/94] Fix spacing in opt_share tests, change wording in opt_share help --- passes/opt/opt_share.cc | 16 +++++--- tests/opt/opt_share_add_sub.v | 12 +++--- tests/opt/opt_share_cat.v | 20 +++++----- tests/opt/opt_share_cat_multiuser.v | 34 ++++++++-------- tests/opt/opt_share_diff_port_widths.v | 32 +++++++-------- tests/opt/opt_share_extend.v | 29 +++++++------- tests/opt/opt_share_large_pmux_cat.v | 35 ++++++++-------- .../opt/opt_share_large_pmux_cat_multipart.v | 40 +++++++++---------- tests/opt/opt_share_large_pmux_multipart.v | 39 +++++++++--------- tests/opt/opt_share_large_pmux_part.v | 35 ++++++++-------- tests/opt/opt_share_mux_tree.v | 29 +++++++------- 11 files changed, 160 insertions(+), 161 deletions(-) diff --git a/passes/opt/opt_share.cc b/passes/opt/opt_share.cc index e9a2f05f9..25b07cbbd 100644 --- a/passes/opt/opt_share.cc +++ b/passes/opt/opt_share.cc @@ -2,6 +2,7 @@ * yosys -- Yosys Open SYnthesis Suite * * Copyright (C) 2012 Clifford Wolf + * 2019 Bogdan Vukobratovic * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -308,17 +309,20 @@ void remove_multi_user_outbits(RTLIL::Module *module, dict, RTLIL::Design *design) YS_OVERRIDE @@ -454,6 +458,6 @@ struct OptRmdffPass : public Pass { } } -} OptRmdffPass; +} OptSharePass; PRIVATE_NAMESPACE_END diff --git a/tests/opt/opt_share_add_sub.v b/tests/opt/opt_share_add_sub.v index 30e093a39..1c2665cf0 100644 --- a/tests/opt/opt_share_add_sub.v +++ b/tests/opt/opt_share_add_sub.v @@ -1,10 +1,10 @@ module opt_share_test( - input [15:0] a, - input [15:0] b, - input sel, - output [15:0] res, - ); + input [15:0] a, + input [15:0] b, + input sel, + output [15:0] res, + ); - assign res = {sel ? a + b : a - b}; + assign res = {sel ? a + b : a - b}; endmodule diff --git a/tests/opt/opt_share_cat.v b/tests/opt/opt_share_cat.v index 605dcfe59..7b6f626b9 100644 --- a/tests/opt/opt_share_cat.v +++ b/tests/opt/opt_share_cat.v @@ -1,15 +1,15 @@ module opt_share_test( - input [15:0] a, - input [15:0] b, - input [15:0] c, - input [15:0] d, - input sel, - output [63:0] res, - ); + input [15:0] a, + input [15:0] b, + input [15:0] c, + input [15:0] d, + input sel, + output [63:0] res, + ); - reg [31: 0] cat1 = {a+b, c+d}; - reg [31: 0] cat2 = {a-b, c-d}; + reg [31: 0] cat1 = {a+b, c+d}; + reg [31: 0] cat2 = {a-b, c-d}; - assign res = {b, sel ? cat1 : cat2, a}; + assign res = {b, sel ? cat1 : cat2, a}; endmodule diff --git a/tests/opt/opt_share_cat_multiuser.v b/tests/opt/opt_share_cat_multiuser.v index 9ac0ceec8..f77f912e9 100644 --- a/tests/opt/opt_share_cat_multiuser.v +++ b/tests/opt/opt_share_cat_multiuser.v @@ -1,22 +1,22 @@ module opt_share_test( - input [15:0] a, - input [15:0] b, - input [15:0] c, - input [15:0] d, - input sel, - output reg [47:0] res, - ); + input [15:0] a, + input [15:0] b, + input [15:0] c, + input [15:0] d, + input sel, + output reg [47:0] res, + ); - wire [15:0] add_res = a+b; - wire [15:0] sub_res = a-b; - wire [31: 0] cat1 = {add_res, c+d}; - wire [31: 0] cat2 = {sub_res, c-d}; + wire [15:0] add_res = a+b; + wire [15:0] sub_res = a-b; + wire [31: 0] cat1 = {add_res, c+d}; + wire [31: 0] cat2 = {sub_res, c-d}; - always @* begin - case(sel) - 0: res = {cat1, add_res}; - 1: res = {cat2, add_res}; - endcase - end + always @* begin + case(sel) + 0: res = {cat1, add_res}; + 1: res = {cat2, add_res}; + endcase + end endmodule diff --git a/tests/opt/opt_share_diff_port_widths.v b/tests/opt/opt_share_diff_port_widths.v index 5e2971e30..e57ab7a83 100644 --- a/tests/opt/opt_share_diff_port_widths.v +++ b/tests/opt/opt_share_diff_port_widths.v @@ -1,21 +1,21 @@ module opt_share_test( - input [15:0] a, - input [15:0] b, - input [15:0] c, - input [1:0] sel, - output reg [15:0] res - ); + input [15:0] a, + input [15:0] b, + input [15:0] c, + input [1:0] sel, + output reg [15:0] res + ); - wire [15:0] add0_res = a+b; - wire [15:0] add1_res = a+c; + wire [15:0] add0_res = a+b; + wire [15:0] add1_res = a+c; - always @* begin - case(sel) - 0: res = add0_res[10:0]; - 1: res = add1_res[10:0]; - 2: res = a - b; - default: res = 32'bx; - endcase - end + always @* begin + case(sel) + 0: res = add0_res[10:0]; + 1: res = add1_res[10:0]; + 2: res = a - b; + default: res = 32'bx; + endcase + end endmodule diff --git a/tests/opt/opt_share_extend.v b/tests/opt/opt_share_extend.v index 5ed6bde6f..60ce1a2f3 100644 --- a/tests/opt/opt_share_extend.v +++ b/tests/opt/opt_share_extend.v @@ -1,19 +1,18 @@ module opt_share_test( - input signed [7:0] a, - input signed [10:0] b, - input signed [15:0] c, - input [1:0] sel, - output reg signed [15:0] res - ); + input signed [7:0] a, + input signed [10:0] b, + input signed [15:0] c, + input [1:0] sel, + output reg signed [15:0] res + ); - - always @* begin - case(sel) - 0: res = a + b; - 1: res = a - b; - 2: res = a + c; - default: res = 16'bx; - endcase - end + always @* begin + case(sel) + 0: res = a + b; + 1: res = a - b; + 2: res = a + c; + default: res = 16'bx; + endcase + end endmodule diff --git a/tests/opt/opt_share_large_pmux_cat.v b/tests/opt/opt_share_large_pmux_cat.v index 6208c796b..0667e6080 100644 --- a/tests/opt/opt_share_large_pmux_cat.v +++ b/tests/opt/opt_share_large_pmux_cat.v @@ -1,22 +1,21 @@ module opt_share_test( - input [15:0] a, - input [15:0] b, - input [15:0] c, - input [2:0] sel, - output reg [31:0] res - ); + input [15:0] a, + input [15:0] b, + input [15:0] c, + input [2:0] sel, + output reg [31:0] res + ); - - always @* begin - case(sel) - 0: res = {a + b, a}; - 1: res = {a - b, b}; - 2: res = {a + c, c}; - 3: res = {a - c, a}; - 4: res = {b, b}; - 5: res = {c, c}; - default: res = 32'bx; - endcase - end + always @* begin + case(sel) + 0: res = {a + b, a}; + 1: res = {a - b, b}; + 2: res = {a + c, c}; + 3: res = {a - c, a}; + 4: res = {b, b}; + 5: res = {c, c}; + default: res = 32'bx; + endcase + end endmodule diff --git a/tests/opt/opt_share_large_pmux_cat_multipart.v b/tests/opt/opt_share_large_pmux_cat_multipart.v index f97971bf6..f26505d3a 100644 --- a/tests/opt/opt_share_large_pmux_cat_multipart.v +++ b/tests/opt/opt_share_large_pmux_cat_multipart.v @@ -1,25 +1,25 @@ module opt_share_test( - input [15:0] a, - input [15:0] b, - input [15:0] c, - input [15:0] d, - input [2:0] sel, - output reg [31:0] res - ); + input [15:0] a, + input [15:0] b, + input [15:0] c, + input [15:0] d, + input [2:0] sel, + output reg [31:0] res + ); - wire [15:0] add0_res = a+d; + wire [15:0] add0_res = a+d; - always @* begin - case(sel) - 0: res = {add0_res, a}; - 1: res = {a - b, add0_res[7], 15'b0}; - 2: res = {b-a, b}; - 3: res = {d, b - c}; - 4: res = {d, b - a}; - 5: res = {c, d}; - 6: res = {a - c, b-d}; - default: res = 32'bx; - endcase - end + always @* begin + case(sel) + 0: res = {add0_res, a}; + 1: res = {a - b, add0_res[7], 15'b0}; + 2: res = {b-a, b}; + 3: res = {d, b - c}; + 4: res = {d, b - a}; + 5: res = {c, d}; + 6: res = {a - c, b-d}; + default: res = 32'bx; + endcase + end endmodule diff --git a/tests/opt/opt_share_large_pmux_multipart.v b/tests/opt/opt_share_large_pmux_multipart.v index e7ba318ef..1c460292f 100644 --- a/tests/opt/opt_share_large_pmux_multipart.v +++ b/tests/opt/opt_share_large_pmux_multipart.v @@ -1,24 +1,23 @@ module opt_share_test( - input [15:0] a, - input [15:0] b, - input [15:0] c, - input [15:0] d, - input [2:0] sel, - output reg [15:0] res - ); + input [15:0] a, + input [15:0] b, + input [15:0] c, + input [15:0] d, + input [2:0] sel, + output reg [15:0] res + ); - - always @* begin - case(sel) - 0: res = a + d; - 1: res = a - b; - 2: res = b; - 3: res = b - c; - 4: res = b - a; - 5: res = c; - 6: res = a - c; - default: res = 16'bx; - endcase - end + always @* begin + case(sel) + 0: res = a + d; + 1: res = a - b; + 2: res = b; + 3: res = b - c; + 4: res = b - a; + 5: res = c; + 6: res = a - c; + default: res = 16'bx; + endcase + end endmodule diff --git a/tests/opt/opt_share_large_pmux_part.v b/tests/opt/opt_share_large_pmux_part.v index 138be0cd6..f9dd17446 100644 --- a/tests/opt/opt_share_large_pmux_part.v +++ b/tests/opt/opt_share_large_pmux_part.v @@ -1,22 +1,21 @@ module opt_share_test( - input [15:0] a, - input [15:0] b, - input [15:0] c, - input [2:0] sel, - output reg [15:0] res - ); + input [15:0] a, + input [15:0] b, + input [15:0] c, + input [2:0] sel, + output reg [15:0] res + ); - - always @* begin - case(sel) - 0: res = a + b; - 1: res = a - b; - 2: res = a + c; - 3: res = a - c; - 4: res = b; - 5: res = c; - default: res = 16'bx; - endcase - end + always @* begin + case(sel) + 0: res = a + b; + 1: res = a - b; + 2: res = a + c; + 3: res = a - c; + 4: res = b; + 5: res = c; + default: res = 16'bx; + endcase + end endmodule diff --git a/tests/opt/opt_share_mux_tree.v b/tests/opt/opt_share_mux_tree.v index c90826204..4a26afb46 100644 --- a/tests/opt/opt_share_mux_tree.v +++ b/tests/opt/opt_share_mux_tree.v @@ -1,19 +1,18 @@ module opt_share_test( - input [15:0] a, - input [15:0] b, - input [15:0] c, - input [1:0] sel, - output reg [15:0] res - ); + input [15:0] a, + input [15:0] b, + input [15:0] c, + input [1:0] sel, + output reg [15:0] res + ); - - always @* begin - case(sel) - 0: res = a + b; - 1: res = a - b; - 2: res = a + c; - default: res = 16'bx; - endcase - end + always @* begin + case(sel) + 0: res = a + b; + 1: res = a - b; + 2: res = a + c; + default: res = 16'bx; + endcase + end endmodule From d8be5ce6ba11ec78d0f7925d488fad09a3eaba2c Mon Sep 17 00:00:00 2001 From: Bogdan Vukobratovic Date: Sat, 3 Aug 2019 12:35:46 +0200 Subject: [PATCH 09/94] Tabs to spaces in opt_share examples --- tests/opt/opt_share_add_sub.v | 12 +++--- tests/opt/opt_share_cat.v | 20 +++++----- tests/opt/opt_share_cat_multiuser.v | 34 ++++++++-------- tests/opt/opt_share_diff_port_widths.v | 32 +++++++-------- tests/opt/opt_share_extend.v | 28 ++++++------- tests/opt/opt_share_large_pmux_cat.v | 34 ++++++++-------- .../opt/opt_share_large_pmux_cat_multipart.v | 40 +++++++++---------- tests/opt/opt_share_large_pmux_multipart.v | 38 +++++++++--------- tests/opt/opt_share_large_pmux_part.v | 34 ++++++++-------- tests/opt/opt_share_mux_tree.v | 28 ++++++------- 10 files changed, 150 insertions(+), 150 deletions(-) diff --git a/tests/opt/opt_share_add_sub.v b/tests/opt/opt_share_add_sub.v index 1c2665cf0..d918f27cc 100644 --- a/tests/opt/opt_share_add_sub.v +++ b/tests/opt/opt_share_add_sub.v @@ -1,10 +1,10 @@ module opt_share_test( - input [15:0] a, - input [15:0] b, - input sel, - output [15:0] res, - ); + input [15:0] a, + input [15:0] b, + input sel, + output [15:0] res, + ); - assign res = {sel ? a + b : a - b}; + assign res = {sel ? a + b : a - b}; endmodule diff --git a/tests/opt/opt_share_cat.v b/tests/opt/opt_share_cat.v index 7b6f626b9..7fb97fef5 100644 --- a/tests/opt/opt_share_cat.v +++ b/tests/opt/opt_share_cat.v @@ -1,15 +1,15 @@ module opt_share_test( - input [15:0] a, - input [15:0] b, - input [15:0] c, - input [15:0] d, - input sel, - output [63:0] res, - ); + input [15:0] a, + input [15:0] b, + input [15:0] c, + input [15:0] d, + input sel, + output [63:0] res, + ); - reg [31: 0] cat1 = {a+b, c+d}; - reg [31: 0] cat2 = {a-b, c-d}; + reg [31: 0] cat1 = {a+b, c+d}; + reg [31: 0] cat2 = {a-b, c-d}; - assign res = {b, sel ? cat1 : cat2, a}; + assign res = {b, sel ? cat1 : cat2, a}; endmodule diff --git a/tests/opt/opt_share_cat_multiuser.v b/tests/opt/opt_share_cat_multiuser.v index f77f912e9..b250689d9 100644 --- a/tests/opt/opt_share_cat_multiuser.v +++ b/tests/opt/opt_share_cat_multiuser.v @@ -1,22 +1,22 @@ module opt_share_test( - input [15:0] a, - input [15:0] b, - input [15:0] c, - input [15:0] d, - input sel, - output reg [47:0] res, - ); + input [15:0] a, + input [15:0] b, + input [15:0] c, + input [15:0] d, + input sel, + output reg [47:0] res, + ); - wire [15:0] add_res = a+b; - wire [15:0] sub_res = a-b; - wire [31: 0] cat1 = {add_res, c+d}; - wire [31: 0] cat2 = {sub_res, c-d}; + wire [15:0] add_res = a+b; + wire [15:0] sub_res = a-b; + wire [31: 0] cat1 = {add_res, c+d}; + wire [31: 0] cat2 = {sub_res, c-d}; - always @* begin - case(sel) - 0: res = {cat1, add_res}; - 1: res = {cat2, add_res}; - endcase - end + always @* begin + case(sel) + 0: res = {cat1, add_res}; + 1: res = {cat2, add_res}; + endcase + end endmodule diff --git a/tests/opt/opt_share_diff_port_widths.v b/tests/opt/opt_share_diff_port_widths.v index e57ab7a83..1a37c80a6 100644 --- a/tests/opt/opt_share_diff_port_widths.v +++ b/tests/opt/opt_share_diff_port_widths.v @@ -1,21 +1,21 @@ module opt_share_test( - input [15:0] a, - input [15:0] b, - input [15:0] c, - input [1:0] sel, - output reg [15:0] res - ); + input [15:0] a, + input [15:0] b, + input [15:0] c, + input [1:0] sel, + output reg [15:0] res + ); - wire [15:0] add0_res = a+b; - wire [15:0] add1_res = a+c; + wire [15:0] add0_res = a+b; + wire [15:0] add1_res = a+c; - always @* begin - case(sel) - 0: res = add0_res[10:0]; - 1: res = add1_res[10:0]; - 2: res = a - b; - default: res = 32'bx; - endcase - end + always @* begin + case(sel) + 0: res = add0_res[10:0]; + 1: res = add1_res[10:0]; + 2: res = a - b; + default: res = 32'bx; + endcase + end endmodule diff --git a/tests/opt/opt_share_extend.v b/tests/opt/opt_share_extend.v index 60ce1a2f3..d39f19069 100644 --- a/tests/opt/opt_share_extend.v +++ b/tests/opt/opt_share_extend.v @@ -1,18 +1,18 @@ module opt_share_test( - input signed [7:0] a, - input signed [10:0] b, - input signed [15:0] c, - input [1:0] sel, - output reg signed [15:0] res - ); + input signed [7:0] a, + input signed [10:0] b, + input signed [15:0] c, + input [1:0] sel, + output reg signed [15:0] res + ); - always @* begin - case(sel) - 0: res = a + b; - 1: res = a - b; - 2: res = a + c; - default: res = 16'bx; - endcase - end + always @* begin + case(sel) + 0: res = a + b; + 1: res = a - b; + 2: res = a + c; + default: res = 16'bx; + endcase + end endmodule diff --git a/tests/opt/opt_share_large_pmux_cat.v b/tests/opt/opt_share_large_pmux_cat.v index 0667e6080..416ba3766 100644 --- a/tests/opt/opt_share_large_pmux_cat.v +++ b/tests/opt/opt_share_large_pmux_cat.v @@ -1,21 +1,21 @@ module opt_share_test( - input [15:0] a, - input [15:0] b, - input [15:0] c, - input [2:0] sel, - output reg [31:0] res - ); + input [15:0] a, + input [15:0] b, + input [15:0] c, + input [2:0] sel, + output reg [31:0] res + ); - always @* begin - case(sel) - 0: res = {a + b, a}; - 1: res = {a - b, b}; - 2: res = {a + c, c}; - 3: res = {a - c, a}; - 4: res = {b, b}; - 5: res = {c, c}; - default: res = 32'bx; - endcase - end + always @* begin + case(sel) + 0: res = {a + b, a}; + 1: res = {a - b, b}; + 2: res = {a + c, c}; + 3: res = {a - c, a}; + 4: res = {b, b}; + 5: res = {c, c}; + default: res = 32'bx; + endcase + end endmodule diff --git a/tests/opt/opt_share_large_pmux_cat_multipart.v b/tests/opt/opt_share_large_pmux_cat_multipart.v index f26505d3a..34d2bd9a8 100644 --- a/tests/opt/opt_share_large_pmux_cat_multipart.v +++ b/tests/opt/opt_share_large_pmux_cat_multipart.v @@ -1,25 +1,25 @@ module opt_share_test( - input [15:0] a, - input [15:0] b, - input [15:0] c, - input [15:0] d, - input [2:0] sel, - output reg [31:0] res - ); + input [15:0] a, + input [15:0] b, + input [15:0] c, + input [15:0] d, + input [2:0] sel, + output reg [31:0] res + ); - wire [15:0] add0_res = a+d; + wire [15:0] add0_res = a+d; - always @* begin - case(sel) - 0: res = {add0_res, a}; - 1: res = {a - b, add0_res[7], 15'b0}; - 2: res = {b-a, b}; - 3: res = {d, b - c}; - 4: res = {d, b - a}; - 5: res = {c, d}; - 6: res = {a - c, b-d}; - default: res = 32'bx; - endcase - end + always @* begin + case(sel) + 0: res = {add0_res, a}; + 1: res = {a - b, add0_res[7], 15'b0}; + 2: res = {b-a, b}; + 3: res = {d, b - c}; + 4: res = {d, b - a}; + 5: res = {c, d}; + 6: res = {a - c, b-d}; + default: res = 32'bx; + endcase + end endmodule diff --git a/tests/opt/opt_share_large_pmux_multipart.v b/tests/opt/opt_share_large_pmux_multipart.v index 1c460292f..535adf96f 100644 --- a/tests/opt/opt_share_large_pmux_multipart.v +++ b/tests/opt/opt_share_large_pmux_multipart.v @@ -1,23 +1,23 @@ module opt_share_test( - input [15:0] a, - input [15:0] b, - input [15:0] c, - input [15:0] d, - input [2:0] sel, - output reg [15:0] res - ); + input [15:0] a, + input [15:0] b, + input [15:0] c, + input [15:0] d, + input [2:0] sel, + output reg [15:0] res + ); - always @* begin - case(sel) - 0: res = a + d; - 1: res = a - b; - 2: res = b; - 3: res = b - c; - 4: res = b - a; - 5: res = c; - 6: res = a - c; - default: res = 16'bx; - endcase - end + always @* begin + case(sel) + 0: res = a + d; + 1: res = a - b; + 2: res = b; + 3: res = b - c; + 4: res = b - a; + 5: res = c; + 6: res = a - c; + default: res = 16'bx; + endcase + end endmodule diff --git a/tests/opt/opt_share_large_pmux_part.v b/tests/opt/opt_share_large_pmux_part.v index f9dd17446..a9008fb5a 100644 --- a/tests/opt/opt_share_large_pmux_part.v +++ b/tests/opt/opt_share_large_pmux_part.v @@ -1,21 +1,21 @@ module opt_share_test( - input [15:0] a, - input [15:0] b, - input [15:0] c, - input [2:0] sel, - output reg [15:0] res - ); + input [15:0] a, + input [15:0] b, + input [15:0] c, + input [2:0] sel, + output reg [15:0] res + ); - always @* begin - case(sel) - 0: res = a + b; - 1: res = a - b; - 2: res = a + c; - 3: res = a - c; - 4: res = b; - 5: res = c; - default: res = 16'bx; - endcase - end + always @* begin + case(sel) + 0: res = a + b; + 1: res = a - b; + 2: res = a + c; + 3: res = a - c; + 4: res = b; + 5: res = c; + default: res = 16'bx; + endcase + end endmodule diff --git a/tests/opt/opt_share_mux_tree.v b/tests/opt/opt_share_mux_tree.v index 4a26afb46..cc5ae4eb9 100644 --- a/tests/opt/opt_share_mux_tree.v +++ b/tests/opt/opt_share_mux_tree.v @@ -1,18 +1,18 @@ module opt_share_test( - input [15:0] a, - input [15:0] b, - input [15:0] c, - input [1:0] sel, - output reg [15:0] res - ); + input [15:0] a, + input [15:0] b, + input [15:0] c, + input [1:0] sel, + output reg [15:0] res + ); - always @* begin - case(sel) - 0: res = a + b; - 1: res = a - b; - 2: res = a + c; - default: res = 16'bx; - endcase - end + always @* begin + case(sel) + 0: res = a + b; + 1: res = a - b; + 2: res = a + c; + default: res = 16'bx; + endcase + end endmodule From ab98f604fd1319e0f42b0c5dc8bb6be5d3d2ba38 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Sat, 3 Aug 2019 12:29:30 +0200 Subject: [PATCH 10/94] Initial EFINIX support --- techlibs/efinix/Makefile.inc | 6 + techlibs/efinix/arith_map.v | 78 ++++++++++++ techlibs/efinix/cells_map.v | 45 +++++++ techlibs/efinix/cells_sim.v | 36 ++++++ techlibs/efinix/synth_efinix.cc | 205 ++++++++++++++++++++++++++++++++ 5 files changed, 370 insertions(+) create mode 100644 techlibs/efinix/Makefile.inc create mode 100644 techlibs/efinix/arith_map.v create mode 100644 techlibs/efinix/cells_map.v create mode 100644 techlibs/efinix/cells_sim.v create mode 100644 techlibs/efinix/synth_efinix.cc diff --git a/techlibs/efinix/Makefile.inc b/techlibs/efinix/Makefile.inc new file mode 100644 index 000000000..3f3394c96 --- /dev/null +++ b/techlibs/efinix/Makefile.inc @@ -0,0 +1,6 @@ + +OBJS += techlibs/efinix/synth_efinix.o + +$(eval $(call add_share_file,share/efinix,techlibs/efinix/cells_map.v)) +$(eval $(call add_share_file,share/efinix,techlibs/efinix/arith_map.v)) +$(eval $(call add_share_file,share/efinix,techlibs/efinix/cells_sim.v)) diff --git a/techlibs/efinix/arith_map.v b/techlibs/efinix/arith_map.v new file mode 100644 index 000000000..ae955663c --- /dev/null +++ b/techlibs/efinix/arith_map.v @@ -0,0 +1,78 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2018 Miodrag Milanovic + * 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. + * + */ + +(* techmap_celltype = "$alu" *) +module _80_efinix_alu (A, B, CI, BI, X, Y, CO); + parameter A_SIGNED = 0; + parameter B_SIGNED = 0; + parameter A_WIDTH = 1; + parameter B_WIDTH = 1; + parameter Y_WIDTH = 1; + + input [A_WIDTH-1:0] A; + input [B_WIDTH-1:0] B; + output [Y_WIDTH-1:0] X, Y; + + input CI, BI; + output CO; + + wire _TECHMAP_FAIL_ = Y_WIDTH <= 2; + + wire [Y_WIDTH-1:0] A_buf, B_buf; + \$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) A_conv (.A(A), .Y(A_buf)); + \$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(B_buf)); + + wire [Y_WIDTH-1:0] AA = A_buf; + wire [Y_WIDTH-1:0] BB = BI ? ~B_buf : B_buf; + wire [Y_WIDTH+1:0] COx; + wire [Y_WIDTH+2:0] C = {COx, CI}; + + EFX_ADD #(.I0_POLARITY(1'b1),.I1_POLARITY(1'b1)) + adder_cin ( + .I0(C[0]), + .I1(1'b1), + .CI(1'b0), + .CO(COx[0]) + ); + + genvar i; + generate for (i = 0; i < Y_WIDTH; i = i + 1) begin: slice + EFX_ADD #(.I0_POLARITY(1'b1),.I1_POLARITY(1'b1)) + adder_i ( + .I0(AA[i]), + .I1(BB[i]), + .CI(C[i+1]), + .O(Y[i]), + .CO(COx[i+1]) + ); + end: slice + endgenerate + + EFX_ADD #(.I0_POLARITY(1'b1),.I1_POLARITY(1'b1)) + adder_cout ( + .I0(1'b0), + .I1(1'b0), + .CI(C[Y_WIDTH+1]), + .O(COx[Y_WIDTH+1]) + ); + assign CO = COx[Y_WIDTH+1]; + /* End implementation */ + assign X = AA ^ BB; +endmodule \ No newline at end of file diff --git a/techlibs/efinix/cells_map.v b/techlibs/efinix/cells_map.v new file mode 100644 index 000000000..70c19635e --- /dev/null +++ b/techlibs/efinix/cells_map.v @@ -0,0 +1,45 @@ +module \$_DFF_N_ (input D, C, output Q); EFX_FF #(.CLK_POLARITY(1'b0), .CE_POLARITY(1'b1), .SR_POLARITY(1'b1), .D_POLARITY(1'b1), .SR_SYNC(1'b1), .SR_VALUE(1'b0), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(1'b1), .CLK(C), .SR(1'b0), .Q(Q)); endmodule +module \$_DFF_P_ (input D, C, output Q); EFX_FF #(.CLK_POLARITY(1'b1), .CE_POLARITY(1'b1), .SR_POLARITY(1'b1), .D_POLARITY(1'b1), .SR_SYNC(1'b1), .SR_VALUE(1'b0), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(1'b1), .CLK(C), .SR(1'b0), .Q(Q)); endmodule + +module \$_DFFE_NN_ (input D, C, E, output Q); EFX_FF #(.CLK_POLARITY(1'b0), .CE_POLARITY(1'b0), .SR_POLARITY(1'b1), .D_POLARITY(1'b1), .SR_SYNC(1'b1), .SR_VALUE(1'b0), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(E), .CLK(C), .SR(1'b0), .Q(Q)); endmodule +module \$_DFFE_NP_ (input D, C, E, output Q); EFX_FF #(.CLK_POLARITY(1'b0), .CE_POLARITY(1'b1), .SR_POLARITY(1'b1), .D_POLARITY(1'b1), .SR_SYNC(1'b1), .SR_VALUE(1'b0), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(E), .CLK(C), .SR(1'b0), .Q(Q)); endmodule + +module \$_DFFE_PN_ (input D, C, E, output Q); EFX_FF #(.CLK_POLARITY(1'b1), .CE_POLARITY(1'b0), .SR_POLARITY(1'b1), .D_POLARITY(1'b1), .SR_SYNC(1'b1), .SR_VALUE(1'b0), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(E), .CLK(C), .SR(1'b0), .Q(Q)); endmodule +module \$_DFFE_PP_ (input D, C, E, output Q); EFX_FF #(.CLK_POLARITY(1'b1), .CE_POLARITY(1'b1), .SR_POLARITY(1'b1), .D_POLARITY(1'b1), .SR_SYNC(1'b1), .SR_VALUE(1'b0), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(E), .CLK(C), .SR(1'b0), .Q(Q)); endmodule + +module \$_DFF_NN0_ (input D, C, R, output Q); EFX_FF #(.CLK_POLARITY(1'b0), .CE_POLARITY(1'b1), .SR_POLARITY(1'b0), .D_POLARITY(1'b1), .SR_SYNC(1'b0), .SR_VALUE(1'b0), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(1'b1), .CLK(C), .SR(R), .Q(Q)); endmodule +module \$_DFF_NN1_ (input D, C, R, output Q); EFX_FF #(.CLK_POLARITY(1'b0), .CE_POLARITY(1'b1), .SR_POLARITY(1'b0), .D_POLARITY(1'b1), .SR_SYNC(1'b1), .SR_VALUE(1'b0), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(1'b1), .CLK(C), .SR(R), .Q(Q)); endmodule +module \$_DFF_PN0_ (input D, C, R, output Q); EFX_FF #(.CLK_POLARITY(1'b1), .CE_POLARITY(1'b1), .SR_POLARITY(1'b0), .D_POLARITY(1'b1), .SR_SYNC(1'b0), .SR_VALUE(1'b0), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(1'b1), .CLK(C), .SR(R), .Q(Q)); endmodule +module \$_DFF_PN1_ (input D, C, R, output Q); EFX_FF #(.CLK_POLARITY(1'b1), .CE_POLARITY(1'b1), .SR_POLARITY(1'b0), .D_POLARITY(1'b1), .SR_SYNC(1'b1), .SR_VALUE(1'b0), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(1'b1), .CLK(C), .SR(R), .Q(Q)); endmodule + +module \$_DFF_NP0_ (input D, C, R, output Q); EFX_FF #(.CLK_POLARITY(1'b0), .CE_POLARITY(1'b1), .SR_POLARITY(1'b1), .D_POLARITY(1'b1), .SR_SYNC(1'b0), .SR_VALUE(1'b0), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(1'b1), .CLK(C), .SR(R), .Q(Q)); endmodule +module \$_DFF_NP1_ (input D, C, R, output Q); EFX_FF #(.CLK_POLARITY(1'b0), .CE_POLARITY(1'b1), .SR_POLARITY(1'b1), .D_POLARITY(1'b1), .SR_SYNC(1'b1), .SR_VALUE(1'b0), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(1'b1), .CLK(C), .SR(R), .Q(Q)); endmodule +module \$_DFF_PP0_ (input D, C, R, output Q); EFX_FF #(.CLK_POLARITY(1'b1), .CE_POLARITY(1'b1), .SR_POLARITY(1'b1), .D_POLARITY(1'b1), .SR_SYNC(1'b0), .SR_VALUE(1'b0), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(1'b1), .CLK(C), .SR(R), .Q(Q)); endmodule +module \$_DFF_PP1_ (input D, C, R, output Q); EFX_FF #(.CLK_POLARITY(1'b1), .CE_POLARITY(1'b1), .SR_POLARITY(1'b1), .D_POLARITY(1'b1), .SR_SYNC(1'b1), .SR_VALUE(1'b0), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(1'b1), .CLK(C), .SR(R), .Q(Q)); endmodule + +`ifndef NO_LUT +module \$lut (A, Y); + parameter WIDTH = 0; + parameter LUT = 0; + + input [WIDTH-1:0] A; + output Y; + + generate + if (WIDTH == 1) begin + EFX_LUT4 #(.LUTMASK(LUT)) _TECHMAP_REPLACE_ (.O(Y), .I0(A[0]), .I1(1'b0), .I2(1'b0), .I3(1'b0)); + end else + if (WIDTH == 2) begin + EFX_LUT4 #(.LUTMASK(LUT)) _TECHMAP_REPLACE_ (.O(Y), .I0(A[0]), .I1(A[1]), .I2(1'b0), .I3(1'b0)); + end else + if (WIDTH == 3) begin + EFX_LUT4 #(.LUTMASK(LUT)) _TECHMAP_REPLACE_ (.O(Y), .I0(A[0]), .I1(A[1]), .I2(A[2]), .I3(1'b0)); + end else + if (WIDTH == 4) begin + EFX_LUT4 #(.LUTMASK(LUT)) _TECHMAP_REPLACE_ (.O(Y), .I0(A[0]), .I1(A[1]), .I2(A[2]), .I3(A[3])); + end else begin + wire _TECHMAP_FAIL_ = 1; + end + endgenerate +endmodule +`endif diff --git a/techlibs/efinix/cells_sim.v b/techlibs/efinix/cells_sim.v new file mode 100644 index 000000000..aaff955a2 --- /dev/null +++ b/techlibs/efinix/cells_sim.v @@ -0,0 +1,36 @@ +module EFX_LUT4( + output O, + input I0, + input I1, + input I2, + input I3 +); + parameter LUTMASK = 16'h0000; +endmodule + +module EFX_ADD( + output O, + output CO, + input I0, + input I1, + input CI +); + parameter I0_POLARITY = 1; + parameter I1_POLARITY = 1; +endmodule + +module EFX_FF( + output Q, + input D, + input CE, + input CLK, + input SR +); + parameter CLK_POLARITY = 1; + parameter CE_POLARITY = 1; + parameter SR_POLARITY = 1; + parameter SR_SYNC = 0; + parameter SR_VALUE = 0; + parameter SR_SYNC_PRIORITY = 0; + parameter D_POLARITY = 1; +endmodule \ No newline at end of file diff --git a/techlibs/efinix/synth_efinix.cc b/techlibs/efinix/synth_efinix.cc new file mode 100644 index 000000000..9c644d363 --- /dev/null +++ b/techlibs/efinix/synth_efinix.cc @@ -0,0 +1,205 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2019 Miodrag Milanovic + * Copyright (C) 2019 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/celltypes.h" +#include "kernel/rtlil.h" +#include "kernel/log.h" + +USING_YOSYS_NAMESPACE +PRIVATE_NAMESPACE_BEGIN + +struct SynthEfinixPass : public ScriptPass +{ + SynthEfinixPass() : ScriptPass("synth_efinix", "synthesis for Efinix FPGAs") { } + + void help() YS_OVERRIDE + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" synth_efinix [options]\n"); + log("\n"); + log("This command runs synthesis for Efinix FPGAs.\n"); + log("\n"); + log(" -top \n"); + log(" use the specified module as top module\n"); + log("\n"); + log(" -edif \n"); + log(" write the design to the specified EDIF file. writing of an output file\n"); + log(" is omitted if this parameter is not specified.\n"); + log("\n"); + log(" -json \n"); + log(" write the design to the specified JSON file. writing of an output file\n"); + log(" is omitted if this parameter is not specified.\n"); + log("\n"); + log(" -run :\n"); + log(" only run the commands between the labels (see below). an empty\n"); + log(" from label is synonymous to 'begin', and empty to label is\n"); + log(" synonymous to the end of the command list.\n"); + log("\n"); + log(" -noflatten\n"); + log(" do not flatten design before synthesis\n"); + log("\n"); + log(" -retime\n"); + log(" run 'abc' with -dff option\n"); + log("\n"); + log("\n"); + log("The following commands are executed by this synthesis command:\n"); + help_script(); + log("\n"); + } + + string top_opt, edif_file, json_file; + bool flatten, retime; + + void clear_flags() YS_OVERRIDE + { + top_opt = "-auto-top"; + edif_file = ""; + json_file = ""; + flatten = true; + retime = false; + } + + void execute(std::vector args, RTLIL::Design *design) YS_OVERRIDE + { + string run_from, run_to; + clear_flags(); + + size_t argidx; + for (argidx = 1; argidx < args.size(); argidx++) + { + if (args[argidx] == "-top" && argidx+1 < args.size()) { + top_opt = "-top " + args[++argidx]; + continue; + } + if (args[argidx] == "-edif" && argidx+1 < args.size()) { + edif_file = args[++argidx]; + continue; + } + if (args[argidx] == "-json" && argidx+1 < args.size()) { + json_file = args[++argidx]; + continue; + } + if (args[argidx] == "-run" && argidx+1 < args.size()) { + size_t pos = args[argidx+1].find(':'); + if (pos == std::string::npos) + break; + run_from = args[++argidx].substr(0, pos); + run_to = args[argidx].substr(pos+1); + continue; + } + if (args[argidx] == "-noflatten") { + flatten = false; + continue; + } + if (args[argidx] == "-retime") { + retime = true; + continue; + } + break; + } + extra_args(args, argidx, design); + + if (!design->full_selection()) + log_cmd_error("This command only operates on fully selected designs!\n"); + + log_header(design, "Executing SYNTH_EFINIX pass.\n"); + log_push(); + + run_script(design, run_from, run_to); + + log_pop(); + } + + void script() YS_OVERRIDE + { + if (check_label("begin")) + { + run("read_verilog -lib +/efinix/cells_sim.v"); + run(stringf("hierarchy -check %s", help_mode ? "-top " : top_opt.c_str())); + } + + if (flatten && check_label("flatten", "(unless -noflatten)")) + { + run("proc"); + run("flatten"); + run("tribuf -logic"); + run("deminout"); + } + + if (check_label("coarse")) + { + run("synth -run coarse"); + } + + if (check_label("fine")) + { + run("opt -fast -mux_undef -undriven -fine"); + run("memory_map"); + run("opt -undriven -fine"); + run("techmap -map +/techmap.v -map +/efinix/arith_map.v"); + if (retime || help_mode) + run("abc -dff", "(only if -retime)"); + } + + if (check_label("map_ffs")) + { + run("dffsr2dff"); + run("techmap -D NO_LUT -map +/efinix/cells_map.v"); + run("dffinit -strinit SET RESET -ff AL_MAP_SEQ q REGSET -noreinit"); + run("opt_expr -mux_undef"); + run("simplemap"); + } + + if (check_label("map_luts")) + { + run("abc -lut 4"); + run("clean"); + } + + if (check_label("map_cells")) + { + run("techmap -map +/efinix/cells_map.v"); + run("clean"); + } + + if (check_label("check")) + { + run("hierarchy -check"); + run("stat"); + run("check -noinit"); + } + + if (check_label("edif")) + { + if (!edif_file.empty() || help_mode) + run(stringf("write_edif %s", help_mode ? "" : edif_file.c_str())); + } + + if (check_label("json")) + { + if (!json_file.empty() || help_mode) + run(stringf("write_json %s", help_mode ? "" : json_file.c_str())); + } + } +} SynthEfinixPass; + +PRIVATE_NAMESPACE_END From 6e210f26fa97fa65c420534f0ec0e26eeb1b078a Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Sat, 3 Aug 2019 14:40:23 +0200 Subject: [PATCH 11/94] Custom step to add global clock buffers --- techlibs/efinix/Makefile.inc | 1 + techlibs/efinix/cells_sim.v | 10 ++- techlibs/efinix/efinix_gbuf.cc | 113 ++++++++++++++++++++++++++++++++ techlibs/efinix/synth_efinix.cc | 6 ++ 4 files changed, 129 insertions(+), 1 deletion(-) create mode 100644 techlibs/efinix/efinix_gbuf.cc diff --git a/techlibs/efinix/Makefile.inc b/techlibs/efinix/Makefile.inc index 3f3394c96..82dfa3cd8 100644 --- a/techlibs/efinix/Makefile.inc +++ b/techlibs/efinix/Makefile.inc @@ -1,5 +1,6 @@ OBJS += techlibs/efinix/synth_efinix.o +OBJS += techlibs/efinix/efinix_gbuf.o $(eval $(call add_share_file,share/efinix,techlibs/efinix/cells_map.v)) $(eval $(call add_share_file,share/efinix,techlibs/efinix/arith_map.v)) diff --git a/techlibs/efinix/cells_sim.v b/techlibs/efinix/cells_sim.v index aaff955a2..2cbf8ae4b 100644 --- a/techlibs/efinix/cells_sim.v +++ b/techlibs/efinix/cells_sim.v @@ -33,4 +33,12 @@ module EFX_FF( parameter SR_VALUE = 0; parameter SR_SYNC_PRIORITY = 0; parameter D_POLARITY = 1; -endmodule \ No newline at end of file +endmodule + +module EFX_GBUFCE ( + input CE, + input I, + output O +); + parameter CE_POLARITY = 1'b1; +endmodule diff --git a/techlibs/efinix/efinix_gbuf.cc b/techlibs/efinix/efinix_gbuf.cc new file mode 100644 index 000000000..50f84c30c --- /dev/null +++ b/techlibs/efinix/efinix_gbuf.cc @@ -0,0 +1,113 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2019 Miodrag Milanovic + * 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/yosys.h" +#include "kernel/sigtools.h" + +USING_YOSYS_NAMESPACE +PRIVATE_NAMESPACE_BEGIN + +static void handle_gbufs(Module *module) +{ + SigMap sigmap(module); + + pool clk_bits; + dict rewrite_bits; + vector> pad_bits; + + for (auto cell : module->cells()) + { + if (cell->type == "\\EFX_FF") { + for (auto bit : sigmap(cell->getPort("\\CLK"))) + clk_bits.insert(bit); + } + } + + for (auto wire : vector(module->wires())) + { + if (!wire->port_input) + continue; + + for (int index = 0; index < GetSize(wire); index++) + { + SigBit bit(wire, index); + SigBit canonical_bit = sigmap(bit); + + if (!clk_bits.count(canonical_bit)) + continue; + + Cell *c = module->addCell(NEW_ID, "\\EFX_GBUFCE"); + SigBit new_bit = module->addWire(NEW_ID); + c->setParam("\\CE_POLARITY", State::S1); + c->setPort("\\O", new_bit); + c->setPort("\\CE", State::S1); + pad_bits.push_back(make_pair(c, bit)); + rewrite_bits[canonical_bit] = new_bit; + + log("Added %s cell %s for port bit %s.\n", log_id(c->type), log_id(c), log_signal(bit)); + } + } + + auto rewrite_function = [&](SigSpec &s) { + for (auto &bit : s) { + SigBit canonical_bit = sigmap(bit); + if (rewrite_bits.count(canonical_bit)) + bit = rewrite_bits.at(canonical_bit); + } + }; + + module->rewrite_sigspecs(rewrite_function); + + for (auto &it : pad_bits) + it.first->setPort("\\I", it.second); +} + +struct EfinixGbufPass : public Pass { + EfinixGbufPass() : Pass("efinix_gbuf", "Efinix: insert global clock buffers") { } + void help() YS_OVERRIDE + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" efinix_gbuf [options] [selection]\n"); + log("\n"); + log("Add Efinix global clock buffers to top module as needed.\n"); + log("\n"); + } + void execute(std::vector args, RTLIL::Design *design) YS_OVERRIDE + { + log_header(design, "Executing efinix_gbuf pass (insert global clock buffers).\n"); + + size_t argidx; + for (argidx = 1; argidx < args.size(); argidx++) + { + break; + } + extra_args(args, argidx, design); + + Module *module = design->top_module(); + + if (module == nullptr) + log_cmd_error("No top module found.\n"); + + handle_gbufs(module); + } +} EfinixGbufPass; + +PRIVATE_NAMESPACE_END diff --git a/techlibs/efinix/synth_efinix.cc b/techlibs/efinix/synth_efinix.cc index 9c644d363..3f17bafa3 100644 --- a/techlibs/efinix/synth_efinix.cc +++ b/techlibs/efinix/synth_efinix.cc @@ -181,6 +181,12 @@ struct SynthEfinixPass : public ScriptPass run("clean"); } + if (check_label("map_gbuf")) + { + run("efinix_gbuf"); + run("clean"); + } + if (check_label("check")) { run("hierarchy -check"); From cf96f41c6d9c405ddc039a8d0629731924b774ed Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Sun, 4 Aug 2019 11:46:36 +0200 Subject: [PATCH 12/94] Added bram support --- techlibs/efinix/Makefile.inc | 3 + techlibs/efinix/bram.txt | 32 +++++++++ techlibs/efinix/brams_map.v | 65 +++++++++++++++++ techlibs/efinix/cells_sim.v | 65 ++++++++++++++++- techlibs/efinix/efinix_determine_init.cc | 89 ++++++++++++++++++++++++ techlibs/efinix/synth_efinix.cc | 7 ++ 6 files changed, 260 insertions(+), 1 deletion(-) create mode 100644 techlibs/efinix/bram.txt create mode 100644 techlibs/efinix/brams_map.v create mode 100644 techlibs/efinix/efinix_determine_init.cc diff --git a/techlibs/efinix/Makefile.inc b/techlibs/efinix/Makefile.inc index 82dfa3cd8..d0593baec 100644 --- a/techlibs/efinix/Makefile.inc +++ b/techlibs/efinix/Makefile.inc @@ -1,7 +1,10 @@ OBJS += techlibs/efinix/synth_efinix.o OBJS += techlibs/efinix/efinix_gbuf.o +OBJS += techlibs/efinix/efinix_determine_init.o $(eval $(call add_share_file,share/efinix,techlibs/efinix/cells_map.v)) $(eval $(call add_share_file,share/efinix,techlibs/efinix/arith_map.v)) $(eval $(call add_share_file,share/efinix,techlibs/efinix/cells_sim.v)) +$(eval $(call add_share_file,share/efinix,techlibs/efinix/brams_map.v)) +$(eval $(call add_share_file,share/efinix,techlibs/efinix/bram.txt)) \ No newline at end of file diff --git a/techlibs/efinix/bram.txt b/techlibs/efinix/bram.txt new file mode 100644 index 000000000..0b3fd9308 --- /dev/null +++ b/techlibs/efinix/bram.txt @@ -0,0 +1,32 @@ +bram $__EFINIX_5K + init 1 + + abits 8 @a8d16 + dbits 16 @a8d16 + abits 9 @a9d8 + dbits 8 @a9d8 + abits 10 @a10d4 + dbits 4 @a10d4 + abits 11 @a11d2 + dbits 2 @a11d2 + abits 12 @a12d1 + dbits 1 @a12d1 + abits 8 @a8d20 + dbits 20 @a8d20 + abits 9 @a9d10 + dbits 10 @a9d10 + + groups 2 + ports 1 1 + wrmode 1 0 + enable 1 1 + transp 0 2 + clocks 2 3 + clkpol 2 3 +endbram + +match $__EFINIX_5K + min bits 256 + min efficiency 5 + shuffle_enable B +endmatch diff --git a/techlibs/efinix/brams_map.v b/techlibs/efinix/brams_map.v new file mode 100644 index 000000000..9ef01d026 --- /dev/null +++ b/techlibs/efinix/brams_map.v @@ -0,0 +1,65 @@ +module \$__EFINIX_5K (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN); + parameter CFG_ABITS = 8; + parameter CFG_DBITS = 20; + parameter CFG_ENABLE_A = 2; + + parameter CLKPOL2 = 1; + parameter CLKPOL3 = 1; + parameter [5119:0] INIT = 5119'bx; + parameter TRANSP2 = 0; + + input CLK2; + input CLK3; + + input [CFG_ABITS-1:0] A1ADDR; + input [CFG_DBITS-1:0] A1DATA; + input [CFG_ENABLE_A-1:0] A1EN; + + input [CFG_ABITS-1:0] B1ADDR; + output [CFG_DBITS-1:0] B1DATA; + input B1EN; + + localparam WRITEMODE_A = TRANSP2 ? "WRITE_FIRST" : "READ_FIRST"; + + EFX_RAM_5K #( + .READ_WIDTH(20), + .WRITE_WIDTH(20), + .OUTPUT_REG(1'b0), + .RCLK_POLARITY(1'b1), + .RE_POLARITY(1'b1), + .WCLK_POLARITY(1'b1), + .WE_POLARITY(1'b1), + .WCLKE_POLARITY(1'b1), + .WRITE_MODE(WRITEMODE_A), + .INIT_0(INIT[ 0*256 +: 256]), + .INIT_1(INIT[ 1*256 +: 256]), + .INIT_2(INIT[ 2*256 +: 256]), + .INIT_3(INIT[ 3*256 +: 256]), + .INIT_4(INIT[ 4*256 +: 256]), + .INIT_5(INIT[ 5*256 +: 256]), + .INIT_6(INIT[ 6*256 +: 256]), + .INIT_7(INIT[ 7*256 +: 256]), + .INIT_8(INIT[ 8*256 +: 256]), + .INIT_9(INIT[ 9*256 +: 256]), + .INIT_A(INIT[10*256 +: 256]), + .INIT_B(INIT[11*256 +: 256]), + .INIT_C(INIT[12*256 +: 256]), + .INIT_D(INIT[13*256 +: 256]), + .INIT_E(INIT[14*256 +: 256]), + .INIT_F(INIT[15*256 +: 256]), + .INIT_10(INIT[16*256 +: 256]), + .INIT_11(INIT[17*256 +: 256]), + .INIT_12(INIT[18*256 +: 256]), + .INIT_13(INIT[19*256 +: 256]) + ) _TECHMAP_REPLACE_ ( + .WDATA(A1DATA), + .WADDR(A1ADDR), + .WE(A1EN), + .WCLK(CLK2), + .WCLKE(1'b1), + .RDATA(B1DATA), + .RADDR(B1ADDR), + .RE(B1EN), + .RCLK(CLK3) + ); +endmodule diff --git a/techlibs/efinix/cells_sim.v b/techlibs/efinix/cells_sim.v index 2cbf8ae4b..8c8f6afaa 100644 --- a/techlibs/efinix/cells_sim.v +++ b/techlibs/efinix/cells_sim.v @@ -35,10 +35,73 @@ module EFX_FF( parameter D_POLARITY = 1; endmodule -module EFX_GBUFCE ( +module EFX_GBUFCE( input CE, input I, output O ); parameter CE_POLARITY = 1'b1; endmodule + +module EFX_RAM_5K( + input [WRITE_WIDTH-1:0] WDATA, + input [WRITE_ADDR_WIDTH-1:0] WADDR, + input WE, + input WCLK, + input WCLKE, + output [READ_WIDTH-1:0] RDATA, + input [READ_ADDR_WIDTH-1:0] RADDR, + input RE, + input RCLK +); + parameter READ_WIDTH = 20; + parameter WRITE_WIDTH = 20; + parameter OUTPUT_REG = 1'b0; + parameter RCLK_POLARITY = 1'b1; + parameter RE_POLARITY = 1'b1; + parameter WCLK_POLARITY = 1'b1; + parameter WE_POLARITY = 1'b1; + parameter WCLKE_POLARITY = 1'b1; + parameter WRITE_MODE = "READ_FIRST"; + parameter INIT_0 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_1 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_2 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_3 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_4 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_5 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_6 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_7 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_8 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_9 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_A = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_B = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_C = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_D = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_E = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_F = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_10 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_11 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_12 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_13 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + + localparam READ_ADDR_WIDTH = + (READ_WIDTH == 16) ? 8 : // 256x16 + (READ_WIDTH == 8) ? 9 : // 512x8 + (READ_WIDTH == 4) ? 10 : // 1024x4 + (READ_WIDTH == 2) ? 11 : // 2048x2 + (READ_WIDTH == 1) ? 12 : // 4096x1 + (READ_WIDTH == 20) ? 8 : // 256x20 + (READ_WIDTH == 10) ? 9 : // 512x10 + (READ_WIDTH == 5) ? 10 : -1; // 1024x5 + + localparam WRITE_ADDR_WIDTH = + (WRITE_WIDTH == 16) ? 8 : // 256x16 + (WRITE_WIDTH == 8) ? 9 : // 512x8 + (WRITE_WIDTH == 4) ? 10 : // 1024x4 + (WRITE_WIDTH == 2) ? 11 : // 2048x2 + (WRITE_WIDTH == 1) ? 12 : // 4096x1 + (WRITE_WIDTH == 20) ? 8 : // 256x20 + (WRITE_WIDTH == 10) ? 9 : // 512x10 + (WRITE_WIDTH == 5) ? 10 : -1; // 1024x5 + +endmodule \ No newline at end of file diff --git a/techlibs/efinix/efinix_determine_init.cc b/techlibs/efinix/efinix_determine_init.cc new file mode 100644 index 000000000..54da703ff --- /dev/null +++ b/techlibs/efinix/efinix_determine_init.cc @@ -0,0 +1,89 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2018 Icenowy Zheng + * + * 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 + +struct EfinixDetermineInitPass : public Pass { + EfinixDetermineInitPass() : Pass("efinix_determine_init", "Efinix: Determine the init value of cells") { } + void help() YS_OVERRIDE + { + log("\n"); + log(" efinix_determine_init [selection]\n"); + log("\n"); + log("Determine the init value of cells that doesn't allow unknown init value.\n"); + log("\n"); + } + + Const determine_init(Const init) + { + for (int i = 0; i < GetSize(init); i++) { + if (init[i] != State::S0 && init[i] != State::S1) + init[i] = State::S0; + } + + return init; + } + + void execute(std::vector args, RTLIL::Design *design) YS_OVERRIDE + { + log_header(design, "Executing EFINIX_DETERMINE_INIT pass (determine init value for cells).\n"); + + extra_args(args, args.size(), design); + + int cnt = 0; + for (auto module : design->selected_modules()) + { + for (auto cell : module->selected_cells()) + { + if (cell->type == "\\EFX_RAM_5K") + { + cell->setParam("\\INIT_0", determine_init(cell->getParam("\\INIT_0"))); + cell->setParam("\\INIT_1", determine_init(cell->getParam("\\INIT_1"))); + cell->setParam("\\INIT_2", determine_init(cell->getParam("\\INIT_2"))); + cell->setParam("\\INIT_3", determine_init(cell->getParam("\\INIT_3"))); + cell->setParam("\\INIT_4", determine_init(cell->getParam("\\INIT_4"))); + cell->setParam("\\INIT_5", determine_init(cell->getParam("\\INIT_5"))); + cell->setParam("\\INIT_6", determine_init(cell->getParam("\\INIT_6"))); + cell->setParam("\\INIT_7", determine_init(cell->getParam("\\INIT_7"))); + cell->setParam("\\INIT_8", determine_init(cell->getParam("\\INIT_8"))); + cell->setParam("\\INIT_9", determine_init(cell->getParam("\\INIT_9"))); + cell->setParam("\\INIT_A", determine_init(cell->getParam("\\INIT_A"))); + cell->setParam("\\INIT_B", determine_init(cell->getParam("\\INIT_B"))); + cell->setParam("\\INIT_C", determine_init(cell->getParam("\\INIT_C"))); + cell->setParam("\\INIT_D", determine_init(cell->getParam("\\INIT_D"))); + cell->setParam("\\INIT_E", determine_init(cell->getParam("\\INIT_E"))); + cell->setParam("\\INIT_F", determine_init(cell->getParam("\\INIT_F"))); + cell->setParam("\\INIT_10", determine_init(cell->getParam("\\INIT_10"))); + cell->setParam("\\INIT_11", determine_init(cell->getParam("\\INIT_11"))); + cell->setParam("\\INIT_12", determine_init(cell->getParam("\\INIT_12"))); + cell->setParam("\\INIT_13", determine_init(cell->getParam("\\INIT_13"))); + + cnt++; + } + } + } + log_header(design, "Updated %d cells with determined init value.\n", cnt); + } +} EfinixDetermineInitPass; + +PRIVATE_NAMESPACE_END diff --git a/techlibs/efinix/synth_efinix.cc b/techlibs/efinix/synth_efinix.cc index 3f17bafa3..000a17310 100644 --- a/techlibs/efinix/synth_efinix.cc +++ b/techlibs/efinix/synth_efinix.cc @@ -150,6 +150,13 @@ struct SynthEfinixPass : public ScriptPass run("synth -run coarse"); } + if (check_label("map_bram", "(skip if -nobram)")) + { + run("memory_bram -rules +/efinix/bram.txt"); + run("techmap -map +/efinix/brams_map.v"); + run("efinix_determine_init"); + } + if (check_label("fine")) { run("opt -fast -mux_undef -undriven -fine"); From 8a3329871ba7bab98982a101327b8375cd73344d Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Sun, 4 Aug 2019 12:17:55 +0200 Subject: [PATCH 13/94] clock for ram trough gbuf --- techlibs/efinix/efinix_gbuf.cc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/techlibs/efinix/efinix_gbuf.cc b/techlibs/efinix/efinix_gbuf.cc index 50f84c30c..e75fb3f4d 100644 --- a/techlibs/efinix/efinix_gbuf.cc +++ b/techlibs/efinix/efinix_gbuf.cc @@ -38,6 +38,12 @@ static void handle_gbufs(Module *module) for (auto bit : sigmap(cell->getPort("\\CLK"))) clk_bits.insert(bit); } + if (cell->type == "\\EFX_RAM_5K") { + for (auto bit : sigmap(cell->getPort("\\RCLK"))) + clk_bits.insert(bit); + for (auto bit : sigmap(cell->getPort("\\WCLK"))) + clk_bits.insert(bit); + } } for (auto wire : vector(module->wires())) From 6a796accc09bc2c8ef98c068185de13d3e01890a Mon Sep 17 00:00:00 2001 From: Bogdan Vukobratovic Date: Sun, 4 Aug 2019 19:06:38 +0200 Subject: [PATCH 14/94] Support various binary operators in opt_share --- Makefile | 1 + passes/opt/opt_share.cc | 610 ++++++++++++++++++++++++------------ tests/opt_share/.gitignore | 1 + tests/opt_share/generate.py | 86 +++++ tests/opt_share/run-test.sh | 39 +++ 5 files changed, 531 insertions(+), 206 deletions(-) create mode 100644 tests/opt_share/.gitignore create mode 100644 tests/opt_share/generate.py create mode 100755 tests/opt_share/run-test.sh diff --git a/Makefile b/Makefile index 3bc119800..d06c7ab3d 100644 --- a/Makefile +++ b/Makefile @@ -678,6 +678,7 @@ test: $(TARGETS) $(EXTRA_TARGETS) +cd tests/asicworld && bash run-test.sh $(SEEDOPT) # +cd tests/realmath && bash run-test.sh $(SEEDOPT) +cd tests/share && bash run-test.sh $(SEEDOPT) + +cd tests/opt_share && bash run-test.sh $(SEEDOPT) +cd tests/fsm && bash run-test.sh $(SEEDOPT) +cd tests/techmap && bash run-test.sh +cd tests/memories && bash run-test.sh $(ABCOPT) $(SEEDOPT) diff --git a/passes/opt/opt_share.cc b/passes/opt/opt_share.cc index 25b07cbbd..e8f44749a 100644 --- a/passes/opt/opt_share.cc +++ b/passes/opt/opt_share.cc @@ -32,37 +32,36 @@ PRIVATE_NAMESPACE_BEGIN SigMap assign_map; -struct InPort { +struct OpMuxConn { RTLIL::SigSpec sig; - RTLIL::Cell *pmux; - int port_id; - RTLIL::Cell *alu; + RTLIL::Cell *mux; + RTLIL::Cell *op; + int mux_port_id; + int mux_port_offset; + int op_outsig_offset; - InPort(RTLIL::SigSpec s, RTLIL::Cell *c, int p, RTLIL::Cell *a = NULL) : sig(s), pmux(c), port_id(p), alu(a) {} + bool operator<(const OpMuxConn &other) const + { + if (mux != other.mux) + return mux < other.mux; + + if (mux_port_id != other.mux_port_id) + return mux_port_id < other.mux_port_id; + + return mux_port_offset < other.mux_port_offset; + } }; -// Helper class that to track whether a SigSpec is signed and whether it is -// connected to the \\B port of the $sub cell, which makes its sign prefix -// negative. +// Helper class to track additiona information about a SigSpec, like whether it is signed and the semantics of the port it is connected to struct ExtSigSpec { RTLIL::SigSpec sig; RTLIL::SigSpec sign; bool is_signed; + RTLIL::IdString semantics; ExtSigSpec() {} - ExtSigSpec(RTLIL::SigSpec s, bool sign = false, bool is_signed = false) : sig(s), sign(sign), is_signed(is_signed) {} - - ExtSigSpec(RTLIL::Cell *cell, RTLIL::IdString port_name, SigMap *sigmap) - { - sign = (port_name == "\\B") ? cell->getPort("\\BI") : RTLIL::Const(0, 1); - sig = (*sigmap)(cell->getPort(port_name)); - - is_signed = false; - if (cell->hasParam(port_name.str() + "_SIGNED")) { - is_signed = cell->getParam(port_name.str() + "_SIGNED").as_bool(); - } - } + ExtSigSpec(RTLIL::SigSpec s, RTLIL::SigSpec sign = RTLIL::Const(0, 1), bool is_signed = false, RTLIL::IdString semantics = RTLIL::IdString()) : sig(s), sign(sign), is_signed(is_signed), semantics(semantics) {} bool empty() const { return sig.empty(); } @@ -74,42 +73,136 @@ struct ExtSigSpec { if (sign != other.sign) return sign < other.sign; - return is_signed < other.is_signed; + if (is_signed != other.is_signed) + return is_signed < other.is_signed; + + return semantics < other.semantics; } bool operator==(const RTLIL::SigSpec &other) const { return (sign != RTLIL::Const(0, 1)) ? false : sig == other; } - bool operator==(const ExtSigSpec &other) const { return is_signed == other.is_signed && sign == other.sign && sig == other.sig; } + bool operator==(const ExtSigSpec &other) const { return is_signed == other.is_signed && sign == other.sign && sig == other.sig && semantics == other.semantics; } }; -void merge_operators(RTLIL::Module *module, RTLIL::Cell *mux, const std::vector &ports, int offset, int width, - const ExtSigSpec &operand) +#define BITWISE_OPS "$_AND_", "$_NAND_", "$_OR_", "$_NOR_", "$_XOR_", "$_XNOR_", "$_ANDNOT_", "$_ORNOT_", "$and", "$or", "$xor", "$xnor" + +#define REDUCTION_OPS "$reduce_and", "$reduce_or", "$reduce_xor", "$reduce_xnor", "$reduce_bool", "$reduce_nand" + +#define LOGICAL_OPS "$logic_and", "$logic_or" + +#define SHIFT_OPS "$shl", "$shr", "$sshl", "$sshr", "$shift", "$shiftx" + +#define RELATIONAL_OPS "$lt", "$le", "$eq", "$ne", "$eqx", "$nex", "$ge", "$gt" + +bool cell_supported(RTLIL::Cell *cell) +{ + + if (cell->type.in("$alu")) { + RTLIL::SigSpec sig_bi = cell->getPort("\\BI"); + RTLIL::SigSpec sig_ci = cell->getPort("\\CI"); + + if (sig_bi.is_fully_const() && sig_ci.is_fully_const() && sig_bi == sig_ci) + return true; + } else if (cell->type.in(LOGICAL_OPS, SHIFT_OPS, BITWISE_OPS, RELATIONAL_OPS, "$add", "$sub", "$mul", "$div", "$mod", "$concat")) { + return true; + } + + return false; +} + +std::map mergeable_type_map{ + {"$sub", "$add"}, +}; + +bool mergeable(RTLIL::Cell *a, RTLIL::Cell *b) +{ + auto a_type = a->type; + if (mergeable_type_map.count(a_type.str())) + a_type = mergeable_type_map.at(a_type.str()); + + auto b_type = b->type; + if (mergeable_type_map.count(b_type.str())) + b_type = mergeable_type_map.at(b_type.str()); + + return a_type == b_type; +} + +RTLIL::IdString decode_port_semantics(RTLIL::Cell *cell, RTLIL::IdString port_name) +{ + if (cell->type.in("$lt", "$le", "$ge", "$gt", "$div", "$mod", "$concat", SHIFT_OPS) && port_name == "\\B") + return port_name; + + return ""; +} + +RTLIL::SigSpec decode_port_sign(RTLIL::Cell *cell, RTLIL::IdString port_name) { + + if (cell->type == "$alu" && port_name == "\\B") + return cell->getPort("\\BI"); + else if (cell->type == "$sub" && port_name == "\\B") + return RTLIL::Const(1, 1); + + return RTLIL::Const(0, 1); +} + +bool decode_port_signed(RTLIL::Cell *cell, RTLIL::IdString port_name) +{ + if (cell->type.in(BITWISE_OPS, LOGICAL_OPS)) + return false; + + if (cell->hasParam(port_name.str() + "_SIGNED")) + return cell->getParam(port_name.str() + "_SIGNED").as_bool(); + + return false; + +} + +ExtSigSpec decode_port(RTLIL::Cell *cell, RTLIL::IdString port_name, SigMap *sigmap) +{ + auto sig = (*sigmap)(cell->getPort(port_name)); + + RTLIL::SigSpec sign = decode_port_sign(cell, port_name); + RTLIL::IdString semantics = decode_port_semantics(cell, port_name); + + bool is_signed = decode_port_signed(cell, port_name); + + return ExtSigSpec(sig, sign, is_signed, semantics); +} + +void merge_operators(RTLIL::Module *module, RTLIL::Cell *mux, const std::vector &ports, const ExtSigSpec &operand) { std::vector muxed_operands; int max_width = 0; for (const auto& p : ports) { - auto op = p.alu; + auto op = p.op; - for (RTLIL::IdString port_name : {"\\A", "\\B"}) { - if (op->getPort(port_name) != operand.sig) { - auto operand = ExtSigSpec(op, port_name, &assign_map); - if (operand.sig.size() > max_width) { - max_width = operand.sig.size(); - } - - muxed_operands.push_back(operand); - } + RTLIL::IdString muxed_port_name = "\\A"; + if (op->getPort("\\A") == operand.sig) { + muxed_port_name = "\\B"; } + + auto operand = decode_port(op, muxed_port_name, &assign_map); + if (operand.sig.size() > max_width) { + max_width = operand.sig.size(); + } + + muxed_operands.push_back(operand); } + auto shared_op = ports[0].op; + + if (std::any_of(muxed_operands.begin(), muxed_operands.end(), [&](ExtSigSpec &op) { return op.sign != muxed_operands[0].sign; })) + if (max_width < shared_op->getParam("\\Y_WIDTH").as_int()) + max_width = shared_op->getParam("\\Y_WIDTH").as_int(); + + for (auto &operand : muxed_operands) { operand.sig.extend_u0(max_width, operand.is_signed); } - auto shared_op = ports[0].alu; for (const auto& p : ports) { - auto op = p.alu; + auto op = p.op; if (op == shared_op) continue; module->remove(op); @@ -126,40 +219,47 @@ void merge_operators(RTLIL::Module *module, RTLIL::Cell *mux, const std::vector< RTLIL::SigSpec mux_b = mux->getPort("\\B"); RTLIL::SigSpec mux_s = mux->getPort("\\S"); - RTLIL::SigSpec alu_x = shared_op->getPort("\\X"); - RTLIL::SigSpec alu_co = shared_op->getPort("\\CO"); - RTLIL::SigSpec shared_pmux_a = RTLIL::Const(RTLIL::State::Sx, max_width); RTLIL::SigSpec shared_pmux_b; RTLIL::SigSpec shared_pmux_s; - shared_op->setPort("\\Y", shared_op->getPort("\\Y").extract(0, width)); + int conn_width = ports[0].sig.size(); + int conn_offset = ports[0].mux_port_offset; + + shared_op->setPort("\\Y", shared_op->getPort("\\Y").extract(0, conn_width)); if (mux->type == "$pmux") { shared_pmux_s = RTLIL::SigSpec(); - for (const auto&p: ports) { - shared_pmux_s.append(mux_s[p.port_id]); - mux_b.replace(p.port_id * mux_a.size() + offset, shared_op->getPort("\\Y")); + for (const auto &p : ports) { + shared_pmux_s.append(mux_s[p.mux_port_id]); + mux_b.replace(p.mux_port_id * mux_a.size() + conn_offset, shared_op->getPort("\\Y")); } } else { shared_pmux_s = RTLIL::SigSpec{mux_s, module->Not(NEW_ID, mux_s)}; - mux_a.replace(offset, shared_op->getPort("\\Y")); - mux_b.replace(offset, shared_op->getPort("\\Y")); + mux_a.replace(conn_offset, shared_op->getPort("\\Y")); + mux_b.replace(conn_offset, shared_op->getPort("\\Y")); } + mux->setPort("\\A", mux_a); + mux->setPort("\\B", mux_b); mux->setPort("\\Y", mux_y); mux->setPort("\\S", mux_s); - mux->setPort("\\B", mux_b); for (const auto &op : muxed_operands) shared_pmux_b.append(op.sig); auto mux_to_oper = module->Pmux(NEW_ID, shared_pmux_a, shared_pmux_b, shared_pmux_s); - shared_op->setPort("\\X", alu_x.extract(0, width)); - shared_op->setPort("\\CO", alu_co.extract(0, width)); - shared_op->setParam("\\Y_WIDTH", width); + if (shared_op->type.in("$alu")) { + RTLIL::SigSpec alu_x = shared_op->getPort("\\X"); + RTLIL::SigSpec alu_co = shared_op->getPort("\\CO"); + + shared_op->setPort("\\X", alu_x.extract(0, conn_width)); + shared_op->setPort("\\CO", alu_co.extract(0, conn_width)); + } + + shared_op->setParam("\\Y_WIDTH", conn_width); if (shared_op->getPort("\\A") == operand.sig) { shared_op->setPort("\\B", mux_to_oper); @@ -173,11 +273,9 @@ void merge_operators(RTLIL::Module *module, RTLIL::Cell *mux, const std::vector< typedef struct { RTLIL::Cell *mux; - std::vector ports; - int offset; - int width; + std::vector ports; ExtSigSpec shared_operand; -} shared_op_t; +} merged_op_t; template void remove_val(std::vector &v, const std::vector &vals) @@ -190,86 +288,60 @@ template void remove_val(std::vector &v, const std::vector &v } } -bool find_op_res_width(int offset, int &width, std::vector& ports, const dict &op_outbit_to_outsig) +void check_muxed_operands(std::vector &ports, const ExtSigSpec &shared_operand) { - std::vector op_outsigs; - dict> op_outsig_span; + auto it = ports.begin(); + ExtSigSpec seed; - std::transform(ports.begin(), ports.end(), std::back_inserter(op_outsigs), [&](InPort *p) { return op_outbit_to_outsig.at(p->sig[offset]); }); + while (it != ports.end()) { + auto p = *it; + auto op = p->op; - std::vector finished(ports.size(), false); - - width = 0; - - std::function all_finished = [&] { return std::find(std::begin(finished), std::end(finished), false) == end(finished);}; - - while (!all_finished()) - { - ++offset; - ++width; - - if (offset >= ports[0]->sig.size()) { - for (size_t i = 0; i < op_outsigs.size(); ++i) { - if (finished[i]) - continue; - - op_outsig_span[width].insert(ports[i]); - finished[i] = true; - } - - break; + RTLIL::IdString muxed_port_name = "\\A"; + if (op->getPort("\\A") == shared_operand.sig) { + muxed_port_name = "\\B"; } - for (size_t i = 0; i < op_outsigs.size(); ++i) { - if (finished[i]) - continue; + auto operand = decode_port(op, muxed_port_name, &assign_map); - if ((width >= op_outsigs[i].size()) || (ports[i]->sig[offset] != op_outsigs[i][width])) { - op_outsig_span[width].insert(ports[i]); - finished[i] = true; - } + if (seed.empty()) + seed = operand; + + if (operand.is_signed != seed.is_signed) { + ports.erase(it); + } else { + ++it; } } - - for (auto w: op_outsig_span) { - if (w.second.size() > 1) { - width = w.first; - - ports.erase(std::remove_if(ports.begin(), ports.end(), [&](InPort *p) { return !w.second.count(p); }), ports.end()); - - return true; - } - } - - return false; } -ExtSigSpec find_shared_operand(InPort* seed, std::vector &ports, const std::map> &operand_to_users) +ExtSigSpec find_shared_operand(const OpMuxConn* seed, std::vector &ports, const std::map> &operand_to_users) { - std::set alus_using_operand; - std::set alus_set; + std::set ops_using_operand; + std::set ops_set; for(const auto& p: ports) - alus_set.insert(p->alu); + ops_set.insert(p->op); ExtSigSpec oper; - auto op_a = seed->alu; + auto op_a = seed->op; for (RTLIL::IdString port_name : {"\\A", "\\B"}) { - oper = ExtSigSpec(op_a, port_name, &assign_map); + oper = decode_port(op_a, port_name, &assign_map); auto operand_users = operand_to_users.at(oper); if (operand_users.size() == 1) continue; - alus_using_operand.clear(); - std::set_intersection(operand_users.begin(), operand_users.end(), alus_set.begin(), alus_set.end(), - std::inserter(alus_using_operand, alus_using_operand.begin())); + ops_using_operand.clear(); + for (auto mux_ops: ops_set) + if (operand_users.count(mux_ops)) + ops_using_operand.insert(mux_ops); - if (alus_using_operand.size() > 1) { - ports.erase(std::remove_if(ports.begin(), ports.end(), [&](InPort *p) { return !alus_using_operand.count(p->alu); }), - ports.end()); + if (ops_using_operand.size() > 1) { + ports.erase(std::remove_if(ports.begin(), ports.end(), [&](const OpMuxConn *p) { return !ops_using_operand.count(p->op); }), + ports.end()); return oper; } } @@ -277,40 +349,135 @@ ExtSigSpec find_shared_operand(InPort* seed, std::vector &ports, const return ExtSigSpec(); } -void remove_multi_user_outbits(RTLIL::Module *module, dict &op_outbit_to_outsig) +dict find_valid_op_mux_conns(RTLIL::Module *module, dict &op_outbit_to_outsig, + dict outsig_to_operator, + dict &op_aux_to_outsig) { - dict op_outbit_user_cnt; + dict op_outsig_user_track; + dict op_mux_conn_map; + + std::function remove_outsig = [&](RTLIL::SigSpec outsig) { + for (auto op_outbit : outsig) + op_outbit_to_outsig.erase(op_outbit); + + if (op_mux_conn_map.count(outsig)) + op_mux_conn_map.erase(outsig); + }; + + std::function remove_outsig_from_aux_bit = [&](RTLIL::SigBit auxbit) { + auto aux_outsig = op_aux_to_outsig.at(auxbit); + auto op = outsig_to_operator.at(aux_outsig); + auto op_outsig = assign_map(op->getPort("\\Y")); + remove_outsig(op_outsig); + + for (auto aux_outbit : aux_outsig) + op_aux_to_outsig.erase(aux_outbit); + }; + + std::function + find_op_mux_conns = [&](RTLIL::Cell *mux) { + RTLIL::SigSpec sig; + int mux_port_size; + + if (mux->type.in("$mux", "$_MUX_")) { + mux_port_size = mux->getPort("\\A").size(); + sig = RTLIL::SigSpec{mux->getPort("\\B"), mux->getPort("\\A")}; + } else { + mux_port_size = mux->getPort("\\A").size(); + sig = mux->getPort("\\B"); + } + + auto mux_insig = assign_map(sig); + + for (int i = 0; i < mux_insig.size(); ++i) { + if (op_aux_to_outsig.count(mux_insig[i])) { + remove_outsig_from_aux_bit(mux_insig[i]); + continue; + } + + if (!op_outbit_to_outsig.count(mux_insig[i])) + continue; + + auto op_outsig = op_outbit_to_outsig.at(mux_insig[i]); + + if (op_mux_conn_map.count(op_outsig)) { + remove_outsig(op_outsig); + continue; + } + + int mux_port_id = i / mux_port_size; + int mux_port_offset = i % mux_port_size; + + int op_outsig_offset; + for (op_outsig_offset = 0; op_outsig[op_outsig_offset] != mux_insig[i]; ++op_outsig_offset) + ; + + int j = op_outsig_offset; + do { + if (!op_outbit_to_outsig.count(mux_insig[i])) + break; + + if (op_outbit_to_outsig.at(mux_insig[i]) != op_outsig) + break; + + ++i; + ++j; + } while ((i / mux_port_size == mux_port_id) && (j < op_outsig.size())); + + int op_conn_width = j - op_outsig_offset; + OpMuxConn inp = { + op_outsig.extract(op_outsig_offset, op_conn_width), + mux, + outsig_to_operator.at(op_outsig), + mux_port_id, + mux_port_offset, + op_outsig_offset, + }; + + op_mux_conn_map[op_outsig] = inp; + + --i; + } + }; + + std::function remove_connected_ops = [&](RTLIL::SigSpec sig) { + auto mux_insig = assign_map(sig); + for (auto outbit : mux_insig) { + if (op_aux_to_outsig.count(outbit)) { + remove_outsig_from_aux_bit(outbit); + continue; + } - std::function update_op_outbit_user_cnt = [&](SigSpec sig) { - auto outsig = assign_map(sig); - for (auto outbit : outsig) { if (!op_outbit_to_outsig.count(outbit)) continue; - if (++op_outbit_user_cnt[outbit] > 1) { - auto alu_outsig = op_outbit_to_outsig.at(outbit); - - for (auto outbit : alu_outsig) - op_outbit_to_outsig.erase(outbit); - } + remove_outsig(op_outbit_to_outsig.at(outbit)); } }; - for (auto cell : module->cells()) - for (auto &conn : cell->connections()) - if (cell->input(conn.first)) - update_op_outbit_user_cnt(conn.second); + for (auto cell : module->cells()) { + if (cell->type.in("$mux", "$_MUX_", "$pmux")) { + remove_connected_ops(cell->getPort("\\S")); + find_op_mux_conns(cell); + } else { + for (auto &conn : cell->connections()) + if (cell->input(conn.first)) + remove_connected_ops(conn.second); + } + } for (auto w : module->wires()) { if (!w->port_output) continue; - update_op_outbit_user_cnt(w); + remove_connected_ops(w); } + + return op_mux_conn_map; } struct OptSharePass : public Pass { - OptSharePass() : Pass("opt_share", "merge arithmetic operators that share an operand") {} + OptSharePass() : Pass("opt_share", "merge mutually exclusive cells of the same type that share an input signal") {} void help() YS_OVERRIDE { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| @@ -318,18 +485,19 @@ struct OptSharePass : public Pass { log(" opt_share [selection]\n"); log("\n"); - log("This pass identifies mutually exclusive $alu arithmetic cells that:\n"); - log(" (a) share an input operand\n"); + log("This pass identifies mutually exclusive cells of the same type that:\n"); + log(" (a) share an input signal\n"); log(" (b) drive the same $mux, $_MUX_, or $pmux multiplexing cell allowing\n"); - log(" the $alu cell to be merged and the multiplexer to be moved from\n"); - log(" multiplexing its output to multiplexing the non-shared input operands.\n"); + log(" the cell to be merged and the multiplexer to be moved from\n"); + log(" multiplexing its output to multiplexing the non-shared input signals.\n"); log("\n"); } - void execute(std::vector, RTLIL::Design *design) YS_OVERRIDE + void execute(std::vector args, RTLIL::Design *design) YS_OVERRIDE { log_header(design, "Executing OPT_SHARE pass.\n"); + extra_args(args, 1, design); for (auto module : design->selected_modules()) { assign_map.clear(); assign_map.set(module); @@ -337,28 +505,30 @@ struct OptSharePass : public Pass { std::map> operand_to_users; dict outsig_to_operator; dict op_outbit_to_outsig; + dict op_aux_to_outsig; bool any_shared_operands = false; std::vector op_insigs; for (auto cell : module->cells()) { - if (!cell->type.in("$alu")) + if (!cell_supported(cell)) continue; - RTLIL::SigSpec sig_bi = cell->getPort("\\BI"); - RTLIL::SigSpec sig_ci = cell->getPort("\\CI"); + if (cell->type == "$alu") { + for (RTLIL::IdString port_name : {"\\X", "\\CO"}) { + auto mux_insig = assign_map(cell->getPort(port_name)); + outsig_to_operator[mux_insig] = cell; + for (auto outbit : mux_insig) + op_aux_to_outsig[outbit] = mux_insig; + } + } - if ((!sig_bi.is_fully_const()) || (!sig_ci.is_fully_const()) || (sig_bi != sig_ci)) - continue; - - RTLIL::SigSpec sig_y = cell->getPort("\\A"); - - auto outsig = assign_map(cell->getPort("\\Y")); - outsig_to_operator[outsig] = cell; - for (auto outbit : outsig) - op_outbit_to_outsig[outbit] = outsig; + auto mux_insig = assign_map(cell->getPort("\\Y")); + outsig_to_operator[mux_insig] = cell; + for (auto outbit : mux_insig) + op_outbit_to_outsig[outbit] = mux_insig; for (RTLIL::IdString port_name : {"\\A", "\\B"}) { - auto op_insig = ExtSigSpec(cell, port_name, &assign_map); + auto op_insig = decode_port(cell, port_name, &assign_map); op_insigs.push_back(op_insig); operand_to_users[op_insig].insert(cell); if (operand_to_users[op_insig].size() > 1) @@ -371,89 +541,117 @@ struct OptSharePass : public Pass { // Operator outputs need to be exclusively connected to the $mux inputs in order to be mergeable. Hence we count to // how many points are operator output bits connected. - remove_multi_user_outbits(module, op_outbit_to_outsig); + dict op_mux_conn_map = + find_valid_op_mux_conns(module, op_outbit_to_outsig, outsig_to_operator, op_aux_to_outsig); - std::vector shared_ops; - for (auto cell : module->cells()) { - if (!cell->type.in("$mux", "$_MUX_", "$pmux")) - continue; + // Group op connections connected to same ports of the same $mux. Sort them in ascending order of their port offset + dict>> mux_port_op_conns; + for (auto& val: op_mux_conn_map) { + OpMuxConn p = val.second; + auto& mux_port_conns = mux_port_op_conns[p.mux]; - RTLIL::SigSpec sig_a = cell->getPort("\\A"); - RTLIL::SigSpec sig_b = cell->getPort("\\B"); - RTLIL::SigSpec sig_s = cell->getPort("\\S"); + if (mux_port_conns.size() == 0) { + int mux_port_num; - std::vector ports; + if (p.mux->type.in("$mux", "$_MUX_")) + mux_port_num = 2; + else + mux_port_num = p.mux->getPort("\\S").size(); - if (cell->type.in("$mux", "$_MUX_")) { - ports.push_back(InPort(assign_map(sig_a), cell, 0)); - ports.push_back(InPort(assign_map(sig_b), cell, 1)); - } else { - RTLIL::SigSpec sig_s = cell->getPort("\\S"); - for (int i = 0; i < sig_s.size(); i++) { - auto inp = sig_b.extract(i * sig_a.size(), sig_a.size()); - ports.push_back(InPort(assign_map(inp), cell, i)); - } + mux_port_conns.resize(mux_port_num); } + mux_port_conns[p.mux_port_id].insert(p); + } + + std::vector merged_ops; + for (auto& val: mux_port_op_conns) { + + RTLIL::Cell* cell = val.first; + auto &mux_port_conns = val.second; + + const OpMuxConn *seed = NULL; + // Look through the bits of the $mux inputs and see which of them are connected to the operator // results. Operator results can be concatenated with other signals before led to the $mux. - for (int i = 0; i < sig_a.size(); ++i) { - std::vector alu_ports; - for (auto& p: ports) - if (op_outbit_to_outsig.count(p.sig[i])) { - p.alu = outsig_to_operator.at(op_outbit_to_outsig.at(p.sig[i])); - alu_ports.push_back(&p); - } + while (true) { - int alu_port_width = 0; - - while (alu_ports.size() > 1) { - std::vector shared_ports(alu_ports); - - auto seed = alu_ports[0]; - alu_ports.erase(alu_ports.begin()); - - // Find ports whose $alu-s share an operand with $alu connected to the seed port - auto shared_operand = find_shared_operand(seed, shared_ports, operand_to_users); - - if (shared_operand.empty()) - continue; - - // Some bits of the operator results might be unconnected. Calculate the number of conneted - // bits. - if (!find_op_res_width(i, alu_port_width, shared_ports, op_outbit_to_outsig)) - break; - - if (shared_ports.size() < 2) - break; - - // Remember the combination for the merger - std::vector shared_p; - for (auto p: shared_ports) - shared_p.push_back(*p); - - shared_ops.push_back(shared_op_t{cell, shared_p, i, alu_port_width, shared_operand}); - - // Remove merged ports from the list and try to find other mergers for the mux - remove_val(alu_ports, shared_ports); + // Remove either the merged ports from the last iteration or the seed that failed to yield a merger + if (seed != NULL) { + mux_port_conns[seed->mux_port_id].erase(*seed); + seed = NULL; } - if (alu_port_width) - i += alu_port_width - 1; + // For a new merger, find the seed op connection that starts at lowest port offset among port connections + for (auto &port_conns : mux_port_conns) { + if (!port_conns.size()) + continue; + + const OpMuxConn *next_p = &(*port_conns.begin()); + + if ((seed == NULL) || (seed->mux_port_offset > next_p->mux_port_offset)) + seed = next_p; + } + + // Cannot find the seed -> nothing to do for this $mux anymore + if (seed == NULL) + break; + + // Find all other op connections that start from the same port offset, and whose ops can be merged with the seed op + std::vector mergeable_conns; + for (auto &port_conns : mux_port_conns) { + if (!port_conns.size()) + continue; + + const OpMuxConn *next_p = &(*port_conns.begin()); + + if ((next_p->op_outsig_offset == seed->op_outsig_offset) && + (next_p->mux_port_offset == seed->mux_port_offset) && mergeable(next_p->op, seed->op) && + next_p->sig.size() == seed->sig.size()) + mergeable_conns.push_back(next_p); + } + + // We need at least two mergeable connections for the merger + if (mergeable_conns.size() < 2) + continue; + + // Filter mergeable connections whose ops share an operand with seed connection's op + auto shared_operand = find_shared_operand(seed, mergeable_conns, operand_to_users); + + if (shared_operand.empty()) + continue; + + check_muxed_operands(mergeable_conns, shared_operand); + + if (mergeable_conns.size() < 2) + continue; + + // Remember the combination for the merger + std::vector merged_ports; + for (auto p : mergeable_conns) { + merged_ports.push_back(*p); + mux_port_conns[p->mux_port_id].erase(*p); + } + + seed = NULL; + + merged_ops.push_back(merged_op_t{cell, merged_ports, shared_operand}); + + design->scratchpad_set_bool("opt.did_something", true); } } - for (auto &shared : shared_ops) { - log(" Found arithmetic cells that share an operand and can be merged by moving the %s %s in front " + for (auto &shared : merged_ops) { + log(" Found cells that share an operand and can be merged by moving the %s %s in front " "of " "them:\n", log_id(shared.mux->type), log_id(shared.mux)); for (const auto& op : shared.ports) - log(" %s\n", log_id(op.alu)); + log(" %s\n", log_id(op.op)); log("\n"); - merge_operators(module, shared.mux, shared.ports, shared.offset, shared.width, shared.shared_operand); + merge_operators(module, shared.mux, shared.ports, shared.shared_operand); } } } diff --git a/tests/opt_share/.gitignore b/tests/opt_share/.gitignore new file mode 100644 index 000000000..9c595a6fb --- /dev/null +++ b/tests/opt_share/.gitignore @@ -0,0 +1 @@ +temp diff --git a/tests/opt_share/generate.py b/tests/opt_share/generate.py new file mode 100644 index 000000000..2ec92f7de --- /dev/null +++ b/tests/opt_share/generate.py @@ -0,0 +1,86 @@ +#!/usr/bin/env python3 + +import argparse +import sys +import random +from contextlib import contextmanager + + +@contextmanager +def redirect_stdout(new_target): + old_target, sys.stdout = sys.stdout, new_target + try: + yield new_target + finally: + sys.stdout = old_target + + +def random_plus_x(): + return "%s x" % random.choice(['+', '+', '+', '-', '-', '|', '&', '^']) + + +def maybe_plus_x(expr): + if random.randint(0, 4) == 0: + return "(%s %s)" % (expr, random_plus_x()) + else: + return expr + + +parser = argparse.ArgumentParser( + formatter_class=argparse.ArgumentDefaultsHelpFormatter) +parser.add_argument('-S', '--seed', type=int, help='seed for PRNG') +parser.add_argument('-c', + '--count', + type=int, + default=100, + help='number of test cases to generate') +args = parser.parse_args() + +if args.seed is not None: + print("PRNG seed: %d" % args.seed) + random.seed(args.seed) + +for idx in range(args.count): + with open('temp/uut_%05d.v' % idx, 'w') as f: + with redirect_stdout(f): + print('module uut_%05d(a, b, c, s, y);' % (idx)) + op = random.choice([ + random.choice(['+', '-', '*', '/', '%']), + random.choice(['<', '<=', '==', '!=', '===', '!==', '>=', + '>']), + random.choice(['<<', '>>', '<<<', '>>>']), + random.choice(['|', '&', '^', '~^', '||', '&&']), + ]) + print(' input%s [%d:0] a;' % (random.choice(['', ' signed']), 8)) + print(' input%s [%d:0] b;' % (random.choice(['', ' signed']), 8)) + print(' input%s [%d:0] c;' % (random.choice(['', ' signed']), 8)) + print(' input s;') + print(' output [%d:0] y;' % 8) + ops1 = ['a', 'b'] + ops2 = ['a', 'c'] + random.shuffle(ops1) + random.shuffle(ops2) + cast1 = random.choice(['', '$signed', '$unsigned']) + cast2 = random.choice(['', '$signed', '$unsigned']) + print(' assign y = (s ? %s(%s %s %s) : %s(%s %s %s));' % + (cast1, ops1[0], op, ops1[1], + cast2, ops2[0], op, ops2[1])) + print('endmodule') + + with open('temp/uut_%05d.ys' % idx, 'w') as f: + with redirect_stdout(f): + print('read_verilog temp/uut_%05d.v' % idx) + print('proc;;') + print('copy uut_%05d gold' % idx) + print('rename uut_%05d gate' % idx) + print('tee -a temp/all_share_log.txt log') + print('tee -a temp/all_share_log.txt log #job# uut_%05d' % idx) + print('tee -a temp/all_share_log.txt opt gate') + print('tee -a temp/all_share_log.txt opt_share gate') + print('tee -a temp/all_share_log.txt opt_clean gate') + print( + 'miter -equiv -flatten -ignore_gold_x -make_outputs -make_outcmp gold gate miter' + ) + print( + 'sat -set-def-inputs -verify -prove trigger 0 -show-inputs -show-outputs miter' + ) diff --git a/tests/opt_share/run-test.sh b/tests/opt_share/run-test.sh new file mode 100755 index 000000000..e01552646 --- /dev/null +++ b/tests/opt_share/run-test.sh @@ -0,0 +1,39 @@ +#!/bin/bash + +# run this test many times: +# time bash -c 'for ((i=0; i<100; i++)); do echo "-- $i --"; bash run-test.sh || exit 1; done' + +set -e + +OPTIND=1 +count=100 +seed="" # default to no seed specified +while getopts "c:S:" opt +do + case "$opt" in + c) count="$OPTARG" ;; + S) seed="-S $OPTARG" ;; + esac +done +shift "$((OPTIND-1))" + +rm -rf temp +mkdir -p temp +echo "generating tests.." +python3 generate.py -c $count $seed + +echo "running tests.." +for i in $( ls temp/*.ys | sed 's,[^0-9],,g; s,^0*\(.\),\1,g;' ); do + echo -n "[$i]" + idx=$( printf "%05d" $i ) + ../../yosys -ql temp/uut_${idx}.log temp/uut_${idx}.ys +done +echo + +failed_share=$( echo $( gawk '/^#job#/ { j=$2; db[j]=0; } /^Removing [246] cells/ { delete db[j]; } END { for (j in db) print(j); }' temp/all_share_log.txt ) ) +if [ -n "$failed_share" ]; then + echo "Resource sharing failed for the following test cases: $failed_share" + false +fi + +exit 0 From 7de098ad4521a78ca109f261a53d50846f8f5667 Mon Sep 17 00:00:00 2001 From: Ben Widawsky Date: Mon, 5 Aug 2019 10:41:35 -0700 Subject: [PATCH 15/94] techlibs/intel: Clean up Makefile Use GNU make's foreach iterator and remove nonexistent files. Gmake is already a requirement of the build system. Signed-off-by: Ben Widawsky --- techlibs/intel/Makefile.inc | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/techlibs/intel/Makefile.inc b/techlibs/intel/Makefile.inc index 7a3d2c71a..4e8f423c8 100644 --- a/techlibs/intel/Makefile.inc +++ b/techlibs/intel/Makefile.inc @@ -5,20 +5,10 @@ $(eval $(call add_share_file,share/intel/common,techlibs/intel/common/m9k_bb.v)) $(eval $(call add_share_file,share/intel/common,techlibs/intel/common/altpll_bb.v)) $(eval $(call add_share_file,share/intel/common,techlibs/intel/common/brams_m9k.txt)) $(eval $(call add_share_file,share/intel/common,techlibs/intel/common/brams_map_m9k.v)) -$(eval $(call add_share_file,share/intel/max10,techlibs/intel/max10/cells_sim.v)) -$(eval $(call add_share_file,share/intel/a10gx,techlibs/intel/a10gx/cells_sim.v)) -$(eval $(call add_share_file,share/intel/cyclonev,techlibs/intel/cyclonev/cells_sim.v)) -$(eval $(call add_share_file,share/intel/cyclone10,techlibs/intel/cyclone10/cells_sim.v)) -$(eval $(call add_share_file,share/intel/cycloneiv,techlibs/intel/cycloneiv/cells_sim.v)) -$(eval $(call add_share_file,share/intel/cycloneive,techlibs/intel/cycloneive/cells_sim.v)) -$(eval $(call add_share_file,share/intel/max10,techlibs/intel/max10/cells_map.v)) -$(eval $(call add_share_file,share/intel/a10gx,techlibs/intel/a10gx/cells_map.v)) -$(eval $(call add_share_file,share/intel/cyclonev,techlibs/intel/cyclonev/cells_map.v)) -$(eval $(call add_share_file,share/intel/cyclone10,techlibs/intel/cyclone10/cells_map.v)) -$(eval $(call add_share_file,share/intel/cycloneiv,techlibs/intel/cycloneiv/cells_map.v)) -$(eval $(call add_share_file,share/intel/cycloneive,techlibs/intel/cycloneive/cells_map.v)) -#$(eval $(call add_share_file,share/intel/max10,techlibs/intel/max10/arith_map.v)) -#$(eval $(call add_share_file,share/intel/a10gx,techlibs/intel/a10gx/arith_map.v)) -#$(eval $(call add_share_file,share/intel/cycloneiv,techlibs/intel/cycloneiv/arith_map.v)) + +# Add the cell models and mappings for the VQM backend +families := max10 a10gx cyclonev cyclone10 cycloneiv cycloneive +$(foreach family,$(families), $(eval $(call add_share_file,share/intel/$(family),techlibs/intel/$(family)/cells_sim.v))) +$(foreach family,$(families), $(eval $(call add_share_file,share/intel/$(family),techlibs/intel/$(family)/cells_map.v))) #$(eval $(call add_share_file,share/intel/cycloneive,techlibs/intel/cycloneive/arith_map.v)) From 067b44938c1fd3e24fc9478b96a47bac7152c111 Mon Sep 17 00:00:00 2001 From: Bogdan Vukobratovic Date: Wed, 7 Aug 2019 09:30:58 +0200 Subject: [PATCH 16/94] Fix wrong results when opt_share called before opt_clean --- passes/opt/opt_share.cc | 32 ++++++++----------- .../opt/opt_share_large_pmux_cat_multipart.ys | 1 - 2 files changed, 14 insertions(+), 19 deletions(-) diff --git a/passes/opt/opt_share.cc b/passes/opt/opt_share.cc index e8f44749a..a2ec9cc37 100644 --- a/passes/opt/opt_share.cc +++ b/passes/opt/opt_share.cc @@ -138,7 +138,7 @@ RTLIL::SigSpec decode_port_sign(RTLIL::Cell *cell, RTLIL::IdString port_name) { if (cell->type == "$alu" && port_name == "\\B") return cell->getPort("\\BI"); - else if (cell->type == "$sub" && port_name == "\\B") + else if (cell->type == "$sub" && port_name == "\\B") return RTLIL::Const(1, 1); return RTLIL::Const(0, 1); @@ -177,14 +177,12 @@ void merge_operators(RTLIL::Module *module, RTLIL::Cell *mux, const std::vector< auto op = p.op; RTLIL::IdString muxed_port_name = "\\A"; - if (op->getPort("\\A") == operand.sig) { + if (decode_port(op, "\\A", &assign_map) == operand) muxed_port_name = "\\B"; - } auto operand = decode_port(op, muxed_port_name, &assign_map); - if (operand.sig.size() > max_width) { + if (operand.sig.size() > max_width) max_width = operand.sig.size(); - } muxed_operands.push_back(operand); } @@ -196,10 +194,8 @@ void merge_operators(RTLIL::Module *module, RTLIL::Cell *mux, const std::vector< max_width = shared_op->getParam("\\Y_WIDTH").as_int(); - for (auto &operand : muxed_operands) { + for (auto &operand : muxed_operands) operand.sig.extend_u0(max_width, operand.is_signed); - } - for (const auto& p : ports) { auto op = p.op; @@ -208,11 +204,10 @@ void merge_operators(RTLIL::Module *module, RTLIL::Cell *mux, const std::vector< module->remove(op); } - for (auto &muxed_op : muxed_operands) { - if (muxed_op.sign != muxed_operands[0].sign) { + for (auto &muxed_op : muxed_operands) + if (muxed_op.sign != muxed_operands[0].sign) muxed_op = ExtSigSpec(module->Neg(NEW_ID, muxed_op.sig, muxed_op.is_signed)); - } - } + RTLIL::SigSpec mux_y = mux->getPort("\\Y"); RTLIL::SigSpec mux_a = mux->getPort("\\A"); @@ -261,7 +256,7 @@ void merge_operators(RTLIL::Module *module, RTLIL::Cell *mux, const std::vector< shared_op->setParam("\\Y_WIDTH", conn_width); - if (shared_op->getPort("\\A") == operand.sig) { + if (decode_port(shared_op, "\\A", &assign_map) == operand) { shared_op->setPort("\\B", mux_to_oper); shared_op->setParam("\\B_WIDTH", max_width); } else { @@ -299,7 +294,7 @@ void check_muxed_operands(std::vector &ports, const ExtSigSpe auto op = p->op; RTLIL::IdString muxed_port_name = "\\A"; - if (op->getPort("\\A") == shared_operand.sig) { + if (decode_port(op, "\\A", &assign_map) == shared_operand) { muxed_port_name = "\\B"; } @@ -486,10 +481,11 @@ struct OptSharePass : public Pass { log("\n"); log("This pass identifies mutually exclusive cells of the same type that:\n"); - log(" (a) share an input signal\n"); - log(" (b) drive the same $mux, $_MUX_, or $pmux multiplexing cell allowing\n"); - log(" the cell to be merged and the multiplexer to be moved from\n"); - log(" multiplexing its output to multiplexing the non-shared input signals.\n"); + log(" (a) share an input signal,\n"); + log(" (b) drive the same $mux, $_MUX_, or $pmux multiplexing cell,\n"); + log("\n"); + log("allowing the cell to be merged and the multiplexer to be moved from\n"); + log("multiplexing its output to multiplexing the non-shared input signals.\n"); log("\n"); } void execute(std::vector args, RTLIL::Design *design) YS_OVERRIDE diff --git a/tests/opt/opt_share_large_pmux_cat_multipart.ys b/tests/opt/opt_share_large_pmux_cat_multipart.ys index 54d200dc7..610bb8c6c 100644 --- a/tests/opt/opt_share_large_pmux_cat_multipart.ys +++ b/tests/opt/opt_share_large_pmux_cat_multipart.ys @@ -7,7 +7,6 @@ opt merged opt_share merged opt_clean merged -opt -full miter -equiv -flatten -ignore_gold_x -make_outputs -make_outcmp opt_share_test merged miter sat -set-def-inputs -verify -prove trigger 0 -show-inputs -show-outputs miter From d51b135e331326032b003934905c17750e116014 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Fri, 9 Aug 2019 12:37:10 +0200 Subject: [PATCH 17/94] Fix CO --- techlibs/efinix/arith_map.v | 50 ++++++++++++++++++------------------- 1 file changed, 24 insertions(+), 26 deletions(-) diff --git a/techlibs/efinix/arith_map.v b/techlibs/efinix/arith_map.v index ae955663c..ef903171f 100644 --- a/techlibs/efinix/arith_map.v +++ b/techlibs/efinix/arith_map.v @@ -31,7 +31,7 @@ module _80_efinix_alu (A, B, CI, BI, X, Y, CO); output [Y_WIDTH-1:0] X, Y; input CI, BI; - output CO; + output [Y_WIDTH-1:0] CO; wire _TECHMAP_FAIL_ = Y_WIDTH <= 2; @@ -41,38 +41,36 @@ module _80_efinix_alu (A, B, CI, BI, X, Y, CO); wire [Y_WIDTH-1:0] AA = A_buf; wire [Y_WIDTH-1:0] BB = BI ? ~B_buf : B_buf; - wire [Y_WIDTH+1:0] COx; - wire [Y_WIDTH+2:0] C = {COx, CI}; + wire [Y_WIDTH:0] C; - EFX_ADD #(.I0_POLARITY(1'b1),.I1_POLARITY(1'b1)) - adder_cin ( - .I0(C[0]), + EFX_ADD #(.I0_POLARITY(1'b1),.I1_POLARITY(1'b1)) + adder_cin ( + .I0(CI), .I1(1'b1), .CI(1'b0), - .CO(COx[0]) + .CO(C[0]) ); genvar i; generate for (i = 0; i < Y_WIDTH; i = i + 1) begin: slice - EFX_ADD #(.I0_POLARITY(1'b1),.I1_POLARITY(1'b1)) - adder_i ( - .I0(AA[i]), - .I1(BB[i]), - .CI(C[i+1]), - .O(Y[i]), - .CO(COx[i+1]) - ); - end: slice + EFX_ADD #(.I0_POLARITY(1'b1),.I1_POLARITY(1'b1)) + adder_i ( + .I0(AA[i]), + .I1(BB[i]), + .CI(C[i]), + .O(Y[i]), + .CO(C[i+1]) + ); + EFX_ADD #(.I0_POLARITY(1'b1),.I1_POLARITY(1'b1)) + adder_cout ( + .I0(1'b0), + .I1(1'b0), + .CI(C[i+1]), + .O(CO[i]) + ); + end: slice endgenerate - EFX_ADD #(.I0_POLARITY(1'b1),.I1_POLARITY(1'b1)) - adder_cout ( - .I0(1'b0), - .I1(1'b0), - .CI(C[Y_WIDTH+1]), - .O(COx[Y_WIDTH+1]) - ); - assign CO = COx[Y_WIDTH+1]; - /* End implementation */ - assign X = AA ^ BB; + /* End implementation */ + assign X = AA ^ BB; endmodule \ No newline at end of file From b3a91d6508943c8e5656af0a624e6ad115aec9c3 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Sun, 11 Aug 2019 08:37:56 +0200 Subject: [PATCH 18/94] cleanup --- techlibs/efinix/arith_map.v | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/techlibs/efinix/arith_map.v b/techlibs/efinix/arith_map.v index ef903171f..56e1b039f 100644 --- a/techlibs/efinix/arith_map.v +++ b/techlibs/efinix/arith_map.v @@ -32,6 +32,9 @@ module _80_efinix_alu (A, B, CI, BI, X, Y, CO); input CI, BI; output [Y_WIDTH-1:0] CO; + + wire CIx; + wire [Y_WIDTH-1:0] COx; wire _TECHMAP_FAIL_ = Y_WIDTH <= 2; @@ -41,14 +44,14 @@ module _80_efinix_alu (A, B, CI, BI, X, Y, CO); wire [Y_WIDTH-1:0] AA = A_buf; wire [Y_WIDTH-1:0] BB = BI ? ~B_buf : B_buf; - wire [Y_WIDTH:0] C; + wire [Y_WIDTH-1:0] C = { COx, CIx }; EFX_ADD #(.I0_POLARITY(1'b1),.I1_POLARITY(1'b1)) adder_cin ( .I0(CI), .I1(1'b1), .CI(1'b0), - .CO(C[0]) + .CO(CIx) ); genvar i; @@ -59,13 +62,13 @@ module _80_efinix_alu (A, B, CI, BI, X, Y, CO); .I1(BB[i]), .CI(C[i]), .O(Y[i]), - .CO(C[i+1]) + .CO(COx[i]) ); EFX_ADD #(.I0_POLARITY(1'b1),.I1_POLARITY(1'b1)) adder_cout ( .I0(1'b0), .I1(1'b0), - .CI(C[i+1]), + .CI(COx[i]), .O(CO[i]) ); end: slice From 8c8100e0df51401870fba13fccf5240461f76051 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Sun, 11 Aug 2019 10:17:49 +0200 Subject: [PATCH 19/94] Adding new pass to fix carry chain --- techlibs/efinix/Makefile.inc | 1 + techlibs/efinix/efinix_fixcarry.cc | 122 +++++++++++++++++++++++++++++ techlibs/efinix/synth_efinix.cc | 1 + 3 files changed, 124 insertions(+) create mode 100644 techlibs/efinix/efinix_fixcarry.cc diff --git a/techlibs/efinix/Makefile.inc b/techlibs/efinix/Makefile.inc index d0593baec..47dadccdd 100644 --- a/techlibs/efinix/Makefile.inc +++ b/techlibs/efinix/Makefile.inc @@ -2,6 +2,7 @@ OBJS += techlibs/efinix/synth_efinix.o OBJS += techlibs/efinix/efinix_gbuf.o OBJS += techlibs/efinix/efinix_determine_init.o +OBJS += techlibs/efinix/efinix_fixcarry.o $(eval $(call add_share_file,share/efinix,techlibs/efinix/cells_map.v)) $(eval $(call add_share_file,share/efinix,techlibs/efinix/arith_map.v)) diff --git a/techlibs/efinix/efinix_fixcarry.cc b/techlibs/efinix/efinix_fixcarry.cc new file mode 100644 index 000000000..b7cd995b8 --- /dev/null +++ b/techlibs/efinix/efinix_fixcarry.cc @@ -0,0 +1,122 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2019 Miodrag Milanovic + * + * 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 + +static SigBit get_bit_or_zero(const SigSpec &sig) +{ + if (GetSize(sig) == 0) + return State::S0; + return sig[0]; +} + +static void fix_carry_chain(Module *module) +{ + SigMap sigmap(module); + + pool ci_bits; + dict mapping_bits; + + for (auto cell : module->cells()) + { + if (cell->type == "\\EFX_ADD") { + SigBit bit_i0 = get_bit_or_zero(cell->getPort("\\I0")); + SigBit bit_i1 = get_bit_or_zero(cell->getPort("\\I1")); + if (bit_i0 == State::S0 && bit_i1== State::S0) { + SigBit bit_ci = get_bit_or_zero(cell->getPort("\\CI")); + SigBit bit_o = sigmap(cell->getPort("\\O")); + ci_bits.insert(bit_ci); + mapping_bits[bit_ci] = bit_o; + } + } + } + + vector adders_to_fix_cells; + for (auto cell : module->cells()) + { + if (cell->type == "\\EFX_ADD") { + SigBit bit_ci = get_bit_or_zero(cell->getPort("\\CI")); + SigBit bit_i0 = get_bit_or_zero(cell->getPort("\\I0")); + SigBit bit_i1 = get_bit_or_zero(cell->getPort("\\I1")); + SigBit canonical_bit = sigmap(bit_ci); + if (!ci_bits.count(canonical_bit)) + continue; + if (bit_i0 == State::S0 && bit_i1== State::S0) + continue; + + adders_to_fix_cells.push_back(cell); + log("Found %s cell named %s with invalid CI signal.\n", log_id(cell->type), log_id(cell)); + } + } + + for (auto cell : adders_to_fix_cells) + { + SigBit bit_ci = get_bit_or_zero(cell->getPort("\\CI")); + SigBit canonical_bit = sigmap(bit_ci); + auto bit = mapping_bits.at(canonical_bit); + log("Fixing %s cell named %s breaking carry chain.\n", log_id(cell->type), log_id(cell)); + Cell *c = module->addCell(NEW_ID, "\\EFX_ADD"); + SigBit new_bit = module->addWire(NEW_ID); + c->setParam("\\I0_POLARITY", State::S1); + c->setParam("\\I1_POLARITY", State::S1); + c->setPort("\\I0", bit); + c->setPort("\\I1", State::S1); + c->setPort("\\CI", State::S0); + c->setPort("\\CO", new_bit); + + cell->setPort("\\CI", new_bit); + } +} + +struct EfinixCarryFixPass : public Pass { + EfinixCarryFixPass() : Pass("efinix_fixcarry", "Efinix: fix carry chain") { } + void help() YS_OVERRIDE + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" efinix_fixcarry [options] [selection]\n"); + log("\n"); + log("Add Efinix adders to fix carry chain if needed.\n"); + log("\n"); + } + void execute(std::vector args, RTLIL::Design *design) YS_OVERRIDE + { + log_header(design, "Executing efinix_fixcarry pass (fix invalid carry chain).\n"); + + size_t argidx; + for (argidx = 1; argidx < args.size(); argidx++) + { + break; + } + extra_args(args, argidx, design); + + Module *module = design->top_module(); + + if (module == nullptr) + log_cmd_error("No top module found.\n"); + + fix_carry_chain(module); + } +} EfinixCarryFixPass; + +PRIVATE_NAMESPACE_END diff --git a/techlibs/efinix/synth_efinix.cc b/techlibs/efinix/synth_efinix.cc index 000a17310..d64491ca8 100644 --- a/techlibs/efinix/synth_efinix.cc +++ b/techlibs/efinix/synth_efinix.cc @@ -191,6 +191,7 @@ struct SynthEfinixPass : public ScriptPass if (check_label("map_gbuf")) { run("efinix_gbuf"); + run("efinix_fixcarry"); run("clean"); } From e609537e386535047f045bf0b8df7ebc5f23c469 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Sun, 11 Aug 2019 10:46:48 +0200 Subject: [PATCH 20/94] Fixed data width --- techlibs/efinix/brams_map.v | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/techlibs/efinix/brams_map.v b/techlibs/efinix/brams_map.v index 9ef01d026..3236f39a5 100644 --- a/techlibs/efinix/brams_map.v +++ b/techlibs/efinix/brams_map.v @@ -22,8 +22,8 @@ module \$__EFINIX_5K (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN); localparam WRITEMODE_A = TRANSP2 ? "WRITE_FIRST" : "READ_FIRST"; EFX_RAM_5K #( - .READ_WIDTH(20), - .WRITE_WIDTH(20), + .READ_WIDTH(CFG_DBITS), + .WRITE_WIDTH(CFG_DBITS), .OUTPUT_REG(1'b0), .RCLK_POLARITY(1'b1), .RE_POLARITY(1'b1), From 853c755a0ca67ae0a75b5cf7783e395d9f49f389 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Sun, 11 Aug 2019 11:01:46 +0200 Subject: [PATCH 21/94] Replaced custom step with setundef --- techlibs/efinix/Makefile.inc | 1 - techlibs/efinix/efinix_determine_init.cc | 89 ------------------------ techlibs/efinix/synth_efinix.cc | 2 +- 3 files changed, 1 insertion(+), 91 deletions(-) delete mode 100644 techlibs/efinix/efinix_determine_init.cc diff --git a/techlibs/efinix/Makefile.inc b/techlibs/efinix/Makefile.inc index 47dadccdd..f1ce58276 100644 --- a/techlibs/efinix/Makefile.inc +++ b/techlibs/efinix/Makefile.inc @@ -1,7 +1,6 @@ OBJS += techlibs/efinix/synth_efinix.o OBJS += techlibs/efinix/efinix_gbuf.o -OBJS += techlibs/efinix/efinix_determine_init.o OBJS += techlibs/efinix/efinix_fixcarry.o $(eval $(call add_share_file,share/efinix,techlibs/efinix/cells_map.v)) diff --git a/techlibs/efinix/efinix_determine_init.cc b/techlibs/efinix/efinix_determine_init.cc deleted file mode 100644 index 54da703ff..000000000 --- a/techlibs/efinix/efinix_determine_init.cc +++ /dev/null @@ -1,89 +0,0 @@ -/* - * yosys -- Yosys Open SYnthesis Suite - * - * Copyright (C) 2018 Icenowy Zheng - * - * 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 - -struct EfinixDetermineInitPass : public Pass { - EfinixDetermineInitPass() : Pass("efinix_determine_init", "Efinix: Determine the init value of cells") { } - void help() YS_OVERRIDE - { - log("\n"); - log(" efinix_determine_init [selection]\n"); - log("\n"); - log("Determine the init value of cells that doesn't allow unknown init value.\n"); - log("\n"); - } - - Const determine_init(Const init) - { - for (int i = 0; i < GetSize(init); i++) { - if (init[i] != State::S0 && init[i] != State::S1) - init[i] = State::S0; - } - - return init; - } - - void execute(std::vector args, RTLIL::Design *design) YS_OVERRIDE - { - log_header(design, "Executing EFINIX_DETERMINE_INIT pass (determine init value for cells).\n"); - - extra_args(args, args.size(), design); - - int cnt = 0; - for (auto module : design->selected_modules()) - { - for (auto cell : module->selected_cells()) - { - if (cell->type == "\\EFX_RAM_5K") - { - cell->setParam("\\INIT_0", determine_init(cell->getParam("\\INIT_0"))); - cell->setParam("\\INIT_1", determine_init(cell->getParam("\\INIT_1"))); - cell->setParam("\\INIT_2", determine_init(cell->getParam("\\INIT_2"))); - cell->setParam("\\INIT_3", determine_init(cell->getParam("\\INIT_3"))); - cell->setParam("\\INIT_4", determine_init(cell->getParam("\\INIT_4"))); - cell->setParam("\\INIT_5", determine_init(cell->getParam("\\INIT_5"))); - cell->setParam("\\INIT_6", determine_init(cell->getParam("\\INIT_6"))); - cell->setParam("\\INIT_7", determine_init(cell->getParam("\\INIT_7"))); - cell->setParam("\\INIT_8", determine_init(cell->getParam("\\INIT_8"))); - cell->setParam("\\INIT_9", determine_init(cell->getParam("\\INIT_9"))); - cell->setParam("\\INIT_A", determine_init(cell->getParam("\\INIT_A"))); - cell->setParam("\\INIT_B", determine_init(cell->getParam("\\INIT_B"))); - cell->setParam("\\INIT_C", determine_init(cell->getParam("\\INIT_C"))); - cell->setParam("\\INIT_D", determine_init(cell->getParam("\\INIT_D"))); - cell->setParam("\\INIT_E", determine_init(cell->getParam("\\INIT_E"))); - cell->setParam("\\INIT_F", determine_init(cell->getParam("\\INIT_F"))); - cell->setParam("\\INIT_10", determine_init(cell->getParam("\\INIT_10"))); - cell->setParam("\\INIT_11", determine_init(cell->getParam("\\INIT_11"))); - cell->setParam("\\INIT_12", determine_init(cell->getParam("\\INIT_12"))); - cell->setParam("\\INIT_13", determine_init(cell->getParam("\\INIT_13"))); - - cnt++; - } - } - } - log_header(design, "Updated %d cells with determined init value.\n", cnt); - } -} EfinixDetermineInitPass; - -PRIVATE_NAMESPACE_END diff --git a/techlibs/efinix/synth_efinix.cc b/techlibs/efinix/synth_efinix.cc index d64491ca8..26a8d4eda 100644 --- a/techlibs/efinix/synth_efinix.cc +++ b/techlibs/efinix/synth_efinix.cc @@ -154,7 +154,7 @@ struct SynthEfinixPass : public ScriptPass { run("memory_bram -rules +/efinix/bram.txt"); run("techmap -map +/efinix/brams_map.v"); - run("efinix_determine_init"); + run("setundef -zero -params t:EFX_RAM_5K"); } if (check_label("fine")) From aa0c37722a99a308e64ea9581111adea2d97e46d Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Sun, 11 Aug 2019 11:40:15 +0200 Subject: [PATCH 22/94] fix mixing signals on FF mapping --- techlibs/efinix/cells_map.v | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/techlibs/efinix/cells_map.v b/techlibs/efinix/cells_map.v index 70c19635e..0aeab1902 100644 --- a/techlibs/efinix/cells_map.v +++ b/techlibs/efinix/cells_map.v @@ -8,14 +8,14 @@ module \$_DFFE_PN_ (input D, C, E, output Q); EFX_FF #(.CLK_POLARITY(1'b1), .CE module \$_DFFE_PP_ (input D, C, E, output Q); EFX_FF #(.CLK_POLARITY(1'b1), .CE_POLARITY(1'b1), .SR_POLARITY(1'b1), .D_POLARITY(1'b1), .SR_SYNC(1'b1), .SR_VALUE(1'b0), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(E), .CLK(C), .SR(1'b0), .Q(Q)); endmodule module \$_DFF_NN0_ (input D, C, R, output Q); EFX_FF #(.CLK_POLARITY(1'b0), .CE_POLARITY(1'b1), .SR_POLARITY(1'b0), .D_POLARITY(1'b1), .SR_SYNC(1'b0), .SR_VALUE(1'b0), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(1'b1), .CLK(C), .SR(R), .Q(Q)); endmodule -module \$_DFF_NN1_ (input D, C, R, output Q); EFX_FF #(.CLK_POLARITY(1'b0), .CE_POLARITY(1'b1), .SR_POLARITY(1'b0), .D_POLARITY(1'b1), .SR_SYNC(1'b1), .SR_VALUE(1'b0), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(1'b1), .CLK(C), .SR(R), .Q(Q)); endmodule +module \$_DFF_NN1_ (input D, C, R, output Q); EFX_FF #(.CLK_POLARITY(1'b0), .CE_POLARITY(1'b1), .SR_POLARITY(1'b0), .D_POLARITY(1'b1), .SR_SYNC(1'b0), .SR_VALUE(1'b1), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(1'b1), .CLK(C), .SR(R), .Q(Q)); endmodule module \$_DFF_PN0_ (input D, C, R, output Q); EFX_FF #(.CLK_POLARITY(1'b1), .CE_POLARITY(1'b1), .SR_POLARITY(1'b0), .D_POLARITY(1'b1), .SR_SYNC(1'b0), .SR_VALUE(1'b0), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(1'b1), .CLK(C), .SR(R), .Q(Q)); endmodule -module \$_DFF_PN1_ (input D, C, R, output Q); EFX_FF #(.CLK_POLARITY(1'b1), .CE_POLARITY(1'b1), .SR_POLARITY(1'b0), .D_POLARITY(1'b1), .SR_SYNC(1'b1), .SR_VALUE(1'b0), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(1'b1), .CLK(C), .SR(R), .Q(Q)); endmodule +module \$_DFF_PN1_ (input D, C, R, output Q); EFX_FF #(.CLK_POLARITY(1'b1), .CE_POLARITY(1'b1), .SR_POLARITY(1'b0), .D_POLARITY(1'b1), .SR_SYNC(1'b0), .SR_VALUE(1'b1), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(1'b1), .CLK(C), .SR(R), .Q(Q)); endmodule module \$_DFF_NP0_ (input D, C, R, output Q); EFX_FF #(.CLK_POLARITY(1'b0), .CE_POLARITY(1'b1), .SR_POLARITY(1'b1), .D_POLARITY(1'b1), .SR_SYNC(1'b0), .SR_VALUE(1'b0), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(1'b1), .CLK(C), .SR(R), .Q(Q)); endmodule -module \$_DFF_NP1_ (input D, C, R, output Q); EFX_FF #(.CLK_POLARITY(1'b0), .CE_POLARITY(1'b1), .SR_POLARITY(1'b1), .D_POLARITY(1'b1), .SR_SYNC(1'b1), .SR_VALUE(1'b0), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(1'b1), .CLK(C), .SR(R), .Q(Q)); endmodule +module \$_DFF_NP1_ (input D, C, R, output Q); EFX_FF #(.CLK_POLARITY(1'b0), .CE_POLARITY(1'b1), .SR_POLARITY(1'b1), .D_POLARITY(1'b1), .SR_SYNC(1'b0), .SR_VALUE(1'b1), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(1'b1), .CLK(C), .SR(R), .Q(Q)); endmodule module \$_DFF_PP0_ (input D, C, R, output Q); EFX_FF #(.CLK_POLARITY(1'b1), .CE_POLARITY(1'b1), .SR_POLARITY(1'b1), .D_POLARITY(1'b1), .SR_SYNC(1'b0), .SR_VALUE(1'b0), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(1'b1), .CLK(C), .SR(R), .Q(Q)); endmodule -module \$_DFF_PP1_ (input D, C, R, output Q); EFX_FF #(.CLK_POLARITY(1'b1), .CE_POLARITY(1'b1), .SR_POLARITY(1'b1), .D_POLARITY(1'b1), .SR_SYNC(1'b1), .SR_VALUE(1'b0), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(1'b1), .CLK(C), .SR(R), .Q(Q)); endmodule +module \$_DFF_PP1_ (input D, C, R, output Q); EFX_FF #(.CLK_POLARITY(1'b1), .CE_POLARITY(1'b1), .SR_POLARITY(1'b1), .D_POLARITY(1'b1), .SR_SYNC(1'b0), .SR_VALUE(1'b1), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(1'b1), .CLK(C), .SR(R), .Q(Q)); endmodule `ifndef NO_LUT module \$lut (A, Y); From ead2b52b5a123e2c93578555de394a7a406e1fa5 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Sun, 11 Aug 2019 13:59:39 +0200 Subject: [PATCH 23/94] one bit enable signal --- techlibs/efinix/brams_map.v | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/techlibs/efinix/brams_map.v b/techlibs/efinix/brams_map.v index 3236f39a5..6786ae769 100644 --- a/techlibs/efinix/brams_map.v +++ b/techlibs/efinix/brams_map.v @@ -1,7 +1,7 @@ module \$__EFINIX_5K (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN); parameter CFG_ABITS = 8; parameter CFG_DBITS = 20; - parameter CFG_ENABLE_A = 2; + parameter CFG_ENABLE_A = 1; parameter CLKPOL2 = 1; parameter CLKPOL3 = 1; From 2897fe4d09118e37934b7e76f4990cc1d69a0cb5 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Sun, 11 Aug 2019 17:05:24 +0200 Subject: [PATCH 24/94] Fix formating --- techlibs/efinix/arith_map.v | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/techlibs/efinix/arith_map.v b/techlibs/efinix/arith_map.v index 56e1b039f..178f57bc5 100644 --- a/techlibs/efinix/arith_map.v +++ b/techlibs/efinix/arith_map.v @@ -33,8 +33,8 @@ module _80_efinix_alu (A, B, CI, BI, X, Y, CO); input CI, BI; output [Y_WIDTH-1:0] CO; - wire CIx; - wire [Y_WIDTH-1:0] COx; + wire CIx; + wire [Y_WIDTH-1:0] COx; wire _TECHMAP_FAIL_ = Y_WIDTH <= 2; From 5f561bdcb1d562d6f975b4a27beca1b8b7af908f Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Mon, 12 Aug 2019 20:19:54 +0200 Subject: [PATCH 25/94] Proper arith for Anlogic and use standard pass --- techlibs/anlogic/Makefile.inc | 2 +- techlibs/anlogic/anlogic_determine_init.cc | 72 ------------ techlibs/anlogic/anlogic_fixcarry.cc | 130 +++++++++++++++++++++ techlibs/anlogic/arith_map.v | 42 ++++--- techlibs/anlogic/synth_anlogic.cc | 7 +- 5 files changed, 162 insertions(+), 91 deletions(-) delete mode 100644 techlibs/anlogic/anlogic_determine_init.cc create mode 100644 techlibs/anlogic/anlogic_fixcarry.cc diff --git a/techlibs/anlogic/Makefile.inc b/techlibs/anlogic/Makefile.inc index 67cf9cf10..9426b5ca5 100644 --- a/techlibs/anlogic/Makefile.inc +++ b/techlibs/anlogic/Makefile.inc @@ -1,7 +1,7 @@ OBJS += techlibs/anlogic/synth_anlogic.o OBJS += techlibs/anlogic/anlogic_eqn.o -OBJS += techlibs/anlogic/anlogic_determine_init.o +OBJS += techlibs/anlogic/anlogic_fixcarry.o $(eval $(call add_share_file,share/anlogic,techlibs/anlogic/cells_map.v)) $(eval $(call add_share_file,share/anlogic,techlibs/anlogic/arith_map.v)) diff --git a/techlibs/anlogic/anlogic_determine_init.cc b/techlibs/anlogic/anlogic_determine_init.cc deleted file mode 100644 index c4089dac2..000000000 --- a/techlibs/anlogic/anlogic_determine_init.cc +++ /dev/null @@ -1,72 +0,0 @@ -/* - * yosys -- Yosys Open SYnthesis Suite - * - * Copyright (C) 2018 Icenowy Zheng - * - * 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 - -struct AnlogicDetermineInitPass : public Pass { - AnlogicDetermineInitPass() : Pass("anlogic_determine_init", "Anlogic: Determine the init value of cells") { } - void help() YS_OVERRIDE - { - log("\n"); - log(" anlogic_determine_init [selection]\n"); - log("\n"); - log("Determine the init value of cells that doesn't allow unknown init value.\n"); - log("\n"); - } - - Const determine_init(Const init) - { - for (int i = 0; i < GetSize(init); i++) { - if (init[i] != State::S0 && init[i] != State::S1) - init[i] = State::S0; - } - - return init; - } - - void execute(std::vector args, RTLIL::Design *design) YS_OVERRIDE - { - log_header(design, "Executing ANLOGIC_DETERMINE_INIT pass (determine init value for cells).\n"); - - extra_args(args, args.size(), design); - - int cnt = 0; - for (auto module : design->selected_modules()) - { - for (auto cell : module->selected_cells()) - { - if (cell->type == "\\EG_LOGIC_DRAM16X4") - { - cell->setParam("\\INIT_D0", determine_init(cell->getParam("\\INIT_D0"))); - cell->setParam("\\INIT_D1", determine_init(cell->getParam("\\INIT_D1"))); - cell->setParam("\\INIT_D2", determine_init(cell->getParam("\\INIT_D2"))); - cell->setParam("\\INIT_D3", determine_init(cell->getParam("\\INIT_D3"))); - cnt++; - } - } - } - log_header(design, "Updated %d cells with determined init value.\n", cnt); - } -} AnlogicDetermineInitPass; - -PRIVATE_NAMESPACE_END diff --git a/techlibs/anlogic/anlogic_fixcarry.cc b/techlibs/anlogic/anlogic_fixcarry.cc new file mode 100644 index 000000000..87164d375 --- /dev/null +++ b/techlibs/anlogic/anlogic_fixcarry.cc @@ -0,0 +1,130 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2019 Miodrag Milanovic + * + * 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 + +static SigBit get_bit_or_zero(const SigSpec &sig) +{ + if (GetSize(sig) == 0) + return State::S0; + return sig[0]; +} + +static void fix_carry_chain(Module *module) +{ + SigMap sigmap(module); + + pool ci_bits; + dict mapping_bits; + + for (auto cell : module->cells()) + { + if (cell->type == "\\AL_MAP_ADDER") { + if (cell->getParam("\\ALUTYPE") != Const("ADD")) continue; + SigBit bit_i0 = get_bit_or_zero(cell->getPort("\\a")); + SigBit bit_i1 = get_bit_or_zero(cell->getPort("\\b")); + if (bit_i0 == State::S0 && bit_i1== State::S0) { + SigBit bit_ci = get_bit_or_zero(cell->getPort("\\c")); + SigSpec o = cell->getPort("\\o"); + if (GetSize(o) == 2) { + SigBit bit_o = o[0]; + ci_bits.insert(bit_ci); + mapping_bits[bit_ci] = bit_o; + } + } + } + } + vector adders_to_fix_cells; + for (auto cell : module->cells()) + { + if (cell->type == "\\AL_MAP_ADDER") { + if (cell->getParam("\\ALUTYPE") != Const("ADD")) continue; + SigBit bit_ci = get_bit_or_zero(cell->getPort("\\c")); + SigBit bit_i0 = get_bit_or_zero(cell->getPort("\\a")); + SigBit bit_i1 = get_bit_or_zero(cell->getPort("\\b")); + SigBit canonical_bit = sigmap(bit_ci); + if (!ci_bits.count(canonical_bit)) + continue; + if (bit_i0 == State::S0 && bit_i1== State::S0) + continue; + + adders_to_fix_cells.push_back(cell); + log("Found %s cell named %s with invalid 'c' signal.\n", log_id(cell->type), log_id(cell)); + } + } + + for (auto cell : adders_to_fix_cells) + { + SigBit bit_ci = get_bit_or_zero(cell->getPort("\\c")); + SigBit canonical_bit = sigmap(bit_ci); + auto bit = mapping_bits.at(canonical_bit); + log("Fixing %s cell named %s breaking carry chain.\n", log_id(cell->type), log_id(cell)); + Cell *c = module->addCell(NEW_ID, "\\AL_MAP_ADDER"); + SigBit new_bit = module->addWire(NEW_ID); + SigBit dummy_bit = module->addWire(NEW_ID); + SigSpec bits; + bits.append(dummy_bit); + bits.append(new_bit); + c->setParam("\\ALUTYPE", Const("ADD_CARRY")); + c->setPort("\\a", bit); + c->setPort("\\b", State::S0); + c->setPort("\\c", State::S0); + c->setPort("\\o", bits); + + cell->setPort("\\c", new_bit); + } + +} + +struct AnlogicCarryFixPass : public Pass { + AnlogicCarryFixPass() : Pass("anlogic_fixcarry", "Anlogic: fix carry chain") { } + void help() YS_OVERRIDE + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" anlogic_fixcarry [options] [selection]\n"); + log("\n"); + log("Add Anlogic adders to fix carry chain if needed.\n"); + log("\n"); + } + void execute(std::vector args, RTLIL::Design *design) YS_OVERRIDE + { + log_header(design, "Executing anlogic_fixcarry pass (fix invalid carry chain).\n"); + + size_t argidx; + for (argidx = 1; argidx < args.size(); argidx++) + { + break; + } + extra_args(args, argidx, design); + + Module *module = design->top_module(); + + if (module == nullptr) + log_cmd_error("No top module found.\n"); + + fix_carry_chain(module); + } +} AnlogicCarryFixPass; + +PRIVATE_NAMESPACE_END diff --git a/techlibs/anlogic/arith_map.v b/techlibs/anlogic/arith_map.v index 6d6a7ca37..d783b0212 100644 --- a/techlibs/anlogic/arith_map.v +++ b/techlibs/anlogic/arith_map.v @@ -31,7 +31,10 @@ module _80_anlogic_alu (A, B, CI, BI, X, Y, CO); output [Y_WIDTH-1:0] X, Y; input CI, BI; - output CO; + output [Y_WIDTH-1:0] CO; + + wire CIx; + wire [Y_WIDTH-1:0] COx; wire _TECHMAP_FAIL_ = Y_WIDTH <= 2; @@ -41,15 +44,16 @@ module _80_anlogic_alu (A, B, CI, BI, X, Y, CO); wire [Y_WIDTH-1:0] AA = A_buf; wire [Y_WIDTH-1:0] BB = BI ? ~B_buf : B_buf; - wire [Y_WIDTH+1:0] COx; - wire [Y_WIDTH+2:0] C = {COx, CI}; + wire [Y_WIDTH-1:0] C = { COx, CIx }; wire dummy; AL_MAP_ADDER #( .ALUTYPE("ADD_CARRY")) adder_cin ( - .a(C[0]), - .o({COx[0], dummy}) + .a(CI), + .b(1'b0), + .c(1'b0), + .o({CIx, dummy}) ); genvar i; @@ -59,18 +63,22 @@ module _80_anlogic_alu (A, B, CI, BI, X, Y, CO); ) adder_i ( .a(AA[i]), .b(BB[i]), - .c(C[i+1]), - .o({COx[i+1],Y[i]}) + .c(C[i]), + .o({COx[i],Y[i]}) ); - end: slice + + wire cout; + AL_MAP_ADDER #( + .ALUTYPE("ADD")) + adder_cout ( + .a(1'b0), + .b(1'b0), + .c(COx[i]), + .o({cout, CO[i]}) + ); + end: slice endgenerate - /* End implementation */ - AL_MAP_ADDER #( - .ALUTYPE("ADD")) - adder_cout ( - .c(C[Y_WIDTH+1]), - .o(COx[Y_WIDTH+1]) - ); - assign CO = COx[Y_WIDTH+1]; - assign X = AA ^ BB; + + /* End implementation */ + assign X = AA ^ BB; endmodule \ No newline at end of file diff --git a/techlibs/anlogic/synth_anlogic.cc b/techlibs/anlogic/synth_anlogic.cc index 620bf3965..b87fc8566 100644 --- a/techlibs/anlogic/synth_anlogic.cc +++ b/techlibs/anlogic/synth_anlogic.cc @@ -154,7 +154,7 @@ struct SynthAnlogicPass : public ScriptPass { run("memory_bram -rules +/anlogic/drams.txt"); run("techmap -map +/anlogic/drams_map.v"); - run("anlogic_determine_init"); + run("setundef -zero -params t:EG_LOGIC_DRAM16X4"); } if (check_label("fine")) @@ -186,6 +186,11 @@ struct SynthAnlogicPass : public ScriptPass { run("techmap -map +/anlogic/cells_map.v"); run("clean"); + } + + if (check_label("map_anlogic")) + { + run("anlogic_fixcarry"); run("anlogic_eqn"); } From 12c692f6eda7367527fde2a8aad49447a73aa643 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 12 Aug 2019 12:06:45 -0700 Subject: [PATCH 26/94] Revert "Merge pull request #1280 from YosysHQ/revert-1266-eddie/ice40_full_adder" This reverts commit c851dc13108021834533094a8a3236da6d9e0161, reversing changes made to f54bf1631ff37a83733c162e6ebd188c1d5ea18f. --- CHANGELOG | 2 + frontends/ast/ast.cc | 2 +- passes/pmgen/Makefile.inc | 10 ++ passes/pmgen/ice40_wrapcarry.cc | 90 +++++++++++++++ passes/pmgen/ice40_wrapcarry.pmg | 11 ++ techlibs/ice40/Makefile.inc | 1 - techlibs/ice40/arith_map.v | 32 ++---- techlibs/ice40/cells_map.v | 23 ++-- techlibs/ice40/ice40_unlut.cc | 106 ------------------ techlibs/ice40/synth_ice40.cc | 13 ++- techlibs/ice40/tests/test_arith.ys | 9 +- tests/{various => opt}/opt_expr.ys | 0 tests/opt/opt_ff.v | 21 ---- tests/opt/opt_ff.ys | 3 - tests/opt/opt_lut.ys | 4 +- tests/{various => opt}/opt_rmdff.v | 0 tests/{various => opt}/opt_rmdff.ys | 0 tests/opt/{opt_ff_sat.v => opt_rmdff_sat.v} | 0 tests/opt/{opt_ff_sat.ys => opt_rmdff_sat.ys} | 2 +- tests/various/wreduce.ys | 33 +++++- 20 files changed, 181 insertions(+), 181 deletions(-) create mode 100644 passes/pmgen/ice40_wrapcarry.cc create mode 100644 passes/pmgen/ice40_wrapcarry.pmg delete mode 100644 techlibs/ice40/ice40_unlut.cc rename tests/{various => opt}/opt_expr.ys (100%) delete mode 100644 tests/opt/opt_ff.v delete mode 100644 tests/opt/opt_ff.ys rename tests/{various => opt}/opt_rmdff.v (100%) rename tests/{various => opt}/opt_rmdff.ys (100%) rename tests/opt/{opt_ff_sat.v => opt_rmdff_sat.v} (100%) rename tests/opt/{opt_ff_sat.ys => opt_rmdff_sat.ys} (70%) diff --git a/CHANGELOG b/CHANGELOG index 638c36121..21fb8a3f5 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -19,6 +19,8 @@ Yosys 0.9 .. Yosys 0.9-dev - Added automatic gzip compression (based on filename extension) for backends - Improve attribute and parameter encoding in JSON to avoid ambiguities between bit vectors and strings containing [01xz]* + - Added "ice40_wrapcarry" to encapsulate SB_LUT+SB_CARRY pairs for techmapping + - Removed "ice40_unlut" Yosys 0.8 .. Yosys 0.8-dev -------------------------- diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 07ef0a86e..0d6626b19 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -1172,7 +1172,7 @@ void AST::process(RTLIL::Design *design, AstNode *ast, bool dump_ast1, bool dump if (design->has((*it)->str)) { RTLIL::Module *existing_mod = design->module((*it)->str); - if (!nooverwrite && !overwrite && !existing_mod->get_bool_attribute("\\blackbox")) { + if (!nooverwrite && !overwrite && !existing_mod->get_blackbox_attribute()) { log_file_error((*it)->filename, (*it)->linenum, "Re-definition of module `%s'!\n", (*it)->str.c_str()); } else if (nooverwrite) { log("Ignoring re-definition of module `%s' at %s:%d.\n", diff --git a/passes/pmgen/Makefile.inc b/passes/pmgen/Makefile.inc index 7911132db..c03606152 100644 --- a/passes/pmgen/Makefile.inc +++ b/passes/pmgen/Makefile.inc @@ -1,4 +1,5 @@ OBJS += passes/pmgen/ice40_dsp.o +OBJS += passes/pmgen/ice40_wrapcarry.o OBJS += passes/pmgen/peepopt.o # -------------------------------------- @@ -12,6 +13,15 @@ passes/pmgen/ice40_dsp_pm.h: passes/pmgen/pmgen.py passes/pmgen/ice40_dsp.pmg # -------------------------------------- +passes/pmgen/ice40_wrapcarry.o: passes/pmgen/ice40_wrapcarry_pm.h +EXTRA_OBJS += passes/pmgen/ice40_wrapcarry_pm.h +.SECONDARY: passes/pmgen/ice40_wrapcarry_pm.h + +passes/pmgen/ice40_wrapcarry_pm.h: passes/pmgen/pmgen.py passes/pmgen/ice40_wrapcarry.pmg + $(P) mkdir -p passes/pmgen && python3 $< -o $@ -p ice40_wrapcarry $(filter-out $<,$^) + +# -------------------------------------- + passes/pmgen/peepopt.o: passes/pmgen/peepopt_pm.h EXTRA_OBJS += passes/pmgen/peepopt_pm.h .SECONDARY: passes/pmgen/peepopt_pm.h diff --git a/passes/pmgen/ice40_wrapcarry.cc b/passes/pmgen/ice40_wrapcarry.cc new file mode 100644 index 000000000..69ef3cd82 --- /dev/null +++ b/passes/pmgen/ice40_wrapcarry.cc @@ -0,0 +1,90 @@ +/* + * 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/yosys.h" +#include "kernel/sigtools.h" + +USING_YOSYS_NAMESPACE +PRIVATE_NAMESPACE_BEGIN + +#include "passes/pmgen/ice40_wrapcarry_pm.h" + +void create_ice40_wrapcarry(ice40_wrapcarry_pm &pm) +{ + auto &st = pm.st_ice40_wrapcarry; + +#if 0 + log("\n"); + log("carry: %s\n", log_id(st.carry, "--")); + log("lut: %s\n", log_id(st.lut, "--")); +#endif + + log(" replacing SB_LUT + SB_CARRY with $__ICE40_CARRY_WRAPPER cell.\n"); + + Cell *cell = pm.module->addCell(NEW_ID, "$__ICE40_CARRY_WRAPPER"); + pm.module->swap_names(cell, st.carry); + + cell->setPort("\\A", st.carry->getPort("\\I0")); + cell->setPort("\\B", st.carry->getPort("\\I1")); + cell->setPort("\\CI", st.carry->getPort("\\CI")); + cell->setPort("\\CO", st.carry->getPort("\\CO")); + + cell->setPort("\\I0", st.lut->getPort("\\I0")); + cell->setPort("\\I3", st.lut->getPort("\\I3")); + cell->setPort("\\O", st.lut->getPort("\\O")); + cell->setParam("\\LUT", st.lut->getParam("\\LUT_INIT")); + + pm.autoremove(st.carry); + pm.autoremove(st.lut); +} + +struct Ice40WrapCarryPass : public Pass { + Ice40WrapCarryPass() : Pass("ice40_wrapcarry", "iCE40: wrap carries") { } + void help() YS_OVERRIDE + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" ice40_wrapcarry [selection]\n"); + log("\n"); + log("Wrap manually instantiated SB_CARRY cells, along with their associated SB_LUTs,\n"); + log("into an internal $__ICE40_CARRY_WRAPPER cell for preservation across technology\n"); + log("mapping."); + log("\n"); + } + void execute(std::vector args, RTLIL::Design *design) YS_OVERRIDE + { + log_header(design, "Executing ICE40_WRAPCARRY pass (wrap carries).\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()) + ice40_wrapcarry_pm(module, module->selected_cells()).run_ice40_wrapcarry(create_ice40_wrapcarry); + } +} Ice40WrapCarryPass; + +PRIVATE_NAMESPACE_END diff --git a/passes/pmgen/ice40_wrapcarry.pmg b/passes/pmgen/ice40_wrapcarry.pmg new file mode 100644 index 000000000..9e64c7467 --- /dev/null +++ b/passes/pmgen/ice40_wrapcarry.pmg @@ -0,0 +1,11 @@ +pattern ice40_wrapcarry + +match carry + select carry->type.in(\SB_CARRY) +endmatch + +match lut + select lut->type.in(\SB_LUT4) + index port(lut, \I1) === port(carry, \I0) + index port(lut, \I2) === port(carry, \I1) +endmatch diff --git a/techlibs/ice40/Makefile.inc b/techlibs/ice40/Makefile.inc index d258d5a5d..76a89b107 100644 --- a/techlibs/ice40/Makefile.inc +++ b/techlibs/ice40/Makefile.inc @@ -4,7 +4,6 @@ OBJS += techlibs/ice40/ice40_braminit.o OBJS += techlibs/ice40/ice40_ffssr.o OBJS += techlibs/ice40/ice40_ffinit.o OBJS += techlibs/ice40/ice40_opt.o -OBJS += techlibs/ice40/ice40_unlut.o GENFILES += techlibs/ice40/brams_init1.vh GENFILES += techlibs/ice40/brams_init2.vh diff --git a/techlibs/ice40/arith_map.v b/techlibs/ice40/arith_map.v index fe83a8e38..26b24db9e 100644 --- a/techlibs/ice40/arith_map.v +++ b/techlibs/ice40/arith_map.v @@ -44,35 +44,21 @@ module _80_ice40_alu (A, B, CI, BI, X, Y, CO); genvar i; generate for (i = 0; i < Y_WIDTH; i = i + 1) begin:slice -`ifdef _ABC - \$__ICE40_FULL_ADDER carry ( + \$__ICE40_CARRY_WRAPPER #( + // A[0]: 1010 1010 1010 1010 + // A[1]: 1100 1100 1100 1100 + // A[2]: 1111 0000 1111 0000 + // A[3]: 1111 1111 0000 0000 + .LUT(16'b 0110_1001_1001_0110) + ) fadd ( .A(AA[i]), .B(BB[i]), .CI(C[i]), + .I0(1'b0), + .I3(C[i]), .CO(CO[i]), .O(Y[i]) ); -`else - SB_CARRY carry ( - .I0(AA[i]), - .I1(BB[i]), - .CI(C[i]), - .CO(CO[i]) - ); - SB_LUT4 #( - // I0: 1010 1010 1010 1010 - // I1: 1100 1100 1100 1100 - // I2: 1111 0000 1111 0000 - // I3: 1111 1111 0000 0000 - .LUT_INIT(16'b 0110_1001_1001_0110) - ) adder ( - .I0(1'b0), - .I1(AA[i]), - .I2(BB[i]), - .I3(C[i]), - .O(Y[i]) - ); -`endif end endgenerate assign X = AA ^ BB; diff --git a/techlibs/ice40/cells_map.v b/techlibs/ice40/cells_map.v index b4b831165..0c10c9ac4 100644 --- a/techlibs/ice40/cells_map.v +++ b/techlibs/ice40/cells_map.v @@ -62,26 +62,21 @@ module \$lut (A, Y); endmodule `endif -`ifdef _ABC -module \$__ICE40_FULL_ADDER (output CO, O, input A, B, CI); +`ifndef NO_ADDER +module \$__ICE40_CARRY_WRAPPER (output CO, O, input A, B, CI, I0, I3); + parameter LUT = 0; SB_CARRY carry ( .I0(A), .I1(B), .CI(CI), .CO(CO) ); - SB_LUT4 #( - // I0: 1010 1010 1010 1010 - // I1: 1100 1100 1100 1100 - // I2: 1111 0000 1111 0000 - // I3: 1111 1111 0000 0000 - .LUT_INIT(16'b 0110_1001_1001_0110) - ) adder ( - .I0(1'b0), - .I1(A), - .I2(B), - .I3(CI), - .O(O) + \$lut #( + .WIDTH(4), + .LUT(LUT) + ) lut ( + .A({I3,B,A,I0}), + .Y(O) ); endmodule `endif diff --git a/techlibs/ice40/ice40_unlut.cc b/techlibs/ice40/ice40_unlut.cc deleted file mode 100644 index f3f70ac1f..000000000 --- a/techlibs/ice40/ice40_unlut.cc +++ /dev/null @@ -1,106 +0,0 @@ -/* - * 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/yosys.h" -#include "kernel/sigtools.h" -#include -#include - -USING_YOSYS_NAMESPACE -PRIVATE_NAMESPACE_BEGIN - -static SigBit get_bit_or_zero(const SigSpec &sig) -{ - if (GetSize(sig) == 0) - return State::S0; - return sig[0]; -} - -static void run_ice40_unlut(Module *module) -{ - SigMap sigmap(module); - - for (auto cell : module->selected_cells()) - { - if (cell->type == "\\SB_LUT4") - { - SigSpec inbits; - - inbits.append(get_bit_or_zero(cell->getPort("\\I0"))); - inbits.append(get_bit_or_zero(cell->getPort("\\I1"))); - inbits.append(get_bit_or_zero(cell->getPort("\\I2"))); - inbits.append(get_bit_or_zero(cell->getPort("\\I3"))); - sigmap.apply(inbits); - - log("Mapping SB_LUT4 cell %s.%s to $lut.\n", log_id(module), log_id(cell)); - - cell->type ="$lut"; - cell->setParam("\\WIDTH", 4); - cell->setParam("\\LUT", cell->getParam("\\LUT_INIT")); - cell->unsetParam("\\LUT_INIT"); - - cell->setPort("\\A", SigSpec({ - get_bit_or_zero(cell->getPort("\\I0")), - get_bit_or_zero(cell->getPort("\\I1")), - get_bit_or_zero(cell->getPort("\\I2")), - get_bit_or_zero(cell->getPort("\\I3")) - })); - cell->setPort("\\Y", cell->getPort("\\O")[0]); - cell->unsetPort("\\I0"); - cell->unsetPort("\\I1"); - cell->unsetPort("\\I2"); - cell->unsetPort("\\I3"); - cell->unsetPort("\\O"); - - cell->check(); - } - } -} - -struct Ice40UnlutPass : public Pass { - Ice40UnlutPass() : Pass("ice40_unlut", "iCE40: transform SB_LUT4 cells to $lut cells") { } - void help() YS_OVERRIDE - { - // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| - log("\n"); - log(" ice40_unlut [options] [selection]\n"); - log("\n"); - log("This command transforms all SB_LUT4 cells to generic $lut cells.\n"); - log("\n"); - } - void execute(std::vector args, RTLIL::Design *design) YS_OVERRIDE - { - log_header(design, "Executing ICE40_UNLUT pass (convert SB_LUT4 to $lut).\n"); - log_push(); - - size_t argidx; - for (argidx = 1; argidx < args.size(); argidx++) { - // if (args[argidx] == "-???") { - // continue; - // } - break; - } - extra_args(args, argidx, design); - - for (auto module : design->selected_modules()) - run_ice40_unlut(module); - } -} Ice40UnlutPass; - -PRIVATE_NAMESPACE_END diff --git a/techlibs/ice40/synth_ice40.cc b/techlibs/ice40/synth_ice40.cc index dc04eed67..c6de81bd9 100644 --- a/techlibs/ice40/synth_ice40.cc +++ b/techlibs/ice40/synth_ice40.cc @@ -238,7 +238,7 @@ struct SynthIce40Pass : public ScriptPass { if (check_label("begin")) { - run("read_verilog -icells -lib -D_ABC +/ice40/cells_sim.v"); + run("read_verilog -icells -lib +/ice40/cells_sim.v"); run(stringf("hierarchy -check %s", help_mode ? "-top " : top_opt.c_str())); run("proc"); } @@ -293,8 +293,10 @@ struct SynthIce40Pass : public ScriptPass { if (nocarry) run("techmap"); - else - run("techmap -map +/techmap.v -map +/ice40/arith_map.v" + std::string(abc == "abc9" ? " -D _ABC" : "")); + else { + run("ice40_wrapcarry"); + run("techmap -map +/techmap.v -map +/ice40/arith_map.v"); + } if (retime || help_mode) run(abc + " -dff", "(only if -retime)"); run("ice40_opt"); @@ -309,7 +311,7 @@ struct SynthIce40Pass : public ScriptPass run("opt_merge"); run(stringf("dff2dffe -unmap-mince %d", min_ce_use)); } - run("techmap -D NO_LUT -map +/ice40/cells_map.v"); + run("techmap -D NO_LUT -D NO_ADDER -map +/ice40/cells_map.v"); run("opt_expr -mux_undef"); run("simplemap"); run("ice40_ffinit"); @@ -338,13 +340,12 @@ struct SynthIce40Pass : public ScriptPass else wire_delay = 250; run(abc + stringf(" -W %d -lut +/ice40/abc_%s.lut -box +/ice40/abc_%s.box", wire_delay, device_opt.c_str(), device_opt.c_str()), "(skip if -noabc)"); - run("techmap -D NO_LUT -D _ABC -map +/ice40/cells_map.v"); } else run(abc + " -dress -lut 4", "(skip if -noabc)"); } + run("techmap -D NO_LUT -map +/ice40/cells_map.v"); run("clean"); - run("ice40_unlut"); run("opt_lut -dlogic SB_CARRY:I0=2:I1=1:CI=0"); } diff --git a/techlibs/ice40/tests/test_arith.ys b/techlibs/ice40/tests/test_arith.ys index 160c767fb..ddb80b700 100644 --- a/techlibs/ice40/tests/test_arith.ys +++ b/techlibs/ice40/tests/test_arith.ys @@ -1,6 +1,5 @@ read_verilog test_arith.v synth_ice40 -techmap -map ../cells_sim.v rename test gate read_verilog test_arith.v @@ -8,3 +7,11 @@ rename test gold miter -equiv -flatten -make_outputs gold gate miter sat -verify -prove trigger 0 -show-ports miter + +synth_ice40 -top gate + +read_verilog test_arith.v +rename test gold + +miter -equiv -flatten -make_outputs gold gate miter +sat -verify -prove trigger 0 -show-ports miter diff --git a/tests/various/opt_expr.ys b/tests/opt/opt_expr.ys similarity index 100% rename from tests/various/opt_expr.ys rename to tests/opt/opt_expr.ys diff --git a/tests/opt/opt_ff.v b/tests/opt/opt_ff.v deleted file mode 100644 index a01b64b61..000000000 --- a/tests/opt/opt_ff.v +++ /dev/null @@ -1,21 +0,0 @@ -module top( - input clk, - input rst, - input [2:0] a, - output [1:0] b -); - reg [2:0] b_reg; - initial begin - b_reg <= 3'b0; - end - - assign b = b_reg[1:0]; - always @(posedge clk or posedge rst) begin - if(rst) begin - b_reg <= 3'b0; - end else begin - b_reg <= a; - end - end -endmodule - diff --git a/tests/opt/opt_ff.ys b/tests/opt/opt_ff.ys deleted file mode 100644 index 704c7acf3..000000000 --- a/tests/opt/opt_ff.ys +++ /dev/null @@ -1,3 +0,0 @@ -read_verilog opt_ff.v -synth_ice40 -ice40_unlut diff --git a/tests/opt/opt_lut.ys b/tests/opt/opt_lut.ys index 59b12c351..a9fccbb62 100644 --- a/tests/opt/opt_lut.ys +++ b/tests/opt/opt_lut.ys @@ -1,4 +1,2 @@ read_verilog opt_lut.v -synth_ice40 -ice40_unlut -equiv_opt -map +/ice40/cells_sim.v -assert opt_lut -dlogic SB_CARRY:I0=1:I1=2:CI=3 +equiv_opt -map +/ice40/cells_sim.v -assert synth_ice40 diff --git a/tests/various/opt_rmdff.v b/tests/opt/opt_rmdff.v similarity index 100% rename from tests/various/opt_rmdff.v rename to tests/opt/opt_rmdff.v diff --git a/tests/various/opt_rmdff.ys b/tests/opt/opt_rmdff.ys similarity index 100% rename from tests/various/opt_rmdff.ys rename to tests/opt/opt_rmdff.ys diff --git a/tests/opt/opt_ff_sat.v b/tests/opt/opt_rmdff_sat.v similarity index 100% rename from tests/opt/opt_ff_sat.v rename to tests/opt/opt_rmdff_sat.v diff --git a/tests/opt/opt_ff_sat.ys b/tests/opt/opt_rmdff_sat.ys similarity index 70% rename from tests/opt/opt_ff_sat.ys rename to tests/opt/opt_rmdff_sat.ys index 4e7cc6ca4..1c3dd9c05 100644 --- a/tests/opt/opt_ff_sat.ys +++ b/tests/opt/opt_rmdff_sat.ys @@ -1,4 +1,4 @@ -read_verilog opt_ff_sat.v +read_verilog opt_rmdff_sat.v prep -flatten opt_rmdff -sat synth diff --git a/tests/various/wreduce.ys b/tests/various/wreduce.ys index 4257292f5..2e0812c48 100644 --- a/tests/various/wreduce.ys +++ b/tests/various/wreduce.ys @@ -36,7 +36,6 @@ design -save gold opt_expr wreduce -dump select -assert-count 1 t:$sub r:A_WIDTH=4 r:B_WIDTH=4 r:Y_WIDTH=5 %i %i %i design -stash gate @@ -46,3 +45,35 @@ design -import gate -as gate miter -equiv -flatten -make_assert -make_outputs gold gate miter sat -verify -prove-asserts -show-ports miter + +########## + +# Testcase from: https://github.com/YosysHQ/yosys/commit/25680f6a078bb32f157bd580705656496717bafb +design -reset +read_verilog < Date: Mon, 12 Aug 2019 12:19:25 -0700 Subject: [PATCH 27/94] Fix $lut pin ordering inside $__ICE40_CARRY_WRAPPER --- techlibs/ice40/cells_map.v | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/techlibs/ice40/cells_map.v b/techlibs/ice40/cells_map.v index 0c10c9ac4..662423f0a 100644 --- a/techlibs/ice40/cells_map.v +++ b/techlibs/ice40/cells_map.v @@ -75,7 +75,7 @@ module \$__ICE40_CARRY_WRAPPER (output CO, O, input A, B, CI, I0, I3); .WIDTH(4), .LUT(LUT) ) lut ( - .A({I3,B,A,I0}), + .A({I0,A,B,I3}), .Y(O) ); endmodule From 0c5db07cd6cc3c19b926da21a46599f97592b20f Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 11 Aug 2019 23:25:46 +0200 Subject: [PATCH 28/94] Fix various NDEBUG compiler warnings, closes #1255 Signed-off-by: Clifford Wolf --- backends/aiger/xaiger.cc | 2 +- frontends/aiger/aigerparse.cc | 20 +++++++++++--------- frontends/verific/verific.cc | 2 ++ kernel/log.h | 2 +- passes/opt/opt_expr.cc | 3 ++- passes/techmap/abc9.cc | 2 +- 6 files changed, 18 insertions(+), 13 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index f49ecbeda..5e12e9a34 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -312,7 +312,7 @@ struct XAigerWriter #if 0 toposort.analyze_loops = true; #endif - bool no_loops = toposort.sort(); + bool no_loops YS_ATTRIBUTE(unused) = toposort.sort(); #if 0 unsigned i = 0; for (auto &it : toposort.loops) { diff --git a/frontends/aiger/aigerparse.cc b/frontends/aiger/aigerparse.cc index bd0596cc0..534cc0daa 100644 --- a/frontends/aiger/aigerparse.cc +++ b/frontends/aiger/aigerparse.cc @@ -67,7 +67,7 @@ struct ConstEvalAig continue; for (auto &it2 : it.second->connections()) if (yosys_celltypes.cell_output(it.second->type, it2.first)) { - auto r = sig2driver.insert(std::make_pair(it2.second, it.second)); + auto r YS_ATTRIBUTE(unused) = sig2driver.insert(std::make_pair(it2.second, it.second)); log_assert(r.second); } } @@ -389,9 +389,9 @@ void AigerReader::parse_xaiger(const dict &box_lookup) f.ignore(1); // XAIGER extensions if (c == 'm') { - uint32_t dataSize = parse_xaiger_literal(f); + uint32_t dataSize YS_ATTRIBUTE(unused) = parse_xaiger_literal(f); uint32_t lutNum = parse_xaiger_literal(f); - uint32_t lutSize = parse_xaiger_literal(f); + uint32_t lutSize YS_ATTRIBUTE(unused) = parse_xaiger_literal(f); log_debug("m: dataSize=%u lutNum=%u lutSize=%u\n", dataSize, lutNum, lutSize); ConstEvalAig ce(module); for (unsigned i = 0; i < lutNum; ++i) { @@ -416,7 +416,7 @@ void AigerReader::parse_xaiger(const dict &box_lookup) int gray = j ^ (j >> 1); ce.set_incremental(input_sig, RTLIL::Const{gray, static_cast(cutLeavesM)}); RTLIL::SigBit o(output_sig); - bool success = ce.eval(o); + bool success YS_ATTRIBUTE(unused) = ce.eval(o); log_assert(success); log_assert(o.wire == nullptr); lut_mask[gray] = o.data; @@ -428,7 +428,7 @@ void AigerReader::parse_xaiger(const dict &box_lookup) } } else if (c == 'r') { - uint32_t dataSize = parse_xaiger_literal(f); + uint32_t dataSize YS_ATTRIBUTE(unused) = parse_xaiger_literal(f); flopNum = parse_xaiger_literal(f); log_assert(dataSize == (flopNum+1) * sizeof(uint32_t)); f.ignore(flopNum * sizeof(uint32_t)); @@ -440,15 +440,15 @@ void AigerReader::parse_xaiger(const dict &box_lookup) } else if (c == 'h') { f.ignore(sizeof(uint32_t)); - uint32_t version = parse_xaiger_literal(f); + uint32_t version YS_ATTRIBUTE(unused) = parse_xaiger_literal(f); log_assert(version == 1); - uint32_t ciNum = parse_xaiger_literal(f); + uint32_t ciNum YS_ATTRIBUTE(unused) = parse_xaiger_literal(f); log_debug("ciNum = %u\n", ciNum); - uint32_t coNum = parse_xaiger_literal(f); + uint32_t coNum YS_ATTRIBUTE(unused) = parse_xaiger_literal(f); log_debug("coNum = %u\n", coNum); piNum = parse_xaiger_literal(f); log_debug("piNum = %u\n", piNum); - uint32_t poNum = parse_xaiger_literal(f); + uint32_t poNum YS_ATTRIBUTE(unused) = parse_xaiger_literal(f); log_debug("poNum = %u\n", poNum); uint32_t boxNum = parse_xaiger_literal(f); log_debug("boxNum = %u\n", poNum); @@ -901,8 +901,10 @@ void AigerReader::post_process() RTLIL::Cell* cell = module->cell(stringf("$__box%d__", variable)); if (cell) { // ABC could have optimised this box away module->rename(cell, escaped_s); + #ifndef NDEBUG RTLIL::Module* box_module = design->module(cell->type); log_assert(box_module); + #endif for (const auto &i : cell->connections()) { RTLIL::IdString port_name = i.first; diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 17c4a1e5b..64152c9cb 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -1789,8 +1789,10 @@ struct VerificExtNets new_net = new Net(name.c_str()); nl->Add(new_net); + #ifndef NDEBUG Net *n = route_up(new_net, port->IsOutput(), ca_nl, ca_net); log_assert(n == ca_net); + #endif } if (verific_verbose) diff --git a/kernel/log.h b/kernel/log.h index 3e1facae8..5f53f533a 100644 --- a/kernel/log.h +++ b/kernel/log.h @@ -91,7 +91,7 @@ YS_NORETURN void log_cmd_error(const char *format, ...) YS_ATTRIBUTE(format(prin static inline bool ys_debug(int n = 0) { if (log_force_debug) return true; log_debug_suppressed += n; return false; } # define log_debug(...) do { if (ys_debug(1)) log(__VA_ARGS__); } while (0) #else -static inline bool ys_debug(int n = 0) { return false; } +static inline bool ys_debug(int = 0) { return false; } # define log_debug(_fmt, ...) do { } while (0) #endif diff --git a/passes/opt/opt_expr.cc b/passes/opt/opt_expr.cc index b2dc9a448..1512cea1b 100644 --- a/passes/opt/opt_expr.cc +++ b/passes/opt/opt_expr.cc @@ -117,7 +117,8 @@ void replace_undriven(RTLIL::Design *design, RTLIL::Module *module) } } -void replace_cell(SigMap &assign_map, RTLIL::Module *module, RTLIL::Cell *cell, std::string info, std::string out_port, RTLIL::SigSpec out_val) +void replace_cell(SigMap &assign_map, RTLIL::Module *module, RTLIL::Cell *cell, + const std::string &info YS_ATTRIBUTE(unused), IdString out_port, RTLIL::SigSpec out_val) { RTLIL::SigSpec Y = cell->getPort(out_port); out_val.extend_u0(Y.size(), false); diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 7418ed4a3..da376d09e 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -741,7 +741,7 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri for (auto driver_cell : bit_drivers.at(it.first)) for (auto user_cell : it.second) toposort.edge(driver_cell, user_cell); - bool no_loops = toposort.sort(); + bool no_loops YS_ATTRIBUTE(unused) = toposort.sort(); log_assert(no_loops); for (auto ii = toposort.sorted.rbegin(); ii != toposort.sorted.rend(); ii++) { From 73bf4539298fdc9f11302582f5e5aff57214cd28 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 15 Aug 2019 18:34:36 +0200 Subject: [PATCH 29/94] Improvements in pmgen for recursive patterns Signed-off-by: Clifford Wolf --- Makefile | 5 ++ passes/pmgen/Makefile.inc | 19 +++-- passes/pmgen/README.md | 25 ++++++- passes/pmgen/peepopt_shiftmul.pmg | 2 + passes/pmgen/pmgen.py | 116 +++++++++++++++++++++++++----- 5 files changed, 139 insertions(+), 28 deletions(-) diff --git a/Makefile b/Makefile index 95b5d451b..db8915225 100644 --- a/Makefile +++ b/Makefile @@ -487,6 +487,11 @@ define add_include_file $(eval $(call add_share_file,$(dir share/include/$(1)),$(1))) endef +define add_extra_objs +EXTRA_OBJS += $(1) +.SECONDARY: $(1) +endef + ifeq ($(PRETTY), 1) P_STATUS = 0 P_OFFSET = 0 diff --git a/passes/pmgen/Makefile.inc b/passes/pmgen/Makefile.inc index 7911132db..0d977635b 100644 --- a/passes/pmgen/Makefile.inc +++ b/passes/pmgen/Makefile.inc @@ -1,20 +1,17 @@ +%_pm.h: passes/pmgen/pmgen.py %.pmg + $(P) mkdir -p passes/pmgen && python3 $< -o $@ -p $(subst _pm.h,,$(notdir $@)) $(filter-out $<,$^) + +# -------------------------------------- + OBJS += passes/pmgen/ice40_dsp.o -OBJS += passes/pmgen/peepopt.o - -# -------------------------------------- - passes/pmgen/ice40_dsp.o: passes/pmgen/ice40_dsp_pm.h -EXTRA_OBJS += passes/pmgen/ice40_dsp_pm.h -.SECONDARY: passes/pmgen/ice40_dsp_pm.h - -passes/pmgen/ice40_dsp_pm.h: passes/pmgen/pmgen.py passes/pmgen/ice40_dsp.pmg - $(P) mkdir -p passes/pmgen && python3 $< -o $@ -p ice40_dsp $(filter-out $<,$^) +$(eval $(call add_extra_objs,passes/pmgen/ice40_dsp_pm.h)) # -------------------------------------- +OBJS += passes/pmgen/peepopt.o passes/pmgen/peepopt.o: passes/pmgen/peepopt_pm.h -EXTRA_OBJS += passes/pmgen/peepopt_pm.h -.SECONDARY: passes/pmgen/peepopt_pm.h +$(eval $(call add_extra_objs,passes/pmgen/peepopt_pm.h)) PEEPOPT_PATTERN = passes/pmgen/peepopt_shiftmul.pmg PEEPOPT_PATTERN += passes/pmgen/peepopt_muldiv.pmg diff --git a/passes/pmgen/README.md b/passes/pmgen/README.md index 2f0b1fd5a..db722c818 100644 --- a/passes/pmgen/README.md +++ b/passes/pmgen/README.md @@ -232,5 +232,28 @@ But in some cases it is more natural to utilize the implicit branch statement: portAB = \B; endcode -There is an implicit `code..endcode` block at the end of each `.pmg` file +There is an implicit `code..endcode` block at the end of each (sub)pattern that just accepts everything that gets all the way there. + +A `code..finally..endcode` block executes the code after `finally` during +back-tracking. This is useful for maintaining user data state or printing +debug messages. For example: + + udata > stack + + code + stack.push_back(addAB); + finally + stack.pop_back(); + endcode + +Declaring a subpattern +---------------------- + +A subpattern starts with a line containing the `subpattern` keyword followed +by the name of the subpattern. Subpatterns can be called from a `code` block +using a `subpattern();` C statement. + +Arguments may be passed to subpattern via state variables. The `subpattern` +line must be followed by a `arg ...` line that lists the +state variables used to pass arguments. Subpatterns allow recursion. diff --git a/passes/pmgen/peepopt_shiftmul.pmg b/passes/pmgen/peepopt_shiftmul.pmg index 6adab4e5f..d766d9e4a 100644 --- a/passes/pmgen/peepopt_shiftmul.pmg +++ b/passes/pmgen/peepopt_shiftmul.pmg @@ -34,6 +34,7 @@ match mul endmatch code +{ IdString const_factor_port = port(mul, \A).is_fully_const() ? \A : \B; IdString const_factor_signed = const_factor_port == \A ? \A_SIGNED : \B_SIGNED; Const const_factor_cnst = port(mul, const_factor_port).as_const(); @@ -91,4 +92,5 @@ code blacklist(shift); reject; +} endcode diff --git a/passes/pmgen/pmgen.py b/passes/pmgen/pmgen.py index 81052afce..22a7a5225 100644 --- a/passes/pmgen/pmgen.py +++ b/passes/pmgen/pmgen.py @@ -38,7 +38,10 @@ for a in args: assert prefix is not None current_pattern = None +current_subpattern = None patterns = dict() +subpatterns = dict() +subpattern_args = dict() state_types = dict() udata_types = dict() blocks = list() @@ -104,9 +107,12 @@ def rewrite_cpp(s): return "".join(t) -def process_pmgfile(f): +def process_pmgfile(f, filename): + linenr = 0 global current_pattern + global current_subpattern while True: + linenr += 1 line = f.readline() if line == "": break line = line.strip() @@ -119,19 +125,41 @@ def process_pmgfile(f): if current_pattern is not None: block = dict() block["type"] = "final" - block["pattern"] = current_pattern + block["pattern"] = (current_pattern, current_subpattern) blocks.append(block) line = line.split() assert len(line) == 2 assert line[1] not in patterns current_pattern = line[1] + current_subpattern = "" patterns[current_pattern] = len(blocks) + subpatterns[(current_pattern, current_subpattern)] = len(blocks) + subpattern_args[(current_pattern, current_subpattern)] = list() state_types[current_pattern] = dict() udata_types[current_pattern] = dict() continue assert current_pattern is not None + if cmd == "subpattern": + block = dict() + block["type"] = "final" + block["pattern"] = (current_pattern, current_subpattern) + blocks.append(block) + line = line.split() + assert len(line) == 2 + current_subpattern = line[1] + subpattern_args[(current_pattern, current_subpattern)] = list() + assert (current_pattern, current_subpattern) not in subpatterns + subpatterns[(current_pattern, current_subpattern)] = len(blocks) + continue + + if cmd == "arg": + line = line.split() + assert len(line) > 1 + subpattern_args[(current_pattern, current_subpattern)] += line[1:] + continue + if cmd == "state": m = re.match(r"^state\s+<(.*?)>\s+(([A-Za-z_][A-Za-z_0-9]*\s+)*[A-Za-z_][A-Za-z_0-9]*)\s*$", line) assert m @@ -155,11 +183,12 @@ def process_pmgfile(f): if cmd == "match": block = dict() block["type"] = "match" - block["pattern"] = current_pattern + block["src"] = "%s:%d" % (filename, linenr) + block["pattern"] = (current_pattern, current_subpattern) line = line.split() assert len(line) == 2 - assert line[1] not in state_types[current_pattern] + assert (line[1] not in state_types[current_pattern]) or (state_types[current_pattern][line[1]] == "Cell*") block["cell"] = line[1] state_types[current_pattern][line[1]] = "Cell*"; @@ -168,8 +197,10 @@ def process_pmgfile(f): block["index"] = list() block["filter"] = list() block["optional"] = False + block["semioptional"] = False while True: + linenr += 1 l = f.readline() assert l != "" a = l.split() @@ -201,31 +232,47 @@ def process_pmgfile(f): block["optional"] = True continue + if a[0] == "semioptional": + block["semioptional"] = True + continue + assert False + if block["optional"]: + assert not block["semioptional"] + blocks.append(block) continue if cmd == "code": block = dict() block["type"] = "code" - block["pattern"] = current_pattern + block["src"] = "%s:%d" % (filename, linenr) + block["pattern"] = (current_pattern, current_subpattern) block["code"] = list() + block["fcode"] = list() block["states"] = set() for s in line.split()[1:]: assert s in state_types[current_pattern] block["states"].add(s) + codetype = "code" + while True: + linenr += 1 l = f.readline() assert l != "" a = l.split() if len(a) == 0: continue if a[0] == "endcode": break - block["code"].append(rewrite_cpp(l.rstrip())) + if a[0] == "finally": + codetype = "fcode" + continue + + block[codetype].append(rewrite_cpp(l.rstrip())) blocks.append(block) continue @@ -234,15 +281,16 @@ def process_pmgfile(f): for fn in pmgfiles: with open(fn, "r") as f: - process_pmgfile(f) + process_pmgfile(f, fn) if current_pattern is not None: block = dict() block["type"] = "final" - block["pattern"] = current_pattern + block["pattern"] = (current_pattern, current_subpattern) blocks.append(block) current_pattern = None +current_subpattern = None if debug: pp.pprint(blocks) @@ -335,7 +383,7 @@ with open(outfile, "w") as f: print(" blacklist_dirty = false;", file=f) for index in range(len(blocks)): block = blocks[index] - if block["pattern"] != current_pattern: + if block["pattern"] != (current_pattern, current_subpattern): continue if block["type"] == "match": print(" if (st_{}.{} != nullptr && blacklist_cells.count(st_{}.{})) {{".format(current_pattern, block["cell"], current_pattern, block["cell"]), file=f) @@ -429,13 +477,21 @@ with open(outfile, "w") as f: print(" run_{}([](){{}});".format(current_pattern, current_pattern), file=f) print(" }", file=f) print("", file=f) + + for p, s in sorted(subpatterns.keys()): + print(" void block_subpattern_{}_{}() {{ block_{}(); }}".format(p, s, subpatterns[(p, s)]), file=f) + current_pattern = None + current_subpattern = None for index in range(len(blocks)): block = blocks[index] + if block["type"] in ("match", "code"): + print(" // {}".format(block["src"]), file=f) + print(" void block_{}() {{".format(index), file=f) - current_pattern = block["pattern"] + current_pattern, current_subpattern = block["pattern"] if block["type"] == "final": print(" on_accept();", file=f) @@ -449,7 +505,10 @@ with open(outfile, "w") as f: nonconst_st = set() restore_st = set() - for i in range(patterns[current_pattern], index): + for s in subpattern_args[(current_pattern, current_subpattern)]: + const_st.add(s) + + for i in range(subpatterns[(current_pattern, current_subpattern)], index): if blocks[i]["type"] == "code": for s in blocks[i]["states"]: const_st.add(s) @@ -482,6 +541,10 @@ with open(outfile, "w") as f: t = state_types[current_pattern][s] print(" {} &{} YS_ATTRIBUTE(unused) = st_{}.{};".format(t, s, current_pattern, s), file=f) + for u in sorted(udata_types[current_pattern].keys()): + t = udata_types[current_pattern][u] + print(" {} &{} YS_ATTRIBUTE(unused) = ud_{}.{};".format(t, u, current_pattern, u), file=f) + if len(restore_st): print("", file=f) for s in sorted(restore_st): @@ -490,24 +553,32 @@ with open(outfile, "w") as f: if block["type"] == "code": print("", file=f) - print(" do {", file=f) print("#define reject do {{ check_blacklist_{}(); goto rollback_label; }} while(0)".format(current_pattern), file=f) print("#define accept do {{ on_accept(); check_blacklist_{}(); if (rollback) goto rollback_label; }} while(0)".format(current_pattern), file=f) print("#define branch do {{ block_{}(); if (rollback) goto rollback_label; }} while(0)".format(index+1), file=f) + print("#define subpattern(pattern_name) block_subpattern_{}_ ## pattern_name ()".format(current_pattern), file=f) for line in block["code"]: - print(" " + line, file=f) + print(" " + line, file=f) print("", file=f) - print(" block_{}();".format(index+1), file=f) + print(" block_{}();".format(index+1), file=f) + print("#undef reject", file=f) print("#undef accept", file=f) print("#undef branch", file=f) - print(" } while (0);", file=f) + print("#undef subpattern", file=f) + print("", file=f) print("rollback_label:", file=f) print(" YS_ATTRIBUTE(unused);", file=f) + if len(block["fcode"]): + print("#define accept do {{ on_accept(); check_blacklist_{}(); }} while(0)".format(current_pattern), file=f) + for line in block["fcode"]: + print(" " + line, file=f) + print("#undef accept", file=f) + if len(restore_st) or len(nonconst_st): print("", file=f) for s in sorted(restore_st): @@ -524,12 +595,15 @@ with open(outfile, "w") as f: elif block["type"] == "match": assert len(restore_st) == 0 + print(" Cell* backup_{} = {};".format(block["cell"], block["cell"]), file=f) + if len(block["if"]): for expr in block["if"]: print("", file=f) print(" if (!({})) {{".format(expr), file=f) print(" {} = nullptr;".format(block["cell"]), file=f) print(" block_{}();".format(index+1), file=f) + print(" {} = backup_{};".format(block["cell"], block["cell"]), file=f) print(" return;", file=f) print(" }", file=f) @@ -539,16 +613,21 @@ with open(outfile, "w") as f: print(" std::get<{}>(key) = {};".format(field, entry[2]), file=f) print(" const vector &cells = index_{}[key];".format(index), file=f) + if block["semioptional"]: + print(" bool found_semioptional_match = false;", file=f) + print("", file=f) print(" for (int idx = 0; idx < GetSize(cells); idx++) {", file=f) print(" {} = cells[idx];".format(block["cell"]), file=f) print(" if (blacklist_cells.count({})) continue;".format(block["cell"]), file=f) for expr in block["filter"]: print(" if (!({})) continue;".format(expr), file=f) + if block["semioptional"]: + print(" found_semioptional_match = true;", file=f) print(" block_{}();".format(index+1), file=f) print(" if (rollback) {", file=f) print(" if (rollback != {}) {{".format(index+1), file=f) - print(" {} = nullptr;".format(block["cell"]), file=f) + print(" {} = backup_{};".format(block["cell"], block["cell"]), file=f) print(" return;", file=f) print(" }", file=f) print(" rollback = 0;", file=f) @@ -561,6 +640,11 @@ with open(outfile, "w") as f: if block["optional"]: print(" block_{}();".format(index+1), file=f) + if block["semioptional"]: + print(" if (!found_semioptional_match) block_{}();".format(index+1), file=f) + + print(" {} = backup_{};".format(block["cell"], block["cell"]), file=f) + else: assert False From 03f98d9176357b73455cf0b2c44ec3897864e893 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 15 Aug 2019 18:35:00 +0200 Subject: [PATCH 30/94] Add demo_reduce pass to demonstrace recursive pattern matching Signed-off-by: Clifford Wolf --- passes/pmgen/.gitignore | 1 + passes/pmgen/Makefile.inc | 6 +++ passes/pmgen/demo_reduce.cc | 99 ++++++++++++++++++++++++++++++++++++ passes/pmgen/demo_reduce.pmg | 81 +++++++++++++++++++++++++++++ 4 files changed, 187 insertions(+) create mode 100644 passes/pmgen/demo_reduce.cc create mode 100644 passes/pmgen/demo_reduce.pmg diff --git a/passes/pmgen/.gitignore b/passes/pmgen/.gitignore index 0ad36ea2c..a1fe9a7dc 100644 --- a/passes/pmgen/.gitignore +++ b/passes/pmgen/.gitignore @@ -1,2 +1,3 @@ +/demo_reduce_pm.h /ice40_dsp_pm.h /peepopt_pm.h diff --git a/passes/pmgen/Makefile.inc b/passes/pmgen/Makefile.inc index 0d977635b..3aaee4047 100644 --- a/passes/pmgen/Makefile.inc +++ b/passes/pmgen/Makefile.inc @@ -9,6 +9,12 @@ $(eval $(call add_extra_objs,passes/pmgen/ice40_dsp_pm.h)) # -------------------------------------- +OBJS += passes/pmgen/demo_reduce.o +passes/pmgen/demo_reduce.o: passes/pmgen/demo_reduce_pm.h +$(eval $(call add_extra_objs,passes/pmgen/demo_reduce_pm.h)) + +# -------------------------------------- + OBJS += passes/pmgen/peepopt.o passes/pmgen/peepopt.o: passes/pmgen/peepopt_pm.h $(eval $(call add_extra_objs,passes/pmgen/peepopt_pm.h)) diff --git a/passes/pmgen/demo_reduce.cc b/passes/pmgen/demo_reduce.cc new file mode 100644 index 000000000..dd8c66f56 --- /dev/null +++ b/passes/pmgen/demo_reduce.cc @@ -0,0 +1,99 @@ +/* + * 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/yosys.h" +#include "kernel/sigtools.h" + +USING_YOSYS_NAMESPACE +PRIVATE_NAMESPACE_BEGIN + +#include "passes/pmgen/demo_reduce_pm.h" + +void create_reduce(demo_reduce_pm &pm) +{ + auto &st = pm.st_reduce; + auto &ud = pm.ud_reduce; + + if (ud.longest_chain.empty()) + return; + + log("Found chain of length %d (%s):\n", GetSize(ud.longest_chain), log_id(st.first->type)); + + SigSpec A; + SigSpec Y = ud.longest_chain.front().first->getPort(ID(Y)); + auto last_cell = ud.longest_chain.back().first; + + for (auto it : ud.longest_chain) { + auto cell = it.first; + if (cell == last_cell) { + A.append(cell->getPort(ID(A))); + A.append(cell->getPort(ID(B))); + } else { + A.append(cell->getPort(it.second == ID(A) ? ID(B) : ID(A))); + } + log(" %s\n", log_id(cell)); + pm.autoremove(cell); + } + + Cell *c; + + if (last_cell->type == ID($_AND_)) + c = pm.module->addReduceAnd(NEW_ID, A, Y); + else if (last_cell->type == ID($_OR_)) + c = pm.module->addReduceOr(NEW_ID, A, Y); + else if (last_cell->type == ID($_XOR_)) + c = pm.module->addReduceXor(NEW_ID, A, Y); + else + log_abort(); + + log(" -> %s (%s)\n", log_id(c), log_id(c->type)); +} + +struct DemoReducePass : public Pass { + DemoReducePass() : Pass("demo_reduce", "map chains of AND/OR/XOR") { } + void help() YS_OVERRIDE + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" demo_reduce [options] [selection]\n"); + log("\n"); + log("Demo for recursive pmgen patterns. Map chains of AND/OR/XOR to $reduce_*.\n"); + log("\n"); + } + void execute(std::vector args, RTLIL::Design *design) YS_OVERRIDE + { + log_header(design, "Executing DEMO_REDUCE pass.\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()) + demo_reduce_pm(module, module->selected_cells()).run_reduce(create_reduce); + } +} DemoReducePass; + +PRIVATE_NAMESPACE_END diff --git a/passes/pmgen/demo_reduce.pmg b/passes/pmgen/demo_reduce.pmg new file mode 100644 index 000000000..ddc932de5 --- /dev/null +++ b/passes/pmgen/demo_reduce.pmg @@ -0,0 +1,81 @@ +pattern reduce + +state portname +udata >> chain longest_chain +udata > non_first_cells + +code + non_first_cells.clear(); + subpattern(setup); +endcode + +match first + select first->type.in($_AND_, $_OR_, $_XOR_) + filter !non_first_cells.count(first) +endmatch + +code + longest_chain.clear(); + chain.push_back(make_pair(first, \A)); + subpattern(tail); + chain.back().second = \B; + subpattern(tail); +finally + chain.pop_back(); + log_assert(chain.empty()); +endcode + +// ------------------------------------------------------------------ + +subpattern setup + +match first + select first->type.in($_AND_, $_OR_, $_XOR_) +endmatch + +code portname + portname = \A; + branch; + portname = \B; +endcode + +match next + select nusers(port(next, \Y)) == 2 + select next->type.in($_AND_, $_OR_, $_XOR_) + index next->type === first->type + index port(next, \Y) === port(first, portname) +endmatch + +code + non_first_cells.insert(next); + reject; +endcode + +// ------------------------------------------------------------------ + +subpattern tail +arg first + +match next + semioptional + select nusers(port(next, \Y)) == 2 + select next->type.in($_AND_, $_OR_, $_XOR_) + index next->type === chain.back().first->type + index port(next, \Y) === port(chain.back().first, chain.back().second) +endmatch + +code + if (next) { + chain.push_back(make_pair(next, \A)); + subpattern(tail); + chain.back().second = \B; + subpattern(tail); + } else { + if (GetSize(chain) > GetSize(longest_chain)) + longest_chain = chain; + } + reject; +finally + if (next) + chain.pop_back(); +endcode From eb80d3d43fdb070fe99718501d3b0fbdca61ab8d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 15 Aug 2019 22:47:59 +0200 Subject: [PATCH 31/94] Change pmgen default rule to reject, switch peepopt behavior to accept Signed-off-by: Clifford Wolf --- passes/pmgen/demo_reduce.pmg | 3 +-- passes/pmgen/ice40_dsp.pmg | 1 + passes/pmgen/peepopt_muldiv.pmg | 2 +- passes/pmgen/peepopt_shiftmul.pmg | 2 +- passes/pmgen/pmgen.py | 4 +--- 5 files changed, 5 insertions(+), 7 deletions(-) diff --git a/passes/pmgen/demo_reduce.pmg b/passes/pmgen/demo_reduce.pmg index ddc932de5..09856e9ae 100644 --- a/passes/pmgen/demo_reduce.pmg +++ b/passes/pmgen/demo_reduce.pmg @@ -23,6 +23,7 @@ code finally chain.pop_back(); log_assert(chain.empty()); + accept; endcode // ------------------------------------------------------------------ @@ -48,7 +49,6 @@ endmatch code non_first_cells.insert(next); - reject; endcode // ------------------------------------------------------------------ @@ -74,7 +74,6 @@ code if (GetSize(chain) > GetSize(longest_chain)) longest_chain = chain; } - reject; finally if (next) chain.pop_back(); diff --git a/passes/pmgen/ice40_dsp.pmg b/passes/pmgen/ice40_dsp.pmg index 1f3590d4e..7003092bb 100644 --- a/passes/pmgen/ice40_dsp.pmg +++ b/passes/pmgen/ice40_dsp.pmg @@ -159,4 +159,5 @@ code clock clock_pol clock_vld clock_pol = cp; clock_vld = true; } + accept; endcode diff --git a/passes/pmgen/peepopt_muldiv.pmg b/passes/pmgen/peepopt_muldiv.pmg index 06c275834..7cad759d0 100644 --- a/passes/pmgen/peepopt_muldiv.pmg +++ b/passes/pmgen/peepopt_muldiv.pmg @@ -32,5 +32,5 @@ code log("muldiv pattern in %s: mul=%s, div=%s\n", log_id(module), log_id(mul), log_id(div)); module->connect(div_y, val_y); autoremove(div); - reject; + accept; endcode diff --git a/passes/pmgen/peepopt_shiftmul.pmg b/passes/pmgen/peepopt_shiftmul.pmg index d766d9e4a..d4748ae19 100644 --- a/passes/pmgen/peepopt_shiftmul.pmg +++ b/passes/pmgen/peepopt_shiftmul.pmg @@ -91,6 +91,6 @@ code shift->setParam(\B_WIDTH, GetSize(new_b)); blacklist(shift); - reject; + accept; } endcode diff --git a/passes/pmgen/pmgen.py b/passes/pmgen/pmgen.py index 22a7a5225..c6e9a9cbf 100644 --- a/passes/pmgen/pmgen.py +++ b/passes/pmgen/pmgen.py @@ -494,8 +494,6 @@ with open(outfile, "w") as f: current_pattern, current_subpattern = block["pattern"] if block["type"] == "final": - print(" on_accept();", file=f) - print(" check_blacklist_{}();".format(current_pattern), file=f) print(" }", file=f) if index+1 != len(blocks): print("", file=f) @@ -556,7 +554,7 @@ with open(outfile, "w") as f: print("#define reject do {{ check_blacklist_{}(); goto rollback_label; }} while(0)".format(current_pattern), file=f) print("#define accept do {{ on_accept(); check_blacklist_{}(); if (rollback) goto rollback_label; }} while(0)".format(current_pattern), file=f) print("#define branch do {{ block_{}(); if (rollback) goto rollback_label; }} while(0)".format(index+1), file=f) - print("#define subpattern(pattern_name) block_subpattern_{}_ ## pattern_name ()".format(current_pattern), file=f) + print("#define subpattern(pattern_name) do {{ block_subpattern_{}_ ## pattern_name (); if (rollback) goto rollback_label; }} while(0)".format(current_pattern), file=f) for line in block["code"]: print(" " + line, file=f) From 969ab9027a8c4ee831e39f193f7ecb68457152c3 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 15 Aug 2019 22:48:13 +0200 Subject: [PATCH 32/94] Update pmgen documentation Signed-off-by: Clifford Wolf --- passes/pmgen/README.md | 62 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 58 insertions(+), 4 deletions(-) diff --git a/passes/pmgen/README.md b/passes/pmgen/README.md index db722c818..4aa7de162 100644 --- a/passes/pmgen/README.md +++ b/passes/pmgen/README.md @@ -118,8 +118,8 @@ write matchers: connected to any of the given signal bits, plus one if any of the signal bits is also a primary input or primary output. -- In `code..endcode` blocks there exist `accept`, `reject`, and `branch` - statements. +- In `code..endcode` blocks there exist `accept`, `reject`, `branch`, and + `subpattern` statements. - In `index` statements there is a special `===` operator for the index lookup. @@ -233,7 +233,7 @@ But in some cases it is more natural to utilize the implicit branch statement: endcode There is an implicit `code..endcode` block at the end of each (sub)pattern -that just accepts everything that gets all the way there. +that just rejects. A `code..finally..endcode` block executes the code after `finally` during back-tracking. This is useful for maintaining user data state or printing @@ -243,10 +243,14 @@ debug messages. For example: code stack.push_back(addAB); + ... finally stack.pop_back(); endcode +`accept` statements can be used inside the `finally` section, but not +`reject`, `branch`, or `subpattern`. + Declaring a subpattern ---------------------- @@ -256,4 +260,54 @@ using a `subpattern();` C statement. Arguments may be passed to subpattern via state variables. The `subpattern` line must be followed by a `arg ...` line that lists the -state variables used to pass arguments. Subpatterns allow recursion. +state variables used to pass arguments. + + state foobar_type + state foobar_state + + code foobar_type foobar_state + foobar_state = false; + foobar_type = $add; + subpattern(foo); + foobar_type = $sub; + subpattern(bar); + endcode + + subpattern foo + arg foobar_type foobar_state + + match addsub + index addsub->type === foobar_type + ... + endmatch + + code + if (foobar_state) { + subpattern(tail); + } else { + foobar_state = true; + subpattern(bar); + } + endcode + + subpattern bar + arg foobar_type foobar_state + + match addsub + index addsub->type === foobar_type + ... + endmatch + + code + if (foobar_state) { + subpattern(tail); + } else { + foobar_state = true; + subpattern(foo); + } + endcode + + subpattern tail + ... + +Subpatterns cann be called recursively. From 016036f247f9538016f4e8cbdb889ac631f4a5c0 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 15 Aug 2019 23:02:37 +0200 Subject: [PATCH 33/94] Add doc for pmgen semioptional statement, Add pmgen changes to CHANGELOG Signed-off-by: Clifford Wolf --- CHANGELOG | 1 + passes/pmgen/README.md | 3 +++ 2 files changed, 4 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index 638c36121..cceb9fc9f 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -19,6 +19,7 @@ Yosys 0.9 .. Yosys 0.9-dev - Added automatic gzip compression (based on filename extension) for backends - Improve attribute and parameter encoding in JSON to avoid ambiguities between bit vectors and strings containing [01xz]* + - Improvements in pmgen: subpattern and recursive matches Yosys 0.8 .. Yosys 0.8-dev -------------------------- diff --git a/passes/pmgen/README.md b/passes/pmgen/README.md index 4aa7de162..f92445a86 100644 --- a/passes/pmgen/README.md +++ b/passes/pmgen/README.md @@ -175,6 +175,9 @@ explore the case where `mul` is set to `nullptr`. Without the `optional` statement a match may only be assigned nullptr when one of the `if` expressions evaluates to `false`. +The `semioptional` statement marks matches that must match if at least one +matching cell exists, but if no matching cell exists it is set to `nullptr`. + Additional code --------------- From 52355f5185fe42e28775e897f458b38a439c0ec5 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 15 Aug 2019 14:50:10 -0700 Subject: [PATCH 34/94] Use more ID::{A,B,Y,blackbox,whitebox} --- kernel/cellaigs.cc | 96 ++++----- kernel/celledges.cc | 14 +- kernel/celltypes.h | 10 +- kernel/consteval.h | 16 +- kernel/macc.h | 8 +- kernel/rtlil.cc | 192 +++++++++--------- kernel/satgen.h | 236 +++++++++++----------- kernel/yosys.h | 2 + passes/opt/muxpack.cc | 38 ++-- passes/opt/opt_clean.cc | 6 +- passes/opt/opt_demorgan.cc | 14 +- passes/opt/opt_expr.cc | 318 +++++++++++++++--------------- passes/opt/opt_lut.cc | 28 +-- passes/opt/opt_merge.cc | 48 ++--- passes/opt/opt_muxtree.cc | 24 +-- passes/opt/opt_reduce.cc | 66 +++---- passes/opt/opt_rmdff.cc | 8 +- passes/opt/pmux2shiftx.cc | 30 +-- passes/opt/share.cc | 70 +++---- passes/opt/wreduce.cc | 46 ++--- passes/techmap/abc.cc | 86 ++++---- passes/techmap/abc9.cc | 26 +-- passes/techmap/alumacc.cc | 34 ++-- passes/techmap/deminout.cc | 4 +- passes/techmap/dff2dffe.cc | 18 +- passes/techmap/dff2dffs.cc | 10 +- passes/techmap/dfflibmap.cc | 6 +- passes/techmap/extract_counter.cc | 38 ++-- passes/techmap/extract_fa.cc | 22 +-- passes/techmap/extract_reduce.cc | 20 +- passes/techmap/iopadmap.cc | 4 +- passes/techmap/lut2mux.cc | 4 +- passes/techmap/maccmap.cc | 28 +-- passes/techmap/muxcover.cc | 30 +-- passes/techmap/nlutmap.cc | 2 +- passes/techmap/pmuxtree.cc | 8 +- passes/techmap/shregmap.cc | 22 +-- passes/techmap/simplemap.cc | 120 +++++------ passes/techmap/techmap.cc | 2 +- passes/techmap/tribuf.cc | 22 +-- 40 files changed, 889 insertions(+), 887 deletions(-) diff --git a/kernel/cellaigs.cc b/kernel/cellaigs.cc index 6d496db45..02854edb2 100644 --- a/kernel/cellaigs.cc +++ b/kernel/cellaigs.cc @@ -292,19 +292,19 @@ Aig::Aig(Cell *cell) if (cell->type.in(ID($not), ID($_NOT_), ID($pos), ID($_BUF_))) { - for (int i = 0; i < GetSize(cell->getPort(ID(Y))); i++) { - int A = mk.inport(ID(A), i); + for (int i = 0; i < GetSize(cell->getPort(ID::Y)); i++) { + int A = mk.inport(ID::A, i); int Y = cell->type.in(ID($not), ID($_NOT_)) ? mk.not_gate(A) : A; - mk.outport(Y, ID(Y), i); + mk.outport(Y, ID::Y, i); } goto optimize; } if (cell->type.in(ID($and), ID($_AND_), ID($_NAND_), ID($or), ID($_OR_), ID($_NOR_), ID($xor), ID($xnor), ID($_XOR_), ID($_XNOR_), ID($_ANDNOT_), ID($_ORNOT_))) { - for (int i = 0; i < GetSize(cell->getPort(ID(Y))); i++) { - int A = mk.inport(ID(A), i); - int B = mk.inport(ID(B), i); + for (int i = 0; i < GetSize(cell->getPort(ID::Y)); i++) { + int A = mk.inport(ID::A, i); + int B = mk.inport(ID::B, i); int Y = cell->type.in(ID($and), ID($_AND_)) ? mk.and_gate(A, B) : cell->type.in(ID($_NAND_)) ? mk.nand_gate(A, B) : cell->type.in(ID($or), ID($_OR_)) ? mk.or_gate(A, B) : @@ -313,7 +313,7 @@ Aig::Aig(Cell *cell) cell->type.in(ID($xnor), ID($_XNOR_)) ? mk.xnor_gate(A, B) : cell->type.in(ID($_ANDNOT_)) ? mk.andnot_gate(A, B) : cell->type.in(ID($_ORNOT_)) ? mk.ornot_gate(A, B) : -1; - mk.outport(Y, ID(Y), i); + mk.outport(Y, ID::Y, i); } goto optimize; } @@ -321,22 +321,22 @@ Aig::Aig(Cell *cell) if (cell->type.in(ID($mux), ID($_MUX_))) { int S = mk.inport(ID(S)); - for (int i = 0; i < GetSize(cell->getPort(ID(Y))); i++) { - int A = mk.inport(ID(A), i); - int B = mk.inport(ID(B), i); + for (int i = 0; i < GetSize(cell->getPort(ID::Y)); i++) { + int A = mk.inport(ID::A, i); + int B = mk.inport(ID::B, i); int Y = mk.mux_gate(A, B, S); if (cell->type == ID($_NMUX_)) Y = mk.not_gate(Y); - mk.outport(Y, ID(Y), i); + mk.outport(Y, ID::Y, i); } goto optimize; } if (cell->type.in(ID($reduce_and), ID($reduce_or), ID($reduce_xor), ID($reduce_xnor), ID($reduce_bool))) { - int Y = mk.inport(ID(A), 0); - for (int i = 1; i < GetSize(cell->getPort(ID(A))); i++) { - int A = mk.inport(ID(A), i); + int Y = mk.inport(ID::A, 0); + for (int i = 1; i < GetSize(cell->getPort(ID::A)); i++) { + int A = mk.inport(ID::A, i); if (cell->type == ID($reduce_and)) Y = mk.and_gate(A, Y); if (cell->type == ID($reduce_or)) Y = mk.or_gate(A, Y); if (cell->type == ID($reduce_bool)) Y = mk.or_gate(A, Y); @@ -345,35 +345,35 @@ Aig::Aig(Cell *cell) } if (cell->type == ID($reduce_xnor)) Y = mk.not_gate(Y); - mk.outport(Y, ID(Y), 0); - for (int i = 1; i < GetSize(cell->getPort(ID(Y))); i++) - mk.outport(mk.bool_node(false), ID(Y), i); + mk.outport(Y, ID::Y, 0); + for (int i = 1; i < GetSize(cell->getPort(ID::Y)); i++) + mk.outport(mk.bool_node(false), ID::Y, i); goto optimize; } if (cell->type.in(ID($logic_not), ID($logic_and), ID($logic_or))) { - int A = mk.inport(ID(A), 0), Y = -1; - for (int i = 1; i < GetSize(cell->getPort(ID(A))); i++) - A = mk.or_gate(mk.inport(ID(A), i), A); + int A = mk.inport(ID::A, 0), Y = -1; + for (int i = 1; i < GetSize(cell->getPort(ID::A)); i++) + A = mk.or_gate(mk.inport(ID::A, i), A); if (cell->type.in(ID($logic_and), ID($logic_or))) { - int B = mk.inport(ID(B), 0); - for (int i = 1; i < GetSize(cell->getPort(ID(B))); i++) - B = mk.or_gate(mk.inport(ID(B), i), B); + int B = mk.inport(ID::B, 0); + for (int i = 1; i < GetSize(cell->getPort(ID::B)); i++) + B = mk.or_gate(mk.inport(ID::B, i), B); if (cell->type == ID($logic_and)) Y = mk.and_gate(A, B); if (cell->type == ID($logic_or)) Y = mk.or_gate(A, B); } else { if (cell->type == ID($logic_not)) Y = mk.not_gate(A); } - mk.outport_bool(Y, ID(Y)); + mk.outport_bool(Y, ID::Y); goto optimize; } if (cell->type.in(ID($add), ID($sub))) { - int width = GetSize(cell->getPort(ID(Y))); - vector A = mk.inport_vec(ID(A), width); - vector B = mk.inport_vec(ID(B), width); + int width = GetSize(cell->getPort(ID::Y)); + vector A = mk.inport_vec(ID::A, width); + vector B = mk.inport_vec(ID::B, width); int carry = mk.bool_node(false); if (cell->type == ID($sub)) { for (auto &n : B) @@ -381,15 +381,15 @@ Aig::Aig(Cell *cell) carry = mk.not_gate(carry); } vector Y = mk.adder(A, B, carry); - mk.outport_vec(Y, ID(Y)); + mk.outport_vec(Y, ID::Y); goto optimize; } if (cell->type == ID($alu)) { - int width = GetSize(cell->getPort(ID(Y))); - vector A = mk.inport_vec(ID(A), width); - vector B = mk.inport_vec(ID(B), width); + int width = GetSize(cell->getPort(ID::Y)); + vector A = mk.inport_vec(ID::A, width); + vector B = mk.inport_vec(ID::B, width); int carry = mk.inport(ID(CI)); int binv = mk.inport(ID(BI)); for (auto &n : B) @@ -398,7 +398,7 @@ Aig::Aig(Cell *cell) vector Y = mk.adder(A, B, carry, &X, &CO); for (int i = 0; i < width; i++) X[i] = mk.xor_gate(A[i], B[i]); - mk.outport_vec(Y, ID(Y)); + mk.outport_vec(Y, ID::Y); mk.outport_vec(X, ID(X)); mk.outport_vec(CO, ID(CO)); goto optimize; @@ -406,57 +406,57 @@ Aig::Aig(Cell *cell) if (cell->type.in(ID($eq), ID($ne))) { - int width = max(GetSize(cell->getPort(ID(A))), GetSize(cell->getPort(ID(B)))); - vector A = mk.inport_vec(ID(A), width); - vector B = mk.inport_vec(ID(B), width); + int width = max(GetSize(cell->getPort(ID::A)), GetSize(cell->getPort(ID::B))); + vector A = mk.inport_vec(ID::A, width); + vector B = mk.inport_vec(ID::B, width); int Y = mk.bool_node(false); for (int i = 0; i < width; i++) Y = mk.or_gate(Y, mk.xor_gate(A[i], B[i])); if (cell->type == ID($eq)) Y = mk.not_gate(Y); - mk.outport_bool(Y, ID(Y)); + mk.outport_bool(Y, ID::Y); goto optimize; } if (cell->type == ID($_AOI3_)) { - int A = mk.inport(ID(A)); - int B = mk.inport(ID(B)); + int A = mk.inport(ID::A); + int B = mk.inport(ID::B); int C = mk.inport(ID(C)); int Y = mk.nor_gate(mk.and_gate(A, B), C); - mk.outport(Y, ID(Y)); + mk.outport(Y, ID::Y); goto optimize; } if (cell->type == ID($_OAI3_)) { - int A = mk.inport(ID(A)); - int B = mk.inport(ID(B)); + int A = mk.inport(ID::A); + int B = mk.inport(ID::B); int C = mk.inport(ID(C)); int Y = mk.nand_gate(mk.or_gate(A, B), C); - mk.outport(Y, ID(Y)); + mk.outport(Y, ID::Y); goto optimize; } if (cell->type == ID($_AOI4_)) { - int A = mk.inport(ID(A)); - int B = mk.inport(ID(B)); + int A = mk.inport(ID::A); + int B = mk.inport(ID::B); int C = mk.inport(ID(C)); int D = mk.inport(ID(D)); int Y = mk.nor_gate(mk.and_gate(A, B), mk.and_gate(C, D)); - mk.outport(Y, ID(Y)); + mk.outport(Y, ID::Y); goto optimize; } if (cell->type == ID($_OAI4_)) { - int A = mk.inport(ID(A)); - int B = mk.inport(ID(B)); + int A = mk.inport(ID::A); + int B = mk.inport(ID::B); int C = mk.inport(ID(C)); int D = mk.inport(ID(D)); int Y = mk.nand_gate(mk.or_gate(A, B), mk.or_gate(C, D)); - mk.outport(Y, ID(Y)); + mk.outport(Y, ID::Y); goto optimize; } diff --git a/kernel/celledges.cc b/kernel/celledges.cc index 7a324a06e..d0bb99e83 100644 --- a/kernel/celledges.cc +++ b/kernel/celledges.cc @@ -24,7 +24,7 @@ PRIVATE_NAMESPACE_BEGIN void bitwise_unary_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell) { - IdString A = ID(A), Y = ID(Y); + IdString A = ID::A, Y = ID::Y; bool is_signed = cell->getParam(ID(A_SIGNED)).as_bool(); int a_width = GetSize(cell->getPort(A)); @@ -41,7 +41,7 @@ void bitwise_unary_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell) void bitwise_binary_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell) { - IdString A = ID(A), B = ID(B), Y = ID(Y); + IdString A = ID::A, B = ID::B, Y = ID::Y; bool is_signed = cell->getParam(ID(A_SIGNED)).as_bool(); int a_width = GetSize(cell->getPort(A)); @@ -71,7 +71,7 @@ void bitwise_binary_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell) void arith_neg_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell) { - IdString A = ID(A), Y = ID(Y); + IdString A = ID::A, Y = ID::Y; bool is_signed = cell->getParam(ID(A_SIGNED)).as_bool(); int a_width = GetSize(cell->getPort(A)); @@ -87,7 +87,7 @@ void arith_neg_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell) void arith_binary_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell) { - IdString A = ID(A), B = ID(B), Y = ID(Y); + IdString A = ID::A, B = ID::B, Y = ID::Y; bool is_signed = cell->getParam(ID(A_SIGNED)).as_bool(); int a_width = GetSize(cell->getPort(A)); @@ -114,7 +114,7 @@ void arith_binary_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell) void reduce_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell) { - IdString A = ID(A), Y = ID(Y); + IdString A = ID::A, Y = ID::Y; int a_width = GetSize(cell->getPort(A)); @@ -124,7 +124,7 @@ void reduce_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell) void compare_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell) { - IdString A = ID(A), B = ID(B), Y = ID(Y); + IdString A = ID::A, B = ID::B, Y = ID::Y; int a_width = GetSize(cell->getPort(A)); int b_width = GetSize(cell->getPort(B)); @@ -138,7 +138,7 @@ void compare_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell) void mux_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell) { - IdString A = ID(A), B = ID(B), S = ID(S), Y = ID(Y); + IdString A = ID::A, B = ID::B, S = ID(S), Y = ID::Y; int a_width = GetSize(cell->getPort(A)); int b_width = GetSize(cell->getPort(B)); diff --git a/kernel/celltypes.h b/kernel/celltypes.h index ade305e83..bc96fd602 100644 --- a/kernel/celltypes.h +++ b/kernel/celltypes.h @@ -84,7 +84,7 @@ struct CellTypes { setup_internals_eval(); - IdString A = ID(A), B = ID(B), EN = ID(EN), Y = ID(Y); + IdString A = ID::A, B = ID::B, EN = ID(EN), Y = ID::Y; IdString SRC = ID(SRC), DST = ID(DST), DAT = ID(DAT); IdString EN_SRC = ID(EN_SRC), EN_DST = ID(EN_DST); @@ -121,7 +121,7 @@ struct CellTypes ID($add), ID($sub), ID($mul), ID($div), ID($mod), ID($pow), ID($logic_and), ID($logic_or), ID($concat), ID($macc) }; - IdString A = ID(A), B = ID(B), S = ID(S), Y = ID(Y); + IdString A = ID::A, B = ID::B, S = ID(S), Y = ID::Y; IdString P = ID(P), G = ID(G), C = ID(C), X = ID(X); IdString BI = ID(BI), CI = ID(CI), CO = ID(CO), EN = ID(EN); @@ -177,19 +177,19 @@ struct CellTypes { setup_stdcells_eval(); - IdString A = ID(A), E = ID(E), Y = ID(Y); + IdString A = ID::A, E = ID(E), Y = ID::Y; setup_type(ID($_TBUF_), {A, E}, {Y}, true); } void setup_stdcells_eval() { - IdString A = ID(A), B = ID(B), C = ID(C), D = ID(D); + IdString A = ID::A, B = ID::B, C = ID(C), D = ID(D); IdString E = ID(E), F = ID(F), G = ID(G), H = ID(H); IdString I = ID(I), J = ID(J), K = ID(K), L = ID(L); IdString M = ID(M), N = ID(N), O = ID(O), P = ID(P); IdString S = ID(S), T = ID(T), U = ID(U), V = ID(V); - IdString Y = ID(Y); + IdString Y = ID::Y; setup_type(ID($_BUF_), {A}, {Y}, true); setup_type(ID($_NOT_), {A}, {Y}, true); diff --git a/kernel/consteval.h b/kernel/consteval.h index 09b4c434b..7a83d28e7 100644 --- a/kernel/consteval.h +++ b/kernel/consteval.h @@ -128,8 +128,8 @@ struct ConstEval RTLIL::SigSpec sig_a, sig_b, sig_s, sig_y; - log_assert(cell->hasPort(ID(Y))); - sig_y = values_map(assign_map(cell->getPort(ID(Y)))); + log_assert(cell->hasPort(ID::Y)); + sig_y = values_map(assign_map(cell->getPort(ID::Y))); if (sig_y.is_fully_const()) return true; @@ -139,11 +139,11 @@ struct ConstEval return false; } - if (cell->hasPort(ID(A))) - sig_a = cell->getPort(ID(A)); + if (cell->hasPort(ID::A)) + sig_a = cell->getPort(ID::A); - if (cell->hasPort(ID(B))) - sig_b = cell->getPort(ID(B)); + if (cell->hasPort(ID::B)) + sig_b = cell->getPort(ID::B); if (cell->type.in(ID($mux), ID($pmux), ID($_MUX_), ID($_NMUX_))) { @@ -298,11 +298,11 @@ struct ConstEval return false; } - RTLIL::Const result(0, GetSize(cell->getPort(ID(Y)))); + RTLIL::Const result(0, GetSize(cell->getPort(ID::Y))); if (!macc.eval(result)) log_abort(); - set(cell->getPort(ID(Y)), result); + set(cell->getPort(ID::Y), result); } else { diff --git a/kernel/macc.h b/kernel/macc.h index e07e7e01a..371f6737d 100644 --- a/kernel/macc.h +++ b/kernel/macc.h @@ -99,10 +99,10 @@ struct Macc void from_cell(RTLIL::Cell *cell) { - RTLIL::SigSpec port_a = cell->getPort(ID(A)); + RTLIL::SigSpec port_a = cell->getPort(ID::A); ports.clear(); - bit_ports = cell->getPort(ID(B)); + bit_ports = cell->getPort(ID::B); std::vector config_bits = cell->getParam(ID(CONFIG)).bits; int config_cursor = 0; @@ -191,8 +191,8 @@ struct Macc port_a.append(port.in_b); } - cell->setPort(ID(A), port_a); - cell->setPort(ID(B), bit_ports); + cell->setPort(ID::A, port_a); + cell->setPort(ID::B, bit_ports); cell->setParam(ID(CONFIG), config_bits); cell->setParam(ID(CONFIG_WIDTH), GetSize(config_bits)); cell->setParam(ID(A_WIDTH), GetSize(port_a)); diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index d01bd0c62..1d380135b 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -717,7 +717,7 @@ void RTLIL::Module::makeblackbox() processes.clear(); remove(delwires); - set_bool_attribute(ID(blackbox)); + set_bool_attribute(ID::blackbox); } void RTLIL::Module::reprocess_module(RTLIL::Design *, dict) @@ -845,8 +845,8 @@ namespace { if (cell->type.in(ID($not), ID($pos), ID($neg))) { param_bool(ID(A_SIGNED)); - port(ID(A), param(ID(A_WIDTH))); - port(ID(Y), param(ID(Y_WIDTH))); + port(ID::A, param(ID(A_WIDTH))); + port(ID::Y, param(ID(Y_WIDTH))); check_expected(); return; } @@ -854,17 +854,17 @@ namespace { if (cell->type.in(ID($and), ID($or), ID($xor), ID($xnor))) { param_bool(ID(A_SIGNED)); param_bool(ID(B_SIGNED)); - port(ID(A), param(ID(A_WIDTH))); - port(ID(B), param(ID(B_WIDTH))); - port(ID(Y), param(ID(Y_WIDTH))); + port(ID::A, param(ID(A_WIDTH))); + port(ID::B, param(ID(B_WIDTH))); + port(ID::Y, param(ID(Y_WIDTH))); check_expected(); return; } if (cell->type.in(ID($reduce_and), ID($reduce_or), ID($reduce_xor), ID($reduce_xnor), ID($reduce_bool))) { param_bool(ID(A_SIGNED)); - port(ID(A), param(ID(A_WIDTH))); - port(ID(Y), param(ID(Y_WIDTH))); + port(ID::A, param(ID(A_WIDTH))); + port(ID::Y, param(ID(Y_WIDTH))); check_expected(); return; } @@ -872,9 +872,9 @@ namespace { if (cell->type.in(ID($shl), ID($shr), ID($sshl), ID($sshr), ID($shift), ID($shiftx))) { param_bool(ID(A_SIGNED)); param_bool(ID(B_SIGNED)); - port(ID(A), param(ID(A_WIDTH))); - port(ID(B), param(ID(B_WIDTH))); - port(ID(Y), param(ID(Y_WIDTH))); + port(ID::A, param(ID(A_WIDTH))); + port(ID::B, param(ID(B_WIDTH))); + port(ID::Y, param(ID(Y_WIDTH))); check_expected(false); return; } @@ -882,9 +882,9 @@ namespace { if (cell->type.in(ID($lt), ID($le), ID($eq), ID($ne), ID($eqx), ID($nex), ID($ge), ID($gt))) { param_bool(ID(A_SIGNED)); param_bool(ID(B_SIGNED)); - port(ID(A), param(ID(A_WIDTH))); - port(ID(B), param(ID(B_WIDTH))); - port(ID(Y), param(ID(Y_WIDTH))); + port(ID::A, param(ID(A_WIDTH))); + port(ID::B, param(ID(B_WIDTH))); + port(ID::Y, param(ID(Y_WIDTH))); check_expected(); return; } @@ -892,19 +892,19 @@ namespace { if (cell->type.in(ID($add), ID($sub), ID($mul), ID($div), ID($mod), ID($pow))) { param_bool(ID(A_SIGNED)); param_bool(ID(B_SIGNED)); - port(ID(A), param(ID(A_WIDTH))); - port(ID(B), param(ID(B_WIDTH))); - port(ID(Y), param(ID(Y_WIDTH))); + port(ID::A, param(ID(A_WIDTH))); + port(ID::B, param(ID(B_WIDTH))); + port(ID::Y, param(ID(Y_WIDTH))); check_expected(cell->type != ID($pow)); return; } if (cell->type == ID($fa)) { - port(ID(A), param(ID(WIDTH))); - port(ID(B), param(ID(WIDTH))); + port(ID::A, param(ID(WIDTH))); + port(ID::B, param(ID(WIDTH))); port(ID(C), param(ID(WIDTH))); port(ID(X), param(ID(WIDTH))); - port(ID(Y), param(ID(WIDTH))); + port(ID::Y, param(ID(WIDTH))); check_expected(); return; } @@ -921,12 +921,12 @@ namespace { if (cell->type == ID($alu)) { param_bool(ID(A_SIGNED)); param_bool(ID(B_SIGNED)); - port(ID(A), param(ID(A_WIDTH))); - port(ID(B), param(ID(B_WIDTH))); + port(ID::A, param(ID(A_WIDTH))); + port(ID::B, param(ID(B_WIDTH))); port(ID(CI), 1); port(ID(BI), 1); port(ID(X), param(ID(Y_WIDTH))); - port(ID(Y), param(ID(Y_WIDTH))); + port(ID::Y, param(ID(Y_WIDTH))); port(ID(CO), param(ID(Y_WIDTH))); check_expected(); return; @@ -935,9 +935,9 @@ namespace { if (cell->type == ID($macc)) { param(ID(CONFIG)); param(ID(CONFIG_WIDTH)); - port(ID(A), param(ID(A_WIDTH))); - port(ID(B), param(ID(B_WIDTH))); - port(ID(Y), param(ID(Y_WIDTH))); + port(ID::A, param(ID(A_WIDTH))); + port(ID::B, param(ID(B_WIDTH))); + port(ID::Y, param(ID(Y_WIDTH))); check_expected(); Macc().from_cell(cell); return; @@ -945,8 +945,8 @@ namespace { if (cell->type == ID($logic_not)) { param_bool(ID(A_SIGNED)); - port(ID(A), param(ID(A_WIDTH))); - port(ID(Y), param(ID(Y_WIDTH))); + port(ID::A, param(ID(A_WIDTH))); + port(ID::Y, param(ID(Y_WIDTH))); check_expected(); return; } @@ -954,17 +954,17 @@ namespace { if (cell->type.in(ID($logic_and), ID($logic_or))) { param_bool(ID(A_SIGNED)); param_bool(ID(B_SIGNED)); - port(ID(A), param(ID(A_WIDTH))); - port(ID(B), param(ID(B_WIDTH))); - port(ID(Y), param(ID(Y_WIDTH))); + port(ID::A, param(ID(A_WIDTH))); + port(ID::B, param(ID(B_WIDTH))); + port(ID::Y, param(ID(Y_WIDTH))); check_expected(false); return; } if (cell->type == ID($slice)) { param(ID(OFFSET)); - port(ID(A), param(ID(A_WIDTH))); - port(ID(Y), param(ID(Y_WIDTH))); + port(ID::A, param(ID(A_WIDTH))); + port(ID::Y, param(ID(Y_WIDTH))); if (param(ID(OFFSET)) + param(ID(Y_WIDTH)) > param(ID(A_WIDTH))) error(__LINE__); check_expected(); @@ -972,35 +972,35 @@ namespace { } if (cell->type == ID($concat)) { - port(ID(A), param(ID(A_WIDTH))); - port(ID(B), param(ID(B_WIDTH))); - port(ID(Y), param(ID(A_WIDTH)) + param(ID(B_WIDTH))); + port(ID::A, param(ID(A_WIDTH))); + port(ID::B, param(ID(B_WIDTH))); + port(ID::Y, param(ID(A_WIDTH)) + param(ID(B_WIDTH))); check_expected(); return; } if (cell->type == ID($mux)) { - port(ID(A), param(ID(WIDTH))); - port(ID(B), param(ID(WIDTH))); + port(ID::A, param(ID(WIDTH))); + port(ID::B, param(ID(WIDTH))); port(ID(S), 1); - port(ID(Y), param(ID(WIDTH))); + port(ID::Y, param(ID(WIDTH))); check_expected(); return; } if (cell->type == ID($pmux)) { - port(ID(A), param(ID(WIDTH))); - port(ID(B), param(ID(WIDTH)) * param(ID(S_WIDTH))); + port(ID::A, param(ID(WIDTH))); + port(ID::B, param(ID(WIDTH)) * param(ID(S_WIDTH))); port(ID(S), param(ID(S_WIDTH))); - port(ID(Y), param(ID(WIDTH))); + port(ID::Y, param(ID(WIDTH))); check_expected(); return; } if (cell->type == ID($lut)) { param(ID(LUT)); - port(ID(A), param(ID(WIDTH))); - port(ID(Y), 1); + port(ID::A, param(ID(WIDTH))); + port(ID::Y, 1); check_expected(); return; } @@ -1008,8 +1008,8 @@ namespace { if (cell->type == ID($sop)) { param(ID(DEPTH)); param(ID(TABLE)); - port(ID(A), param(ID(WIDTH))); - port(ID(Y), 1); + port(ID::A, param(ID(WIDTH))); + port(ID::Y, 1); check_expected(); return; } @@ -1175,36 +1175,36 @@ namespace { } if (cell->type == ID($tribuf)) { - port(ID(A), param(ID(WIDTH))); - port(ID(Y), param(ID(WIDTH))); + port(ID::A, param(ID(WIDTH))); + port(ID::Y, param(ID(WIDTH))); port(ID(EN), 1); check_expected(); return; } if (cell->type.in(ID($assert), ID($assume), ID($live), ID($fair), ID($cover))) { - port(ID(A), 1); + port(ID::A, 1); port(ID(EN), 1); check_expected(); return; } if (cell->type == ID($initstate)) { - port(ID(Y), 1); + port(ID::Y, 1); check_expected(); return; } if (cell->type.in(ID($anyconst), ID($anyseq), ID($allconst), ID($allseq))) { - port(ID(Y), param(ID(WIDTH))); + port(ID::Y, param(ID(WIDTH))); check_expected(); return; } if (cell->type == ID($equiv)) { - port(ID(A), 1); - port(ID(B), 1); - port(ID(Y), 1); + port(ID::A, 1); + port(ID::B, 1); + port(ID::Y, 1); check_expected(); return; } @@ -1831,8 +1831,8 @@ RTLIL::Cell *RTLIL::Module::addCell(RTLIL::IdString name, const RTLIL::Cell *oth cell->parameters[ID(A_SIGNED)] = is_signed; \ cell->parameters[ID(A_WIDTH)] = sig_a.size(); \ cell->parameters[ID(Y_WIDTH)] = sig_y.size(); \ - cell->setPort(ID(A), sig_a); \ - cell->setPort(ID(Y), sig_y); \ + cell->setPort(ID::A, sig_a); \ + cell->setPort(ID::Y, sig_y); \ cell->set_src_attribute(src); \ return cell; \ } \ @@ -1860,9 +1860,9 @@ DEF_METHOD(LogicNot, 1, ID($logic_not)) cell->parameters[ID(A_WIDTH)] = sig_a.size(); \ cell->parameters[ID(B_WIDTH)] = sig_b.size(); \ cell->parameters[ID(Y_WIDTH)] = sig_y.size(); \ - cell->setPort(ID(A), sig_a); \ - cell->setPort(ID(B), sig_b); \ - cell->setPort(ID(Y), sig_y); \ + cell->setPort(ID::A, sig_a); \ + cell->setPort(ID::B, sig_b); \ + cell->setPort(ID::Y, sig_y); \ cell->set_src_attribute(src); \ return cell; \ } \ @@ -1903,10 +1903,10 @@ DEF_METHOD(LogicOr, 1, ID($logic_or)) RTLIL::Cell *cell = addCell(name, _type); \ cell->parameters[ID(WIDTH)] = sig_a.size(); \ if (_pmux) cell->parameters[ID(S_WIDTH)] = sig_s.size(); \ - cell->setPort(ID(A), sig_a); \ - cell->setPort(ID(B), sig_b); \ + cell->setPort(ID::A, sig_a); \ + cell->setPort(ID::B, sig_b); \ cell->setPort(ID(S), sig_s); \ - cell->setPort(ID(Y), sig_y); \ + cell->setPort(ID::Y, sig_y); \ cell->set_src_attribute(src); \ return cell; \ } \ @@ -2006,9 +2006,9 @@ RTLIL::Cell* RTLIL::Module::addPow(RTLIL::IdString name, RTLIL::SigSpec sig_a, R cell->parameters[ID(A_WIDTH)] = sig_a.size(); cell->parameters[ID(B_WIDTH)] = sig_b.size(); cell->parameters[ID(Y_WIDTH)] = sig_y.size(); - cell->setPort(ID(A), sig_a); - cell->setPort(ID(B), sig_b); - cell->setPort(ID(Y), sig_y); + cell->setPort(ID::A, sig_a); + cell->setPort(ID::B, sig_b); + cell->setPort(ID::Y, sig_y); cell->set_src_attribute(src); return cell; } @@ -2019,8 +2019,8 @@ RTLIL::Cell* RTLIL::Module::addSlice(RTLIL::IdString name, RTLIL::SigSpec sig_a, cell->parameters[ID(A_WIDTH)] = sig_a.size(); cell->parameters[ID(Y_WIDTH)] = sig_y.size(); cell->parameters[ID(OFFSET)] = offset; - cell->setPort(ID(A), sig_a); - cell->setPort(ID(Y), sig_y); + cell->setPort(ID::A, sig_a); + cell->setPort(ID::Y, sig_y); cell->set_src_attribute(src); return cell; } @@ -2030,9 +2030,9 @@ RTLIL::Cell* RTLIL::Module::addConcat(RTLIL::IdString name, RTLIL::SigSpec sig_a RTLIL::Cell *cell = addCell(name, ID($concat)); cell->parameters[ID(A_WIDTH)] = sig_a.size(); cell->parameters[ID(B_WIDTH)] = sig_b.size(); - cell->setPort(ID(A), sig_a); - cell->setPort(ID(B), sig_b); - cell->setPort(ID(Y), sig_y); + cell->setPort(ID::A, sig_a); + cell->setPort(ID::B, sig_b); + cell->setPort(ID::Y, sig_y); cell->set_src_attribute(src); return cell; } @@ -2042,8 +2042,8 @@ RTLIL::Cell* RTLIL::Module::addLut(RTLIL::IdString name, RTLIL::SigSpec sig_a, R RTLIL::Cell *cell = addCell(name, ID($lut)); cell->parameters[ID(LUT)] = lut; cell->parameters[ID(WIDTH)] = sig_a.size(); - cell->setPort(ID(A), sig_a); - cell->setPort(ID(Y), sig_y); + cell->setPort(ID::A, sig_a); + cell->setPort(ID::Y, sig_y); cell->set_src_attribute(src); return cell; } @@ -2052,9 +2052,9 @@ RTLIL::Cell* RTLIL::Module::addTribuf(RTLIL::IdString name, RTLIL::SigSpec sig_a { RTLIL::Cell *cell = addCell(name, ID($tribuf)); cell->parameters[ID(WIDTH)] = sig_a.size(); - cell->setPort(ID(A), sig_a); + cell->setPort(ID::A, sig_a); cell->setPort(ID(EN), sig_en); - cell->setPort(ID(Y), sig_y); + cell->setPort(ID::Y, sig_y); cell->set_src_attribute(src); return cell; } @@ -2062,7 +2062,7 @@ RTLIL::Cell* RTLIL::Module::addTribuf(RTLIL::IdString name, RTLIL::SigSpec sig_a RTLIL::Cell* RTLIL::Module::addAssert(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_en, const std::string &src) { RTLIL::Cell *cell = addCell(name, ID($assert)); - cell->setPort(ID(A), sig_a); + cell->setPort(ID::A, sig_a); cell->setPort(ID(EN), sig_en); cell->set_src_attribute(src); return cell; @@ -2071,7 +2071,7 @@ RTLIL::Cell* RTLIL::Module::addAssert(RTLIL::IdString name, RTLIL::SigSpec sig_a RTLIL::Cell* RTLIL::Module::addAssume(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_en, const std::string &src) { RTLIL::Cell *cell = addCell(name, ID($assume)); - cell->setPort(ID(A), sig_a); + cell->setPort(ID::A, sig_a); cell->setPort(ID(EN), sig_en); cell->set_src_attribute(src); return cell; @@ -2080,7 +2080,7 @@ RTLIL::Cell* RTLIL::Module::addAssume(RTLIL::IdString name, RTLIL::SigSpec sig_a RTLIL::Cell* RTLIL::Module::addLive(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_en, const std::string &src) { RTLIL::Cell *cell = addCell(name, ID($live)); - cell->setPort(ID(A), sig_a); + cell->setPort(ID::A, sig_a); cell->setPort(ID(EN), sig_en); cell->set_src_attribute(src); return cell; @@ -2089,7 +2089,7 @@ RTLIL::Cell* RTLIL::Module::addLive(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::Cell* RTLIL::Module::addFair(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_en, const std::string &src) { RTLIL::Cell *cell = addCell(name, ID($fair)); - cell->setPort(ID(A), sig_a); + cell->setPort(ID::A, sig_a); cell->setPort(ID(EN), sig_en); cell->set_src_attribute(src); return cell; @@ -2098,7 +2098,7 @@ RTLIL::Cell* RTLIL::Module::addFair(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::Cell* RTLIL::Module::addCover(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_en, const std::string &src) { RTLIL::Cell *cell = addCell(name, ID($cover)); - cell->setPort(ID(A), sig_a); + cell->setPort(ID::A, sig_a); cell->setPort(ID(EN), sig_en); cell->set_src_attribute(src); return cell; @@ -2107,9 +2107,9 @@ RTLIL::Cell* RTLIL::Module::addCover(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::Cell* RTLIL::Module::addEquiv(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, const std::string &src) { RTLIL::Cell *cell = addCell(name, ID($equiv)); - cell->setPort(ID(A), sig_a); - cell->setPort(ID(B), sig_b); - cell->setPort(ID(Y), sig_y); + cell->setPort(ID::A, sig_a); + cell->setPort(ID::B, sig_b); + cell->setPort(ID::Y, sig_y); cell->set_src_attribute(src); return cell; } @@ -2308,7 +2308,7 @@ RTLIL::SigSpec RTLIL::Module::Anyconst(RTLIL::IdString name, int width, const st RTLIL::SigSpec sig = addWire(NEW_ID, width); Cell *cell = addCell(name, ID($anyconst)); cell->setParam(ID(WIDTH), width); - cell->setPort(ID(Y), sig); + cell->setPort(ID::Y, sig); cell->set_src_attribute(src); return sig; } @@ -2318,7 +2318,7 @@ RTLIL::SigSpec RTLIL::Module::Anyseq(RTLIL::IdString name, int width, const std: RTLIL::SigSpec sig = addWire(NEW_ID, width); Cell *cell = addCell(name, ID($anyseq)); cell->setParam(ID(WIDTH), width); - cell->setPort(ID(Y), sig); + cell->setPort(ID::Y, sig); cell->set_src_attribute(src); return sig; } @@ -2328,7 +2328,7 @@ RTLIL::SigSpec RTLIL::Module::Allconst(RTLIL::IdString name, int width, const st RTLIL::SigSpec sig = addWire(NEW_ID, width); Cell *cell = addCell(name, ID($allconst)); cell->setParam(ID(WIDTH), width); - cell->setPort(ID(Y), sig); + cell->setPort(ID::Y, sig); cell->set_src_attribute(src); return sig; } @@ -2338,7 +2338,7 @@ RTLIL::SigSpec RTLIL::Module::Allseq(RTLIL::IdString name, int width, const std: RTLIL::SigSpec sig = addWire(NEW_ID, width); Cell *cell = addCell(name, ID($allseq)); cell->setParam(ID(WIDTH), width); - cell->setPort(ID(Y), sig); + cell->setPort(ID::Y, sig); cell->set_src_attribute(src); return sig; } @@ -2347,7 +2347,7 @@ RTLIL::SigSpec RTLIL::Module::Initstate(RTLIL::IdString name, const std::string { RTLIL::SigSpec sig = addWire(NEW_ID); Cell *cell = addCell(name, ID($initstate)); - cell->setPort(ID(Y), sig); + cell->setPort(ID::Y, sig); cell->set_src_attribute(src); return sig; } @@ -2569,7 +2569,7 @@ void RTLIL::Cell::fixup_parameters(bool set_a_signed, bool set_b_signed) return; if (type == ID($mux) || type == ID($pmux)) { - parameters[ID(WIDTH)] = GetSize(connections_[ID(Y)]); + parameters[ID(WIDTH)] = GetSize(connections_[ID::Y]); if (type == ID($pmux)) parameters[ID(S_WIDTH)] = GetSize(connections_[ID(S)]); check(); @@ -2577,12 +2577,12 @@ void RTLIL::Cell::fixup_parameters(bool set_a_signed, bool set_b_signed) } if (type == ID($lut) || type == ID($sop)) { - parameters[ID(WIDTH)] = GetSize(connections_[ID(A)]); + parameters[ID(WIDTH)] = GetSize(connections_[ID::A]); return; } if (type == ID($fa)) { - parameters[ID(WIDTH)] = GetSize(connections_[ID(Y)]); + parameters[ID(WIDTH)] = GetSize(connections_[ID::Y]); return; } @@ -2593,28 +2593,28 @@ void RTLIL::Cell::fixup_parameters(bool set_a_signed, bool set_b_signed) bool signedness_ab = !type.in(ID($slice), ID($concat), ID($macc)); - if (connections_.count(ID(A))) { + if (connections_.count(ID::A)) { if (signedness_ab) { if (set_a_signed) parameters[ID(A_SIGNED)] = true; else if (parameters.count(ID(A_SIGNED)) == 0) parameters[ID(A_SIGNED)] = false; } - parameters[ID(A_WIDTH)] = GetSize(connections_[ID(A)]); + parameters[ID(A_WIDTH)] = GetSize(connections_[ID::A]); } - if (connections_.count(ID(B))) { + if (connections_.count(ID::B)) { if (signedness_ab) { if (set_b_signed) parameters[ID(B_SIGNED)] = true; else if (parameters.count(ID(B_SIGNED)) == 0) parameters[ID(B_SIGNED)] = false; } - parameters[ID(B_WIDTH)] = GetSize(connections_[ID(B)]); + parameters[ID(B_WIDTH)] = GetSize(connections_[ID::B]); } - if (connections_.count(ID(Y))) - parameters[ID(Y_WIDTH)] = GetSize(connections_[ID(Y)]); + if (connections_.count(ID::Y)) + parameters[ID(Y_WIDTH)] = GetSize(connections_[ID::Y]); if (connections_.count(ID(Q))) parameters[ID(WIDTH)] = GetSize(connections_[ID(Q)]); diff --git a/kernel/satgen.h b/kernel/satgen.h index aab3017c2..133389eee 100644 --- a/kernel/satgen.h +++ b/kernel/satgen.h @@ -281,9 +281,9 @@ struct SatGen if (model_undef && (cell->type.in(ID($add), ID($sub), ID($mul), ID($div), ID($mod)) || is_arith_compare)) { - std::vector undef_a = importUndefSigSpec(cell->getPort(ID(A)), timestep); - std::vector undef_b = importUndefSigSpec(cell->getPort(ID(B)), timestep); - std::vector undef_y = importUndefSigSpec(cell->getPort(ID(Y)), timestep); + std::vector undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep); + std::vector undef_b = importUndefSigSpec(cell->getPort(ID::B), timestep); + std::vector undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep); if (is_arith_compare) extendSignalWidth(undef_a, undef_b, cell, true); else @@ -294,7 +294,7 @@ struct SatGen int undef_y_bit = ez->OR(undef_any_a, undef_any_b); if (cell->type.in(ID($div), ID($mod))) { - std::vector b = importSigSpec(cell->getPort(ID(B)), timestep); + std::vector b = importSigSpec(cell->getPort(ID::B), timestep); undef_y_bit = ez->OR(undef_y_bit, ez->NOT(ez->expression(ezSAT::OpOr, b))); } @@ -313,9 +313,9 @@ struct SatGen if (cell->type.in(ID($_AND_), ID($_NAND_), ID($_OR_), ID($_NOR_), ID($_XOR_), ID($_XNOR_), ID($_ANDNOT_), ID($_ORNOT_), ID($and), ID($or), ID($xor), ID($xnor), ID($add), ID($sub))) { - std::vector a = importDefSigSpec(cell->getPort(ID(A)), timestep); - std::vector b = importDefSigSpec(cell->getPort(ID(B)), timestep); - std::vector y = importDefSigSpec(cell->getPort(ID(Y)), timestep); + std::vector a = importDefSigSpec(cell->getPort(ID::A), timestep); + std::vector b = importDefSigSpec(cell->getPort(ID::B), timestep); + std::vector y = importDefSigSpec(cell->getPort(ID::Y), timestep); extendSignalWidth(a, b, y, cell); std::vector yy = model_undef ? ez->vec_var(y.size()) : y; @@ -343,9 +343,9 @@ struct SatGen if (model_undef && !arith_undef_handled) { - std::vector undef_a = importUndefSigSpec(cell->getPort(ID(A)), timestep); - std::vector undef_b = importUndefSigSpec(cell->getPort(ID(B)), timestep); - std::vector undef_y = importUndefSigSpec(cell->getPort(ID(Y)), timestep); + std::vector undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep); + std::vector undef_b = importUndefSigSpec(cell->getPort(ID::B), timestep); + std::vector undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep); extendSignalWidth(undef_a, undef_b, undef_y, cell, false); if (cell->type.in(ID($and), ID($_AND_), ID($_NAND_))) { @@ -384,7 +384,7 @@ struct SatGen } else if (model_undef) { - std::vector undef_y = importUndefSigSpec(cell->getPort(ID(Y)), timestep); + std::vector undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep); undefGating(y, yy, undef_y); } return true; @@ -395,11 +395,11 @@ struct SatGen bool aoi_mode = cell->type.in(ID($_AOI3_), ID($_AOI4_)); bool three_mode = cell->type.in(ID($_AOI3_), ID($_OAI3_)); - int a = importDefSigSpec(cell->getPort(ID(A)), timestep).at(0); - int b = importDefSigSpec(cell->getPort(ID(B)), timestep).at(0); + int a = importDefSigSpec(cell->getPort(ID::A), timestep).at(0); + int b = importDefSigSpec(cell->getPort(ID::B), timestep).at(0); int c = importDefSigSpec(cell->getPort(ID(C)), timestep).at(0); int d = three_mode ? (aoi_mode ? ez->CONST_TRUE : ez->CONST_FALSE) : importDefSigSpec(cell->getPort(ID(D)), timestep).at(0); - int y = importDefSigSpec(cell->getPort(ID(Y)), timestep).at(0); + int y = importDefSigSpec(cell->getPort(ID::Y), timestep).at(0); int yy = model_undef ? ez->literal() : y; if (cell->type.in(ID($_AOI3_), ID($_AOI4_))) @@ -409,11 +409,11 @@ struct SatGen if (model_undef) { - int undef_a = importUndefSigSpec(cell->getPort(ID(A)), timestep).at(0); - int undef_b = importUndefSigSpec(cell->getPort(ID(B)), timestep).at(0); + int undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep).at(0); + int undef_b = importUndefSigSpec(cell->getPort(ID::B), timestep).at(0); int undef_c = importUndefSigSpec(cell->getPort(ID(C)), timestep).at(0); int undef_d = three_mode ? ez->CONST_FALSE : importUndefSigSpec(cell->getPort(ID(D)), timestep).at(0); - int undef_y = importUndefSigSpec(cell->getPort(ID(Y)), timestep).at(0); + int undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep).at(0); if (aoi_mode) { @@ -458,16 +458,16 @@ struct SatGen if (cell->type.in(ID($_NOT_), ID($not))) { - std::vector a = importDefSigSpec(cell->getPort(ID(A)), timestep); - std::vector y = importDefSigSpec(cell->getPort(ID(Y)), timestep); + std::vector a = importDefSigSpec(cell->getPort(ID::A), timestep); + std::vector y = importDefSigSpec(cell->getPort(ID::Y), timestep); extendSignalWidthUnary(a, y, cell); std::vector yy = model_undef ? ez->vec_var(y.size()) : y; ez->assume(ez->vec_eq(ez->vec_not(a), yy)); if (model_undef) { - std::vector undef_a = importUndefSigSpec(cell->getPort(ID(A)), timestep); - std::vector undef_y = importUndefSigSpec(cell->getPort(ID(Y)), timestep); + std::vector undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep); + std::vector undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep); extendSignalWidthUnary(undef_a, undef_y, cell, false); ez->assume(ez->vec_eq(undef_a, undef_y)); undefGating(y, yy, undef_y); @@ -477,10 +477,10 @@ struct SatGen if (cell->type.in(ID($_MUX_), ID($mux), ID($_NMUX_))) { - std::vector a = importDefSigSpec(cell->getPort(ID(A)), timestep); - std::vector b = importDefSigSpec(cell->getPort(ID(B)), timestep); + std::vector a = importDefSigSpec(cell->getPort(ID::A), timestep); + std::vector b = importDefSigSpec(cell->getPort(ID::B), timestep); std::vector s = importDefSigSpec(cell->getPort(ID(S)), timestep); - std::vector y = importDefSigSpec(cell->getPort(ID(Y)), timestep); + std::vector y = importDefSigSpec(cell->getPort(ID::Y), timestep); std::vector yy = model_undef ? ez->vec_var(y.size()) : y; if (cell->type == ID($_NMUX_)) @@ -490,10 +490,10 @@ struct SatGen if (model_undef) { - std::vector undef_a = importUndefSigSpec(cell->getPort(ID(A)), timestep); - std::vector undef_b = importUndefSigSpec(cell->getPort(ID(B)), timestep); + std::vector undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep); + std::vector undef_b = importUndefSigSpec(cell->getPort(ID::B), timestep); std::vector undef_s = importUndefSigSpec(cell->getPort(ID(S)), timestep); - std::vector undef_y = importUndefSigSpec(cell->getPort(ID(Y)), timestep); + std::vector undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep); std::vector unequal_ab = ez->vec_not(ez->vec_iff(a, b)); std::vector undef_ab = ez->vec_or(unequal_ab, ez->vec_or(undef_a, undef_b)); @@ -506,10 +506,10 @@ struct SatGen if (cell->type == ID($pmux)) { - std::vector a = importDefSigSpec(cell->getPort(ID(A)), timestep); - std::vector b = importDefSigSpec(cell->getPort(ID(B)), timestep); + std::vector a = importDefSigSpec(cell->getPort(ID::A), timestep); + std::vector b = importDefSigSpec(cell->getPort(ID::B), timestep); std::vector s = importDefSigSpec(cell->getPort(ID(S)), timestep); - std::vector y = importDefSigSpec(cell->getPort(ID(Y)), timestep); + std::vector y = importDefSigSpec(cell->getPort(ID::Y), timestep); std::vector yy = model_undef ? ez->vec_var(y.size()) : y; @@ -522,10 +522,10 @@ struct SatGen if (model_undef) { - std::vector undef_a = importUndefSigSpec(cell->getPort(ID(A)), timestep); - std::vector undef_b = importUndefSigSpec(cell->getPort(ID(B)), timestep); + std::vector undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep); + std::vector undef_b = importUndefSigSpec(cell->getPort(ID::B), timestep); std::vector undef_s = importUndefSigSpec(cell->getPort(ID(S)), timestep); - std::vector undef_y = importUndefSigSpec(cell->getPort(ID(Y)), timestep); + std::vector undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep); int maybe_a = ez->CONST_TRUE; @@ -557,8 +557,8 @@ struct SatGen if (cell->type.in(ID($pos), ID($neg))) { - std::vector a = importDefSigSpec(cell->getPort(ID(A)), timestep); - std::vector y = importDefSigSpec(cell->getPort(ID(Y)), timestep); + std::vector a = importDefSigSpec(cell->getPort(ID::A), timestep); + std::vector y = importDefSigSpec(cell->getPort(ID::Y), timestep); extendSignalWidthUnary(a, y, cell); std::vector yy = model_undef ? ez->vec_var(y.size()) : y; @@ -572,8 +572,8 @@ struct SatGen if (model_undef) { - std::vector undef_a = importUndefSigSpec(cell->getPort(ID(A)), timestep); - std::vector undef_y = importUndefSigSpec(cell->getPort(ID(Y)), timestep); + std::vector undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep); + std::vector undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep); extendSignalWidthUnary(undef_a, undef_y, cell); if (cell->type == ID($pos)) { @@ -591,8 +591,8 @@ struct SatGen if (cell->type.in(ID($reduce_and), ID($reduce_or), ID($reduce_xor), ID($reduce_xnor), ID($reduce_bool), ID($logic_not))) { - std::vector a = importDefSigSpec(cell->getPort(ID(A)), timestep); - std::vector y = importDefSigSpec(cell->getPort(ID(Y)), timestep); + std::vector a = importDefSigSpec(cell->getPort(ID::A), timestep); + std::vector y = importDefSigSpec(cell->getPort(ID::Y), timestep); std::vector yy = model_undef ? ez->vec_var(y.size()) : y; @@ -611,8 +611,8 @@ struct SatGen if (model_undef) { - std::vector undef_a = importUndefSigSpec(cell->getPort(ID(A)), timestep); - std::vector undef_y = importUndefSigSpec(cell->getPort(ID(Y)), timestep); + std::vector undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep); + std::vector undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep); int aX = ez->expression(ezSAT::OpOr, undef_a); if (cell->type == ID($reduce_and)) { @@ -638,12 +638,12 @@ struct SatGen if (cell->type.in(ID($logic_and), ID($logic_or))) { - std::vector vec_a = importDefSigSpec(cell->getPort(ID(A)), timestep); - std::vector vec_b = importDefSigSpec(cell->getPort(ID(B)), timestep); + std::vector vec_a = importDefSigSpec(cell->getPort(ID::A), timestep); + std::vector vec_b = importDefSigSpec(cell->getPort(ID::B), timestep); int a = ez->expression(ez->OpOr, vec_a); int b = ez->expression(ez->OpOr, vec_b); - std::vector y = importDefSigSpec(cell->getPort(ID(Y)), timestep); + std::vector y = importDefSigSpec(cell->getPort(ID::Y), timestep); std::vector yy = model_undef ? ez->vec_var(y.size()) : y; @@ -656,9 +656,9 @@ struct SatGen if (model_undef) { - std::vector undef_a = importUndefSigSpec(cell->getPort(ID(A)), timestep); - std::vector undef_b = importUndefSigSpec(cell->getPort(ID(B)), timestep); - std::vector undef_y = importUndefSigSpec(cell->getPort(ID(Y)), timestep); + std::vector undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep); + std::vector undef_b = importUndefSigSpec(cell->getPort(ID::B), timestep); + std::vector undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep); int a0 = ez->NOT(ez->OR(ez->expression(ezSAT::OpOr, vec_a), ez->expression(ezSAT::OpOr, undef_a))); int b0 = ez->NOT(ez->OR(ez->expression(ezSAT::OpOr, vec_b), ez->expression(ezSAT::OpOr, undef_b))); @@ -685,16 +685,16 @@ struct SatGen if (cell->type.in(ID($lt), ID($le), ID($eq), ID($ne), ID($eqx), ID($nex), ID($ge), ID($gt))) { bool is_signed = cell->parameters[ID(A_SIGNED)].as_bool() && cell->parameters[ID(B_SIGNED)].as_bool(); - std::vector a = importDefSigSpec(cell->getPort(ID(A)), timestep); - std::vector b = importDefSigSpec(cell->getPort(ID(B)), timestep); - std::vector y = importDefSigSpec(cell->getPort(ID(Y)), timestep); + std::vector a = importDefSigSpec(cell->getPort(ID::A), timestep); + std::vector b = importDefSigSpec(cell->getPort(ID::B), timestep); + std::vector y = importDefSigSpec(cell->getPort(ID::Y), timestep); extendSignalWidth(a, b, cell); std::vector yy = model_undef ? ez->vec_var(y.size()) : y; if (model_undef && cell->type.in(ID($eqx), ID($nex))) { - std::vector undef_a = importUndefSigSpec(cell->getPort(ID(A)), timestep); - std::vector undef_b = importUndefSigSpec(cell->getPort(ID(B)), timestep); + std::vector undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep); + std::vector undef_b = importUndefSigSpec(cell->getPort(ID::B), timestep); extendSignalWidth(undef_a, undef_b, cell, true); a = ez->vec_or(a, undef_a); b = ez->vec_or(b, undef_b); @@ -717,9 +717,9 @@ struct SatGen if (model_undef && cell->type.in(ID($eqx), ID($nex))) { - std::vector undef_a = importUndefSigSpec(cell->getPort(ID(A)), timestep); - std::vector undef_b = importUndefSigSpec(cell->getPort(ID(B)), timestep); - std::vector undef_y = importUndefSigSpec(cell->getPort(ID(Y)), timestep); + std::vector undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep); + std::vector undef_b = importUndefSigSpec(cell->getPort(ID::B), timestep); + std::vector undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep); extendSignalWidth(undef_a, undef_b, cell, true); if (cell->type == ID($eqx)) @@ -734,9 +734,9 @@ struct SatGen } else if (model_undef && cell->type.in(ID($eq), ID($ne))) { - std::vector undef_a = importUndefSigSpec(cell->getPort(ID(A)), timestep); - std::vector undef_b = importUndefSigSpec(cell->getPort(ID(B)), timestep); - std::vector undef_y = importUndefSigSpec(cell->getPort(ID(Y)), timestep); + std::vector undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep); + std::vector undef_b = importUndefSigSpec(cell->getPort(ID::B), timestep); + std::vector undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep); extendSignalWidth(undef_a, undef_b, cell, true); int undef_any_a = ez->expression(ezSAT::OpOr, undef_a); @@ -758,7 +758,7 @@ struct SatGen else { if (model_undef) { - std::vector undef_y = importUndefSigSpec(cell->getPort(ID(Y)), timestep); + std::vector undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep); undefGating(y, yy, undef_y); } log_assert(!model_undef || arith_undef_handled); @@ -768,9 +768,9 @@ struct SatGen if (cell->type.in(ID($shl), ID($shr), ID($sshl), ID($sshr), ID($shift), ID($shiftx))) { - std::vector a = importDefSigSpec(cell->getPort(ID(A)), timestep); - std::vector b = importDefSigSpec(cell->getPort(ID(B)), timestep); - std::vector y = importDefSigSpec(cell->getPort(ID(Y)), timestep); + std::vector a = importDefSigSpec(cell->getPort(ID::A), timestep); + std::vector b = importDefSigSpec(cell->getPort(ID::B), timestep); + std::vector y = importDefSigSpec(cell->getPort(ID::Y), timestep); int extend_bit = ez->CONST_FALSE; @@ -801,9 +801,9 @@ struct SatGen if (model_undef) { - std::vector undef_a = importUndefSigSpec(cell->getPort(ID(A)), timestep); - std::vector undef_b = importUndefSigSpec(cell->getPort(ID(B)), timestep); - std::vector undef_y = importUndefSigSpec(cell->getPort(ID(Y)), timestep); + std::vector undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep); + std::vector undef_b = importUndefSigSpec(cell->getPort(ID::B), timestep); + std::vector undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep); std::vector undef_a_shifted; extend_bit = cell->type == ID($shiftx) ? ez->CONST_TRUE : ez->CONST_FALSE; @@ -840,9 +840,9 @@ struct SatGen if (cell->type == ID($mul)) { - std::vector a = importDefSigSpec(cell->getPort(ID(A)), timestep); - std::vector b = importDefSigSpec(cell->getPort(ID(B)), timestep); - std::vector y = importDefSigSpec(cell->getPort(ID(Y)), timestep); + std::vector a = importDefSigSpec(cell->getPort(ID::A), timestep); + std::vector b = importDefSigSpec(cell->getPort(ID::B), timestep); + std::vector y = importDefSigSpec(cell->getPort(ID::Y), timestep); extendSignalWidth(a, b, y, cell); std::vector yy = model_undef ? ez->vec_var(y.size()) : y; @@ -859,7 +859,7 @@ struct SatGen if (model_undef) { log_assert(arith_undef_handled); - std::vector undef_y = importUndefSigSpec(cell->getPort(ID(Y)), timestep); + std::vector undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep); undefGating(y, yy, undef_y); } return true; @@ -867,9 +867,9 @@ struct SatGen if (cell->type == ID($macc)) { - std::vector a = importDefSigSpec(cell->getPort(ID(A)), timestep); - std::vector b = importDefSigSpec(cell->getPort(ID(B)), timestep); - std::vector y = importDefSigSpec(cell->getPort(ID(Y)), timestep); + std::vector a = importDefSigSpec(cell->getPort(ID::A), timestep); + std::vector b = importDefSigSpec(cell->getPort(ID::B), timestep); + std::vector y = importDefSigSpec(cell->getPort(ID::Y), timestep); Macc macc; macc.from_cell(cell); @@ -918,13 +918,13 @@ struct SatGen if (model_undef) { - std::vector undef_a = importUndefSigSpec(cell->getPort(ID(A)), timestep); - std::vector undef_b = importUndefSigSpec(cell->getPort(ID(B)), timestep); + std::vector undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep); + std::vector undef_b = importUndefSigSpec(cell->getPort(ID::B), timestep); int undef_any_a = ez->expression(ezSAT::OpOr, undef_a); int undef_any_b = ez->expression(ezSAT::OpOr, undef_b); - std::vector undef_y = importUndefSigSpec(cell->getPort(ID(Y)), timestep); + std::vector undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep); ez->assume(ez->vec_eq(undef_y, std::vector(GetSize(y), ez->OR(undef_any_a, undef_any_b)))); undefGating(y, tmp, undef_y); @@ -937,9 +937,9 @@ struct SatGen if (cell->type.in(ID($div), ID($mod))) { - std::vector a = importDefSigSpec(cell->getPort(ID(A)), timestep); - std::vector b = importDefSigSpec(cell->getPort(ID(B)), timestep); - std::vector y = importDefSigSpec(cell->getPort(ID(Y)), timestep); + std::vector a = importDefSigSpec(cell->getPort(ID::A), timestep); + std::vector b = importDefSigSpec(cell->getPort(ID::B), timestep); + std::vector y = importDefSigSpec(cell->getPort(ID::Y), timestep); extendSignalWidth(a, b, y, cell); std::vector yy = model_undef ? ez->vec_var(y.size()) : y; @@ -993,11 +993,11 @@ struct SatGen only_first_one.at(0) = ez->CONST_TRUE; div_zero_result = ez->vec_ite(a.back(), only_first_one, all_ones); } else { - div_zero_result.insert(div_zero_result.end(), cell->getPort(ID(A)).size(), ez->CONST_TRUE); + div_zero_result.insert(div_zero_result.end(), cell->getPort(ID::A).size(), ez->CONST_TRUE); div_zero_result.insert(div_zero_result.end(), y.size() - div_zero_result.size(), ez->CONST_FALSE); } } else { - int copy_a_bits = min(cell->getPort(ID(A)).size(), cell->getPort(ID(B)).size()); + int copy_a_bits = min(cell->getPort(ID::A).size(), cell->getPort(ID::B).size()); div_zero_result.insert(div_zero_result.end(), a.begin(), a.begin() + copy_a_bits); if (cell->parameters[ID(A_SIGNED)].as_bool() && cell->parameters[ID(B_SIGNED)].as_bool()) div_zero_result.insert(div_zero_result.end(), y.size() - div_zero_result.size(), div_zero_result.back()); @@ -1009,7 +1009,7 @@ struct SatGen if (model_undef) { log_assert(arith_undef_handled); - std::vector undef_y = importUndefSigSpec(cell->getPort(ID(Y)), timestep); + std::vector undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep); undefGating(y, yy, undef_y); } return true; @@ -1017,8 +1017,8 @@ struct SatGen if (cell->type == ID($lut)) { - std::vector a = importDefSigSpec(cell->getPort(ID(A)), timestep); - std::vector y = importDefSigSpec(cell->getPort(ID(Y)), timestep); + std::vector a = importDefSigSpec(cell->getPort(ID::A), timestep); + std::vector y = importDefSigSpec(cell->getPort(ID::Y), timestep); std::vector lut; for (auto bit : cell->getParam(ID(LUT)).bits) @@ -1029,7 +1029,7 @@ struct SatGen if (model_undef) { - std::vector undef_a = importUndefSigSpec(cell->getPort(ID(A)), timestep); + std::vector undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep); std::vector t(lut), u(GetSize(t), ez->CONST_FALSE); for (int i = GetSize(a)-1; i >= 0; i--) @@ -1047,7 +1047,7 @@ struct SatGen log_assert(GetSize(t) == 1); log_assert(GetSize(u) == 1); undefGating(y, t, u); - ez->assume(ez->vec_eq(importUndefSigSpec(cell->getPort(ID(Y)), timestep), u)); + ez->assume(ez->vec_eq(importUndefSigSpec(cell->getPort(ID::Y), timestep), u)); } else { @@ -1067,8 +1067,8 @@ struct SatGen if (cell->type == ID($sop)) { - std::vector a = importDefSigSpec(cell->getPort(ID(A)), timestep); - int y = importDefSigSpec(cell->getPort(ID(Y)), timestep).at(0); + std::vector a = importDefSigSpec(cell->getPort(ID::A), timestep); + int y = importDefSigSpec(cell->getPort(ID::Y), timestep).at(0); int width = cell->getParam(ID(WIDTH)).as_int(); int depth = cell->getParam(ID(DEPTH)).as_int(); @@ -1096,8 +1096,8 @@ struct SatGen if (model_undef) { std::vector products, undef_products; - std::vector undef_a = importUndefSigSpec(cell->getPort(ID(A)), timestep); - int undef_y = importUndefSigSpec(cell->getPort(ID(Y)), timestep).at(0); + std::vector undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep); + int undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep).at(0); for (int i = 0; i < depth; i++) { @@ -1149,10 +1149,10 @@ struct SatGen if (cell->type == ID($fa)) { - std::vector a = importDefSigSpec(cell->getPort(ID(A)), timestep); - std::vector b = importDefSigSpec(cell->getPort(ID(B)), timestep); + std::vector a = importDefSigSpec(cell->getPort(ID::A), timestep); + std::vector b = importDefSigSpec(cell->getPort(ID::B), timestep); std::vector c = importDefSigSpec(cell->getPort(ID(C)), timestep); - std::vector y = importDefSigSpec(cell->getPort(ID(Y)), timestep); + std::vector y = importDefSigSpec(cell->getPort(ID::Y), timestep); std::vector x = importDefSigSpec(cell->getPort(ID(X)), timestep); std::vector yy = model_undef ? ez->vec_var(y.size()) : y; @@ -1167,11 +1167,11 @@ struct SatGen if (model_undef) { - std::vector undef_a = importUndefSigSpec(cell->getPort(ID(A)), timestep); - std::vector undef_b = importUndefSigSpec(cell->getPort(ID(B)), timestep); + std::vector undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep); + std::vector undef_b = importUndefSigSpec(cell->getPort(ID::B), timestep); std::vector undef_c = importUndefSigSpec(cell->getPort(ID(C)), timestep); - std::vector undef_y = importUndefSigSpec(cell->getPort(ID(Y)), timestep); + std::vector undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep); std::vector undef_x = importUndefSigSpec(cell->getPort(ID(X)), timestep); ez->assume(ez->vec_eq(undef_y, ez->vec_or(ez->vec_or(undef_a, undef_b), undef_c))); @@ -1217,9 +1217,9 @@ struct SatGen if (cell->type == ID($alu)) { - std::vector a = importDefSigSpec(cell->getPort(ID(A)), timestep); - std::vector b = importDefSigSpec(cell->getPort(ID(B)), timestep); - std::vector y = importDefSigSpec(cell->getPort(ID(Y)), timestep); + std::vector a = importDefSigSpec(cell->getPort(ID::A), timestep); + std::vector b = importDefSigSpec(cell->getPort(ID::B), timestep); + std::vector y = importDefSigSpec(cell->getPort(ID::Y), timestep); std::vector x = importDefSigSpec(cell->getPort(ID(X)), timestep); std::vector ci = importDefSigSpec(cell->getPort(ID(CI)), timestep); std::vector bi = importDefSigSpec(cell->getPort(ID(BI)), timestep); @@ -1248,12 +1248,12 @@ struct SatGen if (model_undef) { - std::vector undef_a = importUndefSigSpec(cell->getPort(ID(A)), timestep); - std::vector undef_b = importUndefSigSpec(cell->getPort(ID(B)), timestep); + std::vector undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep); + std::vector undef_b = importUndefSigSpec(cell->getPort(ID::B), timestep); std::vector undef_ci = importUndefSigSpec(cell->getPort(ID(CI)), timestep); std::vector undef_bi = importUndefSigSpec(cell->getPort(ID(BI)), timestep); - std::vector undef_y = importUndefSigSpec(cell->getPort(ID(Y)), timestep); + std::vector undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep); std::vector undef_x = importUndefSigSpec(cell->getPort(ID(X)), timestep); std::vector undef_co = importUndefSigSpec(cell->getPort(ID(CO)), timestep); @@ -1283,17 +1283,17 @@ struct SatGen if (cell->type == ID($slice)) { - RTLIL::SigSpec a = cell->getPort(ID(A)); - RTLIL::SigSpec y = cell->getPort(ID(Y)); + RTLIL::SigSpec a = cell->getPort(ID::A); + RTLIL::SigSpec y = cell->getPort(ID::Y); ez->assume(signals_eq(a.extract(cell->parameters.at(ID(OFFSET)).as_int(), y.size()), y, timestep)); return true; } if (cell->type == ID($concat)) { - RTLIL::SigSpec a = cell->getPort(ID(A)); - RTLIL::SigSpec b = cell->getPort(ID(B)); - RTLIL::SigSpec y = cell->getPort(ID(Y)); + RTLIL::SigSpec a = cell->getPort(ID::A); + RTLIL::SigSpec b = cell->getPort(ID::B); + RTLIL::SigSpec y = cell->getPort(ID::Y); RTLIL::SigSpec ab = a; ab.append(b); @@ -1333,16 +1333,16 @@ struct SatGen if (timestep < 2) return true; - std::vector d = importDefSigSpec(cell->getPort(ID(Y)), timestep-1); - std::vector q = importDefSigSpec(cell->getPort(ID(Y)), timestep); + std::vector d = importDefSigSpec(cell->getPort(ID::Y), timestep-1); + std::vector q = importDefSigSpec(cell->getPort(ID::Y), timestep); std::vector qq = model_undef ? ez->vec_var(q.size()) : q; ez->assume(ez->vec_eq(d, qq)); if (model_undef) { - std::vector undef_d = importUndefSigSpec(cell->getPort(ID(Y)), timestep-1); - std::vector undef_q = importUndefSigSpec(cell->getPort(ID(Y)), timestep); + std::vector undef_d = importUndefSigSpec(cell->getPort(ID::Y), timestep-1); + std::vector undef_q = importUndefSigSpec(cell->getPort(ID::Y), timestep); ez->assume(ez->vec_eq(undef_d, undef_q)); undefGating(q, qq, undef_q); @@ -1357,16 +1357,16 @@ struct SatGen if (cell->type.in(ID($_BUF_), ID($equiv))) { - std::vector a = importDefSigSpec(cell->getPort(ID(A)), timestep); - std::vector y = importDefSigSpec(cell->getPort(ID(Y)), timestep); + std::vector a = importDefSigSpec(cell->getPort(ID::A), timestep); + std::vector y = importDefSigSpec(cell->getPort(ID::Y), timestep); extendSignalWidthUnary(a, y, cell); std::vector yy = model_undef ? ez->vec_var(y.size()) : y; ez->assume(ez->vec_eq(a, yy)); if (model_undef) { - std::vector undef_a = importUndefSigSpec(cell->getPort(ID(A)), timestep); - std::vector undef_y = importUndefSigSpec(cell->getPort(ID(Y)), timestep); + std::vector undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep); + std::vector undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep); extendSignalWidthUnary(undef_a, undef_y, cell, false); ez->assume(ez->vec_eq(undef_a, undef_y)); undefGating(y, yy, undef_y); @@ -1380,12 +1380,12 @@ struct SatGen if (initstates.count(key) == 0) initstates[key] = false; - std::vector y = importDefSigSpec(cell->getPort(ID(Y)), timestep); + std::vector y = importDefSigSpec(cell->getPort(ID::Y), timestep); log_assert(GetSize(y) == 1); ez->SET(y[0], initstates[key] ? ez->CONST_TRUE : ez->CONST_FALSE); if (model_undef) { - std::vector undef_y = importUndefSigSpec(cell->getPort(ID(Y)), timestep); + std::vector undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep); log_assert(GetSize(undef_y) == 1); ez->SET(undef_y[0], ez->CONST_FALSE); } @@ -1396,7 +1396,7 @@ struct SatGen if (cell->type == ID($assert)) { std::string pf = prefix + (timestep == -1 ? "" : stringf("@%d:", timestep)); - asserts_a[pf].append((*sigmap)(cell->getPort(ID(A)))); + asserts_a[pf].append((*sigmap)(cell->getPort(ID::A))); asserts_en[pf].append((*sigmap)(cell->getPort(ID(EN)))); return true; } @@ -1404,7 +1404,7 @@ struct SatGen if (cell->type == ID($assume)) { std::string pf = prefix + (timestep == -1 ? "" : stringf("@%d:", timestep)); - assumes_a[pf].append((*sigmap)(cell->getPort(ID(A)))); + assumes_a[pf].append((*sigmap)(cell->getPort(ID::A))); assumes_en[pf].append((*sigmap)(cell->getPort(ID(EN)))); return true; } diff --git a/kernel/yosys.h b/kernel/yosys.h index 49716ed52..52e7b3383 100644 --- a/kernel/yosys.h +++ b/kernel/yosys.h @@ -210,6 +210,7 @@ namespace RTLIL { struct Module; struct Design; struct Monitor; + namespace ID {} } namespace AST { @@ -224,6 +225,7 @@ using RTLIL::Wire; using RTLIL::Cell; using RTLIL::Module; using RTLIL::Design; +namespace ID = RTLIL::ID; namespace hashlib { template<> struct hash_ops : hash_obj_ops {}; diff --git a/passes/opt/muxpack.cc b/passes/opt/muxpack.cc index cf6752b6e..97c88f423 100644 --- a/passes/opt/muxpack.cc +++ b/passes/opt/muxpack.cc @@ -38,19 +38,19 @@ struct ExclusiveDatabase pool reduce_or; for (auto cell : module->cells()) { if (cell->type == ID($eq)) { - nonconst_sig = sigmap(cell->getPort(ID(A))); - const_sig = sigmap(cell->getPort(ID(B))); + nonconst_sig = sigmap(cell->getPort(ID::A)); + const_sig = sigmap(cell->getPort(ID::B)); if (!const_sig.is_fully_const()) { if (!nonconst_sig.is_fully_const()) continue; std::swap(nonconst_sig, const_sig); } - y_port = sigmap(cell->getPort(ID(Y))); + y_port = sigmap(cell->getPort(ID::Y)); } else if (cell->type == ID($logic_not)) { - nonconst_sig = sigmap(cell->getPort(ID(A))); + nonconst_sig = sigmap(cell->getPort(ID::A)); const_sig = Const(State::S0, GetSize(nonconst_sig)); - y_port = sigmap(cell->getPort(ID(Y))); + y_port = sigmap(cell->getPort(ID::Y)); } else if (cell->type == ID($reduce_or)) { reduce_or.insert(cell); @@ -66,7 +66,7 @@ struct ExclusiveDatabase for (auto cell : reduce_or) { nonconst_sig = SigSpec(); std::vector values; - SigSpec a_port = sigmap(cell->getPort(ID(A))); + SigSpec a_port = sigmap(cell->getPort(ID::A)); for (auto bit : a_port) { auto it = sig_cmp_prev.find(bit); if (it == sig_cmp_prev.end()) { @@ -84,7 +84,7 @@ struct ExclusiveDatabase } if (nonconst_sig.empty()) continue; - y_port = sigmap(cell->getPort(ID(Y))); + y_port = sigmap(cell->getPort(ID::Y)); sig_cmp_prev[y_port] = std::make_pair(nonconst_sig,std::move(values)); } } @@ -145,11 +145,11 @@ struct MuxpackWorker { if (cell->type.in(ID($mux), ID($pmux)) && !cell->get_bool_attribute(ID(keep))) { - SigSpec a_sig = sigmap(cell->getPort(ID(A))); + SigSpec a_sig = sigmap(cell->getPort(ID::A)); SigSpec b_sig; if (cell->type == ID($mux)) - b_sig = sigmap(cell->getPort(ID(B))); - SigSpec y_sig = sigmap(cell->getPort(ID(Y))); + b_sig = sigmap(cell->getPort(ID::B)); + SigSpec y_sig = sigmap(cell->getPort(ID::Y)); if (sig_chain_next.count(a_sig)) for (auto a_bit : a_sig.bits()) @@ -186,9 +186,9 @@ struct MuxpackWorker { log_debug("Considering %s (%s)\n", log_id(cell), log_id(cell->type)); - SigSpec a_sig = sigmap(cell->getPort(ID(A))); + SigSpec a_sig = sigmap(cell->getPort(ID::A)); if (cell->type == ID($mux)) { - SigSpec b_sig = sigmap(cell->getPort(ID(B))); + SigSpec b_sig = sigmap(cell->getPort(ID::B)); if (sig_chain_prev.count(a_sig) + sig_chain_prev.count(b_sig) != 1) goto start_cell; @@ -230,7 +230,7 @@ struct MuxpackWorker { chain.push_back(c); - SigSpec y_sig = sigmap(c->getPort(ID(Y))); + SigSpec y_sig = sigmap(c->getPort(ID::Y)); if (sig_chain_next.count(y_sig) == 0) break; @@ -270,28 +270,28 @@ struct MuxpackWorker pmux_count += 1; first_cell->type = ID($pmux); - SigSpec b_sig = first_cell->getPort(ID(B)); + SigSpec b_sig = first_cell->getPort(ID::B); SigSpec s_sig = first_cell->getPort(ID(S)); for (int i = 1; i < cases; i++) { Cell* prev_cell = chain[cursor+i-1]; Cell* cursor_cell = chain[cursor+i]; - if (sigmap(prev_cell->getPort(ID(Y))) == sigmap(cursor_cell->getPort(ID(A)))) { - b_sig.append(cursor_cell->getPort(ID(B))); + if (sigmap(prev_cell->getPort(ID::Y)) == sigmap(cursor_cell->getPort(ID::A))) { + b_sig.append(cursor_cell->getPort(ID::B)); s_sig.append(cursor_cell->getPort(ID(S))); } else { log_assert(cursor_cell->type == ID($mux)); - b_sig.append(cursor_cell->getPort(ID(A))); + b_sig.append(cursor_cell->getPort(ID::A)); s_sig.append(module->LogicNot(NEW_ID, cursor_cell->getPort(ID(S)))); } remove_cells.insert(cursor_cell); } - first_cell->setPort(ID(B), b_sig); + first_cell->setPort(ID::B, b_sig); first_cell->setPort(ID(S), s_sig); first_cell->setParam(ID(S_WIDTH), GetSize(s_sig)); - first_cell->setPort(ID(Y), last_cell->getPort(ID(Y))); + first_cell->setPort(ID::Y, last_cell->getPort(ID::Y)); cursor += cases; } diff --git a/passes/opt/opt_clean.cc b/passes/opt/opt_clean.cc index 1d3a85b3a..bf75c7adc 100644 --- a/passes/opt/opt_clean.cc +++ b/passes/opt/opt_clean.cc @@ -482,8 +482,8 @@ void rmunused_module(RTLIL::Module *module, bool purge_mode, bool verbose, bool for (auto cell : module->cells()) if (cell->type.in(ID($pos), ID($_BUF_)) && !cell->has_keep_attr()) { bool is_signed = cell->type == ID($pos) && cell->getParam(ID(A_SIGNED)).as_bool(); - RTLIL::SigSpec a = cell->getPort(ID(A)); - RTLIL::SigSpec y = cell->getPort(ID(Y)); + RTLIL::SigSpec a = cell->getPort(ID::A); + RTLIL::SigSpec y = cell->getPort(ID::Y); a.extend_u0(GetSize(y), is_signed); module->connect(y, a); delcells.push_back(cell); @@ -491,7 +491,7 @@ void rmunused_module(RTLIL::Module *module, bool purge_mode, bool verbose, bool for (auto cell : delcells) { if (verbose) log_debug(" removing buffer cell `%s': %s = %s\n", cell->name.c_str(), - log_signal(cell->getPort(ID(Y))), log_signal(cell->getPort(ID(A)))); + log_signal(cell->getPort(ID::Y)), log_signal(cell->getPort(ID::A))); module->remove(cell); } if (!delcells.empty()) diff --git a/passes/opt/opt_demorgan.cc b/passes/opt/opt_demorgan.cc index 7defef442..4bc82815b 100644 --- a/passes/opt/opt_demorgan.cc +++ b/passes/opt/opt_demorgan.cc @@ -38,7 +38,7 @@ void demorgan_worker( if( (cell->type != ID($reduce_and)) && (cell->type != ID($reduce_or)) ) return; - auto insig = sigmap(cell->getPort(ID(A))); + auto insig = sigmap(cell->getPort(ID::A)); log("Inspecting %s cell %s (%d inputs)\n", log_id(cell->type), log_id(cell->name), GetSize(insig)); int num_inverted = 0; for(int i=0; itype == ID($_NOT_)) + if(x.port == ID::Y && x.cell->type == ID($_NOT_)) { inverted = true; break; @@ -85,7 +85,7 @@ void demorgan_worker( RTLIL::Cell* srcinv = NULL; for(auto x : ports) { - if(x.port == ID(Y) && x.cell->type == ID($_NOT_)) + if(x.port == ID::Y && x.cell->type == ID($_NOT_)) { srcinv = x.cell; break; @@ -103,7 +103,7 @@ void demorgan_worker( //We ARE inverted - bypass it //Don't automatically delete the inverter since other stuff might still use it else - insig[i] = srcinv->getPort(ID(A)); + insig[i] = srcinv->getPort(ID::A); } //Cosmetic fixup: If our input is just a scrambled version of one bus, rearrange it @@ -151,7 +151,7 @@ void demorgan_worker( } //Push the new input signal back to the reduction (after bypassing/adding inverters) - cell->setPort(ID(A), insig); + cell->setPort(ID::A, insig); //Change the cell type if(cell->type == ID($reduce_and)) @@ -161,10 +161,10 @@ void demorgan_worker( //don't change XOR //Add an inverter to the output - auto inverted_output = cell->getPort(ID(Y)); + auto inverted_output = cell->getPort(ID::Y); auto uninverted_output = m->addWire(NEW_ID); m->addNot(NEW_ID, RTLIL::SigSpec(uninverted_output), inverted_output); - cell->setPort(ID(Y), uninverted_output); + cell->setPort(ID::Y, uninverted_output); } struct OptDemorganPass : public Pass { diff --git a/passes/opt/opt_expr.cc b/passes/opt/opt_expr.cc index 6dea611e3..85ec9a55a 100644 --- a/passes/opt/opt_expr.cc +++ b/passes/opt/opt_expr.cc @@ -134,14 +134,14 @@ void replace_cell(SigMap &assign_map, RTLIL::Module *module, RTLIL::Cell *cell, bool group_cell_inputs(RTLIL::Module *module, RTLIL::Cell *cell, bool commutative, SigMap &sigmap) { - IdString b_name = cell->hasPort(ID(B)) ? ID(B) : ID(A); + IdString b_name = cell->hasPort(ID::B) ? ID::B : ID::A; bool a_signed = cell->parameters.at(ID(A_SIGNED)).as_bool(); bool b_signed = cell->parameters.at(b_name.str() + "_SIGNED").as_bool(); - RTLIL::SigSpec sig_a = sigmap(cell->getPort(ID(A))); + RTLIL::SigSpec sig_a = sigmap(cell->getPort(ID::A)); RTLIL::SigSpec sig_b = sigmap(cell->getPort(b_name)); - RTLIL::SigSpec sig_y = sigmap(cell->getPort(ID(Y))); + RTLIL::SigSpec sig_y = sigmap(cell->getPort(ID::Y)); sig_a.extend_u0(sig_y.size(), a_signed); sig_b.extend_u0(sig_y.size(), b_signed); @@ -208,24 +208,24 @@ bool group_cell_inputs(RTLIL::Module *module, RTLIL::Cell *cell, bool commutativ RTLIL::Cell *c = module->addCell(NEW_ID, cell->type); - c->setPort(ID(A), new_a); + c->setPort(ID::A, new_a); c->parameters[ID(A_WIDTH)] = new_a.size(); c->parameters[ID(A_SIGNED)] = false; - if (b_name == ID(B)) { - c->setPort(ID(B), new_b); + if (b_name == ID::B) { + c->setPort(ID::B, new_b); c->parameters[ID(B_WIDTH)] = new_b.size(); c->parameters[ID(B_SIGNED)] = false; } - c->setPort(ID(Y), new_y); + c->setPort(ID::Y, new_y); c->parameters[ID(Y_WIDTH)] = new_y->width; c->check(); module->connect(new_conn); log_debug(" New cell `%s': A=%s", log_id(c), log_signal(new_a)); - if (b_name == ID(B)) + if (b_name == ID::B) log_debug(", B=%s", log_signal(new_b)); log_debug("\n"); } @@ -368,11 +368,11 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons for (auto cell : module->cells()) if (design->selected(module, cell) && cell->type[0] == '$') { if (cell->type.in(ID($_NOT_), ID($not), ID($logic_not)) && - cell->getPort(ID(A)).size() == 1 && cell->getPort(ID(Y)).size() == 1) - invert_map[assign_map(cell->getPort(ID(Y)))] = assign_map(cell->getPort(ID(A))); + cell->getPort(ID::A).size() == 1 && cell->getPort(ID::Y).size() == 1) + invert_map[assign_map(cell->getPort(ID::Y))] = assign_map(cell->getPort(ID::A)); if (cell->type.in(ID($mux), ID($_MUX_)) && - cell->getPort(ID(A)) == SigSpec(State::S1) && cell->getPort(ID(B)) == SigSpec(State::S0)) - invert_map[assign_map(cell->getPort(ID(Y)))] = assign_map(cell->getPort(ID(S))); + cell->getPort(ID::A) == SigSpec(State::S1) && cell->getPort(ID::B) == SigSpec(State::S0)) + invert_map[assign_map(cell->getPort(ID::Y))] = assign_map(cell->getPort(ID(S))); if (ct_combinational.cell_known(cell->type)) for (auto &conn : cell->connections()) { RTLIL::SigSpec sig = assign_map(conn.second); @@ -396,7 +396,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons for (auto cell : cells.sorted) { #define ACTION_DO(_p_, _s_) do { cover("opt.opt_expr.action_" S__LINE__); replace_cell(assign_map, module, cell, input.as_string(), _p_, _s_); goto next_cell; } while (0) -#define ACTION_DO_Y(_v_) ACTION_DO(ID(Y), RTLIL::SigSpec(RTLIL::State::S ## _v_)) +#define ACTION_DO_Y(_v_) ACTION_DO(ID::Y, RTLIL::SigSpec(RTLIL::State::S ## _v_)) if (clkinv) { @@ -439,23 +439,23 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons if (cell->type.in(ID($reduce_and), ID($_AND_))) detect_const_and = true; - if (cell->type.in(ID($and), ID($logic_and)) && GetSize(cell->getPort(ID(A))) == 1 && GetSize(cell->getPort(ID(B))) == 1 && !cell->getParam(ID(A_SIGNED)).as_bool()) + if (cell->type.in(ID($and), ID($logic_and)) && GetSize(cell->getPort(ID::A)) == 1 && GetSize(cell->getPort(ID::B)) == 1 && !cell->getParam(ID(A_SIGNED)).as_bool()) detect_const_and = true; if (cell->type.in(ID($reduce_or), ID($reduce_bool), ID($_OR_))) detect_const_or = true; - if (cell->type.in(ID($or), ID($logic_or)) && GetSize(cell->getPort(ID(A))) == 1 && GetSize(cell->getPort(ID(B))) == 1 && !cell->getParam(ID(A_SIGNED)).as_bool()) + if (cell->type.in(ID($or), ID($logic_or)) && GetSize(cell->getPort(ID::A)) == 1 && GetSize(cell->getPort(ID::B)) == 1 && !cell->getParam(ID(A_SIGNED)).as_bool()) detect_const_or = true; if (detect_const_and || detect_const_or) { - pool input_bits = assign_map(cell->getPort(ID(A))).to_sigbit_pool(); + pool input_bits = assign_map(cell->getPort(ID::A)).to_sigbit_pool(); bool found_zero = false, found_one = false, found_undef = false, found_inv = false, many_conconst = false; SigBit non_const_input = State::Sm; - if (cell->hasPort(ID(B))) { - vector more_bits = assign_map(cell->getPort(ID(B))).to_sigbit_vector(); + if (cell->hasPort(ID::B)) { + vector more_bits = assign_map(cell->getPort(ID::B)).to_sigbit_vector(); input_bits.insert(more_bits.begin(), more_bits.end()); } @@ -478,25 +478,25 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons if (detect_const_and && (found_zero || found_inv)) { cover("opt.opt_expr.const_and"); - replace_cell(assign_map, module, cell, "const_and", ID(Y), RTLIL::State::S0); + replace_cell(assign_map, module, cell, "const_and", ID::Y, RTLIL::State::S0); goto next_cell; } if (detect_const_or && (found_one || found_inv)) { cover("opt.opt_expr.const_or"); - replace_cell(assign_map, module, cell, "const_or", ID(Y), RTLIL::State::S1); + replace_cell(assign_map, module, cell, "const_or", ID::Y, RTLIL::State::S1); goto next_cell; } if (non_const_input != State::Sm && !found_undef) { cover("opt.opt_expr.and_or_buffer"); - replace_cell(assign_map, module, cell, "and_or_buffer", ID(Y), non_const_input); + replace_cell(assign_map, module, cell, "and_or_buffer", ID::Y, non_const_input); goto next_cell; } } if (cell->type.in(ID($reduce_and), ID($reduce_or), ID($reduce_bool), ID($reduce_xor), ID($reduce_xnor), ID($neg)) && - GetSize(cell->getPort(ID(A))) == 1 && GetSize(cell->getPort(ID(Y))) == 1) + GetSize(cell->getPort(ID::A)) == 1 && GetSize(cell->getPort(ID::Y)) == 1) { if (cell->type == ID($reduce_xnor)) { cover("opt.opt_expr.reduce_xnor_not"); @@ -506,7 +506,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons did_something = true; } else { cover("opt.opt_expr.unary_buffer"); - replace_cell(assign_map, module, cell, "unary_buffer", ID(Y), cell->getPort(ID(A))); + replace_cell(assign_map, module, cell, "unary_buffer", ID::Y, cell->getPort(ID::A)); } goto next_cell; } @@ -521,7 +521,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons { SigBit neutral_bit = cell->type == ID($reduce_and) ? State::S1 : State::S0; - RTLIL::SigSpec sig_a = assign_map(cell->getPort(ID(A))); + RTLIL::SigSpec sig_a = assign_map(cell->getPort(ID::A)); RTLIL::SigSpec new_sig_a; for (auto bit : sig_a) @@ -534,7 +534,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons cover_list("opt.opt_expr.fine.neutral_A", "$logic_not", "$logic_and", "$logic_or", "$reduce_or", "$reduce_and", "$reduce_bool", cell->type.str()); log_debug("Replacing port A of %s cell `%s' in module `%s' with shorter expression: %s -> %s\n", cell->type.c_str(), cell->name.c_str(), module->name.c_str(), log_signal(sig_a), log_signal(new_sig_a)); - cell->setPort(ID(A), new_sig_a); + cell->setPort(ID::A, new_sig_a); cell->parameters.at(ID(A_WIDTH)) = GetSize(new_sig_a); did_something = true; } @@ -544,7 +544,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons { SigBit neutral_bit = State::S0; - RTLIL::SigSpec sig_b = assign_map(cell->getPort(ID(B))); + RTLIL::SigSpec sig_b = assign_map(cell->getPort(ID::B)); RTLIL::SigSpec new_sig_b; for (auto bit : sig_b) @@ -557,7 +557,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons cover_list("opt.opt_expr.fine.neutral_B", "$logic_and", "$logic_or", cell->type.str()); log_debug("Replacing port B of %s cell `%s' in module `%s' with shorter expression: %s -> %s\n", cell->type.c_str(), cell->name.c_str(), module->name.c_str(), log_signal(sig_b), log_signal(new_sig_b)); - cell->setPort(ID(B), new_sig_b); + cell->setPort(ID::B, new_sig_b); cell->parameters.at(ID(B_WIDTH)) = GetSize(new_sig_b); did_something = true; } @@ -565,7 +565,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons if (cell->type == ID($reduce_and)) { - RTLIL::SigSpec sig_a = assign_map(cell->getPort(ID(A))); + RTLIL::SigSpec sig_a = assign_map(cell->getPort(ID::A)); RTLIL::State new_a = RTLIL::State::S1; for (auto &bit : sig_a.to_sigbit_vector()) @@ -583,7 +583,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons cover("opt.opt_expr.fine.$reduce_and"); log_debug("Replacing port A of %s cell `%s' in module `%s' with constant driver: %s -> %s\n", cell->type.c_str(), cell->name.c_str(), module->name.c_str(), log_signal(sig_a), log_signal(new_a)); - cell->setPort(ID(A), sig_a = new_a); + cell->setPort(ID::A, sig_a = new_a); cell->parameters.at(ID(A_WIDTH)) = 1; did_something = true; } @@ -591,7 +591,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons if (cell->type.in(ID($logic_not), ID($logic_and), ID($logic_or), ID($reduce_or), ID($reduce_bool))) { - RTLIL::SigSpec sig_a = assign_map(cell->getPort(ID(A))); + RTLIL::SigSpec sig_a = assign_map(cell->getPort(ID::A)); RTLIL::State new_a = RTLIL::State::S0; for (auto &bit : sig_a.to_sigbit_vector()) @@ -609,7 +609,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons cover_list("opt.opt_expr.fine.A", "$logic_not", "$logic_and", "$logic_or", "$reduce_or", "$reduce_bool", cell->type.str()); log_debug("Replacing port A of %s cell `%s' in module `%s' with constant driver: %s -> %s\n", cell->type.c_str(), cell->name.c_str(), module->name.c_str(), log_signal(sig_a), log_signal(new_a)); - cell->setPort(ID(A), sig_a = new_a); + cell->setPort(ID::A, sig_a = new_a); cell->parameters.at(ID(A_WIDTH)) = 1; did_something = true; } @@ -617,7 +617,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons if (cell->type.in(ID($logic_and), ID($logic_or))) { - RTLIL::SigSpec sig_b = assign_map(cell->getPort(ID(B))); + RTLIL::SigSpec sig_b = assign_map(cell->getPort(ID::B)); RTLIL::State new_b = RTLIL::State::S0; for (auto &bit : sig_b.to_sigbit_vector()) @@ -635,7 +635,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons cover_list("opt.opt_expr.fine.B", "$logic_and", "$logic_or", cell->type.str()); log_debug("Replacing port B of %s cell `%s' in module `%s' with constant driver: %s -> %s\n", cell->type.c_str(), cell->name.c_str(), module->name.c_str(), log_signal(sig_b), log_signal(new_b)); - cell->setPort(ID(B), sig_b = new_b); + cell->setPort(ID::B, sig_b = new_b); cell->parameters.at(ID(B_WIDTH)) = 1; did_something = true; } @@ -643,9 +643,9 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons if (cell->type.in(ID($add), ID($sub))) { - RTLIL::SigSpec sig_a = assign_map(cell->getPort(ID(A))); - RTLIL::SigSpec sig_b = assign_map(cell->getPort(ID(B))); - RTLIL::SigSpec sig_y = cell->getPort(ID(Y)); + RTLIL::SigSpec sig_a = assign_map(cell->getPort(ID::A)); + RTLIL::SigSpec sig_b = assign_map(cell->getPort(ID::B)); + RTLIL::SigSpec sig_y = cell->getPort(ID::Y); bool sub = cell->type == ID($sub); int i; @@ -659,9 +659,9 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons } if (i > 0) { cover_list("opt.opt_expr.fine", "$add", "$sub", cell->type.str()); - cell->setPort(ID(A), sig_a.extract_end(i)); - cell->setPort(ID(B), sig_b.extract_end(i)); - cell->setPort(ID(Y), sig_y.extract_end(i)); + cell->setPort(ID::A, sig_a.extract_end(i)); + cell->setPort(ID::B, sig_b.extract_end(i)); + cell->setPort(ID::Y, sig_y.extract_end(i)); cell->fixup_parameters(); did_something = true; } @@ -669,12 +669,12 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons if (cell->type == "$alu") { - RTLIL::SigSpec sig_a = assign_map(cell->getPort(ID(A))); - RTLIL::SigSpec sig_b = assign_map(cell->getPort(ID(B))); + RTLIL::SigSpec sig_a = assign_map(cell->getPort(ID::A)); + RTLIL::SigSpec sig_b = assign_map(cell->getPort(ID::B)); RTLIL::SigBit sig_ci = assign_map(cell->getPort(ID(CI))); RTLIL::SigBit sig_bi = assign_map(cell->getPort(ID(BI))); RTLIL::SigSpec sig_x = cell->getPort(ID(X)); - RTLIL::SigSpec sig_y = cell->getPort(ID(Y)); + RTLIL::SigSpec sig_y = cell->getPort(ID::Y); RTLIL::SigSpec sig_co = cell->getPort(ID(CO)); if (sig_ci.wire || sig_bi.wire) @@ -704,10 +704,10 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons } if (i > 0) { cover("opt.opt_expr.fine.$alu"); - cell->setPort(ID(A), sig_a.extract_end(i)); - cell->setPort(ID(B), sig_b.extract_end(i)); + cell->setPort(ID::A, sig_a.extract_end(i)); + cell->setPort(ID::B, sig_b.extract_end(i)); cell->setPort(ID(X), sig_x.extract_end(i)); - cell->setPort(ID(Y), sig_y.extract_end(i)); + cell->setPort(ID::Y, sig_y.extract_end(i)); cell->setPort(ID(CO), sig_co.extract_end(i)); cell->fixup_parameters(); did_something = true; @@ -718,8 +718,8 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons if (cell->type.in(ID($reduce_xor), ID($reduce_xnor), ID($shift), ID($shiftx), ID($shl), ID($shr), ID($sshl), ID($sshr), ID($lt), ID($le), ID($ge), ID($gt), ID($neg), ID($add), ID($sub), ID($mul), ID($div), ID($mod), ID($pow))) { - RTLIL::SigSpec sig_a = assign_map(cell->getPort(ID(A))); - RTLIL::SigSpec sig_b = cell->hasPort(ID(B)) ? assign_map(cell->getPort(ID(B))) : RTLIL::SigSpec(); + RTLIL::SigSpec sig_a = assign_map(cell->getPort(ID::A)); + RTLIL::SigSpec sig_b = cell->hasPort(ID::B) ? assign_map(cell->getPort(ID::B)) : RTLIL::SigSpec(); if (cell->type.in(ID($shl), ID($shr), ID($sshl), ID($sshr), ID($shift), ID($shiftx))) sig_a = RTLIL::SigSpec(); @@ -737,33 +737,33 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons cover_list("opt.opt_expr.xbit", "$reduce_xor", "$reduce_xnor", "$shl", "$shr", "$sshl", "$sshr", "$shift", "$shiftx", "$lt", "$le", "$ge", "$gt", "$neg", "$add", "$sub", "$mul", "$div", "$mod", "$pow", cell->type.str()); if (cell->type.in(ID($reduce_xor), ID($reduce_xnor), ID($lt), ID($le), ID($ge), ID($gt))) - replace_cell(assign_map, module, cell, "x-bit in input", ID(Y), RTLIL::State::Sx); + replace_cell(assign_map, module, cell, "x-bit in input", ID::Y, RTLIL::State::Sx); else - replace_cell(assign_map, module, cell, "x-bit in input", ID(Y), RTLIL::SigSpec(RTLIL::State::Sx, cell->getPort(ID(Y)).size())); + replace_cell(assign_map, module, cell, "x-bit in input", ID::Y, RTLIL::SigSpec(RTLIL::State::Sx, cell->getPort(ID::Y).size())); goto next_cell; } } - if (cell->type.in(ID($_NOT_), ID($not), ID($logic_not)) && cell->getPort(ID(Y)).size() == 1 && - invert_map.count(assign_map(cell->getPort(ID(A)))) != 0) { + if (cell->type.in(ID($_NOT_), ID($not), ID($logic_not)) && cell->getPort(ID::Y).size() == 1 && + invert_map.count(assign_map(cell->getPort(ID::A))) != 0) { cover_list("opt.opt_expr.invert.double", "$_NOT_", "$not", "$logic_not", cell->type.str()); - replace_cell(assign_map, module, cell, "double_invert", ID(Y), invert_map.at(assign_map(cell->getPort(ID(A))))); + replace_cell(assign_map, module, cell, "double_invert", ID::Y, invert_map.at(assign_map(cell->getPort(ID::A)))); goto next_cell; } if (cell->type.in(ID($_MUX_), ID($mux)) && invert_map.count(assign_map(cell->getPort(ID(S)))) != 0) { cover_list("opt.opt_expr.invert.muxsel", "$_MUX_", "$mux", cell->type.str()); log_debug("Optimizing away select inverter for %s cell `%s' in module `%s'.\n", log_id(cell->type), log_id(cell), log_id(module)); - RTLIL::SigSpec tmp = cell->getPort(ID(A)); - cell->setPort(ID(A), cell->getPort(ID(B))); - cell->setPort(ID(B), tmp); + RTLIL::SigSpec tmp = cell->getPort(ID::A); + cell->setPort(ID::A, cell->getPort(ID::B)); + cell->setPort(ID::B, tmp); cell->setPort(ID(S), invert_map.at(assign_map(cell->getPort(ID(S))))); did_something = true; goto next_cell; } if (cell->type == ID($_NOT_)) { - RTLIL::SigSpec input = cell->getPort(ID(A)); + RTLIL::SigSpec input = cell->getPort(ID::A); assign_map.apply(input); if (input.match("1")) ACTION_DO_Y(0); if (input.match("0")) ACTION_DO_Y(1); @@ -772,8 +772,8 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons if (cell->type == ID($_AND_)) { RTLIL::SigSpec input; - input.append(cell->getPort(ID(B))); - input.append(cell->getPort(ID(A))); + input.append(cell->getPort(ID::B)); + input.append(cell->getPort(ID::A)); assign_map.apply(input); if (input.match(" 0")) ACTION_DO_Y(0); if (input.match("0 ")) ACTION_DO_Y(0); @@ -785,14 +785,14 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons if (input.match(" *")) ACTION_DO_Y(0); if (input.match("* ")) ACTION_DO_Y(0); } - if (input.match(" 1")) ACTION_DO(ID(Y), input.extract(1, 1)); - if (input.match("1 ")) ACTION_DO(ID(Y), input.extract(0, 1)); + if (input.match(" 1")) ACTION_DO(ID::Y, input.extract(1, 1)); + if (input.match("1 ")) ACTION_DO(ID::Y, input.extract(0, 1)); } if (cell->type == ID($_OR_)) { RTLIL::SigSpec input; - input.append(cell->getPort(ID(B))); - input.append(cell->getPort(ID(A))); + input.append(cell->getPort(ID::B)); + input.append(cell->getPort(ID::A)); assign_map.apply(input); if (input.match(" 1")) ACTION_DO_Y(1); if (input.match("1 ")) ACTION_DO_Y(1); @@ -804,14 +804,14 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons if (input.match(" *")) ACTION_DO_Y(1); if (input.match("* ")) ACTION_DO_Y(1); } - if (input.match(" 0")) ACTION_DO(ID(Y), input.extract(1, 1)); - if (input.match("0 ")) ACTION_DO(ID(Y), input.extract(0, 1)); + if (input.match(" 0")) ACTION_DO(ID::Y, input.extract(1, 1)); + if (input.match("0 ")) ACTION_DO(ID::Y, input.extract(0, 1)); } if (cell->type == ID($_XOR_)) { RTLIL::SigSpec input; - input.append(cell->getPort(ID(B))); - input.append(cell->getPort(ID(A))); + input.append(cell->getPort(ID::B)); + input.append(cell->getPort(ID::A)); assign_map.apply(input); if (input.match("00")) ACTION_DO_Y(0); if (input.match("01")) ACTION_DO_Y(1); @@ -819,26 +819,26 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons if (input.match("11")) ACTION_DO_Y(0); if (input.match(" *")) ACTION_DO_Y(x); if (input.match("* ")) ACTION_DO_Y(x); - if (input.match(" 0")) ACTION_DO(ID(Y), input.extract(1, 1)); - if (input.match("0 ")) ACTION_DO(ID(Y), input.extract(0, 1)); + if (input.match(" 0")) ACTION_DO(ID::Y, input.extract(1, 1)); + if (input.match("0 ")) ACTION_DO(ID::Y, input.extract(0, 1)); } if (cell->type == ID($_MUX_)) { RTLIL::SigSpec input; input.append(cell->getPort(ID(S))); - input.append(cell->getPort(ID(B))); - input.append(cell->getPort(ID(A))); + input.append(cell->getPort(ID::B)); + input.append(cell->getPort(ID::A)); assign_map.apply(input); if (input.extract(2, 1) == input.extract(1, 1)) - ACTION_DO(ID(Y), input.extract(2, 1)); - if (input.match(" 0")) ACTION_DO(ID(Y), input.extract(2, 1)); - if (input.match(" 1")) ACTION_DO(ID(Y), input.extract(1, 1)); - if (input.match("01 ")) ACTION_DO(ID(Y), input.extract(0, 1)); + ACTION_DO(ID::Y, input.extract(2, 1)); + if (input.match(" 0")) ACTION_DO(ID::Y, input.extract(2, 1)); + if (input.match(" 1")) ACTION_DO(ID::Y, input.extract(1, 1)); + if (input.match("01 ")) ACTION_DO(ID::Y, input.extract(0, 1)); if (input.match("10 ")) { cover("opt.opt_expr.mux_to_inv"); cell->type = ID($_NOT_); - cell->setPort(ID(A), input.extract(0, 1)); - cell->unsetPort(ID(B)); + cell->setPort(ID::A, input.extract(0, 1)); + cell->unsetPort(ID::B); cell->unsetPort(ID(S)); goto next_cell; } @@ -848,24 +848,24 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons if (input.match("01*")) ACTION_DO_Y(x); if (input.match("10*")) ACTION_DO_Y(x); if (mux_undef) { - if (input.match("* ")) ACTION_DO(ID(Y), input.extract(1, 1)); - if (input.match(" * ")) ACTION_DO(ID(Y), input.extract(2, 1)); - if (input.match(" *")) ACTION_DO(ID(Y), input.extract(2, 1)); + if (input.match("* ")) ACTION_DO(ID::Y, input.extract(1, 1)); + if (input.match(" * ")) ACTION_DO(ID::Y, input.extract(2, 1)); + if (input.match(" *")) ACTION_DO(ID::Y, input.extract(2, 1)); } } if (cell->type.in(ID($_TBUF_), ID($tribuf))) { RTLIL::SigSpec input = cell->getPort(cell->type == ID($_TBUF_) ? ID(E) : ID(EN)); - RTLIL::SigSpec a = cell->getPort(ID(A)); + RTLIL::SigSpec a = cell->getPort(ID::A); assign_map.apply(input); assign_map.apply(a); if (input == State::S1) - ACTION_DO(ID(Y), cell->getPort(ID(A))); + ACTION_DO(ID::Y, cell->getPort(ID::A)); if (input == State::S0 && !a.is_fully_undef()) { cover("opt.opt_expr.action_" S__LINE__); log_debug("Replacing data input of %s cell `%s' in module `%s' with constant undef.\n", cell->type.c_str(), cell->name.c_str(), module->name.c_str()); - cell->setPort(ID(A), SigSpec(State::Sx, GetSize(a))); + cell->setPort(ID::A, SigSpec(State::Sx, GetSize(a))); did_something = true; goto next_cell; } @@ -873,8 +873,8 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons if (cell->type.in(ID($eq), ID($ne), ID($eqx), ID($nex))) { - RTLIL::SigSpec a = cell->getPort(ID(A)); - RTLIL::SigSpec b = cell->getPort(ID(B)); + RTLIL::SigSpec a = cell->getPort(ID::A); + RTLIL::SigSpec b = cell->getPort(ID::B); if (cell->parameters[ID(A_WIDTH)].as_int() != cell->parameters[ID(B_WIDTH)].as_int()) { int width = max(cell->parameters[ID(A_WIDTH)].as_int(), cell->parameters[ID(B_WIDTH)].as_int()); @@ -890,7 +890,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons cover_list("opt.opt_expr.eqneq.isneq", "$eq", "$ne", "$eqx", "$nex", cell->type.str()); RTLIL::SigSpec new_y = RTLIL::SigSpec(cell->type.in(ID($eq), ID($eqx)) ? RTLIL::State::S0 : RTLIL::State::S1); new_y.extend_u0(cell->parameters[ID(Y_WIDTH)].as_int(), false); - replace_cell(assign_map, module, cell, "isneq", ID(Y), new_y); + replace_cell(assign_map, module, cell, "isneq", ID::Y, new_y); goto next_cell; } if (a[i] == b[i]) @@ -903,14 +903,14 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons cover_list("opt.opt_expr.eqneq.empty", "$eq", "$ne", "$eqx", "$nex", cell->type.str()); RTLIL::SigSpec new_y = RTLIL::SigSpec(cell->type.in(ID($eq), ID($eqx)) ? RTLIL::State::S1 : RTLIL::State::S0); new_y.extend_u0(cell->parameters[ID(Y_WIDTH)].as_int(), false); - replace_cell(assign_map, module, cell, "empty", ID(Y), new_y); + replace_cell(assign_map, module, cell, "empty", ID::Y, new_y); goto next_cell; } if (new_a.size() < a.size() || new_b.size() < b.size()) { cover_list("opt.opt_expr.eqneq.resize", "$eq", "$ne", "$eqx", "$nex", cell->type.str()); - cell->setPort(ID(A), new_a); - cell->setPort(ID(B), new_b); + cell->setPort(ID::A, new_a); + cell->setPort(ID::B, new_b); cell->parameters[ID(A_WIDTH)] = new_a.size(); cell->parameters[ID(B_WIDTH)] = new_b.size(); } @@ -919,27 +919,27 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons if (cell->type.in(ID($eq), ID($ne)) && cell->parameters[ID(Y_WIDTH)].as_int() == 1 && cell->parameters[ID(A_WIDTH)].as_int() == 1 && cell->parameters[ID(B_WIDTH)].as_int() == 1) { - RTLIL::SigSpec a = assign_map(cell->getPort(ID(A))); - RTLIL::SigSpec b = assign_map(cell->getPort(ID(B))); + RTLIL::SigSpec a = assign_map(cell->getPort(ID::A)); + RTLIL::SigSpec b = assign_map(cell->getPort(ID::B)); if (a.is_fully_const() && !b.is_fully_const()) { cover_list("opt.opt_expr.eqneq.swapconst", "$eq", "$ne", cell->type.str()); - cell->setPort(ID(A), b); - cell->setPort(ID(B), a); + cell->setPort(ID::A, b); + cell->setPort(ID::B, a); std::swap(a, b); } if (b.is_fully_const()) { if (b.as_bool() == (cell->type == ID($eq))) { RTLIL::SigSpec input = b; - ACTION_DO(ID(Y), cell->getPort(ID(A))); + ACTION_DO(ID::Y, cell->getPort(ID::A)); } else { cover_list("opt.opt_expr.eqneq.isnot", "$eq", "$ne", cell->type.str()); log_debug("Replacing %s cell `%s' in module `%s' with inverter.\n", log_id(cell->type), log_id(cell), log_id(module)); cell->type = ID($not); cell->parameters.erase(ID(B_WIDTH)); cell->parameters.erase(ID(B_SIGNED)); - cell->unsetPort(ID(B)); + cell->unsetPort(ID::B); did_something = true; } goto next_cell; @@ -947,33 +947,33 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons } if (cell->type.in(ID($eq), ID($ne)) && - (assign_map(cell->getPort(ID(A))).is_fully_zero() || assign_map(cell->getPort(ID(B))).is_fully_zero())) + (assign_map(cell->getPort(ID::A)).is_fully_zero() || assign_map(cell->getPort(ID::B)).is_fully_zero())) { cover_list("opt.opt_expr.eqneq.cmpzero", "$eq", "$ne", cell->type.str()); log_debug("Replacing %s cell `%s' in module `%s' with %s.\n", log_id(cell->type), log_id(cell), log_id(module), "$eq" ? "$logic_not" : "$reduce_bool"); cell->type = cell->type == ID($eq) ? ID($logic_not) : ID($reduce_bool); - if (assign_map(cell->getPort(ID(A))).is_fully_zero()) { - cell->setPort(ID(A), cell->getPort(ID(B))); + if (assign_map(cell->getPort(ID::A)).is_fully_zero()) { + cell->setPort(ID::A, cell->getPort(ID::B)); cell->setParam(ID(A_SIGNED), cell->getParam(ID(B_SIGNED))); cell->setParam(ID(A_WIDTH), cell->getParam(ID(B_WIDTH))); } - cell->unsetPort(ID(B)); + cell->unsetPort(ID::B); cell->unsetParam(ID(B_SIGNED)); cell->unsetParam(ID(B_WIDTH)); did_something = true; goto next_cell; } - if (cell->type.in(ID($shl), ID($shr), ID($sshl), ID($sshr), ID($shift), ID($shiftx)) && assign_map(cell->getPort(ID(B))).is_fully_const()) + if (cell->type.in(ID($shl), ID($shr), ID($sshl), ID($sshr), ID($shift), ID($shiftx)) && assign_map(cell->getPort(ID::B)).is_fully_const()) { bool sign_ext = cell->type == ID($sshr) && cell->getParam(ID(A_SIGNED)).as_bool(); - int shift_bits = assign_map(cell->getPort(ID(B))).as_int(cell->type.in(ID($shift), ID($shiftx)) && cell->getParam(ID(B_SIGNED)).as_bool()); + int shift_bits = assign_map(cell->getPort(ID::B)).as_int(cell->type.in(ID($shift), ID($shiftx)) && cell->getParam(ID(B_SIGNED)).as_bool()); if (cell->type.in(ID($shl), ID($sshl))) shift_bits *= -1; - RTLIL::SigSpec sig_a = assign_map(cell->getPort(ID(A))); + RTLIL::SigSpec sig_a = assign_map(cell->getPort(ID::A)); RTLIL::SigSpec sig_y(cell->type == ID($shiftx) ? RTLIL::State::Sx : RTLIL::State::S0, cell->getParam(ID(Y_WIDTH)).as_int()); if (GetSize(sig_a) < GetSize(sig_y)) @@ -990,9 +990,9 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons cover_list("opt.opt_expr.constshift", "$shl", "$shr", "$sshl", "$sshr", "$shift", "$shiftx", cell->type.str()); log_debug("Replacing %s cell `%s' (B=%s, SHR=%d) in module `%s' with fixed wiring: %s\n", - log_id(cell->type), log_id(cell), log_signal(assign_map(cell->getPort(ID(B)))), shift_bits, log_id(module), log_signal(sig_y)); + log_id(cell->type), log_id(cell), log_signal(assign_map(cell->getPort(ID::B))), shift_bits, log_id(module), log_signal(sig_y)); - module->connect(cell->getPort(ID(Y)), sig_y); + module->connect(cell->getPort(ID::Y), sig_y); module->remove(cell); did_something = true; @@ -1007,8 +1007,8 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons if (cell->type.in(ID($add), ID($sub), ID($or), ID($xor))) { - RTLIL::SigSpec a = assign_map(cell->getPort(ID(A))); - RTLIL::SigSpec b = assign_map(cell->getPort(ID(B))); + RTLIL::SigSpec a = assign_map(cell->getPort(ID::A)); + RTLIL::SigSpec b = assign_map(cell->getPort(ID::B)); if (cell->type != ID($sub) && a.is_fully_const() && a.as_bool() == false) identity_wrt_b = true; @@ -1019,7 +1019,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons if (cell->type.in(ID($shl), ID($shr), ID($sshl), ID($sshr), ID($shift), ID($shiftx))) { - RTLIL::SigSpec b = assign_map(cell->getPort(ID(B))); + RTLIL::SigSpec b = assign_map(cell->getPort(ID::B)); if (b.is_fully_const() && b.as_bool() == false) identity_wrt_a = true; @@ -1027,8 +1027,8 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons if (cell->type == ID($mul)) { - RTLIL::SigSpec a = assign_map(cell->getPort(ID(A))); - RTLIL::SigSpec b = assign_map(cell->getPort(ID(B))); + RTLIL::SigSpec a = assign_map(cell->getPort(ID::A)); + RTLIL::SigSpec b = assign_map(cell->getPort(ID::B)); if (a.is_fully_const() && is_one_or_minus_one(a.as_const(), cell->getParam(ID(A_SIGNED)).as_bool(), arith_inverse)) identity_wrt_b = true; @@ -1039,7 +1039,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons if (cell->type == ID($div)) { - RTLIL::SigSpec b = assign_map(cell->getPort(ID(B))); + RTLIL::SigSpec b = assign_map(cell->getPort(ID::B)); if (b.is_fully_const() && b.size() <= 32 && b.as_int() == 1) identity_wrt_a = true; @@ -1056,13 +1056,13 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons cell->type.c_str(), cell->name.c_str(), module->name.c_str(), identity_wrt_a ? 'A' : 'B'); if (!identity_wrt_a) { - cell->setPort(ID(A), cell->getPort(ID(B))); + cell->setPort(ID::A, cell->getPort(ID::B)); cell->parameters.at(ID(A_WIDTH)) = cell->parameters.at(ID(B_WIDTH)); cell->parameters.at(ID(A_SIGNED)) = cell->parameters.at(ID(B_SIGNED)); } cell->type = arith_inverse ? ID($neg) : ID($pos); - cell->unsetPort(ID(B)); + cell->unsetPort(ID::B); cell->parameters.erase(ID(B_WIDTH)); cell->parameters.erase(ID(B_SIGNED)); cell->check(); @@ -1073,18 +1073,18 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons } if (mux_bool && cell->type.in(ID($mux), ID($_MUX_)) && - cell->getPort(ID(A)) == State::S0 && cell->getPort(ID(B)) == State::S1) { + cell->getPort(ID::A) == State::S0 && cell->getPort(ID::B) == State::S1) { cover_list("opt.opt_expr.mux_bool", "$mux", "$_MUX_", cell->type.str()); - replace_cell(assign_map, module, cell, "mux_bool", ID(Y), cell->getPort(ID(S))); + replace_cell(assign_map, module, cell, "mux_bool", ID::Y, cell->getPort(ID(S))); goto next_cell; } if (mux_bool && cell->type.in(ID($mux), ID($_MUX_)) && - cell->getPort(ID(A)) == State::S1 && cell->getPort(ID(B)) == State::S0) { + cell->getPort(ID::A) == State::S1 && cell->getPort(ID::B) == State::S0) { cover_list("opt.opt_expr.mux_invert", "$mux", "$_MUX_", cell->type.str()); log_debug("Replacing %s cell `%s' in module `%s' with inverter.\n", log_id(cell->type), log_id(cell), log_id(module)); - cell->setPort(ID(A), cell->getPort(ID(S))); - cell->unsetPort(ID(B)); + cell->setPort(ID::A, cell->getPort(ID(S))); + cell->unsetPort(ID::B); cell->unsetPort(ID(S)); if (cell->type == ID($mux)) { Const width = cell->parameters[ID(WIDTH)]; @@ -1099,10 +1099,10 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons goto next_cell; } - if (consume_x && mux_bool && cell->type.in(ID($mux), ID($_MUX_)) && cell->getPort(ID(A)) == State::S0) { + if (consume_x && mux_bool && cell->type.in(ID($mux), ID($_MUX_)) && cell->getPort(ID::A) == State::S0) { cover_list("opt.opt_expr.mux_and", "$mux", "$_MUX_", cell->type.str()); log_debug("Replacing %s cell `%s' in module `%s' with and-gate.\n", log_id(cell->type), log_id(cell), log_id(module)); - cell->setPort(ID(A), cell->getPort(ID(S))); + cell->setPort(ID::A, cell->getPort(ID(S))); cell->unsetPort(ID(S)); if (cell->type == ID($mux)) { Const width = cell->parameters[ID(WIDTH)]; @@ -1119,10 +1119,10 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons goto next_cell; } - if (consume_x && mux_bool && cell->type.in(ID($mux), ID($_MUX_)) && cell->getPort(ID(B)) == State::S1) { + if (consume_x && mux_bool && cell->type.in(ID($mux), ID($_MUX_)) && cell->getPort(ID::B) == State::S1) { cover_list("opt.opt_expr.mux_or", "$mux", "$_MUX_", cell->type.str()); log_debug("Replacing %s cell `%s' in module `%s' with or-gate.\n", log_id(cell->type), log_id(cell), log_id(module)); - cell->setPort(ID(B), cell->getPort(ID(S))); + cell->setPort(ID::B, cell->getPort(ID(S))); cell->unsetPort(ID(S)); if (cell->type == ID($mux)) { Const width = cell->parameters[ID(WIDTH)]; @@ -1141,22 +1141,22 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons if (mux_undef && cell->type.in(ID($mux), ID($pmux))) { RTLIL::SigSpec new_a, new_b, new_s; - int width = cell->getPort(ID(A)).size(); - if ((cell->getPort(ID(A)).is_fully_undef() && cell->getPort(ID(B)).is_fully_undef()) || + int width = cell->getPort(ID::A).size(); + if ((cell->getPort(ID::A).is_fully_undef() && cell->getPort(ID::B).is_fully_undef()) || cell->getPort(ID(S)).is_fully_undef()) { cover_list("opt.opt_expr.mux_undef", "$mux", "$pmux", cell->type.str()); - replace_cell(assign_map, module, cell, "mux_undef", ID(Y), cell->getPort(ID(A))); + replace_cell(assign_map, module, cell, "mux_undef", ID::Y, cell->getPort(ID::A)); goto next_cell; } for (int i = 0; i < cell->getPort(ID(S)).size(); i++) { - RTLIL::SigSpec old_b = cell->getPort(ID(B)).extract(i*width, width); + RTLIL::SigSpec old_b = cell->getPort(ID::B).extract(i*width, width); RTLIL::SigSpec old_s = cell->getPort(ID(S)).extract(i, 1); if (old_b.is_fully_undef() || old_s.is_fully_undef()) continue; new_b.append(old_b); new_s.append(old_s); } - new_a = cell->getPort(ID(A)); + new_a = cell->getPort(ID::A); if (new_a.is_fully_undef() && new_s.size() > 0) { new_a = new_b.extract((new_s.size()-1)*width, width); new_b = new_b.extract(0, (new_s.size()-1)*width); @@ -1164,20 +1164,20 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons } if (new_s.size() == 0) { cover_list("opt.opt_expr.mux_empty", "$mux", "$pmux", cell->type.str()); - replace_cell(assign_map, module, cell, "mux_empty", ID(Y), new_a); + replace_cell(assign_map, module, cell, "mux_empty", ID::Y, new_a); goto next_cell; } if (new_a == RTLIL::SigSpec(RTLIL::State::S0) && new_b == RTLIL::SigSpec(RTLIL::State::S1)) { cover_list("opt.opt_expr.mux_sel01", "$mux", "$pmux", cell->type.str()); - replace_cell(assign_map, module, cell, "mux_sel01", ID(Y), new_s); + replace_cell(assign_map, module, cell, "mux_sel01", ID::Y, new_s); goto next_cell; } if (cell->getPort(ID(S)).size() != new_s.size()) { cover_list("opt.opt_expr.mux_reduce", "$mux", "$pmux", cell->type.str()); log_debug("Optimized away %d select inputs of %s cell `%s' in module `%s'.\n", GetSize(cell->getPort(ID(S))) - GetSize(new_s), log_id(cell->type), log_id(cell), log_id(module)); - cell->setPort(ID(A), new_a); - cell->setPort(ID(B), new_b); + cell->setPort(ID::A, new_a); + cell->setPort(ID::B, new_b); cell->setPort(ID(S), new_s); if (new_s.size() > 1) { cell->type = ID($pmux); @@ -1192,7 +1192,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons #define FOLD_1ARG_CELL(_t) \ if (cell->type == "$" #_t) { \ - RTLIL::SigSpec a = cell->getPort(ID(A)); \ + RTLIL::SigSpec a = cell->getPort(ID::A); \ assign_map.apply(a); \ if (a.is_fully_const()) { \ RTLIL::Const dummy_arg(RTLIL::State::S0, 1); \ @@ -1200,14 +1200,14 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons cell->parameters[ID(A_SIGNED)].as_bool(), false, \ cell->parameters[ID(Y_WIDTH)].as_int())); \ cover("opt.opt_expr.const.$" #_t); \ - replace_cell(assign_map, module, cell, stringf("%s", log_signal(a)), ID(Y), y); \ + replace_cell(assign_map, module, cell, stringf("%s", log_signal(a)), ID::Y, y); \ goto next_cell; \ } \ } #define FOLD_2ARG_CELL(_t) \ if (cell->type == "$" #_t) { \ - RTLIL::SigSpec a = cell->getPort(ID(A)); \ - RTLIL::SigSpec b = cell->getPort(ID(B)); \ + RTLIL::SigSpec a = cell->getPort(ID::A); \ + RTLIL::SigSpec b = cell->getPort(ID::B); \ assign_map.apply(a), assign_map.apply(b); \ if (a.is_fully_const() && b.is_fully_const()) { \ RTLIL::SigSpec y(RTLIL::const_ ## _t(a.as_const(), b.as_const(), \ @@ -1215,7 +1215,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons cell->parameters[ID(B_SIGNED)].as_bool(), \ cell->parameters[ID(Y_WIDTH)].as_int())); \ cover("opt.opt_expr.const.$" #_t); \ - replace_cell(assign_map, module, cell, stringf("%s, %s", log_signal(a), log_signal(b)), ID(Y), y); \ + replace_cell(assign_map, module, cell, stringf("%s, %s", log_signal(a), log_signal(b)), ID::Y, y); \ goto next_cell; \ } \ } @@ -1263,12 +1263,12 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons // be very conservative with optimizing $mux cells as we do not want to break mux trees if (cell->type == ID($mux)) { RTLIL::SigSpec input = assign_map(cell->getPort(ID(S))); - RTLIL::SigSpec inA = assign_map(cell->getPort(ID(A))); - RTLIL::SigSpec inB = assign_map(cell->getPort(ID(B))); + RTLIL::SigSpec inA = assign_map(cell->getPort(ID::A)); + RTLIL::SigSpec inB = assign_map(cell->getPort(ID::B)); if (input.is_fully_const()) - ACTION_DO(ID(Y), input.as_bool() ? cell->getPort(ID(B)) : cell->getPort(ID(A))); + ACTION_DO(ID::Y, input.as_bool() ? cell->getPort(ID::B) : cell->getPort(ID::A)); else if (inA == inB) - ACTION_DO(ID(Y), cell->getPort(ID(A))); + ACTION_DO(ID::Y, cell->getPort(ID::A)); } if (!keepdc && cell->type == ID($mul)) @@ -1277,9 +1277,9 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons bool b_signed = cell->parameters[ID(B_SIGNED)].as_bool(); bool swapped_ab = false; - RTLIL::SigSpec sig_a = assign_map(cell->getPort(ID(A))); - RTLIL::SigSpec sig_b = assign_map(cell->getPort(ID(B))); - RTLIL::SigSpec sig_y = assign_map(cell->getPort(ID(Y))); + RTLIL::SigSpec sig_a = assign_map(cell->getPort(ID::A)); + RTLIL::SigSpec sig_b = assign_map(cell->getPort(ID::B)); + RTLIL::SigSpec sig_y = assign_map(cell->getPort(ID::Y)); if (sig_b.is_fully_const() && sig_b.size() <= 32) std::swap(sig_a, sig_b), std::swap(a_signed, b_signed), swapped_ab = true; @@ -1314,7 +1314,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons a_val, cell->name.c_str(), module->name.c_str(), i); if (!swapped_ab) { - cell->setPort(ID(A), cell->getPort(ID(B))); + cell->setPort(ID::A, cell->getPort(ID::B)); cell->parameters.at(ID(A_WIDTH)) = cell->parameters.at(ID(B_WIDTH)); cell->parameters.at(ID(A_SIGNED)) = cell->parameters.at(ID(B_SIGNED)); } @@ -1327,7 +1327,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons cell->type = ID($shl); cell->parameters[ID(B_WIDTH)] = GetSize(new_b); cell->parameters[ID(B_SIGNED)] = false; - cell->setPort(ID(B), new_b); + cell->setPort(ID::B, new_b); cell->check(); did_something = true; @@ -1339,8 +1339,8 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons if (!keepdc && cell->type.in(ID($div), ID($mod))) { bool b_signed = cell->parameters[ID(B_SIGNED)].as_bool(); - SigSpec sig_b = assign_map(cell->getPort(ID(B))); - SigSpec sig_y = assign_map(cell->getPort(ID(Y))); + SigSpec sig_b = assign_map(cell->getPort(ID::B)); + SigSpec sig_y = assign_map(cell->getPort(ID::Y)); if (sig_b.is_fully_def() && sig_b.size() <= 32) { @@ -1378,7 +1378,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons cell->type = ID($shr); cell->parameters[ID(B_WIDTH)] = GetSize(new_b); cell->parameters[ID(B_SIGNED)] = false; - cell->setPort(ID(B), new_b); + cell->setPort(ID::B, new_b); cell->check(); } else @@ -1395,7 +1395,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons cell->type = ID($and); cell->parameters[ID(B_WIDTH)] = GetSize(new_b); - cell->setPort(ID(B), new_b); + cell->setPort(ID::B, new_b); cell->check(); } @@ -1421,8 +1421,8 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons bool is_signed = cell->getParam(ID(A_SIGNED)).as_bool(); int width = is_signed ? std::min(a_width, b_width) : std::max(a_width, b_width); - SigSpec sig_a = cell->getPort(ID(A)); - SigSpec sig_b = cell->getPort(ID(B)); + SigSpec sig_a = cell->getPort(ID::A); + SigSpec sig_b = cell->getPort(ID::B); int redundant_bits = 0; @@ -1452,7 +1452,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons if (contradiction_cache.find(State::S0) == contradiction_cache.find(State::S1)) { - SigSpec y_sig = cell->getPort(ID(Y)); + SigSpec y_sig = cell->getPort(ID::Y); Const y_value(cell->type.in(ID($eq), ID($eqx)) ? 0 : 1, GetSize(y_sig)); log_debug("Replacing cell `%s' in module `%s' with constant driver %s.\n", @@ -1470,8 +1470,8 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons log_debug("Removed %d redundant input bits from %s cell `%s' in module `%s'.\n", redundant_bits, log_id(cell->type), log_id(cell), log_id(module)); - cell->setPort(ID(A), sig_a); - cell->setPort(ID(B), sig_b); + cell->setPort(ID::A, sig_a); + cell->setPort(ID::B, sig_b); cell->setParam(ID(A_WIDTH), GetSize(sig_a)); cell->setParam(ID(B_WIDTH), GetSize(sig_b)); @@ -1484,8 +1484,8 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons if (do_fine && cell->type.in(ID($lt), ID($ge), ID($gt), ID($le))) { IdString cmp_type = cell->type; - SigSpec var_sig = cell->getPort(ID(A)); - SigSpec const_sig = cell->getPort(ID(B)); + SigSpec var_sig = cell->getPort(ID::A); + SigSpec const_sig = cell->getPort(ID::B); int var_width = cell->parameters[ID(A_WIDTH)].as_int(); int const_width = cell->parameters[ID(B_WIDTH)].as_int(); bool is_signed = cell->getParam(ID(A_SIGNED)).as_bool(); @@ -1507,7 +1507,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons if (const_sig.is_fully_def() && const_sig.is_fully_const()) { std::string condition, replacement; - SigSpec replace_sig(State::S0, GetSize(cell->getPort(ID(Y)))); + SigSpec replace_sig(State::S0, GetSize(cell->getPort(ID::Y))); bool replace = false; bool remove = false; @@ -1550,14 +1550,14 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons { condition = stringf("unsigned X<%s", log_signal(const_sig)); replacement = stringf("!X[%d:%d]", var_width - 1, const_bit_hot); - module->addLogicNot(NEW_ID, var_high_sig, cell->getPort(ID(Y))); + module->addLogicNot(NEW_ID, var_high_sig, cell->getPort(ID::Y)); remove = true; } if (cmp_type == ID($ge)) { condition = stringf("unsigned X>=%s", log_signal(const_sig)); replacement = stringf("|X[%d:%d]", var_width - 1, const_bit_hot); - module->addReduceOr(NEW_ID, var_high_sig, cell->getPort(ID(Y))); + module->addReduceOr(NEW_ID, var_high_sig, cell->getPort(ID::Y)); remove = true; } } @@ -1599,7 +1599,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons { condition = "signed X>=0"; replacement = stringf("X[%d]", var_width - 1); - module->addNot(NEW_ID, var_sig[var_width - 1], cell->getPort(ID(Y))); + module->addNot(NEW_ID, var_sig[var_width - 1], cell->getPort(ID::Y)); remove = true; } } @@ -1609,7 +1609,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons log_debug("Replacing %s cell `%s' (implementing %s) with %s.\n", log_id(cell->type), log_id(cell), condition.c_str(), replacement.c_str()); if (replace) - module->connect(cell->getPort(ID(Y)), replace_sig); + module->connect(cell->getPort(ID::Y), replace_sig); module->remove(cell); did_something = true; goto next_cell; diff --git a/passes/opt/opt_lut.cc b/passes/opt/opt_lut.cc index e9d72044b..733bc547c 100644 --- a/passes/opt/opt_lut.cc +++ b/passes/opt/opt_lut.cc @@ -40,7 +40,7 @@ struct OptLutWorker bool evaluate_lut(RTLIL::Cell *lut, dict inputs) { - SigSpec lut_input = sigmap(lut->getPort(ID(A))); + SigSpec lut_input = sigmap(lut->getPort(ID::A)); int lut_width = lut->getParam(ID(WIDTH)).as_int(); Const lut_table = lut->getParam(ID(LUT)); int lut_index = 0; @@ -103,12 +103,12 @@ struct OptLutWorker { if (cell->has_keep_attr()) continue; - SigBit lut_output = cell->getPort(ID(Y)); + SigBit lut_output = cell->getPort(ID::Y); if (lut_output.wire->get_bool_attribute(ID(keep))) continue; int lut_width = cell->getParam(ID(WIDTH)).as_int(); - SigSpec lut_input = cell->getPort(ID(A)); + SigSpec lut_input = cell->getPort(ID::A); int lut_arity = 0; log_debug("Found $lut\\WIDTH=%d cell %s.%s.\n", lut_width, log_id(module), log_id(cell)); @@ -205,7 +205,7 @@ struct OptLutWorker } auto lut = worklist.pop(); - SigSpec lut_input = sigmap(lut->getPort(ID(A))); + SigSpec lut_input = sigmap(lut->getPort(ID::A)); pool &lut_dlogic_inputs = luts_dlogic_inputs[lut]; vector lut_inputs; @@ -267,7 +267,7 @@ struct OptLutWorker log_debug(" Not eliminating cell (connected to dedicated logic).\n"); else { - SigSpec lut_output = lut->getPort(ID(Y)); + SigSpec lut_output = lut->getPort(ID::Y); for (auto &port : index.query_ports(lut_output)) { if (port.cell != lut && luts.count(port.cell)) @@ -303,13 +303,13 @@ struct OptLutWorker } auto lutA = worklist.pop(); - SigSpec lutA_input = sigmap(lutA->getPort(ID(A))); - SigSpec lutA_output = sigmap(lutA->getPort(ID(Y))[0]); + SigSpec lutA_input = sigmap(lutA->getPort(ID::A)); + SigSpec lutA_output = sigmap(lutA->getPort(ID::Y)[0]); int lutA_width = lutA->getParam(ID(WIDTH)).as_int(); int lutA_arity = luts_arity[lutA]; pool &lutA_dlogic_inputs = luts_dlogic_inputs[lutA]; - auto lutA_output_ports = index.query_ports(lutA->getPort(ID(Y))); + auto lutA_output_ports = index.query_ports(lutA->getPort(ID::Y)); if (lutA_output_ports.size() != 2) continue; @@ -321,15 +321,15 @@ struct OptLutWorker if (luts.count(port.cell)) { auto lutB = port.cell; - SigSpec lutB_input = sigmap(lutB->getPort(ID(A))); - SigSpec lutB_output = sigmap(lutB->getPort(ID(Y))[0]); + SigSpec lutB_input = sigmap(lutB->getPort(ID::A)); + SigSpec lutB_output = sigmap(lutB->getPort(ID::Y)[0]); int lutB_width = lutB->getParam(ID(WIDTH)).as_int(); int lutB_arity = luts_arity[lutB]; pool &lutB_dlogic_inputs = luts_dlogic_inputs[lutB]; log_debug("Found %s.%s (cell A) feeding %s.%s (cell B).\n", log_id(module), log_id(lutA), log_id(module), log_id(lutB)); - if (index.query_is_output(lutA->getPort(ID(Y)))) + if (index.query_is_output(lutA->getPort(ID::Y))) { log_debug(" Not combining LUTs (cascade connection feeds module output).\n"); continue; @@ -441,7 +441,7 @@ struct OptLutWorker } int lutM_width = lutM->getParam(ID(WIDTH)).as_int(); - SigSpec lutM_input = sigmap(lutM->getPort(ID(A))); + SigSpec lutM_input = sigmap(lutM->getPort(ID::A)); std::vector lutM_new_inputs; for (int i = 0; i < lutM_width; i++) { @@ -487,8 +487,8 @@ struct OptLutWorker log_debug(" Merged truth table: %s.\n", lutM_new_table.as_string().c_str()); lutM->setParam(ID(LUT), lutM_new_table); - lutM->setPort(ID(A), lutM_new_inputs); - lutM->setPort(ID(Y), lutB_output); + lutM->setPort(ID::A, lutM_new_inputs); + lutM->setPort(ID::Y, lutB_output); luts_arity[lutM] = lutM_arity; luts.erase(lutR); diff --git a/passes/opt/opt_merge.cc b/passes/opt/opt_merge.cc index aa1a5c75c..aaea6159e 100644 --- a/passes/opt/opt_merge.cc +++ b/passes/opt/opt_merge.cc @@ -48,7 +48,7 @@ struct OptMergeWorker static void sort_pmux_conn(dict &conn) { SigSpec sig_s = conn.at(ID(S)); - SigSpec sig_b = conn.at(ID(B)); + SigSpec sig_b = conn.at(ID::B); int s_width = GetSize(sig_s); int width = GetSize(sig_b) / s_width; @@ -60,11 +60,11 @@ struct OptMergeWorker std::sort(sb_pairs.begin(), sb_pairs.end()); conn[ID(S)] = SigSpec(); - conn[ID(B)] = SigSpec(); + conn[ID::B] = SigSpec(); for (auto &it : sb_pairs) { conn[ID(S)].append(it.first); - conn[ID(B)].append(it.second); + conn[ID::B].append(it.second); } } @@ -97,28 +97,28 @@ struct OptMergeWorker if (cell->type.in(ID($and), ID($or), ID($xor), ID($xnor), ID($add), ID($mul), ID($logic_and), ID($logic_or), ID($_AND_), ID($_OR_), ID($_XOR_))) { alt_conn = *conn; - if (assign_map(alt_conn.at(ID(A))) < assign_map(alt_conn.at(ID(B)))) { - alt_conn[ID(A)] = conn->at(ID(B)); - alt_conn[ID(B)] = conn->at(ID(A)); + if (assign_map(alt_conn.at(ID::A)) < assign_map(alt_conn.at(ID::B))) { + alt_conn[ID::A] = conn->at(ID::B); + alt_conn[ID::B] = conn->at(ID::A); } conn = &alt_conn; } else if (cell->type.in(ID($reduce_xor), ID($reduce_xnor))) { alt_conn = *conn; - assign_map.apply(alt_conn.at(ID(A))); - alt_conn.at(ID(A)).sort(); + assign_map.apply(alt_conn.at(ID::A)); + alt_conn.at(ID::A).sort(); conn = &alt_conn; } else if (cell->type.in(ID($reduce_and), ID($reduce_or), ID($reduce_bool))) { alt_conn = *conn; - assign_map.apply(alt_conn.at(ID(A))); - alt_conn.at(ID(A)).sort_and_unify(); + assign_map.apply(alt_conn.at(ID::A)); + alt_conn.at(ID::A).sort_and_unify(); conn = &alt_conn; } else if (cell->type == ID($pmux)) { alt_conn = *conn; - assign_map.apply(alt_conn.at(ID(A))); - assign_map.apply(alt_conn.at(ID(B))); + assign_map.apply(alt_conn.at(ID::A)); + assign_map.apply(alt_conn.at(ID::B)); assign_map.apply(alt_conn.at(ID(S))); sort_pmux_conn(alt_conn); conn = &alt_conn; @@ -191,24 +191,24 @@ struct OptMergeWorker if (cell1->type == ID($and) || cell1->type == ID($or) || cell1->type == ID($xor) || cell1->type == ID($xnor) || cell1->type == ID($add) || cell1->type == ID($mul) || cell1->type == ID($logic_and) || cell1->type == ID($logic_or) || cell1->type == ID($_AND_) || cell1->type == ID($_OR_) || cell1->type == ID($_XOR_)) { - if (conn1.at(ID(A)) < conn1.at(ID(B))) { - RTLIL::SigSpec tmp = conn1[ID(A)]; - conn1[ID(A)] = conn1[ID(B)]; - conn1[ID(B)] = tmp; + if (conn1.at(ID::A) < conn1.at(ID::B)) { + RTLIL::SigSpec tmp = conn1[ID::A]; + conn1[ID::A] = conn1[ID::B]; + conn1[ID::B] = tmp; } - if (conn2.at(ID(A)) < conn2.at(ID(B))) { - RTLIL::SigSpec tmp = conn2[ID(A)]; - conn2[ID(A)] = conn2[ID(B)]; - conn2[ID(B)] = tmp; + if (conn2.at(ID::A) < conn2.at(ID::B)) { + RTLIL::SigSpec tmp = conn2[ID::A]; + conn2[ID::A] = conn2[ID::B]; + conn2[ID::B] = tmp; } } else if (cell1->type == ID($reduce_xor) || cell1->type == ID($reduce_xnor)) { - conn1[ID(A)].sort(); - conn2[ID(A)].sort(); + conn1[ID::A].sort(); + conn2[ID::A].sort(); } else if (cell1->type == ID($reduce_and) || cell1->type == ID($reduce_or) || cell1->type == ID($reduce_bool)) { - conn1[ID(A)].sort_and_unify(); - conn2[ID(A)].sort_and_unify(); + conn1[ID::A].sort_and_unify(); + conn2[ID::A].sort_and_unify(); } else if (cell1->type == ID($pmux)) { sort_pmux_conn(conn1); diff --git a/passes/opt/opt_muxtree.cc b/passes/opt/opt_muxtree.cc index 61f194569..3d7e9cccb 100644 --- a/passes/opt/opt_muxtree.cc +++ b/passes/opt/opt_muxtree.cc @@ -86,10 +86,10 @@ struct OptMuxtreeWorker { if (cell->type.in(ID($mux), ID($pmux))) { - RTLIL::SigSpec sig_a = cell->getPort(ID(A)); - RTLIL::SigSpec sig_b = cell->getPort(ID(B)); + RTLIL::SigSpec sig_a = cell->getPort(ID::A); + RTLIL::SigSpec sig_b = cell->getPort(ID::B); RTLIL::SigSpec sig_s = cell->getPort(ID(S)); - RTLIL::SigSpec sig_y = cell->getPort(ID(Y)); + RTLIL::SigSpec sig_y = cell->getPort(ID::Y); muxinfo_t muxinfo; muxinfo.cell = cell; @@ -227,10 +227,10 @@ struct OptMuxtreeWorker continue; } - RTLIL::SigSpec sig_a = mi.cell->getPort(ID(A)); - RTLIL::SigSpec sig_b = mi.cell->getPort(ID(B)); + RTLIL::SigSpec sig_a = mi.cell->getPort(ID::A); + RTLIL::SigSpec sig_b = mi.cell->getPort(ID::B); RTLIL::SigSpec sig_s = mi.cell->getPort(ID(S)); - RTLIL::SigSpec sig_y = mi.cell->getPort(ID(Y)); + RTLIL::SigSpec sig_y = mi.cell->getPort(ID::Y); RTLIL::SigSpec sig_ports = sig_b; sig_ports.append(sig_a); @@ -255,8 +255,8 @@ struct OptMuxtreeWorker } } - mi.cell->setPort(ID(A), new_sig_a); - mi.cell->setPort(ID(B), new_sig_b); + mi.cell->setPort(ID::A, new_sig_a); + mi.cell->setPort(ID::B, new_sig_b); mi.cell->setPort(ID(S), new_sig_s); if (GetSize(new_sig_s) == 1) { mi.cell->type = ID($mux); @@ -364,8 +364,8 @@ struct OptMuxtreeWorker int width = 0; idict ctrl_bits; - if (portname == ID(B)) - width = GetSize(muxinfo.cell->getPort(ID(A))); + if (portname == ID::B) + width = GetSize(muxinfo.cell->getPort(ID::A)); for (int bit : sig2bits(muxinfo.cell->getPort(ID(S)), false)) ctrl_bits(bit); @@ -414,8 +414,8 @@ struct OptMuxtreeWorker // set input ports to constants if we find known active or inactive signals if (do_replace_known) { - replace_known(knowledge, muxinfo, ID(A)); - replace_known(knowledge, muxinfo, ID(B)); + replace_known(knowledge, muxinfo, ID::A); + replace_known(knowledge, muxinfo, ID::B); } // if there is a constant activated port we just use it diff --git a/passes/opt/opt_reduce.cc b/passes/opt/opt_reduce.cc index 332e0443e..6a8d8cabd 100644 --- a/passes/opt/opt_reduce.cc +++ b/passes/opt/opt_reduce.cc @@ -43,7 +43,7 @@ struct OptReduceWorker return; cells.erase(cell); - RTLIL::SigSpec sig_a = assign_map(cell->getPort(ID(A))); + RTLIL::SigSpec sig_a = assign_map(cell->getPort(ID::A)); pool new_sig_a_bits; for (auto &bit : sig_a.to_sigbit_set()) @@ -73,8 +73,8 @@ struct OptReduceWorker for (auto child_cell : drivers.find(bit)) { if (child_cell->type == cell->type) { opt_reduce(cells, drivers, child_cell); - if (child_cell->getPort(ID(Y))[0] == bit) { - pool child_sig_a_bits = assign_map(child_cell->getPort(ID(A))).to_sigbit_pool(); + if (child_cell->getPort(ID::Y)[0] == bit) { + pool child_sig_a_bits = assign_map(child_cell->getPort(ID::A)).to_sigbit_pool(); new_sig_a_bits.insert(child_sig_a_bits.begin(), child_sig_a_bits.end()); } else new_sig_a_bits.insert(RTLIL::State::S0); @@ -87,21 +87,21 @@ struct OptReduceWorker RTLIL::SigSpec new_sig_a(new_sig_a_bits); - if (new_sig_a != sig_a || sig_a.size() != cell->getPort(ID(A)).size()) { + if (new_sig_a != sig_a || sig_a.size() != cell->getPort(ID::A).size()) { log(" New input vector for %s cell %s: %s\n", cell->type.c_str(), cell->name.c_str(), log_signal(new_sig_a)); did_something = true; total_count++; } - cell->setPort(ID(A), new_sig_a); + cell->setPort(ID::A, new_sig_a); cell->parameters[ID(A_WIDTH)] = RTLIL::Const(new_sig_a.size()); return; } void opt_mux(RTLIL::Cell *cell) { - RTLIL::SigSpec sig_a = assign_map(cell->getPort(ID(A))); - RTLIL::SigSpec sig_b = assign_map(cell->getPort(ID(B))); + RTLIL::SigSpec sig_a = assign_map(cell->getPort(ID::A)); + RTLIL::SigSpec sig_b = assign_map(cell->getPort(ID::B)); RTLIL::SigSpec sig_s = assign_map(cell->getPort(ID(S))); RTLIL::SigSpec new_sig_b, new_sig_s; @@ -124,14 +124,14 @@ struct OptReduceWorker if (this_s.size() > 1) { RTLIL::Cell *reduce_or_cell = module->addCell(NEW_ID, ID($reduce_or)); - reduce_or_cell->setPort(ID(A), this_s); + reduce_or_cell->setPort(ID::A, this_s); reduce_or_cell->parameters[ID(A_SIGNED)] = RTLIL::Const(0); reduce_or_cell->parameters[ID(A_WIDTH)] = RTLIL::Const(this_s.size()); reduce_or_cell->parameters[ID(Y_WIDTH)] = RTLIL::Const(1); RTLIL::Wire *reduce_or_wire = module->addWire(NEW_ID); this_s = RTLIL::SigSpec(reduce_or_wire); - reduce_or_cell->setPort(ID(Y), this_s); + reduce_or_cell->setPort(ID::Y, this_s); } new_sig_b.append(this_b); @@ -147,13 +147,13 @@ struct OptReduceWorker if (new_sig_s.size() == 0) { - module->connect(RTLIL::SigSig(cell->getPort(ID(Y)), cell->getPort(ID(A)))); - assign_map.add(cell->getPort(ID(Y)), cell->getPort(ID(A))); + module->connect(RTLIL::SigSig(cell->getPort(ID::Y), cell->getPort(ID::A))); + assign_map.add(cell->getPort(ID::Y), cell->getPort(ID::A)); module->remove(cell); } else { - cell->setPort(ID(B), new_sig_b); + cell->setPort(ID::B, new_sig_b); cell->setPort(ID(S), new_sig_s); if (new_sig_s.size() > 1) { cell->parameters[ID(S_WIDTH)] = RTLIL::Const(new_sig_s.size()); @@ -166,9 +166,9 @@ struct OptReduceWorker void opt_mux_bits(RTLIL::Cell *cell) { - std::vector sig_a = assign_map(cell->getPort(ID(A))).to_sigbit_vector(); - std::vector sig_b = assign_map(cell->getPort(ID(B))).to_sigbit_vector(); - std::vector sig_y = assign_map(cell->getPort(ID(Y))).to_sigbit_vector(); + std::vector sig_a = assign_map(cell->getPort(ID::A)).to_sigbit_vector(); + std::vector sig_b = assign_map(cell->getPort(ID::B)).to_sigbit_vector(); + std::vector sig_y = assign_map(cell->getPort(ID::Y)).to_sigbit_vector(); std::vector new_sig_y; RTLIL::SigSig old_sig_conn; @@ -209,29 +209,29 @@ struct OptReduceWorker if (new_sig_y.size() != sig_y.size()) { log(" Consolidated identical input bits for %s cell %s:\n", cell->type.c_str(), cell->name.c_str()); - log(" Old ports: A=%s, B=%s, Y=%s\n", log_signal(cell->getPort(ID(A))), - log_signal(cell->getPort(ID(B))), log_signal(cell->getPort(ID(Y)))); + log(" Old ports: A=%s, B=%s, Y=%s\n", log_signal(cell->getPort(ID::A)), + log_signal(cell->getPort(ID::B)), log_signal(cell->getPort(ID::Y))); - cell->setPort(ID(A), RTLIL::SigSpec()); + cell->setPort(ID::A, RTLIL::SigSpec()); for (auto &in_tuple : consolidated_in_tuples) { - RTLIL::SigSpec new_a = cell->getPort(ID(A)); + RTLIL::SigSpec new_a = cell->getPort(ID::A); new_a.append(in_tuple.at(0)); - cell->setPort(ID(A), new_a); + cell->setPort(ID::A, new_a); } - cell->setPort(ID(B), RTLIL::SigSpec()); + cell->setPort(ID::B, RTLIL::SigSpec()); for (int i = 1; i <= cell->getPort(ID(S)).size(); i++) for (auto &in_tuple : consolidated_in_tuples) { - RTLIL::SigSpec new_b = cell->getPort(ID(B)); + RTLIL::SigSpec new_b = cell->getPort(ID::B); new_b.append(in_tuple.at(i)); - cell->setPort(ID(B), new_b); + cell->setPort(ID::B, new_b); } cell->parameters[ID(WIDTH)] = RTLIL::Const(new_sig_y.size()); - cell->setPort(ID(Y), new_sig_y); + cell->setPort(ID::Y, new_sig_y); - log(" New ports: A=%s, B=%s, Y=%s\n", log_signal(cell->getPort(ID(A))), - log_signal(cell->getPort(ID(B))), log_signal(cell->getPort(ID(Y)))); + log(" New ports: A=%s, B=%s, Y=%s\n", log_signal(cell->getPort(ID::A)), + log_signal(cell->getPort(ID::B)), log_signal(cell->getPort(ID::Y))); log(" New connections: %s = %s\n", log_signal(old_sig_conn.first), log_signal(old_sig_conn.second)); module->connect(old_sig_conn); @@ -269,12 +269,12 @@ struct OptReduceWorker keep_expanding_mem_wren_sigs = false; for (auto &cell_it : module->cells_) { RTLIL::Cell *cell = cell_it.second; - if (cell->type == ID($mux) && mem_wren_sigs.check_any(assign_map(cell->getPort(ID(Y))))) { - if (!mem_wren_sigs.check_all(assign_map(cell->getPort(ID(A)))) || - !mem_wren_sigs.check_all(assign_map(cell->getPort(ID(B))))) + if (cell->type == ID($mux) && mem_wren_sigs.check_any(assign_map(cell->getPort(ID::Y)))) { + if (!mem_wren_sigs.check_all(assign_map(cell->getPort(ID::A))) || + !mem_wren_sigs.check_all(assign_map(cell->getPort(ID::B)))) keep_expanding_mem_wren_sigs = true; - mem_wren_sigs.add(assign_map(cell->getPort(ID(A)))); - mem_wren_sigs.add(assign_map(cell->getPort(ID(B)))); + mem_wren_sigs.add(assign_map(cell->getPort(ID::A))); + mem_wren_sigs.add(assign_map(cell->getPort(ID::B))); } } } @@ -296,7 +296,7 @@ struct OptReduceWorker RTLIL::Cell *cell = cell_it.second; if (cell->type != type || !design->selected(module, cell)) continue; - drivers.insert(assign_map(cell->getPort(ID(Y))), cell); + drivers.insert(assign_map(cell->getPort(ID::Y)), cell); cells.insert(cell); } @@ -318,7 +318,7 @@ struct OptReduceWorker { // this optimization is to aggressive for most coarse-grain applications. // but we always want it for multiplexers driving write enable ports. - if (do_fine || mem_wren_sigs.check_any(assign_map(cell->getPort(ID(Y))))) + if (do_fine || mem_wren_sigs.check_any(assign_map(cell->getPort(ID::Y)))) opt_mux_bits(cell); opt_mux(cell); diff --git a/passes/opt/opt_rmdff.cc b/passes/opt/opt_rmdff.cc index 4ba61e512..0bf74098a 100644 --- a/passes/opt/opt_rmdff.cc +++ b/passes/opt/opt_rmdff.cc @@ -347,8 +347,8 @@ bool handle_dff(RTLIL::Module *mod, RTLIL::Cell *dff) std::set muxes; mux_drivers.find(sig_d, muxes); for (auto mux : muxes) { - RTLIL::SigSpec sig_a = assign_map(mux->getPort(ID(A))); - RTLIL::SigSpec sig_b = assign_map(mux->getPort(ID(B))); + RTLIL::SigSpec sig_a = assign_map(mux->getPort(ID::A)); + RTLIL::SigSpec sig_b = assign_map(mux->getPort(ID::B)); if (sig_a == sig_q && sig_b.is_fully_const() && (!has_init || val_init == sig_b.as_const())) { mod->connect(sig_q, sig_b); goto delete_dff; @@ -625,8 +625,8 @@ struct OptRmdffPass : public Pass { } if (cell->type.in(ID($mux), ID($pmux))) { - if (cell->getPort(ID(A)).size() == cell->getPort(ID(B)).size()) - mux_drivers.insert(assign_map(cell->getPort(ID(Y))), cell); + if (cell->getPort(ID::A).size() == cell->getPort(ID::B).size()) + mux_drivers.insert(assign_map(cell->getPort(ID::Y)), cell); continue; } diff --git a/passes/opt/pmux2shiftx.cc b/passes/opt/pmux2shiftx.cc index 3e34bfbbd..92b5794ac 100644 --- a/passes/opt/pmux2shiftx.cc +++ b/passes/opt/pmux2shiftx.cc @@ -73,9 +73,9 @@ struct OnehotDatabase if (cell->type.in(ID($mux), ID($pmux))) { - output = cell->getPort(ID(Y)); - inputs.push_back(cell->getPort(ID(A))); - SigSpec B = cell->getPort(ID(B)); + output = cell->getPort(ID::Y); + inputs.push_back(cell->getPort(ID::A)); + SigSpec B = cell->getPort(ID::B); for (int i = 0; i < GetSize(B); i += GetSize(output)) inputs.push_back(B.extract(i, GetSize(output))); } @@ -296,8 +296,8 @@ struct Pmux2ShiftxPass : public Pass { { dict bits; - SigSpec A = sigmap(cell->getPort(ID(A))); - SigSpec B = sigmap(cell->getPort(ID(B))); + SigSpec A = sigmap(cell->getPort(ID::A)); + SigSpec B = sigmap(cell->getPort(ID::B)); int a_width = cell->getParam(ID(A_WIDTH)).as_int(); int b_width = cell->getParam(ID(B_WIDTH)).as_int(); @@ -335,7 +335,7 @@ struct Pmux2ShiftxPass : public Pass { entry.second.bits.push_back(it.second); } - eqdb[sigmap(cell->getPort(ID(Y))[0])] = entry; + eqdb[sigmap(cell->getPort(ID::Y)[0])] = entry; goto next_cell; } @@ -343,7 +343,7 @@ struct Pmux2ShiftxPass : public Pass { { dict bits; - SigSpec A = sigmap(cell->getPort(ID(A))); + SigSpec A = sigmap(cell->getPort(ID::A)); for (int i = 0; i < GetSize(A); i++) bits[A[i]] = State::S0; @@ -356,7 +356,7 @@ struct Pmux2ShiftxPass : public Pass { entry.second.bits.push_back(it.second); } - eqdb[sigmap(cell->getPort(ID(Y))[0])] = entry; + eqdb[sigmap(cell->getPort(ID::Y)[0])] = entry; goto next_cell; } next_cell:; @@ -377,8 +377,8 @@ struct Pmux2ShiftxPass : public Pass { dict> seldb; - SigSpec A = cell->getPort(ID(A)); - SigSpec B = cell->getPort(ID(B)); + SigSpec A = cell->getPort(ID::A); + SigSpec B = cell->getPort(ID::B); SigSpec S = sigmap(cell->getPort(ID(S))); for (int i = 0; i < GetSize(S); i++) { @@ -401,7 +401,7 @@ struct Pmux2ShiftxPass : public Pass { } SigSpec updated_S = cell->getPort(ID(S)); - SigSpec updated_B = cell->getPort(ID(B)); + SigSpec updated_B = cell->getPort(ID::B); while (!seldb.empty()) { @@ -728,7 +728,7 @@ struct Pmux2ShiftxPass : public Pass { // update $pmux cell cell->setPort(ID(S), updated_S); - cell->setPort(ID(B), updated_B); + cell->setPort(ID::B, updated_B); cell->setParam(ID(S_WIDTH), GetSize(updated_S)); } } @@ -782,8 +782,8 @@ struct OnehotPass : public Pass { if (cell->type != ID($eq)) continue; - SigSpec A = sigmap(cell->getPort(ID(A))); - SigSpec B = sigmap(cell->getPort(ID(B))); + SigSpec A = sigmap(cell->getPort(ID::A)); + SigSpec B = sigmap(cell->getPort(ID::B)); int a_width = cell->getParam(ID(A_WIDTH)).as_int(); int b_width = cell->getParam(ID(B_WIDTH)).as_int(); @@ -830,7 +830,7 @@ struct OnehotPass : public Pass { continue; } - SigSpec Y = cell->getPort(ID(Y)); + SigSpec Y = cell->getPort(ID::Y); if (not_onehot) { diff --git a/passes/opt/share.cc b/passes/opt/share.cc index 84290bb97..92ce3fd11 100644 --- a/passes/opt/share.cc +++ b/passes/opt/share.cc @@ -128,7 +128,7 @@ struct ShareWorker static int bits_macc(RTLIL::Cell *c) { Macc m(c); - int width = GetSize(c->getPort(ID(Y))); + int width = GetSize(c->getPort(ID::Y)); return bits_macc(m, width); } @@ -242,7 +242,7 @@ struct ShareWorker { Macc m1(c1), m2(c2), supermacc; - int w1 = GetSize(c1->getPort(ID(Y))), w2 = GetSize(c2->getPort(ID(Y))); + int w1 = GetSize(c1->getPort(ID::Y)), w2 = GetSize(c2->getPort(ID::Y)); int width = max(w1, w2); m1.optimize(w1); @@ -328,11 +328,11 @@ struct ShareWorker { RTLIL::SigSpec sig_y = module->addWire(NEW_ID, width); - supercell_aux->insert(module->addPos(NEW_ID, sig_y, c1->getPort(ID(Y)))); - supercell_aux->insert(module->addPos(NEW_ID, sig_y, c2->getPort(ID(Y)))); + supercell_aux->insert(module->addPos(NEW_ID, sig_y, c1->getPort(ID::Y))); + supercell_aux->insert(module->addPos(NEW_ID, sig_y, c2->getPort(ID::Y))); supercell->setParam(ID(Y_WIDTH), width); - supercell->setPort(ID(Y), sig_y); + supercell->setPort(ID::Y, sig_y); supermacc.optimize(width); supermacc.to_cell(supercell); @@ -513,11 +513,11 @@ struct ShareWorker if (c1->parameters.at(ID(A_SIGNED)).as_bool() != c2->parameters.at(ID(A_SIGNED)).as_bool()) { RTLIL::Cell *unsigned_cell = c1->parameters.at(ID(A_SIGNED)).as_bool() ? c2 : c1; - if (unsigned_cell->getPort(ID(A)).to_sigbit_vector().back() != RTLIL::State::S0) { + if (unsigned_cell->getPort(ID::A).to_sigbit_vector().back() != RTLIL::State::S0) { unsigned_cell->parameters.at(ID(A_WIDTH)) = unsigned_cell->parameters.at(ID(A_WIDTH)).as_int() + 1; - RTLIL::SigSpec new_a = unsigned_cell->getPort(ID(A)); + RTLIL::SigSpec new_a = unsigned_cell->getPort(ID::A); new_a.append_bit(RTLIL::State::S0); - unsigned_cell->setPort(ID(A), new_a); + unsigned_cell->setPort(ID::A, new_a); } unsigned_cell->parameters.at(ID(A_SIGNED)) = true; unsigned_cell->check(); @@ -526,11 +526,11 @@ struct ShareWorker bool a_signed = c1->parameters.at(ID(A_SIGNED)).as_bool(); log_assert(a_signed == c2->parameters.at(ID(A_SIGNED)).as_bool()); - RTLIL::SigSpec a1 = c1->getPort(ID(A)); - RTLIL::SigSpec y1 = c1->getPort(ID(Y)); + RTLIL::SigSpec a1 = c1->getPort(ID::A); + RTLIL::SigSpec y1 = c1->getPort(ID::Y); - RTLIL::SigSpec a2 = c2->getPort(ID(A)); - RTLIL::SigSpec y2 = c2->getPort(ID(Y)); + RTLIL::SigSpec a2 = c2->getPort(ID::A); + RTLIL::SigSpec y2 = c2->getPort(ID::Y); int a_width = max(a1.size(), a2.size()); int y_width = max(y1.size(), y2.size()); @@ -547,8 +547,8 @@ struct ShareWorker supercell->parameters[ID(A_SIGNED)] = a_signed; supercell->parameters[ID(A_WIDTH)] = a_width; supercell->parameters[ID(Y_WIDTH)] = y_width; - supercell->setPort(ID(A), a); - supercell->setPort(ID(Y), y); + supercell->setPort(ID::A, a); + supercell->setPort(ID::Y, y); supercell_aux.insert(module->addPos(NEW_ID, y, y1)); supercell_aux.insert(module->addPos(NEW_ID, y, y2)); @@ -571,9 +571,9 @@ struct ShareWorker if (score_flipped < score_unflipped) { - RTLIL::SigSpec tmp = c2->getPort(ID(A)); - c2->setPort(ID(A), c2->getPort(ID(B))); - c2->setPort(ID(B), tmp); + RTLIL::SigSpec tmp = c2->getPort(ID::A); + c2->setPort(ID::A, c2->getPort(ID::B)); + c2->setPort(ID::B, tmp); std::swap(c2->parameters.at(ID(A_WIDTH)), c2->parameters.at(ID(B_WIDTH))); std::swap(c2->parameters.at(ID(A_SIGNED)), c2->parameters.at(ID(B_SIGNED))); @@ -585,11 +585,11 @@ struct ShareWorker { RTLIL::Cell *unsigned_cell = c1->parameters.at(ID(A_SIGNED)).as_bool() ? c2 : c1; - if (unsigned_cell->getPort(ID(A)).to_sigbit_vector().back() != RTLIL::State::S0) { + if (unsigned_cell->getPort(ID::A).to_sigbit_vector().back() != RTLIL::State::S0) { unsigned_cell->parameters.at(ID(A_WIDTH)) = unsigned_cell->parameters.at(ID(A_WIDTH)).as_int() + 1; - RTLIL::SigSpec new_a = unsigned_cell->getPort(ID(A)); + RTLIL::SigSpec new_a = unsigned_cell->getPort(ID::A); new_a.append_bit(RTLIL::State::S0); - unsigned_cell->setPort(ID(A), new_a); + unsigned_cell->setPort(ID::A, new_a); } unsigned_cell->parameters.at(ID(A_SIGNED)) = true; modified_src_cells = true; @@ -598,11 +598,11 @@ struct ShareWorker if (c1->parameters.at(ID(B_SIGNED)).as_bool() != c2->parameters.at(ID(B_SIGNED)).as_bool()) { RTLIL::Cell *unsigned_cell = c1->parameters.at(ID(B_SIGNED)).as_bool() ? c2 : c1; - if (unsigned_cell->getPort(ID(B)).to_sigbit_vector().back() != RTLIL::State::S0) { + if (unsigned_cell->getPort(ID::B).to_sigbit_vector().back() != RTLIL::State::S0) { unsigned_cell->parameters.at(ID(B_WIDTH)) = unsigned_cell->parameters.at(ID(B_WIDTH)).as_int() + 1; - RTLIL::SigSpec new_b = unsigned_cell->getPort(ID(B)); + RTLIL::SigSpec new_b = unsigned_cell->getPort(ID::B); new_b.append_bit(RTLIL::State::S0); - unsigned_cell->setPort(ID(B), new_b); + unsigned_cell->setPort(ID::B, new_b); } unsigned_cell->parameters.at(ID(B_SIGNED)) = true; modified_src_cells = true; @@ -622,13 +622,13 @@ struct ShareWorker if (c1->type == ID($shl) || c1->type == ID($shr) || c1->type == ID($sshl) || c1->type == ID($sshr)) b_signed = false; - RTLIL::SigSpec a1 = c1->getPort(ID(A)); - RTLIL::SigSpec b1 = c1->getPort(ID(B)); - RTLIL::SigSpec y1 = c1->getPort(ID(Y)); + RTLIL::SigSpec a1 = c1->getPort(ID::A); + RTLIL::SigSpec b1 = c1->getPort(ID::B); + RTLIL::SigSpec y1 = c1->getPort(ID::Y); - RTLIL::SigSpec a2 = c2->getPort(ID(A)); - RTLIL::SigSpec b2 = c2->getPort(ID(B)); - RTLIL::SigSpec y2 = c2->getPort(ID(Y)); + RTLIL::SigSpec a2 = c2->getPort(ID::A); + RTLIL::SigSpec b2 = c2->getPort(ID::B); + RTLIL::SigSpec y2 = c2->getPort(ID::Y); int a_width = max(a1.size(), a2.size()); int b_width = max(b1.size(), b2.size()); @@ -669,9 +669,9 @@ struct ShareWorker supercell->parameters[ID(A_WIDTH)] = a_width; supercell->parameters[ID(B_WIDTH)] = b_width; supercell->parameters[ID(Y_WIDTH)] = y_width; - supercell->setPort(ID(A), a); - supercell->setPort(ID(B), b); - supercell->setPort(ID(Y), y); + supercell->setPort(ID::A, a); + supercell->setPort(ID::B, b); + supercell->setPort(ID::Y, y); if (c1->type == ID($alu)) { RTLIL::Wire *ci = module->addWire(NEW_ID), *bi = module->addWire(NEW_ID); supercell_aux.insert(module->addMux(NEW_ID, c2->getPort(ID(CI)), c1->getPort(ID(CI)), act, ci)); @@ -874,7 +874,7 @@ struct ShareWorker } for (auto &pbit : modwalker.signal_consumers[bit]) { log_assert(fwd_ct.cell_known(pbit.cell->type)); - if ((pbit.cell->type == ID($mux) || pbit.cell->type == ID($pmux)) && (pbit.port == ID(A) || pbit.port == ID(B))) + if ((pbit.cell->type == ID($mux) || pbit.cell->type == ID($pmux)) && (pbit.port == ID::A || pbit.port == ID::B)) driven_data_muxes.insert(pbit.cell); else driven_cells.insert(pbit.cell); @@ -891,8 +891,8 @@ struct ShareWorker std::set used_in_b_parts; int width = c->parameters.at(ID(WIDTH)).as_int(); - std::vector sig_a = modwalker.sigmap(c->getPort(ID(A))); - std::vector sig_b = modwalker.sigmap(c->getPort(ID(B))); + std::vector sig_a = modwalker.sigmap(c->getPort(ID::A)); + std::vector sig_b = modwalker.sigmap(c->getPort(ID::B)); std::vector sig_s = modwalker.sigmap(c->getPort(ID(S))); for (auto &bit : sig_a) diff --git a/passes/opt/wreduce.cc b/passes/opt/wreduce.cc index ca0be54d2..792c69c55 100644 --- a/passes/opt/wreduce.cc +++ b/passes/opt/wreduce.cc @@ -64,10 +64,10 @@ struct WreduceWorker { // Reduce size of MUX if inputs agree on a value for a bit or a output bit is unused - SigSpec sig_a = mi.sigmap(cell->getPort(ID(A))); - SigSpec sig_b = mi.sigmap(cell->getPort(ID(B))); + SigSpec sig_a = mi.sigmap(cell->getPort(ID::A)); + SigSpec sig_b = mi.sigmap(cell->getPort(ID::B)); SigSpec sig_s = mi.sigmap(cell->getPort(ID(S))); - SigSpec sig_y = mi.sigmap(cell->getPort(ID(Y))); + SigSpec sig_y = mi.sigmap(cell->getPort(ID::Y)); std::vector bits_removed; if (sig_y.has_const()) @@ -130,9 +130,9 @@ struct WreduceWorker for (auto bit : new_work_queue_bits) work_queue_bits.insert(bit); - cell->setPort(ID(A), new_sig_a); - cell->setPort(ID(B), new_sig_b); - cell->setPort(ID(Y), new_sig_y); + cell->setPort(ID::A, new_sig_a); + cell->setPort(ID::B, new_sig_b); + cell->setPort(ID::Y, new_sig_y); cell->fixup_parameters(); module->connect(sig_y.extract(n_kept, n_removed), sig_removed); @@ -270,7 +270,7 @@ struct WreduceWorker if (cell->type.in(ID($dff), ID($adff))) return run_cell_dff(cell); - SigSpec sig = mi.sigmap(cell->getPort(ID(Y))); + SigSpec sig = mi.sigmap(cell->getPort(ID::Y)); if (sig.has_const()) return; @@ -278,8 +278,8 @@ struct WreduceWorker // Reduce size of ports A and B based on constant input bits and size of output port - int max_port_a_size = cell->hasPort(ID(A)) ? GetSize(cell->getPort(ID(A))) : -1; - int max_port_b_size = cell->hasPort(ID(B)) ? GetSize(cell->getPort(ID(B))) : -1; + int max_port_a_size = cell->hasPort(ID::A) ? GetSize(cell->getPort(ID::A)) : -1; + int max_port_b_size = cell->hasPort(ID::B) ? GetSize(cell->getPort(ID::B)) : -1; if (cell->type.in(ID($not), ID($pos), ID($neg), ID($and), ID($or), ID($xor), ID($add), ID($sub))) { max_port_a_size = min(max_port_a_size, GetSize(sig)); @@ -295,8 +295,8 @@ struct WreduceWorker if (max_port_b_size >= 0) run_reduce_inport(cell, 'B', max_port_b_size, port_b_signed, did_something); - if (cell->hasPort(ID(A)) && cell->hasPort(ID(B)) && port_a_signed && port_b_signed) { - SigSpec sig_a = mi.sigmap(cell->getPort(ID(A))), sig_b = mi.sigmap(cell->getPort(ID(B))); + if (cell->hasPort(ID::A) && cell->hasPort(ID::B) && port_a_signed && port_b_signed) { + SigSpec sig_a = mi.sigmap(cell->getPort(ID::A)), sig_b = mi.sigmap(cell->getPort(ID::B)); if (GetSize(sig_a) > 0 && sig_a[GetSize(sig_a)-1] == State::S0 && GetSize(sig_b) > 0 && sig_b[GetSize(sig_b)-1] == State::S0) { log("Converting cell %s.%s (%s) from signed to unsigned.\n", @@ -309,8 +309,8 @@ struct WreduceWorker } } - if (cell->hasPort(ID(A)) && !cell->hasPort(ID(B)) && port_a_signed) { - SigSpec sig_a = mi.sigmap(cell->getPort(ID(A))); + if (cell->hasPort(ID::A) && !cell->hasPort(ID::B) && port_a_signed) { + SigSpec sig_a = mi.sigmap(cell->getPort(ID::A)); if (GetSize(sig_a) > 0 && sig_a[GetSize(sig_a)-1] == State::S0) { log("Converting cell %s.%s (%s) from signed to unsigned.\n", log_id(module), log_id(cell), log_id(cell->type)); @@ -347,8 +347,8 @@ struct WreduceWorker bool is_signed = cell->getParam(ID(A_SIGNED)).as_bool() || cell->type == ID($sub); int a_size = 0, b_size = 0; - if (cell->hasPort(ID(A))) a_size = GetSize(cell->getPort(ID(A))); - if (cell->hasPort(ID(B))) b_size = GetSize(cell->getPort(ID(B))); + if (cell->hasPort(ID::A)) a_size = GetSize(cell->getPort(ID::A)); + if (cell->hasPort(ID::B)) b_size = GetSize(cell->getPort(ID::B)); int max_y_size = max(a_size, b_size); @@ -374,7 +374,7 @@ struct WreduceWorker if (bits_removed) { log("Removed top %d bits (of %d) from port Y of cell %s.%s (%s).\n", bits_removed, GetSize(sig) + bits_removed, log_id(module), log_id(cell), log_id(cell->type)); - cell->setPort(ID(Y), sig); + cell->setPort(ID::Y, sig); did_something = true; } @@ -530,10 +530,10 @@ struct WreducePass : public Pass { { if (c->type.in(ID($reduce_and), ID($reduce_or), ID($reduce_xor), ID($reduce_xnor), ID($reduce_bool), ID($lt), ID($le), ID($eq), ID($ne), ID($eqx), ID($nex), ID($ge), ID($gt), - ID($logic_not), ID($logic_and), ID($logic_or)) && GetSize(c->getPort(ID(Y))) > 1) { - SigSpec sig = c->getPort(ID(Y)); + ID($logic_not), ID($logic_and), ID($logic_or)) && GetSize(c->getPort(ID::Y)) > 1) { + SigSpec sig = c->getPort(ID::Y); if (!sig.has_const()) { - c->setPort(ID(Y), sig[0]); + c->setPort(ID::Y, sig[0]); c->setParam(ID(Y_WIDTH), 1); sig.remove(0); module->connect(sig, Const(0, GetSize(sig))); @@ -542,7 +542,7 @@ struct WreducePass : public Pass { if (c->type.in(ID($div), ID($mod), ID($pow))) { - SigSpec A = c->getPort(ID(A)); + SigSpec A = c->getPort(ID::A); int original_a_width = GetSize(A); if (c->getParam(ID(A_SIGNED)).as_bool()) { while (GetSize(A) > 1 && A[GetSize(A)-1] == State::S0 && A[GetSize(A)-2] == State::S0) @@ -554,11 +554,11 @@ struct WreducePass : public Pass { if (original_a_width != GetSize(A)) { log("Removed top %d bits (of %d) from port A of cell %s.%s (%s).\n", original_a_width-GetSize(A), original_a_width, log_id(module), log_id(c), log_id(c->type)); - c->setPort(ID(A), A); + c->setPort(ID::A, A); c->setParam(ID(A_WIDTH), GetSize(A)); } - SigSpec B = c->getPort(ID(B)); + SigSpec B = c->getPort(ID::B); int original_b_width = GetSize(B); if (c->getParam(ID(B_SIGNED)).as_bool()) { while (GetSize(B) > 1 && B[GetSize(B)-1] == State::S0 && B[GetSize(B)-2] == State::S0) @@ -570,7 +570,7 @@ struct WreducePass : public Pass { if (original_b_width != GetSize(B)) { log("Removed top %d bits (of %d) from port B of cell %s.%s (%s).\n", original_b_width-GetSize(B), original_b_width, log_id(module), log_id(c), log_id(c->type)); - c->setPort(ID(B), B); + c->setPort(ID::B, B); c->setParam(ID(B_WIDTH), GetSize(B)); } } diff --git a/passes/techmap/abc.cc b/passes/techmap/abc.cc index 20ebc73c8..205f05ab9 100644 --- a/passes/techmap/abc.cc +++ b/passes/techmap/abc.cc @@ -211,8 +211,8 @@ void extract_cell(RTLIL::Cell *cell, bool keepff) if (cell->type.in(ID($_BUF_), ID($_NOT_))) { - RTLIL::SigSpec sig_a = cell->getPort(ID(A)); - RTLIL::SigSpec sig_y = cell->getPort(ID(Y)); + RTLIL::SigSpec sig_a = cell->getPort(ID::A); + RTLIL::SigSpec sig_y = cell->getPort(ID::Y); assign_map.apply(sig_a); assign_map.apply(sig_y); @@ -225,9 +225,9 @@ void extract_cell(RTLIL::Cell *cell, bool keepff) if (cell->type.in(ID($_AND_), ID($_NAND_), ID($_OR_), ID($_NOR_), ID($_XOR_), ID($_XNOR_), ID($_ANDNOT_), ID($_ORNOT_))) { - RTLIL::SigSpec sig_a = cell->getPort(ID(A)); - RTLIL::SigSpec sig_b = cell->getPort(ID(B)); - RTLIL::SigSpec sig_y = cell->getPort(ID(Y)); + RTLIL::SigSpec sig_a = cell->getPort(ID::A); + RTLIL::SigSpec sig_b = cell->getPort(ID::B); + RTLIL::SigSpec sig_y = cell->getPort(ID::Y); assign_map.apply(sig_a); assign_map.apply(sig_b); @@ -261,10 +261,10 @@ void extract_cell(RTLIL::Cell *cell, bool keepff) if (cell->type.in(ID($_MUX_), ID($_NMUX_))) { - RTLIL::SigSpec sig_a = cell->getPort(ID(A)); - RTLIL::SigSpec sig_b = cell->getPort(ID(B)); + RTLIL::SigSpec sig_a = cell->getPort(ID::A); + RTLIL::SigSpec sig_b = cell->getPort(ID::B); RTLIL::SigSpec sig_s = cell->getPort(ID(S)); - RTLIL::SigSpec sig_y = cell->getPort(ID(Y)); + RTLIL::SigSpec sig_y = cell->getPort(ID::Y); assign_map.apply(sig_a); assign_map.apply(sig_b); @@ -283,10 +283,10 @@ void extract_cell(RTLIL::Cell *cell, bool keepff) if (cell->type.in(ID($_AOI3_), ID($_OAI3_))) { - RTLIL::SigSpec sig_a = cell->getPort(ID(A)); - RTLIL::SigSpec sig_b = cell->getPort(ID(B)); + RTLIL::SigSpec sig_a = cell->getPort(ID::A); + RTLIL::SigSpec sig_b = cell->getPort(ID::B); RTLIL::SigSpec sig_c = cell->getPort(ID(C)); - RTLIL::SigSpec sig_y = cell->getPort(ID(Y)); + RTLIL::SigSpec sig_y = cell->getPort(ID::Y); assign_map.apply(sig_a); assign_map.apply(sig_b); @@ -305,11 +305,11 @@ void extract_cell(RTLIL::Cell *cell, bool keepff) if (cell->type.in(ID($_AOI4_), ID($_OAI4_))) { - RTLIL::SigSpec sig_a = cell->getPort(ID(A)); - RTLIL::SigSpec sig_b = cell->getPort(ID(B)); + RTLIL::SigSpec sig_a = cell->getPort(ID::A); + RTLIL::SigSpec sig_b = cell->getPort(ID::B); RTLIL::SigSpec sig_c = cell->getPort(ID(C)); RTLIL::SigSpec sig_d = cell->getPort(ID(D)); - RTLIL::SigSpec sig_y = cell->getPort(ID(Y)); + RTLIL::SigSpec sig_y = cell->getPort(ID::Y); assign_map.apply(sig_a); assign_map.apply(sig_b); @@ -1042,63 +1042,63 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin cell_stats[RTLIL::unescape_id(c->type)]++; if (c->type.in(ID(ZERO), ID(ONE))) { RTLIL::SigSig conn; - conn.first = RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(Y)).as_wire()->name)]); + conn.first = RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::Y).as_wire()->name)]); conn.second = RTLIL::SigSpec(c->type == ID(ZERO) ? 0 : 1, 1); module->connect(conn); continue; } if (c->type == ID(BUF)) { RTLIL::SigSig conn; - conn.first = RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(Y)).as_wire()->name)]); - conn.second = RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(A)).as_wire()->name)]); + conn.first = RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::Y).as_wire()->name)]); + conn.second = RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::A).as_wire()->name)]); module->connect(conn); continue; } if (c->type == ID(NOT)) { RTLIL::Cell *cell = module->addCell(remap_name(c->name), ID($_NOT_)); if (markgroups) cell->attributes[ID(abcgroup)] = map_autoidx; - cell->setPort(ID(A), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(A)).as_wire()->name)])); - cell->setPort(ID(Y), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(Y)).as_wire()->name)])); + cell->setPort(ID::A, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::A).as_wire()->name)])); + cell->setPort(ID::Y, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::Y).as_wire()->name)])); design->select(module, cell); continue; } if (c->type.in(ID(AND), ID(OR), ID(XOR), ID(NAND), ID(NOR), ID(XNOR), ID(ANDNOT), ID(ORNOT))) { RTLIL::Cell *cell = module->addCell(remap_name(c->name), stringf("$_%s_", c->type.c_str()+1)); if (markgroups) cell->attributes[ID(abcgroup)] = map_autoidx; - cell->setPort(ID(A), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(A)).as_wire()->name)])); - cell->setPort(ID(B), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(B)).as_wire()->name)])); - cell->setPort(ID(Y), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(Y)).as_wire()->name)])); + cell->setPort(ID::A, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::A).as_wire()->name)])); + cell->setPort(ID::B, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::B).as_wire()->name)])); + cell->setPort(ID::Y, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::Y).as_wire()->name)])); design->select(module, cell); continue; } if (c->type.in(ID(MUX), ID(NMUX))) { RTLIL::Cell *cell = module->addCell(remap_name(c->name), stringf("$_%s_", c->type.c_str()+1)); if (markgroups) cell->attributes[ID(abcgroup)] = map_autoidx; - cell->setPort(ID(A), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(A)).as_wire()->name)])); - cell->setPort(ID(B), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(B)).as_wire()->name)])); + cell->setPort(ID::A, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::A).as_wire()->name)])); + cell->setPort(ID::B, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::B).as_wire()->name)])); cell->setPort(ID(S), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(S)).as_wire()->name)])); - cell->setPort(ID(Y), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(Y)).as_wire()->name)])); + cell->setPort(ID::Y, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::Y).as_wire()->name)])); design->select(module, cell); continue; } if (c->type == ID(MUX4)) { RTLIL::Cell *cell = module->addCell(remap_name(c->name), ID($_MUX4_)); if (markgroups) cell->attributes[ID(abcgroup)] = map_autoidx; - cell->setPort(ID(A), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(A)).as_wire()->name)])); - cell->setPort(ID(B), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(B)).as_wire()->name)])); + cell->setPort(ID::A, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::A).as_wire()->name)])); + cell->setPort(ID::B, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::B).as_wire()->name)])); cell->setPort(ID(C), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(C)).as_wire()->name)])); cell->setPort(ID(D), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(D)).as_wire()->name)])); cell->setPort(ID(S), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(S)).as_wire()->name)])); cell->setPort(ID(T), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(T)).as_wire()->name)])); - cell->setPort(ID(Y), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(Y)).as_wire()->name)])); + cell->setPort(ID::Y, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::Y).as_wire()->name)])); design->select(module, cell); continue; } if (c->type == ID(MUX8)) { RTLIL::Cell *cell = module->addCell(remap_name(c->name), ID($_MUX8_)); if (markgroups) cell->attributes[ID(abcgroup)] = map_autoidx; - cell->setPort(ID(A), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(A)).as_wire()->name)])); - cell->setPort(ID(B), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(B)).as_wire()->name)])); + cell->setPort(ID::A, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::A).as_wire()->name)])); + cell->setPort(ID::B, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::B).as_wire()->name)])); cell->setPort(ID(C), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(C)).as_wire()->name)])); cell->setPort(ID(D), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(D)).as_wire()->name)])); cell->setPort(ID(E), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(E)).as_wire()->name)])); @@ -1108,15 +1108,15 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin cell->setPort(ID(S), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(S)).as_wire()->name)])); cell->setPort(ID(T), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(T)).as_wire()->name)])); cell->setPort(ID(U), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(U)).as_wire()->name)])); - cell->setPort(ID(Y), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(Y)).as_wire()->name)])); + cell->setPort(ID::Y, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::Y).as_wire()->name)])); design->select(module, cell); continue; } if (c->type == ID(MUX16)) { RTLIL::Cell *cell = module->addCell(remap_name(c->name), ID($_MUX16_)); if (markgroups) cell->attributes[ID(abcgroup)] = map_autoidx; - cell->setPort(ID(A), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(A)).as_wire()->name)])); - cell->setPort(ID(B), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(B)).as_wire()->name)])); + cell->setPort(ID::A, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::A).as_wire()->name)])); + cell->setPort(ID::B, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::B).as_wire()->name)])); cell->setPort(ID(C), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(C)).as_wire()->name)])); cell->setPort(ID(D), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(D)).as_wire()->name)])); cell->setPort(ID(E), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(E)).as_wire()->name)])); @@ -1135,28 +1135,28 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin cell->setPort(ID(T), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(T)).as_wire()->name)])); cell->setPort(ID(U), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(U)).as_wire()->name)])); cell->setPort(ID(V), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(V)).as_wire()->name)])); - cell->setPort(ID(Y), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(Y)).as_wire()->name)])); + cell->setPort(ID::Y, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::Y).as_wire()->name)])); design->select(module, cell); continue; } if (c->type.in(ID(AOI3), ID(OAI3))) { RTLIL::Cell *cell = module->addCell(remap_name(c->name), stringf("$_%s_", c->type.c_str()+1)); if (markgroups) cell->attributes[ID(abcgroup)] = map_autoidx; - cell->setPort(ID(A), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(A)).as_wire()->name)])); - cell->setPort(ID(B), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(B)).as_wire()->name)])); + cell->setPort(ID::A, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::A).as_wire()->name)])); + cell->setPort(ID::B, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::B).as_wire()->name)])); cell->setPort(ID(C), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(C)).as_wire()->name)])); - cell->setPort(ID(Y), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(Y)).as_wire()->name)])); + cell->setPort(ID::Y, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::Y).as_wire()->name)])); design->select(module, cell); continue; } if (c->type.in(ID(AOI4), ID(OAI4))) { RTLIL::Cell *cell = module->addCell(remap_name(c->name), stringf("$_%s_", c->type.c_str()+1)); if (markgroups) cell->attributes[ID(abcgroup)] = map_autoidx; - cell->setPort(ID(A), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(A)).as_wire()->name)])); - cell->setPort(ID(B), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(B)).as_wire()->name)])); + cell->setPort(ID::A, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::A).as_wire()->name)])); + cell->setPort(ID::B, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::B).as_wire()->name)])); cell->setPort(ID(C), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(C)).as_wire()->name)])); cell->setPort(ID(D), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(D)).as_wire()->name)])); - cell->setPort(ID(Y), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(Y)).as_wire()->name)])); + cell->setPort(ID::Y, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::Y).as_wire()->name)])); design->select(module, cell); continue; } @@ -1207,9 +1207,9 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin continue; } - if (c->type == ID($lut) && GetSize(c->getPort(ID(A))) == 1 && c->getParam(ID(LUT)).as_int() == 2) { - SigSpec my_a = module->wires_[remap_name(c->getPort(ID(A)).as_wire()->name)]; - SigSpec my_y = module->wires_[remap_name(c->getPort(ID(Y)).as_wire()->name)]; + if (c->type == ID($lut) && GetSize(c->getPort(ID::A)) == 1 && c->getParam(ID(LUT)).as_int() == 2) { + SigSpec my_a = module->wires_[remap_name(c->getPort(ID::A).as_wire()->name)]; + SigSpec my_y = module->wires_[remap_name(c->getPort(ID::Y).as_wire()->name)]; module->connect(my_y, my_a); continue; } diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 752535f34..b3de7cdc5 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -582,13 +582,13 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri RTLIL::Cell *cell = nullptr; if (c->type == ID($_NOT_)) { - RTLIL::SigBit a_bit = c->getPort(ID(A)); - RTLIL::SigBit y_bit = c->getPort(ID(Y)); + RTLIL::SigBit a_bit = c->getPort(ID::A); + RTLIL::SigBit y_bit = c->getPort(ID::Y); bit_users[a_bit].insert(c->name); bit_drivers[y_bit].insert(c->name); if (!a_bit.wire) { - c->setPort(ID(Y), module->addWire(NEW_ID)); + c->setPort(ID::Y, module->addWire(NEW_ID)); RTLIL::Wire *wire = module->wire(remap_name(y_bit.wire->name)); log_assert(wire); module->connect(RTLIL::SigBit(wire, y_bit.offset), State::S1); @@ -616,7 +616,7 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri RTLIL::SigBit(module->wires_.at(remap_name(a_bit.wire->name)), a_bit.offset), RTLIL::SigBit(module->wires_.at(remap_name(y_bit.wire->name)), y_bit.offset), RTLIL::Const::from_string("01")); - bit2sinks[cell->getPort(ID(A))].push_back(cell); + bit2sinks[cell->getPort(ID::A)].push_back(cell); cell_stats[ID($lut)]++; } else @@ -632,9 +632,9 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri RTLIL::Cell *existing_cell = nullptr; if (c->type == ID($lut)) { - if (GetSize(c->getPort(ID(A))) == 1 && c->getParam(ID(LUT)) == RTLIL::Const::from_string("01")) { - SigSpec my_a = module->wires_.at(remap_name(c->getPort(ID(A)).as_wire()->name)); - SigSpec my_y = module->wires_.at(remap_name(c->getPort(ID(Y)).as_wire()->name)); + if (GetSize(c->getPort(ID::A)) == 1 && c->getParam(ID(LUT)) == RTLIL::Const::from_string("01")) { + SigSpec my_a = module->wires_.at(remap_name(c->getPort(ID::A).as_wire()->name)); + SigSpec my_y = module->wires_.at(remap_name(c->getPort(ID::Y).as_wire()->name)); module->connect(my_y, my_a); if (markgroups) c->attributes[ID(abcgroup)] = map_autoidx; log_abort(); @@ -751,8 +751,8 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri if (it == not2drivers.end()) continue; RTLIL::Cell *driver_lut = it->second; - RTLIL::SigBit a_bit = not_cell->getPort(ID(A)); - RTLIL::SigBit y_bit = not_cell->getPort(ID(Y)); + RTLIL::SigBit a_bit = not_cell->getPort(ID::A); + RTLIL::SigBit y_bit = not_cell->getPort(ID::Y); RTLIL::Const driver_mask; a_bit.wire = module->wires_.at(remap_name(a_bit.wire->name)); @@ -768,7 +768,7 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri // Push downstream LUTs past inverter for (auto sink_cell : jt->second) { - SigSpec A = sink_cell->getPort(ID(A)); + SigSpec A = sink_cell->getPort(ID::A); RTLIL::Const mask = sink_cell->getParam(ID(LUT)); int index = 0; for (; index < GetSize(A); index++) @@ -782,7 +782,7 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri i += 1 << (index+1); } A[index] = y_bit; - sink_cell->setPort(ID(A), A); + sink_cell->setPort(ID::A, A); sink_cell->setParam(ID(LUT), mask); } @@ -798,10 +798,10 @@ clone_lut: else if (b == RTLIL::State::S1) b = RTLIL::State::S0; } auto cell = module->addLut(NEW_ID, - driver_lut->getPort(ID(A)), + driver_lut->getPort(ID::A), y_bit, driver_mask); - for (auto &bit : cell->connections_.at(ID(A))) { + for (auto &bit : cell->connections_.at(ID::A)) { bit.wire = module->wires_.at(remap_name(bit.wire->name)); bit2sinks[bit].push_back(cell); } diff --git a/passes/techmap/alumacc.cc b/passes/techmap/alumacc.cc index 58ed47ccf..5b168d524 100644 --- a/passes/techmap/alumacc.cc +++ b/passes/techmap/alumacc.cc @@ -91,7 +91,7 @@ struct AlumaccWorker RTLIL::SigSpec get_sf() { if (GetSize(cached_sf) == 0) { - cached_sf = alu_cell->getPort(ID(Y)); + cached_sf = alu_cell->getPort(ID::Y); cached_sf = cached_sf[GetSize(cached_sf)-1]; } return cached_sf; @@ -134,7 +134,7 @@ struct AlumaccWorker Macc::port_t new_port; n->cell = cell; - n->y = sigmap(cell->getPort(ID(Y))); + n->y = sigmap(cell->getPort(ID::Y)); n->users = 0; for (auto bit : n->y) @@ -142,7 +142,7 @@ struct AlumaccWorker if (cell->type.in(ID($pos), ID($neg))) { - new_port.in_a = sigmap(cell->getPort(ID(A))); + new_port.in_a = sigmap(cell->getPort(ID::A)); new_port.is_signed = cell->getParam(ID(A_SIGNED)).as_bool(); new_port.do_subtract = cell->type == ID($neg); n->macc.ports.push_back(new_port); @@ -150,12 +150,12 @@ struct AlumaccWorker if (cell->type.in(ID($add), ID($sub))) { - new_port.in_a = sigmap(cell->getPort(ID(A))); + new_port.in_a = sigmap(cell->getPort(ID::A)); new_port.is_signed = cell->getParam(ID(A_SIGNED)).as_bool(); new_port.do_subtract = false; n->macc.ports.push_back(new_port); - new_port.in_a = sigmap(cell->getPort(ID(B))); + new_port.in_a = sigmap(cell->getPort(ID::B)); new_port.is_signed = cell->getParam(ID(B_SIGNED)).as_bool(); new_port.do_subtract = cell->type == ID($sub); n->macc.ports.push_back(new_port); @@ -163,8 +163,8 @@ struct AlumaccWorker if (cell->type.in(ID($mul))) { - new_port.in_a = sigmap(cell->getPort(ID(A))); - new_port.in_b = sigmap(cell->getPort(ID(B))); + new_port.in_a = sigmap(cell->getPort(ID::A)); + new_port.in_b = sigmap(cell->getPort(ID::B)); new_port.is_signed = cell->getParam(ID(A_SIGNED)).as_bool(); new_port.do_subtract = false; n->macc.ports.push_back(new_port); @@ -361,7 +361,7 @@ struct AlumaccWorker n->macc.optimize(GetSize(n->y)); n->macc.to_cell(cell); - cell->setPort(ID(Y), n->y); + cell->setPort(ID::Y, n->y); cell->fixup_parameters(); module->remove(n->cell); delete n; @@ -390,9 +390,9 @@ struct AlumaccWorker bool cmp_equal = cell->type.in(ID($le), ID($ge)); bool is_signed = cell->getParam(ID(A_SIGNED)).as_bool(); - RTLIL::SigSpec A = sigmap(cell->getPort(ID(A))); - RTLIL::SigSpec B = sigmap(cell->getPort(ID(B))); - RTLIL::SigSpec Y = sigmap(cell->getPort(ID(Y))); + RTLIL::SigSpec A = sigmap(cell->getPort(ID::A)); + RTLIL::SigSpec B = sigmap(cell->getPort(ID::B)); + RTLIL::SigSpec Y = sigmap(cell->getPort(ID::Y)); if (B < A && GetSize(B)) { cmp_less = !cmp_less; @@ -430,9 +430,9 @@ struct AlumaccWorker bool cmp_equal = cell->type.in(ID($eq), ID($eqx)); bool is_signed = cell->getParam(ID(A_SIGNED)).as_bool(); - RTLIL::SigSpec A = sigmap(cell->getPort(ID(A))); - RTLIL::SigSpec B = sigmap(cell->getPort(ID(B))); - RTLIL::SigSpec Y = sigmap(cell->getPort(ID(Y))); + RTLIL::SigSpec A = sigmap(cell->getPort(ID::A)); + RTLIL::SigSpec B = sigmap(cell->getPort(ID::B)); + RTLIL::SigSpec Y = sigmap(cell->getPort(ID::Y)); if (B < A && GetSize(B)) std::swap(A, B); @@ -482,11 +482,11 @@ struct AlumaccWorker if (n->cells.size() > 0) n->alu_cell->set_src_attribute(n->cells[0]->get_src_attribute()); - n->alu_cell->setPort(ID(A), n->a); - n->alu_cell->setPort(ID(B), n->b); + n->alu_cell->setPort(ID::A, n->a); + n->alu_cell->setPort(ID::B, n->b); n->alu_cell->setPort(ID(CI), GetSize(n->c) ? n->c : State::S0); n->alu_cell->setPort(ID(BI), n->invert_b ? State::S1 : State::S0); - n->alu_cell->setPort(ID(Y), n->y); + n->alu_cell->setPort(ID::Y, n->y); n->alu_cell->setPort(ID(X), module->addWire(NEW_ID, GetSize(n->y))); n->alu_cell->setPort(ID(CO), module->addWire(NEW_ID, GetSize(n->y))); n->alu_cell->fixup_parameters(n->is_signed, n->is_signed); diff --git a/passes/techmap/deminout.cc b/passes/techmap/deminout.cc index 585732e6b..b976b401b 100644 --- a/passes/techmap/deminout.cc +++ b/passes/techmap/deminout.cc @@ -83,13 +83,13 @@ struct DeminoutPass : public Pass { for (auto bit : sigmap(conn.second)) bits_used.insert(bit); - if (conn.first == ID(Y) && cell->type.in(ID($mux), ID($pmux), ID($_MUX_), ID($_TBUF_), ID($tribuf))) + if (conn.first == ID::Y && cell->type.in(ID($mux), ID($pmux), ID($_MUX_), ID($_TBUF_), ID($tribuf))) { bool tribuf = cell->type.in(ID($_TBUF_), ID($tribuf)); if (!tribuf) { for (auto &c : cell->connections()) { - if (!c.first.in(ID(A), ID(B))) + if (!c.first.in(ID::A, ID::B)) continue; for (auto b : sigmap(c.second)) if (b == State::Sz) diff --git a/passes/techmap/dff2dffe.cc b/passes/techmap/dff2dffe.cc index 24760420a..e766f2cf6 100644 --- a/passes/techmap/dff2dffe.cc +++ b/passes/techmap/dff2dffe.cc @@ -53,7 +53,7 @@ struct Dff2dffeWorker for (auto cell : module->cells()) { if (cell->type.in(ID($mux), ID($pmux), ID($_MUX_))) { - RTLIL::SigSpec sig_y = sigmap(cell->getPort(ID(Y))); + RTLIL::SigSpec sig_y = sigmap(cell->getPort(ID::Y)); for (int i = 0; i < GetSize(sig_y); i++) bit2mux[sig_y[i]] = cell_int_t(cell, i); } @@ -86,8 +86,8 @@ struct Dff2dffeWorker return ret; cell_int_t mux_cell_int = bit2mux.at(d); - RTLIL::SigSpec sig_a = sigmap(mux_cell_int.first->getPort(ID(A))); - RTLIL::SigSpec sig_b = sigmap(mux_cell_int.first->getPort(ID(B))); + RTLIL::SigSpec sig_a = sigmap(mux_cell_int.first->getPort(ID::A)); + RTLIL::SigSpec sig_b = sigmap(mux_cell_int.first->getPort(ID::B)); RTLIL::SigSpec sig_s = sigmap(mux_cell_int.first->getPort(ID(S))); int width = GetSize(sig_a), index = mux_cell_int.second; @@ -97,9 +97,9 @@ struct Dff2dffeWorker ret = find_muxtree_feedback_patterns(sig_b[i*width + index], q, path); if (sig_b[i*width + index] == q) { - RTLIL::SigSpec s = mux_cell_int.first->getPort(ID(B)); + RTLIL::SigSpec s = mux_cell_int.first->getPort(ID::B); s[i*width + index] = RTLIL::Sx; - mux_cell_int.first->setPort(ID(B), s); + mux_cell_int.first->setPort(ID::B, s); } return ret; @@ -120,9 +120,9 @@ struct Dff2dffeWorker ret.insert(pat); if (sig_b[i*width + index] == q) { - RTLIL::SigSpec s = mux_cell_int.first->getPort(ID(B)); + RTLIL::SigSpec s = mux_cell_int.first->getPort(ID::B); s[i*width + index] = RTLIL::Sx; - mux_cell_int.first->setPort(ID(B), s); + mux_cell_int.first->setPort(ID::B, s); } } @@ -130,9 +130,9 @@ struct Dff2dffeWorker ret.insert(pat); if (sig_a[index] == q) { - RTLIL::SigSpec s = mux_cell_int.first->getPort(ID(A)); + RTLIL::SigSpec s = mux_cell_int.first->getPort(ID::A); s[index] = RTLIL::Sx; - mux_cell_int.first->setPort(ID(A), s); + mux_cell_int.first->setPort(ID::A, s); } return ret; diff --git a/passes/techmap/dff2dffs.cc b/passes/techmap/dff2dffs.cc index f74001b77..0ea033513 100644 --- a/passes/techmap/dff2dffs.cc +++ b/passes/techmap/dff2dffs.cc @@ -72,11 +72,11 @@ struct Dff2dffsPass : public Pass { if (cell->type != ID($_MUX_)) continue; - SigBit bit_a = sigmap(cell->getPort(ID(A))); - SigBit bit_b = sigmap(cell->getPort(ID(B))); + SigBit bit_a = sigmap(cell->getPort(ID::A)); + SigBit bit_b = sigmap(cell->getPort(ID::B)); if (bit_a.wire == nullptr || bit_b.wire == nullptr) - sr_muxes[sigmap(cell->getPort(ID(Y)))] = cell; + sr_muxes[sigmap(cell->getPort(ID::Y))] = cell; } for (auto cell : ff_cells) @@ -92,8 +92,8 @@ struct Dff2dffsPass : public Pass { continue; Cell *mux_cell = sr_muxes.at(bit_d); - SigBit bit_a = sigmap(mux_cell->getPort(ID(A))); - SigBit bit_b = sigmap(mux_cell->getPort(ID(B))); + SigBit bit_a = sigmap(mux_cell->getPort(ID::A)); + SigBit bit_b = sigmap(mux_cell->getPort(ID::B)); SigBit bit_s = sigmap(mux_cell->getPort(ID(S))); log(" Merging %s (A=%s, B=%s, S=%s) into %s (%s).\n", log_id(mux_cell), diff --git a/passes/techmap/dfflibmap.cc b/passes/techmap/dfflibmap.cc index c62224f9d..8a378068e 100644 --- a/passes/techmap/dfflibmap.cc +++ b/passes/techmap/dfflibmap.cc @@ -485,7 +485,7 @@ static void dfflibmap(RTLIL::Design *design, RTLIL::Module *module, bool prepare if (design->selected(module, it.second) && cell_mappings.count(it.second->type) > 0) cell_list.push_back(it.second); if (it.second->type == ID($_NOT_)) - notmap[sigmap(it.second->getPort(ID(A)))].insert(it.second); + notmap[sigmap(it.second->getPort(ID::A))].insert(it.second); } std::map stats; @@ -519,8 +519,8 @@ static void dfflibmap(RTLIL::Design *design, RTLIL::Module *module, bool prepare sig = module->addWire(NEW_ID, GetSize(old_sig)); if (has_q && has_qn) { for (auto &it : notmap[sigmap(old_sig)]) { - module->connect(it->getPort(ID(Y)), sig); - it->setPort(ID(Y), module->addWire(NEW_ID, GetSize(old_sig))); + module->connect(it->getPort(ID::Y), sig); + it->setPort(ID::Y, module->addWire(NEW_ID, GetSize(old_sig))); } } else { module->addNotGate(NEW_ID, sig, old_sig); diff --git a/passes/techmap/extract_counter.cc b/passes/techmap/extract_counter.cc index 2e50bb7b3..17a99493d 100644 --- a/passes/techmap/extract_counter.cc +++ b/passes/techmap/extract_counter.cc @@ -138,7 +138,7 @@ int counter_tryextract( //To be a counter, one input of the ALU must be a constant 1 //TODO: can A or B be swapped in synthesized RTL or is B always the 1? - const RTLIL::SigSpec b_port = sigmap(cell->getPort(ID(B))); + const RTLIL::SigSpec b_port = sigmap(cell->getPort(ID::B)); if(!b_port.is_fully_const() || (b_port.as_int() != 1) ) return 4; @@ -158,7 +158,7 @@ int counter_tryextract( //Y must have exactly one connection, and it has to be a $mux cell. //We must have a direct bus connection from our Y to their A. - const RTLIL::SigSpec aluy = sigmap(cell->getPort(ID(Y))); + const RTLIL::SigSpec aluy = sigmap(cell->getPort(ID::Y)); pool y_loads = get_other_cells(aluy, index, cell); if(y_loads.size() != 1) return 9; @@ -166,11 +166,11 @@ int counter_tryextract( extract.count_mux = count_mux; if(count_mux->type != ID($mux)) return 10; - if(!is_full_bus(aluy, index, cell, ID(Y), count_mux, ID(A))) + if(!is_full_bus(aluy, index, cell, ID::Y, count_mux, ID::A)) return 11; //B connection of the mux is our underflow value - const RTLIL::SigSpec underflow = sigmap(count_mux->getPort(ID(B))); + const RTLIL::SigSpec underflow = sigmap(count_mux->getPort(ID::B)); if(!underflow.is_fully_const()) return 12; extract.count_value = underflow.as_int(); @@ -184,7 +184,7 @@ int counter_tryextract( { if(c->type != ID($logic_not)) continue; - if(!is_full_bus(muxsel, index, c, ID(Y), count_mux, ID(S), true)) + if(!is_full_bus(muxsel, index, c, ID::Y, count_mux, ID(S), true)) continue; underflow_inv = c; @@ -196,7 +196,7 @@ int counter_tryextract( //Y connection of the mux must have exactly one load, the counter's internal register, if there's no clock enable //If we have a clock enable, Y drives the B input of a mux. A of that mux must come from our register - const RTLIL::SigSpec muxy = sigmap(count_mux->getPort(ID(Y))); + const RTLIL::SigSpec muxy = sigmap(count_mux->getPort(ID::Y)); pool muxy_loads = get_other_cells(muxy, index, count_mux); if(muxy_loads.size() != 1) return 14; @@ -209,7 +209,7 @@ int counter_tryextract( //This mux is probably a clock enable mux. //Find our count register (should be our only load) cemux = muxload; - cey = sigmap(cemux->getPort(ID(Y))); + cey = sigmap(cemux->getPort(ID::Y)); pool cey_loads = get_other_cells(cey, index, cemux); if(cey_loads.size() != 1) return 24; @@ -217,11 +217,11 @@ int counter_tryextract( //Mux should have A driven by count Q, and B by muxy //TODO: if A and B are swapped, CE polarity is inverted - if(sigmap(cemux->getPort(ID(B))) != muxy) + if(sigmap(cemux->getPort(ID::B)) != muxy) return 24; - if(sigmap(cemux->getPort(ID(A))) != sigmap(count_reg->getPort(ID(Q)))) + if(sigmap(cemux->getPort(ID::A)) != sigmap(count_reg->getPort(ID(Q)))) return 24; - if(sigmap(cemux->getPort(ID(Y))) != sigmap(count_reg->getPort(ID(D)))) + if(sigmap(cemux->getPort(ID::Y)) != sigmap(count_reg->getPort(ID(D)))) return 24; //Select of the mux is our clock enable @@ -260,12 +260,12 @@ int counter_tryextract( //Sanity check that we use the ALU output properly if(extract.has_ce) { - if(!is_full_bus(muxy, index, count_mux, ID(Y), cemux, ID(B))) + if(!is_full_bus(muxy, index, count_mux, ID::Y, cemux, ID::B)) return 16; - if(!is_full_bus(cey, index, cemux, ID(Y), count_reg, ID(D))) + if(!is_full_bus(cey, index, cemux, ID::Y, count_reg, ID(D))) return 16; } - else if(!is_full_bus(muxy, index, count_mux, ID(Y), count_reg, ID(D))) + else if(!is_full_bus(muxy, index, count_mux, ID::Y, count_reg, ID(D))) return 16; //TODO: Verify count_reg CLK_POLARITY is 1 @@ -312,9 +312,9 @@ int counter_tryextract( } } } - if(!is_full_bus(cnout, index, count_reg, ID(Q), underflow_inv, ID(A), true)) + if(!is_full_bus(cnout, index, count_reg, ID(Q), underflow_inv, ID::A, true)) return 18; - if(!is_full_bus(cnout, index, count_reg, ID(Q), cell, ID(A), true)) + if(!is_full_bus(cnout, index, count_reg, ID(Q), cell, ID::A, true)) return 19; //Look up the clock from the register @@ -348,7 +348,7 @@ void counter_worker( //A input is the count value. Check if it has COUNT_EXTRACT set. //If it's not a wire, don't even try - auto port = sigmap(cell->getPort(ID(A))); + auto port = sigmap(cell->getPort(ID::A)); if(!port.is_wire()) return; RTLIL::Wire* a_wire = port.as_wire(); @@ -434,13 +434,13 @@ void counter_worker( string countname = string("$COUNTx$") + log_id(extract.rwire->name.str()); //Wipe all of the old connections to the ALU - cell->unsetPort(ID(A)); - cell->unsetPort(ID(B)); + cell->unsetPort(ID::A); + cell->unsetPort(ID::B); cell->unsetPort(ID(BI)); cell->unsetPort(ID(CI)); cell->unsetPort(ID(CO)); cell->unsetPort(ID(X)); - cell->unsetPort(ID(Y)); + cell->unsetPort(ID::Y); cell->unsetParam(ID(A_SIGNED)); cell->unsetParam(ID(A_WIDTH)); cell->unsetParam(ID(B_SIGNED)); diff --git a/passes/techmap/extract_fa.cc b/passes/techmap/extract_fa.cc index ff3de1272..29700c37b 100644 --- a/passes/techmap/extract_fa.cc +++ b/passes/techmap/extract_fa.cc @@ -89,7 +89,7 @@ struct ExtractFaWorker ID($_XOR_), ID($_XNOR_), ID($_ANDNOT_), ID($_ORNOT_), ID($_MUX_), ID($_NMUX_), ID($_AOI3_), ID($_OAI3_), ID($_AOI4_), ID($_OAI4_))) { - SigBit y = sigmap(SigBit(cell->getPort(ID(Y)))); + SigBit y = sigmap(SigBit(cell->getPort(ID::Y))); log_assert(driver.count(y) == 0); driver[y] = cell; } @@ -262,8 +262,8 @@ struct ExtractFaWorker pool new_leaves = leaves; new_leaves.erase(bit); - if (cell->hasPort(ID(A))) new_leaves.insert(sigmap(SigBit(cell->getPort(ID(A))))); - if (cell->hasPort(ID(B))) new_leaves.insert(sigmap(SigBit(cell->getPort(ID(B))))); + if (cell->hasPort(ID::A)) new_leaves.insert(sigmap(SigBit(cell->getPort(ID::A)))); + if (cell->hasPort(ID::B)) new_leaves.insert(sigmap(SigBit(cell->getPort(ID::B)))); if (cell->hasPort(ID(C))) new_leaves.insert(sigmap(SigBit(cell->getPort(ID(C))))); if (cell->hasPort(ID(D))) new_leaves.insert(sigmap(SigBit(cell->getPort(ID(D))))); @@ -277,8 +277,8 @@ struct ExtractFaWorker void assign_new_driver(SigBit bit, SigBit new_driver) { Cell *cell = driver.at(bit); - if (sigmap(cell->getPort(ID(Y))) == bit) { - cell->setPort(ID(Y), module->addWire(NEW_ID)); + if (sigmap(cell->getPort(ID::Y)) == bit) { + cell->setPort(ID::Y, module->addWire(NEW_ID)); module->connect(bit, new_driver); } } @@ -395,15 +395,15 @@ struct ExtractFaWorker log(" Created $fa cell %s.\n", log_id(cell)); - cell->setPort(ID(A), f3i.inv_a ? module->NotGate(NEW_ID, A) : A); - cell->setPort(ID(B), f3i.inv_b ? module->NotGate(NEW_ID, B) : B); + cell->setPort(ID::A, f3i.inv_a ? module->NotGate(NEW_ID, A) : A); + cell->setPort(ID::B, f3i.inv_b ? module->NotGate(NEW_ID, B) : B); cell->setPort(ID(C), f3i.inv_c ? module->NotGate(NEW_ID, C) : C); X = module->addWire(NEW_ID); Y = module->addWire(NEW_ID); cell->setPort(ID(X), X); - cell->setPort(ID(Y), Y); + cell->setPort(ID::Y, Y); facache[fakey] = make_tuple(X, Y, cell); } @@ -501,15 +501,15 @@ struct ExtractFaWorker log(" Created $fa cell %s.\n", log_id(cell)); - cell->setPort(ID(A), f2i.inv_a ? module->NotGate(NEW_ID, A) : A); - cell->setPort(ID(B), f2i.inv_b ? module->NotGate(NEW_ID, B) : B); + cell->setPort(ID::A, f2i.inv_a ? module->NotGate(NEW_ID, A) : A); + cell->setPort(ID::B, f2i.inv_b ? module->NotGate(NEW_ID, B) : B); cell->setPort(ID(C), State::S0); X = module->addWire(NEW_ID); Y = module->addWire(NEW_ID); cell->setPort(ID(X), X); - cell->setPort(ID(Y), Y); + cell->setPort(ID::Y, Y); } if (func2.at(key).count(xor2_func)) { diff --git a/passes/techmap/extract_reduce.cc b/passes/techmap/extract_reduce.cc index 2ce111b4f..11cfddcd9 100644 --- a/passes/techmap/extract_reduce.cc +++ b/passes/techmap/extract_reduce.cc @@ -148,7 +148,7 @@ struct ExtractReducePass : public Pass head_cell = x; - auto y = sigmap(x->getPort(ID(Y))); + auto y = sigmap(x->getPort(ID::Y)); log_assert(y.size() == 1); // Should only continue if there is one fanout back into a cell (not to a port) @@ -166,7 +166,7 @@ struct ExtractReducePass : public Pass { //BFS, following all chains until they hit a cell of a different type //Pick the longest one - auto y = sigmap(cell->getPort(ID(Y))); + auto y = sigmap(cell->getPort(ID::Y)); pool current_loads = sig_to_sink[y]; pool next_loads; @@ -233,7 +233,7 @@ struct ExtractReducePass : public Pass cur_supercell.insert(x); - auto a = sigmap(x->getPort(ID(A))); + auto a = sigmap(x->getPort(ID::A)); log_assert(a.size() == 1); // Must have only one sink unless we're going off chain @@ -249,7 +249,7 @@ struct ExtractReducePass : public Pass } } - auto b = sigmap(x->getPort(ID(B))); + auto b = sigmap(x->getPort(ID::B)); log_assert(b.size() == 1); // Must have only one sink @@ -279,16 +279,16 @@ struct ExtractReducePass : public Pass pool input_pool_intermed; for (auto x : cur_supercell) { - input_pool.insert(sigmap(x->getPort(ID(A)))[0]); - input_pool.insert(sigmap(x->getPort(ID(B)))[0]); - input_pool_intermed.insert(sigmap(x->getPort(ID(Y)))[0]); + input_pool.insert(sigmap(x->getPort(ID::A))[0]); + input_pool.insert(sigmap(x->getPort(ID::B))[0]); + input_pool_intermed.insert(sigmap(x->getPort(ID::Y))[0]); } SigSpec input; for (auto b : input_pool) if (input_pool_intermed.count(b) == 0) input.append_bit(b); - SigBit output = sigmap(head_cell->getPort(ID(Y))[0]); + SigBit output = sigmap(head_cell->getPort(ID::Y)[0]); auto new_reduce_cell = module->addCell(NEW_ID, gt == GateType::And ? ID($reduce_and) : @@ -297,8 +297,8 @@ struct ExtractReducePass : public Pass new_reduce_cell->setParam(ID(A_SIGNED), 0); new_reduce_cell->setParam(ID(A_WIDTH), input.size()); new_reduce_cell->setParam(ID(Y_WIDTH), 1); - new_reduce_cell->setPort(ID(A), input); - new_reduce_cell->setPort(ID(Y), output); + new_reduce_cell->setPort(ID::A, input); + new_reduce_cell->setPort(ID::Y, output); if(allow_off_chain) consumed_cells.insert(head_cell); diff --git a/passes/techmap/iopadmap.cc b/passes/techmap/iopadmap.cc index 726fcb905..898cb77a4 100644 --- a/passes/techmap/iopadmap.cc +++ b/passes/techmap/iopadmap.cc @@ -180,7 +180,7 @@ struct IopadmapPass : public Pass { for (auto cell : module->cells()) if (cell->type == ID($_TBUF_)) { - SigBit bit = sigmap(cell->getPort(ID(Y)).as_bit()); + SigBit bit = sigmap(cell->getPort(ID::Y).as_bit()); tbuf_bits[bit].first = cell->name; } @@ -213,7 +213,7 @@ struct IopadmapPass : public Pass { continue; SigBit en_sig = tbuf_cell->getPort(ID(E)).as_bit(); - SigBit data_sig = tbuf_cell->getPort(ID(A)).as_bit(); + SigBit data_sig = tbuf_cell->getPort(ID::A).as_bit(); if (wire->port_input && !tinoutpad_celltype.empty()) { diff --git a/passes/techmap/lut2mux.cc b/passes/techmap/lut2mux.cc index 6877a75e2..c6618fc9d 100644 --- a/passes/techmap/lut2mux.cc +++ b/passes/techmap/lut2mux.cc @@ -25,8 +25,8 @@ PRIVATE_NAMESPACE_BEGIN int lut2mux(Cell *cell) { - SigSpec sig_a = cell->getPort(ID(A)); - SigSpec sig_y = cell->getPort(ID(Y)); + SigSpec sig_a = cell->getPort(ID::A); + SigSpec sig_y = cell->getPort(ID::Y); Const lut = cell->getParam(ID(LUT)); int count = 1; diff --git a/passes/techmap/maccmap.cc b/passes/techmap/maccmap.cc index 616ff21f2..09f61927c 100644 --- a/passes/techmap/maccmap.cc +++ b/passes/techmap/maccmap.cc @@ -113,10 +113,10 @@ struct MaccmapWorker RTLIL::Cell *cell = module->addCell(NEW_ID, ID($fa)); cell->setParam(ID(WIDTH), width); - cell->setPort(ID(A), in1); - cell->setPort(ID(B), in2); + cell->setPort(ID::A, in1); + cell->setPort(ID::B, in2); cell->setPort(ID(C), in3); - cell->setPort(ID(Y), w1); + cell->setPort(ID::Y, w1); cell->setPort(ID(X), w2); out1 = {out_zeros_msb, w1, out_zeros_lsb}; @@ -238,11 +238,11 @@ struct MaccmapWorker RTLIL::Cell *c = module->addCell(NEW_ID, ID($alu)); - c->setPort(ID(A), summands.front()); - c->setPort(ID(B), summands.back()); + c->setPort(ID::A, summands.front()); + c->setPort(ID::B, summands.back()); c->setPort(ID(CI), State::S0); c->setPort(ID(BI), State::S0); - c->setPort(ID(Y), module->addWire(NEW_ID, width)); + c->setPort(ID::Y, module->addWire(NEW_ID, width)); c->setPort(ID(X), module->addWire(NEW_ID, width)); c->setPort(ID(CO), module->addWire(NEW_ID, width)); c->fixup_parameters(); @@ -253,7 +253,7 @@ struct MaccmapWorker } log_assert(tree_sum_bits.empty()); - return c->getPort(ID(Y)); + return c->getPort(ID::Y); } }; @@ -264,17 +264,17 @@ extern void maccmap(RTLIL::Module *module, RTLIL::Cell *cell, bool unmap = false void maccmap(RTLIL::Module *module, RTLIL::Cell *cell, bool unmap) { - int width = GetSize(cell->getPort(ID(Y))); + int width = GetSize(cell->getPort(ID::Y)); Macc macc; macc.from_cell(cell); RTLIL::SigSpec all_input_bits; - all_input_bits.append(cell->getPort(ID(A))); - all_input_bits.append(cell->getPort(ID(B))); + all_input_bits.append(cell->getPort(ID::A)); + all_input_bits.append(cell->getPort(ID::B)); if (all_input_bits.to_sigbit_set().count(RTLIL::Sx)) { - module->connect(cell->getPort(ID(Y)), RTLIL::SigSpec(RTLIL::Sx, width)); + module->connect(cell->getPort(ID::Y), RTLIL::SigSpec(RTLIL::Sx, width)); return; } @@ -339,9 +339,9 @@ void maccmap(RTLIL::Module *module, RTLIL::Cell *cell, bool unmap) } if (summands.front().second) - module->addNeg(NEW_ID, summands.front().first, cell->getPort(ID(Y))); + module->addNeg(NEW_ID, summands.front().first, cell->getPort(ID::Y)); else - module->connect(cell->getPort(ID(Y)), summands.front().first); + module->connect(cell->getPort(ID::Y), summands.front().first); } else { @@ -356,7 +356,7 @@ void maccmap(RTLIL::Module *module, RTLIL::Cell *cell, bool unmap) for (auto &bit : macc.bit_ports) worker.add(bit, 0); - module->connect(cell->getPort(ID(Y)), worker.synth()); + module->connect(cell->getPort(ID::Y), worker.synth()); } } diff --git a/passes/techmap/muxcover.cc b/passes/techmap/muxcover.cc index 64d5b4f7b..5541b6122 100644 --- a/passes/techmap/muxcover.cc +++ b/passes/techmap/muxcover.cc @@ -122,7 +122,7 @@ struct MuxcoverWorker } } if (cell->type == ID($_MUX_)) - sig_to_mux[sigmap(cell->getPort(ID(Y)))] = cell; + sig_to_mux[sigmap(cell->getPort(ID::Y))] = cell; } log(" Treeifying %d MUXes:\n", GetSize(sig_to_mux)); @@ -141,8 +141,8 @@ struct MuxcoverWorker if (sig_to_mux.count(bit) && (bit == rootsig || !roots.count(bit))) { Cell *c = sig_to_mux.at(bit); tree.muxes[bit] = c; - wavefront.insert(sigmap(c->getPort(ID(A)))); - wavefront.insert(sigmap(c->getPort(ID(B)))); + wavefront.insert(sigmap(c->getPort(ID::A))); + wavefront.insert(sigmap(c->getPort(ID::B))); } } @@ -517,31 +517,31 @@ struct MuxcoverWorker if (GetSize(mux.inputs) == 2) { count_muxes_by_type[0]++; Cell *cell = module->addCell(NEW_ID, ID($_MUX_)); - cell->setPort(ID(A), mux.inputs[0]); - cell->setPort(ID(B), mux.inputs[1]); + cell->setPort(ID::A, mux.inputs[0]); + cell->setPort(ID::B, mux.inputs[1]); cell->setPort(ID(S), mux.selects[0]); - cell->setPort(ID(Y), bit); + cell->setPort(ID::Y, bit); return; } if (GetSize(mux.inputs) == 4) { count_muxes_by_type[1]++; Cell *cell = module->addCell(NEW_ID, ID($_MUX4_)); - cell->setPort(ID(A), mux.inputs[0]); - cell->setPort(ID(B), mux.inputs[1]); + cell->setPort(ID::A, mux.inputs[0]); + cell->setPort(ID::B, mux.inputs[1]); cell->setPort(ID(C), mux.inputs[2]); cell->setPort(ID(D), mux.inputs[3]); cell->setPort(ID(S), mux.selects[0]); cell->setPort(ID(T), mux.selects[1]); - cell->setPort(ID(Y), bit); + cell->setPort(ID::Y, bit); return; } if (GetSize(mux.inputs) == 8) { count_muxes_by_type[2]++; Cell *cell = module->addCell(NEW_ID, ID($_MUX8_)); - cell->setPort(ID(A), mux.inputs[0]); - cell->setPort(ID(B), mux.inputs[1]); + cell->setPort(ID::A, mux.inputs[0]); + cell->setPort(ID::B, mux.inputs[1]); cell->setPort(ID(C), mux.inputs[2]); cell->setPort(ID(D), mux.inputs[3]); cell->setPort(ID(E), mux.inputs[4]); @@ -551,15 +551,15 @@ struct MuxcoverWorker cell->setPort(ID(S), mux.selects[0]); cell->setPort(ID(T), mux.selects[1]); cell->setPort(ID(U), mux.selects[2]); - cell->setPort(ID(Y), bit); + cell->setPort(ID::Y, bit); return; } if (GetSize(mux.inputs) == 16) { count_muxes_by_type[3]++; Cell *cell = module->addCell(NEW_ID, ID($_MUX16_)); - cell->setPort(ID(A), mux.inputs[0]); - cell->setPort(ID(B), mux.inputs[1]); + cell->setPort(ID::A, mux.inputs[0]); + cell->setPort(ID::B, mux.inputs[1]); cell->setPort(ID(C), mux.inputs[2]); cell->setPort(ID(D), mux.inputs[3]); cell->setPort(ID(E), mux.inputs[4]); @@ -578,7 +578,7 @@ struct MuxcoverWorker cell->setPort(ID(T), mux.selects[1]); cell->setPort(ID(U), mux.selects[2]); cell->setPort(ID(V), mux.selects[3]); - cell->setPort(ID(Y), bit); + cell->setPort(ID::Y, bit); return; } diff --git a/passes/techmap/nlutmap.cc b/passes/techmap/nlutmap.cc index 4a3428b3c..798d82248 100644 --- a/passes/techmap/nlutmap.cc +++ b/passes/techmap/nlutmap.cc @@ -85,7 +85,7 @@ struct NlutmapWorker if (cell->type != ID($lut) || mapped_cells.count(cell)) continue; - if (GetSize(cell->getPort(ID(A))) == lut_size || lut_size == 2) + if (GetSize(cell->getPort(ID::A)) == lut_size || lut_size == 2) candidate_ratings[cell] = 0; for (auto &conn : cell->connections()) diff --git a/passes/techmap/pmuxtree.cc b/passes/techmap/pmuxtree.cc index f77652f3b..31ab13cec 100644 --- a/passes/techmap/pmuxtree.cc +++ b/passes/techmap/pmuxtree.cc @@ -92,18 +92,18 @@ struct PmuxtreePass : public Pass { if (cell->type != ID($pmux)) continue; - SigSpec sig_data = cell->getPort(ID(B)); + SigSpec sig_data = cell->getPort(ID::B); SigSpec sig_sel = cell->getPort(ID(S)); - if (!cell->getPort(ID(A)).is_fully_undef()) { - sig_data.append(cell->getPort(ID(A))); + if (!cell->getPort(ID::A).is_fully_undef()) { + sig_data.append(cell->getPort(ID::A)); SigSpec sig_sel_or = module->ReduceOr(NEW_ID, sig_sel); sig_sel.append(module->Not(NEW_ID, sig_sel_or)); } SigSpec result, result_or; result = recursive_mux_generator(module, sig_data, sig_sel, result_or); - module->connect(cell->getPort(ID(Y)), result); + module->connect(cell->getPort(ID::Y), result); module->remove(cell); } } diff --git a/passes/techmap/shregmap.cc b/passes/techmap/shregmap.cc index 92637dfa8..cb877c2f4 100644 --- a/passes/techmap/shregmap.cc +++ b/passes/techmap/shregmap.cc @@ -107,16 +107,16 @@ struct ShregmapTechXilinx7 : ShregmapTech if (cell->type == ID($shiftx)) { if (cell->getParam(ID(Y_WIDTH)) != 1) continue; int j = 0; - for (auto bit : sigmap(cell->getPort(ID(A)))) + for (auto bit : sigmap(cell->getPort(ID::A))) sigbit_to_shiftx_offset[bit] = std::make_tuple(cell, j++, 0); log_assert(j == cell->getParam(ID(A_WIDTH)).as_int()); } else if (cell->type == ID($mux)) { int j = 0; - for (auto bit : sigmap(cell->getPort(ID(A)))) + for (auto bit : sigmap(cell->getPort(ID::A))) sigbit_to_shiftx_offset[bit] = std::make_tuple(cell, 0, j++); j = 0; - for (auto bit : sigmap(cell->getPort(ID(B)))) + for (auto bit : sigmap(cell->getPort(ID::B))) sigbit_to_shiftx_offset[bit] = std::make_tuple(cell, 1, j++); } } @@ -128,9 +128,9 @@ struct ShregmapTechXilinx7 : ShregmapTech if (it == sigbit_to_shiftx_offset.end()) return; if (cell) { - if (cell->type == ID($shiftx) && port == ID(A)) + if (cell->type == ID($shiftx) && port == ID::A) return; - if (cell->type == ID($mux) && port.in(ID(A), ID(B))) + if (cell->type == ID($mux) && port.in(ID::A, ID::B)) return; } sigbit_to_shiftx_offset.erase(it); @@ -183,7 +183,7 @@ struct ShregmapTechXilinx7 : ShregmapTech // Due to padding the most significant bits of A may be 1'bx, // and if so, discount them if (GetSize(taps) < shiftx->getParam(ID(A_WIDTH)).as_int()) { - const SigSpec A = shiftx->getPort(ID(A)); + const SigSpec A = shiftx->getPort(ID::A); const int A_width = shiftx->getParam(ID(A_WIDTH)).as_int(); for (int i = GetSize(taps); i < A_width; ++i) if (A[i] != RTLIL::Sx) return false; @@ -223,14 +223,14 @@ struct ShregmapTechXilinx7 : ShregmapTech Cell* shiftx = std::get<0>(it->second); RTLIL::SigSpec l_wire, q_wire; if (shiftx->type == ID($shiftx)) { - l_wire = shiftx->getPort(ID(B)); - q_wire = shiftx->getPort(ID(Y)); - shiftx->setPort(ID(Y), cell->module->addWire(NEW_ID)); + l_wire = shiftx->getPort(ID::B); + q_wire = shiftx->getPort(ID::Y); + shiftx->setPort(ID::Y, cell->module->addWire(NEW_ID)); } else if (shiftx->type == ID($mux)) { l_wire = shiftx->getPort(ID(S)); - q_wire = shiftx->getPort(ID(Y)); - shiftx->setPort(ID(Y), cell->module->addWire(NEW_ID)); + q_wire = shiftx->getPort(ID::Y); + shiftx->setPort(ID::Y, cell->module->addWire(NEW_ID)); } else log_abort(); diff --git a/passes/techmap/simplemap.cc b/passes/techmap/simplemap.cc index 325a816ee..91574f3c6 100644 --- a/passes/techmap/simplemap.cc +++ b/passes/techmap/simplemap.cc @@ -28,23 +28,23 @@ YOSYS_NAMESPACE_BEGIN void simplemap_not(RTLIL::Module *module, RTLIL::Cell *cell) { - RTLIL::SigSpec sig_a = cell->getPort(ID(A)); - RTLIL::SigSpec sig_y = cell->getPort(ID(Y)); + RTLIL::SigSpec sig_a = cell->getPort(ID::A); + RTLIL::SigSpec sig_y = cell->getPort(ID::Y); sig_a.extend_u0(GetSize(sig_y), cell->parameters.at(ID(A_SIGNED)).as_bool()); for (int i = 0; i < GetSize(sig_y); i++) { RTLIL::Cell *gate = module->addCell(NEW_ID, ID($_NOT_)); gate->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src))); - gate->setPort(ID(A), sig_a[i]); - gate->setPort(ID(Y), sig_y[i]); + gate->setPort(ID::A, sig_a[i]); + gate->setPort(ID::Y, sig_y[i]); } } void simplemap_pos(RTLIL::Module *module, RTLIL::Cell *cell) { - RTLIL::SigSpec sig_a = cell->getPort(ID(A)); - RTLIL::SigSpec sig_y = cell->getPort(ID(Y)); + RTLIL::SigSpec sig_a = cell->getPort(ID::A); + RTLIL::SigSpec sig_y = cell->getPort(ID::Y); sig_a.extend_u0(GetSize(sig_y), cell->parameters.at(ID(A_SIGNED)).as_bool()); @@ -53,9 +53,9 @@ void simplemap_pos(RTLIL::Module *module, RTLIL::Cell *cell) void simplemap_bitop(RTLIL::Module *module, RTLIL::Cell *cell) { - RTLIL::SigSpec sig_a = cell->getPort(ID(A)); - RTLIL::SigSpec sig_b = cell->getPort(ID(B)); - RTLIL::SigSpec sig_y = cell->getPort(ID(Y)); + RTLIL::SigSpec sig_a = cell->getPort(ID::A); + RTLIL::SigSpec sig_b = cell->getPort(ID::B); + RTLIL::SigSpec sig_y = cell->getPort(ID::Y); sig_a.extend_u0(GetSize(sig_y), cell->parameters.at(ID(A_SIGNED)).as_bool()); sig_b.extend_u0(GetSize(sig_y), cell->parameters.at(ID(B_SIGNED)).as_bool()); @@ -67,8 +67,8 @@ void simplemap_bitop(RTLIL::Module *module, RTLIL::Cell *cell) for (int i = 0; i < GetSize(sig_y); i++) { RTLIL::Cell *gate = module->addCell(NEW_ID, ID($_NOT_)); gate->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src))); - gate->setPort(ID(A), sig_t[i]); - gate->setPort(ID(Y), sig_y[i]); + gate->setPort(ID::A, sig_t[i]); + gate->setPort(ID::Y, sig_y[i]); } sig_y = sig_t; @@ -84,16 +84,16 @@ void simplemap_bitop(RTLIL::Module *module, RTLIL::Cell *cell) for (int i = 0; i < GetSize(sig_y); i++) { RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type); gate->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src))); - gate->setPort(ID(A), sig_a[i]); - gate->setPort(ID(B), sig_b[i]); - gate->setPort(ID(Y), sig_y[i]); + gate->setPort(ID::A, sig_a[i]); + gate->setPort(ID::B, sig_b[i]); + gate->setPort(ID::Y, sig_y[i]); } } void simplemap_reduce(RTLIL::Module *module, RTLIL::Cell *cell) { - RTLIL::SigSpec sig_a = cell->getPort(ID(A)); - RTLIL::SigSpec sig_y = cell->getPort(ID(Y)); + RTLIL::SigSpec sig_a = cell->getPort(ID::A); + RTLIL::SigSpec sig_y = cell->getPort(ID::Y); if (sig_y.size() == 0) return; @@ -135,9 +135,9 @@ void simplemap_reduce(RTLIL::Module *module, RTLIL::Cell *cell) RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type); gate->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src))); - gate->setPort(ID(A), sig_a[i]); - gate->setPort(ID(B), sig_a[i+1]); - gate->setPort(ID(Y), sig_t[i/2]); + gate->setPort(ID::A, sig_a[i]); + gate->setPort(ID::B, sig_a[i+1]); + gate->setPort(ID::Y, sig_t[i/2]); last_output_cell = gate; } @@ -148,8 +148,8 @@ void simplemap_reduce(RTLIL::Module *module, RTLIL::Cell *cell) RTLIL::SigSpec sig_t = module->addWire(NEW_ID); RTLIL::Cell *gate = module->addCell(NEW_ID, ID($_NOT_)); gate->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src))); - gate->setPort(ID(A), sig_a); - gate->setPort(ID(Y), sig_t); + gate->setPort(ID::A, sig_a); + gate->setPort(ID::Y, sig_t); last_output_cell = gate; sig_a = sig_t; } @@ -157,7 +157,7 @@ void simplemap_reduce(RTLIL::Module *module, RTLIL::Cell *cell) if (last_output_cell == NULL) { module->connect(RTLIL::SigSig(sig_y, sig_a)); } else { - last_output_cell->setPort(ID(Y), sig_y); + last_output_cell->setPort(ID::Y, sig_y); } } @@ -176,9 +176,9 @@ static void logic_reduce(RTLIL::Module *module, RTLIL::SigSpec &sig, RTLIL::Cell RTLIL::Cell *gate = module->addCell(NEW_ID, ID($_OR_)); gate->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src))); - gate->setPort(ID(A), sig[i]); - gate->setPort(ID(B), sig[i+1]); - gate->setPort(ID(Y), sig_t[i/2]); + gate->setPort(ID::A, sig[i]); + gate->setPort(ID::B, sig[i+1]); + gate->setPort(ID::Y, sig_t[i/2]); } sig = sig_t; @@ -190,10 +190,10 @@ static void logic_reduce(RTLIL::Module *module, RTLIL::SigSpec &sig, RTLIL::Cell void simplemap_lognot(RTLIL::Module *module, RTLIL::Cell *cell) { - RTLIL::SigSpec sig_a = cell->getPort(ID(A)); + RTLIL::SigSpec sig_a = cell->getPort(ID::A); logic_reduce(module, sig_a, cell); - RTLIL::SigSpec sig_y = cell->getPort(ID(Y)); + RTLIL::SigSpec sig_y = cell->getPort(ID::Y); if (sig_y.size() == 0) return; @@ -205,19 +205,19 @@ void simplemap_lognot(RTLIL::Module *module, RTLIL::Cell *cell) RTLIL::Cell *gate = module->addCell(NEW_ID, ID($_NOT_)); gate->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src))); - gate->setPort(ID(A), sig_a); - gate->setPort(ID(Y), sig_y); + gate->setPort(ID::A, sig_a); + gate->setPort(ID::Y, sig_y); } void simplemap_logbin(RTLIL::Module *module, RTLIL::Cell *cell) { - RTLIL::SigSpec sig_a = cell->getPort(ID(A)); + RTLIL::SigSpec sig_a = cell->getPort(ID::A); logic_reduce(module, sig_a, cell); - RTLIL::SigSpec sig_b = cell->getPort(ID(B)); + RTLIL::SigSpec sig_b = cell->getPort(ID::B); logic_reduce(module, sig_b, cell); - RTLIL::SigSpec sig_y = cell->getPort(ID(Y)); + RTLIL::SigSpec sig_y = cell->getPort(ID::Y); if (sig_y.size() == 0) return; @@ -234,16 +234,16 @@ void simplemap_logbin(RTLIL::Module *module, RTLIL::Cell *cell) RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type); gate->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src))); - gate->setPort(ID(A), sig_a); - gate->setPort(ID(B), sig_b); - gate->setPort(ID(Y), sig_y); + gate->setPort(ID::A, sig_a); + gate->setPort(ID::B, sig_b); + gate->setPort(ID::Y, sig_y); } void simplemap_eqne(RTLIL::Module *module, RTLIL::Cell *cell) { - RTLIL::SigSpec sig_a = cell->getPort(ID(A)); - RTLIL::SigSpec sig_b = cell->getPort(ID(B)); - RTLIL::SigSpec sig_y = cell->getPort(ID(Y)); + RTLIL::SigSpec sig_a = cell->getPort(ID::A); + RTLIL::SigSpec sig_b = cell->getPort(ID::B); + RTLIL::SigSpec sig_y = cell->getPort(ID::Y); bool is_signed = cell->parameters.at(ID(A_SIGNED)).as_bool(); bool is_ne = cell->type.in(ID($ne), ID($nex)); @@ -269,38 +269,38 @@ void simplemap_eqne(RTLIL::Module *module, RTLIL::Cell *cell) void simplemap_mux(RTLIL::Module *module, RTLIL::Cell *cell) { - RTLIL::SigSpec sig_a = cell->getPort(ID(A)); - RTLIL::SigSpec sig_b = cell->getPort(ID(B)); - RTLIL::SigSpec sig_y = cell->getPort(ID(Y)); + RTLIL::SigSpec sig_a = cell->getPort(ID::A); + RTLIL::SigSpec sig_b = cell->getPort(ID::B); + RTLIL::SigSpec sig_y = cell->getPort(ID::Y); for (int i = 0; i < GetSize(sig_y); i++) { RTLIL::Cell *gate = module->addCell(NEW_ID, ID($_MUX_)); gate->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src))); - gate->setPort(ID(A), sig_a[i]); - gate->setPort(ID(B), sig_b[i]); + gate->setPort(ID::A, sig_a[i]); + gate->setPort(ID::B, sig_b[i]); gate->setPort(ID(S), cell->getPort(ID(S))); - gate->setPort(ID(Y), sig_y[i]); + gate->setPort(ID::Y, sig_y[i]); } } void simplemap_tribuf(RTLIL::Module *module, RTLIL::Cell *cell) { - RTLIL::SigSpec sig_a = cell->getPort(ID(A)); + RTLIL::SigSpec sig_a = cell->getPort(ID::A); RTLIL::SigSpec sig_e = cell->getPort(ID(EN)); - RTLIL::SigSpec sig_y = cell->getPort(ID(Y)); + RTLIL::SigSpec sig_y = cell->getPort(ID::Y); for (int i = 0; i < GetSize(sig_y); i++) { RTLIL::Cell *gate = module->addCell(NEW_ID, ID($_TBUF_)); gate->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src))); - gate->setPort(ID(A), sig_a[i]); + gate->setPort(ID::A, sig_a[i]); gate->setPort(ID(E), sig_e); - gate->setPort(ID(Y), sig_y[i]); + gate->setPort(ID::Y, sig_y[i]); } } void simplemap_lut(RTLIL::Module *module, RTLIL::Cell *cell) { - SigSpec lut_ctrl = cell->getPort(ID(A)); + SigSpec lut_ctrl = cell->getPort(ID::A); SigSpec lut_data = cell->getParam(ID(LUT)); lut_data.extend_u0(1 << cell->getParam(ID(WIDTH)).as_int()); @@ -310,20 +310,20 @@ void simplemap_lut(RTLIL::Module *module, RTLIL::Cell *cell) for (int i = 0; i < GetSize(lut_data); i += 2) { RTLIL::Cell *gate = module->addCell(NEW_ID, ID($_MUX_)); gate->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src))); - gate->setPort(ID(A), lut_data[i]); - gate->setPort(ID(B), lut_data[i+1]); + gate->setPort(ID::A, lut_data[i]); + gate->setPort(ID::B, lut_data[i+1]); gate->setPort(ID(S), lut_ctrl[idx]); - gate->setPort(ID(Y), new_lut_data[i/2]); + gate->setPort(ID::Y, new_lut_data[i/2]); } lut_data = new_lut_data; } - module->connect(cell->getPort(ID(Y)), lut_data); + module->connect(cell->getPort(ID::Y), lut_data); } void simplemap_sop(RTLIL::Module *module, RTLIL::Cell *cell) { - SigSpec ctrl = cell->getPort(ID(A)); + SigSpec ctrl = cell->getPort(ID::A); SigSpec table = cell->getParam(ID(TABLE)); int width = cell->getParam(ID(WIDTH)).as_int(); @@ -348,22 +348,22 @@ void simplemap_sop(RTLIL::Module *module, RTLIL::Cell *cell) products.append(GetSize(in) > 0 ? module->Eq(NEW_ID, in, pat) : State::S1); } - module->connect(cell->getPort(ID(Y)), module->ReduceOr(NEW_ID, products)); + module->connect(cell->getPort(ID::Y), module->ReduceOr(NEW_ID, products)); } void simplemap_slice(RTLIL::Module *module, RTLIL::Cell *cell) { int offset = cell->parameters.at(ID(OFFSET)).as_int(); - RTLIL::SigSpec sig_a = cell->getPort(ID(A)); - RTLIL::SigSpec sig_y = cell->getPort(ID(Y)); + RTLIL::SigSpec sig_a = cell->getPort(ID::A); + RTLIL::SigSpec sig_y = cell->getPort(ID::Y); module->connect(RTLIL::SigSig(sig_y, sig_a.extract(offset, sig_y.size()))); } void simplemap_concat(RTLIL::Module *module, RTLIL::Cell *cell) { - RTLIL::SigSpec sig_ab = cell->getPort(ID(A)); - sig_ab.append(cell->getPort(ID(B))); - RTLIL::SigSpec sig_y = cell->getPort(ID(Y)); + RTLIL::SigSpec sig_ab = cell->getPort(ID::A); + sig_ab.append(cell->getPort(ID::B)); + RTLIL::SigSpec sig_y = cell->getPort(ID::Y); module->connect(RTLIL::SigSig(sig_y, sig_ab)); } diff --git a/passes/techmap/techmap.cc b/passes/techmap/techmap.cc index e81dc33ee..fa038c1b9 100644 --- a/passes/techmap/techmap.cc +++ b/passes/techmap/techmap.cc @@ -520,7 +520,7 @@ struct TechmapWorker int port_counter = 1; for (auto &c : extmapper_cell->connections_) { RTLIL::Wire *w = extmapper_module->addWire(c.first, GetSize(c.second)); - if (w->name.in(ID(Y), ID(Q))) + if (w->name.in(ID::Y, ID(Q))) w->port_output = true; else w->port_input = true; diff --git a/passes/techmap/tribuf.cc b/passes/techmap/tribuf.cc index 509a9198b..41fdc8f3d 100644 --- a/passes/techmap/tribuf.cc +++ b/passes/techmap/tribuf.cc @@ -64,37 +64,37 @@ struct TribufWorker { for (auto cell : module->selected_cells()) { if (cell->type == ID($tribuf)) - tribuf_cells[sigmap(cell->getPort(ID(Y)))].push_back(cell); + tribuf_cells[sigmap(cell->getPort(ID::Y))].push_back(cell); if (cell->type == ID($_TBUF_)) - tribuf_cells[sigmap(cell->getPort(ID(Y)))].push_back(cell); + tribuf_cells[sigmap(cell->getPort(ID::Y))].push_back(cell); if (cell->type.in(ID($mux), ID($_MUX_))) { IdString en_port = cell->type == ID($mux) ? ID(EN) : ID(E); IdString tri_type = cell->type == ID($mux) ? ID($tribuf) : ID($_TBUF_); - if (is_all_z(cell->getPort(ID(A))) && is_all_z(cell->getPort(ID(B)))) { + if (is_all_z(cell->getPort(ID::A)) && is_all_z(cell->getPort(ID::B))) { module->remove(cell); continue; } - if (is_all_z(cell->getPort(ID(A)))) { - cell->setPort(ID(A), cell->getPort(ID(B))); + if (is_all_z(cell->getPort(ID::A))) { + cell->setPort(ID::A, cell->getPort(ID::B)); cell->setPort(en_port, cell->getPort(ID(S))); - cell->unsetPort(ID(B)); + cell->unsetPort(ID::B); cell->unsetPort(ID(S)); cell->type = tri_type; - tribuf_cells[sigmap(cell->getPort(ID(Y)))].push_back(cell); + tribuf_cells[sigmap(cell->getPort(ID::Y))].push_back(cell); continue; } - if (is_all_z(cell->getPort(ID(B)))) { + if (is_all_z(cell->getPort(ID::B))) { cell->setPort(en_port, module->Not(NEW_ID, cell->getPort(ID(S)))); - cell->unsetPort(ID(B)); + cell->unsetPort(ID::B); cell->unsetPort(ID(S)); cell->type = tri_type; - tribuf_cells[sigmap(cell->getPort(ID(Y)))].push_back(cell); + tribuf_cells[sigmap(cell->getPort(ID::Y))].push_back(cell); continue; } } @@ -122,7 +122,7 @@ struct TribufWorker { pmux_s.append(cell->getPort(ID(EN))); else pmux_s.append(cell->getPort(ID(E))); - pmux_b.append(cell->getPort(ID(A))); + pmux_b.append(cell->getPort(ID::A)); module->remove(cell); } From eae5a6b12c0f44230f61ed23068e7200507f9520 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 15 Aug 2019 14:51:12 -0700 Subject: [PATCH 35/94] Use ID::keep more liberally too --- passes/opt/muxpack.cc | 4 ++-- passes/opt/opt_clean.cc | 8 ++++---- passes/opt/opt_expr.cc | 2 +- passes/opt/opt_lut.cc | 2 +- passes/opt/opt_muxtree.cc | 2 +- passes/opt/wreduce.cc | 2 +- passes/techmap/abc.cc | 4 ++-- passes/techmap/iopadmap.cc | 8 ++++---- passes/techmap/shregmap.cc | 4 ++-- passes/techmap/techmap.cc | 2 +- 10 files changed, 19 insertions(+), 19 deletions(-) diff --git a/passes/opt/muxpack.cc b/passes/opt/muxpack.cc index 97c88f423..c40c02acd 100644 --- a/passes/opt/muxpack.cc +++ b/passes/opt/muxpack.cc @@ -135,7 +135,7 @@ struct MuxpackWorker { for (auto wire : module->wires()) { - if (wire->port_output || wire->get_bool_attribute(ID(keep))) { + if (wire->port_output || wire->get_bool_attribute(ID::keep)) { for (auto bit : sigmap(wire)) sigbit_with_non_chain_users.insert(bit); } @@ -143,7 +143,7 @@ struct MuxpackWorker for (auto cell : module->cells()) { - if (cell->type.in(ID($mux), ID($pmux)) && !cell->get_bool_attribute(ID(keep))) + if (cell->type.in(ID($mux), ID($pmux)) && !cell->get_bool_attribute(ID::keep)) { SigSpec a_sig = sigmap(cell->getPort(ID::A)); SigSpec b_sig; diff --git a/passes/opt/opt_clean.cc b/passes/opt/opt_clean.cc index bf75c7adc..2f69b3d4c 100644 --- a/passes/opt/opt_clean.cc +++ b/passes/opt/opt_clean.cc @@ -52,7 +52,7 @@ struct keep_cache_t return cache.at(module); cache[module] = true; - if (!module->get_bool_attribute(ID(keep))) { + if (!module->get_bool_attribute(ID::keep)) { bool found_keep = false; for (auto cell : module->cells()) if (query(cell)) found_keep = true; @@ -122,7 +122,7 @@ void rmunused_module_cells(Module *module, bool verbose) for (auto &it : module->wires_) { Wire *wire = it.second; - if (wire->port_output || wire->get_bool_attribute(ID(keep))) { + if (wire->port_output || wire->get_bool_attribute(ID::keep)) { for (auto bit : sigmap(wire)) for (auto c : wire2driver[bit]) queue.insert(c), unused.erase(c); @@ -297,7 +297,7 @@ bool rmunused_module_signals(RTLIL::Module *module, bool purge_mode, bool verbos if (!wire->port_input) used_signals_nodrivers.add(sig); } - if (wire->get_bool_attribute(ID(keep))) { + if (wire->get_bool_attribute(ID::keep)) { RTLIL::SigSpec sig = RTLIL::SigSpec(wire); assign_map.apply(sig); used_signals.add(sig); @@ -323,7 +323,7 @@ bool rmunused_module_signals(RTLIL::Module *module, bool purge_mode, bool verbos if (wire->port_id == 0) goto delete_this_wire; } else - if (wire->port_id != 0 || wire->get_bool_attribute(ID(keep)) || !initval.is_fully_undef()) { + if (wire->port_id != 0 || wire->get_bool_attribute(ID::keep) || !initval.is_fully_undef()) { // do not delete anything with "keep" or module ports or initialized wires } else if (!purge_mode && check_public_name(wire->name) && (raw_used_signals.check_any(s1) || used_signals.check_any(s2) || s1 != s2)) { diff --git a/passes/opt/opt_expr.cc b/passes/opt/opt_expr.cc index 85ec9a55a..f7469853b 100644 --- a/passes/opt/opt_expr.cc +++ b/passes/opt/opt_expr.cc @@ -61,7 +61,7 @@ void replace_undriven(RTLIL::Design *design, RTLIL::Module *module) } if (wire->port_input) driven_signals.add(sigmap(wire)); - if (wire->port_output || wire->get_bool_attribute(ID(keep))) + if (wire->port_output || wire->get_bool_attribute(ID::keep)) used_signals.add(sigmap(wire)); all_signals.add(sigmap(wire)); } diff --git a/passes/opt/opt_lut.cc b/passes/opt/opt_lut.cc index 733bc547c..c4f278706 100644 --- a/passes/opt/opt_lut.cc +++ b/passes/opt/opt_lut.cc @@ -104,7 +104,7 @@ struct OptLutWorker if (cell->has_keep_attr()) continue; SigBit lut_output = cell->getPort(ID::Y); - if (lut_output.wire->get_bool_attribute(ID(keep))) + if (lut_output.wire->get_bool_attribute(ID::keep)) continue; int lut_width = cell->getParam(ID(WIDTH)).as_int(); diff --git a/passes/opt/opt_muxtree.cc b/passes/opt/opt_muxtree.cc index 3d7e9cccb..3c486bbcc 100644 --- a/passes/opt/opt_muxtree.cc +++ b/passes/opt/opt_muxtree.cc @@ -137,7 +137,7 @@ struct OptMuxtreeWorker } } for (auto wire : module->wires()) { - if (wire->port_output || wire->get_bool_attribute(ID(keep))) + if (wire->port_output || wire->get_bool_attribute(ID::keep)) for (int idx : sig2bits(RTLIL::SigSpec(wire))) bit2info[idx].seen_non_mux = true; } diff --git a/passes/opt/wreduce.cc b/passes/opt/wreduce.cc index 792c69c55..37de8cb61 100644 --- a/passes/opt/wreduce.cc +++ b/passes/opt/wreduce.cc @@ -398,7 +398,7 @@ struct WreduceWorker SigMap init_attr_sigmap = mi.sigmap; for (auto w : module->wires()) { - if (w->get_bool_attribute(ID(keep))) + if (w->get_bool_attribute(ID::keep)) for (auto bit : mi.sigmap(w)) keep_bits.insert(bit); if (w->attributes.count(ID(init))) { diff --git a/passes/techmap/abc.cc b/passes/techmap/abc.cc index 205f05ab9..4e49b73ba 100644 --- a/passes/techmap/abc.cc +++ b/passes/techmap/abc.cc @@ -198,7 +198,7 @@ void extract_cell(RTLIL::Cell *cell, bool keepff) if (keepff) for (auto &c : sig_q.chunks()) if (c.wire != NULL) - c.wire->attributes[ID(keep)] = 1; + c.wire->attributes[ID::keep] = 1; assign_map.apply(sig_d); assign_map.apply(sig_q); @@ -787,7 +787,7 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin extract_cell(c, keepff); for (auto &wire_it : module->wires_) { - if (wire_it.second->port_id > 0 || wire_it.second->get_bool_attribute(ID(keep))) + if (wire_it.second->port_id > 0 || wire_it.second->get_bool_attribute(ID::keep)) mark_port(RTLIL::SigSpec(wire_it.second)); } diff --git a/passes/techmap/iopadmap.cc b/passes/techmap/iopadmap.cc index 898cb77a4..a2551316f 100644 --- a/passes/techmap/iopadmap.cc +++ b/passes/techmap/iopadmap.cc @@ -226,7 +226,7 @@ struct IopadmapPass : public Pass { cell->setPort(RTLIL::escape_id(tinoutpad_portname2), owire); cell->setPort(RTLIL::escape_id(tinoutpad_portname3), data_sig); cell->setPort(RTLIL::escape_id(tinoutpad_portname4), wire_bit); - cell->attributes[ID(keep)] = RTLIL::Const(1); + cell->attributes[ID::keep] = RTLIL::Const(1); for (auto cn : tbuf_cache.second) { auto c = module->cell(cn); @@ -263,7 +263,7 @@ struct IopadmapPass : public Pass { cell->setPort(RTLIL::escape_id(toutpad_portname), en_sig); cell->setPort(RTLIL::escape_id(toutpad_portname2), data_sig); cell->setPort(RTLIL::escape_id(toutpad_portname3), wire_bit); - cell->attributes[ID(keep)] = RTLIL::Const(1); + cell->attributes[ID::keep] = RTLIL::Const(1); for (auto cn : tbuf_cache.second) { auto c = module->cell(cn); @@ -390,7 +390,7 @@ struct IopadmapPass : public Pass { cell->parameters[RTLIL::escape_id(widthparam)] = RTLIL::Const(1); if (!nameparam.empty()) cell->parameters[RTLIL::escape_id(nameparam)] = RTLIL::Const(stringf("%s[%d]", RTLIL::id2cstr(wire->name), i)); - cell->attributes[ID(keep)] = RTLIL::Const(1); + cell->attributes[ID::keep] = RTLIL::Const(1); } } else @@ -403,7 +403,7 @@ struct IopadmapPass : public Pass { cell->parameters[RTLIL::escape_id(widthparam)] = RTLIL::Const(wire->width); if (!nameparam.empty()) cell->parameters[RTLIL::escape_id(nameparam)] = RTLIL::Const(RTLIL::id2cstr(wire->name)); - cell->attributes[ID(keep)] = RTLIL::Const(1); + cell->attributes[ID::keep] = RTLIL::Const(1); } wire->port_id = 0; diff --git a/passes/techmap/shregmap.cc b/passes/techmap/shregmap.cc index cb877c2f4..5e298d8dd 100644 --- a/passes/techmap/shregmap.cc +++ b/passes/techmap/shregmap.cc @@ -263,7 +263,7 @@ struct ShregmapWorker { for (auto wire : module->wires()) { - if (wire->port_output || wire->get_bool_attribute(ID(keep))) { + if (wire->port_output || wire->get_bool_attribute(ID::keep)) { for (auto bit : sigmap(wire)) { sigbit_with_non_chain_users.insert(bit); if (opts.tech) opts.tech->non_chain_user(bit, nullptr, {}); @@ -283,7 +283,7 @@ struct ShregmapWorker for (auto cell : module->cells()) { - if (opts.ffcells.count(cell->type) && !cell->get_bool_attribute(ID(keep))) + if (opts.ffcells.count(cell->type) && !cell->get_bool_attribute(ID::keep)) { IdString d_port = opts.ffcells.at(cell->type).first; IdString q_port = opts.ffcells.at(cell->type).second; diff --git a/passes/techmap/techmap.cc b/passes/techmap/techmap.cc index fa038c1b9..b271c8781 100644 --- a/passes/techmap/techmap.cc +++ b/passes/techmap/techmap.cc @@ -145,7 +145,7 @@ struct TechmapWorker record.wire = it.second; record.value = it.second; result[p].push_back(record); - it.second->attributes[ID(keep)] = RTLIL::Const(1); + it.second->attributes[ID::keep] = RTLIL::Const(1); it.second->attributes[ID(_techmap_special_)] = RTLIL::Const(1); } } From 453a9429b67551f94f8c714c24f12929e472052c Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 15 Aug 2019 14:54:41 -0700 Subject: [PATCH 36/94] Fix spacing --- kernel/yosys.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/yosys.h b/kernel/yosys.h index 52e7b3383..0cf230722 100644 --- a/kernel/yosys.h +++ b/kernel/yosys.h @@ -210,7 +210,7 @@ namespace RTLIL { struct Module; struct Design; struct Monitor; - namespace ID {} + namespace ID {} } namespace AST { From 0b9ee4fbbf3a5fc818e5ae39a013cdd9e17f641f Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 15 Aug 2019 16:20:54 -0700 Subject: [PATCH 37/94] Try this for gcc-4.8? --- kernel/yosys.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/yosys.h b/kernel/yosys.h index 0cf230722..895286a53 100644 --- a/kernel/yosys.h +++ b/kernel/yosys.h @@ -225,7 +225,7 @@ using RTLIL::Wire; using RTLIL::Cell; using RTLIL::Module; using RTLIL::Design; -namespace ID = RTLIL::ID; +namespace ID = ::YOSYS_NAMESPACE::RTLIL::ID; namespace hashlib { template<> struct hash_ops : hash_obj_ops {}; From 4a57b7e1abe148b36827a393fd7fe62e46c2b1a7 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 16 Aug 2019 11:47:51 +0200 Subject: [PATCH 38/94] Refactor demo_reduce into test_pmgen Signed-off-by: Clifford Wolf --- passes/pmgen/.gitignore | 2 +- passes/pmgen/Makefile.inc | 6 +- .../pmgen/{demo_reduce.cc => test_pmgen.cc} | 86 ++++++++++++++++--- .../pmgen/{demo_reduce.pmg => test_pmgen.pmg} | 3 + 4 files changed, 83 insertions(+), 14 deletions(-) rename passes/pmgen/{demo_reduce.cc => test_pmgen.cc} (53%) rename passes/pmgen/{demo_reduce.pmg => test_pmgen.pmg} (93%) diff --git a/passes/pmgen/.gitignore b/passes/pmgen/.gitignore index a1fe9a7dc..849b73fd4 100644 --- a/passes/pmgen/.gitignore +++ b/passes/pmgen/.gitignore @@ -1,3 +1,3 @@ -/demo_reduce_pm.h +/test_pmgen_pm.h /ice40_dsp_pm.h /peepopt_pm.h diff --git a/passes/pmgen/Makefile.inc b/passes/pmgen/Makefile.inc index 3aaee4047..bea21d971 100644 --- a/passes/pmgen/Makefile.inc +++ b/passes/pmgen/Makefile.inc @@ -9,9 +9,9 @@ $(eval $(call add_extra_objs,passes/pmgen/ice40_dsp_pm.h)) # -------------------------------------- -OBJS += passes/pmgen/demo_reduce.o -passes/pmgen/demo_reduce.o: passes/pmgen/demo_reduce_pm.h -$(eval $(call add_extra_objs,passes/pmgen/demo_reduce_pm.h)) +OBJS += passes/pmgen/test_pmgen.o +passes/pmgen/test_pmgen.o: passes/pmgen/test_pmgen_pm.h +$(eval $(call add_extra_objs,passes/pmgen/test_pmgen_pm.h)) # -------------------------------------- diff --git a/passes/pmgen/demo_reduce.cc b/passes/pmgen/test_pmgen.cc similarity index 53% rename from passes/pmgen/demo_reduce.cc rename to passes/pmgen/test_pmgen.cc index dd8c66f56..3bff9ae12 100644 --- a/passes/pmgen/demo_reduce.cc +++ b/passes/pmgen/test_pmgen.cc @@ -23,9 +23,9 @@ USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN -#include "passes/pmgen/demo_reduce_pm.h" +#include "passes/pmgen/test_pmgen_pm.h" -void create_reduce(demo_reduce_pm &pm) +void reduce_chain(test_pmgen_pm &pm) { auto &st = pm.st_reduce; auto &ud = pm.ud_reduce; @@ -65,23 +65,58 @@ void create_reduce(demo_reduce_pm &pm) log(" -> %s (%s)\n", log_id(c), log_id(c->type)); } -struct DemoReducePass : public Pass { - DemoReducePass() : Pass("demo_reduce", "map chains of AND/OR/XOR") { } +void reduce_tree(test_pmgen_pm &pm) +{ + auto &st = pm.st_reduce; + auto &ud = pm.ud_reduce; + + if (ud.longest_chain.empty()) + return; + + SigSpec A = ud.leaves; + SigSpec Y = st.first->getPort(ID(Y)); + pm.autoremove(st.first); + + log("Found %s tree with %d leaves for %s (%s).\n", log_id(st.first->type), + GetSize(A), log_signal(Y), log_id(st.first)); + + Cell *c; + + if (st.first->type == ID($_AND_)) + c = pm.module->addReduceAnd(NEW_ID, A, Y); + else if (st.first->type == ID($_OR_)) + c = pm.module->addReduceOr(NEW_ID, A, Y); + else if (st.first->type == ID($_XOR_)) + c = pm.module->addReduceXor(NEW_ID, A, Y); + else + log_abort(); + + log(" -> %s (%s)\n", log_id(c), log_id(c->type)); +} + +struct TestPmgenPass : public Pass { + TestPmgenPass() : Pass("test_pmgen", "test pass for pmgen") { } void help() YS_OVERRIDE { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); - log(" demo_reduce [options] [selection]\n"); + log(" test_pmgen -reduce_chain [options] [selection]\n"); log("\n"); log("Demo for recursive pmgen patterns. Map chains of AND/OR/XOR to $reduce_*.\n"); log("\n"); + log("\n"); + log(" test_pmgen -reduce_tree [options] [selection]\n"); + log("\n"); + log("Demo for recursive pmgen patterns. Map trees of AND/OR/XOR to $reduce_*.\n"); + log("\n"); } - void execute(std::vector args, RTLIL::Design *design) YS_OVERRIDE + + void execute_reduce_chain(std::vector args, RTLIL::Design *design) { - log_header(design, "Executing DEMO_REDUCE pass.\n"); + log_header(design, "Executing TEST_PMGEN pass (-reduce_chain).\n"); size_t argidx; - for (argidx = 1; argidx < args.size(); argidx++) + for (argidx = 2; argidx < args.size(); argidx++) { // if (args[argidx] == "-singleton") { // singleton_mode = true; @@ -92,8 +127,39 @@ struct DemoReducePass : public Pass { extra_args(args, argidx, design); for (auto module : design->selected_modules()) - demo_reduce_pm(module, module->selected_cells()).run_reduce(create_reduce); + test_pmgen_pm(module, module->selected_cells()).run_reduce(reduce_chain); } -} DemoReducePass; + + void execute_reduce_tree(std::vector args, RTLIL::Design *design) + { + log_header(design, "Executing TEST_PMGEN pass (-reduce_tree).\n"); + + size_t argidx; + for (argidx = 2; argidx < args.size(); argidx++) + { + // if (args[argidx] == "-singleton") { + // singleton_mode = true; + // continue; + // } + break; + } + extra_args(args, argidx, design); + + for (auto module : design->selected_modules()) + test_pmgen_pm(module, module->selected_cells()).run_reduce(reduce_tree); + } + + void execute(std::vector args, RTLIL::Design *design) YS_OVERRIDE + { + if (GetSize(args) > 1) + { + if (args[1] == "-reduce_chain") + return execute_reduce_chain(args, design); + if (args[1] == "-reduce_tree") + return execute_reduce_tree(args, design); + } + log_cmd_error("Missing or unsupported mode parameter.\n"); + } +} TestPmgenPass; PRIVATE_NAMESPACE_END diff --git a/passes/pmgen/demo_reduce.pmg b/passes/pmgen/test_pmgen.pmg similarity index 93% rename from passes/pmgen/demo_reduce.pmg rename to passes/pmgen/test_pmgen.pmg index 09856e9ae..ccb37e553 100644 --- a/passes/pmgen/demo_reduce.pmg +++ b/passes/pmgen/test_pmgen.pmg @@ -3,6 +3,7 @@ pattern reduce state portname udata >> chain longest_chain udata > non_first_cells +udata leaves code non_first_cells.clear(); @@ -15,6 +16,7 @@ match first endmatch code + leaves = SigSpec(); longest_chain.clear(); chain.push_back(make_pair(first, \A)); subpattern(tail); @@ -73,6 +75,7 @@ code } else { if (GetSize(chain) > GetSize(longest_chain)) longest_chain = chain; + leaves.append(port(chain.back().first, chain.back().second)); } finally if (next) From c710df181c2e9931ce464ea60568c864b7195e8b Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 16 Aug 2019 13:26:36 +0200 Subject: [PATCH 39/94] Add pmgen "generate" feature Signed-off-by: Clifford Wolf --- passes/pmgen/pmgen.py | 57 +++++++++++---- passes/pmgen/test_pmgen.cc | 142 ++++++++++++++++++++++++++++++++++++ passes/pmgen/test_pmgen.pmg | 22 ++++++ 3 files changed, 208 insertions(+), 13 deletions(-) diff --git a/passes/pmgen/pmgen.py b/passes/pmgen/pmgen.py index c6e9a9cbf..e252c52f5 100644 --- a/passes/pmgen/pmgen.py +++ b/passes/pmgen/pmgen.py @@ -186,6 +186,9 @@ def process_pmgfile(f, filename): block["src"] = "%s:%d" % (filename, linenr) block["pattern"] = (current_pattern, current_subpattern) + block["genargs"] = None + block["gencode"] = None + line = line.split() assert len(line) == 2 assert (line[1] not in state_types[current_pattern]) or (state_types[current_pattern][line[1]] == "Cell*") @@ -236,6 +239,19 @@ def process_pmgfile(f, filename): block["semioptional"] = True continue + if a[0] == "generate": + block["genargs"] = list([int(s) for s in a[1:]]) + block["gencode"] = list() + assert len(block["genargs"]) < 2 + while True: + linenr += 1 + l = f.readline() + assert l != "" + a = l.split() + if a[0] == "endmatch": break + block["gencode"].append(rewrite_cpp(l.rstrip())) + break + assert False if block["optional"]: @@ -310,7 +326,17 @@ with open(outfile, "w") as f: print("struct {}_pm {{".format(prefix), file=f) print(" Module *module;", file=f) print(" SigMap sigmap;", file=f) - print(" std::function on_accept;".format(prefix), file=f) + print(" std::function on_accept;", file=f) + print(" bool generate_mode;", file=f) + print("", file=f) + + print(" uint32_t rngseed;", file=f) + print(" int rng(unsigned int n) {", file=f) + print(" rngseed ^= rngseed << 13;", file=f) + print(" rngseed ^= rngseed >> 17;", file=f) + print(" rngseed ^= rngseed << 5;", file=f) + print(" return rngseed % n;", file=f) + print(" }", file=f) print("", file=f) for index in range(len(blocks)): @@ -415,7 +441,7 @@ with open(outfile, "w") as f: print("", file=f) print(" {}_pm(Module *module, const vector &cells) :".format(prefix), file=f) - print(" module(module), sigmap(module) {", file=f) + print(" module(module), sigmap(module), generate_mode(false), rngseed(12345678) {", file=f) for current_pattern in sorted(patterns.keys()): for s, t in sorted(udata_types[current_pattern].items()): if t.endswith("*"): @@ -469,17 +495,15 @@ with open(outfile, "w") as f: print(" run_{}([&](){{on_accept_f(*this);}});".format(current_pattern), file=f) print(" }", file=f) print("", file=f) - print(" void run_{}(std::function on_accept_f) {{".format(current_pattern, current_pattern), file=f) - print(" run_{}([&](){{on_accept_f(st_{});}});".format(current_pattern, current_pattern), file=f) - print(" }", file=f) - print("", file=f) print(" void run_{}() {{".format(current_pattern), file=f) print(" run_{}([](){{}});".format(current_pattern, current_pattern), file=f) print(" }", file=f) print("", file=f) - for p, s in sorted(subpatterns.keys()): - print(" void block_subpattern_{}_{}() {{ block_{}(); }}".format(p, s, subpatterns[(p, s)]), file=f) + if len(subpatterns): + for p, s in sorted(subpatterns.keys()): + print(" void block_subpattern_{}_{}() {{ block_{}(); }}".format(p, s, subpatterns[(p, s)]), file=f) + print("", file=f) current_pattern = None current_subpattern = None @@ -611,8 +635,8 @@ with open(outfile, "w") as f: print(" std::get<{}>(key) = {};".format(field, entry[2]), file=f) print(" const vector &cells = index_{}[key];".format(index), file=f) - if block["semioptional"]: - print(" bool found_semioptional_match = false;", file=f) + if block["semioptional"] or block["genargs"] is not None: + print(" bool found_any_match = false;", file=f) print("", file=f) print(" for (int idx = 0; idx < GetSize(cells); idx++) {", file=f) @@ -620,8 +644,8 @@ with open(outfile, "w") as f: print(" if (blacklist_cells.count({})) continue;".format(block["cell"]), file=f) for expr in block["filter"]: print(" if (!({})) continue;".format(expr), file=f) - if block["semioptional"]: - print(" found_semioptional_match = true;", file=f) + if block["semioptional"] or block["genargs"] is not None: + print(" found_any_match = true;", file=f) print(" block_{}();".format(index+1), file=f) print(" if (rollback) {", file=f) print(" if (rollback != {}) {{".format(index+1), file=f) @@ -639,10 +663,17 @@ with open(outfile, "w") as f: print(" block_{}();".format(index+1), file=f) if block["semioptional"]: - print(" if (!found_semioptional_match) block_{}();".format(index+1), file=f) + print(" if (!found_any_match) block_{}();".format(index+1), file=f) print(" {} = backup_{};".format(block["cell"], block["cell"]), file=f) + if block["genargs"] is not None: + print(" if (generate_mode && !found_any_match) {", file=f) + if len(block["genargs"]) == 1: + print(" if (rng(100) >= {}) return;".format(block["genargs"][0]), file=f) + for line in block["gencode"]: + print(" " + line, file=f) + print(" }", file=f) else: assert False diff --git a/passes/pmgen/test_pmgen.cc b/passes/pmgen/test_pmgen.cc index 3bff9ae12..48d58b263 100644 --- a/passes/pmgen/test_pmgen.cc +++ b/passes/pmgen/test_pmgen.cc @@ -23,7 +23,12 @@ USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN +// for peepopt_pm +bool did_something; + #include "passes/pmgen/test_pmgen_pm.h" +#include "passes/pmgen/ice40_dsp_pm.h" +#include "passes/pmgen/peepopt_pm.h" void reduce_chain(test_pmgen_pm &pm) { @@ -94,6 +99,100 @@ void reduce_tree(test_pmgen_pm &pm) log(" -> %s (%s)\n", log_id(c), log_id(c->type)); } +#define GENERATE_PATTERN(pmclass, pattern) \ + generate_pattern([](pmclass &pm, std::function f){ return pm.run_ ## pattern(f); }, #pmclass, #pattern, design) + +void pmtest_addports(Module *module) +{ + pool driven_bits, used_bits; + SigMap sigmap(module); + int icnt = 0, ocnt = 0; + + for (auto cell : module->cells()) + for (auto conn : cell->connections()) + { + if (cell->input(conn.first)) + for (auto bit : sigmap(conn.second)) + used_bits.insert(bit); + if (cell->output(conn.first)) + for (auto bit : sigmap(conn.second)) + driven_bits.insert(bit); + } + + for (auto wire : vector(module->wires())) + { + SigSpec ibits, obits; + for (auto bit : sigmap(wire)) { + if (!used_bits.count(bit)) + obits.append(bit); + if (!driven_bits.count(bit)) + ibits.append(bit); + } + if (!ibits.empty()) { + Wire *w = module->addWire(stringf("\\i%d", icnt++), GetSize(ibits)); + w->port_input = true; + module->connect(ibits, w); + } + if (!obits.empty()) { + Wire *w = module->addWire(stringf("\\o%d", ocnt++), GetSize(obits)); + w->port_output = true; + module->connect(w, obits); + } + } + + module->fixup_ports(); +} + +template +void generate_pattern(std::function)> run, const char *pmclass, const char *pattern, Design *design) +{ + log("Generating \"%s\" patterns for pattern matcher \"%s\".\n", pattern, pmclass); + + int modcnt = 0; + + while (modcnt < 100) + { + int submodcnt = 0, itercnt = 0, cellcnt = 0; + Module *mod = design->addModule(NEW_ID); + + while (submodcnt < 10 && itercnt++ < 1000) + { + pm matcher(mod, mod->cells()); + + matcher.rng(1); + matcher.rngseed += modcnt; + matcher.rng(1); + matcher.rngseed += submodcnt; + matcher.rng(1); + matcher.rngseed += itercnt; + matcher.rng(1); + matcher.rngseed += cellcnt; + matcher.rng(1); + + if (GetSize(mod->cells()) != cellcnt) + { + bool found_match = false; + run(matcher, [&](){ found_match = true; }); + + if (found_match) { + Module *m = design->addModule(stringf("\\pmtest_%s_%s_%05d", + pmclass, pattern, modcnt++)); + mod->cloneInto(m); + pmtest_addports(m); + submodcnt++; + } + + cellcnt = GetSize(mod->cells()); + } + + matcher.generate_mode = true; + run(matcher, [](){}); + } + + design->remove(mod); + } +} + struct TestPmgenPass : public Pass { TestPmgenPass() : Pass("test_pmgen", "test pass for pmgen") { } void help() YS_OVERRIDE @@ -104,11 +203,18 @@ struct TestPmgenPass : public Pass { log("\n"); log("Demo for recursive pmgen patterns. Map chains of AND/OR/XOR to $reduce_*.\n"); log("\n"); + log("\n"); log(" test_pmgen -reduce_tree [options] [selection]\n"); log("\n"); log("Demo for recursive pmgen patterns. Map trees of AND/OR/XOR to $reduce_*.\n"); log("\n"); + + log("\n"); + log(" test_pmgen -generate [options] \n"); + log("\n"); + log("Create modules that match the specified pattern.\n"); + log("\n"); } void execute_reduce_chain(std::vector args, RTLIL::Design *design) @@ -149,6 +255,40 @@ struct TestPmgenPass : public Pass { test_pmgen_pm(module, module->selected_cells()).run_reduce(reduce_tree); } + void execute_generate(std::vector args, RTLIL::Design *design) + { + log_header(design, "Executing TEST_PMGEN pass (-generate).\n"); + + size_t argidx; + for (argidx = 2; argidx < args.size(); argidx++) + { + // if (args[argidx] == "-singleton") { + // singleton_mode = true; + // continue; + // } + break; + } + + if (argidx+1 != args.size()) + log_cmd_error("Expected exactly one pattern.\n"); + + string pattern = args[argidx]; + + if (pattern == "reduce") + return GENERATE_PATTERN(test_pmgen_pm, reduce); + + if (pattern == "ice40_dsp") + return GENERATE_PATTERN(ice40_dsp_pm, ice40_dsp); + + if (pattern == "peepopt-muldiv") + return GENERATE_PATTERN(peepopt_pm, muldiv); + + if (pattern == "peepopt-shiftmul") + return GENERATE_PATTERN(peepopt_pm, shiftmul); + + log_cmd_error("Unkown pattern: %s\n", pattern.c_str()); + } + void execute(std::vector args, RTLIL::Design *design) YS_OVERRIDE { if (GetSize(args) > 1) @@ -157,6 +297,8 @@ struct TestPmgenPass : public Pass { return execute_reduce_chain(args, design); if (args[1] == "-reduce_tree") return execute_reduce_tree(args, design); + if (args[1] == "-generate") + return execute_generate(args, design); } log_cmd_error("Missing or unsupported mode parameter.\n"); } diff --git a/passes/pmgen/test_pmgen.pmg b/passes/pmgen/test_pmgen.pmg index ccb37e553..077d337d6 100644 --- a/passes/pmgen/test_pmgen.pmg +++ b/passes/pmgen/test_pmgen.pmg @@ -13,6 +13,22 @@ endcode match first select first->type.in($_AND_, $_OR_, $_XOR_) filter !non_first_cells.count(first) +generate + SigSpec A = module->addWire(NEW_ID); + SigSpec B = module->addWire(NEW_ID); + SigSpec Y = module->addWire(NEW_ID); + switch (rng(3)) + { + case 0: + module->addAndGate(NEW_ID, A, B, Y); + break; + case 1: + module->addOrGate(NEW_ID, A, B, Y); + break; + case 2: + module->addXorGate(NEW_ID, A, B, Y); + break; + } endmatch code @@ -64,6 +80,12 @@ match next select next->type.in($_AND_, $_OR_, $_XOR_) index next->type === chain.back().first->type index port(next, \Y) === port(chain.back().first, chain.back().second) +generate 50 + SigSpec A = module->addWire(NEW_ID); + SigSpec B = module->addWire(NEW_ID); + SigSpec Y = port(chain.back().first, chain.back().second); + Cell *c = module->addAndGate(NEW_ID, A, B, Y); + c->type = chain.back().first->type; endmatch code From f45dad8220ed7c24ddaad5fc3f84bb80ddafb5ae Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 16 Aug 2019 13:47:50 +0200 Subject: [PATCH 40/94] Redesign pmgen backtracking for recursive matching Signed-off-by: Clifford Wolf --- passes/pmgen/pmgen.py | 67 ++++++++++++++++++++------------------ passes/pmgen/test_pmgen.cc | 4 ++- 2 files changed, 38 insertions(+), 33 deletions(-) diff --git a/passes/pmgen/pmgen.py b/passes/pmgen/pmgen.py index e252c52f5..95fcd2540 100644 --- a/passes/pmgen/pmgen.py +++ b/passes/pmgen/pmgen.py @@ -351,6 +351,7 @@ with open(outfile, "w") as f: print(" pool blacklist_cells;", file=f) print(" pool autoremove_cells;", file=f) print(" bool blacklist_dirty;", file=f) + print(" vector> rollback_stack;", file=f) print(" int rollback;", file=f) print("", file=f) @@ -393,6 +394,19 @@ with open(outfile, "w") as f: print(" }", file=f) print("", file=f) + print(" void check_blacklist() {", file=f) + print(" if (!blacklist_dirty)", file=f) + print(" return;", file=f) + print(" blacklist_dirty = false;", file=f) + print(" for (int i = 0; i < GetSize(rollback_stack); i++)", file=f) + print(" if (blacklist_cells.count(rollback_stack[i].first)) {", file=f) + print(" rollback = rollback_stack[i].second;", file=f) + print(" rollback_stack.resize(i);", file=f) + print(" return;", file=f) + print(" }", file=f) + print(" }", file=f) + print("", file=f) + print(" void autoremove(Cell *cell) {", file=f) print(" if (cell != nullptr) {", file=f) print(" if (blacklist_cells.insert(cell).second)", file=f) @@ -402,23 +416,6 @@ with open(outfile, "w") as f: print(" }", file=f) print("", file=f) - for current_pattern in sorted(patterns.keys()): - print(" void check_blacklist_{}() {{".format(current_pattern), file=f) - print(" if (!blacklist_dirty)", file=f) - print(" return;", file=f) - print(" blacklist_dirty = false;", file=f) - for index in range(len(blocks)): - block = blocks[index] - if block["pattern"] != (current_pattern, current_subpattern): - continue - if block["type"] == "match": - print(" if (st_{}.{} != nullptr && blacklist_cells.count(st_{}.{})) {{".format(current_pattern, block["cell"], current_pattern, block["cell"]), file=f) - print(" rollback = {};".format(index+1), file=f) - print(" return;", file=f) - print(" }", file=f) - print(" rollback = 0;", file=f) - print(" }", file=f) - print("", file=f) current_pattern = None print(" SigSpec port(Cell *cell, IdString portname) {", file=f) @@ -488,7 +485,8 @@ with open(outfile, "w") as f: print(" st_{}.{} = nullptr;".format(current_pattern, s), file=f) else: print(" st_{}.{} = {}();".format(current_pattern, s, t), file=f) - print(" block_{}();".format(patterns[current_pattern]), file=f) + print(" block_{}(1);".format(patterns[current_pattern]), file=f) + print(" log_assert(rollback_stack.empty());", file=f) print(" }", file=f) print("", file=f) print(" void run_{}(std::function on_accept_f) {{".format(current_pattern, prefix), file=f) @@ -502,7 +500,7 @@ with open(outfile, "w") as f: if len(subpatterns): for p, s in sorted(subpatterns.keys()): - print(" void block_subpattern_{}_{}() {{ block_{}(); }}".format(p, s, subpatterns[(p, s)]), file=f) + print(" void block_subpattern_{}_{}(int recursion) {{ block_{}(recursion); }}".format(p, s, subpatterns[(p, s)]), file=f) print("", file=f) current_pattern = None @@ -514,7 +512,7 @@ with open(outfile, "w") as f: if block["type"] in ("match", "code"): print(" // {}".format(block["src"]), file=f) - print(" void block_{}() {{".format(index), file=f) + print(" void block_{}(int recursion YS_ATTRIBUTE(unused)) {{".format(index), file=f) current_pattern, current_subpattern = block["pattern"] if block["type"] == "final": @@ -575,16 +573,16 @@ with open(outfile, "w") as f: if block["type"] == "code": print("", file=f) - print("#define reject do {{ check_blacklist_{}(); goto rollback_label; }} while(0)".format(current_pattern), file=f) - print("#define accept do {{ on_accept(); check_blacklist_{}(); if (rollback) goto rollback_label; }} while(0)".format(current_pattern), file=f) - print("#define branch do {{ block_{}(); if (rollback) goto rollback_label; }} while(0)".format(index+1), file=f) - print("#define subpattern(pattern_name) do {{ block_subpattern_{}_ ## pattern_name (); if (rollback) goto rollback_label; }} while(0)".format(current_pattern), file=f) + print("#define reject do { check_blacklist(); goto rollback_label; } while(0)", file=f) + print("#define accept do { on_accept(); check_blacklist(); if (rollback) goto rollback_label; } while(0)", file=f) + print("#define branch do {{ block_{}(recursion+1); if (rollback) goto rollback_label; }} while(0)".format(index+1), file=f) + print("#define subpattern(pattern_name) do {{ block_subpattern_{}_ ## pattern_name (recursion+1); if (rollback) goto rollback_label; }} while(0)".format(current_pattern), file=f) for line in block["code"]: print(" " + line, file=f) print("", file=f) - print(" block_{}();".format(index+1), file=f) + print(" block_{}(recursion+1);".format(index+1), file=f) print("#undef reject", file=f) print("#undef accept", file=f) @@ -596,7 +594,7 @@ with open(outfile, "w") as f: print(" YS_ATTRIBUTE(unused);", file=f) if len(block["fcode"]): - print("#define accept do {{ on_accept(); check_blacklist_{}(); }} while(0)".format(current_pattern), file=f) + print("#define accept do { on_accept(); check_blacklist(); } while(0)", file=f) for line in block["fcode"]: print(" " + line, file=f) print("#undef accept", file=f) @@ -624,7 +622,7 @@ with open(outfile, "w") as f: print("", file=f) print(" if (!({})) {{".format(expr), file=f) print(" {} = nullptr;".format(block["cell"]), file=f) - print(" block_{}();".format(index+1), file=f) + print(" block_{}(recursion+1);".format(index+1), file=f) print(" {} = backup_{};".format(block["cell"], block["cell"]), file=f) print(" return;", file=f) print(" }", file=f) @@ -646,9 +644,12 @@ with open(outfile, "w") as f: print(" if (!({})) continue;".format(expr), file=f) if block["semioptional"] or block["genargs"] is not None: print(" found_any_match = true;", file=f) - print(" block_{}();".format(index+1), file=f) - print(" if (rollback) {", file=f) - print(" if (rollback != {}) {{".format(index+1), file=f) + print(" rollback_stack.push_back(make_pair(cells[idx], recursion));", file=f) + print(" block_{}(recursion+1);".format(index+1), file=f) + print(" if (rollback == 0) {", file=f) + print(" rollback_stack.pop_back();", file=f) + print(" } else {", file=f) + print(" if (rollback != recursion) {{".format(index+1), file=f) print(" {} = backup_{};".format(block["cell"], block["cell"]), file=f) print(" return;", file=f) print(" }", file=f) @@ -660,10 +661,10 @@ with open(outfile, "w") as f: print(" {} = nullptr;".format(block["cell"]), file=f) if block["optional"]: - print(" block_{}();".format(index+1), file=f) + print(" block_{}(recursion+1);".format(index+1), file=f) if block["semioptional"]: - print(" if (!found_any_match) block_{}();".format(index+1), file=f) + print(" if (!found_any_match) block_{}(recursion+1);".format(index+1), file=f) print(" {} = backup_{};".format(block["cell"], block["cell"]), file=f) @@ -673,6 +674,8 @@ with open(outfile, "w") as f: print(" if (rng(100) >= {}) return;".format(block["genargs"][0]), file=f) for line in block["gencode"]: print(" " + line, file=f) + print(" rollback_stack.clear();", file=f) + print(" rollback = -1;", file=f) print(" }", file=f) else: assert False diff --git a/passes/pmgen/test_pmgen.cc b/passes/pmgen/test_pmgen.cc index 48d58b263..053dbe021 100644 --- a/passes/pmgen/test_pmgen.cc +++ b/passes/pmgen/test_pmgen.cc @@ -149,13 +149,14 @@ void generate_pattern(std::function)> run, const log("Generating \"%s\" patterns for pattern matcher \"%s\".\n", pattern, pmclass); int modcnt = 0; + int maxsubcnt = 4; while (modcnt < 100) { int submodcnt = 0, itercnt = 0, cellcnt = 0; Module *mod = design->addModule(NEW_ID); - while (submodcnt < 10 && itercnt++ < 1000) + while (submodcnt < maxsubcnt && itercnt++ < 1000) { pm matcher(mod, mod->cells()); @@ -190,6 +191,7 @@ void generate_pattern(std::function)> run, const } design->remove(mod); + maxsubcnt *= 2; } } From 20910fd7c8638ec58c85e750d5b8a7da1c83cded Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 16 Aug 2019 14:16:35 +0200 Subject: [PATCH 41/94] Add pmgen finish statement, return number of matches Signed-off-by: Clifford Wolf --- passes/pmgen/README.md | 117 +++++++++++++++++++++--------------- passes/pmgen/pmgen.py | 58 ++++++++++-------- passes/pmgen/test_pmgen.cc | 2 +- passes/pmgen/test_pmgen.pmg | 5 +- 4 files changed, 108 insertions(+), 74 deletions(-) diff --git a/passes/pmgen/README.md b/passes/pmgen/README.md index f92445a86..be908ef0b 100644 --- a/passes/pmgen/README.md +++ b/passes/pmgen/README.md @@ -45,9 +45,9 @@ of type `foobar_pm::state__t`.) Similarly the `.pmg` file declares user data variables that become members of `.ud_`, a struct of type `foobar_pm::udata__t`. -There are four versions of the `run_()` method: Without callback, -callback without arguments, callback with reference to `pm`, and callback with -reference to `pm.st_`. +There are three versions of the `run_()` method: Without callback, +callback without arguments, and callback with reference to `pm`. All versions +of the `run_()` method return the number of found matches. The .pmg File Format @@ -118,8 +118,8 @@ write matchers: connected to any of the given signal bits, plus one if any of the signal bits is also a primary input or primary output. -- In `code..endcode` blocks there exist `accept`, `reject`, `branch`, and - `subpattern` statements. +- In `code..endcode` blocks there exist `accept`, `reject`, `branch`, + `finish`, and `subpattern` statements. - In `index` statements there is a special `===` operator for the index lookup. @@ -246,13 +246,13 @@ debug messages. For example: code stack.push_back(addAB); - ... + ... finally stack.pop_back(); endcode -`accept` statements can be used inside the `finally` section, but not -`reject`, `branch`, or `subpattern`. +`accept` and `finish` statements can be used inside the `finally` section, +but not `reject`, `branch`, or `subpattern`. Declaring a subpattern ---------------------- @@ -265,52 +265,75 @@ Arguments may be passed to subpattern via state variables. The `subpattern` line must be followed by a `arg ...` line that lists the state variables used to pass arguments. - state foobar_type - state foobar_state + state foobar_type + state foobar_state - code foobar_type foobar_state - foobar_state = false; - foobar_type = $add; - subpattern(foo); - foobar_type = $sub; - subpattern(bar); - endcode + code foobar_type foobar_state + foobar_state = false; + foobar_type = $add; + subpattern(foo); + foobar_type = $sub; + subpattern(bar); + endcode - subpattern foo - arg foobar_type foobar_state + subpattern foo + arg foobar_type foobar_state - match addsub - index addsub->type === foobar_type - ... - endmatch + match addsub + index addsub->type === foobar_type + ... + endmatch - code - if (foobar_state) { - subpattern(tail); - } else { - foobar_state = true; - subpattern(bar); - } - endcode + code + if (foobar_state) { + subpattern(tail); + } else { + foobar_state = true; + subpattern(bar); + } + endcode - subpattern bar - arg foobar_type foobar_state + subpattern bar + arg foobar_type foobar_state - match addsub - index addsub->type === foobar_type - ... - endmatch + match addsub + index addsub->type === foobar_type + ... + endmatch - code - if (foobar_state) { - subpattern(tail); - } else { - foobar_state = true; - subpattern(foo); - } - endcode + code + if (foobar_state) { + subpattern(tail); + } else { + foobar_state = true; + subpattern(foo); + } + endcode - subpattern tail - ... + subpattern tail + ... Subpatterns cann be called recursively. + +Generate Blocks +--------------- + +Match blocks may contain an optional `generate` section that is used for automatic +test-case generation. For example: + + match mul + ... + generate 10 + SigSpec Y = port(ff, \D); + SigSpec A = module->addWire(NEW_ID, GetSize(Y) - rng(GetSize(Y)/2)); + SigSpec B = module->addWire(NEW_ID, GetSize(Y) - rng(GetSize(Y)/2)); + module->addMul(NEW_ID, A, B, Y, rng(2)); + endmatch + +The expression `rng(n)` returns a non-negative integer less than `n`. + +The argument to `generate` is the chance of this generate block being executed +when the match block did not match anything, in percent. + +The special statement `finish` can be used within generate blocks to terminate +the current pattern matcher run. diff --git a/passes/pmgen/pmgen.py b/passes/pmgen/pmgen.py index 95fcd2540..6950a99c0 100644 --- a/passes/pmgen/pmgen.py +++ b/passes/pmgen/pmgen.py @@ -328,6 +328,7 @@ with open(outfile, "w") as f: print(" SigMap sigmap;", file=f) print(" std::function on_accept;", file=f) print(" bool generate_mode;", file=f) + print(" int accept_cnt;", file=f) print("", file=f) print(" uint32_t rngseed;", file=f) @@ -476,7 +477,8 @@ with open(outfile, "w") as f: print("", file=f) for current_pattern in sorted(patterns.keys()): - print(" void run_{}(std::function on_accept_f) {{".format(current_pattern), file=f) + print(" int run_{}(std::function on_accept_f) {{".format(current_pattern), file=f) + print(" accept_cnt = 0;", file=f) print(" on_accept = on_accept_f;", file=f) print(" rollback = 0;", file=f) print(" blacklist_dirty = false;", file=f) @@ -487,14 +489,15 @@ with open(outfile, "w") as f: print(" st_{}.{} = {}();".format(current_pattern, s, t), file=f) print(" block_{}(1);".format(patterns[current_pattern]), file=f) print(" log_assert(rollback_stack.empty());", file=f) + print(" return accept_cnt;", file=f) print(" }", file=f) print("", file=f) - print(" void run_{}(std::function on_accept_f) {{".format(current_pattern, prefix), file=f) - print(" run_{}([&](){{on_accept_f(*this);}});".format(current_pattern), file=f) + print(" int run_{}(std::function on_accept_f) {{".format(current_pattern, prefix), file=f) + print(" return run_{}([&](){{on_accept_f(*this);}});".format(current_pattern), file=f) print(" }", file=f) print("", file=f) - print(" void run_{}() {{".format(current_pattern), file=f) - print(" run_{}([](){{}});".format(current_pattern, current_pattern), file=f) + print(" int run_{}() {{".format(current_pattern), file=f) + print(" return run_{}([](){{}});".format(current_pattern, current_pattern), file=f) print(" }", file=f) print("", file=f) @@ -574,7 +577,8 @@ with open(outfile, "w") as f: if block["type"] == "code": print("", file=f) print("#define reject do { check_blacklist(); goto rollback_label; } while(0)", file=f) - print("#define accept do { on_accept(); check_blacklist(); if (rollback) goto rollback_label; } while(0)", file=f) + print("#define accept do { accept_cnt++; on_accept(); check_blacklist(); if (rollback) goto rollback_label; } while(0)", file=f) + print("#define finish do { rollback = -1; rollback_stack.clean(); goto rollback_label; } while(0)", file=f) print("#define branch do {{ block_{}(recursion+1); if (rollback) goto rollback_label; }} while(0)".format(index+1), file=f) print("#define subpattern(pattern_name) do {{ block_subpattern_{}_ ## pattern_name (recursion+1); if (rollback) goto rollback_label; }} while(0)".format(current_pattern), file=f) @@ -586,6 +590,7 @@ with open(outfile, "w") as f: print("#undef reject", file=f) print("#undef accept", file=f) + print("#undef finish", file=f) print("#undef branch", file=f) print("#undef subpattern", file=f) @@ -594,10 +599,12 @@ with open(outfile, "w") as f: print(" YS_ATTRIBUTE(unused);", file=f) if len(block["fcode"]): - print("#define accept do { on_accept(); check_blacklist(); } while(0)", file=f) + print("#define accept do { accept_cnt++; on_accept(); check_blacklist(); } while(0)", file=f) + print("#define finish do { rollback = -1; rollback_stack.clean(); return; } while(0)", file=f) for line in block["fcode"]: print(" " + line, file=f) print("#undef accept", file=f) + print("#undef finish", file=f) if len(restore_st) or len(nonconst_st): print("", file=f) @@ -631,29 +638,32 @@ with open(outfile, "w") as f: print(" index_{}_key_type key;".format(index), file=f) for field, entry in enumerate(block["index"]): print(" std::get<{}>(key) = {};".format(field, entry[2]), file=f) - print(" const vector &cells = index_{}[key];".format(index), file=f) + print(" auto cells_ptr = index_{}.find(key);".format(index), file=f) if block["semioptional"] or block["genargs"] is not None: print(" bool found_any_match = false;", file=f) print("", file=f) - print(" for (int idx = 0; idx < GetSize(cells); idx++) {", file=f) - print(" {} = cells[idx];".format(block["cell"]), file=f) - print(" if (blacklist_cells.count({})) continue;".format(block["cell"]), file=f) + print(" if (cells_ptr != index_{}.end()) {{".format(index), file=f) + print(" const vector &cells = cells_ptr->second;".format(index), file=f) + print(" for (int idx = 0; idx < GetSize(cells); idx++) {", file=f) + print(" {} = cells[idx];".format(block["cell"]), file=f) + print(" if (blacklist_cells.count({})) continue;".format(block["cell"]), file=f) for expr in block["filter"]: - print(" if (!({})) continue;".format(expr), file=f) + print(" if (!({})) continue;".format(expr), file=f) if block["semioptional"] or block["genargs"] is not None: - print(" found_any_match = true;", file=f) - print(" rollback_stack.push_back(make_pair(cells[idx], recursion));", file=f) - print(" block_{}(recursion+1);".format(index+1), file=f) - print(" if (rollback == 0) {", file=f) - print(" rollback_stack.pop_back();", file=f) - print(" } else {", file=f) - print(" if (rollback != recursion) {{".format(index+1), file=f) - print(" {} = backup_{};".format(block["cell"], block["cell"]), file=f) - print(" return;", file=f) + print(" found_any_match = true;", file=f) + print(" rollback_stack.push_back(make_pair(cells[idx], recursion));", file=f) + print(" block_{}(recursion+1);".format(index+1), file=f) + print(" if (rollback == 0) {", file=f) + print(" rollback_stack.pop_back();", file=f) + print(" } else {", file=f) + print(" if (rollback != recursion) {{".format(index+1), file=f) + print(" {} = backup_{};".format(block["cell"], block["cell"]), file=f) + print(" return;", file=f) + print(" }", file=f) + print(" rollback = 0;", file=f) print(" }", file=f) - print(" rollback = 0;", file=f) print(" }", file=f) print(" }", file=f) @@ -669,14 +679,14 @@ with open(outfile, "w") as f: print(" {} = backup_{};".format(block["cell"], block["cell"]), file=f) if block["genargs"] is not None: + print("#define finish do { rollback = -1; rollback_stack.clean(); return; } while(0)", file=f) print(" if (generate_mode && !found_any_match) {", file=f) if len(block["genargs"]) == 1: print(" if (rng(100) >= {}) return;".format(block["genargs"][0]), file=f) for line in block["gencode"]: print(" " + line, file=f) - print(" rollback_stack.clear();", file=f) - print(" rollback = -1;", file=f) print(" }", file=f) + print("#undef finish", file=f) else: assert False diff --git a/passes/pmgen/test_pmgen.cc b/passes/pmgen/test_pmgen.cc index 053dbe021..d787d49be 100644 --- a/passes/pmgen/test_pmgen.cc +++ b/passes/pmgen/test_pmgen.cc @@ -235,7 +235,7 @@ struct TestPmgenPass : public Pass { extra_args(args, argidx, design); for (auto module : design->selected_modules()) - test_pmgen_pm(module, module->selected_cells()).run_reduce(reduce_chain); + while (test_pmgen_pm(module, module->selected_cells()).run_reduce(reduce_chain)) {} } void execute_reduce_tree(std::vector args, RTLIL::Design *design) diff --git a/passes/pmgen/test_pmgen.pmg b/passes/pmgen/test_pmgen.pmg index 077d337d6..211477a62 100644 --- a/passes/pmgen/test_pmgen.pmg +++ b/passes/pmgen/test_pmgen.pmg @@ -41,7 +41,8 @@ code finally chain.pop_back(); log_assert(chain.empty()); - accept; + if (GetSize(longest_chain) > 1) + accept; endcode // ------------------------------------------------------------------ @@ -80,7 +81,7 @@ match next select next->type.in($_AND_, $_OR_, $_XOR_) index next->type === chain.back().first->type index port(next, \Y) === port(chain.back().first, chain.back().second) -generate 50 +generate 10 SigSpec A = module->addWire(NEW_ID); SigSpec B = module->addWire(NEW_ID); SigSpec Y = port(chain.back().first, chain.back().second); From 64bd414e54aadc1446e114cf95f33dd95f5cf291 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 16 Aug 2019 14:35:13 +0200 Subject: [PATCH 42/94] Minor bugfix in "test_pmgen -generate" Signed-off-by: Clifford Wolf --- passes/pmgen/test_pmgen.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/passes/pmgen/test_pmgen.cc b/passes/pmgen/test_pmgen.cc index d787d49be..5f7bf2189 100644 --- a/passes/pmgen/test_pmgen.cc +++ b/passes/pmgen/test_pmgen.cc @@ -156,7 +156,7 @@ void generate_pattern(std::function)> run, const int submodcnt = 0, itercnt = 0, cellcnt = 0; Module *mod = design->addModule(NEW_ID); - while (submodcnt < maxsubcnt && itercnt++ < 1000) + while (modcnt < 100 && submodcnt < maxsubcnt && itercnt++ < 1000) { pm matcher(mod, mod->cells()); From 29e14e674eccc173b354dacd96fdbe0040c423d0 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 16 Aug 2019 19:36:45 +0000 Subject: [PATCH 43/94] Remove `using namespace RTLIL;` --- passes/opt/wreduce.cc | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/passes/opt/wreduce.cc b/passes/opt/wreduce.cc index 37de8cb61..c02c355cb 100644 --- a/passes/opt/wreduce.cc +++ b/passes/opt/wreduce.cc @@ -22,7 +22,6 @@ #include "kernel/modtools.h" USING_YOSYS_NAMESPACE -using namespace RTLIL; PRIVATE_NAMESPACE_BEGIN @@ -77,15 +76,15 @@ struct WreduceWorker { auto info = mi.query(sig_y[i]); if (!info->is_output && GetSize(info->ports) <= 1 && !keep_bits.count(mi.sigmap(sig_y[i]))) { - bits_removed.push_back(Sx); + bits_removed.push_back(State::Sx); continue; } SigBit ref = sig_a[i]; for (int k = 0; k < GetSize(sig_s); k++) { - if ((config->keepdc || (ref != Sx && sig_b[k*GetSize(sig_a) + i] != Sx)) && ref != sig_b[k*GetSize(sig_a) + i]) + if ((config->keepdc || (ref != State::Sx && sig_b[k*GetSize(sig_a) + i] != State::Sx)) && ref != sig_b[k*GetSize(sig_a) + i]) goto no_match_ab; - if (sig_b[k*GetSize(sig_a) + i] != Sx) + if (sig_b[k*GetSize(sig_a) + i] != State::Sx) ref = sig_b[k*GetSize(sig_a) + i]; } if (0) @@ -245,7 +244,7 @@ struct WreduceWorker while (GetSize(sig) > 1 && sig[GetSize(sig)-1] == sig[GetSize(sig)-2]) work_queue_bits.insert(sig[GetSize(sig)-1]), sig.remove(GetSize(sig)-1), bits_removed++; } else { - while (GetSize(sig) > 1 && sig[GetSize(sig)-1] == S0) + while (GetSize(sig) > 1 && sig[GetSize(sig)-1] == State::S0) work_queue_bits.insert(sig[GetSize(sig)-1]), sig.remove(GetSize(sig)-1), bits_removed++; } @@ -359,7 +358,7 @@ struct WreduceWorker max_y_size = a_size + b_size; while (GetSize(sig) > 1 && GetSize(sig) > max_y_size) { - module->connect(sig[GetSize(sig)-1], is_signed ? sig[GetSize(sig)-2] : S0); + module->connect(sig[GetSize(sig)-1], is_signed ? sig[GetSize(sig)-2] : State::S0); sig.remove(GetSize(sig)-1); bits_removed++; } From 3b19c3657cda6d972bd3b1c3eeacdfca5fb35de8 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 16 Aug 2019 19:37:11 +0000 Subject: [PATCH 44/94] Move namespace alias --- kernel/yosys.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/kernel/yosys.h b/kernel/yosys.h index 895286a53..a80cb00b4 100644 --- a/kernel/yosys.h +++ b/kernel/yosys.h @@ -210,7 +210,6 @@ namespace RTLIL { struct Module; struct Design; struct Monitor; - namespace ID {} } namespace AST { @@ -225,7 +224,6 @@ using RTLIL::Wire; using RTLIL::Cell; using RTLIL::Module; using RTLIL::Design; -namespace ID = ::YOSYS_NAMESPACE::RTLIL::ID; namespace hashlib { template<> struct hash_ops : hash_obj_ops {}; @@ -317,6 +315,7 @@ RTLIL::IdString new_id(std::string file, int line, std::string func); // #define ID(_id) ([]() { const char *p = "\\" #_id, *q = p[1] == '$' ? p+1 : p; \ static const YOSYS_NAMESPACE_PREFIX RTLIL::IdString id(q); return id; })() +namespace ID = RTLIL::ID; RTLIL::Design *yosys_get_design(); std::string proc_self_dirname(); From cd5a372cd18fe71cfa8428be59e355d82f34000d Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 16 Aug 2019 13:00:12 -0700 Subject: [PATCH 45/94] Add help() call --- passes/pmgen/test_pmgen.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/passes/pmgen/test_pmgen.cc b/passes/pmgen/test_pmgen.cc index 5f7bf2189..94e59f62e 100644 --- a/passes/pmgen/test_pmgen.cc +++ b/passes/pmgen/test_pmgen.cc @@ -302,6 +302,7 @@ struct TestPmgenPass : public Pass { if (args[1] == "-generate") return execute_generate(args, design); } + help(); log_cmd_error("Missing or unsupported mode parameter.\n"); } } TestPmgenPass; From 6b156beda16cce69e7318a3a2fdbc3ad547370c6 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 16 Aug 2019 13:35:39 -0700 Subject: [PATCH 46/94] Remove unused variable --- frontends/aiger/aigerparse.cc | 5 ----- 1 file changed, 5 deletions(-) diff --git a/frontends/aiger/aigerparse.cc b/frontends/aiger/aigerparse.cc index 534cc0daa..ac9e31f70 100644 --- a/frontends/aiger/aigerparse.cc +++ b/frontends/aiger/aigerparse.cc @@ -901,11 +901,6 @@ void AigerReader::post_process() RTLIL::Cell* cell = module->cell(stringf("$__box%d__", variable)); if (cell) { // ABC could have optimised this box away module->rename(cell, escaped_s); - #ifndef NDEBUG - RTLIL::Module* box_module = design->module(cell->type); - log_assert(box_module); - #endif - for (const auto &i : cell->connections()) { RTLIL::IdString port_name = i.first; RTLIL::SigSpec rhs = i.second; From fab067cecef205ce246904cf122a5e545e348f99 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 16 Aug 2019 13:47:37 -0700 Subject: [PATCH 47/94] Add 'opt_share' to 'opt -full' --- passes/opt/opt.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/passes/opt/opt.cc b/passes/opt/opt.cc index e9a43e0f3..396819883 100644 --- a/passes/opt/opt.cc +++ b/passes/opt/opt.cc @@ -44,6 +44,7 @@ struct OptPass : public Pass { log(" opt_muxtree\n"); log(" opt_reduce [-fine] [-full]\n"); log(" opt_merge [-share_all]\n"); + log(" opt_share (-full only)\n"); log(" opt_rmdff [-keepdc] [-sat]\n"); log(" opt_clean [-purge]\n"); log(" opt_expr [-mux_undef] [-mux_bool] [-undriven] [-clkinv] [-fine] [-full] [-keepdc]\n"); @@ -70,6 +71,7 @@ struct OptPass : public Pass { std::string opt_reduce_args; std::string opt_merge_args; std::string opt_rmdff_args; + bool opt_share = false; bool fast_mode = false; log_header(design, "Executing OPT pass (performing simple optimizations).\n"); @@ -105,6 +107,7 @@ struct OptPass : public Pass { if (args[argidx] == "-full") { opt_expr_args += " -full"; opt_reduce_args += " -full"; + opt_share = true; continue; } if (args[argidx] == "-keepdc") { @@ -151,6 +154,8 @@ struct OptPass : public Pass { Pass::call(design, "opt_muxtree"); Pass::call(design, "opt_reduce" + opt_reduce_args); Pass::call(design, "opt_merge" + opt_merge_args); + if (opt_share) + Pass::call(design, "opt_share"); Pass::call(design, "opt_rmdff" + opt_rmdff_args); Pass::call(design, "opt_clean" + opt_clean_args); Pass::call(design, "opt_expr" + opt_expr_args); From a29814ca3f448481d351bc9f8ba0a20084afd883 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 16 Aug 2019 13:47:51 -0700 Subject: [PATCH 48/94] Add 'opt_share' to CHANGELOG --- CHANGELOG | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG b/CHANGELOG index 638c36121..8dbe1aee3 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -19,6 +19,7 @@ Yosys 0.9 .. Yosys 0.9-dev - Added automatic gzip compression (based on filename extension) for backends - Improve attribute and parameter encoding in JSON to avoid ambiguities between bit vectors and strings containing [01xz]* + - Added "opt_share" pass, run as part of "opt -full" Yosys 0.8 .. Yosys 0.8-dev -------------------------- From 3d3779b0376b8204ed7637053176a07b7271ac1d Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 16 Aug 2019 14:01:55 -0700 Subject: [PATCH 49/94] Use ID() macro --- passes/opt/opt_share.cc | 228 +++++++++++++++++++--------------------- 1 file changed, 110 insertions(+), 118 deletions(-) diff --git a/passes/opt/opt_share.cc b/passes/opt/opt_share.cc index a2ec9cc37..734cbcf81 100644 --- a/passes/opt/opt_share.cc +++ b/passes/opt/opt_share.cc @@ -83,52 +83,51 @@ struct ExtSigSpec { bool operator==(const ExtSigSpec &other) const { return is_signed == other.is_signed && sign == other.sign && sig == other.sig && semantics == other.semantics; } }; -#define BITWISE_OPS "$_AND_", "$_NAND_", "$_OR_", "$_NOR_", "$_XOR_", "$_XNOR_", "$_ANDNOT_", "$_ORNOT_", "$and", "$or", "$xor", "$xnor" +#define BITWISE_OPS ID($_AND_), ID($_NAND_), ID($_OR_), ID($_NOR_), ID($_XOR_), ID($_XNOR_), ID($_ANDNOT_), ID($_ORNOT_), ID($and), ID($or), ID($xor), ID($xnor) -#define REDUCTION_OPS "$reduce_and", "$reduce_or", "$reduce_xor", "$reduce_xnor", "$reduce_bool", "$reduce_nand" +#define REDUCTION_OPS ID($reduce_and), ID($reduce_or), ID($reduce_xor), ID($reduce_xnor), ID($reduce_bool), ID($reduce_nand) -#define LOGICAL_OPS "$logic_and", "$logic_or" +#define LOGICAL_OPS ID($logic_and), ID($logic_or) -#define SHIFT_OPS "$shl", "$shr", "$sshl", "$sshr", "$shift", "$shiftx" +#define SHIFT_OPS ID($shl), ID($shr), ID($sshl), ID($sshr), ID($shift), ID($shiftx) -#define RELATIONAL_OPS "$lt", "$le", "$eq", "$ne", "$eqx", "$nex", "$ge", "$gt" +#define RELATIONAL_OPS ID($lt), ID($le), ID($eq), ID($ne), ID($eqx), ID($nex), ID($ge), ID($gt) bool cell_supported(RTLIL::Cell *cell) { - - if (cell->type.in("$alu")) { - RTLIL::SigSpec sig_bi = cell->getPort("\\BI"); - RTLIL::SigSpec sig_ci = cell->getPort("\\CI"); + if (cell->type.in(ID($alu))) { + RTLIL::SigSpec sig_bi = cell->getPort(ID(BI)); + RTLIL::SigSpec sig_ci = cell->getPort(ID(CI)); if (sig_bi.is_fully_const() && sig_ci.is_fully_const() && sig_bi == sig_ci) return true; - } else if (cell->type.in(LOGICAL_OPS, SHIFT_OPS, BITWISE_OPS, RELATIONAL_OPS, "$add", "$sub", "$mul", "$div", "$mod", "$concat")) { + } else if (cell->type.in(LOGICAL_OPS, SHIFT_OPS, BITWISE_OPS, RELATIONAL_OPS, ID($add), ID($sub), ID($mul), ID($div), ID($mod), ID($concat))) { return true; } return false; } -std::map mergeable_type_map{ - {"$sub", "$add"}, +std::map mergeable_type_map{ + {ID($sub), ID($add)}, }; bool mergeable(RTLIL::Cell *a, RTLIL::Cell *b) { auto a_type = a->type; - if (mergeable_type_map.count(a_type.str())) - a_type = mergeable_type_map.at(a_type.str()); + if (mergeable_type_map.count(a_type)) + a_type = mergeable_type_map.at(a_type); auto b_type = b->type; - if (mergeable_type_map.count(b_type.str())) - b_type = mergeable_type_map.at(b_type.str()); + if (mergeable_type_map.count(b_type)) + b_type = mergeable_type_map.at(b_type); return a_type == b_type; } RTLIL::IdString decode_port_semantics(RTLIL::Cell *cell, RTLIL::IdString port_name) { - if (cell->type.in("$lt", "$le", "$ge", "$gt", "$div", "$mod", "$concat", SHIFT_OPS) && port_name == "\\B") + if (cell->type.in(ID($lt), ID($le), ID($ge), ID($gt), ID($div), ID($mod), ID($concat), SHIFT_OPS) && port_name == ID(B)) return port_name; return ""; @@ -136,9 +135,9 @@ RTLIL::IdString decode_port_semantics(RTLIL::Cell *cell, RTLIL::IdString port_na RTLIL::SigSpec decode_port_sign(RTLIL::Cell *cell, RTLIL::IdString port_name) { - if (cell->type == "$alu" && port_name == "\\B") - return cell->getPort("\\BI"); - else if (cell->type == "$sub" && port_name == "\\B") + if (cell->type == ID($alu) && port_name == ID(B)) + return cell->getPort(ID(BI)); + else if (cell->type == ID($sub) && port_name == ID(B)) return RTLIL::Const(1, 1); return RTLIL::Const(0, 1); @@ -153,7 +152,6 @@ bool decode_port_signed(RTLIL::Cell *cell, RTLIL::IdString port_name) return cell->getParam(port_name.str() + "_SIGNED").as_bool(); return false; - } ExtSigSpec decode_port(RTLIL::Cell *cell, RTLIL::IdString port_name, SigMap *sigmap) @@ -170,15 +168,14 @@ ExtSigSpec decode_port(RTLIL::Cell *cell, RTLIL::IdString port_name, SigMap *sig void merge_operators(RTLIL::Module *module, RTLIL::Cell *mux, const std::vector &ports, const ExtSigSpec &operand) { - std::vector muxed_operands; int max_width = 0; for (const auto& p : ports) { auto op = p.op; - RTLIL::IdString muxed_port_name = "\\A"; - if (decode_port(op, "\\A", &assign_map) == operand) - muxed_port_name = "\\B"; + RTLIL::IdString muxed_port_name = ID(A); + if (decode_port(op, ID(A), &assign_map) == operand) + muxed_port_name = ID(B); auto operand = decode_port(op, muxed_port_name, &assign_map); if (operand.sig.size() > max_width) @@ -190,8 +187,7 @@ void merge_operators(RTLIL::Module *module, RTLIL::Cell *mux, const std::vector< auto shared_op = ports[0].op; if (std::any_of(muxed_operands.begin(), muxed_operands.end(), [&](ExtSigSpec &op) { return op.sign != muxed_operands[0].sign; })) - if (max_width < shared_op->getParam("\\Y_WIDTH").as_int()) - max_width = shared_op->getParam("\\Y_WIDTH").as_int(); + max_width = std::max(max_width, shared_op->getParam(ID(Y_WIDTH)).as_int()); for (auto &operand : muxed_operands) @@ -208,11 +204,10 @@ void merge_operators(RTLIL::Module *module, RTLIL::Cell *mux, const std::vector< if (muxed_op.sign != muxed_operands[0].sign) muxed_op = ExtSigSpec(module->Neg(NEW_ID, muxed_op.sig, muxed_op.is_signed)); - - RTLIL::SigSpec mux_y = mux->getPort("\\Y"); - RTLIL::SigSpec mux_a = mux->getPort("\\A"); - RTLIL::SigSpec mux_b = mux->getPort("\\B"); - RTLIL::SigSpec mux_s = mux->getPort("\\S"); + RTLIL::SigSpec mux_y = mux->getPort(ID(Y)); + RTLIL::SigSpec mux_a = mux->getPort(ID(A)); + RTLIL::SigSpec mux_b = mux->getPort(ID(B)); + RTLIL::SigSpec mux_s = mux->getPort(ID(S)); RTLIL::SigSpec shared_pmux_a = RTLIL::Const(RTLIL::State::Sx, max_width); RTLIL::SigSpec shared_pmux_b; @@ -221,49 +216,48 @@ void merge_operators(RTLIL::Module *module, RTLIL::Cell *mux, const std::vector< int conn_width = ports[0].sig.size(); int conn_offset = ports[0].mux_port_offset; - shared_op->setPort("\\Y", shared_op->getPort("\\Y").extract(0, conn_width)); + shared_op->setPort(ID(Y), shared_op->getPort(ID(Y)).extract(0, conn_width)); - if (mux->type == "$pmux") { + if (mux->type == ID($pmux)) { shared_pmux_s = RTLIL::SigSpec(); for (const auto &p : ports) { shared_pmux_s.append(mux_s[p.mux_port_id]); - mux_b.replace(p.mux_port_id * mux_a.size() + conn_offset, shared_op->getPort("\\Y")); + mux_b.replace(p.mux_port_id * mux_a.size() + conn_offset, shared_op->getPort(ID(Y))); } } else { shared_pmux_s = RTLIL::SigSpec{mux_s, module->Not(NEW_ID, mux_s)}; - mux_a.replace(conn_offset, shared_op->getPort("\\Y")); - mux_b.replace(conn_offset, shared_op->getPort("\\Y")); + mux_a.replace(conn_offset, shared_op->getPort(ID(Y))); + mux_b.replace(conn_offset, shared_op->getPort(ID(Y))); } - mux->setPort("\\A", mux_a); - mux->setPort("\\B", mux_b); - mux->setPort("\\Y", mux_y); - mux->setPort("\\S", mux_s); + mux->setPort(ID(A), mux_a); + mux->setPort(ID(B), mux_b); + mux->setPort(ID(Y), mux_y); + mux->setPort(ID(S), mux_s); for (const auto &op : muxed_operands) shared_pmux_b.append(op.sig); auto mux_to_oper = module->Pmux(NEW_ID, shared_pmux_a, shared_pmux_b, shared_pmux_s); - if (shared_op->type.in("$alu")) { - RTLIL::SigSpec alu_x = shared_op->getPort("\\X"); - RTLIL::SigSpec alu_co = shared_op->getPort("\\CO"); + if (shared_op->type.in(ID($alu))) { + RTLIL::SigSpec alu_x = shared_op->getPort(ID(X)); + RTLIL::SigSpec alu_co = shared_op->getPort(ID(CO)); - shared_op->setPort("\\X", alu_x.extract(0, conn_width)); - shared_op->setPort("\\CO", alu_co.extract(0, conn_width)); + shared_op->setPort(ID(X), alu_x.extract(0, conn_width)); + shared_op->setPort(ID(CO), alu_co.extract(0, conn_width)); } - shared_op->setParam("\\Y_WIDTH", conn_width); + shared_op->setParam(ID(Y_WIDTH), conn_width); - if (decode_port(shared_op, "\\A", &assign_map) == operand) { - shared_op->setPort("\\B", mux_to_oper); - shared_op->setParam("\\B_WIDTH", max_width); + if (decode_port(shared_op, ID(A), &assign_map) == operand) { + shared_op->setPort(ID(B), mux_to_oper); + shared_op->setParam(ID(B_WIDTH), max_width); } else { - shared_op->setPort("\\A", mux_to_oper); - shared_op->setParam("\\A_WIDTH", max_width); + shared_op->setPort(ID(A), mux_to_oper); + shared_op->setParam(ID(A_WIDTH), max_width); } - } typedef struct { @@ -285,7 +279,6 @@ template void remove_val(std::vector &v, const std::vector &v void check_muxed_operands(std::vector &ports, const ExtSigSpec &shared_operand) { - auto it = ports.begin(); ExtSigSpec seed; @@ -293,9 +286,9 @@ void check_muxed_operands(std::vector &ports, const ExtSigSpe auto p = *it; auto op = p->op; - RTLIL::IdString muxed_port_name = "\\A"; - if (decode_port(op, "\\A", &assign_map) == shared_operand) { - muxed_port_name = "\\B"; + RTLIL::IdString muxed_port_name = ID(A); + if (decode_port(op, ID(A), &assign_map) == shared_operand) { + muxed_port_name = ID(B); } auto operand = decode_port(op, muxed_port_name, &assign_map); @@ -322,7 +315,7 @@ ExtSigSpec find_shared_operand(const OpMuxConn* seed, std::vectorop; - for (RTLIL::IdString port_name : {"\\A", "\\B"}) { + for (RTLIL::IdString port_name : {ID(A), ID(B)}) { oper = decode_port(op_a, port_name, &assign_map); auto operand_users = operand_to_users.at(oper); @@ -362,78 +355,77 @@ dict find_valid_op_mux_conns(RTLIL::Module *module, d std::function remove_outsig_from_aux_bit = [&](RTLIL::SigBit auxbit) { auto aux_outsig = op_aux_to_outsig.at(auxbit); auto op = outsig_to_operator.at(aux_outsig); - auto op_outsig = assign_map(op->getPort("\\Y")); + auto op_outsig = assign_map(op->getPort(ID(Y))); remove_outsig(op_outsig); for (auto aux_outbit : aux_outsig) op_aux_to_outsig.erase(aux_outbit); }; - std::function - find_op_mux_conns = [&](RTLIL::Cell *mux) { - RTLIL::SigSpec sig; - int mux_port_size; + std::function find_op_mux_conns = [&](RTLIL::Cell *mux) { + RTLIL::SigSpec sig; + int mux_port_size; - if (mux->type.in("$mux", "$_MUX_")) { - mux_port_size = mux->getPort("\\A").size(); - sig = RTLIL::SigSpec{mux->getPort("\\B"), mux->getPort("\\A")}; - } else { - mux_port_size = mux->getPort("\\A").size(); - sig = mux->getPort("\\B"); - } + if (mux->type.in(ID($mux), ID($_MUX_))) { + mux_port_size = mux->getPort(ID(A)).size(); + sig = RTLIL::SigSpec{mux->getPort(ID(B)), mux->getPort(ID(A))}; + } else { + mux_port_size = mux->getPort(ID(A)).size(); + sig = mux->getPort(ID(B)); + } - auto mux_insig = assign_map(sig); + auto mux_insig = assign_map(sig); - for (int i = 0; i < mux_insig.size(); ++i) { - if (op_aux_to_outsig.count(mux_insig[i])) { - remove_outsig_from_aux_bit(mux_insig[i]); - continue; - } + for (int i = 0; i < mux_insig.size(); ++i) { + if (op_aux_to_outsig.count(mux_insig[i])) { + remove_outsig_from_aux_bit(mux_insig[i]); + continue; + } - if (!op_outbit_to_outsig.count(mux_insig[i])) - continue; + if (!op_outbit_to_outsig.count(mux_insig[i])) + continue; - auto op_outsig = op_outbit_to_outsig.at(mux_insig[i]); + auto op_outsig = op_outbit_to_outsig.at(mux_insig[i]); - if (op_mux_conn_map.count(op_outsig)) { - remove_outsig(op_outsig); - continue; - } + if (op_mux_conn_map.count(op_outsig)) { + remove_outsig(op_outsig); + continue; + } - int mux_port_id = i / mux_port_size; - int mux_port_offset = i % mux_port_size; + int mux_port_id = i / mux_port_size; + int mux_port_offset = i % mux_port_size; - int op_outsig_offset; - for (op_outsig_offset = 0; op_outsig[op_outsig_offset] != mux_insig[i]; ++op_outsig_offset) - ; + int op_outsig_offset; + for (op_outsig_offset = 0; op_outsig[op_outsig_offset] != mux_insig[i]; ++op_outsig_offset) + ; - int j = op_outsig_offset; - do { - if (!op_outbit_to_outsig.count(mux_insig[i])) - break; + int j = op_outsig_offset; + do { + if (!op_outbit_to_outsig.count(mux_insig[i])) + break; - if (op_outbit_to_outsig.at(mux_insig[i]) != op_outsig) - break; + if (op_outbit_to_outsig.at(mux_insig[i]) != op_outsig) + break; - ++i; - ++j; - } while ((i / mux_port_size == mux_port_id) && (j < op_outsig.size())); + ++i; + ++j; + } while ((i / mux_port_size == mux_port_id) && (j < op_outsig.size())); - int op_conn_width = j - op_outsig_offset; - OpMuxConn inp = { - op_outsig.extract(op_outsig_offset, op_conn_width), - mux, - outsig_to_operator.at(op_outsig), - mux_port_id, - mux_port_offset, - op_outsig_offset, - }; + int op_conn_width = j - op_outsig_offset; + OpMuxConn inp = { + op_outsig.extract(op_outsig_offset, op_conn_width), + mux, + outsig_to_operator.at(op_outsig), + mux_port_id, + mux_port_offset, + op_outsig_offset, + }; - op_mux_conn_map[op_outsig] = inp; + op_mux_conn_map[op_outsig] = inp; - --i; - } - }; + --i; + } + }; std::function remove_connected_ops = [&](RTLIL::SigSpec sig) { auto mux_insig = assign_map(sig); @@ -451,8 +443,8 @@ dict find_valid_op_mux_conns(RTLIL::Module *module, d }; for (auto cell : module->cells()) { - if (cell->type.in("$mux", "$_MUX_", "$pmux")) { - remove_connected_ops(cell->getPort("\\S")); + if (cell->type.in(ID($mux), ID($_MUX_), ID($pmux))) { + remove_connected_ops(cell->getPort(ID(S))); find_op_mux_conns(cell); } else { for (auto &conn : cell->connections()) @@ -509,8 +501,8 @@ struct OptSharePass : public Pass { if (!cell_supported(cell)) continue; - if (cell->type == "$alu") { - for (RTLIL::IdString port_name : {"\\X", "\\CO"}) { + if (cell->type == ID($alu)) { + for (RTLIL::IdString port_name : {ID(X), ID(CO)}) { auto mux_insig = assign_map(cell->getPort(port_name)); outsig_to_operator[mux_insig] = cell; for (auto outbit : mux_insig) @@ -518,12 +510,12 @@ struct OptSharePass : public Pass { } } - auto mux_insig = assign_map(cell->getPort("\\Y")); + auto mux_insig = assign_map(cell->getPort(ID(Y))); outsig_to_operator[mux_insig] = cell; for (auto outbit : mux_insig) op_outbit_to_outsig[outbit] = mux_insig; - for (RTLIL::IdString port_name : {"\\A", "\\B"}) { + for (RTLIL::IdString port_name : {ID(A), ID(B)}) { auto op_insig = decode_port(cell, port_name, &assign_map); op_insigs.push_back(op_insig); operand_to_users[op_insig].insert(cell); @@ -549,10 +541,10 @@ struct OptSharePass : public Pass { if (mux_port_conns.size() == 0) { int mux_port_num; - if (p.mux->type.in("$mux", "$_MUX_")) + if (p.mux->type.in(ID($mux), ID($_MUX_))) mux_port_num = 2; else - mux_port_num = p.mux->getPort("\\S").size(); + mux_port_num = p.mux->getPort(ID(S)).size(); mux_port_conns.resize(mux_port_num); } From 562c9e362487e0aa3a3d250a1a0a8cfcf10cafaa Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 16 Aug 2019 15:40:53 -0700 Subject: [PATCH 50/94] Attach abc_scc_break, abc_carry_{in,out} attr to ports not modules --- techlibs/xilinx/cells_sim.v | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/techlibs/xilinx/cells_sim.v b/techlibs/xilinx/cells_sim.v index 05e46b4e7..910d0e246 100644 --- a/techlibs/xilinx/cells_sim.v +++ b/techlibs/xilinx/cells_sim.v @@ -181,8 +181,14 @@ module XORCY(output O, input CI, LI); assign O = CI ^ LI; endmodule -(* abc_box_id = 4, abc_carry="CI,CO", lib_whitebox *) -module CARRY4(output [3:0] CO, O, input CI, CYINIT, input [3:0] DI, S); +(* abc_box_id = 4, lib_whitebox *) +module CARRY4( + (* abc_carry_out *) output [3:0] CO, + output [3:0] O, + (* abc_carry_in *) input CI, + input CYINIT, + input [3:0] DI, S +); assign O = S ^ {CO[2:0], CI | CYINIT}; assign CO[0] = S[0] ? CI | CYINIT : DI[0]; assign CO[1] = S[1] ? CO[0] : DI[1]; @@ -289,10 +295,12 @@ module FDPE_1 (output reg Q, input C, CE, D, PRE); always @(negedge C, posedge PRE) if (PRE) Q <= 1'b1; else if (CE) Q <= D; endmodule -(* abc_box_id = 5, abc_scc_break="D,WE" *) +(* abc_box_id = 5 *) module RAM32X1D ( output DPO, SPO, - input D, WCLK, WE, + (* abc_scc_break *) input D, + input WCLK, + (* abc_scc_break *) input WE, input A0, A1, A2, A3, A4, input DPRA0, DPRA1, DPRA2, DPRA3, DPRA4 ); @@ -307,10 +315,12 @@ module RAM32X1D ( always @(posedge clk) if (WE) mem[a] <= D; endmodule -(* abc_box_id = 6, abc_scc_break="D,WE" *) +(* abc_box_id = 6 *) module RAM64X1D ( output DPO, SPO, - input D, WCLK, WE, + (* abc_scc_break *) input D, + input WCLK, + (* abc_scc_break *) input WE, input A0, A1, A2, A3, A4, A5, input DPRA0, DPRA1, DPRA2, DPRA3, DPRA4, DPRA5 ); @@ -325,10 +335,12 @@ module RAM64X1D ( always @(posedge clk) if (WE) mem[a] <= D; endmodule -(* abc_box_id = 7, abc_scc_break="D,WE" *) +(* abc_box_id = 7 *) module RAM128X1D ( output DPO, SPO, - input D, WCLK, WE, + (* abc_scc_break *) input D, + input WCLK, + (* abc_scc_break *) input WE, input [6:0] A, DPRA ); parameter INIT = 128'h0; From 4fe307f1bc02e32ae70f7ef9495f3418303e43e9 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 16 Aug 2019 15:41:17 -0700 Subject: [PATCH 51/94] Compute abc_scc_break and move CI/CO outside of each abc9 --- backends/aiger/xaiger.cc | 42 ------------- passes/techmap/abc9.cc | 123 +++++++++++++++++++++++++-------------- 2 files changed, 80 insertions(+), 85 deletions(-) diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index f49ecbeda..41a79d9dd 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -326,7 +326,6 @@ struct XAigerWriter #endif log_assert(no_loops); - pool seen_boxes; for (auto cell_name : toposort.sorted) { RTLIL::Cell *cell = module->cell(cell_name); log_assert(cell); @@ -335,47 +334,6 @@ struct XAigerWriter if (!box_module || !box_module->attributes.count("\\abc_box_id")) continue; - if (seen_boxes.insert(cell->type).second) { - auto it = box_module->attributes.find("\\abc_carry"); - if (it != box_module->attributes.end()) { - RTLIL::Wire *carry_in = nullptr, *carry_out = nullptr; - auto carry_in_out = it->second.decode_string(); - auto pos = carry_in_out.find(','); - if (pos == std::string::npos) - log_error("'abc_carry' attribute on module '%s' does not contain ','.\n", log_id(cell->type)); - auto carry_in_name = RTLIL::escape_id(carry_in_out.substr(0, pos)); - carry_in = box_module->wire(carry_in_name); - if (!carry_in || !carry_in->port_input) - log_error("'abc_carry' on module '%s' contains '%s' which does not exist or is not an input port.\n", log_id(cell->type), carry_in_name.c_str()); - - auto carry_out_name = RTLIL::escape_id(carry_in_out.substr(pos+1)); - carry_out = box_module->wire(carry_out_name); - if (!carry_out || !carry_out->port_output) - log_error("'abc_carry' on module '%s' contains '%s' which does not exist or is not an output port.\n", log_id(cell->type), carry_out_name.c_str()); - - auto &ports = box_module->ports; - for (auto jt = ports.begin(); jt != ports.end(); ) { - RTLIL::Wire* w = box_module->wire(*jt); - log_assert(w); - if (w == carry_in || w == carry_out) { - jt = ports.erase(jt); - continue; - } - if (w->port_id > carry_in->port_id) - --w->port_id; - if (w->port_id > carry_out->port_id) - --w->port_id; - log_assert(w->port_input || w->port_output); - log_assert(ports[w->port_id-1] == w->name); - ++jt; - } - ports.push_back(carry_in->name); - carry_in->port_id = ports.size(); - ports.push_back(carry_out->name); - carry_out->port_id = ports.size(); - } - } - // Fully pad all unused input connections of this box cell with S0 // Fully pad all undriven output connections of this box cell with anonymous wires // NB: Assume box_module->ports are sorted alphabetically diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index c3c8f879f..8e25d3404 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -76,12 +76,11 @@ inline std::string remap_name(RTLIL::IdString abc_name) return stringf("$abc$%d$%s", map_autoidx, abc_name.c_str()+1); } -void handle_loops(RTLIL::Design *design) +void handle_loops(RTLIL::Design *design, + const dict> &scc_break_inputs) { Pass::call(design, "scc -set_attr abc_scc_id {}"); - dict> abc_scc_break; - // For every unique SCC found, (arbitrarily) find the first // cell in the component, and select (and mark) all its output // wires @@ -116,44 +115,29 @@ void handle_loops(RTLIL::Design *design) cell->attributes.erase(it); } - auto jt = abc_scc_break.find(cell->type); - if (jt == abc_scc_break.end()) { - std::vector ports; - RTLIL::Module* box_module = design->module(cell->type); - if (box_module) { - auto ports_csv = box_module->attributes.at(ID(abc_scc_break), RTLIL::Const::from_string("")).decode_string(); - for (const auto &port_name : split_tokens(ports_csv, ",")) { - auto port_id = RTLIL::escape_id(port_name); - auto kt = cell->connections_.find(port_id); - if (kt == cell->connections_.end()) - log_error("abc_scc_break attribute value '%s' does not exist as port on module '%s'\n", port_name.c_str(), log_id(box_module)); - ports.push_back(port_id); + auto jt = scc_break_inputs.find(cell->type); + if (jt != scc_break_inputs.end()) + for (auto port_name : jt->second) { + RTLIL::SigSpec sig; + auto &rhs = cell->connections_.at(port_name); + for (auto b : rhs) { + Wire *w = b.wire; + if (!w) continue; + w->port_output = true; + w->set_bool_attribute(ID(abc_scc_break)); + w = module->wire(stringf("%s.abci", w->name.c_str())); + if (!w) { + w = module->addWire(stringf("%s.abci", b.wire->name.c_str()), GetSize(b.wire)); + w->port_input = true; + } + else { + log_assert(b.offset < GetSize(w)); + log_assert(w->port_input); + } + sig.append(RTLIL::SigBit(w, b.offset)); } + rhs = sig; } - jt = abc_scc_break.insert(std::make_pair(cell->type, std::move(ports))).first; - } - - for (auto port_name : jt->second) { - RTLIL::SigSpec sig; - auto &rhs = cell->connections_.at(port_name); - for (auto b : rhs) { - Wire *w = b.wire; - if (!w) continue; - w->port_output = true; - w->set_bool_attribute(ID(abc_scc_break)); - w = module->wire(stringf("%s.abci", w->name.c_str())); - if (!w) { - w = module->addWire(stringf("%s.abci", b.wire->name.c_str()), GetSize(b.wire)); - w->port_input = true; - } - else { - log_assert(b.offset < GetSize(w)); - log_assert(w->port_input); - } - sig.append(RTLIL::SigBit(w, b.offset)); - } - rhs = sig; - } } module->fixup_ports(); @@ -288,7 +272,9 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri bool cleanup, vector lut_costs, bool dff_mode, std::string clk_str, bool /*keepff*/, std::string delay_target, std::string /*lutin_shared*/, bool fast_mode, bool show_tempdir, std::string box_file, std::string lut_file, - std::string wire_delay, const dict &box_lookup) + std::string wire_delay, const dict &box_lookup, + const dict> &scc_break_inputs +) { module = current_module; map_autoidx = autoidx++; @@ -427,7 +413,7 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri RTLIL::Selection& sel = design->selection_stack.back(); sel.select(module); - handle_loops(design); + handle_loops(design, scc_break_inputs); Pass::call(design, "aigmap"); @@ -1081,6 +1067,7 @@ struct Abc9Pass : public Pass { extra_args(args, argidx, design); dict box_lookup; + dict> scc_break_inputs; for (auto m : design->modules()) { auto it = m->attributes.find(ID(abc_box_id)); if (it == m->attributes.end()) @@ -1093,6 +1080,56 @@ struct Abc9Pass : public Pass { log_error("Module '%s' has the same abc_box_id = %d value as '%s'.\n", log_id(m), id, log_id(r.first->second)); log_assert(r.second); + + RTLIL::Wire *carry_in = nullptr, *carry_out = nullptr; + for (auto p : m->ports) { + auto w = m->wire(p); + log_assert(w); + if (w->port_input) { + if (w->attributes.count("\\abc_scc_break")) + scc_break_inputs[m->name].insert(p); + if (w->attributes.count("\\abc_carry_in")) { + if (carry_in) + log_error("Module '%s' contains more than one 'abc_carry_in' port.\n", log_id(m)); + carry_in = w; + } + } + if (w->port_output) { + if (w->attributes.count("\\abc_carry_out")) { + if (carry_out) + log_error("Module '%s' contains more than one 'abc_carry_out' port.\n", log_id(m)); + carry_out = w; + } + } + } + if (carry_in || carry_out) { + if (carry_in && !carry_out) + log_error("Module '%s' contains an 'abc_carry_in' port but no 'abc_carry_out' port.\n", log_id(m)); + if (!carry_in && carry_out) + log_error("Module '%s' contains an 'abc_carry_out' port but no 'abc_carry_in' port.\n", log_id(m)); + // Make carry_in the last PI, and carry_out the last PO + // since ABC requires it this way + auto &ports = m->ports; + for (auto it = ports.begin(); it != ports.end(); ) { + RTLIL::Wire* w = m->wire(*it); + log_assert(w); + if (w == carry_in || w == carry_out) { + it = ports.erase(it); + continue; + } + if (w->port_id > carry_in->port_id) + --w->port_id; + if (w->port_id > carry_out->port_id) + --w->port_id; + log_assert(w->port_input || w->port_output); + log_assert(ports[w->port_id-1] == w->name); + ++it; + } + ports.push_back(carry_in->name); + carry_in->port_id = ports.size(); + ports.push_back(carry_out->name); + carry_out->port_id = ports.size(); + } } for (auto mod : design->selected_modules()) @@ -1110,7 +1147,7 @@ struct Abc9Pass : public Pass { if (!dff_mode || !clk_str.empty()) { abc9_module(design, mod, script_file, exe_file, cleanup, lut_costs, dff_mode, clk_str, keepff, delay_target, lutin_shared, fast_mode, show_tempdir, - box_file, lut_file, wire_delay, box_lookup); + box_file, lut_file, wire_delay, box_lookup, scc_break_inputs); continue; } @@ -1256,7 +1293,7 @@ struct Abc9Pass : public Pass { en_sig = assign_map(std::get<3>(it.first)); abc9_module(design, mod, script_file, exe_file, cleanup, lut_costs, !clk_sig.empty(), "$", keepff, delay_target, lutin_shared, fast_mode, show_tempdir, - box_file, lut_file, wire_delay, box_lookup); + box_file, lut_file, wire_delay, box_lookup, scc_break_inputs); assign_map.set(mod); } } From 1c57b1e7ea0128aebef8e78bcf4de9aaf9e42c6a Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 16 Aug 2019 15:56:57 -0700 Subject: [PATCH 52/94] Update abc_* attr in ecp5 and ice40 --- techlibs/ecp5/cells_sim.v | 22 +++++++++++++--------- techlibs/ice40/cells_sim.v | 10 ++++++++-- 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/techlibs/ecp5/cells_sim.v b/techlibs/ecp5/cells_sim.v index 3d343b315..864a3550f 100644 --- a/techlibs/ecp5/cells_sim.v +++ b/techlibs/ecp5/cells_sim.v @@ -15,10 +15,13 @@ module L6MUX21 (input D0, D1, SD, output Z); endmodule // --------------------------------------- -(* abc_box_id=1, abc_carry="CIN,COUT", lib_whitebox *) -module CCU2C(input CIN, A0, B0, C0, D0, A1, B1, C1, D1, - output S0, S1, COUT); - +(* abc_box_id=1, lib_whitebox *) +module CCU2C( + (* abc_carry_in *) input CIN, + input A0, B0, C0, D0, A1, B1, C1, D1, + output S0, S1, + (* abc_carry_out *) output COUT +); parameter [15:0] INIT0 = 16'h0000; parameter [15:0] INIT1 = 16'h0000; parameter INJECT1_0 = "YES"; @@ -104,12 +107,13 @@ module PFUMX (input ALUT, BLUT, C0, output Z); endmodule // --------------------------------------- -//(* abc_box_id=2, abc_scc_break="DI,WAD,WRE" *) +//(* abc_box_id=2 *) module TRELLIS_DPR16X4 ( - input [3:0] DI, - input [3:0] WAD, - input WRE, WCK, - input [3:0] RAD, + (* abc_scc_break *) input [3:0] DI, + (* abc_scc_break *) input [3:0] WAD, + (* abc_scc_break *) input WRE, + input WCK, + input [3:0] RAD, output [3:0] DO ); parameter WCKMUX = "WCK"; diff --git a/techlibs/ice40/cells_sim.v b/techlibs/ice40/cells_sim.v index 2205be27d..5b18fec27 100644 --- a/techlibs/ice40/cells_sim.v +++ b/techlibs/ice40/cells_sim.v @@ -141,8 +141,14 @@ module SB_CARRY (output CO, input I0, I1, CI); assign CO = (I0 && I1) || ((I0 || I1) && CI); endmodule -(* abc_box_id = 1, abc_carry="CI,CO", lib_whitebox *) -module \$__ICE40_FULL_ADDER (output CO, O, input A, B, CI); +(* abc_box_id = 1, lib_whitebox *) +module \$__ICE40_FULL_ADDER ( + (* abc_carry_out *) output CO, + output O, + input A, + input B, + (* abc_carry_in *) input CI +); SB_CARRY carry ( .I0(A), .I1(B), From d26c512d7ef5369f26436540efee40201e480f7f Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 16 Aug 2019 16:07:29 -0700 Subject: [PATCH 53/94] Add doc for abc_* attributes --- README.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/README.md b/README.md index d9989eb29..5b30f6bae 100644 --- a/README.md +++ b/README.md @@ -405,6 +405,22 @@ Verilog Attributes and non-standard features blackboxes and whiteboxes. Use ``read_verilog -specify`` to enable this functionality. (By default specify .. endspecify blocks are ignored.) +- The module attribute ``abc_box_id`` specifies a positive integer linking a + blackbox or whitebox definition to a corresponding entry in a `abc9` + box-file. + +- The port attribute ``abc_scc_break`` indicates a module input port that will + be treated as a primary output during `abc9` techmapping. Doing so eliminates + the possibility of a strongly-connected component (i.e. a combinatorial loop) + existing. Typically, this is specified for sequential inputs on otherwise + combinatorial boxes -- for example, applying ``abc_scc_break`` onto the `D` + port of a LUTRAM cell prevents `abc9` from interpreting any `Q` -> `D` paths + as a combinatorial loop. + +- The port attribute ``abc_carry_in`` and ``abc_carry_out`` attributes mark + the carry-in and carry-out ports of a box. This information is necessary for + `abc9` to preserve the integrity of carry-chains. + Non-standard or SystemVerilog features for formal verification ============================================================== From 5abe133323b2a6a46959f796c4730b2d70cdea26 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 16 Aug 2019 16:38:49 -0700 Subject: [PATCH 54/94] Use ID() --- passes/techmap/abc9.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 8e25d3404..4cdd392b5 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -1086,16 +1086,16 @@ struct Abc9Pass : public Pass { auto w = m->wire(p); log_assert(w); if (w->port_input) { - if (w->attributes.count("\\abc_scc_break")) + if (w->attributes.count(ID(abc_scc_break))) scc_break_inputs[m->name].insert(p); - if (w->attributes.count("\\abc_carry_in")) { + if (w->attributes.count(ID(abc_carry_in))) { if (carry_in) log_error("Module '%s' contains more than one 'abc_carry_in' port.\n", log_id(m)); carry_in = w; } } if (w->port_output) { - if (w->attributes.count("\\abc_carry_out")) { + if (w->attributes.count(ID(abc_carry_out))) { if (carry_out) log_error("Module '%s' contains more than one 'abc_carry_out' port.\n", log_id(m)); carry_out = w; From f95853c8228ec8310a1142fe29eea85b765ea3b4 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 17 Aug 2019 11:29:37 +0200 Subject: [PATCH 55/94] Add pmgen "fallthrough" statement Signed-off-by: Clifford Wolf --- passes/pmgen/README.md | 3 +++ passes/pmgen/pmgen.py | 17 ++++++++++++++--- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/passes/pmgen/README.md b/passes/pmgen/README.md index be908ef0b..5f6a8ab1b 100644 --- a/passes/pmgen/README.md +++ b/passes/pmgen/README.md @@ -315,6 +315,9 @@ state variables used to pass arguments. Subpatterns cann be called recursively. +If a `subpattern` statement is preceded by a `fallthrough` statement, this is +equivalent to calling the subpattern at the end of the preceding block. + Generate Blocks --------------- diff --git a/passes/pmgen/pmgen.py b/passes/pmgen/pmgen.py index 6950a99c0..8401e1295 100644 --- a/passes/pmgen/pmgen.py +++ b/passes/pmgen/pmgen.py @@ -141,12 +141,23 @@ def process_pmgfile(f, filename): assert current_pattern is not None - if cmd == "subpattern": + if cmd == "fallthrough": block = dict() - block["type"] = "final" - block["pattern"] = (current_pattern, current_subpattern) + block["type"] = "fallthrough" blocks.append(block) line = line.split() + assert len(line) == 1 + continue + + if cmd == "subpattern": + if len(blocks) == 0 or blocks[-1]["type"] != "fallthrough": + block = dict() + block["type"] = "final" + block["pattern"] = (current_pattern, current_subpattern) + blocks.append(block) + elif len(blocks) and blocks[-1]["type"] == "fallthrough": + del blocks[-1] + line = line.split() assert len(line) == 2 current_subpattern = line[1] subpattern_args[(current_pattern, current_subpattern)] = list() From 318ae0351cdce550cd2f7bf8f5cccc3ecf97cb60 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 17 Aug 2019 13:53:55 +0200 Subject: [PATCH 56/94] Improvements in "test_pmgen -generate" Signed-off-by: Clifford Wolf --- passes/pmgen/test_pmgen.cc | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/passes/pmgen/test_pmgen.cc b/passes/pmgen/test_pmgen.cc index 94e59f62e..9f42a95d0 100644 --- a/passes/pmgen/test_pmgen.cc +++ b/passes/pmgen/test_pmgen.cc @@ -150,6 +150,8 @@ void generate_pattern(std::function)> run, const int modcnt = 0; int maxsubcnt = 4; + int timeout = 0; + vector mods; while (modcnt < 100) { @@ -158,6 +160,9 @@ void generate_pattern(std::function)> run, const while (modcnt < 100 && submodcnt < maxsubcnt && itercnt++ < 1000) { + if (timeout++ > 10000) + log_error("pmgen generator is stuck: 10000 iterations an no matching module generated.\n"); + pm matcher(mod, mod->cells()); matcher.rng(1); @@ -174,25 +179,40 @@ void generate_pattern(std::function)> run, const { bool found_match = false; run(matcher, [&](){ found_match = true; }); + cellcnt = GetSize(mod->cells()); if (found_match) { Module *m = design->addModule(stringf("\\pmtest_%s_%s_%05d", pmclass, pattern, modcnt++)); + log("Creating module %s with %d cells.\n", log_id(m), cellcnt); mod->cloneInto(m); pmtest_addports(m); + mods.push_back(m); submodcnt++; + timeout = 0; } - - cellcnt = GetSize(mod->cells()); } matcher.generate_mode = true; run(matcher, [](){}); } + if (submodcnt) + maxsubcnt *= 2; + design->remove(mod); - maxsubcnt *= 2; } + + Module *m = design->addModule(stringf("\\pmtest_%s_%s", pmclass, pattern)); + log("Creating module %s with %d cells.\n", log_id(m), GetSize(mods)); + for (auto mod : mods) { + Cell *c = m->addCell(mod->name, mod->name); + for (auto port : mod->ports) { + Wire *w = m->addWire(NEW_ID, GetSize(mod->wire(port))); + c->setPort(port, w); + } + } + pmtest_addports(m); } struct TestPmgenPass : public Pass { From f3405fb04878dc030e82ad49a1c12d7fd0b489f0 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 17 Aug 2019 13:54:18 +0200 Subject: [PATCH 57/94] Refactor pmgen rollback mechanism Signed-off-by: Clifford Wolf --- passes/pmgen/pmgen.py | 53 +++++++++++++++++-------------------------- 1 file changed, 21 insertions(+), 32 deletions(-) diff --git a/passes/pmgen/pmgen.py b/passes/pmgen/pmgen.py index 8401e1295..18c3bf5a5 100644 --- a/passes/pmgen/pmgen.py +++ b/passes/pmgen/pmgen.py @@ -362,8 +362,7 @@ with open(outfile, "w") as f: print(" dict> sigusers;", file=f) print(" pool blacklist_cells;", file=f) print(" pool autoremove_cells;", file=f) - print(" bool blacklist_dirty;", file=f) - print(" vector> rollback_stack;", file=f) + print(" dict rollback_cache;", file=f) print(" int rollback;", file=f) print("", file=f) @@ -399,31 +398,20 @@ with open(outfile, "w") as f: print("", file=f) print(" void blacklist(Cell *cell) {", file=f) - print(" if (cell != nullptr) {", file=f) - print(" if (blacklist_cells.insert(cell).second)", file=f) - print(" blacklist_dirty = true;", file=f) + print(" if (cell != nullptr && blacklist_cells.insert(cell).second) {", file=f) + print(" auto ptr = rollback_cache.find(cell);", file=f) + print(" if (ptr == rollback_cache.end()) return;", file=f) + print(" int rb = ptr->second;", file=f) + print(" if (rollback == 0 || rollback > rb)", file=f) + print(" rollback = rb;", file=f) print(" }", file=f) print(" }", file=f) print("", file=f) - print(" void check_blacklist() {", file=f) - print(" if (!blacklist_dirty)", file=f) - print(" return;", file=f) - print(" blacklist_dirty = false;", file=f) - print(" for (int i = 0; i < GetSize(rollback_stack); i++)", file=f) - print(" if (blacklist_cells.count(rollback_stack[i].first)) {", file=f) - print(" rollback = rollback_stack[i].second;", file=f) - print(" rollback_stack.resize(i);", file=f) - print(" return;", file=f) - print(" }", file=f) - print(" }", file=f) - print("", file=f) - print(" void autoremove(Cell *cell) {", file=f) print(" if (cell != nullptr) {", file=f) - print(" if (blacklist_cells.insert(cell).second)", file=f) - print(" blacklist_dirty = true;", file=f) print(" autoremove_cells.insert(cell);", file=f) + print(" blacklist(cell);", file=f) print(" }", file=f) print(" }", file=f) print("", file=f) @@ -492,14 +480,13 @@ with open(outfile, "w") as f: print(" accept_cnt = 0;", file=f) print(" on_accept = on_accept_f;", file=f) print(" rollback = 0;", file=f) - print(" blacklist_dirty = false;", file=f) for s, t in sorted(state_types[current_pattern].items()): if t.endswith("*"): print(" st_{}.{} = nullptr;".format(current_pattern, s), file=f) else: print(" st_{}.{} = {}();".format(current_pattern, s, t), file=f) print(" block_{}(1);".format(patterns[current_pattern]), file=f) - print(" log_assert(rollback_stack.empty());", file=f) + print(" log_assert(rollback_cache.empty());", file=f) print(" return accept_cnt;", file=f) print(" }", file=f) print("", file=f) @@ -587,9 +574,9 @@ with open(outfile, "w") as f: if block["type"] == "code": print("", file=f) - print("#define reject do { check_blacklist(); goto rollback_label; } while(0)", file=f) - print("#define accept do { accept_cnt++; on_accept(); check_blacklist(); if (rollback) goto rollback_label; } while(0)", file=f) - print("#define finish do { rollback = -1; rollback_stack.clean(); goto rollback_label; } while(0)", file=f) + print("#define reject do { goto rollback_label; } while(0)", file=f) + print("#define accept do { accept_cnt++; on_accept(); if (rollback) goto rollback_label; } while(0)", file=f) + print("#define finish do { rollback = -1; goto rollback_label; } while(0)", file=f) print("#define branch do {{ block_{}(recursion+1); if (rollback) goto rollback_label; }} while(0)".format(index+1), file=f) print("#define subpattern(pattern_name) do {{ block_subpattern_{}_ ## pattern_name (recursion+1); if (rollback) goto rollback_label; }} while(0)".format(current_pattern), file=f) @@ -610,10 +597,12 @@ with open(outfile, "w") as f: print(" YS_ATTRIBUTE(unused);", file=f) if len(block["fcode"]): - print("#define accept do { accept_cnt++; on_accept(); check_blacklist(); } while(0)", file=f) - print("#define finish do { rollback = -1; rollback_stack.clean(); return; } while(0)", file=f) + print("#define accept do { accept_cnt++; on_accept(); } while(0)", file=f) + print("#define finish do { rollback = -1; goto finish_label; } while(0)", file=f) for line in block["fcode"]: print(" " + line, file=f) + print("finish_label:", file=f) + print(" YS_ATTRIBUTE(unused);", file=f) print("#undef accept", file=f) print("#undef finish", file=f) @@ -664,11 +653,11 @@ with open(outfile, "w") as f: print(" if (!({})) continue;".format(expr), file=f) if block["semioptional"] or block["genargs"] is not None: print(" found_any_match = true;", file=f) - print(" rollback_stack.push_back(make_pair(cells[idx], recursion));", file=f) + print(" auto rollback_ptr = rollback_cache.insert(make_pair(cells[idx], recursion));", file=f) print(" block_{}(recursion+1);".format(index+1), file=f) - print(" if (rollback == 0) {", file=f) - print(" rollback_stack.pop_back();", file=f) - print(" } else {", file=f) + print(" if (rollback_ptr.second)", file=f) + print(" rollback_cache.erase(rollback_ptr.first);", file=f) + print(" if (rollback) {", file=f) print(" if (rollback != recursion) {{".format(index+1), file=f) print(" {} = backup_{};".format(block["cell"], block["cell"]), file=f) print(" return;", file=f) @@ -690,7 +679,7 @@ with open(outfile, "w") as f: print(" {} = backup_{};".format(block["cell"], block["cell"]), file=f) if block["genargs"] is not None: - print("#define finish do { rollback = -1; rollback_stack.clean(); return; } while(0)", file=f) + print("#define finish do { rollback = -1; return; } while(0)", file=f) print(" if (generate_mode && !found_any_match) {", file=f) if len(block["genargs"]) == 1: print(" if (rng(100) >= {}) return;".format(block["genargs"][0]), file=f) From f20be90436b32e853d68c7e102a65d43f3843d91 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 17 Aug 2019 14:05:10 +0200 Subject: [PATCH 58/94] Add test for pmtest_test "reduce" demo pattern Signed-off-by: Clifford Wolf --- tests/various/pmgen_reduce.ys | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 tests/various/pmgen_reduce.ys diff --git a/tests/various/pmgen_reduce.ys b/tests/various/pmgen_reduce.ys new file mode 100644 index 000000000..c214d3f25 --- /dev/null +++ b/tests/various/pmgen_reduce.ys @@ -0,0 +1,21 @@ +test_pmgen -generate reduce +hierarchy -top pmtest_test_pmgen_pm_reduce +flatten; opt_clean + +design -save gold +test_pmgen -reduce_chain +design -stash gate + +design -copy-from gold -as gold pmtest_test_pmgen_pm_reduce +design -copy-from gate -as gate pmtest_test_pmgen_pm_reduce +miter -equiv -flatten -make_assert gold gate miter +sat -verify -prove-asserts miter + +design -load gold +test_pmgen -reduce_tree +design -stash gate + +design -copy-from gold -as gold pmtest_test_pmgen_pm_reduce +design -copy-from gate -as gate pmtest_test_pmgen_pm_reduce +miter -equiv -flatten -make_assert gold gate miter +sat -verify -prove-asserts miter From 9e940f127691fe9e4fc3c4c92f6f0dc306aa9fb8 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 17 Aug 2019 14:37:07 +0200 Subject: [PATCH 59/94] Speed up "make test" and related cleanups Signed-off-by: Clifford Wolf --- Makefile | 2 +- tests/fsm/run-test.sh | 2 +- tests/simple_abc9/run-test.sh | 3 ++- tests/various/.gitignore | 1 + tests/various/run-test.sh | 16 ++++++++++++---- tests/various/shregmap.ys | 10 +++++----- 6 files changed, 22 insertions(+), 12 deletions(-) diff --git a/Makefile b/Makefile index 95b5d451b..f4ff493b0 100644 --- a/Makefile +++ b/Makefile @@ -682,6 +682,7 @@ endif test: $(TARGETS) $(EXTRA_TARGETS) +cd tests/simple && bash run-test.sh $(SEEDOPT) + +cd tests/simple_abc9 && bash run-test.sh $(SEEDOPT) +cd tests/hana && bash run-test.sh $(SEEDOPT) +cd tests/asicworld && bash run-test.sh $(SEEDOPT) # +cd tests/realmath && bash run-test.sh $(SEEDOPT) @@ -696,7 +697,6 @@ test: $(TARGETS) $(EXTRA_TARGETS) +cd tests/opt && bash run-test.sh +cd tests/aiger && bash run-test.sh $(ABCOPT) +cd tests/arch && bash run-test.sh - +cd tests/simple_abc9 && bash run-test.sh $(SEEDOPT) @echo "" @echo " Passed \"make test\"." @echo "" diff --git a/tests/fsm/run-test.sh b/tests/fsm/run-test.sh index cf506470d..fbdcbf048 100755 --- a/tests/fsm/run-test.sh +++ b/tests/fsm/run-test.sh @@ -6,7 +6,7 @@ set -e OPTIND=1 -count=100 +count=50 seed="" # default to no seed specified while getopts "c:S:" opt do diff --git a/tests/simple_abc9/run-test.sh b/tests/simple_abc9/run-test.sh index 4935d41ad..49ae23338 100755 --- a/tests/simple_abc9/run-test.sh +++ b/tests/simple_abc9/run-test.sh @@ -18,5 +18,6 @@ if ! which iverilog > /dev/null ; then fi cp ../simple/*.v . +cp ../simple/*.sv . DOLLAR='?' -exec ${MAKE:-make} -f ../tools/autotest.mk $seed *.v EXTRA_FLAGS="-p 'hierarchy; synth -run coarse; opt -full; techmap; abc9 -lut 4 -box ../abc.box; stat; check -assert; select -assert-none t:${DOLLAR}_NOT_ t:${DOLLAR}_AND_ %%'" +exec ${MAKE:-make} -f ../tools/autotest.mk $seed *.v EXTRA_FLAGS="-n 300 -p 'hierarchy; synth -run coarse; opt -full; techmap; abc9 -lut 4 -box ../abc.box; stat; check -assert; select -assert-none t:${DOLLAR}_NOT_ t:${DOLLAR}_AND_ %%'" diff --git a/tests/various/.gitignore b/tests/various/.gitignore index 31078b298..4b286fd61 100644 --- a/tests/various/.gitignore +++ b/tests/various/.gitignore @@ -2,3 +2,4 @@ /*.out /write_gzip.v /write_gzip.v.gz +/run-test.mk diff --git a/tests/various/run-test.sh b/tests/various/run-test.sh index 92b905765..ea56b70f0 100755 --- a/tests/various/run-test.sh +++ b/tests/various/run-test.sh @@ -1,12 +1,20 @@ #!/usr/bin/env bash set -e +{ +echo "all::" for x in *.ys; do - echo "Running $x.." - ../../yosys -ql ${x%.ys}.log $x + echo "all:: run-$x" + echo "run-$x:" + echo " @echo 'Running $x..'" + echo " @../../yosys -ql ${x%.ys}.log $x" done for s in *.sh; do if [ "$s" != "run-test.sh" ]; then - echo "Running $s.." - bash $s + echo "all:: run-$s" + echo "run-$s:" + echo " @echo 'Running $s..'" + echo " @bash $s" fi done +} > run-test.mk +exec ${MAKE:-make} -f run-test.mk diff --git a/tests/various/shregmap.ys b/tests/various/shregmap.ys index d644a88aa..5c9c78dd2 100644 --- a/tests/various/shregmap.ys +++ b/tests/various/shregmap.ys @@ -45,7 +45,7 @@ shregmap -tech xilinx stat # show -width -write_verilog -noexpr -norename +# write_verilog -noexpr -norename select -assert-count 1 t:$_DFF_P_ select -assert-count 2 t:$__XILINX_SHREG_ @@ -59,8 +59,8 @@ prep miter -equiv -flatten -make_assert -make_outputs gold gate miter sat -verify -prove-asserts -show-ports -seq 5 miter -design -load gold -stat +# design -load gold +# stat -design -load gate -stat +# design -load gate +# stat From 27d59dc0550432458d4bd636081a7b9f4b4411fe Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 17 Aug 2019 14:47:02 +0200 Subject: [PATCH 60/94] Fix erroneous ifndef-NDEBUG in verific.cc Signed-off-by: Clifford Wolf --- frontends/verific/verific.cc | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 64152c9cb..c5eef4b55 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -1789,10 +1789,8 @@ struct VerificExtNets new_net = new Net(name.c_str()); nl->Add(new_net); - #ifndef NDEBUG - Net *n = route_up(new_net, port->IsOutput(), ca_nl, ca_net); + Net *n YS_ATTRIBUTE(unused) = route_up(new_net, port->IsOutput(), ca_nl, ca_net); log_assert(n == ca_net); - #endif } if (verific_verbose) From dbe3cb9708802af304a4f274d9161b3dc3aae5c5 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Sun, 18 Aug 2019 10:49:17 +0200 Subject: [PATCH 61/94] Ignore all generated headers for pmgen pass --- passes/pmgen/.gitignore | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/passes/pmgen/.gitignore b/passes/pmgen/.gitignore index 0ad36ea2c..e52f3282f 100644 --- a/passes/pmgen/.gitignore +++ b/passes/pmgen/.gitignore @@ -1,2 +1 @@ -/ice40_dsp_pm.h -/peepopt_pm.h +/*_pm.h From f5170a7eda6fddaf482896a2ad67da4bb3131d7b Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Sun, 18 Aug 2019 21:28:45 -0700 Subject: [PATCH 62/94] Removal of more `stat` calls from tests --- tests/various/muxpack.ys | 30 +++++++++++++++--------------- tests/various/opt_rmdff.ys | 10 +++++----- tests/various/shregmap.ys | 12 ++++++------ 3 files changed, 26 insertions(+), 26 deletions(-) diff --git a/tests/various/muxpack.ys b/tests/various/muxpack.ys index af23fcec8..3e90419af 100644 --- a/tests/various/muxpack.ys +++ b/tests/various/muxpack.ys @@ -6,7 +6,7 @@ prep design -save gold muxpack opt -stat +#stat select -assert-count 0 t:$mux select -assert-count 1 t:$pmux design -stash gate @@ -21,7 +21,7 @@ prep design -save gold muxpack opt -stat +#stat select -assert-count 0 t:$mux select -assert-count 1 t:$pmux design -stash gate @@ -52,7 +52,7 @@ prep design -save gold muxpack opt -stat +#stat select -assert-count 0 t:$mux select -assert-count 2 t:$pmux design -stash gate @@ -67,7 +67,7 @@ prep design -save gold muxpack opt -stat +#stat select -assert-count 0 t:$mux select -assert-count 1 t:$pmux design -stash gate @@ -82,7 +82,7 @@ prep design -save gold muxpack opt -stat +#stat select -assert-count 0 t:$mux select -assert-count 1 t:$pmux design -stash gate @@ -97,7 +97,7 @@ prep design -save gold muxpack opt -stat +#stat select -assert-count 0 t:$mux select -assert-count 1 t:$pmux design -stash gate @@ -112,7 +112,7 @@ prep design -save gold muxpack opt -stat +#stat select -assert-count 0 t:$mux select -assert-count 1 t:$pmux design -stash gate @@ -127,7 +127,7 @@ prep design -save gold muxpack opt -stat +#stat select -assert-count 0 t:$mux select -assert-count 1 t:$pmux design -stash gate @@ -142,7 +142,7 @@ prep design -save gold muxpack opt -stat +#stat select -assert-count 7 t:$mux select -assert-count 0 t:$pmux design -stash gate @@ -157,7 +157,7 @@ prep design -save gold muxpack opt -stat +#stat select -assert-count 4 t:$mux select -assert-count 0 t:$pmux design -stash gate @@ -172,7 +172,7 @@ prep design -save gold muxpack opt -stat +#stat select -assert-count 3 t:$mux select -assert-count 0 t:$pmux design -stash gate @@ -204,7 +204,7 @@ prep design -save gold muxpack opt -stat +#stat select -assert-count 0 t:$mux select -assert-count 2 t:$pmux design -stash gate @@ -222,7 +222,7 @@ opt -fast -mux_undef select -assert-count 2 t:$pmux muxpack opt -stat +#stat select -assert-count 0 t:$mux select -assert-count 1 t:$pmux design -stash gate @@ -240,7 +240,7 @@ opt -fast -mux_undef select -assert-count 2 t:$pmux muxpack opt -stat +#stat select -assert-count 0 t:$mux select -assert-count 2 t:$pmux design -stash gate @@ -258,7 +258,7 @@ opt -fast -mux_undef select -assert-count 2 t:$pmux muxpack opt -stat +#stat select -assert-count 0 t:$mux select -assert-count 2 t:$pmux design -stash gate diff --git a/tests/various/opt_rmdff.ys b/tests/various/opt_rmdff.ys index 081f81782..83a162f44 100644 --- a/tests/various/opt_rmdff.ys +++ b/tests/various/opt_rmdff.ys @@ -19,8 +19,8 @@ hierarchy -top equiv equiv_simple -undef equiv_status -assert -design -load gold -stat - -design -load gate -stat +#design -load gold +#stat +# +#design -load gate +#stat diff --git a/tests/various/shregmap.ys b/tests/various/shregmap.ys index 5c9c78dd2..0e5fe882b 100644 --- a/tests/various/shregmap.ys +++ b/tests/various/shregmap.ys @@ -11,7 +11,7 @@ shregmap -init opt -stat +# stat # show -width select -assert-count 1 t:$_DFF_P_ select -assert-count 2 t:$__SHREG_DFF_P_ @@ -26,11 +26,11 @@ prep miter -equiv -flatten -make_assert -make_outputs gold gate miter sat -verify -prove-asserts -show-ports -seq 5 miter -design -load gold -stat +#design -load gold +#stat -design -load gate -stat +#design -load gate +#stat ########## @@ -43,7 +43,7 @@ design -save gold simplemap t:$dff t:$dffe shregmap -tech xilinx -stat +#stat # show -width # write_verilog -noexpr -norename select -assert-count 1 t:$_DFF_P_ From 21699e5840b71433eb242d9c60f1635908717f5e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 19 Aug 2019 13:04:57 +0200 Subject: [PATCH 63/94] Add *.sv to tests/simple_abc9/.gitignore Signed-off-by: Clifford Wolf --- tests/simple_abc9/.gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/simple_abc9/.gitignore b/tests/simple_abc9/.gitignore index 598951333..2355aea29 100644 --- a/tests/simple_abc9/.gitignore +++ b/tests/simple_abc9/.gitignore @@ -1,3 +1,4 @@ *.v +*.sv *.log *.out From 24971fda87e66af528aeeffab841a64fc960410a Mon Sep 17 00:00:00 2001 From: Jakob Wenzel Date: Mon, 19 Aug 2019 14:17:36 +0200 Subject: [PATCH 64/94] handle real values when deriving ast modules --- frontends/ast/ast.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 0d6626b19..82283fb5b 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -1502,7 +1502,10 @@ std::string AstModule::derive_common(RTLIL::Design *design, dictstr.c_str(), log_signal(RTLIL::SigSpec(parameters[para_id]))); delete child->children.at(0); - if ((parameters[para_id].flags & RTLIL::CONST_FLAG_STRING) != 0) + if ((parameters[para_id].flags & RTLIL::CONST_FLAG_REAL) != 0) { + child->children[0] = new AstNode(AST_REALVALUE); + child->children[0]->realvalue = std::stod(parameters[para_id].decode_string()); + } else if ((parameters[para_id].flags & RTLIL::CONST_FLAG_STRING) != 0) child->children[0] = AstNode::mkconst_str(parameters[para_id].decode_string()); else child->children[0] = AstNode::mkconst_bits(parameters[para_id].bits, (parameters[para_id].flags & RTLIL::CONST_FLAG_SIGNED) != 0); From 4a942ba7b9bb76f207adf23369f46d31f7607b75 Mon Sep 17 00:00:00 2001 From: whitequark Date: Mon, 19 Aug 2019 16:44:23 +0000 Subject: [PATCH 65/94] proc_clean: fix order of switch insertion. Fixes #1268. --- Makefile | 1 + passes/proc/proc_clean.cc | 3 +-- tests/proc/.gitignore | 1 + tests/proc/bug_1268.v | 23 +++++++++++++++++++++++ tests/proc/bug_1268.ys | 5 +++++ tests/proc/run-test.sh | 6 ++++++ 6 files changed, 37 insertions(+), 2 deletions(-) create mode 100644 tests/proc/.gitignore create mode 100644 tests/proc/bug_1268.v create mode 100644 tests/proc/bug_1268.ys create mode 100755 tests/proc/run-test.sh diff --git a/Makefile b/Makefile index 16341a268..382f79546 100644 --- a/Makefile +++ b/Makefile @@ -695,6 +695,7 @@ test: $(TARGETS) $(EXTRA_TARGETS) +cd tests/various && bash run-test.sh +cd tests/sat && bash run-test.sh +cd tests/svinterfaces && bash run-test.sh $(SEEDOPT) + +cd tests/proc && bash run-test.sh +cd tests/opt && bash run-test.sh +cd tests/aiger && bash run-test.sh $(ABCOPT) +cd tests/arch && bash run-test.sh diff --git a/passes/proc/proc_clean.cc b/passes/proc/proc_clean.cc index 97f4c6573..114c6ab03 100644 --- a/passes/proc/proc_clean.cc +++ b/passes/proc/proc_clean.cc @@ -69,8 +69,7 @@ void proc_clean_switch(RTLIL::SwitchRule *sw, RTLIL::CaseRule *parent, bool &did did_something = true; for (auto &action : sw->cases[0]->actions) parent->actions.push_back(action); - for (auto sw2 : sw->cases[0]->switches) - parent->switches.push_back(sw2); + parent->switches.insert(parent->switches.begin(), sw->cases[0]->switches.begin(), sw->cases[0]->switches.end()); sw->cases[0]->switches.clear(); delete sw->cases[0]; sw->cases.clear(); diff --git a/tests/proc/.gitignore b/tests/proc/.gitignore new file mode 100644 index 000000000..397b4a762 --- /dev/null +++ b/tests/proc/.gitignore @@ -0,0 +1 @@ +*.log diff --git a/tests/proc/bug_1268.v b/tests/proc/bug_1268.v new file mode 100644 index 000000000..698ac937a --- /dev/null +++ b/tests/proc/bug_1268.v @@ -0,0 +1,23 @@ +module gold (input clock, ctrl, din, output reg dout); + always @(posedge clock) begin + if (1'b1) begin + if (1'b0) begin end else begin + dout <= 0; + end + if (ctrl) + dout <= din; + end + end +endmodule + +module gate (input clock, ctrl, din, output reg dout); + always @(posedge clock) begin + if (1'b1) begin + if (1'b0) begin end else begin + dout <= 0; + end + end + if (ctrl) + dout <= din; + end +endmodule diff --git a/tests/proc/bug_1268.ys b/tests/proc/bug_1268.ys new file mode 100644 index 000000000..b73e94449 --- /dev/null +++ b/tests/proc/bug_1268.ys @@ -0,0 +1,5 @@ +read_verilog bug_1268.v +proc +equiv_make gold gate equiv +equiv_induct +equiv_status -assert diff --git a/tests/proc/run-test.sh b/tests/proc/run-test.sh new file mode 100755 index 000000000..44ce7e674 --- /dev/null +++ b/tests/proc/run-test.sh @@ -0,0 +1,6 @@ +#!/bin/bash +set -e +for x in *.ys; do + echo "Running $x.." + ../../yosys -ql ${x%.ys}.log $x +done From d81a090d89d87837d3e18f9c724fe5c89ddf1f64 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 19 Aug 2019 09:56:17 -0700 Subject: [PATCH 66/94] Unify abc_carry_{in,out} into abc_carry and use port dir, as @mithro --- passes/techmap/abc9.cc | 12 ++++++------ techlibs/ecp5/cells_sim.v | 4 ++-- techlibs/ice40/cells_sim.v | 4 ++-- techlibs/xilinx/cells_sim.v | 4 ++-- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 4cdd392b5..3768786d4 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -1088,25 +1088,25 @@ struct Abc9Pass : public Pass { if (w->port_input) { if (w->attributes.count(ID(abc_scc_break))) scc_break_inputs[m->name].insert(p); - if (w->attributes.count(ID(abc_carry_in))) { + if (w->attributes.count(ID(abc_carry))) { if (carry_in) - log_error("Module '%s' contains more than one 'abc_carry_in' port.\n", log_id(m)); + log_error("Module '%s' contains more than one 'abc_carry' input port.\n", log_id(m)); carry_in = w; } } if (w->port_output) { - if (w->attributes.count(ID(abc_carry_out))) { + if (w->attributes.count(ID(abc_carry))) { if (carry_out) - log_error("Module '%s' contains more than one 'abc_carry_out' port.\n", log_id(m)); + log_error("Module '%s' contains more than one 'abc_carry' input port.\n", log_id(m)); carry_out = w; } } } if (carry_in || carry_out) { if (carry_in && !carry_out) - log_error("Module '%s' contains an 'abc_carry_in' port but no 'abc_carry_out' port.\n", log_id(m)); + log_error("Module '%s' contains an 'abc_carry' input port but no output port.\n", log_id(m)); if (!carry_in && carry_out) - log_error("Module '%s' contains an 'abc_carry_out' port but no 'abc_carry_in' port.\n", log_id(m)); + log_error("Module '%s' contains an 'abc_carry' output port but no input port.\n", log_id(m)); // Make carry_in the last PI, and carry_out the last PO // since ABC requires it this way auto &ports = m->ports; diff --git a/techlibs/ecp5/cells_sim.v b/techlibs/ecp5/cells_sim.v index 864a3550f..2fcb0369e 100644 --- a/techlibs/ecp5/cells_sim.v +++ b/techlibs/ecp5/cells_sim.v @@ -17,10 +17,10 @@ endmodule // --------------------------------------- (* abc_box_id=1, lib_whitebox *) module CCU2C( - (* abc_carry_in *) input CIN, + (* abc_carry *) input CIN, input A0, B0, C0, D0, A1, B1, C1, D1, output S0, S1, - (* abc_carry_out *) output COUT + (* abc_carry *) output COUT ); parameter [15:0] INIT0 = 16'h0000; parameter [15:0] INIT1 = 16'h0000; diff --git a/techlibs/ice40/cells_sim.v b/techlibs/ice40/cells_sim.v index 5b18fec27..ab04808f4 100644 --- a/techlibs/ice40/cells_sim.v +++ b/techlibs/ice40/cells_sim.v @@ -143,11 +143,11 @@ endmodule (* abc_box_id = 1, lib_whitebox *) module \$__ICE40_FULL_ADDER ( - (* abc_carry_out *) output CO, + (* abc_carry *) output CO, output O, input A, input B, - (* abc_carry_in *) input CI + (* abc_carry *) input CI ); SB_CARRY carry ( .I0(A), diff --git a/techlibs/xilinx/cells_sim.v b/techlibs/xilinx/cells_sim.v index 910d0e246..bec9ea1a0 100644 --- a/techlibs/xilinx/cells_sim.v +++ b/techlibs/xilinx/cells_sim.v @@ -183,9 +183,9 @@ endmodule (* abc_box_id = 4, lib_whitebox *) module CARRY4( - (* abc_carry_out *) output [3:0] CO, + (* abc_carry *) output [3:0] CO, output [3:0] O, - (* abc_carry_in *) input CI, + (* abc_carry *) input CI, input CYINIT, input [3:0] DI, S ); From c36fca86f7d096e64b2a0eb6a3c4f5c427c7e537 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 19 Aug 2019 09:59:57 -0700 Subject: [PATCH 67/94] Update doc --- README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 5b30f6bae..fd4d4beb5 100644 --- a/README.md +++ b/README.md @@ -417,9 +417,10 @@ Verilog Attributes and non-standard features port of a LUTRAM cell prevents `abc9` from interpreting any `Q` -> `D` paths as a combinatorial loop. -- The port attribute ``abc_carry_in`` and ``abc_carry_out`` attributes mark - the carry-in and carry-out ports of a box. This information is necessary for - `abc9` to preserve the integrity of carry-chains. +- The port attribute ``abc_carry`` marks the carry-in (if an input port) and + carry-out (if output port) ports of a box. This information is necessary for + `abc9` to preserve the integrity of carry-chains. Specifying this attribute + onto a bus port will affect its most significant bit. Non-standard or SystemVerilog features for formal verification From 29e4c8bd06acf718328c76ec5d6c11e3274b21d1 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 19 Aug 2019 10:00:53 -0700 Subject: [PATCH 68/94] Clarify with 'only' --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index fd4d4beb5..56f428548 100644 --- a/README.md +++ b/README.md @@ -420,7 +420,7 @@ Verilog Attributes and non-standard features - The port attribute ``abc_carry`` marks the carry-in (if an input port) and carry-out (if output port) ports of a box. This information is necessary for `abc9` to preserve the integrity of carry-chains. Specifying this attribute - onto a bus port will affect its most significant bit. + onto a bus port will affect only its most significant bit. Non-standard or SystemVerilog features for formal verification From f42ba811b63e38be8b921c8896e340404b6a5ac5 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 19 Aug 2019 10:11:47 -0700 Subject: [PATCH 69/94] ID({A,B,Y}) -> ID::{A,B,Y} for opt_share.cc --- passes/opt/opt_share.cc | 60 ++++++++++++++++++++--------------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/passes/opt/opt_share.cc b/passes/opt/opt_share.cc index 734cbcf81..c53fb3113 100644 --- a/passes/opt/opt_share.cc +++ b/passes/opt/opt_share.cc @@ -127,7 +127,7 @@ bool mergeable(RTLIL::Cell *a, RTLIL::Cell *b) RTLIL::IdString decode_port_semantics(RTLIL::Cell *cell, RTLIL::IdString port_name) { - if (cell->type.in(ID($lt), ID($le), ID($ge), ID($gt), ID($div), ID($mod), ID($concat), SHIFT_OPS) && port_name == ID(B)) + if (cell->type.in(ID($lt), ID($le), ID($ge), ID($gt), ID($div), ID($mod), ID($concat), SHIFT_OPS) && port_name == ID::B) return port_name; return ""; @@ -135,9 +135,9 @@ RTLIL::IdString decode_port_semantics(RTLIL::Cell *cell, RTLIL::IdString port_na RTLIL::SigSpec decode_port_sign(RTLIL::Cell *cell, RTLIL::IdString port_name) { - if (cell->type == ID($alu) && port_name == ID(B)) + if (cell->type == ID($alu) && port_name == ID::B) return cell->getPort(ID(BI)); - else if (cell->type == ID($sub) && port_name == ID(B)) + else if (cell->type == ID($sub) && port_name == ID::B) return RTLIL::Const(1, 1); return RTLIL::Const(0, 1); @@ -173,9 +173,9 @@ void merge_operators(RTLIL::Module *module, RTLIL::Cell *mux, const std::vector< for (const auto& p : ports) { auto op = p.op; - RTLIL::IdString muxed_port_name = ID(A); - if (decode_port(op, ID(A), &assign_map) == operand) - muxed_port_name = ID(B); + RTLIL::IdString muxed_port_name = ID::A; + if (decode_port(op, ID::A, &assign_map) == operand) + muxed_port_name = ID::B; auto operand = decode_port(op, muxed_port_name, &assign_map); if (operand.sig.size() > max_width) @@ -204,9 +204,9 @@ void merge_operators(RTLIL::Module *module, RTLIL::Cell *mux, const std::vector< if (muxed_op.sign != muxed_operands[0].sign) muxed_op = ExtSigSpec(module->Neg(NEW_ID, muxed_op.sig, muxed_op.is_signed)); - RTLIL::SigSpec mux_y = mux->getPort(ID(Y)); - RTLIL::SigSpec mux_a = mux->getPort(ID(A)); - RTLIL::SigSpec mux_b = mux->getPort(ID(B)); + RTLIL::SigSpec mux_y = mux->getPort(ID::Y); + RTLIL::SigSpec mux_a = mux->getPort(ID::A); + RTLIL::SigSpec mux_b = mux->getPort(ID::B); RTLIL::SigSpec mux_s = mux->getPort(ID(S)); RTLIL::SigSpec shared_pmux_a = RTLIL::Const(RTLIL::State::Sx, max_width); @@ -216,24 +216,24 @@ void merge_operators(RTLIL::Module *module, RTLIL::Cell *mux, const std::vector< int conn_width = ports[0].sig.size(); int conn_offset = ports[0].mux_port_offset; - shared_op->setPort(ID(Y), shared_op->getPort(ID(Y)).extract(0, conn_width)); + shared_op->setPort(ID::Y, shared_op->getPort(ID::Y).extract(0, conn_width)); if (mux->type == ID($pmux)) { shared_pmux_s = RTLIL::SigSpec(); for (const auto &p : ports) { shared_pmux_s.append(mux_s[p.mux_port_id]); - mux_b.replace(p.mux_port_id * mux_a.size() + conn_offset, shared_op->getPort(ID(Y))); + mux_b.replace(p.mux_port_id * mux_a.size() + conn_offset, shared_op->getPort(ID::Y)); } } else { shared_pmux_s = RTLIL::SigSpec{mux_s, module->Not(NEW_ID, mux_s)}; - mux_a.replace(conn_offset, shared_op->getPort(ID(Y))); - mux_b.replace(conn_offset, shared_op->getPort(ID(Y))); + mux_a.replace(conn_offset, shared_op->getPort(ID::Y)); + mux_b.replace(conn_offset, shared_op->getPort(ID::Y)); } - mux->setPort(ID(A), mux_a); - mux->setPort(ID(B), mux_b); - mux->setPort(ID(Y), mux_y); + mux->setPort(ID::A, mux_a); + mux->setPort(ID::B, mux_b); + mux->setPort(ID::Y, mux_y); mux->setPort(ID(S), mux_s); for (const auto &op : muxed_operands) @@ -251,11 +251,11 @@ void merge_operators(RTLIL::Module *module, RTLIL::Cell *mux, const std::vector< shared_op->setParam(ID(Y_WIDTH), conn_width); - if (decode_port(shared_op, ID(A), &assign_map) == operand) { - shared_op->setPort(ID(B), mux_to_oper); + if (decode_port(shared_op, ID::A, &assign_map) == operand) { + shared_op->setPort(ID::B, mux_to_oper); shared_op->setParam(ID(B_WIDTH), max_width); } else { - shared_op->setPort(ID(A), mux_to_oper); + shared_op->setPort(ID::A, mux_to_oper); shared_op->setParam(ID(A_WIDTH), max_width); } } @@ -286,9 +286,9 @@ void check_muxed_operands(std::vector &ports, const ExtSigSpe auto p = *it; auto op = p->op; - RTLIL::IdString muxed_port_name = ID(A); - if (decode_port(op, ID(A), &assign_map) == shared_operand) { - muxed_port_name = ID(B); + RTLIL::IdString muxed_port_name = ID::A; + if (decode_port(op, ID::A, &assign_map) == shared_operand) { + muxed_port_name = ID::B; } auto operand = decode_port(op, muxed_port_name, &assign_map); @@ -315,7 +315,7 @@ ExtSigSpec find_shared_operand(const OpMuxConn* seed, std::vectorop; - for (RTLIL::IdString port_name : {ID(A), ID(B)}) { + for (RTLIL::IdString port_name : {ID::A, ID::B}) { oper = decode_port(op_a, port_name, &assign_map); auto operand_users = operand_to_users.at(oper); @@ -355,7 +355,7 @@ dict find_valid_op_mux_conns(RTLIL::Module *module, d std::function remove_outsig_from_aux_bit = [&](RTLIL::SigBit auxbit) { auto aux_outsig = op_aux_to_outsig.at(auxbit); auto op = outsig_to_operator.at(aux_outsig); - auto op_outsig = assign_map(op->getPort(ID(Y))); + auto op_outsig = assign_map(op->getPort(ID::Y)); remove_outsig(op_outsig); for (auto aux_outbit : aux_outsig) @@ -367,11 +367,11 @@ dict find_valid_op_mux_conns(RTLIL::Module *module, d int mux_port_size; if (mux->type.in(ID($mux), ID($_MUX_))) { - mux_port_size = mux->getPort(ID(A)).size(); - sig = RTLIL::SigSpec{mux->getPort(ID(B)), mux->getPort(ID(A))}; + mux_port_size = mux->getPort(ID::A).size(); + sig = RTLIL::SigSpec{mux->getPort(ID::B), mux->getPort(ID::A)}; } else { - mux_port_size = mux->getPort(ID(A)).size(); - sig = mux->getPort(ID(B)); + mux_port_size = mux->getPort(ID::A).size(); + sig = mux->getPort(ID::B); } auto mux_insig = assign_map(sig); @@ -510,12 +510,12 @@ struct OptSharePass : public Pass { } } - auto mux_insig = assign_map(cell->getPort(ID(Y))); + auto mux_insig = assign_map(cell->getPort(ID::Y)); outsig_to_operator[mux_insig] = cell; for (auto outbit : mux_insig) op_outbit_to_outsig[outbit] = mux_insig; - for (RTLIL::IdString port_name : {ID(A), ID(B)}) { + for (RTLIL::IdString port_name : {ID::A, ID::B}) { auto op_insig = decode_port(cell, port_name, &assign_map); op_insigs.push_back(op_insig); operand_to_users[op_insig].insert(cell); From 7e010834ebaaf6e5c87bc29710feee78298bf369 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 19 Aug 2019 10:41:18 -0700 Subject: [PATCH 70/94] Fix typo --- passes/techmap/dff2dffe.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/passes/techmap/dff2dffe.cc b/passes/techmap/dff2dffe.cc index e766f2cf6..0242256e5 100644 --- a/passes/techmap/dff2dffe.cc +++ b/passes/techmap/dff2dffe.cc @@ -265,7 +265,7 @@ struct Dff2dffePass : public Pass { log("\n"); log(" -unmap\n"); log(" operate in the opposite direction: replace $dffe cells with combinations\n"); - log(" of $dff and $mux cells. the options below are ignore in unmap mode.\n"); + log(" of $dff and $mux cells. the options below are ignored in unmap mode.\n"); log("\n"); log(" -unmap-mince N\n"); log(" Same as -unmap but only unmap $dffe where the clock enable port\n"); From 3f4886e7a3ff14578b9c6d614efd360478e5886e Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 19 Aug 2019 10:42:00 -0700 Subject: [PATCH 71/94] Fix typo --- frontends/aiger/aigerparse.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontends/aiger/aigerparse.cc b/frontends/aiger/aigerparse.cc index ac9e31f70..06522939f 100644 --- a/frontends/aiger/aigerparse.cc +++ b/frontends/aiger/aigerparse.cc @@ -451,7 +451,7 @@ void AigerReader::parse_xaiger(const dict &box_lookup) uint32_t poNum YS_ATTRIBUTE(unused) = parse_xaiger_literal(f); log_debug("poNum = %u\n", poNum); uint32_t boxNum = parse_xaiger_literal(f); - log_debug("boxNum = %u\n", poNum); + log_debug("boxNum = %u\n", boxNum); for (unsigned i = 0; i < boxNum; i++) { f.ignore(2*sizeof(uint32_t)); uint32_t boxUniqueId = parse_xaiger_literal(f); From 6ffb910d12a93e64182b52a58e69386851f2d595 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 20 Aug 2019 11:38:21 +0200 Subject: [PATCH 72/94] Add test case for real parameters Signed-off-by: Clifford Wolf --- tests/simple/realexpr.v | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/tests/simple/realexpr.v b/tests/simple/realexpr.v index 5b756e6be..74ed8faa5 100644 --- a/tests/simple/realexpr.v +++ b/tests/simple/realexpr.v @@ -1,4 +1,3 @@ - module demo_001(y1, y2, y3, y4); output [7:0] y1, y2, y3, y4; @@ -22,3 +21,13 @@ module demo_002(y0, y1, y2, y3); assign y3 = 1 ? -1 : 'd0; endmodule +module demo_003(output A, B); + parameter real p = 0; + assign A = (p==1.0); + assign B = (p!="1.000000"); +endmodule + +module demo_004(output A, B, C, D); + demo_003 #(1.0) demo_real (A, B); + demo_003 #(1) demo_int (C, D); +endmodule From 193eae0c84860c65bd5dd135b7e59c0c11ea76b0 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 20 Aug 2019 19:48:16 -0700 Subject: [PATCH 73/94] techmap -max_iter to apply to each module individually --- passes/techmap/techmap.cc | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/passes/techmap/techmap.cc b/passes/techmap/techmap.cc index b271c8781..a6c1214a7 100644 --- a/passes/techmap/techmap.cc +++ b/passes/techmap/techmap.cc @@ -943,7 +943,8 @@ struct TechmapPass : public Pass { log(" instead of inlining them.\n"); log("\n"); log(" -max_iter \n"); - log(" only run the specified number of iterations.\n"); + log(" only run the specified number of iterations for each module.\n"); + log(" default: unlimited\n"); log("\n"); log(" -recursive\n"); log(" instead of the iterative breadth-first algorithm use a recursive\n"); @@ -1157,15 +1158,16 @@ struct TechmapPass : public Pass { RTLIL::Module *module = *worker.module_queue.begin(); worker.module_queue.erase(module); + int module_max_iter = max_iter; bool did_something = true; std::set handled_cells; while (did_something) { did_something = false; - if (worker.techmap_module(design, module, map, handled_cells, celltypeMap, false)) - did_something = true; + if (worker.techmap_module(design, module, map, handled_cells, celltypeMap, false)) + did_something = true; if (did_something) module->check(); - if (max_iter > 0 && --max_iter == 0) + if (module_max_iter > 0 && --module_max_iter == 0) break; } } From fce8dc7db20d722646cea83ca841160d3d07445e Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 20 Aug 2019 20:05:16 -0700 Subject: [PATCH 74/94] Add test --- tests/techmap/recursive.v | 8 ++++++++ tests/techmap/recursive_map.v | 4 ++++ tests/techmap/recursive_runtest.sh | 3 +++ 3 files changed, 15 insertions(+) create mode 100644 tests/techmap/recursive.v create mode 100644 tests/techmap/recursive_map.v create mode 100644 tests/techmap/recursive_runtest.sh diff --git a/tests/techmap/recursive.v b/tests/techmap/recursive.v new file mode 100644 index 000000000..d281b21d8 --- /dev/null +++ b/tests/techmap/recursive.v @@ -0,0 +1,8 @@ +module top; +sub s0(); +foo f0(); +endmodule + +module foo; +sub s0(); +endmodule diff --git a/tests/techmap/recursive_map.v b/tests/techmap/recursive_map.v new file mode 100644 index 000000000..934256552 --- /dev/null +++ b/tests/techmap/recursive_map.v @@ -0,0 +1,4 @@ +module sub; + sub _TECHMAP_REPLACE_ (); + bar f0(); +endmodule diff --git a/tests/techmap/recursive_runtest.sh b/tests/techmap/recursive_runtest.sh new file mode 100644 index 000000000..30c79bf03 --- /dev/null +++ b/tests/techmap/recursive_runtest.sh @@ -0,0 +1,3 @@ +set -ev + +../../yosys -p 'hierarchy -top top; techmap -map recursive_map.v -max_iter 1; select -assert-count 2 t:sub; select -assert-count 2 t:bar' recursive.v From fe61dcce8b70236b29691fa56c562d17497d3567 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 20 Aug 2019 20:05:51 -0700 Subject: [PATCH 75/94] Grammar --- passes/techmap/techmap.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/passes/techmap/techmap.cc b/passes/techmap/techmap.cc index a6c1214a7..c4496f76f 100644 --- a/passes/techmap/techmap.cc +++ b/passes/techmap/techmap.cc @@ -943,7 +943,7 @@ struct TechmapPass : public Pass { log(" instead of inlining them.\n"); log("\n"); log(" -max_iter \n"); - log(" only run the specified number of iterations for each module.\n"); + log(" only run the specified number of iterations on each module.\n"); log(" default: unlimited\n"); log("\n"); log(" -recursive\n"); From 9b9d75945194f98e08b46e8e506832542ebf73ad Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 20 Aug 2019 20:18:51 -0700 Subject: [PATCH 76/94] Fix copy-paste typo --- passes/pmgen/Makefile.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/passes/pmgen/Makefile.inc b/passes/pmgen/Makefile.inc index 790811d4c..382a1b4ad 100644 --- a/passes/pmgen/Makefile.inc +++ b/passes/pmgen/Makefile.inc @@ -17,7 +17,7 @@ $(eval $(call add_extra_objs,passes/pmgen/ice40_dsp_pm.h)) OBJS += passes/pmgen/ice40_wrapcarry.o passes/pmgen/ice40_wrapcarry.o: passes/pmgen/ice40_wrapcarry_pm.h -$(eval $(call add_extra_objs,passes/pmgen/test_pmgen_pm.h)) +$(eval $(call add_extra_objs,passes/pmgen/ice40_wrapcarry_pm.h)) # -------------------------------------- From 076af2e6176ecc440be7b7fa984ea5b461bb95de Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 20 Aug 2019 20:37:52 -0700 Subject: [PATCH 77/94] Missing newline --- techlibs/common/synth.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/techlibs/common/synth.cc b/techlibs/common/synth.cc index 555de9fba..a176357a7 100644 --- a/techlibs/common/synth.cc +++ b/techlibs/common/synth.cc @@ -175,7 +175,7 @@ struct SynthPass : public ScriptPass log_cmd_error("This command only operates on fully selected designs!\n"); if (abc == "abc9" && !lut) - log_cmd_error("ABC9 flow only supported for FPGA synthesis (using '-lut' option)"); + log_cmd_error("ABC9 flow only supported for FPGA synthesis (using '-lut' option)\n"); log_header(design, "Executing SYNTH pass.\n"); log_push(); From 948b6f91a140dafa4bd47177769eb4974d08f203 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Wed, 21 Aug 2019 17:00:24 +0200 Subject: [PATCH 78/94] Fix test_pmgen deps --- passes/pmgen/Makefile.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/passes/pmgen/Makefile.inc b/passes/pmgen/Makefile.inc index 382a1b4ad..8e0cbdca8 100644 --- a/passes/pmgen/Makefile.inc +++ b/passes/pmgen/Makefile.inc @@ -4,7 +4,7 @@ # -------------------------------------- OBJS += passes/pmgen/test_pmgen.o -passes/pmgen/test_pmgen.o: passes/pmgen/test_pmgen_pm.h +passes/pmgen/test_pmgen.o: passes/pmgen/test_pmgen_pm.h passes/pmgen/ice40_dsp_pm.h passes/pmgen/peepopt_pm.h $(eval $(call add_extra_objs,passes/pmgen/test_pmgen_pm.h)) # -------------------------------------- From a6776ee35ee5404ca7d5b63fd2daccc46354112c Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 21 Aug 2019 13:36:01 -0700 Subject: [PATCH 79/94] mem2reg to preserve user attributes and src --- frontends/ast/simplify.cc | 4 ++++ tests/various/mem2reg.ys | 13 +++++++++++++ 2 files changed, 17 insertions(+) create mode 100644 tests/various/mem2reg.ys diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 54b9efaad..8493aa513 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -150,6 +150,10 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, reg->str = stringf("%s[%d]", node->str.c_str(), i); reg->is_reg = true; reg->is_signed = node->is_signed; + for (auto &it : node->attributes) + reg->attributes.emplace(it.first, it.second->clone()); + reg->filename = node->filename; + reg->linenum = node->linenum; children.push_back(reg); while (reg->simplify(true, false, false, 1, -1, false, false)) { } } diff --git a/tests/various/mem2reg.ys b/tests/various/mem2reg.ys new file mode 100644 index 000000000..00389c700 --- /dev/null +++ b/tests/various/mem2reg.ys @@ -0,0 +1,13 @@ +read_verilog < Date: Wed, 21 Aug 2019 19:18:05 -0700 Subject: [PATCH 80/94] opt_expr to trim A port of $shiftx if Y_WIDTH == 1 --- passes/opt/opt_expr.cc | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/passes/opt/opt_expr.cc b/passes/opt/opt_expr.cc index 858b3560c..b56ce252f 100644 --- a/passes/opt/opt_expr.cc +++ b/passes/opt/opt_expr.cc @@ -745,6 +745,23 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons } } + if (cell->type == ID($shiftx) && cell->getPort(ID::Y).size() == 1) { + SigSpec sig_a = assign_map(cell->getPort(ID::A)); + int width; + for (width = GetSize(sig_a); width > 1; width--) { + if (sig_a[width-1] != State::Sx) + break; + } + + if (width < GetSize(sig_a)) { + sig_a.remove(width, GetSize(sig_a)-width); + cell->setPort(ID::A, sig_a); + cell->setParam(ID(A_WIDTH), width); + did_something = true; + goto next_cell; + } + } + if (cell->type.in(ID($_NOT_), ID($not), ID($logic_not)) && cell->getPort(ID::Y).size() == 1 && invert_map.count(assign_map(cell->getPort(ID::A))) != 0) { cover_list("opt.opt_expr.invert.double", "$_NOT_", "$not", "$logic_not", cell->type.str()); From bb1a8a019030022e8e5ad794691497c725ec86b2 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 21 Aug 2019 21:58:20 -0700 Subject: [PATCH 81/94] Add test --- tests/opt/opt_expr.ys | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/tests/opt/opt_expr.ys b/tests/opt/opt_expr.ys index f0306efa1..4affc1ac8 100644 --- a/tests/opt/opt_expr.ys +++ b/tests/opt/opt_expr.ys @@ -221,3 +221,17 @@ check equiv_opt opt_expr -fine design -load postopt select -assert-count 1 t:$alu r:A_WIDTH=8 r:B_WIDTH=8 r:Y_WIDTH=9 %i %i %i + +########### + +design -reset +read_verilog -icells < Date: Thu, 22 Aug 2019 08:05:01 -0700 Subject: [PATCH 82/94] Canonical form --- passes/opt/opt_expr.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/passes/opt/opt_expr.cc b/passes/opt/opt_expr.cc index b56ce252f..7fdfa82bd 100644 --- a/passes/opt/opt_expr.cc +++ b/passes/opt/opt_expr.cc @@ -369,7 +369,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons for (auto cell : module->cells()) if (design->selected(module, cell) && cell->type[0] == '$') { if (cell->type.in(ID($_NOT_), ID($not), ID($logic_not)) && - cell->getPort(ID::A).size() == 1 && cell->getPort(ID::Y).size() == 1) + GetSize(cell->getPort(ID::A)) == 1 && GetSize(cell->getPort(ID::Y)) == 1) invert_map[assign_map(cell->getPort(ID::Y))] = assign_map(cell->getPort(ID::A)); if (cell->type.in(ID($mux), ID($_MUX_)) && cell->getPort(ID::A) == SigSpec(State::S1) && cell->getPort(ID::B) == SigSpec(State::S0)) @@ -740,12 +740,12 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons if (cell->type.in(ID($reduce_xor), ID($reduce_xnor), ID($lt), ID($le), ID($ge), ID($gt))) replace_cell(assign_map, module, cell, "x-bit in input", ID::Y, RTLIL::State::Sx); else - replace_cell(assign_map, module, cell, "x-bit in input", ID::Y, RTLIL::SigSpec(RTLIL::State::Sx, cell->getPort(ID::Y).size())); + replace_cell(assign_map, module, cell, "x-bit in input", ID::Y, RTLIL::SigSpec(RTLIL::State::Sx, GetSize(cell->getPort(ID::Y)))); goto next_cell; } } - if (cell->type == ID($shiftx) && cell->getPort(ID::Y).size() == 1) { + if (cell->type == ID($shiftx) && GetSize(cell->getPort(ID::Y)) == 1) { SigSpec sig_a = assign_map(cell->getPort(ID::A)); int width; for (width = GetSize(sig_a); width > 1; width--) { @@ -762,7 +762,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons } } - if (cell->type.in(ID($_NOT_), ID($not), ID($logic_not)) && cell->getPort(ID::Y).size() == 1 && + if (cell->type.in(ID($_NOT_), ID($not), ID($logic_not)) && GetSize(cell->getPort(ID::Y)) == 1 && invert_map.count(assign_map(cell->getPort(ID::A))) != 0) { cover_list("opt.opt_expr.invert.double", "$_NOT_", "$not", "$logic_not", cell->type.str()); replace_cell(assign_map, module, cell, "double_invert", ID::Y, invert_map.at(assign_map(cell->getPort(ID::A)))); @@ -1159,7 +1159,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons if (mux_undef && cell->type.in(ID($mux), ID($pmux))) { RTLIL::SigSpec new_a, new_b, new_s; - int width = cell->getPort(ID::A).size(); + int width = GetSize(cell->getPort(ID::A)); if ((cell->getPort(ID::A).is_fully_undef() && cell->getPort(ID::B).is_fully_undef()) || cell->getPort(ID(S)).is_fully_undef()) { cover_list("opt.opt_expr.mux_undef", "$mux", "$pmux", cell->type.str()); From 9e31f01b343a9b246430419e81da647e75bd1626 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 22 Aug 2019 08:06:24 -0700 Subject: [PATCH 83/94] Add cover() --- passes/opt/opt_expr.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/passes/opt/opt_expr.cc b/passes/opt/opt_expr.cc index 7fdfa82bd..aca15e5f2 100644 --- a/passes/opt/opt_expr.cc +++ b/passes/opt/opt_expr.cc @@ -754,6 +754,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons } if (width < GetSize(sig_a)) { + cover("opt.opt_expr.trim_shiftx"); sig_a.remove(width, GetSize(sig_a)-width); cell->setPort(ID::A, sig_a); cell->setParam(ID(A_WIDTH), width); From 379f33af5489850ef8e2e58ef12ff5b22da87711 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 22 Aug 2019 08:22:23 -0700 Subject: [PATCH 84/94] Handle $shift and Y_WIDTH > 1 as per @cliffordwolf --- passes/opt/opt_expr.cc | 12 ++++++++---- tests/opt/opt_expr.ys | 44 +++++++++++++++++++++++++++++++++++++++++- 2 files changed, 51 insertions(+), 5 deletions(-) diff --git a/passes/opt/opt_expr.cc b/passes/opt/opt_expr.cc index aca15e5f2..c4da613ab 100644 --- a/passes/opt/opt_expr.cc +++ b/passes/opt/opt_expr.cc @@ -745,16 +745,20 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons } } - if (cell->type == ID($shiftx) && GetSize(cell->getPort(ID::Y)) == 1) { + if (cell->type.in(ID($shiftx), ID($shift))) { SigSpec sig_a = assign_map(cell->getPort(ID::A)); int width; + bool trim_x = true; + bool trim_0 = cell->type == ID($shift); for (width = GetSize(sig_a); width > 1; width--) { - if (sig_a[width-1] != State::Sx) - break; + if ((trim_x && sig_a[width-1] == State::Sx) || + (trim_0 && sig_a[width-1] == State::S0)) + continue; + break; } if (width < GetSize(sig_a)) { - cover("opt.opt_expr.trim_shiftx"); + cover_list("opt.opt_expr.xbit", "$shiftx", "$shift", cell->type.str()); sig_a.remove(width, GetSize(sig_a)-width); cell->setPort(ID::A, sig_a); cell->setParam(ID(A_WIDTH), width); diff --git a/tests/opt/opt_expr.ys b/tests/opt/opt_expr.ys index 4affc1ac8..02be20a62 100644 --- a/tests/opt/opt_expr.ys +++ b/tests/opt/opt_expr.ys @@ -226,7 +226,7 @@ select -assert-count 1 t:$alu r:A_WIDTH=8 r:B_WIDTH=8 r:Y_WIDTH=9 %i %i %i design -reset read_verilog -icells < Date: Thu, 22 Aug 2019 08:37:27 -0700 Subject: [PATCH 85/94] Respect opt_expr -keepdc as per @cliffordwolf --- passes/opt/opt_expr.cc | 2 +- tests/opt/opt_expr.ys | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/passes/opt/opt_expr.cc b/passes/opt/opt_expr.cc index c4da613ab..73f48317a 100644 --- a/passes/opt/opt_expr.cc +++ b/passes/opt/opt_expr.cc @@ -748,7 +748,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons if (cell->type.in(ID($shiftx), ID($shift))) { SigSpec sig_a = assign_map(cell->getPort(ID::A)); int width; - bool trim_x = true; + bool trim_x = cell->type == ID($shiftx) || !keepdc; bool trim_0 = cell->type == ID($shift); for (width = GetSize(sig_a); width > 1; width--) { if ((trim_x && sig_a[width-1] == State::Sx) || diff --git a/tests/opt/opt_expr.ys b/tests/opt/opt_expr.ys index 02be20a62..ecc2c8da8 100644 --- a/tests/opt/opt_expr.ys +++ b/tests/opt/opt_expr.ys @@ -277,3 +277,17 @@ check equiv_opt opt_expr design -load postopt select -assert-count 1 t:$shift r:A_WIDTH=10 %i + +########### + +design -reset +read_verilog -icells < Date: Thu, 22 Aug 2019 16:37:40 +0100 Subject: [PATCH 86/94] require tcl-tk in Brewfile --- Brewfile | 1 + 1 file changed, 1 insertion(+) diff --git a/Brewfile b/Brewfile index 0c58ce161..4ffe50e86 100644 --- a/Brewfile +++ b/Brewfile @@ -6,3 +6,4 @@ brew "git" brew "graphviz" brew "pkg-config" brew "python3" +brew "tcl-tk" From 9245f0d3f564644290b6650b3f8f642789062e9e Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 22 Aug 2019 08:43:44 -0700 Subject: [PATCH 87/94] Copy-paste typo --- passes/opt/opt_expr.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/passes/opt/opt_expr.cc b/passes/opt/opt_expr.cc index 73f48317a..00d7d6063 100644 --- a/passes/opt/opt_expr.cc +++ b/passes/opt/opt_expr.cc @@ -758,7 +758,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons } if (width < GetSize(sig_a)) { - cover_list("opt.opt_expr.xbit", "$shiftx", "$shift", cell->type.str()); + cover_list("opt.opt_expr.trim", "$shiftx", "$shift", cell->type.str()); sig_a.remove(width, GetSize(sig_a)-width); cell->setPort(ID::A, sig_a); cell->setParam(ID(A_WIDTH), width); From 4c449caf9bb7a855b8e61cb96f99f59141ea6ef5 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 22 Aug 2019 18:06:36 +0200 Subject: [PATCH 88/94] Fix missing newline at end of file Signed-off-by: Clifford Wolf --- techlibs/efinix/Makefile.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/techlibs/efinix/Makefile.inc b/techlibs/efinix/Makefile.inc index f1ce58276..5013f7fc1 100644 --- a/techlibs/efinix/Makefile.inc +++ b/techlibs/efinix/Makefile.inc @@ -7,4 +7,4 @@ $(eval $(call add_share_file,share/efinix,techlibs/efinix/cells_map.v)) $(eval $(call add_share_file,share/efinix,techlibs/efinix/arith_map.v)) $(eval $(call add_share_file,share/efinix,techlibs/efinix/cells_sim.v)) $(eval $(call add_share_file,share/efinix,techlibs/efinix/brams_map.v)) -$(eval $(call add_share_file,share/efinix,techlibs/efinix/bram.txt)) \ No newline at end of file +$(eval $(call add_share_file,share/efinix,techlibs/efinix/bram.txt)) From 151db528e44fd12f3c31561df3bb37c12dca48ad Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 22 Aug 2019 18:09:37 +0200 Subject: [PATCH 89/94] Fix missing newline at end of file Signed-off-by: Clifford Wolf --- techlibs/anlogic/arith_map.v | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/techlibs/anlogic/arith_map.v b/techlibs/anlogic/arith_map.v index d783b0212..1186543da 100644 --- a/techlibs/anlogic/arith_map.v +++ b/techlibs/anlogic/arith_map.v @@ -81,4 +81,4 @@ module _80_anlogic_alu (A, B, CI, BI, X, Y, CO); /* End implementation */ assign X = AA ^ BB; -endmodule \ No newline at end of file +endmodule From e9f3eb97607bc49b6bb77229f1fad9796aea1483 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 22 Aug 2019 18:43:16 +0200 Subject: [PATCH 90/94] Bump year in copyright notice Signed-off-by: Clifford Wolf --- COPYING | 2 +- README.md | 2 +- kernel/yosys.cc | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/COPYING b/COPYING index a121cdfe9..0839088c3 100644 --- a/COPYING +++ b/COPYING @@ -1,4 +1,4 @@ -Copyright (C) 2012 - 2018 Clifford Wolf +Copyright (C) 2012 - 2019 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 diff --git a/README.md b/README.md index 56f428548..a31bd6c37 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ ``` yosys -- Yosys Open SYnthesis Suite -Copyright (C) 2012 - 2018 Clifford Wolf +Copyright (C) 2012 - 2019 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 diff --git a/kernel/yosys.cc b/kernel/yosys.cc index 747f2d739..5018a4888 100644 --- a/kernel/yosys.cc +++ b/kernel/yosys.cc @@ -129,7 +129,7 @@ void yosys_banner() log(" | |\n"); log(" | yosys -- Yosys Open SYnthesis Suite |\n"); log(" | |\n"); - log(" | Copyright (C) 2012 - 2018 Clifford Wolf |\n"); + log(" | Copyright (C) 2012 - 2019 Clifford Wolf |\n"); log(" | |\n"); log(" | Permission to use, copy, modify, and/or distribute this software for any |\n"); log(" | purpose with or without fee is hereby granted, provided that the above |\n"); From e5dac8096d92f526476f2d0b02def2298e6f5bbf Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Thu, 22 Aug 2019 20:43:52 +0200 Subject: [PATCH 91/94] do not require boost if pyosys is not used --- Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Makefile b/Makefile index 666223076..a742f2e50 100644 --- a/Makefile +++ b/Makefile @@ -91,8 +91,10 @@ PLUGIN_LDFLAGS += -undefined dynamic_lookup ifneq ($(shell which brew),) BREW_PREFIX := $(shell brew --prefix)/opt $(info $$BREW_PREFIX is [${BREW_PREFIX}]) +ifeq ($(ENABLE_PYOSYS),1) CXXFLAGS += -I$(BREW_PREFIX)/boost/include/boost LDFLAGS += -L$(BREW_PREFIX)/boost/lib +endif CXXFLAGS += -I$(BREW_PREFIX)/readline/include LDFLAGS += -L$(BREW_PREFIX)/readline/lib PKG_CONFIG_PATH := $(BREW_PREFIX)/libffi/lib/pkgconfig:$(PKG_CONFIG_PATH) From c50d68653d093a8daa47f589836e6178be82b54f Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 22 Aug 2019 14:20:03 -0700 Subject: [PATCH 92/94] Spelling --- passes/equiv/equiv_make.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/passes/equiv/equiv_make.cc b/passes/equiv/equiv_make.cc index dbd8682e6..4855ce29e 100644 --- a/passes/equiv/equiv_make.cc +++ b/passes/equiv/equiv_make.cc @@ -532,10 +532,10 @@ struct EquivMakePass : public Pass { log_cmd_error("Equiv module %s already exists.\n", args[argidx+2].c_str()); if (worker.gold_mod->has_memories() || worker.gold_mod->has_processes()) - log_cmd_error("Gold module contains memories or procresses. Run 'memory' or 'proc' respectively.\n"); + log_cmd_error("Gold module contains memories or processes. Run 'memory' or 'proc' respectively.\n"); if (worker.gate_mod->has_memories() || worker.gate_mod->has_processes()) - log_cmd_error("Gate module contains memories or procresses. Run 'memory' or 'proc' respectively.\n"); + log_cmd_error("Gate module contains memories or processes. Run 'memory' or 'proc' respectively.\n"); worker.read_blacklists(); worker.read_encfiles(); From fe1b2337fd7950e1d563be5b8ccbaa81688261e4 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 22 Aug 2019 16:57:59 -0700 Subject: [PATCH 93/94] Do not propagate mem2reg attribute through to result --- frontends/ast/simplify.cc | 3 ++- tests/various/mem2reg.ys | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 8493aa513..86dd80c65 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -151,7 +151,8 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, reg->is_reg = true; reg->is_signed = node->is_signed; for (auto &it : node->attributes) - reg->attributes.emplace(it.first, it.second->clone()); + if (it.first != ID(mem2reg)) + reg->attributes.emplace(it.first, it.second->clone()); reg->filename = node->filename; reg->linenum = node->linenum; children.push_back(reg); diff --git a/tests/various/mem2reg.ys b/tests/various/mem2reg.ys index 00389c700..85d6267c5 100644 --- a/tests/various/mem2reg.ys +++ b/tests/various/mem2reg.ys @@ -11,3 +11,4 @@ proc cd top select -assert-count 1 m:data1 a:src=< Date: Fri, 23 Aug 2019 10:37:50 +0200 Subject: [PATCH 94/94] Make macOS depenency clear --- README.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index a31bd6c37..606c4942e 100644 --- a/README.md +++ b/README.md @@ -69,11 +69,14 @@ prerequisites for building yosys: graphviz xdot pkg-config python3 libboost-system-dev \ libboost-python-dev libboost-filesystem-dev zlib1g-dev -Similarily, on Mac OS X MacPorts or Homebrew can be used to install dependencies: +Similarily, on Mac OS X Homebrew can be used to install dependencies: $ brew tap Homebrew/bundle && brew bundle + +or MacPorts: + $ sudo port install bison flex readline gawk libffi \ - git graphviz pkgconfig python36 boost zlib + git graphviz pkgconfig python36 boost zlib tcl On FreeBSD use the following command to install all prerequisites: