[Ibis] Divorce symbol and actual names in class and container ops (#7123)

... while factoring out `InnerSymbol`+name logic into a new interface that is also used by Ibis port-like ops. This model could probably be factored into the `hw` dialect, seeing as we're also eventually going to divorce symbol names and actual names in `hw.module`.

Also adds de-aliasing logic to `ContainersToHW`, which is required given that `hw.module` doesn't yet split its symbol and name (#7023).
This commit is contained in:
Morten Borup Petersen 2024-06-10 10:06:16 +02:00 committed by GitHub
parent e0f884a450
commit 0bf789e607
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
32 changed files with 317 additions and 252 deletions

View File

@ -18,7 +18,38 @@ include "circt/Dialect/HW/HWOpInterfaces.td"
include "mlir/IR/OpBase.td"
include "mlir/IR/SymbolInterfaces.td"
def PortOpInterface : OpInterface<"PortOpInterface"> {
def NamedInnerSymbol : OpInterface<"NamedInnerSymbolInterface", [InnerSymbol]> {
let cppNamespace = "circt::ibis";
let description = [{
An interface for operations which define inner symbols with an optional
namehint.
}];
let methods = [
InterfaceMethod<
"Returns the namehint attribute of this op",
"mlir::StringAttr", "getNameHintAttr",
(ins),
"",
[{
if(auto nameHint = $_op.getNameAttr())
return nameHint;
return $_op.getInnerSymAttr().getSymName();
}]
>,
InterfaceMethod<
"Returns the namehint of this op",
"llvm::StringRef", "getNameHint",
(ins),
"",
[{
return getNameHintAttr().strref();
}]
>
];
}
def PortOpInterface : OpInterface<"PortOpInterface", [NamedInnerSymbol]> {
let cppNamespace = "circt::ibis";
let description =
"An interface for operations which describe ports.";
@ -27,9 +58,6 @@ def PortOpInterface : OpInterface<"PortOpInterface"> {
InterfaceMethod<
"Returns the data type of the port.",
"mlir::Type", "getPortType">,
InterfaceMethod<
"Returns the name of the port",
"mlir::StringAttr", "getPortName">,
InterfaceMethod<
"Returns the `!ibis.portref` value defined by the op",
"mlir::TypedValue<PortRefType>", "getPort"
@ -37,7 +65,7 @@ def PortOpInterface : OpInterface<"PortOpInterface"> {
];
}
def ScopeOpInterface : OpInterface<"ScopeOpInterface", [InnerSymbol]> {
def ScopeOpInterface : OpInterface<"ScopeOpInterface", [NamedInnerSymbol]> {
let cppNamespace = "circt::ibis";
let description = [{
An interface for operations which define Ibis scopes, that can be referenced

View File

@ -50,10 +50,10 @@ def ClassOp : IbisOp<"class", [
`ibis.port`s, `ibis.container`s, and contain logic for member variables.
}];
let arguments = (ins InnerSymAttr:$inner_sym);
let arguments = (ins InnerSymAttr:$inner_sym, OptionalAttr<StrAttr>:$name);
let regions = (region SizedRegion<1>:$body);
let assemblyFormat = [{
$inner_sym attr-dict-with-keyword $body
($name^)? `sym` $inner_sym attr-dict-with-keyword $body
}];
let extraClassDeclaration = [{
@ -62,14 +62,6 @@ def ClassOp : IbisOp<"class", [
Block* getBodyBlock() { return &getBody().front(); }
StringAttr getModuleNameAttr() {
return getInnerSymAttr().getSymName();
}
llvm::StringRef getModuleName() {
return getModuleNameAttr();
}
// For hw:InnerSymbol - the symbol targets the operation and not any result.
static std::optional<size_t> getTargetResultIndex() {
return std::nullopt;
@ -604,7 +596,7 @@ def ContainerOp : IbisOp<"container", [
ScopeOpInterface, IsolatedFromAbove,
InstanceGraphModuleOpInterface,
RegionKindInterface,
DeclareOpInterfaceMethods<InnerSymbol>,
DeclareOpInterfaceMethods<NamedInnerSymbol>,
ParentOneOf<["DesignOp", "ClassOp"]>
]> {
let summary = "Ibis container";
@ -612,11 +604,11 @@ def ContainerOp : IbisOp<"container", [
An ibis container describes a collection of logic nested within an Ibis class.
}];
let arguments = (ins InnerSymAttr:$inner_sym, UnitAttr:$isTopLevel);
let arguments = (ins InnerSymAttr:$inner_sym, UnitAttr:$isTopLevel, OptionalAttr<StrAttr>:$name);
let regions = (region SizedRegion<1>:$body);
let assemblyFormat = [{
$inner_sym (`top_level` $isTopLevel^)? attr-dict-with-keyword $body
($name^)? `sym` $inner_sym (`top_level` $isTopLevel^)? attr-dict-with-keyword $body
}];
let extraClassDeclaration = [{
@ -625,34 +617,33 @@ def ContainerOp : IbisOp<"container", [
Block* getBodyBlock() { return &getBody().front(); }
StringAttr getModuleNameAttr() {
return getInnerSymAttr().getSymName();
}
llvm::StringRef getModuleName() {
return getModuleNameAttr();
}
}];
let extraClassDefinition = [{
// For hw:InnerSymbol - the symbol targets the operation and not any result.
std::optional<size_t> $cppClass::getTargetResultIndex() {
static std::optional<size_t> getTargetResultIndex() {
return std::nullopt;
}
// Override InstanceGraphModuleOpInterface::getModuleNameAttr to return the
// inner_sym name of the container instead of the `name` which is the default
// behavior of InstanceGraphModuleOpInterface.
mlir::StringAttr getModuleNameAttr() {
return getInnerSymAttr().getSymName();
}
}];
let skipDefaultBuilders = 1;
let builders = [
OpBuilder<(ins "StringRef":$inner_sym, "bool":$isTopLevel), [{
OpBuilder<(ins "StringRef":$inner_sym, "bool":$isTopLevel, CArg<"mlir::StringAttr", "nullptr">:$name), [{
build($_builder, $_state,
hw::InnerSymAttr::get($_builder.getStringAttr(inner_sym)), isTopLevel);
hw::InnerSymAttr::get($_builder.getStringAttr(inner_sym)), isTopLevel, name);
}]>,
OpBuilder<(ins "hw::InnerSymAttr":$inner_sym, "bool":$isTopLevel), [{
OpBuilder<(ins "hw::InnerSymAttr":$inner_sym, "bool":$isTopLevel, CArg<"mlir::StringAttr", "nullptr">:$name), [{
auto region = $_state.addRegion();
region->push_back(new Block());
$_state.addAttribute(getInnerSymAttrName($_state.name), inner_sym);
if (isTopLevel)
$_state.addAttribute(getIsTopLevelAttrName($_state.name), $_builder.getUnitAttr());
if(name)
$_state.addAttribute(getNameAttrName($_state.name), name);
}]>
];
}
@ -740,7 +731,7 @@ class PortLikeOp<string mnemonic, list<Trait> traits = []> :
ParentOneOf<["ClassOp", "ContainerOp"]>,
InferTypeOpInterface,
HasCustomSSAName,
DeclareOpInterfaceMethods<InnerSymbol,["getTargetResultIndex"]>
NamedInnerSymbol
])> {
let description = [{
@ -749,7 +740,7 @@ class PortLikeOp<string mnemonic, list<Trait> traits = []> :
related, and all references to a port is done through the port symbol.
}];
let arguments = (ins OptionalAttr<StrAttr>:$name, InnerSymAttr:$inner_sym, TypeAttrOf<AnyType>:$type);
let arguments = (ins InnerSymAttr:$inner_sym, TypeAttrOf<AnyType>:$type, OptionalAttr<StrAttr>:$name);
let results = (outs PortRefType:$port);
let assemblyFormat = [{
($name^)? `sym` $inner_sym `:` $type attr-dict
@ -760,10 +751,6 @@ class PortLikeOp<string mnemonic, list<Trait> traits = []> :
return getTypeAttr().getValue();
}
mlir::StringAttr getPortName() {
return getInnerSymAttr().getSymName();
}
static ibis::Direction getPortDirection();
/// Infer the return types of this operation.
@ -779,6 +766,11 @@ class PortLikeOp<string mnemonic, list<Trait> traits = []> :
getPortDirection()));
return success();
}
// For hw:InnerSymbol - the symbol targets the operation and not any result.
static std::optional<size_t> getTargetResultIndex() {
return std::nullopt;
}
}];
let hasVerifier = 1;
@ -791,15 +783,6 @@ class PortLikeOp<string mnemonic, list<Trait> traits = []> :
return success();
}
void $cppClass::getAsmResultNames(OpAsmSetValueNameFn setNameFn) {
setNameFn(getResult(), getPortName());
}
// For hw:InnerSymbol - the symbol targets the operation and not any result.
std::optional<size_t> $cppClass::getTargetResultIndex() {
return std::nullopt;
}
}];
}
@ -836,10 +819,6 @@ class WireLikeOp<string mnemonic, list<Trait> traits = []> :
return getPort().getType();
}
mlir::StringAttr getPortName() {
return getInnerSymAttr().getSymName();
}
static ibis::Direction getPortDirection();
}];
@ -869,7 +848,7 @@ def InputWireOp : WireLikeOp<"wire.input", [
of type `T` which represents the value to-be-written to the wire.
}];
let arguments = (ins InnerSymAttr:$inner_sym);
let arguments = (ins InnerSymAttr:$inner_sym, OptionalAttr<StrAttr>:$name);
let results = (outs PortRefType:$port, AnyType:$output);
let assemblyFormat = [{
$inner_sym `:` qualified(type($output)) attr-dict
@ -879,19 +858,13 @@ def InputWireOp : WireLikeOp<"wire.input", [
ibis::Direction $cppClass::getPortDirection() {
return ibis::Direction::Input;
}
void $cppClass::getAsmResultNames(OpAsmSetValueNameFn setNameFn) {
setNameFn(getPort(), getPortName());
setNameFn(getOutput(), StringAttr::get(getContext(),
getPortName().strref() + ".out").strref());
}
}];
let builders = [
OpBuilder<(ins "StringAttr":$name, "Type":$innerPortType), [{
OpBuilder<(ins "StringAttr":$inner_sym, "Type":$innerPortType, CArg<"mlir::StringAttr", "nullptr">:$name), [{
build($_builder, $_state,
{$_builder.getType<PortRefType>(
innerPortType, ibis::Direction::Input), innerPortType}, hw::InnerSymAttr::get(name));
innerPortType, ibis::Direction::Input), innerPortType}, hw::InnerSymAttr::get(inner_sym), name);
}]>
];
@ -908,7 +881,7 @@ def OutputWireOp : WireLikeOp<"wire.output", [
on the output portref.
}];
let arguments = (ins InnerSymAttr:$inner_sym, AnyType:$input);
let arguments = (ins InnerSymAttr:$inner_sym, AnyType:$input, OptionalAttr<StrAttr>:$name);
let results = (outs PortRefType:$port);
let assemblyFormat = [{
$inner_sym `,` $input `:` qualified(type($input)) attr-dict
@ -918,10 +891,6 @@ def OutputWireOp : WireLikeOp<"wire.output", [
ibis::Direction $cppClass::getPortDirection() {
return ibis::Direction::Output;
}
void $cppClass::getAsmResultNames(OpAsmSetValueNameFn setNameFn) {
setNameFn(getPort(), getPortName());
}
}];
let hasCanonicalizeMethod = 1;

View File

@ -6,14 +6,14 @@ ibis.design @foo {
// A class hierarchy with a shared parent, and accessing between the children
ibis.class @C1 {
ibis.class sym @C1 {
%this = ibis.this <@foo::@C1>
%out = ibis.port.output "out" sym @out : i32
%c0 = hw.constant 42 : i32
ibis.port.write %out, %c0 : !ibis.portref<out i32>
}
ibis.class @C2 {
ibis.class sym @C2 {
%this = ibis.this <@foo::@C2>
%go_port = ibis.port.input "go" sym @go : i1
@ -22,7 +22,7 @@ ibis.class @C2 {
%done_port = ibis.port.output "done" sym @done : i1
%out_port = ibis.port.output "out" sym @out : i32
ibis.container @MyMethod {
ibis.container sym @MyMethod {
%t = ibis.this <@foo::@MyMethod>
// Grab parent go, clk, reset inputs - note that the requested direction of
@ -68,7 +68,7 @@ ibis.class @C2 {
}
}
ibis.class @Parent {
ibis.class sym @Parent {
%this = ibis.this <@foo::@Parent>
%c1 = ibis.instance @c1, <@foo::@C1>
%c2 = ibis.instance @c2, <@foo::@C2>

View File

@ -46,7 +46,7 @@ static llvm::raw_string_ostream &genValueName(llvm::raw_string_ostream &os,
.Case<ThisOp>([&](auto op) { os << "this"; })
.Case<InstanceOp, ContainerInstanceOp>(
[&](auto op) { os << op.getInstanceNameAttr().strref(); })
.Case<PortOpInterface>([&](auto op) { os << op.getPortName().strref(); })
.Case<PortOpInterface>([&](auto op) { os << op.getNameHint(); })
.Case<PathOp>([&](auto op) {
llvm::interleave(
op.getPathAsRange(), os,
@ -518,6 +518,18 @@ LogicalResult OutputPortOp::canonicalize(OutputPortOp op,
return failure();
}
void OutputPortOp::getAsmResultNames(OpAsmSetValueNameFn setNameFn) {
setNameFn(getPort(), genValueNameAttr(getPort()));
}
//===----------------------------------------------------------------------===//
// InputPortOp
//===----------------------------------------------------------------------===//
void InputPortOp::getAsmResultNames(OpAsmSetValueNameFn setNameFn) {
setNameFn(getPort(), genValueNameAttr(getPort()));
}
//===----------------------------------------------------------------------===//
// InputWireOp
//===----------------------------------------------------------------------===//
@ -540,6 +552,13 @@ LogicalResult InputWireOp::canonicalize(InputWireOp op,
return failure();
}
void InputWireOp::getAsmResultNames(OpAsmSetValueNameFn setNameFn) {
auto name = genValueNameAttr(getOutput());
setNameFn(getPort(), name);
setNameFn(getOutput(),
StringAttr::get(getContext(), name.strref() + ".out").strref());
}
//===----------------------------------------------------------------------===//
// OutputWireOp
//===----------------------------------------------------------------------===//
@ -563,6 +582,10 @@ LogicalResult OutputWireOp::canonicalize(OutputWireOp op,
return failure();
}
void OutputWireOp::getAsmResultNames(OpAsmSetValueNameFn setNameFn) {
setNameFn(getPort(), genValueNameAttr(getPort()));
}
//===----------------------------------------------------------------------===//
// StaticBlockOp
//===----------------------------------------------------------------------===//

View File

@ -157,15 +157,16 @@ struct InputPortOpConversionPattern : public OpConversionPattern<InputPortOp> {
bool anyOutsideReads = llvm::any_of(node->uses(), [&](auto use) {
Block *userBlock = use->getInstance()->getBlock();
for (auto getPortOp : userBlock->getOps<GetPortOp>()) {
if (getPortOp.getPortSymbol() == op.getPortName())
if (getPortOp.getPortSymbol() == *op.getInnerName()) {
return true;
}
}
return false;
});
if (anyOutsideReads) {
auto outputPort = rewriter.create<OutputPortOp>(
op.getLoc(), op.getNameAttr(), op.getInnerSym(), op.getType());
op.getLoc(), op.getInnerSym(), op.getType(), op.getNameAttr());
rewriter.create<PortWriteOp>(op.getLoc(), outputPort, wire);
}
}

View File

@ -78,7 +78,8 @@ struct ClassToContainerPattern : public OpConversionPattern<ClassOp> {
ConversionPatternRewriter &rewriter) const override {
// Replace the class by a container of the same name.
auto newContainer =
rewriter.create<ContainerOp>(op.getLoc(), op.getInnerSymAttr(), false);
rewriter.create<ContainerOp>(op.getLoc(), op.getInnerSymAttr(),
/*topLevel*/ false, op.getNameAttr());
rewriter.mergeBlocks(op.getBodyBlock(), newContainer.getBodyBlock(), {});
rewriter.eraseOp(op);
return success();

View File

@ -64,7 +64,7 @@ struct ContainerPortInfo {
Namespace portNs;
for (auto input : container.getBodyBlock()->getOps<InputPortOp>()) {
auto uniquePortName =
StringAttr::get(ctx, portNs.newName(input.getNameAttr().getValue()));
StringAttr::get(ctx, portNs.newName(input.getNameHint()));
opInputs[uniquePortName] = input;
hw::PortInfo portInfo;
portInfo.name = uniquePortName;
@ -97,17 +97,16 @@ using ContainerPortInfoMap =
llvm::DenseMap<hw::InnerRefAttr, ContainerPortInfo>;
using ContainerHWModSymbolMap = llvm::DenseMap<hw::InnerRefAttr, StringAttr>;
static StringAttr concatNames(hw::InnerRefAttr ref) {
return StringAttr::get(ref.getContext(), ref.getModule().getValue() + "_" +
ref.getName().getValue());
static StringAttr concatNames(mlir::StringAttr lhs, mlir::StringAttr rhs) {
return StringAttr::get(lhs.getContext(), lhs.strref() + "_" + rhs.strref());
}
struct ContainerOpConversionPattern : public OpConversionPattern<ContainerOp> {
ContainerOpConversionPattern(MLIRContext *ctx,
ContainerOpConversionPattern(MLIRContext *ctx, Namespace &modNamespace,
ContainerPortInfoMap &portOrder,
ContainerHWModSymbolMap &modSymMap)
: OpConversionPattern<ContainerOp>(ctx), portOrder(portOrder),
modSymMap(modSymMap) {}
: OpConversionPattern<ContainerOp>(ctx), modNamespace(modNamespace),
portOrder(portOrder), modSymMap(modSymMap) {}
LogicalResult
matchAndRewrite(ContainerOp op, OpAdaptor adaptor,
@ -115,12 +114,17 @@ struct ContainerOpConversionPattern : public OpConversionPattern<ContainerOp> {
auto design = op->getParentOfType<DesignOp>();
rewriter.setInsertionPoint(design);
// Generate and de-alias the hw.module name.
// If the container is a top level container, ignore the design name.
StringAttr hwmodName;
if (op.getIsTopLevel())
hwmodName = op.getInnerNameAttr();
hwmodName = op.getNameHintAttr();
else
hwmodName = concatNames(op.getInnerRef());
hwmodName =
concatNames(op.getInnerRef().getModule(), op.getNameHintAttr());
hwmodName = StringAttr::get(op.getContext(),
modNamespace.newName(hwmodName.getValue()));
const ContainerPortInfo &cpi = portOrder.at(op.getInnerRef());
auto hwMod =
@ -175,6 +179,7 @@ struct ContainerOpConversionPattern : public OpConversionPattern<ContainerOp> {
return success();
}
Namespace &modNamespace;
ContainerPortInfoMap &portOrder;
ContainerHWModSymbolMap &modSymMap;
};
@ -347,6 +352,10 @@ void ContainersToHWPass::runOnOperation() {
ConversionTarget target(*ctx);
ContainerHWModSymbolMap modSymMap;
SymbolCache modSymCache;
modSymCache.addDefinitions(getOperation());
Namespace modNamespace;
modNamespace.add(modSymCache);
target.addIllegalOp<ContainerOp, ContainerInstanceOp, ThisOp>();
target.markUnknownOpDynamicallyLegal([](Operation *) { return true; });
@ -357,9 +366,9 @@ void ContainersToHWPass::runOnOperation() {
target.addLegalDialect<IbisDialect>();
RewritePatternSet patterns(ctx);
patterns
.add<ContainerOpConversionPattern, ContainerInstanceOpConversionPattern>(
ctx, portOrder, modSymMap);
patterns.add<ContainerOpConversionPattern>(ctx, modNamespace, portOrder,
modSymMap);
patterns.add<ContainerInstanceOpConversionPattern>(ctx, portOrder, modSymMap);
patterns.add<ThisOpConversionPattern>(ctx);
if (failed(

View File

@ -45,7 +45,7 @@ struct DataflowMethodOpConversion
for (auto [arg, name] : llvm::zip_equal(
op.getArguments(), op.getArgNames().getAsRange<StringAttr>())) {
auto port = rewriter.create<InputPortOp>(
arg.getLoc(), name, hw::InnerSymAttr::get(name), arg.getType());
arg.getLoc(), hw::InnerSymAttr::get(name), arg.getType(), name);
argValues.push_back(rewriter.create<PortReadOp>(arg.getLoc(), port));
}
@ -54,7 +54,7 @@ struct DataflowMethodOpConversion
cast<MethodLikeOpInterface>(op.getOperation()).getResultTypes())) {
auto portName = rewriter.getStringAttr("out" + std::to_string(idx));
auto port = rewriter.create<OutputPortOp>(
op.getLoc(), portName, hw::InnerSymAttr::get(portName), resType);
op.getLoc(), hw::InnerSymAttr::get(portName), resType, portName);
rewriter.create<PortWriteOp>(op.getLoc(), port, returnOp.getOperand(idx));
}

View File

@ -66,7 +66,7 @@ public:
if (d == Direction::Input) {
// references to inputs becomes outputs (write from this container)
auto rawOutput = rewriter.create<OutputPortOp>(
op.getLoc(), op.getNameAttr(), op.getInnerSym(), innerType);
op.getLoc(), op.getInnerSym(), innerType, op.getNameAttr());
// Replace writes to the unwrapped port with writes to the new port.
for (auto *unwrappedPortUser :
@ -82,7 +82,7 @@ public:
} else {
// References to outputs becomes inputs (read from this container)
auto rawInput = rewriter.create<InputPortOp>(
op.getLoc(), op.getNameAttr(), op.getInnerSym(), innerType);
op.getLoc(), op.getInnerSym(), innerType, op.getNameAttr());
// TODO: RewriterBase::replaceAllUsesWith is not currently supported by
// DialectConversion. Using it may lead to assertions about mutating
// replaced/erased ops. For now, do this RAUW directly, until
@ -147,7 +147,7 @@ public:
// Create the raw input port and write the input port reference with a
// read of the raw input port.
auto rawInput = rewriter.create<InputPortOp>(
op.getLoc(), op.getNameAttr(), op.getInnerSym(), innerType);
op.getLoc(), op.getInnerSym(), innerType, op.getNameAttr());
rewriter.create<PortWriteOp>(
op.getLoc(), portWrapper.getValue(),
rewriter.create<PortReadOp>(op.getLoc(), rawInput));
@ -155,7 +155,7 @@ public:
// Outputs of outputs are outputs (external driver out of this container).
// Create the raw output port and do a read of the input port reference.
auto rawOutput = rewriter.create<OutputPortOp>(
op.getLoc(), op.getNameAttr(), op.getInnerSym(), innerType);
op.getLoc(), op.getInnerSym(), innerType, op.getNameAttr());
rewriter.create<PortWriteOp>(
op.getLoc(), rawOutput,
rewriter.create<PortReadOp>(op.getLoc(), portWrapper.getValue()));
@ -298,8 +298,8 @@ class GetPortConversionPattern : public OpConversionPattern<GetPortOp> {
// inputs.
auto fwPortName = rewriter.getStringAttr(portName.strref() + "_fw");
auto forwardedInputPort = rewriter.create<InputPortOp>(
op.getLoc(), fwPortName, hw::InnerSymAttr::get(fwPortName),
innerType);
op.getLoc(), hw::InnerSymAttr::get(fwPortName), innerType,
fwPortName);
// TODO: RewriterBase::replaceAllUsesWith is not currently supported
// by DialectConversion. Using it may lead to assertions about

View File

@ -212,8 +212,7 @@ Value Tunneler::portForwardIfNeeded(PortOpInterface actualPort,
// output port.
if (requestedDir == Direction::Input) {
auto wireOp = rewriter.create<InputWireOp>(
op.getLoc(),
rewriter.getStringAttr(actualPort.getPortName().strref() + ".wr"),
op.getLoc(), rewriter.getStringAttr(*actualPort.getInnerName() + ".wr"),
portInfo.getInnerType());
rewriter.create<PortWriteOp>(op.getLoc(), actualPort.getPort(),
@ -230,8 +229,8 @@ Value Tunneler::portForwardIfNeeded(PortOpInterface actualPort,
auto wireOp = rewriter.create<OutputWireOp>(
op.getLoc(),
hw::InnerSymAttr::get(
rewriter.getStringAttr(actualPort.getPortName().strref() + ".rd")),
inputValue);
rewriter.getStringAttr(*actualPort.getInnerName() + ".rd")),
inputValue, rewriter.getStringAttr(actualPort.getNameHint() + ".rd"));
return wireOp.getPort();
}
@ -296,8 +295,8 @@ LogicalResult Tunneler::tunnelDown(InstanceGraphNode *currentContainer,
llvm::DenseMap<StringAttr, OutputPortOp> outputPortOps;
for (PortInfo &pi : portInfos) {
outputPortOps[pi.portName] = rewriter.create<OutputPortOp>(
op.getLoc(), pi.portName, circt::hw::InnerSymAttr::get(pi.portName),
pi.getType());
op.getLoc(), circt::hw::InnerSymAttr::get(pi.portName), pi.getType(),
pi.portName);
}
// Recurse into the tunnel instance container.
@ -376,8 +375,8 @@ LogicalResult Tunneler::tunnelUp(InstanceGraphNode *currentContainer,
rewriter.setInsertionPointToEnd(scopeOp.getBodyBlock());
for (PortInfo &pi : portInfos) {
auto inputPort = rewriter.create<InputPortOp>(
op.getLoc(), pi.portName, hw::InnerSymAttr::get(pi.portName),
pi.getType());
op.getLoc(), hw::InnerSymAttr::get(pi.portName), pi.getType(),
pi.portName);
// Read the input port of the current container to forward the portref.
portMapping[&pi] =

View File

@ -1,6 +1,6 @@
// RUN: circt-opt --ibis-argify-blocks %s | FileCheck %s
// CHECK-LABEL: ibis.class @Argify {
// CHECK-LABEL: ibis.class sym @Argify {
// CHECK-NEXT: %this = ibis.this <@foo::@Argify>
// CHECK-NEXT: ibis.method @foo() -> () {
// CHECK-NEXT: %c32_i32 = hw.constant 32 : i32
@ -14,7 +14,7 @@
// CHECK-NEXT: }
ibis.design @foo {
ibis.class @Argify {
ibis.class sym @Argify {
%this = ibis.this <@foo::@Argify>
ibis.method @foo() {

View File

@ -40,7 +40,7 @@
// CHECK: }
ibis.design @foo {
ibis.class @ToHandshake {
ibis.class sym @ToHandshake {
%this = ibis.this <@foo::@ToHandshake>
// Just a simple test demonstrating the intended mixing of `ibis.sblock`s and
// control flow operations. The meat of cf-to-handshake conversion is tested

View File

@ -1,14 +1,14 @@
// RUN: circt-opt --allow-unregistered-dialect --split-input-file --ibis-clean-selfdrivers %s | FileCheck %s
ibis.design @D {
// CHECK-LABEL: ibis.container @C {
// CHECK-LABEL: ibis.container sym @C {
// CHECK: %[[VAL_0:.*]] = ibis.this <@D::@C>
// CHECK: %[[VAL_1:.*]] = hw.wire %[[VAL_2:.*]] : i1
// CHECK: %[[VAL_3:.*]] = ibis.port.output "out" sym @out : i1
// CHECK: %[[VAL_2]] = hw.constant true
// CHECK: ibis.port.write %[[VAL_3]], %[[VAL_1]] : !ibis.portref<out i1>
// CHECK: }
ibis.container @C {
ibis.container sym @C {
%this = ibis.this <@D::@C>
%in = ibis.port.input "in" sym @in : i1
%out = ibis.port.output "out" sym @out : i1
@ -23,29 +23,29 @@ ibis.container @C {
// -----
ibis.design @D {
// CHECK-LABEL: ibis.container @Selfdriver {
// CHECK-LABEL: ibis.container sym @Selfdriver {
// CHECK: %[[VAL_0:.*]] = ibis.this <@D::@Selfdriver>
// CHECK: %[[VAL_1:.*]] = hw.wire %[[VAL_2:.*]] : i1
// CHECK: %[[VAL_3:.*]] = ibis.port.output "in" sym @in : i1
// CHECK: %[[VAL_3:.*]] = ibis.port.output "myIn" sym @in : i1
// CHECK: ibis.port.write %[[VAL_3]], %[[VAL_1]] : !ibis.portref<out i1>
// CHECK: %[[VAL_2]] = hw.constant true
// CHECK: }
// CHECK-LABEL: ibis.container @ParentReader {
// CHECK-LABEL: ibis.container sym @ParentReader {
// CHECK: %[[VAL_0:.*]] = ibis.this <@D::@ParentReader>
// CHECK: %[[VAL_1:.*]] = ibis.container.instance @selfdriver, <@D::@Selfdriver>
// CHECK: %[[VAL_2:.*]] = ibis.get_port %[[VAL_1]], @in : !ibis.scoperef<@D::@Selfdriver> -> !ibis.portref<out i1>
// CHECK: %[[VAL_3:.*]] = ibis.port.read %[[VAL_2]] : !ibis.portref<out i1>
// CHECK: }
ibis.container @Selfdriver {
ibis.container sym @Selfdriver {
%this = ibis.this <@D::@Selfdriver>
%in = ibis.port.input "in" sym @in : i1
%in = ibis.port.input "myIn" sym @in : i1
%true = hw.constant 1 : i1
ibis.port.write %in, %true : !ibis.portref<in i1>
}
ibis.container @ParentReader {
ibis.container sym @ParentReader {
%this = ibis.this <@D::@ParentReader>
%selfdriver = ibis.container.instance @selfdriver, <@D::@Selfdriver>
%in_ref = ibis.get_port %selfdriver, @in : !ibis.scoperef<@D::@Selfdriver> -> !ibis.portref<out i1>
@ -58,12 +58,12 @@ ibis.container @ParentReader {
ibis.design @D {
ibis.container @Foo {
ibis.container sym @Foo {
%this = ibis.this <@D::@Foo>
%in = ibis.port.input "in" sym @in : i1
}
// CHECK-LABEL: ibis.container @ParentReaderWriter {
// CHECK-LABEL: ibis.container sym @ParentReaderWriter {
// CHECK: %[[VAL_0:.*]] = ibis.this <@D::@ParentReaderWriter>
// CHECK: %[[VAL_1:.*]] = ibis.container.instance @f, <@D::@Foo>
// CHECK: %[[VAL_2:.*]] = ibis.get_port %[[VAL_1]], @in : !ibis.scoperef<@D::@Foo> -> !ibis.portref<in i1>
@ -71,7 +71,7 @@ ibis.container @Foo {
// CHECK: %[[VAL_3]] = hw.constant true
// CHECK: ibis.port.write %[[VAL_2]], %[[VAL_3]] : !ibis.portref<in i1>
// CHECK: }
ibis.container @ParentReaderWriter {
ibis.container sym @ParentReaderWriter {
%this = ibis.this <@D::@ParentReaderWriter>
%f = ibis.container.instance @f, <@D::@Foo>
%in_wr_ref = ibis.get_port %f, @in : !ibis.scoperef<@D::@Foo> -> !ibis.portref<in i1>

View File

@ -2,11 +2,11 @@
ibis.design @foo {
// CHECK-LABEL: ibis.container @A_B
// CHECK-LABEL: ibis.container @MyClass
// CHECK-LABEL: ibis.container @A_B_0
// CHECK-LABEL: ibis.container @A_C
// CHECK-LABEL: ibis.container @A {
// CHECK-LABEL: ibis.container sym @A_B
// CHECK-LABEL: ibis.container "MyClassName" sym @MyClass
// CHECK-LABEL: ibis.container sym @A_B_0
// CHECK-LABEL: ibis.container sym @A_C
// CHECK-LABEL: ibis.container sym @A {
// CHECK: %[[VAL_0:.*]] = ibis.this <@foo::@A>
// CHECK: ibis.port.input "A_in" sym @A_in : i1
// CHECK: %[[VAL_1:.*]] = ibis.container.instance @myClass, <@foo::@MyClass>
@ -15,22 +15,22 @@ ibis.design @foo {
// This container will alias with the @B inside @A, and thus checks the
// name uniquing logic.
ibis.container @A_B {
ibis.container sym @A_B {
%this = ibis.this <@foo::@A_B>
}
ibis.class @MyClass {
ibis.class "MyClassName" sym @MyClass {
%this = ibis.this <@foo::@MyClass>
}
ibis.class @A {
ibis.class sym @A {
%this = ibis.this <@foo::@A>
ibis.port.input "A_in" sym @A_in : i1
%myClass = ibis.instance @myClass, <@foo::@MyClass>
ibis.container @B {
ibis.container sym @B {
%B_this = ibis.this <@foo::@B>
}
ibis.container @C {
ibis.container sym @C {
%C_this = ibis.this <@foo::@C>
}
}

View File

@ -2,7 +2,7 @@
ibis.design @D {
// CHECK: hw.module @D_B(in %in_foo : i1 {inputAttr}, out out_foo : i1 {outputAttr}) {
// CHECK: hw.module @D_MyB(in %in_foo : i1 {inputAttr}, out out_foo : i1 {outputAttr}) {
// CHECK: hw.output %in_foo : i1
// CHECK: }
// CHECK: hw.module @D_AccessSibling(in %p_b_out_foo : i1, out p_b_in_foo : i1) {
@ -10,11 +10,11 @@ ibis.design @D {
// CHECK: }
// CHECK: hw.module @Parent() {
// CHECK: %a.p_b_in_foo = hw.instance "a" @D_AccessSibling(p_b_out_foo: %b.out_foo: i1) -> (p_b_in_foo: i1)
// CHECK: %b.out_foo = hw.instance "b" @D_B(in_foo: %a.p_b_in_foo: i1) -> (out_foo: i1)
// CHECK: %b.out_foo = hw.instance "b" @D_MyB(in_foo: %a.p_b_in_foo: i1) -> (out_foo: i1)
// CHECK: hw.output
// CHECK: }
ibis.container @B {
ibis.container "MyB" sym @B {
%this = ibis.this <@D::@B>
// Test different port names vs. symbol names
%in = ibis.port.input "in_foo" sym @in : i1 {"inputAttr"}
@ -25,14 +25,14 @@ ibis.container @B {
ibis.port.write %out, %v : !ibis.portref<out i1>
}
ibis.container @AccessSibling {
ibis.container sym @AccessSibling {
%this = ibis.this <@D::@AccessSibling>
%p_b_out = ibis.port.input "p_b_out_foo" sym @p_b_out : i1
%p_b_in = ibis.port.output "p_b_in_foo" sym @p_b_in : i1
ibis.port.write %p_b_in, %p_b_out.val : !ibis.portref<out i1>
%p_b_out.val = ibis.port.read %p_b_out : !ibis.portref<in i1>
}
ibis.container @Parent top_level {
ibis.container sym @Parent top_level {
%this = ibis.this <@D::@Parent>
%a = ibis.container.instance @a, <@D::@AccessSibling>
%a.p_b_out.ref = ibis.get_port %a, @p_b_out : !ibis.scoperef<@D::@AccessSibling> -> !ibis.portref<in i1>
@ -62,7 +62,7 @@ ibis.design @D {
// CHECK: hw.output
// CHECK: }
ibis.container @C {
ibis.container sym @C {
%this = ibis.this <@D::@C>
%in = ibis.port.input "in_foo" sym @in : i1
%out = ibis.port.output "out_foo" sym @out : i1
@ -98,13 +98,13 @@ ibis.design @D {
// CHECK: hw.output
// CHECK: }
ibis.container @Inst {
ibis.container sym @Inst {
%this = ibis.this <@D::@Inst>
%out = ibis.port.output "out" sym @out : i1
%true = hw.constant 1 : i1
ibis.port.write %out, %true : !ibis.portref<out i1>
}
ibis.container @Top {
ibis.container sym @Top {
%this = ibis.this <@D::@Top>
%myInst = ibis.container.instance @myInst, <@D::@Inst>
%true = hw.constant 1 : i1
@ -123,7 +123,7 @@ ibis.design @D {
// CHECK: hw.module @D_Top(in %clk : i1, in %clk_0 : i1, out out : i1, out out_0 : i1) {
// CHECK: hw.output %clk, %clk_0 : i1, i1
ibis.container @Top {
ibis.container sym @Top {
%this = ibis.this <@D::@Top>
%clk1 = ibis.port.input "clk" sym @clk1 : i1
%clk2 = ibis.port.input "clk" sym @clk2 : i1
@ -136,3 +136,30 @@ ibis.container @Top {
ibis.port.write %out2, %v2 : !ibis.portref<out i1>
}
}
// -----
// Test that we can de-alias module names.
// CHECK: hw.module @D_Foo_0() {
// CHECK: hw.output
// CHECK: }
// CHECK: hw.module @Foo_0() {
// CHECK: hw.output
// CHECK: }
// CHECK: hw.module.extern @D_Foo(in %theExternModule : i1)
// CHECK: hw.module.extern @Foo(in %theExternModule : i1)
ibis.design @D {
ibis.container "Foo" sym @A {
%this = ibis.this <@D::@A>
}
ibis.container "Foo" sym @B top_level {
%this = ibis.this <@D::@B>
}
}
hw.module.extern @D_Foo(in %theExternModule : i1)
hw.module.extern @Foo(in %theExternModule : i1)

View File

@ -3,7 +3,7 @@
// Actual handshake-to-dc conversion is tested in the respective pass tests.
// This file just tests the ibis-specific hooks.
// CHECK-LABEL: ibis.class @ToDC {
// CHECK-LABEL: ibis.class sym @ToDC {
// CHECK: %[[VAL_0:.*]] = ibis.this <@foo::@ToDC>
// CHECK: ibis.method.df @foo(%[[VAL_1:.*]]: !dc.value<i32>) -> !dc.value<i32> {
// CHECK: %[[VAL_2:.*]], %[[VAL_3:.*]] = dc.unpack %[[VAL_1]] : !dc.value<i32>
@ -19,7 +19,7 @@
// CHECK: }
ibis.design @foo {
ibis.class @ToDC {
ibis.class sym @ToDC {
%this = ibis.this <@foo::@ToDC>
ibis.method.df @foo(%arg0: i32) -> (i32) {
%o0, %o1 = handshake.fork [2] %arg0 : i32

View File

@ -3,7 +3,7 @@
ibis.design @foo {
// CHECK-LABEL: ibis.class @Inline1 {
// CHECK-LABEL: ibis.class sym @Inline1 {
// CHECK: %[[VAL_0:.*]] = ibis.this <@foo::@Inline1>
// CHECK: ibis.method @foo(%[[VAL_1:.*]]: i32, %[[VAL_2:.*]]: i32) -> () {
// CHECK: ibis.sblock.inline.begin {maxThreads = 1 : i64}
@ -12,7 +12,7 @@ ibis.design @foo {
// CHECK: ibis.return
// CHECK: }
// CHECK: }
ibis.class @Inline1 {
ibis.class sym @Inline1 {
%this = ibis.this <@foo::@Inline1>
ibis.method @foo(%a : i32, %b : i32) {
@ -24,7 +24,7 @@ ibis.class @Inline1 {
}
}
// CHECK-LABEL: ibis.class @Inline2 {
// CHECK-LABEL: ibis.class sym @Inline2 {
// CHECK: %[[VAL_0:.*]] = ibis.this <@foo::@Inline2>
// CHECK: ibis.method @foo(%[[VAL_1:.*]]: i32, %[[VAL_2:.*]]: i32) -> () {
// CHECK: "foo.unused1"() : () -> ()
@ -40,7 +40,7 @@ ibis.class @Inline1 {
// CHECK: ibis.return
// CHECK: }
// CHECK: }
ibis.class @Inline2 {
ibis.class sym @Inline2 {
%this = ibis.this <@foo::@Inline2>
ibis.method @foo(%a : i32, %b : i32) {
"foo.unused1"() : () -> ()

View File

@ -1,8 +1,8 @@
// RUN: circt-opt --pass-pipeline='builtin.module(ibis.design(ibis.class(ibis-convert-methods-to-containers)))' %s | FileCheck %s
// CHECK-LABEL: ibis.class @ToContainers {
// CHECK-LABEL: ibis.class sym @ToContainers {
// CHECK: %[[VAL_0:.*]] = ibis.this <@foo::@ToContainers>
// CHECK: ibis.container @foo {
// CHECK: ibis.container sym @foo {
// CHECK: %[[VAL_1:.*]] = ibis.this <@foo::@foo>
// CHECK: %[[VAL_2:.*]] = ibis.port.input "arg0" sym @arg0 : !dc.value<i32>
// CHECK: %[[VAL_3:.*]] = ibis.port.read %[[VAL_2]] : !ibis.portref<in !dc.value<i32>>
@ -20,7 +20,7 @@
// CHECK: }
ibis.design @foo {
ibis.class @ToContainers {
ibis.class sym @ToContainers {
%this = ibis.this <@foo::@ToContainers>
ibis.method.df @foo(%arg0: !dc.value<i32>) -> !dc.value<i32> {
%token, %output = dc.unpack %arg0 : !dc.value<i32>

View File

@ -7,7 +7,7 @@
// RUN: --ibis-convert-containers-to-hw
ibis.design @foo {
ibis.container @D_up {
ibis.container sym @D_up {
%this = ibis.this <@foo::@D_up>
%d = ibis.path [
#ibis.step<parent : !ibis.scoperef>,
@ -31,39 +31,39 @@ ibis.container @D_up {
%clk_out_ref = ibis.get_port %d, @clk_out : !ibis.scoperef<@D_down> -> !ibis.portref<out i1>
%clk_out_val = ibis.port.read %clk_out_ref : !ibis.portref<out i1>
}
ibis.container @C_up {
ibis.container sym @C_up {
%this = ibis.this <@foo::@C_up>
%d = ibis.container.instance @d, @D_up
}
ibis.container @B_up {
ibis.container sym @B_up {
%this = ibis.this <@foo::@B_up>
%c = ibis.container.instance @c, @C_up
}
ibis.container @A_up {
ibis.container sym @A_up {
%this = ibis.this <@foo::@A_up>
%b = ibis.container.instance @b, @B_up
}
ibis.container @Top {
ibis.container sym @Top {
%this = ibis.this <@foo::@Top>
%a_down = ibis.container.instance @a_down, @A_down
%a_up = ibis.container.instance @a_up, @A_up
}
ibis.container @A_down {
ibis.container sym @A_down {
%this = ibis.this <@foo::@A_down>
%b = ibis.container.instance @b, @B_down
}
ibis.container @B_down {
ibis.container sym @B_down {
%this = ibis.this <@foo::@B_down>
%c = ibis.container.instance @c, @C_down
}
ibis.container @C_down {
ibis.container sym @C_down {
%this = ibis.this <@foo::@C_down>
%d = ibis.container.instance @d, @D_down
}
ibis.container @D_down {
ibis.container sym @D_down {
%this = ibis.this <@foo::@D_down>
%clk = ibis.port.input "clk_in" sym @clk_in : i1
%clk_out = ibis.port.output "clk_out" sym @clk_out : i1

View File

@ -2,20 +2,20 @@
ibis.design @D {
ibis.container @C {
ibis.container sym @C {
%this = ibis.this <@D::@C>
%in = ibis.port.input "in" sym @in : i1
%out = ibis.port.output "out" sym @out : i1
}
// CHECK-LABEL: ibis.container @AccessSibling {
// CHECK-LABEL: ibis.container sym @AccessSibling {
// CHECK: %[[VAL_0:.*]] = ibis.this <@D::@AccessSibling>
// CHECK: %[[VAL_1:.*]] = ibis.port.input "p_b_out" sym @p_b_out : i1
// CHECK: %[[VAL_2:.*]] = ibis.port.output "p_b_in" sym @p_b_in : i1
// CHECK: ibis.port.write %[[VAL_2]], %[[VAL_3:.*]] : !ibis.portref<out i1>
// CHECK: %[[VAL_3]] = ibis.port.read %[[VAL_1]] : !ibis.portref<in i1>
// CHECK: }
ibis.container @AccessSibling {
ibis.container sym @AccessSibling {
%this = ibis.this <@D::@AccessSibling>
%p_b_out = ibis.port.input "p_b_out" sym @p_b_out : !ibis.portref<out i1>
%p_b_out_val = ibis.port.read %p_b_out : !ibis.portref<in !ibis.portref<out i1>>
@ -27,7 +27,7 @@ ibis.container @AccessSibling {
ibis.port.write %p_b_in_val, %v : !ibis.portref<in i1>
}
// CHECK-LABEL: ibis.container @Parent {
// CHECK-LABEL: ibis.container sym @Parent {
// CHECK: %[[VAL_0:.*]] = ibis.this <@D::@Parent>
// CHECK: %[[VAL_1:.*]] = ibis.container.instance @a, <@D::@AccessSibling>
// CHECK: %[[VAL_2:.*]] = ibis.get_port %[[VAL_1]], @p_b_out : !ibis.scoperef<@D::@AccessSibling> -> !ibis.portref<in i1>
@ -40,7 +40,7 @@ ibis.container @AccessSibling {
// CHECK: %[[VAL_4]] = ibis.get_port %[[VAL_8]], @out : !ibis.scoperef<@D::@C> -> !ibis.portref<out i1>
// CHECK: %[[VAL_7]] = ibis.get_port %[[VAL_8]], @in : !ibis.scoperef<@D::@C> -> !ibis.portref<in i1>
// CHECK: }
ibis.container @Parent {
ibis.container sym @Parent {
%this = ibis.this <@D::@Parent>
%a = ibis.container.instance @a, <@D::@AccessSibling>
%a.p_b_out = ibis.get_port %a, @p_b_out : !ibis.scoperef<@D::@AccessSibling> -> !ibis.portref<in !ibis.portref<out i1>>
@ -59,12 +59,12 @@ ibis.container @Parent {
ibis.design @D {
// CHECK-LABEL: ibis.container @ParentPortAccess {
// CHECK-LABEL: ibis.container sym @ParentPortAccess {
// CHECK: %[[VAL_0:.*]] = ibis.this <@D::@ParentPortAccess>
// CHECK: %[[VAL_1:.*]] = ibis.port.output "p_in" sym @p_in : i1
// CHECK: %[[VAL_2:.*]] = ibis.port.input "p_out" sym @p_out : i1
// CHECK: }
ibis.container @ParentPortAccess {
ibis.container sym @ParentPortAccess {
%this = ibis.this <@D::@ParentPortAccess>
%p_in = ibis.port.input "p_in" sym @p_in : !ibis.portref<in i1>
%p_in_val = ibis.port.read %p_in : !ibis.portref<in !ibis.portref<in i1>>
@ -72,7 +72,7 @@ ibis.container @ParentPortAccess {
%p_out_val = ibis.port.read %p_out : !ibis.portref<in !ibis.portref<out i1>>
}
// CHECK-LABEL: ibis.container @Parent {
// CHECK-LABEL: ibis.container sym @Parent {
// CHECK: %[[VAL_0:.*]] = ibis.this <@D::@Parent>
// CHECK: %[[VAL_1:.*]] = ibis.container.instance @c, <@D::@ParentPortAccess>
// CHECK: %[[VAL_2:.*]] = ibis.get_port %[[VAL_1]], @p_in : !ibis.scoperef<@D::@ParentPortAccess> -> !ibis.portref<out i1>
@ -84,7 +84,7 @@ ibis.container @ParentPortAccess {
// CHECK: %[[VAL_4]] = ibis.port.input "in" sym @in : i1
// CHECK: %[[VAL_7]] = ibis.port.output "out" sym @out : i1
// CHECK: }
ibis.container @Parent {
ibis.container sym @Parent {
%this = ibis.this <@D::@Parent>
%c = ibis.container.instance @c, <@D::@ParentPortAccess>
%c.p_in = ibis.get_port %c, @p_in : !ibis.scoperef<@D::@ParentPortAccess> -> !ibis.portref<in !ibis.portref<in i1>>
@ -104,14 +104,14 @@ ibis.design @D {
// C1 child -> P1 parent -> P2 parent -> C2 child -> C3 child
// CHECK-LABEL: ibis.container @C1 {
// CHECK-LABEL: ibis.container sym @C1 {
// CHECK: %[[VAL_0:.*]] = ibis.this <@D::@C1>
// CHECK: %[[VAL_1:.*]] = ibis.port.output "parent_parent_c2_c3_in" sym @parent_parent_c2_c3_in : i1
// CHECK: ibis.port.write %[[VAL_1]], %[[VAL_2:.*]] : !ibis.portref<out i1>
// CHECK: %[[VAL_3:.*]] = ibis.port.input "parent_parent_c2_c3_out" sym @parent_parent_c2_c3_out : i1
// CHECK: %[[VAL_2]] = ibis.port.read %[[VAL_3]] : !ibis.portref<in i1>
// CHECK: }
ibis.container @C1 {
ibis.container sym @C1 {
%this = ibis.this <@D::@C1>
%parent_parent_c2_c3_in = ibis.port.input "parent_parent_c2_c3_in" sym @parent_parent_c2_c3_in : !ibis.portref<in i1>
%parent_parent_c2_c3_out = ibis.port.input "parent_parent_c2_c3_out" sym @parent_parent_c2_c3_out : !ibis.portref<out i1>
@ -123,7 +123,7 @@ ibis.container @C1 {
ibis.port.write %parent_b_in_unwrapped, %parent_b_out_value : !ibis.portref<in i1>
}
// CHECK-LABEL: ibis.container @C2 {
// CHECK-LABEL: ibis.container sym @C2 {
// CHECK: %[[VAL_0:.*]] = ibis.this <@D::@C2>
// CHECK: %[[VAL_1:.*]] = ibis.container.instance @c3, <@D::@C>
// CHECK: %[[VAL_2:.*]] = ibis.get_port %[[VAL_1]], @in : !ibis.scoperef<@D::@C> -> !ibis.portref<in i1>
@ -135,7 +135,7 @@ ibis.container @C1 {
// CHECK: %[[VAL_7:.*]] = ibis.port.read %[[VAL_3]] : !ibis.portref<out i1>
// CHECK: ibis.port.write %[[VAL_6]], %[[VAL_7]] : !ibis.portref<out i1>
// CHECK: }
ibis.container @C2 {
ibis.container sym @C2 {
%this = ibis.this <@D::@C2>
%c3 = ibis.container.instance @c3, <@D::@C>
%c3.in = ibis.get_port %c3, @in : !ibis.scoperef<@D::@C> -> !ibis.portref<in i1>
@ -145,13 +145,13 @@ ibis.container @C2 {
ibis.port.write %parent_parent_c2_c3_in, %c3.in : !ibis.portref<out !ibis.portref<in i1>>
ibis.port.write %parent_parent_c2_c3_out, %c3.out : !ibis.portref<out !ibis.portref<out i1>>
}
ibis.container @C {
ibis.container sym @C {
%this = ibis.this <@D::@C>
%in = ibis.port.input "in" sym @in : i1
%out = ibis.port.output "out" sym @out : i1
}
// CHECK-LABEL: ibis.container @P1 {
// CHECK-LABEL: ibis.container sym @P1 {
// CHECK: %[[VAL_0:.*]] = ibis.this <@D::@P1>
// CHECK: %[[VAL_1:.*]] = ibis.container.instance @c1, <@D::@C1>
// CHECK: %[[VAL_2:.*]] = ibis.get_port %[[VAL_1]], @parent_parent_c2_c3_in : !ibis.scoperef<@D::@C1> -> !ibis.portref<out i1>
@ -163,7 +163,7 @@ ibis.container @C {
// CHECK: ibis.port.write %[[VAL_7]], %[[VAL_3]] : !ibis.portref<out i1>
// CHECK: %[[VAL_6]] = ibis.port.input "parent_parent_c2_c3_out" sym @parent_parent_c2_c3_out : i1
// CHECK: }
ibis.container @P1 {
ibis.container sym @P1 {
%this = ibis.this <@D::@P1>
%c1 = ibis.container.instance @c1, <@D::@C1>
%c1.parent_parent_c2_c3_in = ibis.get_port %c1, @parent_parent_c2_c3_in : !ibis.scoperef<@D::@C1> -> !ibis.portref<in !ibis.portref<in i1>>
@ -176,7 +176,7 @@ ibis.container @P1 {
%1 = ibis.port.read %parent_parent_c2_c3_out : !ibis.portref<in !ibis.portref<out i1>>
}
// CHECK-LABEL: ibis.container @P2 {
// CHECK-LABEL: ibis.container sym @P2 {
// CHECK: %[[VAL_0:.*]] = ibis.this <@D::@P2>
// CHECK: %[[VAL_1:.*]] = ibis.container.instance @p1, <@D::@P1>
// CHECK: %[[VAL_2:.*]] = ibis.get_port %[[VAL_1]], @parent_parent_c2_c3_in : !ibis.scoperef<@D::@P1> -> !ibis.portref<out i1>
@ -192,7 +192,7 @@ ibis.container @P1 {
// CHECK: %[[VAL_10:.*]] = ibis.get_port %[[VAL_8]], @parent_parent_c2_c3_in : !ibis.scoperef<@D::@C2> -> !ibis.portref<in i1>
// CHECK: ibis.port.write %[[VAL_10]], %[[VAL_9]] : !ibis.portref<in i1>
// CHECK: }
ibis.container @P2 {
ibis.container sym @P2 {
%this = ibis.this <@D::@P2>
%p1 = ibis.container.instance @p1, <@D::@P1>
%p1.parent_parent_c2_c3_in = ibis.get_port %p1, @parent_parent_c2_c3_in : !ibis.scoperef<@D::@P1> -> !ibis.portref<in !ibis.portref<in i1>>
@ -213,12 +213,12 @@ ibis.container @P2 {
ibis.design @D {
// CHECK-LABEL: ibis.container @AccessParent {
// CHECK-LABEL: ibis.container sym @AccessParent {
// CHECK: %[[VAL_0:.*]] = ibis.this <@D::@AccessParent>
// CHECK: %[[VAL_1:.*]] = ibis.port.output "p_out" sym @p_out : i1
// CHECK: %[[VAL_2:.*]] = ibis.port.input "p_in" sym @p_in : i1
// CHECK: }
ibis.container @AccessParent {
ibis.container sym @AccessParent {
%this = ibis.this <@D::@AccessParent>
%p_out = ibis.port.input "p_out" sym @p_out : !ibis.portref<in i1>
%p_out.val = ibis.port.read %p_out : !ibis.portref<in !ibis.portref<in i1>>
@ -226,7 +226,7 @@ ibis.container @AccessParent {
%p_in.val = ibis.port.read %p_in : !ibis.portref<in !ibis.portref<out i1>>
}
// CHECK-LABEL: ibis.container @Parent {
// CHECK-LABEL: ibis.container sym @Parent {
// CHECK: %[[VAL_0:.*]] = ibis.this <@D::@Parent>
// CHECK: %[[VAL_1:.*]] = ibis.port.input "in" sym @in : i1
// CHECK: %[[VAL_2:.*]] = ibis.port.read %[[VAL_1]] : !ibis.portref<in i1>
@ -242,7 +242,7 @@ ibis.container @AccessParent {
// CHECK: %[[VAL_11:.*]] = ibis.port.read %[[VAL_3]] : !ibis.portref<out i1>
// CHECK: ibis.port.write %[[VAL_10]], %[[VAL_11]] : !ibis.portref<in i1>
// CHECK: }
ibis.container @Parent {
ibis.container sym @Parent {
%this = ibis.this <@D::@Parent>
%in = ibis.port.input "in" sym @in : i1
%in.val = ibis.port.read %in : !ibis.portref<in i1>

View File

@ -12,7 +12,7 @@
// CHECK: }
ibis.design @foo {
ibis.class @PrepareScheduling {
ibis.class sym @PrepareScheduling {
%this = ibis.this <@foo::@PrepareScheduling>
// A test wherein the returned values are either a value generated by an
// operation in the pipeline, or a value that's passed through the pipeline.

View File

@ -1,6 +1,6 @@
// RUN: circt-opt --pass-pipeline='builtin.module(ibis.design(ibis.class(ibis.method(ibis-reblock))))' %s | FileCheck %s
// CHECK-LABEL: ibis.class @Reblock {
// CHECK-LABEL: ibis.class sym @Reblock {
// CHECK: %[[VAL_0:.*]] = ibis.this <@foo::@Reblock>
// CHECK: ibis.method @foo(%[[VAL_1:.*]]: i32, %[[VAL_2:.*]]: i32) -> i32 {
// CHECK: %[[VAL_3:.*]] = ibis.sblock () -> i32 {
@ -27,7 +27,7 @@
// CHECK: }
ibis.design @foo {
ibis.class @Reblock {
ibis.class sym @Reblock {
%this = ibis.this <@foo::@Reblock>
ibis.method @foo(%arg0 : i32, %arg1 : i32) -> i32 {

View File

@ -16,7 +16,7 @@
// CHECK: operator_type @comb.shrs [latency<1>]
// CHECK: }
// CHECK-LABEL: ibis.class @SchedulePipeline {
// CHECK-LABEL: ibis.class sym @SchedulePipeline {
// CHECK: %[[VAL_0:.*]] = ibis.this <@foo::@SchedulePipeline>
// CHECK: ibis.method.df @foo(%[[VAL_1:.*]]: i32, %[[VAL_2:.*]]: i32) -> i32 {
// CHECK: %[[VAL_3:.*]] = ibis.sblock.isolated (%[[VAL_4:.*]] : i32 = %[[VAL_1]], %[[VAL_5:.*]] : i32 = %[[VAL_2]]) -> i32 {
@ -45,7 +45,7 @@
// CHECK: }
ibis.design @foo {
ibis.class @SchedulePipeline {
ibis.class sym @SchedulePipeline {
%this = ibis.this <@foo::@SchedulePipeline>
// A test wherein the returned values are either a value generated by an
// operation in the pipeline, or a value that's passed through the pipeline.

View File

@ -2,20 +2,20 @@
ibis.design @D {
ibis.container @C {
ibis.container sym @C {
%this = ibis.this <@D::@C>
%in = ibis.port.input "in" sym @in : i1
%out = ibis.port.output "out" sym @out : i1
}
// CHECK-LABEL: ibis.container @AccessChild {
// CHECK-LABEL: ibis.container sym @AccessChild {
// CHECK: %[[VAL_0:.*]] = ibis.this <@D::@AccessChild>
// CHECK: %[[VAL_1:.*]] = ibis.container.instance @c, <@D::@C>
// CHECK: %[[VAL_2:.*]] = ibis.get_port %[[VAL_1]], @out : !ibis.scoperef<@D::@C> -> !ibis.portref<out i1>
// CHECK: %[[VAL_3:.*]] = ibis.get_port %[[VAL_1]], @in : !ibis.scoperef<@D::@C> -> !ibis.portref<in i1>
// CHECK-NEXT: }
ibis.container @AccessChild {
ibis.container sym @AccessChild {
%this = ibis.this <@D::@AccessChild>
%c = ibis.container.instance @c, <@D::@C>
%c_ref = ibis.path [
@ -31,20 +31,20 @@ ibis.container @AccessChild {
// CHECK-LABEL: // -----
ibis.design @D {
ibis.container @C {
ibis.container sym @C {
%this = ibis.this <@D::@C>
%in = ibis.port.input "in" sym @in : i1
%out = ibis.port.output "out" sym @out : i1
}
// CHECK-LABEL: ibis.container @AccessSibling {
// CHECK-LABEL: ibis.container sym @AccessSibling {
// CHECK: %[[VAL_0:.*]] = ibis.this <@D::@AccessSibling>
// CHECK: %[[VAL_1:.*]] = ibis.port.input "[[VAL_1]]" sym @[[VAL_1]] : !ibis.portref<out i1>
// CHECK: %[[VAL_2:.*]] = ibis.port.read %[[VAL_1]] : !ibis.portref<in !ibis.portref<out i1>>
// CHECK: %[[VAL_3:.*]] = ibis.port.input "[[VAL_3]]" sym @[[VAL_3]] : !ibis.portref<in i1>
// CHECK: %[[VAL_4:.*]] = ibis.port.read %[[VAL_3]] : !ibis.portref<in !ibis.portref<in i1>>
// CHECK: }
ibis.container @AccessSibling {
ibis.container sym @AccessSibling {
%this = ibis.this <@D::@AccessSibling>
%sibling = ibis.path [
#ibis.step<parent : !ibis.scoperef>,
@ -54,7 +54,7 @@ ibis.container @AccessSibling {
%c_out = ibis.get_port %sibling, @out : !ibis.scoperef<@D::@C> -> !ibis.portref<out i1>
}
// CHECK-LABEL: ibis.container @Parent {
// CHECK-LABEL: ibis.container sym @Parent {
// CHECK: %[[VAL_0:.*]] = ibis.this <@D::@Parent>
// CHECK: %[[VAL_1:.*]] = ibis.container.instance @a, <@D::@AccessSibling>
// CHECK: %[[VAL_2:.*]] = ibis.get_port %[[VAL_1]], @p_b_out.rd : !ibis.scoperef<@D::@AccessSibling> -> !ibis.portref<in !ibis.portref<out i1>>
@ -65,7 +65,7 @@ ibis.container @AccessSibling {
// CHECK: %[[VAL_3]] = ibis.get_port %[[VAL_6]], @out : !ibis.scoperef<@D::@C> -> !ibis.portref<out i1>
// CHECK: %[[VAL_5]] = ibis.get_port %[[VAL_6]], @in : !ibis.scoperef<@D::@C> -> !ibis.portref<in i1>
// CHECK: }
ibis.container @Parent {
ibis.container sym @Parent {
%this = ibis.this <@D::@Parent>
%a = ibis.container.instance @a, <@D::@AccessSibling>
%b = ibis.container.instance @b, <@D::@C>
@ -80,14 +80,14 @@ ibis.container @Parent {
// C1 child -> P1 parent -> P2 parent -> C2 child -> C3 child
ibis.design @D {
// CHECK-LABEL: ibis.container @C1 {
// CHECK-LABEL: ibis.container sym @C1 {
// CHECK: %[[VAL_0:.*]] = ibis.this <@D::@C1>
// CHECK: %[[VAL_1:.*]] = ibis.port.input "p_p_c2_c3_out.rd" sym @p_p_c2_c3_out.rd : !ibis.portref<out i1>
// CHECK: %[[VAL_2:.*]] = ibis.port.read %[[VAL_1]] : !ibis.portref<in !ibis.portref<out i1>>
// CHECK: %[[VAL_3:.*]] = ibis.port.input "p_p_c2_c3_in.wr" sym @p_p_c2_c3_in.wr : !ibis.portref<in i1>
// CHECK: %[[VAL_4:.*]] = ibis.port.read %[[VAL_3]] : !ibis.portref<in !ibis.portref<in i1>>
// CHECK: }
ibis.container @C1 {
ibis.container sym @C1 {
%this = ibis.this <@D::@C1>
%c3 = ibis.path [
#ibis.step<parent : !ibis.scoperef>,
@ -99,7 +99,7 @@ ibis.container @C1 {
%c_out = ibis.get_port %c3, @out : !ibis.scoperef<@D::@C> -> !ibis.portref<out i1>
}
// CHECK-LABEL: ibis.container @C2 {
// CHECK-LABEL: ibis.container sym @C2 {
// CHECK: %[[VAL_0:.*]] = ibis.this <@D::@C2>
// CHECK: %[[VAL_1:.*]] = ibis.container.instance @c3, <@D::@C>
// CHECK: %[[VAL_2:.*]] = ibis.get_port %[[VAL_1]], @out : !ibis.scoperef<@D::@C> -> !ibis.portref<out i1>
@ -109,18 +109,18 @@ ibis.container @C1 {
// CHECK: ibis.port.write %[[VAL_4]], %[[VAL_2]] : !ibis.portref<out !ibis.portref<out i1>>
// CHECK: ibis.port.write %[[VAL_5]], %[[VAL_3]] : !ibis.portref<out !ibis.portref<in i1>>
// CHECK: }
ibis.container @C2 {
ibis.container sym @C2 {
%this = ibis.this <@D::@C2>
%c3 = ibis.container.instance @c3, <@D::@C>
}
ibis.container @C {
ibis.container sym @C {
%this = ibis.this <@D::@C>
%in = ibis.port.input "in" sym @in : i1
%out = ibis.port.output "out" sym @out : i1
}
// CHECK-LABEL: ibis.container @P1 {
// CHECK-LABEL: ibis.container sym @P1 {
// CHECK: %[[VAL_0:.*]] = ibis.this <@D::@P1>
// CHECK: %[[VAL_1:.*]] = ibis.container.instance @c1, <@D::@C1>
// CHECK: %[[VAL_2:.*]] = ibis.get_port %[[VAL_1]], @p_p_c2_c3_out.rd : !ibis.scoperef<@D::@C1> -> !ibis.portref<in !ibis.portref<out i1>>
@ -132,12 +132,12 @@ ibis.container @C {
// CHECK: %[[VAL_7:.*]] = ibis.port.input "p_p_c2_c3_in.wr" sym @p_p_c2_c3_in.wr : !ibis.portref<in i1>
// CHECK: %[[VAL_5]] = ibis.port.read %[[VAL_7]] : !ibis.portref<in !ibis.portref<in i1>>
// CHECK: }
ibis.container @P1 {
ibis.container sym @P1 {
%this = ibis.this <@D::@P1>
%c1 = ibis.container.instance @c1, <@D::@C1>
}
// CHECK-LABEL: ibis.container @P2 {
// CHECK-LABEL: ibis.container sym @P2 {
// CHECK: %[[VAL_0:.*]] = ibis.this <@D::@P2>
// CHECK: %[[VAL_1:.*]] = ibis.container.instance @p1, <@D::@P1>
// CHECK: %[[VAL_2:.*]] = ibis.get_port %[[VAL_1]], @p_p_c2_c3_out.rd : !ibis.scoperef<@D::@P1> -> !ibis.portref<in !ibis.portref<out i1>>
@ -150,7 +150,7 @@ ibis.container @P1 {
// CHECK: %[[VAL_8:.*]] = ibis.get_port %[[VAL_6]], @p_p_c2_c3_out.rd : !ibis.scoperef<@D::@C2> -> !ibis.portref<out !ibis.portref<out i1>>
// CHECK: %[[VAL_3]] = ibis.port.read %[[VAL_8]] : !ibis.portref<out !ibis.portref<out i1>>
// CHECK: }
ibis.container @P2 {
ibis.container sym @P2 {
%this = ibis.this <@D::@P2>
%p1 = ibis.container.instance @p1, <@D::@P1>
%c2 = ibis.container.instance @c2, <@D::@C2>
@ -162,14 +162,14 @@ ibis.container @P2 {
// CHECK-LABEL: // -----
ibis.design @D {
// CHECK-LABEL: ibis.container @AccessParent {
// CHECK-LABEL: ibis.container sym @AccessParent {
// CHECK: %[[VAL_0:.*]] = ibis.this <@D::@AccessParent>
// CHECK: %[[VAL_1:.*]] = ibis.port.input "p_out.wr" sym @p_out.wr : !ibis.portref<in i1>
// CHECK: %[[VAL_2:.*]] = ibis.port.read %[[VAL_1]] : !ibis.portref<in !ibis.portref<in i1>>
// CHECK: %[[VAL_3:.*]] = ibis.port.input "p_in.rd" sym @p_in.rd : !ibis.portref<out i1>
// CHECK: %[[VAL_4:.*]] = ibis.port.read %[[VAL_3]] : !ibis.portref<in !ibis.portref<out i1>>
// CHECK: }
ibis.container @AccessParent {
ibis.container sym @AccessParent {
%this = ibis.this <@D::@AccessParent>
%p = ibis.path [
#ibis.step<parent : !ibis.scoperef<@D::@Parent>>
@ -183,7 +183,7 @@ ibis.container @AccessParent {
%p_out_ref = ibis.get_port %p, @out : !ibis.scoperef<@D::@Parent> -> !ibis.portref<in i1>
}
// CHECK-LABEL: ibis.container @Parent {
// CHECK-LABEL: ibis.container sym @Parent {
// CHECK: %[[VAL_0:.*]] = ibis.this <@D::@Parent>
// CHECK: %[[VAL_1:.*]] = ibis.port.input "in" sym @in : i1
// CHECK: %[[VAL_2:.*]] = ibis.port.read %[[VAL_1]] : !ibis.portref<in i1>
@ -197,7 +197,7 @@ ibis.container @AccessParent {
// CHECK: %[[VAL_9:.*]] = ibis.get_port %[[VAL_7]], @p_in.rd : !ibis.scoperef<@D::@AccessParent> -> !ibis.portref<in !ibis.portref<out i1>>
// CHECK: ibis.port.write %[[VAL_9]], %[[VAL_3]] : !ibis.portref<in !ibis.portref<out i1>>
// CHECK: }
ibis.container @Parent {
ibis.container sym @Parent {
%this = ibis.this <@D::@Parent>
%in = ibis.port.input "in" sym @in : i1
%out = ibis.port.output "out" sym @out : i1
@ -211,7 +211,7 @@ ibis.container @Parent {
ibis.design @D {
ibis.container @C {
ibis.container sym @C {
%this = ibis.this <@D::@C>
%in = ibis.port.input "in" sym @in : i1
%out = ibis.port.output "out" sym @out : i1
@ -248,7 +248,7 @@ ibis.design @D {
// and downwards tunneling, we are sure test all the possible combinations of
// tunneling.
ibis.container @D_up {
ibis.container sym @D_up {
%this = ibis.this <@D::@D_up>
%d = ibis.path [
#ibis.step<parent : !ibis.scoperef>,
@ -272,39 +272,39 @@ ibis.container @D_up {
%clk_out_ref = ibis.get_port %d, @clk_out : !ibis.scoperef<@D::@D_down> -> !ibis.portref<out i1>
%clk_out_val = ibis.port.read %clk_out_ref : !ibis.portref<out i1>
}
ibis.container @C_up {
ibis.container sym @C_up {
%this = ibis.this <@D::@C_up>
%d = ibis.container.instance @d, <@D::@D_up>
}
ibis.container @B_up {
ibis.container sym @B_up {
%this = ibis.this <@D::@B_up>
%c = ibis.container.instance @c, <@D::@C_up>
}
ibis.container @A_up {
ibis.container sym @A_up {
%this = ibis.this <@D::@A_up>
%b = ibis.container.instance @b, <@D::@B_up>
}
ibis.container @Top {
ibis.container sym @Top {
%this = ibis.this <@D::@Top>
%a_down = ibis.container.instance @a_down, <@D::@A_down>
%a_up = ibis.container.instance @a_up, <@D::@A_up>
}
ibis.container @A_down {
ibis.container sym @A_down {
%this = ibis.this <@D::@A_down>
%b = ibis.container.instance @b, <@D::@B_down>
}
ibis.container @B_down {
ibis.container sym @B_down {
%this = ibis.this <@D::@B_down>
%c = ibis.container.instance @c, <@D::@C_down>
}
ibis.container @C_down {
ibis.container sym @C_down {
%this = ibis.this <@D::@C_down>
%d = ibis.container.instance @d, <@D::@D_down>
}
ibis.container @D_down {
ibis.container sym @D_down {
%this = ibis.this <@D::@D_down>
%clk = ibis.port.input "clk_in" sym @clk_in : i1
%clk_out = ibis.port.output "clk_out" sym @clk_out : i1

View File

@ -2,13 +2,13 @@
// RUN: circt-opt %s --ibis-call-prep | circt-opt | FileCheck %s --check-prefix=PREP
// CHECK-LABEL: ibis.class @C {
// CHECK-LABEL: ibis.class sym @C {
// CHECK: ibis.method @getAndSet(%x: ui32) -> ui32 {
// CHECK: ibis.return %x : ui32
// CHECK: ibis.method @returnNothingWithRet() -> () {
// CHECK: ibis.return
// PREP-LABEL: ibis.class @C {
// PREP-LABEL: ibis.class sym @C {
// PREP: ibis.method @getAndSet(%arg: !hw.struct<x: ui32>) -> ui32 {
// PREP: %x = hw.struct_explode %arg : !hw.struct<x: ui32>
// PREP: ibis.return %x : ui32
@ -17,7 +17,7 @@
// PREP: ibis.return
ibis.design @foo {
ibis.class @C {
ibis.class sym @C {
%this = ibis.this <@foo::@C>
ibis.method @getAndSet(%x: ui32) -> ui32 {
ibis.return %x : ui32
@ -27,7 +27,7 @@ ibis.class @C {
}
}
// CHECK-LABEL: ibis.class @User {
// CHECK-LABEL: ibis.class sym @User {
// CHECK: [[c:%.+]] = ibis.instance @c, <@foo::@C>
// CHECK: ibis.method @getAndSetWrapper(%new_value: ui32) -> ui32 {
// CHECK: [[x:%.+]] = ibis.call <@foo::@getAndSet>(%new_value) : (ui32) -> ui32
@ -37,7 +37,7 @@ ibis.class @C {
// CHECK: ibis.return [[x]] : ui32
// PREP-LABEL: ibis.class @User {
// PREP-LABEL: ibis.class sym @User {
// PREP: [[c:%.+]] = ibis.instance @c, <@foo::@C>
// PREP: ibis.method @getAndSetWrapper(%arg: !hw.struct<new_value: ui32>) -> ui32 {
// PREP: %new_value = hw.struct_explode %arg : !hw.struct<new_value: ui32>
@ -48,7 +48,7 @@ ibis.class @C {
// PREP: [[STRUCT2:%.+]] = hw.struct_create (%new_value) {sv.namehint = "getAndSet_args_called_from_getAndSetDup"} : !hw.struct<x: ui32>
// PREP: [[CALLRES2:%.+]] = ibis.call <@foo::@getAndSet>([[STRUCT2]]) : (!hw.struct<x: ui32>) -> ui32
// PREP: ibis.return [[CALLRES2]] : ui32
ibis.class @User {
ibis.class sym @User {
%this = ibis.this <@foo::@User>
ibis.instance @c, <@foo::@C>
ibis.method @getAndSetWrapper(%new_value: ui32) -> ui32 {

View File

@ -1,12 +1,12 @@
// RUN: circt-opt --split-input-file --allow-unregistered-dialect --ibis-tunneling --verify-diagnostics %s
ibis.design @foo {
ibis.container @Parent {
ibis.container sym @Parent {
%this = ibis.this <@foo::@Parent>
%in = ibis.port.input "in" sym @in : i1
}
ibis.container @Orphan {
ibis.container sym @Orphan {
%this = ibis.this <@foo::@Orphan>
// expected-error @+2 {{'ibis.path' op cannot tunnel up from "Orphan" because it has no uses}}
// expected-error @+1 {{failed to legalize operation 'ibis.path' that was explicitly marked illegal}}
@ -20,17 +20,17 @@ ibis.container @Orphan {
// -----
ibis.design @foo {
ibis.container @Parent {
ibis.container sym @Parent {
%this = ibis.this <@foo::@Parent>
%mc = ibis.container.instance @mc, <@foo::@MissingChild>
}
ibis.container @Child {
ibis.container sym @Child {
%this = ibis.this <@foo::@Child>
%in = ibis.port.input "in" sym @in : i1
}
ibis.container @MissingChild {
ibis.container sym @MissingChild {
%this = ibis.this <@foo::@MissingChild>
// expected-error @+2 {{'ibis.path' op expected an instance named @c in @Parent but found none}}
// expected-error @+1 {{failed to legalize operation 'ibis.path' that was explicitly marked illegal}}

View File

@ -2,12 +2,12 @@
ibis.design @foo {
// CHECK-LABEL: ibis.container @GetPortOnThis {
// CHECK-LABEL: ibis.container sym @GetPortOnThis {
// CHECK: %[[VAL_0:.*]] = ibis.this <@foo::@GetPortOnThis>
// CHECK: %[[VAL_1:.*]] = ibis.port.input "in" sym @in : i1
// CHECK: "foo.user"(%[[VAL_1]]) : (!ibis.portref<in i1>) -> ()
// CHECK: }
ibis.container @GetPortOnThis {
ibis.container sym @GetPortOnThis {
%this = ibis.this <@foo::@GetPortOnThis>
%p = ibis.port.input "in" sym @in : i1
%p2 = ibis.get_port %this, @in : !ibis.scoperef<@foo::@GetPortOnThis> -> !ibis.portref<in i1>
@ -20,16 +20,16 @@ ibis.container @GetPortOnThis {
ibis.design @foo {
ibis.container @C {
ibis.container sym @C {
%this = ibis.this <@foo::@C>
}
// CHECK-LABEL: ibis.container @AccessChild {
// CHECK-LABEL: ibis.container sym @AccessChild {
// CHECK: %[[VAL_0:.*]] = ibis.this <@foo::@AccessChild>
// CHECK: %[[VAL_1:.*]] = ibis.container.instance @c, <@foo::@C
// CHECK: "foo.user"(%[[VAL_1]]) : (!ibis.scoperef<@foo::@C>) -> ()
// CHECK: }
ibis.container @AccessChild {
ibis.container sym @AccessChild {
%this = ibis.this <@foo::@AccessChild>
%c = ibis.container.instance @c, <@foo::@C>
%c_ref = ibis.path [

View File

@ -1,7 +1,7 @@
// RUN: circt-opt --split-input-file --verify-diagnostics %s
ibis.design @foo {
ibis.class @C {
ibis.class sym @C {
%this = ibis.this <@foo::@C>
ibis.method @typeMismatch1() -> (ui32, i32) {
// expected-error @+1 {{'ibis.return' op must have the same number of operands as the method has results}}
@ -12,7 +12,7 @@ ibis.class @C {
// -----
ibis.design @foo {
ibis.class @C {
ibis.class sym @C {
%this = ibis.this <@foo::@C>
ibis.method @typeMismatch3() -> ui32 {
%c = hw.constant 1 : i8
@ -26,7 +26,7 @@ ibis.class @C {
ibis.design @foo {
// expected-error @+1 {{'ibis.class' op must contain only one 'ibis.this' operation}}
ibis.class @MultipleThis {
ibis.class sym @MultipleThis {
%this = ibis.this <@foo::@MultipleThis>
%this2 = ibis.this <@foo::@MultipleThis>
}
@ -36,14 +36,14 @@ ibis.class @MultipleThis {
ibis.design @foo {
// expected-error @+1 {{'ibis.container' op must contain a 'ibis.this' operation}}
ibis.container @NoThis {
ibis.container sym @NoThis {
}
}
// -----
ibis.design @foo {
ibis.class @PathStepParentWithInstanceName {
ibis.class sym @PathStepParentWithInstanceName {
%this = ibis.this <@foo::@PathStepParentWithInstanceName>
// expected-error @+1 {{ibis.step 'parent' may not specify an instance name}}
%p = ibis.path [#ibis.step<parent , @a : !ibis.scoperef>]
@ -53,7 +53,7 @@ ibis.class @PathStepParentWithInstanceName {
// -----
ibis.design @foo {
ibis.class @PathStepInvalidType {
ibis.class sym @PathStepInvalidType {
%this = ibis.this <@foo::@PathStepParentWithInstanceName>
// expected-error @+1 {{ibis.step type must be an !ibis.scoperef type}}
%p = ibis.path [#ibis.step<parent : i1>]
@ -63,7 +63,7 @@ ibis.class @PathStepInvalidType {
// -----
ibis.design @foo {
ibis.class @PathStepChildMissingSymbol {
ibis.class sym @PathStepChildMissingSymbol {
%this = ibis.this <@foo::@PathStepNonExistingChild>
// expected-error @+1 {{ibis.step 'child' must specify an instance name}}
%p = ibis.path [#ibis.step<child : !ibis.scoperef<@foo::@A>>]
@ -73,7 +73,7 @@ ibis.class @PathStepChildMissingSymbol {
// -----
ibis.design @foo {
ibis.class @InvalidVar {
ibis.class sym @InvalidVar {
%this = ibis.this <@foo::@C>
// expected-error @+1 {{'ibis.var' op attribute 'type' failed to satisfy constraint: any memref type}}
ibis.var @var : i32
@ -83,7 +83,7 @@ ibis.class @InvalidVar {
// -----
ibis.design @foo {
ibis.class @InvalidReturn {
ibis.class sym @InvalidReturn {
%this = ibis.this <@foo::@InvalidReturn>
ibis.method @foo() {
%c = hw.constant 1 : i32

View File

@ -1,7 +1,7 @@
// RUN: circt-opt --hw-verify-irn --split-input-file --verify-diagnostics %s
ibis.design @foo {
ibis.class @MissingPort {
ibis.class sym @MissingPort {
%this = ibis.this <@foo::@MissingPort>
// expected-error @+1 {{'ibis.get_port' op port '@C_in' does not exist in @MissingPort}}
%c_in = ibis.get_port %this, @C_in : !ibis.scoperef<@foo::@MissingPort> -> !ibis.portref<in i1>
@ -11,7 +11,7 @@ ibis.class @MissingPort {
// -----
ibis.design @foo {
ibis.class @InvalidGetVar2 {
ibis.class sym @InvalidGetVar2 {
%this = ibis.this <@foo::@InvalidGetVar2>
ibis.var @var : memref<i32>
ibis.method @foo() {
@ -28,7 +28,7 @@ ibis.class @InvalidGetVar2 {
// -----
ibis.design @foo {
ibis.class @InvalidGetVar {
ibis.class sym @InvalidGetVar {
%this = ibis.this <@foo::@InvalidGetVar>
ibis.var @var : memref<i32>
ibis.method @foo() {
@ -45,7 +45,7 @@ ibis.class @InvalidGetVar {
// -----
ibis.design @foo {
ibis.class @PortTypeMismatch {
ibis.class sym @PortTypeMismatch {
%this = ibis.this <@foo::@PortTypeMismatch>
ibis.port.input "in" sym @in : i1
// expected-error @+1 {{'ibis.get_port' op symbol '@in' refers to a port of type 'i1', but this op has type 'i2'}}
@ -56,7 +56,7 @@ ibis.class @PortTypeMismatch {
// -----
ibis.design @foo {
ibis.class @PathStepNonExistingChild {
ibis.class sym @PathStepNonExistingChild {
%this = ibis.this <@foo::@PathStepNonExistingChild>
// expected-error @+1 {{'ibis.path' op ibis.step scoperef symbol '@A' does not exist}}
%p = ibis.path [#ibis.step<child , @a : !ibis.scoperef<@foo::@A>>]
@ -66,7 +66,7 @@ ibis.class @PathStepNonExistingChild {
// -----
ibis.design @foo {
ibis.class @PathStepNonExistingParent {
ibis.class sym @PathStepNonExistingParent {
%this = ibis.this <@foo::@PathStepNonExistingParent>
// expected-error @+1 {{'ibis.path' op last ibis.step in path must specify a symbol for the scoperef}}
%p = ibis.path [#ibis.step<parent : !ibis.scoperef>]

View File

@ -2,7 +2,7 @@
ibis.design @foo {
// CHECK-LABEL: ibis.class @HighLevel {
// CHECK-LABEL: ibis.class sym @HighLevel {
// CHECK-NEXT: %this = ibis.this <@foo::@HighLevel>
// CHECK-NEXT: ibis.var @single : memref<i32>
// CHECK-NEXT: ibis.var @array : memref<10xi32>
@ -26,7 +26,7 @@ ibis.design @foo {
// CHECK-NEXT: }
ibis.class @HighLevel {
ibis.class sym @HighLevel {
%this = ibis.this <@foo::@HighLevel>
ibis.var @single : memref<i32>
ibis.var @array : memref<10xi32>
@ -54,14 +54,14 @@ ibis.class @HighLevel {
}
// CHECK-LABEL: ibis.class @A {
// CHECK-LABEL: ibis.class sym @A {
// CHECK-NEXT: %this = ibis.this <@foo::@A>
// CHECK-NEXT: %in = ibis.port.input "in" sym @in : i1
// CHECK-NEXT: %out = ibis.port.output "out" sym @out : i1
// CHECK-NEXT: %AnonymousPort = ibis.port.input sym @AnonymousPort : i1
// CHECK-NEXT: }
// CHECK-LABEL: ibis.class @LowLevel {
// CHECK-LABEL: ibis.class sym @LowLevel {
// CHECK-NEXT: %this = ibis.this <@foo::@LowLevel>
// CHECK-NEXT: %LowLevel_in = ibis.port.input "LowLevel_in" sym @LowLevel_in : i1
// CHECK-NEXT: %LowLevel_out = ibis.port.output "LowLevel_out" sym @LowLevel_out : i1
@ -69,7 +69,7 @@ ibis.class @HighLevel {
// CHECK-NEXT: %true = hw.constant true
// CHECK-NEXT: %out_wire = ibis.wire.output @out_wire, %true : i1
// CHECK-NEXT: %a = ibis.instance @a, <@foo::@A>
// CHECK-NEXT: ibis.container @D {
// CHECK-NEXT: ibis.container sym @D {
// CHECK-NEXT: %this_0 = ibis.this <@foo::@D>
// CHECK-NEXT: %parent = ibis.path [#ibis.step<parent : !ibis.scoperef<@foo::@LowLevel>> : !ibis.scoperef<@foo::@LowLevel>]
// CHECK-NEXT: %parent.LowLevel_in.ref = ibis.get_port %parent, @LowLevel_in : !ibis.scoperef<@foo::@LowLevel> -> !ibis.portref<in i1>
@ -84,16 +84,20 @@ ibis.class @HighLevel {
// CHECK-NEXT: %parent.a.out.ref.val = ibis.port.read %parent.a.out.ref : !ibis.portref<out i1>
// CHECK-NEXT: hw.instance "foo" @externModule() -> ()
// CHECK-NEXT: }
// CHECK-NEXT: ibis.container "ThisName" sym @ThisSymbol {
// CHECK-NEXT: %this_0 = ibis.this <@foo::@ThisSymbol>
// CHECK-NEXT: }
// CHECK-NEXT: }
ibis.class @A {
ibis.class sym @A {
%this = ibis.this <@foo::@A>
ibis.port.input "in" sym @in : i1
ibis.port.output "out" sym @out : i1
ibis.port.input sym @AnonymousPort : i1
}
ibis.class @LowLevel {
ibis.class sym @LowLevel {
%this = ibis.this <@foo::@LowLevel>
ibis.port.input "LowLevel_in" sym @LowLevel_in : i1
ibis.port.output "LowLevel_out" sym @LowLevel_out : i1
@ -105,7 +109,7 @@ ibis.class @LowLevel {
// Instantiation
%a = ibis.instance @a, <@foo::@A>
ibis.container @D {
ibis.container sym @D {
%this_d = ibis.this <@foo::@D>
%parent_C = ibis.path [
#ibis.step<parent : !ibis.scoperef<@foo::@LowLevel>>
@ -130,6 +134,10 @@ ibis.class @LowLevel {
// Test hw.instance ops inside a container (symbol table usage)
hw.instance "foo" @externModule() -> ()
}
ibis.container "ThisName" sym @ThisSymbol {
%this2 = ibis.this <@foo::@ThisSymbol>
}
}
}

View File

@ -1,6 +1,6 @@
// RUN: ibistool --hi --post-ibis-ir %s | FileCheck %s
// CHECK-LABEL: ibis.class @ToHandshake {
// CHECK-LABEL: ibis.class sym @ToHandshake {
// CHECK: %[[VAL_0:.*]] = ibis.this <@foo::@ToHandshake>
// CHECK: ibis.method @foo(%[[VAL_1:.*]]: i32, %[[VAL_2:.*]]: i32, %[[VAL_3:.*]]: i1) -> i32 {
// CHECK: %[[VAL_4:.*]]:3 = ibis.sblock.isolated () -> (i32, i32, i32) {
@ -47,7 +47,7 @@
// CHECK: }
ibis.design @foo {
ibis.class @ToHandshake {
ibis.class sym @ToHandshake {
%this = ibis.this <@foo::@ToHandshake>
ibis.method @foo(%a: i32, %b: i32, %c: i1) -> i32 {
%c2_i32 = arith.constant 2 : i32

View File

@ -56,7 +56,7 @@
// CHECK-VERILOG: endmodule
ibis.design @foo {
ibis.class @A {
ibis.class sym @A {
%this = ibis.this @A
ibis.port.input "in" sym @in : i1
ibis.port.output "out" sym @out : i1