Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

[HW][SV] Transition "HWToSV" to "ProceduralCoreToSV" pass. #7335

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 0 additions & 38 deletions include/circt/Conversion/HWToSV.h

This file was deleted.

2 changes: 1 addition & 1 deletion include/circt/Conversion/Passes.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@
#include "circt/Conversion/HWToLLHD.h"
#include "circt/Conversion/HWToLLVM.h"
#include "circt/Conversion/HWToSMT.h"
#include "circt/Conversion/HWToSV.h"
#include "circt/Conversion/HWToSystemC.h"
#include "circt/Conversion/HandshakeToDC.h"
#include "circt/Conversion/HandshakeToHW.h"
Expand All @@ -41,6 +40,7 @@
#include "circt/Conversion/LoopScheduleToCalyx.h"
#include "circt/Conversion/MooreToCore.h"
#include "circt/Conversion/PipelineToHW.h"
#include "circt/Conversion/ProceduralCoreToSV.h"
#include "circt/Conversion/SCFToCalyx.h"
#include "circt/Conversion/SMTToZ3LLVM.h"
#include "circt/Conversion/SeqToSV.h"
Expand Down
10 changes: 5 additions & 5 deletions include/circt/Conversion/Passes.td
Original file line number Diff line number Diff line change
Expand Up @@ -589,15 +589,15 @@ def ConvertHWToSystemC : Pass<"convert-hw-to-systemc", "mlir::ModuleOp"> {
}

//===----------------------------------------------------------------------===//
// HWToSV
// ProceduralCoreToSV
//===----------------------------------------------------------------------===//

def LowerHWToSV : Pass<"lower-hw-to-sv", "hw::HWModuleOp"> {
let summary = "Convert HW to SV";
def ProceduralCoreToSV : Pass<"lower-procedural-core-to-sv", "hw::HWModuleOp"> {
let summary = "Lower procedural core dialect operations to SV";
let description = [{
This pass converts various HW contructs to SV.
This pass lowers procedural 'hw.triggered' operations and their body
regions to the SystemVerilog dialect.
}];
let constructor = "circt::createLowerHWToSVPass()";
let dependentDialects = ["sv::SVDialect"];
}

Expand Down
26 changes: 26 additions & 0 deletions include/circt/Conversion/ProceduralCoreToSV.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
//===- ProceduralCoreToSV.h - Porcedural Core to SV pass entry point ------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This header file defines prototypes that expose the declarations for the
// procedural core to SV lowering pass.
//
//===----------------------------------------------------------------------===//

#ifndef CIRCT_CONVERSION_PROCEDURALCORETOSV_H
#define CIRCT_CONVERSION_PROCEDURALCORETOSV_H

#include "circt/Support/LLVM.h"
#include <memory>
namespace circt {

#define GEN_PASS_DECL_PROCEDURALCORETOSV
#include "circt/Conversion/Passes.h.inc"

} // namespace circt

#endif // CIRCT_CONVERSION_PROCEDURALCORETOSV_H
3 changes: 3 additions & 0 deletions include/circt/Dialect/HW/HWStructure.td
Original file line number Diff line number Diff line change
Expand Up @@ -730,6 +730,9 @@ def TriggeredOp : HWOp<"triggered", [
let builders = [
OpBuilder<(ins "EventControlAttr":$event, "Value":$trigger, "ValueRange":$inputs)>
];

let hasVerifier = 1;
let hasRegionVerifier = 1;
}

#endif // CIRCT_DIALECT_HW_HWSTRUCTURE_TD
2 changes: 1 addition & 1 deletion lib/CAPI/Conversion/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,13 @@ add_circt_public_c_api_library(CIRCTCAPIConversion
CIRCTHWToLLVM
CIRCTHWToBTOR2
CIRCTHWToSMT
CIRCTHWToSV
CIRCTHWToSystemC
CIRCTLLHDToLLVM
CIRCTLoopScheduleToCalyx
CIRCTLTLToCore
CIRCTMooreToCore
CIRCTPipelineToHW
CIRCTProceduralCoreToSV
CIRCTSCFToCalyx
CIRCTSeqToSV
CIRCTSimToSV
Expand Down
2 changes: 1 addition & 1 deletion lib/Conversion/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@ add_subdirectory(HWToBTOR2)
add_subdirectory(HWToLLHD)
add_subdirectory(HWToLLVM)
add_subdirectory(HWToSMT)
add_subdirectory(HWToSV)
add_subdirectory(HWToSystemC)
add_subdirectory(LLHDToLLVM)
add_subdirectory(LoopScheduleToCalyx)
add_subdirectory(MooreToCore)
add_subdirectory(PipelineToHW)
add_subdirectory(ProceduralCoreToSV)
add_subdirectory(SCFToCalyx)
add_subdirectory(SeqToSV)
add_subdirectory(SimToSV)
Expand Down
88 changes: 0 additions & 88 deletions lib/Conversion/HWToSV/HWToSV.cpp

This file was deleted.

1 change: 0 additions & 1 deletion lib/Conversion/LTLToCore/LTLToCore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
//===----------------------------------------------------------------------===//

#include "circt/Conversion/LTLToCore.h"
#include "circt/Conversion/HWToSV.h"
#include "circt/Dialect/Comb/CombOps.h"
#include "circt/Dialect/HW/HWOps.h"
#include "circt/Dialect/LTL/LTLDialect.h"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
add_circt_conversion_library(CIRCTHWToSV
HWToSV.cpp
add_circt_conversion_library(CIRCTProceduralCoreToSV
ProceduralCoreToSV.cpp

DEPENDS
CIRCTConversionPassIncGen
Expand All @@ -9,7 +9,7 @@ add_circt_conversion_library(CIRCTHWToSV

LINK_LIBS PUBLIC
CIRCTHW
CIRCTSim
CIRCTSV
MLIREmitCDialect
MLIRTransforms
)
75 changes: 75 additions & 0 deletions lib/Conversion/ProceduralCoreToSV/ProceduralCoreToSV.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
//===- ProceduralCoreToSV.cpp - Procedural Core To SV Conversion Pass -----===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// Lower procedural core dialect (HW/Sim) operations to the SV dialect.
//
//===----------------------------------------------------------------------===//

#include "circt/Conversion/ProceduralCoreToSV.h"

#include "circt/Dialect/SV/SVDialect.h"
#include "circt/Dialect/SV/SVOps.h"
#include "circt/Dialect/Sim/SimDialect.h"
#include "circt/Dialect/Sim/SimOps.h"
#include "mlir/Dialect/SCF/IR/SCF.h"
#include "mlir/IR/Threading.h"
#include "mlir/Pass/Pass.h"

namespace circt {
#define GEN_PASS_DEF_PROCEDURALCORETOSV
#include "circt/Conversion/Passes.h.inc"
} // namespace circt

using namespace circt;
using namespace mlir;

static sv::EventControl hwToSvEventControl(hw::EventControl ec) {
switch (ec) {
case hw::EventControl::AtPosEdge:
return sv::EventControl::AtPosEdge;
case hw::EventControl::AtNegEdge:
return sv::EventControl::AtNegEdge;
case hw::EventControl::AtEdge:
return sv::EventControl::AtEdge;
}
llvm_unreachable("Unknown event control kind");
}

namespace {

struct ProceduralOpRewriter : public RewriterBase {
ProceduralOpRewriter(MLIRContext *ctxt) : RewriterBase::RewriterBase(ctxt) {}
};

struct ProceduralCoreToSVPass
: public circt::impl::ProceduralCoreToSVBase<ProceduralCoreToSVPass> {
ProceduralCoreToSVPass() = default;
void runOnOperation() override;
};
} // namespace

void ProceduralCoreToSVPass::runOnOperation() {
hw::HWModuleOp theModule = getOperation();

ProceduralOpRewriter rewriter(theModule.getContext());

theModule.walk<mlir::WalkOrder::PreOrder>([&](hw::TriggeredOp triggeredOp)
-> WalkResult {
// Create an AlwaysOp, move the body over and remove the TriggeredOp
rewriter.setInsertionPoint(triggeredOp);
auto alwaysOp = rewriter.create<sv::AlwaysOp>(
triggeredOp.getLoc(),
ArrayRef<sv::EventControl>{hwToSvEventControl(triggeredOp.getEvent())},
ArrayRef<Value>{triggeredOp.getTrigger()});
rewriter.mergeBlocks(triggeredOp.getBodyBlock(), alwaysOp.getBodyBlock(),
triggeredOp.getInputs());
rewriter.eraseOp(triggeredOp);
// Don't recurse into the body.
Comment on lines +64 to +72
Copy link
Member

@uenoku uenoku Jul 18, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was a there specific reason that removes OpConversion pattern and does manual walk? I think we generally prefer OpConversion pattern for the maintainability.

return WalkResult::skip();
});
}
16 changes: 16 additions & 0 deletions lib/Dialect/HW/HWOps.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3349,6 +3349,22 @@ void TriggeredOp::build(OpBuilder &builder, OperationState &odsState,
b->addArguments(inputs.getTypes(), argLocs);
}

LogicalResult TriggeredOp::verify() {
if (!!getOperation()->getParentOfType<hw::TriggeredOp>())
return emitOpError("must not be nested under another TriggeredOp.");
Comment on lines +3353 to +3354
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we add `hasParentOp<"hw::HWModuleOp"> to TriggeredOp instead?

return success();
}

LogicalResult TriggeredOp::verifyRegions() {
auto numInputs = getInputs().size();
auto numArgs = getBodyBlock()->getNumArguments();
if (numInputs != numArgs)
return emitOpError("number of inputs (" + Twine(numInputs) +
") does not match number of body arguments (" +
Twine(numArgs) + ").");
return success();
}

//===----------------------------------------------------------------------===//
// TableGen generated logic.
//===----------------------------------------------------------------------===//
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// RUN: circt-opt --lower-hw-to-sv --allow-unregistered-dialect %s | FileCheck %s
// RUN: circt-opt --lower-procedural-core-to-sv --allow-unregistered-dialect %s | FileCheck %s

hw.module @foo(in %trigger : i1, in %in : i32) {
// CHECK: sv.always posedge %trigger {
Expand Down
19 changes: 19 additions & 0 deletions test/Dialect/HW/errors.mlir
Original file line number Diff line number Diff line change
Expand Up @@ -501,3 +501,22 @@ hw.module @Foo () {
hw.instance_choice "inst" option "foo" @DoesNotExist () -> ()
}

// -----

hw.module @Nested_Triggered(in %trg1 : i1, in %trg2 : i1) {
hw.triggered posedge %trg1(%trg2) : i1 {
^bb0(%arg0: i1):
// expected-error @below {{op must not be nested under another TriggeredOp.}}
hw.triggered posedge %arg0 {
}
}
}

// -----

hw.module @Triggered_Arguments(in %trg1 : i1, in %trg2 : i1) {
// expected-error @below {{number of inputs (1) does not match number of body arguments (2).}}
hw.triggered posedge %trg1(%trg2) : i1 {
^bb0(%arg0: i1, %arg1: i1):
}
}
2 changes: 1 addition & 1 deletion tools/circt-opt/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -66,11 +66,11 @@ target_link_libraries(circt-opt
CIRCTHWToLLHD
CIRCTHWToSMT
CIRCTHWToSystemC
CIRCTHWToSV
CIRCTHWTransforms
CIRCTLoopSchedule
CIRCTLoopScheduleToCalyx
CIRCTLTL
CIRCTProceduralCoreToSV
CIRCTSCFToCalyx
CIRCTScheduling
CIRCTSeq
Expand Down
Loading