diff options
Diffstat (limited to 'backends/cxxrtl/cxxrtl_backend.cc')
-rw-r--r-- | backends/cxxrtl/cxxrtl_backend.cc | 60 |
1 files changed, 54 insertions, 6 deletions
diff --git a/backends/cxxrtl/cxxrtl_backend.cc b/backends/cxxrtl/cxxrtl_backend.cc index 23ea57b5a..7efb0aeaf 100644 --- a/backends/cxxrtl/cxxrtl_backend.cc +++ b/backends/cxxrtl/cxxrtl_backend.cc @@ -1036,8 +1036,12 @@ struct CxxrtlWorker { // Edge-sensitive logic RTLIL::SigBit clk_bit = cell->getPort(ID::CLK)[0]; clk_bit = sigmaps[clk_bit.wire->module](clk_bit); - f << indent << "if (" << (cell->getParam(ID::CLK_POLARITY).as_bool() ? "posedge_" : "negedge_") - << mangle(clk_bit) << ") {\n"; + if (clk_bit.wire) { + f << indent << "if (" << (cell->getParam(ID::CLK_POLARITY).as_bool() ? "posedge_" : "negedge_") + << mangle(clk_bit) << ") {\n"; + } else { + f << indent << "if (false) {\n"; + } inc_indent(); if (cell->hasPort(ID::EN)) { f << indent << "if ("; @@ -1130,8 +1134,12 @@ struct CxxrtlWorker { if (cell->getParam(ID::CLK_ENABLE).as_bool()) { RTLIL::SigBit clk_bit = cell->getPort(ID::CLK)[0]; clk_bit = sigmaps[clk_bit.wire->module](clk_bit); - f << indent << "if (" << (cell->getParam(ID::CLK_POLARITY).as_bool() ? "posedge_" : "negedge_") - << mangle(clk_bit) << ") {\n"; + if (clk_bit.wire) { + f << indent << "if (" << (cell->getParam(ID::CLK_POLARITY).as_bool() ? "posedge_" : "negedge_") + << mangle(clk_bit) << ") {\n"; + } else { + f << indent << "if (false) {\n"; + } inc_indent(); } RTLIL::Memory *memory = cell->module->memories[cell->getParam(ID::MEMID).decode_string()]; @@ -1869,6 +1877,46 @@ struct CxxrtlWorker { } if (has_cells) f << "\n"; + f << indent << mangle(module) << "() {}\n"; + if (has_cells) { + f << indent << mangle(module) << "(adopt, " << mangle(module) << " other) :\n"; + bool first = true; + for (auto cell : module->cells()) { + if (is_internal_cell(cell->type)) + continue; + if (first) { + first = false; + } else { + f << ",\n"; + } + RTLIL::Module *cell_module = module->design->module(cell->type); + if (cell_module->get_bool_attribute(ID(cxxrtl_blackbox))) { + f << indent << " " << mangle(cell) << "(std::move(other." << mangle(cell) << "))"; + } else { + f << indent << " " << mangle(cell) << "(adopt {}, std::move(other." << mangle(cell) << "))"; + } + } + f << " {\n"; + inc_indent(); + for (auto cell : module->cells()) { + if (is_internal_cell(cell->type)) + continue; + RTLIL::Module *cell_module = module->design->module(cell->type); + if (cell_module->get_bool_attribute(ID(cxxrtl_blackbox))) + f << indent << mangle(cell) << "->reset();\n"; + } + dec_indent(); + f << indent << "}\n"; + } else { + f << indent << mangle(module) << "(adopt, " << mangle(module) << " other) {}\n"; + } + f << "\n"; + f << indent << "void reset() override {\n"; + inc_indent(); + f << indent << "*this = " << mangle(module) << "(adopt {}, std::move(*this));\n"; + dec_indent(); + f << indent << "}\n"; + f << "\n"; f << indent << "bool eval() override;\n"; f << indent << "bool commit() override;\n"; if (debug_info) @@ -2105,14 +2153,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 (cell->getPort(ID::CLK).is_wire()) + if (sigmap(cell->getPort(ID::CLK)).is_wire()) 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 (cell->getPort(ID::CLK).is_wire()) + if (sigmap(cell->getPort(ID::CLK)).is_wire()) register_edge_signal(sigmap, cell->getPort(ID::CLK), cell->parameters[ID::CLK_POLARITY].as_bool() ? RTLIL::STp : RTLIL::STn); } |