mirror of https://github.com/llvm/circt.git
[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:
parent
e0f884a450
commit
0bf789e607
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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] =
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"() : () -> ()
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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}}
|
||||
|
|
|
@ -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 [
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>]
|
||||
|
|
|
@ -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>
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue