diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index cfbe6e396..5be054516 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -730,21 +730,27 @@ struct AST_INTERNAL::ProcessGenerator current_case->module = current_module; pool backup_assigned_bits = std::move(current_case_assigned_bits); current_case_assigned_bits.clear(); - set_src_attr(current_case, child.get()); + current_case->compare_src = current_module->design->twines.add(Twine{child->loc_string()}); last_generated_case = current_case; - addChunkActions(current_case->actions, this_case_eq_ltemp, this_case_eq_rvalue, child.get()); + std::optional block; + for (auto& node : child->children) { + if (node->type == AST_DEFAULT) { + default_case = current_case; + } else if (node->type == AST_BLOCK) { + log_assert(!block.has_value()); + block = node.get(); + } else { + current_case->compare.push_back(node->genWidthRTLIL(width_hint, sign_hint, &subst_rvalue_map.stdmap())); + } + } + log_assert(block.has_value()); + set_src_attr(current_case, *block); + addChunkActions(current_case->actions, this_case_eq_ltemp, this_case_eq_rvalue, *block); // Track temp assignments for (auto &bit : this_case_eq_ltemp) if (bit.wire != NULL) current_case_assigned_bits.insert(bit); - for (auto& node : child->children) { - if (node->type == AST_DEFAULT) - default_case = current_case; - else if (node->type == AST_BLOCK) - processAst(node.get()); - else - current_case->compare.push_back(node->genWidthRTLIL(width_hint, sign_hint, &subst_rvalue_map.stdmap())); - } + processAst(*block); if (default_case != current_case) sw->cases.push_back(current_case); else diff --git a/passes/proc/proc_mux.cc b/passes/proc/proc_mux.cc index 7752da6a9..f6517af3c 100644 --- a/passes/proc/proc_mux.cc +++ b/passes/proc/proc_mux.cc @@ -242,6 +242,8 @@ struct MuxGenCtx { // create compare cell RTLIL::Cell *eq_cell = mod->addCell(mod->design->twines.add(std::string{stringf("%s_CMP%d", sstr.str(), cmp_wire->width)}), ifxmode ? TW($eqx) : TW($eq)); apply_attrs(eq_cell, cs); + if (cs->compare_src != Twine::Null) + eq_cell->set_src_attribute(cs->compare_src); eq_cell->parameters[ID::A_SIGNED] = RTLIL::Const(0); eq_cell->parameters[ID::B_SIGNED] = RTLIL::Const(0); @@ -268,6 +270,8 @@ struct MuxGenCtx { // reduce cmp vector to one logic signal RTLIL::Cell *any_cell = mod->addCell(mod->design->twines.add(std::string{sstr.str() + "_ANY"}), TW($reduce_or)); apply_attrs(any_cell, cs); + if (cs->compare_src != Twine::Null) + any_cell->set_src_attribute(cs->compare_src); any_cell->parameters[ID::A_SIGNED] = RTLIL::Const(0); any_cell->parameters[ID::A_WIDTH] = RTLIL::Const(cmp_wire->width); diff --git a/tests/proc/proc_mux_src.v b/tests/proc/proc_mux_src.v index 17d6da104..2856a4280 100644 --- a/tests/proc/proc_mux_src.v +++ b/tests/proc/proc_mux_src.v @@ -90,3 +90,25 @@ module tiny2( endcase end endmodule + +module ifelse(input clk, + input cond1, + input cond2, + output reg [1:0] out +); + + always @(posedge clk) begin + if (cond1) begin + out <= 0; + end else begin + if(cond2) + begin + out <= 1; + end + else + begin + out <= 2; + end + end + end +endmodule diff --git a/tests/proc/proc_mux_src.ys b/tests/proc/proc_mux_src.ys index 8c146db70..d72977a1c 100644 --- a/tests/proc/proc_mux_src.ys +++ b/tests/proc/proc_mux_src.ys @@ -28,3 +28,10 @@ select -assert-count 5 nested/t:$pmux select -assert-count 1 nested/t:$pmux a:src=proc_mux_src.v:21.5-21.20|proc_mux_src.v:26.5-26.20|proc_mux_src.v:32.5-45.12|proc_mux_src.v:48.5-48.19 %i # No nesting for output reg arith select -assert-count 1 nested/t:$pmux a:src=proc_mux_src.v:23.5-23.18|proc_mux_src.v:28.5-28.18|proc_mux_src.v:31.5-31.18|proc_mux_src.v:50.5-50.18 %i + +# if/elseif can't be turned into a $pmux +# Otherwise, behaves as expected +select -assert-count 0 ifelse/t:$pmux +select -assert-count 2 ifelse/t:$mux +select -assert-count 1 ifelse/t:$mux a:src=proc_mux_src.v:102.4-102.12|proc_mux_src.v:103.11-112.6 %i +select -assert-count 1 ifelse/t:$mux a:src=proc_mux_src.v:106.6-106.14|proc_mux_src.v:110.6-110.14 %i \ No newline at end of file