| // Copyright 2017-2020 The Verible Authors. | |
| // | |
| // Licensed under the Apache License, Version 2.0 (the "License"); | |
| // you may not use this file except in compliance with the License. | |
| // You may obtain a copy of the License at | |
| // | |
| // http://www.apache.org/licenses/LICENSE-2.0 | |
| // | |
| // Unless required by applicable law or agreed to in writing, software | |
| // distributed under the License is distributed on an "AS IS" BASIS, | |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| // See the License for the specific language governing permissions and | |
| // limitations under the License. | |
| #include "verilog/analysis/checkers/module_instantiation_rules.h" | |
| #include <initializer_list> | |
| #include "gtest/gtest.h" | |
| #include "common/analysis/linter_test_utils.h" | |
| #include "common/analysis/syntax_tree_linter_test_utils.h" | |
| #include "common/text/symbol.h" | |
| #include "verilog/CST/verilog_nonterminals.h" | |
| #include "verilog/CST/verilog_treebuilder_utils.h" | |
| #include "verilog/analysis/verilog_analyzer.h" | |
| #include "verilog/parser/verilog_token_enum.h" | |
| namespace verilog { | |
| namespace analysis { | |
| namespace { | |
| using verible::LintTestCase; | |
| using verible::RunLintTestCases; | |
| TEST(ModuleInstantiationTests, Parameters) { | |
| const std::initializer_list<LintTestCase> kTestCases = { | |
| // Test incorrect code | |
| {"module m; foo #(", | |
| {SymbolIdentifier, "fizz"}, | |
| ", buzz) bar; endmodule"}, | |
| // Note: The following cases are already syntactically rejected: | |
| // {"module m; foo #(.fizz(bang), buzz) bar;"}, | |
| // {"module m; foo #(fizz, .buzz(pop)) bar;"}, | |
| {"module m; foo #(", {TK_DecNumber, "1"}, ", 2, 3) bar; endmodule"}, | |
| {"module m; foo #(", {TK_DecNumber, "1"}, ", \n2, \n3) bar; endmodule"}, | |
| { | |
| "module m; foo #(", | |
| {TK_DecNumber, "3"}, | |
| ", 1) bar; endmodule\n" | |
| "function f; beep #(1, 2) boop; endfunction" // inside function does | |
| // not trigger | |
| }, | |
| // TODO(fangism): determine how to handle conditionals | |
| // {"module m; foo #(\n`ifdef FOO\n2,\n`endif\n4) bar; endmodule"}, | |
| // Test correct code | |
| {""}, | |
| {"\n"}, | |
| {"module m; endmodule"}, | |
| {"module m; wire money; endmodule"}, | |
| {"function f; endfunction"}, | |
| {"class c; endclass"}, | |
| { | |
| "function f; beep #(5, 2) boop; endfunction" | |
| // inside function does not trigger | |
| }, | |
| { | |
| "class c; beep #(5, 2) boop; endclass" | |
| // inside class does not trigger | |
| }, | |
| { | |
| "class c; function f; beep #(5, 2) boop; endfunction endclass" | |
| // inside method does not trigger | |
| }, | |
| {"module m; foo #(1) bar; endmodule"}, | |
| {"module m; foo bar; endmodule"}, | |
| {"module m; foo bar (merp, la, derp); endmodule"}, | |
| {"module m; foo bar (.he(ooo)); endmodule"}, | |
| {"module m; foo #(.roo(ra)) bar; endmodule"}, | |
| {"module m; foo #(.roo(ra), .bing(bong)) bar; endmodule"}, | |
| {"module m; foo #(.roo, .bing) bar; endmodule"}, | |
| {"module m; foo #(.roo(ra), \n.bing(bong)) bar; endmodule"}, | |
| {"module m; foo #(.roo, \n.bing) bar; endmodule"}, | |
| {"module m; foo #(.roo) bar; endmodule"}, | |
| {"class c; uvm_analysis_imp_ingress_pe #(seqitem_t, scoreboard_t) " | |
| "ingress_pe_port; endclass"}, | |
| }; | |
| RunLintTestCases<VerilogAnalyzer, ModuleParameterRule>(kTestCases); | |
| } | |
| TEST(ModuleInstantiationTests, Ports) { | |
| const std::initializer_list<LintTestCase> kTestCases = { | |
| {""}, | |
| {"module m; endmodule"}, | |
| {"module m; foo bar (", {TK_DecNumber, "1"}, ", 2, 3); endmodule"}, | |
| {"module m; foo bar (", {TK_DecNumber, "1"}, ", \n 2, \n 3); endmodule"}, | |
| {"module m; foo bar (", | |
| {PP_ifndef, "`ifndef"}, // TODO(fangism): not sure this is best location | |
| " FOOR\n" | |
| " 1\n" | |
| "`else\n" | |
| " 2\n" | |
| "`endif\n" | |
| "); endmodule"}, | |
| {"module m; foo bar (\n", | |
| {'.', "."}, // TODO(fangism): location could be better | |
| "foo(bar),\n" | |
| "`ifndef FOOR\n" | |
| " 1\n" | |
| "`else\n" | |
| " 2\n" | |
| "`endif\n" | |
| "); endmodule"}, | |
| {"module m; foo bar (", | |
| {TK_DecNumber, "3"}, | |
| ", 1); endmodule\n" | |
| "function f; beep boop (", | |
| {TK_DecNumber, "1"}, | |
| ", 2); endfunction"}, | |
| {"module m; foo bar (\n" | |
| "`ifndef FOOR\n" | |
| " .roo(ra)\n" | |
| "`else\n" | |
| " .merp(le)\n" | |
| "`endif\n" | |
| "); endmodule"}, | |
| {"module m; foo bar (", {MacroIdentifier, "`ROO"}, ", `RAA ); endmodule"}, | |
| {"module m; blah bar(", {SymbolIdentifier, "foo"}, ", fizz); endmodule"}, | |
| {"module m; and bar(foo, fizz); endmodule"}, // primitive gate | |
| {"module m; foo bar(1); endmodule"}, | |
| {"module m; foo bar(1,); endmodule"}, | |
| {"module m; foo bar; endmodule"}, | |
| {"module m; foo #(merp, la, derp) bar; endmodule"}, | |
| {"module m; foo bar (.he(ooo)); endmodule"}, | |
| {"module m; foo #(.roo(ra)) bar; endmodule"}, | |
| {"module m; foo bar (.roo(ra), .bing(bong)); endmodule"}, | |
| {"module m; foo bar (.roo, .bing); endmodule"}, | |
| {"module m; foo #(.roo(ra)) \n bar; endmodule"}, | |
| {"module m; foo bar (.roo(ra), \n.bing(bong)); endmodule"}, | |
| {"module m; foo bar (.roo,\n.bing); endmodule"}, | |
| {"module m; foo bar (.roo); endmodule"}, | |
| }; | |
| RunLintTestCases<VerilogAnalyzer, ModulePortRule>(kTestCases); | |
| } | |
| } // namespace | |
| } // namespace analysis | |
| } // namespace verilog |