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

[Seq] Add a new pass to sink clock_gate ops to the users #7474

Open
wants to merge 6 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
5 changes: 5 additions & 0 deletions include/circt/Dialect/HW/HWStructure.td
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,11 @@ def HWModuleOp : HWModuleOpBase<"module",

/// Verifies the body of the function.
LogicalResult verifyBody();

/// Append ports to the module, use the `outputVals` to update the output op
/// and set the `inputVals` with the new block args added.
void appendPorts(ArrayRef<PortInfo> ports, ArrayRef<Value> outputVals,
SmallVectorImpl<Value> &inputVals);
}];

let hasCustomAssemblyFormat = 1;
Expand Down
2 changes: 2 additions & 0 deletions include/circt/Dialect/Seq/SeqPasses.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ namespace seq {

#define GEN_PASS_DECL_EXTERNALIZECLOCKGATE
#define GEN_PASS_DECL_HWMEMSIMIMPL
#define GEN_PASS_DECL_SINKCLOCKGATES
#include "circt/Dialect/Seq/SeqPasses.h.inc"

std::unique_ptr<mlir::Pass> createLowerSeqHLMemPass();
Expand All @@ -31,6 +32,7 @@ std::unique_ptr<mlir::Pass> createLowerSeqFIFOPass();
std::unique_ptr<mlir::Pass>
createHWMemSimImplPass(const HWMemSimImplOptions &options = {});
std::unique_ptr<mlir::Pass> createLowerSeqShiftRegPass();
std::unique_ptr<mlir::Pass> createSinkClockGatesPass();

/// Generate the code for registering passes.
#define GEN_PASS_REGISTRATION
Expand Down
11 changes: 11 additions & 0 deletions include/circt/Dialect/Seq/SeqPasses.td
Original file line number Diff line number Diff line change
Expand Up @@ -107,4 +107,15 @@ def LowerSeqShiftReg : Pass<"lower-seq-shiftreg", "hw::HWModuleOp"> {
let dependentDialects = ["circt::hw::HWDialect"];
}

def SinkClockGates : Pass<"sink-clock-gates", "mlir::ModuleOp"> {
let summary = "Sink the gated clock enables into the op that is driven by the clock.";
let constructor = "circt::seq::createSinkClockGatesPass()";
let dependentDialects = ["circt::hw::HWDialect", "circt::comb::CombDialect"];
prithayan marked this conversation as resolved.
Show resolved Hide resolved
let statistics = [
Statistic<"numClockGatesConverted", "num-clock-gates-converted",
"Number of clock gates that this transformation was applied to">
];
}


#endif // CIRCT_DIALECT_SEQ_SEQPASSES
61 changes: 61 additions & 0 deletions lib/Dialect/HW/HWOps.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,13 @@
#include "circt/Support/Namespace.h"
#include "circt/Support/Naming.h"
#include "mlir/IR/Builders.h"
#include "mlir/IR/Location.h"
#include "mlir/IR/PatternMatch.h"
#include "mlir/Interfaces/FunctionImplementation.h"
#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/StringSet.h"
#include <tuple>

using namespace circt;
using namespace hw;
Expand Down Expand Up @@ -501,6 +503,65 @@ OpFoldResult ParamValueOp::fold(FoldAdaptor adaptor) {
return getValueAttr();
}

void HWModuleOp::appendPorts(ArrayRef<PortInfo> ports,
ArrayRef<Value> outputVals,
SmallVectorImpl<Value> &inputVals) {

HWModuleOp module = *this;
auto *context = module->getContext();
auto oldType = module.getHWModuleType();
auto *body = module.getBodyBlock();

ArrayRef<ModulePort> oldPorts = oldType.getPorts();

unsigned newPortsCount = oldPorts.size() + ports.size();

SmallVector<ModulePort> newPorts;
newPorts.reserve(newPortsCount);
newPorts.append(oldPorts.begin(), oldPorts.end());

SmallVector<Attribute> newResultLocs;
if (!outputVals.empty()) {
// Update the output op.
auto oldResultLocs = module.getResultLocs();
if (oldResultLocs.has_value())
newResultLocs.append(oldResultLocs->getValue().begin(),
oldResultLocs->getValue().end());
auto outputOp = cast<OutputOp>(body->getTerminator());
auto oldOperands = outputOp->getOperands();

SmallVector<Value> newOutputOperands;
llvm::append_range(newOutputOperands, oldOperands);
llvm::append_range(newOutputOperands, outputVals);
outputOp->setOperands(newOutputOperands);
}
auto oldPortAttrs = module.getAllPortAttrs();
SmallVector<Attribute> newPortAttrs(oldPortAttrs);
inputVals.reserve(ports.size() - outputVals.size());

for (auto &portInfo : ports) {
assert(!portInfo.isInOut() && "can only handle input or output ports");
if (portInfo.isInput())
inputVals.push_back(body->addArgument(portInfo.type, portInfo.loc));
else if (portInfo.isOutput())
newResultLocs.emplace_back(portInfo.loc);
newPorts.push_back(portInfo);
if (portInfo.attrs) {
if (newPortAttrs.empty() || newPortAttrs.size() < newPortsCount)
newPortAttrs.append(newPortsCount, {});
newPortAttrs[newPorts.size() - 1] = portInfo.attrs;
}
}

if (!outputVals.empty())
module.setResultLocsAttr(ArrayAttr::get(context, newResultLocs));

auto newType = ModuleType::get(context, newPorts);

module.setModuleType(newType);
module.setAllPortAttrs(newPortAttrs);
}

//===----------------------------------------------------------------------===//
// HWModuleOp
//===----------------------------------------------------------------------===/
Expand Down
1 change: 1 addition & 0 deletions lib/Dialect/Seq/Transforms/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ add_circt_dialect_library(CIRCTSeqTransforms
LowerSeqHLMem.cpp
LowerSeqFIFO.cpp
LowerSeqShiftReg.cpp
SinkClockGates.cpp

DEPENDS
CIRCTSeqTransformsIncGen
Expand Down
Loading
Loading