Skip to content

Commit

Permalink
Add getters for AssignModifyStatements and NetVariableAssignment
Browse files Browse the repository at this point in the history
  • Loading branch information
IEncinas10 committed Jul 14, 2023
1 parent 1c7bb01 commit 628301a
Show file tree
Hide file tree
Showing 3 changed files with 272 additions and 0 deletions.
40 changes: 40 additions & 0 deletions verilog/CST/statement.cc
Original file line number Diff line number Diff line change
Expand Up @@ -505,4 +505,44 @@ const verible::Symbol *GetEventControlFromProceduralTimingControl(
0, NodeEnum::kEventControl);
}

const verible::SyntaxTreeLeaf *GetAssignModifyOperator(
const verible::SyntaxTreeNode &assign_modify) {
if (!assign_modify.MatchesTag(NodeEnum::kAssignModifyStatement)) {
return nullptr;
}

return verible::GetSubtreeAsLeaf(assign_modify,
NodeEnum::kAssignModifyStatement, 1);
}

const verible::SyntaxTreeNode *GetAssignModifyRhs(
const verible::SyntaxTreeNode &assign_modify) {
if (!assign_modify.MatchesTag(NodeEnum::kAssignModifyStatement)) {
return nullptr;
}

return verible::GetSubtreeAsNode(assign_modify,
NodeEnum::kAssignModifyStatement, 2);
}

const verible::SyntaxTreeNode *GetAssignModifyLhs(
const verible::SyntaxTreeNode &assign_modify) {
if (!assign_modify.MatchesTag(NodeEnum::kAssignModifyStatement)) {
return nullptr;
}

return verible::GetSubtreeAsNode(assign_modify,
NodeEnum::kAssignModifyStatement, 0);
}

const verible::SyntaxTreeNode *GetNetVariableAssignmentLhs(
const verible::SyntaxTreeNode &assignment) {
if (!assignment.MatchesTag(NodeEnum::kNetVariableAssignment)) {
return nullptr;
}

return verible::GetSubtreeAsNode(assignment, NodeEnum::kNetVariableAssignment,
0);
}

} // namespace verilog
20 changes: 20 additions & 0 deletions verilog/CST/statement.h
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,26 @@ const verible::SyntaxTreeNode *GetProceduralTimingControlFromAlways(
const verible::Symbol *GetEventControlFromProceduralTimingControl(
const verible::SyntaxTreeNode &proc_timing_ctrl);

// Return the operator from an AssignModifyStatement
// Example: get '&' from 'x &= y'
const verible::SyntaxTreeLeaf *GetAssignModifyOperator(
const verible::SyntaxTreeNode &assign_modify);

// Return the right hand side (Rhs) from an AssignModifyStatement
// Example: get 'y' from 'x &= y'
const verible::SyntaxTreeNode *GetAssignModifyRhs(
const verible::SyntaxTreeNode &assign_modify);

// Return the left hand side (Lhs) from an AssignModifyStatement
// Example: get 'x' from 'x &= y'
const verible::SyntaxTreeNode *GetAssignModifyLhs(
const verible::SyntaxTreeNode &assign_modify);

// Return the left hand side (Lhs) from a NetVariableAssignment
// Example: get 'x' from 'x = y'
const verible::SyntaxTreeNode *GetNetVariableAssignmentLhs(
const verible::SyntaxTreeNode &assignment);

} // namespace verilog

#endif // VERIBLE_VERILOG_CST_STATEMENT_H_
212 changes: 212 additions & 0 deletions verilog/CST/statement_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1373,5 +1373,217 @@ TEST(GetGenerateBlockEndTest, Various) {
}
}

TEST(GetAssignModifyOperator, Various) {
constexpr int kTag = 1; // value doesn't matter
const SyntaxTreeSearchTestCase kTestCases[] = {
{""},
{"module m;\nendmodule\n"},
{"module m;\n"
"reg k;\n"
"always_comb begin\n"
"k ",
{kTag, "&="},
" 1;\nend\n"
"endmodule\n"},
{"module m;\n"
"reg k;\n"
"always_comb begin\n"
"k ",
{kTag, "|="},
" 1;\nend\n"
"endmodule\n"},
{"module m;\n"
"reg k;\n"
"always_comb begin\n"
"k ",
{kTag, "+="},
" 1;\nend\n"
"endmodule\n"},
{"module m;\n"
"reg k;\n"
"always_comb begin\n"
"k = 1;\nend\n"
"endmodule\n"},
{"module m;\n"
"always_comb begin "
"reg k = 1;\nend\n"
"endmodule\n"},
};
for (const auto &test : kTestCases) {
TestVerilogSyntaxRangeMatches(
__FUNCTION__, test, [](const TextStructureView &text_structure) {
const auto &root = text_structure.SyntaxTree();
const auto &assign_modify_statements = SearchSyntaxTree(
*ABSL_DIE_IF_NULL(root), NodekAssignModifyStatement());

std::vector<TreeSearchMatch> operators;
for (const auto &block : assign_modify_statements) {
const auto *operator_ = GetAssignModifyOperator(
verible::SymbolCastToNode(*block.match));
operators.emplace_back(
TreeSearchMatch{operator_, {/* ignored context */}});
}
return operators;
});
}
}

TEST(GetAssignModifyLhs, Various) {
constexpr int kTag = 1; // value doesn't matter
const SyntaxTreeSearchTestCase kTestCases[] = {
{""},
{"module m;\nendmodule\n"},
{"module m;\n"
"reg k;\n"
"always_comb begin ",
{kTag, "k"},
" &= 1;\nend\n"
"endmodule\n"},
{"module m;\n"
"reg k;\n"
"always_comb begin\n",
{kTag, "k"},
" |= 1;\nend\n"
"endmodule\n"},
{"module m;\n"
"reg k;\n"
"always_comb begin\n",
{kTag, "k"},
" += 1;\nend\n"
"endmodule\n"},
{"module m;\n"
"reg k;\n"
"always_comb begin\n"
"k = 1;\nend\n"
"endmodule\n"},
{"module m;\n"
"always_comb begin\n"
"reg k = 1;\nend\n"
"endmodule\n"},
};
for (const auto &test : kTestCases) {
TestVerilogSyntaxRangeMatches(
__FUNCTION__, test, [](const TextStructureView &text_structure) {
const auto &root = text_structure.SyntaxTree();
const auto &assign_modify_statements = SearchSyntaxTree(
*ABSL_DIE_IF_NULL(root), NodekAssignModifyStatement());

std::vector<TreeSearchMatch> left_hand_sides;
for (const auto &block : assign_modify_statements) {
const auto *lhs =
GetAssignModifyLhs(verible::SymbolCastToNode(*block.match));
left_hand_sides.emplace_back(
TreeSearchMatch{lhs, {/* ignored context */}});
}
return left_hand_sides;
});
}
}

TEST(GetAssignModifyRhs, Various) {
constexpr int kTag = 1; // value doesn't matter
const SyntaxTreeSearchTestCase kTestCases[] = {
{""},
{"module m;\nendmodule\n"},
{"module m;\n"
"reg k;\n"
"always_comb begin "
"k &= ",
{kTag, "1"},
";\nend\nendmodule\n"},
{"module m;\n"
"reg k;\n"
"always_comb begin\n"
"k |= ",
{kTag, "(1 + 2)"},
";\nend\nendmodule\n"},
{"module m;\n"
"reg k;\n"
"always_comb begin\n"
"k += ",
{kTag, "1"},
";\nend\nendmodule\n"},
{"module m;\n"
"reg k;\n"
"always_comb begin\n"
"k = 1;\nend\n"
"endmodule\n"},
{"module m;\n"
"always_comb begin\n"
"reg k = 1;\nend\n"
"endmodule\n"},
};
for (const auto &test : kTestCases) {
TestVerilogSyntaxRangeMatches(
__FUNCTION__, test, [](const TextStructureView &text_structure) {
const auto &root = text_structure.SyntaxTree();
const auto &assign_modify_statements = SearchSyntaxTree(
*ABSL_DIE_IF_NULL(root), NodekAssignModifyStatement());

std::vector<TreeSearchMatch> right_hand_sides;
for (const auto &block : assign_modify_statements) {
const auto *rhs =
GetAssignModifyRhs(verible::SymbolCastToNode(*block.match));
right_hand_sides.emplace_back(
TreeSearchMatch{rhs, {/* ignored context */}});
}
return right_hand_sides;
});
}
}

TEST(GetNetVariableAssignmentLhs, Various) {
constexpr int kTag = 1; // value doesn't matter
const SyntaxTreeSearchTestCase kTestCases[] = {
{""},
{"module m;\nendmodule\n"},
{"module m;\n"
"reg k;\n"
"always_comb begin\n",
{kTag, "k"},
" = 1;\nend\n",
"endmodule\n"},
{"module m;\n"
"reg k;\n"
"always_comb begin\n",
{kTag, "k"},
" = 1;\nend\n"
"endmodule\n"},
{"module m;\n"
"reg k;\n"
"always_comb begin\n",
{kTag, "k"},
" = 1;\nend\n"
"endmodule\n"},
{"module m;\n"
"reg k;\n"
"always_comb begin\n"
"k |= 1;\nend\n"
"endmodule\n"},
{"module m;\n"
"reg k;\n"
"always_ff begin\n"
"k <= 1;\nend\n"
"endmodule\n"},
};
for (const auto &test : kTestCases) {
TestVerilogSyntaxRangeMatches(
__FUNCTION__, test, [](const TextStructureView &text_structure) {
const auto &root = text_structure.SyntaxTree();
const auto &net_var_assignments = SearchSyntaxTree(
*ABSL_DIE_IF_NULL(root), NodekNetVariableAssignment());

std::vector<TreeSearchMatch> left_hand_sides;
for (const auto &assignment : net_var_assignments) {
const auto *lhs = GetNetVariableAssignmentLhs(
verible::SymbolCastToNode(*assignment.match));
left_hand_sides.emplace_back(
TreeSearchMatch{lhs, {/* ignored context */}});
}
return left_hand_sides;
});
}
}

} // namespace
} // namespace verilog

0 comments on commit 628301a

Please sign in to comment.