Skip to content

Commit

Permalink
Add --allow-merging-ansi-ports option for compatibility with non-stan…
Browse files Browse the repository at this point in the history
…dard port declaration syntax
  • Loading branch information
MikePopoloski committed May 27, 2024
1 parent 5dd33c6 commit 895805e
Show file tree
Hide file tree
Showing 6 changed files with 84 additions and 24 deletions.
3 changes: 2 additions & 1 deletion bindings/python/CompBindings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ void registerCompilation(py::module_& m) {
.value("AllowRecursiveImplicitCall", CompilationFlags::AllowRecursiveImplicitCall)
.value("AllowBareValParamAssignment", CompilationFlags::AllowBareValParamAssignment)
.value("AllowSelfDeterminedStreamConcat", CompilationFlags::AllowSelfDeterminedStreamConcat)
.value("AllowMultiDrivenLocals", CompilationFlags::AllowMultiDrivenLocals);
.value("AllowMultiDrivenLocals", CompilationFlags::AllowMultiDrivenLocals)
.value("AllowMergingAnsiPorts", CompilationFlags::AllowMergingAnsiPorts);

py::class_<CompilationOptions>(m, "CompilationOptions")
.def(py::init<>())
Expand Down
16 changes: 16 additions & 0 deletions docs/command-line-ref.dox
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,22 @@ Allow subroutine local variables to be driven from multiple always_comb/always_f
The LRM does not make an exception for local variables in assignment rules but
most tools allow it anyway so this flag exists for compatibility with those tools.

`--allow-merging-ansi-ports`

Allow ANSI port declarations to merge with a net or variable declaration internal to the
instance, instead of creating a new internal symbol to connect to. This is not allowed in
SystemVerilog but some tools support it anyway so this flag can be used for compatibility purposes.

For example:

@code{.sv}
module m(input a, output b);
wire [31:0] a;
logic [31:0] b;
assign b = a;
endmodule
@endcode

`--strict-driver-checking`

Perform strict driver checking, which currently means disabling procedural 'for' @ref loop-unroll
Expand Down
8 changes: 6 additions & 2 deletions include/slang/ast/Compilation.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,9 +125,13 @@ enum class SLANG_EXPORT CompilationFlags {
AllowSelfDeterminedStreamConcat = 1 << 12,

/// Allow multi-driven subroutine local variables.
AllowMultiDrivenLocals = 1 << 13
AllowMultiDrivenLocals = 1 << 13,

/// Allow merging ANSI port declarations with nets and variables
/// declared in the module body.
AllowMergingAnsiPorts = 1 << 14
};
SLANG_BITMASK(CompilationFlags, AllowMultiDrivenLocals)
SLANG_BITMASK(CompilationFlags, AllowMergingAnsiPorts)

/// Contains various options that can control compilation behavior.
struct SLANG_EXPORT CompilationOptions {
Expand Down
53 changes: 33 additions & 20 deletions source/ast/symbols/PortSymbols.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -255,29 +255,42 @@ class AnsiPortListBuilder {
}
}

// Create a new symbol to represent this port internally to the instance.
ValueSymbol* symbol;
if (netType) {
symbol = comp.emplace<NetSymbol>(port->name, port->location, *netType);
}
else {
symbol = comp.emplace<VariableSymbol>(port->name, port->location,
VariableLifetime::Static);
// Support a compatibility option which allows ANSI ports to still look
// up and connect to an identically named net or variable declared in
// the definition body instead of creating a new symbol internally.
if (comp.hasFlag(CompilationFlags::AllowMergingAnsiPorts)) {
if (auto symbol = scope.find(port->name);
symbol &&
(symbol->kind == SymbolKind::Variable || symbol->kind == SymbolKind::Net)) {
port->internalSymbol = symbol;
}
}

if (type) {
symbol->setDeclaredType(*type, decl.dimensions);
}
else {
SLANG_ASSERT(netType);
if (!decl.dimensions.empty())
symbol->getDeclaredType()->setDimensionSyntax(decl.dimensions);
}
// Create a new symbol to represent this port internally to the instance.
if (!port->internalSymbol) {
ValueSymbol* symbol;
if (netType) {
symbol = comp.emplace<NetSymbol>(port->name, port->location, *netType);
}
else {
symbol = comp.emplace<VariableSymbol>(port->name, port->location,
VariableLifetime::Static);
}

if (type) {
symbol->setDeclaredType(*type, decl.dimensions);
}
else {
SLANG_ASSERT(netType);
if (!decl.dimensions.empty())
symbol->getDeclaredType()->setDimensionSyntax(decl.dimensions);
}

symbol->setSyntax(decl);
symbol->setAttributes(scope, attrs);
port->internalSymbol = symbol;
implicitMembers.emplace_back(symbol, port);
symbol->setSyntax(decl);
symbol->setAttributes(scope, attrs);
port->internalSymbol = symbol;
implicitMembers.emplace_back(symbol, port);
}

if (decl.initializer) {
if (netType && netType->netKind == NetType::Interconnect) {
Expand Down
6 changes: 5 additions & 1 deletion source/driver/Driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,9 @@ void Driver::addStandardArgs() {
addCompFlag(
CompilationFlags::AllowMultiDrivenLocals, "--allow-multi-driven-locals",
"Allow subroutine local variables to be driven from multiple always_comb/_ff blocks");
addCompFlag(CompilationFlags::AllowMergingAnsiPorts, "--allow-merging-ansi-ports",
"Allow merging ANSI port declarations with nets and variables declared in the "
"instance body");
addCompFlag(CompilationFlags::StrictDriverChecking, "--strict-driver-checking",
"Perform strict driver checking, which currently means disabling "
"procedural 'for' loop unrolling.");
Expand Down Expand Up @@ -439,7 +442,8 @@ bool Driver::processOptions() {
CompilationFlags::AllowRecursiveImplicitCall,
CompilationFlags::AllowBareValParamAssignment,
CompilationFlags::AllowSelfDeterminedStreamConcat,
CompilationFlags::AllowMultiDrivenLocals};
CompilationFlags::AllowMultiDrivenLocals,
CompilationFlags::AllowMergingAnsiPorts};

for (auto flag : vcsCompatFlags) {
auto& option = options.compilationFlags.at(flag);
Expand Down
22 changes: 22 additions & 0 deletions tests/unittests/ast/PortTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1728,3 +1728,25 @@ endmodule
compilation.addSyntaxTree(tree);
NO_COMPILATION_ERRORS;
}

TEST_CASE("Ansi duplicate port compatibility option") {
auto tree = SyntaxTree::fromText(R"(
module m(input a, output b);
wire [31:0] a;
logic [31:0] b;
assign b = a;
endmodule
module top;
logic [31:0] a, b;
m m1(.a, .b);
endmodule
)");

CompilationOptions options;
options.flags |= CompilationFlags::AllowMergingAnsiPorts;

Compilation compilation(options);
compilation.addSyntaxTree(tree);
NO_COMPILATION_ERRORS;
}

0 comments on commit 895805e

Please sign in to comment.