Correct hierarchical path names for structs and unions

This commit is contained in:
Dag Lem 2024-01-04 17:22:07 +01:00
parent df65634e07
commit 1bbea13f80
2 changed files with 23 additions and 19 deletions

View File

@ -226,17 +226,6 @@ void AstNode::annotateTypedEnums(AstNode *template_node)
}
}
static bool name_has_dot(const std::string &name, std::string &struct_name)
{
// check if plausible struct member name \sss.mmm
std::string::size_type pos;
if (name.substr(0, 1) == "\\" && (pos = name.find('.', 0)) != std::string::npos) {
struct_name = name.substr(0, pos);
return true;
}
return false;
}
static AstNode *make_range(int left, int right, bool is_signed = false)
{
// generate a pre-validated range node for a fixed signal range.
@ -2185,11 +2174,24 @@ bool AstNode::simplify(bool const_fold, int stage, int width_hint, bool sign_hin
if (type == AST_IDENTIFIER && !basic_prep) {
// check if a plausible struct member sss.mmmm
std::string sname;
if (name_has_dot(str, sname)) {
if (current_scope.count(str) > 0) {
auto item_node = current_scope[str];
if (item_node->type == AST_STRUCT_ITEM || item_node->type == AST_STRUCT || item_node->type == AST_UNION) {
if (!str.empty() && str[0] == '\\' && current_scope.count(str)) {
auto item_node = current_scope[str];
if (item_node->type == AST_STRUCT_ITEM || item_node->type == AST_STRUCT || item_node->type == AST_UNION) {
// Traverse any hierarchical path until the full name for the referenced struct/union is found.
std::string sname;
bool found_sname = false;
for (std::string::size_type pos = 0; (pos = str.find('.', pos)) != std::string::npos; pos++) {
sname = str.substr(0, pos);
if (current_scope.count(sname)) {
auto stype = current_scope[sname]->type;
if (stype == AST_WIRE || stype == AST_PARAMETER || stype == AST_LOCALPARAM) {
found_sname = true;
break;
}
}
}
if (found_sname) {
// structure member, rewrite this node to reference the packed struct wire
auto range = make_struct_member_range(this, item_node);
newNode = new AstNode(AST_IDENTIFIER, range);
@ -4681,6 +4683,8 @@ void AstNode::expand_genblock(const std::string &prefix)
switch (child->type) {
case AST_WIRE:
case AST_MEMORY:
case AST_STRUCT:
case AST_UNION:
case AST_PARAMETER:
case AST_LOCALPARAM:
case AST_FUNCTION:

View File

@ -45,12 +45,12 @@ module top;
localparam W = 10;
typedef T U;
typedef logic [W-1:0] V;
struct packed {
typedef struct packed {
logic [W-1:0] x; // width 10
U y; // width 5
V z; // width 10
} shadow;
// This currently only works as long as long as shadow is not typedef'ed
} shadow_t;
shadow_t shadow;
always @(*) assert($bits(shadow.x) == 10);
always @(*) assert($bits(shadow.y) == 5);
always @(*) assert($bits(shadow.z) == 10);