cxxrtl: allow `always` sync rules in debug_eval.
authorwhitequark <whitequark@whitequark.org>
Sun, 7 Mar 2021 14:28:45 +0000 (14:28 +0000)
committerwhitequark <whitequark@whitequark.org>
Sun, 7 Mar 2021 14:28:45 +0000 (14:28 +0000)
These can be produced from `always @*` processes, if `-noproc`
is used.

backends/cxxrtl/cxxrtl_backend.cc

index d7402087fdd36981aeb7dd49a3654f06f2cac56b..b6cc4bb6dc739b30e3820f60455c9649c1ceba2a 100644 (file)
@@ -1415,30 +1415,30 @@ struct CxxrtlWorker {
                                collect_sigspec_rhs(port.second, for_debug, cells);
        }
 
-       void dump_assign(const RTLIL::SigSig &sigsig)
+       void dump_assign(const RTLIL::SigSig &sigsig, bool for_debug = false)
        {
                f << indent;
-               dump_sigspec_lhs(sigsig.first);
+               dump_sigspec_lhs(sigsig.first, for_debug);
                f << " = ";
-               dump_sigspec_rhs(sigsig.second);
+               dump_sigspec_rhs(sigsig.second, for_debug);
                f << ";\n";
        }
 
-       void dump_case_rule(const RTLIL::CaseRule *rule)
+       void dump_case_rule(const RTLIL::CaseRule *rule, bool for_debug = false)
        {
                for (auto action : rule->actions)
-                       dump_assign(action);
+                       dump_assign(action, for_debug);
                for (auto switch_ : rule->switches)
-                       dump_switch_rule(switch_);
+                       dump_switch_rule(switch_, for_debug);
        }
 
-       void dump_switch_rule(const RTLIL::SwitchRule *rule)
+       void dump_switch_rule(const RTLIL::SwitchRule *rule, bool for_debug = false)
        {
                // The switch attributes are printed before the switch condition is captured.
                dump_attrs(rule);
                std::string signal_temp = fresh_temporary();
                f << indent << "const value<" << rule->signal.size() << "> &" << signal_temp << " = ";
-               dump_sigspec(rule->signal, /*is_lhs=*/false);
+               dump_sigspec(rule->signal, /*is_lhs=*/false, for_debug);
                f << ";\n";
 
                bool first = true;
@@ -1458,7 +1458,7 @@ struct CxxrtlWorker {
                                        first = false;
                                        if (compare.is_fully_def()) {
                                                f << signal_temp << " == ";
-                                               dump_sigspec(compare, /*is_lhs=*/false);
+                                               dump_sigspec(compare, /*is_lhs=*/false, for_debug);
                                        } else if (compare.is_fully_const()) {
                                                RTLIL::Const compare_mask, compare_value;
                                                for (auto bit : compare.as_const()) {
@@ -1492,26 +1492,28 @@ struct CxxrtlWorker {
                        }
                        f << "{\n";
                        inc_indent();
-                               dump_case_rule(case_);
+                               dump_case_rule(case_, for_debug);
                        dec_indent();
                }
                f << indent << "}\n";
        }
 
-       void dump_process_case(const RTLIL::Process *proc)
+       void dump_process_case(const RTLIL::Process *proc, bool for_debug = false)
        {
                dump_attrs(proc);
                f << indent << "// process " << proc->name.str() << " case\n";
                // The case attributes (for root case) are always empty.
                log_assert(proc->root_case.attributes.empty());
-               dump_case_rule(&proc->root_case);
+               dump_case_rule(&proc->root_case, for_debug);
        }
 
-       void dump_process_syncs(const RTLIL::Process *proc)
+       void dump_process_syncs(const RTLIL::Process *proc, bool for_debug = false)
        {
                dump_attrs(proc);
                f << indent << "// process " << proc->name.str() << " syncs\n";
                for (auto sync : proc->syncs) {
+                       log_assert(!for_debug || sync->type == RTLIL::STa);
+
                        RTLIL::SigBit sync_bit;
                        if (!sync->signal.empty()) {
                                sync_bit = sync->signal[0];
@@ -1556,7 +1558,7 @@ struct CxxrtlWorker {
                                f << ") {\n";
                                inc_indent();
                                        for (auto action : sync->actions)
-                                               dump_assign(action);
+                                               dump_assign(action, for_debug);
                                dec_indent();
                                f << indent << "}\n";
                        }
@@ -1725,12 +1727,12 @@ struct CxxrtlWorker {
                                                case FlowGraph::Node::Type::CELL_EVAL:
                                                        dump_cell_eval(node.cell);
                                                        break;
-                                               case FlowGraph::Node::Type::PROCESS_SYNC:
-                                                       dump_process_syncs(node.process);
-                                                       break;
                                                case FlowGraph::Node::Type::PROCESS_CASE:
                                                        dump_process_case(node.process);
                                                        break;
+                                               case FlowGraph::Node::Type::PROCESS_SYNC:
+                                                       dump_process_syncs(node.process);
+                                                       break;
                                        }
                                }
                        }
@@ -1754,6 +1756,12 @@ struct CxxrtlWorker {
                                        case FlowGraph::Node::Type::CELL_EVAL:
                                                dump_cell_eval(node.cell, /*for_debug=*/true);
                                                break;
+                                       case FlowGraph::Node::Type::PROCESS_CASE:
+                                               dump_process_case(node.process, /*for_debug=*/true);
+                                               break;
+                                       case FlowGraph::Node::Type::PROCESS_SYNC:
+                                               dump_process_syncs(node.process, /*for_debug=*/true);
+                                               break;
                                        default:
                                                log_abort();
                                }