forked from MikePopoloski/slang
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[slang-tidy] Add checks for port connections
This commit adds two new checks for port connections: NoDotStarInPortConnection: Checks if the syntax .* has been used to connect ports NoImplicitPortNameInPortConnection: Checks if the syntax .port_name has been used to connect ports
- Loading branch information
Showing
8 changed files
with
252 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
// SPDX-FileCopyrightText: Michael Popoloski | ||
// SPDX-License-Identifier: MIT | ||
|
||
#include "ASTHelperVisitors.h" | ||
#include "TidyDiags.h" | ||
|
||
#include "slang/syntax/AllSyntax.h" | ||
#include "slang/syntax/SyntaxVisitor.h" | ||
|
||
using namespace slang; | ||
using namespace slang::ast; | ||
using namespace slang::syntax; | ||
|
||
namespace no_dot_start_in_port_connection { | ||
|
||
struct PortConnectionVisitor : public SyntaxVisitor<PortConnectionVisitor> { | ||
void handle(const WildcardPortConnectionSyntax&) { found = true; } | ||
|
||
public: | ||
bool found{false}; | ||
}; | ||
|
||
struct MainVisitor : public TidyVisitor, ASTVisitor<MainVisitor, true, true> { | ||
explicit MainVisitor(Diagnostics& diagnostics) : TidyVisitor(diagnostics) {} | ||
|
||
void handle(const InstanceBodySymbol& symbol) { | ||
NEEDS_SKIP_SYMBOL(symbol) | ||
PortConnectionVisitor visitor; | ||
symbol.getSyntax()->visit(visitor); | ||
if (visitor.found) | ||
diags.add(diag::NoDotStarInPortConnection, symbol.location); | ||
} | ||
}; | ||
} // namespace no_dot_start_in_port_connection | ||
|
||
using namespace no_dot_start_in_port_connection; | ||
|
||
class NoDotStarInPortConnection : public TidyCheck { | ||
public: | ||
[[maybe_unused]] explicit NoDotStarInPortConnection(TidyKind kind) : TidyCheck(kind) {} | ||
|
||
bool check(const RootSymbol& root) override { | ||
MainVisitor visitor(diagnostics); | ||
root.visit(visitor); | ||
if (!diagnostics.empty()) | ||
return false; | ||
return true; | ||
} | ||
|
||
DiagCode diagCode() const override { return diag::NoDotStarInPortConnection; } | ||
|
||
std::string diagString() const override { return "use of .* in port connection list"; } | ||
|
||
DiagnosticSeverity diagSeverity() const override { return DiagnosticSeverity::Warning; } | ||
|
||
std::string name() const override { return "NoDotStarInPortConnection"; } | ||
|
||
std::string description() const override { return shortDescription(); } | ||
|
||
std::string shortDescription() const override { | ||
return "Checks if in a module instantiation any port is connected using .* syntax."; | ||
} | ||
}; | ||
|
||
REGISTER(NoDotStarInPortConnection, NoDotStarInPortConnection, TidyKind::Style) |
71 changes: 71 additions & 0 deletions
71
tools/tidy/src/style/NoImplicitPortNameInPortConnection.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
// SPDX-FileCopyrightText: Michael Popoloski | ||
// SPDX-License-Identifier: MIT | ||
|
||
#include "ASTHelperVisitors.h" | ||
#include "TidyDiags.h" | ||
#include <iostream> | ||
|
||
#include "slang/syntax/AllSyntax.h" | ||
#include "slang/syntax/SyntaxVisitor.h" | ||
|
||
using namespace slang; | ||
using namespace slang::ast; | ||
using namespace slang::syntax; | ||
|
||
namespace no_implicit_port_name_in_port_connection { | ||
|
||
struct PortConnectionVisitor : public SyntaxVisitor<PortConnectionVisitor> { | ||
void handle(const PortConnectionSyntax& syntax) { | ||
if (syntax.toString().find('(') == std::string::npos) | ||
found = true; | ||
} | ||
|
||
public: | ||
bool found{false}; | ||
}; | ||
|
||
struct MainVisitor : public TidyVisitor, ASTVisitor<MainVisitor, true, true> { | ||
explicit MainVisitor(Diagnostics& diagnostics) : TidyVisitor(diagnostics) {} | ||
|
||
void handle(const InstanceBodySymbol& symbol) { | ||
NEEDS_SKIP_SYMBOL(symbol) | ||
PortConnectionVisitor visitor; | ||
symbol.getSyntax()->visit(visitor); | ||
if (visitor.found) | ||
diags.add(diag::NoImplicitPortNameInPortConnection, symbol.location); | ||
} | ||
}; | ||
} // namespace no_implicit_port_name_in_port_connection | ||
|
||
using namespace no_implicit_port_name_in_port_connection; | ||
|
||
class NoImplicitPortNameInPortConnection : public TidyCheck { | ||
public: | ||
[[maybe_unused]] explicit NoImplicitPortNameInPortConnection(TidyKind kind) : TidyCheck(kind) {} | ||
|
||
bool check(const RootSymbol& root) override { | ||
MainVisitor visitor(diagnostics); | ||
root.visit(visitor); | ||
if (!diagnostics.empty()) | ||
return false; | ||
return true; | ||
} | ||
|
||
DiagCode diagCode() const override { return diag::NoImplicitPortNameInPortConnection; } | ||
|
||
std::string diagString() const override { | ||
return "port name not specified. Please use .port_name(net) syntax."; | ||
} | ||
|
||
DiagnosticSeverity diagSeverity() const override { return DiagnosticSeverity::Warning; } | ||
|
||
std::string name() const override { return "NoImplicitPortNameInPortConnection"; } | ||
|
||
std::string description() const override { return shortDescription(); } | ||
|
||
std::string shortDescription() const override { | ||
return "Checks if in a module instantiation any port is connected using .port_name syntax."; | ||
} | ||
}; | ||
|
||
REGISTER(NoImplicitPortNameInPortConnection, NoImplicitPortNameInPortConnection, TidyKind::Style) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
// SPDX-FileCopyrightText: Michael Popoloski | ||
// SPDX-License-Identifier: MIT | ||
|
||
#include "Test.h" | ||
#include "TidyFactory.h" | ||
|
||
TEST_CASE("NoDotStarInPortConnection: Use of dot star in module port connection") { | ||
auto tree = SyntaxTree::fromText(R"( | ||
module test (input clk, input rst); | ||
endmodule | ||
module top (); | ||
logic clk, rst; | ||
test t (.clk(clk), .*); | ||
endmodule | ||
)"); | ||
|
||
Compilation compilation; | ||
compilation.addSyntaxTree(tree); | ||
compilation.getAllDiagnostics(); | ||
auto& root = compilation.getRoot(); | ||
|
||
TidyConfig config; | ||
Registry::setConfig(config); | ||
Registry::setSourceManager(compilation.getSourceManager()); | ||
auto visitor = Registry::create("NoDotStarInPortConnection"); | ||
bool result = visitor->check(root); | ||
CHECK_FALSE(result); | ||
} | ||
|
||
TEST_CASE("NoDotStarInPortConnection: Module port connection port by port") { | ||
auto tree = SyntaxTree::fromText(R"( | ||
module test (input clk, input rst); | ||
endmodule | ||
module top (); | ||
logic clk, rst; | ||
test t (.clk, .rst(rst)); | ||
endmodule | ||
)"); | ||
|
||
Compilation compilation; | ||
compilation.addSyntaxTree(tree); | ||
compilation.getAllDiagnostics(); | ||
auto& root = compilation.getRoot(); | ||
|
||
TidyConfig config; | ||
Registry::setConfig(config); | ||
Registry::setSourceManager(compilation.getSourceManager()); | ||
auto visitor = Registry::create("NoDotStarInPortConnection"); | ||
bool result = visitor->check(root); | ||
CHECK(result); | ||
} |
53 changes: 53 additions & 0 deletions
53
tools/tidy/tests/NoImplicitPortNameInPortConnectionTest.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
// SPDX-FileCopyrightText: Michael Popoloski | ||
// SPDX-License-Identifier: MIT | ||
|
||
#include "Test.h" | ||
#include "TidyFactory.h" | ||
|
||
TEST_CASE("NoImplicitPortNameInPortConnection: Only port name specified in module port connection") { | ||
auto tree = SyntaxTree::fromText(R"( | ||
module test (input clk, input rst); | ||
endmodule | ||
module top (); | ||
logic clk, rst; | ||
test t (.clk, .rst(rst)); | ||
endmodule | ||
)"); | ||
|
||
Compilation compilation; | ||
compilation.addSyntaxTree(tree); | ||
compilation.getAllDiagnostics(); | ||
auto& root = compilation.getRoot(); | ||
|
||
TidyConfig config; | ||
Registry::setConfig(config); | ||
Registry::setSourceManager(compilation.getSourceManager()); | ||
auto visitor = Registry::create("NoImplicitPortNameInPortConnection"); | ||
bool result = visitor->check(root); | ||
CHECK_FALSE(result); | ||
} | ||
|
||
TEST_CASE("NoImplicitPortNameInPortConnection: Module port connection port by port") { | ||
auto tree = SyntaxTree::fromText(R"( | ||
module test (input cl()k, input rst); | ||
endmodule | ||
module top (); | ||
logic clk, rst; | ||
test t (.clk(clk), .rst(rst)); | ||
endmodule | ||
)"); | ||
|
||
Compilation compilation; | ||
compilation.addSyntaxTree(tree); | ||
compilation.getAllDiagnostics(); | ||
auto& root = compilation.getRoot(); | ||
|
||
TidyConfig config; | ||
Registry::setConfig(config); | ||
Registry::setSourceManager(compilation.getSourceManager()); | ||
auto visitor = Registry::create("NoImplicitPortNameInPortConnection"); | ||
bool result = visitor->check(root); | ||
CHECK(result); | ||
} |