Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SV] Add sv.reserve_names op to disallow names #7024

Merged
merged 2 commits into from
May 14, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions include/circt/Dialect/SV/SVStatements.td
Original file line number Diff line number Diff line change
Expand Up @@ -879,3 +879,17 @@ def MacroDefOp : SVOp<"macro.def",
MacroDeclOp getReferencedMacro(const hw::HWSymbolCache *cache);
}];
}


//===----------------------------------------------------------------------===//
// SV output control.
//===----------------------------------------------------------------------===//

def ReserveNamesOp : SVOp<"reserve_names", []> {
teqdruid marked this conversation as resolved.
Show resolved Hide resolved
let summary = "Disallow a set of names to be used during emission";

let arguments = (ins StrArrayAttr:$reservedNames);
let assemblyFormat = [{
$reservedNames attr-dict
}];
}
3 changes: 3 additions & 0 deletions lib/Conversion/ExportVerilog/ExportVerilog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6344,6 +6344,9 @@ void SharedEmitterState::gatherFiles(bool separateModules) {
.Case<MacroDeclOp>([&](auto op) {
symbolCache.addDefinition(op.getSymNameAttr(), op);
})
.Case<sv::ReserveNamesOp>([](auto op) {
// This op was already used in gathering used names.
})
.Case<om::ClassLike>([&](auto op) {
symbolCache.addDefinition(op.getSymNameAttr(), op);
})
Expand Down
7 changes: 7 additions & 0 deletions lib/Conversion/ExportVerilog/ExportVerilogInternals.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ struct LoweringOptions;

namespace ExportVerilog {
class GlobalNameResolver;
struct NameCollisionResolver;

/// Check if the value is from read of a wire or reg or is a port.
bool isSimpleReadOrPort(Value v);
Expand Down Expand Up @@ -57,6 +58,9 @@ struct GlobalNameTable {
return it != enumPrefixes.end() ? it->second : StringAttr();
}

// Add the set of reserved names to a resolver.
void addReservedNames(NameCollisionResolver &nameResolver) const;

private:
friend class GlobalNameResolver;
GlobalNameTable() {}
Expand All @@ -76,6 +80,9 @@ struct GlobalNameTable {
// This contains prefixes for any typedecl'd enum types. Keys are type-aliases
// of enum types.
DenseMap<Type, StringAttr> enumPrefixes;

/// List of names which are marked as reserved for any name.
StringSet<> reservedNames;
teqdruid marked this conversation as resolved.
Show resolved Hide resolved
};

//===----------------------------------------------------------------------===//
Expand Down
17 changes: 17 additions & 0 deletions lib/Conversion/ExportVerilog/LegalizeNames.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,15 @@ using namespace sv;
using namespace hw;
using namespace ExportVerilog;

//===----------------------------------------------------------------------===//
// GlobalNameTable
//===----------------------------------------------------------------------===//

void GlobalNameTable::addReservedNames(NameCollisionResolver &resolver) const {
for (auto &name : reservedNames)
resolver.insertUsedName(name.getKey());
}

//===----------------------------------------------------------------------===//
// NameCollisionResolver
//===----------------------------------------------------------------------===//
Expand Down Expand Up @@ -134,6 +143,8 @@ static void legalizeModuleLocalNames(HWModuleOp module,
const GlobalNameTable &globalNameTable) {
// A resolver for a local name collison.
NameCollisionResolver nameResolver(options);
globalNameTable.addReservedNames(nameResolver);

// Register names used by parameters.
for (auto param : module.getParameters())
nameResolver.insertUsedName(globalNameTable.getParameterVerilogName(
Expand Down Expand Up @@ -237,6 +248,12 @@ GlobalNameResolver::GlobalNameResolver(mlir::ModuleOp topLevel,
op.emitError("name \"")
<< name << "\" is not allowed in Verilog output";
globalNameResolver.insertUsedName(name);
} else if (auto reservedNamesOp = dyn_cast<sv::ReserveNamesOp>(op)) {
for (StringAttr name :
reservedNamesOp.getReservedNames().getAsRange<StringAttr>()) {
globalNameTable.reservedNames.insert(name);
globalNameResolver.insertUsedName(name);
}
}
}

Expand Down
8 changes: 8 additions & 0 deletions test/Conversion/ExportVerilog/sv-dialect.mlir
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,14 @@
sv.macro.decl @SYNTHESIS
sv.macro.decl @VERILATOR

// CHECK-NOT: module ReservedName1(
// CHECK-NOT: input reservedName2{{$}}
// CHECK-NOT: reg reservedName3;
sv.reserve_names ["ReservedName1", "reservedName2", "reservedName3"]
hw.module @ReservedName1 (in %reservedName2 : i1) {
%reservedName3 = sv.reg : !hw.inout<i1>
}

// CHECK-LABEL: module M1
// CHECK-NEXT: #(parameter [41:0] param1) (
hw.module @M1<param1: i42>(in %clock : i1, in %cond : i1, in %val : i8) {
Expand Down
Loading