blob: 89e4527e72a4b0807783db289427ae8a97fb1647 [file] [log] [blame]
// 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