aboutsummaryrefslogtreecommitdiffstats
path: root/backends
diff options
context:
space:
mode:
Diffstat (limited to 'backends')
-rw-r--r--backends/btor/btor.cc15
-rw-r--r--backends/cxxrtl/cxxrtl.h16
-rw-r--r--backends/cxxrtl/cxxrtl_backend.cc22
-rw-r--r--backends/cxxrtl/cxxrtl_vcd.h4
-rw-r--r--backends/smt2/smt2.cc12
-rw-r--r--backends/smv/smv.cc18
-rw-r--r--backends/spice/spice.cc22
7 files changed, 82 insertions, 27 deletions
diff --git a/backends/btor/btor.cc b/backends/btor/btor.cc
index 639c6f129..692452aad 100644
--- a/backends/btor/btor.cc
+++ b/backends/btor/btor.cc
@@ -860,7 +860,20 @@ struct BtorWorker
goto okay;
}
- log_error("Unsupported cell type: %s (%s)\n", log_id(cell->type), log_id(cell));
+ if (cell->type.in(ID($dffe), ID($sdff), ID($sdffe), ID($sdffce)) || cell->type.str().substr(0, 6) == "$_SDFF" || (cell->type.str().substr(0, 6) == "$_DFFE" && cell->type.str().size() == 10)) {
+ log_error("Unsupported cell type %s for cell %s.%s -- please run `dffunmap` before `write_btor`.\n",
+ log_id(cell->type), log_id(module), log_id(cell));
+ }
+ if (cell->type.in(ID($adff), ID($adffe), ID($dffsr), ID($dffsre)) || cell->type.str().substr(0, 5) == "$_DFF") {
+ log_error("Unsupported cell type %s for cell %s.%s -- please run `async2sync; dffunmap` or `clk2fflogic` before `write_btor`.\n",
+ log_id(cell->type), log_id(module), log_id(cell));
+ }
+ if (cell->type.in(ID($sr), ID($dlatch), ID($adlatch), ID($dlatchsr)) || cell->type.str().substr(0, 8) == "$_DLATCH" || cell->type.str().substr(0, 5) == "$_SR_") {
+ log_error("Unsupported cell type %s for cell %s.%s -- please run `clk2fflogic` before `write_btor`.\n",
+ log_id(cell->type), log_id(module), log_id(cell));
+ }
+ log_error("Unsupported cell type %s for cell %s.%s.\n",
+ log_id(cell->type), log_id(module), log_id(cell));
okay:
btorf_pop(log_id(cell));
diff --git a/backends/cxxrtl/cxxrtl.h b/backends/cxxrtl/cxxrtl.h
index 0a6bcb849..0e55c46c2 100644
--- a/backends/cxxrtl/cxxrtl.h
+++ b/backends/cxxrtl/cxxrtl.h
@@ -1217,49 +1217,49 @@ value<BitsY> xnor_ss(const value<BitsA> &a, const value<BitsB> &b) {
template<size_t BitsY, size_t BitsA, size_t BitsB>
CXXRTL_ALWAYS_INLINE
value<BitsY> shl_uu(const value<BitsA> &a, const value<BitsB> &b) {
- return a.template zcast<BitsY>().template shl(b);
+ return a.template zcast<BitsY>().shl(b);
}
template<size_t BitsY, size_t BitsA, size_t BitsB>
CXXRTL_ALWAYS_INLINE
value<BitsY> shl_su(const value<BitsA> &a, const value<BitsB> &b) {
- return a.template scast<BitsY>().template shl(b);
+ return a.template scast<BitsY>().shl(b);
}
template<size_t BitsY, size_t BitsA, size_t BitsB>
CXXRTL_ALWAYS_INLINE
value<BitsY> sshl_uu(const value<BitsA> &a, const value<BitsB> &b) {
- return a.template zcast<BitsY>().template shl(b);
+ return a.template zcast<BitsY>().shl(b);
}
template<size_t BitsY, size_t BitsA, size_t BitsB>
CXXRTL_ALWAYS_INLINE
value<BitsY> sshl_su(const value<BitsA> &a, const value<BitsB> &b) {
- return a.template scast<BitsY>().template shl(b);
+ return a.template scast<BitsY>().shl(b);
}
template<size_t BitsY, size_t BitsA, size_t BitsB>
CXXRTL_ALWAYS_INLINE
value<BitsY> shr_uu(const value<BitsA> &a, const value<BitsB> &b) {
- return a.template shr(b).template zcast<BitsY>();
+ return a.shr(b).template zcast<BitsY>();
}
template<size_t BitsY, size_t BitsA, size_t BitsB>
CXXRTL_ALWAYS_INLINE
value<BitsY> shr_su(const value<BitsA> &a, const value<BitsB> &b) {
- return a.template shr(b).template scast<BitsY>();
+ return a.shr(b).template scast<BitsY>();
}
template<size_t BitsY, size_t BitsA, size_t BitsB>
CXXRTL_ALWAYS_INLINE
value<BitsY> sshr_uu(const value<BitsA> &a, const value<BitsB> &b) {
- return a.template shr(b).template zcast<BitsY>();
+ return a.shr(b).template zcast<BitsY>();
}
template<size_t BitsY, size_t BitsA, size_t BitsB>
CXXRTL_ALWAYS_INLINE
value<BitsY> sshr_su(const value<BitsA> &a, const value<BitsB> &b) {
- return a.template sshr(b).template scast<BitsY>();
+ return a.sshr(b).template scast<BitsY>();
}
template<size_t BitsY, size_t BitsA, size_t BitsB>
diff --git a/backends/cxxrtl/cxxrtl_backend.cc b/backends/cxxrtl/cxxrtl_backend.cc
index 861b484f4..39046bd78 100644
--- a/backends/cxxrtl/cxxrtl_backend.cc
+++ b/backends/cxxrtl/cxxrtl_backend.cc
@@ -601,6 +601,12 @@ struct WireType {
bool is_exact() const { return type == ALIAS || type == CONST; }
};
+// Tests for a SigSpec that is a valid clock input, clocks have to have a backing wire and be a single bit
+// using this instead of sig.is_wire() solves issues when the clock is a slice instead of a full wire
+bool is_valid_clock(const RTLIL::SigSpec& sig) {
+ return sig.is_chunk() && sig.is_bit() && sig[0].wire;
+}
+
struct CxxrtlWorker {
bool split_intf = false;
std::string intf_filename;
@@ -1110,7 +1116,8 @@ struct CxxrtlWorker {
// Flip-flops
} else if (is_ff_cell(cell->type)) {
log_assert(!for_debug);
- if (cell->hasPort(ID::CLK) && cell->getPort(ID::CLK).is_wire()) {
+ // Clocks might be slices of larger signals but should only ever be single bit
+ if (cell->hasPort(ID::CLK) && is_valid_clock(cell->getPort(ID::CLK))) {
// Edge-sensitive logic
RTLIL::SigBit clk_bit = cell->getPort(ID::CLK)[0];
clk_bit = sigmaps[clk_bit.wire->module](clk_bit);
@@ -2266,7 +2273,7 @@ struct CxxrtlWorker {
void register_edge_signal(SigMap &sigmap, RTLIL::SigSpec signal, RTLIL::SyncType type)
{
signal = sigmap(signal);
- log_assert(signal.is_wire() && signal.is_bit());
+ log_assert(is_valid_clock(signal));
log_assert(type == RTLIL::STp || type == RTLIL::STn || type == RTLIL::STe);
RTLIL::SigBit sigbit = signal[0];
@@ -2274,7 +2281,8 @@ struct CxxrtlWorker {
edge_types[sigbit] = type;
else if (edge_types[sigbit] != type)
edge_types[sigbit] = RTLIL::STe;
- edge_wires.insert(signal.as_wire());
+ // Cannot use as_wire because signal might not be a full wire, instead extract the wire from the sigbit
+ edge_wires.insert(sigbit.wire);
}
void analyze_design(RTLIL::Design *design)
@@ -2355,14 +2363,14 @@ struct CxxrtlWorker {
// Various DFF cells are treated like posedge/negedge processes, see above for details.
if (cell->type.in(ID($dff), ID($dffe), ID($adff), ID($adffe), ID($dffsr), ID($dffsre), ID($sdff), ID($sdffe), ID($sdffce))) {
- if (sigmap(cell->getPort(ID::CLK)).is_wire())
+ if (is_valid_clock(cell->getPort(ID::CLK)))
register_edge_signal(sigmap, cell->getPort(ID::CLK),
cell->parameters[ID::CLK_POLARITY].as_bool() ? RTLIL::STp : RTLIL::STn);
}
// Similar for memory port cells.
if (cell->type.in(ID($memrd), ID($memwr))) {
if (cell->getParam(ID::CLK_ENABLE).as_bool()) {
- if (sigmap(cell->getPort(ID::CLK)).is_wire())
+ if (is_valid_clock(cell->getPort(ID::CLK)))
register_edge_signal(sigmap, cell->getPort(ID::CLK),
cell->parameters[ID::CLK_POLARITY].as_bool() ? RTLIL::STp : RTLIL::STn);
}
@@ -2372,7 +2380,7 @@ struct CxxrtlWorker {
if (cell->type == ID($memwr))
writable_memories.insert(module->memories[cell->getParam(ID::MEMID).decode_string()]);
// Collect groups of memory write ports in the same domain.
- if (cell->type == ID($memwr) && cell->getParam(ID::CLK_ENABLE).as_bool() && cell->getPort(ID::CLK).is_wire()) {
+ if (cell->type == ID($memwr) && cell->getParam(ID::CLK_ENABLE).as_bool() && is_valid_clock(cell->getPort(ID::CLK))) {
RTLIL::SigBit clk_bit = sigmap(cell->getPort(ID::CLK))[0];
const RTLIL::Memory *memory = module->memories[cell->getParam(ID::MEMID).decode_string()];
memwr_per_domain[{clk_bit, memory}].insert(cell);
@@ -2384,7 +2392,7 @@ struct CxxrtlWorker {
}
for (auto cell : module->cells()) {
// Collect groups of memory write ports read by every transparent read port.
- if (cell->type == ID($memrd) && cell->getParam(ID::CLK_ENABLE).as_bool() && cell->getPort(ID::CLK).is_wire() &&
+ if (cell->type == ID($memrd) && cell->getParam(ID::CLK_ENABLE).as_bool() && is_valid_clock(cell->getPort(ID::CLK)) &&
cell->getParam(ID::TRANSPARENT).as_bool()) {
RTLIL::SigBit clk_bit = sigmap(cell->getPort(ID::CLK))[0];
const RTLIL::Memory *memory = module->memories[cell->getParam(ID::MEMID).decode_string()];
diff --git a/backends/cxxrtl/cxxrtl_vcd.h b/backends/cxxrtl/cxxrtl_vcd.h
index 6ee98b428..3f40a8d12 100644
--- a/backends/cxxrtl/cxxrtl_vcd.h
+++ b/backends/cxxrtl/cxxrtl_vcd.h
@@ -228,13 +228,13 @@ public:
}
void add(const debug_items &items) {
- this->template add(items, [](const std::string &, const debug_item &) {
+ this->add(items, [](const std::string &, const debug_item &) {
return true;
});
}
void add_without_memories(const debug_items &items) {
- this->template add(items, [](const std::string &, const debug_item &item) {
+ this->add(items, [](const std::string &, const debug_item &item) {
return item.type != debug_item::MEMORY;
});
}
diff --git a/backends/smt2/smt2.cc b/backends/smt2/smt2.cc
index a185fdd74..8be9e05f1 100644
--- a/backends/smt2/smt2.cc
+++ b/backends/smt2/smt2.cc
@@ -855,6 +855,18 @@ struct Smt2Worker
return;
}
+ if (cell->type.in(ID($dffe), ID($sdff), ID($sdffe), ID($sdffce)) || cell->type.str().substr(0, 6) == "$_SDFF" || (cell->type.str().substr(0, 6) == "$_DFFE" && cell->type.str().size() == 10)) {
+ log_error("Unsupported cell type %s for cell %s.%s -- please run `dffunmap` before `write_smt2`.\n",
+ log_id(cell->type), log_id(module), log_id(cell));
+ }
+ if (cell->type.in(ID($adff), ID($adffe), ID($dffsr), ID($dffsre)) || cell->type.str().substr(0, 5) == "$_DFF") {
+ log_error("Unsupported cell type %s for cell %s.%s -- please run `async2sync; dffunmap` or `clk2fflogic` before `write_smt2`.\n",
+ log_id(cell->type), log_id(module), log_id(cell));
+ }
+ if (cell->type.in(ID($sr), ID($dlatch), ID($adlatch), ID($dlatchsr)) || cell->type.str().substr(0, 8) == "$_DLATCH" || cell->type.str().substr(0, 5) == "$_SR_") {
+ log_error("Unsupported cell type %s for cell %s.%s -- please run `clk2fflogic` before `write_smt2`.\n",
+ log_id(cell->type), log_id(module), log_id(cell));
+ }
log_error("Unsupported cell type %s for cell %s.%s.\n",
log_id(cell->type), log_id(module), log_id(cell));
}
diff --git a/backends/smv/smv.cc b/backends/smv/smv.cc
index 4e5c6050d..e41582fea 100644
--- a/backends/smv/smv.cc
+++ b/backends/smv/smv.cc
@@ -573,8 +573,22 @@ struct SmvWorker
continue;
}
- if (cell->type[0] == '$')
- log_error("Found currently unsupported cell type %s (%s.%s).\n", log_id(cell->type), log_id(module), log_id(cell));
+ if (cell->type[0] == '$') {
+ if (cell->type.in(ID($dffe), ID($sdff), ID($sdffe), ID($sdffce)) || cell->type.str().substr(0, 6) == "$_SDFF" || (cell->type.str().substr(0, 6) == "$_DFFE" && cell->type.str().size() == 10)) {
+ log_error("Unsupported cell type %s for cell %s.%s -- please run `dffunmap` before `write_smv`.\n",
+ log_id(cell->type), log_id(module), log_id(cell));
+ }
+ if (cell->type.in(ID($adff), ID($adffe), ID($dffsr), ID($dffsre)) || cell->type.str().substr(0, 5) == "$_DFF") {
+ log_error("Unsupported cell type %s for cell %s.%s -- please run `async2sync; dffunmap` or `clk2fflogic` before `write_smv`.\n",
+ log_id(cell->type), log_id(module), log_id(cell));
+ }
+ if (cell->type.in(ID($sr), ID($dlatch), ID($adlatch), ID($dlatchsr)) || cell->type.str().substr(0, 8) == "$_DLATCH" || cell->type.str().substr(0, 5) == "$_SR_") {
+ log_error("Unsupported cell type %s for cell %s.%s -- please run `clk2fflogic` before `write_smv`.\n",
+ log_id(cell->type), log_id(module), log_id(cell));
+ }
+ log_error("Unsupported cell type %s for cell %s.%s.\n",
+ log_id(cell->type), log_id(module), log_id(cell));
+ }
// f << stringf(" %s : %s;\n", cid(cell->name), cid(cell->type));
diff --git a/backends/spice/spice.cc b/backends/spice/spice.cc
index aa20f106a..ca5c680c9 100644
--- a/backends/spice/spice.cc
+++ b/backends/spice/spice.cc
@@ -64,7 +64,7 @@ static void print_spice_net(std::ostream &f, RTLIL::SigBit s, std::string &neg,
}
}
-static void print_spice_module(std::ostream &f, RTLIL::Module *module, RTLIL::Design *design, std::string &neg, std::string &pos, std::string &ncpf, bool big_endian, bool use_inames)
+static void print_spice_module(std::ostream &f, RTLIL::Module *module, RTLIL::Design *design, std::string &neg, std::string &pos, std::string &buf, std::string &ncpf, bool big_endian, bool use_inames)
{
SigMap sigmap(module);
idict<IdString, 1> inums;
@@ -121,10 +121,10 @@ static void print_spice_module(std::ostream &f, RTLIL::Module *module, RTLIL::De
for (auto &conn : module->connections())
for (int i = 0; i < conn.first.size(); i++) {
- f << stringf("V%d", conn_counter++);
- print_spice_net(f, conn.first.extract(i, 1), neg, pos, ncpf, nc_counter, use_inames, inums);
+ f << (buf == "DC" ? stringf("V%d", conn_counter++) : stringf("X%d", cell_counter++));
print_spice_net(f, conn.second.extract(i, 1), neg, pos, ncpf, nc_counter, use_inames, inums);
- f << stringf(" DC 0\n");
+ print_spice_net(f, conn.first.extract(i, 1), neg, pos, ncpf, nc_counter, use_inames, inums);
+ f << (buf == "DC" ? " DC 0\n" : stringf(" %s\n", buf.c_str()));
}
}
@@ -148,6 +148,10 @@ struct SpiceBackend : public Backend {
log(" -pos net_name\n");
log(" set the net name for constant 1 (default: Vdd)\n");
log("\n");
+ log(" -buf DC|subckt_name\n");
+ log(" set the name for jumper element (default: DC)\n");
+ log(" (used to connect different nets)\n");
+ log("\n");
log(" -nc_prefix\n");
log(" prefix for not-connected nets (default: _NC)\n");
log("\n");
@@ -164,7 +168,7 @@ struct SpiceBackend : public Backend {
std::string top_module_name;
RTLIL::Module *top_module = NULL;
bool big_endian = false, use_inames = false;
- std::string neg = "Vss", pos = "Vdd", ncpf = "_NC";
+ std::string neg = "Vss", pos = "Vdd", ncpf = "_NC", buf = "DC";
log_header(design, "Executing SPICE backend.\n");
@@ -187,6 +191,10 @@ struct SpiceBackend : public Backend {
pos = args[++argidx];
continue;
}
+ if (args[argidx] == "-buf" && argidx+1 < args.size()) {
+ buf = args[++argidx];
+ continue;
+ }
if (args[argidx] == "-nc_prefix" && argidx+1 < args.size()) {
ncpf = args[++argidx];
continue;
@@ -241,14 +249,14 @@ struct SpiceBackend : public Backend {
*f << stringf(" %s", spice_id2str(wire->name).c_str());
}
*f << stringf("\n");
- print_spice_module(*f, module, design, neg, pos, ncpf, big_endian, use_inames);
+ print_spice_module(*f, module, design, neg, pos, buf, ncpf, big_endian, use_inames);
*f << stringf(".ENDS %s\n\n", spice_id2str(module->name).c_str());
}
if (!top_module_name.empty()) {
if (top_module == NULL)
log_error("Can't find top module `%s'!\n", top_module_name.c_str());
- print_spice_module(*f, top_module, design, neg, pos, ncpf, big_endian, use_inames);
+ print_spice_module(*f, top_module, design, neg, pos, buf, ncpf, big_endian, use_inames);
*f << stringf("\n");
}