aboutsummaryrefslogtreecommitdiffstats
path: root/backends
diff options
context:
space:
mode:
authorClifford Wolf <clifford@clifford.at>2019-02-28 14:45:04 -0800
committerGitHub <noreply@github.com>2019-02-28 14:45:04 -0800
commit6d143c9a018e5ba352a06785afeba8d50178a835 (patch)
tree99a407c011ff773195f889cd04926ec0f5f1a3c1 /backends
parent64d91219b4e81366976a0e0a9b28efa4bd825022 (diff)
parent171c425cf9addb61ef3f03596fd26355ed8af76d (diff)
downloadyosys-6d143c9a018e5ba352a06785afeba8d50178a835.tar.gz
yosys-6d143c9a018e5ba352a06785afeba8d50178a835.tar.bz2
yosys-6d143c9a018e5ba352a06785afeba8d50178a835.zip
Merge pull request #827 from ucb-bar/firrtlfixes
Fix FIRRTL to Verilog process instance subfield assignment.
Diffstat (limited to 'backends')
-rw-r--r--backends/firrtl/firrtl.cc28
1 files changed, 20 insertions, 8 deletions
diff --git a/backends/firrtl/firrtl.cc b/backends/firrtl/firrtl.cc
index 0917ecba6..88c1038b7 100644
--- a/backends/firrtl/firrtl.cc
+++ b/backends/firrtl/firrtl.cc
@@ -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"));