diff options
Diffstat (limited to 'backends')
-rw-r--r-- | backends/btor/btor.cc | 5 | ||||
-rw-r--r-- | backends/cxxrtl/cxxrtl.h | 36 | ||||
-rw-r--r-- | backends/cxxrtl/cxxrtl_backend.cc | 18 | ||||
-rw-r--r-- | backends/firrtl/firrtl.cc | 6 | ||||
-rw-r--r-- | backends/smt2/smt2.cc | 5 | ||||
-rw-r--r-- | backends/smv/smv.cc | 5 | ||||
-rw-r--r-- | backends/verilog/verilog_backend.cc | 4 |
7 files changed, 77 insertions, 2 deletions
diff --git a/backends/btor/btor.cc b/backends/btor/btor.cc index 96df54a2c..d62cc4c3d 100644 --- a/backends/btor/btor.cc +++ b/backends/btor/btor.cc @@ -1399,6 +1399,11 @@ struct BtorBackend : public Backend { log_header(design, "Executing BTOR backend.\n"); + log_push(); + Pass::call(design, "bmuxmap"); + Pass::call(design, "demuxmap"); + log_pop(); + size_t argidx; for (argidx = 1; argidx < args.size(); argidx++) { diff --git a/backends/cxxrtl/cxxrtl.h b/backends/cxxrtl/cxxrtl.h index 3e1357498..b4ffa87cd 100644 --- a/backends/cxxrtl/cxxrtl.h +++ b/backends/cxxrtl/cxxrtl.h @@ -457,6 +457,42 @@ struct value : public expr_base<value<Bits>> { return shr<AmountBits, /*Signed=*/true>(amount); } + template<size_t ResultBits, size_t SelBits> + value<ResultBits> bmux(const value<SelBits> &sel) const { + static_assert(ResultBits << SelBits == Bits, "invalid sizes used in bmux()"); + size_t amount = sel.data[0] * ResultBits; + size_t shift_chunks = amount / chunk::bits; + size_t shift_bits = amount % chunk::bits; + value<ResultBits> result; + chunk::type carry = 0; + if (ResultBits % chunk::bits + shift_bits > chunk::bits) + carry = data[result.chunks + shift_chunks] << (chunk::bits - shift_bits); + for (size_t n = 0; n < result.chunks; n++) { + result.data[result.chunks - 1 - n] = carry | (data[result.chunks + shift_chunks - 1 - n] >> shift_bits); + carry = (shift_bits == 0) ? 0 + : data[result.chunks + shift_chunks - 1 - n] << (chunk::bits - shift_bits); + } + return result; + } + + template<size_t ResultBits, size_t SelBits> + value<ResultBits> demux(const value<SelBits> &sel) const { + static_assert(Bits << SelBits == ResultBits, "invalid sizes used in demux()"); + size_t amount = sel.data[0] * Bits; + size_t shift_chunks = amount / chunk::bits; + size_t shift_bits = amount % chunk::bits; + value<ResultBits> result; + chunk::type carry = 0; + for (size_t n = 0; n < chunks; n++) { + result.data[shift_chunks + n] = (data[n] << shift_bits) | carry; + carry = (shift_bits == 0) ? 0 + : data[n] >> (chunk::bits - shift_bits); + } + if (Bits % chunk::bits + shift_bits > chunk::bits) + result.data[shift_chunks + chunks] = carry; + return result; + } + size_t ctpop() const { size_t count = 0; for (size_t n = 0; n < chunks; n++) { diff --git a/backends/cxxrtl/cxxrtl_backend.cc b/backends/cxxrtl/cxxrtl_backend.cc index 7a336f8c1..404755b1e 100644 --- a/backends/cxxrtl/cxxrtl_backend.cc +++ b/backends/cxxrtl/cxxrtl_backend.cc @@ -198,7 +198,7 @@ bool is_extending_cell(RTLIL::IdString type) bool is_inlinable_cell(RTLIL::IdString type) { return is_unary_cell(type) || is_binary_cell(type) || type.in( - ID($mux), ID($concat), ID($slice), ID($pmux)); + ID($mux), ID($concat), ID($slice), ID($pmux), ID($bmux), ID($demux)); } bool is_ff_cell(RTLIL::IdString type) @@ -1154,6 +1154,22 @@ struct CxxrtlWorker { for (int part = 0; part < s_width; part++) { f << ")"; } + // Big muxes + } else if (cell->type == ID($bmux)) { + dump_sigspec_rhs(cell->getPort(ID::A), for_debug); + f << ".bmux<"; + f << cell->getParam(ID::WIDTH).as_int(); + f << ">("; + dump_sigspec_rhs(cell->getPort(ID::S), for_debug); + f << ").val()"; + // Demuxes + } else if (cell->type == ID($demux)) { + dump_sigspec_rhs(cell->getPort(ID::A), for_debug); + f << ".demux<"; + f << GetSize(cell->getPort(ID::Y)); + f << ">("; + dump_sigspec_rhs(cell->getPort(ID::S), for_debug); + f << ").val()"; // Concats } else if (cell->type == ID($concat)) { dump_sigspec_rhs(cell->getPort(ID::B), for_debug); diff --git a/backends/firrtl/firrtl.cc b/backends/firrtl/firrtl.cc index 7abe584c9..85c44824f 100644 --- a/backends/firrtl/firrtl.cc +++ b/backends/firrtl/firrtl.cc @@ -1188,6 +1188,8 @@ struct FirrtlBackend : public Backend { log("Write a FIRRTL netlist of the current design.\n"); log("The following commands are executed by this command:\n"); log(" pmuxtree\n"); + log(" bmuxmap\n"); + log(" demuxmap\n"); log("\n"); } void execute(std::ostream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design) override @@ -1210,7 +1212,9 @@ struct FirrtlBackend : public Backend { log_header(design, "Executing FIRRTL backend.\n"); log_push(); - Pass::call(design, stringf("pmuxtree")); + Pass::call(design, "pmuxtree"); + Pass::call(design, "bmuxmap"); + Pass::call(design, "demuxmap"); namecache.clear(); autoid_counter = 0; diff --git a/backends/smt2/smt2.cc b/backends/smt2/smt2.cc index f2fa003bc..a928419a1 100644 --- a/backends/smt2/smt2.cc +++ b/backends/smt2/smt2.cc @@ -1531,6 +1531,11 @@ struct Smt2Backend : public Backend { log_header(design, "Executing SMT2 backend.\n"); + log_push(); + Pass::call(design, "bmuxmap"); + Pass::call(design, "demuxmap"); + log_pop(); + size_t argidx; for (argidx = 1; argidx < args.size(); argidx++) { diff --git a/backends/smv/smv.cc b/backends/smv/smv.cc index 7bace6912..7d4f94adc 100644 --- a/backends/smv/smv.cc +++ b/backends/smv/smv.cc @@ -741,6 +741,11 @@ struct SmvBackend : public Backend { log_header(design, "Executing SMV backend.\n"); + log_push(); + Pass::call(design, "bmuxmap"); + Pass::call(design, "demuxmap"); + log_pop(); + size_t argidx; for (argidx = 1; argidx < args.size(); argidx++) { diff --git a/backends/verilog/verilog_backend.cc b/backends/verilog/verilog_backend.cc index e4781ef3e..32003cf54 100644 --- a/backends/verilog/verilog_backend.cc +++ b/backends/verilog/verilog_backend.cc @@ -2300,7 +2300,11 @@ struct VerilogBackend : public Backend { extmem_prefix = filename.substr(0, filename.rfind('.')); } + log_push(); + Pass::call(design, "bmuxmap"); + Pass::call(design, "demuxmap"); Pass::call(design, "clean_zerowidth"); + log_pop(); design->sort(); |