1394 lines
46 KiB
C++
1394 lines
46 KiB
C++
//===- unittest/Format/FormatTestVerilog.cpp ------------------------------===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "FormatTestBase.h"
|
|
|
|
#define DEBUG_TYPE "format-test"
|
|
|
|
namespace clang {
|
|
namespace format {
|
|
namespace test {
|
|
namespace {
|
|
class FormatTestVerilog : public test::FormatTestBase {
|
|
protected:
|
|
FormatStyle getDefaultStyle() const override {
|
|
return getLLVMStyle(FormatStyle::LK_Verilog);
|
|
}
|
|
std::string messUp(llvm::StringRef Code) const override {
|
|
return test::messUp(Code, /*HandleHash=*/false);
|
|
}
|
|
};
|
|
|
|
TEST_F(FormatTestVerilog, Align) {
|
|
FormatStyle Style = getDefaultStyle();
|
|
Style.AlignConsecutiveAssignments.Enabled = true;
|
|
verifyFormat("x <= x;\n"
|
|
"sfdbddfbdfbb <= x;\n"
|
|
"x = x;",
|
|
Style);
|
|
verifyFormat("x = x;\n"
|
|
"sfdbddfbdfbb = x;\n"
|
|
"x = x;",
|
|
Style);
|
|
// Compound assignments are not aligned by default. '<=' is not a compound
|
|
// assignment.
|
|
verifyFormat("x <= x;\n"
|
|
"sfdbddfbdfbb <= x;",
|
|
Style);
|
|
verifyFormat("x += x;\n"
|
|
"sfdbddfbdfbb <= x;",
|
|
Style);
|
|
verifyFormat("x <<= x;\n"
|
|
"sfdbddfbdfbb <= x;",
|
|
Style);
|
|
verifyFormat("x <<<= x;\n"
|
|
"sfdbddfbdfbb <= x;",
|
|
Style);
|
|
verifyFormat("x >>= x;\n"
|
|
"sfdbddfbdfbb <= x;",
|
|
Style);
|
|
verifyFormat("x >>>= x;\n"
|
|
"sfdbddfbdfbb <= x;",
|
|
Style);
|
|
Style.AlignConsecutiveAssignments.AlignCompound = true;
|
|
verifyFormat("x <= x;\n"
|
|
"sfdbddfbdfbb <= x;",
|
|
Style);
|
|
verifyFormat("x += x;\n"
|
|
"sfdbddfbdfbb <= x;",
|
|
Style);
|
|
verifyFormat("x <<= x;\n"
|
|
"sfdbddfbdfbb <= x;",
|
|
Style);
|
|
verifyFormat("x <<<= x;\n"
|
|
"sfdbddfbdfbb <= x;",
|
|
Style);
|
|
verifyFormat("x >>= x;\n"
|
|
"sfdbddfbdfbb <= x;",
|
|
Style);
|
|
verifyFormat("x >>>= x;\n"
|
|
"sfdbddfbdfbb <= x;",
|
|
Style);
|
|
}
|
|
|
|
TEST_F(FormatTestVerilog, Assign) {
|
|
verifyFormat("assign mynet = enable;");
|
|
verifyFormat("assign (strong1, pull0) #1 mynet = enable;");
|
|
verifyFormat("assign #1 mynet = enable;");
|
|
verifyFormat("assign mynet = enable;");
|
|
// Test that assignments are on separate lines.
|
|
verifyFormat("assign mynet = enable,\n"
|
|
" mynet1 = enable1;");
|
|
// Test that `<=` and `,` don't confuse it.
|
|
verifyFormat("assign mynet = enable1 <= enable2;");
|
|
verifyFormat("assign mynet = enable1 <= enable2,\n"
|
|
" mynet1 = enable3;");
|
|
verifyFormat("assign mynet = enable,\n"
|
|
" mynet1 = enable2 <= enable3;");
|
|
verifyFormat("assign mynet = enable(enable1, enable2);");
|
|
}
|
|
|
|
TEST_F(FormatTestVerilog, BasedLiteral) {
|
|
verifyFormat("x = '0;");
|
|
verifyFormat("x = '1;");
|
|
verifyFormat("x = 'X;");
|
|
verifyFormat("x = 'x;");
|
|
verifyFormat("x = 'Z;");
|
|
verifyFormat("x = 'z;");
|
|
verifyFormat("x = 659;");
|
|
verifyFormat("x = 'h837ff;");
|
|
verifyFormat("x = 'o7460;");
|
|
verifyFormat("x = 4'b1001;");
|
|
verifyFormat("x = 5'D3;");
|
|
verifyFormat("x = 3'b01x;");
|
|
verifyFormat("x = 12'hx;");
|
|
verifyFormat("x = 16'hz;");
|
|
verifyFormat("x = -8'd6;");
|
|
verifyFormat("x = 4'shf;");
|
|
verifyFormat("x = -4'sd15;");
|
|
verifyFormat("x = 16'sd?;");
|
|
}
|
|
|
|
TEST_F(FormatTestVerilog, Block) {
|
|
verifyFormat("begin\n"
|
|
" x = x;\n"
|
|
"end");
|
|
verifyFormat("begin : x\n"
|
|
" x = x;\n"
|
|
"end : x");
|
|
verifyFormat("begin\n"
|
|
" x = x;\n"
|
|
" x = x;\n"
|
|
"end");
|
|
verifyFormat("fork\n"
|
|
" x = x;\n"
|
|
"join");
|
|
verifyFormat("fork\n"
|
|
" x = x;\n"
|
|
"join_any");
|
|
verifyFormat("fork\n"
|
|
" x = x;\n"
|
|
"join_none");
|
|
verifyFormat("generate\n"
|
|
" x = x;\n"
|
|
"endgenerate");
|
|
verifyFormat("generate : x\n"
|
|
" x = x;\n"
|
|
"endgenerate : x");
|
|
// Nested blocks.
|
|
verifyFormat("begin\n"
|
|
" begin\n"
|
|
" end\n"
|
|
"end");
|
|
verifyFormat("begin : x\n"
|
|
" begin\n"
|
|
" end\n"
|
|
"end : x");
|
|
verifyFormat("begin : x\n"
|
|
" begin : x\n"
|
|
" end : x\n"
|
|
"end : x");
|
|
verifyFormat("begin\n"
|
|
" begin : x\n"
|
|
" end : x\n"
|
|
"end");
|
|
// Test that 'disable fork' and 'rand join' don't get mistaken as blocks.
|
|
verifyFormat("disable fork;\n"
|
|
"x = x;");
|
|
verifyFormat("rand join x x;\n"
|
|
"x = x;");
|
|
// The begin keyword should not be indented if it is too long to fit on the
|
|
// same line.
|
|
verifyFormat("while (true) //\n"
|
|
"begin\n"
|
|
" while (true) //\n"
|
|
" begin\n"
|
|
" end\n"
|
|
"end");
|
|
verifyFormat("while (true) //\n"
|
|
"begin : x\n"
|
|
" while (true) //\n"
|
|
" begin : x\n"
|
|
" end : x\n"
|
|
"end : x");
|
|
verifyFormat("while (true) //\n"
|
|
"fork\n"
|
|
" while (true) //\n"
|
|
" fork\n"
|
|
" join\n"
|
|
"join");
|
|
auto Style = getDefaultStyle();
|
|
Style.ColumnLimit = 17;
|
|
verifyFormat("while (true)\n"
|
|
"begin\n"
|
|
" while (true)\n"
|
|
" begin\n"
|
|
" end\n"
|
|
"end",
|
|
"while (true) begin\n"
|
|
" while (true) begin"
|
|
" end\n"
|
|
"end",
|
|
Style);
|
|
}
|
|
|
|
TEST_F(FormatTestVerilog, Case) {
|
|
verifyFormat("case (data)\n"
|
|
"endcase");
|
|
verifyFormat("casex (data)\n"
|
|
"endcase");
|
|
verifyFormat("casez (data)\n"
|
|
"endcase");
|
|
verifyFormat("case (data) inside\n"
|
|
"endcase");
|
|
verifyFormat("case (data)\n"
|
|
" 16'd0:\n"
|
|
" result = 10'b0111111111;\n"
|
|
"endcase");
|
|
verifyFormat("case (data)\n"
|
|
" xxxxxxxx:\n"
|
|
" result = 10'b0111111111;\n"
|
|
"endcase");
|
|
// Test labels with multiple options.
|
|
verifyFormat("case (data)\n"
|
|
" 16'd0, 16'd1:\n"
|
|
" result = 10'b0111111111;\n"
|
|
"endcase");
|
|
verifyFormat("case (data)\n"
|
|
" 16'd0, //\n"
|
|
" 16'd1:\n"
|
|
" result = 10'b0111111111;\n"
|
|
"endcase");
|
|
// Test that blocks following labels are indented.
|
|
verifyFormat("case (data)\n"
|
|
" 16'd1: fork\n"
|
|
" result = 10'b1011111111;\n"
|
|
" join\n"
|
|
"endcase");
|
|
verifyFormat("case (data)\n"
|
|
" 16'd1: fork : x\n"
|
|
" result = 10'b1011111111;\n"
|
|
" join : x\n"
|
|
"endcase");
|
|
// Test default.
|
|
verifyFormat("case (data)\n"
|
|
" default\n"
|
|
" result = 10'b1011111111;\n"
|
|
"endcase");
|
|
verifyFormat("case (data)\n"
|
|
" default:\n"
|
|
" result = 10'b1011111111;\n"
|
|
"endcase");
|
|
// Test that question marks and colons don't get mistaken as labels.
|
|
verifyFormat("case (data)\n"
|
|
" 8'b1???????:\n"
|
|
" instruction1(ir);\n"
|
|
"endcase");
|
|
verifyFormat("case (data)\n"
|
|
" x ? 8'b1??????? : 1:\n"
|
|
" instruction3(ir);\n"
|
|
"endcase");
|
|
// Test indention options.
|
|
auto Style = getDefaultStyle();
|
|
Style.IndentCaseLabels = false;
|
|
verifyFormat("case (data)\n"
|
|
"16'd0:\n"
|
|
" result = 10'b0111111111;\n"
|
|
"endcase",
|
|
Style);
|
|
verifyFormat("case (data)\n"
|
|
"16'd0: begin\n"
|
|
" result = 10'b0111111111;\n"
|
|
"end\n"
|
|
"endcase",
|
|
Style);
|
|
Style.IndentCaseLabels = true;
|
|
verifyFormat("case (data)\n"
|
|
" 16'd0:\n"
|
|
" result = 10'b0111111111;\n"
|
|
"endcase",
|
|
Style);
|
|
verifyFormat("case (data)\n"
|
|
" 16'd0: begin\n"
|
|
" result = 10'b0111111111;\n"
|
|
" end\n"
|
|
"endcase",
|
|
Style);
|
|
// Other colons should not be mistaken as case colons.
|
|
Style = getDefaultStyle();
|
|
Style.BitFieldColonSpacing = FormatStyle::BFCS_None;
|
|
verifyFormat("case (x[1:0])\n"
|
|
"endcase",
|
|
Style);
|
|
verifyFormat("default:\n"
|
|
" x[1:0] = x[1:0];",
|
|
Style);
|
|
Style.BitFieldColonSpacing = FormatStyle::BFCS_Both;
|
|
verifyFormat("case (x[1 : 0])\n"
|
|
"endcase",
|
|
Style);
|
|
verifyFormat("default:\n"
|
|
" x[1 : 0] = x[1 : 0];",
|
|
Style);
|
|
Style = getDefaultStyle();
|
|
Style.SpacesInContainerLiterals = true;
|
|
verifyFormat("case ('{x : x, default : 9})\n"
|
|
"endcase",
|
|
Style);
|
|
verifyFormat("x = '{x : x, default : 9};", Style);
|
|
verifyFormat("default:\n"
|
|
" x = '{x : x, default : 9};",
|
|
Style);
|
|
Style.SpacesInContainerLiterals = false;
|
|
verifyFormat("case ('{x: x, default: 9})\n"
|
|
"endcase",
|
|
Style);
|
|
verifyFormat("x = '{x: x, default: 9};", Style);
|
|
verifyFormat("default:\n"
|
|
" x = '{x: x, default: 9};",
|
|
Style);
|
|
// When the line following the case label needs to be broken, the continuation
|
|
// should be indented correctly.
|
|
verifyFormat("case (data)\n"
|
|
" 16'd0:\n"
|
|
" result = //\n"
|
|
" 10'b0111111111;\n"
|
|
"endcase");
|
|
verifyFormat("case (data)\n"
|
|
" 16'd0, //\n"
|
|
" 16'd1:\n"
|
|
" result = //\n"
|
|
" 10'b0111111111;\n"
|
|
"endcase");
|
|
verifyFormat("case (data)\n"
|
|
" 16'd0:\n"
|
|
" result = (10'b0111111111 + //\n"
|
|
" 10'b0111111111 + //\n"
|
|
" 10'b0111111111);\n"
|
|
"endcase");
|
|
verifyFormat("case (data)\n"
|
|
" 16'd0:\n"
|
|
" result = //\n"
|
|
" (10'b0111111111 + //\n"
|
|
" 10'b0111111111 + //\n"
|
|
" 10'b0111111111);\n"
|
|
"endcase");
|
|
verifyFormat("case (data)\n"
|
|
" 16'd0:\n"
|
|
" result = //\n"
|
|
" longfunction( //\n"
|
|
" arg);\n"
|
|
"endcase");
|
|
verifyFormat("case (data)\n"
|
|
" 16'd0:\n"
|
|
" //\n"
|
|
" result = //\n"
|
|
" 10'b0111111111;\n"
|
|
"endcase");
|
|
verifyFormat("case (data)\n"
|
|
" 16'd0:\n"
|
|
" //\n"
|
|
"\n"
|
|
" //\n"
|
|
" result = //\n"
|
|
" 10'b0111111111;\n"
|
|
"endcase");
|
|
Style = getDefaultStyle();
|
|
Style.ContinuationIndentWidth = 1;
|
|
verifyFormat("case (data)\n"
|
|
" 16'd0:\n"
|
|
" result = //\n"
|
|
" 10'b0111111111;\n"
|
|
"endcase",
|
|
Style);
|
|
verifyFormat("case (data)\n"
|
|
" 16'd0:\n"
|
|
" result = //\n"
|
|
" longfunction( //\n"
|
|
" arg);\n"
|
|
"endcase",
|
|
Style);
|
|
|
|
verifyFormat("case (v) matches\n"
|
|
" tagged Valid .n:\n"
|
|
" ;\n"
|
|
"endcase");
|
|
}
|
|
|
|
TEST_F(FormatTestVerilog, Coverage) {
|
|
verifyFormat("covergroup x\n"
|
|
" @@(begin x);\n"
|
|
"endgroup");
|
|
}
|
|
|
|
TEST_F(FormatTestVerilog, Declaration) {
|
|
verifyFormat("wire mynet;");
|
|
verifyFormat("wire mynet, mynet1;");
|
|
verifyFormat("wire mynet, //\n"
|
|
" mynet1;");
|
|
verifyFormat("wire mynet = enable;");
|
|
verifyFormat("wire mynet = enable, mynet1;");
|
|
verifyFormat("wire mynet = enable, //\n"
|
|
" mynet1;");
|
|
verifyFormat("wire mynet, mynet1 = enable;");
|
|
verifyFormat("wire mynet, //\n"
|
|
" mynet1 = enable;");
|
|
verifyFormat("wire mynet = enable, mynet1 = enable;");
|
|
verifyFormat("wire mynet = enable, //\n"
|
|
" mynet1 = enable;");
|
|
verifyFormat("wire (strong1, pull0) mynet;");
|
|
verifyFormat("wire (strong1, pull0) mynet, mynet1;");
|
|
verifyFormat("wire (strong1, pull0) mynet, //\n"
|
|
" mynet1;");
|
|
verifyFormat("wire (strong1, pull0) mynet = enable;");
|
|
verifyFormat("wire (strong1, pull0) mynet = enable, mynet1;");
|
|
verifyFormat("wire (strong1, pull0) mynet = enable, //\n"
|
|
" mynet1;");
|
|
verifyFormat("wire (strong1, pull0) mynet, mynet1 = enable;");
|
|
verifyFormat("wire (strong1, pull0) mynet, //\n"
|
|
" mynet1 = enable;");
|
|
}
|
|
|
|
TEST_F(FormatTestVerilog, Delay) {
|
|
// Delay by the default unit.
|
|
verifyFormat("#0;");
|
|
verifyFormat("#1;");
|
|
verifyFormat("#10;");
|
|
verifyFormat("#1.5;");
|
|
// Explicit unit.
|
|
verifyFormat("#1fs;");
|
|
verifyFormat("#1.5fs;");
|
|
verifyFormat("#1ns;");
|
|
verifyFormat("#1.5ns;");
|
|
verifyFormat("#1us;");
|
|
verifyFormat("#1.5us;");
|
|
verifyFormat("#1ms;");
|
|
verifyFormat("#1.5ms;");
|
|
verifyFormat("#1s;");
|
|
verifyFormat("#1.5s;");
|
|
// The following expression should be on the same line.
|
|
verifyFormat("#1 x = x;");
|
|
verifyFormat("#1 x = x;", "#1\n"
|
|
"x = x;");
|
|
}
|
|
|
|
TEST_F(FormatTestVerilog, Enum) {
|
|
verifyFormat("enum { x } x;");
|
|
verifyFormat("typedef enum { x } x;");
|
|
verifyFormat("enum { red, yellow, green } x;");
|
|
verifyFormat("typedef enum { red, yellow, green } x;");
|
|
verifyFormat("enum integer { x } x;");
|
|
verifyFormat("typedef enum { x = 0 } x;");
|
|
verifyFormat("typedef enum { red = 0, yellow = 1, green = 2 } x;");
|
|
verifyFormat("typedef enum integer { x } x;");
|
|
verifyFormat("typedef enum bit [0 : 1] { x } x;");
|
|
verifyFormat("typedef enum { add = 10, sub[5], jmp[6 : 8] } E1;");
|
|
verifyFormat("typedef enum { add = 10, sub[5] = 0, jmp[6 : 8] = 1 } E1;");
|
|
}
|
|
|
|
TEST_F(FormatTestVerilog, Headers) {
|
|
// Test headers with multiple ports.
|
|
verifyFormat("module mh1\n"
|
|
" (input var int in1,\n"
|
|
" input var shortreal in2,\n"
|
|
" output tagged_st out);\n"
|
|
"endmodule");
|
|
// There should be a space following the type but not the variable name.
|
|
verifyFormat("module test\n"
|
|
" (input wire [7 : 0] a,\n"
|
|
" input wire b[7 : 0],\n"
|
|
" input wire [7 : 0] c[7 : 0]);\n"
|
|
"endmodule");
|
|
// Ports should be grouped by types.
|
|
verifyFormat("module test\n"
|
|
" (input [7 : 0] a,\n"
|
|
" input signed [7 : 0] b, c, d);\n"
|
|
"endmodule");
|
|
verifyFormat("module test\n"
|
|
" (input [7 : 0] a,\n"
|
|
" (* x = x *) input signed [7 : 0] b, c, d);\n"
|
|
"endmodule");
|
|
verifyFormat("module test\n"
|
|
" (input [7 : 0] a = 0,\n"
|
|
" input signed [7 : 0] b = 0, c = 0, d = 0);\n"
|
|
"endmodule");
|
|
verifyFormat("module test\n"
|
|
" #(parameter x)\n"
|
|
" (input [7 : 0] a,\n"
|
|
" input signed [7 : 0] b, c, d);\n"
|
|
"endmodule");
|
|
// When a line needs to be broken, ports of the same type should be aligned to
|
|
// the same column.
|
|
verifyFormat("module test\n"
|
|
" (input signed [7 : 0] b, c, //\n"
|
|
" d);\n"
|
|
"endmodule");
|
|
verifyFormat("module test\n"
|
|
" ((* x = x *) input signed [7 : 0] b, c, //\n"
|
|
" d);\n"
|
|
"endmodule");
|
|
verifyFormat("module test\n"
|
|
" (input signed [7 : 0] b = 0, c, //\n"
|
|
" d);\n"
|
|
"endmodule");
|
|
verifyFormat("module test\n"
|
|
" (input signed [7 : 0] b, c = 0, //\n"
|
|
" d);\n"
|
|
"endmodule");
|
|
verifyFormat("module test\n"
|
|
" (input signed [7 : 0] b, c, //\n"
|
|
" d = 0);\n"
|
|
"endmodule");
|
|
verifyFormat("module test\n"
|
|
" (input wire logic signed [7 : 0][0 : 1] b, c, //\n"
|
|
" d);\n"
|
|
"endmodule");
|
|
verifyFormat("module test\n"
|
|
" (input signed [7 : 0] b, //\n"
|
|
" c, //\n"
|
|
" d);\n"
|
|
"endmodule");
|
|
verifyFormat("module test\n"
|
|
" (input [7 : 0] a,\n"
|
|
" input signed [7 : 0] b, //\n"
|
|
" c, //\n"
|
|
" d);\n"
|
|
"endmodule");
|
|
verifyFormat("module test\n"
|
|
" (input signed [7 : 0] b, //\n"
|
|
" c, //\n"
|
|
" d,\n"
|
|
" output signed [7 : 0] h);\n"
|
|
"endmodule");
|
|
// With a modport.
|
|
verifyFormat("module m\n"
|
|
" (i2.master i);\n"
|
|
"endmodule");
|
|
verifyFormat("module m\n"
|
|
" (i2.master i, ii);\n"
|
|
"endmodule");
|
|
verifyFormat("module m\n"
|
|
" (i2.master i, //\n"
|
|
" ii);\n"
|
|
"endmodule");
|
|
verifyFormat("module m\n"
|
|
" (i2.master i,\n"
|
|
" input ii);\n"
|
|
"endmodule");
|
|
verifyFormat("module m\n"
|
|
" (i2::i2.master i);\n"
|
|
"endmodule");
|
|
verifyFormat("module m\n"
|
|
" (i2::i2.master i, ii);\n"
|
|
"endmodule");
|
|
verifyFormat("module m\n"
|
|
" (i2::i2.master i, //\n"
|
|
" ii);\n"
|
|
"endmodule");
|
|
verifyFormat("module m\n"
|
|
" (i2::i2.master i,\n"
|
|
" input ii);\n"
|
|
"endmodule");
|
|
verifyFormat("module m\n"
|
|
" (i2::i2 i);\n"
|
|
"endmodule");
|
|
verifyFormat("module m\n"
|
|
" (i2::i2 i, ii);\n"
|
|
"endmodule");
|
|
verifyFormat("module m\n"
|
|
" (i2::i2 i, //\n"
|
|
" ii);\n"
|
|
"endmodule");
|
|
verifyFormat("module m\n"
|
|
" (i2::i2 i,\n"
|
|
" input ii);\n"
|
|
"endmodule");
|
|
// With a macro in the names.
|
|
verifyFormat("module m\n"
|
|
" (input var `x a, b);\n"
|
|
"endmodule");
|
|
verifyFormat("module m\n"
|
|
" (input var `x a, //\n"
|
|
" b);\n"
|
|
"endmodule");
|
|
verifyFormat("module m\n"
|
|
" (input var x `a, b);\n"
|
|
"endmodule");
|
|
verifyFormat("module m\n"
|
|
" (input var x `a, //\n"
|
|
" b);\n"
|
|
"endmodule");
|
|
// A line comment shouldn't disrupt the indentation of the port list.
|
|
verifyFormat("extern module x\n"
|
|
" (//\n"
|
|
" output y);");
|
|
verifyFormat("extern module x\n"
|
|
" #(//\n"
|
|
" parameter x)\n"
|
|
" (//\n"
|
|
" output y);");
|
|
// With a concatenation in the names.
|
|
auto Style = getDefaultStyle();
|
|
Style.ColumnLimit = 40;
|
|
verifyFormat("`define X(x) \\\n"
|
|
" module test \\\n"
|
|
" (input var x``x a, b);",
|
|
Style);
|
|
verifyFormat("`define X(x) \\\n"
|
|
" module test \\\n"
|
|
" (input var x``x aaaaaaaaaaaaaaa, \\\n"
|
|
" b);",
|
|
Style);
|
|
verifyFormat("`define X(x) \\\n"
|
|
" module test \\\n"
|
|
" (input var x a``x, b);",
|
|
Style);
|
|
verifyFormat("`define X(x) \\\n"
|
|
" module test \\\n"
|
|
" (input var x aaaaaaaaaaaaaaa``x, \\\n"
|
|
" b);",
|
|
Style);
|
|
// When the ports line is not to be formatted, following lines should not take
|
|
// on its indentation.
|
|
verifyFormat("module x\n"
|
|
" (output x);\n"
|
|
" assign x = 0;\n"
|
|
"endmodule",
|
|
"module x\n"
|
|
" (output x);\n"
|
|
" assign x = 0;\n"
|
|
"endmodule",
|
|
getDefaultStyle(), {tooling::Range(25, 18)});
|
|
}
|
|
|
|
TEST_F(FormatTestVerilog, Hierarchy) {
|
|
verifyFormat("module x;\n"
|
|
"endmodule");
|
|
// Test that the end label is on the same line as the end keyword.
|
|
verifyFormat("module x;\n"
|
|
"endmodule : x");
|
|
// Test that things inside are indented.
|
|
verifyFormat("module x;\n"
|
|
" generate\n"
|
|
" endgenerate\n"
|
|
"endmodule");
|
|
verifyFormat("program x;\n"
|
|
" generate\n"
|
|
" endgenerate\n"
|
|
"endprogram");
|
|
verifyFormat("interface x;\n"
|
|
" generate\n"
|
|
" endgenerate\n"
|
|
"endinterface");
|
|
verifyFormat("task x;\n"
|
|
" generate\n"
|
|
" endgenerate\n"
|
|
"endtask");
|
|
verifyFormat("function x;\n"
|
|
" generate\n"
|
|
" endgenerate\n"
|
|
"endfunction");
|
|
verifyFormat("class x;\n"
|
|
" generate\n"
|
|
" endgenerate\n"
|
|
"endclass");
|
|
// Test that they nest.
|
|
verifyFormat("module x;\n"
|
|
" program x;\n"
|
|
" program x;\n"
|
|
" endprogram\n"
|
|
" endprogram\n"
|
|
"endmodule");
|
|
// Test that an extern declaration doesn't change the indentation.
|
|
verifyFormat("extern module x;\n"
|
|
"x = x;");
|
|
// Test complex headers
|
|
verifyFormat("extern module x\n"
|
|
" import x.x::x::*;\n"
|
|
" import x;\n"
|
|
" #(parameter x)\n"
|
|
" (output x);");
|
|
verifyFormat("module x\n"
|
|
" import x.x::x::*;\n"
|
|
" import x;\n"
|
|
" #(parameter x)\n"
|
|
" (output x);\n"
|
|
" generate\n"
|
|
" endgenerate\n"
|
|
"endmodule : x");
|
|
verifyFormat("virtual class x\n"
|
|
" (x)\n"
|
|
" extends x(x)\n"
|
|
" implements x, x, x;\n"
|
|
" generate\n"
|
|
" endgenerate\n"
|
|
"endclass : x");
|
|
verifyFormat("function automatic logic [1 : 0] x\n"
|
|
" (input x);\n"
|
|
" generate\n"
|
|
" endgenerate\n"
|
|
"endfunction : x");
|
|
}
|
|
|
|
TEST_F(FormatTestVerilog, Identifiers) {
|
|
// Escaped identifiers should not be split.
|
|
verifyFormat("\\busa+index");
|
|
verifyFormat("\\-clock");
|
|
verifyFormat("\\***error-condition***");
|
|
verifyFormat("\\net1\\/net2");
|
|
verifyFormat("\\{a,b}");
|
|
verifyFormat("\\a*(b+c)");
|
|
// Escaped identifiers can't be joined with the next token. Extra space
|
|
// should be removed.
|
|
verifyFormat("\\busa+index ;", "\\busa+index\n"
|
|
";");
|
|
verifyFormat("\\busa+index ;", "\\busa+index\r\n"
|
|
";");
|
|
verifyFormat("\\busa+index ;", "\\busa+index ;");
|
|
verifyFormat("\\busa+index ;", "\\busa+index\n"
|
|
" ;");
|
|
verifyFormat("\\busa+index ;");
|
|
verifyFormat("(\\busa+index );");
|
|
verifyFormat("\\busa+index \\busa+index ;");
|
|
}
|
|
|
|
TEST_F(FormatTestVerilog, If) {
|
|
verifyFormat("if (x)\n"
|
|
" x = x;");
|
|
verifyFormat("unique if (x)\n"
|
|
" x = x;");
|
|
verifyFormat("unique0 if (x)\n"
|
|
" x = x;");
|
|
verifyFormat("priority if (x)\n"
|
|
" x = x;");
|
|
verifyFormat("if (x)\n"
|
|
" x = x;\n"
|
|
"x = x;");
|
|
|
|
// Test else
|
|
verifyFormat("if (x)\n"
|
|
" x = x;\n"
|
|
"else if (x)\n"
|
|
" x = x;\n"
|
|
"else\n"
|
|
" x = x;");
|
|
verifyFormat("if (x) begin\n"
|
|
" x = x;\n"
|
|
"end else if (x) begin\n"
|
|
" x = x;\n"
|
|
"end else begin\n"
|
|
" x = x;\n"
|
|
"end");
|
|
verifyFormat("if (x) begin : x\n"
|
|
" x = x;\n"
|
|
"end : x else if (x) begin : x\n"
|
|
" x = x;\n"
|
|
"end : x else begin : x\n"
|
|
" x = x;\n"
|
|
"end : x");
|
|
|
|
// Test block keywords.
|
|
verifyFormat("if (x) begin\n"
|
|
" x = x;\n"
|
|
"end");
|
|
verifyFormat("if (x) begin : x\n"
|
|
" x = x;\n"
|
|
"end : x");
|
|
verifyFormat("if (x) begin\n"
|
|
" x = x;\n"
|
|
" x = x;\n"
|
|
"end");
|
|
verifyFormat("if (x) fork\n"
|
|
" x = x;\n"
|
|
"join");
|
|
verifyFormat("if (x) fork\n"
|
|
" x = x;\n"
|
|
"join_any");
|
|
verifyFormat("if (x) fork\n"
|
|
" x = x;\n"
|
|
"join_none");
|
|
verifyFormat("if (x) generate\n"
|
|
" x = x;\n"
|
|
"endgenerate");
|
|
verifyFormat("if (x) generate : x\n"
|
|
" x = x;\n"
|
|
"endgenerate : x");
|
|
|
|
// Test that concatenation braces don't get regarded as blocks.
|
|
verifyFormat("if (x)\n"
|
|
" {x} = x;");
|
|
verifyFormat("if (x)\n"
|
|
" x = {x};");
|
|
verifyFormat("if (x)\n"
|
|
" x = {x};\n"
|
|
"else\n"
|
|
" {x} = {x};");
|
|
|
|
// With attributes.
|
|
verifyFormat("(* x *) if (x)\n"
|
|
" x = x;");
|
|
verifyFormat("(* x = \"x\" *) if (x)\n"
|
|
" x = x;");
|
|
verifyFormat("(* x, x = \"x\" *) if (x)\n"
|
|
" x = x;");
|
|
|
|
// Assert are treated similar to if. But the else parts should not be
|
|
// chained.
|
|
verifyFormat("assert (x);");
|
|
verifyFormat("assert (x)\n"
|
|
" $info();");
|
|
verifyFormat("assert (x)\n"
|
|
" $info();\n"
|
|
"else\n"
|
|
" $error();");
|
|
verifyFormat("assert (x)\n"
|
|
"else\n"
|
|
" $error();");
|
|
verifyFormat("assert (x)\n"
|
|
"else begin\n"
|
|
"end");
|
|
verifyFormat("assert (x)\n"
|
|
"else\n"
|
|
" if (x)\n"
|
|
" $error();");
|
|
verifyFormat("assert (x)\n"
|
|
" $info();\n"
|
|
"else\n"
|
|
" if (x)\n"
|
|
" $error();");
|
|
verifyFormat("assert (x)\n"
|
|
" $info();\n"
|
|
"else\n"
|
|
" if (x)\n"
|
|
" $error();\n"
|
|
" else\n"
|
|
" $error();");
|
|
verifyFormat("assert (x)\n"
|
|
" $info();\n"
|
|
"else\n"
|
|
" if (x)\n"
|
|
" $error();\n"
|
|
" else if (x)\n"
|
|
" $error();\n"
|
|
" else\n"
|
|
" $error();");
|
|
// The body is optional for asserts. The next line should not be indented if
|
|
// the statement already ended with a semicolon.
|
|
verifyFormat("assert (x);\n"
|
|
"x = x;");
|
|
verifyFormat("if (x)\n"
|
|
" assert (x);\n"
|
|
"else if (x) begin\n"
|
|
"end else begin\n"
|
|
"end");
|
|
verifyFormat("if (x)\n"
|
|
" assert (x);\n"
|
|
"else begin\n"
|
|
"end");
|
|
verifyFormat("if (x)\n"
|
|
" assert (x)\n"
|
|
" else begin\n"
|
|
" end");
|
|
// Other keywords.
|
|
verifyFormat("assume (x)\n"
|
|
" $info();");
|
|
verifyFormat("cover (x)\n"
|
|
" $info();");
|
|
verifyFormat("restrict (x)\n"
|
|
" $info();");
|
|
verifyFormat("assert #0 (x)\n"
|
|
" $info();");
|
|
verifyFormat("assert final (x)\n"
|
|
" $info();");
|
|
verifyFormat("cover #0 (x)\n"
|
|
" $info();");
|
|
verifyFormat("cover final (x)\n"
|
|
" $info();");
|
|
|
|
// The space around parentheses options should work.
|
|
auto Style = getDefaultStyle();
|
|
verifyFormat("if (x)\n"
|
|
" x = x;\n"
|
|
"else if (x)\n"
|
|
" x = x;",
|
|
Style);
|
|
verifyFormat("assert (x);", Style);
|
|
verifyFormat("assert #0 (x);", Style);
|
|
verifyFormat("assert (x)\n"
|
|
"else\n"
|
|
" if (x)\n"
|
|
" x = x;",
|
|
Style);
|
|
Style.SpacesInParens = FormatStyle::SIPO_Custom;
|
|
Style.SpacesInParensOptions.InConditionalStatements = true;
|
|
verifyFormat("if ( x )\n"
|
|
" x = x;\n"
|
|
"else if ( x )\n"
|
|
" x = x;",
|
|
Style);
|
|
verifyFormat("assert ( x );", Style);
|
|
verifyFormat("assert #0 ( x );", Style);
|
|
verifyFormat("assert ( x )\n"
|
|
"else\n"
|
|
" if ( x )\n"
|
|
" x = x;",
|
|
Style);
|
|
}
|
|
|
|
TEST_F(FormatTestVerilog, Instantiation) {
|
|
// Without ports.
|
|
verifyFormat("ffnand ff1;");
|
|
// With named ports.
|
|
verifyFormat("ffnand ff1(.qbar(out1),\n"
|
|
" .clear(in1),\n"
|
|
" .preset(in2));");
|
|
// With wildcard.
|
|
verifyFormat("ffnand ff1(.qbar(out1),\n"
|
|
" .clear(in1),\n"
|
|
" .preset(in2),\n"
|
|
" .*);");
|
|
verifyFormat("ffnand ff1(.*,\n"
|
|
" .qbar(out1),\n"
|
|
" .clear(in1),\n"
|
|
" .preset(in2));");
|
|
// With unconnected ports.
|
|
verifyFormat("ffnand ff1(.q(),\n"
|
|
" .qbar(out1),\n"
|
|
" .clear(in1),\n"
|
|
" .preset(in2));");
|
|
verifyFormat("ffnand ff1(.q(),\n"
|
|
" .qbar(),\n"
|
|
" .clear(),\n"
|
|
" .preset());");
|
|
verifyFormat("ffnand ff1(,\n"
|
|
" .qbar(out1),\n"
|
|
" .clear(in1),\n"
|
|
" .preset(in2));");
|
|
// With positional ports.
|
|
verifyFormat("ffnand ff1(out1,\n"
|
|
" in1,\n"
|
|
" in2);");
|
|
verifyFormat("ffnand ff1(,\n"
|
|
" out1,\n"
|
|
" in1,\n"
|
|
" in2);");
|
|
// Multiple instantiations.
|
|
verifyFormat("ffnand ff1(.q(),\n"
|
|
" .qbar(out1),\n"
|
|
" .clear(in1),\n"
|
|
" .preset(in2)),\n"
|
|
" ff1(.q(),\n"
|
|
" .qbar(out1),\n"
|
|
" .clear(in1),\n"
|
|
" .preset(in2));");
|
|
verifyFormat("ffnand //\n"
|
|
" ff1(.q(),\n"
|
|
" .qbar(out1),\n"
|
|
" .clear(in1),\n"
|
|
" .preset(in2)),\n"
|
|
" ff1(.q(),\n"
|
|
" .qbar(out1),\n"
|
|
" .clear(in1),\n"
|
|
" .preset(in2));");
|
|
// With breaking between instance ports disabled.
|
|
auto Style = getDefaultStyle();
|
|
Style.VerilogBreakBetweenInstancePorts = false;
|
|
verifyFormat("ffnand ff1;", Style);
|
|
verifyFormat("ffnand ff1(.qbar(out1), .clear(in1), .preset(in2), .*);",
|
|
Style);
|
|
verifyFormat("ffnand ff1(out1, in1, in2);", Style);
|
|
verifyFormat("ffnand ff1(.q(), .qbar(out1), .clear(in1), .preset(in2)),\n"
|
|
" ff1(.q(), .qbar(out1), .clear(in1), .preset(in2));",
|
|
Style);
|
|
verifyFormat("ffnand //\n"
|
|
" ff1(.q(), .qbar(out1), .clear(in1), .preset(in2)),\n"
|
|
" ff1(.q(), .qbar(out1), .clear(in1), .preset(in2));",
|
|
Style);
|
|
}
|
|
|
|
TEST_F(FormatTestVerilog, Loop) {
|
|
verifyFormat("foreach (x[x])\n"
|
|
" x = x;");
|
|
verifyFormat("repeat (x)\n"
|
|
" x = x;");
|
|
verifyFormat("foreach (x[x]) begin\n"
|
|
"end");
|
|
verifyFormat("repeat (x) begin\n"
|
|
"end");
|
|
auto Style = getDefaultStyle();
|
|
Style.SpacesInParens = FormatStyle::SIPO_Custom;
|
|
Style.SpacesInParensOptions.InConditionalStatements = true;
|
|
verifyFormat("foreach ( x[x] )\n"
|
|
" x = x;",
|
|
Style);
|
|
verifyFormat("repeat ( x )\n"
|
|
" x = x;",
|
|
Style);
|
|
}
|
|
|
|
TEST_F(FormatTestVerilog, Operators) {
|
|
// Test that unary operators are not followed by space.
|
|
verifyFormat("x = +x;");
|
|
verifyFormat("x = -x;");
|
|
verifyFormat("x = !x;");
|
|
verifyFormat("x = ~x;");
|
|
verifyFormat("x = &x;");
|
|
verifyFormat("x = ~&x;");
|
|
verifyFormat("x = |x;");
|
|
verifyFormat("x = ~|x;");
|
|
verifyFormat("x = ^x;");
|
|
verifyFormat("x = ~^x;");
|
|
verifyFormat("x = ^~x;");
|
|
verifyFormat("x = ++x;");
|
|
verifyFormat("x = --x;");
|
|
|
|
// Test that `*` and `*>` are binary.
|
|
verifyFormat("x = x * x;");
|
|
verifyFormat("x = (x * x);");
|
|
verifyFormat("(opcode *> o1) = 6.1;");
|
|
verifyFormat("(C, D *> Q) = 18;");
|
|
// The wildcard import is not a binary operator.
|
|
verifyFormat("import p::*;");
|
|
|
|
// Test that operators don't get split.
|
|
verifyFormat("x = x++;");
|
|
verifyFormat("x = x--;");
|
|
verifyFormat("x = x ** x;");
|
|
verifyFormat("x = x << x;");
|
|
verifyFormat("x = x >> x;");
|
|
verifyFormat("x = x <<< x;");
|
|
verifyFormat("x = x >>> x;");
|
|
verifyFormat("x = x <= x;");
|
|
verifyFormat("x = x >= x;");
|
|
verifyFormat("x = x == x;");
|
|
verifyFormat("x = x != x;");
|
|
verifyFormat("x = x === x;");
|
|
verifyFormat("x = x !== x;");
|
|
verifyFormat("x = x ==? x;");
|
|
verifyFormat("x = x !=? x;");
|
|
verifyFormat("x = x ~^ x;");
|
|
verifyFormat("x = x ^~ x;");
|
|
verifyFormat("x = x && x;");
|
|
verifyFormat("x = x || x;");
|
|
verifyFormat("x = x -> x;");
|
|
verifyFormat("x = x <-> x;");
|
|
verifyFormat("x += x;");
|
|
verifyFormat("x -= x;");
|
|
verifyFormat("x *= x;");
|
|
verifyFormat("x /= x;");
|
|
verifyFormat("x %= x;");
|
|
verifyFormat("x &= x;");
|
|
verifyFormat("x ^= x;");
|
|
verifyFormat("x |= x;");
|
|
verifyFormat("x <<= x;");
|
|
verifyFormat("x >>= x;");
|
|
verifyFormat("x <<<= x;");
|
|
verifyFormat("x >>>= x;");
|
|
verifyFormat("x <= x;");
|
|
|
|
// Test that space is added between operators.
|
|
verifyFormat("x = x < -x;", "x=x<-x;");
|
|
verifyFormat("x = x << -x;", "x=x<<-x;");
|
|
verifyFormat("x = x <<< -x;", "x=x<<<-x;");
|
|
|
|
// Test that operators that are C++ identifiers get treated as operators.
|
|
verifyFormat("solve s before d;"); // before
|
|
verifyFormat("binsof(i) intersect {0};"); // intersect
|
|
verifyFormat("req dist {1};"); // dist
|
|
verifyFormat("a inside {b, c};"); // inside
|
|
verifyFormat("bus.randomize() with { atype == low; };"); // with
|
|
}
|
|
|
|
TEST_F(FormatTestVerilog, Preprocessor) {
|
|
auto Style = getDefaultStyle();
|
|
Style.ColumnLimit = 20;
|
|
|
|
// Macro definitions.
|
|
verifyFormat("`define X \\\n"
|
|
" if (x) \\\n"
|
|
" x = x;",
|
|
"`define X if(x)x=x;", Style);
|
|
verifyFormat("`define X(x) \\\n"
|
|
" if (x) \\\n"
|
|
" x = x;",
|
|
"`define X(x) if(x)x=x;", Style);
|
|
verifyFormat("`define X \\\n"
|
|
" x = x; \\\n"
|
|
" x = x;",
|
|
"`define X x=x;x=x;", Style);
|
|
// Macro definitions with invocations inside.
|
|
verifyFormat("`define LIST \\\n"
|
|
" `ENTRY \\\n"
|
|
" `ENTRY",
|
|
"`define LIST \\\n"
|
|
"`ENTRY \\\n"
|
|
"`ENTRY",
|
|
Style);
|
|
verifyFormat("`define LIST \\\n"
|
|
" `x = `x; \\\n"
|
|
" `x = `x;",
|
|
"`define LIST \\\n"
|
|
"`x = `x; \\\n"
|
|
"`x = `x;",
|
|
Style);
|
|
verifyFormat("`define LIST \\\n"
|
|
" `x = `x; \\\n"
|
|
" `x = `x;",
|
|
"`define LIST `x=`x;`x=`x;", Style);
|
|
// Macro invocations.
|
|
verifyFormat("`x = (`x1 + `x2 + x);");
|
|
// Lines starting with a preprocessor directive should not be indented.
|
|
std::string Directives[] = {
|
|
"begin_keywords",
|
|
"celldefine",
|
|
"default_nettype",
|
|
"define",
|
|
"else",
|
|
"elsif",
|
|
"end_keywords",
|
|
"endcelldefine",
|
|
"endif",
|
|
"ifdef",
|
|
"ifndef",
|
|
"include",
|
|
"line",
|
|
"nounconnected_drive",
|
|
"pragma",
|
|
"resetall",
|
|
"timescale",
|
|
"unconnected_drive",
|
|
"undef",
|
|
"undefineall",
|
|
};
|
|
for (auto &Name : Directives) {
|
|
verifyFormat("if (x)\n"
|
|
"`" +
|
|
Name +
|
|
"\n"
|
|
" ;",
|
|
"if (x)\n"
|
|
"`" +
|
|
Name +
|
|
"\n"
|
|
";",
|
|
Style);
|
|
}
|
|
// Lines starting with a regular macro invocation should be indented as a
|
|
// normal line.
|
|
verifyFormat("if (x)\n"
|
|
" `x = `x;\n"
|
|
"`timescale 1ns / 1ps",
|
|
"if (x)\n"
|
|
"`x = `x;\n"
|
|
"`timescale 1ns / 1ps",
|
|
Style);
|
|
verifyFormat("if (x)\n"
|
|
"`timescale 1ns / 1ps\n"
|
|
" `x = `x;",
|
|
"if (x)\n"
|
|
"`timescale 1ns / 1ps\n"
|
|
"`x = `x;",
|
|
Style);
|
|
std::string NonDirectives[] = {
|
|
// For `__FILE__` and `__LINE__`, although the standard classifies them as
|
|
// preprocessor directives, they are used like regular macros.
|
|
"__FILE__", "__LINE__", "elif", "foo", "x",
|
|
};
|
|
for (auto &Name : NonDirectives) {
|
|
verifyFormat("if (x)\n"
|
|
" `" +
|
|
Name + ";",
|
|
"if (x)\n"
|
|
"`" +
|
|
Name +
|
|
"\n"
|
|
";",
|
|
Style);
|
|
}
|
|
}
|
|
|
|
TEST_F(FormatTestVerilog, Primitive) {
|
|
verifyFormat("primitive multiplexer\n"
|
|
" (mux, control, dataA, dataB);\n"
|
|
" output mux;\n"
|
|
" input control, dataA, dataB;\n"
|
|
" table\n"
|
|
" 0 1 ? : 1;\n"
|
|
" 0 0 ? : 0;\n"
|
|
" 1 ? 1 : 1;\n"
|
|
" 1 ? 0 : 0;\n"
|
|
" x 0 0 : 0;\n"
|
|
" x 1 1 : 1;\n"
|
|
" endtable\n"
|
|
"endprimitive");
|
|
verifyFormat("primitive latch\n"
|
|
" (q, ena_, data);\n"
|
|
" output q;\n"
|
|
" reg q;\n"
|
|
" input ena_, data;\n"
|
|
" table\n"
|
|
" 0 1 : ? : 1;\n"
|
|
" 0 0 : ? : 0;\n"
|
|
" 1 ? : ? : -;\n"
|
|
" ? * : ? : -;\n"
|
|
" endtable\n"
|
|
"endprimitive");
|
|
verifyFormat("primitive d\n"
|
|
" (q, clock, data);\n"
|
|
" output q;\n"
|
|
" reg q;\n"
|
|
" input clock, data;\n"
|
|
" table\n"
|
|
" (01) 0 : ? : 0;\n"
|
|
" (01) 1 : ? : 1;\n"
|
|
" (0?) 1 : 1 : 1;\n"
|
|
" (0?) 0 : 0 : 0;\n"
|
|
" (?0) ? : ? : -;\n"
|
|
" (?\?) ? : ? : -;\n"
|
|
" endtable\n"
|
|
"endprimitive");
|
|
}
|
|
|
|
TEST_F(FormatTestVerilog, Streaming) {
|
|
verifyFormat("x = {>>{j}};");
|
|
verifyFormat("x = {>>byte{j}};");
|
|
verifyFormat("x = {<<{j}};");
|
|
verifyFormat("x = {<<byte{j}};");
|
|
verifyFormat("x = {<<16{j}};");
|
|
verifyFormat("x = {<<{8'b0011_0101}};");
|
|
verifyFormat("x = {<<4{6'b11_0101}};");
|
|
verifyFormat("x = {>>4{6'b11_0101}};");
|
|
verifyFormat("x = {<<2{{<<{4'b1101}}}};");
|
|
verifyFormat("bit [96 : 1] y = {>>{a, b, c}};");
|
|
verifyFormat("int j = {>>{a, b, c}};");
|
|
verifyFormat("{>>{a, b, c}} = 23'b1;");
|
|
verifyFormat("{>>{a, b, c}} = x;");
|
|
verifyFormat("{>>{j}} = x;");
|
|
verifyFormat("{>>byte{j}} = x;");
|
|
verifyFormat("{<<{j}} = x;");
|
|
verifyFormat("{<<byte{j}} = x;");
|
|
}
|
|
|
|
TEST_F(FormatTestVerilog, StringLiteral) {
|
|
// Long strings should be broken.
|
|
verifyFormat(R"(x({"xxxxxxxxxxxxxxxx ",
|
|
"xxxx"});)",
|
|
R"(x({"xxxxxxxxxxxxxxxx xxxx"});)",
|
|
getStyleWithColumns(getDefaultStyle(), 23));
|
|
verifyFormat(R"(x({"xxxxxxxxxxxxxxxx",
|
|
" xxxx"});)",
|
|
R"(x({"xxxxxxxxxxxxxxxx xxxx"});)",
|
|
getStyleWithColumns(getDefaultStyle(), 22));
|
|
// Braces should be added when they don't already exist.
|
|
verifyFormat(R"(x({"xxxxxxxxxxxxxxxx ",
|
|
"xxxx"});)",
|
|
R"(x("xxxxxxxxxxxxxxxx xxxx");)",
|
|
getStyleWithColumns(getDefaultStyle(), 23));
|
|
verifyFormat(R"(x({"xxxxxxxxxxxxxxxx",
|
|
" xxxx"});)",
|
|
R"(x("xxxxxxxxxxxxxxxx xxxx");)",
|
|
getStyleWithColumns(getDefaultStyle(), 22));
|
|
verifyFormat(R"(x({{"xxxxxxxxxxxxxxxx ",
|
|
"xxxx"} == x});)",
|
|
R"(x({"xxxxxxxxxxxxxxxx xxxx" == x});)",
|
|
getStyleWithColumns(getDefaultStyle(), 24));
|
|
verifyFormat(R"(string x = {"xxxxxxxxxxxxxxxx ",
|
|
"xxxxxxxx"};)",
|
|
R"(string x = "xxxxxxxxxxxxxxxx xxxxxxxx";)",
|
|
getStyleWithColumns(getDefaultStyle(), 32));
|
|
// Space around braces should be correct.
|
|
auto Style = getStyleWithColumns(getDefaultStyle(), 24);
|
|
Style.Cpp11BracedListStyle = false;
|
|
verifyFormat(R"(x({ "xxxxxxxxxxxxxxxx ",
|
|
"xxxx" });)",
|
|
R"(x("xxxxxxxxxxxxxxxx xxxx");)", Style);
|
|
// Braces should not be added twice.
|
|
verifyFormat(R"(x({"xxxxxxxx",
|
|
"xxxxxxxx",
|
|
"xxxxxx"});)",
|
|
R"(x("xxxxxxxxxxxxxxxxxxxxxx");)",
|
|
getStyleWithColumns(getDefaultStyle(), 14));
|
|
verifyFormat(R"(x({"xxxxxxxxxxxxxxxx ",
|
|
"xxxxxxxxxxxxxxxx ",
|
|
"xxxx"});)",
|
|
R"(x("xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx xxxx");)",
|
|
getStyleWithColumns(getDefaultStyle(), 23));
|
|
verifyFormat(R"(x({"xxxxxxxxxxxxxxxx ",
|
|
"xxxxxxxxxxxxxxxx ",
|
|
"xxxx"});)",
|
|
R"(x({"xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx ", "xxxx"});)",
|
|
getStyleWithColumns(getDefaultStyle(), 23));
|
|
// import/export "DPI"/"DPI-C" cannot be split.
|
|
verifyFormat(R"(import
|
|
"DPI-C" function void foo
|
|
();)",
|
|
R"(import "DPI-C" function void foo();)",
|
|
getStyleWithColumns(getDefaultStyle(), 23));
|
|
verifyFormat(R"(export "DPI-C" function foo;)",
|
|
R"(export "DPI-C" function foo;)",
|
|
getStyleWithColumns(getDefaultStyle(), 23));
|
|
// These kinds of strings don't exist in Verilog.
|
|
verifyNoCrash(R"(x(@"xxxxxxxxxxxxxxxx xxxx");)",
|
|
getStyleWithColumns(getDefaultStyle(), 23));
|
|
verifyNoCrash(R"(x(u"xxxxxxxxxxxxxxxx xxxx");)",
|
|
getStyleWithColumns(getDefaultStyle(), 23));
|
|
verifyNoCrash(R"(x(u8"xxxxxxxxxxxxxxxx xxxx");)",
|
|
getStyleWithColumns(getDefaultStyle(), 23));
|
|
verifyNoCrash(R"(x(_T("xxxxxxxxxxxxxxxx xxxx"));)",
|
|
getStyleWithColumns(getDefaultStyle(), 23));
|
|
}
|
|
|
|
TEST_F(FormatTestVerilog, StructLiteral) {
|
|
verifyFormat("c = '{0, 0.0};");
|
|
verifyFormat("c = '{'{1, 1.0}, '{2, 2.0}};");
|
|
verifyFormat("c = '{a: 0, b: 0.0};");
|
|
verifyFormat("c = '{a: 0, b: 0.0, default: 0};");
|
|
verifyFormat("d = {int: 1, shortreal: 1.0};");
|
|
verifyFormat("c = '{default: 0};");
|
|
|
|
// The identifier before the quote can be either a tag or a type case. There
|
|
// should be a space between the tag and the quote.
|
|
verifyFormat("c = ab'{a: 0, b: 0.0};");
|
|
verifyFormat("c = ab'{cd: cd'{1, 1.0}, ef: ef'{2, 2.0}};");
|
|
verifyFormat("c = ab'{cd'{1, 1.0}, ef'{2, 2.0}};");
|
|
verifyFormat("d = ab'{int: 1, shortreal: 1.0};");
|
|
verifyFormat("x = tagged Add '{e1, 4, ed};");
|
|
|
|
auto Style = getDefaultStyle();
|
|
Style.SpacesInContainerLiterals = true;
|
|
verifyFormat("c = '{a : 0, b : 0.0};", Style);
|
|
verifyFormat("c = '{a : 0, b : 0.0, default : 0};", Style);
|
|
verifyFormat("c = ab'{a : 0, b : 0.0};", Style);
|
|
verifyFormat("c = ab'{cd : cd'{1, 1.0}, ef : ef'{2, 2.0}};", Style);
|
|
|
|
// It should be indented correctly when the line has to break.
|
|
verifyFormat("c = //\n"
|
|
" '{default: 0};");
|
|
Style = getDefaultStyle();
|
|
Style.ContinuationIndentWidth = 2;
|
|
verifyFormat("c = //\n"
|
|
" '{default: 0};",
|
|
Style);
|
|
}
|
|
|
|
TEST_F(FormatTestVerilog, StructuredProcedure) {
|
|
// Blocks should be indented correctly.
|
|
verifyFormat("initial begin\n"
|
|
"end");
|
|
verifyFormat("initial begin\n"
|
|
" x <= x;\n"
|
|
" x <= x;\n"
|
|
"end");
|
|
verifyFormat("initial\n"
|
|
" x <= x;\n"
|
|
"x <= x;");
|
|
verifyFormat("always @(x) begin\n"
|
|
"end");
|
|
verifyFormat("always @(x) begin\n"
|
|
" x <= x;\n"
|
|
" x <= x;\n"
|
|
"end");
|
|
verifyFormat("always @(x)\n"
|
|
" x <= x;\n"
|
|
"x <= x;");
|
|
// Various keywords.
|
|
verifyFormat("always @(x)\n"
|
|
" x <= x;");
|
|
verifyFormat("always @(posedge x)\n"
|
|
" x <= x;");
|
|
verifyFormat("always @(posedge x or posedge y)\n"
|
|
" x <= x;");
|
|
verifyFormat("always @(posedge x, posedge y)\n"
|
|
" x <= x;");
|
|
verifyFormat("always @(negedge x, negedge y)\n"
|
|
" x <= x;");
|
|
verifyFormat("always @(edge x, edge y)\n"
|
|
" x <= x;");
|
|
verifyFormat("always\n"
|
|
" x <= x;");
|
|
verifyFormat("always @*\n"
|
|
" x <= x;");
|
|
verifyFormat("always @(*)\n"
|
|
" x <= x;");
|
|
verifyFormat("always_comb\n"
|
|
" x <= x;");
|
|
verifyFormat("always_latch @(x)\n"
|
|
" x <= x;");
|
|
verifyFormat("always_ff @(posedge x)\n"
|
|
" x <= x;");
|
|
verifyFormat("initial\n"
|
|
" x <= x;");
|
|
verifyFormat("final\n"
|
|
" x <= x;");
|
|
verifyFormat("forever\n"
|
|
" x <= x;");
|
|
}
|
|
} // namespace
|
|
} // namespace test
|
|
} // namespace format
|
|
} // namespace clang
|