[Calyx] Replace calyx.program with module attribute calyx.entrypoint (#3580)

This commit is contained in:
Andrew Butt 2022-07-25 12:22:30 -04:00 committed by GitHub
parent c5b0a7c5d2
commit 6838ec2173
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
29 changed files with 894 additions and 1019 deletions

View File

@ -400,13 +400,13 @@ private:
/// An interface for conversion passes that lower Calyx programs. This handles
/// state during the lowering of a Calyx program.
class ProgramLoweringState {
class CalyxLoweringState {
public:
explicit ProgramLoweringState(calyx::ProgramOp program,
StringRef topLevelFunction);
explicit CalyxLoweringState(mlir::ModuleOp module,
StringRef topLevelFunction);
/// Returns the current program.
calyx::ProgramOp getProgram();
mlir::ModuleOp getModule();
/// Returns the name of the top-level function in the source program.
StringRef getTopLevelFunction() const;
@ -438,7 +438,7 @@ public:
std::string irName(ValueOrBlock &v) {
std::string s;
llvm::raw_string_ostream os(s);
mlir::AsmState asmState(program);
mlir::AsmState asmState(module);
v.printAsOperand(os, asmState);
return s;
}
@ -447,7 +447,7 @@ private:
/// The name of this top-level function.
StringRef topLevelFunction;
/// The program associated with this state.
calyx::ProgramOp program;
mlir::ModuleOp module;
/// Mapping from ComponentOp to component lowering state.
DenseMap<Operation *, std::unique_ptr<ComponentLoweringStateInterface>>
componentStates;
@ -481,14 +481,12 @@ private:
};
struct ModuleOpConversion : public OpRewritePattern<mlir::ModuleOp> {
ModuleOpConversion(MLIRContext *context, StringRef topLevelFunction,
calyx::ProgramOp *programOpOutput);
ModuleOpConversion(MLIRContext *context, StringRef topLevelFunction);
LogicalResult matchAndRewrite(mlir::ModuleOp moduleOp,
PatternRewriter &rewriter) const override;
private:
calyx::ProgramOp *programOpOutput;
StringRef topLevelFunction;
};
@ -501,7 +499,7 @@ public:
FuncOpPartialLoweringPattern(
MLIRContext *context, LogicalResult &resRef,
DenseMap<mlir::func::FuncOp, calyx::ComponentOp> &map,
calyx::ProgramLoweringState &state);
calyx::CalyxLoweringState &state);
/// Entry point to initialize the state of this class and conduct the partial
/// lowering.
@ -524,8 +522,8 @@ public:
return *static_cast<T *>(componentLoweringState);
}
/// Return the program lowering state for this pattern.
ProgramLoweringState &programState() const;
/// Return the calyx lowering state for this pattern.
CalyxLoweringState &loweringState() const;
/// Partial lowering implementation.
virtual LogicalResult
@ -539,7 +537,7 @@ protected:
private:
mutable ComponentOp componentOp;
mutable ComponentLoweringStateInterface *componentLoweringState = nullptr;
ProgramLoweringState &programLoweringState;
CalyxLoweringState &calyxLoweringState;
};
/// Converts all index-typed operations and values to i32 values.
@ -594,7 +592,7 @@ class InlineCombGroups
mlir::OpInterfaceRewritePattern> {
public:
InlineCombGroups(MLIRContext *context, LogicalResult &resRef,
calyx::ProgramLoweringState &pls);
calyx::CalyxLoweringState &pls);
LogicalResult partiallyLower(calyx::GroupInterface originGroup,
PatternRewriter &rewriter) const override;
@ -607,7 +605,7 @@ private:
calyx::GroupInterface originGroup,
calyx::GroupInterface recGroup, bool doInline) const;
calyx::ProgramLoweringState &pls;
calyx::CalyxLoweringState &cls;
};
/// This pass rewrites memory accesses that have a width mismatch. Such
@ -617,14 +615,14 @@ class RewriteMemoryAccesses
: public calyx::PartialLoweringPattern<calyx::AssignOp> {
public:
RewriteMemoryAccesses(MLIRContext *context, LogicalResult &resRef,
calyx::ProgramLoweringState &pls)
: PartialLoweringPattern(context, resRef), pls(pls) {}
calyx::CalyxLoweringState &cls)
: PartialLoweringPattern(context, resRef), cls(cls) {}
LogicalResult partiallyLower(calyx::AssignOp assignOp,
PatternRewriter &rewriter) const override;
private:
calyx::ProgramLoweringState &pls;
calyx::CalyxLoweringState &cls;
};
/// Builds registers for each block argument in the program.

View File

@ -14,6 +14,7 @@
#define CIRCT_DIALECT_CALYX_OPS_H
#include "circt/Dialect/Calyx/CalyxDialect.h"
#include "mlir/IR/BuiltinOps.h"
#include "mlir/IR/FunctionInterfaces.h"
#include "mlir/IR/OpImplementation.h"
#include "mlir/IR/RegionKindInterface.h"

View File

@ -29,35 +29,8 @@ def UndefinedOp : CalyxOp<"undef", [
let assemblyFormat = "attr-dict `:` qualified(type($res))";
}
def ProgramOp : CalyxContainer<"program", [
IsolatedFromAbove,
SymbolTable /* contains ComponentOp names. */
]> {
let summary = "Calyx Program";
let description = [{
The "calyx.program" operation represents an overall Calyx
program, containing a list of Calyx components. This must
include an entry-point component.
```mlir
calyx.program "main" { ... }
```
}];
let arguments = (ins StrAttr:$entryPointName);
let extraClassDeclaration = [{
/// Returns the entry-point component into the
/// Calyx program.
ComponentOp getEntryPointComponent() {
return lookupSymbol<ComponentOp>(entryPointName());
}
}];
let assemblyFormat = "$entryPointName $body attr-dict";
let hasVerifier = 1;
}
def ComponentOp : CalyxOp<"component", [
HasParent<"ProgramOp">,
HasParent<"mlir::ModuleOp">,
SymbolTable, /* contains Cell names. */
Symbol,
FunctionOpInterface,

View File

@ -35,19 +35,6 @@ using namespace circt::sv;
/// ConversionPatterns.
struct ConvertProgramOp : public OpConversionPattern<ProgramOp> {
using OpConversionPattern::OpConversionPattern;
LogicalResult
matchAndRewrite(ProgramOp program, OpAdaptor adaptor,
ConversionPatternRewriter &rewriter) const override {
ModuleOp mod = program->getParentOfType<ModuleOp>();
rewriter.inlineRegionBefore(program.body(), &mod.getBodyRegion().front());
rewriter.eraseBlock(&mod.getBodyRegion().back());
return success();
}
};
struct ConvertComponentOp : public OpConversionPattern<ComponentOp> {
using OpConversionPattern::OpConversionPattern;
@ -419,18 +406,17 @@ public:
void runOnOperation() override;
private:
LogicalResult runOnProgram(ProgramOp program);
LogicalResult runOnModule(ModuleOp module);
};
} // end anonymous namespace
void CalyxToHWPass::runOnOperation() {
ModuleOp mod = getOperation();
for (auto program : llvm::make_early_inc_range(mod.getOps<ProgramOp>()))
if (failed(runOnProgram(program)))
return signalPassFailure();
if (failed(runOnModule(mod)))
return signalPassFailure();
}
LogicalResult CalyxToHWPass::runOnProgram(ProgramOp program) {
LogicalResult CalyxToHWPass::runOnModule(ModuleOp module) {
MLIRContext &context = getContext();
ConversionTarget target(context);
@ -441,14 +427,13 @@ LogicalResult CalyxToHWPass::runOnProgram(ProgramOp program) {
target.addLegalDialect<SVDialect>();
RewritePatternSet patterns(&context);
patterns.add<ConvertProgramOp>(&context);
patterns.add<ConvertComponentOp>(&context);
patterns.add<ConvertWiresOp>(&context);
patterns.add<ConvertControlOp>(&context);
patterns.add<ConvertCellOp>(&context);
patterns.add<ConvertAssignOp>(&context);
return applyPartialConversion(program, target, std::move(patterns));
return applyPartialConversion(module, target, std::move(patterns));
}
std::unique_ptr<mlir::Pass> circt::createCalyxToHWPass() {

View File

@ -25,6 +25,7 @@
#include "mlir/Dialect/MemRef/IR/MemRef.h"
#include "mlir/IR/AsmState.h"
#include "mlir/IR/Matchers.h"
#include "mlir/Support/LogicalResult.h"
#include "mlir/Transforms/GreedyPatternRewriteDriver.h"
#include "llvm/ADT/TypeSwitch.h"
@ -227,7 +228,7 @@ private:
TGroupOp createGroupForOp(PatternRewriter &rewriter, Operation *op) const {
Block *block = op->getBlock();
auto groupName = getState<ComponentLoweringState>().getUniqueName(
programState().blockName(block));
loweringState().blockName(block));
return calyx::createGroup<TGroupOp>(
rewriter, getState<ComponentLoweringState>().getComponentOp(),
op->getLoc(), groupName);
@ -492,8 +493,8 @@ LogicalResult BuildOpGroups::buildOp(PatternRewriter &rewriter,
if (succOperands.empty())
continue;
// Create operand passing group
std::string groupName = programState().blockName(srcBlock) + "_to_" +
programState().blockName(succBlock.value());
std::string groupName = loweringState().blockName(srcBlock) + "_to_" +
loweringState().blockName(succBlock.value());
auto groupOp = calyx::createGroup<calyx::GroupOp>(rewriter, getComponent(),
brOp.getLoc(), groupName);
// Fetch block argument registers associated with the basic block
@ -772,7 +773,7 @@ struct FuncOpConversion : public calyx::FuncOpPartialLoweringPattern {
/// Store the function-to-component mapping.
functionMapping[funcOp] = compOp;
auto *compState = programState().getState<ComponentLoweringState>(compOp);
auto *compState = loweringState().getState<ComponentLoweringState>(compOp);
compState->setFuncOpResultMapping(funcOpResultMapping);
/// Rewrite funcOp SSA argument values to the CompOp arguments.
@ -843,8 +844,8 @@ class BuildWhileGroups : public calyx::FuncOpPartialLoweringPattern {
auto condOp = scfWhileOp.getConditionOp().getArgs()[barg.index()];
if (barg.value() != condOp) {
res = whileOp.getOperation()->emitError()
<< programState().irName(barg.value())
<< " != " << programState().irName(condOp)
<< loweringState().irName(barg.value())
<< " != " << loweringState().irName(condOp)
<< "do-while loops not supported; expected iter-args to "
"remain untransformed in the 'before' region of the "
"scf.while op.";
@ -1172,13 +1173,11 @@ public:
Strategy strategy;
};
//// Creates a new Calyx program with the contents of the source module
/// inlined within.
//// Labels the entry point of a Calyx program.
/// Furthermore, this function performs validation on the input function,
/// to ensure that we've implemented the capabilities necessary to convert
/// it.
LogicalResult createProgram(StringRef topLevelFunction,
calyx::ProgramOp *programOpOut) {
LogicalResult labelEntryPoint(StringRef topLevelFunction) {
// Program legalization - the partial conversion driver will not run
// unless some pattern is provided - provide a dummy pattern.
struct DummyPattern : public OpRewritePattern<mlir::ModuleOp> {
@ -1216,8 +1215,8 @@ public:
// Program conversion
RewritePatternSet conversionPatterns(&getContext());
conversionPatterns.add<calyx::ModuleOpConversion>(
&getContext(), topLevelFunction, programOpOut);
conversionPatterns.add<calyx::ModuleOpConversion>(&getContext(),
topLevelFunction);
return applyOpPatternsAndFold(getOperation(),
std::move(conversionPatterns));
}
@ -1266,7 +1265,7 @@ public:
private:
LogicalResult partialPatternRes;
std::shared_ptr<calyx::ProgramLoweringState> loweringState = nullptr;
std::shared_ptr<calyx::CalyxLoweringState> loweringState = nullptr;
};
void SCFToCalyxPass::runOnOperation() {
@ -1281,16 +1280,12 @@ void SCFToCalyxPass::runOnOperation() {
}
/// Start conversion
calyx::ProgramOp programOp;
if (failed(createProgram(topLevelFunction, &programOp))) {
if (failed(labelEntryPoint(topLevelFunction))) {
signalPassFailure();
return;
}
assert(programOp.getOperation() != nullptr &&
"programOp should have been set during module "
"conversion, if module conversion succeeded.");
loweringState = std::make_shared<calyx::ProgramLoweringState>(
programOp, topLevelFunction);
loweringState = std::make_shared<calyx::CalyxLoweringState>(getOperation(),
topLevelFunction);
/// --------------------------------------------------------------------------
/// If you are a developer, it may be helpful to add a

View File

@ -325,7 +325,7 @@ private:
TGroupOp createGroupForOp(PatternRewriter &rewriter, Operation *op) const {
Block *block = op->getBlock();
auto groupName = getState<ComponentLoweringState>().getUniqueName(
programState().blockName(block));
loweringState().blockName(block));
return calyx::createGroup<TGroupOp>(
rewriter, getState<ComponentLoweringState>().getComponentOp(),
op->getLoc(), groupName);
@ -564,8 +564,8 @@ LogicalResult BuildOpGroups::buildOp(PatternRewriter &rewriter,
if (succOperands.empty())
continue;
// Create operand passing group
std::string groupName = programState().blockName(srcBlock) + "_to_" +
programState().blockName(succBlock.value());
std::string groupName = loweringState().blockName(srcBlock) + "_to_" +
loweringState().blockName(succBlock.value());
auto groupOp = calyx::createGroup<calyx::GroupOp>(rewriter, getComponent(),
brOp.getLoc(), groupName);
// Fetch block argument registers associated with the basic block
@ -787,7 +787,7 @@ struct FuncOpConversion : public calyx::FuncOpPartialLoweringPattern {
/// Store the function-to-component mapping.
functionMapping[funcOp] = compOp;
auto *compState = programState().getState<ComponentLoweringState>(compOp);
auto *compState = loweringState().getState<ComponentLoweringState>(compOp);
compState->setFuncOpResultMapping(funcOpResultMapping);
/// Rewrite funcOp SSA argument values to the CompOp arguments.
@ -1396,13 +1396,11 @@ public:
Strategy strategy;
};
//// Creates a new Calyx program with the contents of the source module
/// inlined within.
//// Labels the entry point of a Calyx program.
/// Furthermore, this function performs validation on the input function,
/// to ensure that we've implemented the capabilities necessary to convert
/// it.
LogicalResult createProgram(StringRef topLevelFunction,
calyx::ProgramOp *programOpOut) {
LogicalResult labelEntryPoint(StringRef topLevelFunction) {
// Program legalization - the partial conversion driver will not run
// unless some pattern is provided - provide a dummy pattern.
struct DummyPattern : public OpRewritePattern<mlir::ModuleOp> {
@ -1415,15 +1413,20 @@ public:
ConversionTarget target(getContext());
target.addLegalDialect<calyx::CalyxDialect>();
target.addLegalDialect<scf::SCFDialect>();
target.addIllegalDialect<hw::HWDialect>();
target.addIllegalDialect<comb::CombDialect>();
// Only accept std operations which we've added lowerings for.
// For loops should have been lowered to while loops
target.addIllegalOp<scf::ForOp>();
// Only accept std operations which we've added lowerings for
target.addIllegalDialect<FuncDialect>();
target.addIllegalDialect<ArithmeticDialect>();
target.addLegalOp<AddIOp, SubIOp, CmpIOp, ShLIOp, ShRUIOp, ShRSIOp, AndIOp,
XOrIOp, OrIOp, ExtUIOp, TruncIOp, CondBranchOp, BranchOp,
MulIOp, DivUIOp, RemUIOp, ReturnOp, arith::ConstantOp,
IndexCastOp, FuncOp>();
MulIOp, DivUIOp, DivSIOp, RemUIOp, RemSIOp, ReturnOp,
arith::ConstantOp, IndexCastOp, FuncOp, ExtSIOp>();
RewritePatternSet legalizePatterns(&getContext());
legalizePatterns.add<DummyPattern>(&getContext());
@ -1435,8 +1438,8 @@ public:
// Program conversion
RewritePatternSet conversionPatterns(&getContext());
conversionPatterns.add<calyx::ModuleOpConversion>(
&getContext(), topLevelFunction, programOpOut);
conversionPatterns.add<calyx::ModuleOpConversion>(&getContext(),
topLevelFunction);
return applyOpPatternsAndFold(getOperation(),
std::move(conversionPatterns));
}
@ -1485,7 +1488,7 @@ public:
private:
LogicalResult partialPatternRes;
std::shared_ptr<calyx::ProgramLoweringState> loweringState = nullptr;
std::shared_ptr<calyx::CalyxLoweringState> loweringState = nullptr;
};
void StaticLogicToCalyxPass::runOnOperation() {
@ -1500,16 +1503,12 @@ void StaticLogicToCalyxPass::runOnOperation() {
}
/// Start conversion
calyx::ProgramOp programOp;
if (failed(createProgram(topLevelFunction, &programOp))) {
if (failed(labelEntryPoint(topLevelFunction))) {
signalPassFailure();
return;
}
assert(programOp.getOperation() != nullptr &&
"programOp should have been set during module "
"conversion, if module conversion succeeded.");
loweringState = std::make_shared<calyx::ProgramLoweringState>(
programOp, topLevelFunction);
loweringState = std::make_shared<calyx::CalyxLoweringState>(getOperation(),
topLevelFunction);
/// --------------------------------------------------------------------------
/// If you are a developer, it may be helpful to add a

View File

@ -314,18 +314,6 @@ static void eraseControlWithGroupAndConditional(OpTy op,
rewriter.eraseOp(cond.getDefiningOp());
}
//===----------------------------------------------------------------------===//
// ProgramOp
//===----------------------------------------------------------------------===//
LogicalResult ProgramOp::verify() {
if (getEntryPointComponent() == nullptr)
return emitOpError() << "has undefined entry-point component: \""
<< entryPointName() << "\".";
return success();
}
//===----------------------------------------------------------------------===//
// ComponentOp
//===----------------------------------------------------------------------===//
@ -1187,11 +1175,11 @@ void AssignOp::print(OpAsmPrinter &p) {
/// Lookup the component for the symbol. This returns null on
/// invalid IR.
ComponentOp InstanceOp::getReferencedComponent() {
auto program = (*this)->getParentOfType<ProgramOp>();
if (!program)
auto module = (*this)->getParentOfType<ModuleOp>();
if (!module)
return nullptr;
return program.lookupSymbol<ComponentOp>(componentName());
return module.lookupSymbol<ComponentOp>(componentName());
}
/// Verifies the port information in comparison with the referenced component
@ -1199,8 +1187,9 @@ ComponentOp InstanceOp::getReferencedComponent() {
/// referenced component twice.
static LogicalResult verifyInstanceOpType(InstanceOp instance,
ComponentOp referencedComponent) {
auto program = instance->getParentOfType<ProgramOp>();
StringRef entryPointName = program.entryPointName();
auto module = instance->getParentOfType<ModuleOp>();
StringRef entryPointName =
module->getAttrOfType<StringAttr>("calyx.entrypoint");
if (instance.componentName() == entryPointName)
return instance.emitOpError()
<< "cannot reference the entry-point component: '" << entryPointName
@ -1230,15 +1219,15 @@ static LogicalResult verifyInstanceOpType(InstanceOp instance,
LogicalResult InstanceOp::verifySymbolUses(SymbolTableCollection &symbolTable) {
Operation *op = *this;
auto program = op->getParentOfType<ProgramOp>();
auto module = op->getParentOfType<ModuleOp>();
Operation *referencedComponent =
symbolTable.lookupNearestSymbolFrom(program, componentNameAttr());
symbolTable.lookupNearestSymbolFrom(module, componentNameAttr());
if (referencedComponent == nullptr)
return emitError() << "referencing component: '" << componentName()
<< "', which does not exist.";
Operation *shadowedComponentName =
symbolTable.lookupNearestSymbolFrom(program, sym_nameAttr());
symbolTable.lookupNearestSymbolFrom(module, sym_nameAttr());
if (shadowedComponentName != nullptr)
return emitError() << "instance symbol: '" << instanceName()
<< "' is already a symbol for another component.";

View File

@ -88,8 +88,8 @@ struct ImportTracker {
public:
/// Returns the list of library names used for in this program.
/// E.g. if `primitives/core.futil` is used, returns { "core" }.
FailureOr<llvm::SmallSet<StringRef, 4>> getLibraryNames(ProgramOp program) {
auto walkRes = program.walk([&](ComponentOp component) {
FailureOr<llvm::SmallSet<StringRef, 4>> getLibraryNames(ModuleOp module) {
auto walkRes = module.walk([&](ComponentOp component) {
for (auto &op : *component.getBody()) {
if (!isa<CellInterface>(op) || isa<InstanceOp>(op))
// It is not a primitive.
@ -156,8 +156,8 @@ struct Emitter {
currentIndent -= 2;
}
// Program emission
void emitProgram(ProgramOp op);
// Module emission
void emitModule(ModuleOp op);
// Metadata emission for the Cider debugger.
void emitCiderMetadata(mlir::ModuleOp op) {
@ -178,7 +178,7 @@ struct Emitter {
}
/// Import emission.
LogicalResult emitImports(ProgramOp op) {
LogicalResult emitImports(ModuleOp op) {
auto emitImport = [&](StringRef library) {
// Libraries share a common relative path:
// primitives/<library-name>.futil
@ -505,7 +505,7 @@ private:
LogicalResult Emitter::finalize() { return failure(encounteredError); }
/// Emit an entire program.
void Emitter::emitProgram(ProgramOp op) {
void Emitter::emitModule(ModuleOp op) {
for (auto &bodyOp : *op.getBody()) {
if (auto componentOp = dyn_cast<ComponentOp>(bodyOp))
emitComponent(componentOp);
@ -726,16 +726,9 @@ void Emitter::emitControl(ControlOp control) {
mlir::LogicalResult circt::calyx::exportCalyx(mlir::ModuleOp module,
llvm::raw_ostream &os) {
Emitter emitter(os);
for (auto &op : *module.getBody()) {
auto walkRes = op.walk([&](ProgramOp program) {
if (failed(emitter.emitImports(program)))
return WalkResult::interrupt();
emitter.emitProgram(program);
return WalkResult::advance();
});
if (walkRes.wasInterrupted())
return failure();
}
if (failed(emitter.emitImports(module)))
return failure();
emitter.emitModule(module);
emitter.emitCiderMetadata(module);
return emitter.finalize();
}

View File

@ -320,23 +320,23 @@ unsigned ComponentLoweringStateInterface::getFuncOpResultMapping(
}
//===----------------------------------------------------------------------===//
// ProgramLoweringState
// CalyxLoweringState
//===----------------------------------------------------------------------===//
ProgramLoweringState::ProgramLoweringState(calyx::ProgramOp program,
StringRef topLevelFunction)
: topLevelFunction(topLevelFunction), program(program) {}
CalyxLoweringState::CalyxLoweringState(mlir::ModuleOp module,
StringRef topLevelFunction)
: topLevelFunction(topLevelFunction), module(module) {}
calyx::ProgramOp ProgramLoweringState::getProgram() {
assert(program.getOperation() != nullptr);
return program;
mlir::ModuleOp CalyxLoweringState::getModule() {
assert(module.getOperation() != nullptr);
return module;
}
StringRef ProgramLoweringState::getTopLevelFunction() const {
StringRef CalyxLoweringState::getTopLevelFunction() const {
return topLevelFunction;
}
std::string ProgramLoweringState::blockName(Block *b) {
std::string CalyxLoweringState::blockName(Block *b) {
std::string blockName = irName(*b);
blockName.erase(std::remove(blockName.begin(), blockName.end(), '^'),
blockName.end());
@ -348,38 +348,18 @@ std::string ProgramLoweringState::blockName(Block *b) {
//===----------------------------------------------------------------------===//
ModuleOpConversion::ModuleOpConversion(MLIRContext *context,
StringRef topLevelFunction,
calyx::ProgramOp *programOpOutput)
StringRef topLevelFunction)
: OpRewritePattern<mlir::ModuleOp>(context),
programOpOutput(programOpOutput), topLevelFunction(topLevelFunction) {
assert(programOpOutput->getOperation() == nullptr &&
"this function will set programOpOutput post module conversion");
}
topLevelFunction(topLevelFunction) {}
LogicalResult
ModuleOpConversion::matchAndRewrite(mlir::ModuleOp moduleOp,
PatternRewriter &rewriter) const {
if (!moduleOp.getOps<calyx::ProgramOp>().empty())
if (moduleOp->hasAttr("calyx.entrypoint"))
return failure();
rewriter.updateRootInPlace(moduleOp, [&] {
// Create ProgramOp
rewriter.setInsertionPointAfter(moduleOp);
auto programOp = rewriter.create<calyx::ProgramOp>(
moduleOp.getLoc(), StringAttr::get(getContext(), topLevelFunction));
// Inline the module body region
rewriter.inlineRegionBefore(moduleOp.getBodyRegion(),
programOp.getBodyRegion(),
programOp.getBodyRegion().end());
// Inlining the body region also removes ^bb0 from the module body
// region, so recreate that, before finally inserting the programOp
auto *moduleBlock = rewriter.createBlock(&moduleOp.getBodyRegion());
rewriter.setInsertionPointToStart(moduleBlock);
rewriter.insert(programOp);
*programOpOutput = programOp;
});
moduleOp->setAttr("calyx.entrypoint",
rewriter.getStringAttr(topLevelFunction));
return success();
}
@ -390,9 +370,9 @@ ModuleOpConversion::matchAndRewrite(mlir::ModuleOp moduleOp,
FuncOpPartialLoweringPattern::FuncOpPartialLoweringPattern(
MLIRContext *context, LogicalResult &resRef,
DenseMap<mlir::func::FuncOp, calyx::ComponentOp> &map,
calyx::ProgramLoweringState &state)
calyx::CalyxLoweringState &state)
: PartialLoweringPattern(context, resRef), functionMapping(map),
programLoweringState(state) {}
calyxLoweringState(state) {}
LogicalResult
FuncOpPartialLoweringPattern::partiallyLower(mlir::func::FuncOp funcOp,
@ -402,7 +382,7 @@ FuncOpPartialLoweringPattern::partiallyLower(mlir::func::FuncOp funcOp,
if (auto it = functionMapping.find(funcOp); it != functionMapping.end()) {
componentOp = it->second;
componentLoweringState =
programLoweringState.getState<ComponentLoweringStateInterface>(
calyxLoweringState.getState<ComponentLoweringStateInterface>(
componentOp);
}
@ -415,8 +395,8 @@ calyx::ComponentOp FuncOpPartialLoweringPattern::getComponent() const {
return componentOp;
}
ProgramLoweringState &FuncOpPartialLoweringPattern::programState() const {
return programLoweringState;
CalyxLoweringState &FuncOpPartialLoweringPattern::loweringState() const {
return calyxLoweringState;
}
//===----------------------------------------------------------------------===//
@ -520,14 +500,14 @@ EliminateUnusedCombGroups::matchAndRewrite(calyx::CombGroupOp combGroupOp,
//===----------------------------------------------------------------------===//
InlineCombGroups::InlineCombGroups(MLIRContext *context, LogicalResult &resRef,
calyx::ProgramLoweringState &pls)
: PartialLoweringPattern(context, resRef), pls(pls) {}
calyx::CalyxLoweringState &cls)
: PartialLoweringPattern(context, resRef), cls(cls) {}
LogicalResult
InlineCombGroups::partiallyLower(calyx::GroupInterface originGroup,
PatternRewriter &rewriter) const {
auto component = originGroup->getParentOfType<calyx::ComponentOp>();
ComponentLoweringStateInterface *state = pls.getState(component);
ComponentLoweringStateInterface *state = cls.getState(component);
// Filter groups which are not part of the control schedule.
if (SymbolTable::symbolKnownUseEmpty(originGroup.symName(),
@ -599,7 +579,7 @@ void InlineCombGroups::recurseInlineCombGroups(
LogicalResult
RewriteMemoryAccesses::partiallyLower(calyx::AssignOp assignOp,
PatternRewriter &rewriter) const {
auto *state = pls.getState(assignOp->getParentOfType<calyx::ComponentOp>());
auto *state = cls.getState(assignOp->getParentOfType<calyx::ComponentOp>());
Value dest = assignOp.dest();
if (!state->isInputPortOfMemory(dest).hasValue())
@ -650,7 +630,7 @@ BuildBasicBlockRegs::partiallyLowerFuncToComp(mlir::func::FuncOp funcOp,
assert(argType.isa<IntegerType>() && "unsupported block argument type");
unsigned width = argType.getIntOrFloatBitWidth();
std::string index = std::to_string(arg.index());
std::string name = programState().blockName(block) + "_arg" + index;
std::string name = loweringState().blockName(block) + "_arg" + index;
auto reg = createRegister(arg.value().getLoc(), rewriter, getComponent(),
width, name);
getState().addBlockArgReg(block, reg, arg.index());

View File

@ -1,4 +1,4 @@
// RUN: circt-opt --split-input-file -pass-pipeline='calyx.program(calyx.component(lower-calyx-to-fsm))' %s | FileCheck %s
// RUN: circt-opt --split-input-file -pass-pipeline='calyx.component(lower-calyx-to-fsm)' %s | FileCheck %s
// CHECK: fsm.machine @control() attributes {compiledGroups = [@true, @false, @cond], initialState = "fsm_entry"} {
// CHECK-NEXT: fsm.state @fsm_entry output {
@ -52,48 +52,46 @@
// CHECK-NEXT: }
// CHECK-NEXT: }
calyx.program "main" {
calyx.component @main(%go: i1 {go}, %reset: i1 {reset}, %clk: i1 {clk}) -> (%done: i1 {done}) {
%false = hw.constant false
%true = hw.constant true
%lt_reg.in, %lt_reg.write_en, %lt_reg.clk, %lt_reg.reset, %lt_reg.out, %lt_reg.done = calyx.register @lt_reg : i1, i1, i1, i1, i1, i1
%t.in, %t.write_en, %t.clk, %t.reset, %t.out, %t.done = calyx.register @t : i1, i1, i1, i1, i1, i1
%f.in, %f.write_en, %f.clk, %f.reset, %f.out, %f.done = calyx.register @f : i1, i1, i1, i1, i1, i1
%lt.left, %lt.right, %lt.out = calyx.std_lt @lt : i1, i1, i1
calyx.wires {
%0 = calyx.undef : i1
calyx.group @true {
%true.go = calyx.group_go %0 : i1
calyx.assign %t.in = %true.go ? %true : i1
calyx.assign %t.write_en = %true.go ? %true : i1
calyx.group_done %t.done : i1
}
calyx.group @false {
%false.go = calyx.group_go %0 : i1
calyx.assign %f.in = %false.go ? %true : i1
calyx.assign %f.write_en = %false.go ? %true : i1
calyx.group_done %f.done : i1
}
calyx.group @cond {
%cond.go = calyx.group_go %0 : i1
calyx.assign %lt_reg.in = %cond.go ? %lt.out : i1
calyx.assign %lt_reg.write_en = %cond.go ? %true : i1
calyx.assign %lt.left = %cond.go ? %true : i1
calyx.assign %lt.right = %cond.go ? %false : i1
calyx.group_done %lt_reg.done ? %true : i1
}
calyx.component @main(%go: i1 {go}, %reset: i1 {reset}, %clk: i1 {clk}) -> (%done: i1 {done}) {
%false = hw.constant false
%true = hw.constant true
%lt_reg.in, %lt_reg.write_en, %lt_reg.clk, %lt_reg.reset, %lt_reg.out, %lt_reg.done = calyx.register @lt_reg : i1, i1, i1, i1, i1, i1
%t.in, %t.write_en, %t.clk, %t.reset, %t.out, %t.done = calyx.register @t : i1, i1, i1, i1, i1, i1
%f.in, %f.write_en, %f.clk, %f.reset, %f.out, %f.done = calyx.register @f : i1, i1, i1, i1, i1, i1
%lt.left, %lt.right, %lt.out = calyx.std_lt @lt : i1, i1, i1
calyx.wires {
%0 = calyx.undef : i1
calyx.group @true {
%true.go = calyx.group_go %0 : i1
calyx.assign %t.in = %true.go ? %true : i1
calyx.assign %t.write_en = %true.go ? %true : i1
calyx.group_done %t.done : i1
}
calyx.control {
calyx.seq {
calyx.enable @cond
calyx.if %lt_reg.out {
calyx.seq {
calyx.enable @true
}
} else {
calyx.seq {
calyx.enable @false
}
calyx.group @false {
%false.go = calyx.group_go %0 : i1
calyx.assign %f.in = %false.go ? %true : i1
calyx.assign %f.write_en = %false.go ? %true : i1
calyx.group_done %f.done : i1
}
calyx.group @cond {
%cond.go = calyx.group_go %0 : i1
calyx.assign %lt_reg.in = %cond.go ? %lt.out : i1
calyx.assign %lt_reg.write_en = %cond.go ? %true : i1
calyx.assign %lt.left = %cond.go ? %true : i1
calyx.assign %lt.right = %cond.go ? %false : i1
calyx.group_done %lt_reg.done ? %true : i1
}
}
calyx.control {
calyx.seq {
calyx.enable @cond
calyx.if %lt_reg.out {
calyx.seq {
calyx.enable @true
}
} else {
calyx.seq {
calyx.enable @false
}
}
}

View File

@ -1,4 +1,4 @@
// RUN: circt-opt --split-input-file -pass-pipeline='calyx.program(calyx.component(lower-calyx-to-fsm))' %s | FileCheck %s
// RUN: circt-opt --split-input-file -pass-pipeline='calyx.component(lower-calyx-to-fsm)' %s | FileCheck %s
// CHECK: fsm.machine @control() attributes {compiledGroups = [@C, @B, @A], initialState = "fsm_entry"} {
// CHECK-NEXT: fsm.state @fsm_entry output {
@ -31,42 +31,40 @@
// CHECK-NEXT: }
calyx.program "main" {
calyx.component @main(%go: i1 {go}, %reset: i1 {reset}, %clk: i1 {clk}) -> (%done: i1 {done}) {
%c2_i8 = hw.constant 2 : i8
%c1_i8 = hw.constant 1 : i8
%c0_i8 = hw.constant 0 : i8
%true = hw.constant true
%a.in, %a.write_en, %a.clk, %a.reset, %a.out, %a.done = calyx.register @a : i8, i1, i1, i1, i8, i1
%b.in, %b.write_en, %b.clk, %b.reset, %b.out, %b.done = calyx.register @b : i8, i1, i1, i1, i8, i1
%c.in, %c.write_en, %c.clk, %c.reset, %c.out, %c.done = calyx.register @c : i8, i1, i1, i1, i8, i1
calyx.wires {
%0 = calyx.undef : i1
calyx.group @A {
%A.go = calyx.group_go %0 : i1
calyx.assign %a.in = %A.go ? %c0_i8 : i8
calyx.assign %a.write_en = %A.go ? %true : i1
calyx.group_done %a.done : i1
}
calyx.group @B {
%B.go = calyx.group_go %0 : i1
calyx.assign %b.in = %B.go ? %c1_i8 : i8
calyx.assign %b.write_en = %B.go ? %true : i1
calyx.group_done %b.done : i1
}
calyx.group @C {
%C.go = calyx.group_go %0 : i1
calyx.assign %c.in = %C.go ? %c2_i8 : i8
calyx.assign %c.write_en = %C.go ? %true : i1
calyx.group_done %c.done : i1
}
calyx.component @main(%go: i1 {go}, %reset: i1 {reset}, %clk: i1 {clk}) -> (%done: i1 {done}) {
%c2_i8 = hw.constant 2 : i8
%c1_i8 = hw.constant 1 : i8
%c0_i8 = hw.constant 0 : i8
%true = hw.constant true
%a.in, %a.write_en, %a.clk, %a.reset, %a.out, %a.done = calyx.register @a : i8, i1, i1, i1, i8, i1
%b.in, %b.write_en, %b.clk, %b.reset, %b.out, %b.done = calyx.register @b : i8, i1, i1, i1, i8, i1
%c.in, %c.write_en, %c.clk, %c.reset, %c.out, %c.done = calyx.register @c : i8, i1, i1, i1, i8, i1
calyx.wires {
%0 = calyx.undef : i1
calyx.group @A {
%A.go = calyx.group_go %0 : i1
calyx.assign %a.in = %A.go ? %c0_i8 : i8
calyx.assign %a.write_en = %A.go ? %true : i1
calyx.group_done %a.done : i1
}
calyx.control {
calyx.seq {
calyx.enable @A
calyx.enable @B
calyx.enable @C
}
calyx.group @B {
%B.go = calyx.group_go %0 : i1
calyx.assign %b.in = %B.go ? %c1_i8 : i8
calyx.assign %b.write_en = %B.go ? %true : i1
calyx.group_done %b.done : i1
}
calyx.group @C {
%C.go = calyx.group_go %0 : i1
calyx.assign %c.in = %C.go ? %c2_i8 : i8
calyx.assign %c.write_en = %C.go ? %true : i1
calyx.group_done %c.done : i1
}
}
calyx.control {
calyx.seq {
calyx.enable @A
calyx.enable @B
calyx.enable @C
}
}
}

View File

@ -1,4 +1,4 @@
// RUN: circt-opt --split-input-file -pass-pipeline='calyx.program(calyx.component(lower-calyx-to-fsm))' %s | FileCheck %s
// RUN: circt-opt --split-input-file -pass-pipeline='calyx.component(lower-calyx-to-fsm)' %s | FileCheck %s
// CHECK: fsm.machine @control() attributes {compiledGroups = [@do_add, @do_add, @do_add, @cond], initialState = "fsm_entry"} {
// CHECK-NEXT: fsm.state @fsm_entry output {
@ -70,48 +70,46 @@
// CHECK-NEXT: }
// CHECK-NEXT: }
calyx.program "main" {
calyx.component @main(%go: i1 {go}, %reset: i1 {reset}, %clk: i1 {clk}) -> (%done: i1 {done}) {
%true = hw.constant true
%c1_i32 = hw.constant 1 : i32
%c5_i32 = hw.constant 5 : i32
%c4_i32 = hw.constant 4 : i32
%lt_reg.in, %lt_reg.write_en, %lt_reg.clk, %lt_reg.reset, %lt_reg.out, %lt_reg.done = calyx.register @lt_reg : i1, i1, i1, i1, i1, i1
%r.in, %r.write_en, %r.clk, %r.reset, %r.out, %r.done = calyx.register @r : i32, i1, i1, i1, i32, i1
%add.left, %add.right, %add.out = calyx.std_add @add : i32, i32, i32
%lt.left, %lt.right, %lt.out = calyx.std_lt @lt : i32, i32, i1
calyx.wires {
%0 = calyx.undef : i1
calyx.group @do_add {
%do_add.go = calyx.group_go %0 : i1
calyx.assign %add.right = %do_add.go ? %c4_i32 : i32
calyx.assign %add.left = %do_add.go ? %c4_i32 : i32
calyx.assign %r.in = %do_add.go ? %add.out : i32
calyx.assign %r.write_en = %do_add.go ? %true : i1
calyx.group_done %r.done : i1
}
calyx.group @cond {
%cond.go = calyx.group_go %0 : i1
calyx.assign %lt_reg.in = %cond.go ? %lt.out : i1
calyx.assign %lt_reg.write_en = %cond.go ? %true : i1
calyx.assign %lt.right = %cond.go ? %c5_i32 : i32
calyx.assign %lt.left = %cond.go ? %c1_i32 : i32
calyx.group_done %lt_reg.done ? %true : i1
}
calyx.component @main(%go: i1 {go}, %reset: i1 {reset}, %clk: i1 {clk}) -> (%done: i1 {done}) {
%true = hw.constant true
%c1_i32 = hw.constant 1 : i32
%c5_i32 = hw.constant 5 : i32
%c4_i32 = hw.constant 4 : i32
%lt_reg.in, %lt_reg.write_en, %lt_reg.clk, %lt_reg.reset, %lt_reg.out, %lt_reg.done = calyx.register @lt_reg : i1, i1, i1, i1, i1, i1
%r.in, %r.write_en, %r.clk, %r.reset, %r.out, %r.done = calyx.register @r : i32, i1, i1, i1, i32, i1
%add.left, %add.right, %add.out = calyx.std_add @add : i32, i32, i32
%lt.left, %lt.right, %lt.out = calyx.std_lt @lt : i32, i32, i1
calyx.wires {
%0 = calyx.undef : i1
calyx.group @do_add {
%do_add.go = calyx.group_go %0 : i1
calyx.assign %add.right = %do_add.go ? %c4_i32 : i32
calyx.assign %add.left = %do_add.go ? %c4_i32 : i32
calyx.assign %r.in = %do_add.go ? %add.out : i32
calyx.assign %r.write_en = %do_add.go ? %true : i1
calyx.group_done %r.done : i1
}
calyx.control {
calyx.seq {
calyx.enable @cond
calyx.while %lt_reg.out {
calyx.if %lt_reg.out {
calyx.seq {
calyx.enable @do_add
calyx.enable @do_add
}
} else {
calyx.seq {
calyx.enable @do_add
}
calyx.group @cond {
%cond.go = calyx.group_go %0 : i1
calyx.assign %lt_reg.in = %cond.go ? %lt.out : i1
calyx.assign %lt_reg.write_en = %cond.go ? %true : i1
calyx.assign %lt.right = %cond.go ? %c5_i32 : i32
calyx.assign %lt.left = %cond.go ? %c1_i32 : i32
calyx.group_done %lt_reg.done ? %true : i1
}
}
calyx.control {
calyx.seq {
calyx.enable @cond
calyx.while %lt_reg.out {
calyx.if %lt_reg.out {
calyx.seq {
calyx.enable @do_add
calyx.enable @do_add
}
} else {
calyx.seq {
calyx.enable @do_add
}
}
}

View File

@ -28,7 +28,7 @@
//
// futil -p pre-opt -p compile -p post-opt -p lower -p lower-guards -b mlir
calyx.program "main" {
// module attributes {calyx.entrypoint = "main"} {
calyx.component @main(%a: i32, %b: i32, %go: i1 {go = 1 : i64}, %clk: i1 {clk = 1 : i64}, %reset: i1 {reset = 1 : i64}) -> (%out: i32, %done: i1 {done = 1 : i64}) {
// CHECK-DAG: %add_left = sv.wire
// CHECK-DAG: %[[ADD_LEFT_VAL:.+]] = sv.read_inout %add_left
@ -131,4 +131,4 @@ calyx.program "main" {
calyx.control {
}
}
}
// }

View File

@ -18,7 +18,7 @@
// CHECK: sv.assign %done, %true : i1
// CHECK: hw.output %0, %1 : i8, i1
// CHECK: }
calyx.program "main" {
module attributes {calyx.entrypoint = "main"} {
calyx.component @main(%in0: i4, %clk: i1 {clk}, %reset: i1 {reset}, %go: i1 {go}) -> (%out0: i8, %done: i1 {done}) {
%true = hw.constant true
%std_pad.in, %std_pad.out = calyx.std_pad @std_pad : i4, i8
@ -52,7 +52,7 @@ calyx.program "main" {
// CHECK: sv.assign %done, %true : i1
// CHECK: hw.output %0, %1 : i8, i1
calyx.program "main" {
module attributes {calyx.entrypoint = "main"} {
calyx.component @main(%in0: i4, %clk: i1 {clk}, %reset: i1 {reset}, %go: i1 {go}) -> (%out0: i8, %done: i1 {done}) {
%true = hw.constant true
%std_extsi.in, %std_extsi.out = calyx.std_extsi @std_extsi : i4, i8

View File

@ -1,7 +1,7 @@
// RUN: circt-opt %s --lower-scf-to-calyx='cider-source-location-metadata' -canonicalize | FileCheck %s
module {
// CHECK: module attributes {calyx.metadata = ["loc({{.*}}11:5)", "loc({{.*}}13:5)"]}
// CHECK: module attributes {calyx.entrypoint = "main", calyx.metadata = ["loc({{.*}}11:5)", "loc({{.*}}13:5)"]}
func.func @main(%a0 : i32, %a1 : i32, %a2 : i32) -> i32 {
%0 = arith.addi %a0, %a1 : i32
%1 = arith.addi %0, %a1 : i32

View File

@ -1,50 +1,48 @@
// RUN: circt-opt %s --lower-scf-to-calyx -canonicalize -split-input-file | FileCheck %s
// CHECK: module {
// CHECK-NEXT: calyx.program "main" {
// CHECK-NEXT: calyx.component @main(%in0: i32, %in1: i32, %clk: i1 {clk}, %reset: i1 {reset}, %go: i1 {go}) -> (%out0: i32, %done: i1 {done}) {
// CHECK-DAG: %true = hw.constant true
// CHECK-DAG: %std_slt_0.left, %std_slt_0.right, %std_slt_0.out = calyx.std_slt @std_slt_0 : i32, i32, i1
// CHECK-DAG: %ret_arg0_reg.in, %ret_arg0_reg.write_en, %ret_arg0_reg.clk, %ret_arg0_reg.reset, %ret_arg0_reg.out, %ret_arg0_reg.done = calyx.register @ret_arg0_reg : i32, i1, i1, i1, i32, i1
// CHECK-DAG: %bb3_arg0_reg.in, %bb3_arg0_reg.write_en, %bb3_arg0_reg.clk, %bb3_arg0_reg.reset, %bb3_arg0_reg.out, %bb3_arg0_reg.done = calyx.register @bb3_arg0_reg : i32, i1, i1, i1, i32, i1
// CHECK-NEXT: calyx.wires {
// CHECK-NEXT: calyx.assign %out0 = %ret_arg0_reg.out : i32
// CHECK-NEXT: calyx.comb_group @bb0_0 {
// CHECK-NEXT: calyx.assign %std_slt_0.left = %in0 : i32
// CHECK-NEXT: calyx.assign %std_slt_0.right = %in1 : i32
// CHECK-NEXT: }
// CHECK-NEXT: calyx.group @bb1_to_bb3 {
// CHECK-NEXT: calyx.assign %bb3_arg0_reg.in = %in0 : i32
// CHECK-NEXT: calyx.assign %bb3_arg0_reg.write_en = %true : i1
// CHECK-NEXT: calyx.group_done %bb3_arg0_reg.done : i1
// CHECK-NEXT: }
// CHECK-NEXT: calyx.group @bb2_to_bb3 {
// CHECK-NEXT: calyx.assign %bb3_arg0_reg.in = %in1 : i32
// CHECK-NEXT: calyx.assign %bb3_arg0_reg.write_en = %true : i1
// CHECK-NEXT: calyx.group_done %bb3_arg0_reg.done : i1
// CHECK-NEXT: }
// CHECK-NEXT: calyx.group @ret_assign_0 {
// CHECK-NEXT: calyx.assign %ret_arg0_reg.in = %bb3_arg0_reg.out : i32
// CHECK-NEXT: calyx.assign %ret_arg0_reg.write_en = %true : i1
// CHECK-NEXT: calyx.group_done %ret_arg0_reg.done : i1
// CHECK-NEXT: }
// CHECK: module attributes {calyx.entrypoint = "main"} {
// CHECK-NEXT: calyx.component @main(%in0: i32, %in1: i32, %clk: i1 {clk}, %reset: i1 {reset}, %go: i1 {go}) -> (%out0: i32, %done: i1 {done}) {
// CHECK-DAG: %true = hw.constant true
// CHECK-DAG: %std_slt_0.left, %std_slt_0.right, %std_slt_0.out = calyx.std_slt @std_slt_0 : i32, i32, i1
// CHECK-DAG: %ret_arg0_reg.in, %ret_arg0_reg.write_en, %ret_arg0_reg.clk, %ret_arg0_reg.reset, %ret_arg0_reg.out, %ret_arg0_reg.done = calyx.register @ret_arg0_reg : i32, i1, i1, i1, i32, i1
// CHECK-DAG: %bb3_arg0_reg.in, %bb3_arg0_reg.write_en, %bb3_arg0_reg.clk, %bb3_arg0_reg.reset, %bb3_arg0_reg.out, %bb3_arg0_reg.done = calyx.register @bb3_arg0_reg : i32, i1, i1, i1, i32, i1
// CHECK-NEXT: calyx.wires {
// CHECK-NEXT: calyx.assign %out0 = %ret_arg0_reg.out : i32
// CHECK-NEXT: calyx.comb_group @bb0_0 {
// CHECK-NEXT: calyx.assign %std_slt_0.left = %in0 : i32
// CHECK-NEXT: calyx.assign %std_slt_0.right = %in1 : i32
// CHECK-NEXT: }
// CHECK-NEXT: calyx.control {
// CHECK-NEXT: calyx.seq {
// CHECK-NEXT: calyx.if %std_slt_0.out with @bb0_0 {
// CHECK-NEXT: calyx.seq {
// CHECK-NEXT: calyx.enable @bb1_to_bb3
// CHECK-NEXT: }
// CHECK-NEXT: } else {
// CHECK-NEXT: calyx.seq {
// CHECK-NEXT: calyx.enable @bb2_to_bb3
// CHECK-NEXT: }
// CHECK-NEXT: calyx.group @bb1_to_bb3 {
// CHECK-NEXT: calyx.assign %bb3_arg0_reg.in = %in0 : i32
// CHECK-NEXT: calyx.assign %bb3_arg0_reg.write_en = %true : i1
// CHECK-NEXT: calyx.group_done %bb3_arg0_reg.done : i1
// CHECK-NEXT: }
// CHECK-NEXT: calyx.group @bb2_to_bb3 {
// CHECK-NEXT: calyx.assign %bb3_arg0_reg.in = %in1 : i32
// CHECK-NEXT: calyx.assign %bb3_arg0_reg.write_en = %true : i1
// CHECK-NEXT: calyx.group_done %bb3_arg0_reg.done : i1
// CHECK-NEXT: }
// CHECK-NEXT: calyx.group @ret_assign_0 {
// CHECK-NEXT: calyx.assign %ret_arg0_reg.in = %bb3_arg0_reg.out : i32
// CHECK-NEXT: calyx.assign %ret_arg0_reg.write_en = %true : i1
// CHECK-NEXT: calyx.group_done %ret_arg0_reg.done : i1
// CHECK-NEXT: }
// CHECK-NEXT: }
// CHECK-NEXT: calyx.control {
// CHECK-NEXT: calyx.seq {
// CHECK-NEXT: calyx.if %std_slt_0.out with @bb0_0 {
// CHECK-NEXT: calyx.seq {
// CHECK-NEXT: calyx.enable @bb1_to_bb3
// CHECK-NEXT: }
// CHECK-NEXT: } else {
// CHECK-NEXT: calyx.seq {
// CHECK-NEXT: calyx.enable @bb2_to_bb3
// CHECK-NEXT: }
// CHECK-NEXT: calyx.enable @ret_assign_0
// CHECK-NEXT: }
// CHECK-NEXT: calyx.enable @ret_assign_0
// CHECK-NEXT: }
// CHECK-NEXT: } {toplevel}
// CHECK-NEXT: }
// CHECK-NEXT: }
// CHECK-NEXT: } {toplevel}
// CHECK-NEXT: }
module {
func.func @main(%arg0 : i32, %arg1 : i32) -> i32 {
@ -63,111 +61,109 @@ module {
// Test a while op where the loop body contains basic blocks that may be simplified.
// CHECK: module {
// CHECK-NEXT: calyx.program "main" {
// CHECK-LABEL: calyx.component @main(%in0: i32, %in1: i32, %in2: i32, %clk: i1 {clk}, %reset: i1 {reset}, %go: i1 {go}) -> (%out0: i32, %done: i1 {done}) {
// CHECK-DAG: %true = hw.constant true
// CHECK-DAG: %c0_i32 = hw.constant 0 : i32
// CHECK-DAG: %std_add_2.left, %std_add_2.right, %std_add_2.out = calyx.std_add @std_add_2 : i32, i32, i32
// CHECK-DAG: %std_add_1.left, %std_add_1.right, %std_add_1.out = calyx.std_add @std_add_1 : i32, i32, i32
// CHECK-DAG: %std_add_0.left, %std_add_0.right, %std_add_0.out = calyx.std_add @std_add_0 : i32, i32, i32
// CHECK-DAG: %std_slt_1.left, %std_slt_1.right, %std_slt_1.out = calyx.std_slt @std_slt_1 : i32, i32, i1
// CHECK-DAG: %std_slt_0.left, %std_slt_0.right, %std_slt_0.out = calyx.std_slt @std_slt_0 : i32, i32, i1
// CHECK-DAG: %while_0_arg2_reg.in, %while_0_arg2_reg.write_en, %while_0_arg2_reg.clk, %while_0_arg2_reg.reset, %while_0_arg2_reg.out, %while_0_arg2_reg.done = calyx.register @while_0_arg2_reg : i32, i1, i1, i1, i32, i1
// CHECK-DAG: %while_0_arg1_reg.in, %while_0_arg1_reg.write_en, %while_0_arg1_reg.clk, %while_0_arg1_reg.reset, %while_0_arg1_reg.out, %while_0_arg1_reg.done = calyx.register @while_0_arg1_reg : i32, i1, i1, i1, i32, i1
// CHECK-DAG: %while_0_arg0_reg.in, %while_0_arg0_reg.write_en, %while_0_arg0_reg.clk, %while_0_arg0_reg.reset, %while_0_arg0_reg.out, %while_0_arg0_reg.done = calyx.register @while_0_arg0_reg : i32, i1, i1, i1, i32, i1
// CHECK-DAG: %ret_arg0_reg.in, %ret_arg0_reg.write_en, %ret_arg0_reg.clk, %ret_arg0_reg.reset, %ret_arg0_reg.out, %ret_arg0_reg.done = calyx.register @ret_arg0_reg : i32, i1, i1, i1, i32, i1
// CHECK-DAG: %bb3_arg1_reg.in, %bb3_arg1_reg.write_en, %bb3_arg1_reg.clk, %bb3_arg1_reg.reset, %bb3_arg1_reg.out, %bb3_arg1_reg.done = calyx.register @bb3_arg1_reg : i32, i1, i1, i1, i32, i1
// CHECK-DAG: %bb3_arg0_reg.in, %bb3_arg0_reg.write_en, %bb3_arg0_reg.clk, %bb3_arg0_reg.reset, %bb3_arg0_reg.out, %bb3_arg0_reg.done = calyx.register @bb3_arg0_reg : i32, i1, i1, i1, i32, i1
// CHECK-NEXT: calyx.wires {
// CHECK-NEXT: calyx.assign %out0 = %ret_arg0_reg.out : i32
// CHECK-NEXT: calyx.group @assign_while_0_init_0 {
// CHECK-NEXT: calyx.assign %while_0_arg0_reg.in = %in0 : i32
// CHECK-NEXT: calyx.assign %while_0_arg0_reg.write_en = %true : i1
// CHECK-NEXT: calyx.group_done %while_0_arg0_reg.done : i1
// CHECK-NEXT: }
// CHECK-NEXT: calyx.group @assign_while_0_init_1 {
// CHECK-NEXT: calyx.assign %while_0_arg1_reg.in = %c0_i32 : i32
// CHECK-NEXT: calyx.assign %while_0_arg1_reg.write_en = %true : i1
// CHECK-NEXT: calyx.group_done %while_0_arg1_reg.done : i1
// CHECK-NEXT: }
// CHECK-NEXT: calyx.group @assign_while_0_init_2 {
// CHECK-NEXT: calyx.assign %while_0_arg2_reg.in = %c0_i32 : i32
// CHECK-NEXT: calyx.assign %while_0_arg2_reg.write_en = %true : i1
// CHECK-NEXT: calyx.group_done %while_0_arg2_reg.done : i1
// CHECK-NEXT: }
// CHECK-NEXT: calyx.comb_group @bb0_0 {
// CHECK-NEXT: calyx.assign %std_slt_0.left = %while_0_arg0_reg.out : i32
// CHECK-NEXT: calyx.assign %std_slt_0.right = %in1 : i32
// CHECK-NEXT: }
// CHECK-NEXT: calyx.comb_group @bb0_1 {
// CHECK-NEXT: calyx.assign %std_slt_1.left = %while_0_arg1_reg.out : i32
// CHECK-NEXT: calyx.assign %std_slt_1.right = %while_0_arg2_reg.out : i32
// CHECK-NEXT: }
// CHECK-NEXT: calyx.group @bb1_to_bb3 {
// CHECK-NEXT: calyx.assign %bb3_arg0_reg.in = %std_add_0.out : i32
// CHECK-NEXT: calyx.assign %bb3_arg0_reg.write_en = %true : i1
// CHECK-NEXT: calyx.assign %bb3_arg1_reg.in = %std_add_0.out : i32
// CHECK-NEXT: calyx.assign %bb3_arg1_reg.write_en = %true : i1
// CHECK-NEXT: calyx.assign %std_add_0.left = %while_0_arg1_reg.out : i32
// CHECK-NEXT: calyx.assign %std_add_0.right = %while_0_arg2_reg.out : i32
// CHECK-NEXT: %0 = comb.and %bb3_arg0_reg.done, %bb3_arg1_reg.done : i1
// CHECK-NEXT: calyx.group_done %0 ? %true : i1
// CHECK-NEXT: }
// CHECK-NEXT: calyx.group @bb2_to_bb3 {
// CHECK-NEXT: calyx.assign %bb3_arg0_reg.in = %std_add_1.out : i32
// CHECK-NEXT: calyx.assign %bb3_arg0_reg.write_en = %true : i1
// CHECK-NEXT: calyx.assign %bb3_arg1_reg.in = %std_add_1.out : i32
// CHECK-NEXT: calyx.assign %bb3_arg1_reg.write_en = %true : i1
// CHECK-NEXT: calyx.assign %std_add_1.left = %while_0_arg1_reg.out : i32
// CHECK-NEXT: calyx.assign %std_add_1.right = %while_0_arg2_reg.out : i32
// CHECK-NEXT: %0 = comb.and %bb3_arg0_reg.done, %bb3_arg1_reg.done : i1
// CHECK-NEXT: calyx.group_done %0 ? %true : i1
// CHECK-NEXT: }
// CHECK-NEXT: calyx.group @assign_while_0_latch {
// CHECK-NEXT: calyx.assign %while_0_arg0_reg.in = %std_add_2.out : i32
// CHECK-NEXT: calyx.assign %while_0_arg0_reg.write_en = %true : i1
// CHECK-NEXT: calyx.assign %while_0_arg1_reg.in = %bb3_arg0_reg.out : i32
// CHECK-NEXT: calyx.assign %while_0_arg1_reg.write_en = %true : i1
// CHECK-NEXT: calyx.assign %while_0_arg2_reg.in = %bb3_arg1_reg.out : i32
// CHECK-NEXT: calyx.assign %while_0_arg2_reg.write_en = %true : i1
// CHECK-NEXT: calyx.assign %std_add_2.left = %while_0_arg0_reg.out : i32
// CHECK-NEXT: calyx.assign %std_add_2.right = %in2 : i32
// CHECK-NEXT: %0 = comb.and %while_0_arg0_reg.done, %while_0_arg1_reg.done, %while_0_arg2_reg.done : i1
// CHECK-NEXT: calyx.group_done %0 ? %true : i1
// CHECK-NEXT: }
// CHECK-NEXT: calyx.group @ret_assign_0 {
// CHECK-NEXT: calyx.assign %ret_arg0_reg.in = %while_0_arg2_reg.out : i32
// CHECK-NEXT: calyx.assign %ret_arg0_reg.write_en = %true : i1
// CHECK-NEXT: calyx.group_done %ret_arg0_reg.done : i1
// CHECK-NEXT: }
// CHECK: module attributes {calyx.entrypoint = "main"} {
// CHECK-LABEL: calyx.component @main(%in0: i32, %in1: i32, %in2: i32, %clk: i1 {clk}, %reset: i1 {reset}, %go: i1 {go}) -> (%out0: i32, %done: i1 {done}) {
// CHECK-DAG: %true = hw.constant true
// CHECK-DAG: %c0_i32 = hw.constant 0 : i32
// CHECK-DAG: %std_add_2.left, %std_add_2.right, %std_add_2.out = calyx.std_add @std_add_2 : i32, i32, i32
// CHECK-DAG: %std_add_1.left, %std_add_1.right, %std_add_1.out = calyx.std_add @std_add_1 : i32, i32, i32
// CHECK-DAG: %std_add_0.left, %std_add_0.right, %std_add_0.out = calyx.std_add @std_add_0 : i32, i32, i32
// CHECK-DAG: %std_slt_1.left, %std_slt_1.right, %std_slt_1.out = calyx.std_slt @std_slt_1 : i32, i32, i1
// CHECK-DAG: %std_slt_0.left, %std_slt_0.right, %std_slt_0.out = calyx.std_slt @std_slt_0 : i32, i32, i1
// CHECK-DAG: %while_0_arg2_reg.in, %while_0_arg2_reg.write_en, %while_0_arg2_reg.clk, %while_0_arg2_reg.reset, %while_0_arg2_reg.out, %while_0_arg2_reg.done = calyx.register @while_0_arg2_reg : i32, i1, i1, i1, i32, i1
// CHECK-DAG: %while_0_arg1_reg.in, %while_0_arg1_reg.write_en, %while_0_arg1_reg.clk, %while_0_arg1_reg.reset, %while_0_arg1_reg.out, %while_0_arg1_reg.done = calyx.register @while_0_arg1_reg : i32, i1, i1, i1, i32, i1
// CHECK-DAG: %while_0_arg0_reg.in, %while_0_arg0_reg.write_en, %while_0_arg0_reg.clk, %while_0_arg0_reg.reset, %while_0_arg0_reg.out, %while_0_arg0_reg.done = calyx.register @while_0_arg0_reg : i32, i1, i1, i1, i32, i1
// CHECK-DAG: %ret_arg0_reg.in, %ret_arg0_reg.write_en, %ret_arg0_reg.clk, %ret_arg0_reg.reset, %ret_arg0_reg.out, %ret_arg0_reg.done = calyx.register @ret_arg0_reg : i32, i1, i1, i1, i32, i1
// CHECK-DAG: %bb3_arg1_reg.in, %bb3_arg1_reg.write_en, %bb3_arg1_reg.clk, %bb3_arg1_reg.reset, %bb3_arg1_reg.out, %bb3_arg1_reg.done = calyx.register @bb3_arg1_reg : i32, i1, i1, i1, i32, i1
// CHECK-DAG: %bb3_arg0_reg.in, %bb3_arg0_reg.write_en, %bb3_arg0_reg.clk, %bb3_arg0_reg.reset, %bb3_arg0_reg.out, %bb3_arg0_reg.done = calyx.register @bb3_arg0_reg : i32, i1, i1, i1, i32, i1
// CHECK-NEXT: calyx.wires {
// CHECK-NEXT: calyx.assign %out0 = %ret_arg0_reg.out : i32
// CHECK-NEXT: calyx.group @assign_while_0_init_0 {
// CHECK-NEXT: calyx.assign %while_0_arg0_reg.in = %in0 : i32
// CHECK-NEXT: calyx.assign %while_0_arg0_reg.write_en = %true : i1
// CHECK-NEXT: calyx.group_done %while_0_arg0_reg.done : i1
// CHECK-NEXT: }
// CHECK-NEXT: calyx.control {
// CHECK-NEXT: calyx.seq {
// CHECK-NEXT: calyx.par {
// CHECK-NEXT: calyx.enable @assign_while_0_init_0
// CHECK-NEXT: calyx.enable @assign_while_0_init_1
// CHECK-NEXT: calyx.enable @assign_while_0_init_2
// CHECK-NEXT: }
// CHECK-NEXT: calyx.while %std_slt_0.out with @bb0_0 {
// CHECK-NEXT: calyx.seq {
// CHECK-NEXT: calyx.if %std_slt_1.out with @bb0_1 {
// CHECK-NEXT: calyx.seq {
// CHECK-NEXT: calyx.enable @bb1_to_bb3
// CHECK-NEXT: }
// CHECK-NEXT: } else {
// CHECK-NEXT: calyx.seq {
// CHECK-NEXT: calyx.enable @bb2_to_bb3
// CHECK-NEXT: }
// CHECK-NEXT: calyx.group @assign_while_0_init_1 {
// CHECK-NEXT: calyx.assign %while_0_arg1_reg.in = %c0_i32 : i32
// CHECK-NEXT: calyx.assign %while_0_arg1_reg.write_en = %true : i1
// CHECK-NEXT: calyx.group_done %while_0_arg1_reg.done : i1
// CHECK-NEXT: }
// CHECK-NEXT: calyx.group @assign_while_0_init_2 {
// CHECK-NEXT: calyx.assign %while_0_arg2_reg.in = %c0_i32 : i32
// CHECK-NEXT: calyx.assign %while_0_arg2_reg.write_en = %true : i1
// CHECK-NEXT: calyx.group_done %while_0_arg2_reg.done : i1
// CHECK-NEXT: }
// CHECK-NEXT: calyx.comb_group @bb0_0 {
// CHECK-NEXT: calyx.assign %std_slt_0.left = %while_0_arg0_reg.out : i32
// CHECK-NEXT: calyx.assign %std_slt_0.right = %in1 : i32
// CHECK-NEXT: }
// CHECK-NEXT: calyx.comb_group @bb0_1 {
// CHECK-NEXT: calyx.assign %std_slt_1.left = %while_0_arg1_reg.out : i32
// CHECK-NEXT: calyx.assign %std_slt_1.right = %while_0_arg2_reg.out : i32
// CHECK-NEXT: }
// CHECK-NEXT: calyx.group @bb1_to_bb3 {
// CHECK-NEXT: calyx.assign %bb3_arg0_reg.in = %std_add_0.out : i32
// CHECK-NEXT: calyx.assign %bb3_arg0_reg.write_en = %true : i1
// CHECK-NEXT: calyx.assign %bb3_arg1_reg.in = %std_add_0.out : i32
// CHECK-NEXT: calyx.assign %bb3_arg1_reg.write_en = %true : i1
// CHECK-NEXT: calyx.assign %std_add_0.left = %while_0_arg1_reg.out : i32
// CHECK-NEXT: calyx.assign %std_add_0.right = %while_0_arg2_reg.out : i32
// CHECK-NEXT: %0 = comb.and %bb3_arg0_reg.done, %bb3_arg1_reg.done : i1
// CHECK-NEXT: calyx.group_done %0 ? %true : i1
// CHECK-NEXT: }
// CHECK-NEXT: calyx.group @bb2_to_bb3 {
// CHECK-NEXT: calyx.assign %bb3_arg0_reg.in = %std_add_1.out : i32
// CHECK-NEXT: calyx.assign %bb3_arg0_reg.write_en = %true : i1
// CHECK-NEXT: calyx.assign %bb3_arg1_reg.in = %std_add_1.out : i32
// CHECK-NEXT: calyx.assign %bb3_arg1_reg.write_en = %true : i1
// CHECK-NEXT: calyx.assign %std_add_1.left = %while_0_arg1_reg.out : i32
// CHECK-NEXT: calyx.assign %std_add_1.right = %while_0_arg2_reg.out : i32
// CHECK-NEXT: %0 = comb.and %bb3_arg0_reg.done, %bb3_arg1_reg.done : i1
// CHECK-NEXT: calyx.group_done %0 ? %true : i1
// CHECK-NEXT: }
// CHECK-NEXT: calyx.group @assign_while_0_latch {
// CHECK-NEXT: calyx.assign %while_0_arg0_reg.in = %std_add_2.out : i32
// CHECK-NEXT: calyx.assign %while_0_arg0_reg.write_en = %true : i1
// CHECK-NEXT: calyx.assign %while_0_arg1_reg.in = %bb3_arg0_reg.out : i32
// CHECK-NEXT: calyx.assign %while_0_arg1_reg.write_en = %true : i1
// CHECK-NEXT: calyx.assign %while_0_arg2_reg.in = %bb3_arg1_reg.out : i32
// CHECK-NEXT: calyx.assign %while_0_arg2_reg.write_en = %true : i1
// CHECK-NEXT: calyx.assign %std_add_2.left = %while_0_arg0_reg.out : i32
// CHECK-NEXT: calyx.assign %std_add_2.right = %in2 : i32
// CHECK-NEXT: %0 = comb.and %while_0_arg0_reg.done, %while_0_arg1_reg.done, %while_0_arg2_reg.done : i1
// CHECK-NEXT: calyx.group_done %0 ? %true : i1
// CHECK-NEXT: }
// CHECK-NEXT: calyx.group @ret_assign_0 {
// CHECK-NEXT: calyx.assign %ret_arg0_reg.in = %while_0_arg2_reg.out : i32
// CHECK-NEXT: calyx.assign %ret_arg0_reg.write_en = %true : i1
// CHECK-NEXT: calyx.group_done %ret_arg0_reg.done : i1
// CHECK-NEXT: }
// CHECK-NEXT: }
// CHECK-NEXT: calyx.control {
// CHECK-NEXT: calyx.seq {
// CHECK-NEXT: calyx.par {
// CHECK-NEXT: calyx.enable @assign_while_0_init_0
// CHECK-NEXT: calyx.enable @assign_while_0_init_1
// CHECK-NEXT: calyx.enable @assign_while_0_init_2
// CHECK-NEXT: }
// CHECK-NEXT: calyx.while %std_slt_0.out with @bb0_0 {
// CHECK-NEXT: calyx.seq {
// CHECK-NEXT: calyx.if %std_slt_1.out with @bb0_1 {
// CHECK-NEXT: calyx.seq {
// CHECK-NEXT: calyx.enable @bb1_to_bb3
// CHECK-NEXT: }
// CHECK-NEXT: } else {
// CHECK-NEXT: calyx.seq {
// CHECK-NEXT: calyx.enable @bb2_to_bb3
// CHECK-NEXT: }
// CHECK-NEXT: calyx.enable @assign_while_0_latch
// CHECK-NEXT: }
// CHECK-NEXT: calyx.enable @assign_while_0_latch
// CHECK-NEXT: }
// CHECK-NEXT: calyx.enable @ret_assign_0
// CHECK-NEXT: }
// CHECK-NEXT: calyx.enable @ret_assign_0
// CHECK-NEXT: }
// CHECK-NEXT: } {toplevel}
// CHECK-NEXT: }
// CHECK-NEXT: }
// CHECK-NEXT: } {toplevel}
// CHECK-NEXT: }
module {
func.func @main(%arg0: i32, %arg1: i32, %arg2: i32) -> i32 {
@ -198,111 +194,109 @@ module {
// Test an executeRegion with multiple yields.
// CHECK: module {
// CHECK-NEXT: calyx.program "main" {
// CHECK-LABEL: calyx.component @main(%in0: i32, %in1: i32, %in2: i32, %clk: i1 {clk}, %reset: i1 {reset}, %go: i1 {go}) -> (%out0: i32, %done: i1 {done}) {
// CHECK-DAG: %true = hw.constant true
// CHECK-DAG: %c0_i32 = hw.constant 0 : i32
// CHECK-DAG: %std_add_1.left, %std_add_1.right, %std_add_1.out = calyx.std_add @std_add_1 : i32, i32, i32
// CHECK-DAG: %std_sub_0.left, %std_sub_0.right, %std_sub_0.out = calyx.std_sub @std_sub_0 : i32, i32, i32
// CHECK-DAG: %std_add_0.left, %std_add_0.right, %std_add_0.out = calyx.std_add @std_add_0 : i32, i32, i32
// CHECK-DAG: %std_slt_1.left, %std_slt_1.right, %std_slt_1.out = calyx.std_slt @std_slt_1 : i32, i32, i1
// CHECK-DAG: %std_slt_0.left, %std_slt_0.right, %std_slt_0.out = calyx.std_slt @std_slt_0 : i32, i32, i1
// CHECK-DAG: %while_0_arg2_reg.in, %while_0_arg2_reg.write_en, %while_0_arg2_reg.clk, %while_0_arg2_reg.reset, %while_0_arg2_reg.out, %while_0_arg2_reg.done = calyx.register @while_0_arg2_reg : i32, i1, i1, i1, i32, i1
// CHECK-DAG: %while_0_arg1_reg.in, %while_0_arg1_reg.write_en, %while_0_arg1_reg.clk, %while_0_arg1_reg.reset, %while_0_arg1_reg.out, %while_0_arg1_reg.done = calyx.register @while_0_arg1_reg : i32, i1, i1, i1, i32, i1
// CHECK-DAG: %while_0_arg0_reg.in, %while_0_arg0_reg.write_en, %while_0_arg0_reg.clk, %while_0_arg0_reg.reset, %while_0_arg0_reg.out, %while_0_arg0_reg.done = calyx.register @while_0_arg0_reg : i32, i1, i1, i1, i32, i1
// CHECK-DAG: %ret_arg0_reg.in, %ret_arg0_reg.write_en, %ret_arg0_reg.clk, %ret_arg0_reg.reset, %ret_arg0_reg.out, %ret_arg0_reg.done = calyx.register @ret_arg0_reg : i32, i1, i1, i1, i32, i1
// CHECK-DAG: %bb3_arg1_reg.in, %bb3_arg1_reg.write_en, %bb3_arg1_reg.clk, %bb3_arg1_reg.reset, %bb3_arg1_reg.out, %bb3_arg1_reg.done = calyx.register @bb3_arg1_reg : i32, i1, i1, i1, i32, i1
// CHECK-DAG: %bb3_arg0_reg.in, %bb3_arg0_reg.write_en, %bb3_arg0_reg.clk, %bb3_arg0_reg.reset, %bb3_arg0_reg.out, %bb3_arg0_reg.done = calyx.register @bb3_arg0_reg : i32, i1, i1, i1, i32, i1
// CHECK-NEXT: calyx.wires {
// CHECK-NEXT: calyx.assign %out0 = %ret_arg0_reg.out : i32
// CHECK-NEXT: calyx.group @assign_while_0_init_0 {
// CHECK-NEXT: calyx.assign %while_0_arg0_reg.in = %in0 : i32
// CHECK-NEXT: calyx.assign %while_0_arg0_reg.write_en = %true : i1
// CHECK-NEXT: calyx.group_done %while_0_arg0_reg.done : i1
// CHECK-NEXT: }
// CHECK-NEXT: calyx.group @assign_while_0_init_1 {
// CHECK-NEXT: calyx.assign %while_0_arg1_reg.in = %c0_i32 : i32
// CHECK-NEXT: calyx.assign %while_0_arg1_reg.write_en = %true : i1
// CHECK-NEXT: calyx.group_done %while_0_arg1_reg.done : i1
// CHECK-NEXT: }
// CHECK-NEXT: calyx.group @assign_while_0_init_2 {
// CHECK-NEXT: calyx.assign %while_0_arg2_reg.in = %c0_i32 : i32
// CHECK-NEXT: calyx.assign %while_0_arg2_reg.write_en = %true : i1
// CHECK-NEXT: calyx.group_done %while_0_arg2_reg.done : i1
// CHECK-NEXT: }
// CHECK-NEXT: calyx.comb_group @bb0_0 {
// CHECK-NEXT: calyx.assign %std_slt_0.left = %while_0_arg0_reg.out : i32
// CHECK-NEXT: calyx.assign %std_slt_0.right = %in1 : i32
// CHECK-NEXT: }
// CHECK-NEXT: calyx.comb_group @bb0_1 {
// CHECK-NEXT: calyx.assign %std_slt_1.left = %while_0_arg1_reg.out : i32
// CHECK-NEXT: calyx.assign %std_slt_1.right = %while_0_arg2_reg.out : i32
// CHECK-NEXT: }
// CHECK-NEXT: calyx.group @bb1_to_bb3 {
// CHECK-NEXT: calyx.assign %bb3_arg0_reg.in = %std_add_0.out : i32
// CHECK-NEXT: calyx.assign %bb3_arg0_reg.write_en = %true : i1
// CHECK-NEXT: calyx.assign %bb3_arg1_reg.in = %std_add_0.out : i32
// CHECK-NEXT: calyx.assign %bb3_arg1_reg.write_en = %true : i1
// CHECK-NEXT: calyx.assign %std_add_0.left = %while_0_arg1_reg.out : i32
// CHECK-NEXT: calyx.assign %std_add_0.right = %while_0_arg2_reg.out : i32
// CHECK-NEXT: %0 = comb.and %bb3_arg0_reg.done, %bb3_arg1_reg.done : i1
// CHECK-NEXT: calyx.group_done %0 ? %true : i1
// CHECK-NEXT: }
// CHECK-NEXT: calyx.group @bb2_to_bb3 {
// CHECK-NEXT: calyx.assign %bb3_arg0_reg.in = %std_sub_0.out : i32
// CHECK-NEXT: calyx.assign %bb3_arg0_reg.write_en = %true : i1
// CHECK-NEXT: calyx.assign %bb3_arg1_reg.in = %std_sub_0.out : i32
// CHECK-NEXT: calyx.assign %bb3_arg1_reg.write_en = %true : i1
// CHECK-NEXT: calyx.assign %std_sub_0.left = %while_0_arg1_reg.out : i32
// CHECK-NEXT: calyx.assign %std_sub_0.right = %while_0_arg2_reg.out : i32
// CHECK-NEXT: %0 = comb.and %bb3_arg0_reg.done, %bb3_arg1_reg.done : i1
// CHECK-NEXT: calyx.group_done %0 ? %true : i1
// CHECK-NEXT: }
// CHECK-NEXT: calyx.group @assign_while_0_latch {
// CHECK-NEXT: calyx.assign %while_0_arg0_reg.in = %std_add_1.out : i32
// CHECK-NEXT: calyx.assign %while_0_arg0_reg.write_en = %true : i1
// CHECK-NEXT: calyx.assign %while_0_arg1_reg.in = %bb3_arg0_reg.out : i32
// CHECK-NEXT: calyx.assign %while_0_arg1_reg.write_en = %true : i1
// CHECK-NEXT: calyx.assign %while_0_arg2_reg.in = %bb3_arg1_reg.out : i32
// CHECK-NEXT: calyx.assign %while_0_arg2_reg.write_en = %true : i1
// CHECK-NEXT: calyx.assign %std_add_1.left = %while_0_arg0_reg.out : i32
// CHECK-NEXT: calyx.assign %std_add_1.right = %in2 : i32
// CHECK-NEXT: %0 = comb.and %while_0_arg0_reg.done, %while_0_arg1_reg.done, %while_0_arg2_reg.done : i1
// CHECK-NEXT: calyx.group_done %0 ? %true : i1
// CHECK-NEXT: }
// CHECK-NEXT: calyx.group @ret_assign_0 {
// CHECK-NEXT: calyx.assign %ret_arg0_reg.in = %while_0_arg2_reg.out : i32
// CHECK-NEXT: calyx.assign %ret_arg0_reg.write_en = %true : i1
// CHECK-NEXT: calyx.group_done %ret_arg0_reg.done : i1
// CHECK-NEXT: }
// CHECK: module attributes {calyx.entrypoint = "main"} {
// CHECK-LABEL: calyx.component @main(%in0: i32, %in1: i32, %in2: i32, %clk: i1 {clk}, %reset: i1 {reset}, %go: i1 {go}) -> (%out0: i32, %done: i1 {done}) {
// CHECK-DAG: %true = hw.constant true
// CHECK-DAG: %c0_i32 = hw.constant 0 : i32
// CHECK-DAG: %std_add_1.left, %std_add_1.right, %std_add_1.out = calyx.std_add @std_add_1 : i32, i32, i32
// CHECK-DAG: %std_sub_0.left, %std_sub_0.right, %std_sub_0.out = calyx.std_sub @std_sub_0 : i32, i32, i32
// CHECK-DAG: %std_add_0.left, %std_add_0.right, %std_add_0.out = calyx.std_add @std_add_0 : i32, i32, i32
// CHECK-DAG: %std_slt_1.left, %std_slt_1.right, %std_slt_1.out = calyx.std_slt @std_slt_1 : i32, i32, i1
// CHECK-DAG: %std_slt_0.left, %std_slt_0.right, %std_slt_0.out = calyx.std_slt @std_slt_0 : i32, i32, i1
// CHECK-DAG: %while_0_arg2_reg.in, %while_0_arg2_reg.write_en, %while_0_arg2_reg.clk, %while_0_arg2_reg.reset, %while_0_arg2_reg.out, %while_0_arg2_reg.done = calyx.register @while_0_arg2_reg : i32, i1, i1, i1, i32, i1
// CHECK-DAG: %while_0_arg1_reg.in, %while_0_arg1_reg.write_en, %while_0_arg1_reg.clk, %while_0_arg1_reg.reset, %while_0_arg1_reg.out, %while_0_arg1_reg.done = calyx.register @while_0_arg1_reg : i32, i1, i1, i1, i32, i1
// CHECK-DAG: %while_0_arg0_reg.in, %while_0_arg0_reg.write_en, %while_0_arg0_reg.clk, %while_0_arg0_reg.reset, %while_0_arg0_reg.out, %while_0_arg0_reg.done = calyx.register @while_0_arg0_reg : i32, i1, i1, i1, i32, i1
// CHECK-DAG: %ret_arg0_reg.in, %ret_arg0_reg.write_en, %ret_arg0_reg.clk, %ret_arg0_reg.reset, %ret_arg0_reg.out, %ret_arg0_reg.done = calyx.register @ret_arg0_reg : i32, i1, i1, i1, i32, i1
// CHECK-DAG: %bb3_arg1_reg.in, %bb3_arg1_reg.write_en, %bb3_arg1_reg.clk, %bb3_arg1_reg.reset, %bb3_arg1_reg.out, %bb3_arg1_reg.done = calyx.register @bb3_arg1_reg : i32, i1, i1, i1, i32, i1
// CHECK-DAG: %bb3_arg0_reg.in, %bb3_arg0_reg.write_en, %bb3_arg0_reg.clk, %bb3_arg0_reg.reset, %bb3_arg0_reg.out, %bb3_arg0_reg.done = calyx.register @bb3_arg0_reg : i32, i1, i1, i1, i32, i1
// CHECK-NEXT: calyx.wires {
// CHECK-NEXT: calyx.assign %out0 = %ret_arg0_reg.out : i32
// CHECK-NEXT: calyx.group @assign_while_0_init_0 {
// CHECK-NEXT: calyx.assign %while_0_arg0_reg.in = %in0 : i32
// CHECK-NEXT: calyx.assign %while_0_arg0_reg.write_en = %true : i1
// CHECK-NEXT: calyx.group_done %while_0_arg0_reg.done : i1
// CHECK-NEXT: }
// CHECK-NEXT: calyx.control {
// CHECK-NEXT: calyx.seq {
// CHECK-NEXT: calyx.par {
// CHECK-NEXT: calyx.enable @assign_while_0_init_0
// CHECK-NEXT: calyx.enable @assign_while_0_init_1
// CHECK-NEXT: calyx.enable @assign_while_0_init_2
// CHECK-NEXT: }
// CHECK-NEXT: calyx.while %std_slt_0.out with @bb0_0 {
// CHECK-NEXT: calyx.seq {
// CHECK-NEXT: calyx.if %std_slt_1.out with @bb0_1 {
// CHECK-NEXT: calyx.seq {
// CHECK-NEXT: calyx.enable @bb1_to_bb3
// CHECK-NEXT: }
// CHECK-NEXT: } else {
// CHECK-NEXT: calyx.seq {
// CHECK-NEXT: calyx.enable @bb2_to_bb3
// CHECK-NEXT: }
// CHECK-NEXT: calyx.group @assign_while_0_init_1 {
// CHECK-NEXT: calyx.assign %while_0_arg1_reg.in = %c0_i32 : i32
// CHECK-NEXT: calyx.assign %while_0_arg1_reg.write_en = %true : i1
// CHECK-NEXT: calyx.group_done %while_0_arg1_reg.done : i1
// CHECK-NEXT: }
// CHECK-NEXT: calyx.group @assign_while_0_init_2 {
// CHECK-NEXT: calyx.assign %while_0_arg2_reg.in = %c0_i32 : i32
// CHECK-NEXT: calyx.assign %while_0_arg2_reg.write_en = %true : i1
// CHECK-NEXT: calyx.group_done %while_0_arg2_reg.done : i1
// CHECK-NEXT: }
// CHECK-NEXT: calyx.comb_group @bb0_0 {
// CHECK-NEXT: calyx.assign %std_slt_0.left = %while_0_arg0_reg.out : i32
// CHECK-NEXT: calyx.assign %std_slt_0.right = %in1 : i32
// CHECK-NEXT: }
// CHECK-NEXT: calyx.comb_group @bb0_1 {
// CHECK-NEXT: calyx.assign %std_slt_1.left = %while_0_arg1_reg.out : i32
// CHECK-NEXT: calyx.assign %std_slt_1.right = %while_0_arg2_reg.out : i32
// CHECK-NEXT: }
// CHECK-NEXT: calyx.group @bb1_to_bb3 {
// CHECK-NEXT: calyx.assign %bb3_arg0_reg.in = %std_add_0.out : i32
// CHECK-NEXT: calyx.assign %bb3_arg0_reg.write_en = %true : i1
// CHECK-NEXT: calyx.assign %bb3_arg1_reg.in = %std_add_0.out : i32
// CHECK-NEXT: calyx.assign %bb3_arg1_reg.write_en = %true : i1
// CHECK-NEXT: calyx.assign %std_add_0.left = %while_0_arg1_reg.out : i32
// CHECK-NEXT: calyx.assign %std_add_0.right = %while_0_arg2_reg.out : i32
// CHECK-NEXT: %0 = comb.and %bb3_arg0_reg.done, %bb3_arg1_reg.done : i1
// CHECK-NEXT: calyx.group_done %0 ? %true : i1
// CHECK-NEXT: }
// CHECK-NEXT: calyx.group @bb2_to_bb3 {
// CHECK-NEXT: calyx.assign %bb3_arg0_reg.in = %std_sub_0.out : i32
// CHECK-NEXT: calyx.assign %bb3_arg0_reg.write_en = %true : i1
// CHECK-NEXT: calyx.assign %bb3_arg1_reg.in = %std_sub_0.out : i32
// CHECK-NEXT: calyx.assign %bb3_arg1_reg.write_en = %true : i1
// CHECK-NEXT: calyx.assign %std_sub_0.left = %while_0_arg1_reg.out : i32
// CHECK-NEXT: calyx.assign %std_sub_0.right = %while_0_arg2_reg.out : i32
// CHECK-NEXT: %0 = comb.and %bb3_arg0_reg.done, %bb3_arg1_reg.done : i1
// CHECK-NEXT: calyx.group_done %0 ? %true : i1
// CHECK-NEXT: }
// CHECK-NEXT: calyx.group @assign_while_0_latch {
// CHECK-NEXT: calyx.assign %while_0_arg0_reg.in = %std_add_1.out : i32
// CHECK-NEXT: calyx.assign %while_0_arg0_reg.write_en = %true : i1
// CHECK-NEXT: calyx.assign %while_0_arg1_reg.in = %bb3_arg0_reg.out : i32
// CHECK-NEXT: calyx.assign %while_0_arg1_reg.write_en = %true : i1
// CHECK-NEXT: calyx.assign %while_0_arg2_reg.in = %bb3_arg1_reg.out : i32
// CHECK-NEXT: calyx.assign %while_0_arg2_reg.write_en = %true : i1
// CHECK-NEXT: calyx.assign %std_add_1.left = %while_0_arg0_reg.out : i32
// CHECK-NEXT: calyx.assign %std_add_1.right = %in2 : i32
// CHECK-NEXT: %0 = comb.and %while_0_arg0_reg.done, %while_0_arg1_reg.done, %while_0_arg2_reg.done : i1
// CHECK-NEXT: calyx.group_done %0 ? %true : i1
// CHECK-NEXT: }
// CHECK-NEXT: calyx.group @ret_assign_0 {
// CHECK-NEXT: calyx.assign %ret_arg0_reg.in = %while_0_arg2_reg.out : i32
// CHECK-NEXT: calyx.assign %ret_arg0_reg.write_en = %true : i1
// CHECK-NEXT: calyx.group_done %ret_arg0_reg.done : i1
// CHECK-NEXT: }
// CHECK-NEXT: }
// CHECK-NEXT: calyx.control {
// CHECK-NEXT: calyx.seq {
// CHECK-NEXT: calyx.par {
// CHECK-NEXT: calyx.enable @assign_while_0_init_0
// CHECK-NEXT: calyx.enable @assign_while_0_init_1
// CHECK-NEXT: calyx.enable @assign_while_0_init_2
// CHECK-NEXT: }
// CHECK-NEXT: calyx.while %std_slt_0.out with @bb0_0 {
// CHECK-NEXT: calyx.seq {
// CHECK-NEXT: calyx.if %std_slt_1.out with @bb0_1 {
// CHECK-NEXT: calyx.seq {
// CHECK-NEXT: calyx.enable @bb1_to_bb3
// CHECK-NEXT: }
// CHECK-NEXT: } else {
// CHECK-NEXT: calyx.seq {
// CHECK-NEXT: calyx.enable @bb2_to_bb3
// CHECK-NEXT: }
// CHECK-NEXT: calyx.enable @assign_while_0_latch
// CHECK-NEXT: }
// CHECK-NEXT: calyx.enable @assign_while_0_latch
// CHECK-NEXT: }
// CHECK-NEXT: calyx.enable @ret_assign_0
// CHECK-NEXT: }
// CHECK-NEXT: calyx.enable @ret_assign_0
// CHECK-NEXT: }
// CHECK-NEXT: } {toplevel}
// CHECK-NEXT: }
// CHECK-NEXT: }
// CHECK-NEXT: } {toplevel}
// CHECK-NEXT: }
module {
func.func @main(%arg0: i32, %arg1: i32, %arg2: i32) -> i32 {
@ -335,50 +329,48 @@ module {
// combinational operations. We expect all combinational logic in this sequence
// to be inlined into the combinational group. This also tests multiple returns.
// CHECK: module {
// CHECK-NEXT: calyx.program "main" {
// CHECK-LABEL: calyx.component @main(%in0: i32, %in1: i32, %in2: i32, %clk: i1 {clk}, %reset: i1 {reset}, %go: i1 {go}) -> (%out0: i32, %done: i1 {done}) {
// CHECK-DAG: %true = hw.constant true
// CHECK-DAG: %std_ge_0.left, %std_ge_0.right, %std_ge_0.out = calyx.std_ge @std_ge_0 : i32, i32, i1
// CHECK-DAG: %std_add_1.left, %std_add_1.right, %std_add_1.out = calyx.std_add @std_add_1 : i32, i32, i32
// CHECK-DAG: %std_add_0.left, %std_add_0.right, %std_add_0.out = calyx.std_add @std_add_0 : i32, i32, i32
// CHECK-DAG: %ret_arg0_reg.in, %ret_arg0_reg.write_en, %ret_arg0_reg.clk, %ret_arg0_reg.reset, %ret_arg0_reg.out, %ret_arg0_reg.done = calyx.register @ret_arg0_reg : i32, i1, i1, i1, i32, i1
// CHECK-NEXT: calyx.wires {
// CHECK-NEXT: calyx.assign %out0 = %ret_arg0_reg.out : i32
// CHECK-NEXT: calyx.comb_group @bb0_2 {
// CHECK-NEXT: calyx.assign %std_ge_0.left = %std_add_1.out : i32
// CHECK-NEXT: calyx.assign %std_ge_0.right = %in2 : i32
// CHECK-NEXT: calyx.assign %std_add_1.left = %std_add_0.out : i32
// CHECK-NEXT: calyx.assign %std_add_0.left = %in0 : i32
// CHECK-NEXT: calyx.assign %std_add_0.right = %in1 : i32
// CHECK-NEXT: calyx.assign %std_add_1.right = %in1 : i32
// CHECK-NEXT: }
// CHECK-NEXT: calyx.group @ret_assign_0 {
// CHECK-NEXT: calyx.assign %ret_arg0_reg.in = %in1 : i32
// CHECK-NEXT: calyx.assign %ret_arg0_reg.write_en = %true : i1
// CHECK-NEXT: calyx.group_done %ret_arg0_reg.done : i1
// CHECK-NEXT: }
// CHECK-NEXT: calyx.group @ret_assign_1 {
// CHECK-NEXT: calyx.assign %ret_arg0_reg.in = %in2 : i32
// CHECK-NEXT: calyx.assign %ret_arg0_reg.write_en = %true : i1
// CHECK-NEXT: calyx.group_done %ret_arg0_reg.done : i1
// CHECK-NEXT: }
// CHECK: module attributes {calyx.entrypoint = "main"} {
// CHECK-LABEL: calyx.component @main(%in0: i32, %in1: i32, %in2: i32, %clk: i1 {clk}, %reset: i1 {reset}, %go: i1 {go}) -> (%out0: i32, %done: i1 {done}) {
// CHECK-DAG: %true = hw.constant true
// CHECK-DAG: %std_ge_0.left, %std_ge_0.right, %std_ge_0.out = calyx.std_ge @std_ge_0 : i32, i32, i1
// CHECK-DAG: %std_add_1.left, %std_add_1.right, %std_add_1.out = calyx.std_add @std_add_1 : i32, i32, i32
// CHECK-DAG: %std_add_0.left, %std_add_0.right, %std_add_0.out = calyx.std_add @std_add_0 : i32, i32, i32
// CHECK-DAG: %ret_arg0_reg.in, %ret_arg0_reg.write_en, %ret_arg0_reg.clk, %ret_arg0_reg.reset, %ret_arg0_reg.out, %ret_arg0_reg.done = calyx.register @ret_arg0_reg : i32, i1, i1, i1, i32, i1
// CHECK-NEXT: calyx.wires {
// CHECK-NEXT: calyx.assign %out0 = %ret_arg0_reg.out : i32
// CHECK-NEXT: calyx.comb_group @bb0_2 {
// CHECK-NEXT: calyx.assign %std_ge_0.left = %std_add_1.out : i32
// CHECK-NEXT: calyx.assign %std_ge_0.right = %in2 : i32
// CHECK-NEXT: calyx.assign %std_add_1.left = %std_add_0.out : i32
// CHECK-NEXT: calyx.assign %std_add_0.left = %in0 : i32
// CHECK-NEXT: calyx.assign %std_add_0.right = %in1 : i32
// CHECK-NEXT: calyx.assign %std_add_1.right = %in1 : i32
// CHECK-NEXT: }
// CHECK-NEXT: calyx.control {
// CHECK-NEXT: calyx.seq {
// CHECK-NEXT: calyx.if %std_ge_0.out with @bb0_2 {
// CHECK-NEXT: calyx.seq {
// CHECK-NEXT: calyx.enable @ret_assign_0
// CHECK-NEXT: }
// CHECK-NEXT: } else {
// CHECK-NEXT: calyx.seq {
// CHECK-NEXT: calyx.enable @ret_assign_1
// CHECK-NEXT: }
// CHECK-NEXT: calyx.group @ret_assign_0 {
// CHECK-NEXT: calyx.assign %ret_arg0_reg.in = %in1 : i32
// CHECK-NEXT: calyx.assign %ret_arg0_reg.write_en = %true : i1
// CHECK-NEXT: calyx.group_done %ret_arg0_reg.done : i1
// CHECK-NEXT: }
// CHECK-NEXT: calyx.group @ret_assign_1 {
// CHECK-NEXT: calyx.assign %ret_arg0_reg.in = %in2 : i32
// CHECK-NEXT: calyx.assign %ret_arg0_reg.write_en = %true : i1
// CHECK-NEXT: calyx.group_done %ret_arg0_reg.done : i1
// CHECK-NEXT: }
// CHECK-NEXT: }
// CHECK-NEXT: calyx.control {
// CHECK-NEXT: calyx.seq {
// CHECK-NEXT: calyx.if %std_ge_0.out with @bb0_2 {
// CHECK-NEXT: calyx.seq {
// CHECK-NEXT: calyx.enable @ret_assign_0
// CHECK-NEXT: }
// CHECK-NEXT: } else {
// CHECK-NEXT: calyx.seq {
// CHECK-NEXT: calyx.enable @ret_assign_1
// CHECK-NEXT: }
// CHECK-NEXT: }
// CHECK-NEXT: }
// CHECK-NEXT: } {toplevel}
// CHECK-NEXT: }
// CHECK-NEXT: }
// CHECK-NEXT: } {toplevel}
// CHECK-NEXT: }
module {
func.func @main(%a0 : i32, %a1 : i32, %a2 : i32) -> i32 {

View File

@ -1,59 +1,57 @@
// RUN: circt-opt %s --lower-scf-to-calyx -canonicalize -split-input-file | FileCheck %s
// CHECK: module {
// CHECK-NEXT: calyx.program "main" {
// CHECK-LABEL: calyx.component @main(%clk: i1 {clk}, %reset: i1 {reset}, %go: i1 {go}) -> (%done: i1 {done}) {
// CHECK-DAG: %c64_i32 = hw.constant 64 : i32
// CHECK-DAG: %c0_i32 = hw.constant 0 : i32
// CHECK-DAG: %c1_i32 = hw.constant 1 : i32
// CHECK-DAG: %true = hw.constant true
// CHECK-DAG: %std_slice_1.in, %std_slice_1.out = calyx.std_slice @std_slice_1 : i32, i6
// CHECK-DAG: %std_slice_0.in, %std_slice_0.out = calyx.std_slice @std_slice_0 : i32, i6
// CHECK-DAG: %std_add_0.left, %std_add_0.right, %std_add_0.out = calyx.std_add @std_add_0 : i32, i32, i32
// CHECK-DAG: %std_lt_0.left, %std_lt_0.right, %std_lt_0.out = calyx.std_lt @std_lt_0 : i32, i32, i1
// CHECK-DAG: %mem_1.addr0, %mem_1.write_data, %mem_1.write_en, %mem_1.clk, %mem_1.read_data, %mem_1.done = calyx.memory @mem_1 <[64] x 32> [6] {external = true} : i6, i32, i1, i1, i32, i1
// CHECK-DAG: %mem_0.addr0, %mem_0.write_data, %mem_0.write_en, %mem_0.clk, %mem_0.read_data, %mem_0.done = calyx.memory @mem_0 <[64] x 32> [6] {external = true} : i6, i32, i1, i1, i32, i1
// CHECK-DAG: %while_0_arg0_reg.in, %while_0_arg0_reg.write_en, %while_0_arg0_reg.clk, %while_0_arg0_reg.reset, %while_0_arg0_reg.out, %while_0_arg0_reg.done = calyx.register @while_0_arg0_reg : i32, i1, i1, i1, i32, i1
// CHECK-NEXT: calyx.wires {
// CHECK-NEXT: calyx.group @assign_while_0_init_0 {
// CHECK-NEXT: calyx.assign %while_0_arg0_reg.in = %c0_i32 : i32
// CHECK-NEXT: calyx.assign %while_0_arg0_reg.write_en = %true : i1
// CHECK-NEXT: calyx.group_done %while_0_arg0_reg.done : i1
// CHECK-NEXT: }
// CHECK-NEXT: calyx.comb_group @bb0_0 {
// CHECK-NEXT: calyx.assign %std_lt_0.left = %while_0_arg0_reg.out : i32
// CHECK-NEXT: calyx.assign %std_lt_0.right = %c64_i32 : i32
// CHECK-NEXT: }
// CHECK-NEXT: calyx.group @bb0_2 {
// CHECK-NEXT: calyx.assign %std_slice_1.in = %while_0_arg0_reg.out : i32
// CHECK-NEXT: calyx.assign %std_slice_0.in = %while_0_arg0_reg.out : i32
// CHECK-NEXT: calyx.assign %mem_1.addr0 = %std_slice_1.out : i6
// CHECK-NEXT: calyx.assign %mem_1.write_data = %mem_0.read_data : i32
// CHECK-NEXT: calyx.assign %mem_1.write_en = %true : i1
// CHECK-NEXT: calyx.assign %mem_0.addr0 = %std_slice_0.out : i6
// CHECK-NEXT: calyx.group_done %mem_1.done : i1
// CHECK-NEXT: }
// CHECK-NEXT: calyx.group @assign_while_0_latch {
// CHECK-NEXT: calyx.assign %while_0_arg0_reg.in = %std_add_0.out : i32
// CHECK-NEXT: calyx.assign %while_0_arg0_reg.write_en = %true : i1
// CHECK-NEXT: calyx.assign %std_add_0.left = %while_0_arg0_reg.out : i32
// CHECK-NEXT: calyx.assign %std_add_0.right = %c1_i32 : i32
// CHECK-NEXT: calyx.group_done %while_0_arg0_reg.done : i1
// CHECK-NEXT: }
// CHECK: module attributes {calyx.entrypoint = "main"} {
// CHECK-LABEL: calyx.component @main(%clk: i1 {clk}, %reset: i1 {reset}, %go: i1 {go}) -> (%done: i1 {done}) {
// CHECK-DAG: %c64_i32 = hw.constant 64 : i32
// CHECK-DAG: %c0_i32 = hw.constant 0 : i32
// CHECK-DAG: %c1_i32 = hw.constant 1 : i32
// CHECK-DAG: %true = hw.constant true
// CHECK-DAG: %std_slice_1.in, %std_slice_1.out = calyx.std_slice @std_slice_1 : i32, i6
// CHECK-DAG: %std_slice_0.in, %std_slice_0.out = calyx.std_slice @std_slice_0 : i32, i6
// CHECK-DAG: %std_add_0.left, %std_add_0.right, %std_add_0.out = calyx.std_add @std_add_0 : i32, i32, i32
// CHECK-DAG: %std_lt_0.left, %std_lt_0.right, %std_lt_0.out = calyx.std_lt @std_lt_0 : i32, i32, i1
// CHECK-DAG: %mem_1.addr0, %mem_1.write_data, %mem_1.write_en, %mem_1.clk, %mem_1.read_data, %mem_1.done = calyx.memory @mem_1 <[64] x 32> [6] {external = true} : i6, i32, i1, i1, i32, i1
// CHECK-DAG: %mem_0.addr0, %mem_0.write_data, %mem_0.write_en, %mem_0.clk, %mem_0.read_data, %mem_0.done = calyx.memory @mem_0 <[64] x 32> [6] {external = true} : i6, i32, i1, i1, i32, i1
// CHECK-DAG: %while_0_arg0_reg.in, %while_0_arg0_reg.write_en, %while_0_arg0_reg.clk, %while_0_arg0_reg.reset, %while_0_arg0_reg.out, %while_0_arg0_reg.done = calyx.register @while_0_arg0_reg : i32, i1, i1, i1, i32, i1
// CHECK-NEXT: calyx.wires {
// CHECK-NEXT: calyx.group @assign_while_0_init_0 {
// CHECK-NEXT: calyx.assign %while_0_arg0_reg.in = %c0_i32 : i32
// CHECK-NEXT: calyx.assign %while_0_arg0_reg.write_en = %true : i1
// CHECK-NEXT: calyx.group_done %while_0_arg0_reg.done : i1
// CHECK-NEXT: }
// CHECK-NEXT: calyx.control {
// CHECK-NEXT: calyx.seq {
// CHECK-NEXT: calyx.enable @assign_while_0_init_0
// CHECK-NEXT: calyx.while %std_lt_0.out with @bb0_0 {
// CHECK-NEXT: calyx.seq {
// CHECK-NEXT: calyx.enable @bb0_2
// CHECK-NEXT: calyx.enable @assign_while_0_latch
// CHECK-NEXT: }
// CHECK-NEXT: calyx.comb_group @bb0_0 {
// CHECK-NEXT: calyx.assign %std_lt_0.left = %while_0_arg0_reg.out : i32
// CHECK-NEXT: calyx.assign %std_lt_0.right = %c64_i32 : i32
// CHECK-NEXT: }
// CHECK-NEXT: calyx.group @bb0_2 {
// CHECK-NEXT: calyx.assign %std_slice_1.in = %while_0_arg0_reg.out : i32
// CHECK-NEXT: calyx.assign %std_slice_0.in = %while_0_arg0_reg.out : i32
// CHECK-NEXT: calyx.assign %mem_1.addr0 = %std_slice_1.out : i6
// CHECK-NEXT: calyx.assign %mem_1.write_data = %mem_0.read_data : i32
// CHECK-NEXT: calyx.assign %mem_1.write_en = %true : i1
// CHECK-NEXT: calyx.assign %mem_0.addr0 = %std_slice_0.out : i6
// CHECK-NEXT: calyx.group_done %mem_1.done : i1
// CHECK-NEXT: }
// CHECK-NEXT: calyx.group @assign_while_0_latch {
// CHECK-NEXT: calyx.assign %while_0_arg0_reg.in = %std_add_0.out : i32
// CHECK-NEXT: calyx.assign %while_0_arg0_reg.write_en = %true : i1
// CHECK-NEXT: calyx.assign %std_add_0.left = %while_0_arg0_reg.out : i32
// CHECK-NEXT: calyx.assign %std_add_0.right = %c1_i32 : i32
// CHECK-NEXT: calyx.group_done %while_0_arg0_reg.done : i1
// CHECK-NEXT: }
// CHECK-NEXT: }
// CHECK-NEXT: calyx.control {
// CHECK-NEXT: calyx.seq {
// CHECK-NEXT: calyx.enable @assign_while_0_init_0
// CHECK-NEXT: calyx.while %std_lt_0.out with @bb0_0 {
// CHECK-NEXT: calyx.seq {
// CHECK-NEXT: calyx.enable @bb0_2
// CHECK-NEXT: calyx.enable @assign_while_0_latch
// CHECK-NEXT: }
// CHECK-NEXT: }
// CHECK-NEXT: }
// CHECK-NEXT: } {toplevel}
// CHECK-NEXT: }
// CHECK-NEXT: }
// CHECK-NEXT: } {toplevel}
// CHECK-NEXT: }
module {
func.func @main() {
@ -82,46 +80,44 @@ module {
// that any referenced combinational assignments are re-applied in each
// sequential group.
// CHECK: module {
// CHECK-NEXT: calyx.program "main" {
// CHECK-LABEL: calyx.component @main(%in0: i32, %clk: i1 {clk}, %reset: i1 {reset}, %go: i1 {go}) -> (%out0: i32, %done: i1 {done}) {
// CHECK-DAG: %c0_i32 = hw.constant 0 : i32
// CHECK-DAG: %c1_i32 = hw.constant 1 : i32
// CHECK-DAG: %true = hw.constant true
// CHECK-DAG: %std_slice_0.in, %std_slice_0.out = calyx.std_slice @std_slice_0 : i32, i6
// CHECK-DAG: %std_add_1.left, %std_add_1.right, %std_add_1.out = calyx.std_add @std_add_1 : i32, i32, i32
// CHECK-DAG: %std_add_0.left, %std_add_0.right, %std_add_0.out = calyx.std_add @std_add_0 : i32, i32, i32
// CHECK-DAG: %mem_0.addr0, %mem_0.write_data, %mem_0.write_en, %mem_0.clk, %mem_0.read_data, %mem_0.done = calyx.memory @mem_0 <[64] x 32> [6] {external = true} : i6, i32, i1, i1, i32, i1
// CHECK-DAG: %ret_arg0_reg.in, %ret_arg0_reg.write_en, %ret_arg0_reg.clk, %ret_arg0_reg.reset, %ret_arg0_reg.out, %ret_arg0_reg.done = calyx.register @ret_arg0_reg : i32, i1, i1, i1, i32, i1
// CHECK-NEXT: calyx.wires {
// CHECK-NEXT: calyx.assign %out0 = %ret_arg0_reg.out : i32
// CHECK-NEXT: calyx.group @bb0_1 {
// CHECK-NEXT: calyx.assign %std_slice_0.in = %c0_i32 : i32
// CHECK-NEXT: calyx.assign %mem_0.addr0 = %std_slice_0.out : i6
// CHECK-NEXT: calyx.assign %mem_0.write_data = %std_add_0.out : i32
// CHECK-NEXT: calyx.assign %mem_0.write_en = %true : i1
// CHECK-NEXT: calyx.assign %std_add_0.left = %in0 : i32
// CHECK-NEXT: calyx.assign %std_add_0.right = %c1_i32 : i32
// CHECK-NEXT: calyx.group_done %mem_0.done : i1
// CHECK-NEXT: }
// CHECK-NEXT: calyx.group @ret_assign_0 {
// CHECK-NEXT: calyx.assign %ret_arg0_reg.in = %std_add_1.out : i32
// CHECK-NEXT: calyx.assign %ret_arg0_reg.write_en = %true : i1
// CHECK-NEXT: calyx.assign %std_add_1.left = %std_add_0.out : i32
// CHECK-NEXT: calyx.assign %std_add_0.left = %in0 : i32
// CHECK-NEXT: calyx.assign %std_add_0.right = %c1_i32 : i32
// CHECK-NEXT: calyx.assign %std_add_1.right = %c1_i32 : i32
// CHECK-NEXT: calyx.group_done %ret_arg0_reg.done : i1
// CHECK-NEXT: }
// CHECK: module attributes {calyx.entrypoint = "main"} {
// CHECK-LABEL: calyx.component @main(%in0: i32, %clk: i1 {clk}, %reset: i1 {reset}, %go: i1 {go}) -> (%out0: i32, %done: i1 {done}) {
// CHECK-DAG: %c0_i32 = hw.constant 0 : i32
// CHECK-DAG: %c1_i32 = hw.constant 1 : i32
// CHECK-DAG: %true = hw.constant true
// CHECK-DAG: %std_slice_0.in, %std_slice_0.out = calyx.std_slice @std_slice_0 : i32, i6
// CHECK-DAG: %std_add_1.left, %std_add_1.right, %std_add_1.out = calyx.std_add @std_add_1 : i32, i32, i32
// CHECK-DAG: %std_add_0.left, %std_add_0.right, %std_add_0.out = calyx.std_add @std_add_0 : i32, i32, i32
// CHECK-DAG: %mem_0.addr0, %mem_0.write_data, %mem_0.write_en, %mem_0.clk, %mem_0.read_data, %mem_0.done = calyx.memory @mem_0 <[64] x 32> [6] {external = true} : i6, i32, i1, i1, i32, i1
// CHECK-DAG: %ret_arg0_reg.in, %ret_arg0_reg.write_en, %ret_arg0_reg.clk, %ret_arg0_reg.reset, %ret_arg0_reg.out, %ret_arg0_reg.done = calyx.register @ret_arg0_reg : i32, i1, i1, i1, i32, i1
// CHECK-NEXT: calyx.wires {
// CHECK-NEXT: calyx.assign %out0 = %ret_arg0_reg.out : i32
// CHECK-NEXT: calyx.group @bb0_1 {
// CHECK-NEXT: calyx.assign %std_slice_0.in = %c0_i32 : i32
// CHECK-NEXT: calyx.assign %mem_0.addr0 = %std_slice_0.out : i6
// CHECK-NEXT: calyx.assign %mem_0.write_data = %std_add_0.out : i32
// CHECK-NEXT: calyx.assign %mem_0.write_en = %true : i1
// CHECK-NEXT: calyx.assign %std_add_0.left = %in0 : i32
// CHECK-NEXT: calyx.assign %std_add_0.right = %c1_i32 : i32
// CHECK-NEXT: calyx.group_done %mem_0.done : i1
// CHECK-NEXT: }
// CHECK-NEXT: calyx.control {
// CHECK-NEXT: calyx.seq {
// CHECK-NEXT: calyx.enable @bb0_1
// CHECK-NEXT: calyx.enable @ret_assign_0
// CHECK-NEXT: }
// CHECK-NEXT: calyx.group @ret_assign_0 {
// CHECK-NEXT: calyx.assign %ret_arg0_reg.in = %std_add_1.out : i32
// CHECK-NEXT: calyx.assign %ret_arg0_reg.write_en = %true : i1
// CHECK-NEXT: calyx.assign %std_add_1.left = %std_add_0.out : i32
// CHECK-NEXT: calyx.assign %std_add_0.left = %in0 : i32
// CHECK-NEXT: calyx.assign %std_add_0.right = %c1_i32 : i32
// CHECK-NEXT: calyx.assign %std_add_1.right = %c1_i32 : i32
// CHECK-NEXT: calyx.group_done %ret_arg0_reg.done : i1
// CHECK-NEXT: }
// CHECK-NEXT: } {toplevel}
// CHECK-NEXT: }
// CHECK-NEXT: }
// CHECK-NEXT: calyx.control {
// CHECK-NEXT: calyx.seq {
// CHECK-NEXT: calyx.enable @bb0_1
// CHECK-NEXT: calyx.enable @ret_assign_0
// CHECK-NEXT: }
// CHECK-NEXT: }
// CHECK-NEXT: } {toplevel}
// CHECK-NEXT: }
module {
func.func @main(%arg0 : i32) -> i32 {
@ -137,49 +133,47 @@ module {
// -----
// CHECK: module {
// CHECK-NEXT: calyx.program "main" {
// CHECK-LABEL: calyx.component @main(%in0: i32, %clk: i1 {clk}, %reset: i1 {reset}, %go: i1 {go}) -> (%out0: i32, %done: i1 {done}) {
// CHECK-DAG: %c0_i32 = hw.constant 0 : i32
// CHECK-DAG: %c1_i32 = hw.constant 1 : i32
// CHECK-DAG: %true = hw.constant true
// CHECK-DAG: %std_slice_0.in, %std_slice_0.out = calyx.std_slice @std_slice_0 : i32, i6
// CHECK-DAG: %std_add_2.left, %std_add_2.right, %std_add_2.out = calyx.std_add @std_add_2 : i32, i32, i32
// CHECK-DAG: %std_add_1.left, %std_add_1.right, %std_add_1.out = calyx.std_add @std_add_1 : i32, i32, i32
// CHECK-DAG: %std_add_0.left, %std_add_0.right, %std_add_0.out = calyx.std_add @std_add_0 : i32, i32, i32
// CHECK-DAG: %mem_0.addr0, %mem_0.write_data, %mem_0.write_en, %mem_0.clk, %mem_0.read_data, %mem_0.done = calyx.memory @mem_0 <[64] x 32> [6] {external = true} : i6, i32, i1, i1, i32, i1
// CHECK-DAG: %ret_arg0_reg.in, %ret_arg0_reg.write_en, %ret_arg0_reg.clk, %ret_arg0_reg.reset, %ret_arg0_reg.out, %ret_arg0_reg.done = calyx.register @ret_arg0_reg : i32, i1, i1, i1, i32, i1
// CHECK-NEXT: calyx.wires {
// CHECK-NEXT: calyx.assign %out0 = %ret_arg0_reg.out : i32
// CHECK-NEXT: calyx.group @bb0_2 {
// CHECK-NEXT: calyx.assign %std_slice_0.in = %c0_i32 : i32
// CHECK-NEXT: calyx.assign %mem_0.addr0 = %std_slice_0.out : i6
// CHECK-NEXT: calyx.assign %mem_0.write_data = %std_add_0.out : i32
// CHECK-NEXT: calyx.assign %mem_0.write_en = %true : i1
// CHECK-NEXT: calyx.assign %std_add_0.left = %in0 : i32
// CHECK-NEXT: calyx.assign %std_add_0.right = %c1_i32 : i32
// CHECK-NEXT: calyx.group_done %mem_0.done : i1
// CHECK-NEXT: }
// CHECK-NEXT: calyx.group @ret_assign_0 {
// CHECK-NEXT: calyx.assign %ret_arg0_reg.in = %std_add_2.out : i32
// CHECK-NEXT: calyx.assign %ret_arg0_reg.write_en = %true : i1
// CHECK-NEXT: calyx.assign %std_add_2.left = %std_add_1.out : i32
// CHECK-NEXT: calyx.assign %std_add_1.left = %std_add_0.out : i32
// CHECK-NEXT: calyx.assign %std_add_0.left = %in0 : i32
// CHECK-NEXT: calyx.assign %std_add_0.right = %c1_i32 : i32
// CHECK-NEXT: calyx.assign %std_add_1.right = %c1_i32 : i32
// CHECK-NEXT: calyx.assign %std_add_2.right = %c1_i32 : i32
// CHECK-NEXT: calyx.group_done %ret_arg0_reg.done : i1
// CHECK-NEXT: }
// CHECK: module attributes {calyx.entrypoint = "main"} {
// CHECK-LABEL: calyx.component @main(%in0: i32, %clk: i1 {clk}, %reset: i1 {reset}, %go: i1 {go}) -> (%out0: i32, %done: i1 {done}) {
// CHECK-DAG: %c0_i32 = hw.constant 0 : i32
// CHECK-DAG: %c1_i32 = hw.constant 1 : i32
// CHECK-DAG: %true = hw.constant true
// CHECK-DAG: %std_slice_0.in, %std_slice_0.out = calyx.std_slice @std_slice_0 : i32, i6
// CHECK-DAG: %std_add_2.left, %std_add_2.right, %std_add_2.out = calyx.std_add @std_add_2 : i32, i32, i32
// CHECK-DAG: %std_add_1.left, %std_add_1.right, %std_add_1.out = calyx.std_add @std_add_1 : i32, i32, i32
// CHECK-DAG: %std_add_0.left, %std_add_0.right, %std_add_0.out = calyx.std_add @std_add_0 : i32, i32, i32
// CHECK-DAG: %mem_0.addr0, %mem_0.write_data, %mem_0.write_en, %mem_0.clk, %mem_0.read_data, %mem_0.done = calyx.memory @mem_0 <[64] x 32> [6] {external = true} : i6, i32, i1, i1, i32, i1
// CHECK-DAG: %ret_arg0_reg.in, %ret_arg0_reg.write_en, %ret_arg0_reg.clk, %ret_arg0_reg.reset, %ret_arg0_reg.out, %ret_arg0_reg.done = calyx.register @ret_arg0_reg : i32, i1, i1, i1, i32, i1
// CHECK-NEXT: calyx.wires {
// CHECK-NEXT: calyx.assign %out0 = %ret_arg0_reg.out : i32
// CHECK-NEXT: calyx.group @bb0_2 {
// CHECK-NEXT: calyx.assign %std_slice_0.in = %c0_i32 : i32
// CHECK-NEXT: calyx.assign %mem_0.addr0 = %std_slice_0.out : i6
// CHECK-NEXT: calyx.assign %mem_0.write_data = %std_add_0.out : i32
// CHECK-NEXT: calyx.assign %mem_0.write_en = %true : i1
// CHECK-NEXT: calyx.assign %std_add_0.left = %in0 : i32
// CHECK-NEXT: calyx.assign %std_add_0.right = %c1_i32 : i32
// CHECK-NEXT: calyx.group_done %mem_0.done : i1
// CHECK-NEXT: }
// CHECK-NEXT: calyx.control {
// CHECK-NEXT: calyx.seq {
// CHECK-NEXT: calyx.enable @bb0_2
// CHECK-NEXT: calyx.enable @ret_assign_0
// CHECK-NEXT: }
// CHECK-NEXT: calyx.group @ret_assign_0 {
// CHECK-NEXT: calyx.assign %ret_arg0_reg.in = %std_add_2.out : i32
// CHECK-NEXT: calyx.assign %ret_arg0_reg.write_en = %true : i1
// CHECK-NEXT: calyx.assign %std_add_2.left = %std_add_1.out : i32
// CHECK-NEXT: calyx.assign %std_add_1.left = %std_add_0.out : i32
// CHECK-NEXT: calyx.assign %std_add_0.left = %in0 : i32
// CHECK-NEXT: calyx.assign %std_add_0.right = %c1_i32 : i32
// CHECK-NEXT: calyx.assign %std_add_1.right = %c1_i32 : i32
// CHECK-NEXT: calyx.assign %std_add_2.right = %c1_i32 : i32
// CHECK-NEXT: calyx.group_done %ret_arg0_reg.done : i1
// CHECK-NEXT: }
// CHECK-NEXT: } {toplevel}
// CHECK-NEXT: }
// CHECK-NEXT: }
// CHECK-NEXT: calyx.control {
// CHECK-NEXT: calyx.seq {
// CHECK-NEXT: calyx.enable @bb0_2
// CHECK-NEXT: calyx.enable @ret_assign_0
// CHECK-NEXT: }
// CHECK-NEXT: }
// CHECK-NEXT: } {toplevel}
// CHECK-NEXT: }
module {
func.func @main(%arg0 : i32) -> i32 {
@ -197,53 +191,51 @@ module {
// -----
// Test multiple reads from the same memory (structural hazard).
// CHECK: module {
// CHECK-NEXT: calyx.program "main" {
// CHECK-LABEL: calyx.component @main(%in0: i6, %clk: i1 {clk}, %reset: i1 {reset}, %go: i1 {go}) -> (%out0: i32, %done: i1 {done}) {
// CHECK-DAG: %c1_i32 = hw.constant 1 : i32
// CHECK-DAG: %true = hw.constant true
// CHECK-DAG: %std_slice_1.in, %std_slice_1.out = calyx.std_slice @std_slice_1 : i32, i6
// CHECK-DAG: %std_slice_0.in, %std_slice_0.out = calyx.std_slice @std_slice_0 : i32, i6
// CHECK-DAG: %std_add_0.left, %std_add_0.right, %std_add_0.out = calyx.std_add @std_add_0 : i32, i32, i32
// CHECK-DAG: %load_1_reg.in, %load_1_reg.write_en, %load_1_reg.clk, %load_1_reg.reset, %load_1_reg.out, %load_1_reg.done = calyx.register @load_1_reg : i32, i1, i1, i1, i32, i1
// CHECK-DAG: %load_0_reg.in, %load_0_reg.write_en, %load_0_reg.clk, %load_0_reg.reset, %load_0_reg.out, %load_0_reg.done = calyx.register @load_0_reg : i32, i1, i1, i1, i32, i1
// CHECK-DAG: %std_pad_0.in, %std_pad_0.out = calyx.std_pad @std_pad_0 : i6, i32
// CHECK-DAG: %mem_0.addr0, %mem_0.write_data, %mem_0.write_en, %mem_0.clk, %mem_0.read_data, %mem_0.done = calyx.memory @mem_0 <[64] x 32> [6] {external = true} : i6, i32, i1, i1, i32, i1
// CHECK-DAG: %ret_arg0_reg.in, %ret_arg0_reg.write_en, %ret_arg0_reg.clk, %ret_arg0_reg.reset, %ret_arg0_reg.out, %ret_arg0_reg.done = calyx.register @ret_arg0_reg : i32, i1, i1, i1, i32, i1
// CHECK-NEXT: calyx.wires {
// CHECK-NEXT: calyx.assign %out0 = %ret_arg0_reg.out : i32
// CHECK-NEXT: calyx.group @bb0_1 {
// CHECK-NEXT: calyx.assign %std_slice_1.in = %std_pad_0.out : i32
// CHECK-NEXT: calyx.assign %mem_0.addr0 = %std_slice_1.out : i6
// CHECK-NEXT: calyx.assign %load_0_reg.in = %mem_0.read_data : i32
// CHECK-NEXT: calyx.assign %load_0_reg.write_en = %true : i1
// CHECK-NEXT: calyx.assign %std_pad_0.in = %in0 : i6
// CHECK-NEXT: calyx.group_done %load_0_reg.done : i1
// CHECK-NEXT: }
// CHECK-NEXT: calyx.group @bb0_2 {
// CHECK-NEXT: calyx.assign %std_slice_0.in = %c1_i32 : i32
// CHECK-NEXT: calyx.assign %mem_0.addr0 = %std_slice_0.out : i6
// CHECK-NEXT: calyx.assign %load_1_reg.in = %mem_0.read_data : i32
// CHECK-NEXT: calyx.assign %load_1_reg.write_en = %true : i1
// CHECK-NEXT: calyx.group_done %load_1_reg.done : i1
// CHECK-NEXT: }
// CHECK-NEXT: calyx.group @ret_assign_0 {
// CHECK-NEXT: calyx.assign %ret_arg0_reg.in = %std_add_0.out : i32
// CHECK-NEXT: calyx.assign %ret_arg0_reg.write_en = %true : i1
// CHECK-NEXT: calyx.assign %std_add_0.left = %load_0_reg.out : i32
// CHECK-NEXT: calyx.assign %std_add_0.right = %load_1_reg.out : i32
// CHECK-NEXT: calyx.group_done %ret_arg0_reg.done : i1
// CHECK-NEXT: }
// CHECK: module attributes {calyx.entrypoint = "main"} {
// CHECK-LABEL: calyx.component @main(%in0: i6, %clk: i1 {clk}, %reset: i1 {reset}, %go: i1 {go}) -> (%out0: i32, %done: i1 {done}) {
// CHECK-DAG: %c1_i32 = hw.constant 1 : i32
// CHECK-DAG: %true = hw.constant true
// CHECK-DAG: %std_slice_1.in, %std_slice_1.out = calyx.std_slice @std_slice_1 : i32, i6
// CHECK-DAG: %std_slice_0.in, %std_slice_0.out = calyx.std_slice @std_slice_0 : i32, i6
// CHECK-DAG: %std_add_0.left, %std_add_0.right, %std_add_0.out = calyx.std_add @std_add_0 : i32, i32, i32
// CHECK-DAG: %load_1_reg.in, %load_1_reg.write_en, %load_1_reg.clk, %load_1_reg.reset, %load_1_reg.out, %load_1_reg.done = calyx.register @load_1_reg : i32, i1, i1, i1, i32, i1
// CHECK-DAG: %load_0_reg.in, %load_0_reg.write_en, %load_0_reg.clk, %load_0_reg.reset, %load_0_reg.out, %load_0_reg.done = calyx.register @load_0_reg : i32, i1, i1, i1, i32, i1
// CHECK-DAG: %std_pad_0.in, %std_pad_0.out = calyx.std_pad @std_pad_0 : i6, i32
// CHECK-DAG: %mem_0.addr0, %mem_0.write_data, %mem_0.write_en, %mem_0.clk, %mem_0.read_data, %mem_0.done = calyx.memory @mem_0 <[64] x 32> [6] {external = true} : i6, i32, i1, i1, i32, i1
// CHECK-DAG: %ret_arg0_reg.in, %ret_arg0_reg.write_en, %ret_arg0_reg.clk, %ret_arg0_reg.reset, %ret_arg0_reg.out, %ret_arg0_reg.done = calyx.register @ret_arg0_reg : i32, i1, i1, i1, i32, i1
// CHECK-NEXT: calyx.wires {
// CHECK-NEXT: calyx.assign %out0 = %ret_arg0_reg.out : i32
// CHECK-NEXT: calyx.group @bb0_1 {
// CHECK-NEXT: calyx.assign %std_slice_1.in = %std_pad_0.out : i32
// CHECK-NEXT: calyx.assign %mem_0.addr0 = %std_slice_1.out : i6
// CHECK-NEXT: calyx.assign %load_0_reg.in = %mem_0.read_data : i32
// CHECK-NEXT: calyx.assign %load_0_reg.write_en = %true : i1
// CHECK-NEXT: calyx.assign %std_pad_0.in = %in0 : i6
// CHECK-NEXT: calyx.group_done %load_0_reg.done : i1
// CHECK-NEXT: }
// CHECK-NEXT: calyx.control {
// CHECK-NEXT: calyx.seq {
// CHECK-NEXT: calyx.enable @bb0_1
// CHECK-NEXT: calyx.enable @bb0_2
// CHECK-NEXT: calyx.enable @ret_assign_0
// CHECK-NEXT: }
// CHECK-NEXT: calyx.group @bb0_2 {
// CHECK-NEXT: calyx.assign %std_slice_0.in = %c1_i32 : i32
// CHECK-NEXT: calyx.assign %mem_0.addr0 = %std_slice_0.out : i6
// CHECK-NEXT: calyx.assign %load_1_reg.in = %mem_0.read_data : i32
// CHECK-NEXT: calyx.assign %load_1_reg.write_en = %true : i1
// CHECK-NEXT: calyx.group_done %load_1_reg.done : i1
// CHECK-NEXT: }
// CHECK-NEXT: } {toplevel}
// CHECK-NEXT: }
// CHECK-NEXT: calyx.group @ret_assign_0 {
// CHECK-NEXT: calyx.assign %ret_arg0_reg.in = %std_add_0.out : i32
// CHECK-NEXT: calyx.assign %ret_arg0_reg.write_en = %true : i1
// CHECK-NEXT: calyx.assign %std_add_0.left = %load_0_reg.out : i32
// CHECK-NEXT: calyx.assign %std_add_0.right = %load_1_reg.out : i32
// CHECK-NEXT: calyx.group_done %ret_arg0_reg.done : i1
// CHECK-NEXT: }
// CHECK-NEXT: }
// CHECK-NEXT: calyx.control {
// CHECK-NEXT: calyx.seq {
// CHECK-NEXT: calyx.enable @bb0_1
// CHECK-NEXT: calyx.enable @bb0_2
// CHECK-NEXT: calyx.enable @ret_assign_0
// CHECK-NEXT: }
// CHECK-NEXT: }
// CHECK-NEXT: } {toplevel}
// CHECK-NEXT: }
module {
func.func @main(%arg0 : i6) -> i32 {
@ -261,30 +253,28 @@ module {
// Test index types as inputs.
// CHECK: module {
// CHECK-NEXT: calyx.program "main" {
// CHECK-NEXT: calyx.component @main(%in0: i32, %clk: i1 {clk}, %reset: i1 {reset}, %go: i1 {go}) -> (%out0: i32, %done: i1 {done}) {
// CHECK-DAG: %true = hw.constant true
// CHECK-DAG: %std_slice_0.in, %std_slice_0.out = calyx.std_slice @std_slice_0 : i32, i6
// CHECK-DAG: %mem_0.addr0, %mem_0.write_data, %mem_0.write_en, %mem_0.clk, %mem_0.read_data, %mem_0.done = calyx.memory @mem_0 <[64] x 32> [6] {external = true} : i6, i32, i1, i1, i32, i1
// CHECK-DAG: %ret_arg0_reg.in, %ret_arg0_reg.write_en, %ret_arg0_reg.clk, %ret_arg0_reg.reset, %ret_arg0_reg.out, %ret_arg0_reg.done = calyx.register @ret_arg0_reg : i32, i1, i1, i1, i32, i1
// CHECK-NEXT: calyx.wires {
// CHECK-NEXT: calyx.assign %out0 = %ret_arg0_reg.out : i32
// CHECK-NEXT: calyx.group @ret_assign_0 {
// CHECK-NEXT: calyx.assign %std_slice_0.in = %in0 : i32
// CHECK-NEXT: calyx.assign %ret_arg0_reg.in = %mem_0.read_data : i32
// CHECK-NEXT: calyx.assign %ret_arg0_reg.write_en = %true : i1
// CHECK-NEXT: calyx.assign %mem_0.addr0 = %std_slice_0.out : i6
// CHECK-NEXT: calyx.group_done %ret_arg0_reg.done : i1
// CHECK-NEXT: }
// CHECK: module attributes {calyx.entrypoint = "main"} {
// CHECK-NEXT: calyx.component @main(%in0: i32, %clk: i1 {clk}, %reset: i1 {reset}, %go: i1 {go}) -> (%out0: i32, %done: i1 {done}) {
// CHECK-DAG: %true = hw.constant true
// CHECK-DAG: %std_slice_0.in, %std_slice_0.out = calyx.std_slice @std_slice_0 : i32, i6
// CHECK-DAG: %mem_0.addr0, %mem_0.write_data, %mem_0.write_en, %mem_0.clk, %mem_0.read_data, %mem_0.done = calyx.memory @mem_0 <[64] x 32> [6] {external = true} : i6, i32, i1, i1, i32, i1
// CHECK-DAG: %ret_arg0_reg.in, %ret_arg0_reg.write_en, %ret_arg0_reg.clk, %ret_arg0_reg.reset, %ret_arg0_reg.out, %ret_arg0_reg.done = calyx.register @ret_arg0_reg : i32, i1, i1, i1, i32, i1
// CHECK-NEXT: calyx.wires {
// CHECK-NEXT: calyx.assign %out0 = %ret_arg0_reg.out : i32
// CHECK-NEXT: calyx.group @ret_assign_0 {
// CHECK-NEXT: calyx.assign %std_slice_0.in = %in0 : i32
// CHECK-NEXT: calyx.assign %ret_arg0_reg.in = %mem_0.read_data : i32
// CHECK-NEXT: calyx.assign %ret_arg0_reg.write_en = %true : i1
// CHECK-NEXT: calyx.assign %mem_0.addr0 = %std_slice_0.out : i6
// CHECK-NEXT: calyx.group_done %ret_arg0_reg.done : i1
// CHECK-NEXT: }
// CHECK-NEXT: calyx.control {
// CHECK-NEXT: calyx.seq {
// CHECK-NEXT: calyx.enable @ret_assign_0
// CHECK-NEXT: }
// CHECK-NEXT: }
// CHECK-NEXT: calyx.control {
// CHECK-NEXT: calyx.seq {
// CHECK-NEXT: calyx.enable @ret_assign_0
// CHECK-NEXT: }
// CHECK-NEXT: } {toplevel}
// CHECK-NEXT: }
// CHECK-NEXT: }
// CHECK-NEXT: } {toplevel}
// CHECK-NEXT: }
module {
func.func @main(%i : index) -> i32 {
@ -298,28 +288,26 @@ module {
// Test index types as outputs.
// CHECH: module {
// CHECH-NEXT: calyx.program "main" {
// CHECH-NEXT: calyx.component @main(%in0: i8, %clk: i1 {clk}, %reset: i1 {reset}, %go: i1 {go}) -> (%out0: i32, %done: i1 {done}) {
// CHECH-DAG: %true = hw.constant true
// CHECH-DAG: %std_pad_0.in, %std_pad_0.out = calyx.std_pad @std_pad_0 : i8, i32
// CHECH-DAG: %ret_arg0_reg.in, %ret_arg0_reg.write_en, %ret_arg0_reg.clk, %ret_arg0_reg.reset, %ret_arg0_reg.out, %ret_arg0_reg.done = calyx.register @ret_arg0_reg : i32, i1, i1, i1, i32, i1
// CHECH-NEXT: calyx.wires {
// CHECH-NEXT: calyx.assign %out0 = %ret_arg0_reg.out : i32
// CHECH-NEXT: calyx.group @ret_assign_0 {
// CHECH-NEXT: calyx.assign %ret_arg0_reg.in = %std_pad_0.out : i32
// CHECH-NEXT: calyx.assign %ret_arg0_reg.write_en = %true : i1
// CHECH-NEXT: calyx.assign %std_pad_0.in = %in0 : i8
// CHECH-NEXT: calyx.group_done %ret_arg0_reg.done : i1
// CHECH-NEXT: }
// CHECH: module attributes {calyx.entrypoint = "main"} {
// CHECH-NEXT: calyx.component @main(%in0: i8, %clk: i1 {clk}, %reset: i1 {reset}, %go: i1 {go}) -> (%out0: i32, %done: i1 {done}) {
// CHECH-DAG: %true = hw.constant true
// CHECH-DAG: %std_pad_0.in, %std_pad_0.out = calyx.std_pad @std_pad_0 : i8, i32
// CHECH-DAG: %ret_arg0_reg.in, %ret_arg0_reg.write_en, %ret_arg0_reg.clk, %ret_arg0_reg.reset, %ret_arg0_reg.out, %ret_arg0_reg.done = calyx.register @ret_arg0_reg : i32, i1, i1, i1, i32, i1
// CHECH-NEXT: calyx.wires {
// CHECH-NEXT: calyx.assign %out0 = %ret_arg0_reg.out : i32
// CHECH-NEXT: calyx.group @ret_assign_0 {
// CHECH-NEXT: calyx.assign %ret_arg0_reg.in = %std_pad_0.out : i32
// CHECH-NEXT: calyx.assign %ret_arg0_reg.write_en = %true : i1
// CHECH-NEXT: calyx.assign %std_pad_0.in = %in0 : i8
// CHECH-NEXT: calyx.group_done %ret_arg0_reg.done : i1
// CHECH-NEXT: }
// CHECH-NEXT: calyx.control {
// CHECH-NEXT: calyx.seq {
// CHECH-NEXT: calyx.enable @ret_assign_0
// CHECH-NEXT: }
// CHECH-NEXT: }
// CHECH-NEXT: calyx.control {
// CHECH-NEXT: calyx.seq {
// CHECH-NEXT: calyx.enable @ret_assign_0
// CHECH-NEXT: }
// CHECH-NEXT: } {toplevel}
// CHECH-NEXT: }
// CHECH-NEXT: }
// CHECH-NEXT: } {toplevel}
// CHECH-NEXT: }
module {
func.func @main(%i : i8) -> index {
@ -332,27 +320,25 @@ module {
// External memory store.
// CHECK: module {
// CHECK-NEXT: calyx.program "main" {
// CHECK: calyx.component @main(%in0: i32, %ext_mem0_read_data: i32 {mem = {id = 0 : i32, tag = "read_data"}}, %ext_mem0_done: i1 {mem = {id = 0 : i32, tag = "done"}}, %in2: i32, %clk: i1 {clk}, %reset: i1 {reset}, %go: i1 {go}) -> (%ext_mem0_write_data: i32 {mem = {id = 0 : i32, tag = "write_data"}}, %ext_mem0_addr0: i3 {mem = {addr_idx = 0 : i32, id = 0 : i32, tag = "addr"}}, %ext_mem0_write_en: i1 {mem = {id = 0 : i32, tag = "write_en"}}, %done: i1 {done}) {
// CHECK-DAG: %true = hw.constant true
// CHECK-DAG: %std_slice_0.in, %std_slice_0.out = calyx.std_slice @std_slice_0 : i32, i3
// CHECK-NEXT: calyx.wires {
// CHECK-NEXT: calyx.group @bb0_0 {
// CHECK-NEXT: calyx.assign %std_slice_0.in = %in2 : i32
// CHECK-NEXT: calyx.assign %ext_mem0_addr0 = %std_slice_0.out : i3
// CHECK-NEXT: calyx.assign %ext_mem0_write_data = %in0 : i32
// CHECK-NEXT: calyx.assign %ext_mem0_write_en = %true : i1
// CHECK-NEXT: calyx.group_done %ext_mem0_done : i1
// CHECK-NEXT: }
// CHECK: module attributes {calyx.entrypoint = "main"} {
// CHECK: calyx.component @main(%in0: i32, %ext_mem0_read_data: i32 {mem = {id = 0 : i32, tag = "read_data"}}, %ext_mem0_done: i1 {mem = {id = 0 : i32, tag = "done"}}, %in2: i32, %clk: i1 {clk}, %reset: i1 {reset}, %go: i1 {go}) -> (%ext_mem0_write_data: i32 {mem = {id = 0 : i32, tag = "write_data"}}, %ext_mem0_addr0: i3 {mem = {addr_idx = 0 : i32, id = 0 : i32, tag = "addr"}}, %ext_mem0_write_en: i1 {mem = {id = 0 : i32, tag = "write_en"}}, %done: i1 {done}) {
// CHECK-DAG: %true = hw.constant true
// CHECK-DAG: %std_slice_0.in, %std_slice_0.out = calyx.std_slice @std_slice_0 : i32, i3
// CHECK-NEXT: calyx.wires {
// CHECK-NEXT: calyx.group @bb0_0 {
// CHECK-NEXT: calyx.assign %std_slice_0.in = %in2 : i32
// CHECK-NEXT: calyx.assign %ext_mem0_addr0 = %std_slice_0.out : i3
// CHECK-NEXT: calyx.assign %ext_mem0_write_data = %in0 : i32
// CHECK-NEXT: calyx.assign %ext_mem0_write_en = %true : i1
// CHECK-NEXT: calyx.group_done %ext_mem0_done : i1
// CHECK-NEXT: }
// CHECK-NEXT: calyx.control {
// CHECK-NEXT: calyx.seq {
// CHECK-NEXT: calyx.enable @bb0_0
// CHECK-NEXT: }
// CHECK-NEXT: }
// CHECK-NEXT: calyx.control {
// CHECK-NEXT: calyx.seq {
// CHECK-NEXT: calyx.enable @bb0_0
// CHECK-NEXT: }
// CHECK-NEXT: } {toplevel}
// CHECK-NEXT: }
// CHECK-NEXT: }
// CHECK-NEXT: } {toplevel}
// CHECK-NEXT: }
module {
func.func @main(%arg0 : i32, %mem0 : memref<8xi32>, %i : index) {
@ -365,29 +351,27 @@ module {
// External memory load.
// CHECK: module {
// CHECK-NEXT: calyx.program "main" {
// CHECK: calyx.component @main(%in0: i32, %ext_mem0_read_data: i32 {mem = {id = 0 : i32, tag = "read_data"}}, %ext_mem0_done: i1 {mem = {id = 0 : i32, tag = "done"}}, %clk: i1 {clk}, %reset: i1 {reset}, %go: i1 {go}) -> (%ext_mem0_write_data: i32 {mem = {id = 0 : i32, tag = "write_data"}}, %ext_mem0_addr0: i3 {mem = {addr_idx = 0 : i32, id = 0 : i32, tag = "addr"}}, %ext_mem0_write_en: i1 {mem = {id = 0 : i32, tag = "write_en"}}, %out0: i32, %done: i1 {done}) {
// CHECK: %true = hw.constant true
// CHECK: %std_slice_0.in, %std_slice_0.out = calyx.std_slice @std_slice_0 : i32, i3
// CHECK: %ret_arg0_reg.in, %ret_arg0_reg.write_en, %ret_arg0_reg.clk, %ret_arg0_reg.reset, %ret_arg0_reg.out, %ret_arg0_reg.done = calyx.register @ret_arg0_reg : i32, i1, i1, i1, i32, i1
// CHECK-NEXT: calyx.wires {
// CHECK-NEXT: calyx.assign %out0 = %ret_arg0_reg.out : i32
// CHECK-NEXT: calyx.group @ret_assign_0 {
// CHECK-NEXT: calyx.assign %std_slice_0.in = %in0 : i32
// CHECK-NEXT: calyx.assign %ret_arg0_reg.in = %ext_mem0_read_data : i32
// CHECK-NEXT: calyx.assign %ret_arg0_reg.write_en = %true : i1
// CHECK-NEXT: calyx.assign %ext_mem0_addr0 = %std_slice_0.out : i3
// CHECK-NEXT: calyx.group_done %ret_arg0_reg.done : i1
// CHECK-NEXT: }
// CHECK: module attributes {calyx.entrypoint = "main"} {
// CHECK: calyx.component @main(%in0: i32, %ext_mem0_read_data: i32 {mem = {id = 0 : i32, tag = "read_data"}}, %ext_mem0_done: i1 {mem = {id = 0 : i32, tag = "done"}}, %clk: i1 {clk}, %reset: i1 {reset}, %go: i1 {go}) -> (%ext_mem0_write_data: i32 {mem = {id = 0 : i32, tag = "write_data"}}, %ext_mem0_addr0: i3 {mem = {addr_idx = 0 : i32, id = 0 : i32, tag = "addr"}}, %ext_mem0_write_en: i1 {mem = {id = 0 : i32, tag = "write_en"}}, %out0: i32, %done: i1 {done}) {
// CHECK: %true = hw.constant true
// CHECK: %std_slice_0.in, %std_slice_0.out = calyx.std_slice @std_slice_0 : i32, i3
// CHECK: %ret_arg0_reg.in, %ret_arg0_reg.write_en, %ret_arg0_reg.clk, %ret_arg0_reg.reset, %ret_arg0_reg.out, %ret_arg0_reg.done = calyx.register @ret_arg0_reg : i32, i1, i1, i1, i32, i1
// CHECK-NEXT: calyx.wires {
// CHECK-NEXT: calyx.assign %out0 = %ret_arg0_reg.out : i32
// CHECK-NEXT: calyx.group @ret_assign_0 {
// CHECK-NEXT: calyx.assign %std_slice_0.in = %in0 : i32
// CHECK-NEXT: calyx.assign %ret_arg0_reg.in = %ext_mem0_read_data : i32
// CHECK-NEXT: calyx.assign %ret_arg0_reg.write_en = %true : i1
// CHECK-NEXT: calyx.assign %ext_mem0_addr0 = %std_slice_0.out : i3
// CHECK-NEXT: calyx.group_done %ret_arg0_reg.done : i1
// CHECK-NEXT: }
// CHECK-NEXT: calyx.control {
// CHECK-NEXT: calyx.seq {
// CHECK-NEXT: calyx.enable @ret_assign_0
// CHECK-NEXT: }
// CHECK-NEXT: }
// CHECK-NEXT: calyx.control {
// CHECK-NEXT: calyx.seq {
// CHECK-NEXT: calyx.enable @ret_assign_0
// CHECK-NEXT: }
// CHECK-NEXT: } {toplevel}
// CHECK-NEXT: }
// CHECK-NEXT: }
// CHECK-NEXT: } {toplevel}
// CHECK-NEXT: }
module {
func.func @main(%i : index, %mem0 : memref<8xi32>) -> i32 {
@ -400,51 +384,49 @@ module {
// External memory hazard.
// CHECK: module {
// CHECK-NEXT: calyx.program "main" {
// CHECK: calyx.component @main(%in0: i32, %in1: i32, %ext_mem0_read_data: i32 {mem = {id = 0 : i32, tag = "read_data"}}, %ext_mem0_done: i1 {mem = {id = 0 : i32, tag = "done"}}, %clk: i1 {clk}, %reset: i1 {reset}, %go: i1 {go}) -> (%ext_mem0_write_data: i32 {mem = {id = 0 : i32, tag = "write_data"}}, %ext_mem0_addr0: i3 {mem = {addr_idx = 0 : i32, id = 0 : i32, tag = "addr"}}, %ext_mem0_write_en: i1 {mem = {id = 0 : i32, tag = "write_en"}}, %out0: i32, %out1: i32, %done: i1 {done}) {
// CHECK-DAG: %true = hw.constant true
// CHECK-DAG: %std_slice_1.in, %std_slice_1.out = calyx.std_slice @std_slice_1 : i32, i3
// CHECK-DAG: %std_slice_0.in, %std_slice_0.out = calyx.std_slice @std_slice_0 : i32, i3
// CHECK-DAG: %load_1_reg.in, %load_1_reg.write_en, %load_1_reg.clk, %load_1_reg.reset, %load_1_reg.out, %load_1_reg.done = calyx.register @load_1_reg : i32, i1, i1, i1, i32, i1
// CHECK-DAG: %load_0_reg.in, %load_0_reg.write_en, %load_0_reg.clk, %load_0_reg.reset, %load_0_reg.out, %load_0_reg.done = calyx.register @load_0_reg : i32, i1, i1, i1, i32, i1
// CHECK-DAG: %ret_arg1_reg.in, %ret_arg1_reg.write_en, %ret_arg1_reg.clk, %ret_arg1_reg.reset, %ret_arg1_reg.out, %ret_arg1_reg.done = calyx.register @ret_arg1_reg : i32, i1, i1, i1, i32, i1
// CHECK-DAG: %ret_arg0_reg.in, %ret_arg0_reg.write_en, %ret_arg0_reg.clk, %ret_arg0_reg.reset, %ret_arg0_reg.out, %ret_arg0_reg.done = calyx.register @ret_arg0_reg : i32, i1, i1, i1, i32, i1
// CHECK-NEXT: calyx.wires {
// CHECK-NEXT: calyx.assign %out1 = %ret_arg1_reg.out : i32
// CHECK-NEXT: calyx.assign %out0 = %ret_arg0_reg.out : i32
// CHECK-NEXT: calyx.group @bb0_0 {
// CHECK-NEXT: calyx.assign %std_slice_1.in = %in0 : i32
// CHECK-NEXT: calyx.assign %ext_mem0_addr0 = %std_slice_1.out : i3
// CHECK-NEXT: calyx.assign %load_0_reg.in = %ext_mem0_read_data : i32
// CHECK-NEXT: calyx.assign %load_0_reg.write_en = %true : i1
// CHECK-NEXT: calyx.group_done %load_0_reg.done : i1
// CHECK-NEXT: }
// CHECK-NEXT: calyx.group @bb0_1 {
// CHECK-NEXT: calyx.assign %std_slice_0.in = %in1 : i32
// CHECK-NEXT: calyx.assign %ext_mem0_addr0 = %std_slice_0.out : i3
// CHECK-NEXT: calyx.assign %load_1_reg.in = %ext_mem0_read_data : i32
// CHECK-NEXT: calyx.assign %load_1_reg.write_en = %true : i1
// CHECK-NEXT: calyx.group_done %load_1_reg.done : i1
// CHECK-NEXT: }
// CHECK-NEXT: calyx.group @ret_assign_0 {
// CHECK-NEXT: calyx.assign %ret_arg0_reg.in = %load_0_reg.out : i32
// CHECK-NEXT: calyx.assign %ret_arg0_reg.write_en = %true : i1
// CHECK-NEXT: calyx.assign %ret_arg1_reg.in = %load_1_reg.out : i32
// CHECK-NEXT: calyx.assign %ret_arg1_reg.write_en = %true : i1
// CHECK-NEXT: %0 = comb.and %ret_arg0_reg.done, %ret_arg1_reg.done : i1
// CHECK-NEXT: calyx.group_done %0 ? %true : i1
// CHECK-NEXT: }
// CHECK: module attributes {calyx.entrypoint = "main"} {
// CHECK: calyx.component @main(%in0: i32, %in1: i32, %ext_mem0_read_data: i32 {mem = {id = 0 : i32, tag = "read_data"}}, %ext_mem0_done: i1 {mem = {id = 0 : i32, tag = "done"}}, %clk: i1 {clk}, %reset: i1 {reset}, %go: i1 {go}) -> (%ext_mem0_write_data: i32 {mem = {id = 0 : i32, tag = "write_data"}}, %ext_mem0_addr0: i3 {mem = {addr_idx = 0 : i32, id = 0 : i32, tag = "addr"}}, %ext_mem0_write_en: i1 {mem = {id = 0 : i32, tag = "write_en"}}, %out0: i32, %out1: i32, %done: i1 {done}) {
// CHECK-DAG: %true = hw.constant true
// CHECK-DAG: %std_slice_1.in, %std_slice_1.out = calyx.std_slice @std_slice_1 : i32, i3
// CHECK-DAG: %std_slice_0.in, %std_slice_0.out = calyx.std_slice @std_slice_0 : i32, i3
// CHECK-DAG: %load_1_reg.in, %load_1_reg.write_en, %load_1_reg.clk, %load_1_reg.reset, %load_1_reg.out, %load_1_reg.done = calyx.register @load_1_reg : i32, i1, i1, i1, i32, i1
// CHECK-DAG: %load_0_reg.in, %load_0_reg.write_en, %load_0_reg.clk, %load_0_reg.reset, %load_0_reg.out, %load_0_reg.done = calyx.register @load_0_reg : i32, i1, i1, i1, i32, i1
// CHECK-DAG: %ret_arg1_reg.in, %ret_arg1_reg.write_en, %ret_arg1_reg.clk, %ret_arg1_reg.reset, %ret_arg1_reg.out, %ret_arg1_reg.done = calyx.register @ret_arg1_reg : i32, i1, i1, i1, i32, i1
// CHECK-DAG: %ret_arg0_reg.in, %ret_arg0_reg.write_en, %ret_arg0_reg.clk, %ret_arg0_reg.reset, %ret_arg0_reg.out, %ret_arg0_reg.done = calyx.register @ret_arg0_reg : i32, i1, i1, i1, i32, i1
// CHECK-NEXT: calyx.wires {
// CHECK-NEXT: calyx.assign %out1 = %ret_arg1_reg.out : i32
// CHECK-NEXT: calyx.assign %out0 = %ret_arg0_reg.out : i32
// CHECK-NEXT: calyx.group @bb0_0 {
// CHECK-NEXT: calyx.assign %std_slice_1.in = %in0 : i32
// CHECK-NEXT: calyx.assign %ext_mem0_addr0 = %std_slice_1.out : i3
// CHECK-NEXT: calyx.assign %load_0_reg.in = %ext_mem0_read_data : i32
// CHECK-NEXT: calyx.assign %load_0_reg.write_en = %true : i1
// CHECK-NEXT: calyx.group_done %load_0_reg.done : i1
// CHECK-NEXT: }
// CHECK-NEXT: calyx.control {
// CHECK-NEXT: calyx.seq {
// CHECK-NEXT: calyx.enable @bb0_0
// CHECK-NEXT: calyx.enable @bb0_1
// CHECK-NEXT: calyx.enable @ret_assign_0
// CHECK-NEXT: }
// CHECK-NEXT: calyx.group @bb0_1 {
// CHECK-NEXT: calyx.assign %std_slice_0.in = %in1 : i32
// CHECK-NEXT: calyx.assign %ext_mem0_addr0 = %std_slice_0.out : i3
// CHECK-NEXT: calyx.assign %load_1_reg.in = %ext_mem0_read_data : i32
// CHECK-NEXT: calyx.assign %load_1_reg.write_en = %true : i1
// CHECK-NEXT: calyx.group_done %load_1_reg.done : i1
// CHECK-NEXT: }
// CHECK-NEXT: } {toplevel}
// CHECK-NEXT: }
// CHECK-NEXT: calyx.group @ret_assign_0 {
// CHECK-NEXT: calyx.assign %ret_arg0_reg.in = %load_0_reg.out : i32
// CHECK-NEXT: calyx.assign %ret_arg0_reg.write_en = %true : i1
// CHECK-NEXT: calyx.assign %ret_arg1_reg.in = %load_1_reg.out : i32
// CHECK-NEXT: calyx.assign %ret_arg1_reg.write_en = %true : i1
// CHECK-NEXT: %0 = comb.and %ret_arg0_reg.done, %ret_arg1_reg.done : i1
// CHECK-NEXT: calyx.group_done %0 ? %true : i1
// CHECK-NEXT: }
// CHECK-NEXT: }
// CHECK-NEXT: calyx.control {
// CHECK-NEXT: calyx.seq {
// CHECK-NEXT: calyx.enable @bb0_0
// CHECK-NEXT: calyx.enable @bb0_1
// CHECK-NEXT: calyx.enable @ret_assign_0
// CHECK-NEXT: }
// CHECK-NEXT: }
// CHECK-NEXT: } {toplevel}
// CHECK-NEXT: }
module {
func.func @main(%i0 : index, %i1 : index, %mem0 : memref<8xi32>) -> (i32, i32) {

View File

@ -1,34 +1,32 @@
// RUN: circt-opt %s --lower-scf-to-calyx -canonicalize -split-input-file | FileCheck %s
// CHECK: module {
// CHECK-NEXT: calyx.program "main" {
// CHECK-LABEL: calyx.component @main(%in0: i32, %in1: i32, %clk: i1 {clk}, %reset: i1 {reset}, %go: i1 {go}) -> (%out0: i32, %done: i1 {done}) {
// CHECK-DAG: %true = hw.constant true
// CHECK-DAG: %std_sub_0.left, %std_sub_0.right, %std_sub_0.out = calyx.std_sub @std_sub_0 : i32, i32, i32
// CHECK-DAG: %std_lsh_0.left, %std_lsh_0.right, %std_lsh_0.out = calyx.std_lsh @std_lsh_0 : i32, i32, i32
// CHECK-DAG: %std_add_0.left, %std_add_0.right, %std_add_0.out = calyx.std_add @std_add_0 : i32, i32, i32
// CHECK-DAG: %ret_arg0_reg.in, %ret_arg0_reg.write_en, %ret_arg0_reg.clk, %ret_arg0_reg.reset, %ret_arg0_reg.out, %ret_arg0_reg.done = calyx.register @ret_arg0_reg : i32, i1, i1, i1, i32, i1
// CHECK-NEXT: calyx.wires {
// CHECK-NEXT: calyx.assign %out0 = %ret_arg0_reg.out : i32
// CHECK-NEXT: calyx.group @ret_assign_0 {
// CHECK-NEXT: calyx.assign %ret_arg0_reg.in = %std_sub_0.out : i32
// CHECK-NEXT: calyx.assign %ret_arg0_reg.write_en = %true : i1
// CHECK-NEXT: calyx.assign %std_sub_0.left = %std_lsh_0.out : i32
// CHECK-NEXT: calyx.assign %std_lsh_0.left = %std_add_0.out : i32
// CHECK-NEXT: calyx.assign %std_add_0.left = %in0 : i32
// CHECK-NEXT: calyx.assign %std_add_0.right = %in1 : i32
// CHECK-NEXT: calyx.assign %std_lsh_0.right = %in0 : i32
// CHECK-NEXT: calyx.assign %std_sub_0.right = %std_add_0.out : i32
// CHECK-NEXT: calyx.group_done %ret_arg0_reg.done : i1
// CHECK-NEXT: }
// CHECK: module attributes {calyx.entrypoint = "main"} {
// CHECK-LABEL: calyx.component @main(%in0: i32, %in1: i32, %clk: i1 {clk}, %reset: i1 {reset}, %go: i1 {go}) -> (%out0: i32, %done: i1 {done}) {
// CHECK-DAG: %true = hw.constant true
// CHECK-DAG: %std_sub_0.left, %std_sub_0.right, %std_sub_0.out = calyx.std_sub @std_sub_0 : i32, i32, i32
// CHECK-DAG: %std_lsh_0.left, %std_lsh_0.right, %std_lsh_0.out = calyx.std_lsh @std_lsh_0 : i32, i32, i32
// CHECK-DAG: %std_add_0.left, %std_add_0.right, %std_add_0.out = calyx.std_add @std_add_0 : i32, i32, i32
// CHECK-DAG: %ret_arg0_reg.in, %ret_arg0_reg.write_en, %ret_arg0_reg.clk, %ret_arg0_reg.reset, %ret_arg0_reg.out, %ret_arg0_reg.done = calyx.register @ret_arg0_reg : i32, i1, i1, i1, i32, i1
// CHECK-NEXT: calyx.wires {
// CHECK-NEXT: calyx.assign %out0 = %ret_arg0_reg.out : i32
// CHECK-NEXT: calyx.group @ret_assign_0 {
// CHECK-NEXT: calyx.assign %ret_arg0_reg.in = %std_sub_0.out : i32
// CHECK-NEXT: calyx.assign %ret_arg0_reg.write_en = %true : i1
// CHECK-NEXT: calyx.assign %std_sub_0.left = %std_lsh_0.out : i32
// CHECK-NEXT: calyx.assign %std_lsh_0.left = %std_add_0.out : i32
// CHECK-NEXT: calyx.assign %std_add_0.left = %in0 : i32
// CHECK-NEXT: calyx.assign %std_add_0.right = %in1 : i32
// CHECK-NEXT: calyx.assign %std_lsh_0.right = %in0 : i32
// CHECK-NEXT: calyx.assign %std_sub_0.right = %std_add_0.out : i32
// CHECK-NEXT: calyx.group_done %ret_arg0_reg.done : i1
// CHECK-NEXT: }
// CHECK-NEXT: calyx.control {
// CHECK-NEXT: calyx.seq {
// CHECK-NEXT: calyx.enable @ret_assign_0
// CHECK-NEXT: }
// CHECK-NEXT: }
// CHECK-NEXT: calyx.control {
// CHECK-NEXT: calyx.seq {
// CHECK-NEXT: calyx.enable @ret_assign_0
// CHECK-NEXT: }
// CHECK-NEXT: } {toplevel}
// CHECK-NEXT: }
// CHECK-NEXT: }
// CHECK-NEXT: } {toplevel}
// CHECK-NEXT: }
module {
func.func @main(%a0 : i32, %a1 : i32) -> i32 {
@ -43,31 +41,29 @@ module {
// Test multiple return values.
// CHECK: module {
// CHECK-NEXT: calyx.program "main" {
// CHECK-LABEL: calyx.component @main(%in0: i32, %in1: i32, %clk: i1 {clk}, %reset: i1 {reset}, %go: i1 {go}) -> (%out0: i32, %out1: i32, %done: i1 {done}) {
// CHECK-DAG: %true = hw.constant true
// CHECK-DAG: %ret_arg1_reg.in, %ret_arg1_reg.write_en, %ret_arg1_reg.clk, %ret_arg1_reg.reset, %ret_arg1_reg.out, %ret_arg1_reg.done = calyx.register @ret_arg1_reg : i32, i1, i1, i1, i32, i1
// CHECK-DAG: %ret_arg0_reg.in, %ret_arg0_reg.write_en, %ret_arg0_reg.clk, %ret_arg0_reg.reset, %ret_arg0_reg.out, %ret_arg0_reg.done = calyx.register @ret_arg0_reg : i32, i1, i1, i1, i32, i1
// CHECK-NEXT: calyx.wires {
// CHECK-NEXT: calyx.assign %out1 = %ret_arg1_reg.out : i32
// CHECK-NEXT: calyx.assign %out0 = %ret_arg0_reg.out : i32
// CHECK-NEXT: calyx.group @ret_assign_0 {
// CHECK-NEXT: calyx.assign %ret_arg0_reg.in = %in0 : i32
// CHECK-NEXT: calyx.assign %ret_arg0_reg.write_en = %true : i1
// CHECK-NEXT: calyx.assign %ret_arg1_reg.in = %in1 : i32
// CHECK-NEXT: calyx.assign %ret_arg1_reg.write_en = %true : i1
// CHECK-NEXT: %0 = comb.and %ret_arg0_reg.done, %ret_arg1_reg.done : i1
// CHECK-NEXT: calyx.group_done %0 ? %true : i1
// CHECK-NEXT: }
// CHECK: module attributes {calyx.entrypoint = "main"} {
// CHECK-LABEL: calyx.component @main(%in0: i32, %in1: i32, %clk: i1 {clk}, %reset: i1 {reset}, %go: i1 {go}) -> (%out0: i32, %out1: i32, %done: i1 {done}) {
// CHECK-DAG: %true = hw.constant true
// CHECK-DAG: %ret_arg1_reg.in, %ret_arg1_reg.write_en, %ret_arg1_reg.clk, %ret_arg1_reg.reset, %ret_arg1_reg.out, %ret_arg1_reg.done = calyx.register @ret_arg1_reg : i32, i1, i1, i1, i32, i1
// CHECK-DAG: %ret_arg0_reg.in, %ret_arg0_reg.write_en, %ret_arg0_reg.clk, %ret_arg0_reg.reset, %ret_arg0_reg.out, %ret_arg0_reg.done = calyx.register @ret_arg0_reg : i32, i1, i1, i1, i32, i1
// CHECK-NEXT: calyx.wires {
// CHECK-NEXT: calyx.assign %out1 = %ret_arg1_reg.out : i32
// CHECK-NEXT: calyx.assign %out0 = %ret_arg0_reg.out : i32
// CHECK-NEXT: calyx.group @ret_assign_0 {
// CHECK-NEXT: calyx.assign %ret_arg0_reg.in = %in0 : i32
// CHECK-NEXT: calyx.assign %ret_arg0_reg.write_en = %true : i1
// CHECK-NEXT: calyx.assign %ret_arg1_reg.in = %in1 : i32
// CHECK-NEXT: calyx.assign %ret_arg1_reg.write_en = %true : i1
// CHECK-NEXT: %0 = comb.and %ret_arg0_reg.done, %ret_arg1_reg.done : i1
// CHECK-NEXT: calyx.group_done %0 ? %true : i1
// CHECK-NEXT: }
// CHECK-NEXT: calyx.control {
// CHECK-NEXT: calyx.seq {
// CHECK-NEXT: calyx.enable @ret_assign_0
// CHECK-NEXT: }
// CHECK-NEXT: }
// CHECK-NEXT: calyx.control {
// CHECK-NEXT: calyx.seq {
// CHECK-NEXT: calyx.enable @ret_assign_0
// CHECK-NEXT: }
// CHECK-NEXT: } {toplevel}
// CHECK-NEXT: }
// CHECK-NEXT: }
// CHECK-NEXT: } {toplevel}
// CHECK-NEXT: }
module {
func.func @main(%a0 : i32, %a1 : i32) -> (i32, i32) {

View File

@ -1,6 +1,6 @@
// RUN: circt-opt %s -lower-static-logic-to-calyx -split-input-file | FileCheck %s
// CHECK: calyx.program "minimal"
// CHECK: module attributes {calyx.entrypoint = "minimal"} {
// CHECK: calyx.component @minimal
// CHECK-DAG: %[[TRUE:.+]] = hw.constant true
// CHECK-DAG: %[[C0:.+]] = hw.constant 0 : i64
@ -53,7 +53,7 @@ func.func @minimal() {
// -----
// CHECK: calyx.program "dot"
// CHECK: module attributes {calyx.entrypoint = "dot"} {
// CHECK: calyx.component @dot(%[[MEM0_READ:.+]]: i32 {mem = {id = 0 : i32, tag = "read_data"}}, {{.+}}, %[[MEM1_READ:.+]]: i32 {mem = {id = 1 : i32, tag = "read_data"}}, {{.+}}) -> ({{.+}} %[[MEM0_ADDR:.+]]: i6 {mem = {addr_idx = 0 : i32, id = 0 : i32, tag = "addr"}}, {{.+}} %[[MEM1_ADDR:.+]]: i6 {mem = {addr_idx = 0 : i32, id = 1 : i32, tag = "addr"}}, {{.+}} %[[OUT:.+]]: i32, {{.+}}) {
// CHECK-DAG: %[[TRUE:.+]] = hw.constant true
// CHECK-DAG: %[[C0:.+]] = hw.constant 0 : i32
@ -191,6 +191,7 @@ func.func @dot(%arg0: memref<64xi32>, %arg1: memref<64xi32>) -> i32 {
// Verify that independent store operations are still pipelined.
// See: https://github.com/llvm/circt/issues/3112
// CHECK: module attributes {calyx.entrypoint = "store"} {
// CHECK: calyx.component @store({{.+}}, {{.+}}, {{.+}}, %[[MEM1_DONE:.+]]: i1 {mem = {id = 1 : i32, tag = "done"}}, {{.+}}) -> ({{.+}}, %[[MEM1_WRITE_DATA:.+]]: i32 {mem = {id = 1 : i32, tag = "write_data"}}, %[[MEM1_ADDR0:.+]]: i2 {mem = {addr_idx = 0 : i32, id = 1 : i32, tag = "addr"}}, %[[MEM1_WRITE_EN:.+]]: i1 {mem = {id = 1 : i32, tag = "write_en"}}, {{.+}}) {
// CHECK-DAG: %[[SLICE0_IN:.+]], %[[SLICE0_OUT:.+]] = calyx.std_slice @std_slice_0
// CHECK-DAG: {{.+}}, {{.+}}, {{.+}}, {{.+}}, %[[S0_REG0_OUT:.+]], {{.+}} = calyx.register @stage_0_register_0_reg
@ -217,6 +218,7 @@ func.func @dot(%arg0: memref<64xi32>, %arg1: memref<64xi32>) -> i32 {
// CHECK-NEXT: calyx.enable @[[STORE_GROUP1]]
// CHECK-NEXT: calyx.enable @[[STORE_GROUP2]]
// CHECK-NEXT: }
// CHECK-NEXT: }
module {
func.func @store(%arg0: memref<4xi32>, %arg1: memref<4xi32>) {
%c0 = arith.constant 0 : index

View File

@ -1,7 +1,7 @@
// RUN: circt-opt %s -canonicalize -split-input-file | FileCheck %s
// Nested SeqOps are collapsed.
calyx.program "main" {
module attributes {calyx.entrypoint = "main"} {
calyx.component @main(%go: i1 {go}, %clk: i1 {clk}, %reset: i1 {reset}) -> (%done: i1 {done}) {
%r.in, %r.write_en, %r.clk, %r.reset, %r.out, %r.done = calyx.register @r : i1, i1, i1, i1, i1, i1
%c1_1 = hw.constant 1 : i1
@ -30,7 +30,7 @@ calyx.program "main" {
// -----
// Nested ParOps are collapsed.
calyx.program "main" {
module attributes {calyx.entrypoint = "main"} {
calyx.component @main(%go: i1 {go}, %clk: i1 {clk}, %reset: i1 {reset}) -> (%done: i1 {done}) {
%r.in, %r.write_en, %r.clk, %r.reset, %r.out, %r.done = calyx.register @r : i1, i1, i1, i1, i1, i1
%c1_1 = hw.constant 1 : i1
@ -59,7 +59,7 @@ calyx.program "main" {
// -----
// IfOp nested in SeqOp removes common tail from within SeqOps.
calyx.program "main" {
module attributes {calyx.entrypoint = "main"} {
calyx.component @main(%go: i1 {go}, %clk: i1 {clk}, %reset: i1 {reset}) -> (%done: i1 {done}) {
%r.in, %r.write_en, %r.clk, %r.reset, %r.out, %r.done = calyx.register @r : i1, i1, i1, i1, i1, i1
%eq.left, %eq.right, %eq.out = calyx.std_eq @eq : i1, i1, i1
@ -120,7 +120,7 @@ calyx.program "main" {
// -----
// IfOp nested in ParOp removes common tails from within ParOps.
calyx.program "main" {
module attributes {calyx.entrypoint = "main"} {
calyx.component @main(%go: i1 {go}, %clk: i1 {clk}, %reset: i1 {reset}) -> (%done: i1 {done}) {
%r.in, %r.write_en, %r.clk, %r.reset, %r.out, %r.done = calyx.register @r : i1, i1, i1, i1, i1, i1
%eq.left, %eq.right, %eq.out = calyx.std_eq @eq : i1, i1, i1
@ -190,7 +190,7 @@ calyx.program "main" {
// IfOp nested in ParOp removes common tail from within SeqOps. The important check
// here is ensuring the removed EnableOps are still computed sequentially.
calyx.program "main" {
module attributes {calyx.entrypoint = "main"} {
calyx.component @main(%go: i1 {go}, %clk: i1 {clk}, %reset: i1 {reset}) -> (%done: i1 {done}) {
%r.in, %r.write_en, %r.clk, %r.reset, %r.out, %r.done = calyx.register @r : i1, i1, i1, i1, i1, i1
%eq.left, %eq.right, %eq.out = calyx.std_eq @eq : i1, i1, i1
@ -254,7 +254,7 @@ calyx.program "main" {
// IfOp nested in SeqOp removes common tail from within ParOps. The important check
// here is ensuring the removed EnableOps are still computed in parallel.
calyx.program "main" {
module attributes {calyx.entrypoint = "main"} {
calyx.component @main(%go: i1 {go}, %clk: i1 {clk}, %reset: i1 {reset}) -> (%done: i1 {done}) {
%r.in, %r.write_en, %r.clk, %r.reset, %r.out, %r.done = calyx.register @r : i1, i1, i1, i1, i1, i1
%eq.left, %eq.right, %eq.out = calyx.std_eq @eq : i1, i1, i1
@ -325,7 +325,7 @@ calyx.program "main" {
// -----
// Empty Then and Else regions lead to the removal of the IfOp (as well as unused cells and groups).
calyx.program "main" {
module attributes {calyx.entrypoint = "main"} {
calyx.component @main(%go: i1 {go}, %clk: i1 {clk}, %reset: i1 {reset}) -> (%done: i1 {done}) {
%r.in, %r.write_en, %r.clk, %r.reset, %r.out, %r.done = calyx.register @r : i1, i1, i1, i1, i1, i1
// CHECK-NOT: %eq.left, %eq.right, %eq.out = calyx.std_eq @eq : i1, i1, i1
@ -367,7 +367,7 @@ calyx.program "main" {
// -----
// Empty Then region and no Else region leads to removal of IfOp (as well as unused cells).
calyx.program "main" {
module attributes {calyx.entrypoint = "main"} {
calyx.component @main(%go: i1 {go}, %clk: i1 {clk}, %reset: i1 {reset}) -> (%done: i1 {done}) {
%r.in, %r.write_en, %r.clk, %r.reset, %r.out, %r.done = calyx.register @r : i1, i1, i1, i1, i1, i1
// CHECK-NOT: %eq.left, %eq.right, %eq.out = calyx.std_eq @eq : i1, i1, i1
@ -397,7 +397,7 @@ calyx.program "main" {
// -----
// Empty body leads to removal of WhileOp (as well as unused cells and groups).
calyx.program "main" {
module attributes {calyx.entrypoint = "main"} {
calyx.component @main(%go: i1 {go}, %clk: i1 {clk}, %reset: i1 {reset}) -> (%done: i1 {done}) {
%r.in, %r.write_en, %r.clk, %r.reset, %r.out, %r.done = calyx.register @r : i1, i1, i1, i1, i1, i1
// CHECK: %eq.left, %eq.right, %eq.out = calyx.std_eq @eq : i1, i1, i1
@ -433,7 +433,7 @@ calyx.program "main" {
// -----
// Empty ParOp and SeqOp are removed.
calyx.program "main" {
module attributes {calyx.entrypoint = "main"} {
calyx.component @main(%go: i1 {go}, %clk: i1 {clk}, %reset: i1 {reset}) -> (%done: i1 {done}) {
%r.in, %r.write_en, %r.clk, %r.reset, %r.out, %r.done = calyx.register @r : i1, i1, i1, i1, i1, i1
%c1_1 = hw.constant 1 : i1
@ -462,7 +462,7 @@ calyx.program "main" {
// -----
// Unary control operations are collapsed.
calyx.program "main" {
module attributes {calyx.entrypoint = "main"} {
calyx.component @main(%go: i1 {go}, %clk: i1 {clk}, %reset: i1 {reset}) -> (%done: i1 {done}) {
%r.in, %r.write_en, %r.clk, %r.reset, %r.out, %r.done = calyx.register @r : i1, i1, i1, i1, i1, i1
%c1_1 = hw.constant 1 : i1

View File

@ -1,6 +1,6 @@
// RUN: circt-opt -pass-pipeline='calyx.program(calyx.component(calyx-clk-insertion,calyx-reset-insertion))' %s | FileCheck %s
// RUN: circt-opt -pass-pipeline='calyx.component(calyx-clk-insertion,calyx-reset-insertion)' %s | FileCheck %s
calyx.program "main" {
module attributes {calyx.entrypoint = "main"} {
calyx.component @A(%in: i8, %go: i1 {go}, %clk: i1 {clk}, %reset: i1 {reset}) -> (%out: i8, %done: i1 {done}) {
%c1_1 = hw.constant 1 : i1
calyx.wires { calyx.assign %done = %c1_1 : i1 }

View File

@ -1,6 +1,6 @@
// RUN: circt-opt -pass-pipeline='calyx.program(calyx.component(calyx-compile-control))' %s | FileCheck %s
// RUN: circt-opt -pass-pipeline='calyx.component(calyx-compile-control)' %s | FileCheck %s
calyx.program "main" {
module attributes {calyx.entrypoint = "main"} {
calyx.component @Z(%go : i1 {go}, %reset : i1 {reset}, %clk : i1 {clk}) -> (%flag :i1, %done : i1 {done}) {
%c1_1 = hw.constant 1 : i1
calyx.wires { calyx.assign %done = %c1_1 : i1 }

View File

@ -1,9 +1,8 @@
// RUN: circt-translate --export-calyx --verify-diagnostics %s | FileCheck %s --strict-whitespace
module attributes {calyx.metadata = ["location1", "location2"]} {
module attributes {calyx.metadata = ["location1", "location2"], calyx.entrypoint = "main"} {
// CHECK: import "primitives/core.futil";
calyx.program "main" {
// CHECK: import "primitives/core.futil";
// CHECK-LABEL: component A<"static"=1>(in: 32, @go go: 1, @clk clk: 1, @reset reset: 1) -> (out: 32, @done done: 1) {
calyx.component @A(%in: i32, %go: i1 {go = 1}, %clk: i1 {clk = 1}, %reset: i1 {reset = 1}) -> (%out: i32, %done: i1 {done = 1}) {
%c1_1 = hw.constant 1 : i1
@ -199,7 +198,6 @@ calyx.program "main" {
}
}
}
}
// CHECK-LABEL: metadata #{
// CHECK-NEXT: 0: location1

View File

@ -1,12 +1,10 @@
// RUN: circt-opt %s -split-input-file -verify-diagnostics
// expected-error @+1 {{'calyx.program' op has undefined entry-point component: "main".}}
calyx.program "main" {}
module attributes {calyx.entrypoint = "main"} {}
// -----
// expected-error @+1 {{'calyx.program' op has undefined entry-point component: "foo".}}
calyx.program "foo" {
module attributes {calyx.entrypoint = "foo"} {
calyx.component @bar(%in: i16, %go: i1 {go}, %clk: i1 {clk}, %reset: i1 {reset}) -> (%done: i1 {done}) {
%c1_1 = hw.constant 1 : i1
calyx.wires { calyx.assign %done = %c1_1 : i1 }
@ -16,7 +14,7 @@ calyx.program "foo" {
// -----
calyx.program "main" {
module attributes {calyx.entrypoint = "main"} {
calyx.component @foo(%go: i1 {go}, %clk: i1 {clk}, %reset: i1 {reset}) -> (%done: i1 {done}) {
// expected-error @+1 {{'calyx.instance' op cannot reference the entry-point component: 'main'.}}
calyx.instance @c of @main : i16, i1, i1, i1, i1
@ -33,7 +31,7 @@ calyx.program "main" {
// -----
calyx.program "main" {
module attributes {calyx.entrypoint = "main"} {
calyx.component @foo(%go: i1 {go}, %clk: i1 {clk}, %reset: i1 {reset}) -> (%done: i1 {done}) {
%c1_1 = hw.constant 1 : i1
calyx.wires { calyx.assign %done = %c1_1 : i1 }
@ -52,7 +50,7 @@ calyx.program "main" {
// -----
calyx.program "main" {
module attributes {calyx.entrypoint = "main"} {
calyx.component @foo(%go: i1 {go}, %clk: i1 {clk}, %reset: i1 {reset}) -> (%done: i1 {done}) {
%c1_1 = hw.constant 1 : i1
calyx.wires { calyx.assign %done = %c1_1 : i1 }
@ -69,7 +67,7 @@ calyx.program "main" {
// -----
calyx.program "main" {
module attributes {calyx.entrypoint = "main"} {
// expected-error @+1 {{'calyx.component' op requires exactly one of each: 'calyx.wires', 'calyx.control'.}}
calyx.component @main(%go: i1 {go}, %clk: i1 {clk}, %reset: i1 {reset}) -> (%done: i1 {done}) {
calyx.control {}
@ -78,7 +76,7 @@ calyx.program "main" {
// -----
calyx.program "main" {
module attributes {calyx.entrypoint = "main"} {
calyx.component @main(%go: i1 {go}, %clk: i1 {clk}, %reset: i1 {reset}) -> (%done: i1 {done}) {
// expected-error @+1 {{referencing component: 'A', which does not exist.}}
calyx.instance @c of @A
@ -90,7 +88,7 @@ calyx.program "main" {
// -----
calyx.program "main" {
module attributes {calyx.entrypoint = "main"} {
calyx.component @main(%go: i1 {go}, %clk: i1 {clk}, %reset: i1 {reset}) -> (%done: i1 {done}) {
// expected-error @+1 {{recursive instantiation of its parent component: 'main'}}
calyx.instance @c of @main : i1, i1, i1, i1
@ -102,7 +100,7 @@ calyx.program "main" {
// -----
calyx.program "main" {
module attributes {calyx.entrypoint = "main"} {
calyx.component @A(%in: i16, %go: i1 {go}, %clk: i1 {clk}, %reset: i1 {reset}) -> (%done: i1 {done}) {
%c1_1 = hw.constant 1 : i1
calyx.wires { calyx.assign %done = %c1_1 : i1 }
@ -119,7 +117,7 @@ calyx.program "main" {
// -----
calyx.program "main" {
module attributes {calyx.entrypoint = "main"} {
calyx.component @B(%in: i16, %go: i1 {go}, %clk: i1 {clk}, %reset: i1 {reset}) -> (%done: i1 {done}) {
%c1_1 = hw.constant 1 : i1
calyx.wires { calyx.assign %done = %c1_1 : i1 }
@ -135,7 +133,7 @@ calyx.program "main" {
// -----
calyx.program "main" {
module attributes {calyx.entrypoint = "main"} {
calyx.component @A(%go: i1 {go}, %clk: i1 {clk}, %reset: i1 {reset}) -> (%out: i16, %done: i1 {done}) {
%c1_1 = hw.constant 1 : i1
calyx.wires { calyx.assign %done = %c1_1 : i1 }
@ -159,7 +157,7 @@ calyx.program "main" {
// -----
calyx.program "main" {
module attributes {calyx.entrypoint = "main"} {
calyx.component @main(%go: i1 {go}, %clk: i1 {clk}, %reset: i1 {reset}) -> (%done: i1 {done}) {
calyx.wires {}
calyx.control {
@ -173,7 +171,7 @@ calyx.program "main" {
// -----
calyx.program "main" {
module attributes {calyx.entrypoint = "main"} {
calyx.component @main(%go: i1 {go}, %clk: i1 {clk}, %reset: i1 {reset}) -> (%done: i1 {done}) {
%r.in, %r.write_en, %r.clk, %r.reset, %r.out, %r.done = calyx.register @r : i1, i1, i1, i1, i1, i1
%c1_1 = hw.constant 1 : i1
@ -194,7 +192,7 @@ calyx.program "main" {
// -----
calyx.program "main" {
module attributes {calyx.entrypoint = "main"} {
calyx.component @main(%go: i1 {go}, %clk: i1 {clk}, %reset: i1 {reset}) -> (%done: i1 {done}) {
%r.in, %r.write_en, %r.clk, %r.reset, %r.out, %r.done = calyx.register @r : i1, i1, i1, i1, i1, i1
%c1_1 = hw.constant 1 : i1
@ -213,7 +211,7 @@ calyx.program "main" {
// -----
calyx.program "main" {
module attributes {calyx.entrypoint = "main"} {
calyx.component @A(%go: i1 {go}, %clk: i1 {clk}, %reset: i1 {reset}) -> (%out: i1, %done: i1 {done}) {
%r.in, %r.write_en, %r.clk, %r.reset, %r.out, %r.done = calyx.register @r : i8, i1, i1, i1, i8, i1
calyx.wires {
@ -248,7 +246,7 @@ calyx.program "main" {
// -----
calyx.program "main" {
module attributes {calyx.entrypoint = "main"} {
calyx.component @A(%go: i1 {go}, %clk: i1 {clk}, %reset: i1 {reset}) -> (%out: i1, %done: i1 {done}) {
%c1_1 = hw.constant 1 : i1
calyx.wires { calyx.assign %done = %c1_1 : i1 }
@ -276,7 +274,7 @@ calyx.program "main" {
// -----
calyx.program "main" {
module attributes {calyx.entrypoint = "main"} {
calyx.component @A(%in: i1, %go: i1 {go}, %clk: i1 {clk}, %reset: i1 {reset}) -> (%out: i1, %done: i1 {done}) {
%c1_1 = hw.constant 1 : i1
calyx.wires { calyx.assign %done = %c1_1 : i1 }
@ -307,7 +305,7 @@ calyx.program "main" {
// -----
calyx.program "main" {
module attributes {calyx.entrypoint = "main"} {
calyx.component @A(%go: i1 {go}, %clk: i1 {clk}, %reset: i1 {reset}) -> (%out: i1, %done: i1 {done}) {
%c1_1 = hw.constant 1 : i1
calyx.wires { calyx.assign %done = %c1_1 : i1 }
@ -330,7 +328,7 @@ calyx.program "main" {
// -----
calyx.program "main" {
module attributes {calyx.entrypoint = "main"} {
calyx.component @A(%in: i1, %go: i1 {go}, %clk: i1 {clk}, %reset: i1 {reset}) -> (%out: i1, %done: i1 {done}) {
%c1_1 = hw.constant 1 : i1
calyx.wires { calyx.assign %done = %c1_1 : i1 }
@ -361,7 +359,7 @@ calyx.program "main" {
// -----
calyx.program "main" {
module attributes {calyx.entrypoint = "main"} {
calyx.component @main(%go: i1 {go}, %clk: i1 {clk}, %reset: i1 {reset}) -> (%done: i1 {done}) {
// expected-error @+1 {{'calyx.memory' op mismatched number of dimensions (1) and address sizes (2)}}
%m.addr0, %m.write_data, %m.write_en, %m.clk, %m.read_data, %m.done = calyx.memory @m <[64] x 8> [6, 6] : i6, i8, i1, i1, i8, i1
@ -372,7 +370,7 @@ calyx.program "main" {
// -----
calyx.program "main" {
module attributes {calyx.entrypoint = "main"} {
calyx.component @main(%go: i1 {go}, %clk: i1 {clk}, %reset: i1 {reset}) -> (%done: i1 {done}) {
// expected-error @+1 {{'calyx.memory' op incorrect number of address ports, expected 2}}
%m.addr0, %m.write_data, %m.write_en, %m.clk, %m.read_data, %m.done = calyx.memory @m <[64, 64] x 8> [6, 6] : i6, i8, i1, i1, i8, i1
@ -383,7 +381,7 @@ calyx.program "main" {
// -----
calyx.program "main" {
module attributes {calyx.entrypoint = "main"} {
calyx.component @main(%go: i1 {go}, %clk: i1 {clk}, %reset: i1 {reset}) -> (%done: i1 {done}) {
// expected-error @+1 {{'calyx.memory' op address size (5) for dimension 0 can't address the entire range (64)}}
%m.addr0, %m.write_data, %m.write_en, %m.clk, %m.read_data, %m.done = calyx.memory @m <[64] x 8> [5] : i5, i8, i1, i1, i5, i1
@ -394,7 +392,7 @@ calyx.program "main" {
// -----
calyx.program "main" {
module attributes {calyx.entrypoint = "main"} {
calyx.component @main(%go: i1 {go}, %clk: i1 {clk}, %reset: i1 {reset}) -> (%done: i1 {done}) {
%c1_1 = hw.constant 1 : i1
calyx.wires {
@ -407,7 +405,7 @@ calyx.program "main" {
// -----
calyx.program "main" {
module attributes {calyx.entrypoint = "main"} {
calyx.component @main(%go: i1 {go}, %clk: i1 {clk}, %reset: i1 {reset}) -> (%done: i1 {done}) {
%c1_1 = hw.constant 1 : i1
calyx.wires {
@ -420,7 +418,7 @@ calyx.program "main" {
// -----
calyx.program "main" {
module attributes {calyx.entrypoint = "main"} {
calyx.component @main(%go: i1 {go}, %clk: i1 {clk}, %reset: i1 {reset}) -> (%done: i1 {done}) {
%r.in, %r.write_en, %r.clk, %r.reset, %r.out, %r.done = calyx.register @r : i8, i1, i1, i1, i8, i1
calyx.wires {
@ -433,7 +431,7 @@ calyx.program "main" {
// -----
calyx.program "main" {
module attributes {calyx.entrypoint = "main"} {
calyx.component @main(%go: i1 {go}, %clk: i1 {clk}, %reset: i1 {reset}) -> (%done: i1 {done}) {
%r.in, %r.write_en, %r.clk, %r.reset, %r.out, %r.done = calyx.register @r : i8, i1, i1, i1, i8, i1
calyx.wires {
@ -446,7 +444,7 @@ calyx.program "main" {
// -----
calyx.program "main" {
module attributes {calyx.entrypoint = "main"} {
calyx.component @main(%go: i1 {go}, %clk: i1 {clk}, %reset: i1 {reset}) -> (%done: i1 {done}) {
%r.in, %r.write_en, %r.clk, %r.reset, %r.out, %r.done = calyx.register @r : i8, i1, i1, i1, i8, i1
calyx.wires {
@ -459,7 +457,7 @@ calyx.program "main" {
// -----
calyx.program "main" {
module attributes {calyx.entrypoint = "main"} {
calyx.component @main(%go: i1 {go}, %clk: i1 {clk}, %reset: i1 {reset}) -> (%done: i1 {done}) {
%r.in, %r.write_en, %r.clk, %r.reset, %r.out, %r.done = calyx.register @r : i1, i1, i1, i1, i1, i1
%c1_1 = hw.constant 1 : i1
@ -480,7 +478,7 @@ calyx.program "main" {
// -----
calyx.program "main" {
module attributes {calyx.entrypoint = "main"} {
calyx.component @main(%go: i1 {go}, %clk: i1 {clk}, %reset: i1 {reset}) -> (%done: i1 {done}) {
%r.in, %r.write_en, %r.clk, %r.reset, %r.out, %r.done = calyx.register @r : i1, i1, i1, i1, i1, i1
%c1_1 = hw.constant 1 : i1
@ -503,7 +501,7 @@ calyx.program "main" {
// -----
calyx.program "main" {
module attributes {calyx.entrypoint = "main"} {
calyx.component @A(%go: i1 {go}, %clk: i1 {clk}, %reset: i1 {reset}) -> (%out: i1, %done: i1 {done}) {
%c1_1 = hw.constant 1 : i1
calyx.wires { calyx.assign %done = %c1_1 : i1 }
@ -531,7 +529,7 @@ calyx.program "main" {
// -----
calyx.program "main" {
module attributes {calyx.entrypoint = "main"} {
calyx.component @A(%go: i1 {go}, %clk: i1 {clk}, %reset: i1 {reset}) -> (%out: i1, %done: i1 {done}) {
%c1_1 = hw.constant 1 : i1
calyx.wires { calyx.assign %done = %c1_1 : i1 }
@ -559,7 +557,7 @@ calyx.program "main" {
// -----
calyx.program "main" {
module attributes {calyx.entrypoint = "main"} {
calyx.component @A(%go: i1 {go}, %clk: i1 {clk}, %reset: i1 {reset}) -> (%out: i1, %done: i1 {done}) {
%c1_1 = hw.constant 1 : i1
calyx.wires { calyx.assign %done = %c1_1 : i1 }
@ -582,7 +580,7 @@ calyx.program "main" {
// -----
calyx.program "main" {
module attributes {calyx.entrypoint = "main"} {
// expected-error @+1 {{'calyx.component' op is missing the following required port attribute identifiers: done, go}}
calyx.component @main(%go: i1, %clk: i1 {clk}, %reset: i1 {reset}) -> (%done: i1) {
%c1_1 = hw.constant 1 : i1
@ -593,7 +591,7 @@ calyx.program "main" {
// -----
calyx.program "main" {
module attributes {calyx.entrypoint = "main"} {
calyx.component @main(%go: i1 {go}, %clk: i1 {clk}, %reset: i1 {reset}) -> (%done: i1 {done}) {
%r.in, %r.write_en, %r.clk, %r.reset, %r.out, %r.done = calyx.register @r : i1, i1, i1, i1, i1, i1
%c1_1 = hw.constant 1 : i1
@ -610,7 +608,7 @@ calyx.program "main" {
// -----
calyx.program "main" {
module attributes {calyx.entrypoint = "main"} {
calyx.component @main(%go: i1 {go}, %clk: i1 {clk}, %reset: i1 {reset}) -> (%done: i1 {done}) {
%m.addr0, %m.addr1, %m.write_data, %m.write_en, %m.clk, %m.read_data, %m.done = calyx.memory @m <[64, 64] x 8> [6, 6] : i6, i6, i8, i1, i1, i8, i1
%c1_i8 = hw.constant 1 : i8
@ -627,7 +625,7 @@ calyx.program "main" {
// -----
calyx.program "main" {
module attributes {calyx.entrypoint = "main"} {
calyx.component @main(%go: i1 {go}, %clk: i1 {clk}, %reset: i1 {reset}) -> (%done: i1 {done}) {
%gt.left, %gt.right, %gt.out = calyx.std_gt @gt : i8, i8, i1
%r.in, %r.write_en, %r.clk, %r.reset, %r.out, %r.done = calyx.register @r : i1, i1, i1, i1, i1, i1
@ -648,7 +646,7 @@ calyx.program "main" {
// -----
calyx.program "main" {
module attributes {calyx.entrypoint = "main"} {
calyx.component @main(%go: i1 {go}, %clk: i1 {clk}, %reset: i1 {reset}) -> (%done: i1 {done}) {
%m.addr0, %m.addr1, %m.write_data, %m.write_en, %m.clk, %m.read_data, %m.done = calyx.memory @m <[64, 64] x 8> [6, 6] : i6, i6, i8, i1, i1, i8, i1
%r.in, %r.write_en, %r.clk, %r.reset, %r.out, %r.done = calyx.register @r : i8, i1, i1, i1, i8, i1
@ -667,7 +665,7 @@ calyx.program "main" {
// -----
calyx.program "main" {
module attributes {calyx.entrypoint = "main"} {
calyx.component @main(%go: i1 {go}, %clk: i1 {clk}, %reset: i1 {reset}) -> (%done: i1 {done}) {
%r.in, %r.write_en, %r.clk, %r.reset, %r.out, %r.done = calyx.register @r : i1, i1, i1, i1, i1, i1
%c1_1 = hw.constant 1 : i1
@ -695,7 +693,7 @@ calyx.program "main" {
// -----
calyx.program "main" {
module attributes {calyx.entrypoint = "main"} {
calyx.component @main(%go: i1 {go}, %clk: i1 {clk}, %reset: i1 {reset}) -> (%done: i1 {done}) {
%m.addr0, %m.addr1, %m.write_data, %m.write_en, %m.clk, %m.read_data, %m.done = calyx.memory @m <[64, 64] x 8> [6, 6] : i6, i6, i8, i1, i1, i8, i1
%r.in, %r.write_en, %r.clk, %r.reset, %r.out, %r.done = calyx.register @r : i1, i1, i1, i1, i1, i1
@ -728,7 +726,7 @@ calyx.program "main" {
// -----
calyx.program "main" {
module attributes {calyx.entrypoint = "main"} {
calyx.component @main(%go: i1 {go}, %clk: i1 {clk}, %reset: i1 {reset}) -> (%done: i1 {done}) {
%r.in, %r.write_en, %r.clk, %r.reset, %r.out, %r.done = calyx.register @r : i1, i1, i1, i1, i1, i1
%c1_1 = hw.constant 1 : i1
@ -747,7 +745,7 @@ calyx.program "main" {
// -----
calyx.program "main" {
module attributes {calyx.entrypoint = "main"} {
calyx.component @main(%go: i1 {go}, %clk: i1 {clk}, %reset: i1 {reset}) -> (%done: i1 {done}) {
%r.in, %r.write_en, %r.clk, %r.reset, %r.out, %r.done = calyx.register @r : i1, i1, i1, i1, i1, i1
%c1_1 = hw.constant 1 : i1
@ -766,7 +764,7 @@ calyx.program "main" {
// -----
calyx.program "main" {
module attributes {calyx.entrypoint = "main"} {
calyx.component @main(%go: i1 {go}, %clk: i1 {clk}, %reset: i1 {reset}) -> (%done: i1 {done}) {
%r.in, %r.write_en, %r.clk, %r.reset, %r.out, %r.done = calyx.register @r : i1, i1, i1, i1, i1, i1
%c1_1 = hw.constant 1 : i1
@ -786,7 +784,7 @@ calyx.program "main" {
// -----
calyx.program "main" {
module attributes {calyx.entrypoint = "main"} {
calyx.component @main(%go: i1 {go}, %clk: i1 {clk}, %reset: i1 {reset}) -> (%done: i1 {done}) {
%c1_1 = hw.constant 1 : i1
calyx.wires {
@ -801,7 +799,7 @@ calyx.program "main" {
// -----
calyx.program "main" {
module attributes {calyx.entrypoint = "main"} {
calyx.component @main(%go: i1 {go}, %clk: i1 {clk}, %reset: i1 {reset}) -> (%done: i1 {done}) {
// expected-error @+1 {{'calyx.std_slice' op expected input bits (32) to be greater than output bits (64)}}
%std_slice.in, %std_slice.out = calyx.std_slice @std_slice : i32, i64
@ -813,7 +811,7 @@ calyx.program "main" {
// -----
calyx.program "main" {
module attributes {calyx.entrypoint = "main"} {
calyx.component @main(%go: i1 {go}, %clk: i1 {clk}, %reset: i1 {reset}) -> (%done: i1 {done}) {
// expected-error @+1 {{'calyx.std_pad' op expected input bits (64) to be less than output bits (32)}}
%std_pad.in, %std_pad.out = calyx.std_pad @std_pad : i64, i32
@ -825,7 +823,7 @@ calyx.program "main" {
// -----
calyx.program "main" {
module attributes {calyx.entrypoint = "main"} {
calyx.component @main(%go: i1 {go}, %clk: i1 {clk}, %reset: i1 {reset}) -> (%done: i1 {done}) {
%std_lt_0.left, %std_lt_0.right, %std_lt_0.out = calyx.std_lt @std_lt_0 : i32, i32, i1
%c64_i32 = hw.constant 64 : i32
@ -843,7 +841,7 @@ calyx.program "main" {
// -----
calyx.program "main" {
module attributes {calyx.entrypoint = "main"} {
calyx.component @main(%go: i1 {go}, %clk: i1 {clk}, %reset: i1 {reset}) -> (%done: i1 {done}) {
%std_lt_0.left, %std_lt_0.right, %std_lt_0.out = calyx.std_lt @std_lt_0 : i32, i32, i1
%c64_i32 = hw.constant 64 : i32

View File

@ -1,6 +1,6 @@
// RUN: circt-translate -split-input-file --export-calyx --verify-diagnostics %s
calyx.program "main" {
module attributes {calyx.entrypoint = "main"} {
calyx.component @main(%in0: i4, %clk: i1 {clk}, %reset: i1 {reset}, %go: i1 {go}) -> (%out0: i8, %done: i1 {done}) {
%true = hw.constant true
// expected-error @+2 {{'calyx.std_extsi' op not supported for emission}}

View File

@ -1,6 +1,6 @@
// RUN: circt-opt -pass-pipeline='calyx.program(calyx.component(calyx-gicm))' %s | FileCheck %s
// RUN: circt-opt -pass-pipeline='calyx.component(calyx-gicm)' %s | FileCheck %s
calyx.program "main" {
module attributes {calyx.entrypoint = "main"} {
calyx.component @main(%go: i1 {go}, %clk: i1 {clk}, %reset: i1 {reset}) -> (%done: i1 {done}) {
%add.left, %add.right, %add.out = calyx.std_add @add : i8, i8, i8
%r.in, %r.write_en, %r.clk, %r.reset, %r.out, %r.done = calyx.register @r : i8, i1, i1, i1, i8, i1

View File

@ -1,6 +1,6 @@
// RUN: circt-opt -pass-pipeline='calyx.program(calyx.component(calyx-go-insertion))' %s | FileCheck %s
// RUN: circt-opt -pass-pipeline='calyx.component(calyx-go-insertion)' %s | FileCheck %s
calyx.program "main" {
module attributes {calyx.entrypoint = "main"} {
calyx.component @A(%in: i8, %go: i1 {go}, %clk: i1 {clk}, %reset: i1 {reset}) -> (%out: i8, %done: i1 {done}) {
%c1_1 = hw.constant 1 : i1
calyx.wires { calyx.assign %done = %c1_1 : i1 }

View File

@ -1,6 +1,6 @@
// RUN: circt-opt -pass-pipeline='calyx.program(calyx.component(calyx-remove-groups))' %s | FileCheck %s
// RUN: circt-opt -pass-pipeline='calyx.component(calyx-remove-groups)' %s | FileCheck %s
calyx.program "main" {
module attributes {calyx.entrypoint = "main"} {
calyx.component @Z(%go: i1 {go}, %reset: i1 {reset}, %clk: i1 {clk}) -> (%flag: i1, %out :i2, %done: i1 {done}) {
%c1_1 = hw.constant 1 : i1
calyx.wires { calyx.assign %done = %c1_1 : i1 }

View File

@ -1,7 +1,7 @@
// RUN: circt-opt %s -verify-diagnostics | circt-opt -verify-diagnostics | FileCheck %s
// CHECK: calyx.program "main" {
calyx.program "main" {
// CHECK: module attributes {calyx.entrypoint = "main"} {
module attributes {calyx.entrypoint = "main"} {
// CHECK-LABEL: calyx.component @A(%in: i8, %go: i1 {go}, %clk: i1 {clk}, %reset: i1 {reset}) -> (%out: i8, %done: i1 {done}) {
calyx.component @A(%in: i8, %go: i1 {go}, %clk: i1 {clk}, %reset: i1 {reset}) -> (%out: i8, %done: i1 {done}) {
%c1_1 = hw.constant 1 : i1