Track rand/randc qualifier on unpacked struct members
The random_qualifier on struct/union members was discarded at parse time. Record it as a VRandAttr on AstMemberDType (mirroring AstVar), threaded through GRAMMARP->m_memRand and applied when each member node is built, with dump()/dumpJson() support. No behavioral change on its own; consumed by the following commit.
This commit is contained in:
parent
1d42c45a34
commit
8d2f859adc
|
|
@ -968,7 +968,7 @@ class AstMemberDType final : public AstNodeDType {
|
|||
string m_tag; // Holds the string of the verilator tag -- used in JSON output.
|
||||
int m_lsb = -1; // Within this level's packed struct, the LSB of the first bit of the member
|
||||
bool m_constrainedRand = false;
|
||||
// UNSUP: int m_randType; // Randomization type (IEEE)
|
||||
VRandAttr m_rand; // Randomizability of this member (rand, randc, etc)
|
||||
public:
|
||||
AstMemberDType(FileLine* fl, const string& name, VFlagChildDType, AstNodeDType* dtp,
|
||||
AstNode* valuep)
|
||||
|
|
@ -1025,6 +1025,8 @@ public:
|
|||
}
|
||||
bool isConstrainedRand() const { return m_constrainedRand; }
|
||||
void markConstrainedRand(bool flag) { m_constrainedRand = flag; }
|
||||
VRandAttr rand() const { return m_rand; }
|
||||
void rand(const VRandAttr flag) { m_rand = flag; }
|
||||
};
|
||||
class AstNBACommitQueueDType final : public AstNodeDType {
|
||||
// @astgen ptr := m_subDTypep : AstNodeDType // Type of the corresponding variable
|
||||
|
|
|
|||
|
|
@ -2488,12 +2488,14 @@ const char* AstLoopTest::broken() const {
|
|||
void AstMemberDType::dump(std::ostream& str) const {
|
||||
this->AstNodeDType::dump(str);
|
||||
if (isConstrainedRand()) str << " [CONSTRAINEDRAND]";
|
||||
if (rand().isRandomizable()) str << " [" << rand() << "]";
|
||||
if (name() != "") str << " name=" << name();
|
||||
if (tag() != "") str << " tag=" << tag();
|
||||
}
|
||||
|
||||
void AstMemberDType::dumpJson(std::ostream& str) const {
|
||||
dumpJsonBoolFuncIf(str, isConstrainedRand);
|
||||
if (rand().isRandomizable()) dumpJsonStr(str, "rand", rand().ascii());
|
||||
dumpJsonStrFunc(str, name);
|
||||
dumpJsonStrFunc(str, tag);
|
||||
dumpJsonGen(str);
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ public:
|
|||
AstCase* m_caseAttrp = nullptr; // Current case statement for attribute adding
|
||||
AstNodeDType* m_varDTypep = nullptr; // Pointer to data type for next signal declaration
|
||||
AstNodeDType* m_memDTypep = nullptr; // Pointer to data type for next member declaration
|
||||
VRandAttr m_memRand; // 'rand'/'randc' qualifier for next member declaration
|
||||
AstDelay* m_netDelayp = nullptr; // Pointer to delay for next signal declaration
|
||||
AstStrengthSpec* m_netStrengthp = nullptr; // Pointer to strength for next net declaration
|
||||
FileLine* m_instModuleFl = nullptr; // Fileline of module referenced for instantiations
|
||||
|
|
|
|||
|
|
@ -69,6 +69,11 @@ struct VMemberQualifiers final {
|
|||
q.m_flags = a.m_flags | b.m_flags;
|
||||
return q;
|
||||
}
|
||||
VRandAttr randAttr() const {
|
||||
if (m_randc) return VRandAttr::RAND_CYCLIC;
|
||||
if (m_rand) return VRandAttr::RAND;
|
||||
return VRandAttr::NONE;
|
||||
}
|
||||
void applyToNodes(AstNodeFTask* nodesp) const {
|
||||
for (AstNodeFTask* nodep = nodesp; nodep; nodep = VN_AS(nodep->nextp(), NodeFTask)) {
|
||||
if (m_local) nodep->isHideLocal(true);
|
||||
|
|
|
|||
|
|
@ -2204,11 +2204,13 @@ struct_union_memberList<memberDTypep>: // IEEE: { struct_union_member }
|
|||
;
|
||||
|
||||
struct_union_member<memberDTypep>: // ==IEEE: struct_union_member
|
||||
// // UNSUP random_qualifer not propagated until have randomize support
|
||||
random_qualifierE data_type_or_void
|
||||
/*mid*/ { GRAMMARP->m_memDTypep = $2; } // As a list follows, need to attach this dtype to each member.
|
||||
/*mid*/ { GRAMMARP->m_memDTypep = $2; // As a list follows, need to attach this dtype to each member.
|
||||
GRAMMARP->m_memRand = $1.randAttr(); }
|
||||
/*cont*/ list_of_member_decl_assignments ';'
|
||||
{ $$ = $4; DEL(GRAMMARP->m_memDTypep); GRAMMARP->m_memDTypep = nullptr; }
|
||||
{ $$ = $4;
|
||||
DEL(GRAMMARP->m_memDTypep); GRAMMARP->m_memDTypep = nullptr;
|
||||
GRAMMARP->m_memRand = VRandAttr::NONE; }
|
||||
| vlTag { $$ = nullptr; }
|
||||
;
|
||||
|
||||
|
|
@ -2226,6 +2228,7 @@ member_decl_assignment<memberDTypep>: // Derived from IEEE: variable_decl_assi
|
|||
? GRAMMARP->m_memDTypep->cloneTree(true) : nullptr),
|
||||
$2, false),
|
||||
nullptr};
|
||||
$$->rand(GRAMMARP->m_memRand);
|
||||
PARSEP->tagNodep($$);
|
||||
}
|
||||
| idAny variable_dimensionListE '=' variable_declExpr
|
||||
|
|
@ -2234,6 +2237,7 @@ member_decl_assignment<memberDTypep>: // Derived from IEEE: variable_decl_assi
|
|||
? GRAMMARP->m_memDTypep->cloneTree(true) : nullptr),
|
||||
$2, false),
|
||||
$4};
|
||||
$$->rand(GRAMMARP->m_memRand);
|
||||
PARSEP->tagNodep($$);
|
||||
}
|
||||
| idSVKwd { $$ = nullptr; }
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ module Vt_debug_emitv_t;
|
|||
} ps_t;
|
||||
typedef struct {
|
||||
logic signed [2:0] a;
|
||||
logic [1:0] b;
|
||||
} us_t;
|
||||
typedef union {
|
||||
logic a;
|
||||
|
|
@ -19,6 +20,7 @@ module Vt_debug_emitv_t;
|
|||
} ps[0:2];
|
||||
struct {
|
||||
logic signed [2:0] a;
|
||||
logic [1:0] b;
|
||||
} us;
|
||||
union {
|
||||
logic a;
|
||||
|
|
|
|||
|
|
@ -64,6 +64,7 @@ module t (/*AUTOARG*/
|
|||
} ps_t;
|
||||
typedef struct {
|
||||
logic signed [2:0] a;
|
||||
rand logic [1:0] b;
|
||||
} us_t;
|
||||
typedef union {
|
||||
logic a;
|
||||
|
|
|
|||
Loading…
Reference in New Issue