}
// helper function for extending bit width (preferred over SigSpec::extend() because of correct undef propagation in ConstEval)
-static void widthExtend(AstNode *that, RTLIL::SigSpec &sig, int width, bool is_signed, std::string celltype)
+static void widthExtend(AstNode *that, RTLIL::SigSpec &sig, int width, bool is_signed)
{
if (width <= sig.size()) {
- sig.extend(width, is_signed);
+ sig.extend_u0(width, is_signed);
return;
}
std::stringstream sstr;
sstr << "$extend" << "$" << that->filename << ":" << that->linenum << "$" << (autoidx++);
- RTLIL::Cell *cell = current_module->addCell(sstr.str(), celltype);
+ RTLIL::Cell *cell = current_module->addCell(sstr.str(), "$pos");
cell->attributes["\\src"] = stringf("%s:%d", that->filename.c_str(), that->linenum);
RTLIL::Wire *wire = current_module->addWire(cell->name.str() + "_Y", width);
// 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_map = subst_lvalue_from.to_sigbit_map(RTLIL::SigSpec(RTLIL::State::Sx, SIZE(subst_lvalue_from)));
+ subst_rvalue_map = subst_lvalue_from.to_sigbit_map(RTLIL::SigSpec(RTLIL::State::Sx, GetSize(subst_lvalue_from)));
} else {
addChunkActions(current_case->actions, subst_lvalue_to, subst_lvalue_from);
}
for (auto &init_lvalue_c : init_lvalue.chunks()) {
RTLIL::SigSpec lhs = init_lvalue_c;
RTLIL::SigSpec rhs = init_rvalue.extract(offset, init_lvalue_c.width);
+ remove_unwanted_lvalue_bits(lhs, rhs);
sync->actions.push_back(RTLIL::SigSig(lhs, rhs));
offset += lhs.size();
}
outputSignals = RTLIL::SigSpec(subst_lvalue_from);
}
+ void remove_unwanted_lvalue_bits(RTLIL::SigSpec &lhs, RTLIL::SigSpec &rhs)
+ {
+ RTLIL::SigSpec new_lhs, new_rhs;
+
+ log_assert(GetSize(lhs) == GetSize(rhs));
+ for (int i = 0; i < GetSize(lhs); i++) {
+ if (lhs[i].wire == nullptr)
+ continue;
+ new_lhs.append(lhs[i]);
+ new_rhs.append(rhs[i]);
+ }
+
+ lhs = new_lhs;
+ rhs = new_rhs;
+ }
+
// create new temporary signals
RTLIL::SigSpec new_temp_signal(RTLIL::SigSpec sig)
{
std::vector<RTLIL::SigChunk> chunks = sig.chunks();
- for (int i = 0; i < SIZE(chunks); i++)
+ for (int i = 0; i < GetSize(chunks); i++)
{
RTLIL::SigChunk &chunk = chunks[i];
if (chunk.wire == NULL)
log_abort();
}
- if (run_sort_and_unify)
- reg.sort_and_unify();
+ if (run_sort_and_unify) {
+ std::set<RTLIL::SigBit> sorted_reg;
+ for (auto bit : reg)
+ if (bit.wire)
+ sorted_reg.insert(bit);
+ reg = RTLIL::SigSpec(sorted_reg);
+ }
}
// remove all assignments to the given signal pattern in a case and all its children.
RTLIL::SigSpec rhs = rvalue.extract(offset, lvalue_c.width);
if (inSyncRule && lvalue_c.wire && lvalue_c.wire->get_bool_attribute("\\nosync"))
rhs = RTLIL::SigSpec(RTLIL::State::Sx, rhs.size());
+ remove_unwanted_lvalue_bits(lhs, rhs);
actions.push_back(RTLIL::SigSig(lhs, rhs));
offset += lhs.size();
}
lvalue.replace(subst_lvalue_map.stdmap());
if (ast->type == AST_ASSIGN_EQ) {
- for (int i = 0; i < SIZE(unmapped_lvalue); i++)
+ for (int i = 0; i < GetSize(unmapped_lvalue); i++)
subst_rvalue_map.set(unmapped_lvalue[i], rvalue[i]);
}
removeSignalFromCaseTree(lvalue.to_sigbit_set(), current_case);
+ remove_unwanted_lvalue_bits(lvalue, rvalue);
current_case->actions.push_back(RTLIL::SigSig(lvalue, rvalue));
}
break;
subst_lvalue_map.save();
subst_rvalue_map.save();
- for (int i = 0; i < SIZE(this_case_eq_lvalue); i++)
+ for (int i = 0; i < GetSize(this_case_eq_lvalue); i++)
subst_lvalue_map.set(this_case_eq_lvalue[i], this_case_eq_ltemp[i]);
RTLIL::CaseRule *backup_case = current_case;
sw->cases.push_back(default_case);
}
- for (int i = 0; i < SIZE(this_case_eq_lvalue); i++)
+ for (int i = 0; i < GetSize(this_case_eq_lvalue); i++)
subst_rvalue_map.set(this_case_eq_lvalue[i], this_case_eq_ltemp[i]);
this_case_eq_lvalue.replace(subst_lvalue_map.stdmap());
case AST_REALVALUE:
{
RTLIL::SigSpec sig = realAsConst(width_hint);
- log("Warning: converting real value %e to binary %s at %s:%d.\n",
+ log_warning("converting real value %e to binary %s at %s:%d.\n",
realvalue, log_signal(sig), filename.c_str(), linenum);
return sig;
}
wire->attributes["\\src"] = stringf("%s:%d", filename.c_str(), linenum);
wire->name = str;
if (flag_autowire)
- log("Warning: Identifier `%s' is implicitly declared at %s:%d.\n", str.c_str(), filename.c_str(), linenum);
+ log_warning("Identifier `%s' is implicitly declared at %s:%d.\n", str.c_str(), filename.c_str(), linenum);
else
log_error("Identifier `%s' is implicitly declared at %s:%d and `default_nettype is set to none.\n", str.c_str(), filename.c_str(), linenum);
}
shift_val = current_module->Sub(NEW_ID, RTLIL::SigSpec(source_width - width), shift_val, fake_ast->children[1]->is_signed);
fake_ast->children[1]->is_signed = true;
}
- if (SIZE(shift_val) >= 32)
+ if (GetSize(shift_val) >= 32)
fake_ast->children[1]->is_signed = true;
RTLIL::SigSpec sig = binop2rtlil(fake_ast, "$shiftx", width, fake_ast->children[0]->genRTLIL(), shift_val);
delete left_at_zero_ast;
chunk.offset = (id2ast->range_left - id2ast->range_right + 1) - (chunk.offset + chunk.width);
if (chunk.offset >= source_width || chunk.offset + chunk.width < 0) {
if (chunk.width == 1)
- log("Warning: Range select out of bounds on signal `%s' at %s:%d: Setting result bit to undef.\n",
+ log_warning("Range select out of bounds on signal `%s' at %s:%d: Setting result bit to undef.\n",
str.c_str(), filename.c_str(), linenum);
else
- log("Warning: Range select out of bounds on signal `%s' at %s:%d: Setting all %d result bits to undef.\n",
+ log_warning("Range select out of bounds on signal `%s' at %s:%d: Setting all %d result bits to undef.\n",
str.c_str(), filename.c_str(), linenum, chunk.width);
chunk = RTLIL::SigChunk(RTLIL::State::Sx, chunk.width);
} else {
chunk.offset += add_undef_bits_lsb;
}
if (add_undef_bits_lsb)
- log("Warning: Range select out of bounds on signal `%s' at %s:%d: Setting %d LSB bits to undef.\n",
+ log_warning("Range select out of bounds on signal `%s' at %s:%d: Setting %d LSB bits to undef.\n",
str.c_str(), filename.c_str(), linenum, add_undef_bits_lsb);
if (add_undef_bits_msb)
- log("Warning: Range select out of bounds on signal `%s' at %s:%d: Setting %d MSB bits to undef.\n",
+ log_warning("Range select out of bounds on signal `%s' at %s:%d: Setting %d MSB bits to undef.\n",
str.c_str(), filename.c_str(), linenum, add_undef_bits_msb);
}
}
int width = arg.size();
if (width_hint > 0) {
width = width_hint;
- widthExtend(this, arg, width, is_signed, "$pos");
+ widthExtend(this, arg, width, is_signed);
}
return uniop2rtlil(this, type_name, width, arg);
}
int width = std::max(val1.size(), val2.size());
is_signed = children[1]->is_signed && children[2]->is_signed;
- widthExtend(this, val1, width, is_signed, "$bu0");
- widthExtend(this, val2, width, is_signed, "$bu0");
+ widthExtend(this, val1, width, is_signed);
+ widthExtend(this, val2, width, is_signed);
RTLIL::SigSpec sig = mux2rtlil(this, cond, val1, val2);