mirror of
https://github.com/YosysHQ/yosys
synced 2025-04-24 01:25:33 +00:00
Fix FIRRTL to Verilog process instance subfield assignment.
Don't emit subfield assignments: bits(x, y, z) <= ... - but instead, add them to the reverse-wire-map where they'll be treated at the end of the module. Enable tests which were disabled due to incorrect treatment of subfields. Assume the `$firrtl2verilog` variable contains any additional switches to control verilog generation (i.e. `--no-dedup -X mverilog`)
This commit is contained in:
parent
c258b99040
commit
171c425cf9
4 changed files with 21 additions and 11 deletions
|
@ -169,7 +169,6 @@ struct FirrtlWorker
|
|||
return *str == '\\' ? str + 1 : str;
|
||||
}
|
||||
|
||||
|
||||
std::string cellname(RTLIL::Cell *cell)
|
||||
{
|
||||
return fid(cell->name).c_str();
|
||||
|
@ -219,29 +218,42 @@ struct FirrtlWorker
|
|||
if (it->second.size() > 0) {
|
||||
const SigSpec &secondSig = it->second;
|
||||
const std::string firstName = cell_name + "." + make_id(it->first);
|
||||
const std::string secondName = make_expr(secondSig);
|
||||
const std::string secondExpr = make_expr(secondSig);
|
||||
// Find the direction for this port.
|
||||
FDirection dir = getPortFDirection(it->first, instModule);
|
||||
std::string source, sink;
|
||||
std::string sourceExpr, sinkExpr;
|
||||
const SigSpec *sinkSig = nullptr;
|
||||
switch (dir) {
|
||||
case FD_INOUT:
|
||||
log_warning("Instance port connection %s.%s is INOUT; treating as OUT\n", cell_type.c_str(), log_signal(it->second));
|
||||
case FD_OUT:
|
||||
source = firstName;
|
||||
sink = secondName;
|
||||
sourceExpr = firstName;
|
||||
sinkExpr = secondExpr;
|
||||
sinkSig = &secondSig;
|
||||
break;
|
||||
case FD_NODIRECTION:
|
||||
log_warning("Instance port connection %s.%s is NODIRECTION; treating as IN\n", cell_type.c_str(), log_signal(it->second));
|
||||
/* FALL_THROUGH */
|
||||
case FD_IN:
|
||||
source = secondName;
|
||||
sink = firstName;
|
||||
sourceExpr = secondExpr;
|
||||
sinkExpr = firstName;
|
||||
break;
|
||||
default:
|
||||
log_error("Instance port %s.%s unrecognized connection direction 0x%x !\n", cell_type.c_str(), log_signal(it->second), dir);
|
||||
break;
|
||||
}
|
||||
wire_exprs.push_back(stringf("\n%s%s <= %s", indent.c_str(), sink.c_str(), source.c_str()));
|
||||
// Check for subfield assignment.
|
||||
std::string bitsString = "bits(";
|
||||
if (sinkExpr.substr(0, bitsString.length()) == bitsString ) {
|
||||
if (sinkSig == nullptr)
|
||||
log_error("Unknown subfield %s.%s\n", cell_type.c_str(), sinkExpr.c_str());
|
||||
// Don't generate the assignment here.
|
||||
// Add the source and sink to the "reverse_wire_map" and we'll output the assignment
|
||||
// as part of the coalesced subfield assignments for this wire.
|
||||
register_reverse_wire_map(sourceExpr, *sinkSig);
|
||||
} else {
|
||||
wire_exprs.push_back(stringf("\n%s%s <= %s", indent.c_str(), sinkExpr.c_str(), sourceExpr.c_str()));
|
||||
}
|
||||
}
|
||||
}
|
||||
wire_exprs.push_back(stringf("\n"));
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue