Fix change detection on unpacked arrays

Expand array assignment when creating the trigger, as V3Expand might
mangle it otherwise.
This commit is contained in:
Geza Lore 2022-08-02 12:21:02 +01:00
parent ba66fa7200
commit 39d1a62f9e
2 changed files with 29 additions and 3 deletions

View File

@ -926,6 +926,8 @@ template <class T_Value, std::size_t T_Depth> struct VlUnpacked final {
// *this != that, which might be used for change detection/trigger computation, but avoid
// operator overloading in VlUnpacked for safety in other contexts.
inline bool neq(const VlUnpacked<T_Value, T_Depth>& that) const { return neq(*this, that); }
// Similar to 'neq' above, *this = that used for change detection
void assign(const VlUnpacked<T_Value, T_Depth>& that) { *this = that; }
// Dumping. Verilog: str = $sformatf("%p", assoc)
std::string to_string() const {

View File

@ -274,6 +274,15 @@ class SenExprBuilder final {
V3UniqueNames m_uniqueNames{"__Vtrigprev__expression"}; // For generating unique signal names
static bool isSupportedDType(AstNodeDType* dtypep) {
dtypep = dtypep->skipRefp();
if (VN_IS(dtypep, BasicDType)) return true;
if (VN_IS(dtypep, PackArrayDType)) return true;
if (VN_IS(dtypep, UnpackArrayDType)) return isSupportedDType(dtypep->subDTypep());
if (VN_IS(dtypep, NodeUOrStructDType)) return true; // All are packed at the moment
return false;
}
// METHODS
AstVarScope* getPrev(AstNode* currp) {
FileLine* const flp = currp->fileline();
@ -303,10 +312,25 @@ class SenExprBuilder final {
AstVarScope* const prevp = it->second;
// Add update if it does not exist yet in this round
const auto wrPrev = [=]() { return new AstVarRef{flp, prevp, VAccess::WRITE}; };
// Add update if it does not exist yet
if (m_hasUpdate.emplace(*currp).second) {
m_updates.push_back(
new AstAssign{flp, new AstVarRef{flp, prevp, VAccess::WRITE}, rdCurr()});
if (!isSupportedDType(currp->dtypep())) {
currp->v3warn(E_UNSUPPORTED,
"Unsupported: Cannot detect changes on expression of complex type"
" (see combinational cycles reported by UNOPTFLAT)");
return prevp;
}
if (AstUnpackArrayDType* const dtypep = VN_CAST(currp->dtypep(), UnpackArrayDType)) {
AstCMethodHard* const cmhp = new AstCMethodHard{flp, wrPrev(), "assign", rdCurr()};
cmhp->dtypeSetVoid();
cmhp->statement(true);
m_updates.push_back(cmhp);
} else {
m_updates.push_back(new AstAssign{flp, wrPrev(), rdCurr()});
}
}
return prevp;