Skip to content

Commit

Permalink
Merge pull request #1908 from IEncinas10/always_comb_blocking_autofix
Browse files Browse the repository at this point in the history
Add autofix for always_comb_blocking rule
  • Loading branch information
hzeller authored Jul 13, 2023
2 parents 76cc3fa + c9615fe commit cf9afe7
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 10 deletions.
24 changes: 15 additions & 9 deletions verilog/analysis/checkers/always_comb_blocking_rule.cc
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2017-2020 The Verible Authors.
// Copyright 2017-2023 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.
Expand Down Expand Up @@ -33,6 +33,7 @@
namespace verilog {
namespace analysis {

using verible::AutoFix;
using verible::down_cast;
using verible::LintRuleStatus;
using verible::LintViolation;
Expand All @@ -46,7 +47,7 @@ VERILOG_REGISTER_LINT_RULE(AlwaysCombBlockingRule);
static constexpr absl::string_view kMessage =
"Use only blocking assignments in \'always_comb\' combinational blocks.";

const LintRuleDescriptor& AlwaysCombBlockingRule::GetDescriptor() {
const LintRuleDescriptor &AlwaysCombBlockingRule::GetDescriptor() {
static const LintRuleDescriptor d{
.name = "always-comb-blocking",
.topic = "combinational-logic",
Expand All @@ -58,27 +59,32 @@ const LintRuleDescriptor& AlwaysCombBlockingRule::GetDescriptor() {
}

// Matches always_comb blocks.
static const Matcher& AlwaysCombMatcher() {
static const Matcher &AlwaysCombMatcher() {
static const Matcher matcher(NodekAlwaysStatement(AlwaysCombKeyword()));
return matcher;
}

void AlwaysCombBlockingRule::HandleSymbol(const verible::Symbol& symbol,
const SyntaxTreeContext& context) {
void AlwaysCombBlockingRule::HandleSymbol(const verible::Symbol &symbol,
const SyntaxTreeContext &context) {
verible::matcher::BoundSymbolManager manager;

if (AlwaysCombMatcher().Matches(symbol, &manager)) {
for (const auto& match :
for (const auto &match :
SearchSyntaxTree(symbol, NodekNonblockingAssignmentStatement())) {
if (match.match->Kind() != verible::SymbolKind::kNode) continue;

const auto* node = down_cast<const verible::SyntaxTreeNode*>(match.match);
const auto *node =
down_cast<const verible::SyntaxTreeNode *>(match.match);

const verible::SyntaxTreeLeaf* leaf = verible::GetSubtreeAsLeaf(
const verible::SyntaxTreeLeaf *leaf = verible::GetSubtreeAsLeaf(
*node, NodeEnum::kNonblockingAssignmentStatement, 1);

if (leaf && leaf->get().token_enum() == TK_LE) {
violations_.insert(LintViolation(*leaf, kMessage, match.context));
violations_.insert(
LintViolation(*leaf, kMessage, match.context,
{AutoFix("Use blocking assignment '=' instead of "
"nonblocking assignment '<='",
{leaf->get(), "="})}));
}
}
}
Expand Down
22 changes: 21 additions & 1 deletion verilog/analysis/checkers/always_comb_blocking_rule_test.cc
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2017-2020 The Verible Authors.
// Copyright 2017-2023 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.
Expand Down Expand Up @@ -30,6 +30,7 @@ namespace analysis {
namespace {

using verible::LintTestCase;
using verible::RunApplyFixCases;
using verible::RunLintTestCases;

TEST(AlwaysCombBlockingRule, FunctionFailures) {
Expand Down Expand Up @@ -62,6 +63,25 @@ TEST(AlwaysCombBlockingRule, FunctionFailures) {
kAlwaysCombBlockingTestCases);
}

TEST(AlwaysCombBlockingTest, AutoFixAlwaysCombBlocking) {
const std::initializer_list<verible::AutoFixInOut> kTestCases = {
{"module m;\nalways_comb a <= b;\nendmodule",
"module m;\nalways_comb a = b;\nendmodule"},
{"module m;\nalways_comb begin a <= b; end\nendmodule",
"module m;\nalways_comb begin a = b; end\nendmodule"},
{"module m;\nalways_comb begin if (sel == 0) a <= b; else a = 1'b0; "
"end\nendmodule",
"module m;\nalways_comb begin if (sel == 0) a = b; else a = 1'b0; "
"end\nendmodule"},
{"module m;\nalways_comb begin\n`ifdef RST\nf <= g;\n`else\nf = "
"1'b1;\n`endif\nend\nendmodule",
"module m;\nalways_comb begin\n`ifdef RST\nf = g;\n`else\nf = "
"1'b1;\n`endif\nend\nendmodule"},
};

RunApplyFixCases<VerilogAnalyzer, AlwaysCombBlockingRule>(kTestCases, "");
}

} // namespace
} // namespace analysis
} // namespace verilog

0 comments on commit cf9afe7

Please sign in to comment.