aboutsummaryrefslogtreecommitdiffstats
path: root/backends
diff options
context:
space:
mode:
Diffstat (limited to 'backends')
-rw-r--r--backends/btor/btor.cc5
-rw-r--r--backends/cxxrtl/cxxrtl.h36
-rw-r--r--backends/cxxrtl/cxxrtl_backend.cc18
-rw-r--r--backends/firrtl/firrtl.cc6
-rw-r--r--backends/smt2/smt2.cc5
-rw-r--r--backends/smv/smv.cc5
-rw-r--r--backends/verilog/verilog_backend.cc4
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();