blob: b9430c58471d2be0bcae7aa802446783f287c96e [file] [log] [blame]
// Copyright 2017-2020 The Verible Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// 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"},
{// conditional generate (case), with comments
"module mc; case(s)\n//comment a\na:bb c;\n//comment b\n endcase "
"endmodule",
"module mc;\n"
" case (s)\n"
" //comment a\n" // indented to case-item level
" a: bb c;\n"
" //comment b\n" // indented to case-item level
" 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, comments
"function f; case (x)inside \n//comment\n"
"[0:1]:x=y; \n"
" //comment\n"
"endcase endfunction\n",
"function f;\n"
" case (x) inside\n"
" //comment\n"
" [0 : 1]: x = y;\n"
" //comment\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"},
{// case-inside: small difference between flush-left and align, so align
"function f; case (x)inside [0:3] :yy=zzz; [4:11] :yy=zz;"
"endcase endfunction\n",
"function f;\n"
" case (x) inside\n"
" [0 : 3]: yy = zzz;\n" // aligned, only adds 1 spaces
" [4 : 11]: yy = zz;\n"
" endcase\n"
"endfunction\n"},
{// case-inside: align with comments
"function f; case (x)inside \n//c1\n[0:3] :yy=zzz;\n//c2\n"
" [4:11] :yy=zz;\n//c3\n"
"endcase endfunction\n",
"function f;\n"
" case (x) inside\n"
" //c1\n"
" [0 : 3]: yy = zzz;\n" // aligned, only adds 1 spaces
" //c2\n"
" [4 : 11]: yy = zz;\n"
" //c3\n"
" endcase\n"
"endfunction\n"},
{// case-inside: flush left
"function f; case (x)inside [0:3] :yy=zzz; [4:999999] :yy=zz;"
"endcase endfunction\n",
"function f;\n"
" case (x) inside\n"
" [0 : 3]: yy = zzz;\n" // flush-left
" [4 : 999999]: yy = zz;\n"
" endcase\n"
"endfunction\n"},
{// case-inside: induce alignment
"function f; case (x)inside [0:3 ] :yy=zzz; [4:999999] :yy=zz;"
"endcase endfunction\n",
"function f;\n"
" case (x) inside\n"
" [0 : 3]: yy = zzz;\n" // aligned
" [4 : 999999]: yy = zz;\n"
" endcase\n"
"endfunction\n"},
{// case-generate: align would add few spaces, so align
"module mc ; case (x)kZ : gg h(); kXYY :j kk();"
"endcase endmodule\n",
"module mc;\n"
" case (x)\n"
" kZ: gg h ();\n" // align
" kXYY: j kk ();\n"
" endcase\n"
"endmodule\n"},
{// case-generate + comment: align would add few spaces, so align
"module mc ; case (x)kZ : gg h(); \n//c1\n kXYY :j kk();"
"endcase endmodule\n",
"module mc;\n"
" case (x)\n"
" kZ: gg h ();\n" // align
" //c1\n"
" kXYY: j kk ();\n"
" endcase\n"
"endmodule\n"},
{// case-generate: align would add too many space, so flush-left
"module mc ; case (x)kZ : gg h(); kXYYYY :j kk();"
"endcase endmodule\n",
"module mc;\n"
" case (x)\n"
" kZ: gg h ();\n" // flush-left
" kXYYYY: j kk ();\n"
" endcase\n"
"endmodule\n"},
{// case-generate: inject spaces to induce alignment
"module mc ; case (x)kZ : gg h(); kXYYYY : j kk();"
"endcase endmodule\n",
"module mc;\n"
" case (x)\n"
" kZ: gg h ();\n" // align
" kXYYYY: j kk ();\n"
" endcase\n"
"endmodule\n"},
{// randcase: align (small difference from flush-left)
"task trc ;randcase 10: x = 1; 1: x = 3; endcase endtask",
"task trc;\n"
" randcase\n"
" 10: x = 1;\n"
" 1: x = 3;\n" // aligned
" endcase\n"
"endtask\n"},
{// randcase: inferred flush-left
"task trc ;randcase 10000: x = 1; 1: x = 3; endcase endtask",
"task trc;\n"
" randcase\n"
" 10000: x = 1;\n"
" 1: x = 3;\n"
" endcase\n"
"endtask\n"},
{// randcase: induce alignment
"task trc ;randcase 10000: x = 1 ; 1: x = 3; endcase endtask",
"task trc;\n"
" randcase\n"
" 10000: x = 1;\n"
" 1: x = 3;\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