| // 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. | |
| // Test cases in this file should be *insensitive* to wrapping penalties. | |
| // Penalty-sensitive tests belong in formatter_tuning_test.cc. | |
| // Methods for keeping tests penalty insensitive: | |
| // * Short lines and partitions. Lines that fit need no wrapping. | |
| // * Forced line breaks using //comments (reduce decision-making) | |
| #include "verilog/formatting/formatter.h" | |
| #include <memory> | |
| #include <sstream> | |
| #include <string> | |
| #include <vector> | |
| #include "gmock/gmock.h" | |
| #include "gtest/gtest.h" | |
| #include "absl/status/status.h" | |
| #include "absl/strings/match.h" | |
| #include "absl/strings/string_view.h" | |
| #include "common/formatting/align.h" | |
| #include "common/strings/position.h" | |
| #include "common/text/text_structure.h" | |
| #include "common/util/logging.h" | |
| #include "verilog/analysis/verilog_analyzer.h" | |
| #include "verilog/formatting/format_style.h" | |
| #undef EXPECT_OK | |
| #define EXPECT_OK(value) EXPECT_TRUE((value).ok()) | |
| #undef ASSERT_OK | |
| #define ASSERT_OK(value) ASSERT_TRUE((value).ok()) | |
| namespace verilog { | |
| namespace formatter { | |
| // private, extern function in formatter.cc, directly tested here. | |
| absl::Status VerifyFormatting(const verible::TextStructureView& text_structure, | |
| absl::string_view formatted_output, | |
| absl::string_view filename); | |
| namespace { | |
| using absl::StatusCode; | |
| using verible::AlignmentPolicy; | |
| using verible::IndentationStyle; | |
| using verible::LineNumberSet; | |
| // Tests that clean output passes. | |
| TEST(VerifyFormattingTest, NoError) { | |
| const absl::string_view code("class c;endclass\n"); | |
| const std::unique_ptr<VerilogAnalyzer> analyzer = | |
| VerilogAnalyzer::AnalyzeAutomaticMode(code, "<filename>"); | |
| const auto& text_structure = ABSL_DIE_IF_NULL(analyzer)->Data(); | |
| const auto status = VerifyFormatting(text_structure, code, "<filename>"); | |
| EXPECT_OK(status); | |
| } | |
| // Tests that un-lexable outputs are caught as errors. | |
| TEST(VerifyFormattingTest, LexError) { | |
| const absl::string_view code("class c;endclass\n"); | |
| const std::unique_ptr<VerilogAnalyzer> analyzer = | |
| VerilogAnalyzer::AnalyzeAutomaticMode(code, "<filename>"); | |
| const auto& text_structure = ABSL_DIE_IF_NULL(analyzer)->Data(); | |
| const absl::string_view bad_code("1class c;endclass\n"); // lexical error | |
| const auto status = VerifyFormatting(text_structure, bad_code, "<filename>"); | |
| EXPECT_FALSE(status.ok()); | |
| EXPECT_EQ(status.code(), StatusCode::kDataLoss); | |
| } | |
| // Tests that un-parseable outputs are caught as errors. | |
| TEST(VerifyFormattingTest, ParseError) { | |
| const absl::string_view code("class c;endclass\n"); | |
| const std::unique_ptr<VerilogAnalyzer> analyzer = | |
| VerilogAnalyzer::AnalyzeAutomaticMode(code, "<filename>"); | |
| const auto& text_structure = ABSL_DIE_IF_NULL(analyzer)->Data(); | |
| const absl::string_view bad_code("classc;endclass\n"); // syntax error | |
| const auto status = VerifyFormatting(text_structure, bad_code, "<filename>"); | |
| EXPECT_FALSE(status.ok()); | |
| EXPECT_EQ(status.code(), StatusCode::kDataLoss); | |
| } | |
| // Tests that lexical differences are caught as errors. | |
| TEST(VerifyFormattingTest, LexicalDifference) { | |
| const absl::string_view code("class c;endclass\n"); | |
| const std::unique_ptr<VerilogAnalyzer> analyzer = | |
| VerilogAnalyzer::AnalyzeAutomaticMode(code, "<filename>"); | |
| const auto& text_structure = ABSL_DIE_IF_NULL(analyzer)->Data(); | |
| const absl::string_view bad_code("class c;;endclass\n"); // different tokens | |
| const auto status = VerifyFormatting(text_structure, bad_code, "<filename>"); | |
| EXPECT_FALSE(status.ok()); | |
| EXPECT_EQ(status.code(), StatusCode::kDataLoss); | |
| } | |
| struct FormatterTestCase { | |
| absl::string_view input; | |
| absl::string_view expected; | |
| }; | |
| static const LineNumberSet kEnableAllLines; | |
| // Test that the expected output is produced with the formatter using a custom | |
| // FormatStyle. | |
| TEST(FormatterTest, FormatCustomStyleTest) { | |
| static constexpr FormatterTestCase kTestCases[] = { | |
| {"", ""}, | |
| {"module m;wire w;endmodule\n", | |
| "module m;\n" | |
| " wire w;\n" | |
| "endmodule\n"}, | |
| }; | |
| FormatStyle style; | |
| style.column_limit = 40; | |
| style.indentation_spaces = 10; // unconventional indentation | |
| style.wrap_spaces = 4; | |
| for (const auto& test_case : kTestCases) { | |
| VLOG(1) << "code-to-format:\n" << test_case.input << "<EOF>"; | |
| std::ostringstream stream; | |
| const auto status = | |
| FormatVerilog(test_case.input, "<filename>", style, stream); | |
| EXPECT_OK(status); | |
| EXPECT_EQ(stream.str(), test_case.expected) << "code:\n" << test_case.input; | |
| } | |
| } | |
| static constexpr FormatterTestCase kFormatterTestCases[] = { | |
| {"", ""}, | |
| {"\n", "\n"}, | |
| {"\n\n", "\n\n"}, | |
| {"\t//comment\n", "//comment\n"}, | |
| {"\t/*comment*/\n", "/*comment*/\n"}, | |
| {"\t/*multi-line\ncomment*/\n", "/*multi-line\ncomment*/\n"}, | |
| // preprocessor test cases | |
| {"`include \"path/to/file.vh\"\n", "`include \"path/to/file.vh\"\n"}, | |
| {"`include `\"path/to/file.vh`\"\n", "`include `\"path/to/file.vh`\"\n"}, | |
| {"`define FOO\n", "`define FOO\n"}, | |
| {"`define FOO BAR\n", "`define FOO BAR\n"}, | |
| {"`define FOO\n" | |
| "`define BAR\n", | |
| "`define FOO\n" | |
| "`define BAR\n"}, | |
| {"`ifndef FOO\n" | |
| "`endif // FOO\n", | |
| "`ifndef FOO\n" | |
| "`endif // FOO\n"}, | |
| {"`ifndef FOO\n" | |
| "`define BAR\n" | |
| "`endif\n", | |
| "`ifndef FOO\n" | |
| "`define BAR\n" | |
| "`endif\n"}, | |
| {"`ifndef FOO\n" | |
| "`define BAR\n\n" // one more blank line | |
| "`endif\n", | |
| "`ifndef FOO\n" | |
| "`define BAR\n\n" | |
| "`endif\n"}, | |
| {"`define FOO \\\n" | |
| " BAR\n", | |
| "`define FOO \\\n" // TODO(b/72527558): right align '\'s to column limit | |
| " BAR\n"}, | |
| {"`define FOOOOOOOOOOOOOOOO \\\n" | |
| " BAAAAAAAAAAAAAAAAR BAAAAAAAAAAAAAZ;\n", | |
| "`define FOOOOOOOOOOOOOOOO \\\n" // macro text starts at '\' | |
| " BAAAAAAAAAAAAAAAAR BAAAAAAAAAAAAAZ;\n"}, | |
| {"`ifdef FOO\n" | |
| " `fine()\n" | |
| "`else\n" | |
| " `error()\n" | |
| "`endif\n", | |
| "`ifdef FOO\n" | |
| "`fine()\n" | |
| "`else\n" | |
| "`error()\n" | |
| "`endif\n"}, | |
| {"`ifdef FOO\n" | |
| " `fine()\n" | |
| "`else // trouble\n" | |
| " `error()\n" | |
| "`endif\n", | |
| "`ifdef FOO\n" | |
| "`fine()\n" | |
| "`else // trouble\n" | |
| "`error()\n" | |
| "`endif\n"}, | |
| {"`ifdef FOO\n" | |
| " `fine()\n" | |
| "`else /* trouble */\n" | |
| " `error()\n" | |
| "`endif\n", | |
| "`ifdef FOO\n" | |
| "`fine()\n" | |
| "`else /* trouble */\n" | |
| "`error()\n" | |
| "`endif\n"}, | |
| {" // lonely comment\n", "// lonely comment\n"}, | |
| {" // first comment\n" | |
| " // last comment\n", | |
| "// first comment\n" | |
| "// last comment\n"}, | |
| {" // starting comment\n" | |
| " `define FOO\n", | |
| "// starting comment\n" | |
| "`define FOO\n"}, | |
| {" `define FOO\n" | |
| " // trailing comment\n", | |
| "`define FOO\n" | |
| "// trailing comment\n"}, | |
| {" `define FOO\n" | |
| " // trailing comment 1\n" | |
| " // trailing comment 2\n", | |
| "`define FOO\n" | |
| "// trailing comment 1\n" | |
| "// trailing comment 2\n"}, | |
| { | |
| " `define FOO \\\n" // multiline macro definition | |
| " 1\n", | |
| "`define FOO \\\n" | |
| " 1\n" // TODO(b/141517267): Reflowing macro definitions | |
| }, | |
| {"`define FOO \\\n" // multiline macro definition | |
| " b\n", | |
| "`define FOO \\\n" // no need to align '\' | |
| " b\n"}, | |
| {"`define FOO \\\n" // multiline macro definition | |
| " a + \\\n" | |
| " b\n", | |
| "`define FOO \\\n" // preserve spacing before '\' | |
| " a + \\\n" // to stay aligned with this one | |
| " b\n"}, | |
| {" // comment with backslash\\\n", "// comment with backslash\\\n"}, | |
| {// macro with MacroArg tokens as arguments | |
| "`FOOOOOO(\nbar1...\n,\nbar2...\n,\nbar3...\n,\nbar4\n)\n", | |
| "`FOOOOOO(bar1..., bar2..., bar3...,\n" | |
| " bar4)\n"}, | |
| {// macro declaration exceeds line length limit | |
| "`F_MACRO(looooooong_type if_it_fits_I_sits)\n", | |
| "`F_MACRO(\n" | |
| " looooooong_type if_it_fits_I_sits)\n"}, | |
| {// macro call with not fitting arguments | |
| "`MACRO_FFFFFFFFFFF(" | |
| "type_a_aaaa,type_b_bbbbb," | |
| "type_c_cccccc,type_d_dddddddd," | |
| "type_e_eeeeeeee,type_f_ffff)\n", | |
| "`MACRO_FFFFFFFFFFF(\n" | |
| " type_a_aaaa, type_b_bbbbb,\n" | |
| " type_c_cccccc, type_d_dddddddd,\n" | |
| " type_e_eeeeeeee, type_f_ffff)\n"}, | |
| {// nested macro call | |
| "`MACRO_FFFFFFFFFFF( " | |
| "`A(type_a_aaaa), `B(type_b_bbbbb), " | |
| "`C(type_c_cccccc), `D(type_d_dddddddd), " | |
| "`E(type_e_eeeeeeee), `F(type_f_ffff))\n", | |
| "`MACRO_FFFFFFFFFFF(`A(type_a_aaaa),\n" | |
| " `B(type_b_bbbbb),\n" | |
| " `C(type_c_cccccc),\n" | |
| " `D(type_d_dddddddd),\n" | |
| " `E(type_e_eeeeeeee),\n" | |
| " `F(type_f_ffff))\n"}, | |
| {// two-level nested macro call | |
| "`MACRO_FFFFFFFFFFF( " | |
| "`A(type_a_aaaa, `B(type_b_bbbbb)), " | |
| "`C(type_c_cccccc, `D(type_d_dddddddd)), " | |
| "`E(type_e_eeeeeeee, `F(type_f_ffff)))\n", | |
| "`MACRO_FFFFFFFFFFF(\n" | |
| " `A(type_a_aaaa, `B(type_b_bbbbb)),\n" | |
| " `C(type_c_cccccc,\n" | |
| " `D(type_d_dddddddd)),\n" | |
| " `E(type_e_eeeeeeee,\n" | |
| " `F(type_f_ffff)))\n"}, | |
| {// three-level nested macro call | |
| "`MACRO_FFFFFFFFFFF(`A(type_a_aaaa," | |
| "`B(type_b_bbbbb,`C(type_c_cccccc)))," | |
| "`D(type_d_dddddddd,`E(type_e_eeeeeeee," | |
| "`F(type_f_ffff))))\n", | |
| "`MACRO_FFFFFFFFFFF(\n" | |
| " `A(type_a_aaaa,\n" | |
| " `B(type_b_bbbbb,\n" | |
| " `C(type_c_cccccc))),\n" | |
| " `D(type_d_dddddddd,\n" | |
| " `E(type_e_eeeeeeee,\n" | |
| " `F(type_f_ffff))))\n"}, | |
| {// macro call with MacroArg tokens as arugments and with semicolon | |
| "`FOOOOOO(\nbar1...\n,\nbar2...\n,\nbar3...\n,\nbar4\n);\n", | |
| "`FOOOOOO(bar1..., bar2..., bar3...,\n" | |
| " bar4);\n"}, | |
| {// macro declaration exceeds line length limit and contains semicolon | |
| "`F_MACRO(looooooong_type if_it_fits_I_sits);\n", | |
| "`F_MACRO(\n" | |
| " looooooong_type if_it_fits_I_sits);\n"}, | |
| {// macro call with not fitting arguments and semicolon | |
| "`MACRO_FFFFFFFFFFF(" | |
| "type_a_aaaa,type_b_bbbbb," | |
| "type_c_cccccc,type_d_dddddddd," | |
| "type_e_eeeeeeee,type_f_ffff);\n", | |
| "`MACRO_FFFFFFFFFFF(\n" | |
| " type_a_aaaa, type_b_bbbbb,\n" | |
| " type_c_cccccc, type_d_dddddddd,\n" | |
| " type_e_eeeeeeee, type_f_ffff);\n"}, | |
| {// nested macro call with semicolon | |
| "`MACRO_FFFFFFFFFFF( " | |
| "`A(type_a_aaaa), `B(type_b_bbbbb), " | |
| "`C(type_c_cccccc), `D(type_d_dddddddd), " | |
| "`E(type_e_eeeeeeee), `F(type_f_ffff));\n", | |
| "`MACRO_FFFFFFFFFFF(`A(type_a_aaaa),\n" | |
| " `B(type_b_bbbbb),\n" | |
| " `C(type_c_cccccc),\n" | |
| " `D(type_d_dddddddd),\n" | |
| " `E(type_e_eeeeeeee),\n" | |
| " `F(type_f_ffff));\n"}, | |
| {// two-level nested macro call with semicolon | |
| "`MACRO_FFFFFFFFFFF( " | |
| "`A(type_a_aaaa, `B(type_b_bbbbb)), " | |
| "`C(type_c_cccccc, `D(type_d_dddddddd)), " | |
| "`E(type_e_eeeeeeee, `F(type_f_ffff)));\n", | |
| "`MACRO_FFFFFFFFFFF(\n" | |
| " `A(type_a_aaaa, `B(type_b_bbbbb)),\n" | |
| " `C(type_c_cccccc,\n" | |
| " `D(type_d_dddddddd)),\n" | |
| " `E(type_e_eeeeeeee,\n" | |
| " `F(type_f_ffff)));\n"}, | |
| {// three-level nested macro call with semicolon | |
| "`MACRO_FFFFFFFFFFF(`A(type_a_aaaa," | |
| "`B(type_b_bbbbb,`C(type_c_cccccc)))," | |
| "`D(type_d_dddddddd,`E(type_e_eeeeeeee," | |
| "`F(type_f_ffff))));\n", | |
| "`MACRO_FFFFFFFFFFF(\n" | |
| " `A(type_a_aaaa,\n" | |
| " `B(type_b_bbbbb,\n" | |
| " `C(type_c_cccccc))),\n" | |
| " `D(type_d_dddddddd,\n" | |
| " `E(type_e_eeeeeeee,\n" | |
| " `F(type_f_ffff))));\n"}, | |
| {// macro call with no args | |
| "`FOOOOOO()\n", "`FOOOOOO()\n"}, | |
| {// macro call with no args and semicolon | |
| "`FOOOOOO();\n", "`FOOOOOO();\n"}, | |
| {// macro call with no args and semicolon separated by space | |
| "`FOOOOOO() ;\n", "`FOOOOOO();\n"}, | |
| {// macro call with comments in argument list | |
| "`FOO(aa, //aa\nbb , // bb\ncc)\n", | |
| "`FOO(aa, //aa\n" | |
| " bb, // bb\n" | |
| " cc)\n"}, | |
| {// macro call with comment before first argument | |
| "`FOO(//aa\naa, //bb\nbb , // cc\ncc)\n", | |
| "`FOO( //aa\n" | |
| " aa, //bb\n" | |
| " bb, // cc\n" | |
| " cc)\n"}, | |
| {// macro call with argument including trailing EOL comment | |
| "`FOO(aa, bb,//cc\ndd)\n", | |
| "`FOO(aa, bb, //cc\n" | |
| " dd)\n"}, | |
| {// macro call with argument including EOL comment on own line | |
| "`FOOOO(aa, bb,\n//cc\ndd)\n", | |
| "`FOOOO(aa, bb, //cc\n" | |
| // TODO(b/152324712): //cc comment should start its own line | |
| " dd)\n"}, | |
| {" // leading comment\n" | |
| " `define FOO \\\n" // multiline macro definition | |
| "1\n" | |
| " // trailing comment\n", | |
| "// leading comment\n" | |
| "`define FOO \\\n" | |
| "1\n" // TODO(b/141517267): Reflowing macro definitions | |
| "// trailing comment\n"}, | |
| {// macro call after define | |
| "`define FOO BAR\n" | |
| " `FOO( bar )\n", | |
| "`define FOO BAR\n" | |
| "`FOO(bar)\n"}, | |
| {// multiple argument macro call | |
| " `FOO( bar , baz )\n", "`FOO(bar, baz)\n"}, | |
| {// macro call in function | |
| "function void foo( ); foo=`FOO( bar , baz ) ; endfunction\n", | |
| "function void foo();\n" | |
| " foo = `FOO(bar, baz);\n" | |
| "endfunction\n"}, | |
| {// nested macro call in function | |
| "function void foo( ); foo=`FOO( `BAR ( baz ) ) ; endfunction\n", | |
| "function void foo();\n" | |
| " foo = `FOO(`BAR(baz));\n" | |
| "endfunction\n"}, | |
| {// macro call in class | |
| "class foo; `FOO ( bar , baz ) ; endclass\n", | |
| "class foo;\n" | |
| " `FOO(bar, baz);\n" | |
| "endclass\n"}, | |
| {// nested macro call in class | |
| "class foo; `FOO ( `BAR ( baz1 , baz2 ) ) ; endclass\n", | |
| "class foo;\n" | |
| " `FOO(`BAR(baz1, baz2));\n" | |
| "endclass\n"}, | |
| {// multi-line macro arg "aaaa..." should start on its own line, | |
| // even if its first line would fit under the column limit | |
| "`CHECK_FATAL(rd_tr,\n" | |
| " aaaa == zzz;\n" | |
| " ggg == vv::w;,\n" | |
| " \"Failed to ..........\")\n", | |
| "`CHECK_FATAL(rd_tr,\n" | |
| " aaaa == zzz;\n" | |
| " ggg == vv::w;,\n" | |
| " \"Failed to ..........\")\n"}, | |
| // `uvm macros indenting | |
| { | |
| // simple test case | |
| "`uvm_object_utils_begin(aa)\n" | |
| "`uvm_field_int(bb, UVM_DEFAULT)\n" | |
| "`uvm_field_int(cc, UVM_DEFAULT)\n" | |
| "`uvm_object_utils_end\n", | |
| "`uvm_object_utils_begin(aa)\n" | |
| " `uvm_field_int(bb, UVM_DEFAULT)\n" | |
| " `uvm_field_int(cc, UVM_DEFAULT)\n" | |
| "`uvm_object_utils_end\n", | |
| }, | |
| {// multiple uvm.*begin - uvm.*end ranges | |
| "`uvm_object_utils_begin(aa)\n" | |
| "`uvm_field_int(bb, UVM_DEFAULT)\n" | |
| "`uvm_field_int(cc, UVM_DEFAULT)\n" | |
| "`uvm_object_utils_end\n" | |
| "`uvm_field_int(bb, UVM_DEFAULT)\n" | |
| "`uvm_field_int(cc, UVM_DEFAULT)\n" | |
| "`uvm_object_utils_begin(bb)\n" | |
| "`uvm_field_int(bb, UVM_DEFAULT)\n" | |
| "`uvm_field_int(cc, UVM_DEFAULT)\n" | |
| "`uvm_object_utils_end\n" | |
| "`uvm_field_int(bb, UVM_DEFAULT)\n" | |
| "`uvm_field_int(cc, UVM_DEFAULT)\n", | |
| "`uvm_object_utils_begin(aa)\n" | |
| " `uvm_field_int(bb, UVM_DEFAULT)\n" | |
| " `uvm_field_int(cc, UVM_DEFAULT)\n" | |
| "`uvm_object_utils_end\n" | |
| "`uvm_field_int(bb, UVM_DEFAULT)\n" | |
| "`uvm_field_int(cc, UVM_DEFAULT)\n" | |
| "`uvm_object_utils_begin(bb)\n" | |
| " `uvm_field_int(bb, UVM_DEFAULT)\n" | |
| " `uvm_field_int(cc, UVM_DEFAULT)\n" | |
| "`uvm_object_utils_end\n" | |
| "`uvm_field_int(bb, UVM_DEFAULT)\n" | |
| "`uvm_field_int(cc, UVM_DEFAULT)\n"}, | |
| { | |
| // empty uvm.*begin - uvm.*end range | |
| "`uvm_component_utils_begin(aa)\n" | |
| "`uvm_component_utils_end\n", | |
| "`uvm_component_utils_begin(aa)\n" | |
| "`uvm_component_utils_end\n", | |
| }, | |
| { | |
| // uvm_field_utils | |
| "`uvm_field_utils_begin(aa)\n" | |
| "`uvm_field_int(bb, UVM_DEFAULT)\n" | |
| "`uvm_field_int(cc, UVM_DEFAULT)\n" | |
| "`uvm_field_utils_end\n", | |
| "`uvm_field_utils_begin(aa)\n" | |
| " `uvm_field_int(bb, UVM_DEFAULT)\n" | |
| " `uvm_field_int(cc, UVM_DEFAULT)\n" | |
| "`uvm_field_utils_end\n", | |
| }, | |
| { | |
| // uvm_component | |
| "`uvm_component_utils_begin(aa)\n" | |
| "`uvm_field_int(bb, UVM_DEFAULT)\n" | |
| "`uvm_field_int(cc, UVM_DEFAULT)\n" | |
| "`uvm_component_utils_end\n", | |
| "`uvm_component_utils_begin(aa)\n" | |
| " `uvm_field_int(bb, UVM_DEFAULT)\n" | |
| " `uvm_field_int(cc, UVM_DEFAULT)\n" | |
| "`uvm_component_utils_end\n", | |
| }, | |
| { | |
| // nested uvm macros | |
| "`uvm_field_int(l0, UVM_DEFAULT)\n" | |
| "`uvm_component_utils_begin(l0)\n" | |
| "`uvm_field_int(l1, UVM_DEFAULT)\n" | |
| "`uvm_component_utils_begin(l1)\n" | |
| "`uvm_field_int(l2, UVM_DEFAULT)\n" | |
| "`uvm_component_utils_begin(l2)\n" | |
| "`uvm_field_int(l3, UVM_DEFAULT)\n" | |
| "`uvm_component_utils_end\n" | |
| "`uvm_field_int(l2, UVM_DEFAULT)\n" | |
| "`uvm_component_utils_end\n" | |
| "`uvm_field_int(l1, UVM_DEFAULT)\n" | |
| "`uvm_component_utils_end\n" | |
| "`uvm_field_int(l0, UVM_DEFAULT)\n", | |
| "`uvm_field_int(l0, UVM_DEFAULT)\n" | |
| "`uvm_component_utils_begin(l0)\n" | |
| " `uvm_field_int(l1, UVM_DEFAULT)\n" | |
| " `uvm_component_utils_begin(l1)\n" | |
| " `uvm_field_int(l2, UVM_DEFAULT)\n" | |
| " `uvm_component_utils_begin(l2)\n" | |
| " `uvm_field_int(l3, UVM_DEFAULT)\n" | |
| " `uvm_component_utils_end\n" | |
| " `uvm_field_int(l2, UVM_DEFAULT)\n" | |
| " `uvm_component_utils_end\n" | |
| " `uvm_field_int(l1, UVM_DEFAULT)\n" | |
| "`uvm_component_utils_end\n" | |
| "`uvm_field_int(l0, UVM_DEFAULT)\n", | |
| }, | |
| { | |
| // non-uvm macro | |
| "`my_macro_begin(aa)\n" | |
| "`my_field(b)\n" | |
| "`my_field(c)\n" | |
| "`my_macro_end\n", | |
| "`my_macro_begin(aa)\n" | |
| "`my_field(b)\n" | |
| "`my_field(c)\n" | |
| "`my_macro_end\n", | |
| }, | |
| { | |
| // unbalanced uvm macros: missing uvm.*end macro | |
| "`uvm_component_utils_begin(aa)\n" | |
| "`uvm_field_int(bb, UVM_DEFAULT)\n" | |
| "`uvm_field_int(cc, UVM_DEFAULT)\n", | |
| "`uvm_component_utils_begin(aa)\n" | |
| "`uvm_field_int(bb, UVM_DEFAULT)\n" | |
| "`uvm_field_int(cc, UVM_DEFAULT)\n", | |
| }, | |
| { | |
| // unbalanced uvm macros: missing uvm.*begin macro | |
| "`uvm_field_int(bb, UVM_DEFAULT)\n" | |
| "`uvm_field_int(cc, UVM_DEFAULT)\n" | |
| "`uvm_component_utils_end\n", | |
| "`uvm_field_int(bb, UVM_DEFAULT)\n" | |
| "`uvm_field_int(cc, UVM_DEFAULT)\n" | |
| "`uvm_component_utils_end\n", | |
| }, | |
| {// unbalanced uvm macros: missing _begin macro between | |
| // matching uvm.*begin-uvm.*end macros | |
| "`uvm_component_utils_begin(aa)\n" | |
| "`uvm_field_int(bb, UVM_DEFAULT)\n" | |
| "`uvm_field_int(cc, UVM_DEFAULT)\n" | |
| "`uvm_component_utils_end\n" | |
| "`uvm_field_int(bb, UVM_DEFAULT)\n" | |
| "`uvm_field_int(bb, UVM_DEFAULT)\n" | |
| "`uvm_field_int(cc, UVM_DEFAULT)\n" | |
| "`uvm_component_utils_end\n" | |
| "`uvm_field_int(bb, UVM_DEFAULT)\n" | |
| "`uvm_component_utils_begin(aa)\n" | |
| "`uvm_field_int(bb, UVM_DEFAULT)\n" | |
| "`uvm_field_int(cc, UVM_DEFAULT)\n" | |
| "`uvm_component_utils_end\n", | |
| "`uvm_component_utils_begin(aa)\n" | |
| " `uvm_field_int(bb, UVM_DEFAULT)\n" | |
| " `uvm_field_int(cc, UVM_DEFAULT)\n" | |
| "`uvm_component_utils_end\n" | |
| "`uvm_field_int(bb, UVM_DEFAULT)\n" | |
| "`uvm_field_int(bb, UVM_DEFAULT)\n" | |
| "`uvm_field_int(cc, UVM_DEFAULT)\n" | |
| "`uvm_component_utils_end\n" | |
| "`uvm_field_int(bb, UVM_DEFAULT)\n" | |
| "`uvm_component_utils_begin(aa)\n" | |
| " `uvm_field_int(bb, UVM_DEFAULT)\n" | |
| " `uvm_field_int(cc, UVM_DEFAULT)\n" | |
| "`uvm_component_utils_end\n"}, | |
| // top-level directive test cases | |
| {"`timescale 1ns/1ps\n", // | |
| "`timescale 1ns / 1ps\n"}, | |
| // parameter test cases | |
| { | |
| " parameter int foo=0 ;", | |
| "parameter int foo = 0;\n", | |
| }, | |
| { | |
| " parameter int foo=bar [ 0 ] ;", // index expression | |
| "parameter int foo = bar[0];\n", | |
| }, | |
| { | |
| " parameter int foo=bar [ a+b ] ;", // binary inside index expr | |
| "parameter int foo = bar[a+b];\n", // allowed to be 0 spaces | |
| // (preserved) | |
| }, | |
| { | |
| " parameter int foo=bar [ a+ b ] ;", // binary inside index expr | |
| "parameter int foo = bar[a+b];\n", // allowed to be 0 spaces | |
| // (symmetrized) | |
| }, | |
| { | |
| " parameter int foo=bar [ a +b ] ;", // binary inside index expr | |
| "parameter int foo = bar[a + b];\n", // allowed to be 1 space | |
| // (symmetrized) | |
| }, | |
| { | |
| " parameter int foo=bar [ a +b ] ;", // binary inside index expr | |
| "parameter int foo = bar[a + b];\n", // limited to 1 space (and | |
| // symmetrized) | |
| }, | |
| { | |
| // with line continuations | |
| " parameter \\\nint \\\nfoo=a+ \\\nb ;", | |
| "parameter\\\n int\\\n foo = a +\\\n b;\n", | |
| // TODO(fangism): should text following a line continuation hang-indent? | |
| }, | |
| // unary prefix expressions | |
| { | |
| " parameter int foo=- 1 ;", | |
| "parameter int foo = -1;\n", | |
| }, | |
| { | |
| " parameter int foo=+ 7 ;", | |
| "parameter int foo = +7;\n", | |
| }, | |
| { | |
| " parameter int foo=- J ;", | |
| "parameter int foo = -J;\n", | |
| }, | |
| { | |
| " parameter int foo=- ( y ) ;", | |
| "parameter int foo = -(y);\n", | |
| }, | |
| { | |
| " parameter int foo=- ( z*y ) ;", | |
| "parameter int foo = -(z * y);\n", | |
| }, | |
| { | |
| " parameter int foo=- z*- y ;", | |
| "parameter int foo = -z * -y;\n", | |
| }, | |
| { | |
| " parameter int foo=( - 2 ) ;", // | |
| "parameter int foo = (-2);\n", | |
| }, | |
| { | |
| " parameter int foo=$bar(- z,- y ) ;", | |
| "parameter int foo = $bar(-z, -y);\n", | |
| }, | |
| {" parameter int a=b&~(c<<d);", "parameter int a = b & ~(c << d);\n"}, | |
| {" parameter int a=~~~~b;", "parameter int a = ~~~~b;\n"}, | |
| {" parameter int a = ~ ~ ~ ~ b;", "parameter int a = ~~~~b;\n"}, | |
| {" parameter int a = ~--b;", "parameter int a = ~--b;\n"}, | |
| {" parameter int a = ~ --b;", "parameter int a = ~--b;\n"}, | |
| {" parameter int a = ~ ++ b;", "parameter int a = ~++b;\n"}, | |
| {" parameter int a=--b- --c;", "parameter int a = --b - --c;\n"}, | |
| // ^~ and ~^ are bitwise nor, but ^ ~ isn't | |
| {" parameter int a=b^~(c<<d);", "parameter int a = b ^~ (c << d);\n"}, | |
| {" parameter int a=b~^(c<<d);", "parameter int a = b ~^ (c << d);\n"}, | |
| {" parameter int a=b^ ~ (c<<d);", "parameter int a = b ^ ~(c << d);\n"}, | |
| {" parameter int a=b ^ ~(c<<d);", "parameter int a = b ^ ~(c << d);\n"}, | |
| {" parameter int a=b^~{c};", "parameter int a = b ^~ {c};\n"}, | |
| {" parameter int a=b~^{c};", "parameter int a = b ~^ {c};\n"}, | |
| {" parameter int a=b^ ~ {c};", "parameter int a = b ^ ~{c};\n"}, | |
| {" parameter int a=b ^ ~{c};", "parameter int a = b ^ ~{c};\n"}, | |
| {" parameter int a={a}^{b};", "parameter int a = {a} ^ {b};\n"}, | |
| {" parameter int a={b}^(c);", "parameter int a = {b} ^ (c);\n"}, | |
| {" parameter int a=b[0]^ {c};", "parameter int a = b[0] ^ {c};\n"}, | |
| {" parameter int a={c}^a[b];", "parameter int a = {c} ^ a[b];\n"}, | |
| {" parameter int a=(c)^{a[b]};", "parameter int a = (c) ^ {a[b]};\n"}, | |
| {" parameter int a={^{a,^b},c};", "parameter int a = {^{a, ^b}, c};\n"}, | |
| {" parameter int a=(a)^(^d[e]^{c});", | |
| "parameter int a = (a) ^ (^d[e] ^ {c});\n"}, | |
| {" parameter int a=(a)^(^d[e]^f[g]);", | |
| "parameter int a = (a) ^ (^d[e] ^ f[g]);\n"}, | |
| {" parameter int a=(b^(c^(d^e)));", | |
| "parameter int a = (b ^ (c ^ (d ^ e)));\n"}, | |
| {" parameter int a={b^{c^{d^e}}};", | |
| "parameter int a = {b ^ {c ^ {d ^ e}}};\n"}, | |
| {" parameter int a={b^{c[d^e]}};", | |
| "parameter int a = {b ^ {c[d^e]}};\n"}, // allow 0 spaces inside "[d^e]" | |
| {" parameter int a={(b^c),(d^^e)};", | |
| "parameter int a = {(b ^ c), (d ^ ^e)};\n"}, | |
| {" parameter int a={(b[x]^{c[y]})};", | |
| "parameter int a = {(b[x] ^ {c[y]})};\n"}, | |
| {" parameter int a={d^^e[f] ^ (g)};", | |
| "parameter int a = {d ^ ^e[f] ^ (g)};\n"}, | |
| // ~| is unary reduction NOR, |~ and | ~ aren't | |
| {" parameter int a=b| ~(c<<d);", "parameter int a = b | ~(c << d);\n"}, | |
| {" parameter int a=b|~(c<<d);", "parameter int a = b | ~(c << d);\n"}, | |
| {" parameter int a=b| ~| ( c<<d);", "parameter int a = b | ~|(c << d);\n"}, | |
| {" parameter int a=b| ~| ~| ( c<<d);", | |
| "parameter int a = b | ~|~|(c << d);\n"}, | |
| {" parameter int a=b| ~~~( c<<d);", | |
| "parameter int a = b | ~~~(c << d);\n"}, | |
| { | |
| " parameter int foo=- - 1 ;", // double negative | |
| "parameter int foo = - -1;\n", | |
| }, | |
| { | |
| " parameter int ternary=1?2:3;", | |
| "parameter int ternary = 1 ? 2 : 3;\n", | |
| }, | |
| { | |
| " parameter int ternary=a?b:c;", | |
| "parameter int ternary = a ? b : c;\n", | |
| }, | |
| { | |
| " parameter int ternary=\"a\"?\"b\":\"c\";", | |
| "parameter int ternary = \"a\" ? \"b\" : \"c\";\n", | |
| }, | |
| { | |
| " parameter int t=`\"a`\"?`\"b`\":`\"c`\";", | |
| "parameter int t = `\"a`\" ? `\"b`\" : `\"c`\";\n", | |
| }, | |
| { | |
| " parameter int ternary=(a)?(b):(c);", | |
| "parameter int ternary = (a) ? (b) : (c);\n", | |
| }, | |
| { | |
| " parameter int ternary={a}?{b}:{c};", | |
| "parameter int ternary = {a} ? {b} : {c};\n", | |
| }, | |
| // streaming operators | |
| { | |
| " parameter int b={ >> { a } } ;", | |
| "parameter int b = {>>{a}};\n", | |
| }, | |
| { | |
| " parameter int b={ >> { a , b, c } } ;", | |
| "parameter int b = {>>{a, b, c}};\n", | |
| }, | |
| { | |
| " parameter int b={ >> 4 { a } } ;", | |
| "parameter int b = {>>4{a}};\n", | |
| }, | |
| { | |
| " parameter int b={ >> byte { a } } ;", | |
| "parameter int b = {>>byte{a}};\n", | |
| }, | |
| { | |
| " parameter int b={ >> my_type_t { a } } ;", | |
| "parameter int b = {>>my_type_t{a}};\n", | |
| }, | |
| { | |
| " parameter int b={ >> `GET_TYPE { a } } ;", | |
| "parameter int b = {>>`GET_TYPE{a}};\n", | |
| }, | |
| { | |
| " parameter int b={ >> 4 {{ >> 2 { a } }} } ;", | |
| "parameter int b = {>>4{{>>2{a}}}};\n", | |
| }, | |
| { | |
| " parameter int b={ << { a } } ;", | |
| "parameter int b = {<<{a}};\n", | |
| }, | |
| { | |
| " parameter int b={ << { a , b, c } } ;", | |
| "parameter int b = {<<{a, b, c}};\n", | |
| }, | |
| { | |
| " parameter int b={ << 4 { a } } ;", | |
| "parameter int b = {<<4{a}};\n", | |
| }, | |
| { | |
| " parameter int b={ << byte { a } } ;", | |
| "parameter int b = {<<byte{a}};\n", | |
| }, | |
| { | |
| " parameter int b={ << my_type_t { a } } ;", | |
| "parameter int b = {<<my_type_t{a}};\n", | |
| }, | |
| { | |
| " parameter int b={ << `GET_TYPE { a } } ;", | |
| "parameter int b = {<<`GET_TYPE{a}};\n", | |
| }, | |
| { | |
| " parameter int b={ << 4 {{ << 2 { a } }} } ;", | |
| "parameter int b = {<<4{{<<2{a}}}};\n", | |
| }, | |
| // basic module test cases | |
| {"module foo;endmodule:foo\n", | |
| "module foo;\n" | |
| "endmodule : foo\n"}, | |
| {"module\nfoo\n;\nendmodule\n:\nfoo\n", | |
| "module foo;\n" | |
| "endmodule : foo\n"}, | |
| {"module\tfoo\t;\tendmodule\t:\tfoo", | |
| "module foo;\n" | |
| "endmodule : foo\n"}, | |
| {"module foo; // foo\n" | |
| "endmodule:foo\n", | |
| "module foo; // foo\n" | |
| "endmodule : foo\n"}, | |
| {"module foo;/* foo */endmodule:foo\n", | |
| "module foo; /* foo */\n" | |
| "endmodule : foo\n"}, | |
| {"module pm #(\n" | |
| "//comment\n" | |
| ") (wire ww);\n" | |
| "endmodule\n", | |
| "module pm #(\n" | |
| " //comment\n" // comment indented | |
| ") (\n" | |
| " wire ww\n" | |
| ");\n" | |
| "endmodule\n"}, | |
| {"module pm ( ) ;\n" // empty ports list | |
| "endmodule\n", | |
| "module pm ();\n" | |
| "endmodule\n"}, | |
| {"module pm #(\n" | |
| "//comment\n" | |
| ") ( );\n" | |
| "endmodule\n", | |
| "module pm #(\n" | |
| " //comment\n" // comment indented | |
| ") ();\n" // (); grouped together | |
| "endmodule\n"}, | |
| {"`ifdef FOO\n" | |
| " `ifndef BAR\n" | |
| " `endif\n" | |
| "`endif\n", | |
| "`ifdef FOO\n" | |
| "`ifndef BAR\n" | |
| "`endif\n" | |
| "`endif\n"}, | |
| {"module foo(\n" | |
| " `include \"ports.svh\"\n" | |
| " ) ; endmodule\n", | |
| "module foo (\n" | |
| " `include \"ports.svh\"\n" | |
| ");\n" | |
| "endmodule\n"}, | |
| {"module foo(\n" | |
| " `define FOO\n" | |
| "`undef\tFOO\n" | |
| " ) ; endmodule\n", | |
| "module foo (\n" | |
| " `define FOO\n" | |
| " `undef FOO\n" | |
| ");\n" | |
| "endmodule\n"}, | |
| {"module foo( input x , output y ) ;endmodule:foo\n", | |
| "module foo (\n" | |
| " input x,\n" // aligned | |
| " output y\n" | |
| ");\n" | |
| "endmodule : foo\n"}, | |
| {"module foo( input[2:0]x , output y [3:0] ) ;endmodule:foo\n", | |
| // each port item should be on its own line | |
| "module foo (\n" | |
| " input [2:0] x,\n" // aligned | |
| " output y[3:0]\n" | |
| ");\n" | |
| "endmodule : foo\n"}, | |
| {"module foo( input wire x , output reg yy ) ;endmodule:foo\n", | |
| "module foo (\n" | |
| " input wire x,\n" // aligned | |
| " output reg yy\n" | |
| ");\n" | |
| "endmodule : foo\n"}, | |
| {"module foo( input wire x ,//c1\n" | |
| "output reg yyy //c2\n" | |
| " ) ;endmodule:foo\n", | |
| "module foo (\n" | |
| " input wire x, //c1\n" // aligned | |
| " output reg yyy //c2\n" // trailing comments not aligned | |
| ");\n" | |
| "endmodule : foo\n"}, | |
| {"module foo( input wire x , output yy ) ;endmodule:foo\n", | |
| "module foo (\n" | |
| " input wire x,\n" // aligned | |
| " output yy\n" | |
| ");\n" | |
| "endmodule : foo\n"}, | |
| {"module foo( input x , output reg yy ) ;endmodule:foo\n", | |
| "module foo (\n" | |
| " input x,\n" // aligned | |
| " output reg yy\n" | |
| ");\n" | |
| "endmodule : foo\n"}, | |
| {"module foo( input x , output reg[a:b]yy ) ;endmodule:foo\n", | |
| "module foo (\n" | |
| " input x,\n" // aligned | |
| " output reg [a:b] yy\n" | |
| ");\n" | |
| "endmodule : foo\n"}, | |
| {"module foo( input [a:b]x , output reg yy ) ;endmodule:foo\n", | |
| "module foo (\n" | |
| " input [a:b] x,\n" // aligned | |
| " output reg yy\n" | |
| ");\n" | |
| "endmodule : foo\n"}, | |
| {"module foo( input x , " | |
| " output logic yy ) ;endmodule:foo\n", | |
| "module foo (\n" | |
| " input x,\n" // aligned | |
| " output logic yy\n" | |
| ");\n" | |
| "endmodule : foo\n"}, | |
| {"module foo( input [a:c]x , " | |
| " output logic[a-b: c] yy ) ;endmodule:foo\n", | |
| "module foo (\n" | |
| " input [ a:c] x,\n" // aligned | |
| " output logic [a-b:c] yy\n" | |
| ");\n" | |
| "endmodule : foo\n"}, | |
| {"module foo( input [a:c]x , " | |
| " output logic[a - b: c] yy ) ;endmodule:foo\n", | |
| "module foo (\n" | |
| " input [ a:c] x,\n" // aligned | |
| " output logic [a - b:c] yy\n" | |
| ");\n" | |
| "endmodule : foo\n"}, | |
| {"module foo( input [a:c]x , input zzz ," | |
| " output logic[a - b: c] yy ) ;endmodule:foo\n", | |
| "module foo (\n" | |
| " input [ a:c] x,\n" // aligned []'s | |
| " input zzz,\n" // aligned ids | |
| " output logic [a - b:c] yy\n" | |
| ");\n" | |
| "endmodule : foo\n"}, | |
| {"module foo( input [a:b]x , " | |
| " output reg[e: f] yy ) ;endmodule:foo\n", | |
| "module foo (\n" | |
| " input [a:b] x,\n" // aligned | |
| " output reg [e:f] yy\n" | |
| ");\n" | |
| "endmodule : foo\n"}, | |
| {"module foo( input tri[aa: bb]x , " | |
| " output reg[e: f] yy ) ;endmodule:foo\n", | |
| "module foo (\n" | |
| " input tri [aa:bb] x,\n" // aligned | |
| " output reg [ e:f] yy\n" // TODO(b/70310743): align ':' | |
| ");\n" | |
| "endmodule : foo\n"}, | |
| {"module foo( input [a:b][c:d]x , " | |
| " output reg[e: f] yy ) ;endmodule:foo\n", | |
| "module foo (\n" | |
| " input [a:b][c:d] x,\n" // aligned | |
| " output reg [e:f] yy\n" | |
| ");\n" | |
| "endmodule : foo\n"}, | |
| {"module foo( input wire x [j:k], output reg yy ) ;endmodule:foo\n", | |
| "module foo (\n" | |
| " input wire x [j:k],\n" // aligned | |
| " output reg yy\n" | |
| ");\n" | |
| "endmodule : foo\n"}, | |
| {"module foo( input wire x , output reg yy [j:k]) ;endmodule:foo\n", | |
| "module foo (\n" | |
| " input wire x,\n" // aligned | |
| " output reg yy[j:k]\n" | |
| ");\n" | |
| "endmodule : foo\n"}, | |
| {"module foo( input wire x [p:q], output reg yy [j:k]) ;endmodule:foo\n", | |
| "module foo (\n" | |
| " input wire x [p:q],\n" // aligned | |
| " output reg yy[j:k]\n" | |
| ");\n" | |
| "endmodule : foo\n"}, | |
| {"module foo( input wire x [p:q][r:s], output reg yy [j:k]) " | |
| ";endmodule:foo\n", | |
| "module foo (\n" | |
| " input wire x [p:q][r:s],\n" // aligned | |
| " output reg yy[j:k]\n" | |
| ");\n" | |
| "endmodule : foo\n"}, | |
| {"module foo( input wire x [p:q][rr:ss], output reg yy [jj:kk][m:n]) " | |
| ";endmodule:foo\n", | |
| "module foo (\n" | |
| // TODO(b/70310743): align :'s | |
| " input wire x [ p:q][rr:ss],\n" | |
| " output reg yy[jj:kk][ m:n]\n" // aligned | |
| ");\n" | |
| "endmodule : foo\n"}, | |
| {"module foo( input wire [p:q]x, output reg yy [j:k]) ;endmodule:foo\n", | |
| "module foo (\n" | |
| " input wire [p:q] x,\n" // aligned | |
| " output reg yy[j:k]\n" | |
| ");\n" | |
| "endmodule : foo\n"}, | |
| {"module foo( input wire x [p:q], output reg[j:k]yy) ;endmodule:foo\n", | |
| "module foo (\n" | |
| " input wire x [p:q],\n" // aligned | |
| " output reg [j:k] yy\n" | |
| ");\n" | |
| "endmodule : foo\n"}, | |
| {"module foo( input pkg::bar_t x , output reg yy) ;endmodule:foo\n", | |
| "module foo (\n" | |
| " input pkg::bar_t x,\n" // aligned | |
| " output reg yy\n" | |
| ");\n" | |
| "endmodule : foo\n"}, | |
| {"module foo( input wire x , output pkg::bar_t yy) ;endmodule:foo\n", | |
| "module foo (\n" | |
| " input wire x,\n" // aligned | |
| " output pkg::bar_t yy\n" | |
| ");\n" | |
| "endmodule : foo\n"}, | |
| {"module foo( input pkg::bar_t#(1) x , output reg yy) ;endmodule:foo\n", | |
| "module foo (\n" // with parameterized port type | |
| " input pkg::bar_t#(1) x,\n" | |
| " output reg yy\n" // aligned | |
| ");\n" | |
| "endmodule : foo\n"}, | |
| {"module foo( input signed x , output reg yy) ;endmodule:foo\n", | |
| "module foo (\n" | |
| " input signed x,\n" // aligned | |
| " output reg yy\n" | |
| ");\n" | |
| "endmodule : foo\n"}, | |
| {"module foo( input signed x , output reg [m:n] yy) ;endmodule:foo\n", | |
| "module foo (\n" | |
| " input signed x,\n" // aligned | |
| " output reg [m:n] yy\n" | |
| ");\n" | |
| "endmodule : foo\n"}, | |
| {"module foo( input int signed x , output reg [m:n] yy) ;endmodule:foo\n", | |
| "module foo (\n" | |
| " input int signed x,\n" // aligned | |
| " output reg [m:n] yy\n" | |
| ");\n" | |
| "endmodule : foo\n"}, | |
| {"module foo( input signed x , output pkg::bar_t yy) ;endmodule:foo\n", | |
| "module foo (\n" | |
| " input signed x,\n" // aligned | |
| " output pkg::bar_t yy\n" | |
| ");\n" | |
| "endmodule : foo\n"}, | |
| {"module somefunction (" | |
| "logic clk, int a, int b);endmodule", | |
| "module somefunction (\n" | |
| " logic clk,\n" // direction missing | |
| " int a,\n" // direction missing | |
| " int b\n" // direction missing | |
| ");\n" | |
| "endmodule\n"}, | |
| {"module somefunction (" | |
| "logic clk, input int a, int b);endmodule", | |
| "module somefunction (\n" | |
| " logic clk,\n" // direction missing | |
| " input int a,\n" | |
| " int b\n" // direction missing | |
| ");\n" | |
| "endmodule\n"}, | |
| {"module somefunction (" | |
| "input logic clk, input int a, int b);endmodule", | |
| "module somefunction (\n" | |
| " input logic clk,\n" | |
| " input int a,\n" | |
| " int b\n" // direction missing | |
| ");\n" | |
| "endmodule\n"}, | |
| {"module somefunction (" | |
| "input clk, input int a, int b);endmodule", | |
| "module somefunction (\n" | |
| " input clk,\n" // type missing | |
| " input int a,\n" | |
| " int b\n" | |
| ");\n" | |
| "endmodule\n"}, | |
| {"module somefunction (" | |
| "input logic clk, input a, int b);endmodule", | |
| "module somefunction (\n" | |
| " input logic clk,\n" | |
| " input a,\n" // type missing | |
| " int b\n" // direction missing | |
| ");\n" | |
| "endmodule\n"}, | |
| {"module m;foo bar(.baz({larry, moe, curly}));endmodule", | |
| "module m;\n" | |
| " foo bar (.baz({larry, moe, curly}));\n" | |
| "endmodule\n"}, | |
| {"module m;foo bar(.baz({larry,// expand this\n" | |
| "moe, curly}));endmodule", | |
| "module m;\n" | |
| " foo bar (\n" | |
| " .baz({\n" | |
| " larry, // expand this\n" | |
| " moe,\n" | |
| " curly\n" | |
| " })\n" | |
| " );\n" | |
| "endmodule\n"}, | |
| {"parameter priv_reg_t impl_csr[] = {\n" | |
| "// Machine mode mode CSR\n" | |
| "MVENDORID, //\n" | |
| "MARCHID, //\n" | |
| "DSCRATCH0, //\n" | |
| "DSCRATCH1 //\n" | |
| "};", | |
| "parameter priv_reg_t impl_csr[] = {\n" | |
| " // Machine mode mode CSR\n" | |
| " MVENDORID, //\n" | |
| " MARCHID, //\n" | |
| " DSCRATCH0, //\n" | |
| " DSCRATCH1 //\n" | |
| "};\n"}, | |
| {"parameter priv_reg_t impl_csr[] = {\n" | |
| "// Expand elements\n" | |
| "MVENDORID,\n" | |
| "MARCHID,\n" | |
| "DSCRATCH0,\n" | |
| "DSCRATCH1\n" | |
| "};", | |
| "parameter priv_reg_t impl_csr[] = {\n" | |
| " // Expand elements\n" | |
| " MVENDORID,\n" | |
| " MARCHID,\n" | |
| " DSCRATCH0,\n" | |
| " DSCRATCH1\n" | |
| "};\n"}, | |
| /* TODO(b/158131099): to fix these, reinterpret 'b' as a kPortDeclaration | |
| {"module somefunction (" | |
| "input logic clk, input a, b);endmodule", | |
| "module somefunction (\n" | |
| " input logic clk,\n" | |
| " input a,\n" // type missing | |
| " b\n" // type and direction missing | |
| ");\n" | |
| "endmodule\n"}, | |
| {"module somefunction (" | |
| "input logic clk, int a, b);endmodule", | |
| "module somefunction (\n" | |
| " input logic clk,\n" | |
| " int a,\n" // direction missing | |
| " b\n" // type and direction missing | |
| ");\n" | |
| "endmodule\n"}, | |
| */ | |
| {"module foo(\n" | |
| "//c1\n" | |
| "input wire x , \n" | |
| "//c2\n" | |
| "output reg yy\n" | |
| "//c3\n" | |
| ") ;endmodule:foo\n", | |
| "module foo (\n" | |
| " //c1\n" | |
| " input wire x,\n" // aligned, ignoring comments | |
| " //c2\n" | |
| " output reg yy\n" | |
| " //c3\n" | |
| ");\n" | |
| "endmodule : foo\n"}, | |
| {"module foo(\n" | |
| "//c1\n" | |
| "input wire x , \n" | |
| "//c2a\n" // longer comment | |
| "//c2b\n" | |
| "output reg yy\n" | |
| "//c3\n" | |
| ") ;endmodule:foo\n", | |
| "module foo (\n" | |
| " //c1\n" | |
| " input wire x,\n" // aligned, ignoring comments | |
| " //c2a\n" // note: separated by 2 lines of comments | |
| " //c2b\n" | |
| " output reg yy\n" | |
| " //c3\n" | |
| ");\n" | |
| "endmodule : foo\n"}, | |
| {"module foo(\n" | |
| "`ifdef FOO\n" | |
| "input wire x , \n" | |
| " `else\n" | |
| "output reg yy\n" | |
| " `endif\n" | |
| ") ;endmodule:foo\n", | |
| "module foo (\n" | |
| "`ifdef FOO\n" | |
| " input wire x,\n" // aligned, ignoring preprocessor conditionals | |
| "`else\n" | |
| " output reg yy\n" | |
| "`endif\n" | |
| ");\n" | |
| "endmodule : foo\n"}, | |
| {"module foo(\n" | |
| "input w , \n" | |
| "`define FOO BAR\n" | |
| "input wire x , \n" | |
| " `include \"stuff.svh\"\n" | |
| "output reg yy\n" | |
| " `undef FOO\n" | |
| "output zz\n" | |
| ") ;endmodule:foo\n", | |
| "module foo (\n" | |
| " input w,\n" // aligned, ignoring preprocessor directives | |
| " `define FOO BAR\n" | |
| " input wire x,\n" | |
| " `include \"stuff.svh\"\n" | |
| " output reg yy\n" | |
| " `undef FOO\n" | |
| " output zz\n" // aligned, ignoring preprocessor directives | |
| ");\n" | |
| "endmodule : foo\n"}, | |
| {"module foo(\n" | |
| "input wire x , \n \n" // blank line, separating alignment groups | |
| "output reg yy\n" | |
| ") ;endmodule:foo\n", | |
| "module foo (\n" | |
| " input wire x,\n" // not aligned, due to blank line separating groups | |
| "\n" | |
| " output reg yy\n" | |
| ");\n" | |
| "endmodule : foo\n"}, | |
| {"module foo(\n" | |
| "input wire x1 [r:s],\n" | |
| "input [p:q] x2 , \n \n" // blank line, separating alignment groups | |
| "output reg [jj:kk]yy1,\n" | |
| "output pkg::barr_t [mm:nn] yy2\n" | |
| ") ;endmodule:foo\n", | |
| "module foo (\n" | |
| " input wire x1[r:s],\n" // aligned in this group, but not across | |
| // groups | |
| " input [p:q] x2,\n" | |
| "\n" | |
| " output reg [jj:kk] yy1,\n" | |
| " output pkg::barr_t [mm:nn] yy2\n" | |
| ");\n" | |
| "endmodule : foo\n"}, | |
| {"module foo(\n" // same as previous, with comments | |
| " //c1\n" | |
| "input wire x1 [r:s],\n" | |
| "input [p:q] x2 , \n" | |
| " //c2\n\n" // blank line, separating alignment groups | |
| " //c3\n" | |
| "output reg [jj:kk]yy1,\n" | |
| " //c4\n" | |
| "output pkg::barr_t [mm:nn] yy2\n" | |
| ") ;endmodule:foo\n", | |
| "module foo (\n" | |
| " //c1\n" | |
| " input wire x1[r:s],\n" // aligned in this group, but not across | |
| // groups | |
| " input [p:q] x2,\n" | |
| " //c2\n" | |
| "\n" | |
| " //c3\n" | |
| " output reg [jj:kk] yy1,\n" | |
| " //c4\n" | |
| " output pkg::barr_t [mm:nn] yy2\n" | |
| ");\n" | |
| "endmodule : foo\n"}, | |
| {// aligning here just barely fits in the 40col limit | |
| "module foo( input int signed x [a:b]," | |
| "output reg [mm:nn] yy) ;endmodule:foo\n", | |
| "module foo (\n" | |
| // ---------------40col-----------------> | |
| " input int signed x [a:b],\n" // aligned, still fits | |
| " output reg [mm:nn] yy\n" | |
| ");\n" | |
| "endmodule : foo\n"}, | |
| {// when aligning would result in exceeding column limit, don't align for | |
| // now | |
| "module foo( input int signed x [aa:bb]," | |
| "output reg [mm:nn] yy) ;endmodule:foo\n", | |
| "module foo (\n" | |
| // ---------------40col-----------------> | |
| // input int signed x [aa:bb],\n" | |
| // output reg [mm:nn] yy\n" | |
| " input int signed x [aa:bb],\n" // aligned, still fits | |
| " output reg [mm:nn] yy\n" | |
| ");\n" | |
| "endmodule : foo\n"}, | |
| {// when aligning would result in exceeding column limit, don't align for | |
| // now | |
| "module foo( input int signed x [aa:bb]," | |
| "output reg [mm:nn] yyy) ;endmodule:foo\n", | |
| "module foo (\n" | |
| // ---------------40col-----------------> | |
| // input int signed x [aa:bb],\n" // over limit, by comma | |
| // output reg [mm:nn] yyy\n" | |
| " input int signed x[aa:bb],\n" // aligned would be 41 columns | |
| " output reg [mm:nn] yyy\n" | |
| ");\n" | |
| "endmodule : foo\n"}, | |
| {// when aligning would result in exceeding column limit, don't align for | |
| // now | |
| "module foo( input int signed x [a:b],//c\n" | |
| "output reg [m:n] yy) ;endmodule:foo\n", | |
| "module foo (\n" | |
| // ---------------40col----------------> | |
| // input int signed x [a:b], //c\n" // over limit, by comment | |
| // output reg [m:n] yy\n" | |
| " input int signed x[a:b], //c\n" // aligned would be 42 columns | |
| " output reg [m:n] yy\n" | |
| ");\n" | |
| "endmodule : foo\n"}, | |
| {// aligning interfaces in port headers like types | |
| // TODO(b/161181877): flush interface port type left (multi-column) | |
| "module foo( input clk , inter.face yy) ;endmodule:foo\n", | |
| "module foo (\n" | |
| " input clk,\n" // aligned | |
| " inter.face yy\n" | |
| ");\n" | |
| "endmodule : foo\n"}, | |
| {// aligning interfaces in port headers like types | |
| // TODO(b/161181877): flush interface port type left (multi-column) | |
| "module foo( input wire clk , inter.face yy) ;endmodule:foo\n", | |
| "module foo (\n" | |
| " input wire clk,\n" // aligned | |
| " inter.face yy\n" | |
| ");\n" | |
| "endmodule : foo\n"}, | |
| // module local variable/net declaration alignment test cases | |
| {"module m;\n" | |
| "logic a;\n" | |
| "bit b;\n" | |
| "endmodule\n", | |
| "module m;\n" | |
| " logic a;\n" | |
| " bit b;\n" | |
| "endmodule\n"}, | |
| {"module m;\n" | |
| "logic a;\n" | |
| "bit b;\n" | |
| "initial e=f;\n" // separates alignment groups | |
| "wire c;\n" | |
| "bit d;\n" | |
| "endmodule\n", | |
| "module m;\n" | |
| " logic a;\n" | |
| " bit b;\n" | |
| " initial e = f;\n" // separates alignment groups | |
| " wire c;\n" | |
| " bit d;\n" | |
| "endmodule\n"}, | |
| {"module m;\n" | |
| "// hello a\n" | |
| "logic a;\n" | |
| "// hello b\n" | |
| "bit b;\n" | |
| "endmodule\n", | |
| "module m;\n" | |
| " // hello a\n" | |
| " logic a;\n" | |
| " // hello b\n" | |
| " bit b;\n" // aligned across comments | |
| "endmodule\n"}, | |
| {"module m;\n" | |
| "// hello a\n" | |
| "logic a;\n" | |
| "\n" // extra blank line | |
| "// hello b\n" | |
| "bit b;\n" | |
| "endmodule\n", | |
| "module m;\n" | |
| " // hello a\n" | |
| " logic a;\n" | |
| "\n" // extra blank line | |
| " // hello b\n" // aligned across blank lines | |
| " bit b;\n" // aligned across comments | |
| "endmodule\n"}, | |
| {"module m;\n" | |
| "logic [x:y]a;\n" // packed dimensions | |
| "bit b;\n" | |
| "endmodule\n", | |
| "module m;\n" | |
| " logic [x:y] a;\n" | |
| " bit b;\n" | |
| "endmodule\n"}, | |
| {"module m;\n" | |
| "logic a;\n" | |
| "bit [pp:qq]b;\n" // packed dimensions | |
| "endmodule\n", | |
| "module m;\n" | |
| " logic a;\n" | |
| " bit [pp:qq] b;\n" | |
| "endmodule\n"}, | |
| {"module m;\n" | |
| "logic [x:y]a;\n" // packed dimensions | |
| "bit [pp:qq]b;\n" // packed dimensions | |
| "endmodule\n", | |
| "module m;\n" | |
| " logic [ x:y] a;\n" | |
| " bit [pp:qq] b;\n" | |
| "endmodule\n"}, | |
| {"module m;\n" | |
| "logic [x:y]a;\n" // packed dimensions | |
| "wire [pp:qq] [e:f]b;\n" // packed dimensions, 2D | |
| "endmodule\n", | |
| "module m;\n" | |
| " logic [ x:y] a;\n" | |
| " wire [pp:qq][e:f] b;\n" | |
| "endmodule\n"}, | |
| {"module m;\n" | |
| "logic a [x:y];\n" // unpacked dimensions | |
| "bit bbb;\n" | |
| "endmodule\n", | |
| "module m;\n" | |
| " logic a [x:y];\n" | |
| " bit bbb;\n" | |
| "endmodule\n"}, | |
| {"module m;\n" | |
| "logic aaa ;\n" | |
| "wire w [yy:zz];\n" // unpacked dimensions | |
| "endmodule\n", | |
| "module m;\n" | |
| " logic aaa;\n" | |
| " wire w [yy:zz];\n" | |
| "endmodule\n"}, | |
| {"module m;\n" | |
| "logic aaa [s:t] ;\n" // unpacked dimensions | |
| "wire w [yy:zz];\n" // unpacked dimensions | |
| "endmodule\n", | |
| "module m;\n" | |
| " logic aaa[ s:t];\n" | |
| " wire w [yy:zz];\n" | |
| "endmodule\n"}, | |
| {"module m;\n" | |
| "logic aaa [s:t] ;\n" // unpacked dimensions | |
| "wire w [yy:zz][u:v];\n" // unpacked dimensions, 2D | |
| "endmodule\n", | |
| "module m;\n" | |
| " logic aaa[ s:t];\n" | |
| " wire w [yy:zz] [u:v];\n" | |
| // TODO(b/165323560): unwanted space between unpacked dimensions of 'w' | |
| "endmodule\n"}, | |
| {"module m;\n" | |
| "qqq::rrr s;\n" // user-defined type | |
| "wire [pp:qq]w;\n" // packed dimensions | |
| "endmodule\n", | |
| "module m;\n" | |
| " qqq::rrr s;\n" | |
| " wire [pp:qq] w;\n" | |
| "endmodule\n"}, | |
| {"module m;\n" | |
| "qqq#(rr) s;\n" // parameterized type | |
| "wire [pp:qq]w;\n" // packed dimensions | |
| "endmodule\n", | |
| "module m;\n" | |
| " qqq #(rr) s;\n" | |
| " wire [pp:qq] w;\n" | |
| "endmodule\n"}, | |
| {"module m;\n" | |
| "logic a;\n" | |
| "bit b;\n" | |
| "my_module my_inst( );\n" // module instance separates alignment groups | |
| "wire c;\n" | |
| "bit d;\n" | |
| "endmodule\n", | |
| "module m;\n" | |
| " logic a;\n" // these two are aligned | |
| " bit b;\n" | |
| " my_module my_inst ();\n" // module instance separates alignment groups | |
| " wire c;\n" // these two are aligned | |
| " bit d;\n" | |
| "endmodule\n"}, | |
| {"module m;\n" | |
| "logic aaa = expr1;\n" | |
| "bit b = expr2;\n" | |
| "endmodule\n", | |
| "module m;\n" | |
| " logic aaa = expr1;\n" | |
| " bit b = expr2;\n" // no alignment at '=' yet | |
| "endmodule\n"}, | |
| {"module foo #(int x,int y) ;endmodule:foo\n", // parameters | |
| "module foo #(\n" | |
| " int x,\n" | |
| " int y\n" | |
| ");\n" // each parameter on its own line | |
| "endmodule : foo\n"}, | |
| {"module foo #(int x)(input y) ;endmodule:foo\n", | |
| // parameter and port | |
| "module foo #(\n" | |
| " int x\n" | |
| ") (\n" | |
| " input y\n" | |
| ");\n" // each paramater and port item should be on its own line | |
| "endmodule : foo\n"}, | |
| {"module foo #(parameter int x,parameter int y) ;endmodule:foo\n", | |
| // parameters don't fit (also should be on its own line) | |
| "module foo #(\n" | |
| " parameter int x,\n" | |
| " parameter int y\n" | |
| ");\n" | |
| "endmodule : foo\n"}, | |
| {"module foo #(parameter int xxxx,parameter int yyyy) ;endmodule:foo\n", | |
| // parameters don't fit | |
| "module foo #(\n" | |
| " parameter int xxxx,\n" | |
| " parameter int yyyy\n" | |
| ");\n" | |
| "endmodule : foo\n"}, | |
| {"module foo #(//comment\n" | |
| "parameter bar =1,\n" | |
| "localparam baz =2" | |
| ") ();" | |
| "endmodule", | |
| "module foo #( //comment\n" | |
| " parameter bar = 1,\n" | |
| " localparam baz = 2\n" | |
| ") ();\n" | |
| "endmodule\n"}, | |
| {"module foo #(" | |
| "parameter bar =1,//comment\n" | |
| "localparam baz =2" | |
| ") ();" | |
| "endmodule", | |
| "module foo #(\n" | |
| " parameter bar = 1, //comment\n" | |
| " localparam baz = 2\n" | |
| ") ();\n" | |
| "endmodule\n"}, | |
| {"module foo #(" | |
| "parameter bar =1," | |
| "localparam baz =2//comment\n" | |
| ") ();" | |
| "endmodule", | |
| "module foo #(\n" | |
| " parameter bar = 1,\n" | |
| " localparam baz = 2 //comment\n" | |
| ") ();\n" | |
| "endmodule\n"}, | |
| {"module top;" | |
| "foo#( \"test\" ) foo( );" | |
| "bar#( \"test\" ,5) bar( );" | |
| "endmodule\n", | |
| "module top;\n" | |
| " foo #(\"test\") foo ();\n" // module instantiation, string arg | |
| " bar #(\"test\", 5) bar ();\n" | |
| "endmodule\n"}, | |
| {"module top;" | |
| "foo#( `\"test`\" ) foo( );" | |
| "bar#( `\"test`\" ,5) bar( );" | |
| "endmodule\n", | |
| "module top;\n" | |
| " foo #(`\"test`\") foo ();\n" // module instantiation, eval string arg | |
| " bar #(`\"test`\", 5) bar ();\n" | |
| "endmodule\n"}, | |
| {"`ifdef FOO\n" | |
| " module bar;endmodule\n" | |
| "`endif\n", | |
| "`ifdef FOO\n" | |
| "module bar;\n" | |
| "endmodule\n" | |
| "`endif\n"}, | |
| {"`ifdef FOO\n" | |
| " module bar;endmodule\n" | |
| "`else module baz;endmodule\n" | |
| "`endif\n", | |
| "`ifdef FOO\n" | |
| "module bar;\n" | |
| "endmodule\n" | |
| "`else\n" | |
| "module baz;\n" | |
| "endmodule\n" | |
| "`endif\n"}, | |
| {"`ifdef FOO\n" | |
| " module bar;endmodule\n" | |
| "`else /* glue me */ module baz;endmodule\n" | |
| "`endif\n", | |
| "`ifdef FOO\n" | |
| "module bar;\n" | |
| "endmodule\n" | |
| "`else /* glue me */\n" | |
| "module baz;\n" | |
| "endmodule\n" | |
| "`endif\n"}, | |
| {"`ifdef FOO\n" | |
| " module bar;endmodule\n" | |
| "`else// different unit\n" | |
| " module baz;endmodule\n" | |
| "`endif\n", | |
| "`ifdef FOO\n" | |
| "module bar;\n" | |
| "endmodule\n" | |
| "`else // different unit\n" | |
| "module baz;\n" | |
| "endmodule\n" | |
| "`endif\n"}, | |
| // unary: + - ! ~ & | ^ ~& ~| ~^ ^~ | |
| {"module m;foo bar(.x(-{a,b}));endmodule", | |
| "module m;\n" | |
| " foo bar (.x(-{a, b}));\n" | |
| "endmodule\n"}, | |
| {"module m;foo bar(.x(!{a,b}));endmodule", | |
| "module m;\n" | |
| " foo bar (.x(!{a, b}));\n" | |
| "endmodule\n"}, | |
| {"module m;foo bar(.x(~{a,b}));endmodule", | |
| "module m;\n" | |
| " foo bar (.x(~{a, b}));\n" | |
| "endmodule\n"}, | |
| {"module m;foo bar(.x(&{a,b}));endmodule", | |
| "module m;\n" | |
| " foo bar (.x(&{a, b}));\n" | |
| "endmodule\n"}, | |
| {"module m;foo bar(.x(|{a,b}));endmodule", | |
| "module m;\n" | |
| " foo bar (.x(|{a, b}));\n" | |
| "endmodule\n"}, | |
| {"module m;foo bar(.x(^{a,b}));endmodule", | |
| "module m;\n" | |
| " foo bar (.x(^{a, b}));\n" | |
| "endmodule\n"}, | |
| {"module m;foo bar(.x(~&{a,b}));endmodule", | |
| "module m;\n" | |
| " foo bar (.x(~&{a, b}));\n" | |
| "endmodule\n"}, | |
| {"module m;foo bar(.x(~|{a,b}));endmodule", | |
| "module m;\n" | |
| " foo bar (.x(~|{a, b}));\n" | |
| "endmodule\n"}, | |
| {"module m;foo bar(.x(~^{a,b}));endmodule", | |
| "module m;\n" | |
| " foo bar (.x(~^{a, b}));\n" | |
| "endmodule\n"}, | |
| {"module m;foo bar(.x(^~{a,b}));endmodule", | |
| "module m;\n" | |
| " foo bar (.x(^~{a, b}));\n" | |
| "endmodule\n"}, | |
| // binary: + - * / % & | ^ ^~ ~^ && || | |
| {"module m;foo bar(.x(a+b));endmodule", | |
| "module m;\n" | |
| " foo bar (.x(a + b));\n" | |
| "endmodule\n"}, | |
| {"module m;foo bar(.x(a-b));endmodule", | |
| "module m;\n" | |
| " foo bar (.x(a - b));\n" | |
| "endmodule\n"}, | |
| {"module m;foo bar(.x(a*b));endmodule", | |
| "module m;\n" | |
| " foo bar (.x(a * b));\n" | |
| "endmodule\n"}, | |
| {"module m;foo bar(.x(a/b));endmodule", | |
| "module m;\n" | |
| " foo bar (.x(a / b));\n" | |
| "endmodule\n"}, | |
| {"module m;foo bar(.x(a%b));endmodule", | |
| "module m;\n" | |
| " foo bar (.x(a % b));\n" | |
| "endmodule\n"}, | |
| {"module m;foo bar(.x(a&b));endmodule", | |
| "module m;\n" | |
| " foo bar (.x(a & b));\n" | |
| "endmodule\n"}, | |
| {"module m;foo bar(.x(a|b));endmodule", | |
| "module m;\n" | |
| " foo bar (.x(a | b));\n" | |
| "endmodule\n"}, | |
| {"module m;foo bar(.x(a^b));endmodule", | |
| "module m;\n" | |
| " foo bar (.x(a ^ b));\n" | |
| "endmodule\n"}, | |
| {"module m;foo bar(.x(a^~b));endmodule", | |
| "module m;\n" | |
| " foo bar (.x(a ^~ b));\n" | |
| "endmodule\n"}, | |
| {"module m;foo bar(.x(a~^b));endmodule", | |
| "module m;\n" | |
| " foo bar (.x(a ~^ b));\n" | |
| "endmodule\n"}, | |
| {"module m;foo bar(.x(a&&b));endmodule", | |
| "module m;\n" | |
| " foo bar (.x(a && b));\n" | |
| "endmodule\n"}, | |
| {"module m;foo bar(.x(a||b));endmodule", | |
| "module m;\n" | |
| " foo bar (.x(a || b));\n" | |
| "endmodule\n"}, | |
| // {a} op {b} | |
| {"module m;foo bar(.x({a}+{b}));endmodule", | |
| "module m;\n" | |
| " foo bar (.x({a} + {b}));\n" | |
| "endmodule\n"}, | |
| {"module m;foo bar(.x({a}-{b}));endmodule", | |
| "module m;\n" | |
| " foo bar (.x({a} - {b}));\n" | |
| "endmodule\n"}, | |
| {"module m;foo bar(.x({a}*{b}));endmodule", | |
| "module m;\n" | |
| " foo bar (.x({a} * {b}));\n" | |
| "endmodule\n"}, | |
| {"module m;foo bar(.x({a}/{b}));endmodule", | |
| "module m;\n" | |
| " foo bar (.x({a} / {b}));\n" | |
| "endmodule\n"}, | |
| {"module m;foo bar(.x({a}%{b}));endmodule", | |
| "module m;\n" | |
| " foo bar (.x({a} % {b}));\n" | |
| "endmodule\n"}, | |
| {"module m;foo bar(.x({a}&{b}));endmodule", | |
| "module m;\n" | |
| " foo bar (.x({a} & {b}));\n" | |
| "endmodule\n"}, | |
| {"module m;foo bar(.x({a}|{b}));endmodule", | |
| "module m;\n" | |
| " foo bar (.x({a} | {b}));\n" | |
| "endmodule\n"}, | |
| {"module m;foo bar(.x({a}^{b}));endmodule", | |
| "module m;\n" | |
| " foo bar (.x({a} ^ {b}));\n" | |
| "endmodule\n"}, | |
| {"module m;foo bar(.x({a}^~{b}));endmodule", | |
| "module m;\n" | |
| " foo bar (.x({a} ^~ {b}));\n" | |
| "endmodule\n"}, | |
| {"module m;foo bar(.x({a}~^{b}));endmodule", | |
| "module m;\n" | |
| " foo bar (.x({a} ~^ {b}));\n" | |
| "endmodule\n"}, | |
| {"module m;foo bar(.x({a}&&{b}));endmodule", | |
| "module m;\n" | |
| " foo bar (.x({a} && {b}));\n" | |
| "endmodule\n"}, | |
| {"module m;foo bar(.x({a}||{b}));endmodule", | |
| "module m;\n" | |
| " foo bar (.x({a} || {b}));\n" | |
| "endmodule\n"}, | |
| // (a) op (b) | |
| {"module m;foo bar(.x((a)+(b)));endmodule", | |
| "module m;\n" | |
| " foo bar (.x((a) + (b)));\n" | |
| "endmodule\n"}, | |
| {"module m;foo bar(.x((a)-(b)));endmodule", | |
| "module m;\n" | |
| " foo bar (.x((a) - (b)));\n" | |
| "endmodule\n"}, | |
| {"module m;foo bar(.x((a)*(b)));endmodule", | |
| "module m;\n" | |
| " foo bar (.x((a) * (b)));\n" | |
| "endmodule\n"}, | |
| {"module m;foo bar(.x((a)/(b)));endmodule", | |
| "module m;\n" | |
| " foo bar (.x((a) / (b)));\n" | |
| "endmodule\n"}, | |
| {"module m;foo bar(.x((a)%(b)));endmodule", | |
| "module m;\n" | |
| " foo bar (.x((a) % (b)));\n" | |
| "endmodule\n"}, | |
| {"module m;foo bar(.x((a)&(b)));endmodule", | |
| "module m;\n" | |
| " foo bar (.x((a) & (b)));\n" | |
| "endmodule\n"}, | |
| {"module m;foo bar(.x((a)|(b)));endmodule", | |
| "module m;\n" | |
| " foo bar (.x((a) | (b)));\n" | |
| "endmodule\n"}, | |
| {"module m;foo bar(.x((a)^(b)));endmodule", | |
| "module m;\n" | |
| " foo bar (.x((a) ^ (b)));\n" | |
| "endmodule\n"}, | |
| {"module m;foo bar(.x((a)^~(b)));endmodule", | |
| "module m;\n" | |
| " foo bar (.x((a) ^~ (b)));\n" | |
| "endmodule\n"}, | |
| {"module m;foo bar(.x((a)~^(b)));endmodule", | |
| "module m;\n" | |
| " foo bar (.x((a) ~^ (b)));\n" | |
| "endmodule\n"}, | |
| {"module m;foo bar(.x((a)&&(b)));endmodule", | |
| "module m;\n" | |
| " foo bar (.x((a) && (b)));\n" | |
| "endmodule\n"}, | |
| {"module m;foo bar(.x((a)||(b)));endmodule", | |
| "module m;\n" | |
| " foo bar (.x((a) || (b)));\n" | |
| "endmodule\n"}, | |
| // a[b] op c | |
| {"module m;foo bar(.x(a[b]+c));endmodule", | |
| "module m;\n" | |
| " foo bar (.x(a[b] + c));\n" | |
| "endmodule\n"}, | |
| {"module m;foo bar(.x(a[b]-c));endmodule", | |
| "module m;\n" | |
| " foo bar (.x(a[b] - c));\n" | |
| "endmodule\n"}, | |
| {"module m;foo bar(.x(a[b]*c));endmodule", | |
| "module m;\n" | |
| " foo bar (.x(a[b] * c));\n" | |
| "endmodule\n"}, | |
| {"module m;foo bar(.x(a[b]/c));endmodule", | |
| "module m;\n" | |
| " foo bar (.x(a[b] / c));\n" | |
| "endmodule\n"}, | |
| {"module m;foo bar(.x(a[b]%c));endmodule", | |
| "module m;\n" | |
| " foo bar (.x(a[b] % c));\n" | |
| "endmodule\n"}, | |
| {"module m;foo bar(.x(a[b]&c));endmodule", | |
| "module m;\n" | |
| " foo bar (.x(a[b] & c));\n" | |
| "endmodule\n"}, | |
| {"module m;foo bar(.x(a[b]|c));endmodule", | |
| "module m;\n" | |
| " foo bar (.x(a[b] | c));\n" | |
| "endmodule\n"}, | |
| {"module m;foo bar(.x(a[b]^c));endmodule", | |
| "module m;\n" | |
| " foo bar (.x(a[b] ^ c));\n" | |
| "endmodule\n"}, | |
| {"module m;foo bar(.x(a[b]^~c));endmodule", | |
| "module m;\n" | |
| " foo bar (.x(a[b] ^~ c));\n" | |
| "endmodule\n"}, | |
| {"module m;foo bar(.x(a[b]~^c));endmodule", | |
| "module m;\n" | |
| " foo bar (.x(a[b] ~^ c));\n" | |
| "endmodule\n"}, | |
| {"module m;foo bar(.x(a[b]&&c));endmodule", | |
| "module m;\n" | |
| " foo bar (.x(a[b] && c));\n" | |
| "endmodule\n"}, | |
| {"module m;foo bar(.x(a[b]||c));endmodule", | |
| "module m;\n" | |
| " foo bar (.x(a[b] || c));\n" | |
| "endmodule\n"}, | |
| // misc | |
| {"module m;foo bar(.x(a[1:0]^b[2:1]));endmodule", | |
| "module m;\n" | |
| " foo bar (.x(a[1:0] ^ b[2:1]));\n" | |
| "endmodule\n"}, | |
| {"module m;foo bar(.x(a[b] | b[c]));endmodule", | |
| "module m;\n" | |
| " foo bar (.x(a[b] | b[c]));\n" | |
| "endmodule\n"}, | |
| {"module m;foo bar(.x(a[b] & b[c]));endmodule", | |
| "module m;\n" | |
| " foo bar (.x(a[b] & b[c]));\n" | |
| "endmodule\n"}, | |
| {"module m;foo bar(.x((a^c)^(b^ ~c)));endmodule", | |
| "module m;\n" | |
| " foo bar (.x((a ^ c) ^ (b ^ ~c)));\n" | |
| "endmodule\n"}, | |
| {"module m;foo bar(.x((a^c)^(b^~c)));endmodule", | |
| "module m;\n" | |
| " foo bar (.x((a ^ c) ^ (b ^~ c)));\n" | |
| "endmodule\n"}, | |
| {"module m;foo bar(.x((a^{c,d})^(b^^{c,d})));endmodule", | |
| "module m;\n" | |
| " foo bar (\n" | |
| " .x((a ^ {c, d}) ^ (b ^ ^{c, d}))\n" | |
| " );\n" | |
| "endmodule\n"}, | |
| {// module items mixed with preprocessor conditionals and comments | |
| " module foo;\n" | |
| "// comment1\n" | |
| " `ifdef SIM\n" | |
| "// comment2\n" | |
| " `elsif SYN\n" | |
| " // comment3\n" | |
| " `else\n" | |
| "// comment4\n" | |
| " `endif\n" | |
| "// comment5\n" | |
| " endmodule", | |
| "module foo;\n" | |
| " // comment1\n" | |
| "`ifdef SIM\n" | |
| " // comment2\n" | |
| "`elsif SYN\n" | |
| " // comment3\n" | |
| "`else\n" | |
| " // comment4\n" | |
| "`endif\n" | |
| " // comment5\n" | |
| "endmodule\n"}, | |
| {" module bar;wire foo;reg bear;endmodule\n", | |
| "module bar;\n" | |
| " wire foo;\n" | |
| " reg bear;\n" // aligned | |
| "endmodule\n"}, | |
| {" module bar;initial\nbegin a<=b . c ; end endmodule\n", | |
| "module bar;\n" | |
| " initial begin\n" | |
| " a <= b.c;\n" | |
| " end\n" | |
| "endmodule\n"}, | |
| {" module bar;for(genvar i = 0 ; i<N ; ++ i ) begin end endmodule\n", | |
| "module bar;\n" | |
| " for (genvar i = 0; i < N; ++i) begin\n" | |
| " end\n" | |
| "endmodule\n"}, | |
| {" module bar;for(genvar i = 0 ; i!=N ; i ++ ) begin " | |
| "foo f;end endmodule\n", | |
| "module bar;\n" | |
| " for (genvar i = 0; i != N; i++) begin\n" | |
| " foo f;\n" | |
| " end\n" | |
| "endmodule\n"}, | |
| { | |
| "module block_generate;\n" | |
| "`ASSERT(blah)\n" | |
| "generate endgenerate endmodule\n", | |
| "module block_generate;\n" | |
| " `ASSERT(blah)\n" | |
| " generate\n" | |
| " endgenerate\n" | |
| "endmodule\n", | |
| }, | |
| { | |
| "module conditional_generate;\n" | |
| "if(foo) ; \t" // null action | |
| "endmodule\n", | |
| "module conditional_generate;\n" | |
| " if (foo);\n" | |
| "endmodule\n", | |
| }, | |
| { | |
| "module conditional_generate;\n" | |
| "if(foo[a*b+c]) ; \t" // null action | |
| "endmodule\n", | |
| "module conditional_generate;\n" | |
| " if (foo[a*b+c]);\n" // allow compact expressions inside [] | |
| "endmodule\n", | |
| }, | |
| { | |
| "module conditional_generate;\n" | |
| "if(foo)begin\n" | |
| "`ASSERT()\n" | |
| "`COVER()\n" | |
| " end\n" | |
| "endmodule\n", | |
| "module conditional_generate;\n" | |
| " if (foo) begin\n" | |
| " `ASSERT()\n" | |
| " `COVER()\n" | |
| " end\n" | |
| "endmodule\n", | |
| }, | |
| { | |
| "module conditional_generate;\n" | |
| "`ASSERT()\n" | |
| "if(foo)begin\n" | |
| " end\n" | |
| "`COVER()\n" | |
| "endmodule\n", | |
| "module conditional_generate;\n" | |
| " `ASSERT()\n" | |
| " if (foo) begin\n" | |
| " end\n" | |
| " `COVER()\n" | |
| "endmodule\n", | |
| }, | |
| { | |
| "module conditional_generate;\n" | |
| "if(foo)begin\n" | |
| " // comment1\n" | |
| " // comment2\n" | |
| " end\n" | |
| "endmodule\n", | |
| "module conditional_generate;\n" | |
| " if (foo) begin\n" | |
| " // comment1\n" | |
| " // comment2\n" | |
| " end\n" | |
| "endmodule\n", | |
| }, | |
| { | |
| "module m ;" | |
| "for(genvar i=0; ;)\n; " // null generate statement | |
| "for(genvar j=0 ;; )\n; " // null generate statement | |
| "endmodule", | |
| "module m;\n" | |
| " for (genvar i = 0;;);\n" | |
| " for (genvar j = 0;;);\n" | |
| "endmodule\n", | |
| }, | |
| { | |
| "module m ;" | |
| "for (genvar f = 0; f < N; f++) begin " | |
| "assign x = y; assign y = z;" | |
| "end endmodule", | |
| "module m;\n" | |
| " for (genvar f = 0; f < N; f++) begin\n" | |
| " assign x = y;\n" | |
| " assign y = z;\n" | |
| " end\n" | |
| "endmodule\n", | |
| }, | |
| { | |
| // standalone genvar statement | |
| "module m ;" | |
| "genvar f;" | |
| "for(f=0; f<N; f ++ )begin " | |
| "end endmodule", | |
| "module m;\n" | |
| " genvar f;\n" | |
| " for (f = 0; f < N; f++) begin\n" | |
| " end\n" | |
| "endmodule\n", | |
| }, | |
| { | |
| // multiple arguments to genvar statement | |
| "module m ;" | |
| "genvar f, g;" | |
| "for(f=0; f<N; f ++ )begin " | |
| "end for(g=N; g>0; g -- )begin " | |
| "end endmodule", | |
| "module m;\n" | |
| " genvar f, g;\n" | |
| " for (f = 0; f < N; f++) begin\n" | |
| " end\n" | |
| " for (g = N; g > 0; g--) begin\n" | |
| " end\n" | |
| "endmodule\n", | |
| }, | |
| { | |
| // multiple genvar statements | |
| "module m ;" | |
| "genvar f;" | |
| "genvar g;" | |
| "for(f=0; f<N; f ++ )begin " | |
| "end for(g=N; g>0; g -- )begin " | |
| "end endmodule", | |
| "module m;\n" | |
| " genvar f;\n" | |
| " genvar g;\n" | |
| " for (f = 0; f < N; f++) begin\n" | |
| " end\n" | |
| " for (g = N; g > 0; g--) begin\n" | |
| " end\n" | |
| "endmodule\n", | |
| }, | |
| { | |
| "module event_control ;" | |
| "always@ ( posedge clk )z<=y;" | |
| "endmodule\n", | |
| "module event_control;\n" | |
| " always @(posedge clk) z <= y;\n" | |
| "endmodule\n", | |
| }, | |
| { | |
| "module always_if ;" | |
| "always@ ( posedge clk ) if (expr) z<=y;" | |
| "endmodule\n", | |
| "module always_if;\n" | |
| " always @(posedge clk)\n" // doesn't fit | |
| " if (expr)\n" | |
| " z <= y;\n" | |
| "endmodule\n", | |
| }, | |
| { | |
| "module always_if ;" | |
| "always@* if (expr) z<=y;" | |
| "endmodule\n", | |
| "module always_if;\n" | |
| " always @* if (expr) z <= y;\n" // fits | |
| "endmodule\n", | |
| }, | |
| { | |
| "module \talways_if_else ;" | |
| "always@* if (expr) z<=y; else g<=0;" | |
| "endmodule\n", | |
| "module always_if_else;\n" | |
| " always @*\n" | |
| " if (expr) z <= y;\n" // fits | |
| " else g <= 0;\n" // fits | |
| "endmodule\n", | |
| }, | |
| { | |
| "module \talways_if_else_if ;" | |
| "always@* if (expr) z<=y; else if (w) g<=0;" | |
| "endmodule\n", | |
| "module always_if_else_if;\n" | |
| " always @*\n" | |
| " if (expr) z <= y;\n" // fits | |
| " else if (w) g <= 0;\n" // fits | |
| "endmodule\n", | |
| }, | |
| { | |
| "module \talways_if_else_if_else ;" | |
| "always@* if (expr) z<=y; else if (w) g<=0;else h<=1;" | |
| "endmodule\n", | |
| "module always_if_else_if_else;\n" | |
| " always @*\n" | |
| " if (expr) z <= y;\n" // fits | |
| " else if (w) g <= 0;\n" // fits | |
| " else h <= 1;\n" | |
| "endmodule\n", | |
| }, | |
| { | |
| "module m;\n" | |
| "always @(b, c)" | |
| " for (;;)\ts = y;" | |
| "endmodule", | |
| "module m;\n" | |
| " always @(b, c) for (;;) s = y;\n" // fits | |
| "endmodule\n", | |
| }, | |
| { | |
| "module m;\n" | |
| "always @(posedge clk)" | |
| " for (i=0;i<k;++i)\ts = y;" | |
| "endmodule", | |
| "module m;\n" | |
| " always @(posedge clk)\n" | |
| " for (i = 0; i < k; ++i)\n" | |
| " s = y;\n" | |
| "endmodule\n", | |
| }, | |
| { | |
| "module m;\n" | |
| "always @(posedge clk)" | |
| " repeat (jj+kk)\ts = y;" | |
| "endmodule", | |
| "module m;\n" | |
| " always @(posedge clk)\n" | |
| " repeat (jj + kk)\n" | |
| " s = y;\n" | |
| "endmodule\n", | |
| }, | |
| { | |
| "module m;\n" | |
| "always @(posedge clk)" | |
| " foreach(jj[kk])\ts = y;" | |
| "endmodule", | |
| "module m;\n" | |
| " always @(posedge clk)\n" | |
| " foreach (jj[kk])\n" | |
| " s = y;\n" | |
| "endmodule\n", | |
| }, | |
| { | |
| "module m;\n" | |
| "always @(posedge clk)" | |
| " while(jj[kk])\ts = y;" | |
| "endmodule", | |
| "module m;\n" | |
| " always @(posedge clk)\n" | |
| " while (jj[kk])\n" | |
| " s = y;\n" | |
| "endmodule\n", | |
| }, | |
| { | |
| "module m;\n" | |
| "always @(posedge clk)" | |
| " do s=y;while(jj[kk]);\t" | |
| "endmodule", | |
| "module m;\n" | |
| " always @(posedge clk)\n" | |
| " do\n" | |
| " s = y;\n" | |
| " while (jj[kk]);\n" | |
| "endmodule\n", | |
| }, | |
| { | |
| "module m;\n" | |
| "always @(posedge clk) \n" | |
| " case(jj)\tS:s = y;endcase\t" | |
| "endmodule", | |
| "module m;\n" | |
| " always @(posedge clk)\n" | |
| " case (jj)\n" | |
| " S: s = y;\n" | |
| " endcase\n" | |
| "endmodule\n", | |
| }, | |
| { | |
| "module always_if ;" | |
| "always@ ( posedge clk ) if (expr) z<=y;" | |
| "endmodule\n", | |
| "module always_if;\n" | |
| " always @(posedge clk)\n" // doesn't fit | |
| " if (expr)\n" | |
| " z <= y;\n" | |
| "endmodule\n", | |
| }, | |
| { | |
| "module always_if ;" | |
| "always@* if (expr) z<=y;" | |
| "endmodule\n", | |
| "module always_if;\n" | |
| " always @* if (expr) z <= y;\n" // fits | |
| "endmodule\n", | |
| }, | |
| { | |
| "module \talways_if_else ;" | |
| "always@* if (expr) z<=y; else g<=0;" | |
| "endmodule\n", | |
| "module always_if_else;\n" | |
| " always @*\n" | |
| " if (expr) z <= y;\n" // fits | |
| " else g <= 0;\n" // fits | |
| "endmodule\n", | |
| }, | |
| { | |
| "module \talways_if_else_if ;" | |
| "always@* if (expr) z<=y; else if (w) g<=0;" | |
| "endmodule\n", | |
| "module always_if_else_if;\n" | |
| " always @*\n" | |
| " if (expr) z <= y;\n" // fits | |
| " else if (w) g <= 0;\n" // fits | |
| "endmodule\n", | |
| }, | |
| { | |
| "module \talways_if_else_if_else ;" | |
| "always@* if (expr) z<=y; else if (w) g<=0;else h<=1;" | |
| "endmodule\n", | |
| "module always_if_else_if_else;\n" | |
| " always @*\n" | |
| " if (expr) z <= y;\n" // fits | |
| " else if (w) g <= 0;\n" // fits | |
| " else h <= 1;\n" | |
| "endmodule\n", | |
| }, | |
| { | |
| "module m;\n" | |
| "always @(b, c)" | |
| " for (;;)\ts = y;" | |
| "endmodule", | |
| "module m;\n" | |
| " always @(b, c) for (;;) s = y;\n" // fits | |
| "endmodule\n", | |
| }, | |
| { | |
| "module m;\n" | |
| "always @(posedge clk)" | |
| " for (i=0;i<k;++i)\ts = y;" | |
| "endmodule", | |
| "module m;\n" | |
| " always @(posedge clk)\n" | |
| " for (i = 0; i < k; ++i)\n" | |
| " s = y;\n" | |
| "endmodule\n", | |
| }, | |
| { | |
| "module m;\n" | |
| "always @(posedge clk)" | |
| " repeat (jj+kk)\ts = y;" | |
| "endmodule", | |
| "module m;\n" | |
| " always @(posedge clk)\n" | |
| " repeat (jj + kk)\n" | |
| " s = y;\n" | |
| "endmodule\n", | |
| }, | |
| { | |
| "module m;\n" | |
| "always @(posedge clk)" | |
| " foreach(jj[kk])\ts = y;" | |
| "endmodule", | |
| "module m;\n" | |
| " always @(posedge clk)\n" | |
| " foreach (jj[kk])\n" | |
| " s = y;\n" | |
| "endmodule\n", | |
| }, | |
| { | |
| "module m;\n" | |
| "always @(posedge clk)" | |
| " while(jj[kk])\ts = y;" | |
| "endmodule", | |
| "module m;\n" | |
| " always @(posedge clk)\n" | |
| " while (jj[kk])\n" | |
| " s = y;\n" | |
| "endmodule\n", | |
| }, | |
| { | |
| "module m;\n" | |
| "always @(posedge clk)" | |
| " do s=y;while(jj[kk]);\t" | |
| "endmodule", | |
| "module m;\n" | |
| " always @(posedge clk)\n" | |
| " do\n" | |
| " s = y;\n" | |
| " while (jj[kk]);\n" | |
| "endmodule\n", | |
| }, | |
| { | |
| "module m;\n" | |
| "always @(posedge clk) \n" | |
| " case(jj)\tS:s = y;endcase\t" | |
| "endmodule", | |
| "module m;\n" | |
| " always @(posedge clk)\n" | |
| " case (jj)\n" | |
| " S: s = y;\n" | |
| " endcase\n" | |
| "endmodule\n", | |
| }, | |
| { | |
| "module always_if ;" | |
| "always@ ( posedge clk ) if (expr) z<=y;" | |
| "endmodule\n", | |
| "module always_if;\n" | |
| " always @(posedge clk)\n" // doesn't fit | |
| " if (expr)\n" | |
| " z <= y;\n" | |
| "endmodule\n", | |
| }, | |
| { | |
| "module always_if ;" | |
| "always@* if (expr) z<=y;" | |
| "endmodule\n", | |
| "module always_if;\n" | |
| " always @* if (expr) z <= y;\n" // fits | |
| "endmodule\n", | |
| }, | |
| { | |
| "module \talways_if_else ;" | |
| "always@* if (expr) z<=y; else g<=0;" | |
| "endmodule\n", | |
| "module always_if_else;\n" | |
| " always @*\n" | |
| " if (expr) z <= y;\n" // fits | |
| " else g <= 0;\n" // fits | |
| "endmodule\n", | |
| }, | |
| { | |
| "module \talways_if_else_if ;" | |
| "always@* if (expr) z<=y; else if (w) g<=0;" | |
| "endmodule\n", | |
| "module always_if_else_if;\n" | |
| " always @*\n" | |
| " if (expr) z <= y;\n" // fits | |
| " else if (w) g <= 0;\n" // fits | |
| "endmodule\n", | |
| }, | |
| { | |
| "module \talways_if_else_if_else ;" | |
| "always@* if (expr) z<=y; else if (w) g<=0;else h<=1;" | |
| "endmodule\n", | |
| "module always_if_else_if_else;\n" | |
| " always @*\n" | |
| " if (expr) z <= y;\n" // fits | |
| " else if (w) g <= 0;\n" // fits | |
| " else h <= 1;\n" | |
| "endmodule\n", | |
| }, | |
| { | |
| "module m;\n" | |
| "always @(b, c)" | |
| " for (;;)\ts = y;" | |
| "endmodule", | |
| "module m;\n" | |
| " always @(b, c) for (;;) s = y;\n" // fits | |
| "endmodule\n", | |
| }, | |
| { | |
| "module m;\n" | |
| "always @(posedge clk)" | |
| " for (i=0;i<k;++i)\ts = y;" | |
| "endmodule", | |
| "module m;\n" | |
| " always @(posedge clk)\n" | |
| " for (i = 0; i < k; ++i)\n" | |
| " s = y;\n" | |
| "endmodule\n", | |
| }, | |
| { | |
| "module m;\n" | |
| "always @(posedge clk)" | |
| " repeat (jj+kk)\ts = y;" | |
| "endmodule", | |
| "module m;\n" | |
| " always @(posedge clk)\n" | |
| " repeat (jj + kk)\n" | |
| " s = y;\n" | |
| "endmodule\n", | |
| }, | |
| { | |
| "module m;\n" | |
| "always @(posedge clk)" | |
| " foreach(jj[kk])\ts = y;" | |
| "endmodule", | |
| "module m;\n" | |
| " always @(posedge clk)\n" | |
| " foreach (jj[kk])\n" | |
| " s = y;\n" | |
| "endmodule\n", | |
| }, | |
| { | |
| "module m;\n" | |
| "always @(posedge clk)" | |
| " while(jj[kk])\ts = y;" | |
| "endmodule", | |
| "module m;\n" | |
| " always @(posedge clk)\n" | |
| " while (jj[kk])\n" | |
| " s = y;\n" | |
| "endmodule\n", | |
| }, | |
| { | |
| "module m;\n" | |
| "always @(posedge clk)" | |
| " do s=y;while(jj[kk]);\t" | |
| "endmodule", | |
| "module m;\n" | |
| " always @(posedge clk)\n" | |
| " do\n" | |
| " s = y;\n" | |
| " while (jj[kk]);\n" | |
| "endmodule\n", | |
| }, | |
| { | |
| "module m;\n" | |
| "always @(posedge clk) \n" | |
| " case(jj)\tS:s = y;endcase\t" | |
| "endmodule", | |
| "module m;\n" | |
| " always @(posedge clk)\n" | |
| " case (jj)\n" | |
| " S: s = y;\n" | |
| " endcase\n" | |
| "endmodule\n", | |
| }, | |
| { | |
| "module always_if ;" | |
| "always@ ( posedge clk ) if (expr) z<=y;" | |
| "endmodule\n", | |
| "module always_if;\n" | |
| " always @(posedge clk)\n" // doesn't fit | |
| " if (expr)\n" | |
| " z <= y;\n" | |
| "endmodule\n", | |
| }, | |
| { | |
| "module always_if ;" | |
| "always@* if (expr) z<=y;" | |
| "endmodule\n", | |
| "module always_if;\n" | |
| " always @* if (expr) z <= y;\n" // fits | |
| "endmodule\n", | |
| }, | |
| { | |
| "module \talways_if_else ;" | |
| "always@* if (expr) z<=y; else g<=0;" | |
| "endmodule\n", | |
| "module always_if_else;\n" | |
| " always @*\n" | |
| " if (expr) z <= y;\n" // fits | |
| " else g <= 0;\n" // fits | |
| "endmodule\n", | |
| }, | |
| { | |
| "module \talways_if_else_if ;" | |
| "always@* if (expr) z<=y; else if (w) g<=0;" | |
| "endmodule\n", | |
| "module always_if_else_if;\n" | |
| " always @*\n" | |
| " if (expr) z <= y;\n" // fits | |
| " else if (w) g <= 0;\n" // fits | |
| "endmodule\n", | |
| }, | |
| { | |
| "module \talways_if_else_if_else ;" | |
| "always@* if (expr) z<=y; else if (w) g<=0;else h<=1;" | |
| "endmodule\n", | |
| "module always_if_else_if_else;\n" | |
| " always @*\n" | |
| " if (expr) z <= y;\n" // fits | |
| " else if (w) g <= 0;\n" // fits | |
| " else h <= 1;\n" | |
| "endmodule\n", | |
| }, | |
| { | |
| "module m;\n" | |
| "always @(b, c)" | |
| " for (;;)\ts = y;" | |
| "endmodule", | |
| "module m;\n" | |
| " always @(b, c) for (;;) s = y;\n" // fits | |
| "endmodule\n", | |
| }, | |
| { | |
| "module m;\n" | |
| "always @(posedge clk)" | |
| " for (i=0;i<k;++i)\ts = y;" | |
| "endmodule", | |
| "module m;\n" | |
| " always @(posedge clk)\n" | |
| " for (i = 0; i < k; ++i)\n" | |
| " s = y;\n" | |
| "endmodule\n", | |
| }, | |
| { | |
| "module m;\n" | |
| "always @(posedge clk)" | |
| " repeat (jj+kk)\ts = y;" | |
| "endmodule", | |
| "module m;\n" | |
| " always @(posedge clk)\n" | |
| " repeat (jj + kk)\n" | |
| " s = y;\n" | |
| "endmodule\n", | |
| }, | |
| { | |
| "module m;\n" | |
| "always @(posedge clk)" | |
| " foreach(jj[kk])\ts = y;" | |
| "endmodule", | |
| "module m;\n" | |
| " always @(posedge clk)\n" | |
| " foreach (jj[kk])\n" | |
| " s = y;\n" | |
| "endmodule\n", | |
| }, | |
| { | |
| "module m;\n" | |
| "always @(posedge clk)" | |
| " while(jj[kk])\ts = y;" | |
| "endmodule", | |
| "module m;\n" | |
| " always @(posedge clk)\n" | |
| " while (jj[kk])\n" | |
| " s = y;\n" | |
| "endmodule\n", | |
| }, | |
| { | |
| "module m;\n" | |
| "always @(posedge clk)" | |
| " do s=y;while(jj[kk]);\t" | |
| "endmodule", | |
| "module m;\n" | |
| " always @(posedge clk)\n" | |
| " do\n" | |
| " s = y;\n" | |
| " while (jj[kk]);\n" | |
| "endmodule\n", | |
| }, | |
| { | |
| "module m;\n" | |
| "always @(posedge clk) \n" | |
| " case(jj)\tS:s = y;endcase\t" | |
| "endmodule", | |
| "module m;\n" | |
| " always @(posedge clk)\n" | |
| " case (jj)\n" | |
| " S: s = y;\n" | |
| " endcase\n" | |
| "endmodule\n", | |
| }, | |
| { | |
| // begin/end with labels | |
| "module m ;initial begin:yyy\tend:yyy endmodule", | |
| "module m;\n" | |
| " initial begin : yyy\n" | |
| " end : yyy\n" | |
| "endmodule\n", | |
| }, | |
| { | |
| // conditional generate begin/end with labels | |
| "module m ;if\n( 1) begin:yyy\tend:yyy endmodule", | |
| "module m;\n" | |
| " if (1) begin : yyy\n" | |
| " end : yyy\n" | |
| "endmodule\n", | |
| }, | |
| { | |
| // begin/end with labels, nested | |
| "module m ;initial begin:yyy if(1)begin:zzz " | |
| "end:zzz\tend:yyy endmodule", | |
| "module m;\n" | |
| " initial begin : yyy\n" | |
| " if (1) begin : zzz\n" | |
| " end : zzz\n" | |
| " end : yyy\n" | |
| "endmodule\n", | |
| }, | |
| { | |
| "module m ;initial begin # 1 x<=y ;end endmodule", | |
| "module m;\n" | |
| " initial begin\n" | |
| " #1 x <= y;\n" | |
| " end\n" | |
| "endmodule\n", | |
| }, | |
| { | |
| "module m ;initial begin x<=y ; y<=z;end endmodule", | |
| "module m;\n" | |
| " initial begin\n" | |
| " x <= y;\n" | |
| " y <= z;\n" | |
| " end\n" | |
| "endmodule\n", | |
| }, | |
| { | |
| "module m ;initial begin # 10 x<=y ; # 20 y<=z;end endmodule", | |
| "module m;\n" | |
| " initial begin\n" | |
| " #10 x <= y;\n" | |
| " #20 y <= z;\n" | |
| " end\n" | |
| "endmodule\n", | |
| }, | |
| { | |
| // qualified variables | |
| "module m ;initial begin automatic int a; " | |
| " static byte s=0;end endmodule", | |
| "module m;\n" | |
| " initial begin\n" | |
| " automatic int a;\n" | |
| " static byte s = 0;\n" | |
| " end\n" | |
| "endmodule\n", | |
| }, | |
| { | |
| "module m ;initial begin automatic int a,b; " | |
| " static byte s,t;end endmodule", | |
| "module m;\n" | |
| " initial begin\n" | |
| " automatic int a, b;\n" | |
| " static byte s, t;\n" | |
| " end\n" | |
| "endmodule\n", | |
| }, | |
| { | |
| "module m ;initial begin static byte a=1,b=0;end endmodule", | |
| "module m;\n" | |
| " initial begin\n" | |
| " static byte a = 1, b = 0;\n" | |
| " end\n" | |
| "endmodule\n", | |
| }, | |
| { | |
| "module m ;initial begin const int a=0;end endmodule", | |
| "module m;\n" | |
| " initial begin\n" | |
| " const int a = 0;\n" | |
| " end\n" | |
| "endmodule\n", | |
| }, | |
| { | |
| "module m ;initial begin automatic const int a=0;end endmodule", | |
| "module m;\n" | |
| " initial begin\n" | |
| " automatic const int a = 0;\n" | |
| " end\n" | |
| "endmodule\n", | |
| }, | |
| { | |
| "module m ;initial begin const var automatic int a=0;end endmodule", | |
| "module m;\n" | |
| " initial begin\n" | |
| " const var automatic int a = 0;\n" | |
| " end\n" | |
| "endmodule\n", | |
| }, | |
| { | |
| "module m ;initial begin static byte s ={<<{a}};end endmodule", | |
| "module m;\n" | |
| " initial begin\n" | |
| " static byte s = {<<{a}};\n" | |
| " end\n" | |
| "endmodule\n", | |
| }, | |
| { | |
| "module m ;initial begin static int s ={>>4{a}};end endmodule", | |
| "module m;\n" | |
| " initial begin\n" | |
| " static int s = {>>4{a}};\n" | |
| " end\n" | |
| "endmodule\n", | |
| }, | |
| { | |
| "module m; final assert (expr ) ;endmodule", | |
| "module m;\n" | |
| " final assert (expr);\n" | |
| "endmodule\n", | |
| }, | |
| { | |
| "module m; final begin\tassert (expr ) ;end endmodule", | |
| "module m;\n" | |
| " final begin\n" | |
| " assert (expr);\n" | |
| " end\n" | |
| "endmodule\n", | |
| }, | |
| { | |
| "module m; final assume (expr ) ;endmodule", | |
| "module m;\n" | |
| " final assume (expr);\n" | |
| "endmodule\n", | |
| }, | |
| { | |
| "module m; final cover (expr ) ;endmodule", | |
| "module m;\n" | |
| " final cover (expr);\n" | |
| "endmodule\n", | |
| }, | |
| { | |
| // two consecutive clocking declarations in modules | |
| " module mcd ; " | |
| "clocking cb @( posedge clk);\t\tendclocking " | |
| "clocking cb2 @ (posedge clk\n); endclocking endmodule", | |
| "module mcd;\n" | |
| " clocking cb @(posedge clk);\n" | |
| " endclocking\n" | |
| " clocking cb2 @(posedge clk);\n" | |
| " endclocking\n" | |
| "endmodule\n", | |
| }, | |
| { | |
| // two consecutive clocking declarations in modules, with end labels | |
| " module mcd ; " | |
| "clocking cb @( posedge clk);\t\tendclocking: cb " | |
| "clocking cb2 @ (posedge clk\n); endclocking :cb2 endmodule", | |
| "module mcd;\n" | |
| " clocking cb @(posedge clk);\n" | |
| " endclocking : cb\n" | |
| " clocking cb2 @(posedge clk);\n" | |
| " endclocking : cb2\n" | |
| "endmodule\n", | |
| }, | |
| { | |
| // clocking declarations with ports in modules | |
| " module mcd ; " | |
| "clocking cb @ (posedge clk\n); input a; output b; endclocking " | |
| "endmodule", | |
| "module mcd;\n" | |
| " clocking cb @(posedge clk);\n" | |
| " input a;\n" | |
| " output b;\n" | |
| " endclocking\n" | |
| "endmodule\n", | |
| }, | |
| { | |
| // DPI import declarations in modules | |
| "module mdi;" | |
| "import \"DPI-C\" function int add(\n) ;" | |
| "import \"DPI-C\"\t\tfunction int\nsleep( input int secs );" | |
| "endmodule", | |
| "module mdi;\n" | |
| " import \"DPI-C\" function int add();\n" | |
| " import \"DPI-C\" function int sleep(\n" // doesn't fit in 40-col | |
| " input int secs);\n" | |
| "endmodule\n", | |
| }, | |
| {// module with system task call | |
| "module m; initial begin #10 $display(\"foo\"); $display(\"bar\");" | |
| "end endmodule", | |
| "module m;\n" | |
| " initial begin\n" | |
| " #10 $display(\"foo\");\n" | |
| " $display(\"bar\");\n" | |
| " end\n" | |
| "endmodule\n"}, | |
| // interface test cases | |
| {// two interface declarations | |
| " interface if1 ; endinterface\t\t" | |
| "interface if2; endinterface ", | |
| "interface if1;\n" | |
| "endinterface\n" | |
| "interface if2;\n" | |
| "endinterface\n"}, | |
| {// two interface declarations, end labels | |
| " interface if1 ; endinterface:if1\t\t" | |
| "interface if2; endinterface : if2 ", | |
| "interface if1;\n" | |
| "endinterface : if1\n" | |
| "interface if2;\n" | |
| "endinterface : if2\n"}, | |
| {// interface declaration with parameters | |
| " interface if1#( parameter int W= 8 );endinterface\t\t", | |
| "interface if1 #(\n" | |
| " parameter int W = 8\n" | |
| ");\n" | |
| "endinterface\n"}, | |
| {// interface declaration with ports (empty) | |
| " interface if1()\n;endinterface\t\t", | |
| "interface if1 ();\n" | |
| "endinterface\n"}, | |
| {// interface declaration with parameter comment only, empty ports | |
| " interface if1#( \n" | |
| "//param\n" | |
| ")();endinterface\t\t", | |
| "interface if1 #(\n" | |
| " //param\n" | |
| ") ();\n" | |
| "endinterface\n"}, | |
| {// interface declaration with parameter, empty ports | |
| " interface if1#( parameter int W= 8 )();endinterface\t\t", | |
| "interface if1 #(\n" | |
| " parameter int W = 8\n" | |
| ") ();\n" | |
| "endinterface\n"}, | |
| {// interface declaration with ports | |
| " interface if1( input\tlogic z)\n;endinterface\t\t", | |
| "interface if1 (\n" | |
| " input logic z\n" | |
| ");\n" | |
| "endinterface\n"}, | |
| {// interface declaration with multiple ports | |
| " interface if1( input\tlogic z, output logic a)\n;endinterface\t\t", | |
| "interface if1 (\n" | |
| " input logic z,\n" // should be one-per-line, even it it fits | |
| " output logic a\n" // aligned | |
| ");\n" | |
| "endinterface\n"}, | |
| {// interface declaration with parameters and ports | |
| " interface if1#( parameter int W= 8 )(input logic z);endinterface\t\t", | |
| // doesn't fit on one line | |
| "interface if1 #(\n" | |
| " parameter int W = 8\n" | |
| ") (\n" | |
| " input logic z\n" | |
| ");\n" | |
| "endinterface\n"}, | |
| { | |
| // interface with modport declarations | |
| "interface\tfoo_if ;" | |
| "modport mp1\t( output a, input b);" | |
| "modport\tmp2 (output c,input d );\t" | |
| "endinterface", | |
| "interface foo_if;\n" | |
| " modport mp1(output a, input b);\n" | |
| " modport mp2(output c, input d);\n" | |
| "endinterface\n", | |
| }, | |
| { | |
| // interface with long modport port names | |
| "interface\tfoo_if ;" | |
| "modport mp1\t( output a_long_output, input detailed_input_name);" | |
| "endinterface", | |
| "interface foo_if;\n" | |
| " modport mp1(\n" | |
| " output a_long_output,\n" | |
| " input detailed_input_name\n" | |
| " );\n" | |
| "endinterface\n", | |
| }, | |
| { | |
| // interface with modport declaration with multiple ports | |
| "interface\tfoo_if ;" | |
| "modport mp1\t( output a_long_output, input detailed_input_name);" | |
| "endinterface", | |
| "interface foo_if;\n" | |
| " modport mp1(\n" | |
| " output a_long_output,\n" | |
| " input detailed_input_name\n" | |
| " );\n" | |
| "endinterface\n", | |
| }, | |
| { | |
| // interface with modport TF port declaration | |
| "interface\tfoo_if ;" | |
| "modport mp1\t( output a, input b, import c);" | |
| "endinterface", | |
| "interface foo_if;\n" | |
| " modport mp1(\n" | |
| " output a,\n" | |
| " input b,\n" | |
| " import c\n" | |
| " );\n" | |
| "endinterface\n", | |
| }, | |
| { | |
| // interface with complex modport ports list | |
| "interface\tfoo_if ;" | |
| "modport producer\t(input ready,\toutput data, valid, user," | |
| " strobe, keep, last,\timport producer_reset, producer_tick);" | |
| "modport consumer\t(input data, valid, user, strobe, keep, last," | |
| " output ready,\timport consumer_reset, consumer_tick, consume);" | |
| "endinterface", | |
| "interface foo_if;\n" | |
| " modport producer(\n" | |
| " input ready,\n" | |
| " output data, valid, user, strobe,\n" | |
| " keep, last,\n" | |
| " import producer_reset,\n" | |
| " producer_tick\n" | |
| " );\n" | |
| " modport consumer(\n" | |
| " input data, valid, user, strobe,\n" | |
| " keep, last,\n" | |
| " output ready,\n" | |
| " import consumer_reset,\n" | |
| " consumer_tick, consume\n" | |
| " );\n" | |
| "endinterface\n", | |
| }, | |
| { | |
| // interface with modports and comments inside | |
| "interface foo_if;\n" | |
| " modport mp1(\n" | |
| " // Our output\n" | |
| " output a,\n" | |
| " /* Inputs */\n" | |
| " input b1, b_f /*last*/," | |
| " import c\n" | |
| " );\n" | |
| "endinterface\n", | |
| "interface foo_if;\n" | |
| " modport mp1(\n" | |
| " // Our output\n" | |
| " output a,\n" | |
| " /* Inputs */\n" | |
| " input b1, b_f /*last*/,\n" | |
| " import c\n" | |
| " );\n" | |
| "endinterface\n", | |
| }, | |
| // class test cases | |
| {"class action;int xyz;endclass : action\n", | |
| "class action;\n" | |
| " int xyz;\n" | |
| "endclass : action\n"}, | |
| {"class action extends mypkg :: inaction;endclass : action\n", | |
| "class action extends mypkg::inaction;\n" // tests for spacing around :: | |
| "endclass : action\n"}, | |
| {"class c;function new;endfunction endclass", | |
| "class c;\n" | |
| " function new;\n" | |
| " endfunction\n" | |
| "endclass\n"}, | |
| {"class c;function new ( );endfunction endclass", | |
| "class c;\n" | |
| " function new();\n" | |
| " endfunction\n" | |
| "endclass\n"}, | |
| {"class c;function new ( string s );endfunction endclass", | |
| "class c;\n" | |
| " function new(string s);\n" | |
| " endfunction\n" | |
| "endclass\n"}, | |
| {"class c;function new ( string s ,int i );endfunction endclass", | |
| "class c;\n" | |
| " function new(string s, int i);\n" | |
| " endfunction\n" | |
| "endclass\n"}, | |
| {"class c;function void f;endfunction endclass", | |
| "class c;\n" | |
| " function void f;\n" | |
| " endfunction\n" | |
| "endclass\n"}, | |
| {"class c;virtual function void f;endfunction endclass", | |
| "class c;\n" | |
| " virtual function void f;\n" | |
| " endfunction\n" | |
| "endclass\n"}, | |
| {"class c;function int f ( );endfunction endclass", | |
| "class c;\n" | |
| " function int f();\n" | |
| " endfunction\n" | |
| "endclass\n"}, | |
| {"class c;function int f ( int ii );endfunction endclass", | |
| "class c;\n" | |
| " function int f(int ii);\n" | |
| " endfunction\n" | |
| "endclass\n"}, | |
| {"class c;function int f ( int ii ,bit bb );endfunction endclass", | |
| "class c;\n" | |
| " function int f(int ii, bit bb);\n" | |
| " endfunction\n" | |
| "endclass\n"}, | |
| {"class c;task t ;endtask endclass", | |
| "class c;\n" | |
| " task t;\n" | |
| " endtask\n" | |
| "endclass\n"}, | |
| {"class c;task t ( int ii ,bit bb );endtask endclass", | |
| "class c;\n" | |
| " task t(int ii, bit bb);\n" | |
| " endtask\n" | |
| "endclass\n"}, | |
| {"class c; task automatic repeated_assigner;" | |
| "repeat (count) y = w;" // single statement body | |
| "endtask endclass", | |
| "class c;\n" | |
| " task automatic repeated_assigner;\n" | |
| " repeat (count) y = w;\n" | |
| " endtask\n" | |
| "endclass\n"}, | |
| {"class c; task automatic delayed_assigner;" | |
| "# 100 y = w;" // delayed assignment | |
| "endtask endclass", | |
| "class c;\n" | |
| " task automatic delayed_assigner;\n" | |
| " #100 y = w;\n" | |
| " endtask\n" | |
| "endclass\n"}, | |
| {"class c; task automatic labeled_assigner;" | |
| "lbl : y = w;" // delayed assignment | |
| "endtask endclass", | |
| "class c;\n" | |
| " task automatic labeled_assigner;\n" | |
| " lbl : y = w;\n" // TODO(fangism): no space before ':' | |
| " endtask\n" | |
| "endclass\n"}, | |
| // tasks with control statements | |
| {"class c; task automatic waiter;" | |
| "if (count == 0) begin #0; return;end " | |
| "endtask endclass", | |
| "class c;\n" | |
| " task automatic waiter;\n" | |
| " if (count == 0) begin\n" | |
| " #0;\n" | |
| " return;\n" | |
| " end\n" | |
| " endtask\n" | |
| "endclass\n"}, | |
| {"class c; task automatic heartbreaker;" | |
| "if( c)if( d) break ;" | |
| "endtask endclass", | |
| "class c;\n" | |
| " task automatic heartbreaker;\n" | |
| " if (c) if (d) break;\n" | |
| " endtask\n" | |
| "endclass\n"}, | |
| {"class c; task automatic waiter;" | |
| "repeat (count) @(posedge clk);" | |
| "endtask endclass", | |
| "class c;\n" | |
| " task automatic waiter;\n" | |
| " repeat (count) @(posedge clk);\n" | |
| " endtask\n" | |
| "endclass\n"}, | |
| {"class c; task automatic repeat_assigner;" | |
| "repeat( r )\ny = w;" | |
| "repeat( q )\ny = 1;" | |
| "endtask endclass", | |
| "class c;\n" | |
| " task automatic repeat_assigner;\n" | |
| " repeat (r) y = w;\n" | |
| " repeat (q) y = 1;\n" | |
| " endtask\n" | |
| "endclass\n"}, | |
| {"class c; task automatic event_control_assigner;" | |
| "@ ( posedge clk )\ny = w;" | |
| "@ ( negedge clk )\nz = w;" | |
| "endtask endclass", | |
| "class c;\n" | |
| " task automatic event_control_assigner;\n" | |
| " @(posedge clk) y = w;\n" | |
| " @(negedge clk) z = w;\n" | |
| " endtask\n" | |
| "endclass\n"}, | |
| { | |
| // classes with surrrounding comments | |
| // vertical spacing preserved | |
| "\n// pre-c\n\n" | |
| " class c ;\n" | |
| "// c stuff\n" | |
| "endclass\n" | |
| " // pre-d\n" | |
| "\n\nclass d ;\n" | |
| " // d stuff\n" | |
| "endclass\n" | |
| "\n// the end\n", | |
| "\n// pre-c\n\n" | |
| "class c;\n" | |
| " // c stuff\n" | |
| "endclass\n" | |
| "// pre-d\n\n\n" | |
| "class d;\n" | |
| " // d stuff\n" | |
| "endclass\n\n" | |
| "// the end\n", | |
| }, | |
| {// class with comments around task/function declarations | |
| "class c; // c is for cookie\n" | |
| " // f is for false\n" | |
| "\tfunction f(integer size) ; endfunction\n" | |
| " // t is for true\n" | |
| "task t();endtask\n" | |
| " // class is about to end\n" | |
| "endclass", | |
| "class c; // c is for cookie\n" | |
| " // f is for false\n" | |
| " function f(integer size);\n" | |
| " endfunction\n" | |
| " // t is for true\n" | |
| " task t();\n" | |
| " endtask\n" | |
| " // class is about to end\n" | |
| "endclass\n"}, | |
| // class property alignment test cases | |
| {"class c;\n" | |
| "int foo ;\n" | |
| "byte bar;\n" | |
| "endclass : c\n", | |
| "class c;\n" | |
| " int foo;\n" | |
| " byte bar;\n" | |
| "endclass : c\n"}, | |
| {"class c;\n" | |
| "int foo;\n" | |
| "const bit b;\n" | |
| "endclass : c\n", | |
| "class c;\n" | |
| " int foo;\n" | |
| " const bit b;\n" | |
| "endclass : c\n"}, | |
| {"class c;\n" | |
| "rand logic l;\n" | |
| "int foo;\n" | |
| "endclass : c\n", | |
| "class c;\n" | |
| " rand logic l;\n" | |
| " int foo;\n" | |
| "endclass : c\n"}, | |
| {"class c;\n" | |
| "rand logic l;\n" | |
| "const static int foo;\n" // more qualifiers | |
| "endclass : c\n", | |
| "class c;\n" | |
| " rand logic l;\n" | |
| " const static int foo;\n" | |
| "endclass : c\n"}, | |
| {"class c;\n" | |
| "static local int foo;\n" | |
| "const bit b;\n" | |
| "endclass : c\n", | |
| "class c;\n" | |
| " static local int foo;\n" | |
| " const bit b;\n" | |
| "endclass : c\n"}, | |
| {// example with queue | |
| "class c;\n" | |
| "int foo [$] ;\n" | |
| "int foo_bar ;\n" | |
| "endclass : c\n", | |
| "class c;\n" | |
| " int foo[$];\n" | |
| " int foo_bar;\n" | |
| "endclass : c\n"}, | |
| {// aligns over comments (ignored) | |
| "class c;\n" | |
| "// foo is...\n" | |
| "int foo;\n" | |
| "// b is...\n" | |
| "const bit b;\n" | |
| " // llama is...\n" | |
| "logic llama;\n" | |
| "endclass : c\n", | |
| "class c;\n" | |
| " // foo is...\n" | |
| " int foo;\n" | |
| " // b is...\n" | |
| " const bit b;\n" | |
| " // llama is...\n" | |
| " logic llama;\n" | |
| "endclass : c\n"}, | |
| {// aligns over comments (ignored), even with blank lines | |
| "class c;\n" | |
| "// foo is...\n" | |
| "int foo;\n" | |
| "\n" | |
| "// b is...\n" | |
| "const bit b;\n" | |
| "\n" | |
| " // llama is...\n" | |
| "logic llama;\n" | |
| "endclass : c\n", | |
| "class c;\n" | |
| " // foo is...\n" | |
| " int foo;\n" | |
| "\n" | |
| " // b is...\n" | |
| " const bit b;\n" | |
| "\n" | |
| " // llama is...\n" | |
| " logic llama;\n" | |
| "endclass : c\n"}, | |
| {// array dimensions do not have their own columns | |
| "class c;\n" | |
| "rand logic l;\n" | |
| "int [1:0] foo;\n" | |
| "endclass : c\n", | |
| "class c;\n" | |
| " rand logic l;\n" | |
| " int [1:0] foo;\n" | |
| "endclass : c\n"}, | |
| {// non-data-declarations break up groups | |
| "class c;\n" | |
| "rand logic l;\n" | |
| "int foo;\n" | |
| "`uvm_bar_foo()\n" | |
| "logic k;\n" | |
| "rand int bar;\n" | |
| "endclass : c\n", | |
| "class c;\n" | |
| " rand logic l;\n" | |
| " int foo;\n" | |
| " `uvm_bar_foo()\n" // separates alignment groups above/below | |
| " logic k;\n" | |
| " rand int bar;\n" | |
| "endclass : c\n"}, | |
| {// non-data-declarations break up groups | |
| "class c;\n" | |
| "logic k;\n" | |
| "rand int bar;\n" | |
| "function void f();\n" | |
| "endfunction\n" | |
| "rand logic l;\n" | |
| "int foo;\n" | |
| "endclass : c\n", | |
| "class c;\n" | |
| " logic k;\n" | |
| " rand int bar;\n" | |
| " function void f();\n" // function declaration breaks groups | |
| " endfunction\n" | |
| " rand logic l;\n" | |
| " int foo;\n" | |
| "endclass : c\n"}, | |
| {// align single-value initializers at the '=' | |
| "class c;\n" | |
| "const logic foo=0;\n" | |
| "const bit b=1;\n" | |
| "endclass : c\n", | |
| "class c;\n" | |
| " const logic foo = 0;\n" | |
| " const bit b = 1;\n" | |
| "endclass : c\n"}, | |
| {// align single-value initializers at the '=', over non-initialized | |
| "class c;\n" | |
| "const logic foo=0;\n" | |
| "rand int iidrv;\n" | |
| "const bit b=1;\n" | |
| "endclass : c\n", | |
| "class c;\n" | |
| " const logic foo = 0;\n" | |
| " rand int iidrv;\n" // no initializer, but align across this | |
| " const bit b = 1;\n" | |
| "endclass : c\n"}, | |
| // constraint test cases | |
| { | |
| "class foo; constraint c1_c{ } endclass", | |
| "class foo;\n" | |
| " constraint c1_c {}\n" | |
| "endclass\n", | |
| }, | |
| { | |
| "class foo; constraint c1_c{ } constraint c2_c{ } endclass", | |
| "class foo;\n" | |
| " constraint c1_c {}\n" | |
| " constraint c2_c {}\n" | |
| "endclass\n", | |
| }, | |
| { | |
| "class foo; constraint c1_c{soft z==y;unique{baz};}endclass", | |
| "class foo;\n" | |
| " constraint c1_c {\n" | |
| " soft z == y;\n" | |
| " unique {baz};\n" | |
| " }\n" | |
| "endclass\n", | |
| }, | |
| { | |
| "class foo; constraint c1_c{ //comment1\n" | |
| "//comment2\n" | |
| "//comment3\n" | |
| "} endclass", | |
| "class foo;\n" | |
| " constraint c1_c { //comment1\n" | |
| " //comment2\n" | |
| " //comment3\n" | |
| " }\n" | |
| "endclass\n", | |
| }, | |
| {"class foo;constraint c { " | |
| "timer_enable dist { [ 8'h0 : 8'hfe ] :/ 90 , 8'hff :/ 10 }; " | |
| "} endclass\n", | |
| "class foo;\n" | |
| " constraint c {\n" | |
| " timer_enable dist {\n" | |
| " [8'h0 : 8'hfe] :/ 90,\n" | |
| " 8'hff :/ 10\n" | |
| " };\n" | |
| " }\n" | |
| "endclass\n"}, | |
| { | |
| "class Foo; constraint if_c { if (z) { soft x == y; } } endclass\n", | |
| "class Foo;\n" | |
| " constraint if_c {\n" | |
| " if (z) {soft x == y;}\n" // TODO(fangism): always expand? | |
| " }\n" | |
| "endclass\n", | |
| }, | |
| { | |
| "class Foo; constraint if_c { if (z) {\n" | |
| "//comment-a\n" | |
| "soft x == y;\n" | |
| "//comment-b\n" | |
| "} } endclass\n", | |
| "class Foo;\n" | |
| " constraint if_c {\n" | |
| " if (z) {\n" | |
| " //comment-a\n" // properly indented | |
| " soft x == y;\n" | |
| " //comment-b\n" // properly indented | |
| " }\n" | |
| " }\n" | |
| "endclass\n", | |
| }, | |
| // class with empty parameter list | |
| {"class foo #(); endclass", | |
| "class foo #();\n" | |
| "endclass\n"}, | |
| // class with empty parameter list, with comment | |
| {"class foo #( \n" | |
| "// comment\n" | |
| "); endclass", | |
| "class foo #(\n" | |
| " // comment\n" | |
| ");\n" | |
| "endclass\n"}, | |
| // class with empty parameter list, extends | |
| {"class foo #()extends bar ; endclass", | |
| "class foo #() extends bar;\n" | |
| "endclass\n"}, | |
| // class extends from type with named parameters | |
| {"class foo extends bar #(.N(N), .M(M)); endclass", | |
| "class foo extends bar#(\n" | |
| " .N(N),\n" | |
| " .M(M)\n" | |
| ");\n" | |
| "endclass\n"}, | |
| // class with one parameter list | |
| {"class foo #(type a = b); endclass", | |
| "class foo #(\n" | |
| " type a = b\n" | |
| ");\n" | |
| "endclass\n"}, | |
| // class with multiple paramter list | |
| {"class foo #(type a = b, type c = d, type e = f); endclass", | |
| "class foo #(\n" | |
| " type a = b,\n" | |
| " type c = d,\n" | |
| " type e = f\n" | |
| ");\n" | |
| "endclass\n"}, | |
| // class with data members | |
| {"class i_love_data ;const\ninteger sizer\t;endclass", | |
| "class i_love_data;\n" | |
| " const integer sizer;\n" | |
| "endclass\n"}, | |
| {"class i_love_data ;const\ninteger sizer=3\t;endclass", | |
| "class i_love_data;\n" | |
| " const integer sizer = 3;\n" | |
| "endclass\n"}, | |
| {"class i_love_data ;protected\nint count \t;endclass", | |
| "class i_love_data;\n" | |
| " protected int count;\n" | |
| "endclass\n"}, | |
| {"class i_love_data ;\t\nint counter\n ;int countess \t;endclass", | |
| "class i_love_data;\n" | |
| " int counter;\n" | |
| " int countess;\n" | |
| "endclass\n"}, | |
| {"class i_love_params ;foo#( . bar) baz\t;endclass", | |
| "class i_love_params;\n" | |
| " foo #(.bar) baz;\n" | |
| "endclass\n"}, | |
| {"class i_love_params ;foo#( . bar ( bah )) baz\t;endclass", | |
| "class i_love_params;\n" | |
| " foo #(.bar(bah)) baz;\n" | |
| "endclass\n"}, | |
| {"class i_love_params ;foo#( . bar ( bah\n)," | |
| ".\ncat( dog) ) baz\t;endclass", | |
| "class i_love_params;\n" | |
| " foo #(\n" | |
| " .bar(bah),\n" | |
| " .cat(dog)\n" | |
| " ) baz;\n" | |
| "endclass\n"}, | |
| {"class i_love_params ;foo#( . bar) baz1,baz2\t;endclass", | |
| "class i_love_params;\n" | |
| " foo #(.bar) baz1, baz2;\n" | |
| "endclass\n"}, | |
| {"class i_love_params ;foo#( . bar) baz\t;baz#(.foo)bar;endclass", | |
| "class i_love_params;\n" | |
| " foo #(.bar) baz;\n" | |
| " baz #(.foo) bar;\n" | |
| "endclass\n"}, | |
| // typedef test cases | |
| {"typedef enum logic\t{ A=0, B=1 }foo_t;", | |
| "typedef enum logic {\n" | |
| " A = 0,\n" | |
| " B = 1\n" | |
| "} foo_t;\n"}, | |
| {// With comments on same line as enum value | |
| "typedef enum logic\t{ A=0, // foo\n" | |
| "B,// bar\n" | |
| "`ifndef DO_PANIC\n" | |
| "C=42,// answer\n" | |
| "`endif\n" | |
| "D=3 // baz\n" | |
| "}foo_t;", | |
| "typedef enum logic {\n" | |
| " A = 0, // foo\n" | |
| " B, // bar\n" | |
| "`ifndef DO_PANIC\n" | |
| " C = 42, // answer\n" | |
| "`endif\n" | |
| " D = 3 // baz\n" | |
| "} foo_t;\n"}, | |
| {// with scalar dimensions | |
| "typedef enum logic[2]\t{ A=0, B=1 }foo_t;", | |
| "typedef enum logic [2] {\n" | |
| " A = 0,\n" | |
| " B = 1\n" | |
| "} foo_t;\n"}, | |
| {// with range dimensions | |
| "typedef enum logic[1:0]\t{ A=0, B=1 }foo_t;", | |
| "typedef enum logic [1:0] {\n" | |
| " A = 0,\n" | |
| " B = 1\n" | |
| "} foo_t;\n"}, | |
| {"typedef foo_pkg::baz_t#(.L(L), .W(W)) bar_t;\n", | |
| "typedef foo_pkg::baz_t#(\n" | |
| " .L(L),\n" | |
| " .W(W)\n" | |
| ") bar_t;\n"}, | |
| // package test cases | |
| {"package fedex;localparam int www=3 ;endpackage : fedex\n", | |
| "package fedex;\n" | |
| " localparam int www = 3;\n" | |
| "endpackage : fedex\n"}, | |
| {"package typey ;" | |
| "typedef enum int{ A=0, B=1 }foo_t;" | |
| "typedef enum{ C=0, D=1 }bar_t;" | |
| "endpackage:typey\n", | |
| "package typey;\n" | |
| " typedef enum int {\n" | |
| " A = 0,\n" | |
| " B = 1\n" | |
| " } foo_t;\n" | |
| " typedef enum {\n" | |
| " C = 0,\n" | |
| " D = 1\n" | |
| " } bar_t;\n" | |
| "endpackage : typey\n"}, | |
| {"package foo_pkg; \n" | |
| "// function description.......\n" | |
| "function automatic void bar();" | |
| "endfunction " | |
| "endpackage\n", | |
| "package foo_pkg;\n" | |
| " // function description.......\n" | |
| " function automatic void bar();\n" | |
| " endfunction\n" | |
| "endpackage\n"}, | |
| {"package foo_pkg; \n" | |
| "// function description.......\n" | |
| "function void bar(string name=\"x\" ) ;" | |
| "endfunction " | |
| "endpackage\n", | |
| "package foo_pkg;\n" | |
| " // function description.......\n" | |
| " function void bar(string name = \"x\");\n" | |
| " endfunction\n" | |
| "endpackage\n"}, | |
| {" package foo_pkg; \n" | |
| "// class description.............\n" | |
| "class classy;" | |
| "endclass " | |
| "endpackage\n", | |
| "package foo_pkg;\n" | |
| " // class description.............\n" | |
| " class classy;\n" | |
| " endclass\n" | |
| "endpackage\n"}, | |
| {"package\tfoo_pkg; \n" | |
| "// class description.............\n" | |
| "class classy; \n" | |
| "// function description.......\n" | |
| "function\nautomatic void bar( );" | |
| "endfunction " | |
| "endclass\t" | |
| "endpackage\n", | |
| "package foo_pkg;\n" | |
| " // class description.............\n" | |
| " class classy;\n" | |
| " // function description.......\n" | |
| " function automatic void bar();\n" | |
| " endfunction\n" | |
| " endclass\n" | |
| "endpackage\n"}, | |
| // function test cases | |
| {"function f ;endfunction", "function f;\nendfunction\n"}, | |
| {"function f ;endfunction: f", "function f;\nendfunction : f\n"}, | |
| {"function f ( );endfunction", "function f();\nendfunction\n"}, | |
| {"function f (input bit x);endfunction", | |
| "function f(input bit x);\nendfunction\n"}, | |
| {"function f (input bit x,logic y );endfunction", | |
| "function f(input bit x, logic y);\nendfunction\n"}, | |
| {"function f;\n// statement comment\nendfunction\n", | |
| "function f;\n" | |
| " // statement comment\n" // indented | |
| "endfunction\n"}, | |
| {"function f();\n// statement comment\nendfunction\n", | |
| "function f();\n" | |
| " // statement comment\n" // indented | |
| "endfunction\n"}, | |
| {"function f(input int x);\n" | |
| "// statement comment\n" | |
| "f=x;\n" | |
| "// statement comment\n" | |
| "endfunction\n", | |
| "function f(input int x);\n" | |
| " // statement comment\n" // indented | |
| " f = x;\n" | |
| " // statement comment\n" // indented | |
| "endfunction\n"}, | |
| {// line breaks around assignments | |
| "function f;a=b;c+=d;endfunction", | |
| "function f;\n" | |
| " a = b;\n" | |
| " c += d;\n" | |
| "endfunction\n"}, | |
| {"function f;a&=b;c=d;endfunction", | |
| "function f;\n" | |
| " a &= b;\n" | |
| " c = d;\n" | |
| "endfunction\n"}, | |
| {"function f;a<<=b;c=b;d>>>=b;endfunction", | |
| "function f;\n" | |
| " a <<= b;\n" | |
| " c = b;\n" | |
| " d >>>= b;\n" | |
| "endfunction\n"}, | |
| {// port declaration exceeds line length limit | |
| "function f (loooong_type if_it_fits_I_sits);endfunction", | |
| "function f(\n" | |
| " loooong_type if_it_fits_I_sits);\n" | |
| "endfunction\n"}, | |
| {"function\nvoid\tspace;a=( b+c )\n;endfunction :space\n", | |
| "function void space;\n" | |
| " a = (b + c);\n" | |
| "endfunction : space\n"}, | |
| {"function\nvoid\twarranty;return to_sender\n;endfunction :warranty\n", | |
| "function void warranty;\n" | |
| " return to_sender;\n" | |
| "endfunction : warranty\n"}, | |
| {// if statement that fits on one line | |
| "function if_i_fits_i_sits;" | |
| "if(x)y=x;" | |
| "endfunction", | |
| "function if_i_fits_i_sits;\n" | |
| " if (x) y = x;\n" | |
| "endfunction\n"}, | |
| {// for loop | |
| "function\nvoid\twarranty;for(j=0; j<k; --k)begin " | |
| "++j\n;end endfunction :warranty\n", | |
| "function void warranty;\n" | |
| " for (j = 0; j < k; --k) begin\n" | |
| " ++j;\n" | |
| " end\n" | |
| "endfunction : warranty\n"}, | |
| {// for loop that needs wrapping | |
| "function\nvoid\twarranty;for(jjjjj=0; jjjjj<kkkkk; --kkkkk)begin " | |
| "++j\n;end endfunction :warranty\n", | |
| "function void warranty;\n" | |
| " for (\n" | |
| " jjjjj = 0; jjjjj < kkkkk; --kkkkk\n" | |
| " ) begin\n" | |
| " ++j;\n" | |
| " end\n" | |
| "endfunction : warranty\n"}, | |
| {// for loop that needs more wrapping | |
| "function\nvoid\twarranty;" | |
| "for(jjjjjjjj=0; jjjjjjjj<kkkkkkkk; --kkkkkkkk)begin " | |
| "++j\n;end endfunction :warranty\n", | |
| "function void warranty;\n" | |
| " for (\n" | |
| " jjjjjjjj = 0;\n" | |
| " jjjjjjjj < kkkkkkkk;\n" | |
| " --kkkkkkkk\n" | |
| " ) begin\n" | |
| " ++j;\n" | |
| " end\n" | |
| "endfunction : warranty\n"}, | |
| {// for loop that fits on one line | |
| "function loop_fits;" | |
| "for(x=0;x<N;++x) y=x;" | |
| "endfunction", | |
| "function loop_fits;\n" | |
| " for (x = 0; x < N; ++x) y = x;\n" | |
| "endfunction\n"}, | |
| {// for loop that would fit on one line, but is force-split with //comment | |
| "function loop_fits;" | |
| "for(x=0;x<N;++x) //\n y=x;" | |
| "endfunction", | |
| "function loop_fits;\n" | |
| " for (x = 0; x < N; ++x) //\n" | |
| " y = x;\n" | |
| "endfunction\n"}, | |
| {// forever loop | |
| "function\nvoid\tforevah;forever begin " | |
| "++k\n;end endfunction\n", | |
| "function void forevah;\n" | |
| " forever begin\n" | |
| " ++k;\n" | |
| " end\n" | |
| "endfunction\n"}, | |
| {// forever loop | |
| "function\nvoid\tforevah;forever " | |
| "++k\n;endfunction\n", | |
| "function void forevah;\n" | |
| " forever ++k;\n" | |
| "endfunction\n"}, | |
| {// forever loop, forced break | |
| "function\nvoid\tforevah;forever //\n" | |
| "++k\n;endfunction\n", | |
| "function void forevah;\n" | |
| " forever //\n" | |
| " ++k;\n" | |
| "endfunction\n"}, | |
| {// repeat loop | |
| "function\nvoid\tpete;repeat(3) begin " | |
| "++k\n;end endfunction\n", | |
| "function void pete;\n" | |
| " repeat (3) begin\n" | |
| " ++k;\n" | |
| " end\n" | |
| "endfunction\n"}, | |
| {// repeat loop | |
| "function\nvoid\tpete;repeat(3) " | |
| "++k\n;endfunction\n", | |
| "function void pete;\n" | |
| " repeat (3)++k;\n" // TODO(fangism): space before ++ | |
| "endfunction\n"}, | |
| {// repeat loop, forced break | |
| "function\nvoid\tpete;repeat(3)//\n" | |
| "++k\n;endfunction\n", | |
| "function void pete;\n" | |
| " repeat (3) //\n" | |
| " ++k;\n" | |
| "endfunction\n"}, | |
| {// while loop | |
| "function\nvoid\twily;while( coyote ) begin " | |
| "++super_genius\n;end endfunction\n", | |
| "function void wily;\n" | |
| " while (coyote) begin\n" | |
| " ++super_genius;\n" | |
| " end\n" | |
| "endfunction\n"}, | |
| {// while loop | |
| "function\nvoid\twily;while( coyote ) " | |
| "++ super_genius\n; endfunction\n", | |
| "function void wily;\n" | |
| " while (coyote)++super_genius;\n" // TODO(fangism): space before ++ | |
| "endfunction\n"}, | |
| {// while loop, forced break | |
| "function\nvoid\twily;while( coyote ) //\n " | |
| "++ super_genius\n; endfunction\n", | |
| "function void wily;\n" | |
| " while (coyote) //\n" | |
| " ++super_genius;\n" | |
| "endfunction\n"}, | |
| {// do-while loop | |
| "function\nvoid\tdonot;do begin " | |
| "++s\n;end while( z);endfunction\n", | |
| "function void donot;\n" | |
| " do begin\n" | |
| " ++s;\n" | |
| " end while (z);\n" | |
| "endfunction\n"}, | |
| {// do-while loop, single statement | |
| "function\nvoid\tdonot;do " | |
| "++s\n; while( z);endfunction\n", | |
| "function void donot;\n" | |
| " do ++s; while (z);\n" | |
| "endfunction\n"}, | |
| {// do-while loop, single statement, forced break | |
| "function\nvoid\tdonot;do " | |
| "++s\n;//\n while( z);endfunction\n", | |
| "function void donot;\n" | |
| " do\n" | |
| " ++s; //\n" | |
| " while (z);\n" | |
| "endfunction\n"}, | |
| {// foreach loop | |
| "function\nvoid\tforeacher;foreach( m [n] ) begin " | |
| "++m\n;end endfunction\n", | |
| "function void foreacher;\n" | |
| " foreach (m[n]) begin\n" | |
| " ++m;\n" | |
| " end\n" | |
| "endfunction\n"}, | |
| {// spaces in ternary expression | |
| "function f; return {a}? {b} :{ c };endfunction", | |
| "function f;\n" | |
| " return {a} ? {b} : {c};\n" | |
| "endfunction\n"}, | |
| {"task t;endtask", | |
| "task t;\n" | |
| "endtask\n"}, | |
| {"task t ( );endtask", | |
| "task t();\n" | |
| "endtask\n"}, | |
| {"task t (input bit drill ) ;endtask", | |
| "task t(input bit drill);\n" | |
| "endtask\n"}, | |
| {"task t; ## 100 ;endtask", | |
| "task t;\n" | |
| " ##100;\n" | |
| "endtask\n"}, | |
| {"task t; ## (1+1) ;endtask", // delay expression | |
| "task t;\n" | |
| " ##(1 + 1);\n" | |
| "endtask\n"}, | |
| {"task t; ## delay_value ;endtask", | |
| "task t;\n" | |
| " ##delay_value;\n" | |
| "endtask\n"}, | |
| {"task t; ## `DELAY_VALUE ;endtask", | |
| "task t;\n" | |
| " ##`DELAY_VALUE;\n" | |
| "endtask\n"}, | |
| {"task t;\n" | |
| "`uvm_error( foo,bar);\n" | |
| "endtask\n", | |
| "task t;\n" | |
| " `uvm_error(foo, bar);\n" | |
| "endtask\n"}, | |
| {"task t;\n" | |
| "`uvm_error(foo,bar)\n" | |
| ";\n" // null statement | |
| "endtask\n", | |
| "task t;\n" | |
| " `uvm_error(foo, bar)\n" | |
| " ;\n" | |
| "endtask\n"}, | |
| {"task t;\n" | |
| "if(expr)begin\t\n" | |
| "`uvm_error(foo,bar);\n" | |
| "end\n" | |
| "endtask\n", | |
| "task t;\n" | |
| " if (expr) begin\n" | |
| " `uvm_error(foo, bar);\n" | |
| " end\n" | |
| "endtask\n"}, | |
| {"task\nrabbit;$kill(the,\nrabbit)\n;endtask: rabbit\n", | |
| "task rabbit;\n" | |
| " $kill(the, rabbit);\n" | |
| "endtask : rabbit\n"}, | |
| {"function int foo( );if( a )a+=1 ; endfunction", | |
| "function int foo();\n" | |
| " if (a) a += 1;\n" | |
| "endfunction\n"}, | |
| {"function void foo( );foo=`MACRO(b,c) ; endfunction", | |
| "function void foo();\n" | |
| " foo = `MACRO(b, c);\n" | |
| "endfunction\n"}, | |
| {"module foo;if \t (bar)begin assign a=1; end endmodule", | |
| "module foo;\n" | |
| " if (bar) begin\n" | |
| " assign a = 1;\n" | |
| " end\n" | |
| "endmodule\n"}, | |
| {"module proc_cont_assigner;\n" | |
| "always begin\n" | |
| "assign x1 = y1;\n" | |
| "deassign x2 ;\n" | |
| "force x3=y3;\n" | |
| "release x4 ;\n" | |
| "end\n" | |
| "endmodule\n", | |
| "module proc_cont_assigner;\n" | |
| " always begin\n" | |
| " assign x1 = y1;\n" | |
| " deassign x2;\n" | |
| " force x3 = y3;\n" | |
| " release x4;\n" | |
| " end\n" | |
| "endmodule\n"}, | |
| {"module g_test( );\n" | |
| "\tinitial begin:main_test \t" | |
| "for(int i=0;i<k;i++)begin " | |
| "case(i )\n" | |
| " 6'd0 :release in[0]; \n" | |
| " endcase " | |
| " \t\tend \t" | |
| "\t end:main_test\n" | |
| "endmodule:g_test\n", | |
| "module g_test ();\n" | |
| " initial begin : main_test\n" | |
| " for (int i = 0; i < k; i++) begin\n" | |
| " case (i)\n" | |
| " 6'd0: release in[0];\n" | |
| " endcase\n" | |
| " end\n" | |
| " end : main_test\n" | |
| "endmodule : g_test\n"}, | |
| {// conditional generate (case) | |
| "module mc; case(s)a : bb c ; d : ee f; endcase endmodule", | |
| "module mc;\n" | |
| " case (s)\n" | |
| " a: bb c;\n" | |
| " d: ee f;\n" | |
| " endcase\n" | |
| "endmodule\n"}, | |
| {// "default:", not "default :" | |
| "function f; case (x) default: x=y; endcase endfunction\n", | |
| "function f;\n" | |
| " case (x)\n" | |
| " default: x = y;\n" | |
| " endcase\n" | |
| "endfunction\n"}, | |
| {// default with null statement: "default: ;", not "default :;" | |
| "function f; case (x) default :; endcase endfunction\n", | |
| "function f;\n" | |
| " case (x)\n" | |
| " default: ;\n" | |
| " endcase\n" | |
| "endfunction\n"}, | |
| {// case statement | |
| "function f; case (x) State0 : a=b; State1 : begin a=b; end " | |
| "endcase endfunction\n", | |
| "function f;\n" | |
| " case (x)\n" | |
| " State0: a = b;\n" | |
| " State1: begin\n" | |
| " a = b;\n" | |
| " end\n" | |
| " endcase\n" | |
| "endfunction\n"}, | |
| {// case statement, interleaved with comments | |
| "function f; case (x) \n//c1\nState0 : a=b;//c2\n//c3\n State1 : " | |
| "a=b;//c4\n//c5\n " | |
| "endcase endfunction\n", | |
| "function f;\n" | |
| " case (x)\n" | |
| " //c1\n" | |
| " State0: a = b; //c2\n" | |
| " //c3\n" | |
| " State1: a = b; //c4\n" | |
| " //c5\n" | |
| " endcase\n" | |
| "endfunction\n"}, | |
| {// case inside statement | |
| "function f; case (x)inside k1 : return b; k2 : begin return b; end " | |
| "endcase endfunction\n", | |
| "function f;\n" | |
| " case (x) inside\n" | |
| " k1: return b;\n" | |
| " k2: begin\n" | |
| " return b;\n" | |
| " end\n" | |
| " endcase\n" | |
| "endfunction\n"}, | |
| {// case inside statement, with ranges | |
| "function f; case (x) inside[a:b] : return b; [c:d] : return b; " | |
| "default :return z;" | |
| "endcase endfunction\n", | |
| "function f;\n" | |
| " case (x) inside\n" | |
| " [a : b]: return b;\n" | |
| " [c : d]: return b;\n" | |
| " default: return z;\n" | |
| " endcase\n" | |
| "endfunction\n"}, | |
| {// case pattern statement | |
| "function f;" | |
| "case (y) matches " | |
| ".foo : return 0;" | |
| ".*\t: return 1;" | |
| "endcase " | |
| "case (z) matches " | |
| ".foo\t\t: return 0;" | |
| ".* : return 1;" | |
| "endcase " | |
| "endfunction", | |
| "function f;\n" | |
| " case (y) matches\n" | |
| " .foo: return 0;\n" | |
| " .*: return 1;\n" | |
| " endcase\n" | |
| " case (z) matches\n" | |
| " .foo: return 0;\n" | |
| " .*: return 1;\n" | |
| " endcase\n" | |
| "endfunction\n"}, | |
| {// keep short case items on one line | |
| "function f; case (x)k1 : if( b )break; default :return 2;" | |
| "endcase endfunction\n", | |
| "function f;\n" | |
| " case (x)\n" | |
| " k1: if (b) break;\n" // aligned | |
| " default: return 2;\n" | |
| " endcase\n" | |
| "endfunction\n"}, | |
| {// keep short default items on one line | |
| "function f; case (x)k1 :break; default :if( c )return 2;" | |
| "endcase endfunction\n", | |
| "function f;\n" | |
| " case (x)\n" | |
| " k1: break;\n" // aligned | |
| " default: if (c) return 2;\n" | |
| " endcase\n" | |
| "endfunction\n"}, | |
| {// keep short case inside items on one line | |
| "function f; case (x)inside k1 : if( b )return c; k2 : return a;" | |
| "endcase endfunction\n", | |
| "function f;\n" | |
| " case (x) inside\n" | |
| " k1: if (b) return c;\n" | |
| " k2: return a;\n" | |
| " endcase\n" | |
| "endfunction\n"}, | |
| {// keep short case pattern items on one line | |
| "function f;" | |
| "case (y) matches " | |
| ".foo :if( n )return 0;" | |
| ".*\t: return 1;" | |
| "endcase " | |
| "endfunction", | |
| "function f;\n" | |
| " case (y) matches\n" | |
| " .foo: if (n) return 0;\n" | |
| " .*: return 1;\n" | |
| " endcase\n" | |
| "endfunction\n"}, | |
| {// randcase | |
| "function f; randcase k1 : return c; k2 : return a;" | |
| "endcase endfunction\n", | |
| "function f;\n" | |
| " randcase\n" | |
| " k1: return c;\n" | |
| " k2: return a;\n" | |
| " endcase\n" | |
| "endfunction\n"}, | |
| // This tests checks for not breaking around hierarchy operators. | |
| {"function\nvoid\twarranty;" | |
| "foo.bar = fancyfunction(aaaaaaaa.bbbbbbb," | |
| " ccccccccc.ddddddddd) ;" | |
| "endfunction :warranty\n", | |
| "function void warranty;\n" | |
| " foo.bar = fancyfunction(\n" | |
| " aaaaaaaa.bbbbbbb,\n" | |
| " ccccccccc.ddddddddd\n" | |
| " );\n" | |
| "endfunction : warranty\n"}, | |
| // Group of tests testing partitioning of arguments inside function calls | |
| {// function with function call inside if statement header | |
| "function foo;if(aa(bb,cc));endfunction\n", | |
| "function foo;\n" | |
| " if (aa(bb, cc));\n" | |
| "endfunction\n"}, | |
| {// function with function call inside if statement header and with | |
| // begin-end block | |
| "function foo;if (aa(bb,cc,dd,ee))begin end endfunction\n", | |
| "function foo;\n" | |
| " if (aa(bb, cc, dd, ee)) begin\n" | |
| " end\n" | |
| "endfunction\n"}, | |
| {// function with kMethodCallExtension inside if statement header and with | |
| // begin-end block | |
| "function foo;if (aa.bb(cc,dd,ee))begin end endfunction\n", | |
| "function foo;\n" | |
| " if (aa.bb(cc, dd, ee)) begin\n" | |
| " end\n" | |
| "endfunction\n"}, | |
| {// nested kMethodCallExtension calls - one level | |
| "function foo;aa.bb(cc.dd(a1), ee.ff(a2));endfunction\n", | |
| "function foo;\n" | |
| " aa.bb(cc.dd(a1), ee.ff(a2));\n" | |
| "endfunction\n"}, | |
| {// nested kMethodCallExtension calls - two level | |
| "function foo;aa.bb(cc.dd(a1.b1(a2), b1), ee.ff(c1, d1));endfunction\n", | |
| "function foo;\n" | |
| " aa.bb(cc.dd(a1.b1(a2), b1), ee.ff(\n" | |
| " c1, d1));\n" | |
| "endfunction\n"}, | |
| {// simple initial statement with function call | |
| "module m;initial aa(bb,cc,dd,ee);endmodule\n", | |
| "module m;\n" | |
| " initial aa(bb, cc, dd, ee);\n" | |
| "endmodule\n"}, | |
| {// expressions and function calls inside if-statement headers | |
| "module m;initial begin if(aa(bb)==cc(dd))a=b;if (xx()) b = a;end " | |
| "endmodule\n", | |
| "module m;\n" | |
| " initial begin\n" | |
| " if (aa(bb) == cc(dd)) a = b;\n" | |
| " if (xx()) b = a;\n" | |
| " end\n" | |
| "endmodule\n"}, | |
| {// fuction with two arguments inside if-statement headers | |
| "module\nm;initial\nbegin\nif(aa(bb,cc))x=y;end\nendmodule\n", | |
| "module m;\n" | |
| " initial begin\n" | |
| " if (aa(bb, cc)) x = y;\n" | |
| " end\n" | |
| "endmodule\n"}, | |
| {// kMethodCallExtension inside if-statement headers | |
| "module m;initial begin if (aa.bb(cc)) x = y;end endmodule", | |
| "module m;\n" | |
| " initial begin\n" | |
| " if (aa.bb(cc)) x = y;\n" | |
| " end\n" | |
| "endmodule\n"}, | |
| {// initial statement with object method call | |
| "module m; initial a.b(a,b,c); endmodule\n", | |
| "module m;\n" | |
| " initial a.b(a, b, c);\n" | |
| "endmodule\n"}, | |
| {// initial statement with method call on indexed object | |
| "module m; initial a[i].b(a,b,c); endmodule\n", | |
| "module m;\n" | |
| " initial a[i].b(a, b, c);\n" | |
| "endmodule\n"}, | |
| {// initial statement with method call on function returned object | |
| "module m; initial a(d,e,f).b(a,b,c); endmodule\n", | |
| "module m;\n" | |
| " initial a(d, e, f).b(a, b, c);\n" | |
| "endmodule\n"}, | |
| {// initial statement with indexed access to function returned object | |
| "module m; initial a(a,b,c)[i]; endmodule\n", | |
| "module m;\n" | |
| " initial a(a, b, c) [i];\n" | |
| "endmodule\n"}, | |
| {// method call with no arguments on an object | |
| "module m; initial foo.bar();endmodule\n", | |
| "module m;\n" | |
| " initial foo.bar();\n" | |
| "endmodule\n"}, | |
| {// method call with one argument on an object | |
| "module m; initial foo.bar(aa);endmodule\n", | |
| "module m;\n" | |
| " initial foo.bar(aa);\n" | |
| "endmodule\n"}, | |
| {// method call with two arguments on an object | |
| "module m; initial foo.bar(aa,bb);endmodule\n", | |
| "module m;\n" | |
| " initial foo.bar(aa, bb);\n" | |
| "endmodule\n"}, | |
| {// method call with three arguments on an object | |
| "module m; initial foo.bar(aa,bb,cc);endmodule\n", | |
| "module m;\n" | |
| " initial foo.bar(aa, bb, cc);\n" | |
| "endmodule\n"}, | |
| { | |
| // This tests for if-statements with null statements | |
| "function foo;" | |
| "if (zz) ; " | |
| "if (yy) ; " | |
| "endfunction", | |
| "function foo;\n" | |
| " if (zz);\n" | |
| " if (yy);\n" | |
| "endfunction\n", | |
| }, | |
| { | |
| // This tests for if-statements starting on their own line. | |
| "function foo;" | |
| "if (zz) begin " | |
| "return 0;" | |
| "end " | |
| "if (yy) begin " | |
| "return 1;" | |
| "end " | |
| "endfunction", | |
| "function foo;\n" | |
| " if (zz) begin\n" | |
| " return 0;\n" | |
| " end\n" | |
| " if (yy) begin\n" | |
| " return 1;\n" | |
| " end\n" | |
| "endfunction\n", | |
| }, | |
| { | |
| // This tests for if-statements with single statement bodies | |
| "function foo;" | |
| "if (zz) return 0;" | |
| "if (yy) return 1;" | |
| "endfunction", | |
| "function foo;\n" | |
| " if (zz) return 0;\n" | |
| " if (yy) return 1;\n" | |
| "endfunction\n", | |
| }, | |
| { | |
| // This tests for if-statement mixed with plain statements | |
| "function foo;" | |
| "a=b;" | |
| "if (zz) return 0;" | |
| "c=d;" | |
| "endfunction", | |
| "function foo;\n" | |
| " a = b;\n" | |
| " if (zz) return 0;\n" | |
| " c = d;\n" | |
| "endfunction\n", | |
| }, | |
| { | |
| // This tests for if-statement with forced break mixed with others | |
| "function foo;" | |
| "a=b;" | |
| "if (zz)//\n return 0;" | |
| "c=d;" | |
| "endfunction", | |
| "function foo;\n" | |
| " a = b;\n" | |
| " if (zz) //\n" | |
| " return 0;\n" | |
| " c = d;\n" | |
| "endfunction\n", | |
| }, | |
| { | |
| "function t;" | |
| "if (r == t)" | |
| "a.b(c);" | |
| "endfunction", | |
| "function t;\n" | |
| " if (r == t) a.b(c);\n" | |
| "endfunction\n", | |
| }, | |
| {// This tests for for-statement with forced break mixed with others | |
| "function f;" | |
| "x=y;" | |
| "for (int i=0; i<S*IPS; i++) #1ps a += $urandom();" | |
| "return 2;" | |
| "endfunction", | |
| "function f;\n" | |
| " x = y;\n" | |
| " for (int i = 0; i < S * IPS; i++)\n" // doesn't fit, so indents | |
| " #1ps a += $urandom();\n" | |
| " return 2;\n" | |
| "endfunction\n"}, | |
| { | |
| // This tests for-statements with null statements | |
| "function foo;" | |
| "for(;;) ;\t" | |
| "for(;;) ;\t" | |
| "endfunction", | |
| "function foo;\n" | |
| " for (;;);\n" | |
| " for (;;);\n" | |
| "endfunction\n", | |
| }, | |
| { | |
| // This tests for if-else-statements with null statements | |
| "function foo;" | |
| "if (zz) ; else ;" | |
| "if (yy) ; else ;" | |
| "endfunction", | |
| "function foo;\n" | |
| " if (zz);\n" | |
| " else;\n" | |
| " if (yy);\n" | |
| " else;\n" | |
| "endfunction\n", | |
| }, | |
| { | |
| // This tests for end-else-begin. | |
| "function foo;" | |
| "if (zz) begin " | |
| "return 0;" | |
| "end " | |
| "else " | |
| "begin " | |
| "return 1;" | |
| "end " | |
| "endfunction", | |
| "function foo;\n" | |
| " if (zz) begin\n" | |
| " return 0;\n" | |
| " end else begin\n" | |
| " return 1;\n" | |
| " end\n" | |
| "endfunction\n", | |
| }, | |
| { | |
| // This tests for end-else-if | |
| "function foo;" | |
| "if (zz) begin " | |
| "return 0;" | |
| "end " | |
| "else " | |
| "if(yy)begin " | |
| "return 1;" | |
| "end " | |
| "endfunction", | |
| "function foo;\n" | |
| " if (zz) begin\n" | |
| " return 0;\n" | |
| " end else if (yy) begin\n" | |
| " return 1;\n" | |
| " end\n" | |
| "endfunction\n", | |
| }, | |
| { | |
| // This tests labeled end-else-if | |
| "function foo;" | |
| "if (zz) begin : label1 " | |
| "return 0;" | |
| "end : label1 " | |
| "else if (yy) begin : label2 " | |
| "return 1;" | |
| "end : label2 " | |
| "endfunction", | |
| "function foo;\n" | |
| " if (zz) begin : label1\n" | |
| " return 0;\n" | |
| " end : label1\n" | |
| " else if (yy) begin : label2\n" | |
| " return 1;\n" | |
| " end : label2\n" | |
| "endfunction\n", | |
| }, | |
| { | |
| // This tests labeled end-else-if-else | |
| "function foo;" | |
| "if (zz) begin : label1 " | |
| "return 0;" | |
| "end : label1 " | |
| "else if (yy) begin : label2 " | |
| "return 1;" | |
| "end : label2 " | |
| "else begin : label3 " | |
| "return 2;" | |
| "end : label3 " | |
| "endfunction", | |
| "function foo;\n" | |
| " if (zz) begin : label1\n" | |
| " return 0;\n" | |
| " end : label1\n" | |
| " else if (yy) begin : label2\n" | |
| " return 1;\n" | |
| " end : label2\n" | |
| " else begin : label3\n" | |
| " return 2;\n" | |
| " end : label3\n" | |
| "endfunction\n", | |
| }, | |
| { | |
| // randomize function | |
| "function r ;" | |
| "if ( ! randomize (bar )) begin end " | |
| "if ( ! obj.randomize (bar )) begin end " | |
| "endfunction", | |
| "function r;\n" | |
| " if (!randomize(bar)) begin\n" | |
| " end\n" | |
| " if (!obj.randomize(bar)) begin\n" | |
| " end\n" | |
| "endfunction\n", | |
| }, | |
| { | |
| // randomize-with call, with comments | |
| "function f;" | |
| "s = std::randomize() with {\n" | |
| "// comment1\n" | |
| "a == e;\n" | |
| "// comment2\n" | |
| "};" | |
| "endfunction\n", | |
| "function f;\n" | |
| " s = std::randomize() with {\n" | |
| " // comment1\n" | |
| " a == e;\n" | |
| " // comment2\n" | |
| " };\n" | |
| "endfunction\n", | |
| }, | |
| { | |
| // randomize-with call, with comments, one joined | |
| "function f;" | |
| "s = std::randomize() with {\n" | |
| "// comment1\n" | |
| "a == e;// comment2\n" | |
| "};" | |
| "endfunction\n", | |
| "function f;\n" | |
| " s = std::randomize() with {\n" | |
| " // comment1\n" | |
| " a == e; // comment2\n" | |
| " };\n" | |
| "endfunction\n", | |
| }, | |
| { | |
| // randomize-with call, with comment, and conditional | |
| "function f;" | |
| "s = std::randomize() with {\n" | |
| "// comment\n" | |
| "a == e;" | |
| "if (x) {" | |
| "a;" | |
| "}" | |
| "};" | |
| "endfunction\n", | |
| "function f;\n" | |
| " s = std::randomize() with {\n" | |
| " // comment\n" | |
| " a == e;\n" | |
| " if (x) {a;}\n" // TODO(fangism): consider expanding | |
| " };\n" | |
| "endfunction\n", | |
| }, | |
| // module declaration test cases | |
| {" module foo ; endmodule\n", | |
| "module foo;\n" | |
| "endmodule\n"}, | |
| {" module foo ( ) ; endmodule\n", | |
| "module foo ();\n" | |
| "endmodule\n"}, | |
| {" module foo ( .x ( x) ); endmodule\n", | |
| "module foo (\n" | |
| " .x(x)\n" | |
| ");\n" | |
| "endmodule\n"}, | |
| {" module foo ( .x ( x) \n,\n . y " | |
| " ( \ny) ); endmodule\n", | |
| "module foo (\n" | |
| " .x(x),\n" | |
| " .y(y)\n" | |
| ");\n" | |
| "endmodule\n"}, | |
| // module instantiation test cases | |
| {" module foo ; bar bq();endmodule\n", | |
| "module foo;\n" | |
| " bar bq ();\n" // single instance | |
| "endmodule\n"}, | |
| {" module foo ; bar bq(), bq2( );endmodule\n", | |
| "module foo;\n" | |
| " bar bq (), bq2 ();\n" // multiple instances, still fitting on one line | |
| "endmodule\n"}, | |
| {"module foo; bar #(.N(N)) bq (.bus(bus));endmodule\n", | |
| // instance parameter and port fits on line | |
| "module foo;\n" | |
| " bar #(.N(N)) bq (.bus(bus));\n" | |
| "endmodule\n"}, | |
| {"module foo; bar #(.N(N),.M(M)) bq ();endmodule\n", // two named params | |
| "module foo;\n" | |
| " bar #(\n" | |
| " .N(N),\n" | |
| " .M(M)\n" | |
| " ) bq ();\n" | |
| "endmodule\n"}, | |
| {"module foo; bar #(//comment\n.N(N),.M(M)) bq ();endmodule\n", | |
| "module foo;\n" | |
| " bar #( //comment\n" // EOL comment before first param | |
| " .N(N),\n" | |
| " .M(M)\n" | |
| " ) bq ();\n" | |
| "endmodule\n"}, | |
| {"module foo; bar #(.N(N),//comment\n.M(M)) bq ();endmodule\n", | |
| "module foo;\n" | |
| " bar #(\n" | |
| " .N(N), //comment\n" // EOL comment after first param | |
| " .M(M)\n" | |
| " ) bq ();\n" | |
| "endmodule\n"}, | |
| {"module foo; bar #(.N(N),.M(M)//comment\n) bq ();endmodule\n", | |
| "module foo;\n" | |
| " bar #(\n" | |
| " .N(N),\n" | |
| " .M(M) //comment\n" // EOL comment after last param | |
| " ) bq ();\n" | |
| "endmodule\n"}, | |
| {" module foo ; bar bq(aa,bb,cc);endmodule\n", | |
| "module foo;\n" | |
| " bar bq (\n" | |
| " aa,\n" | |
| " bb,\n" | |
| " cc\n" | |
| " );\n" // multiple positional ports, one per line | |
| "endmodule\n"}, | |
| {" module foo ; bar bq(aa,\n" | |
| "`ifdef BB\n" | |
| "bb,\n" | |
| "`endif\n" | |
| "cc);endmodule\n", | |
| "module foo;\n" | |
| " bar bq (\n" | |
| " aa,\n" | |
| "`ifdef BB\n" | |
| " bb,\n" // keep same indentation as outside conditional | |
| "`endif\n" | |
| " cc\n" | |
| " );\n" // multiple positional ports, one per line | |
| "endmodule\n"}, | |
| {" module foo ; bar bq(.aa,.bb);endmodule\n", | |
| "module foo;\n" | |
| " bar bq (\n" | |
| " .aa,\n" | |
| " .bb\n" | |
| " );\n" // multiple named ports, one per line | |
| "endmodule\n"}, | |
| {" module foo ; bar bq(.aa(aa),.bb(bb));endmodule\n", | |
| "module foo;\n" | |
| " bar bq (\n" | |
| " .aa(aa),\n" | |
| " .bb(bb)\n" | |
| " );\n" // multiple named ports, one per line | |
| "endmodule\n"}, | |
| {" module foo ; bar bq(.aa(aa),\n" | |
| "`ifdef ZZ\n" | |
| ".zz( zz ),\n" | |
| "`else\n" | |
| ".yy( yy ),\n" | |
| "`endif\n" | |
| ".bb(bb)\n" | |
| ");endmodule\n", | |
| "module foo;\n" | |
| " bar bq (\n" | |
| " .aa(aa),\n" | |
| "`ifdef ZZ\n" | |
| " .zz(zz),\n" | |
| "`else\n" | |
| " .yy(yy),\n" | |
| "`endif\n" | |
| " .bb(bb)\n" | |
| " );\n" // multiple named ports, one per line | |
| "endmodule\n"}, | |
| {" module foo ; bar#(NNNNNNNN)" | |
| "bq(.aa(aaaaaa),.bb(bbbbbb));endmodule\n", | |
| "module foo;\n" | |
| " bar #(NNNNNNNN) bq (\n" | |
| " .aa(aaaaaa),\n" | |
| " .bb(bbbbbb)\n" | |
| " );\n" | |
| "endmodule\n"}, | |
| {" module foo ; barrrrrrr " | |
| "bq(.aaaaaa(aaaaaa),.bbbbbb(bbbbbb));endmodule\n", | |
| "module foo;\n" | |
| " barrrrrrr bq (\n" | |
| " .aaaaaa(aaaaaa),\n" | |
| " .bbbbbb(bbbbbb)\n" | |
| " );\n" | |
| "endmodule\n"}, | |
| {"module foo; bar #(.NNNNN(NNNNN)) bq (.bussss(bussss));endmodule\n", | |
| // instance parameter and port does not fit on line | |
| "module foo;\n" | |
| " bar #(\n" | |
| " .NNNNN(NNNNN)\n" | |
| " ) bq (\n" | |
| " .bussss(bussss)\n" | |
| " );\n" | |
| "endmodule\n"}, | |
| {"module foo; bar #(//\n.N(N)) bq (.bus(bus));endmodule\n", | |
| "module foo;\n" | |
| " bar #( //\n" // would fit on one line, but forced to expand by // | |
| " .N(N)\n" | |
| " ) bq (\n" | |
| " .bus(bus)\n" | |
| " );\n" | |
| "endmodule\n"}, | |
| {"module foo; bar #(\n" | |
| "`ifdef MM\n" | |
| ".M(M)\n" | |
| "`else\n" | |
| ".N(N)\n" | |
| "`endif\n" | |
| ") bq (.bus(bus));endmodule\n", | |
| "module foo;\n" | |
| " bar #(\n" | |
| "`ifdef MM\n" | |
| " .M(M)\n" | |
| "`else\n" | |
| " .N(N)\n" | |
| "`endif\n" | |
| " ) bq (\n" | |
| " .bus(bus)\n" | |
| " );\n" | |
| "endmodule\n"}, | |
| {"module foo; bar #(.N(N)//\n) bq (.bus(bus));endmodule\n", | |
| "module foo;\n" | |
| " bar #(\n" // would fit on one line, but forced to expand by // | |
| " .N(N) //\n" | |
| " ) bq (\n" | |
| " .bus(bus)\n" | |
| " );\n" | |
| "endmodule\n"}, | |
| {"module foo; bar #(.N(N)) bq (//\n.bus(bus));endmodule\n", | |
| "module foo;\n" | |
| " bar #(\n" // would fit on one line, but forced to expand by // | |
| " .N(N)\n" | |
| " ) bq ( //\n" | |
| " .bus(bus)\n" | |
| " );\n" | |
| "endmodule\n"}, | |
| {"module foo; bar #(.N(N)) bq (.bus(bus)//\n);endmodule\n", | |
| "module foo;\n" | |
| " bar #(\n" // would fit on one line, but forced to expand by // | |
| " .N(N)\n" | |
| " ) bq (\n" | |
| " .bus(bus) //\n" | |
| " );\n" | |
| "endmodule\n"}, | |
| {" module foo ; bar " | |
| "bq(.aaa(aaa),.bbb(bbb),.ccc(ccc),.ddd(ddd));endmodule\n", | |
| "module foo;\n" | |
| " bar bq (\n" | |
| " .aaa(aaa),\n" // ports don't fit on one line, so expanded | |
| " .bbb(bbb),\n" | |
| " .ccc(ccc),\n" | |
| " .ddd(ddd)\n" | |
| " );\n" | |
| "endmodule\n"}, | |
| {" module foo ; bar " | |
| "bq(.aa(aa),.bb(bb),.cc(cc),.dd(dd));endmodule\n", | |
| "module foo;\n" | |
| " bar bq (\n" | |
| " .aa(aa),\n" // one named port per line | |
| " .bb(bb),\n" | |
| " .cc(cc),\n" | |
| " .dd(dd)\n" | |
| " );\n" | |
| "endmodule\n"}, | |
| {" module foo ; bar " | |
| "bq(.aa(aa),//\n.bb(bb),.cc(cc),.dd(dd));endmodule\n", | |
| "module foo;\n" | |
| " bar bq (\n" | |
| " .aa(aa), //\n" // forced to expand by // | |
| " .bb(bb),\n" | |
| " .cc(cc),\n" | |
| " .dd(dd)\n" | |
| " );\n" | |
| "endmodule\n"}, | |
| {" module foo ; bar " | |
| "bq(.aa(aa),.bb(bb),.cc(cc),.dd(dd)//\n);endmodule\n", | |
| "module foo;\n" | |
| " bar bq (\n" | |
| " .aa(aa),\n" | |
| " .bb(bb),\n" | |
| " .cc(cc),\n" | |
| " .dd(dd) //\n" // forced to expand by // | |
| " );\n" | |
| "endmodule\n"}, | |
| {// gate instantiation test | |
| "module m;" | |
| "and\tx0(a, \t\tb,c);" | |
| "or\nx1(a, \n b, d);" | |
| "endmodule\n", | |
| "module m;\n" | |
| " and x0 (a, b, c);\n" | |
| " or x1 (a, b, d);\n" | |
| "endmodule\n"}, | |
| {// ifdef inside port actuals | |
| "module m; foo bar (\n" | |
| "`ifdef BAZ\n" | |
| "`endif\n" | |
| ") ;endmodule\n", | |
| "module m;\n" | |
| " foo bar (\n" | |
| "`ifdef BAZ\n" | |
| "`endif\n" | |
| " );\n" | |
| "endmodule\n"}, | |
| {// ifdef inside port actuals after a port connection | |
| "module m; foo bar ( .a (a) ,\n" | |
| "`ifdef BAZ\n" | |
| "`endif\n" | |
| ") ;endmodule\n", | |
| "module m;\n" | |
| " foo bar (\n" | |
| " .a(a),\n" | |
| "`ifdef BAZ\n" | |
| "`endif\n" | |
| " );\n" | |
| "endmodule\n"}, | |
| {// ifdef inside port actuals before a port connection | |
| "module m; foo bar (\n" | |
| "`ifdef BAZ\n" | |
| "`endif\n" | |
| ". b(b) ) ;endmodule\n", | |
| "module m;\n" | |
| " foo bar (\n" | |
| "`ifdef BAZ\n" | |
| "`endif\n" | |
| " .b(b)\n" | |
| " );\n" | |
| "endmodule\n"}, | |
| {// ifdef-conditional port connection | |
| "module m; foo bar (\n" | |
| "`ifdef BAZ\n" | |
| ". c (\tc) \n" | |
| "`endif\n" | |
| " ) ;endmodule\n", | |
| "module m;\n" | |
| " foo bar (\n" | |
| "`ifdef BAZ\n" | |
| " .c(c)\n" | |
| "`endif\n" | |
| " );\n" | |
| "endmodule\n"}, | |
| {// ifndef-else-conditional port connection | |
| "module m; foo bar (\n" | |
| "`ifndef BAZ\n" | |
| ". c (\tc) \n" | |
| " `else\n" | |
| " . d(d\t)\n" | |
| " `endif\n" | |
| " ) ;endmodule\n", | |
| "module m;\n" | |
| " foo bar (\n" | |
| "`ifndef BAZ\n" | |
| " .c(c)\n" | |
| "`else\n" | |
| " .d(d)\n" | |
| "`endif\n" | |
| " );\n" | |
| "endmodule\n"}, | |
| { | |
| // test that alternate top-syntax mode works | |
| "// verilog_syntax: parse-as-module-body\n" | |
| "`define FOO\n", | |
| "// verilog_syntax: parse-as-module-body\n" | |
| "`define FOO\n", | |
| }, | |
| { | |
| // test alternate parsing mode in macro expansion | |
| "class foo;\n" | |
| "`MY_MACRO(\n" | |
| " // verilog_syntax: parse-as-statements\n" | |
| " // EOL comment\n" | |
| " int count;\n" | |
| " if(cfg.enable) begin\n" | |
| " count = 1;\n" | |
| " end,\n" | |
| " utils_pkg::decrement())\n" | |
| "endclass\n", | |
| "class foo;\n" | |
| " `MY_MACRO(\n" | |
| " // verilog_syntax: parse-as-statements\n" | |
| " // EOL comment\n" | |
| " int count;\n" | |
| " if (cfg.enable) begin\n" | |
| " count = 1;\n" | |
| " end,\n" | |
| " utils_pkg::decrement())\n" | |
| "endclass\n", | |
| }, | |
| // tests top-level data declarations | |
| {"a;", // implicit type | |
| "a;\n"}, | |
| {"a\tb;", // explicit type | |
| "a b;\n"}, | |
| {"a;b;", | |
| "a;\n" | |
| "b;\n"}, | |
| {"a ,b;", // implicit type | |
| "a, b;\n"}, | |
| /* TODO(b/149591599): implicit type data declarations in module body | |
| {"module\tm ;a ;endmodule", | |
| "module m;\n" | |
| " a;\n" | |
| "endmodule\n"}, | |
| */ | |
| {"package\tp ;a ;endpackage", // implicit type | |
| "package p;\n" | |
| " a;\n" | |
| "endpackage\n"}, | |
| {"package\tp ;a ,b ;endpackage", // implicit type | |
| "package p;\n" | |
| " a, b;\n" | |
| "endpackage\n"}, | |
| {"package\tp ;a ;b ;endpackage", // implicit type | |
| "package p;\n" | |
| " a;\n" | |
| " b;\n" | |
| "endpackage\n"}, | |
| /* TODO(b/149591627) : implicit type data declarations in class body | |
| {"class\tc ;a ;endclass", | |
| "class c;\n" | |
| " a;\n" | |
| "endclass\n"}, | |
| */ | |
| {"function\tf ;a ;endfunction", // implicit type | |
| "function f;\n" | |
| " a;\n" | |
| "endfunction\n"}, | |
| {"function\tf ;a ;x ;endfunction", // implicit type | |
| "function f;\n" | |
| " a;\n" | |
| " x;\n" | |
| "endfunction\n"}, | |
| /* TODO(b/149592527): multi-variable data declaration as block_item_decl | |
| // same inside tasks | |
| {"function\tf ;a \t,x ;endfunction", // implicit type | |
| "function f;\n" | |
| " a, x;\n" | |
| "endfunction\n"}, | |
| */ | |
| {"task\tt ;a ;endtask", // implicit type | |
| "task t;\n" | |
| " a;\n" | |
| "endtask\n"}, | |
| {"task\tt ;a ;x ;endtask", // implicit type | |
| "task t;\n" | |
| " a;\n" | |
| " x;\n" | |
| "endtask\n"}, | |
| {// tests bind declaration | |
| "bind foo bar baz ( . clk ( clk ) ) ;", | |
| "bind foo bar baz (.clk(clk));\n"}, | |
| {// tests bind declaration, with type params | |
| "bind foo bar# ( . W ( W ) ) baz ( . clk ( clk ) ) ;", | |
| "bind foo bar #(.W(W)) baz (.clk(clk));\n"}, | |
| {// tests bind declarations | |
| "bind foo bar baz ( ) ;" | |
| "bind goo car caz ( );", | |
| "bind foo bar baz ();\n" | |
| "bind goo car caz ();\n"}, | |
| {"bind blah foo #( .MaxCount(MaxCount), .MaxDelta(MaxDelta)) bar (" | |
| " .clk(clk), .rst(rst), .value(value) );", | |
| "bind blah foo #(\n" | |
| " .MaxCount(MaxCount),\n" | |
| " .MaxDelta(MaxDelta)\n" | |
| ") bar (\n" | |
| " .clk(clk), .rst(rst), .value(value)\n" | |
| ");\n"}, | |
| { | |
| "bind expaaaaaaaaaaand_meeee looooooooong_name# (" | |
| ".W(W_CONST), .H(H_CONST), .D(D_CONST) )" | |
| "instaaance_name (.in(iiiiiiiin), .out(ooooooout), .clk(ccccccclk));", | |
| "bind expaaaaaaaaaaand_meeee\n" | |
| " looooooooong_name #(\n" | |
| " .W(W_CONST),\n" | |
| " .H(H_CONST),\n" | |
| " .D(D_CONST)\n" | |
| ") instaaance_name (\n" | |
| " .in(iiiiiiiin),\n" | |
| " .out(ooooooout),\n" | |
| " .clk(ccccccclk)\n" | |
| ");\n", | |
| }, | |
| { | |
| "bind expand_inst name# (" | |
| ".W(W_CONST), .H(H_CONST), .D(D_CONST) )" | |
| "instaaance_name (.in(iiiiiiiin), .out(ooooooout), .clk(ccccccclk));", | |
| "bind expand_inst name #(\n" | |
| " .W(W_CONST),\n" | |
| " .H(H_CONST),\n" | |
| " .D(D_CONST)\n" | |
| ") instaaance_name (\n" | |
| " .in(iiiiiiiin),\n" | |
| " .out(ooooooout),\n" | |
| " .clk(ccccccclk)\n" | |
| ");\n", | |
| }, | |
| { | |
| // tests import declaration | |
| "import foo_pkg :: bar ;", | |
| "import foo_pkg::bar;\n", | |
| }, | |
| { | |
| // tests import declaration with wildcard | |
| "import foo_pkg :: * ;", | |
| "import foo_pkg::*;\n", | |
| }, | |
| { | |
| // tests import declarations | |
| "import foo_pkg :: *\t;" | |
| "import goo_pkg\n:: thing ;", | |
| "import foo_pkg::*;\n" | |
| "import goo_pkg::thing;\n", | |
| }, | |
| // preserve spaces inside [] dimensions, but limit spaces around ':' to one | |
| // and adjust everything else | |
| {"foo[W-1:0]a[0:K-1];", // data declaration | |
| "foo [W-1:0] a[0:K-1];\n"}, | |
| {"foo[W-1 : 0]a[0 : K-1];", "foo [W-1 : 0] a[0 : K-1];\n"}, | |
| {"foo[W - 1 : 0 ]a [ 0 : K - 1] ;", | |
| "foo [W - 1 : 0] a[0 : K - 1];\n"}, | |
| // remove spaces between [...] [...] in multi-dimension arrays | |
| {"foo[K] [W]a;", // | |
| "foo [K][W] a;\n"}, | |
| {"foo b [K] [W] ;", // | |
| "foo b[K][W];\n"}, | |
| {"logic[K:1] [W:1]a;", // | |
| "logic [K:1][W:1] a;\n"}, | |
| {"logic b [K:1] [W:1] ;", // | |
| "logic b[K:1][W:1];\n"}, | |
| // spaces in bit slicing | |
| { | |
| // preserve 0 spaces | |
| "always_ff @(posedge clk) begin " | |
| "dummy <=\tfoo [ 7:2 ] ; " | |
| "end", | |
| "always_ff @(posedge clk) begin\n" | |
| " dummy <= foo[7:2];\n" | |
| "end\n", | |
| }, | |
| { | |
| // preserve 1 space | |
| "always_ff @(posedge clk) begin " | |
| "dummy <=\tfoo [ 7 : 2 ] ; " | |
| "end", | |
| "always_ff @(posedge clk) begin\n" | |
| " dummy <= foo[7 : 2];\n" | |
| "end\n", | |
| }, | |
| { | |
| // limit multiple spaces to 1 | |
| "always_ff @(posedge clk) begin " | |
| "dummy <=\tfoo [ 7 : 2 ] ; " | |
| "end", | |
| "always_ff @(posedge clk) begin\n" | |
| " dummy <= foo[7 : 2];\n" | |
| "end\n", | |
| }, | |
| { | |
| "always_ff @(posedge clk) begin " | |
| "dummy <=\tfoo [ 7 : 2 ] ; " | |
| "end", | |
| "always_ff @(posedge clk) begin\n" | |
| " dummy <= foo[7 : 2];\n" | |
| "end\n", | |
| }, | |
| { | |
| // keep value on the left when symmetrizing | |
| "always_ff @(posedge clk) begin " | |
| "dummy <=\tfoo [ 7: 2 ] ; " | |
| "end", | |
| "always_ff @(posedge clk) begin\n" | |
| " dummy <= foo[7:2];\n" | |
| "end\n", | |
| }, | |
| { | |
| "always_ff @(posedge clk) begin " | |
| "dummy <=\tfoo [ 7: 2 ] ; " | |
| "end", | |
| "always_ff @(posedge clk) begin\n" | |
| " dummy <= foo[7:2];\n" | |
| "end\n", | |
| }, | |
| { | |
| "always_ff @(posedge clk) begin " | |
| "dummy <=\tfoo [ 7 :2 ] ; " | |
| "end", | |
| "always_ff @(posedge clk) begin\n" | |
| " dummy <= foo[7 : 2];\n" | |
| "end\n", | |
| }, | |
| { | |
| "always_ff @(posedge clk) begin " | |
| "dummy <=\tfoo [ 7 : 2 ] ; " | |
| "end", | |
| "always_ff @(posedge clk) begin\n" | |
| " dummy <= foo[7 : 2];\n" | |
| "end\n", | |
| }, | |
| { | |
| // use value on the left, but limit to 1 space | |
| "always_ff @(posedge clk) begin " | |
| "dummy <=\tfoo [ 7 :2 ] ; " | |
| "end", | |
| "always_ff @(posedge clk) begin\n" | |
| " dummy <= foo[7 : 2];\n" | |
| "end\n", | |
| }, | |
| // task test cases | |
| {"task t ;endtask:t", // | |
| "task t;\n" | |
| "endtask : t\n"}, | |
| {"task t ;# 10 ;# 5ns ; # 0.1 ; # 1step ;endtask", | |
| "task t;\n" | |
| " #10;\n" // no space in delay expression | |
| " #5ns;\n" | |
| " #0.1;\n" | |
| " #1step;\n" | |
| "endtask\n"}, | |
| {"task t\n;a<=b ;c<=d ;endtask\n", | |
| "task t;\n" | |
| " a <= b;\n" | |
| " c <= d;\n" | |
| "endtask\n"}, | |
| {"class c; virtual protected task\tt ( foo bar);" | |
| "a.a<=b.b;\t\tc.c\n<= d.d; endtask endclass", | |
| "class c;\n" | |
| " virtual protected task t(foo bar);\n" | |
| " a.a <= b.b;\n" | |
| " c.c <= d.d;\n" | |
| " endtask\n" | |
| "endclass\n"}, | |
| {"task t;\n// statement comment\nendtask\n", | |
| "task t;\n" | |
| " // statement comment\n" // indented | |
| "endtask\n"}, | |
| {"task t( );\n// statement comment\nendtask\n", | |
| "task t();\n" | |
| " // statement comment\n" // indented | |
| "endtask\n"}, | |
| {"task t( input x );\n" | |
| "// statement comment\n" | |
| "s();\n" | |
| "// statement comment\n" | |
| "endtask\n", | |
| "task t(input x);\n" | |
| " // statement comment\n" // indented | |
| " s();\n" | |
| " // statement comment\n" // indented | |
| "endtask\n"}, | |
| {"task fj;fork join fork join\tendtask", | |
| "task fj;\n" | |
| " fork\n" | |
| " join\n" | |
| " fork\n" | |
| " join\n" | |
| "endtask\n"}, | |
| {"task fj;fork join_any fork join_any\tendtask", | |
| "task fj;\n" | |
| " fork\n" | |
| " join_any\n" | |
| " fork\n" | |
| " join_any\n" | |
| "endtask\n"}, | |
| {"task fj;fork join_none fork join_none\tendtask", | |
| "task fj;\n" | |
| " fork\n" | |
| " join_none\n" | |
| " fork\n" | |
| " join_none\n" | |
| "endtask\n"}, | |
| {"task fj;fork\n" | |
| "//c1\njoin\n" | |
| "//c2\n" | |
| "fork \n" | |
| "//c3\n" | |
| "join\tendtask", | |
| "task fj;\n" | |
| " fork\n" | |
| " //c1\n" | |
| " join\n" | |
| " //c2\n" | |
| " fork\n" | |
| " //c3\n" | |
| " join\n" | |
| "endtask\n"}, | |
| {"task fj;\n" | |
| "fork " | |
| "begin " | |
| "end " | |
| "foo();" | |
| "begin " | |
| "end " | |
| "join_any endtask", | |
| "task fj;\n" | |
| " fork\n" | |
| " begin\n" | |
| " end\n" | |
| " foo();\n" | |
| " begin\n" | |
| " end\n" | |
| " join_any\n" | |
| "endtask\n"}, | |
| { | |
| // call and assertion statements | |
| "task t ;Fire() ;assert ( x);assert(y );endtask", | |
| "task t;\n" | |
| " Fire();\n" | |
| " assert (x);\n" | |
| " assert (y);\n" | |
| "endtask\n", | |
| }, | |
| { | |
| // assertion statements with body clause | |
| "task t ;Fire() ;assert ( x) fee ( );assert(y ) foo ( ) ;endtask", | |
| "task t;\n" | |
| " Fire();\n" | |
| " assert (x) fee();\n" | |
| " assert (y) foo();\n" | |
| "endtask\n", | |
| }, | |
| { | |
| // assertion statements with else clause | |
| "task t ;Fire() ;assert ( x) else fee ( );" | |
| "assert(y ) else foo ( ) ;endtask", | |
| "task t;\n" | |
| " Fire();\n" | |
| " assert (x)\n" | |
| " else fee();\n" | |
| " assert (y)\n" | |
| " else foo();\n" | |
| "endtask\n", | |
| }, | |
| { | |
| // assertion statements with else clause | |
| "task t ;Fire() ;assert ( x) fa(); else fee ( );" | |
| "assert(y ) fi(); else foo ( ) ;endtask", | |
| "task t;\n" | |
| " Fire();\n" | |
| " assert (x) fa();\n" | |
| " else fee();\n" | |
| " assert (y) fi();\n" | |
| " else foo();\n" | |
| "endtask\n", | |
| }, | |
| { | |
| // assume statements | |
| "task t ;Fire() ;assume ( x);assume(y );endtask", | |
| "task t;\n" | |
| " Fire();\n" | |
| " assume (x);\n" | |
| " assume (y);\n" | |
| "endtask\n", | |
| }, | |
| { | |
| // cover statements | |
| "task t ;Fire() ;cover ( x);cover(y );endtask", | |
| "task t;\n" | |
| " Fire();\n" | |
| " cover (x);\n" | |
| " cover (y);\n" | |
| "endtask\n", | |
| }, | |
| { | |
| // cover statements, with action | |
| "task t ;Fire() ;cover ( x)g( );cover(y ) h();endtask", | |
| "task t;\n" | |
| " Fire();\n" | |
| " cover (x) g();\n" | |
| " cover (y) h();\n" | |
| "endtask\n", | |
| }, | |
| { | |
| // cover statements, with action block | |
| "task t ;Fire() ;cover ( x) begin g( ); end " | |
| "cover(y ) begin h(); end endtask", | |
| "task t;\n" | |
| " Fire();\n" | |
| " cover (x) begin\n" | |
| " g();\n" | |
| " end\n" | |
| " cover (y) begin\n" | |
| " h();\n" | |
| " end\n" | |
| "endtask\n", | |
| }, | |
| {// shuffle calls | |
| "task t; foo. shuffle ( );bar .shuffle( ); endtask", | |
| "task t;\n" | |
| " foo.shuffle();\n" | |
| " bar.shuffle();\n" | |
| "endtask\n"}, | |
| {// wait statements (null) | |
| "task t; wait (a==b);wait(c<d); endtask", | |
| "task t;\n" | |
| " wait(a == b);\n" | |
| " wait(c < d);\n" | |
| "endtask\n"}, | |
| {// wait statements, single action statement | |
| "task t; wait (a==b) p();wait(c<d) q(); endtask", | |
| "task t;\n" | |
| " wait(a == b) p();\n" | |
| " wait(c < d) q();\n" | |
| "endtask\n"}, | |
| {// wait statements, block action statement | |
| "task t; wait (a==b) begin p(); end " | |
| "wait(c<d) begin q(); end endtask", | |
| "task t;\n" | |
| " wait(a == b) begin\n" | |
| " p();\n" | |
| " end\n" | |
| " wait(c < d) begin\n" | |
| " q();\n" | |
| " end\n" | |
| "endtask\n"}, | |
| {// wait fork statements | |
| "task t ; wait\tfork;wait fork ;endtask", | |
| "task t;\n" | |
| " wait fork;\n" | |
| " wait fork;\n" | |
| "endtask\n"}, | |
| {// labeled single statements (prefix-style) | |
| "task t;l1:x<=y ;endtask", | |
| "task t;\n" | |
| " l1 : x <= y;\n" | |
| "endtask\n"}, | |
| {// labeled block statements (prefix-style) | |
| "task t;l1:begin end:l1 endtask", | |
| "task t;\n" | |
| " l1 : begin\n" | |
| " end : l1\n" | |
| "endtask\n"}, | |
| {// labeled seq block statements | |
| "task t;begin:l1 end:l1 endtask", | |
| "task t;\n" | |
| " begin : l1\n" | |
| " end : l1\n" | |
| "endtask\n"}, | |
| {// labeled par block statements | |
| "task t;fork:l1 join:l1 endtask", | |
| "task t;\n" | |
| " fork : l1\n" | |
| " join : l1\n" | |
| "endtask\n"}, | |
| {// task with disable statements | |
| "task t ;fork\tjoin\tdisable\tfork;endtask", | |
| "task t;\n" | |
| " fork\n" | |
| " join\n" | |
| " disable fork;\n" | |
| "endtask\n"}, | |
| {"task t ;fork\tjoin_any\tdisable\tfork ;endtask", | |
| "task t;\n" | |
| " fork\n" | |
| " join_any\n" | |
| " disable fork;\n" | |
| "endtask\n"}, | |
| {"task t ;disable\tbean_counter ;endtask", | |
| "task t;\n" | |
| " disable bean_counter;\n" | |
| "endtask\n"}, | |
| { | |
| // task with if-statement | |
| "task t;" | |
| "if (r == t)" | |
| "a.b(c);" | |
| "endtask", | |
| "task t;\n" | |
| " if (r == t) a.b(c);\n" | |
| "endtask\n", | |
| }, | |
| { | |
| // task with system call inside if header | |
| "task t;" | |
| "if (!$cast(ssssssssssssssss,vvvvvvvvvv,gggggggg))begin end endtask:t", | |
| "task t;\n" | |
| " if (!$cast(\n" | |
| " ssssssssssssssss,\n" | |
| " vvvvvvvvvv,\n" | |
| " gggggggg\n" | |
| " )) begin\n" | |
| " end\n" | |
| "endtask : t\n", | |
| }, | |
| { | |
| // task with nested subtask call and arguments passed by name | |
| "task t;" | |
| "if (!$cast(ssssssssssssssss, vvvvvvvvvv.gggggggg(" | |
| ".ppppppp(ppppppp)," | |
| ".yyyyy(\"xxxxxxxxxxxxx\")" | |
| "))) begin " | |
| "end " | |
| "endtask : t", | |
| "task t;\n" | |
| " if (!$cast(\n" | |
| " ssssssssssssssss,\n" | |
| " vvvvvvvvvv.gggggggg(\n" | |
| " .ppppppp(ppppppp),\n" | |
| " .yyyyy(\"xxxxxxxxxxxxx\")\n" | |
| " )\n" | |
| " )) begin\n" | |
| " end\n" | |
| "endtask : t\n", | |
| }, | |
| { | |
| // assert property statements | |
| "task t ;assert property( x);assert\tproperty(y );endtask", | |
| "task t;\n" | |
| " assert property (x);\n" | |
| " assert property (y);\n" | |
| "endtask\n", | |
| }, | |
| { | |
| // assert property statements, with action | |
| "task t ;assert property( x) j();assert\tproperty(y )k( );endtask", | |
| "task t;\n" | |
| " assert property (x) j();\n" | |
| " assert property (y) k();\n" | |
| "endtask\n", | |
| }, | |
| { | |
| // assert property statements, with action block | |
| "task t ;assert property( x) begin j();end " | |
| " assert\tproperty(y )begin\tk( ); end endtask", | |
| "task t;\n" | |
| " assert property (x) begin\n" | |
| " j();\n" | |
| " end\n" | |
| " assert property (y) begin\n" | |
| " k();\n" | |
| " end\n" | |
| "endtask\n", | |
| }, | |
| { | |
| // assert property statements, else with null | |
| "task t ;assert property( x) else;assert\tproperty(y )else;endtask", | |
| "task t;\n" | |
| " assert property (x)\n" | |
| " else;\n" | |
| " assert property (y)\n" | |
| " else;\n" | |
| "endtask\n", | |
| }, | |
| { | |
| // assert property statements, else with actions | |
| "task t ;assert property( x) f(); else p(); " | |
| "\tassert\tproperty(y ) g();else q( );endtask", | |
| "task t;\n" | |
| " assert property (x) f();\n" | |
| " else p();\n" | |
| " assert property (y) g();\n" | |
| " else q();\n" | |
| "endtask\n", | |
| }, | |
| { | |
| // assert property statement, with action block, else statement | |
| "task t ;assert property( x) begin j();end else\tk( ); endtask", | |
| "task t;\n" | |
| " assert property (x) begin\n" | |
| " j();\n" | |
| " end else k();\n" | |
| "endtask\n", | |
| }, | |
| { | |
| // assert property statement, with action statement, else block | |
| "task t ;assert property( x) j(); else begin\tk( );end endtask", | |
| "task t;\n" | |
| " assert property (x) j();\n" | |
| " else begin\n" | |
| " k();\n" | |
| " end\n" | |
| "endtask\n", | |
| }, | |
| { | |
| // assert property statement, with action block, else block | |
| "task t ;assert property( x)begin j();end " | |
| "else begin\tk( );end endtask", | |
| "task t;\n" | |
| " assert property (x) begin\n" | |
| " j();\n" | |
| " end else begin\n" | |
| " k();\n" | |
| " end\n" | |
| "endtask\n", | |
| }, | |
| { | |
| // assume property statements | |
| "task t ;assume property( x);assume\tproperty(y );endtask", | |
| "task t;\n" | |
| " assume property (x);\n" | |
| " assume property (y);\n" | |
| "endtask\n", | |
| }, | |
| { | |
| // assume property statements, with action | |
| "task t ;assume property( x) j();assume\tproperty(y )k( );endtask", | |
| "task t;\n" | |
| " assume property (x) j();\n" | |
| " assume property (y) k();\n" | |
| "endtask\n", | |
| }, | |
| { | |
| // assume property statements, with action block | |
| "task t ;assume property( x) begin j();end " | |
| " assume\tproperty(y )begin\tk( ); end endtask", | |
| "task t;\n" | |
| " assume property (x) begin\n" | |
| " j();\n" | |
| " end\n" | |
| " assume property (y) begin\n" | |
| " k();\n" | |
| " end\n" | |
| "endtask\n", | |
| }, | |
| { | |
| // assume property statements, else with null | |
| "task t ;assume property( x) else;assume\tproperty(y )else;endtask", | |
| "task t;\n" | |
| " assume property (x)\n" | |
| " else;\n" | |
| " assume property (y)\n" | |
| " else;\n" | |
| "endtask\n", | |
| }, | |
| { | |
| // assume property statements, else with actions | |
| "task t ;assume property( x) f(); else p(); " | |
| "\tassume\tproperty(y ) g();else q( );endtask", | |
| "task t;\n" | |
| " assume property (x) f();\n" | |
| " else p();\n" | |
| " assume property (y) g();\n" | |
| " else q();\n" | |
| "endtask\n", | |
| }, | |
| { | |
| // assume property statement, with action block, else statement | |
| "task t ;assume property( x) begin j();end else\tk( ); endtask", | |
| "task t;\n" | |
| " assume property (x) begin\n" | |
| " j();\n" | |
| " end else k();\n" | |
| "endtask\n", | |
| }, | |
| { | |
| // assume property statement, with action statement, else block | |
| "task t ;assume property( x) j(); else begin\tk( );end endtask", | |
| "task t;\n" | |
| " assume property (x) j();\n" | |
| " else begin\n" | |
| " k();\n" | |
| " end\n" | |
| "endtask\n", | |
| }, | |
| { | |
| // assume property statement, with action block, else block | |
| "task t ;assume property( x)begin j();end " | |
| "else begin\tk( );end endtask", | |
| "task t;\n" | |
| " assume property (x) begin\n" | |
| " j();\n" | |
| " end else begin\n" | |
| " k();\n" | |
| " end\n" | |
| "endtask\n", | |
| }, | |
| { | |
| // expect property statements | |
| "task t ;expect ( x);expect\t(y );endtask", | |
| "task t;\n" | |
| " expect (x);\n" | |
| " expect (y);\n" | |
| "endtask\n", | |
| }, | |
| { | |
| // expect property statements, with action | |
| "task t ;expect ( x) j();expect\t(y )k( );endtask", | |
| "task t;\n" | |
| " expect (x) j();\n" | |
| " expect (y) k();\n" | |
| "endtask\n", | |
| }, | |
| { | |
| // expect property statements, with action block | |
| "task t ;expect ( x) begin j();end " | |
| " expect\t(y )begin\tk( ); end endtask", | |
| "task t;\n" | |
| " expect (x) begin\n" | |
| " j();\n" | |
| " end\n" | |
| " expect (y) begin\n" | |
| " k();\n" | |
| " end\n" | |
| "endtask\n", | |
| }, | |
| { | |
| // expect property statements, else with null | |
| "task t ;expect ( x) else;expect\t(y )else;endtask", | |
| "task t;\n" | |
| " expect (x)\n" | |
| " else;\n" | |
| " expect (y)\n" | |
| " else;\n" | |
| "endtask\n", | |
| }, | |
| { | |
| // expect property statements, else with actions | |
| "task t ;expect ( x) f(); else p(); " | |
| "\texpect\t(y ) g();else q( );endtask", | |
| "task t;\n" | |
| " expect (x) f();\n" | |
| " else p();\n" | |
| " expect (y) g();\n" | |
| " else q();\n" | |
| "endtask\n", | |
| }, | |
| { | |
| // expect property statement, with action block, else statement | |
| "task t ;expect ( x) begin j();end else\tk( ); endtask", | |
| "task t;\n" | |
| " expect (x) begin\n" | |
| " j();\n" | |
| " end else k();\n" | |
| "endtask\n", | |
| }, | |
| { | |
| // expect property statement, with action statement, else block | |
| "task t ;expect ( x) j(); else begin\tk( );end endtask", | |
| "task t;\n" | |
| " expect (x) j();\n" | |
| " else begin\n" | |
| " k();\n" | |
| " end\n" | |
| "endtask\n", | |
| }, | |
| { | |
| // expect property statement, with action block, else block | |
| "task t ;expect ( x)begin j();end " | |
| "else begin\tk( );end endtask", | |
| "task t;\n" | |
| " expect (x) begin\n" | |
| " j();\n" | |
| " end else begin\n" | |
| " k();\n" | |
| " end\n" | |
| "endtask\n", | |
| }, | |
| { | |
| // cover property statements | |
| "task t ;cover property( x);cover\tproperty(y );endtask", | |
| "task t;\n" | |
| " cover property (x);\n" | |
| " cover property (y);\n" | |
| "endtask\n", | |
| }, | |
| { | |
| // cover property statements, with action | |
| "task t ;cover property( x) j();cover\tproperty(y )k( );endtask", | |
| "task t;\n" | |
| " cover property (x) j();\n" | |
| " cover property (y) k();\n" | |
| "endtask\n", | |
| }, | |
| { | |
| // cover property statements, with action block | |
| "task t ;cover property( x) begin j();end " | |
| " cover\tproperty(y )begin\tk( ); end endtask", | |
| "task t;\n" | |
| " cover property (x) begin\n" | |
| " j();\n" | |
| " end\n" | |
| " cover property (y) begin\n" | |
| " k();\n" | |
| " end\n" | |
| "endtask\n", | |
| }, | |
| { | |
| // cover sequence statements | |
| "task t ;cover sequence( x);cover\tsequence(y );endtask", | |
| "task t;\n" | |
| " cover sequence (x);\n" | |
| " cover sequence (y);\n" | |
| "endtask\n", | |
| }, | |
| { | |
| // cover sequence statements, with action | |
| "task t ;cover sequence( x) j();cover\tsequence(y )k( );endtask", | |
| "task t;\n" | |
| " cover sequence (x) j();\n" | |
| " cover sequence (y) k();\n" | |
| "endtask\n", | |
| }, | |
| { | |
| // cover sequence statements, with action block | |
| "task t ;cover sequence( x) begin j();end " | |
| " cover\tsequence(y )begin\tk( ); end endtask", | |
| "task t;\n" | |
| " cover sequence (x) begin\n" | |
| " j();\n" | |
| " end\n" | |
| " cover sequence (y) begin\n" | |
| " k();\n" | |
| " end\n" | |
| "endtask\n", | |
| }, | |
| {// module with disable statements | |
| "module m;always begin :block disable m.block; end endmodule", | |
| "module m;\n" | |
| " always begin : block\n" | |
| " disable m.block;\n" | |
| " end\n" | |
| "endmodule\n"}, | |
| {"module m;always begin disable m.block; end endmodule", | |
| "module m;\n" | |
| " always begin\n" | |
| " disable m.block;\n" | |
| " end\n" | |
| "endmodule\n"}, | |
| // property test cases | |
| {"module mp ;property p1 ; a|->b;endproperty endmodule", | |
| "module mp;\n" | |
| " property p1;\n" | |
| " a |-> b;\n" | |
| " endproperty\n" | |
| "endmodule\n"}, | |
| {"module mp ;property p1 ; a|->b;endproperty:p1 endmodule", | |
| "module mp;\n" | |
| " property p1;\n" | |
| " a |-> b;\n" | |
| " endproperty : p1\n" // with end label | |
| "endmodule\n"}, | |
| {"module mp ;property p1 ; a|->## 1 b;endproperty endmodule", | |
| "module mp;\n" | |
| " property p1;\n" | |
| " a |-> ##1 b;\n" // with delay | |
| " endproperty\n" | |
| "endmodule\n"}, | |
| {"module mp ;property p1 ; a|->## [0: 1] b;endproperty endmodule", | |
| "module mp;\n" | |
| " property p1;\n" | |
| " a |-> ##[0:1] b;\n" // prefer no spaces with delay range | |
| " endproperty\n" | |
| "endmodule\n"}, | |
| {"module mp ;property p1 ; a|->## [0 : 1] b;endproperty endmodule", | |
| "module mp;\n" | |
| " property p1;\n" | |
| " a |-> ##[0 : 1] b;\n" // limit to one space, symmetrize | |
| " endproperty\n" | |
| "endmodule\n"}, | |
| {"module mp ;property p1 ; a## 1 b;endproperty endmodule", | |
| "module mp;\n" | |
| " property p1;\n" | |
| " a ##1 b;\n" | |
| " endproperty\n" | |
| "endmodule\n"}, | |
| {"module mp ;property p1 ; (a^c)## 1 b;endproperty endmodule", | |
| "module mp;\n" | |
| " property p1;\n" | |
| " (a ^ c) ##1 b;\n" | |
| " endproperty\n" | |
| "endmodule\n"}, | |
| // covergroup test cases | |
| {// Minimal case | |
| "covergroup c; endgroup\n", | |
| "covergroup c;\n" | |
| "endgroup\n"}, | |
| {// Minimal useful case | |
| "covergroup c @ (posedge clk); coverpoint a; endgroup\n", | |
| "covergroup c @(posedge clk);\n" | |
| " coverpoint a;\n" | |
| "endgroup\n"}, | |
| {// Multiple coverpoints | |
| "covergroup foo @(posedge clk); coverpoint a; coverpoint b; " | |
| "coverpoint c; coverpoint d; endgroup\n", | |
| "covergroup foo @(posedge clk);\n" | |
| " coverpoint a;\n" | |
| " coverpoint b;\n" | |
| " coverpoint c;\n" | |
| " coverpoint d;\n" | |
| "endgroup\n"}, | |
| {// Multiple bins | |
| "covergroup memory @ (posedge ce); address :coverpoint addr {" | |
| "bins low={0,127}; bins high={128,255};} endgroup\n", | |
| "covergroup memory @(posedge ce);\n" | |
| " address: coverpoint addr {\n" | |
| " bins low = {0, 127};\n" | |
| " bins high = {128, 255};\n" | |
| " }\n" | |
| "endgroup\n"}, | |
| {// Custom sample() function | |
| "covergroup c with function sample(bit i); endgroup\n", | |
| "covergroup c with function sample (\n" | |
| " bit i\n" // test cases are wrapped at 40 | |
| ");\n" | |
| "endgroup\n"}, | |
| // comment-controlled formatter disabling | |
| {"// verilog_format: off\n" // disables whole file | |
| " `include \t\t \"path/to/file.vh\"\n", | |
| "// verilog_format: off\n" | |
| " `include \t\t \"path/to/file.vh\"\n"}, // keeps bad spacing | |
| {"/* verilog_format: off */\n" // disables whole file | |
| " `include \t\t \"path/to/file.svh\" \n", | |
| "/* verilog_format: off */\n" | |
| " `include \t\t \"path/to/file.svh\" \n"}, // keeps bad spacing | |
| {"// verilog_format: on\n" // already enabled, no effect | |
| " `include \t \"path/to/file.svh\" \t\n", | |
| "// verilog_format: on\n" | |
| "`include \"path/to/file.svh\"\n"}, | |
| {"// verilog_format: off\n" | |
| "// verilog_format: on\n" // re-enable right away | |
| " `include \t\t \"path/to/file.svh\" \n", | |
| "// verilog_format: off\n" | |
| "// verilog_format: on\n" | |
| "`include \"path/to/file.svh\"\n"}, | |
| {"/* aaa *//* bbb */\n" // not formatting controls | |
| " `include \t\t \"path/to/file.svh\" \n", // should format | |
| "/* aaa */ /* bbb */\n" // currently inserts 2 spaces | |
| "`include \"path/to/file.svh\"\n"}, | |
| {"/* verilog_format: off *//* verilog_format: on */\n" // re-enable | |
| " `include \t\t \"path/to/file.svh\" \n", | |
| // Note that this case normally wouldn't fit in 40 columns, | |
| // but disabling formatting lets it overflow. | |
| "/* verilog_format: off *//* verilog_format: on */\n" | |
| "`include \"path/to/file.svh\"\n"}, | |
| {"// verilog_format: off\n" | |
| " `include \t\t \"path/to/fileA.svh\" // verilog_format: on\n" | |
| " `include \t\t \"path/to/fileB.svh\" \n", | |
| // re-enable formatting with comment trailing other tokens | |
| "// verilog_format: off\n" | |
| " `include \t\t \"path/to/fileA.svh\" // verilog_format: on\n" | |
| "`include \"path/to/fileB.svh\"\n"}, | |
| {" `include \t\t \"path/to/file1.vh\" \n" // format this | |
| "// verilog_format: off\n" // start disabling | |
| " `include \t\t \"path/to/file2.vh\" \n" | |
| "\t\t\n" | |
| " `include \t\t \"path/to/file3.vh\" \n" | |
| "// verilog_format: on\n" // stop disabling | |
| " `include \t\t \"path/to/file4.vh\" \n", // format this | |
| "`include \"path/to/file1.vh\"\n" | |
| "// verilog_format: off\n" // start disabling | |
| " `include \t\t \"path/to/file2.vh\" \n" | |
| "\t\t\n" | |
| " `include \t\t \"path/to/file3.vh\" \n" | |
| "// verilog_format: on\n" // stop disabling | |
| "`include \"path/to/file4.vh\"\n"}, | |
| {// disabling formatting on a module (to end of file) | |
| "// verilog_format: off\n" | |
| "module m;endmodule\n", | |
| "// verilog_format: off\n" | |
| "module m;endmodule\n"}, | |
| {// disabling formatting on a module (to end of file) | |
| "// verilog_format: off\n" | |
| "module m;\n" | |
| "unindented instantiation;\n" | |
| "endmodule\n", | |
| "// verilog_format: off\n" | |
| "module m;\n" | |
| "unindented instantiation;\n" | |
| "endmodule\n"}, | |
| {// disabling formatting inside a port declaration list disables alignment, | |
| // but falls back to standard compaction. | |
| "module align_off(\n" | |
| "input w ,\n" | |
| " // verilog_format: off\n" | |
| "input wire [y:z] wwww,\n" | |
| " // verilog_format: on\n" | |
| "output reg xx\n" | |
| ");\n" | |
| "endmodule", | |
| "module align_off (\n" | |
| " input w ,\n" // preserved because group is partially disabled | |
| " // verilog_format: off\n" | |
| "input wire [y:z] wwww,\n" // not compacted | |
| " // verilog_format: on\n" | |
| " output reg xx\n" // preserved because group is partially disabled | |
| ");\n" | |
| "endmodule\n"}, | |
| {// multiple tokens with EOL comment | |
| "module please; // don't break before the comment\n" | |
| "endmodule\n", | |
| "module please\n" | |
| " ; // don't break before the comment\n" | |
| "endmodule\n"}, | |
| {// one token with EOL comment | |
| "module please;\n" | |
| "endmodule // don't break before the comment\n", | |
| "module please;\n" | |
| "endmodule // don't break before the comment\n"}, | |
| { | |
| // line with only an EOL comment | |
| "module wild;\n" | |
| "// a really long comment on its own line to be left alone\n" | |
| "endmodule", | |
| "module wild;\n" | |
| " // a really long comment on its own line to be left alone\n" | |
| "endmodule\n", | |
| }, | |
| { | |
| // primitive declaration | |
| "primitive primitive1(o, s, r);output o;reg o;input s;input r;table 1 " | |
| "? :" | |
| " ? : 0; ? 1 : 0 : -; endtable endprimitive", | |
| "primitive primitive1(o, s, r);\n" | |
| " output o;\n" | |
| " reg o;\n" | |
| " input s;\n" | |
| " input r;\n" | |
| " table\n" | |
| " 1 ? : ? : 0;\n" | |
| " ? 1 : 0 : -;\n" | |
| " endtable\n" | |
| "endprimitive\n", | |
| }, | |
| { | |
| // one-input combinatorial UDP | |
| "primitive primitive1 ( o,i ) ;output o;input i;" | |
| " table 1 : 0 ; 0 : 1 ; endtable endprimitive", | |
| "primitive primitive1(o, i);\n" | |
| " output o;\n" | |
| " input i;\n" | |
| " table\n" | |
| " 1 : 0;\n" | |
| " 0 : 1;\n" | |
| " endtable\n" | |
| "endprimitive\n", | |
| }, | |
| { | |
| // two-input combinatorial UDP | |
| "primitive primitive2(o, s, r);output o;input s;input r;" | |
| "table 1 ? : 0;? 1 : -; endtable endprimitive", | |
| "primitive primitive2(o, s, r);\n" | |
| " output o;\n" | |
| " input s;\n" | |
| " input r;\n" | |
| " table\n" | |
| " 1 ? : 0;\n" | |
| " ? 1 : -;\n" | |
| " endtable\n" | |
| "endprimitive\n", | |
| }, | |
| { | |
| // ten-input combinatorial UDP | |
| "primitive comb10(o, i0, i1, i2, i3, i4, i5, i6, i7, i8, i9);" | |
| "output o;input i0, i1, i2, i3, i4, i5, i6, i7, i8, i9;" | |
| "table 0 ? ? ? ? ? ? ? ? 0 : 0;1 ? ? ? ? ? ? ? ? 0 : 1;" | |
| "1 ? ? ? ? ? ? ? ? 1 : 1;0 ? ? ? ? ? ? ? ? 1 : 0;endtable endprimitive", | |
| "primitive comb10(o, i0, i1, i2, i3, i4,\n" | |
| " i5, i6, i7, i8, i9);\n" | |
| " output o;\n" | |
| " input i0, i1, i2, i3, i4, i5, i6, i7,\n" | |
| " i8, i9;\n" | |
| " table\n" | |
| " 0 ? ? ? ? ? ? ? ? 0 : 0;\n" | |
| " 1 ? ? ? ? ? ? ? ? 0 : 1;\n" | |
| " 1 ? ? ? ? ? ? ? ? 1 : 1;\n" | |
| " 0 ? ? ? ? ? ? ? ? 1 : 0;\n" | |
| " endtable\n" | |
| "endprimitive\n", | |
| }, | |
| { | |
| // sequential level-sensitive UDP | |
| "primitive level_seq(o, c, d);output o;reg o;" | |
| " input c;input d;table\n" | |
| "// C D state O\n" | |
| "0 ? : ? : -; // No Change\n" | |
| "? 0 : 0 : 0; // Unknown\n" | |
| "endtable endprimitive", | |
| "primitive level_seq(o, c, d);\n" | |
| " output o;\n" | |
| " reg o;\n" | |
| " input c;\n" | |
| " input d;\n" | |
| " table\n" | |
| " // C D state O\n" | |
| " 0 ? : ? : -; // No Change\n" | |
| " ? 0 : 0 : 0; // Unknown\n" | |
| " endtable\n" | |
| "endprimitive\n", | |
| }, | |
| { | |
| // sequential edge-sensitive UDP | |
| "primitive edge_seq(o, c, d);output o;reg o;input c;input d;" | |
| "table (01) 0 : ? : 0;(01) 1 : ? : 1;(0?) 1 : 1 : 1;(0?) 0 : 0 : " | |
| "0;\n" | |
| "// ignore negative c\n" | |
| "(?0) ? : ? : -;\n" | |
| "// ignore changes on steady c\n" | |
| "? (?\?) : ? : -; endtable endprimitive", | |
| "primitive edge_seq(o, c, d);\n" | |
| " output o;\n" | |
| " reg o;\n" | |
| " input c;\n" | |
| " input d;\n" | |
| " table\n" | |
| " (01) 0 : ? : 0;\n" | |
| " (01) 1 : ? : 1;\n" | |
| " (0?) 1 : 1 : 1;\n" | |
| " (0?) 0 : 0 : 0;\n" | |
| " // ignore negative c\n" | |
| " (?0) ? : ? : -;\n" | |
| " // ignore changes on steady c\n" | |
| " ? (?\?) : ? : -;\n" | |
| " endtable\n" | |
| "endprimitive\n", | |
| }, | |
| { | |
| // mixed sequential UDP | |
| "primitive mixed(o, clk, j, k, preset, clear);output o;reg o;" | |
| "input c;input j, k;input preset, clear;table " | |
| "? ?? 01:?:1 ; // preset logic\n" | |
| "? ?? *1:1:1 ;? ?? 10:?:0 ; // clear logic\n" | |
| "? ?? 1*:0:0 ;r 00 00:0:1 ; // normal\n" | |
| "r 00 11:?:- ;r 01 11:?:0 ;r 10 11:?:1 ;r 11 11:0:1 ;" | |
| "r 11 11:1:0 ;f ?? ??:?:- ;b *? ??:?:- ;" | |
| " // j and k\n" | |
| "b ?* ??:?:- ;endtable endprimitive\n", | |
| "primitive mixed(o, clk, j, k, preset,\n" | |
| " clear);\n" | |
| " output o;\n" | |
| " reg o;\n" | |
| " input c;\n" | |
| " input j, k;\n" | |
| " input preset, clear;\n" | |
| " table\n" | |
| " ? ? ? 0 1 : ? : 1; // preset logic\n" | |
| " ? ? ? * 1 : 1 : 1;\n" | |
| " ? ? ? 1 0 : ? : 0; // clear logic\n" | |
| " ? ? ? 1 * : 0 : 0;\n" | |
| " r 0 0 0 0 : 0 : 1; // normal\n" | |
| " r 0 0 1 1 : ? : -;\n" | |
| " r 0 1 1 1 : ? : 0;\n" | |
| " r 1 0 1 1 : ? : 1;\n" | |
| " r 1 1 1 1 : 0 : 1;\n" | |
| " r 1 1 1 1 : 1 : 0;\n" | |
| " f ? ? ? ? : ? : -;\n" | |
| " b * ? ? ? : ? : -; // j and k\n" | |
| " b ? * ? ? : ? : -;\n" | |
| " endtable\n" | |
| "endprimitive\n", | |
| }, | |
| // un-lexed multiline macro arg token | |
| { | |
| " task S ; " | |
| "`ppgJH3JoxhwyTmZ2dgPiuMQzpRAWiSs(" | |
| "{xYtxuh6.FIMcVPEWfhtoI2FSe, xYtxuh6.ZVL5XASVGLYz32} == " | |
| "SqRgavM[15:2];\n" | |
| "JgQLBG == 4'h0;, \"foo\" )\n" | |
| "endtask\n", | |
| "task S;\n" | |
| " `ppgJH3JoxhwyTmZ2dgPiuMQzpRAWiSs(\n" | |
| " {xYtxuh6.FIMcVPEWfhtoI2FSe, xYtxuh6.ZVL5XASVGLYz32} == " | |
| "SqRgavM[15:2];\n" | |
| "JgQLBG == 4'h0;, \"foo\")\n" | |
| "endtask\n", | |
| }, | |
| // module instantiation named ports tabular alignment | |
| //{// module instantiation with no port, only comments | |
| // "module m;\n" | |
| // "foo bar(\n" | |
| // "\t//comment1\n" | |
| // "//comment2\n" | |
| // ");\n" | |
| // "endmodule\n", | |
| // "module m;\n" | |
| // " foo bar (\n" | |
| // " //comment1\n" | |
| // " //comment2\n" | |
| // " );\n" | |
| // "endmodule\n" | |
| //}, | |
| {// all named ports | |
| "module m;\n" | |
| "foo bar(.a(a), .aa(aa), .aaa(aaa));\n" | |
| "endmodule\n", | |
| "module m;\n" | |
| " foo bar (\n" | |
| " .a (a),\n" | |
| " .aa (aa),\n" | |
| " .aaa(aaa)\n" | |
| " );\n" | |
| "endmodule\n"}, | |
| {// named ports left unconnected | |
| "module m;\n" | |
| "foo bar(.a(), .aa(), .aaa());\n" | |
| "endmodule\n", | |
| "module m;\n" | |
| " foo bar (\n" | |
| " .a (),\n" | |
| " .aa (),\n" | |
| " .aaa()\n" | |
| " );\n" | |
| "endmodule\n"}, | |
| {// multiple named ports groups separated by blank line | |
| "module m;\n" | |
| "foo bar(.a(a), .aaa(aaa),\n\n .b(b), .bbbbbb(bbbbb));\n" | |
| "endmodule\n", | |
| "module m;\n" | |
| " foo bar (\n" | |
| " .a (a),\n" | |
| " .aaa(aaa),\n" | |
| "\n" | |
| " .b (b),\n" | |
| " .bbbbbb(bbbbb)\n" | |
| " );\n" | |
| "endmodule\n"}, | |
| {// named ports with concatenation | |
| "module m;\n" | |
| "foo bar(.a(a), .aaa({a,b,c}));\n" | |
| "endmodule\n", | |
| "module m;\n" | |
| " foo bar (\n" | |
| " .a (a),\n" | |
| " .aaa({a, b, c})\n" | |
| " );\n" | |
| "endmodule\n"}, | |
| {// name ports with slices | |
| "module m;\n" | |
| "foo bar(.a(a), .aaa(q[r:s]));\n" | |
| "endmodule\n", | |
| "module m;\n" | |
| " foo bar (\n" | |
| " .a (a),\n" | |
| " .aaa(q[r:s])\n" | |
| " );\n" | |
| "endmodule\n"}, | |
| {// named ports with pre-proc directives | |
| "module m;\n" | |
| "foo bar(.a(a), `ifdef MACRO .aa(aa), `endif .aaa(aaa));\n" | |
| "endmodule\n", | |
| "module m;\n" | |
| " foo bar (\n" | |
| " .a (a),\n" | |
| "`ifdef MACRO\n" | |
| " .aa (aa),\n" | |
| "`endif\n" | |
| " .aaa(aaa)\n" | |
| " );\n" | |
| "endmodule\n"}, | |
| {// named ports with macros | |
| "module m;\n" | |
| "foo bar(.a(a), .aa(aa[`RANGE]), .aaa(aaa));\n" | |
| "endmodule\n", | |
| "module m;\n" | |
| " foo bar (\n" | |
| " .a (a),\n" | |
| " .aa (aa[`RANGE]),\n" | |
| " .aaa(aaa)\n" | |
| " );\n" | |
| "endmodule\n"}, | |
| {"module m;\n" | |
| "foo bar(.a(a), .AA, .aaa(aaa));\n" | |
| "endmodule\n", | |
| "module m;\n" | |
| " foo bar (\n" | |
| " .a (a),\n" | |
| " .AA,\n" | |
| " .aaa(aaa)\n" | |
| " );\n" | |
| "endmodule\n"}, | |
| {// name ports with comments | |
| "module m;\n" | |
| "foo bar(.a(a), .aa(aa)/*comment*/, .aaa(aaa));\n" | |
| "endmodule\n", | |
| "module m;\n" | |
| " foo bar (\n" | |
| " .a (a),\n" | |
| " .aa (aa) /*comment*/,\n" | |
| " .aaa(aaa)\n" | |
| " );\n" | |
| "endmodule\n"}, | |
| {"module m;\n" | |
| "foo bar(.a(a),//comment1\n .aaa(aaa)//comment2\n);\n" | |
| "endmodule\n", | |
| "module m;\n" | |
| " foo bar (\n" | |
| " .a (a), //comment1\n" | |
| " .aaa(aaa) //comment2\n" | |
| " );\n" | |
| "endmodule\n"}, | |
| {"module m;\n" | |
| "foo bar(.a(a),\n" | |
| " //.aa(aa),\n" | |
| ".aaa(aaa));\n" | |
| "endmodule\n", | |
| "module m;\n" | |
| " foo bar (\n" | |
| " .a (a),\n" | |
| " //.aa(aa),\n" | |
| " .aaa(aaa)\n" | |
| " );\n" | |
| "endmodule\n"}, | |
| {// module instantiation with all implicit connections | |
| "module m;\n" | |
| "foo bar(.a, .aa, .aaaaa);\n" | |
| "endmodule\n", | |
| "module m;\n" | |
| " foo bar (\n" | |
| " .a,\n" | |
| " .aa,\n" | |
| " .aaaaa\n" | |
| " );\n" | |
| "endmodule\n"}, | |
| {// named ports corssed with implicit connections | |
| "module m;\n" | |
| "foo bar(.a(a), .aa, .aaaaa(aaaaa));\n" | |
| "endmodule\n", | |
| "module m;\n" | |
| " foo bar (\n" | |
| " .a (a),\n" | |
| " .aa,\n" | |
| " .aaaaa(aaaaa)\n" | |
| " );\n" | |
| "endmodule\n"}, | |
| {// named ports corssed with wildcard connections | |
| "module m;\n" | |
| "foo bar(.a(a), .aaa(aaa), .*);\n" | |
| "endmodule\n", | |
| "module m;\n" | |
| " foo bar (\n" | |
| " .a (a),\n" | |
| " .aaa(aaa),\n" | |
| " .*\n" | |
| " );\n" | |
| "endmodule\n"}, | |
| //{ | |
| // "module m;\n" | |
| // "foo bar(.a(a), .aa(aa), .* , .aaa(aaa));\n" | |
| // "endmodule\n", | |
| // "module m;\n" | |
| // " foo bar (\n" | |
| // " .a (a),\n" | |
| // " .aa (aa),\n" | |
| // " .*,\n" | |
| // " .aaa(aaa)\n" | |
| // " );\n" | |
| // "endmodule\n" | |
| //}, | |
| // Parameterized data types, declarations inside #() tabular alignment | |
| {// parameterized module with 'list_of_param_assignments' | |
| "module foo #(A = 2, AA = 22, AAA = 222);\n" | |
| "endmodule\n", | |
| "module foo #(\n" | |
| " A = 2,\n" | |
| " AA = 22,\n" | |
| " AAA = 222\n" | |
| ");\n" | |
| "endmodule\n"}, | |
| {// parameterized module with 'parameter_declaration' | |
| "module foo #(parameter int a = 2, parameter int aa = 22);\n" | |
| "endmodule\n", | |
| "module foo #(\n" | |
| " parameter int a = 2,\n" | |
| " parameter int aa = 22\n" | |
| ");\n" | |
| "endmodule\n"}, | |
| {// parameterized module with 'parameter_declaration' and comments | |
| "module foo #(//comment\nparameter int a = 2, parameter int aa = 22);\n" | |
| "endmodule\n", | |
| "module foo #( //comment\n" | |
| " parameter int a = 2,\n" | |
| " parameter int aa = 22\n" | |
| ");\n" | |
| "endmodule\n"}, | |
| {// parameterized module with 'parameter_declaration' and trailing comments | |
| "module foo #(parameter int a = 2,//comment\n parameter int aa = 22);\n" | |
| "endmodule\n", | |
| "module foo #(\n" | |
| " parameter int a = 2, //comment\n" | |
| " parameter int aa = 22\n" | |
| ");\n" | |
| "endmodule\n"}, | |
| {// parameterized module with 'parameter_declaration' and pre-proc | |
| "module foo #(parameter int a = 2,\n" | |
| "`ifdef MACRO parameter int aa = 22, `endif\n" | |
| "parameter int aaa = 222);\n" | |
| "endmodule\n", | |
| "module foo #(\n" | |
| " parameter int a = 2,\n" | |
| "`ifdef MACRO\n" | |
| " parameter int aa = 22,\n" | |
| "`endif\n" | |
| " parameter int aaa = 222\n" | |
| ");\n" | |
| "endmodule\n"}, | |
| {// parameterized module with 'parameter_declaration' and packed dimensions | |
| "module foo #(parameter logic [3:0] a = 2, parameter logic [30:0] aa = " | |
| "22);\n" | |
| "endmodule\n", | |
| "module foo #(\n" | |
| " parameter logic [ 3:0] a = 2,\n" | |
| " parameter logic [30:0] aa = 22\n" | |
| ");\n" | |
| "endmodule\n"}, | |
| {// parameterized module with 'parameter_declaration' and unpacked | |
| // dimensions | |
| "module foo #(parameter logic a[3:0] = 2, parameter logic aa [30:0] = " | |
| "22);\n" | |
| "endmodule\n", | |
| "module foo #(\n" | |
| " parameter logic a [ 3:0] = 2,\n" | |
| " parameter logic aa[30:0] = 22\n" | |
| ");\n" | |
| "endmodule\n"}, | |
| {// parameterized module with 'local_parameter_declaration' | |
| "module foo #(localparam int a = 2, localparam int aa = 22);\n" | |
| "endmodule\n", | |
| "module foo #(\n" | |
| " localparam int a = 2,\n" | |
| " localparam int aa = 22\n" | |
| ");\n" | |
| "endmodule\n"}, | |
| {// parameterized module with 'local_parameter_declaration' and comments | |
| "module foo #(//comment\nlocalparam int a = 2, localparam int aa = 22);\n" | |
| "endmodule\n", | |
| "module foo #( //comment\n" | |
| " localparam int a = 2,\n" | |
| " localparam int aa = 22\n" | |
| ");\n" | |
| "endmodule\n"}, | |
| {// parameterized module with 'local_parameter_declaration' and trailing | |
| // comments | |
| "module foo #(localparam int a = 2,//comment\n localparam int aa = 22);\n" | |
| "endmodule\n", | |
| "module foo #(\n" | |
| " localparam int a = 2, //comment\n" | |
| " localparam int aa = 22\n" | |
| ");\n" | |
| "endmodule\n"}, | |
| {// parameterized module with 'local_parameter_declaration' and pre-proc | |
| "module foo #(localparam int a = 2,\n" | |
| "`ifdef MACRO localparam int aa = 22, `endif\n" | |
| "localparam int aaa = 222);\n" | |
| "endmodule\n", | |
| "module foo #(\n" | |
| " localparam int a = 2,\n" | |
| "`ifdef MACRO\n" | |
| " localparam int aa = 22,\n" | |
| "`endif\n" | |
| " localparam int aaa = 222\n" | |
| ");\n" | |
| "endmodule\n"}, | |
| {// parameterized module with 'local_parameter_declaration' and packed | |
| // dimensions | |
| "module foo #(localparam logic [3:0] a = 2, localparam logic [30:0] aa = " | |
| "22);\n" | |
| "endmodule\n", | |
| "module foo #(\n" | |
| " localparam logic [ 3:0] a = 2,\n" | |
| " localparam logic [30:0] aa = 22\n" | |
| ");\n" | |
| "endmodule\n"}, | |
| {// parameterized module with 'local_parameter_declaration' and unpacked | |
| // dimensions | |
| "module foo #(localparam logic a[3:0] = 2, localparam logic aa [30:0] = " | |
| "22);\n" | |
| "endmodule\n", | |
| "module foo #(\n" | |
| " localparam logic a [ 3:0] = 2,\n" | |
| " localparam logic aa[30:0] = 22\n" | |
| ");\n" | |
| "endmodule\n"}, | |
| {// parameterized module with 'data_type list_of_param_assignments' | |
| "module foo #( int a = 2, real aa = 22, longint aaa = 222);\n" | |
| "endmodule\n", | |
| "module foo #(\n" | |
| " int a = 2,\n" | |
| " real aa = 22,\n" | |
| " longint aaa = 222\n" | |
| ");\n" | |
| "endmodule\n"}, | |
| {// parameterized module with 'data_type list_of_param_assignments' and | |
| // comments | |
| "module foo #(//comment\nint a = 2, shortreal aa = 22, longint aaa = " | |
| "222);\n" | |
| "endmodule\n", | |
| "module foo #( //comment\n" | |
| " int a = 2,\n" | |
| " shortreal aa = 22,\n" | |
| " longint aaa = 222\n" | |
| ");\n" | |
| "endmodule\n"}, | |
| {// parameterized module with 'data_type list_of_param_assignments' and | |
| // trailing comments | |
| "module foo #(int a = 2, shortreal aa = 22,//comment\n longint aaa = " | |
| "222);\n" | |
| "endmodule\n", | |
| "module foo #(\n" | |
| " int a = 2,\n" | |
| " shortreal aa = 22, //comment\n" | |
| " longint aaa = 222\n" | |
| ");\n" | |
| "endmodule\n"}, | |
| {// parameterized module with 'data_type list_of_param_assignments' and | |
| // pre-proc | |
| "module foo #(int a = 2,\n" | |
| "`ifdef MACRO shortreal aa = 22, `endif\n" | |
| " longint aaa = 222);\n" | |
| "endmodule\n", | |
| "module foo #(\n" | |
| " int a = 2,\n" | |
| "`ifdef MACRO\n" | |
| " shortreal aa = 22,\n" | |
| "`endif\n" | |
| " longint aaa = 222\n" | |
| ");\n" | |
| "endmodule\n"}, | |
| {// parameterized module with 'data_type list_of_param_assignments' and | |
| // packed dimensions | |
| "module foo #(bit [1:0] a = 2, reg [12:0] aa = 22, logic [123:0] aaa = " | |
| "222);\n" | |
| "endmodule\n", | |
| "module foo #(\n" | |
| " bit [ 1:0] a = 2,\n" | |
| " reg [ 12:0] aa = 22,\n" | |
| " logic [123:0] aaa = 222\n" | |
| ");\n" | |
| "endmodule\n"}, | |
| {// parameterized module with 'data_type list_of_param_assignments' and | |
| // unpacked dimensions | |
| "module foo #(bit a[1:0] = 2, reg aa[12:0] = 22, logic aaa [123:0] = " | |
| "222);\n" | |
| "endmodule\n", | |
| "module foo #(\n" | |
| " bit a [ 1:0] = 2,\n" | |
| " reg aa [ 12:0] = 22,\n" | |
| " logic aaa[123:0] = 222\n" | |
| ");\n" | |
| "endmodule\n"}, | |
| {// parameterized module with 'type list_of_type_assignments' | |
| "module foo #(type T = int, type TT = bit, type TTT= C#(logic) );\n" | |
| "endmodule\n", | |
| "module foo #(\n" | |
| " type T = int,\n" | |
| " type TT = bit,\n" | |
| " type TTT = C#(logic)\n" | |
| ");\n" | |
| "endmodule\n"}, | |
| {// parameterized module with 'type list_of_type_assignments' and comments | |
| "module foo #(//comment\ntype T = int, type TT = bit, type TTT= C#(logic) " | |
| ");\n" | |
| "endmodule\n", | |
| "module foo #( //comment\n" | |
| " type T = int,\n" | |
| " type TT = bit,\n" | |
| " type TTT = C#(logic)\n" | |
| ");\n" | |
| "endmodule\n"}, | |
| {// parameterized module with 'data_type list_of_param_assignments' and | |
| // trailing comments | |
| "module foo #(type T = int, type TT = bit, //comment\n type TTT= " | |
| "C#(logic) );\n" | |
| "endmodule\n", | |
| "module foo #(\n" | |
| " type T = int,\n" | |
| " type TT = bit, //comment\n" | |
| " type TTT = C#(logic)\n" | |
| ");\n" | |
| "endmodule\n"}, | |
| {// parameterized module with 'data_type list_of_param_assignments' and | |
| // pre-proc | |
| "module foo #(type T = int,\n" | |
| "`ifdef MACRO type TT = bit, `endif\n" | |
| " type TTT= C#(logic));\n" | |
| "endmodule\n", | |
| "module foo #(\n" | |
| " type T = int,\n" | |
| "`ifdef MACRO\n" | |
| " type TT = bit,\n" | |
| "`endif\n" | |
| " type TTT = C#(logic)\n" | |
| ");\n" | |
| "endmodule\n"}, | |
| {// parameterized module with 'data_type list_of_param_assignments' and | |
| // packed dimensions | |
| "module foo #(type T = int [3:0], type TT = bit [250:0]);\n" | |
| "endmodule\n", | |
| "module foo #(\n" | |
| " type T = int [ 3:0],\n" | |
| " type TT = bit [250:0]\n" | |
| ");\n" | |
| "endmodule\n"}, | |
| {"module foo #(type T = int, " | |
| "A = 2, int AA = 22, parameter AAA = 222, parameter longint AAAA = 2222, " | |
| "localparam AAAAA = 22222, localparam real AAAAAA = 222222" | |
| ");\n" | |
| "endmodule\n", | |
| "module foo #(\n" | |
| " type T = int,\n" | |
| " A = 2,\n" | |
| " int AA = 22,\n" | |
| " parameter AAA = 222,\n" | |
| " parameter longint AAAA = 2222,\n" | |
| " localparam AAAAA = 22222,\n" | |
| " localparam real AAAAAA = 222222\n" | |
| ");\n" | |
| "endmodule\n"}, | |
| {// parameterized module with built-in data type | |
| "module foo #(int a = 2, real abc = 2234);\n" | |
| "endmodule\n", | |
| "module foo #(\n" | |
| " int a = 2,\n" | |
| " real abc = 2234\n" | |
| ");\n" | |
| "endmodule\n"}, | |
| {// parameterized module with type | |
| "module foo #(type TYPE1 = int, type TYPE2 = boo);\n" | |
| "endmodule\n", | |
| "module foo #(\n" | |
| " type TYPE1 = int,\n" | |
| " type TYPE2 = boo\n" | |
| ");\n" | |
| "endmodule\n"}, | |
| {"module foo#(localparam type TYPE1 = int, type TYPE22 = bool, parameter " | |
| " type TYPE333 = real);\n" | |
| "endmodule\n", | |
| "module foo #(\n" | |
| " localparam type TYPE1 = int,\n" | |
| " type TYPE22 = bool,\n" | |
| " parameter type TYPE333 = real\n" | |
| ");\n" | |
| "endmodule\n"}, | |
| {// parameterized module with 'data_type list_of_param_assignments' and 1D | |
| // packed dimensions | |
| "module foo #(parameter type T = int [3:0], type TT = bit [123:0]);\n" | |
| "endmodule\n", | |
| "module foo #(\n" | |
| " parameter type T = int [ 3:0],\n" | |
| " type TT = bit [123:0]\n" | |
| ");\n" | |
| "endmodule\n"}, | |
| {// parameterized module with 'data_type list_of_param_assignments' and 2D | |
| // packed dimensions | |
| "module foo #(type T = int [3:0][123:0], type TT = bit [123:0][1:0]);\n" | |
| "endmodule\n", | |
| "module foo #(\n" | |
| " type T = int [ 3:0][123:0],\n" | |
| " type TT = bit [123:0][ 1:0]\n" | |
| ");\n" | |
| "endmodule\n"}, | |
| {// parametrized module with user defined data types | |
| "module foo #(type T = my_type1_t, type TT = my_pkg::my_type2_t);\n" | |
| "endmodule\n", | |
| "module foo #(\n" | |
| " type T = my_type1_t,\n" | |
| " type TT = my_pkg::my_type2_t\n" | |
| ");\n" | |
| "endmodule\n"}, | |
| {// parameterized class with 'list_of_param_assignments' | |
| "class foo #(A = 2, AA = 22, AAA = 222);\n" | |
| "endclass\n", | |
| "class foo #(\n" | |
| " A = 2,\n" | |
| " AA = 22,\n" | |
| " AAA = 222\n" | |
| ");\n" | |
| "endclass\n"}, | |
| {// parameterized class with 'parameter_declaration' | |
| "class foo #(parameter int a = 2, parameter int aa = 22);\n" | |
| "endclass\n", | |
| "class foo #(\n" | |
| " parameter int a = 2,\n" | |
| " parameter int aa = 22\n" | |
| ");\n" | |
| "endclass\n"}, | |
| {// parameterized class with 'parameter_declaration' and comments | |
| "class foo #(//comment\nparameter int a = 2, parameter int aa = 22);\n" | |
| "endclass\n", | |
| "class foo #( //comment\n" | |
| " parameter int a = 2,\n" | |
| " parameter int aa = 22\n" | |
| ");\n" | |
| "endclass\n"}, | |
| {// parameterized class with 'parameter_declaration' and trailing comments | |
| "class foo #(parameter int a = 2,//comment\n parameter int aa = 22);\n" | |
| "endclass\n", | |
| "class foo #(\n" | |
| " parameter int a = 2, //comment\n" | |
| " parameter int aa = 22\n" | |
| ");\n" | |
| "endclass\n"}, | |
| {// parameterized class with 'parameter_declaration' and pre-proc | |
| "class foo #(parameter int a = 2,\n" | |
| "`ifdef MACRO parameter int aa = 22, `endif\n" | |
| "parameter int aaa = 222);\n" | |
| "endclass\n", | |
| "class foo #(\n" | |
| " parameter int a = 2,\n" | |
| "`ifdef MACRO\n" | |
| " parameter int aa = 22,\n" | |
| "`endif\n" | |
| " parameter int aaa = 222\n" | |
| ");\n" | |
| "endclass\n"}, | |
| {// parameterized class with 'parameter_declaration' and packed dimensions | |
| "class foo #(parameter logic [3:0] a = 2, parameter logic [30:0] aa = " | |
| "22);\n" | |
| "endclass\n", | |
| "class foo #(\n" | |
| " parameter logic [ 3:0] a = 2,\n" | |
| " parameter logic [30:0] aa = 22\n" | |
| ");\n" | |
| "endclass\n"}, | |
| {// parameterized class with 'parameter_declaration' and unpacked dimensions | |
| "class foo #(parameter logic a[3:0] = 2, parameter logic aa [30:0] = " | |
| "22);\n" | |
| "endclass\n", | |
| "class foo #(\n" | |
| " parameter logic a [ 3:0] = 2,\n" | |
| " parameter logic aa[30:0] = 22\n" | |
| ");\n" | |
| "endclass\n"}, | |
| {// parameterized class with 'local_parameter_declaration' | |
| "class foo #(localparam int a = 2, localparam int aa = 22);\n" | |
| "endclass\n", | |
| "class foo #(\n" | |
| " localparam int a = 2,\n" | |
| " localparam int aa = 22\n" | |
| ");\n" | |
| "endclass\n"}, | |
| {// parameterized class with 'local_parameter_declaration' and comments | |
| "class foo #(//comment\nlocalparam int a = 2, localparam int aa = 22);\n" | |
| "endclass\n", | |
| "class foo #( //comment\n" | |
| " localparam int a = 2,\n" | |
| " localparam int aa = 22\n" | |
| ");\n" | |
| "endclass\n"}, | |
| {// parameterized class with 'local_parameter_declaration' and trailing | |
| // comments | |
| "class foo #(localparam int a = 2,//comment\n localparam int aa = 22);\n" | |
| "endclass\n", | |
| "class foo #(\n" | |
| " localparam int a = 2, //comment\n" | |
| " localparam int aa = 22\n" | |
| ");\n" | |
| "endclass\n"}, | |
| {// parameterized class with 'local_parameter_declaration' and pre-proc | |
| "class foo #(localparam int a = 2,\n" | |
| "`ifdef MACRO localparam int aa = 22, `endif\n" | |
| "localparam int aaa = 222);\n" | |
| "endclass\n", | |
| "class foo #(\n" | |
| " localparam int a = 2,\n" | |
| "`ifdef MACRO\n" | |
| " localparam int aa = 22,\n" | |
| "`endif\n" | |
| " localparam int aaa = 222\n" | |
| ");\n" | |
| "endclass\n"}, | |
| {// parameterized class with 'local_parameter_declaration' and packed | |
| // dimensions | |
| "class foo #(localparam logic [3:0] a = 2, localparam logic [30:0] aa = " | |
| "22);\n" | |
| "endclass\n", | |
| "class foo #(\n" | |
| " localparam logic [ 3:0] a = 2,\n" | |
| " localparam logic [30:0] aa = 22\n" | |
| ");\n" | |
| "endclass\n"}, | |
| {// parameterized class with 'local_parameter_declaration' and unpacked | |
| // dimensions | |
| "class foo #(localparam logic a[3:0] = 2, localparam logic aa [30:0] = " | |
| "22);\n" | |
| "endclass\n", | |
| "class foo #(\n" | |
| " localparam logic a [ 3:0] = 2,\n" | |
| " localparam logic aa[30:0] = 22\n" | |
| ");\n" | |
| "endclass\n"}, | |
| {// parameterized class with 'data_type list_of_param_assignments' | |
| "class foo #( int a = 2, real aa = 22, longint aaa = 222);\n" | |
| "endclass\n", | |
| "class foo #(\n" | |
| " int a = 2,\n" | |
| " real aa = 22,\n" | |
| " longint aaa = 222\n" | |
| ");\n" | |
| "endclass\n"}, | |
| {// parameterized class with 'data_type list_of_param_assignments' and | |
| // comments | |
| "class foo #(//comment\nint a = 2, shortreal aa = 22, longint aaa = " | |
| "222);\n" | |
| "endclass\n", | |
| "class foo #( //comment\n" | |
| " int a = 2,\n" | |
| " shortreal aa = 22,\n" | |
| " longint aaa = 222\n" | |
| ");\n" | |
| "endclass\n"}, | |
| {// parameterized class with 'data_type list_of_param_assignments' and | |
| // trailing comments | |
| "class foo #(int a = 2, shortreal aa = 22,//comment\n longint aaa = " | |
| "222);\n" | |
| "endclass\n", | |
| "class foo #(\n" | |
| " int a = 2,\n" | |
| " shortreal aa = 22, //comment\n" | |
| " longint aaa = 222\n" | |
| ");\n" | |
| "endclass\n"}, | |
| {// parameterized class with 'data_type list_of_param_assignments' and | |
| // pre-proc | |
| "class foo #(int a = 2,\n" | |
| "`ifdef MACRO shortreal aa = 22, `endif\n" | |
| " longint aaa = 222);\n" | |
| "endclass\n", | |
| "class foo #(\n" | |
| " int a = 2,\n" | |
| "`ifdef MACRO\n" | |
| " shortreal aa = 22,\n" | |
| "`endif\n" | |
| " longint aaa = 222\n" | |
| ");\n" | |
| "endclass\n"}, | |
| {// parameterized class with 'data_type list_of_param_assignments' and | |
| // packed dimensions | |
| "class foo #(bit [1:0] a = 2, reg [12:0] aa = 22, logic [123:0] aaa = " | |
| "222);\n" | |
| "endclass\n", | |
| "class foo #(\n" | |
| " bit [ 1:0] a = 2,\n" | |
| " reg [ 12:0] aa = 22,\n" | |
| " logic [123:0] aaa = 222\n" | |
| ");\n" | |
| "endclass\n"}, | |
| {// parameterized class with 'data_type list_of_param_assignments' and | |
| // unpacked dimensions | |
| "class foo #(bit a[1:0] = 2, reg aa[12:0] = 22, logic aaa [123:0] = " | |
| "222);\n" | |
| "endclass\n", | |
| "class foo #(\n" | |
| " bit a [ 1:0] = 2,\n" | |
| " reg aa [ 12:0] = 22,\n" | |
| " logic aaa[123:0] = 222\n" | |
| ");\n" | |
| "endclass\n"}, | |
| {// parameterized class with 'type list_of_type_assignments' | |
| "class foo #(type T = int, type TT = bit, type TTT= C#(logic) );\n" | |
| "endclass\n", | |
| "class foo #(\n" | |
| " type T = int,\n" | |
| " type TT = bit,\n" | |
| " type TTT = C#(logic)\n" | |
| ");\n" | |
| "endclass\n"}, | |
| {// parameterized class with 'type list_of_type_assignments' and comments | |
| "class foo #(//comment\ntype T = int, type TT = bit, type TTT= C#(logic) " | |
| ");\n" | |
| "endclass\n", | |
| "class foo #( //comment\n" | |
| " type T = int,\n" | |
| " type TT = bit,\n" | |
| " type TTT = C#(logic)\n" | |
| ");\n" | |
| "endclass\n"}, | |
| {// parameterized class with 'data_type list_of_param_assignments' and | |
| // trailing comments | |
| "class foo #(type T = int, type TT = bit, //comment\n type TTT= C#(logic) " | |
| ");\n" | |
| "endclass\n", | |
| "class foo #(\n" | |
| " type T = int,\n" | |
| " type TT = bit, //comment\n" | |
| " type TTT = C#(logic)\n" | |
| ");\n" | |
| "endclass\n"}, | |
| {// parameterized class with 'data_type list_of_param_assignments' and | |
| // pre-proc | |
| "class foo #(type T = int,\n" | |
| "`ifdef MACRO type TT = bit, `endif\n" | |
| " type TTT= C#(logic));\n" | |
| "endclass\n", | |
| "class foo #(\n" | |
| " type T = int,\n" | |
| "`ifdef MACRO\n" | |
| " type TT = bit,\n" | |
| "`endif\n" | |
| " type TTT = C#(logic)\n" | |
| ");\n" | |
| "endclass\n"}, | |
| {// parameterized class with 'data_type list_of_param_assignments' and | |
| // packed dimensions | |
| "class foo #(type T = int [3:0], type TT = bit [250:0]);\n" | |
| "endclass\n", | |
| "class foo #(\n" | |
| " type T = int [ 3:0],\n" | |
| " type TT = bit [250:0]\n" | |
| ");\n" | |
| "endclass\n"}, | |
| {"class foo #(type T = int, " | |
| "A = 2, int AA = 22, parameter AAA = 222, parameter longint AAAA = 2222, " | |
| "localparam AAAAA = 22222, localparam real AAAAAA = 222222" | |
| ");\n" | |
| "endclass\n", | |
| "class foo #(\n" | |
| " type T = int,\n" | |
| " A = 2,\n" | |
| " int AA = 22,\n" | |
| " parameter AAA = 222,\n" | |
| " parameter longint AAAA = 2222,\n" | |
| " localparam AAAAA = 22222,\n" | |
| " localparam real AAAAAA = 222222\n" | |
| ");\n" | |
| "endclass\n"}, | |
| {// parameterized class with built-in data type | |
| "class foo #(int a = 2, real abc = 2234);\n" | |
| "endclass\n", | |
| "class foo #(\n" | |
| " int a = 2,\n" | |
| " real abc = 2234\n" | |
| ");\n" | |
| "endclass\n"}, | |
| {// parameterized class with type | |
| "class foo #(type TYPE1 = int, type TYPE2 = boo);\n" | |
| "endclass\n", | |
| "class foo #(\n" | |
| " type TYPE1 = int,\n" | |
| " type TYPE2 = boo\n" | |
| ");\n" | |
| "endclass\n"}, | |
| {"class foo#(localparam type TYPE1 = int, type TYPE22 = bool, parameter " | |
| "type TYPE333 = real);\n" | |
| "endclass\n", | |
| "class foo #(\n" | |
| " localparam type TYPE1 = int,\n" | |
| " type TYPE22 = bool,\n" | |
| " parameter type TYPE333 = real\n" | |
| ");\n" | |
| "endclass\n"}, | |
| {// parameterized class with 'data_type list_of_param_assignments' and 1D | |
| // packed dimensions | |
| "class foo #(parameter type T = int [3:0], type TT = bit [123:0]);\n" | |
| "endclass\n", | |
| "class foo #(\n" | |
| " parameter type T = int [ 3:0],\n" | |
| " type TT = bit [123:0]\n" | |
| ");\n" | |
| "endclass\n"}, | |
| {// parameterized class with 'data_type list_of_param_assignments' and 2D | |
| // packed dimensions | |
| "class foo #(type T = int [3:0][123:0], type TT = bit [123:0][1:0]);\n" | |
| "endclass\n", | |
| "class foo #(\n" | |
| " type T = int [ 3:0][123:0],\n" | |
| " type TT = bit [123:0][ 1:0]\n" | |
| ");\n" | |
| "endclass\n"}, | |
| {// parametrized class with user defined data types | |
| "class foo #(type T = my_type1_t, type TT = my_pkg::my_type2_t);\n" | |
| "endclass\n", | |
| "class foo #(\n" | |
| " type T = my_type1_t,\n" | |
| " type TT = my_pkg::my_type2_t\n" | |
| ");\n" | |
| "endclass\n"}, | |
| {// parameterized interface with 'local_parameter_declaration' | |
| "interface foo #(localparam int a = 2, localparam int aa = 22);\n" | |
| "endinterface\n", | |
| "interface foo #(\n" | |
| " localparam int a = 2,\n" | |
| " localparam int aa = 22\n" | |
| ");\n" | |
| "endinterface\n"}, | |
| {// parameterized interface with 'local_parameter_declaration' and comments | |
| "interface foo #(//comment\nlocalparam int a = 2, localparam int aa = " | |
| "22);\n" | |
| "endinterface\n", | |
| "interface foo #( //comment\n" | |
| " localparam int a = 2,\n" | |
| " localparam int aa = 22\n" | |
| ");\n" | |
| "endinterface\n"}, | |
| {// parameterized interface with 'local_parameter_declaration' and trailing | |
| // comments | |
| "interface foo #(localparam int a = 2,//comment\n localparam int aa = " | |
| "22);\n" | |
| "endinterface\n", | |
| "interface foo #(\n" | |
| " localparam int a = 2, //comment\n" | |
| " localparam int aa = 22\n" | |
| ");\n" | |
| "endinterface\n"}, | |
| {// parameterized interface with 'local_parameter_declaration' and pre-proc | |
| "interface foo #(localparam int a = 2,\n" | |
| "`ifdef MACRO localparam int aa = 22, `endif\n" | |
| "localparam int aaa = 222);\n" | |
| "endinterface\n", | |
| "interface foo #(\n" | |
| " localparam int a = 2,\n" | |
| "`ifdef MACRO\n" | |
| " localparam int aa = 22,\n" | |
| "`endif\n" | |
| " localparam int aaa = 222\n" | |
| ");\n" | |
| "endinterface\n"}, | |
| {// parameterized interface with 'local_parameter_declaration' and packed | |
| // dimensions | |
| "interface foo #(localparam logic [3:0] a = 2, localparam logic [30:0] aa " | |
| "= 22);\n" | |
| "endinterface\n", | |
| "interface foo #(\n" | |
| " localparam logic [ 3:0] a = 2,\n" | |
| " localparam logic [30:0] aa = 22\n" | |
| ");\n" | |
| "endinterface\n"}, | |
| {// parameterized interface with 'local_parameter_declaration' and unpacked | |
| // dimensions | |
| "interface foo #(localparam logic a[3:0] = 2, localparam logic aa [30:0] " | |
| "= 22);\n" | |
| "endinterface\n", | |
| "interface foo #(\n" | |
| " localparam logic a [ 3:0] = 2,\n" | |
| " localparam logic aa[30:0] = 22\n" | |
| ");\n" | |
| "endinterface\n"}, | |
| {// parameterized interface with 'data_type list_of_param_assignments' | |
| "interface foo #( int a = 2, real aa = 22, longint aaa = 222);\n" | |
| "endinterface\n", | |
| "interface foo #(\n" | |
| " int a = 2,\n" | |
| " real aa = 22,\n" | |
| " longint aaa = 222\n" | |
| ");\n" | |
| "endinterface\n"}, | |
| {// parameterized interface with 'data_type list_of_param_assignments' and | |
| // comments | |
| "interface foo #(//comment\nint a = 2, shortreal aa = 22, longint aaa = " | |
| "222);\n" | |
| "endinterface\n", | |
| "interface foo #( //comment\n" | |
| " int a = 2,\n" | |
| " shortreal aa = 22,\n" | |
| " longint aaa = 222\n" | |
| ");\n" | |
| "endinterface\n"}, | |
| {// parameterized interface with 'data_type list_of_param_assignments' and | |
| // trailing comments | |
| "interface foo #(int a = 2, shortreal aa = 22,//comment\n longint aaa = " | |
| "222);\n" | |
| "endinterface\n", | |
| "interface foo #(\n" | |
| " int a = 2,\n" | |
| " shortreal aa = 22, //comment\n" | |
| " longint aaa = 222\n" | |
| ");\n" | |
| "endinterface\n"}, | |
| {// parameterized interface with 'data_type list_of_param_assignments' and | |
| // pre-proc | |
| "interface foo #(int a = 2,\n" | |
| "`ifdef MACRO shortreal aa = 22, `endif\n" | |
| " longint aaa = 222);\n" | |
| "endinterface\n", | |
| "interface foo #(\n" | |
| " int a = 2,\n" | |
| "`ifdef MACRO\n" | |
| " shortreal aa = 22,\n" | |
| "`endif\n" | |
| " longint aaa = 222\n" | |
| ");\n" | |
| "endinterface\n"}, | |
| {// parameterized interface with 'data_type list_of_param_assignments' and | |
| // packed dimensions | |
| "interface foo #(bit [1:0] a = 2, reg [12:0] aa = 22, logic [123:0] aaa " | |
| "= 222);\n" | |
| "endinterface\n", | |
| "interface foo #(\n" | |
| " bit [ 1:0] a = 2,\n" | |
| " reg [ 12:0] aa = 22,\n" | |
| " logic [123:0] aaa = 222\n" | |
| ");\n" | |
| "endinterface\n"}, | |
| {// parameterized interface with 'data_type list_of_param_assignments' and | |
| // unpacked dimensions | |
| "interface foo #(bit a[1:0] = 2, reg aa[12:0] = 22, logic aaa [123:0] " | |
| "= 222);\n" | |
| "endinterface\n", | |
| "interface foo #(\n" | |
| " bit a [ 1:0] = 2,\n" | |
| " reg aa [ 12:0] = 22,\n" | |
| " logic aaa[123:0] = 222\n" | |
| ");\n" | |
| "endinterface\n"}, | |
| {// parameterized interface with 'type list_of_type_assignments' | |
| "interface foo #(type T = int, type TT = bit, type TTT= C#(logic) );\n" | |
| "endinterface\n", | |
| "interface foo #(\n" | |
| " type T = int,\n" | |
| " type TT = bit,\n" | |
| " type TTT = C#(logic)\n" | |
| ");\n" | |
| "endinterface\n"}, | |
| {// parameterized interface with 'type list_of_type_assignments' and | |
| // comments | |
| "interface foo #(//comment\ntype T = int, type TT = bit, type TTT= " | |
| "C#(logic) );\n" | |
| "endinterface\n", | |
| "interface foo #( //comment\n" | |
| " type T = int,\n" | |
| " type TT = bit,\n" | |
| " type TTT = C#(logic)\n" | |
| ");\n" | |
| "endinterface\n"}, | |
| {// parameterized interface with 'data_type list_of_param_assignments' and | |
| // trailing comments | |
| "interface foo #(type T = int, type TT = bit, //comment\n type TTT= " | |
| "C#(logic) );\n" | |
| "endinterface\n", | |
| "interface foo #(\n" | |
| " type T = int,\n" | |
| " type TT = bit, //comment\n" | |
| " type TTT = C#(logic)\n" | |
| ");\n" | |
| "endinterface\n"}, | |
| {// parameterized interface with 'data_type list_of_param_assignments' and | |
| // pre-proc | |
| "interface foo #(type T = int,\n" | |
| "`ifdef MACRO type TT = bit, `endif\n" | |
| " type TTT= C#(logic));\n" | |
| "endinterface\n", | |
| "interface foo #(\n" | |
| " type T = int,\n" | |
| "`ifdef MACRO\n" | |
| " type TT = bit,\n" | |
| "`endif\n" | |
| " type TTT = C#(logic)\n" | |
| ");\n" | |
| "endinterface\n"}, | |
| {// parameterized interface with 'data_type list_of_param_assignments' and | |
| // packed dimensions | |
| "interface foo #(type T = int [3:0], type TT = bit [250:0]);\n" | |
| "endinterface\n", | |
| "interface foo #(\n" | |
| " type T = int [ 3:0],\n" | |
| " type TT = bit [250:0]\n" | |
| ");\n" | |
| "endinterface\n"}, | |
| {"interface foo #(type T = int, " | |
| "A = 2, int AA = 22, parameter AAA = 222, parameter longint AAAA = 2222, " | |
| "localparam AAAAA = 22222, localparam real AAAAAA = 222222" | |
| ");\n" | |
| "endinterface\n", | |
| "interface foo #(\n" | |
| " type T = int,\n" | |
| " A = 2,\n" | |
| " int AA = 22,\n" | |
| " parameter AAA = 222,\n" | |
| " parameter longint AAAA = 2222,\n" | |
| " localparam AAAAA = 22222,\n" | |
| " localparam real AAAAAA = 222222\n" | |
| ");\n" | |
| "endinterface\n"}, | |
| {// parameterized interface with built-in data type | |
| "interface foo #(int a = 2, real abc = 2234);\n" | |
| "endinterface\n", | |
| "interface foo #(\n" | |
| " int a = 2,\n" | |
| " real abc = 2234\n" | |
| ");\n" | |
| "endinterface\n"}, | |
| {// parameterized interface with type | |
| "interface foo #(type TYPE1 = int, type TYPE2 = boo);\n" | |
| "endinterface\n", | |
| "interface foo #(\n" | |
| " type TYPE1 = int,\n" | |
| " type TYPE2 = boo\n" | |
| ");\n" | |
| "endinterface\n"}, | |
| {"interface foo#(localparam type TYPE1 = int, type TYPE22 = bool, " | |
| "parameter type TYPE333 = real);\n" | |
| "endinterface\n", | |
| "interface foo #(\n" | |
| " localparam type TYPE1 = int,\n" | |
| " type TYPE22 = bool,\n" | |
| " parameter type TYPE333 = real\n" | |
| ");\n" | |
| "endinterface\n"}, | |
| {// parameterized interface with 'data_type list_of_param_assignments' and | |
| // 1D packed dimensions | |
| "interface foo #(parameter type T = int [3:0], type TT = bit [123:0]);\n" | |
| "endinterface\n", | |
| "interface foo #(\n" | |
| " parameter type T = int [ 3:0],\n" | |
| " type TT = bit [123:0]\n" | |
| ");\n" | |
| "endinterface\n"}, | |
| {// parameterized interface with 'data_type list_of_param_assignments' and | |
| // 2D packed dimensions | |
| "interface foo #(type T = int [3:0][123:0], type TT = bit [123:0][1:0]);\n" | |
| "endinterface\n", | |
| "interface foo #(\n" | |
| " type T = int [ 3:0][123:0],\n" | |
| " type TT = bit [123:0][ 1:0]\n" | |
| ");\n" | |
| "endinterface\n"}, | |
| {// parametrized interface with user defined data types | |
| "interface foo #(type T = my_type1_t, type TT = my_pkg::my_type2_t);\n" | |
| "endinterface\n", | |
| "interface foo #(\n" | |
| " type T = my_type1_t,\n" | |
| " type TT = my_pkg::my_type2_t\n" | |
| ");\n" | |
| "endinterface\n"}, | |
| //{ // parameterized class with 'parameter_declaration' and MACRO | |
| // "class foo #(parameter int a = 2,\n" | |
| // "parameter int aaa = `MACRO);\n" | |
| // "endclass\n", | |
| // "class foo #(\n" | |
| // " parameter int a = 2,\n" | |
| // " parameter int aaa = `MACRO\n" | |
| // ");\n" | |
| // "endclass\n" | |
| //}, | |
| }; | |
| // Tests that formatter produces expected results, end-to-end. | |
| TEST(FormatterEndToEndTest, VerilogFormatTest) { | |
| // Use a fixed style. | |
| FormatStyle style; | |
| style.column_limit = 40; | |
| style.indentation_spaces = 2; | |
| style.wrap_spaces = 4; | |
| for (const auto& test_case : kFormatterTestCases) { | |
| VLOG(1) << "code-to-format:\n" << test_case.input << "<EOF>"; | |
| std::ostringstream stream; | |
| const auto status = | |
| FormatVerilog(test_case.input, "<filename>", style, stream); | |
| // Require these test cases to be valid. | |
| EXPECT_OK(status) << status.message(); | |
| EXPECT_EQ(stream.str(), test_case.expected) << "code:\n" << test_case.input; | |
| } | |
| } | |
| TEST(FormatterEndToEndTest, AutoInferAlignment) { | |
| static constexpr FormatterTestCase kTestCases[] = { | |
| {"", ""}, | |
| {"\n", "\n"}, | |
| {"class cc ;\n" | |
| "endclass:cc\n", | |
| "class cc;\n" | |
| "endclass : cc\n"}, | |
| // module port declarations | |
| {"module pd(\n" | |
| "input wire foo,\n" | |
| "output reg bar\n" | |
| ");\n" | |
| "endmodule:pd\n", | |
| "module pd (\n" | |
| " input wire foo,\n" // flush-left vs. align are similar enough, | |
| " output reg bar\n" // so automatic policy will align. | |
| ");\n" | |
| "endmodule : pd\n"}, | |
| {"module pd(\n" | |
| "input foo_pkg::baz_t foo,\n" | |
| "output reg bar\n" | |
| ");\n" | |
| "endmodule:pd\n", | |
| "module pd (\n" | |
| " input foo_pkg::baz_t foo,\n" // alignment would add too many spaces | |
| " output reg bar\n" // so infer intent to flush-left. | |
| ");\n" | |
| "endmodule : pd\n"}, | |
| {"module pd(\n" | |
| "input foo_pkg::baz_t foo,\n" | |
| "output reg bar\n" // user injects 4 excess spaces here ... | |
| ");\n" | |
| "endmodule:pd\n", | |
| "module pd (\n" | |
| " input foo_pkg::baz_t foo,\n" | |
| " output reg bar\n" // ... and triggers alignment. | |
| ");\n" | |
| "endmodule : pd\n"}, | |
| // named parameter arguments | |
| {"module mm ;\n" | |
| "foo #(\n" | |
| ".a(a),\n" | |
| ".bb(bb)\n" | |
| ")bar( );\n" | |
| "endmodule:mm\n", | |
| "module mm;\n" | |
| " foo #(\n" | |
| " .a (a),\n" // align doesn't add too many spaces, so align | |
| " .bb(bb)\n" | |
| " ) bar ();\n" | |
| "endmodule : mm\n"}, | |
| {"module mm ;\n" | |
| "foo #(\n" | |
| ".a(a),\n" | |
| ".bbcccc(bb)\n" | |
| ")bar( );\n" | |
| "endmodule:mm\n", | |
| "module mm;\n" | |
| " foo #(\n" | |
| " .a(a),\n" // align would add too many spaces, so flush-left | |
| " .bbcccc(bb)\n" | |
| " ) bar ();\n" | |
| "endmodule : mm\n"}, | |
| {"module mm ;\n" | |
| "foo #(\n" | |
| ".a(a ),\n" // user manually triggers alignment with excess spaces | |
| ".bbcccc(bb)\n" | |
| ")bar( );\n" | |
| "endmodule:mm\n", | |
| "module mm;\n" | |
| " foo #(\n" | |
| " .a (a),\n" // induced alignment | |
| " .bbcccc(bb)\n" | |
| " ) bar ();\n" | |
| "endmodule : mm\n"}, | |
| {"module mm ;\n" | |
| "foo #(\n" | |
| "//c1\n" // with comments (indented but not aligned) | |
| ".a(a ),\n" // user manually triggers alignment with excess spaces | |
| "//c2\n" | |
| ".bbcccc(bb)\n" | |
| "//c3\n" | |
| ")bar( );\n" | |
| "endmodule:mm\n", | |
| "module mm;\n" | |
| " foo #(\n" | |
| " //c1\n" | |
| " .a (a),\n" // induced alignment | |
| " //c2\n" | |
| " .bbcccc(bb)\n" | |
| " //c3\n" | |
| " ) bar ();\n" | |
| "endmodule : mm\n"}, | |
| {"module mm ;\n" | |
| "foo #(\n" | |
| ".a( (1 +2)),\n" // excess spaces, testing extra parentheses | |
| ".bbcccc((c*d)+(e*f))\n" | |
| ")bar( );\n" | |
| "endmodule:mm\n", | |
| "module mm;\n" | |
| " foo #(\n" | |
| " .a ((1 + 2)),\n" // induced alignment | |
| " .bbcccc((c * d) + (e * f))\n" | |
| " ) bar ();\n" | |
| "endmodule : mm\n"}, | |
| // named port connections | |
| {"module mm ;\n" | |
| "foo bar(\n" | |
| ".a(a),\n" | |
| ".bb(bb)\n" | |
| ");\n" | |
| "endmodule:mm\n", | |
| "module mm;\n" | |
| " foo bar (\n" | |
| " .a (a),\n" // align doesn't add too many spaces, so align | |
| " .bb(bb)\n" | |
| " );\n" | |
| "endmodule : mm\n"}, | |
| {"module mm ;\n" | |
| "foo bar(\n" | |
| ".a(a),\n" | |
| ".bbbbbb(bb)\n" | |
| ");\n" | |
| "endmodule:mm\n", | |
| "module mm;\n" | |
| " foo bar (\n" | |
| " .a(a),\n" // align would add too many spaces, so flush-left | |
| " .bbbbbb(bb)\n" | |
| " );\n" | |
| "endmodule : mm\n"}, | |
| {"module mm ;\n" | |
| "foo bar(\n" | |
| ".a (a),\n" // user manually triggers alignment with excess spaces | |
| ".bbbbbb(bb)\n" | |
| ");\n" | |
| "endmodule:mm\n", | |
| "module mm;\n" | |
| " foo bar (\n" | |
| " .a (a),\n" // alignment fixed | |
| " .bbbbbb(bb)\n" | |
| " );\n" | |
| "endmodule : mm\n"}, | |
| // net variable declarations | |
| {"module nn;\n" | |
| "wire wwwww;\n" | |
| "logic lll;\n" | |
| "endmodule : nn\n", | |
| "module nn;\n" | |
| " wire wwwww;\n" // alignment adds few spaces, so align | |
| " logic lll;\n" | |
| "endmodule : nn\n"}, | |
| {"module nn;\n" | |
| "wire wwwww;\n" | |
| "foo_pkg::baz_t lll;\n" | |
| "endmodule : nn\n", | |
| "module nn;\n" | |
| " wire wwwww;\n" // alignment adds too many spaces, so flush-left | |
| " foo_pkg::baz_t lll;\n" | |
| "endmodule : nn\n"}, | |
| {"module nn;\n" | |
| "wire wwwww;\n" // user injects spaces to trigger alignment | |
| "foo_pkg::baz_t lll;\n" | |
| "endmodule : nn\n", | |
| "module nn;\n" | |
| " wire wwwww;\n" // ... and gets alignment | |
| " foo_pkg::baz_t lll;\n" | |
| "endmodule : nn\n"}, | |
| // formal parameters | |
| {"module pp #(\n" | |
| "int W,\n" | |
| "type T\n" | |
| ") ();\n" | |
| "endmodule : pp\n", | |
| "module pp #(\n" | |
| " int W,\n" // alignment adds few spaces, so do it | |
| " type T\n" | |
| ") ();\n" | |
| "endmodule : pp\n"}, | |
| {"module pp #(\n" | |
| "int W,\n" | |
| "int[xx:yy] T\n" | |
| ") ();\n" | |
| "endmodule : pp\n", | |
| "module pp #(\n" | |
| " int W,\n" // alignment adds many spaces, so flush-left | |
| " int [xx:yy] T\n" | |
| ") ();\n" | |
| "endmodule : pp\n"}, | |
| {"module pp #(\n" | |
| "int W,\n" | |
| "int[xx:yy] T\n" // user injected spaces intentionally | |
| ") ();\n" | |
| "endmodule : pp\n", | |
| "module pp #(\n" | |
| " int W,\n" // ... trigger alignment | |
| " int [xx:yy] T\n" | |
| ") ();\n" | |
| "endmodule : pp\n"}, | |
| // class member variables | |
| {"class cc ;\n" | |
| "int my_int;\n" | |
| "bar_t my_bar;\n" | |
| "endclass:cc\n", | |
| "class cc;\n" | |
| " int my_int;\n" // align doesn't add too many spaces, so align | |
| " bar_t my_bar;\n" | |
| "endclass : cc\n"}, | |
| {"class cc ;\n" | |
| "int my_int;\n" | |
| "foo_pkg::bar_t my_bar;\n" | |
| "endclass:cc\n", | |
| "class cc;\n" | |
| " int my_int;\n" // align would add too many spaces, so flush-left | |
| " foo_pkg::bar_t my_bar;\n" | |
| "endclass : cc\n"}, | |
| {"class cc ;\n" | |
| "int my_int;\n" // intentional excessive spaces, trigger alignment | |
| "foo_pkg::bar_t my_bar;\n" | |
| "endclass:cc\n", | |
| "class cc;\n" | |
| " int my_int;\n" | |
| " foo_pkg::bar_t my_bar;\n" | |
| "endclass : cc\n"}, | |
| {"class cc ;\n" | |
| "int my_int;\n" // unable to infer user's intent, so preserve | |
| "foo_pkg::bar_t my_bar;\n" | |
| "endclass:cc\n", | |
| "class cc;\n" | |
| " int my_int;\n" // ... but still indent | |
| " foo_pkg::bar_t my_bar;\n" | |
| "endclass : cc\n"}, | |
| // case item test cases | |
| {// small difference between flush-left and align, so align | |
| "function f; case (x)kZZZZ :if( b )break; default :return 2;" | |
| "endcase endfunction\n", | |
| "function f;\n" | |
| " case (x)\n" | |
| " kZZZZ: if (b) break;\n" // aligned, only adds 2 spaces | |
| " default: return 2;\n" | |
| " endcase\n" | |
| "endfunction\n"}, | |
| {// small error relative to flush-left, so flush-left | |
| "function f; case (x)kZ :if( b )break; default :return 2;" | |
| "endcase endfunction\n", | |
| "function f;\n" | |
| " case (x)\n" | |
| " kZ: if (b) break;\n" // flush-left | |
| " default: return 2;\n" | |
| " endcase\n" | |
| "endfunction\n"}, | |
| {// intentional spacing error (delta=4) induces alignment | |
| "function f; case (x)kZ :if( b )break; default :return 2;" | |
| "endcase endfunction\n", | |
| "function f;\n" | |
| " case (x)\n" | |
| " kZ: if (b) break;\n" | |
| " default: return 2;\n" | |
| " endcase\n" | |
| "endfunction\n"}, | |
| {// induced alignment, with ignored comments | |
| "function f; case (x)kZ :if( b )break; \n//c1\n kXX: g = f; " | |
| "\n//c2\ndefault :return 2;" | |
| "endcase endfunction\n", | |
| "function f;\n" | |
| " case (x)\n" | |
| " kZ: if (b) break;\n" | |
| " //c1\n" | |
| " kXX: g = f;\n" | |
| " //c2\n" | |
| " default: return 2;\n" | |
| " endcase\n" | |
| "endfunction\n"}, | |
| {// induced alignment, ignore multiline case item in the middle | |
| "function f; case (x)" | |
| "kZ :if( b )break; " | |
| "kYY :return 2;" // excess spaces induce alignment | |
| " kXXXXXXXXX: begin end" // multi-line, ignored | |
| " kWWWWW: cc = 23;\n" | |
| " kVVV: cd = 24;\n" | |
| "endcase endfunction\n", | |
| "function f;\n" | |
| " case (x)\n" | |
| " kZ: if (b) break;\n" | |
| " kYY: return 2;\n" | |
| " kXXXXXXXXX: begin\n" // separates above/below groups | |
| " end\n" | |
| " kWWWWW: cc = 23;\n" | |
| " kVVV: cd = 24;\n" // aligned | |
| " endcase\n" | |
| "endfunction\n"}, | |
| {// induced alignment, ignore multiline case item in the middle | |
| "function f; case (x)" | |
| "kZ :if( b )break; " | |
| "kYY :return 2;" // excess spaces induce alignment | |
| " kXXXXXXXXX: if(w)begin end" // multi-line, ignored | |
| " kWWWWW: cc = 23;\n" | |
| " kVVV: cd = 24;\n" | |
| "endcase endfunction\n", | |
| "function f;\n" | |
| " case (x)\n" | |
| " kZ: if (b) break;\n" | |
| " kYY: return 2;\n" | |
| " kXXXXXXXXX:\n" // TODO(fangism): allow this to merge with if() | |
| // else indent the following two lines | |
| " if (w) begin\n" // separates above/below groups | |
| " end\n" | |
| " kWWWWW: cc = 23;\n" | |
| " kVVV: cd = 24;\n" // aligned | |
| " endcase\n" | |
| "endfunction\n"}, | |
| {// induced alignment, ignore multiline case item in the middle | |
| "task t; case (x)" | |
| "kZ :if( b )break; " | |
| "kYY :return 2;" // excess spaces induce alignment | |
| " kXXXXXXXXX: fork join" // multi-line, ignored | |
| " kWWWWW: cc = 23;\n" | |
| " kVVV: cd = 24;\n" | |
| "endcase endtask\n", | |
| "task t;\n" | |
| " case (x)\n" | |
| " kZ: if (b) break;\n" | |
| " kYY: return 2;\n" | |
| " kXXXXXXXXX:\n" // TODO(fangism): allow this to merge with fork | |
| // else indent the following two lines | |
| " fork\n" // separates above/below groups | |
| " join\n" | |
| " kWWWWW: cc = 23;\n" | |
| " kVVV: cd = 24;\n" // aligned | |
| " endcase\n" | |
| "endtask\n"}, | |
| }; | |
| // Use a fixed style. | |
| FormatStyle style; | |
| style.column_limit = 40; | |
| style.indentation_spaces = 2; | |
| style.wrap_spaces = 4; | |
| // Override some settings to test auto-inferred alignment. | |
| style.ApplyToAllAlignmentPolicies(AlignmentPolicy::kInferUserIntent); | |
| for (const auto& test_case : kTestCases) { | |
| VLOG(1) << "code-to-format:\n" << test_case.input << "<EOF>"; | |
| std::ostringstream stream; | |
| const auto status = | |
| FormatVerilog(test_case.input, "<filename>", style, stream); | |
| // Require these test cases to be valid. | |
| EXPECT_OK(status) << status.message(); | |
| EXPECT_EQ(stream.str(), test_case.expected) << "code:\n" << test_case.input; | |
| } | |
| } | |
| static constexpr FormatterTestCase kFormatterWideTestCases[] = { | |
| // specify blocks | |
| {"module specify_tests ;\n" | |
| "specify\n" // empty list | |
| "endspecify\n" | |
| "endmodule", | |
| "module specify_tests;\n" | |
| " specify\n" | |
| " endspecify\n" | |
| "endmodule\n"}, | |
| {"module specify_tests ;\n" | |
| "specify\n" | |
| "$recrem (posedge R, posedge C,\n" | |
| "t1, t2);\n" | |
| "endspecify\n" | |
| "endmodule", | |
| "module specify_tests;\n" | |
| " specify\n" | |
| " $recrem(posedge R, posedge C, t1, t2);\n" | |
| " endspecify\n" | |
| "endmodule\n"}, | |
| {"module specify_tests ;\n" | |
| "specify\n" | |
| "// TODO: add this\n" | |
| "endspecify \n" | |
| "endmodule", | |
| "module specify_tests;\n" | |
| " specify\n" | |
| " // TODO: add this\n" | |
| " endspecify\n" | |
| "endmodule\n"}, | |
| {"module specify_tests ;\n" | |
| "specify \n" | |
| " //c1\n" | |
| "$setup ( posedge A, posedge B,\n" | |
| "t1);//c2\n" | |
| " //c3\n" | |
| "$hold ( posedge B , posedge A,t2); //c4\n" | |
| "\t//c5\n" | |
| "endspecify\n" | |
| "endmodule", | |
| "module specify_tests;\n" | |
| " specify\n" | |
| " //c1\n" | |
| " $setup(posedge A, posedge B, t1); //c2\n" | |
| " //c3\n" | |
| " $hold(posedge B, posedge A, t2); //c4\n" | |
| " //c5\n" | |
| " endspecify\n" | |
| "endmodule\n"}, | |
| {"module specify_tests ;\n" | |
| "specify \n" | |
| "$setup ( posedge A, posedge B,\n" | |
| "t1);\n" | |
| "$hold ( posedge B , posedge A,t2);\n" | |
| "endspecify\n" | |
| "endmodule", | |
| "module specify_tests;\n" | |
| " specify\n" | |
| " $setup(posedge A, posedge B, t1);\n" | |
| " $hold(posedge B, posedge A, t2);\n" | |
| " endspecify\n" | |
| "endmodule\n"}, | |
| {"module specify_tests ;\n" | |
| "specify \n" | |
| " `ifdef CCC\n" | |
| "$setup ( posedge A, posedge B,\n" | |
| "t1);\n" | |
| " `else\n" | |
| "$hold ( posedge B , posedge A,t2); \n" | |
| "\t`endif\n" | |
| "endspecify\n" | |
| "endmodule", | |
| "module specify_tests;\n" | |
| " specify\n" | |
| "`ifdef CCC\n" | |
| " $setup(posedge A, posedge B, t1);\n" | |
| "`else\n" | |
| " $hold(posedge B, posedge A, t2);\n" | |
| "`endif\n" | |
| " endspecify\n" | |
| "endmodule\n"}, | |
| }; | |
| // These tests just need a larger column limit to fit on one line. | |
| TEST(FormatterEndToEndTest, VerilogFormatWideTest) { | |
| // Use a fixed style. | |
| FormatStyle style; | |
| style.column_limit = 60; | |
| style.indentation_spaces = 2; | |
| style.wrap_spaces = 4; | |
| for (const auto& test_case : kFormatterWideTestCases) { | |
| VLOG(1) << "code-to-format:\n" << test_case.input << "<EOF>"; | |
| std::ostringstream stream; | |
| const auto status = | |
| FormatVerilog(test_case.input, "<filename>", style, stream); | |
| // Require these test cases to be valid. | |
| EXPECT_OK(status) << status.message(); | |
| EXPECT_EQ(stream.str(), test_case.expected) << "code:\n" << test_case.input; | |
| } | |
| } | |
| TEST(FormatterEndToEndTest, DisableModulePortDeclarations) { | |
| static constexpr FormatterTestCase kTestCases[] = { | |
| {"", ""}, | |
| {"\n", "\n"}, | |
| {"\n\n", "\n\n"}, | |
| {"module m ;\t\n" | |
| " endmodule\n", | |
| "module m;\n" | |
| "endmodule\n"}, | |
| {"module m( ) ;\n" | |
| " endmodule\n", | |
| "module m ();\n" // empty ports formatted compactly | |
| "endmodule\n"}, | |
| {// for a single port, the alignment handler doesn't even consider it a | |
| // group so it falls back to standard flush-left behavior. | |
| "module m ( input clk )\t;\n" | |
| " endmodule\n", | |
| "module m (\n" | |
| " input clk\n" | |
| ");\n" | |
| "endmodule\n"}, | |
| {// example with two ports | |
| "module m (\n" | |
| "input clk,\n" | |
| "output bar\n" | |
| ")\t;\n" | |
| " endmodule\n", | |
| "module m (\n" | |
| " input clk,\n" // indented, but internal pre-existing spacing | |
| // preserved | |
| " output bar\n" | |
| ");\n" | |
| "endmodule\n"}, | |
| }; | |
| FormatStyle style; | |
| style.column_limit = 40; | |
| style.indentation_spaces = 2; | |
| style.wrap_spaces = 4; | |
| style.port_declarations_alignment = verible::AlignmentPolicy::kPreserve; | |
| for (const auto& test_case : kTestCases) { | |
| VLOG(1) << "code-to-format:\n" << test_case.input << "<EOF>"; | |
| std::ostringstream stream; | |
| const auto status = | |
| FormatVerilog(test_case.input, "<filename>", style, stream); | |
| // Require these test cases to be valid. | |
| EXPECT_OK(status) << status.message(); | |
| EXPECT_EQ(stream.str(), test_case.expected) << "code:\n" << test_case.input; | |
| } | |
| } | |
| TEST(FormatterEndToEndTest, DisableModuleInstantiations) { | |
| static constexpr FormatterTestCase kTestCases[] = { | |
| {"", ""}, | |
| {"\n", "\n"}, | |
| {"\n\n", "\n\n"}, | |
| {"module m ;\t\n" | |
| " endmodule\n", | |
| "module m;\n" | |
| "endmodule\n"}, | |
| {"module m ;\t\n" | |
| "foo bar();" | |
| " endmodule\n", | |
| "module m;\n" | |
| " foo bar ();\n" // indentation still takes effect | |
| "endmodule\n"}, | |
| {"module m ;\t\n" | |
| "logic xyz;" | |
| "wire\tabc;" | |
| " endmodule\n", | |
| "module m;\n" | |
| " logic xyz;\n" // indentation still takes effect | |
| " wire abc;\n" // aligned too | |
| "endmodule\n"}, | |
| {" function f ;\t\n" | |
| " endfunction\n", | |
| "function f;\n" | |
| "endfunction\n"}, | |
| {" function f ;\t" | |
| "foo bar,baz; " | |
| " endfunction\n", | |
| "function f;\n" | |
| " foo bar, baz;\n" | |
| "endfunction\n"}, | |
| {" task t ;\t" | |
| "foo bar,baz; " | |
| " endtask\n", | |
| "task t;\n" | |
| " foo bar, baz;\n" | |
| "endtask\n"}, | |
| {"module m ;\t\n" | |
| "foo bar( .baz(baz) );" | |
| " endmodule\n", | |
| "module m;\n" | |
| " foo bar (.baz(baz));\n" // indentation still takes effect | |
| "endmodule\n"}, | |
| {"module m ;\t\n" | |
| "foo bar(\n" | |
| " .baz (baz ),\n" // example of user-manual alignment | |
| " .blaaa(blaaa)\n" | |
| ");" | |
| " endmodule\n", | |
| "module m;\n" | |
| " foo bar (\n" // indentation still takes effect | |
| " .baz (baz ),\n" // named port connections preserved | |
| " .blaaa(blaaa)\n" // named port connections preserved | |
| " );\n" // this indentation is fixed | |
| "endmodule\n"}, | |
| {"module m ;\t\n" | |
| "foo #( .baz(baz) ) bar();" // named parameters | |
| " endmodule\n", | |
| "module m;\n" | |
| " foo #(.baz(baz)) bar ();\n" // indentation still takes effect | |
| "endmodule\n"}, | |
| {"module m ;\t\n" | |
| "foo #(\n" | |
| " .baz (baz ),\n" // example of user-manual alignment | |
| " .blaaa(blaaa)\n" | |
| ") bar( );" | |
| " endmodule\n", | |
| "module m;\n" | |
| " foo #(\n" // indentation still takes effect | |
| " .baz (baz ),\n" // named parameter arguments preserved | |
| " .blaaa(blaaa)\n" // named parameter arguments preserved | |
| " ) bar ();\n" // this indentation is fixed | |
| "endmodule\n"}, | |
| }; | |
| FormatStyle style; | |
| style.column_limit = 40; | |
| style.indentation_spaces = 2; | |
| style.wrap_spaces = 4; | |
| // Testing preservation of spaces | |
| style.named_parameter_alignment = AlignmentPolicy::kPreserve; | |
| style.named_port_alignment = AlignmentPolicy::kPreserve; | |
| for (const auto& test_case : kTestCases) { | |
| VLOG(1) << "code-to-format:\n" << test_case.input << "<EOF>"; | |
| std::ostringstream stream; | |
| const auto status = | |
| FormatVerilog(test_case.input, "<filename>", style, stream); | |
| // Require these test cases to be valid. | |
| EXPECT_OK(status) << status.message(); | |
| EXPECT_EQ(stream.str(), test_case.expected) << "code:\n" << test_case.input; | |
| } | |
| } | |
| TEST(FormatterEndToEndTest, DisableTryWrapLongLines) { | |
| static constexpr FormatterTestCase kTestCases[] = { | |
| {"", ""}, | |
| {"\n", "\n"}, | |
| {"\n\n", "\n\n"}, | |
| {"module m ;\t\n" | |
| " endmodule\n", | |
| "module m;\n" | |
| "endmodule\n"}, | |
| {"module m( ) ;\n" | |
| " endmodule\n", | |
| "module m ();\n" | |
| "endmodule\n"}, | |
| {"module m( ) ;\n" | |
| "initial assign a = b;\n" | |
| " endmodule\n", | |
| "module m ();\n" | |
| " initial assign a = b;\n" | |
| "endmodule\n"}, | |
| {"module m( ) ;\n" | |
| "initial assign a = {never +gonna +give +you +up,\n" // over 40 columns, | |
| // give up | |
| "never + gonna +Let +you +down};\n" | |
| " endmodule\n", | |
| "module m ();\n" | |
| " initial assign a = {never +gonna +give +you +up,\n" | |
| "never + gonna +Let +you +down};\n" | |
| "endmodule\n"}, | |
| {// The if-header is a single leaf partition, and does not fit, | |
| // so its original spacing should be preserved. | |
| // We deliberately insert weird spacing to show that it is preserved. | |
| "function f;\n" | |
| "if ((xxx.aaaa >= bbbbbbbbbbbbbbb) &&\n" | |
| " ((ccc.ddd + eee.ffffff * g) <=\n" | |
| " (hhhhhhhhhhhhhhh+iiiiiiiiiiiiiiiiiiii))) begin\n" | |
| "end\n" | |
| "endfunction\n", | |
| "function f;\n" | |
| " if ((xxx.aaaa >= bbbbbbbbbbbbbbb) &&\n" // indentation fixed | |
| " ((ccc.ddd + eee.ffffff * g) <=\n" | |
| " (hhhhhhhhhhhhhhh+iiiiiiiiiiiiiiiiiiii))) begin\n" | |
| " end\n" // indentation fixed | |
| "endfunction\n"}, | |
| }; | |
| FormatStyle style; | |
| style.column_limit = 40; | |
| style.indentation_spaces = 2; | |
| style.wrap_spaces = 4; | |
| style.try_wrap_long_lines = false; | |
| for (const auto& test_case : kTestCases) { | |
| VLOG(1) << "code-to-format:\n" << test_case.input << "<EOF>"; | |
| std::ostringstream stream; | |
| const auto status = | |
| FormatVerilog(test_case.input, "<filename>", style, stream); | |
| // Require these test cases to be valid. | |
| EXPECT_OK(status) << status.message(); | |
| EXPECT_EQ(stream.str(), test_case.expected) << "code:\n" << test_case.input; | |
| } | |
| } | |
| TEST(FormatterEndToEndTest, ModulePortDeclarationsIndentNotWrap) { | |
| static constexpr FormatterTestCase kTestCases[] = { | |
| {"", ""}, | |
| {"\n", "\n"}, | |
| {"\n\n", "\n\n"}, | |
| {"module m ;\t\n" | |
| " endmodule\n", | |
| "module m;\n" | |
| "endmodule\n"}, | |
| {"module m( ) ;\n" | |
| " endmodule\n", | |
| "module m ();\n" // empty ports formatted compactly | |
| "endmodule\n"}, | |
| {// single port example | |
| "module m ( input clk )\t;\n" | |
| " endmodule\n", | |
| "module m (\n" | |
| " input clk\n" // 2 spaces | |
| ");\n" | |
| "endmodule\n"}, | |
| {// example with two ports | |
| "module m (\n" | |
| "input clk,\n" | |
| "output bar\n" | |
| ")\t;\n" | |
| " endmodule\n", | |
| "module m (\n" | |
| " input clk,\n" // indented 2 spaces, and aligned | |
| " output bar\n" | |
| ");\n" | |
| "endmodule\n"}, | |
| {// interface example | |
| "interface handshake (\n" | |
| "wire req,\n" | |
| "wire ack\n" | |
| ")\t;\n" | |
| " endinterface\n", | |
| "interface handshake (\n" | |
| " wire req,\n" // indented 2 spaces | |
| " wire ack\n" | |
| ");\n" | |
| "endinterface\n"}, | |
| }; | |
| FormatStyle style; | |
| style.column_limit = 40; | |
| style.indentation_spaces = 2; | |
| style.wrap_spaces = 4; | |
| // Indent 2 spaces instead of wrapping 4 spaces. | |
| style.port_declarations_indentation = IndentationStyle::kIndent; | |
| for (const auto& test_case : kTestCases) { | |
| VLOG(1) << "code-to-format:\n" << test_case.input << "<EOF>"; | |
| std::ostringstream stream; | |
| const auto status = | |
| FormatVerilog(test_case.input, "<filename>", style, stream); | |
| // Require these test cases to be valid. | |
| EXPECT_OK(status) << status.message(); | |
| EXPECT_EQ(stream.str(), test_case.expected) << "code:\n" << test_case.input; | |
| } | |
| } | |
| TEST(FormatterEndToEndTest, NamedPortConnectionsIndentNotWrap) { | |
| static constexpr FormatterTestCase kTestCases[] = { | |
| {"", ""}, | |
| {"\n", "\n"}, | |
| {"\n\n", "\n\n"}, | |
| {"module m ;\t\n" | |
| " endmodule\n", | |
| "module m;\n" | |
| "endmodule\n"}, | |
| {"module m( ) ;\n" | |
| " endmodule\n", | |
| "module m ();\n" // empty ports formatted compactly | |
| "endmodule\n"}, | |
| {// single port example | |
| "module m ;\n" | |
| "foo bar( .clk( clk ) )\t;\n" | |
| " endmodule\n", | |
| "module m;\n" | |
| " foo bar (.clk(clk));\n" | |
| "endmodule\n"}, | |
| {// two port example | |
| "module m ;\n" | |
| "foo bar( .clk2( clk ),.data (data) )\t;\n" | |
| " endmodule\n", | |
| "module m;\n" | |
| " foo bar (\n" | |
| " .clk2(clk),\n" // indent only +2 spaces | |
| " .data(data)\n" | |
| " );\n" | |
| "endmodule\n"}, | |
| }; | |
| FormatStyle style; | |
| style.column_limit = 40; | |
| style.indentation_spaces = 2; | |
| style.wrap_spaces = 4; | |
| // Indent 2 spaces instead of wrapping 4 spaces. | |
| style.named_port_indentation = IndentationStyle::kIndent; | |
| for (const auto& test_case : kTestCases) { | |
| VLOG(1) << "code-to-format:\n" << test_case.input << "<EOF>"; | |
| std::ostringstream stream; | |
| const auto status = | |
| FormatVerilog(test_case.input, "<filename>", style, stream); | |
| // Require these test cases to be valid. | |
| EXPECT_OK(status) << status.message(); | |
| EXPECT_EQ(stream.str(), test_case.expected) << "code:\n" << test_case.input; | |
| } | |
| } | |
| TEST(FormatterEndToEndTest, FormalParametersIndentNotWrap) { | |
| static constexpr FormatterTestCase kTestCases[] = { | |
| {"", ""}, | |
| {"\n", "\n"}, | |
| {"\n\n", "\n\n"}, | |
| {"module m ;\t\n" | |
| " endmodule\n", | |
| "module m;\n" | |
| "endmodule\n"}, | |
| {"module m #( ) ;\n" // empty parameters | |
| " endmodule\n", | |
| "module m #();\n" | |
| "endmodule\n"}, | |
| {// single parameter example | |
| "module m #( int W = 2)\t;\n" | |
| " endmodule\n", | |
| "module m #(\n" | |
| " int W = 2\n" // indented 2 spaces | |
| ");\n" | |
| "endmodule\n"}, | |
| {// module with two parameters | |
| "module m #(\n" | |
| "int W = 2,\n" | |
| "int L = 4\n" | |
| ")\t;\n" | |
| " endmodule\n", | |
| "module m #(\n" | |
| " int W = 2,\n" // indented 2 spaces | |
| " int L = 4\n" | |
| ");\n" | |
| "endmodule\n"}, | |
| {// interface with two parameters | |
| "interface m #(\n" | |
| "int W = 2,\n" | |
| "int L = 4\n" | |
| ")\t;\n" | |
| " endinterface\n", | |
| "interface m #(\n" | |
| " int W = 2,\n" // indented 2 spaces | |
| " int L = 4\n" | |
| ");\n" | |
| "endinterface\n"}, | |
| {// class with two parameters | |
| "class c #(\n" | |
| "int W = 2,\n" | |
| "int L = 4\n" | |
| ")\t;\n" | |
| " endclass\n", | |
| "class c #(\n" | |
| " int W = 2,\n" // indented 2 spaces | |
| " int L = 4\n" | |
| ");\n" | |
| "endclass\n"}, | |
| }; | |
| FormatStyle style; | |
| style.column_limit = 40; | |
| style.indentation_spaces = 2; | |
| style.wrap_spaces = 4; | |
| // Indent 2 spaces instead of wrapping 4 spaces. | |
| style.formal_parameters_indentation = IndentationStyle::kIndent; | |
| for (const auto& test_case : kTestCases) { | |
| VLOG(1) << "code-to-format:\n" << test_case.input << "<EOF>"; | |
| std::ostringstream stream; | |
| const auto status = | |
| FormatVerilog(test_case.input, "<filename>", style, stream); | |
| // Require these test cases to be valid. | |
| EXPECT_OK(status) << status.message(); | |
| EXPECT_EQ(stream.str(), test_case.expected) << "code:\n" << test_case.input; | |
| } | |
| } | |
| TEST(FormatterEndToEndTest, NamedParametersIndentNotWrap) { | |
| static constexpr FormatterTestCase kTestCases[] = { | |
| {"", ""}, | |
| {"\n", "\n"}, | |
| {"\n\n", "\n\n"}, | |
| {"module m ;\t\n" | |
| " endmodule\n", | |
| "module m;\n" | |
| "endmodule\n"}, | |
| {"module m #( ) ;\n" // empty parameters | |
| " endmodule\n", | |
| "module m #();\n" | |
| "endmodule\n"}, | |
| {"module m ;\t\n" | |
| " foo #()bar();\n" | |
| " endmodule\n", | |
| "module m;\n" | |
| " foo #() bar ();\n" | |
| "endmodule\n"}, | |
| {// one named parameter | |
| "module m ;\n" | |
| "foo #(.W(1)) bar();\n" | |
| " endmodule\n", | |
| "module m;\n" | |
| " foo #(.W(1)) bar ();\n" | |
| "endmodule\n"}, | |
| {// two named parameters | |
| "module m ;\n" | |
| "foo #(.W(1), .L(2)) bar();\n" | |
| " endmodule\n", | |
| "module m;\n" | |
| " foo #(\n" | |
| " .W(1),\n" // indent +2 spaces only | |
| " .L(2)\n" | |
| " ) bar ();\n" | |
| "endmodule\n"}, | |
| {// class data member with two parameters | |
| "class c ;\n" | |
| " foo_pkg::bar_t#(\n" | |
| ".W(2),.L(4)" | |
| ") baz;\n" | |
| " endclass\n", | |
| "class c;\n" | |
| " foo_pkg::bar_t #(\n" | |
| " .W(2),\n" // indent +2 spaces only | |
| " .L(4)\n" | |
| " ) baz;\n" | |
| "endclass\n"}, | |
| {// typedef with two parameters | |
| "typedef \n" | |
| " foo_pkg::bar_t #(" | |
| ".W(2),.L(4)" | |
| ") baz;\n", | |
| "typedef foo_pkg::bar_t#(\n" | |
| " .W(2),\n" // indent +2 spaces only | |
| " .L(4)\n" | |
| ") baz;\n"}, | |
| }; | |
| FormatStyle style; | |
| style.column_limit = 40; | |
| style.indentation_spaces = 2; | |
| style.wrap_spaces = 4; | |
| // Indent 2 spaces instead of wrapping 4 spaces. | |
| style.named_parameter_indentation = IndentationStyle::kIndent; | |
| for (const auto& test_case : kTestCases) { | |
| VLOG(1) << "code-to-format:\n" << test_case.input << "<EOF>"; | |
| std::ostringstream stream; | |
| const auto status = | |
| FormatVerilog(test_case.input, "<filename>", style, stream); | |
| // Require these test cases to be valid. | |
| EXPECT_OK(status) << status.message(); | |
| EXPECT_EQ(stream.str(), test_case.expected) << "code:\n" << test_case.input; | |
| } | |
| } | |
| struct SelectLinesTestCase { | |
| absl::string_view input; | |
| LineNumberSet lines; // explicit set of lines to enable formatting | |
| absl::string_view expected; | |
| }; | |
| // Tests that formatter honors selected line numbers. | |
| TEST(FormatterEndToEndTest, SelectLines) { | |
| const SelectLinesTestCase kTestCases[] = { | |
| {"", {}, ""}, | |
| {"", {{1, 2}}, ""}, | |
| {// expect all three lines for format | |
| " parameter int foo_line1 = 0 ;\n" | |
| " parameter int foo_line2 = 0 ;\n" | |
| " parameter int foo_line3 = 0 ;\n", | |
| {}, | |
| "parameter int foo_line1 = 0;\n" | |
| "parameter int foo_line2 = 0;\n" | |
| "parameter int foo_line3 = 0;\n"}, | |
| {// expect only one line to format | |
| " parameter int foo_line1 = 0 ;\n" | |
| " parameter int foo_line2 = 0 ;\n" | |
| " parameter int foo_line3 = 0 ;\n", | |
| {{1, 2}}, | |
| "parameter int foo_line1 = 0;\n" | |
| " parameter int foo_line2 = 0 ;\n" | |
| " parameter int foo_line3 = 0 ;\n"}, | |
| {// expect only one line to format | |
| " parameter int foo_line1 = 0 ;\n" | |
| " parameter int foo_line2 = 0 ;\n" | |
| " parameter int foo_line3 = 0 ;\n", | |
| {{2, 3}}, | |
| " parameter int foo_line1 = 0 ;\n" | |
| "parameter int foo_line2 = 0;\n" | |
| " parameter int foo_line3 = 0 ;\n"}, | |
| {// expect only one line to format | |
| " parameter int foo_line1 = 0 ;\n" | |
| " parameter int foo_line2 = 0 ;\n" | |
| " parameter int foo_line3 = 0 ;\n", | |
| {{3, 4}}, | |
| " parameter int foo_line1 = 0 ;\n" | |
| " parameter int foo_line2 = 0 ;\n" | |
| "parameter int foo_line3 = 0;\n"}, | |
| {// expect to format two lines | |
| " parameter int foo_line1 = 0 ;\n" | |
| " parameter int foo_line2 = 0 ;\n" | |
| " parameter int foo_line3 = 0 ;\n", | |
| {{1, 3}}, | |
| "parameter int foo_line1 = 0;\n" | |
| "parameter int foo_line2 = 0;\n" | |
| " parameter int foo_line3 = 0 ;\n"}, | |
| {// expect to format two lines | |
| " parameter int foo_line1 = 0 ;\n" | |
| " parameter int foo_line2 = 0 ;\n" | |
| " parameter int foo_line3 = 0 ;\n", | |
| {{2, 4}}, | |
| " parameter int foo_line1 = 0 ;\n" | |
| "parameter int foo_line2 = 0;\n" | |
| "parameter int foo_line3 = 0;\n"}, | |
| {// expect to format two lines | |
| " parameter int foo_line1 = 0 ;\n" | |
| " parameter int foo_line2 = 0 ;\n" | |
| " parameter int foo_line3 = 0 ;\n", | |
| {{1, 2}, {3, 4}}, | |
| "parameter int foo_line1 = 0;\n" | |
| " parameter int foo_line2 = 0 ;\n" | |
| "parameter int foo_line3 = 0;\n"}, | |
| {// expect to format all lines | |
| " parameter int foo_line1 = 0 ;\n" | |
| " parameter int foo_line2 = 0 ;\n" | |
| " parameter int foo_line3 = 0 ;\n", | |
| {{1, 4}}, | |
| "parameter int foo_line1 = 0;\n" | |
| "parameter int foo_line2 = 0;\n" | |
| "parameter int foo_line3 = 0;\n"}, | |
| {// expect to format no lines (line numbers out of bounds) | |
| " parameter int foo_line1 = 0 ;\n" | |
| " parameter int foo_line2 = 0 ;\n" | |
| " parameter int foo_line3 = 0 ;\n", | |
| {{4, 6}}, | |
| " parameter int foo_line1 = 0 ;\n" | |
| " parameter int foo_line2 = 0 ;\n" | |
| " parameter int foo_line3 = 0 ;\n"}, | |
| {// expect to format all lines | |
| "// verilog_format: on\n" | |
| " parameter int foo_line2 = 0 ;\n" | |
| " parameter int foo_line3 = 0 ;\n" | |
| " parameter int foo_line4 = 0 ;\n", | |
| {}, | |
| "// verilog_format: on\n" | |
| "parameter int foo_line2 = 0;\n" | |
| "parameter int foo_line3 = 0;\n" | |
| "parameter int foo_line4 = 0;\n"}, | |
| {// expect to format no lines | |
| "// verilog_format: off\n" | |
| " parameter int foo_line2 = 0 ;\n" | |
| " parameter int foo_line3 = 0 ;\n" | |
| " parameter int foo_line4 = 0 ;\n", | |
| {}, | |
| "// verilog_format: off\n" | |
| " parameter int foo_line2 = 0 ;\n" | |
| " parameter int foo_line3 = 0 ;\n" | |
| " parameter int foo_line4 = 0 ;\n"}, | |
| {// expect to format some lines | |
| "// verilog_format: on\n" | |
| " parameter int foo_line2 = 0 ;\n" | |
| " parameter int foo_line3 = 0 ;\n" | |
| " parameter int foo_line4 = 0 ;\n", | |
| {{3, 5}}, | |
| "// verilog_format: on\n" | |
| " parameter int foo_line2 = 0 ;\n" | |
| "parameter int foo_line3 = 0;\n" // disable lines 3,4 | |
| "parameter int foo_line4 = 0;\n"}, | |
| {// enable all lines, but respect format-off | |
| " parameter int foo_line1 = 0 ;\n" | |
| " parameter int foo_line2 = 0 ;\n" | |
| "// verilog_format: off\n" | |
| " parameter int foo_line4 = 0 ;\n", | |
| {{1, 5}}, | |
| "parameter int foo_line1 = 0;\n" | |
| "parameter int foo_line2 = 0;\n" | |
| "// verilog_format: off\n" | |
| " parameter int foo_line4 = 0 ;\n"}, | |
| {// enable all lines, but respect format-off | |
| " parameter int foo_line1 = 0 ;\n" | |
| "// verilog_format: off\n" | |
| " parameter int foo_line3 = 0 ;\n" | |
| "// verilog_format: on\n" | |
| " parameter int foo_line5 = 0 ;\n", | |
| {{1, 6}}, | |
| "parameter int foo_line1 = 0;\n" | |
| "// verilog_format: off\n" | |
| " parameter int foo_line3 = 0 ;\n" | |
| "// verilog_format: on\n" | |
| "parameter int foo_line5 = 0;\n"}, | |
| {// enable all lines, but respect format-off | |
| "// verilog_format: off\n" | |
| " parameter int foo_line2 = 0 ;\n" | |
| " parameter int foo_line3 = 0 ;\n" | |
| "// verilog_format: on\n" | |
| " parameter int foo_line5 = 0 ;\n", | |
| {{1, 6}}, | |
| "// verilog_format: off\n" | |
| " parameter int foo_line2 = 0 ;\n" | |
| " parameter int foo_line3 = 0 ;\n" | |
| "// verilog_format: on\n" | |
| "parameter int foo_line5 = 0;\n"}, | |
| {"module m;\n" | |
| " if (foo) begin:l1\n" | |
| " if (foo) begin:l2\n" | |
| " always_comb\n" // normally this line and next would fit together | |
| " d<=#1ps x_lat\t;\n" // only format this line, 5 | |
| " end : l2\n" | |
| " end : l1\n" | |
| "endmodule\n", | |
| {{5, 6}}, | |
| "module m;\n" | |
| " if (foo) begin:l1\n" | |
| " if (foo) begin:l2\n" | |
| " always_comb\n" // incremental mode prevents joining next line | |
| " d <= #1ps x_lat;\n" // only this line changed | |
| " end : l2\n" | |
| " end : l1\n" | |
| "endmodule\n"}, | |
| // Next three test cases: one whole-file, two incremental | |
| {"module m(\n" | |
| " input wire f,\n" | |
| " input foo::bar ggg\n" | |
| ");\n" | |
| "endmodule:m\n", | |
| {}, // format all lines | |
| "module m (\n" | |
| " input wire f,\n" | |
| " input foo::bar ggg\n" | |
| ");\n" | |
| "endmodule : m\n"}, | |
| {"module m(\n" | |
| " input wire f,\n" | |
| " input foo::bar ggg\n" // "new line", formatted incrementally | |
| ");\n" | |
| "endmodule:m\n", | |
| {{3, 4}}, // format incrementally | |
| "module m(\n" | |
| " input wire f,\n" | |
| " input foo::bar ggg\n" // "new line" remains untouched | |
| ");\n" | |
| "endmodule:m\n"}, | |
| {"module m(\n" | |
| " input wire f,\n" // "new line", formatted incrementally | |
| " input foo::bar ggg\n" | |
| ");\n" | |
| "endmodule:m\n", | |
| {{2, 3}}, // format incrementally | |
| "module m(\n" | |
| " input wire f,\n" // "new line" indented, but other spaces kept | |
| " input foo::bar ggg\n" | |
| ");\n" | |
| "endmodule:m\n"}, | |
| }; | |
| // Use a fixed style. | |
| FormatStyle style; | |
| style.column_limit = 40; | |
| style.indentation_spaces = 2; | |
| style.wrap_spaces = 4; | |
| for (const auto& test_case : kTestCases) { | |
| VLOG(1) << "code-to-format:\n" << test_case.input << "<EOF>"; | |
| std::ostringstream stream; | |
| const auto status = FormatVerilog(test_case.input, "<filename>", style, | |
| stream, test_case.lines); | |
| EXPECT_OK(status) << status.message() << '\n' | |
| << "Lines: " << test_case.lines; | |
| EXPECT_EQ(stream.str(), test_case.expected) | |
| << "code:\n" | |
| << test_case.input << "\nlines: " << test_case.lines; | |
| } | |
| } | |
| // These tests verify the mode where horizontal spacing is discarded while | |
| // vertical spacing is preserved. | |
| TEST(FormatterEndToEndTest, PreserveVSpacesOnly) { | |
| static constexpr FormatterTestCase kTestCases[] = { | |
| // {input, expected}, | |
| // No tokens cases: still preserve vertical spacing, but not horizontal | |
| {"", ""}, | |
| {" ", ""}, | |
| {"\n", "\n"}, | |
| {"\n\n", "\n\n"}, | |
| {" \n", "\n"}, | |
| {"\n ", "\n"}, | |
| {" \n ", "\n"}, | |
| {" \n \t\t\n\t ", "\n\n"}, | |
| // The remaining cases have at least one non-whitespace token. | |
| // single comment | |
| {"//\n", "//\n"}, | |
| {"// \n", "// \n"}, // trailing spaces inside comment untouched | |
| {"\n//\n", "\n//\n"}, | |
| {"\n\n//\n", "\n\n//\n"}, | |
| {"\n//\n\n", "\n//\n\n"}, | |
| {" //\n", "//\n"}, // spaces before comment discarded | |
| {" \n //\n", "\n//\n"}, | |
| {" \n //\n \n ", "\n//\n\n"}, // trailing spaces discarded | |
| // multi-comment | |
| {"//\n//\n", "//\n//\n"}, | |
| {"\n//\n\n//\n\n", "\n//\n\n//\n\n"}, | |
| {"\n//\n\n//\n", "\n//\n\n//\n"}, // blank line between comments | |
| // Module cases with token partition boundary (before 'endmodule'). | |
| {"module foo;endmodule\n", "module foo;\nendmodule\n"}, | |
| {"module foo;\nendmodule\n", "module foo;\nendmodule\n"}, | |
| {"module foo;\n\nendmodule\n", "module foo;\n\nendmodule\n"}, | |
| {"\nmodule foo;endmodule\n", "\nmodule foo;\nendmodule\n"}, | |
| {"\nmodule foo ; endmodule\n", "\nmodule foo;\nendmodule\n"}, | |
| {"\nmodule\nfoo\n;endmodule\n", "\nmodule foo;\nendmodule\n"}, | |
| {"\nmodule foo;endmodule\n\n\n", "\nmodule foo;\nendmodule\n\n\n"}, | |
| {"\n\n\nmodule foo;endmodule\n", "\n\n\nmodule foo;\nendmodule\n"}, | |
| {"\nmodule\nfoo\n;\n\n\nendmodule\n", "\nmodule foo;\n\n\nendmodule\n"}, | |
| // Module cases with one indented item, various original vertical spacing | |
| {"module foo;wire w;endmodule\n", "module foo;\n wire w;\nendmodule\n"}, | |
| {" module foo ;wire w ;endmodule \n ", | |
| "module foo;\n wire w;\nendmodule\n"}, | |
| {"\nmodule\nfoo\n;\nwire\nw\n;endmodule\n\n", | |
| "\nmodule foo;\n wire w;\nendmodule\n\n"}, | |
| {"\n\nmodule\nfoo\n;\n\n\nwire\nw\n;\n\nendmodule\n\n", | |
| "\n\nmodule foo;\n\n\n wire w;\n\nendmodule\n\n"}, | |
| // The following cases show that some horizontal whitespace is discarded, | |
| // while vertical spacing is preserved on partition boundaries. | |
| {" module foo\t \t; endmodule \n", | |
| "module foo;\nendmodule\n"}, | |
| {"\t\n module foo\t\t; endmodule \n", | |
| "\nmodule foo;\nendmodule\n"}, | |
| // Module with comments intermingled. | |
| { | |
| "//1\nmodule foo;//2\nwire w;//3\n//4\nendmodule\n", | |
| "//1\nmodule foo; //2\n wire w; //3\n //4\nendmodule\n" | |
| // TODO(fangism): whether or not //4 should be indented is | |
| // questionable (in similar cases below too). | |
| }, | |
| {// now with extra blank lines | |
| "//1\n\nmodule foo;//2\n\nwire w;//3\n\n//4\n\nendmodule\n\n", | |
| "//1\n\nmodule foo; //2\n\n wire w; //3\n\n //4\n\nendmodule\n\n"}, | |
| { | |
| // module with comments-only in some empty blocks, properly indented | |
| " // humble module\n" | |
| " module foo (// non-port comment\n" | |
| "// port comment 1\n" | |
| "// port comment 2\n" | |
| ");// header trailing comment\n" | |
| "// item comment 1\n" | |
| "// item comment 2\n" | |
| "endmodule\n", | |
| "// humble module\n" | |
| "module foo ( // non-port comment\n" | |
| " // port comment 1\n" | |
| " // port comment 2\n" | |
| "); // header trailing comment\n" | |
| " // item comment 1\n" | |
| " // item comment 2\n" | |
| "endmodule\n", | |
| }, | |
| { | |
| // module with comments around non-empty blocks | |
| " // humble module\n" | |
| " module foo (// non-port comment\n" | |
| "// port comment 1\n" | |
| "input logic f \n" | |
| "// port comment 2\n" | |
| ");// header trailing comment\n" | |
| "// item comment 1\n" | |
| "wire w ; \n" | |
| "// item comment 2\n" | |
| "endmodule\n", | |
| "// humble module\n" | |
| "module foo ( // non-port comment\n" | |
| " // port comment 1\n" | |
| " input logic f\n" | |
| " // port comment 2\n" | |
| "); // header trailing comment\n" | |
| " // item comment 1\n" | |
| " wire w;\n" | |
| " // item comment 2\n" | |
| "endmodule\n", | |
| }, | |
| }; | |
| FormatStyle style; | |
| for (const auto& test_case : kTestCases) { | |
| VLOG(1) << "code-to-format:\n" << test_case.input << "<EOF>"; | |
| std::ostringstream stream; | |
| const auto status = | |
| FormatVerilog(test_case.input, "<filename>", style, stream); | |
| EXPECT_OK(status) << status.message(); | |
| EXPECT_EQ(stream.str(), test_case.expected) << "code:\n" << test_case.input; | |
| } | |
| } | |
| static constexpr FormatterTestCase kFormatterTestCasesElseStatements[] = { | |
| {"module m;" | |
| "task static t; if (r == t) a.b(c); else d.e(f); endtask;" | |
| "endmodule", | |
| "module m;\n" | |
| " task static t;\n" | |
| " if (r == t) a.b(c);\n" | |
| " else d.e(f);\n" | |
| " endtask\n" | |
| " ;\n" // possibly unintended stray ';' | |
| "endmodule\n"}, | |
| {"module m;" | |
| "task static t; if (r == t) begin a.b(c); end else begin d.e(f); end " | |
| "endtask;" | |
| "endmodule", | |
| "module m;\n" | |
| " task static t;\n" | |
| " if (r == t) begin\n" | |
| " a.b(c);\n" | |
| " end else begin\n" | |
| " d.e(f);\n" | |
| " end\n" | |
| " endtask\n" | |
| " ;\n" // stray ';' | |
| "endmodule\n"}, | |
| {"module m;initial begin if(a==b)" | |
| "c.d(e);else\n" | |
| "f.g(h);end endmodule", | |
| "module m;\n" | |
| " initial begin\n" | |
| " if (a == b) c.d(e);\n" | |
| " else f.g(h);\n" | |
| " end\n" | |
| "endmodule\n"}, | |
| {" module m; always_comb begin \n" | |
| " if ( a ) b = 16'hdead ; \n" | |
| " else if ( c ) d= 16 'hbeef ; \n" | |
| " else if (e) f=16'hca_fe ; \n" | |
| "end \n endmodule\n", | |
| "module m;\n" | |
| " always_comb begin\n" | |
| " if (a) b = 16'hdead;\n" | |
| " else if (c) d = 16'hbeef;\n" | |
| " else if (e) f = 16'hca_fe;\n" | |
| " end\n" | |
| "endmodule\n"}, | |
| {"module m; initial begin\n" | |
| " if (a||b) c = 1'b1;\n" | |
| "d = 1'b1; if (e)\n" | |
| "begin f = 1'b0; end else begin\n" | |
| " g = h;\n" | |
| " end \n" | |
| " i = 1'b1; " | |
| "end endmodule\n", | |
| "module m;\n" | |
| " initial begin\n" | |
| " if (a || b) c = 1'b1;\n" | |
| " d = 1'b1;\n" | |
| " if (e) begin\n" | |
| " f = 1'b0;\n" | |
| " end else begin\n" | |
| " g = h;\n" | |
| " end\n" | |
| " i = 1'b1;\n" | |
| " end\n" | |
| "endmodule\n"}, | |
| {"module m; initial begin\n" | |
| "if (a&&b&&c) begin\n" | |
| " d = 1'b1;\n" | |
| " if (e) begin\n" | |
| " f = ff;\n" | |
| " end else if ( g ) begin\n" | |
| " h = hh;\n" | |
| "end else if (i) begin\n" | |
| " j = (kk == ll) ? mm :\n" | |
| " gg;\n" | |
| " end else if ( qq ) begin\n" | |
| " if ( xx ||yy ) begin d0 = 1'b0; d1 = " | |
| "1'b1;\n" | |
| " end else if (oo) begin aa = bb; cc = dd;" | |
| " if (zz) zx = xz; else ba = ab;" | |
| " end else \n begin vv = tt ; \n" | |
| " end end " | |
| "end \n else if (uu)\nbegin\n\na=b;if (aa) b = c;\n" | |
| "\nelse if \n (bb) \n\nc =d ;\n\n\n\n\n " | |
| " else e\n\n = h;\n\n" | |
| "end \n else \n begin if(x)y=a;else\nbegin\n" | |
| "\n\n\na=y; if (a) b = c;\n\n\n\nelse\n\n\nd=e;end \n" | |
| "end\n" | |
| "end endmodule\n", | |
| "module m;\n" | |
| " initial begin\n" | |
| " if (a && b && c) begin\n" | |
| " d = 1'b1;\n" | |
| " if (e) begin\n" | |
| " f = ff;\n" | |
| " end else if (g) begin\n" | |
| " h = hh;\n" | |
| " end else if (i) begin\n" | |
| " j = (kk == ll) ? mm : gg;\n" | |
| " end else if (qq) begin\n" | |
| " if (xx || yy) begin\n" | |
| " d0 = 1'b0;\n" | |
| " d1 = 1'b1;\n" | |
| " end else if (oo) begin\n" | |
| " aa = bb;\n" | |
| " cc = dd;\n" | |
| " if (zz) zx = xz;\n" | |
| " else ba = ab;\n" | |
| " end else begin\n" | |
| " vv = tt;\n" | |
| " end\n" | |
| " end\n" | |
| " end else if (uu) begin\n\n" | |
| " a = b;\n" | |
| " if (aa) b = c;\n\n" | |
| " else if (bb) c = d;\n\n\n\n\n" | |
| " else e = h;\n\n" | |
| " end else begin\n" | |
| " if (x) y = a;\n" | |
| " else begin\n\n\n\n" | |
| " a = y;\n" | |
| " if (a) b = c;\n\n\n\n" | |
| " else d = e;\n" | |
| " end\n" | |
| " end\n" | |
| " end\n" | |
| "endmodule\n"}}; | |
| TEST(FormatterEndToEndTest, FormatElseStatements) { | |
| // Use a fixed style. | |
| FormatStyle style; | |
| style.column_limit = 40; | |
| style.indentation_spaces = 2; | |
| style.wrap_spaces = 4; | |
| for (const auto& test_case : kFormatterTestCasesElseStatements) { | |
| VLOG(1) << "code-to-format:\n" << test_case.input << "<EOF>"; | |
| std::ostringstream stream; | |
| const auto status = | |
| FormatVerilog(test_case.input, "<filename>", style, stream); | |
| EXPECT_OK(status) << status.message(); | |
| EXPECT_EQ(stream.str(), test_case.expected) << "code:\n" << test_case.input; | |
| } | |
| } | |
| TEST(FormatterEndToEndTest, DiagnosticShowFullTree) { | |
| // Use a fixed style. | |
| FormatStyle style; | |
| style.column_limit = 40; | |
| style.indentation_spaces = 2; | |
| style.wrap_spaces = 4; | |
| for (const auto& test_case : kFormatterTestCases) { | |
| std::ostringstream stream, debug_stream; | |
| ExecutionControl control; | |
| control.stream = &debug_stream; | |
| control.show_token_partition_tree = true; | |
| const auto status = FormatVerilog(test_case.input, "<filename>", style, | |
| stream, kEnableAllLines, control); | |
| EXPECT_EQ(status.code(), StatusCode::kCancelled); | |
| EXPECT_TRUE( | |
| absl::StartsWith(debug_stream.str(), "Full token partition tree")); | |
| } | |
| } | |
| TEST(FormatterEndToEndTest, DiagnosticLargestPartitions) { | |
| // Use a fixed style. | |
| FormatStyle style; | |
| style.column_limit = 40; | |
| style.indentation_spaces = 2; | |
| style.wrap_spaces = 4; | |
| for (const auto& test_case : kFormatterTestCases) { | |
| std::ostringstream stream, debug_stream; | |
| ExecutionControl control; | |
| control.stream = &debug_stream; | |
| control.show_largest_token_partitions = 2; | |
| const auto status = FormatVerilog(test_case.input, "<filename>", style, | |
| stream, kEnableAllLines, control); | |
| EXPECT_EQ(status.code(), StatusCode::kCancelled); | |
| EXPECT_TRUE(absl::StartsWith(debug_stream.str(), "Showing the ")) | |
| << "got: " << debug_stream.str(); | |
| } | |
| } | |
| TEST(FormatterEndToEndTest, DiagnosticEquallyOptimalWrappings) { | |
| // Use a fixed style. | |
| FormatStyle style; | |
| style.column_limit = 40; | |
| style.indentation_spaces = 2; | |
| style.wrap_spaces = 4; | |
| for (const auto& test_case : kFormatterTestCases) { | |
| std::ostringstream stream, debug_stream; | |
| ExecutionControl control; | |
| control.stream = &debug_stream; | |
| control.show_equally_optimal_wrappings = true; | |
| const auto status = FormatVerilog(test_case.input, "<filename>", style, | |
| stream, kEnableAllLines, control); | |
| EXPECT_OK(status) << status.message(); | |
| if (!debug_stream.str().empty()) { | |
| EXPECT_TRUE(absl::StartsWith(debug_stream.str(), "Showing the ")) | |
| << "got: " << debug_stream.str(); | |
| // Cannot guarantee among unit tests that there will be >1 solution. | |
| } | |
| } | |
| } | |
| // Test that hitting search space limit results in correct error status. | |
| TEST(FormatterEndToEndTest, UnfinishedLineWrapSearching) { | |
| FormatStyle style; | |
| style.column_limit = 40; | |
| style.indentation_spaces = 2; | |
| style.wrap_spaces = 4; | |
| const absl::string_view code("parameter int x = 1+1;\n"); | |
| std::ostringstream stream, debug_stream; | |
| ExecutionControl control; | |
| control.max_search_states = 2; // Cause search to abort early. | |
| control.stream = &debug_stream; | |
| const auto status = FormatVerilog(code, "<filename>", style, stream, | |
| kEnableAllLines, control); | |
| EXPECT_EQ(status.code(), StatusCode::kResourceExhausted); | |
| EXPECT_TRUE(absl::StartsWith(status.message(), "***")); | |
| } | |
| // TODO(fangism): directed tests using style variations | |
| } // namespace | |
| } // namespace formatter | |
| } // namespace verilog |