Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
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
19 changes: 19 additions & 0 deletions include/circt/Dialect/HW/HWStructure.td
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#define CIRCT_DIALECT_HW_HWSTRUCTURE_TD

include "circt/Dialect/HW/HWAttributes.td"
include "circt/Dialect/HW/HWAttributesNaming.td"
include "circt/Dialect/HW/HWDialect.td"
include "circt/Dialect/HW/HWOpInterfaces.td"
include "circt/Dialect/HW/HWTypes.td"
Expand Down Expand Up @@ -653,6 +654,24 @@ def HierPathOp : HWOp<"hierpath",
}];
}

def DontTouchOp : HWOp<"donttouch",
[DeclareOpInterfaceMethods<InnerRefUserOpInterface>,
HasParent<"ModuleOp">]> {
let summary = "A user of an inner ref that blocks removal";
let description = [{
An operation that marks an InnerRef as having external users. The operation
with the InnerRef should not be optimized in any way and may be used
externally by name.

This operation roughly implements the notion of "don't touch" that many
Verilog tools understand.
}];
let arguments = (ins InnerRefAttr:$ref);
let assemblyFormat = [{
$ref attr-dict
}];
}

// Edge behavior for trigger blocks. Currently these map 1:1 to SV event
// control kinds.

Expand Down
18 changes: 18 additions & 0 deletions lib/Dialect/HW/HWOps.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1762,6 +1762,24 @@ LogicalResult OutputOp::verify() {
return success();
}

//===----------------------------------------------------------------------===//
// DontTouchOp
//===----------------------------------------------------------------------===//

LogicalResult DontTouchOp::verifyInnerRefs(hw::InnerRefNamespace &ns) {
auto ref = getRef();
if (ns.lookup(getRef()))
return success();
auto diag = emitOpError()
<< "references non-existent inner symbol '" << ref << "'";
auto moduleName = ref.getModule();
if (auto *moduleOp = ns.symTable.lookup(moduleName))
return diag.attachNote(moduleOp->getLoc())
<< "the inner symbol should exist in the body of this operation";
return diag.attachNote() << "no operation with symbol '@"
<< moduleName.getValue() << "' exists";
}

//===----------------------------------------------------------------------===//
// Other Operations
//===----------------------------------------------------------------------===//
Expand Down
6 changes: 6 additions & 0 deletions test/Dialect/HW/basic.mlir
Original file line number Diff line number Diff line change
Expand Up @@ -270,3 +270,9 @@ hw.module @aggregate_const(out o : !hw.array<1x!seq.clock>) {
%0 = hw.aggregate_constant [#seq<clock_constant high> : !seq.clock] : !hw.array<1x!seq.clock>
hw.output %0 : !hw.array<1x!seq.clock>
}

// CHECK-LABEL: hw.donttouch <@DontTouch::@a>
hw.donttouch <@DontTouch::@a>
hw.module public @DontTouch() {
%0 = sv.wire sym @a : !hw.inout<i1>
}
9 changes: 9 additions & 0 deletions test/Dialect/HW/cse.mlir
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// RUN: circt-opt -cse %s | FileCheck %s

// CSE should not result in the deletion of `hw.donttouch`.
//
// CHECK-LABEL: hw.donttouch <@Foo::@a>
hw.donttouch <@Foo::@a>
hw.module public @Foo() {
%a = sv.wire sym @a : !hw.inout<i1>
}
13 changes: 13 additions & 0 deletions test/Dialect/HW/verify-irn.mlir
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,16 @@ hw.module @XMRRefD() {
hw.module @XMRRefOp() {
hw.instance_choice "foo" sym @foo option "bar" @XMRRefA or @XMRRefB if "B" or @XMRRefC if "C"() -> ()
}

// -----

// expected-error @below {{references non-existent inner symbol '#hw.innerNameRef<@Foo::@a>'}}
// expected-note @below {{no operation with symbol '@Foo' exists}}
hw.donttouch <@Foo::@a>

// -----

// expected-error @below {{references non-existent inner symbol '#hw.innerNameRef<@Foo::@a>'}}
hw.donttouch <@Foo::@a>
// expected-note @below {{the inner symbol should exist in the body of this operation}}
hw.module public @Foo() {}