From 628301ae32dfa2e73c4b6cf335296172fb42a036 Mon Sep 17 00:00:00 2001 From: IEncinas10 Date: Sun, 7 May 2023 20:45:48 +0200 Subject: [PATCH] Add getters for AssignModifyStatements and NetVariableAssignment --- verilog/CST/statement.cc | 40 +++++++ verilog/CST/statement.h | 20 ++++ verilog/CST/statement_test.cc | 212 ++++++++++++++++++++++++++++++++++ 3 files changed, 272 insertions(+) diff --git a/verilog/CST/statement.cc b/verilog/CST/statement.cc index 668952d120..098051033f 100644 --- a/verilog/CST/statement.cc +++ b/verilog/CST/statement.cc @@ -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 diff --git a/verilog/CST/statement.h b/verilog/CST/statement.h index a6811a9a04..a437ab7dea 100644 --- a/verilog/CST/statement.h +++ b/verilog/CST/statement.h @@ -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_ diff --git a/verilog/CST/statement_test.cc b/verilog/CST/statement_test.cc index 3447778e70..ab4e08c414 100644 --- a/verilog/CST/statement_test.cc +++ b/verilog/CST/statement_test.cc @@ -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 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 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 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 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