// This always points to the RTLIL::CaseRule beeing filled at the moment
RTLIL::CaseRule *current_case;
- // This two variables contain the replacement pattern to be used in the right hand side
+ // This map contains the replacement pattern to be used in the right hand side
// of an assignment. E.g. in the code "foo = bar; foo = func(foo);" the foo in the right
// hand side of the 2nd assignment needs to be replace with the temporary signal holding
// the value assigned in the first assignment. So when the first assignement is processed
// the according information is appended to subst_rvalue_from and subst_rvalue_to.
- RTLIL::SigSpec subst_rvalue_from, subst_rvalue_to;
+ std::map<RTLIL::SigBit, RTLIL::SigBit> subst_rvalue_map;
- // This two variables contain the replacement pattern to be used in the left hand side
+ // This map contains the replacement pattern to be used in the left hand side
// of an assignment. E.g. in the code "always @(posedge clk) foo <= bar" the signal bar
// should not be connected to the signal foo. Instead it must be connected to the temporary
// signal that is used as input for the register that drives the signal foo.
- RTLIL::SigSpec subst_lvalue_from, subst_lvalue_to;
+ std::map<RTLIL::SigBit, RTLIL::SigBit> subst_lvalue_map;
// The code here generates a number of temprorary signal for each output register. This
// map helps generating nice numbered names for all this temporary signals.
current_case = &proc->root_case;
// create initial temporary signal for all output registers
+ RTLIL::SigSpec subst_lvalue_from, subst_lvalue_to;
collect_lvalues(subst_lvalue_from, always, true, true);
subst_lvalue_to = new_temp_signal(subst_lvalue_from);
+ subst_lvalue_map = subst_lvalue_from.to_sigbit_map(subst_lvalue_to);
bool found_anyedge_syncs = false;
for (auto child : always->children)
// create initial assignments for the temporary signals
if ((flag_nolatches || always->get_bool_attribute("\\nolatches") || current_module->get_bool_attribute("\\nolatches")) && !found_clocked_sync) {
- subst_rvalue_from = subst_lvalue_from;
- subst_rvalue_to = RTLIL::SigSpec(RTLIL::State::Sx, subst_rvalue_from.size());
+ subst_rvalue_map = subst_lvalue_from.to_sigbit_map(RTLIL::SigSpec(RTLIL::State::Sx, SIZE(subst_lvalue_from)));
} else {
addChunkActions(current_case->actions, subst_lvalue_to, subst_lvalue_from);
}
case AST_ASSIGN_EQ:
case AST_ASSIGN_LE:
{
- std::map<RTLIL::SigBit, RTLIL::SigBit> new_subst_rvalue_map = subst_rvalue_from.to_sigbit_map(subst_rvalue_to);
RTLIL::SigSpec unmapped_lvalue = ast->children[0]->genRTLIL(), lvalue = unmapped_lvalue;
- RTLIL::SigSpec rvalue = ast->children[1]->genWidthRTLIL(lvalue.size(), &new_subst_rvalue_map);
- lvalue.replace(subst_lvalue_from, subst_lvalue_to);
+ RTLIL::SigSpec rvalue = ast->children[1]->genWidthRTLIL(lvalue.size(), &subst_rvalue_map);
+ lvalue.replace(subst_lvalue_map);
if (ast->type == AST_ASSIGN_EQ) {
- subst_rvalue_from.remove2(unmapped_lvalue, &subst_rvalue_to);
- subst_rvalue_from.append(unmapped_lvalue);
- subst_rvalue_to.append(rvalue);
+ for (int i = 0; i < SIZE(unmapped_lvalue); i++)
+ subst_rvalue_map[unmapped_lvalue[i]] = rvalue[i];
}
removeSignalFromCaseTree(lvalue, current_case);
case AST_CASE:
{
- std::map<RTLIL::SigBit, RTLIL::SigBit> new_subst_rvalue_map = subst_rvalue_from.to_sigbit_map(subst_rvalue_to);
RTLIL::SwitchRule *sw = new RTLIL::SwitchRule;
- sw->signal = ast->children[0]->genWidthRTLIL(-1, &new_subst_rvalue_map);
+ sw->signal = ast->children[0]->genWidthRTLIL(-1, &subst_rvalue_map);
current_case->switches.push_back(sw);
for (auto &attr : ast->attributes) {
RTLIL::SigSpec this_case_eq_ltemp = new_temp_signal(this_case_eq_lvalue);
RTLIL::SigSpec this_case_eq_rvalue = this_case_eq_lvalue;
- this_case_eq_rvalue.replace(subst_rvalue_from, subst_rvalue_to);
+ this_case_eq_rvalue.replace(subst_rvalue_map);
- RTLIL::SigSpec backup_subst_lvalue_from = subst_lvalue_from;
- RTLIL::SigSpec backup_subst_lvalue_to = subst_lvalue_to;
-
- RTLIL::SigSpec backup_subst_rvalue_from = subst_rvalue_from;
- RTLIL::SigSpec backup_subst_rvalue_to = subst_rvalue_to;
+ std::map<RTLIL::SigBit, RTLIL::SigBit> backup_subst_lvalue_map = subst_lvalue_map;
+ std::map<RTLIL::SigBit, RTLIL::SigBit> backup_subst_rvalue_map = subst_rvalue_map;
RTLIL::CaseRule *default_case = NULL;
RTLIL::CaseRule *last_generated_case = NULL;
continue;
log_assert(child->type == AST_COND);
- subst_lvalue_from = backup_subst_lvalue_from;
- subst_lvalue_to = backup_subst_lvalue_to;
-
- subst_rvalue_from = backup_subst_rvalue_from;
- subst_rvalue_to = backup_subst_rvalue_to;
+ subst_lvalue_map = backup_subst_lvalue_map;
+ subst_rvalue_map = backup_subst_rvalue_map;
- subst_lvalue_from.remove2(this_case_eq_lvalue, &subst_lvalue_to);
- subst_lvalue_from.append(this_case_eq_lvalue);
- subst_lvalue_to.append(this_case_eq_ltemp);
+ for (int i = 0; i < SIZE(this_case_eq_lvalue); i++)
+ subst_lvalue_map[this_case_eq_lvalue[i]] = this_case_eq_ltemp[i];
RTLIL::CaseRule *backup_case = current_case;
current_case = new RTLIL::CaseRule;
default_case = current_case;
else if (node->type == AST_BLOCK)
processAst(node);
- else {
- std::map<RTLIL::SigBit, RTLIL::SigBit> new_subst_rvalue_map = subst_rvalue_from.to_sigbit_map(subst_rvalue_to);
- current_case->compare.push_back(node->genWidthRTLIL(sw->signal.size(), &new_subst_rvalue_map));
- }
+ else
+ current_case->compare.push_back(node->genWidthRTLIL(sw->signal.size(), &subst_rvalue_map));
}
if (default_case != current_case)
sw->cases.push_back(current_case);
sw->cases.push_back(default_case);
}
- subst_lvalue_from = backup_subst_lvalue_from;
- subst_lvalue_to = backup_subst_lvalue_to;
-
- subst_rvalue_from = backup_subst_rvalue_from;
- subst_rvalue_to = backup_subst_rvalue_to;
+ subst_lvalue_map = backup_subst_lvalue_map;
+ subst_rvalue_map = backup_subst_rvalue_map;
- subst_rvalue_from.remove2(this_case_eq_lvalue, &subst_rvalue_to);
- subst_rvalue_from.append(this_case_eq_lvalue);
- subst_rvalue_to.append(this_case_eq_ltemp);
+ for (int i = 0; i < SIZE(this_case_eq_lvalue); i++)
+ subst_rvalue_map[this_case_eq_lvalue[i]] = this_case_eq_ltemp[i];
- this_case_eq_lvalue.replace(subst_lvalue_from, subst_lvalue_to);
+ this_case_eq_lvalue.replace(subst_lvalue_map);
removeSignalFromCaseTree(this_case_eq_lvalue, current_case);
addChunkActions(current_case->actions, this_case_eq_lvalue, this_case_eq_ltemp);
}